Repository navigation
Build(deps): bump clap_mangen from 0.2.33 to 0.3.0 - #422
Merged
Merged
Conversation
Bumps [clap_mangen](https://github.com/clap-rs/clap) from 0.2.33 to 0.3.0. - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](clap-rs/clap@clap_mangen-v0.2.33...clap_mangen-v0.3.0) --- updated-dependencies: - dependency-name: clap_mangen dependency-version: 0.3.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
Contributor
There was a problem hiding this comment.
Sorry @dependabot[bot], you have reached your weekly rate limit of 500000 diff characters.
Please try again later or upgrade to continue using Sourcery
leynos
added a commit
that referenced
this pull request
Sep 3, 2026
Repins `generate-coverage` to the merge of shared-actions#428, which supplies the `all-features`, `all-targets`, and `doctests` inputs the single-execution rule was written against. Every other shared action stays on the #422 placeholder, which is still unmerged; the two pins are independent actions with no shared surface. The merged action turns out to run the doctests itself, uninstrumented and under the same feature selection as the instrumented run, for exactly the reason this repository needed them: so one coverage job can be a lane's only test execution. The bespoke `make doctest` step is therefore removed rather than kept beside it. Two statements of the feature selection could drift; one cannot, and widening the instrumented run in future now widens the doctest run with it. `make test` keeps composing both passes for local use, and a contract holds its flags equal to what CI drives, so a contributor's run still matches the gate. Checked before repinning rather than after: the merged action still accepts `cache-provider`, so the caller remains the single cache owner, and its own cargo cache no longer lists a `target` tree at all. Claude-Session: https://claude.ai/code/session_01QrjNTnTwM7FmWXe5KFPMPY
leynos
added a commit
that referenced
this pull request
Sep 3, 2026
Repins `generate-coverage` to the merge of shared-actions#428, which supplies the `all-features`, `all-targets`, and `doctests` inputs the single-execution rule was written against. Every other shared action stays on the #422 placeholder, which is still unmerged; the two pins are independent actions with no shared surface. The merged action turns out to run the doctests itself, uninstrumented and under the same feature selection as the instrumented run, for exactly the reason this repository needed them: so one coverage job can be a lane's only test execution. The bespoke `make doctest` step is therefore removed rather than kept beside it. Two statements of the feature selection could drift; one cannot, and widening the instrumented run in future now widens the doctest run with it. `make test` keeps composing both passes for local use, and a contract holds its flags equal to what CI drives, so a contributor's run still matches the gate. Checked before repinning rather than after: the merged action still accepts `cache-provider`, so the caller remains the single cache owner, and its own cargo cache no longer lists a `target` tree at all. Claude-Session: https://claude.ai/code/session_01QrjNTnTwM7FmWXe5KFPMPY
leynos
added a commit
that referenced
this pull request
Sep 4, 2026
…664) * Optimize Namespace runner caches Give every Namespace job exactly one cache owner and make its effect observable, following the estate adoption recipe's Phase 8 guidance. - Mount one `nscloud-cache-action` volume per job and record its `cache-hit` output in the step summary, so a warm run is distinguishable from a cold one. - Prefer explicit durable paths over command-dependent cache modes. The `rust` mode mounts Cargo's `target` directory, which duplicates sccache's role and breaks `cargo clean`; the `uv` and `bun` modes probe tools that are not always present. - Hand the shared setup, Whitaker, and coverage actions `cache-provider: external` so they stop mounting a second owner for the same paths, and drop the `actions/cache` steps the volume now covers. - Run sccache as the compiler-cache measurement layer, zeroing its counters before the build and emitting JSON statistics afterwards. - Bound compilation and nextest workers to the profile's four vCPUs. - Install Kani's Cargo front-end and verifier bundle from pinned, checksum verified prebuilt archives, and keep their Cargo, verifier, and Rustup homes on the volume so warm jobs skip the downloads entirely. - Document the cache lanes and their owners in the developers' guide, and add workflow-contract tests that fail if a job loses its cache owner, gains a duplicate, or reintroduces a source build. This squashes the branch's four incremental commits so the change rebases onto main as one coherent unit. Claude-Session: https://claude.ai/code/session_01QrjNTnTwM7FmWXe5KFPMPY * Address CodeRabbit findings on the cache rollout Split the merge gate, harden the prebuilt-tool installs, and tighten the contracts that guard them. - Move `build-test-windows` and the pull-request Windows recipe smoke job into `.github/workflows/ci-windows.yml`, invoked as a reusable workflow. `ci.yml` had grown to 574 lines, well past the 400-line file limit AGENTS.md sets. GitHub does not expose the `env` context to a reusable workflow's inputs, so the caller repeats its version pins as literals and a contract test holds the two copies equal. - Install `cargo-orthohelp` after `rust-build-release` in the packaging workflow. That action provides the checksum-verified `cargo binstall`, so the earlier placement failed on any runner without a preinstalled `cargo-binstall`. Nothing before the help-generation step needs the tool. - Pass `--disable-strategies compile` to every `cargo binstall` call, so a missing prebuilt release fails the job instead of silently compiling. - Restrict the packaging build job and its three callers to `contents: read`. The pinned action chain builds and uploads artefacts; it neither publishes packages nor exchanges an OIDC token. - Give Kani's front-end and verifier bundle version-qualified directories on the cache volume, so raising the pin in `tools/kani/VERSION` cannot be satisfied by a stale binary an earlier run left behind. - Fold the yamllint and actionlint `actions/cache` steps that arrived with main into the Namespace volume, and reuse the cached actionlint only when it reports the pinned version. - Contract tests: reject any `cargo install` form that would compile `cargo-orthohelp`, whatever flags precede the crate name; require the Kani cache to be mounted before Kani is installed; bind each archive's `sha256sum --check` to that archive's own extraction; and require every cache summary to carry `if: always()` and report the volume's `cache-hit`. - Correct the developers' guide punctuation and document the split, the version-qualified Kani layout, and the caller-owned Whitaker cache. Claude-Session: https://claude.ai/code/session_01QrjNTnTwM7FmWXe5KFPMPY * Clear the empty Whitaker mount before installing The Linux merge gate failed with `git pull failed: fatal: not a git repository` while installing Whitaker. Mounting the cache volume creates `~/.local/share/whitaker` even on a cold run, and `whitaker-installer` 0.2.7 chooses between cloning and pulling on directory existence alone, so it pulled against a directory that held no repository. Add a `Prepare Whitaker cache directory` step to both Whitaker jobs that deletes the data directory when it is not a Git repository, and record the removal condition in the developers' guide. Correct the Windows cache path at the same time: the installer clones into `~/AppData/Roaming/github/whitaker` there, so the previous `~/.local/share/whitaker` entry cached nothing. Split the two workflow-contract modules that crossed the 400-line limit, extracting the actionlint installer constants and the Kani cache contract into their own modules, and factor the long helpers the Clippy and Pylint gates flagged. Claude-Session: https://claude.ai/code/session_01QrjNTnTwM7FmWXe5KFPMPY * Mark the shared-actions pin as a placeholder The pinned revision is the head of shared-actions pull request 422, which is still open. Say so in the developers' guide and state the removal condition, so the pin is not mistaken for a merged commit. Claude-Session: https://claude.ai/code/session_01QrjNTnTwM7FmWXe5KFPMPY * Hold the formatter installers to a prebuilt release `cargo-binstall`'s default strategy list ends in `compile`, so a missing prebuilt artefact would be compiled in CI without anyone noticing. Both formatter jobs already pass `--disable-strategies compile`; require it in the workflow contract, and reject `cargo install` in the same step. Start the CI workflow from an empty token and let each job opt in, rather than inheriting the repository default. Move the formatter installer contract into its own module: adding the assertion pushed `ci_lint_test.py` past the 400-line limit. `SETUP_RUST_JOBS` moves to `workflow_loading.py` so both suites read it from one place. Claude-Session: https://claude.ai/code/session_01QrjNTnTwM7FmWXe5KFPMPY * Move Linux CI to Ubicloud and Windows to GitHub-hosted runners Ubicloud offers Linux runners only, so the estate splits along one line: the Linux jobs that block a developer run on `ubicloud-standard-2-ubuntu-2404`, and everything else runs on a GitHub-hosted runner. Windows and macOS have no Ubicloud image; the metadata, publication, and delayed-comment jobs are API-bound, and Ubicloud has no single-vCPU shape to make them cheaper. The Ubuntu 22.04 compatibility lane takes the `-ubuntu-2204` label so the older glibc it exists to exercise is still the one it runs on. Every Linux job starts at the two-vCPU shape. `ubicloud-standard-4` is the ceiling, not the default, and no escalation evidence exists yet, so the worker bounds now derive from one named lane constant per shape rather than the four workers the retired Namespace profiles supplied. Ubicloud destroys the runner VM after each job, so the cache-volume design has no counterpart: warm state arrives only through archives. Each lane's cache steps move into a composite action that renders its keys once and owns a disjoint path set, so restore, save, and the observation summary cannot drift apart and no path gains a second owner. Restores precede every install; saves happen only on a push to `main` where that key missed, which is why `ci.yml` gains a trunk trigger and the Kani job now runs on it. One job writes each key family and the rest restore only. Linux keeps sccache on the GitHub Actions backend and exports the two runner variables itself, because disabling the shared action's sccache also disables the step that normally publishes them. The local-directory fallback is wired behind a single repository variable, so exactly one backend is ever active. Windows keeps its compiler cache in an explicit workspace directory under `actions/cache`, keyed by OS and architecture so a Linux archive can never restore onto it. The Namespace contract modules are replaced by runner-placement, cache ownership, write-policy, and compiler-cache suites over the same shared pure validators, with the Hypothesis properties retargeted onto duplicated cache ownership, oversubscribed worker counts, and save conditions that do not name a trunk push. Claude-Session: https://claude.ai/code/session_01QrjNTnTwM7FmWXe5KFPMPY * Make sccache the only owner of compiler output on every lane Cargo's build tree is now archived nowhere. sccache holds every build shape this repository produces, and the shapes coexist in one store because sccache hashes the flags that separate them, so a `target` archive would be a second owner of the same bytes and would be invalidated far more often than it helped. `cache-provider: external` was already keeping the shared actions' `target` caches switched off; the change is that the coverage build, the Netsukefile compatibility build, and the packaging build now compile through sccache too, rather than leaving whole shapes uncached. Sizing rises to 4 GB because one store now holds two shapes. One gap stays open and is recorded rather than papered over: the shared `rust-build-release` action nests an older `setup-rust` revision that caches `target/${BUILD_PROFILE}` unconditionally and exposes no passthrough, so the packaging lane still archives a build tree. Closing it needs a shared-actions change, so the packaging job sets the wrapper and installs no second sccache beside the nested one. Ubicloud's transparent cache intercepts `actions/cache` at v6.1.0, so one action at one pin now serves every lane and the deprecated `ubicloud/cache` fork is gone. That also retires the rule that the fork must never appear in a job which can reach a GitHub-hosted label. sccache keeps its GitHub Actions backend, whose objects land in Ubicloud's own store. Reaching it needs the two Actions cache variables, and the runner hands those to JavaScript actions rather than to shell steps, so every lane exports them through a dedicated action immediately after checkout. Ordering is the substance of that contract: `--zero-stats`, `--start-server`, and the first wrapped `rustc` all start the server, and a server started without those variables stays on local disk for the whole job and reports zero compile requests, which this repository's pilot has already suffered once. The export also runs on the Windows lanes, which the estate directive says do not need it. It costs a second and removes the same silent failure mode, and Windows moves to the same backend here, so the guard is worth more than the step it saves. Claude-Session: https://claude.ai/code/session_01QrjNTnTwM7FmWXe5KFPMPY * Cite the tracking issue for the packaging lane's build-tree archive The packaging lane is the one place that still archives a Cargo build tree, because the shared build action nests a setup-rust revision that caches it unconditionally. Both the call-site comment and the developers guide said only that the fix belonged to shared-actions, which left a reader no way to find out whether it had happened. Name leynos/shared-actions#426 and say what to do when it lands, so the note retires itself rather than ageing into folklore. Claude-Session: https://claude.ai/code/session_01QrjNTnTwM7FmWXe5KFPMPY * Correct the Ubicloud App grant note The guide claimed the App did not yet cover this repository. It does; the account-wide installation was already in place. The claim came from reading the Ubicloud repository listing as a grant inventory, but that listing names only repositories which have already run a job, so any repository awaiting its first Ubicloud run is absent from it either way. Say what the prerequisite is, say why the listing cannot answer it, and point at the symptom that would justify rechecking the console. Claude-Session: https://claude.ai/code/session_01QrjNTnTwM7FmWXe5KFPMPY * Measure coverage once per commit On a push to `main` the merge gate and the trunk coverage job both ran an instrumented build of the same commit, and both wrote the ratchet baseline, so the estate paid twice for one measurement and gave a cached artefact two owners. The gate now measures coverage only on a pull request, where the changed-line check is the sole consumer of the report. The trunk job keeps the upload and becomes the single baseline writer. The other half of the deduplication rule does not apply here, and the enumeration that shows why is now in the guide. The gate's suite is a strict superset of the coverage run rather than a subset of it: the coverage action invokes nextest with default features and default targets and does not deny warnings, so folding the gate into it would stop exercising the `legacy-digests` feature, stop compiling the bench targets, stop denying warnings in the test tree, and drop doctests entirely. Keeping both on a pull request buys real coverage; keeping both on the trunk bought nothing. A contract now holds the gate to the full workspace, every target, every feature, warnings denied, and the doctest pass, so a later edit cannot narrow it into a duplicate of the coverage run and make the fold look safe in retrospect. Claude-Session: https://claude.ai/code/session_01QrjNTnTwM7FmWXe5KFPMPY * Execute the Linux suite once, inside the coverage run The merge gate compiled and ran the workspace twice per pull request: once uninstrumented through `make test`, then again instrumented to measure it. The instrumented run now does both, so the lane pays for one compile instead of two, and the uninstrumented pass is gone. That is only sound while the instrumented invocation is as broad as the pass it replaced. The coverage action defaults to nextest with default features and default targets, which would have quietly retired the `legacy-digests` tests and stopped compiling the bench targets, so both coverage callers now ask for every feature and every target. Warnings stay denied through setup-rust's `rustflags` input rather than a job-level RUSTFLAGS, which the Polonius contract forbids, and `cargo llvm-cov` appends its instrumentation to whatever it finds. Doctests are the one thing an instrumented run cannot execute at all, so a cheap uninstrumented pass follows it on every event, including the trunk. The trunk coverage job gains the same flags, so the baseline it writes is measured over the set the ratchet later checks against rather than a narrower one. `build-test` keeps its name, so the required context is unchanged; the fold moved work into the job rather than replacing it. The worker bounds move with the work: the instrumented run reads cargo's and nextest's own variables, so the two Make variables the removed step consumed are replaced by the ones that now take effect, rather than left behind as decoration. The workflow is written against the `all-features`, `all-targets`, and `doctests` inputs that leynos/shared-actions#428 adds. Until that merges the pinned action ignores them with an "Unexpected input(s)" warning, so this is not exercisable in CI before the repin. Claude-Session: https://claude.ai/code/session_01QrjNTnTwM7FmWXe5KFPMPY * Take the doctest pass from the coverage action Repins `generate-coverage` to the merge of shared-actions#428, which supplies the `all-features`, `all-targets`, and `doctests` inputs the single-execution rule was written against. Every other shared action stays on the #422 placeholder, which is still unmerged; the two pins are independent actions with no shared surface. The merged action turns out to run the doctests itself, uninstrumented and under the same feature selection as the instrumented run, for exactly the reason this repository needed them: so one coverage job can be a lane's only test execution. The bespoke `make doctest` step is therefore removed rather than kept beside it. Two statements of the feature selection could drift; one cannot, and widening the instrumented run in future now widens the doctest run with it. `make test` keeps composing both passes for local use, and a contract holds its flags equal to what CI drives, so a contributor's run still matches the gate. Checked before repinning rather than after: the merged action still accepts `cache-provider`, so the caller remains the single cache owner, and its own cargo cache no longer lists a `target` tree at all. Claude-Session: https://claude.ai/code/session_01QrjNTnTwM7FmWXe5KFPMPY * Pin every shared action to one merged revision shared-actions#422 merged, and its merge commit is also the main tip carrying #425, #427, and #428, so every reference in this repository now shares one SHA instead of a placeholder and a second pin. A future bump moves them together. That revision also closes the packaging lane's build-tree archive. `rust-build-release` now forwards `cache-provider` to its nested `setup-rust`, so the reusable packaging workflow passes `external` and no lane in this repository archives a `target` tree any more. `use-sccache` stays enabled there deliberately: the nested action is what installs sccache and exports the backend's credentials, so disabling it would leave `RUSTC_WRAPPER` pointing at a binary that was never installed. The contract that held the shared actions to caller-owned caches now covers the packaging step too, so the gap cannot reopen quietly the way it was opened: by a nested pin nobody was watching. Claude-Session: https://claude.ai/code/session_01QrjNTnTwM7FmWXe5KFPMPY * Install the two tools that publish no usable binaries The first genuinely cold run found what a warm cache volume had been hiding: neither mdtablefix nor cargo-orthohelp can be installed from a prebuilt release, and with the compile strategy correctly disabled both simply failed. The policy was right; the artefacts were never there to test it against. mdtablefix publishes perfectly good tarballs, but its binstall metadata sets `bin-dir = "."`, so resolution fails before it reaches them (leynos/mdtablefix#458). The Linux lane now takes the tarball directly and verifies it against a digest pinned in the action and cross-checked against the release's own sidecar, the way actionlint is already installed. No Windows binary is published at all, so that lane compiles the tool once per cache generation into a directory the tool cache owns and the product never shares. cargo-orthohelp has no binaries on any platform (leynos/ortho-config#479), so the packaging lane keeps binary-only strategies first and falls back to a source build on a genuine miss, into a dedicated target directory cached under a key carrying the tool version. That lane is the one place a save is not restricted to a push on `main`: no trunk event reaches the release workflow, so the run that builds the tool has to be the run that publishes it, and the key is content-addressed by version so concurrent writers agree. Both exceptions are recorded with the issue that retires them. The contract counts `cargo install` occurrences rather than pattern-matching them, so a second source build cannot shelter behind the first, and the packaging contract admits the fallback only in its exact guarded form. Claude-Session: https://claude.ai/code/session_01QrjNTnTwM7FmWXe5KFPMPY * Resolve the orthohelp build directory in the shell, not in env The macOS packaging job failed the moment it reached the source-build fallback, for two reasons that only bite outside Linux. GitHub does not expand `~` in an `env:` value, so the target directory was a literal tilde rather than a path under the home directory; and `mkdir --parents` is a GNU long option that the BSD coreutils on macOS reject outright, which is where the exit code 64 came from. Resolving the path from `$HOME` inside the script and using `-p` fixes both, and the installer action drops the same long option so it cannot repeat the failure if a macOS lane is ever added. Claude-Session: https://claude.ai/code/session_01QrjNTnTwM7FmWXe5KFPMPY * Size the gate to its workload and stop fighting GitHub's cache limits Two runner-shaped failures, two different answers. The merge gate lost its VM 16 minutes into the instrumented build on the two-vCPU shape: every later step reported a null conclusion and GitHub served no log, which is a machine disappearing rather than a step failing. The instrumented run compiles the whole workspace with every feature and every target, so memory is the plausible cause, and the recipe's escalation path allows `-4` on exactly that evidence. But the cause was inferred, not measured, so the job now samples used memory every 15 seconds and prints the peak into its summary. If the peak comes back well under 6 GB the shape goes back to `-2`; the note saying so lives beside the label rather than in this message. The Windows lanes were not short of anything. They were being rate-limited: the gate recorded 643 failed cache writes out of 643 on sccache's GitHub Actions backend, and the packaging build 68. Those lanes now keep the compiler cache in a workspace directory that the cache action owns, under a rolling key with a prefix restore-key, and set no backend flag at all. The Ubicloud and macOS lanes keep the backend, where it works, so the credential export narrows to the lanes that still need it. The packaging lane also gains the sccache installer it never had. Setting `RUSTC_WRAPPER` to a binary nobody installed is the whole of "sccache: error: failed to spawn Command", and a contract now ties the wrapper to an installer that precedes the build. Claude-Session: https://claude.ai/code/session_01QrjNTnTwM7FmWXe5KFPMPY * Escalate the trunk coverage job alongside the gate The trunk coverage job runs the same instrumented workload that lost the merge gate's runner, and it is the writer every warm run reads from, so a VM lost there would leave the whole estate cold rather than just failing one check. It moves to the same shape on the same evidence instead of waiting to reproduce the failure on `main`. The sampler moves into a composite action rather than being pasted into a second workflow. It was already the kind of thing that drifts: two copies of a background loop, a PID handed between steps, and a summary format that only matters if both copies agree. One implementation also gives the contract one thing to assert. Both jobs now declare the same lane size and derive their worker bounds from it, and a contract holds the two equal, so a future resize cannot move one and leave the other with the failure this addressed. The contracts split along the same seam: placement says which provider runs a job, shape says how large that runner is and requires the measurement that lets the escalation be reversed. Claude-Session: https://claude.ai/code/session_01QrjNTnTwM7FmWXe5KFPMPY * Pin the shared actions to the Whitaker digest fix The Windows gate was rejecting a correct Whitaker archive: GNU `sha256sum` prefixes its output with a backslash when the path it was given contains one, so the comparison failed on the digest rather than on the download. The shared action now hashes the archive from standard input, where there is no path to escape, and all twenty-three references move to that revision together. Claude-Session: https://claude.ai/code/session_01QrjNTnTwM7FmWXe5KFPMPY * Probe before installing orthohelp, and log the cache evidence Two things the first green-ish run exposed. The orthohelp step had no version probe, alone among the installers here. The cache restores `~/.cargo/bin`, and `cargo install` refuses to overwrite a binary that is already present, so a warm run walked into the source-build branch and failed on a cache hit. Probing first is what every other installer in this repository already did; this one should have from the start. The cache observations and the memory peak were written only to the job summary, which the jobs API does not expose, so the evidence the exit gate asks for could be read in a browser and nowhere else. They are teed to the log as well now, which is where anyone reconstructing a run actually looks. Claude-Session: https://claude.ai/code/session_01QrjNTnTwM7FmWXe5KFPMPY * Route sccache through Ubicloud's proxy, and stop caching Windows releases Three findings from the run, and the contracts that should have caught two of them. The compiler cache was writing to GitHub the whole time. The export published `ACTIONS_RESULTS_URL`, which is GitHub's v2 results service, and sccache 0.16 prefers v2 whenever the service switch is set, so every object resolved past Ubicloud's local proxy: 5310 requests, zero hits, one write error per miss, and 92 objects in GitHub's store rather than Ubicloud's. The export now publishes the proxy address the runner advertises and clears the v2 switch, so sccache uses the endpoint the proxy actually serves. The Windows packaging lane stops using a compiler cache at all. sccache re-spawns rustc there with the aarch64 target's whole `--extern` and `-L` list and exceeds the operating system's command-line limit, which nothing in this repository can shorten. Release builds are infrequent, so that lane runs uncached rather than unreliably; the Windows merge gate keeps its local sccache. Two contracts were quietly blind. The cache-step matcher looked for `/cache/` and so missed the combined `actions/cache@` form entirely, meaning a second owner declared that way would have passed every ownership check; and forbidden paths were compared exactly, so `target` was rejected while `target/debug` sailed through. A lane that lost its cache steps altogether also satisfied every contract vacuously. All three now fail rather than pass in silence. The Windows cache action takes its toolchain as a declared input instead of reading a variable its caller happened to set, which would have silently shared one key across toolchains the first time a new caller forgot it. Claude-Session: https://claude.ai/code/session_01QrjNTnTwM7FmWXe5KFPMPY * Pin the shared actions to the Windows tar-path fix The Whitaker digest verified after the last repin, but extraction then failed: GNU tar in Git Bash reads the colon in a Windows drive letter as a remote host separator, so a staging directory of `D:\a\_temp/...` became an attempt to connect to host `D`. The shared action now converts the path with `cygpath` before unpacking, and all twenty-three references move to that revision together. Claude-Session: https://claude.ai/code/session_01QrjNTnTwM7FmWXe5KFPMPY * Measure disk, discard the instrumented tree, and fix an inverted guard The Windows packaging lane still compiled through sccache after being told not to. GitHub's `&&`/`||` yields the last truthy operand and an empty string is falsy, so `platform == 'windows' && '' || 'sccache'` set the wrapper on exactly the platform it meant to exempt, and the build then failed looking for an sccache nobody had installed. Both guards are negated now, with the non-empty value on the `&&` side, and a contract pins that shape because the mistake is invisible on reading. The escalation story turns out to be about disk, not memory. The gate peaked at 3,640 MiB against 16 GB, so memory was never the constraint; a sibling repository's silent death on the smaller shape was disk exhaustion from a second target tree. The sampler now records disk used and free alongside memory, both jobs delete the instrumented tree once the report exists with `df -h` either side, and the guide says the return to the smaller shape turns on the disk figures rather than the memory one. Two contracts close gaps a sibling repository fell into: the compiler-cache backend flag must accompany the wrapper on every Ubicloud lane, since the shared setup action sets neither, and the credential export must precede both the toolchain setup and any step that starts the server. On Ubicloud the runner re-injects the v2 service variables into every action step, so a server started inside the setup action binds GitHub's service whatever the export said. Claude-Session: https://claude.ai/code/session_01QrjNTnTwM7FmWXe5KFPMPY * Bind cache gates to the keys they publish Action the outstanding review findings on the Ubicloud runner move, and close three gaps the contracts did not previously reach. Wiring: - Bump every shared-actions reference from 1f303985 to c6125f19. The two revisions differ only in setup-rust's rustc-wrapper export, which every caller here disables, so this unifies the pin without changing behaviour. - Give the Kani cache action an explicit `runner-image` input. It read NETSUKE_RUNNER_IMAGE under `set -u` while declaring no dependency on it, so a caller without the workflow-level variable would have aborted while rendering the key rather than failing on a missing input. - Rename that action's hit input from `cache-hit` to `kani-hit`, so every composite save is gated on an input named for the key it publishes and the write policy can derive the expected name rather than pattern-match it. - Fail the sccache credentials action when SCCACHE_GHA_ENABLED is true and either credential is empty. That combination is otherwise silent: the server falls back to local disk and the job still passes. - Derive coverage-main's SCCACHE_GHA_ENABLED from the same repository variable the merge gate reads, and restore the gate's local store on the local-directory arm. Pinned true, the trunk baseline would have compiled cold on every run with nothing failing. - Read coverage-main's cache-key toolchain from rust-toolchain.toml instead of restating the nightly date. The Setup Rust literal stays, because the Polonius contract checks it against that file; both are now anchored to one source and cannot drift apart. - Carry the pinned rust-build-release revision in the cargo-orthohelp cache key. The entry owns ~/.cargo/bin, which also holds the cargo-binstall that action provisions, so a bump to the action must turn the entry over. - Give the packaging job a `timeout-minutes`. It had none, and its runner is caller-selected, so release.build-linux could leave a Ubicloud VM running. Contracts: - Bind each cache save's hit gate to its own key, for composite and inline saves alike. Matching any `-hit` input let a tools save gate on the registry result, which is the mis-gate the write policy exists to prevent. - Derive the inline-save parametrization from KEY_WRITERS. - Reject a top-level disjunction in a trunk-only save condition. - Require a listed read-only lane to declare a restore step rather than skipping when it has none. - Assert the statistics reset precedes the first compile and the report follows the last, on every lane declaring both. - Cover the caller-selected Linux package job's timeout. - Enforce the Kani `runner-image` input at the action and at every caller. - Scan composite action inputs, not only `run` scripts, for a second Linux suite execution. - Promote the inline job inventories into cache_contract_data, so a lane added there cannot go unchecked. Structure and documentation: - Split the runner-placement mutations and the sccache compile-step recognizer into sibling data modules, keeping every file inside the 400-line limit. - Give the shared cache and invariant helpers full NumPy docstrings. - Document the guarded cargo-orthohelp fallback as the three stages the lane actually runs, rather than the single binstall line. Forwarding NEXTEST_TEST_JOBS to `dev-test` is tracked separately as #671; it is a local-workflow change that no CI lane exercises. Claude-Session: https://claude.ai/code/session_01QrjNTnTwM7FmWXe5KFPMPY * Flatten the second-execution scan into helpers CodeScene flagged the widened forbidden-command scan on three biomarkers at once: cyclomatic complexity 9, two blocks of nested conditional logic, and a nesting depth of 4. Scanning `with` values as well as `run` scripts added a fourth loop inside the existing three. Split the traversal into `_step_offenders`, `_is_scannable_job` and `_workflow_offenders`. The contract is unchanged and the exemption comment moves to the predicate that applies it. Claude-Session: https://claude.ai/code/session_01QrjNTnTwM7FmWXe5KFPMPY * Run the release packaging lanes without a compiler cache The Windows lane already ran uncached, because sccache re-spawns rustc with the aarch64 target's whole `--extern` and `-L` list and exceeds the operating system's command-line limit. The other lanes were only nominally cached: their server starts inside the nested `setup-rust`, whose `mozilla-actions/ sccache-action` re-exports `ACTIONS_CACHE_SERVICE_V2` and GitHub's own results address to `GITHUB_ENV` as its last act. On a Ubicloud runner that sends every write past the cache proxy to GitHub, where it is rate-limited and lands in no store this repository reads. There is no credentials export in this workflow to clobber, so the lane was paying sccache's overhead for nothing. Reproducing the merge gate's export, install and run-step start sequence for a workflow that runs on tag pushes and the dry run only would not pay back, so the lane now runs uncached on every platform: no `RUSTC_WRAPPER`, no backend flag, no installer, and `use-sccache: 'false'` into the nested action. That also removes the negated `platform != 'windows'` expressions. Getting that negation backwards cost a release build once; requiring the variables to be absent outright removes the expression and the whole class of mistake with it. Correct the credentials action's own explanation while here. It claimed the runner withholds reserved variables from shell steps. Measurement on shared-actions runs 33854048777 and 33854213968 shows composite `run` steps do see them, and that the real failure is the clobber described above. The developers guide carried the same superseded reading. Claude-Session: https://claude.ai/code/session_01QrjNTnTwM7FmWXe5KFPMPY * Reject a cache-save disjunction at any depth Four findings from the second review round. `is_trunk_only_save` rejected a top-level `||` but accepted the same disjunction in parentheses, which means exactly the same thing while presenting no top-level operator to find. It now rejects `||` anywhere outside a quoted literal. Rejecting outright, rather than deciding which disjunctions are safe, is deliberate: every cache-save condition here is a conjunction of equality tests, so nothing legitimate needs one, and a predicate that tried to tell safe from unsafe would be a second, subtler thing to get wrong. The parenthesised form joins the mutation set, and the named regression test becomes three cases: bare, parenthesised, and nested inside a conjunction. The mdtablefix `build-dir` check compared substrings, which was wrong in both directions: it accepted the relative `target/tool-build` and its Windows spelling, which are the product's own tree, while rejecting `build/target-cache`, whose first component merely shares a prefix. It also accepted `.`, the workspace root, despite the whole point being a dedicated directory. `is_dedicated_build_dir` now compares path components under both POSIX and Windows flavours, and eleven parametrized cases pin the ones the substring test got wrong. Three workflow sweeps globbed `*.yml` only. GitHub Actions accepts `.yaml` just as readily, so a workflow using it would have slipped past the cache ownership, Kani and runner placement contracts unexamined. Spelling: this repository is en-GB-oxendict, which takes the `-ize` forms. The docstrings added on this branch used `normalised`, `recognised` and `unrecognised`. Claude-Session: https://claude.ai/code/session_01QrjNTnTwM7FmWXe5KFPMPY * Let a warm-run dispatch reach every cache The runner migration's exit gate measures warm cache behaviour by dispatching the gate workflows on `main`. Two lanes were unreachable that way, so two of the five key families would have had no warm evidence short of merging something. `kani-smoke` excluded dispatches on the grounds that a manual run has no verification work to gate. True, but it is also the only job that touches the Kani cache, so excluding it left that key measurable only by a real push. It now runs on every trigger. `coverage-main.yml` had no dispatch trigger at all. It now has one. Neither can publish a generation. Every save in this repository gates on `github.event_name == 'push'` together with `github.ref == 'refs/heads/main'`, and `coverage-upload` declares no save at all. A new contract holds that directly rather than by inference: for every workflow that accepts a dispatch, each composite writer flag and each inline save must name the push event. Naming the ref alone would not be enough, because `github.ref` is `refs/heads/main` on a dispatch against the trunk too. Dropping the push predicate from the Kani action's writer flag makes it fail. Claude-Session: https://claude.ai/code/session_01QrjNTnTwM7FmWXe5KFPMPY * Pin shared-actions to the Windows extraction fix The Windows merge gate has been failing since the lanes moved to `windows-latest`. `install-whitaker` chose its archive extractor by probing what `tar` is, and on that image the answer is GNU tar, which cannot read the `.zip` installer asset. The step's `shell: bash` is Git Bash, whose PATH puts MSYS2's tar ahead of the Windows system directory, so the probe never saw the bsdtar its own comment assumed. That held only on the Namespace image this branch migrated away from. leynos/shared-actions#448 fixes it upstream, choosing the extractor by the resolved asset extension instead, and is now merged. Repin all 23 references from c6125f19 to that merge commit. The new revision also carries #440 and #445, so `setup-rust` now restores the cache service variables that `mozilla-actions/sccache-action` overwrites; nothing here depends on that yet, since every caller keeps `use-sccache: 'false'`. Claude-Session: https://claude.ai/code/session_01QrjNTnTwM7FmWXe5KFPMPY * Split the dispatch contract into named steps CodeScene flagged the new contract as a Complex Method, and fairly: it walked the composite actions, the inline saves and the dispatchable workflows in one body, with the assertion at the end. Each walk becomes a helper that returns labelled conditions, so the test reads as its three parts: something must accept a dispatch, saves must exist, and every one of them must name the push event. The contract is unchanged, and dropping the push predicate from the Kani action still fails it. Claude-Session: https://claude.ai/code/session_01QrjNTnTwM7FmWXe5KFPMPY * Give the isolated-build tests a Windows budget With the Whitaker installer fixed, the Windows gate reaches its `Test` step, and `harness_compiles_under_a_split_build_dir` terminated there at 300.081s with the other 2,503 tests passing. The immediately preceding run finished the same test inside the budget, which is what marginal looks like rather than broken. These two tests each spawn a complete isolated Cargo build. The Windows gate now runs on a four-vCPU GitHub-hosted runner rather than the Namespace profile it used before, and that shape's compile throughput does not fit the 300s default. This is the genuine external-resource constraint the configuration's own policy reserves a targeted override for, so it gets one with the rationale written down, rather than a retry. Scoped to Windows. On Ubicloud these finish in a fraction of the budget, and widening the timeout there would blunt the hang detection the default exists to provide. Claude-Session: https://claude.ai/code/session_01QrjNTnTwM7FmWXe5KFPMPY * Hold the worker bounds and the lane shapes under contract Three gaps the review round found, none of them in the workflows themselves. The Makefile forwards two separate worker bounds to `cargo nextest run`, and nothing held either in place. `NEXTEST_BUILD_JOBS` limits the compile that precedes the run and `NEXTEST_TEST_JOBS` limits the test processes, so a lane on a small runner can bound each without oversubscribing the other. Dropping either silently returns that half to nextest's default of one worker per core, which is what exhausted a two-vCPU runner in the first place. The Makefile contract now requires both, and requires the test bound to appear after `nextest run` rather than merely somewhere in the recipe, where it would read as configured while bounding nothing. The developers guide still described one two-vCPU merge gate deriving every worker bound from a single count. That has not been true since the instrumented lanes were escalated. It now carries a table of the six lanes with their runners and actual variables, and separates the two four-vCPU instrumented lanes from the two-vCPU Kani, Netsukefile and packaging lanes. The escalation's justification is recorded with the evidence rather than asserted: peak volume usage of about 80.6 GiB across three runs, against `ubicloud-standard-2`'s whole 72 GB volume, with memory never above 2,668 MiB of 16 GB. Two of the guide's universal claims had acquired an exception. The release packaging lane records no cache observations, because its entry is content-addressed and reached only by tag pushes and the dry run, so there is no warm-versus-cold trend to report; and it uses no compiler cache at all, so it must stay free of `RUSTC_WRAPPER`, `SCCACHE_GHA_ENABLED` and `SCCACHE_DIR` rather than merely setting them empty. Both exceptions are now stated where the rule is. Also rename the dispatch contract's first helper to say what it returns, and give both helpers the docstrings their new status as a module interface earns. Claude-Session: https://claude.ai/code/session_01QrjNTnTwM7FmWXe5KFPMPY * Bind the worker bounds to the command they bound Four review findings, one of which weakened a contract I had just added. `target_recipe` returns the recipe's lines joined together, so checking that `$(NEXTEST_TEST_JOBS)` appears after `nextest run` in that string would accept a bound sitting in an unrelated later command, reading as configured while bounding nothing. Both bounds are now asserted against the line that invokes `nextest run`, which is the thing they have to be arguments to. Composite actions were discovered with a single-level glob, so one nested a directory deeper would have bypassed both the save-gating policy and the source-build scan without any test noticing. Both now recurse. Two `isinstance` checks become structural pattern matches, per the repository's Python guidance. `_accepts_a_dispatch` keeps returning False for the scalar and list spellings of `on`, neither of which can carry the trigger's inputs. Claude-Session: https://claude.ai/code/session_01QrjNTnTwM7FmWXe5KFPMPY * Extract the nextest worker-bound assertions Adding the two bounds took `behavioural_make_test_composes_the_nextest_and_doctest_passes` to exactly the 70-line threshold CodeScene enforces. The bounds check is a self-contained question about one command, so it becomes `ensure_worker_bounds_reach_nextest`, which carries the reasoning that was previously two comment blocks in the middle of the test: why there are two variables rather than one, and why the assertion is made against the invoking line rather than the joined recipe. The test drops to 55 lines and reads as the sequence of properties it checks. Claude-Session: https://claude.ai/code/session_01QrjNTnTwM7FmWXe5KFPMPY
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bumps clap_mangen from 0.2.33 to 0.3.0.
Commits
f0d30d9chore: Release004fee9docs: Update changelog92e7e73Merge pull request #6319 from epage/envdd1fcd3fix(man)!: Put env support behind the env feature87f57faMerge pull request #6318 from casey/fix-ui-tests1f54684fix: Make ui_tests test conditional on env featureDependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting
@dependabot rebase.Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR:
@dependabot rebasewill rebase this PR@dependabot recreatewill recreate this PR, overwriting any edits that have been made to it@dependabot show <dependency name> ignore conditionswill show all of the ignore conditions of the specified dependency@dependabot ignore this major versionwill close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)@dependabot ignore this minor versionwill close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)@dependabot ignore this dependencywill close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)