feat(parental-leave): Fixed rights DVAL #194
Workflow file for this run
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Docker Build | |
# This workflow builds Docker images for projects in the repository. | |
# It can be triggered by: | |
# - Labeling a pull request with "docker build" | |
# - Being called from another workflow via `workflow_call` | |
# - Manual dispatch using `workflow_dispatch` | |
# The workflow uses matrix builds to parallelize the process and leverages caching | |
# to speed up dependency and final image builds. | |
on: | |
pull_request: | |
types: | |
- labeled | |
- synchronize | |
workflow_call: | |
inputs: | |
projects: | |
description: 'Comma-separated list of project names to build.' | |
type: string | |
required: true | |
runners: | |
description: 'The runners to run the jobs on.' | |
type: string | |
required: false | |
default: 'arc-runners' | |
version: | |
description: 'The version to tag the image with (previously DOCKER_TAG)' | |
type: string | |
required: false | |
workflow_dispatch: | |
inputs: | |
projects: | |
description: 'Comma-separated list of project names to build.' | |
type: string | |
required: true | |
runners: | |
description: 'The runners to run the jobs on.' | |
required: false | |
type: string | |
default: 'arc-runners' | |
version: | |
description: 'The version to tag the image with (previously DOCKER_TAG)' | |
type: string | |
required: false | |
concurrency: | |
group: container-build-${{ github.head_ref || github.run_id }} | |
cancel-in-progress: true | |
defaults: | |
run: | |
shell: bash -euo pipefail {0} | |
env: | |
# Regsitry to for build images and cache | |
IMAGE_REGISTRY: ${{ vars.IMAGE_REGISTRY || 'localhost' }} | |
AWS_ECR_REPO_BASE: ${{ vars.AWS_ECR_REPO_BASE || 'docker.io' }} | |
NODE_IMAGE_VERSION: 20 | |
jobs: | |
prepare: | |
name: Prepare | |
if: ${{ github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'docker build') }} | |
runs-on: ${{ inputs.runners || 'arc-runners' }} | |
outputs: | |
matrix: ${{ steps.set-matrix.outputs.matrix }} | |
node-image-version: ${{ steps.build-args.outputs.node-image-version }} | |
playwright-image-tag: ${{ steps.build-args.outputs.playwright-image-tag }} | |
container-registry: ${{ steps.build-args.outputs.container-registry }} | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Build arg prep | |
id: build-args | |
run: | | |
node_image_version="$NODE_IMAGE_VERSION" | |
echo node-image-version="$node_image_version" >>"$GITHUB_OUTPUT" | |
yarn info --json @playwright/test | jq -r '.children.Version | "playwright-image-tag=v\(.)-focal"' >>"$GITHUB_OUTPUT" | |
- name: Create matrix from input | |
id: set-matrix | |
env: | |
localrun: ${{ !!github.event.localrun }} | |
projects: ${{ inputs.projects }} | |
run: | | |
if [[ ${{ contains(github.event.pull_request.labels.*.name, 'docker build') }} ]]; then | |
echo "Using small subset for testing docker build (on ${{ github.event.pull_request.base.ref }})" | |
# A representative sample of various docker build targets | |
export projects="web,air-discount-scheme-backend,license-api" | |
fi | |
# Create a list of objects of the form: | |
# [ | |
# { | |
# "name": "services-my-service", | |
# "docker": "next|nest|mytype" | |
# }, | |
# ... | |
# ] | |
echo "matrix=$(git ls-files '**/project.json' | | |
xargs cat | | |
jq -s -c --arg projects "$projects" '{ include: [ | |
.[] | |
| select( .name | IN($projects | split(",") | .[]) ) | |
| { | |
project: .name, | |
docker: (.targets | keys | map(select(startswith("docker-") and . != "docker-native")) | map(sub("^docker-"; "")) | .[]) | |
} | |
] | |
}')" | tee -a "$GITHUB_OUTPUT" | |
build: | |
name: Build ${{ matrix.project }} | |
runs-on: ${{ inputs.runners || 'arc-runners' }} | |
needs: prepare | |
strategy: | |
fail-fast: false | |
matrix: ${{ fromJson(needs.prepare.outputs.matrix) }} | |
permissions: | |
id-token: write # This is required for requesting the JWT for AWS/ECR login | |
contents: read # This is required for actions/checkout | |
steps: | |
- name: Prepare arguments | |
id: args | |
env: | |
# We don't use a repository prefix (e.g. <registry>/island.is/<project>), just the raw project | |
image_repository: ${{ env.IMAGE_REGISTRY }}/${{ matrix.project }} | |
localrun: ${{ github.event.localrun }} | |
run: | | |
echo image-repository="$image_repository" >>"$GITHUB_OUTPUT" | |
echo build-cache-local="type=local,src=/tmp,dest=/tmp,mode=max,enabled=${{ !!github.event.localrun }}" >>"$GITHUB_OUTPUT" | |
echo build-cache="type=registry,image-manifest=true,oci-mediatypes=true,ref=$image_repository:cache,enabled=${{ !github.event.localrun }}" >>"$GITHUB_OUTPUT" | |
- name: Check out repo | |
uses: actions/checkout@v4 | |
- name: Configure AWS Credentials | |
if: ${{ !github.event.localrun }} | |
id: aws-creds | |
uses: aws-actions/configure-aws-credentials@v4 | |
with: | |
role-session-name: container-build | |
aws-region: ${{ vars.AWS_REGION }} | |
# Identical to usage in push.yml | |
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
# TODO: Use this instead of aws-{access,secret}, but needs proper roles & policies | |
# role-to-assume: ${{ vars.AWS_ECR_ROLE }} | |
- name: Log in to Amazon ECR | |
if: ${{ steps.aws-creds.conclusion == 'success' }} | |
id: ecr-login | |
uses: aws-actions/amazon-ecr-login@v2 | |
- name: Set up Docker Buildx | |
uses: docker/setup-buildx-action@v3 | |
with: | |
driver: docker-container | |
# We get rate-limited if using docker.io's image for buildkit. | |
driver-opts: | | |
image=${{ env.AWS_ECR_REPO_BASE }}/moby/buildkit:buildx-stable-1 | |
install: true | |
use: true | |
- name: Generate image metadata | |
id: meta | |
# This step requires a valid GitHub token to query the API for e.g. description of repository | |
if: ${{ !github.event.localrun }} | |
uses: docker/metadata-action@v5 | |
with: | |
images: | | |
${{ steps.args.outputs.image-repository }} | |
tags: | | |
# Edge without prefix should only be used on `main`, so as not to conflict with type=sha | |
# type=edge | |
type=edge,prefix=edge- | |
# SemVer by tag (e.g. v1.2.3) | |
type=semver,pattern={{version}} | |
type=pep440,pattern={{version}} | |
# PR branch/name | |
# type=ref,event=<branch|tag|pr> Defaults are good | |
# Git SHA | |
type=sha,format=short,prefix= | |
type=sha,format=long,prefix= | |
# The final sha for the merge commit | |
# mcgh: Merge Commit GitHub | |
type=raw,value=${{ inputs.version }},enable=${{ !!inputs.version }} | |
type=raw,value=mcgh-${{ github.event.pull_request.merge_commit_sha }} | |
- name: Godegen if needed | |
if: ${{ contains(github.event.pull_request.labels.*.name, 'docker build') }} | |
run: | | |
# In PRs we don't have the generated files context from when being called. | |
corepack enable && yarn install --immutable && yarn codegen | |
- name: Docker build/cache dependencies | |
uses: docker/build-push-action@v6 | |
with: | |
context: . | |
file: scripts/ci/Dockerfile | |
push: false | |
target: deps | |
build-args: | | |
NODE_IMAGE_VERSION=${{ needs.prepare.outputs.node-image-version }} | |
PLAYWRIGHT_IMAGE_TAG=${{ needs.prepare.outputs.playwright-image-tag }} | |
cache-from: | | |
${{ steps.args.outputs.build-cache-local }} | |
${{ steps.args.outputs.build-cache }} | |
cache-to: | | |
${{ steps.args.outputs.build-cache-local }},mode=max | |
${{ steps.args.outputs.build-cache }},mode=max | |
- name: Docker build/cache output base | |
uses: docker/build-push-action@v6 | |
with: | |
context: . | |
file: scripts/ci/Dockerfile | |
push: false | |
target: output-base | |
build-args: | | |
NODE_IMAGE_VERSION=${{ needs.prepare.outputs.node-image-version }} | |
PLAYWRIGHT_IMAGE_TAG=${{ needs.prepare.outputs.playwright-image-tag }} | |
cache-from: | | |
${{ steps.args.outputs.build-cache-local }} | |
${{ steps.args.outputs.build-cache }} | |
cache-to: | | |
${{ steps.args.outputs.build-cache-local }},mode=max | |
${{ steps.args.outputs.build-cache }},mode=max | |
- name: Build and push Docker image | |
uses: docker/build-push-action@v6 | |
with: | |
context: . | |
file: scripts/ci/Dockerfile | |
push: ${{ !github.event.localrun }} | |
labels: ${{ steps.meta.outputs.labels }} | |
tags: ${{ steps.meta.outputs.tags }} | |
target: output-${{ matrix.docker }} | |
build-args: | | |
NODE_IMAGE_VERSION=${{ needs.prepare.outputs.node-image-version }} | |
APP=${{ matrix.project }} | |
PLAYWRIGHT_IMAGE_TAG=${{ needs.prepare.outputs.playwright-image-tag }} | |
# Caching final images doesn't make sense when this should only run if the project is affected (changed) | |
cache-from: | | |
${{ steps.args.outputs.build-cache-local }} | |
${{ steps.args.outputs.build-cache }} | |
cache-to: | | |
${{ steps.args.outputs.build-cache }},mode=min |