Skip to content

Commit f80c1af

Browse files
TimPansinolrafeei
authored andcommitted
Distributed CI Image Build (#1478)
* Distribute build of CI image across runners * Add weekly CI image rebuild * Add rust to toolchain * Add human readable job names * Linting
1 parent 206aaa1 commit f80c1af

File tree

2 files changed

+101
-9
lines changed

2 files changed

+101
-9
lines changed

.github/containers/Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
5050
pkg-config \
5151
python3-dev \
5252
python3-pip \
53+
rustc \
5354
sudo \
5455
tzdata \
5556
unixodbc-dev \

.github/workflows/build-ci-image.yml

Lines changed: 100 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,31 @@ name: Build CI Image
1616

1717
on:
1818
workflow_dispatch: # Allow manual trigger
19+
schedule:
20+
- cron: "15 16 * * 0" # At 16:15 UTC on Sunday
1921

2022
permissions:
2123
contents: read
24+
packages: write
2225

2326
concurrency:
2427
group: ${{ github.ref || github.run_id }}
2528
cancel-in-progress: true
2629

2730
jobs:
2831
build:
29-
runs-on: ubuntu-24.04
32+
strategy:
33+
matrix:
34+
include:
35+
- platform: linux/amd64
36+
cache_tag: linux-amd64
37+
runner: ubuntu-24.04
38+
- platform: linux/arm64
39+
cache_tag: linux-arm64
40+
runner: ubuntu-24.04-arm
3041

31-
permissions:
32-
contents: read
33-
packages: write
42+
runs-on: ${{ matrix.runner }}
43+
name: Docker Build ${{ matrix.platform }}
3444

3545
steps:
3646
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # 5.0.0
@@ -42,11 +52,17 @@ jobs:
4252
id: buildx
4353
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # 3.11.1
4454

55+
# Lowercase image name and append -ci
56+
- name: Generate Image Name
57+
id: image-name
58+
run: |
59+
echo "IMAGE_NAME=${GITHUB_REPOSITORY@L}-ci" >>"${GITHUB_OUTPUT}"
60+
4561
- name: Generate Docker Metadata (Tags and Labels)
4662
id: meta
4763
uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # 5.8.0
4864
with:
49-
images: ghcr.io/${{ github.repository }}-ci
65+
images: ghcr.io/${{ steps.image-name.outputs.IMAGE_NAME }}
5066
flavor: |
5167
prefix=
5268
suffix=
@@ -65,11 +81,86 @@ jobs:
6581
username: ${{ github.repository_owner }}
6682
password: ${{ secrets.GITHUB_TOKEN }}
6783

68-
- name: Build and Publish Image
84+
- name: Build and Push Image by Digest
85+
id: build
6986
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # 6.18.0
7087
with:
71-
push: ${{ github.event_name != 'pull_request' }}
7288
context: .github/containers
73-
platforms: ${{ (format('refs/heads/{0}', github.event.repository.default_branch) == github.ref) && 'linux/amd64,linux/arm64' || 'linux/amd64' }}
74-
tags: ${{ steps.meta.outputs.tags }}
89+
platforms: ${{ matrix.platform }}
7590
labels: ${{ steps.meta.outputs.labels }}
91+
outputs: type=image,name=ghcr.io/${{ steps.image-name.outputs.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true
92+
cache-from: type=gha,scope=build-${{ matrix.cache_tag }}
93+
cache-to: type=gha,scope=build-${{ matrix.cache_tag }}
94+
95+
- name: Export Digest
96+
run: |
97+
mkdir -p ${{ runner.temp }}/digests
98+
digest="${{ steps.build.outputs.digest }}"
99+
touch "${{ runner.temp }}/digests/${digest#sha256:}"
100+
101+
- name: Upload Digest
102+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # 4.6.2
103+
with:
104+
name: digests-${{ matrix.cache_tag }}
105+
path: ${{ runner.temp }}/digests/*
106+
if-no-files-found: error
107+
retention-days: 1
108+
109+
merge:
110+
runs-on: ubuntu-latest
111+
if: github.event_name != 'pull_request'
112+
needs:
113+
- build
114+
115+
name: Docker Merge Image
116+
117+
steps:
118+
- name: Download Digests
119+
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # 5.0.0
120+
with:
121+
path: ${{ runner.temp }}/digests
122+
pattern: digests-*
123+
merge-multiple: true
124+
125+
- name: Login to GitHub Container Registry
126+
if: github.event_name != 'pull_request'
127+
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # 3.5.0
128+
with:
129+
registry: ghcr.io
130+
username: ${{ github.repository_owner }}
131+
password: ${{ secrets.GITHUB_TOKEN }}
132+
133+
- name: Set up Docker Buildx
134+
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # 3.11.1
135+
136+
# Lowercase image name and append -ci
137+
- name: Generate Image Name
138+
id: image-name
139+
run: |
140+
echo "IMAGE_NAME=${GITHUB_REPOSITORY@L}-ci" >>"${GITHUB_OUTPUT}"
141+
142+
- name: Generate Docker Metadata (Tags and Labels)
143+
id: meta
144+
uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # 5.8.0
145+
with:
146+
images: ghcr.io/${{ steps.image-name.outputs.IMAGE_NAME }}
147+
flavor: |
148+
prefix=
149+
suffix=
150+
latest=false
151+
tags: |
152+
type=raw,value=latest,enable={{is_default_branch}}
153+
type=schedule,pattern={{date 'YYYY-MM-DD'}}
154+
type=sha,format=short,prefix=sha-
155+
type=sha,format=long,prefix=sha-
156+
157+
- name: Create Manifest List and Push
158+
working-directory: ${{ runner.temp }}/digests
159+
run: |
160+
# shellcheck disable=SC2046
161+
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
162+
$(printf 'ghcr.io/${{ steps.image-name.outputs.IMAGE_NAME }}@sha256:%s ' *)
163+
164+
- name: Inspect Image
165+
run: |
166+
docker buildx imagetools inspect ghcr.io/${{ steps.image-name.outputs.IMAGE_NAME }}:${{ steps.meta.outputs.version }}

0 commit comments

Comments
 (0)