Skip to content

Commit

Permalink
feat(container-build): improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
ruzickap committed Nov 16, 2022
1 parent 45986ce commit 3405ab8
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 52 deletions.
123 changes: 73 additions & 50 deletions .github/workflows/container-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,49 @@ on:
workflow_dispatch:
inputs:
container_registry_push:
description: "Should push the image to Container Registry"
description: "Push the image to Container Registry"
type: boolean
required: true
default: false
container_image_vulnerability_checks:
description: "Scan image for vulnerability issues"
type: boolean
required: true
default: true
container_image_expires_after:
description: "Expires after (days) [or 'Never']"
type: string
required: false
default: "30"

push:
tags:
# For code tagging you can use 'v' prefix, but 'v' prefix should not be part of container tag
- "v[0-9]+.[0-9]+.[0-9]+*"
schedule:
- cron: "0 0 1 * *"
- cron: "0 0 * * 1"

env:
DOCKERFILE_LOCATION: Dockerfile
# Container image destination - with registry and without tags
CONTAINER_IMAGE: quay.io/petr_ruzicka/malware-cryptominer-container
CONTAINER_REGISTRY_USER: ${{ secrets.CONTAINER_REGISTRY_USER }}
CONTAINER_REGISTRY_PASSWORD: ${{ secrets.CONTAINER_REGISTRY_PASSWORD }}
IMAGE_PRODUCT_ID: 12345
IMAGE_LICENSES: Apache-2.0
IMAGE_VENDOR: MyCompany
IMAGE_AUTHORS: [email protected]
IMAGE_REPOSITORY_URL: https://quay.io/repository/petr_ruzicka/malware-cryptominer-container?tab=tags
CONTAINER_IMAGE_PRODUCT_ID: 12345
CONTAINER_IMAGE_LICENSES: Apache-2.0
CONTAINER_IMAGE_VENDOR: MyCompany
CONTAINER_IMAGE_AUTHORS: [email protected]
CONTAINER_IMAGE_REPOSITORY_URL: https://quay.io/repository/petr_ruzicka/malware-cryptominer-container?tab=tags
CONTAINER_IMAGE_EXPIRES_AFTER: Never # days
# Prisma cloud credentials
PCC_CONSOLE_URL: ${{ secrets.PCC_CONSOLE_URL }}
PCC_PASS: ${{ secrets.PCC_PASS }}
PCC_USER: ${{ secrets.PCC_USER }}
# Snyk credentials
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
# Wiz credentials
WIZ_CLIENT_ID: ${{ secrets.WIZ_CLIENT_ID }}
WIZ_CLIENT_SECRET: ${{ secrets.WIZ_CLIENT_SECRET }}

jobs:
container-build:
Expand Down Expand Up @@ -53,40 +74,55 @@ jobs:
# Add 'docker.io' to base container images which are missing it
echo "${BASE_IMAGE}" | grep -E '[^.]+\..+:' || BASE_IMAGE="docker.io/${BASE_IMAGE}"
echo "BASE_IMAGE=${BASE_IMAGE}" | tee -a "${GITHUB_OUTPUT}"
BASE_IMAGE_DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' "${BASE_IMAGE}" | cut -d @ -f 2)
echo "BASE_IMAGE_DIGEST=${BASE_IMAGE_DIGEST}" | tee -a "${GITHUB_OUTPUT}"
BASE_CONTAINER_IMAGE_DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' "${BASE_IMAGE}" | cut -d @ -f 2)
echo "BASE_CONTAINER_IMAGE_DIGEST=${BASE_CONTAINER_IMAGE_DIGEST}" | tee -a "${GITHUB_OUTPUT}"
# Set variables for com.mycompany.image.expires.after and com.mycompany.image.expires
if [[ ${{ inputs.container_image_expires_after || env.CONTAINER_IMAGE_EXPIRES_AFTER }} = 'Never' ]]; then
echo "IMAGE_EXPIRES=Never" | tee -a "${GITHUB_OUTPUT}"
echo "IMAGE_EXPIRES_AFTER=Never" | tee -a "${GITHUB_OUTPUT}"
else
echo "IMAGE_EXPIRES=$(date -u --date='+${{ inputs.container_image_expires_after || env.CONTAINER_IMAGE_EXPIRES_AFTER }} days' +'%FT%TZ')" | tee -a "${GITHUB_OUTPUT}"
echo "IMAGE_EXPIRES_AFTER=${{ inputs.container_image_expires_after || env.CONTAINER_IMAGE_EXPIRES_AFTER }}d" | tee -a "${GITHUB_OUTPUT}"
fi
- name: Docker meta
id: docker_meta
uses: docker/metadata-action@v4
with:
images: ${{ env.CONTAINER_IMAGE }}
images: |
${{ env.CONTAINER_IMAGE }}
tags: |
type=raw,value=latest
# Whever the pipeline runs form "main" - use "latest" container tag
type=raw,value=latest,enable={{ is_default_branch }}
type=semver,pattern={{version}},event=tag
type=semver,pattern={{major}}.{{minor}},event=tag
type=semver,pattern={{major}},enable=${{ !startsWith(github.ref, 'refs/tags/v0.') }},event=tag
type=semver,pattern={{major}},event=tag,enable=${{ !startsWith(github.ref, 'refs/tags/v0.') }}
# When the pipeline is not excuted form 'main' branch use "pr-<mybranch>" tag
type=ref,prefix=br-,event=branch,enable=${{ github.ref_name != github.event.repository.default_branch }}
labels: |
# org.opencontainers.image.created - it is there by default
org.opencontainers.image.authors=${{ env.IMAGE_AUTHORS }}
org.opencontainers.image.authors=${{ env.CONTAINER_IMAGE_AUTHORS }}
# org.opencontainers.image.description - it is there by default (repository description)
org.opencontainers.image.documentation=${{ github.event.repository.html_url }}/blob/${{ github.sha }}/README.md
# org.opencontainers.image.revision - it is there by default
# org.opencontainers.image.source - it is there by default
# org.opencontainers.image.title - it is there by default
# org.opencontainers.image.url - it is there by default
# org.opencontainers.image.version - it is there by default
org.opencontainers.image.vendor=${{ env.IMAGE_VENDOR }}
org.opencontainers.image.licenses=${{ env.IMAGE_LICENSES }}
org.opencontainers.image.vendor=${{ env.CONTAINER_IMAGE_VENDOR }}
org.opencontainers.image.licenses=${{ env.CONTAINER_IMAGE_LICENSES }}
org.opencontainers.image.ref.name=${{ github.ref_name }}
org.opencontainers.image.base.digest=${{ steps.variables.outputs.BASE_IMAGE_DIGEST }}
org.opencontainers.image.base.digest=${{ steps.variables.outputs.BASE_CONTAINER_IMAGE_DIGEST }}
org.opencontainers.image.base.name=${{ steps.variables.outputs.BASE_IMAGE }}
com.mycompany.image.pipeline.url=${{ github.event.repository.html_url }}/actions/runs/${{ github.run_id }}
com.mycompany.image.pipeline.source=${{ github.event.repository.html_url }}/actions/runs/${{ github.run_id }}/workflow
com.mycompany.image.product_id=${{ env.IMAGE_PRODUCT_ID }}
com.mycompany.image.repository.url=${{ env.IMAGE_REPOSITORY_URL }}
com.mycompany.image.product_id=${{ env.CONTAINER_IMAGE_PRODUCT_ID }}
com.mycompany.image.repository.url=${{ env.CONTAINER_IMAGE_REPOSITORY_URL }}
com.mycompany.image.used_for=all
quay.expires-after=365d
com.mycompany.image.expires=${{ steps.variables.outputs.IMAGE_EXPIRES }}
com.mycompany.image.expires.after=${{ steps.variables.outputs.IMAGE_EXPIRES_AFTER }}
quay.expires-after=${{ steps.variables.outputs.IMAGE_EXPIRES_AFTER }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
Expand All @@ -104,54 +140,41 @@ jobs:
# Trivy Scanner
#########################

- name: Trivy Scan Image - sarif
- name: Trivy - scan container image
uses: aquasecurity/trivy-action@master
continue-on-error: true
if: always() && steps.build-push-action.outcome == 'success'
continue-on-error: ${{ ! inputs.container_image_vulnerability_checks || false }}
with:
image-ref: ${{ env.CONTAINER_IMAGE }}:${{ steps.docker_meta.outputs.version }}
format: "sarif"
output: "trivy-results.sarif"
exit-code: 1
ignore-unfixed: true
severity: CRITICAL

- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: "trivy-results.sarif"

- name: Trivy Scan Image - table
uses: aquasecurity/trivy-action@master
continue-on-error: true
with:
image-ref: ${{ env.CONTAINER_IMAGE }}:${{ steps.docker_meta.outputs.version }}
exit-code: 1
ignore-unfixed: true

#########################
# Anchore - Grype
#########################

- name: Grype Scan image - sarif
id: anchore-scan
- name: Grype - scan container image
uses: anchore/scan-action@v3
continue-on-error: true
# Continue whenever container was built (no matter if previous scanner failed)
if: always() && steps.build-push-action.outcome == 'success'
continue-on-error: ${{ ! inputs.container_image_vulnerability_checks || false }}
with:
severity-cutoff: critical
image: ${{ env.CONTAINER_IMAGE }}:${{ steps.docker_meta.outputs.version }}
severity-cutoff: critical
output-format: table

- name: Upload Anchore scan SARIF report
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: ${{ steps.anchore-scan.outputs.sarif }}
#########################
# Dockle
#########################

- name: Grype Scan image - table
uses: anchore/scan-action@v3
continue-on-error: true
- name: Dockle - scan container image
if: always() && steps.build-push-action.outcome == 'success'
continue-on-error: ${{ ! inputs.container_image_vulnerability_checks || false }}
uses: erzz/dockle-action@v1
with:
image: ${{ env.CONTAINER_IMAGE }}:${{ steps.docker_meta.outputs.version }}
severity-cutoff: critical
output-format: table
image: "${{ env.CONTAINER_IMAGE }}:${{ steps.docker_meta.outputs.version }}"
exit-code: 1

###############################################
# Push container image to registry and sign it
Expand Down
2 changes: 0 additions & 2 deletions .github/workflows/mega-linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ jobs:
steps:
- name: Checkout Code
uses: actions/checkout@v3
with:
fetch-depth: 0

- name: MegaLinter
uses: megalinter/[email protected]
Expand Down

0 comments on commit 3405ab8

Please sign in to comment.