---
name: Docker Image Generation
on:
workflow_call:
workflow_dispatch:
concurrency:
group: docker-{github.event.ref}
env:
DOCKER_USERNAME: ${{ vars.DOCKER_USERNAME }}
DOCKER_REPOSITORY_NAME: ${{ vars.DOCKER_REPOSITORY_NAME }}
REPOSITORY_NAME: ${{ github.event.repository.name }}
COSIGN_RELEASE_VERSION: v2.2.4
SYFT_VERSION: v1.7.0
SOURCE_DATE_EPOCH: 0
jobs:
docker-build-push:
runs-on: ubuntu-latest
permissions:
id-token: write
packages: write
steps:
- name: Checkout
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 - name: Get Last Commit Date/Time for reproducible builds
run: echo "SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)" >> $GITHUB_ENV
- name: Generate Docker Metadata
id: meta
uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 with:
images: |
${{env.DOCKER_REPOSITORY_NAME}}/${{env.REPOSITORY_NAME}}
ghcr.io/${{ github.repository}}
tags: |
type=ref,event=branch
type=ref,event=pr
type=ref,event=tag
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha
labels: |
org.opencontainers.image.licenses="MIT AND Apache-2.0"
- name: Debug Metadata
run: echo "${{ steps.meta.outputs.json }}"
- name: Setup Buildx
uses: docker/setup-buildx-action@4fd812986e6c8c2a69e18311145f9371337f27d4 with:
install: true
buildkitd-flags: --debug
- name: Setup QEMU
uses: docker/setup-qemu-action@5927c834f5b4fdf503fca6f4c7eccda82949e1ee with:
platforms: aarch64,amd64
- name: Login to DockerHub
uses: docker/login-action@0d4c9c5ea7693da7b068278f7b52bda2a190a446 with:
username: ${{ env.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Login to GitHub Container Registry
uses: docker/login-action@0d4c9c5ea7693da7b068278f7b52bda2a190a446 with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GHCR_TOKEN }}
- name: Build and Push Docker Images
id: build
uses: docker/build-push-action@1ca370b3a9802c92e886402e0dd88098a2533b12 env:
SOURCE_DATE_EPOCH: ${{ env.SOURCE_DATE_EPOCH }}
with:
context: .
push: true
provenance: true
annotations: ${{ steps.meta.outputs.annotations }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
platforms: linux/amd64,linux/arm64
- name: Debug Build
run: echo "${{join(steps.build.outputs.*, '\n')}}"
- name: Install cosign
uses: sigstore/cosign-installer@59acb6260d9c0ba8f4a2f9d9b48431a222b68e20 with:
cosign-release: ${{ env.COSIGN_RELEASE_VERSION }}
- name: Install Syft
uses: anchore/sbom-action/download-syft@d94f46e13c6c62f59525ac9a1e147a99dc0b9bf5 with:
syft-version: ${{ env.SYFT_VERSION }}
- name: Sign and Push
env:
IMAGE_DIGEST: ${{ steps.build.outputs.digest }}
IMAGE_TAGS: ${{ steps.meta.outputs.tags }}
GITHUB_TOKEN: ${{ github.token }}
SOURCE_DATE_EPOCH: ${{ env.SOURCE_DATE_EPOCH }}
run: |
for tag in ${IMAGE_TAGS}; do
image="${tag}@${IMAGE_DIGEST}"
original_name="sbom-${tag}.json"
sanitized_name=$(echo "$original_name" | sed 's|[/:]|_|g' | tr '_-' '-_')
echo "Signing the image: ${image}"
echo "Using the original name: $original_name"
echo "Using the sanitized name: $sanitized_name"
echo "Signing and pushing ${tag}@${IMAGE_DIGEST}"
cosign sign --yes ${image}
echo "Generating Software Bill of Materials for ${image}"
syft ${image} -o spdx-json=${sanitized_name} -v
echo "Attesting the Software Bill of Materials for ${image}"
cosign attest --type=spdxjson --yes --predicate ${sanitized_name} ${image}
echo "Done signing and pushing ${tag}@${IMAGE_DIGEST} with SBOM"
done
shell: bash
- name: Verify Signatures
env:
IMAGE_DIGEST: ${{ steps.build.outputs.digest }}
IMAGE_TAGS: ${{ steps.meta.outputs.tags }}
GITHUB_TOKEN: ${{ github.token }}
SOURCE_DATE_EPOCH: ${{ env.SOURCE_DATE_EPOCH }}
run: |
for tag in ${IMAGE_TAGS}; do
mkdir -p /tmp/cosign-verifications
image="${tag}@${IMAGE_DIGEST}"
echo "Verifying ${image}"
cosign verify ${image} --certificate-identity-regexp="${{vars.COSIGN_CERTIFICATE_IDENTITY}}" --certificate-oidc-issuer-regexp="${{vars.COSIGN_CERTIFICATE_OIDC_ISSUER}}" --output-file="/tmp/cosign-verifications/cosign-verify.json"
echo "Verifying SBOM Attestation for ${image}"
cosign verify-attestation ${image} --type=spdxjson --certificate-identity-regexp="${{vars.COSIGN_CERTIFICATE_IDENTITY}}" --certificate-oidc-issuer-regexp="${{vars.COSIGN_CERTIFICATE_OIDC_ISSUER}}" --output-file="/tmp/cosign-verifications/cosign-verify-attestation.json"
echo "Done verifying ${image}"
done
shell: bash
- name: Upload verification results
uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b with:
path: /tmp/cosign-verifications
name: cosign-verifications
compression-level: 9