@@ -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