diff --git a/.gitea/workflows/publish.yaml b/.gitea/workflows/publish.yaml index 71bf753..152043d 100644 --- a/.gitea/workflows/publish.yaml +++ b/.gitea/workflows/publish.yaml @@ -122,13 +122,45 @@ jobs: apko build --arch aarch64 ${{ matrix.config }} \ ${{ secrets.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ matrix.variant }}-${{ steps.tag.outputs.suffix }} \ /tmp/build-arm64/image.tar - cat > /tmp/Dockerfile <<'EOF' - FROM scratch - ARG TARGETARCH - ADD build-${TARGETARCH}/image.tar / - USER 65532 - EOF - sed -i 's/^ //' /tmp/Dockerfile + + # Extract the rootfs layer from the OCI archive for each arch. + # apko outputs an OCI image tarball; we need to extract just the + # filesystem layer (.tar.gz) and the config metadata. + for arch in amd64 arm64; do + cd /tmp/build-${arch} + tar xf image.tar + # The .tar.gz file is the filesystem layer + ROOTFS=$(ls *.tar.gz 2>/dev/null | head -1) + mv "$ROOTFS" rootfs.tar.gz + # Extract ENV and ENTRYPOINT from the OCI config + MANIFEST_DIGEST=$(jq -r '.manifests[0].digest' index.json | sed 's/sha256://') + CONFIG_DIGEST=$(jq -r '.config.digest' "sha256:${MANIFEST_DIGEST}" | sed 's/sha256://') + cp "sha256:${CONFIG_DIGEST}" config.json + # Clean up OCI artifacts + rm -f image.tar index.json manifest.json oci-layout sha256:* + cd /tmp + done + + # Generate Dockerfile with metadata from the OCI config + # (use amd64 config as reference — env vars are the same for both arches) + ENV_LINES=$(jq -r '(.config.Env // [])[] | "ENV " + .' /tmp/build-amd64/config.json) + ENTRYPOINT=$(jq -r '(.config.Entrypoint // [])[]' /tmp/build-amd64/config.json | head -1) + USER_ID=$(jq -r '.config.User // "65532"' /tmp/build-amd64/config.json) + WORKDIR=$(jq -r '.config.WorkingDir // "/"' /tmp/build-amd64/config.json) + + { + echo "FROM scratch" + echo "ARG TARGETARCH" + echo "ADD build-\${TARGETARCH}/rootfs.tar.gz /" + if [ -n "$ENV_LINES" ]; then + echo "$ENV_LINES" + fi + if [ -n "$ENTRYPOINT" ] && [ "$ENTRYPOINT" != "null" ]; then + echo "ENTRYPOINT [\"${ENTRYPOINT}\"]" + fi + echo "WORKDIR ${WORKDIR}" + echo "USER ${USER_ID}" + } > /tmp/Dockerfile - name: Build and push with buildx (SBOM + provenance) uses: docker/build-push-action@v5 diff --git a/.gitea/workflows/rebuild.yaml b/.gitea/workflows/rebuild.yaml index 06ad821..9df01fb 100644 --- a/.gitea/workflows/rebuild.yaml +++ b/.gitea/workflows/rebuild.yaml @@ -114,13 +114,45 @@ jobs: apko build --arch aarch64 ${{ matrix.config }} \ ${{ secrets.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ matrix.variant }}-latest \ /tmp/build-arm64/image.tar - cat > /tmp/Dockerfile <<'EOF' - FROM scratch - ARG TARGETARCH - ADD build-${TARGETARCH}/image.tar / - USER 65532 - EOF - sed -i 's/^ //' /tmp/Dockerfile + + # Extract the rootfs layer from the OCI archive for each arch. + # apko outputs an OCI image tarball; we need to extract just the + # filesystem layer (.tar.gz) and the config metadata. + for arch in amd64 arm64; do + cd /tmp/build-${arch} + tar xf image.tar + # The .tar.gz file is the filesystem layer + ROOTFS=$(ls *.tar.gz 2>/dev/null | head -1) + mv "$ROOTFS" rootfs.tar.gz + # Extract ENV and ENTRYPOINT from the OCI config + MANIFEST_DIGEST=$(jq -r '.manifests[0].digest' index.json | sed 's/sha256://') + CONFIG_DIGEST=$(jq -r '.config.digest' "sha256:${MANIFEST_DIGEST}" | sed 's/sha256://') + cp "sha256:${CONFIG_DIGEST}" config.json + # Clean up OCI artifacts + rm -f image.tar index.json manifest.json oci-layout sha256:* + cd /tmp + done + + # Generate Dockerfile with metadata from the OCI config + # (use amd64 config as reference — env vars are the same for both arches) + ENV_LINES=$(jq -r '(.config.Env // [])[] | "ENV " + .' /tmp/build-amd64/config.json) + ENTRYPOINT=$(jq -r '(.config.Entrypoint // [])[]' /tmp/build-amd64/config.json | head -1) + USER_ID=$(jq -r '.config.User // "65532"' /tmp/build-amd64/config.json) + WORKDIR=$(jq -r '.config.WorkingDir // "/"' /tmp/build-amd64/config.json) + + { + echo "FROM scratch" + echo "ARG TARGETARCH" + echo "ADD build-\${TARGETARCH}/rootfs.tar.gz /" + if [ -n "$ENV_LINES" ]; then + echo "$ENV_LINES" + fi + if [ -n "$ENTRYPOINT" ] && [ "$ENTRYPOINT" != "null" ]; then + echo "ENTRYPOINT [\"${ENTRYPOINT}\"]" + fi + echo "WORKDIR ${WORKDIR}" + echo "USER ${USER_ID}" + } > /tmp/Dockerfile - name: Build and push with buildx (SBOM + provenance) uses: docker/build-push-action@v5