Skip to content

Commit

Permalink
feat: try separated workflow (#35)
Browse files Browse the repository at this point in the history
* try separated workflow

* inherit secrets

* use commit hash

* try without run-on

* remove environment too

* use boolean instead of bool

* use branch instead of commit hash

* set image params required to false

* move envs for image scanning to inputs

* move them back to env

* run prettier

* rename

* comment out secrets for test

* removing secrets entry since they are inherited

* add initialize to the commit step needs

* run prettier

* set version for build

* pin main for build
  • Loading branch information
kpplis authored Jan 17, 2025
1 parent 34e4ddb commit 6641465
Show file tree
Hide file tree
Showing 2 changed files with 347 additions and 282 deletions.
332 changes: 332 additions & 0 deletions .github/workflows/build-image.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,332 @@
name: Reusable image build workflow with options to push to ECR or GitHub Registry
on:
workflow_call:
inputs:
artifactName:
required: false
description: If provided, downloads a previously uploaded artifact (has to be in the same workflow). Both artifactPath and artifactName have to be passed.
default: ""
type: string
artifactPath:
required: false
description: If provided, downloads a previously uploaded artifact (has to be in the same workflow). Both artifactPath and artifactName have to be passed.
default: ""
type: string
imageTargets:
required: false
description: If provided, sets targets for as many image builds as targets specified
default: ""
type: string
preScript:
required: false
description: If provided, runs a script after repo checkout and before the docker image is built. Useful in case that you need to build a package outside of the docker image (and load the artifacts via copy).
default: ""
type: string
registryHostname:
required: false
description: The hostname for the container registry
default: ghcr.io
type: string
registryOrg:
required: false
description: The registry organization
default: parcellab
type: string
registryUsername:
required: false
description: The username for the container registry
default: parcellab-dev-bot
type: string
repository_kind:
required: false
description: The kind of repository (github or ecr)
default: "github"
type: string
runner:
required: false
description: Runner type
default: ubuntu-latest
type: string
version:
required: true
type: string

env:
IMAGE_SCAN_SEVERITY: LOW
IMAGE_SCAN_SEVERITY_THRESHOLD: CRITICAL
IMAGE_SCAN_ANNOTATIONS: true
IMAGE_SCAN_TRIVY_TIMEOUT: 10m

jobs:
build-github-single:
if: inputs.repository_kind == 'github' && inputs.imageTargets == ''
environment: ${{ github.event.deployment.payload.env }}
runs-on: ${{ inputs.runner }}
steps:
- name: Checkout current git repository
uses: actions/checkout@v4
- if: inputs.preScript != ''
name: Run script before the docker image is built
run: |
echo "Run '${{ inputs.preScript }}'"
${{ inputs.preScript }}
env:
NPM_GITHUB_TOKEN: ${{ secrets.npmGithubReadToken }}
- if: inputs.artifactPath != '' && inputs.artifactName != ''
name: Download artifact
uses: actions/download-artifact@v4
with:
name: ${{ inputs.artifactName }}
path: ${{ inputs.artifactPath }}
- name: Login to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ inputs.registryHostname }}
username: ${{ inputs.registryUsername }}
password: ${{ secrets.repoAccessToken }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Build image
uses: docker/build-push-action@v6
with:
build-args: |
GITHUB_SHA=${{ github.sha }}
VERSION=${{ inputs.version }}
APP_NAME=${{ github.event.deployment.payload.name }}
ENVIRONMENT=${{ github.event.deployment.payload.env }}
NPM_GITHUB_TOKEN=${{ secrets.npmGithubReadToken }}
cache-from: type=registry,ref=${{ inputs.registryHostname }}/${{ inputs.registryOrg }}/${{ github.event.deployment.payload.name }}
cache-to: type=inline
context: ${{ github.event.deployment.payload.container.context }}
load: true
file: ${{ github.event.deployment.payload.container.file }}
platforms: linux/amd64
tags: |
${{ inputs.registryHostname }}/${{ inputs.registryOrg }}/${{ github.event.deployment.payload.name }}:latest
${{ inputs.registryHostname }}/${{ inputs.registryOrg }}/${{ github.event.deployment.payload.name }}:${{ inputs.version }}
${{ inputs.registryHostname }}/${{ inputs.registryOrg }}/${{ github.event.deployment.payload.name }}:${{ github.sha }}
- name: Scan for vulnerabilities
uses: crazy-max/ghaction-container-scan@v3
with:
image: ${{ inputs.registryHostname }}/${{ inputs.registryOrg }}/${{ github.event.deployment.payload.name }}:latest
dockerfile: Containerfile
severity: ${{ env.IMAGE_SCAN_SEVERITY }}
severity_threshold: ${{ env.IMAGE_SCAN_SEVERITY_THRESHOLD }}
annotations: ${{ env.IMAGE_SCAN_ANNOTATIONS }}
env:
TRIVY_TIMEOUT: ${{ env.IMAGE_SCAN_TRIVY_TIMEOUT }}
- name: Push image to GitHub
run: |
docker push -a ${{ inputs.registryHostname }}/${{ inputs.registryOrg }}/${{ github.event.deployment.payload.name }}
build-ecr-single:
if: inputs.repository_kind == 'ecr' && inputs.imageTargets == ''
environment: ${{ github.event.deployment.payload.env }}
runs-on: ${{ inputs.runner }}
steps:
- name: Checkout current git repository
uses: actions/checkout@v4
- if: inputs.preScript != ''
name: Run script before the docker image is built
run: |
echo "Run '${{ inputs.preScript }}'"
${{ inputs.preScript }}
env:
NPM_GITHUB_TOKEN: ${{ secrets.npmGithubReadToken }}
- if: inputs.artifactPath != '' && inputs.artifactName != ''
name: Download artifact
uses: actions/download-artifact@v4
with:
name: ${{ inputs.artifactName }}
path: ${{ inputs.artifactPath }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Configure AWS credentials
if: inputs.repository_kind == 'ecr'
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: eu-central-1
- name: Create ECR repository if it doesn't exist
run: |
aws ecr describe-repositories --repository-names ${{ github.event.deployment.payload.name }} || \
aws ecr create-repository --repository-name ${{ github.event.deployment.payload.name }}
LIFECYCLE_POLICY='{"rules":[{"rulePriority":1,"description":"Keep last 500 images","selection":{"tagStatus":"any","countType":"imageCountMoreThan","countNumber":500},"action":{"type":"expire"}}]}'
aws ecr put-lifecycle-policy --repository-name ${{ github.event.deployment.payload.name }} --lifecycle-policy-text "$LIFECYCLE_POLICY"
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Build image
uses: docker/build-push-action@v6
with:
build-args: |
GITHUB_SHA=${{ github.sha }}
VERSION=${{ inputs.version }}
APP_NAME=${{ github.event.deployment.payload.name }}
ENVIRONMENT=${{ github.event.deployment.payload.env }}
NPM_GITHUB_TOKEN=${{ secrets.npmGithubReadToken }}
cache-from: type=registry,ref=${{ inputs.registryHostname }}/${{ inputs.registryOrg }}/${{ github.event.deployment.payload.name }}
cache-to: type=inline
context: ${{ github.event.deployment.payload.container.context }}
load: true
file: ${{ github.event.deployment.payload.container.file }}
platforms: linux/amd64
tags: |
${{ steps.login-ecr.outputs.registry }}/${{ github.event.deployment.payload.name }}:latest
${{ steps.login-ecr.outputs.registry }}/${{ github.event.deployment.payload.name }}:${{ inputs.version }}
${{ steps.login-ecr.outputs.registry }}/${{ github.event.deployment.payload.name }}:${{ github.sha }}
- name: Scan for vulnerabilities
if: inputs.repository_kind == 'ecr'
uses: crazy-max/ghaction-container-scan@v3
with:
image: ${{ steps.login-ecr.outputs.registry }}/${{ github.event.deployment.payload.name }}:latest
dockerfile: Containerfile
severity: ${{ env.IMAGE_SCAN_SEVERITY }}
severity_threshold: ${{ env.IMAGE_SCAN_SEVERITY_THRESHOLD }}
annotations: ${{ env.IMAGE_SCAN_ANNOTATIONS }}
env:
TRIVY_TIMEOUT: ${{ env.IMAGE_SCAN_TRIVY_TIMEOUT }}
- name: Push image to ECR
if: inputs.repository_kind == 'ecr'
run: |
docker push -a ${{ steps.login-ecr.outputs.registry }}/${{ github.event.deployment.payload.name }}
build-github-matrix:
if: inputs.repository_kind == 'github' && inputs.imageTargets != ''
environment: ${{ github.event.deployment.payload.env }}
runs-on: ${{ inputs.runner }}
strategy:
matrix:
containerfile_targets: ${{ fromJson(inputs.imageTargets) }}
steps:
- name: Checkout current git repository
uses: actions/checkout@v4
- if: inputs.preScript != ''
name: Run script before the docker image is built
run: |
echo "Run '${{ inputs.preScript }}'"
${{ inputs.preScript }}
env:
NPM_GITHUB_TOKEN: ${{ secrets.npmGithubReadToken }}
- if: inputs.artifactPath != '' && inputs.artifactName != ''
name: Download artifact
uses: actions/download-artifact@v4
with:
name: ${{ inputs.artifactName }}
path: ${{ inputs.artifactPath }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ inputs.registryHostname }}
username: ${{ inputs.registryUsername }}
password: ${{ secrets.repoAccessToken }}
- name: Build ${{ matrix.containerfile_targets }} image
uses: docker/build-push-action@v6
with:
build-args: |
GITHUB_SHA=${{ github.sha }}
VERSION=${{ inputs.version }}
APP_NAME=${{ github.event.deployment.payload.name }}
ENVIRONMENT=${{ github.event.deployment.payload.env }}
NPM_GITHUB_TOKEN=${{ secrets.npmGithubReadToken }}
cache-from: type=registry,ref=${{ inputs.registryHostname }}/${{ inputs.registryOrg }}/${{ github.event.deployment.payload.name }}
cache-to: type=inline
context: ${{ github.event.deployment.payload.container.context }}
load: true
file: ${{ github.event.deployment.payload.container.file }}
platforms: linux/amd64
tags: |
${{ inputs.registryHostname }}/${{ inputs.registryOrg }}/${{ github.event.deployment.payload.name }}-${{ matrix.containerfile_targets }}:latest
${{ inputs.registryHostname }}/${{ inputs.registryOrg }}/${{ github.event.deployment.payload.name }}-${{ matrix.containerfile_targets }}:${{ inputs.version }}
${{ inputs.registryHostname }}/${{ inputs.registryOrg }}/${{ github.event.deployment.payload.name }}-${{ matrix.containerfile_targets }}:${{ github.sha }}
target: ${{ matrix.containerfile_targets }}
- name: Scan for vulnerabilities
uses: crazy-max/ghaction-container-scan@v3
with:
image: ${{ inputs.registryHostname }}/${{ inputs.registryOrg }}/${{ github.event.deployment.payload.name }}-${{ matrix.containerfile_targets }}:latest
dockerfile: Containerfile
severity: ${{ env.IMAGE_SCAN_SEVERITY }}
severity_threshold: ${{ env.IMAGE_SCAN_SEVERITY_THRESHOLD }}
annotations: ${{ env.IMAGE_SCAN_ANNOTATIONS }}
env:
TRIVY_TIMEOUT: ${{ env.IMAGE_SCAN_TRIVY_TIMEOUT }}
- name: Push ${{ matrix.containerfile_targets }} image to ECR
run: |
docker push -a ${{ inputs.registryHostname }}/${{ inputs.registryOrg }}/${{ github.event.deployment.payload.name }}-${{ matrix.containerfile_targets }}
build-ecr-matrix:
if: inputs.repository_kind == 'ecr' && inputs.imageTargets != ''
environment: ${{ github.event.deployment.payload.env }}
runs-on: ${{ inputs.runner }}
strategy:
matrix:
containerfile_targets: ${{ fromJson(inputs.imageTargets) }}
steps:
- name: Checkout current git repository
uses: actions/checkout@v4
- if: inputs.preScript != ''
name: Run script before the docker image is built
run: |
echo "Run '${{ inputs.preScript }}'"
${{ inputs.preScript }}
env:
NPM_GITHUB_TOKEN: ${{ secrets.npmGithubReadToken }}
- if: inputs.artifactPath != '' && inputs.artifactName != ''
name: Download artifact
uses: actions/download-artifact@v4
with:
name: ${{ inputs.artifactName }}
path: ${{ inputs.artifactPath }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: eu-central-1
- name: Create ${{ matrix.containerfile_targets }} ECR repository if it doesn't exist
run: |
aws ecr describe-repositories --repository-names ${{ github.event.deployment.payload.name }}-${{ matrix.containerfile_targets }} || \
aws ecr create-repository --repository-name ${{ github.event.deployment.payload.name }}-${{ matrix.containerfile_targets }}
LIFECYCLE_POLICY='{"rules":[{"rulePriority":1,"description":"Keep last 500 images","selection":{"tagStatus":"any","countType":"imageCountMoreThan","countNumber":500},"action":{"type":"expire"}}]}'
aws ecr put-lifecycle-policy --repository-name ${{ github.event.deployment.payload.name }}-${{ matrix.containerfile_targets }} --lifecycle-policy-text "$LIFECYCLE_POLICY"
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Build ${{ matrix.containerfile_targets }} image
uses: docker/build-push-action@v6
with:
build-args: |
GITHUB_SHA=${{ github.sha }}
VERSION=${{ inputs.version }}
APP_NAME=${{ github.event.deployment.payload.name }}
ENVIRONMENT=${{ github.event.deployment.payload.env }}
NPM_GITHUB_TOKEN=${{ secrets.npmGithubReadToken }}
cache-from: type=registry,ref=${{ inputs.registryHostname }}/${{ inputs.registryOrg }}/${{ github.event.deployment.payload.name }}
cache-to: type=inline
context: ${{ github.event.deployment.payload.container.context }}
load: true
file: ${{ github.event.deployment.payload.container.file }}
platforms: linux/amd64
tags: |
${{ steps.login-ecr.outputs.registry }}/${{ github.event.deployment.payload.name }}-${{ matrix.containerfile_targets }}:latest
${{ steps.login-ecr.outputs.registry }}/${{ github.event.deployment.payload.name }}-${{ matrix.containerfile_targets }}:${{ inputs.version }}
${{ steps.login-ecr.outputs.registry }}/${{ github.event.deployment.payload.name }}-${{ matrix.containerfile_targets }}:${{ github.sha }}
target: ${{ matrix.containerfile_targets }}
- name: Scan for vulnerabilities
uses: crazy-max/ghaction-container-scan@v3
with:
image: ${{ steps.login-ecr.outputs.registry }}/${{ github.event.deployment.payload.name }}-${{ matrix.containerfile_targets }}:latest
dockerfile: Containerfile
severity: ${{ env.IMAGE_SCAN_SEVERITY }}
severity_threshold: ${{ env.IMAGE_SCAN_SEVERITY_THRESHOLD }}
annotations: ${{ env.IMAGE_SCAN_ANNOTATIONS }}
env:
TRIVY_TIMEOUT: ${{ env.IMAGE_SCAN_TRIVY_TIMEOUT }}
- name: Push ${{ matrix.containerfile_targets }} image to ECR
run: |
docker push -a ${{ steps.login-ecr.outputs.registry }}/${{ github.event.deployment.payload.name }}-${{ matrix.containerfile_targets }}
Loading

0 comments on commit 6641465

Please sign in to comment.