Skip to content

Commit

Permalink
Merge pull request #3 from ukhsa-collaboration/feature/doe-150-reusab…
Browse files Browse the repository at this point in the history
…le-container-build

DOE-150: Add reusable container build workflow
  • Loading branch information
ntse authored Nov 11, 2024
2 parents e052b5c + 9fdda27 commit 7f34f79
Show file tree
Hide file tree
Showing 8 changed files with 229 additions and 4 deletions.
17 changes: 17 additions & 0 deletions .github/workflows/_skip_test-container-image-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: "Test Build Container Image"

on:
pull_request:
branches:
- main
paths-ignore:
- .github/workflows/_test-container-image-build.yml
- .github/workflows/container-image-build.yml
- .github/workflows/container-image-release.yml

jobs:
container_image_build_regression_test:
name: Test using devops-terraform-ci@main
runs-on: ubuntu-latest
steps:
- run: 'echo "No build required" '
2 changes: 1 addition & 1 deletion .github/workflows/_skip_test-terraform-destroy.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: "[Test] Skip Destroy Terraform stacks"
name: "Test Destroy Terraform stacks"

on:
pull_request:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/_skip_test-terraform-plan-apply.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: "[Test] Skip Deploy Terraform stacks"
name: "Test Deploy Terraform stacks"

on:
pull_request:
Expand Down
24 changes: 24 additions & 0 deletions .github/workflows/_test-container-image-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: "Test Build Container Image"
# Regression testing to try and catch and breaking changes

on:
pull_request:
branches:
- main
paths:
- .github/workflows/_test-container-image-build.yml
- .github/workflows/container-image-build.yml
- .github/workflows/container-image-release.yml

jobs:
container_image_build_regression_test:
name: Test using devops-terraform-ci@main
uses: ./.github/workflows/container-image-build.yml
with:
repo: ukhsa-collaboration/devops-terraform-ci
ref: "main"
release_after_build: false
permissions:
id-token: write
contents: write
actions: read
2 changes: 1 addition & 1 deletion .github/workflows/_test-terraform-destroy.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: "[Test] Destroy Terraform stacks"
name: "Test Destroy Terraform stacks"
# Regression testing to try and catch and breaking changes. Will only run a destroy plan.

on:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/_test-terraform-plan-apply.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: "[Test] Deploy Terraform stacks"
name: "Test Deploy Terraform stacks"
# Regression testing to try and catch and breaking changes

on:
Expand Down
99 changes: 99 additions & 0 deletions .github/workflows/container-image-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
name: "Build, Test and Push Container Image"
on:
workflow_call:
inputs:
image_name:
description: "The name of the image"
type: string
unit_tests_command:
description: "The command to run unit tests of the application"
type: string
default: echo docker run container:latest pytest || exit 1
release_after_build:
description: "Whether or not to generate a tag and release after building the image"
type: boolean
default: false
dockerfile:
description: "Name of the Dockerfile relative to the build context"
type: string
default: "Dockerfile"
docker_build_context:
description: "The context of the Docker build command"
type: string
default: "."
repo:
required: false
type: string
default: ${{ github.repository }}
description: "Specify the org/repo of the repo containing Terraform code. Normally left blank to clone calling repo."
ref:
required: false
type: string
default: ${{ github.ref }}
description: "Specify the branch of the Terraform code. Normally left blank to use calling ref."
outputs:
artifact_url:
value: ${{ jobs.build.outputs.artifact_url }}
secrets:
AWS_ROLE_NAME:
required: false
description: "The name of the role used to push the image. Only used if `release_after_build` is true."
AWS_ACCOUNT_ID:
required: false
description: "The account ID hosting the ECR repository. Only used if `release_after_build` is true."


jobs:
build:
name: Docker build image
runs-on: ubuntu-latest
outputs:
artifact_url: ${{ steps.upload.outputs.artifact-url }}
permissions:
id-token: write
contents: write
actions: read
steps:
- uses: actions/checkout@v4
with:
repository: ${{ inputs.repo }}
ref: ${{ inputs.ref }}
token: ${{ secrets.GITHUB_TOKEN }}

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

- name: Build Docker image
uses: docker/build-push-action@v6
with:
context: ${{ inputs.docker_build_context }}
push: false
tags: "container:latest"
load: true
file: "${{ inputs.docker_build_context }}/${{ inputs.dockerfile }}"
outputs: type=docker,dest=/tmp/container-image.tar

- name: Unit tests
if: inputs.unit_tests_command != ''
run: |
${{ inputs.unit_tests_command }}
- uses: actions/upload-artifact@v4
if: inputs.release_after_build
id: upload
with:
name: container-image
path: /tmp/container-image.tar
retention-days: 1

release:
uses: ./.github/workflows/container-image-release.yml
if: inputs.release_after_build
needs:
- build
with:
artifact_run_id: ${{ github.run_id }}
image_name: ${{ inputs.image_name }}
secrets:
AWS_ROLE_NAME: ${{ secrets.AWS_ROLE_NAME }}
AWS_ACCOUNT_ID: ${{ secrets.AWS_ACCOUNT_ID }}
85 changes: 85 additions & 0 deletions .github/workflows/container-image-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
name: "Tag and Release image"
on:
workflow_call:
inputs:
artifact_run_id:
description: "The run ID of the workflow that generated a container-image artifact"
type: string
aws_region:
description: "The AWS region containing the ECR repo"
type: string
default: "eu-west-2"
image_name:
description: "The name of the container image"
type: string
repo:
required: false
type: string
default: ${{ github.repository }}
description: "Specify the org/repo of the repo containing Terraform code. Normally left blank to clone calling repo."
ref:
required: false
type: string
default: ${{ github.ref }}
description: "Specify the branch of the Terraform code. Normally left blank to use calling ref."
secrets:
AWS_ROLE_NAME:
required: false
description: "The name of the role used to push the image."
AWS_ACCOUNT_ID:
required: false
description: "The account ID hosting the ECR repository."


permissions:
id-token: write
contents: write
actions: read

jobs:
release:
name: Tag and release
runs-on: ubuntu-latest
outputs:
release_tag: ${{ steps.tag_bump.outputs.new_tag }}
image: ${{ steps.push.outputs.image }}
steps:
- uses: actions/checkout@v4
with:
ref: ${{ inputs.ref }}
repository: ${{ inputs.repo }}

- uses: ukhsa-collaboration/devops-github-actions/.github/actions/[email protected]
id: tag_bump
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
WITH_V: true

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/${{ secrets.AWS_ROLE_NAME }}
role-session-name: build-and-push-${{ github.sha }}
aws-region: ${{ inputs.aws_region }}

- uses: actions/download-artifact@v4
with:
name: container-image
github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ inputs.artifact_run_id }}

- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2

- name: Load, tag and push image
id: push
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
IMAGE_TAG: ${{ steps.tag_bump.outputs.new_tag }}
APP_NAME: ${{ inputs.image_name }}
run: |
docker load --input $GITHUB_WORKSPACE/container-image.tar
docker tag container:latest $ECR_REGISTRY/$APP_NAME:$IMAGE_TAG
docker push $ECR_REGISTRY/$APP_NAME:$IMAGE_TAG
echo "image=$ECR_REGISTRY/$APP_NAME:$IMAGE_TAG" >> $GITHUB_OUTPUT

0 comments on commit 7f34f79

Please sign in to comment.