diff --git a/.gitea/workflows/build-and-push.yaml b/.gitea/workflows/build-and-push.yaml index 99fe1d8..3bd958a 100644 --- a/.gitea/workflows/build-and-push.yaml +++ b/.gitea/workflows/build-and-push.yaml @@ -124,50 +124,97 @@ jobs: - name: Build and Push Docker Image if: steps.check_changes.outputs.should_build == 'true' run: | - IMAGE=${{ steps.prep.outputs.image_name }} + IMAGE_GITEA=${{ steps.prep.outputs.image_name }} TAG=${{ steps.prep.outputs.docker_tag }} - BASE=${{ steps.prep.outputs.base_image }} ARGS_HASH=${{ steps.prep.outputs.build_args_hash }} + BASE=${{ steps.prep.outputs.base_image }} + REPO_PURE=${{ steps.prep.outputs.repo_pure }} set -a source <(grep -v '^#' buildargs.env | sed 's/\r$//') set +a - # Wir übergeben trotzdem ALLE Variablen als Build-Arg. - # Docker ist schlau genug, nicht genutzte Args zu ignorieren. - # WICHTIG: Bash-Array nutzen, um Leerzeichen (z.B. in DESCRIPTION) zu schützen! + # 1. Ziel-Images definieren + # Wir starten immer mit Gitea + TARGETS=("-t $IMAGE_GITEA:tmp-amd64" "-t $IMAGE_GITEA:tmp-arm64") + FINAL_TAGS=("-t $IMAGE_GITEA:$TAG" "-t $IMAGE_GITEA:latest") + + # 2. Docker Hub Check + if [[ "$PUSH" == *"dockerhub"* ]]; then + DOCKERHUB_REPO="${{ secrets.DOCKERHUB_USERNAME }}/$REPO_PURE" + echo "📢 Docker Hub Push aktiviert für: $DOCKERHUB_REPO" + TARGETS+=("-t $DOCKERHUB_REPO:tmp-amd64" "-t $DOCKERHUB_REPO:tmp-arm64") + FINAL_TAGS+=("-t $DOCKERHUB_REPO:$TAG" "-t $DOCKERHUB_REPO:latest") + fi + + # 3. Build-Args Array (wie besprochen) DOCKER_ARGS=() keys=$(grep -v '^#' buildargs.env | cut -d'=' -f1 | tr -d '\r') - for k in $keys; do - val="${!k}" - DOCKER_ARGS+=("--build-arg" "$k=$val") - done + for k in $keys; do DOCKER_ARGS+=("--build-arg" "$k=${!k}"); done - RESOLVED_BASE=$(echo $BASE) - BASE_SHA=$(docker buildx imagetools inspect $RESOLVED_BASE --format '{{json .Manifest.Digest}}' 2>/dev/null | tr -d '"' || echo "unknown") - - # AMD64 Build (Beachte die Anführungszeichen um das Array: "${DOCKER_ARGS[@]}") + BASE_SHA=$(docker buildx imagetools inspect $BASE --format '{{json .Manifest.Digest}}' 2>/dev/null | tr -d '"' || echo "unknown") + + # 4. Multi-Arch Build (Pusht die Fragmente zu allen Zielen) + # Wir filtern hier nach Architektur-Tags + AMD_TARGETS=$(echo "${TARGETS[@]}" | tr ' ' '\n' | grep 'amd64' | xargs) + ARM_TARGETS=$(echo "${TARGETS[@]}" | tr ' ' '\n' | grep 'arm64' | xargs) + docker buildx build "${DOCKER_ARGS[@]}" --pull --platform linux/amd64 -f Dockerfile \ - --label "pi_farm.base_digest=$BASE_SHA" \ - --label "pi_farm.args_hash=$ARGS_HASH" \ - -t $IMAGE:tmp-amd64 --push . + --label "pi_farm.base_digest=$BASE_SHA" --label "pi_farm.args_hash=$ARGS_HASH" \ + $AMD_TARGETS --push . - # ARM64 Build docker buildx build "${DOCKER_ARGS[@]}" --pull --platform linux/arm64 -f Dockerfile.aarch64 \ - --label "pi_farm.base_digest=$BASE_SHA" \ - --label "pi_farm.args_hash=$ARGS_HASH" \ - -t $IMAGE:tmp-arm64 --push . + --label "pi_farm.base_digest=$BASE_SHA" --label "pi_farm.args_hash=$ARGS_HASH" \ + $ARM_TARGETS --push . - # Manifest Create (mit Annotationen im Index) + # 5. Manifeste zusammenführen (Multi-Registry Support) + # Wir erstellen das Manifest für Gitea UND Docker Hub + # Hier loopen wir durch die finalen Image-Namen (Gitea und ggf. Dockerhub) + + # Gitea Manifest docker buildx imagetools create \ --annotation "index:pi_farm.base_digest=$BASE_SHA" \ --annotation "index:pi_farm.args_hash=$ARGS_HASH" \ - -t $IMAGE:$TAG $IMAGE:tmp-amd64 $IMAGE:tmp-arm64 + -t $IMAGE_GITEA:$TAG -t $IMAGE_GITEA:latest $IMAGE_GITEA:tmp-amd64 $IMAGE_GITEA:tmp-arm64 + + # Docker Hub Manifest (falls gewünscht) + if [[ "$PUSH" == *"dockerhub"* ]]; then + DOCKERHUB_REPO="${{ secrets.DOCKERHUB_USERNAME }}/$REPO_PURE" + docker buildx imagetools create \ + --annotation "index:pi_farm.base_digest=$BASE_SHA" \ + --annotation "index:pi_farm.args_hash=$ARGS_HASH" \ + -t $DOCKERHUB_REPO:$TAG -t $DOCKERHUB_REPO:latest $IMAGE_GITEA:tmp-amd64 $IMAGE_GITEA:tmp-arm64 + fi + + - name: Push README to Docker Hub + if: steps.check_changes.outputs.should_build == 'true' && contains(env.PUSH, 'dockerhub') + run: | + # 1. Login-Token holen + TOKEN=$(curl -s -X POST "https://hub.docker.com/v2/users/login/" \ + -H "Content-Type: application/json" \ + -d "{\"username\": \"${{ secrets.DOCKERHUB_USERNAME }}\", \"password\": \"${{ secrets.DOCKERHUB_TOKEN }}\"}" | jq -r .token) + + if [ "$TOKEN" != "null" ]; then + REPO_PURE=${{ steps.prep.outputs.repo_pure }} + DH_USER="${{ secrets.DOCKERHUB_USERNAME }}" - docker buildx imagetools create \ - --annotation "index:pi_farm.base_digest=$BASE_SHA" \ - --annotation "index:pi_farm.args_hash=$ARGS_HASH" \ - -t $IMAGE:latest $IMAGE:tmp-amd64 $IMAGE:tmp-arm64 + # 2. README und Kurzbeschreibung (DESCRIPTION) übertragen + # jq --raw-input --slurp liest die ganze Datei als einen JSON-String ein + echo "📤 Übertrage README zu Docker Hub..." + curl -s -X PATCH "https://hub.docker.com/v2/repositories/${DH_USER}/${REPO_PURE}/" \ + -H "Authorization: JWT ${TOKEN}" \ + -H "Content-Type: application/json" \ + -d "{ + \"description\": \"${DESCRIPTION}\", + \"full_description\": $(jq -Rs . < README.md) + }" + echo "✅ README erfolgreich aktualisiert." + else + echo "❌ Docker Hub API Login fehlgeschlagen!" + exit 1 + fi + env: + DESCRIPTION: ${{ env.DESCRIPTION }} # Aus buildargs.env - name: Cleanup Temporary Registry Tags if: steps.check_changes.outputs.should_build == 'true' @@ -310,6 +357,13 @@ jobs: RUN_CMD="${RUN_CMD} \\ \n ${FULL_URL}:${BUILD_TAG}" DOCKER_RUN_FINAL=$(echo -e "$RUN_CMD") + # --- DOCKER HUB LINK GENERATOR --- + DOCKERHUB_LINK_CONTENT="" + if [[ "$PUSH" == *"dockerhub"* ]]; then + DH_USER="${{ secrets.DOCKERHUB_USERNAME }}" + DOCKERHUB_LINK_CONTENT="[![Docker Hub](https://img.shields.io/badge/docker-hub-blue?logo=docker&logoColor=white)](https://hub.docker.com/r/${DH_USER}/${REPO_PURE})" + fi + # --- TEMPLATE ENGINE (KORRIGIERT & ERWEITERT) --- process_template() { local template=$1; local output=$2 @@ -325,6 +379,7 @@ jobs: line="${line//__CURRENT_DATE__/$CURRENT_TIME}" line="${line//__HISTORY_CONTENT__/$HISTORY_CONTENT}" line="${line//__DOCKER_RUN__/$DOCKER_RUN_FINAL}" + line="${line//__DOCKERHUB_LINK__/$DOCKERHUB_LINK_CONTENT}" # NEU: Description (mit Fallback, falls die Variable mal fehlt) line="${line//__DESCRIPTION__/${DESCRIPTION:-Keine Beschreibung angegeben.}}" diff --git a/buildargs.env b/buildargs.env index 7a66c40..060e993 100644 --- a/buildargs.env +++ b/buildargs.env @@ -19,4 +19,5 @@ ENV_PGID=1000 # VOL_CONFIG=./config:/config # VOL_DATA=./data:/data # PORT_WEB=8080:80 +PUSH=gitea,dockerhub DESCRIPTION="Dies ist ein Alpine-basiertes Base-Image für meine Pi-Farm."