fix(ci): per-target locked cargo cache mounts for the desktop/web builds (VAPP-59) #67

Merged
nrupard merged 2 commits from fix/VAPP-59-desktop-cargo-cache-race into main 2026-06-30 21:54:06 +02:00
Owner

What

Fixes VAPP-59: the build-desktop-windows run on main (#344) failed unpacking base16 v0.2.1 with failed to open .../base16-0.2.1/.cargo-ok: File exists (os error 17). That is a half-written crate dir in the shared cargo registry cache, not a defect in the repo source.

Root cause

The desktop-linux, desktop-windows, and web image builds all trigger on: push: branches: main and can run concurrently on the same buildkit instance. Each RUN used a bare --mount=type=cache,target=/usr/local/cargo/registry, whose cache id defaults to just the target path. So the concurrent builds unpacked crates into the SAME registry cache and raced - one build left base16 partially unpacked (dir present, .cargo-ok not yet written), and another then failed trying to create .cargo-ok.

Fix

In all three Dockerfiles (ci-build/Dockerfile.desktop-windows, Dockerfile.desktop-linux, Dockerfile.web):

  • Give each build target a distinct cache id - vervain-app-cargo-registry-{windows,linux,web} and the matching -git ids - so the builds no longer share the registry cache and cannot race each other on unpack.
  • Add sharing=locked so any two runs that DO share an id (e.g. two pushes to the same target) serialise the unpack instead of racing.

The new ids also start from a clean cache, so they sidestep the already-corrupted shared mount that failed run #344 - no manual cache prune on the runner is needed.

Verification

  • Built the windows desktop image locally with the patched Dockerfile (full x86_64-pc-windows-gnu cross-compile via docker buildx build -f ci-build/Dockerfile.desktop-windows .): completes successfully, produces the vervain-app.exe artifact, no .cargo-ok error.
  • All three Dockerfiles pass docker build --check (no warnings).

Note

This was triaged human_action (clear the corrupted cache + re-run), but the same race would recur on the next concurrent push. This change removes the race at the source, so the cache fix is permanent rather than a one-off prune.

#VAPP-59

## What Fixes VAPP-59: the `build-desktop-windows` run on main (#344) failed unpacking `base16 v0.2.1` with `failed to open .../base16-0.2.1/.cargo-ok: File exists (os error 17)`. That is a half-written crate dir in the shared cargo registry cache, not a defect in the repo source. ## Root cause The desktop-linux, desktop-windows, and web image builds all trigger `on: push: branches: main` and can run concurrently on the same buildkit instance. Each `RUN` used a bare `--mount=type=cache,target=/usr/local/cargo/registry`, whose cache id defaults to just the target path. So the concurrent builds unpacked crates into the SAME registry cache and raced - one build left `base16` partially unpacked (dir present, `.cargo-ok` not yet written), and another then failed trying to create `.cargo-ok`. ## Fix In all three Dockerfiles (`ci-build/Dockerfile.desktop-windows`, `Dockerfile.desktop-linux`, `Dockerfile.web`): - Give each build target a distinct cache id - `vervain-app-cargo-registry-{windows,linux,web}` and the matching `-git` ids - so the builds no longer share the registry cache and cannot race each other on unpack. - Add `sharing=locked` so any two runs that DO share an id (e.g. two pushes to the same target) serialise the unpack instead of racing. The new ids also start from a clean cache, so they sidestep the already-corrupted shared mount that failed run #344 - no manual cache prune on the runner is needed. ## Verification - Built the windows desktop image locally with the patched Dockerfile (full `x86_64-pc-windows-gnu` cross-compile via `docker buildx build -f ci-build/Dockerfile.desktop-windows .`): completes successfully, produces the `vervain-app.exe` artifact, no `.cargo-ok` error. - All three Dockerfiles pass `docker build --check` (no warnings). ## Note This was triaged `human_action` (clear the corrupted cache + re-run), but the same race would recur on the next concurrent push. This change removes the race at the source, so the cache fix is permanent rather than a one-off prune. #VAPP-59
fix(ci): give each desktop/web build its own locked cargo cache mount (VAPP-59)
All checks were successful
Check / fmt + clippy + build + tests (pull_request) Successful in 31s
cb5e0df922
The build-desktop-windows run on main failed unpacking `base16 v0.2.1` with `.cargo-ok: File exists (os error 17)` - a half-written crate dir in the shared cargo registry cache, not a source defect.

Root cause: the desktop-linux, desktop-windows, and web image builds all trigger on a push to main and can run concurrently on the same buildkit instance. Each used a bare `--mount=type=cache,target=/usr/local/cargo/registry`, which defaults to a cache id keyed only on the target path, so the concurrent builds unpacked crates into the SAME registry cache and raced.

Give each build target its own cache id (`vervain-app-cargo-registry-{linux,windows,web}` and the matching git ids) so the builds no longer share the registry, and add `sharing=locked` so any same-id concurrent run serialises its unpack instead of racing itself. The new ids also start from a clean cache, so they sidestep the already-corrupted shared mount that failed run #344.

Verified by building the windows desktop image locally with the patched Dockerfile (full x86_64-pc-windows-gnu cross-compile): the build completes and produces the `vervain-app.exe` artifact, with no `.cargo-ok` error. All three Dockerfiles pass `docker build --check`.

#VAPP-59

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
fix(ci): move the syntax directive to line 1 so the frontend pin applies (VAPP-59 review)
All checks were successful
Check / fmt + clippy + build + tests (pull_request) Successful in 1m0s
Create release / Create release from merged PR (pull_request) Has been skipped
77331a22c9
The `# syntax=docker/dockerfile:1.6` parser directive sat below the header comment block in all three ci-build Dockerfiles. A parser directive is only recognised as the first line of the file - once any comment or instruction is processed, BuildKit stops looking for directives and treats it as an ordinary comment. So the 1.6 frontend pin was inert and the builds silently used buildkit's default frontend.

Harmless in practice (the default frontend already honours the `id=` / `sharing=locked` cache-mount options this branch adds, proven by the passing windows desktop build), but the pin should actually apply. Move the directive to line 1 in each file so the intended frontend version is used. `docker build --check` passes on all three with the pinned frontend now loaded.

#VAPP-59

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
nrupard scheduled this pull request to auto merge when all checks succeed 2026-06-30 21:53:32 +02:00
nrupard deleted branch fix/VAPP-59-desktop-cargo-cache-race 2026-06-30 21:54:06 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/vervain-apps!67
No description provided.