Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
186 changes: 77 additions & 109 deletions .github/workflows/publish-image.yml
Original file line number Diff line number Diff line change
@@ -1,33 +1,24 @@
---
name: Docker

# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# This workflow builds, signs and validates Docker images for CNCF GitHub Actions runners

on:
push:
branches: [main]
# Publish semver tags as releases.
tags: ['v*.*.*']
pull_request:
branches: [main]
release:
types: [published]
workflow_dispatch: # Manual trigger capability

env:
# Use docker.io for Docker Hub if empty
REGISTRY: ghcr.io
# IMAGE_NAME maps to the Docker image name
IMAGE_NAME: cncf/external-gha-runner

# Map current release tag to the version of booty
BOOTY_VERSION: $GITHUB_REF_NAME
# Map last repo update to the build timestamp
BOOTY_VERSION: ${{ github.ref_name }}
BOOTY_TIMESTAMP: ${{ github.event.repository.updated_at}}


jobs:
build:
outputs:
Expand All @@ -37,122 +28,105 @@ jobs:
permissions:
contents: read
packages: write
# This is used to complete the identity challenge
# with sigstore/fulcio when running outside of PRs.
id-token: write

steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v3

# Install the cosign tool except on PR
# https://github.com/sigstore/cosign-installer
- name: Install cosign
if: github.event_name != 'pull_request'
uses: sigstore/cosign-installer@main
uses: sigstore/cosign-installer@v2.8.1
with:
cosign-release: 'v2.1.1'

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

# Login against a Docker registry except on PR
# https://github.com/docker/login-action
- name: Log into registry ${{ env.REGISTRY }}
if: github.event_name != 'pull_request'
uses: docker/login-action@28218f9b04b4f3f62068d7b6ce6ca5b26e35336c
- name: Log into registry
# Only log in when pushing is required
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
uses: docker/login-action@v2
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

# Extract metadata (tags, labels) for Docker
# https://github.com/docker/metadata-action
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
uses: docker/metadata-action@v4
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

# Build and push Docker image with Buildx (don't push on PR)
# https://github.com/docker/build-push-action
- name: Build and push Docker image
id: build-and-push
uses: docker/build-push-action@v3
uses: docker/build-push-action@v4
with:
context: ./ci/gha-runner-image/
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
# Allow pushing from PRs from the same repository
push: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
# Build and push Docker image with Buildx (don't push on PR)
# https://github.com/docker/build-push-action

- name: Sign the published Docker image
if: ${{ github.event_name != 'pull_request' }}
# Only sign when we've pushed the image
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
env:
COSIGN_EXPERIMENTAL: "true"
# uses the identity token to provision an ephemeral certificate
# against the sigstore community Fulcio instance.
run: |
cosign sign --yes \
${{env.REGISTRY}}/${{env.IMAGE_NAME}}@${{steps.build-and-push.outputs.digest}}
cosign sign --yes ${{env.REGISTRY}}/${{env.IMAGE_NAME}}@${{steps.build-and-push.outputs.digest}}

- name: Output image
id: image
run: |
# NOTE: We need to use the image and digest in order to make sure
# that the image we attest has not been modified.
# NOTE: The digest output from docker/build-push-action is of the
# form "sha256:<digest>"
image_name="${REGISTRY}/${IMAGE_NAME}:${{ github.ref_name }}"
echo "::set-output name=image::$image_name"
echo "image=${REGISTRY}/${IMAGE_NAME}:${{ github.ref_name }}" >> $GITHUB_OUTPUT

build-openeuler:
outputs:
image: ${{ steps.image.outputs.image }}
digest: ${{ steps.build-and-push.outputs.digest }}
digest: ${{ steps.build-and-push-openeuler.outputs.digest }}
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
# This is used to complete the identity challenge
# with sigstore/fulcio when running outside of PRs.
id-token: write

steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v3

# Install the cosign tool except on PR
# https://github.com/sigstore/cosign-installer
- name: Install cosign
if: github.event_name != 'pull_request'
uses: sigstore/cosign-installer@main
uses: sigstore/cosign-installer@v2.8.1
with:
cosign-release: 'v2.1.1'

- name: Set up QEMU
uses: docker/setup-qemu-action@v2
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@v3

# Login against a Docker registry except on PR
# https://github.com/docker/login-action
- name: Log into registry ${{ env.REGISTRY }}
- name: Log into registry
if: github.event_name != 'pull_request'
uses: docker/login-action@28218f9b04b4f3f62068d7b6ce6ca5b26e35336c
uses: docker/login-action@v2
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

# Extract metadata (tags, labels) for Docker
# https://github.com/docker/metadata-action
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
uses: docker/metadata-action@v4
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

# Build and push Docker image with Buildx (don't push on PR)
# https://github.com/docker/build-push-action
- name: Build and push OpenEuler Docker image
id: build-and-push-openeuler
uses: docker/build-push-action@v3
uses: docker/build-push-action@v4
with:
context: ./ci/gha-runner-image/
platforms: linux/amd64,linux/arm64
Expand All @@ -161,63 +135,57 @@ jobs:
ghcr.io/cncf/gha-runner:openeuler
labels: ${{ steps.meta.outputs.labels }}
file: ./ci/gha-runner-image/Dockerfile.openeuler

- name: Sign the published OpenEuler Docker image
if: ${{ github.event_name != 'pull_request' }}
env:
COSIGN_EXPERIMENTAL: "true"
# Uses the identity token to provision an ephemeral certificate
# against the sigstore community Fulcio instance.
run: cosign sign -y ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:openeuler

- name: Output image
id: image
run: |
# NOTE: We need to use the image and digest in order to make sure
# that the image we attest has not been modified.
# NOTE: The digest output from docker/build-push-action is of the
# form "sha256:<digest>"
image_name="${REGISTRY}/${IMAGE_NAME}:${{ github.ref_name }}"
echo "::set-output name=image::$image_name"
# Generate SLSA provenance for the image
# Upload the provenance to ghcr.io
provenance:
needs: [build]
permissions:
id-token: write # For signing.
actions: read # For reading workflow info.
packages: write # For uploading attestations.
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@main
with:
image: ${{ needs.build.outputs.image }}
digest: ${{ needs.build.outputs.digest }}
registry-username: ${{ github.actor }}
compile-generator: true
secrets:
registry-password: ${{ secrets.GITHUB_TOKEN }}
# Verify the created provenance attestation.
verify:
# NOTE: this name is used as the status check name and by protected
# branches for required status checks. It should have a unique name among
# other pre-submits.
name: verify container provenance
needs: [build, provenance]
permissions:
packages: read # For reading attestations.
echo "image=${REGISTRY}/${IMAGE_NAME}:openeuler" >> $GITHUB_OUTPUT

# Image validation job
validate:
name: validate images
needs: [build, build-openeuler]
runs-on: ubuntu-latest
if: ${{ always() }}
# Run validation on PRs from the same repository
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
permissions:
packages: read
steps:
- uses: sigstore/cosign-installer@main
- name: Install cosign
uses: sigstore/cosign-installer@v2.8.1
with:
cosign-release: 'v2.4.2'
- env:
REGISTRY_USERNAME: ${{ github.actor }}
REGISTRY_PASSWORD: ${{ secrets.GITHUB_TOKEN }}
cosign-release: 'v2.1.1'
- name: Verify standard image
env:
IMAGE_NAME: ${{ needs.build.outputs.image }}
IMAGE_DIGEST: ${{ needs.build.outputs.digest }}
run: |
cosign version \
COSIGN_EXPERIMENTAL=1 cosign verify-attestation \
--certificate-identity-regexp=".*" \
--certificate-oidc-issuer-regexp=".*" \
--type slsaprovenance "${{ env.IMAGE_NAME }}@${{env.IMAGE_DIGEST}}"
# TODO (github.com/slsa-framework/slsa-verifier/issues/92):
# Add step to verify using slsa-verifier
echo "Verifying image: $IMAGE_NAME@$IMAGE_DIGEST"

if [ -z "$IMAGE_DIGEST" ]; then
echo "Error: Image digest is empty"
exit 1
fi

COSIGN_EXPERIMENTAL=1 cosign verify $IMAGE_NAME@$IMAGE_DIGEST

- name: Verify OpenEuler image
env:
IMAGE_NAME: ${{ needs.build-openeuler.outputs.image }}
IMAGE_DIGEST: ${{ needs.build-openeuler.outputs.digest }}
run: |
echo "Verifying OpenEuler image: $IMAGE_NAME@$IMAGE_DIGEST"

if [ -z "$IMAGE_DIGEST" ]; then
echo "Error: OpenEuler image digest is empty"
exit 1
fi

COSIGN_EXPERIMENTAL=1 cosign verify $IMAGE_NAME@$IMAGE_DIGEST
Loading