Skip to content

Commit 70ddf79

Browse files
author
Janne Rönkkö
committed
Add reusable GHA workflow for building and publishing Docker image
1 parent ae7fda6 commit 70ddf79

2 files changed

Lines changed: 161 additions & 0 deletions

File tree

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
---
2+
name: Build and publish Docker Image
3+
4+
on:
5+
workflow_call:
6+
inputs:
7+
acr_name:
8+
type: string
9+
default: crjore4prod001
10+
docker_image_name:
11+
type: string
12+
required: true
13+
build_arm64_image:
14+
description: Should arm64 Docker image be built
15+
type: boolean
16+
required: false
17+
default: false
18+
file:
19+
description: Path to Dockerfile
20+
type: string
21+
required: false
22+
default: Dockerfile
23+
context:
24+
description: Docker build context. This needs to be Git repository context; see https://docs.docker.com/build/concepts/context/#url-fragments
25+
type: string
26+
required: false
27+
default: null
28+
build_args:
29+
description: Docker build time arguments
30+
type: string
31+
required: false
32+
default: null
33+
target:
34+
description: Sets the target stage to build
35+
type: string
36+
required: false
37+
default: null
38+
secrets:
39+
azure_tenant_id:
40+
required: true
41+
azure_subscription_id:
42+
required: true
43+
azure_client_id:
44+
required: true
45+
outputs:
46+
docker_image:
47+
description: Docker image with tag
48+
value: ${{ jobs.shared_build_and_publish_docker_image.outputs.docker_image }}
49+
50+
permissions:
51+
id-token: write
52+
contents: read
53+
54+
jobs:
55+
shared_build_and_publish_docker_image:
56+
runs-on: ubuntu-24.04
57+
outputs:
58+
docker_image: ${{ steps.variables.outputs.docker_image }}
59+
steps:
60+
- name: Set variables
61+
id: variables
62+
shell: bash
63+
run: |
64+
# GITHUB_HEAD_REF is the source branch of a pull request
65+
# GITHUB_REF is the name of the branch or tag that triggered the workflow
66+
# i.e. for pull requests the branch name is read from GITHUB_HEAD_REF and for
67+
# branch/tag updates from GITHUB_REF
68+
ref="${GITHUB_HEAD_REF:-${GITHUB_REF}}"
69+
70+
# Strip refs/heads/ or refs/tags/ out
71+
ref_name=$(basename ${ref})
72+
73+
docker_tag=$(echo -n "${ref_name}" | tr -C '0-9a-zA-Z._' '-')-$(date +%Y-%m-%d)-${GITHUB_SHA}
74+
75+
base_docker_image=${{ inputs.acr_name }}.azurecr.io/${{ inputs.docker_image_name }}
76+
echo "docker_image_latest=${base_docker_image}:latest" >> ${GITHUB_OUTPUT}
77+
echo "docker_image_cache=${base_docker_image}:cache" >> ${GITHUB_OUTPUT}
78+
echo "docker_image=${base_docker_image}:${docker_tag}" >> ${GITHUB_OUTPUT}
79+
80+
- name: Set up QEMU
81+
if: ${{ inputs.build_arm64_image }}
82+
uses: docker/setup-qemu-action@v3
83+
with:
84+
platforms: 'arm64'
85+
86+
- name: Set up Docker Buildx
87+
uses: docker/setup-buildx-action@v3
88+
89+
- name: Azure login
90+
uses: azure/login@v2
91+
with:
92+
client-id: ${{ secrets.azure_client_id }}
93+
tenant-id: ${{ secrets.azure_tenant_id }}
94+
subscription-id: ${{ secrets.azure_subscription_id }}
95+
96+
- name: Login to ACR via OIDC
97+
run: az acr login --name ${{ inputs.acr_name }}
98+
99+
- name: Build and push
100+
uses: docker/build-push-action@v6
101+
with:
102+
tags: |
103+
${{ steps.variables.outputs.docker_image }}
104+
${{ github.ref_name == 'main' && steps.variables.outputs.docker_image_latest || '' }}
105+
cache-from: type=registry,ref=${{ steps.variables.outputs.docker_image_cache }}
106+
cache-to: ${{ github.ref_name == 'main' && format('type=registry,ref={0},mode=max', steps.variables.outputs.docker_image_cache) || '' }}
107+
push: true
108+
platforms: ${{ inputs.build_arm64_image && 'linux/amd64,linux/arm64' || 'linux/amd64' }}
109+
context: ${{ inputs.context }}
110+
build-args: ${{ inputs.build_args }}
111+
file: ${{ inputs.file }}
112+
target: ${{ inputs.target }}

README.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ Tools which are commonly used by other JORE4 projects
99
- [Tools for Docker](#tools-for-docker)
1010
- [read-secrets.sh](#read-secretssh)
1111
- [download-docker-bundle.sh](#download-docker-bundlesh)
12+
- [Reusable GitHub Workflows](#reusable-github-workflows)
13+
- [shared-build-and-publish-docker-image](#shared-build-and-publish-docker-image)
1214
- [Github Actions](#github-actions)
1315
- [extract-metadata](#extract-metadata)
1416
- [healthcheck](#healthcheck)
@@ -115,6 +117,53 @@ to use this natively running service, you could use
115117
For this, the `extra_hosts` parameter is already set for every service within the docker-compose
116118
package.
117119

120+
## Reusable GitHub Workflows
121+
122+
### shared-build-and-publish-docker-image
123+
124+
Builds and publishes Docker image to ACR (Azure Container Registry).
125+
126+
The workflow uses workload identity federation (see https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation),
127+
i.e. there needs to be an user managed identity with federated credentials allowing the GitHub Actions workflow to federate its
128+
identity.
129+
130+
The workflow updates *latest* and *cache* image if the workflow has been triggered by ref update to *main* branch.
131+
132+
Arguments:
133+
134+
- `acr_name` (optional): Name of the ACR registry to use. By default crjore4prod001
135+
- `docker_image_name` (required): Name of the Docker image in ACR
136+
- `build_arm64_image` (optional): Set to `true` if ARM64 image should be build in addition to amd64 image
137+
- `file` (optional): Path to Dockerfile (`Dockerfile` by default)
138+
- `context` (optional): Set the build context which must be a Git context, i.e. reference to a Git repository as the
139+
workflow does not checkout the repository. For supported format see https://docs.docker.com/build/concepts/context/#url-fragments
140+
The parameter is passed to docker/build-push-action's context argument which by default uses format
141+
`<github_server_url>/<organization>/<repository>.git/#<ref>` (see https://github.com/docker/actions-toolkit/blob/v0.56.0/src/context.ts#L58)
142+
- `build_args` (optional): List of build time arguments for Docker build
143+
144+
The workflow uses the following credentials:
145+
146+
- `azure_tenant_id`: Azure tentant ID
147+
- `azure_subscription_id`: Azure subscription containing the user managed identity
148+
- `azure_client_id`: Client ID of the user managed identity in Azure to which the workflow has federated credentials
149+
150+
Example usage:
151+
152+
```yaml
153+
docker-image:
154+
name: Publish Docker image to ACR
155+
permissions:
156+
id-token: write
157+
contents: read
158+
uses: HSLdevcom/jore4-tools/.github/workflows/shared-build-and-publish-docker-image.yml@build-and-publish-docker-image-v1
159+
with:
160+
docker_image_name: my-docker-image-name
161+
secrets:
162+
azure_client_id: ${{ secrets.AZURE_CLIENT_ID }}
163+
azure_tenant_id: ${{ secrets.AZURE_TENANT_ID }}
164+
azure_subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
165+
```
166+
118167
## Github Actions
119168
120169
### extract-metadata

0 commit comments

Comments
 (0)