Skip to content

Commit

Permalink
Rebuild Docker image when Trivy scan fails (#12)
Browse files Browse the repository at this point in the history
* IT-3921: Rebuild container when Trivy code scan fails
  • Loading branch information
brucehoff authored Dec 30, 2024
1 parent 2821f55 commit 73743f3
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 46 deletions.
46 changes: 16 additions & 30 deletions .github/workflows/docker_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,50 +2,38 @@
name: Run precommit and conditionally build container

on:
push:
branches:
- '*'
tags:
- 'v[0-9]+\.[0-9]+\.[0-9]+'
pull_request:
branches:
- '*'
workflow_call:
inputs:
REF_TO_CHECKOUT:
required: false
type: string
description: reference to checkout, e.g. a tag like v1.0.1. Defaults to the branch/tag of the current event.
IMAGE_REFERENCES:
required: true
type: string
description: "image references, e.g., ghcr.io/sage-bionetworks/rstudio-service-catalog:1.0.1"

env:
REGISTRY: ghcr.io
IMAGE_PATH: ghcr.io/${{ github.repository }}
TARFILE_NAME: image.tar


jobs:
tests:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: ${{ inputs.REF_TO_CHECKOUT }}

- name: Static Analysis
uses: pre-commit/[email protected]

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/[email protected]
with:
images: ${{ env.IMAGE_PATH }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}} # major.minor.patch
type=semver,pattern={{major}}.{{minor}}
- name: Check that build works, save for scanning, but don't push yet
uses: docker/[email protected]
with:
context: .
push: false
outputs: type=tar,dest=${{ env.TARFILE_NAME }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

- name: Upload tarball for use by Trivy job
uses: actions/upload-artifact@v4
Expand All @@ -54,7 +42,6 @@ jobs:
path: ${{ env.TARFILE_NAME }}

outputs:
meta_json: ${{ steps.meta.outputs.json }}
tarfile_artifact: ${{ env.TARFILE_NAME }}

trivy-scan:
Expand All @@ -67,15 +54,12 @@ jobs:
EXIT_CODE: 1

push-image:
if: ${{ github.event_name == 'push' }}
if: ${{ github.event_name == 'push' || github.event_name == 'schedule' }}
needs: [tests, trivy-scan]
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
strategy:
matrix:
value: ${{ fromJSON(needs.tests.outputs.meta_json).tags }}

steps:
- name: Login to GitHub Container Registry
Expand All @@ -87,11 +71,13 @@ jobs:

- name: Checkout repository
uses: actions/checkout@v4
with:
ref: ${{ inputs.REF_TO_CHECKOUT }}

- name: Build and push Docker image
uses: docker/[email protected]
with:
context: .
push: true
tags: ${{ matrix.value }}
tags: ${{ inputs.IMAGE_REFERENCES }}
...
41 changes: 41 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
name: Determine the Docker 'tags' to use, then invoke the build/test/publish workflow.

on:
push:
branches:
- '*'
tags:
- 'v[0-9]+\.[0-9]+\.[0-9]+'
pull_request:
branches:
- '*'

env:
IMAGE_PATH: ghcr.io/${{ github.repository }}

jobs:
get-tags:
runs-on: ubuntu-latest
steps:
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/[email protected]
with:
images: ${{ env.IMAGE_PATH }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}} # major.minor.patch
type=semver,pattern={{major}}.{{minor}}
outputs:
tags: ${{ steps.meta.outputs.tags }}

docker-build:
needs: get-tags
uses: "./.github/workflows/docker_build.yml"
with:
IMAGE_REFERENCES: ${{ needs.get-tags.outputs.tags }}

...
4 changes: 2 additions & 2 deletions .github/workflows/trivy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ on:
default: 0
outputs:
trivy_conclusion:
description: "The pass/fail return code from Trivy"
description: "The pass/fail status from Trivy"
value: ${{ jobs.trivy.outputs.trivy_conclusion }}

env:
Expand Down Expand Up @@ -98,5 +98,5 @@ jobs:
wait-for-processing: true

outputs:
trivy_conclusion: steps.trivy.conclusion
trivy_conclusion: ${{ steps.trivy.conclusion }}
...
52 changes: 38 additions & 14 deletions .github/workflows/trivy_periodic_image_scan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,33 +9,39 @@ name: Trivy Periodic Image Scan

on:
schedule:
# run daily
- cron: "0 0 * * *"
- cron: "0 0 * * *" # run daily

jobs:
to-lower-case:
get-image-reference:
runs-on: ubuntu-latest
steps:
- name: Ensure image name is lower case
id: repo_name
uses: vishalmamidi/lowercase-action@v1
- name: Convert repo' name to lower case
id: to_lower_case
run: |
# While GitHub repo's can be mixed (upper and lower) case,
# Docker images can only be lower case
repo_name=$(echo ${{ github.repository }} | tr '[:upper:]' '[:lower:]')
echo "repo_name=$repo_name" >> $GITHUB_ENV
- name: Find current version
id: find_version
uses: mathieudutour/[email protected]
with:
string: ghcr.io/${{ github.repository }}:main
github_token: ${{ secrets.GITHUB_TOKEN }}
dry_run: true #setting to 'true' means no new version is created
outputs:
lowercase-repo-name: ${{ steps.repo_name.outputs.lowercase }}
image_repo: ghcr.io/${{ env.repo_name }}
image_tag: ${{ steps.find_version.outputs.previous_version }}

periodic-scan:
needs: to-lower-case
needs: get-image-reference
uses: "./.github/workflows/trivy.yml"
with:
SOURCE_TYPE: image
# While GitHub repo's can be mixed (upper and lower) case,
# Docker images can only be lower case
IMAGE_NAME: ${{ needs.to-lower-case.outputs.lowercase-repo-name }}
IMAGE_NAME: ${{ needs.get-image-reference.outputs.image_repo }}:${{ needs.get-image-reference.outputs.image_tag }}
EXIT_CODE: 1

# If scan failed, rebuild the image
update-image:
# If scan failed, bump tag and rebuild the image
bump-tag:
needs: periodic-scan
runs-on: ubuntu-latest
if: ${{!cancelled() && needs.periodic-scan.outputs.trivy_conclusion == 'failure' }}
Expand All @@ -46,4 +52,22 @@ jobs:
uses: mathieudutour/[email protected]
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: parse new version
id: parsed
uses: booxmedialtd/ws-action-parse-semver@v1
with:
input_string: ${{ steps.tag_version.outputs.new_version }}
outputs:
new_tag: ${{ steps.tag_version.outputs.new_tag }}
new_version: ${{ steps.tag_version.outputs.new_version }}
new_major_minor: ${{ steps.parsed.outputs.major }}.${{ steps.parsed.outputs.minor }}

update-image:
needs: [get-image-reference, periodic-scan, bump-tag]
if: ${{!cancelled() && needs.periodic-scan.outputs.trivy_conclusion == 'failure' }}
uses: "./.github/workflows/docker_build.yml"
with:
REF_TO_CHECKOUT: ${{ needs.bump-tag.outputs.new_tag }}
IMAGE_REFERENCES: "${{ needs.get-image-reference.outputs.image_repo }}:${{ needs.bump-tag.outputs.new_version }},\
${{ needs.get-image-reference.outputs.image_repo }}:${{ needs.bump-tag.outputs.new_major_minor }}"
...

0 comments on commit 73743f3

Please sign in to comment.