diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c885eb4..823cc6f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -9,8 +9,8 @@ on: env: IMAGE_DESC: "Custom Fedora bootc image" - IMAGE_NAME: "${{ github.event.repository.name }}" # output image name, usually same as repo name - IMAGE_REGISTRY: "ghcr.io/${{ github.repository_owner }}" # do not edit + IMAGE_NAME: "${{ github.event.repository.name }}" + IMAGE_REGISTRY: "ghcr.io/${{ github.repository_owner }}" DEFAULT_TAG: "stable" concurrency: @@ -95,6 +95,10 @@ jobs: set -x BASE_IMAGE="${{ env.IMAGE_NAME }}:${{ env.DEFAULT_TAG }}" + # 1. Das kritische ostree-Label im Runner sichern, bevor wir das Image zerlegen + OSTREE_DIFFID=$(podman inspect $BASE_IMAGE --format '{{index .Config.Labels "ostree.final-diffid"}}' 2>/dev/null || echo "") + echo "OSTREE_DIFFID=$OSTREE_DIFFID" >> $GITHUB_ENV + # Rootfs extrahieren CONTAINER_ID=$(podman create $BASE_IMAGE) mkdir -p ./chunkah-in ./chunkah-out @@ -103,16 +107,8 @@ jobs: # Die komplette Image-Config sichern podman inspect $BASE_IMAGE --format '{{json .Config}}' > ./chunkah-config.json - - # Das kritische ostree-Label explizit auslesen, falls vorhanden - OSTREE_DIFFID=$(podman inspect $BASE_IMAGE --format '{{index .Config.Labels "ostree.final-diffid"}}' 2>/dev/null || echo "") - - # Chunkah-Lauf: Annotation explizit übergeben - ANNOTATION_ARG="" - if [ ! -z "$OSTREE_DIFFID" ]; then - ANNOTATION_ARG="--annotation ostree.final-diffid=$OSTREE_DIFFID" - fi + # Chunkah-Lauf podman run --rm \ -v ./chunkah-in:/inputs:z \ -v ./chunkah-out:/outputs:z \ @@ -120,31 +116,12 @@ jobs: quay.io/coreos/chunkah:latest \ build \ --config /config.json \ - $ANNOTATION_ARG \ --prune /sysroot/ \ --max-layers 128 \ --compressed \ --output /outputs/image.ociarchive \ --rootfs /inputs - # WIEDER EINGEFÜGT: Das OCI-Archiv in Podman laden, damit die Action es findet - podman rmi $BASE_IMAGE || true - podman load -i ./chunkah-out/image.ociarchive - - # Image sauber taggen - IMAGE_ID=$(podman images --filter "dangling=true" --format "{{.ID}}" | head -n 1) - if [ -z "$IMAGE_ID" ]; then - IMAGE_ID=$(podman images --format "{{.ID}} {{.Repository}}" | grep -v "chunkah" | head -n 1 | awk '{print $1}') - fi - podman tag $IMAGE_ID $BASE_IMAGE - - # WIEDER EINGEFÜGT: Die restlichen Tags für Datum, etc. lokal erzeugen - - name: Tag for registry - run: | - for tag in ${{ steps.metadata.outputs.tags }}; do - podman tag ${{ env.IMAGE_NAME }}:${{ env.DEFAULT_TAG }} ${{ env.IMAGE_NAME }}:$tag - done - - name: Login to GitHub Container Registry uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v3 if: github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) @@ -153,21 +130,35 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Push To GHCR - uses: redhat-actions/push-to-registry@5ed88d269cf581ea9ef6dd6806d01562096bee9c # v2 + - name: Push to GHCR via Skopeo if: github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) - id: push - env: - REGISTRY_USER: ${{ github.actor }} - REGISTRY_PASSWORD: ${{ github.token }} - with: - registry: ${{ env.IMAGE_REGISTRY }} - image: ${{ env.IMAGE_NAME }} - tags: ${{ steps.metadata.outputs.tags }} - username: ${{ env.REGISTRY_USER }} - password: ${{ env.REGISTRY_PASSWORD }} - # KORREKTUR: "image-archive" entfernt, da ungültig. - extra-args: --compression-format=zstd --compression-level=5 + run: | + set -x + + # Skopeo-Authentisierung über die Docker-Config des vorherigen Login-Schritts laden + export REGISTRY_AUTH_FILE=$HOME/.docker/config.json + REGISTRY_PATH="${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAME }}" + + # Vorbereitung für das Injezieren des Labels in die OCI Config auf der Registry + PATCH_ARG="" + if [ ! -z "${{ env.OSTREE_DIFFID }}" ]; then + # Erstellt das exakte JSON-Fragment, das Skopeo in die Image-Config patcht + PATCH_ARG="--patch-config {\"config\":{\"Labels\":{\"ostree.final-diffid\":\"${{ env.OSTREE_DIFFID }}\"}}}" + fi + + # Loop über alle von metadata-action generierten Tags + for tag in ${{ steps.metadata.outputs.tags }}; do + skopeo copy \ + $PATCH_ARG \ + --dest-compress-format=zstd \ + --dest-compress-level=5 \ + oci-archive:./chunkah-out/image.ociarchive \ + docker://$REGISTRY_PATH:$tag + done + + # Den finalen Digest ermitteln und für den nächsten Schritt in GITHUB_ENV schreiben + DIGEST=$(skopeo inspect oci-archive:./chunkah-out/image.ociarchive --format '{{.Digest}}') + echo "FINAL_IMAGE_DIGEST=$DIGEST" >> $GITHUB_ENV - name: Install Cosign uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2 @@ -176,7 +167,8 @@ jobs: - name: Sign container image if: github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) run: | - cosign sign -y --key env://COSIGN_PRIVATE_KEY "${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAME }}@${{ steps.push.outputs.digest }}" + # Nutzt den über Skopeo ermittelten Digest für das statische Signieren + cosign sign -y --key env://COSIGN_PRIVATE_KEY "${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAME }}@${{ env.FINAL_IMAGE_DIGEST }}" env: COSIGN_EXPERIMENTAL: false COSIGN_PRIVATE_KEY: ${{ secrets.SIGNING_SECRET }}