-
Notifications
You must be signed in to change notification settings - Fork 257
156 lines (142 loc) · 4.9 KB
/
build-devcontainer.yaml
File metadata and controls
156 lines (142 loc) · 4.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
name: build-devcontainer
# Multi-platform build for devcontainer base image
on:
workflow_call:
inputs:
push:
type: boolean
default: false
workflow_dispatch:
inputs:
push:
type: boolean
default: false
env:
IMAGE_NAME: ghcr.io/prql/prql-devcontainer-base
jobs:
build:
strategy:
fail-fast: false
matrix:
include:
- platform: linux/amd64
platform_name: amd64
runner: ubuntu-24.04
- platform: linux/arm64
platform_name: arm64
runner: ubuntu-24.04-arm
runs-on: ${{ matrix.runner }}
timeout-minutes: 240
steps:
- uses: actions/checkout@v5
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/setup-buildx-action@v3
- name: Prep build args
run:
echo "cargo_crates=$(yq -r '.vars.cargo_crates' Taskfile.yaml)" >>
"$GITHUB_ENV"
- name: Build and push by digest
id: build
uses: docker/build-push-action@v6
timeout-minutes: 240
with:
context: .devcontainer/base-image
build-args: cargo_crates=${{ env.cargo_crates }}
platforms: ${{ matrix.platform }}
outputs:
type=image,name=${{ env.IMAGE_NAME
}},push-by-digest=true,name-canonical=true,push=${{ inputs.push }}
cache-from: type=gha,scope=${{ matrix.platform }}
cache-to: type=gha,mode=max,scope=${{ matrix.platform }}
# Smoke test: build local image and verify tools work
- name: Build local image for smoke test
uses: docker/build-push-action@v6
with:
context: .devcontainer/base-image
build-args: cargo_crates=${{ env.cargo_crates }}
load: true
tags: devcontainer-test:latest
cache-from: type=gha,scope=${{ matrix.platform }}
- name: Smoke test - run tests and build book
run: |
docker run --rm -v "${{ github.workspace }}:/workspace" -w /workspace \
devcontainer-test:latest bash -c "
set -euxo pipefail
cargo test
mdbook build web/book/
"
- name: Export digest
if: inputs.push
run: |
mkdir -p /tmp/digests
digest="${{ steps.build.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}"
- name: Upload digest
if: inputs.push
uses: actions/upload-artifact@v5
with:
name: digests-${{ matrix.platform_name }}
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1
merge:
runs-on: ubuntu-24.04
timeout-minutes: 30
if: inputs.push
needs: build
steps:
- name: Download digests
uses: actions/download-artifact@v6
with:
path: /tmp/digests
pattern: digests-*
merge-multiple: true
- name: Validate digests
run: |
digest_count=$(find /tmp/digests -type f | wc -l)
if [ "$digest_count" -ne 2 ]; then
echo "Error: Expected 2 digests (amd64 + arm64), found $digest_count"
ls -la /tmp/digests
exit 1
fi
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/setup-buildx-action@v3
- uses: docker/metadata-action@v5
id: meta
with:
images: ${{ env.IMAGE_NAME }}
tags: type=raw,latest
- name: Create manifest list and push
working-directory: /tmp/digests
run: |
tags=$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON")
digests=$(printf '${{ env.IMAGE_NAME }}@sha256:%s ' *)
# shellcheck disable=SC2086
docker buildx imagetools create $tags $digests
- name: Verify multi-platform manifest
run: |
docker buildx imagetools inspect ${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }}
platforms=$(docker buildx imagetools inspect ${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }} --raw | \
jq -r '.manifests[] | select(.platform.os != "unknown") | .platform | "\(.os)/\(.architecture)"' | sort)
expected="linux/amd64
linux/arm64"
if [ "$platforms" != "$expected" ]; then
echo "Error: Expected platforms not found"
echo "Expected: $expected"
echo "Found: $platforms"
exit 1
fi
echo "✓ Multi-platform manifest verified: amd64 + arm64"