Skip to content

Commit 5987607

Browse files
authored
Merge pull request #279 from crazy-max/github-builder
ci: use docker github builder to build images and binaries
2 parents 2062d3e + 380ebcf commit 5987607

File tree

5 files changed

+393
-312
lines changed

5 files changed

+393
-312
lines changed

.github/workflows/.build.yml

Lines changed: 309 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,309 @@
1+
# reusable workflow
2+
name: .build
3+
4+
on:
5+
workflow_call:
6+
inputs:
7+
target:
8+
type: string
9+
required: true
10+
release:
11+
type: boolean
12+
required: false
13+
default: false
14+
qemu_repo:
15+
type: string
16+
required: false
17+
qemu_ref:
18+
type: string
19+
required: false
20+
qemu_version:
21+
type: string
22+
required: false
23+
latest:
24+
type: boolean
25+
required: false
26+
default: false
27+
dry-run:
28+
type: boolean
29+
required: false
30+
default: true
31+
32+
env:
33+
REPO_SLUG: tonistiigi/binfmt
34+
35+
jobs:
36+
prepare-build:
37+
runs-on: ubuntu-24.04
38+
outputs:
39+
image_name: ${{ env.REPO_SLUG }}
40+
qemu_repo: ${{ steps.set.outputs.qemu_repo }}
41+
qemu_ref: ${{ steps.set.outputs.qemu_ref }}
42+
qemu_version: ${{ steps.set.outputs.qemu_version }}
43+
tag_prefix: ${{ steps.set.outputs.tag_prefix }}
44+
git_tag: ${{ steps.set.outputs.git_tag }}
45+
steps:
46+
-
47+
name: Checkout
48+
uses: actions/checkout@v5
49+
-
50+
name: Set outputs
51+
id: set
52+
uses: actions/github-script@v8
53+
env:
54+
INPUT_GITHUB-RUN-NUMBER: ${{ github.run_number }}
55+
INPUT_TARGET: ${{ inputs.target }}
56+
INPUT_QEMU_REPO: ${{ inputs.qemu_repo }}
57+
INPUT_QEMU_REF: ${{ inputs.qemu_ref }}
58+
INPUT_QEMU_VERSION: ${{ inputs.qemu_version }}
59+
with:
60+
script: |
61+
const inpGitHubRunNumber = core.getInput('github-run-number');
62+
const inpTarget = core.getInput('target');
63+
const inpQemuRepo = core.getInput('qemu_repo');
64+
const inpQemuRef = core.getInput('qemu_ref');
65+
const inpQemuVersion = core.getInput('qemu_version');
66+
67+
let qemuRepo = '';
68+
let qemuRef = '';
69+
let qemuVersion = '';
70+
await exec.getExecOutput('docker', ['buildx', 'bake', inpTarget, '--print'], {
71+
ignoreReturnCode: true,
72+
silent: true
73+
}).then(res => {
74+
if (res.stderr.length > 0 && res.exitCode != 0) {
75+
throw new Error(res.stderr);
76+
}
77+
const dt = JSON.parse(res.stdout.trim());
78+
qemuRepo = dt.target[inpTarget].args.QEMU_REPO;
79+
qemuRef = dt.target[inpTarget].args.QEMU_REF;
80+
qemuVersion = dt.target[inpTarget].args.QEMU_VERSION;
81+
if (inpQemuRepo !== '') {
82+
qemuRepo = inpQemuRepo;
83+
}
84+
if (inpQemuRef !== '') {
85+
qemuVersion = inpQemuRef;
86+
qemuRef = inpQemuRef;
87+
}
88+
});
89+
90+
let tagPrefix = '';
91+
let gitTag = '';
92+
if (inpTarget === 'mainline') {
93+
tagPrefix = 'qemu-';
94+
gitTag = `deploy/${inpQemuVersion}-${inpGitHubRunNumber}`;
95+
} else {
96+
tagPrefix = `${inpTarget}-`;
97+
gitTag = `${inpTarget}/${inpQemuVersion}-${inpGitHubRunNumber}`;
98+
}
99+
100+
core.setOutput('qemu_repo', qemuRepo);
101+
core.setOutput('qemu_ref', qemuRef);
102+
core.setOutput('qemu_version', qemuVersion);
103+
core.setOutput('tag_prefix', tagPrefix);
104+
core.setOutput('git_tag', gitTag);
105+
106+
image:
107+
uses: docker/github-builder-experimental/.github/workflows/bake.yml@af87571fd3347a8a760e6053efba57325c00b74b
108+
needs:
109+
- prepare-build
110+
permissions:
111+
contents: read # same as global permission
112+
id-token: write # for signing attestation(s) with GitHub OIDC Token
113+
with:
114+
setup-qemu: true
115+
target: ${{ inputs.target }}-all
116+
output: image
117+
push: ${{ ! inputs.dry-run }}
118+
set: |
119+
*.args.QEMU_REPO=${{ needs.prepare-build.outputs.qemu_repo }}
120+
*.args.QEMU_VERSION=${{ needs.prepare-build.outputs.qemu_version }}
121+
set-meta-annotations: true
122+
meta-images: |
123+
${{ needs.prepare-build.outputs.image_name }}
124+
meta-tags: |
125+
type=ref,event=branch,enable=${{ ! inputs.release && inputs.target == 'mainline' }}
126+
type=ref,event=branch,prefix=${{ inputs.target }}-,enable=${{ ! inputs.release && inputs.target != 'mainline' }}
127+
type=ref,event=pr,enable=${{ ! inputs.release && inputs.target == 'mainline' }}
128+
type=ref,event=pr,prefix=${{ inputs.target }}-,enable=${{ ! inputs.release && inputs.target != 'mainline' }}
129+
type=raw,value=${{ needs.prepare-build.outputs.tag_prefix }}${{ needs.prepare-build.outputs.qemu_version }}-${{ github.run_number }},enable=${{ inputs.release }}
130+
type=raw,value=${{ needs.prepare-build.outputs.tag_prefix }}${{ needs.prepare-build.outputs.qemu_version }},enable=${{ inputs.release }}
131+
type=raw,value=${{ needs.prepare-build.outputs.tag_prefix }}latest,enable=${{ inputs.release && inputs.target != 'mainline' && inputs.latest }}
132+
type=raw,value=latest,enable=${{ inputs.release && inputs.target == 'mainline' && inputs.latest }}
133+
meta-flavor: |
134+
latest=false
135+
meta-annotations: |
136+
org.opencontainers.image.title=Binfmt
137+
org.opencontainers.image.description=Cross-platform emulator collection distributed with Docker images
138+
meta-bake-target: meta-helper
139+
secrets:
140+
registry-auths: |
141+
- registry: docker.io
142+
username: ${{ secrets.DOCKERIO_USERNAME }}
143+
password: ${{ secrets.DOCKERIO_PASSWORD }}
144+
145+
qemu-archive:
146+
uses: docker/github-builder-experimental/.github/workflows/bake.yml@af87571fd3347a8a760e6053efba57325c00b74b
147+
if: inputs.target == 'mainline'
148+
permissions:
149+
contents: read # same as global permission
150+
id-token: write # for signing attestation(s) with GitHub OIDC Token
151+
with:
152+
setup-qemu: true
153+
artifact-name: qemu-archive
154+
artifact-upload: true
155+
target: build-archive-all
156+
output: local
157+
sign: ${{ ! inputs.dry-run }}
158+
159+
qemu-archive-finalize:
160+
runs-on: ubuntu-24.04
161+
needs:
162+
- qemu-archive
163+
steps:
164+
-
165+
name: Download artifacts
166+
uses: actions/download-artifact@v6
167+
with:
168+
path: /tmp/buildx-output
169+
pattern: ${{ needs.qemu-archive.outputs.artifact-name }}*
170+
merge-multiple: true
171+
-
172+
name: Rename provenance and sbom
173+
run: |
174+
for pdir in /tmp/buildx-output/*/; do
175+
(
176+
cd "$pdir"
177+
binname=$(find . -name 'qemu_*')
178+
filename=$(basename "$binname" | sed -E 's/\.(tar\.gz|zip)$//')
179+
mv "provenance.json" "${filename}.provenance.json"
180+
if [ -f "provenance.sigstore.json" ]; then
181+
mv "provenance.sigstore.json" "${filename}.provenance.sigstore.json"
182+
fi
183+
)
184+
done
185+
mkdir -p /tmp/qemu-artifacts
186+
mv /tmp/buildx-output/**/* /tmp/qemu-artifacts
187+
-
188+
name: List artifacts
189+
working-directory: /tmp/qemu-artifacts
190+
run: |
191+
tree -nh .
192+
-
193+
name: Upload qemu archives release
194+
uses: actions/upload-artifact@v5
195+
with:
196+
name: release-qemu
197+
path: /tmp/qemu-artifacts/*
198+
if-no-files-found: error
199+
200+
binfmt-archive:
201+
uses: docker/github-builder-experimental/.github/workflows/bake.yml@af87571fd3347a8a760e6053efba57325c00b74b
202+
if: inputs.target == 'mainline'
203+
permissions:
204+
contents: read # same as global permission
205+
id-token: write # for signing attestation(s) with GitHub OIDC Token
206+
with:
207+
setup-qemu: true
208+
artifact-name: binfmt-archive
209+
artifact-upload: true
210+
target: binfmt-archive-all
211+
output: local
212+
sign: ${{ ! inputs.dry-run }}
213+
214+
binfmt-archive-finalize:
215+
runs-on: ubuntu-24.04
216+
needs:
217+
- binfmt-archive
218+
steps:
219+
-
220+
name: Download artifacts
221+
uses: actions/download-artifact@v6
222+
with:
223+
path: /tmp/buildx-output
224+
pattern: ${{ needs.binfmt-archive.outputs.artifact-name }}*
225+
merge-multiple: true
226+
-
227+
name: Rename provenance and sbom
228+
run: |
229+
for pdir in /tmp/buildx-output/*/; do
230+
(
231+
cd "$pdir"
232+
binname=$(find . -name 'binfmt_*')
233+
filename=$(basename "$binname" | sed -E 's/\.(tar\.gz|zip)$//')
234+
mv "provenance.json" "${filename}.provenance.json"
235+
if [ -f "provenance.sigstore.json" ]; then
236+
mv "provenance.sigstore.json" "${filename}.provenance.sigstore.json"
237+
fi
238+
)
239+
done
240+
mkdir -p /tmp/binfmt-artifacts
241+
mv /tmp/buildx-output/**/* /tmp/binfmt-artifacts
242+
-
243+
name: List artifacts
244+
working-directory: /tmp/binfmt-artifacts
245+
run: |
246+
tree -nh .
247+
-
248+
name: Upload binfmt archives release
249+
uses: actions/upload-artifact@v5
250+
with:
251+
name: release-binfmt
252+
path: /tmp/binfmt-artifacts/*
253+
if-no-files-found: error
254+
255+
release:
256+
runs-on: ubuntu-24.04
257+
if: always()
258+
needs:
259+
- prepare-build
260+
- image
261+
- qemu-archive-finalize
262+
- binfmt-archive-finalize
263+
steps:
264+
-
265+
name: Download archives releases
266+
if: inputs.target == 'mainline'
267+
uses: actions/download-artifact@v6
268+
with:
269+
pattern: release-*
270+
merge-multiple: true
271+
path: ${{ runner.temp }}/artifacts
272+
-
273+
name: List artifacts
274+
if: inputs.target == 'mainline'
275+
working-directory: ${{ runner.temp }}/artifacts
276+
run: |
277+
tree -nh .
278+
-
279+
name: Prepare
280+
id: prepare
281+
uses: actions/github-script@v8
282+
env:
283+
INPUT_META-JSON: ${{ needs.image.outputs.meta-json }}
284+
with:
285+
script: |
286+
const inpMetaJSON = JSON.parse(core.getInput('meta-json'));
287+
const imageTag = inpMetaJSON['tag-names'][0];
288+
core.setOutput('image_tag', imageTag);
289+
-
290+
name: Create Release
291+
uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090 # v2.4.1
292+
if: ${{ inputs.release && ! inputs.dry-run }}
293+
with:
294+
name: ${{ needs.prepare-build.outputs.git_tag }}
295+
tag_name: ${{ needs.prepare-build.outputs.git_tag }}
296+
prerelease: ${{ ! inputs.latest }}
297+
files: ${{ runner.temp }}/artifacts/*
298+
fail_on_unmatched_files: false
299+
target_commitish: ${{ github.sha }}
300+
body: |
301+
```
302+
docker run --privileged --rm ${{ env.REPO_SLUG }}:${{ steps.prepare.outputs.image_tag }} --uninstall qemu-*
303+
docker run --privileged --rm ${{ env.REPO_SLUG }}:${{ steps.prepare.outputs.image_tag }} --install all
304+
```
305+
306+
* logs: ${{ github.event.repository.html_url }}/actions/runs/${{ github.run_id }}
307+
* qemu repo: ${{ needs.prepare-build.outputs.qemu_repo }}/tree/${{ needs.prepare-build.outputs.qemu_ref }}
308+
env:
309+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

0 commit comments

Comments
 (0)