Skip to content

Commit

Permalink
ci: updates publish.yml image releasing process (RedHatProductSecurit…
Browse files Browse the repository at this point in the history
…y#220)

* ci: updates publish.yml image releasing process

The schedule trigger is added to rebuild images for
base image updates and semver tags are introduces to
continuous updates

Closes: PSCE-410

Signed-off-by: Jennifer Power <[email protected]>

* fix: minor styling fix on publish-image action

Signed-off-by: Jennifer Power <[email protected]>

* fix: adds fixes for issues found with actionlint

Signed-off-by: Jennifer Power <[email protected]>

* fix: clone the repository to get access to the composite action

Signed-off-by: Jennifer Power <[email protected]>

* fix: runs trivy action pointing to a version tag

Signed-off-by: Jennifer Power <[email protected]>

* fix: adds GH_TOKEN to schedule step

Signed-off-by: Jennifer Power <[email protected]>

* fix: moves checkout to earlier in the process

Signed-off-by: Jennifer Power <[email protected]>

* feat: adds raw inputs for non-semver tags

Signed-off-by: Jennifer Power <[email protected]>

* docs: updates tag input description

Signed-off-by: Jennifer Power <[email protected]>

* fix: ensure the schedule build checks out the git tag

The git tag must be checkout and the the image must be built
from that context to ensure only base image updates are in the
rebuilt image.

Signed-off-by: Jennifer Power <[email protected]>

* fix: adds fix for shellcheck SC2129

Signed-off-by: Jennifer Power <[email protected]>

* chore: adds minor improvements to publish-image input descriptions

Signed-off-by: Jennifer Power <[email protected]>

---------

Signed-off-by: Jennifer Power <[email protected]>
  • Loading branch information
jpower432 authored May 15, 2024
1 parent 357937c commit 9f2bba0
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 61 deletions.
96 changes: 96 additions & 0 deletions .github/actions/publish-image/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
name: "publish-image"
description: "Composite action to publish trestle-bot images."

inputs:
image:
required: true
description: The image repository location in the format of registry/name/app
release_version:
required: true
description: The version to build type semver tags from
git_ref:
required: true
description: The git reference to build image from
no_cache:
description: Skip using cache when building the image.
required: false
default: "false"
outputs:
image_sha:
value: ${{ inputs.image }}@${{ steps.build-and-push.outputs.digest }}
description: The published image with digest

runs:
using: "composite"
steps:
- name: Set up QEMU
uses: docker/setup-qemu-action@v3

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

- name: Set up cosign
uses: sigstore/[email protected]

# Tags are defined here based on workflow triggers
- name: Define metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ inputs.image }}
tags: |
type=semver,pattern=v{{major}},enable=${{ !startsWith(inputs.release_version, 'v0.') }},value=${{ inputs.release_version }}
type=semver,pattern=v{{major}}.{{minor}},value=${{ inputs.release_version }}
type=semver,pattern=v{{version}},value=${{ inputs.release_version }}
type=raw,value=${{ inputs.release_version }}-{{branch}}-{{sha}},event=workflow_dispatch
type=schedule,pattern={{date 'YYYYMMDD'}},prefix=${{ inputs.release_version }}.
flavor: |
latest=false
- name: Build and export to Docker
uses: docker/build-push-action@v5
id: build-and-export
with:
context: "${{ github.server_url }}/${{ github.repository }}.git#${{ inputs.git_ref }}"
load: true
no-cache: ${{ inputs.no_cache == 'true' }}
cache-from: type=gha
cache-to: type=gha,mode=max
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

- name: Pre-push Image Scan
uses: aquasecurity/[email protected]
with:
image-ref: ${{ inputs.image }}:${{ steps.meta.outputs.version }}
exit-code: 1
skip-files: "**/.venv/lib/**/METADATA"
scanners: secret
severity: HIGH,CRITICAL,MEDIUM

# Does not rebuild. Uses internal cache from previous step.
- name: Build and Push
uses: docker/build-push-action@v5
id: build-and-push
with:
context: "${{ github.server_url }}/${{ github.repository }}.git#${{ inputs.git_ref }}"
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

- name: Sign the image with GitHub OIDC Token
run: cosign sign --yes "$IMAGE@$DIGEST"
env:
DIGEST: ${{ steps.build-and-push.outputs.digest }}
IMAGE: ${{ inputs.image }}
shell: bash

- name: Verify image
run: |
cosign verify "$IMAGE@$DIGEST" --certificate-identity-regexp="$SUBJECT" \
--certificate-oidc-issuer=https://token.actions.githubusercontent.com
env:
SUBJECT: https://github\.com/${{ github.repository_owner }}/trestle-bot/\.github/.+
IMAGE: ${{ inputs.image }}
DIGEST: ${{ steps.build-and-push.outputs.digest }}
shell: bash
101 changes: 40 additions & 61 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
name: Publish Image to Quay

on:
schedule:
- cron: 0 0 */30 * *
release:
types: [published]
workflow_dispatch:
inputs:
tag:
description: "Name of the tag for the published image"
description: |
Name of the tag for the published image. Will be published as <tag>-<branch>-<sha>.
If a valid semver, associated semver tags will be published as well.
type: string
required: true
skip_tests:
Expand All @@ -24,7 +28,6 @@ env:
IMAGE_REGISTRY: quay.io

jobs:

publish-image:
runs-on: 'ubuntu-latest'
permissions:
Expand All @@ -35,92 +38,68 @@ jobs:
skip_tests: ${{ steps.check_event.outputs.event_type == 'release' ||
(steps.check_event.outputs.event_type == 'workflow_dispatch' &&
github.event.inputs.skip_tests == 'true') }}
image: ${{ steps.set_image_repo.outputs.image_repo }}@${{ steps.build-and-push.outputs.digest }}
image: ${{ steps.build_publish_image.outputs.image_sha }}
steps:
- name: Set up QEMU
uses: docker/setup-qemu-action@v3

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

- name: Set up cosign
uses: sigstore/[email protected]

- name: Login to Quay
uses: docker/login-action@v3
with:
username: ${{ secrets.QUAY_USER }}
password: ${{ secrets.QUAY_TOKEN }}
registry: ${{ env.IMAGE_REGISTRY }}

- name: Set image repository
id: set_image_repo
run: |
echo "image_repo=${{ env.IMAGE_REGISTRY }}/${{ vars.QUAY_ORG }}/${{ env.IMAGE_NAME }}" >> "$GITHUB_OUTPUT"
- name: Check out
uses: actions/checkout@v4
with:
persist-credentials: false

- name: Check if triggered by release or workflow dispatch
id: check_event
run: echo "event_type=${{ toJson(github.event_name) }}" >> "$GITHUB_OUTPUT"

# Using intermediary variable to process event based input
- name: Set TAG environment variable for Release
- name: Set environment information for release
if: ${{ steps.check_event.outputs.event_type == 'release' }}
run: |
echo "TAG=$RELEASE_VERSION" >> "$GITHUB_ENV"
echo "NO_CACHE=true" >> "$GITHUB_ENV"
{
echo "TAG=$RELEASE_VERSION"
echo "NO_CACHE=true"
echo "BUILD_GIT_REF=$RELEASE_VERSION"
} >> "$GITHUB_ENV"
env:
RELEASE_VERSION: ${{ github.event.release.tag_name }}

- name: Set TAG environment variable for Workflow Dispatch
- name: Set environment information for workflow dispatch
if: ${{ steps.check_event.outputs.event_type == 'workflow_dispatch' }}
run: |
echo "TAG=$INPUT_VERSION" >> "$GITHUB_ENV"
echo "NO_CACHE=$INPUT_NO_CACHE" >> "$GITHUB_ENV"
{
echo "TAG=$INPUT_VERSION"
echo "NO_CACHE=$INPUT_NO_CACHE"
echo "BUILD_GIT_REF=${{ github.ref }}"
} >> "$GITHUB_ENV"
env:
INPUT_VERSION: ${{ github.event.inputs.tag }}
INPUT_NO_CACHE: ${{ github.event.inputs.no_cache }}

- name: Build and export to Docker
uses: docker/build-push-action@v5
id: build-and-export
with:
load: true
no-cache: ${{ env.NO_CACHE == 'true' }}
cache-from: type=gha
cache-to: type=gha,mode=max
tags: ${{ steps.set_image_repo.outputs.image_repo }}:${{ env.TAG }}

- name: Pre-push Image Scan
uses: aquasecurity/[email protected]
with:
image-ref: ${{ steps.set_image_repo.outputs.image_repo }}:${{ env.TAG }}
exit-code: 1
skip-files: "**/.venv/lib/**/METADATA"
scanners: secret
severity: HIGH,CRITICAL,MEDIUM

# Does not rebuild. Uses internal cache from previous step.
- name: Build and Push
uses: docker/build-push-action@v5
id: build-and-push
with:
push: true
tags: ${{ steps.set_image_repo.outputs.image_repo }}:${{ env.TAG }}

- name: Sign the image with GitHub OIDC Token
run: cosign sign --yes "$IMAGE@$DIGEST"
env:
DIGEST: ${{ steps.build-and-push.outputs.digest }}
IMAGE: ${{ steps.set_image_repo.outputs.image_repo }}

- name: Verify image
- name: Set environment information for schedule
if: ${{ steps.check_event.outputs.event_type == 'schedule' }}
run: |
cosign verify "$IMAGE@$DIGEST" --certificate-identity-regexp="$SUBJECT" \
--certificate-oidc-issuer=https://token.actions.githubusercontent.com
LATEST_VERSION=$( gh release view --json tagName --jq '.["tagName"]' )
{
echo "TAG=$LATEST_VERSION"
echo "NO_CACHE=true"
echo "BUILD_GIT_REF=$LATEST_VERSION"
} >> "$GITHUB_ENV"
env:
SUBJECT: https://github\.com/${{ github.repository_owner }}/trestle-bot/\.github/.+
IMAGE: ${{ steps.set_image_repo.outputs.image_repo }}
DIGEST: ${{ steps.build-and-push.outputs.digest }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Build and Publish the image
uses: ./.github/actions/publish-image
id: build_publish_image
with:
image: ${{ env.IMAGE_REGISTRY }}/${{ vars.QUAY_ORG }}/${{ env.IMAGE_NAME }}
release_version: ${{ env.TAG }}
no_cache: ${{ env.NO_CACHE }}
git_ref: ${{ env.BUILD_GIT_REF }}

test:
permissions:
Expand Down

0 comments on commit 9f2bba0

Please sign in to comment.