Skip to content

Commit 27e251e

Browse files
authored
Run the container image in CI, and build the arm64 half of it (#355)
1 parent 7615b40 commit 27e251e

1 file changed

Lines changed: 77 additions & 1 deletion

File tree

‎.github/workflows/test.yml‎

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,16 +86,92 @@ jobs:
8686
- uses: actions/checkout@v7
8787
- name: Set up Docker Buildx
8888
uses: docker/setup-buildx-action@v3
89+
8990
# the image is only built when it is pushed to the registry, so a broken
90-
# Dockerfile would otherwise surface after a change reached master
91+
# Dockerfile would otherwise surface after a change reached master.
92+
# loaded into the daemon rather than discarded, so the steps below can
93+
# actually run the thing that was built
9194
- name: Build the image
9295
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83
9396
with:
9497
context: .
98+
platforms: linux/amd64
99+
load: true
100+
tags: keepass4web-rs:ci
101+
cache-from: type=gha
102+
cache-to: type=gha,mode=max
103+
104+
# the published image is a two-platform manifest, but only amd64 is built
105+
# above. arm64 is the half that goes through the cross-compilation path,
106+
# where an unpinned helper image or a toolchain the build never installed
107+
# stays invisible on the native target
108+
- name: Build the image for arm64
109+
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83
110+
with:
111+
context: .
112+
platforms: linux/arm64
95113
push: false
96114
cache-from: type=gha
97115
cache-to: type=gha,mode=max
98116

117+
# AES-NI and SSE are picked per target triple, and losing them costs every
118+
# unlock without breaking the build. the build stage runs on the host
119+
# platform, so its record of the selected flags can just be read back
120+
- name: Export the amd64 build stage
121+
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83
122+
with:
123+
context: .
124+
target: build
125+
platforms: linux/amd64
126+
load: true
127+
tags: keepass4web-rs:build-amd64
128+
cache-from: type=gha
129+
130+
- name: The amd64 build keeps its AES-NI and SSE flags
131+
run: |
132+
flags=$(docker run --rm --entrypoint /bin/cat keepass4web-rs:build-amd64 /rustflags)
133+
echo "amd64 rustflags: $flags"
134+
case "$flags" in
135+
*+aes*) ;;
136+
*) echo "::error::the amd64 build lost its AES-NI flags"; exit 1 ;;
137+
esac
138+
139+
- name: The image serves /health
140+
run: |
141+
docker run -d --name k4w -p 8080:8080 keepass4web-rs:ci
142+
for _ in $(seq 1 30); do
143+
if curl -fsS http://127.0.0.1:8080/health >/dev/null 2>&1; then break; fi
144+
sleep 1
145+
done
146+
body=$(curl -fsS http://127.0.0.1:8080/health)
147+
echo "GET /health -> $body"
148+
echo "$body" | grep -q '"status":"ok"'
149+
150+
# the flag the HEALTHCHECK runs. the image has no shell or curl, so a
151+
# probe that cannot reach the server would only show up as an image that
152+
# never turns healthy
153+
- name: The bundled health probe agrees
154+
run: docker exec k4w /keepass4web --config /conf/config.yml --health-check
155+
156+
- name: Docker reports the container healthy
157+
run: |
158+
for _ in $(seq 1 60); do
159+
status=$(docker inspect --format '{{.State.Health.Status}}' k4w)
160+
case "$status" in
161+
healthy) echo "container is healthy"; exit 0 ;;
162+
unhealthy) echo "::error::container reported unhealthy"; docker logs k4w; exit 1 ;;
163+
esac
164+
sleep 2
165+
done
166+
echo "::error::container never became healthy"
167+
docker inspect --format '{{json .State.Health}}' k4w
168+
docker logs k4w
169+
exit 1
170+
171+
- name: Container logs
172+
if: always()
173+
run: docker logs k4w || true
174+
99175
dependency-review:
100176
name: Dependency Review
101177
runs-on: ubuntu-latest

0 commit comments

Comments
 (0)