196 lines
7.4 KiB
YAML
196 lines
7.4 KiB
YAML
name: Docker Build, Test & Push
|
|
|
|
on:
|
|
push:
|
|
branches-ignore:
|
|
- main
|
|
- default
|
|
workflow_dispatch:
|
|
|
|
# ==============================================================================
|
|
# KONFIGURATION (Für andere Repositories einfach hier oben anpassen)
|
|
# ==============================================================================
|
|
env:
|
|
# Registry, Benutzer & Image-Name (leer lassen = automatisch aus Gitea-Kontext)
|
|
REGISTRY: git.dsit.me
|
|
REGISTRY_USER: ""
|
|
CUSTOM_IMAGE_NAME: "webhost"
|
|
|
|
# Pfad zum Build-Kontext und Dockerfile
|
|
BUILD_CONTEXT: ./dockerfile
|
|
DOCKERFILE: ./dockerfile/Dockerfile
|
|
|
|
# Name des temporären Test-Containers & Start-Timeout (in Sekunden)
|
|
CONTAINER_NAME: ci-test-container
|
|
STARTUP_TIMEOUT: 15
|
|
|
|
# Umgebungsvariablen für den Test-Container (leer lassen falls nicht benötigt)
|
|
CONTAINER_ENV: >-
|
|
-e SMTP_HOST=127.0.0.1
|
|
-e SMTP_PORT=2525
|
|
-e SMTP_USER=testuser@example.com
|
|
-e SMTP_PASS=supersecret
|
|
-e SMTP_FROM=noreply@example.com
|
|
-e SMTP_TLS=off
|
|
-e SMTP_STARTTLS=off
|
|
|
|
# Optionale Checks im Container (jeweils leer "" lassen zum Überspringen)
|
|
READINESS_CMD: "apache2ctl -t"
|
|
REQUIRED_PHP_EXTENSIONS: "mysqli gd imagick intl zip exif"
|
|
REQUIRED_APACHE_MODULES: "ssl_module rewrite_module"
|
|
TEST_HTTP_PORT: "80"
|
|
TEST_HTTPS_PORT: "443"
|
|
WEBROOT_DIR: "/var/www/html"
|
|
|
|
jobs:
|
|
build-test-push:
|
|
name: Build, Test & Push (${{ gitea.ref_name }})
|
|
runs-on: ubuntu-latest
|
|
if: gitea.ref_name != 'main' && gitea.ref_name != 'default'
|
|
|
|
steps:
|
|
- name: Checkout Repository
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Prepare Image Tag from Branch
|
|
id: meta
|
|
run: |
|
|
if [ -n "${CUSTOM_IMAGE_NAME}" ]; then
|
|
IMAGE_REPO=$(echo "${CUSTOM_IMAGE_NAME}" | tr '[:upper:]' '[:lower:]')
|
|
else
|
|
IMAGE_REPO=$(echo "${{ gitea.repository }}" | tr '[:upper:]' '[:lower:]')
|
|
fi
|
|
|
|
# Branch-Namen als Docker-Tag nutzen (Schrägstriche durch Bindestriche ersetzen)
|
|
BRANCH_TAG=$(echo "${{ gitea.ref_name }}" | sed 's/[^a-zA-Z0-9._-]/-/g')
|
|
FULL_TAG="${REGISTRY}/${IMAGE_REPO}:${BRANCH_TAG}"
|
|
|
|
echo "Target Image Tag: ${FULL_TAG}"
|
|
echo "image_tag=${FULL_TAG}" >> "$GITEA_OUTPUT"
|
|
|
|
- name: Build Docker Image
|
|
run: |
|
|
docker build \
|
|
-f "${DOCKERFILE}" \
|
|
-t "${{ steps.meta.outputs.image_tag }}" \
|
|
"${BUILD_CONTEXT}"
|
|
|
|
- name: Start Container & Wait for Readiness
|
|
run: |
|
|
docker rm -f "${CONTAINER_NAME}" 2>/dev/null || true
|
|
# shellcheck disable=SC2086
|
|
docker run -d \
|
|
--name "${CONTAINER_NAME}" \
|
|
${CONTAINER_ENV} \
|
|
"${{ steps.meta.outputs.image_tag }}"
|
|
|
|
echo "Waiting up to ${STARTUP_TIMEOUT}s for container to become ready..."
|
|
for i in $(seq 1 "${STARTUP_TIMEOUT}"); do
|
|
if [ "$(docker inspect -f '{{.State.Running}}' "${CONTAINER_NAME}" 2>/dev/null)" = "true" ]; then
|
|
if [ -z "${READINESS_CMD}" ] || docker exec "${CONTAINER_NAME}" sh -c "${READINESS_CMD}" >/dev/null 2>&1; then
|
|
echo "Container is running and ready."
|
|
break
|
|
fi
|
|
fi
|
|
if [ "$i" -eq "${STARTUP_TIMEOUT}" ]; then
|
|
echo "Container failed readiness check!"
|
|
docker logs "${CONTAINER_NAME}"
|
|
exit 1
|
|
fi
|
|
sleep 1
|
|
done
|
|
|
|
- name: Verify PHP Extensions
|
|
if: env.REQUIRED_PHP_EXTENSIONS != ''
|
|
run: |
|
|
docker exec "${CONTAINER_NAME}" php -v
|
|
docker exec -e REQUIRED_EXTS="${REQUIRED_PHP_EXTENSIONS}" "${CONTAINER_NAME}" php -r '
|
|
$required = preg_split("/\s+/", trim(getenv("REQUIRED_EXTS")), -1, PREG_SPLIT_NO_EMPTY);
|
|
$missing = [];
|
|
foreach ($required as $ext) {
|
|
if (!extension_loaded($ext)) {
|
|
$missing[] = $ext;
|
|
}
|
|
}
|
|
if (!empty($missing)) {
|
|
fwrite(STDERR, "Missing PHP extensions: " . implode(", ", $missing) . PHP_EOL);
|
|
exit(1);
|
|
}
|
|
echo "Verified PHP extensions: " . implode(", ", $required) . PHP_EOL;
|
|
'
|
|
|
|
- name: Verify Apache Modules
|
|
if: env.REQUIRED_APACHE_MODULES != ''
|
|
run: |
|
|
MODULES=$(docker exec "${CONTAINER_NAME}" apache2ctl -M)
|
|
for mod in ${REQUIRED_APACHE_MODULES}; do
|
|
echo "$MODULES" | grep -q "$mod" || { echo "Missing Apache module: $mod"; exit 1; }
|
|
done
|
|
echo "Verified Apache modules: ${REQUIRED_APACHE_MODULES}"
|
|
|
|
- name: Verify HTTP / HTTPS Response
|
|
if: env.TEST_HTTP_PORT != '' || env.TEST_HTTPS_PORT != ''
|
|
run: |
|
|
if [ -n "${WEBROOT_DIR}" ]; then
|
|
docker exec "${CONTAINER_NAME}" sh -c "
|
|
mkdir -p '${WEBROOT_DIR}' &&
|
|
if [ ! -f '${WEBROOT_DIR}/index.php' ] && [ ! -f '${WEBROOT_DIR}/index.html' ]; then
|
|
echo 'OK' > '${WEBROOT_DIR}/index.html'
|
|
fi
|
|
"
|
|
fi
|
|
|
|
if [ -n "${TEST_HTTP_PORT}" ]; then
|
|
echo "Testing HTTP on port ${TEST_HTTP_PORT}..."
|
|
docker exec "${CONTAINER_NAME}" curl -fsS "http://127.0.0.1:${TEST_HTTP_PORT}/" >/dev/null
|
|
echo "HTTP check passed."
|
|
fi
|
|
|
|
if [ -n "${TEST_HTTPS_PORT}" ]; then
|
|
echo "Testing HTTPS on port ${TEST_HTTPS_PORT}..."
|
|
docker exec "${CONTAINER_NAME}" curl -fsSk "https://127.0.0.1:${TEST_HTTPS_PORT}/" >/dev/null
|
|
echo "HTTPS check passed."
|
|
fi
|
|
|
|
- name: Login to Gitea Container Registry
|
|
if: success() && gitea.event_name != 'pull_request'
|
|
env:
|
|
SECRET_TOKEN: ${{ secrets.PACKAGE_TOKEN }}
|
|
VAR_TOKEN: ${{ vars.PACKAGE_TOKEN }}
|
|
DEFAULT_TOKEN: ${{ gitea.token }}
|
|
ACTOR_NAME: ${{ gitea.actor }}
|
|
OWNER_NAME: ${{ gitea.repository_owner }}
|
|
run: |
|
|
# Benutzername bestimmen (REGISTRY_USER -> gitea.actor -> gitea.repository_owner)
|
|
LOGIN_USER="${REGISTRY_USER:-${ACTOR_NAME:-${OWNER_NAME}}}"
|
|
echo "Registry-Login Benutzer: '${LOGIN_USER}'"
|
|
|
|
# Token bestimmen (Secrets -> Variables -> gitea.token)
|
|
if [ -n "${SECRET_TOKEN}" ]; then
|
|
echo "Token-Quelle: secrets.PACKAGE_TOKEN (Länge: ${#SECRET_TOKEN} Zeichen)"
|
|
RAW_TOKEN="${SECRET_TOKEN}"
|
|
elif [ -n "${VAR_TOKEN}" ]; then
|
|
echo "Token-Quelle: vars.PACKAGE_TOKEN (Länge: ${#VAR_TOKEN} Zeichen)"
|
|
RAW_TOKEN="${VAR_TOKEN}"
|
|
else
|
|
echo "WARNUNG: Weder secrets.PACKAGE_TOKEN noch vars.PACKAGE_TOKEN gefunden! Nutze gitea.token (Länge: ${#DEFAULT_TOKEN} Zeichen)"
|
|
RAW_TOKEN="${DEFAULT_TOKEN}"
|
|
fi
|
|
|
|
# Eventuelle Leerzeichen/Zeilenumbrüche entfernen
|
|
CLEAN_TOKEN=$(printf '%s' "${RAW_TOKEN}" | tr -d '\r\n ')
|
|
printf '%s\n' "${CLEAN_TOKEN}" | docker login "${REGISTRY}" -u "${LOGIN_USER}" --password-stdin
|
|
|
|
- name: Push Docker Image
|
|
if: success() && gitea.event_name != 'pull_request'
|
|
run: |
|
|
docker push "${{ steps.meta.outputs.image_tag }}"
|
|
|
|
- name: Cleanup
|
|
if: always()
|
|
run: |
|
|
echo "--- Container Logs ---"
|
|
docker logs "${CONTAINER_NAME}" || true
|
|
docker rm -f "${CONTAINER_NAME}" || true
|
|
docker logout "${REGISTRY}" 2>/dev/null || true
|