fix(ci): include packaging assets in the Docker build context (#322)
## Summary
`main` has been red since #319 (issue #309) merged. The Docker image build fails to compile:
```
error: couldn't read src/service_cmd/../../packaging/systemd/all-smi.service
--> src/service_cmd/template.rs:56:33
|
56 | pub const UNIT_TEMPLATE: &str = include_str!("../../packaging/systemd/all-smi.service");
```
Run: https://github.com/lablup/all-smi/actions/runs/30997457472
## Cause
Issue #309 added the first asset embedded with `include_str!`. The Dockerfile builder stage copies only `Cargo.toml`, `Cargo.lock`, `build.rs`, `proto/` and `src/`, so the narrowed build context has no `packaging/` directory and the crate cannot compile inside the image.
Two files have to agree here and nothing enforced it: the set of paths reachable from `include_str!` in `src/`, and the set of paths the Dockerfile copies into the build context.
## Why no check caught it before merge
`docker-check` in `.github/workflows/ci.yml` is gated on:
```yaml
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
```
It never runs on a pull request. PR #319 was fully green, and the failure appeared only on the merge commit. Every other gate (`cargo test`, `cargo clippy`, `cargo build`) builds from a full checkout and cannot see a build-context problem.
## Changes
1. `Dockerfile`: add `COPY packaging/ ./packaging/` to the builder stage.
2. `tests/docker_build_context_test.rs`: a contract test that keeps the two files in agreement.
The test extracts every `include_str!` / `include_bytes!` string literal under `src/`, resolves each against the file that embeds it, and asserts the result is covered by a builder-stage `COPY` and is not stripped back out by `.dockerignore`. It runs in the normal test suite, so this class of break now fails on the pull request instead of on `main`. The failure message names the exact `COPY` line to add:
```
These embedded assets are unreachable from the Docker build context, so `docker build`
fails at compile time even though every other check passes.
packaging/systemd/all-smi.service
embedded by: src/service_cmd/template.rs
To fix: add `COPY packaging/ ./packaging/` to the builder stage of the Dockerfile.
```
This also covers the launchd plist that #310 adds under `packaging/`, since the `COPY` takes the whole directory.
## Verification
- `cargo test --test docker_build_context_test`: 5 passed.
- Negative control on the test: removing the `COPY` line makes `embedded_assets_are_inside_the_docker_build_context` fail with the message above. The test is not vacuous.
- Negative control on the real build context: a Dockerfile built from this Dockerfile's exact builder-stage `COPY` set plus `RUN test -f packaging/systemd/all-smi.service` succeeds with the fix, and fails with `exit code: 1` on that same `RUN` without it. The unit template and the env-file example are both present in the resulting image.
- `cargo fmt --check`: clean.
- `cargo clippy --all-targets --all-features -- -D warnings`: clean.
## Not addressed here
`docker-check` still does not run on pull requests. The new test covers the embedded-asset class specifically, but a Docker build can also break for reasons it cannot see, for example a missing system dependency in the builder stage. Whether to run the image build on pull requests is a CI cost decision and is filed separately. J
Jeongkyu Shin committed
acb3c946242346fc913e7d36f00d304e8a12270b
Parent: 74f75d2
Committed by GitHub <noreply@github.com>
on 8/5/2026, 11:43:39 AM