Skip to content

Commit b5d89f8

Browse files
Split workflows for reusability
- Separates workflow into distinct stages: - meta: determines the base (sha) and permatags (branch, git-tag) to apply to the image - build: builds the multi-platform dockerfile with a build-specific tag - test: a repo-specific workflow that runs the tests - tag: applies permatags to the tested image - This is a proof-of-concept on the path towards centralizing and versioning the reusable parts of our workflows. The common elements (meta, build, and tag) would be centralized, with individual repos only having to write a test workflow to run their tests and a ci workflow to weave the different reusable workflows together.
1 parent dc76f55 commit b5d89f8

File tree

6 files changed

+163
-151
lines changed

6 files changed

+163
-151
lines changed

.github/workflows/build.yml

Lines changed: 19 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,19 @@
1-
name: Build / Test / Push
1+
name: Build image
22

33
on:
4-
push:
5-
branches:
6-
- '**'
7-
workflow_dispatch:
8-
9-
env:
10-
BUILD_SUFFIX: -build-${{ github.run_id }}_${{ github.run_attempt }}
11-
DOCKER_METADATA_SET_OUTPUT_ENV: 'true'
4+
workflow_call:
5+
outputs:
6+
image:
7+
description: ID of the image created by the workflow run
8+
value: ${{ jobs.merge.outputs.image }}
129

1310
jobs:
1411
build:
1512
runs-on: ${{ matrix.runner }}
1613
outputs:
17-
build-image-arm: ${{ steps.gen-output.outputs.image-arm64 }}
18-
build-image-x64: ${{ steps.gen-output.outputs.image-x64 }}
14+
image-digest-arm: ${{ steps.gen-output.outputs.image-digest-arm64 }}
15+
image-digest-x64: ${{ steps.gen-output.outputs.image-digest-x64 }}
16+
build-tag: ${{ steps.build-meta.outputs.tags }}
1917
strategy:
2018
fail-fast: false
2119
matrix:
@@ -41,7 +39,7 @@ jobs:
4139
uses: docker/metadata-action@v5
4240
with:
4341
images: ghcr.io/${{ github.repository }}
44-
tags: type=sha,suffix=${{ env.BUILD_SUFFIX }}
42+
tags: type=sha,suffix=-build-${{ github.run_id }}_${{ github.run_attempt }}
4543

4644
# Build cache is shared among all builds of the same architecture
4745
- id: cache-meta
@@ -71,17 +69,18 @@ jobs:
7169
- id: gen-output
7270
name: Write arch-specific image digest to outputs
7371
run: |
74-
echo "image-${RUNNER_ARCH,,}=${{ steps.get-registry.outputs.registry }}@${{ steps.build.outputs.digest }}" | tee -a "$GITHUB_OUTPUT"
72+
echo "image-digest-${RUNNER_ARCH,,}=${{ steps.get-registry.outputs.registry }}@${{ steps.build.outputs.digest }}" | tee -a "$GITHUB_OUTPUT"
7573
7674
merge:
75+
name: create multi-platform image
76+
needs: build
7777
runs-on: ubuntu-24.04
78-
needs:
79-
- build
8078
env:
81-
DOCKER_APP_IMAGE_ARM64: ${{ needs.build.outputs.build-image-arm }}
82-
DOCKER_APP_IMAGE_X64: ${{ needs.build.outputs.build-image-x64 }}
79+
DOCKER_APP_IMAGE: ${{ needs.build.outputs.build-tag }}
80+
DOCKER_APP_IMAGE_DIGEST_ARM64: ${{ needs.build.outputs.image-digest-arm }}
81+
DOCKER_APP_IMAGE_DIGEST_X64: ${{ needs.build.outputs.image-digest-x64 }}
8382
outputs:
84-
build-image: ${{ steps.meta.outputs.tags }}
83+
image: ${{ needs.build.outputs.build-tag }}
8584
steps:
8685
- name: Checkout code
8786
uses: actions/checkout@v4
@@ -96,77 +95,8 @@ jobs:
9695
username: ${{ github.actor }}
9796
password: ${{ secrets.GITHUB_TOKEN }}
9897

99-
- name: Docker meta
100-
id: meta
101-
uses: docker/metadata-action@v5
102-
with:
103-
images: ghcr.io/${{ github.repository }}
104-
tags: |
105-
type=sha,suffix=-build-${{ github.run_id }}_${{ github.run_attempt }}
106-
10798
- name: Push the multi-platform image
10899
run: |
109100
docker buildx imagetools create \
110-
--tag "$DOCKER_METADATA_OUTPUT_TAGS" \
111-
"$DOCKER_APP_IMAGE_ARM64" "$DOCKER_APP_IMAGE_X64"
112-
113-
test:
114-
runs-on: ubuntu-24.04
115-
needs:
116-
- merge
117-
env:
118-
COMPOSE_FILE: docker-compose.yml:docker-compose.ci.yml
119-
DOCKER_APP_IMAGE: ${{ needs.merge.outputs.build-image }}
120-
steps:
121-
- name: Checkout code
122-
uses: actions/checkout@v4
123-
124-
- name: Set up Docker Compose
125-
uses: docker/setup-compose-action@v1
126-
127-
- name: Login to GitHub Container Registry
128-
uses: docker/login-action@v3
129-
with:
130-
registry: ghcr.io
131-
username: ${{ github.actor }}
132-
password: ${{ secrets.GITHUB_TOKEN }}
133-
134-
- name: Run the test script
135-
run: |
136-
docker compose run --rm --user root app chown -R avplayer:avplayer artifacts
137-
docker compose up --detach --wait
138-
docker compose exec app bin/test
139-
140-
push:
141-
runs-on: ubuntu-24.04
142-
needs:
143-
- merge
144-
- test
145-
env:
146-
DOCKER_APP_IMAGE: ${{ needs.merge.outputs.build-image }}
147-
steps:
148-
- name: Checkout code
149-
uses: actions/checkout@v4
150-
151-
- name: Login to GitHub Container Registry
152-
uses: docker/login-action@v3
153-
with:
154-
registry: ghcr.io
155-
username: ${{ github.actor }}
156-
password: ${{ secrets.GITHUB_TOKEN }}
157-
158-
- name: Produce permanent image tags
159-
id: branch-meta
160-
uses: docker/metadata-action@v5
161-
with:
162-
images: ghcr.io/${{ github.repository }}
163-
tags: |
164-
type=sha
165-
type=ref,event=branch
166-
type=raw,value=latest,enable={{is_default_branch}}
167-
168-
- name: Retag and push the image
169-
run: |
170-
docker pull "$DOCKER_APP_IMAGE"
171-
echo "$DOCKER_METADATA_OUTPUT_TAGS" | tr ' ' '\n' | xargs -n1 docker tag "$DOCKER_APP_IMAGE"
172-
docker push --all-tags "$(echo "$DOCKER_APP_IMAGE" | cut -f1 -d:)"
101+
--tag "$DOCKER_APP_IMAGE" \
102+
"$DOCKER_APP_IMAGE_DIGEST_ARM64" "$DOCKER_APP_IMAGE_DIGEST_X64"

.github/workflows/ci.yml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: Build / Test / Tag
2+
3+
on:
4+
push:
5+
branches:
6+
- '**'
7+
tags:
8+
- '**'
9+
10+
jobs:
11+
meta:
12+
name: Determine image permatags
13+
uses: ./.github/workflows/meta.yml
14+
15+
build:
16+
name: Build the image
17+
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
18+
uses: ./.github/workflows/build.yml
19+
20+
test:
21+
name: Test built image
22+
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
23+
needs: build
24+
uses: ./.github/workflows/test.yml
25+
with:
26+
image: ${{ needs.build.outputs.image }}
27+
28+
tag:
29+
name: Tag/push tested image
30+
needs: [build, test, meta]
31+
uses: ./.github/workflows/tag.yml
32+
with:
33+
image: ${{ needs.build.outputs.image || needs.meta.outputs.base-tag }}
34+
tags: ${{ needs.meta.outputs.permatags }}

.github/workflows/meta.yml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: Extract image metadata
2+
3+
on:
4+
workflow_call:
5+
outputs:
6+
base-tag:
7+
description: SHA-based tag for the built ref (org/repo:sha-1234567)
8+
value: ${{ jobs.meta.outputs.base-tag }}
9+
permatags:
10+
description: Space-separated list of all tags to apply to the ref
11+
value: ${{ jobs.meta.outputs.permatags }}
12+
13+
jobs:
14+
meta:
15+
runs-on: ubuntu-24.04
16+
outputs:
17+
base-tag: ${{ steps.base-tag.outputs.tags }}
18+
permatags: ${{ steps.permatags.outputs.tags }}
19+
steps:
20+
- name: Checkout code
21+
uses: actions/checkout@v4
22+
23+
- id: base-tag
24+
name: Determine base tag (for git-tag builds)
25+
uses: docker/metadata-action@v5
26+
with:
27+
images: ghcr.io/${{ github.repository }}
28+
tags: type=sha
29+
30+
- id: permatags
31+
name: Determine permatags
32+
uses: docker/metadata-action@v5
33+
with:
34+
images: ghcr.io/${{ github.repository }}
35+
tags: |
36+
type=sha
37+
type=raw,value=latest,enable={{is_default_branch}}
38+
type=ref,event=branch
39+
type=ref,event=tag
40+
type=semver,event=tag,pattern={{major}}
41+
type=semver,event=tag,pattern={{major}}.{{minor}}
42+
type=semver,event=tag,pattern={{version}}

.github/workflows/release.yml

Lines changed: 0 additions & 62 deletions
This file was deleted.

.github/workflows/tag.yml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: Tag Docker image
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
# Image to be retagged. This must exist in the registry.
7+
image:
8+
type: string
9+
10+
# Space-separated list of fully qualified image tags (including registry address)
11+
# Format matches the output of `docker/metadata-action`.
12+
tags:
13+
type: string
14+
15+
env:
16+
DOCKER_APP_IMAGE: ${{ inputs.image }}
17+
DOCKER_METADATA_OUTPUT_TAGS: ${{ inputs.tags }}
18+
19+
jobs:
20+
tag:
21+
runs-on: ubuntu-24.04
22+
steps:
23+
- name: Login to GitHub Container Registry
24+
uses: docker/login-action@v3
25+
with:
26+
registry: ghcr.io
27+
username: ${{ github.actor }}
28+
password: ${{ secrets.GITHUB_TOKEN }}
29+
30+
- name: Apply tags to the image
31+
run: |
32+
docker pull "$DOCKER_APP_IMAGE"
33+
echo "$DOCKER_METADATA_OUTPUT_TAGS" | tr ' ' '\n' | xargs -n1 docker tag "$DOCKER_APP_IMAGE"
34+
docker push --all-tags "$(echo "$DOCKER_APP_IMAGE" | cut -f1 -d:)"

.github/workflows/test.yml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: Test Docker image
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
image:
7+
type: string
8+
9+
env:
10+
COMPOSE_FILE: docker-compose.yml:docker-compose.ci.yml
11+
DOCKER_APP_IMAGE: ${{ inputs.image }}
12+
13+
jobs:
14+
test:
15+
runs-on: ubuntu-24.04
16+
steps:
17+
- name: Checkout code
18+
uses: actions/checkout@v4
19+
20+
- name: Set up Docker Compose
21+
uses: docker/setup-compose-action@v1
22+
23+
- name: Login to GitHub Container Registry
24+
uses: docker/login-action@v3
25+
with:
26+
registry: ghcr.io
27+
username: ${{ github.actor }}
28+
password: ${{ secrets.GITHUB_TOKEN }}
29+
30+
- name: Run the test script
31+
run: |
32+
docker compose run --rm --user root app chown -R avplayer:avplayer artifacts
33+
docker compose up --detach --wait
34+
docker compose exec app bin/test

0 commit comments

Comments
 (0)