SIGN IN SIGN UP

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