From 0f5316e5a96c397d6d6e1fa2a72b7c36155f2ead Mon Sep 17 00:00:00 2001 From: Dan Barr Date: Tue, 8 Oct 2024 14:42:03 -0400 Subject: [PATCH 1/2] Handle mixed case names in build-image workflows The workflows fail if the GitHub organization name or repository name use mixed case, since Docker only supports lower-cased image names. Updated to use the docker/metadata-action tags output since that action handles the normalization. --- .../build-image-signed-cosign-malicious.yml | 11 ++++++++--- .../build-image-signed-cosign-static-copied.yml | 7 +++++-- .../build-image-signed-cosign-static.yml | 8 +++++--- .github/workflows/build-image-signed-cosign.yml | 10 ++++++---- .../build-image-signed-ghat-malicious.yml | 16 +++++++++++++++- .../build-image-signed-ghat-static-copied.yml | 14 +++++++++++++- .../build-image-signed-ghat-static.yml | 14 +++++++++++++- .github/workflows/build-image-signed-ghat.yml | 14 +++++++++++++- .github/workflows/build-image-unsigned.yml | 17 ++++------------- Makefile | 3 +++ 10 files changed, 85 insertions(+), 29 deletions(-) diff --git a/.github/workflows/build-image-signed-cosign-malicious.yml b/.github/workflows/build-image-signed-cosign-malicious.yml index f4f0848..929fbc9 100644 --- a/.github/workflows/build-image-signed-cosign-malicious.yml +++ b/.github/workflows/build-image-signed-cosign-malicious.yml @@ -20,6 +20,8 @@ jobs: uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 - name: The malicious step + env: + IMAGE_NAME: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} run: | make build-malicious-image @@ -41,6 +43,9 @@ jobs: uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=raw,value=latest + type=raw,value=daily - name: Build and push Docker image id: build-and-push @@ -48,7 +53,7 @@ jobs: with: context: . push: ${{ github.event_name != 'pull_request' }} - tags: ghcr.io/${{ github.repository }}:latest,ghcr.io/${{ github.repository }}:daily + tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=max @@ -56,8 +61,8 @@ jobs: - name: Sign the published Docker image env: + TAGS: ${{ steps.meta.outputs.tags }} DIGEST: ${{ steps.build-and-push.outputs.digest }} run: | cosign version - echo "ghcr.io/${{ github.repository }}:daily" | xargs -I {} cosign sign --yes {}@${DIGEST} - echo "ghcr.io/${{ github.repository }}:latest" | xargs -I {} cosign sign --yes {}@${DIGEST} + echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST} diff --git a/.github/workflows/build-image-signed-cosign-static-copied.yml b/.github/workflows/build-image-signed-cosign-static-copied.yml index 0532b2b..cd749b2 100644 --- a/.github/workflows/build-image-signed-cosign-static-copied.yml +++ b/.github/workflows/build-image-signed-cosign-static-copied.yml @@ -37,20 +37,23 @@ jobs: uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=raw,value=static - name: Build and push Docker image id: build-and-push uses: docker/build-push-action@ac9327eae2b366085ac7f6a2d02df8aa8ead720a with: push: true - tags: ghcr.io/${{ github.repository }}:static + tags: ${{ steps.meta.outputs.tags }} context: . file : Dockerfile.static - name: Sign the published Docker image env: + TAGS: ${{ steps.meta.outputs.tags }} DIGEST: ${{ steps.build-and-push.outputs.digest }} run: | cosign version - echo "ghcr.io/${{ github.repository }}:static" | xargs -I {} cosign sign --yes {}@${DIGEST} + echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST} diff --git a/.github/workflows/build-image-signed-cosign-static.yml b/.github/workflows/build-image-signed-cosign-static.yml index 90b9346..dfb1ba0 100644 --- a/.github/workflows/build-image-signed-cosign-static.yml +++ b/.github/workflows/build-image-signed-cosign-static.yml @@ -37,20 +37,22 @@ jobs: uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=raw,value=static - name: Build and push Docker image id: build-and-push uses: docker/build-push-action@ac9327eae2b366085ac7f6a2d02df8aa8ead720a with: push: true - tags: ghcr.io/${{ github.repository }}:static + tags: ${{ steps.meta.outputs.tags }} context: . file : Dockerfile.static - - name: Sign the published Docker image env: + TAGS: ${{ steps.meta.outputs.tags }} DIGEST: ${{ steps.build-and-push.outputs.digest }} run: | cosign version - echo "ghcr.io/${{ github.repository }}:static" | xargs -I {} cosign sign --yes {}@${DIGEST} + echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST} diff --git a/.github/workflows/build-image-signed-cosign.yml b/.github/workflows/build-image-signed-cosign.yml index 9220232..84369bc 100644 --- a/.github/workflows/build-image-signed-cosign.yml +++ b/.github/workflows/build-image-signed-cosign.yml @@ -37,6 +37,9 @@ jobs: uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=raw,value=latest + type=raw,value=daily - name: Build and push Docker image id: build-and-push @@ -44,16 +47,15 @@ jobs: with: context: . push: ${{ github.event_name != 'pull_request' }} - tags: ghcr.io/${{ github.repository }}:latest,ghcr.io/${{ github.repository }}:daily + tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=max - - name: Sign the published Docker image env: + TAGS: ${{ steps.meta.outputs.tags }} DIGEST: ${{ steps.build-and-push.outputs.digest }} run: | cosign version - echo "ghcr.io/${{ github.repository }}:daily" | xargs -I {} cosign sign --yes {}@${DIGEST} - echo "ghcr.io/${{ github.repository }}:latest" | xargs -I {} cosign sign --yes {}@${DIGEST} + echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST} diff --git a/.github/workflows/build-image-signed-ghat-malicious.yml b/.github/workflows/build-image-signed-ghat-malicious.yml index 47c0497..56fb309 100644 --- a/.github/workflows/build-image-signed-ghat-malicious.yml +++ b/.github/workflows/build-image-signed-ghat-malicious.yml @@ -2,6 +2,10 @@ name: image-signed-ghat(latest)-malicious on: workflow_dispatch: +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + jobs: build: runs-on: ubuntu-latest @@ -16,6 +20,8 @@ jobs: uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 - name: The malicious step + env: + IMAGE_NAME: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} run: | make build-malicious-image @@ -26,12 +32,20 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Extract Docker metadata + id: meta + uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=raw,value=latest + - name: Build and push image id: push-step uses: docker/build-push-action@ac9327eae2b366085ac7f6a2d02df8aa8ead720a with: push: true - tags: ghcr.io/${{ github.repository }}:latest + tags: ${{ steps.meta.outputs.tags }} context: . - name: Attest image diff --git a/.github/workflows/build-image-signed-ghat-static-copied.yml b/.github/workflows/build-image-signed-ghat-static-copied.yml index dc719c5..12da64f 100644 --- a/.github/workflows/build-image-signed-ghat-static-copied.yml +++ b/.github/workflows/build-image-signed-ghat-static-copied.yml @@ -2,6 +2,10 @@ name: image-signed-ghat(static)-copied on: workflow_dispatch: +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + jobs: build: runs-on: ubuntu-latest @@ -22,12 +26,20 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Extract Docker metadata + id: meta + uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=raw,value=static + - name: Build and push image id: push-step uses: docker/build-push-action@ac9327eae2b366085ac7f6a2d02df8aa8ead720a with: push: true - tags: ghcr.io/${{ github.repository }}:static + tags: ${{ steps.meta.outputs.tags }} context: . file : Dockerfile.static diff --git a/.github/workflows/build-image-signed-ghat-static.yml b/.github/workflows/build-image-signed-ghat-static.yml index 195ad21..c05ae55 100644 --- a/.github/workflows/build-image-signed-ghat-static.yml +++ b/.github/workflows/build-image-signed-ghat-static.yml @@ -2,6 +2,10 @@ name: image-signed-ghat(static) on: workflow_dispatch: +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + jobs: build: runs-on: ubuntu-latest @@ -22,12 +26,20 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Extract Docker metadata + id: meta + uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=raw,value=static + - name: Build and push image id: push-step uses: docker/build-push-action@ac9327eae2b366085ac7f6a2d02df8aa8ead720a with: push: true - tags: ghcr.io/${{ github.repository }}:static + tags: ${{ steps.meta.outputs.tags }} context: . file : Dockerfile.static diff --git a/.github/workflows/build-image-signed-ghat.yml b/.github/workflows/build-image-signed-ghat.yml index d91b6fc..8ad9135 100644 --- a/.github/workflows/build-image-signed-ghat.yml +++ b/.github/workflows/build-image-signed-ghat.yml @@ -2,6 +2,10 @@ name: image-signed-ghat(latest) on: workflow_dispatch: +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + jobs: build: runs-on: ubuntu-latest @@ -22,12 +26,20 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Extract Docker metadata + id: meta + uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=raw,value=latest + - name: Build and push image id: push-step uses: docker/build-push-action@ac9327eae2b366085ac7f6a2d02df8aa8ead720a with: push: true - tags: ghcr.io/${{ github.repository }}:latest + tags: ${{ steps.meta.outputs.tags }} context: . - name: Attest image diff --git a/.github/workflows/build-image-unsigned.yml b/.github/workflows/build-image-unsigned.yml index 255ccb2..3759df4 100644 --- a/.github/workflows/build-image-unsigned.yml +++ b/.github/workflows/build-image-unsigned.yml @@ -19,11 +19,6 @@ jobs: - name: Checkout repository uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 -# - name: Install Cosign -# uses: sigstore/cosign-installer@6e04d228eb30da1757ee4e1dd75a0ec73a653e06 #v3.1.1 -# with: -# cosign-release: 'v2.1.1' - - name: Setup Docker buildx uses: docker/setup-buildx-action@79abd3f86f79a9d68a23c75a09a9a85889262adf @@ -39,6 +34,9 @@ jobs: uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=raw,value=latest + type=raw,value=daily - name: Build and push Docker image id: build-and-push @@ -46,14 +44,7 @@ jobs: with: context: . push: ${{ github.event_name != 'pull_request' }} - tags: ghcr.io/${{ github.repository }}:latest,ghcr.io/${{ github.repository }}:daily + tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=max - -# - name: Sign the published Docker image -# env: -# DIGEST: ${{ steps.build-and-push.outputs.digest }} -# run: | -# echo "ghcr.io/${{ github.repository }}:daily" | xargs -I {} cosign sign --yes {}@${DIGEST} -# echo "ghcr.io/${{ github.repository }}:latest" | xargs -I {} cosign sign --yes {}@${DIGEST} diff --git a/Makefile b/Makefile index 43c3ff8..58ccda3 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,9 @@ # Replace this with your image name, i.e. ghcr.io//demo-repo-js:latest IMAGE_NAME?=ghcr.io/stacklok/demo-repo-js:latest +# Lowercase the image name to handle mixed-case GitHub org/repo names +IMAGE_NAME := $(shell echo $(IMAGE_NAME) | tr '[:upper:]' '[:lower:]') + # Replace this with your GitHub username and PAT. # This is used to authenticate with GitHub Container Registry (GHCR) # and push the image to your repository. From 58831be9d097b04f9b1b704f23a0d41463c142cb Mon Sep 17 00:00:00 2001 From: Dan Barr Date: Wed, 9 Oct 2024 12:16:33 -0400 Subject: [PATCH 2/2] Minor formatting --- .github/workflows/build-image-signed-cosign-malicious.yml | 2 -- .../workflows/build-image-signed-cosign-static-copied.yml | 4 +--- .github/workflows/build-image-signed-cosign-static.yml | 3 +-- .github/workflows/build-image-signed-cosign.yml | 1 - .../workflows/build-image-signed-ghat-static-copied.yml | 2 +- .github/workflows/build-image-signed-ghat-static.yml | 2 +- .github/workflows/build-image-unsigned.yml | 1 - README.md | 8 +++++--- 8 files changed, 9 insertions(+), 14 deletions(-) diff --git a/.github/workflows/build-image-signed-cosign-malicious.yml b/.github/workflows/build-image-signed-cosign-malicious.yml index 929fbc9..2f411a6 100644 --- a/.github/workflows/build-image-signed-cosign-malicious.yml +++ b/.github/workflows/build-image-signed-cosign-malicious.yml @@ -8,7 +8,6 @@ env: jobs: build: - runs-on: ubuntu-latest permissions: contents: read @@ -58,7 +57,6 @@ jobs: cache-from: type=gha cache-to: type=gha,mode=max - - name: Sign the published Docker image env: TAGS: ${{ steps.meta.outputs.tags }} diff --git a/.github/workflows/build-image-signed-cosign-static-copied.yml b/.github/workflows/build-image-signed-cosign-static-copied.yml index cd749b2..c8b40bb 100644 --- a/.github/workflows/build-image-signed-cosign-static-copied.yml +++ b/.github/workflows/build-image-signed-cosign-static-copied.yml @@ -8,7 +8,6 @@ env: jobs: build: - runs-on: ubuntu-latest permissions: contents: read @@ -47,8 +46,7 @@ jobs: push: true tags: ${{ steps.meta.outputs.tags }} context: . - file : Dockerfile.static - + file: Dockerfile.static - name: Sign the published Docker image env: diff --git a/.github/workflows/build-image-signed-cosign-static.yml b/.github/workflows/build-image-signed-cosign-static.yml index dfb1ba0..3681b85 100644 --- a/.github/workflows/build-image-signed-cosign-static.yml +++ b/.github/workflows/build-image-signed-cosign-static.yml @@ -8,7 +8,6 @@ env: jobs: build: - runs-on: ubuntu-latest permissions: contents: read @@ -47,7 +46,7 @@ jobs: push: true tags: ${{ steps.meta.outputs.tags }} context: . - file : Dockerfile.static + file: Dockerfile.static - name: Sign the published Docker image env: diff --git a/.github/workflows/build-image-signed-cosign.yml b/.github/workflows/build-image-signed-cosign.yml index 84369bc..b0ea08d 100644 --- a/.github/workflows/build-image-signed-cosign.yml +++ b/.github/workflows/build-image-signed-cosign.yml @@ -8,7 +8,6 @@ env: jobs: build: - runs-on: ubuntu-latest permissions: contents: read diff --git a/.github/workflows/build-image-signed-ghat-static-copied.yml b/.github/workflows/build-image-signed-ghat-static-copied.yml index 12da64f..354aa2f 100644 --- a/.github/workflows/build-image-signed-ghat-static-copied.yml +++ b/.github/workflows/build-image-signed-ghat-static-copied.yml @@ -41,7 +41,7 @@ jobs: push: true tags: ${{ steps.meta.outputs.tags }} context: . - file : Dockerfile.static + file: Dockerfile.static - name: Attest image uses: actions/attest-build-provenance@v1.4.1 diff --git a/.github/workflows/build-image-signed-ghat-static.yml b/.github/workflows/build-image-signed-ghat-static.yml index c05ae55..9c89292 100644 --- a/.github/workflows/build-image-signed-ghat-static.yml +++ b/.github/workflows/build-image-signed-ghat-static.yml @@ -41,7 +41,7 @@ jobs: push: true tags: ${{ steps.meta.outputs.tags }} context: . - file : Dockerfile.static + file: Dockerfile.static - name: Attest image uses: actions/attest-build-provenance@v1.4.1 diff --git a/.github/workflows/build-image-unsigned.yml b/.github/workflows/build-image-unsigned.yml index 3759df4..1c6fa43 100644 --- a/.github/workflows/build-image-unsigned.yml +++ b/.github/workflows/build-image-unsigned.yml @@ -8,7 +8,6 @@ env: jobs: build: - runs-on: ubuntu-latest permissions: contents: read diff --git a/README.md b/README.md index 324a8ae..685c556 100644 --- a/README.md +++ b/README.md @@ -3,12 +3,11 @@ ## Overview The `demo-repo-js` project is a repository template primarily intended for testing and -demonstration purposes with stacklok projects. It is a simple JS project that allows you to +demonstration purposes with Stacklok projects. It is a simple JavaScript project that allows you to quickly get started with testing and demonstrating how you can use Minder and Trusty with -your Python projects. It features continuous integration (CI) workflows that demonstrate how to +your JavaScript projects. It features continuous integration (CI) workflows that demonstrate how to build, test, and sign artifacts using Sigstore and GitHub Attestations. - ## Features - Pre-configured `package.json` with `react` and `next` dependencies @@ -17,18 +16,21 @@ build, test, and sign artifacts using Sigstore and GitHub Attestations. - Dockerfile for building a container image GitHub Actions workflows for: + - Producing signed and unsigned artifacts using Sigstore and GitHub attestations API - Producing artifacts such as container images and binaries - Producing container images that are reproducible (always the same digest) - Producing "malicious" container images for testing purposes (e.g., code content was altered while building the image) Makefile targets for simulating out-of-band signing of artifacts (both intended and not): + - Generating signed container images and "malicious" images - Pushing container images to container registry (GHCR) - Generating a local key pair for signing container images - Sign container images using Sigstore by using a local key pair or by going through the Sigstore OIDC sign-in flow Branches: + - Set of pre-created branches to use for opening PRs each demonstrating a different feature or use case with Minder and Trusty ## How to Use This Template