Skip to content

Adopt cargo orthohelp release help#288

Open
lodyai[bot] wants to merge 22 commits into
mainfrom
cargo-orthohelp-adoption
Open

Adopt cargo orthohelp release help#288
lodyai[bot] wants to merge 22 commits into
mainfrom
cargo-orthohelp-adoption

Conversation

@lodyai
Copy link
Copy Markdown

@lodyai lodyai Bot commented May 1, 2026

Summary

This branch carries the pre-implementation plan for adopting cargo orthohelp as Netsuke's release help generator. It documents how the release workflow should replace clap_mangen and the current build.rs man-page output with explicit generation of Unix manual pages and Windows PowerShell MAML help.

Execplan: docs/execplans/cargo-orthohelp-adoption.md

This branch also updates Makefile so make markdownlint can resolve the Bun-installed markdownlint-cli2 in sparse hook environments where ~/.bun/bin is not on PATH.

This is a pre-implementation planning PR. It does not authorize implementation until the execplan is approved.

Review walkthrough

  • Start with docs/execplans/cargo-orthohelp-adoption.md to review the proposed release-help migration, approval gate, risks, tolerances, test strategy, and documentation updates.
  • Then review Makefile to confirm the MDLINT fallback keeps the existing override behaviour while fixing hook environments with a sparse PATH.

Validation

  • make check-fmt: passed.
  • make lint: passed.
  • make test: passed.
  • make markdownlint: passed.
  • PATH=/usr/bin:/bin make markdownlint: passed.
  • mbake validate Makefile: passed.

Notes

No roadmap task or issue reference was found in the branch context. The execplan records that implementation must wait for explicit approval.

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @LodyAI[bot], you have reached your weekly rate limit of 2500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 1, 2026

Review Change Stack

This PR is a planning / pre-implementation change set to adopt cargo-orthohelp as Netsuke’s release-help generator. It adds a living ExecPlan and the configuration, scripts, tests and docs needed to support the migration while deferring actual release-help generation until explicit approval and coordination with pinned shared-actions.

Key points

  • ExecPlan: adds docs/execplans/cargo-orthohelp-adoption.md (677 lines) describing constraints, risks, tolerances, approval gate, implementation phases, acceptance criteria and rollout/testing strategy. The ExecPlan is referenced from related design docs.
  • Blocking posture: this PR is preparatory only — do not enable release-help generation or related workflow changes until the ExecPlan is approved and shared-actions coordination (pins, new inputs/outputs) is finalised.
  • Release-help boundary: removes man-page generation from build.rs and introduces scripts/generate-release-help.sh which invokes cargo-orthohelp directly (not via Cargo dispatch) to produce Unix man pages and Windows PowerShell MAML. The script enforces expected output paths and SOURCE_DATE_EPOCH-based dates (with fallback).
  • CI / workflows and staging:
    • Adds .github/release-staging.toml (restructured common + per-target artefacts), declaring orthohelp outputs (required Unix man pages; optional Windows PowerShell module/MAML sidecars).
    • Adds/updates .github/workflows/build-and-package.yml to install cargo-orthohelp and run the generation script, and to expose staged outputs including powershell_help_dir and man_path for downstream packaging.
    • release.yml and CI workflows are updated to pin shared-actions and to forward per-arch stage keys into build-and-package.
    • Workflows must pin leynos/shared-actions to the provided SHA and set skip-man-page-discovery where appropriate; these wiring steps are included in the branch but must not be activated until execplan approval.
  • Packaging and GoReleaser: .goreleaser.yaml now ensures dist/netsuke.1.gz is present (either pre-staged or created from target/orthohelp/…/man1/netsuke.1) before archive/nfpms are built. scripts/package-artifact.sh is updated to read man pages from target/orthohelp paths.
  • Crate/build changes:
    • Cargo.toml: adds [package.metadata.ortho_config], bumps minijinja to 2.18.0, removes clap_mangen/time from build-deps and adds ortho_config + serde/serde_json/thiserror for build-time use.
    • build.rs: simplified to perform only Fluent localisation-key audits and rerun directives; it no longer emits man pages.
  • Minijinja deprecation fix: replaces eval_to_state usage with render_captured (src/manifest/jinja_macros/*) to address deprecation-as-error failures in newer minijinja versions.
  • Tests: extensive additions and updates to validate the planned workflow and contract:
    • BDD/feature tests (tests/features/... and tests/bdd/steps/release_help_generation.rs).
    • Integration/unit tests including a fake cargo-orthohelp harness (tests/release_help_script_tests.rs), release-staging and workflow contract tests (tests/release_staging_tests.rs, tests/workflow_build_and_package.rs, tests/workflow_release.rs).
    • Tests assert expected artefact paths under target/orthohelp/**, correct staging wiring, SOURCE_DATE_EPOCH handling, and that build.rs-generated help paths are no longer referenced.
  • Developer experience: Makefile updates to resolve CARGO and markdownlint-cli2 from PATH with fallbacks; adds a typecheck target. README and design docs updated to document the new release-help flow and artefact locations.
  • Coordination notes / upstream issue:
    • cargo-orthohelp must be invoked directly (cargo-orthohelp) because Cargo-dispatched invocation injects an argv token that current orthohelp clap interfaces reject. An upstream issue was opened (cargo-orthohelp fails when invoked via cargo orthohelp due to Cargo external-subcommand argument injection ortho-config#326) to record the incompatibility and potential remediation options.
    • Shared-actions composite rust-build-release was updated to accept an opt-out input skip-man-page-discovery to avoid failing projects that still use build.rs; the new input must be consumed by pinned shared-actions before enabling the workflow wiring in production.
  • Commits: document iterative preparation — add execplan, update workflows and staging, add generation script and tests, patch deprecated minijinja API usage, alter packaging hooks and Makefile improvements.

Status

  • Planning / prerequisite PR: contains documentation, test contracts, scripts and workflow/template changes required for migration and validation results (format/lint/tests/markdownlint passed in branch), but implementation and activation of release-help generation and workflow staging MUST WAIT for explicit ExecPlan approval and the agreed shared-actions pins/inputs/outputs to be coordinated and applied.

Walkthrough

Migrate release help generation from build.rs to a workflow-invoked script using cargo-orthohelp; restructure release-staging.toml and packaging hooks; refactor MiniJinja macro caching; add tests and documentation; update CI/workflow pins and Makefile tooling resolution.

Changes

Release help generation and packaging migration

Layer / File(s) Summary
Release help generation script and date handling
scripts/generate-release-help.sh
Wraps cargo-orthohelp invocation with argument validation, SOURCE_DATE_EPOCH-derived manual-date (Python-assisted conversion), Windows target detection, and require_file checks for generated man/PowerShell artefacts.
Build configuration and dependency updates
Cargo.toml, build.rs, Makefile
Add package.metadata.ortho_config, bump minijinja to 2.18.0, revise [build-dependencies], simplify build.rs to only audit localisation keys, and make Makefile resolve CARGO/MDLINT from PATH plus add typecheck.
Release staging, packaging, and workflow integration
.github/release-staging.toml, .github/workflows/build-and-package.yml, .github/workflows/release.yml, .goreleaser.yaml, scripts/package-artifact.sh, .github/workflows/ci.yml, .github/workflows/netsukefile-test.yml
Restructure release-staging TOML into [common] plus per-target [[targets...artefacts]], enumerate orthohelp man and PowerShell artefacts, add cargo-orthohelp install and script run to build workflow, wire staged man_path/powershell_help_dir into packaging, add goreleaser before.hooks to ensure dist/netsuke.1.gz, update package-artifact paths, and bump workflow action pins and matrix passthrough.
MiniJinja capture-based macro caching refactor
src/manifest/jinja_macros/cache.rs, src/manifest/jinja_macros/mod.rs, src/manifest/tests/macros.rs
Refactor macro caching to store Captured<'static> via template.render_captured(), box the capture, and derive &State via captured.state(); update doc examples and tests to match the new API.
Comprehensive release help and workflow testing
tests/features/release_help_generation.feature, tests/bdd/steps/release_help_generation.rs, tests/bdd/steps/mod.rs, tests/release_help_script_tests.rs, tests/release_staging_tests.rs, tests/workflow_build_and_package.rs, tests/workflow_release.rs
Add BDD feature and step defs for release help flows; add integration tests with a fake cargo-orthohelp to validate script behaviour and error cases; add TOML/workflow parsing tests to assert staged artefacts and removed build-script references; add parameterised release workflow assertions.
Documentation updates describing cargo-orthohelp adoption
docs/developers-guide.md, docs/execplans/cargo-orthohelp-adoption.md, docs/netsuke-cli-design-document.md, docs/netsuke-design.md, docs/users-guide.md, README.md
Document release help tooling, the migration ExecPlan, updated artefact output locations (target/orthohelp/<target>/release/), SOURCE_DATE_EPOCH handling, and Windows PowerShell help packaging.

Sequence Diagram(s)

sequenceDiagram
  participant ReleaseWorkflow as release.yml
  participant BuildAndPackage as build-and-package.yml
  participant GenerateHelpScript as scripts/generate-release-help.sh
  participant CargoOrthohelp as cargo-orthohelp
  participant StagingAction as stage-release-artefacts
  ReleaseWorkflow->>BuildAndPackage: trigger with stage-target
  BuildAndPackage->>GenerateHelpScript: run for selected target
  GenerateHelpScript->>CargoOrthohelp: --format man / --format ps (+ --ps-module-name)
  CargoOrthohelp->>StagingAction: write target/orthohelp/{target}/release artefacts
  StagingAction->>BuildAndPackage: export man_path, powershell_help_dir
  BuildAndPackage->>Packaging: pass staged paths to packaging steps
Loading

Possibly related PRs

  • leynos/shared-actions#265: Adds ps-module-name input and powershell_help_dir output to the shared staging action used by this PR.

Poem

From build.rs the help did stray,
cargo-orthohelp now saves the day,
Scripts, staging, tests align in tune,
Manpages, PowerShell — boxed and in June,
Ship artefacts neat beneath the moon.


Caution

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

  • Ignore

❌ Failed checks (2 errors, 3 warnings)

Check name Status Explanation Resolution
Module-Level Documentation ❌ Error Shell module scripts/generate-release-help.sh lacks module-level documentation. All Rust test modules have proper docstrings; only this new shell script is undocumented. Add documentation comment block after shebang in scripts/generate-release-help.sh explaining its purpose: generate Unix man pages and Windows PowerShell help assets via cargo-orthohelp invocation.
Unit Architecture ❌ Error scripts/generate-release-help.sh hardcodes module_name instead of accepting it as an injectable parameter, violating dependency-injection principles for composable units. Add module_name as a positional parameter to generate-release-help.sh (fourth argument) and update .github/workflows/build-and-package.yml to pass it explicitly.
Testing (Unit And Behavioural) ⚠️ Warning BDD release_help_generation tests are disguised unit tests—they only check file contents via string matching rather than exercising functional workflow boundaries. Replace BDD file-content assertions with actual workflow tests. Execute release-help, validate staged outputs, verify help artefacts appear correctly. Remove BDD steps that only check .contains() on YAML/TOML/shell.
Testing (Compile-Time / Ui) ⚠️ Warning Snapshot tests for man page and PowerShell help generated outputs are absent. Release help script tests only verify file existence, not actual content or format. Add snapshot tests with insta to validate man page format (.TH section) and PowerShell module structure (XML/MAML, manifest files) emitted by fake cargo-orthohelp.
Observability ⚠️ Warning Missing observability for cargo-orthohelp invocation failures and version validation. When cargo-orthohelp execution fails, error context lacks target/format/locale details and invocation logging. Add explicit logging of cargo-orthohelp invocations (target, format, locale, output dir) to scripts/generate-release-help.sh; add version validation after installation; wrap cargo-orthohelp stderr with contextual GitHub Actions annotations.
✅ Passed checks (13 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Adopt cargo orthohelp release help' clearly and directly describes the main objective of the PR: adopting cargo-orthohelp as the release help generator, replacing clap_mangen and build.rs man-page generation.
Description check ✅ Passed The description comprehensively relates to the changeset, explaining the migration strategy, referencing the execplan documentation, documenting Makefile updates for sparse PATH environments, and clarifying that this is a pre-implementation planning PR awaiting approval before implementation proceeds.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Testing (Overall) ✅ Passed Script integration test validates outputs and error handling; config tests verify orthohelp paths and absence of build.rs paths; workflow tests check staging. Would fail for incorrect implementations.
User-Facing Documentation ✅ Passed docs/users-guide.md adds "Release help artefacts" subsection documenting platform-specific help files (Unix manpages, Windows PowerShell), and README documents the same functionality adequately.
Developer Documentation ✅ Passed Cargo-orthohelp adoption comprehensively documented: Release help tooling section in developers-guide, design documents updated, ExecPlan complete with all 21 progress items marked finished.
Testing (Property / Proof) ✅ Passed Configuration, workflow, and API deprecation updates with straightforward logic covered by tests. No invariants, state transitions, or proof assumptions warrant property tests or model checking.
Domain Architecture ✅ Passed Manifest parsing segregated from help generation; jinja_macros properly boundaries MiniJinja adapter; build.rs simplified to l10n audit; help generation moved to release-time via external tool.
Security And Privacy ✅ Passed No secrets, injection risks, unsafe deserialization, or privacy exposure found. Parameters properly quoted, environment variables validated, file operations checked, TOML parsing safe.
Performance And Resource Use ✅ Passed No performance regressions: build.rs faster, macro cache API change neutral, release script off-path, no unbounded allocations or algorithmic complexity increase.
Concurrency And State ✅ Passed Unsafe code in cache.rs follows a single-threaded model: OnceLock-guarded initialisation, debug-assert thread checks, thread-local Environment lifecycles, no mutable shared state across threads.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cargo-orthohelp-adoption

Comment @coderabbitai help to get the list of available commands and usage tips.

codescene-delta-analysis[bot]

This comment was marked as outdated.

codescene-delta-analysis[bot]

This comment was marked as outdated.

codescene-delta-analysis[bot]

This comment was marked as outdated.

@lodyai lodyai Bot force-pushed the cargo-orthohelp-adoption branch from f669b09 to 99e3f3c Compare May 3, 2026 23:12
codescene-delta-analysis[bot]

This comment was marked as outdated.

codescene-delta-analysis[bot]

This comment was marked as outdated.

@leynos
Copy link
Copy Markdown
Owner

leynos commented May 7, 2026

@coderabbitai Please investigate the cause of the following issue using codegraph exploration and research, identify a fix and provide an AI coding agent prompt for the fix:

Run scripts/generate-release-help.sh "aarch64-apple-darwin" "netsuke" "target/orthohelp/aarch64-apple-darwin/release"
  scripts/generate-release-help.sh "aarch64-apple-darwin" "netsuke" "target/orthohelp/aarch64-apple-darwin/release"
  shell: /opt/homebrew/bin/bash --noprofile --norc -e -o pipefail {0}
  env:
    BIN_NAME: netsuke
    VERSION: 0.1.0
    MAN_ARCH: unknown
    UV_CACHE_DIR: /Users/runner/work/_temp/setup-uv-cache
    RBR_TOOLCHAIN: 1.89.0
    CARGO_INCREMENTAL: 0
    CARGO_PROFILE_DEV_DEBUG: 0
    CARGO_TERM_COLOR: always
    RUST_BACKTRACE: short
    RUSTFLAGS: -D warnings
    CARGO_UNSTABLE_SPARSE_REGISTRY: true
    CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
    SCCACHE_PATH: /Users/runner/hostedtoolcache/sccache/0.15.0/arm64/sccache
    ACTIONS_CACHE_SERVICE_V2: on
    ACTIONS_RESULTS_URL: https://results-receiver.actions.githubusercontent.com/
    ACTIONS_RUNTIME_TOKEN: ***
error: unexpected argument 'orthohelp' found

Usage: cargo-orthohelp [OPTIONS]

For more information, try '--help'.
Error: Process completed with exit code 2.

@lodyai lodyai Bot force-pushed the cargo-orthohelp-adoption branch from 7d79b22 to 4335334 Compare May 7, 2026 16:53
codescene-delta-analysis[bot]

This comment was marked as outdated.

@coderabbitai

This comment was marked as resolved.

codescene-delta-analysis[bot]

This comment was marked as outdated.

@leynos
Copy link
Copy Markdown
Owner

leynos commented May 8, 2026

@coderabbitai Please investigate the cause of the following issue using codegraph exploration and research, identify a fix and provide an AI coding agent prompt for the fix:

Run leynos/shared-actions/.github/actions/rust-build-release@d400b079fb6a8fa92f7e7b6c57f3d1c92a4b2d54
  with:
    target: x86_64-unknown-linux-gnu
    bin-name: netsuke
    project-dir: .
    manifest-path: Cargo.toml
  env:
    BIN_NAME: netsuke
    VERSION: 0.1.0
    MAN_ARCH: amd64
Run astral-sh/setup-uv@557e51de59eb14aaaba2ed9621916900a91d50c6
  with:
    activate-environment: false
    working-directory: /home/runner/work/netsuke/netsuke
    server-url: https://github.com
    github-token: ***
    enable-cache: auto
    cache-dependency-glob: **/*requirements*.txt
  **/*requirements*.in
  **/*constraints*.txt
  **/*constraints*.in
  **/pyproject.toml
  **/uv.lock
  
    prune-cache: true
    ignore-nothing-to-cache: false
    ignore-empty-workdir: false
    add-problem-matchers: true
  env:
    BIN_NAME: netsuke
    VERSION: 0.1.0
    MAN_ARCH: amd64
Trying to find version for uv in: /home/runner/work/netsuke/netsuke/uv.toml
Could not find file: /home/runner/work/netsuke/netsuke/uv.toml
Trying to find version for uv in: /home/runner/work/netsuke/netsuke/pyproject.toml
Could not find file: /home/runner/work/netsuke/netsuke/pyproject.toml
Could not determine uv version from uv.toml or pyproject.toml. Falling back to latest.
Getting latest version from GitHub API...
manifest-file not provided, reading from local file.
manifest-file does not contain version 0.11.11, arch x86_64, platform unknown-linux-gnu. Falling back to GitHub releases.
Downloading uv from "https://github.com/astral-sh/uv/releases/download/0.11.11/uv-x86_64-unknown-linux-gnu.tar.gz" ...
/usr/bin/tar xz --warning=no-unknown-keyword --overwrite -C /home/runner/work/_temp/521f040b-a9f5-408a-ae65-842ccda446a0 -f /home/runner/work/_temp/c38ff597-c683-40c7-bf25-28148debd01e
Added /home/runner/.local/bin to the path
Added /opt/hostedtoolcache/uv/0.11.11/x86_64 to the path
Set UV_CACHE_DIR to /home/runner/work/_temp/setup-uv-cache
Successfully installed uv version 0.11.11
Searching files using cache dependency glob: /home/runner/work/netsuke/netsuke/**/*requirements*.txt,/home/runner/work/netsuke/netsuke/**/*requirements*.in,/home/runner/work/netsuke/netsuke/**/*constraints*.txt,/home/runner/work/netsuke/netsuke/**/*constraints*.in,/home/runner/work/netsuke/netsuke/**/pyproject.toml,/home/runner/work/netsuke/netsuke/**/uv.lock
No matches found for glob
Warning: No file matched to [/home/runner/work/netsuke/netsuke/**/*requirements*.txt,/home/runner/work/netsuke/netsuke/**/*requirements*.in,/home/runner/work/netsuke/netsuke/**/*constraints*.txt,/home/runner/work/netsuke/netsuke/**/*constraints*.in,/home/runner/work/netsuke/netsuke/**/pyproject.toml,/home/runner/work/netsuke/netsuke/**/uv.lock]. The cache will never get invalidated. Make sure you have checked out the target repository and configured the cache-dependency-glob input correctly.
Trying to restore uv cache from GitHub Actions cache with key: setup-uv-1-x86_64-unknown-linux-gnu-3.12.3-pruned-no-dependency-glob
Cache hit for: setup-uv-1-x86_64-unknown-linux-gnu-3.12.3-pruned-no-dependency-glob
Received 133395 of 133395 (100.0%), 1.0 MBs/sec
Cache Size: ~0 MB (133395 B)
/usr/bin/tar -xf /home/runner/work/_temp/c0bc6e91-d9fb-4e18-9e49-17e0423963af/cache.tzst -P -C /home/runner/work/netsuke/netsuke --use-compress-program unzstd
Cache restored successfully
uv cache restored from GitHub Actions cache with key: setup-uv-1-x86_64-unknown-linux-gnu-3.12.3-pruned-no-dependency-glob
Run set -euo pipefail
  set -euo pipefail
  uv run --script "$GITHUB_ACTION_PATH/src/action_setup.py" \
    validate "x86_64-unknown-linux-gnu"
  shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0}
  env:
    BIN_NAME: netsuke
    VERSION: 0.1.0
    MAN_ARCH: amd64
    UV_CACHE_DIR: /home/runner/work/_temp/setup-uv-cache
Downloading pygments (1.2MiB)
 Downloaded pygments
Installed 10 packages in 11ms
Run set -euo pipefail
  set -euo pipefail
  TOOLCHAIN="$(uv run --script "$GITHUB_ACTION_PATH/src/action_setup.py" \
    toolchain \
    --toolchain "" \
    --manifest-path "Cargo.toml" \
    --target "x86_64-unknown-linux-gnu" \
    --runner-os "Linux" \
    --runner-arch "X64")"
  echo "RBR_TOOLCHAIN=$TOOLCHAIN" >> "$GITHUB_ENV"
  shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0}
  env:
    BIN_NAME: netsuke
    VERSION: 0.1.0
    MAN_ARCH: amd64
    UV_CACHE_DIR: /home/runner/work/_temp/setup-uv-cache
Run leynos/shared-actions/.github/actions/setup-rust@aebb3f5b831102e2a10ef909c83d7d50ea86c332
  with:
    toolchain: 1.89.0
    install-postgres-deps: false
    install-sqlite-deps: false
    use-sccache: true
    install-binstall: true
    with-darwin: false
    darwin-sdk-version: 12.3
    with-openbsd: false
    openbsd-nightly: nightly-2025-07-20
  env:
    BIN_NAME: netsuke
    VERSION: 0.1.0
    MAN_ARCH: amd64
    UV_CACHE_DIR: /home/runner/work/_temp/setup-uv-cache
    RBR_TOOLCHAIN: 1.89.0
Run actions-rust-lang/setup-rust-toolchain@9d7e65c320fdb52dcd45ffaa68deb6c02c8754d9
  with:
    override: true
    toolchain: 1.89.0
    components: rustfmt, clippy, llvm-tools-preview
    cache: false
    cache-on-failure: true
    cache-bin: true
    matcher: true
    rustflags: -D warnings
  env:
    BIN_NAME: netsuke
    VERSION: 0.1.0
    MAN_ARCH: amd64
    UV_CACHE_DIR: /home/runner/work/_temp/setup-uv-cache
    RBR_TOOLCHAIN: 1.89.0
Run : construct rustup command line
  : construct rustup command line
  echo "targets=$(for t in ${targets//,/ }; do echo -n ' --target' $t; done)" >> $GITHUB_OUTPUT
  echo "components=$(for c in ${components//,/ }; do echo -n ' --component' $c; done)" >> $GITHUB_OUTPUT
  echo "downgrade=" >> $GITHUB_OUTPUT
  shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0}
  env:
    BIN_NAME: netsuke
    VERSION: 0.1.0
    MAN_ARCH: amd64
    UV_CACHE_DIR: /home/runner/work/_temp/setup-uv-cache
    RBR_TOOLCHAIN: 1.89.0
    targets: 
    components: rustfmt, clippy, llvm-tools-preview
Run if [[ ! -v CARGO_INCREMENTAL ]]; then
  if [[ ! -v CARGO_INCREMENTAL ]]; then
    echo "CARGO_INCREMENTAL=0" >> $GITHUB_ENV
  fi
  if [[ ! -v CARGO_PROFILE_DEV_DEBUG ]]; then
    echo "CARGO_PROFILE_DEV_DEBUG=0" >> $GITHUB_ENV
  fi
  if [[ ! -v CARGO_TERM_COLOR ]]; then
    echo "CARGO_TERM_COLOR=always" >> $GITHUB_ENV
  fi
  if [[ ! -v RUST_BACKTRACE ]]; then
    echo "RUST_BACKTRACE=short" >> $GITHUB_ENV
  fi
  if [[ ( ! -v RUSTFLAGS ) && $NEW_RUSTFLAGS != "" ]]; then
    echo "RUSTFLAGS=$NEW_RUSTFLAGS" >> $GITHUB_ENV
  fi
  # Enable faster sparse index on nightly
  # The value is ignored on stable and causes no problems
  # https://internals.rust-lang.org/t/call-for-testing-cargo-sparse-registry/16862
  if [[ ! -v CARGO_UNSTABLE_SPARSE_REGISTRY ]]; then
    echo "CARGO_UNSTABLE_SPARSE_REGISTRY=true" >> $GITHUB_ENV
  fi
  if [[ ! -v CARGO_REGISTRIES_CRATES_IO_PROTOCOL ]]; then
    echo "CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse" >> $GITHUB_ENV
  fi
  shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0}
  env:
    BIN_NAME: netsuke
    VERSION: 0.1.0
    MAN_ARCH: amd64
    UV_CACHE_DIR: /home/runner/work/_temp/setup-uv-cache
    RBR_TOOLCHAIN: 1.89.0
    NEW_RUSTFLAGS: -D warnings
Run echo "::add-matcher::/home/runner/work/_actions/actions-rust-lang/setup-rust-toolchain/9d7e65c320fdb52dcd45ffaa68deb6c02c8754d9/rust.json"
  echo "::add-matcher::/home/runner/work/_actions/actions-rust-lang/setup-rust-toolchain/9d7e65c320fdb52dcd45ffaa68deb6c02c8754d9/rust.json"
  shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0}
  env:
    BIN_NAME: netsuke
    VERSION: 0.1.0
    MAN_ARCH: amd64
    UV_CACHE_DIR: /home/runner/work/_temp/setup-uv-cache
    RBR_TOOLCHAIN: 1.89.0
    CARGO_INCREMENTAL: 0
    CARGO_PROFILE_DEV_DEBUG: 0
    CARGO_TERM_COLOR: always
    RUST_BACKTRACE: short
    RUSTFLAGS: -D warnings
    CARGO_UNSTABLE_SPARSE_REGISTRY: true
    CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
Run if ! command -v rustup &> /dev/null ; then
  if ! command -v rustup &> /dev/null ; then
    curl --proto '=https' --tlsv1.2 --retry 10 --retry-connrefused -fsSL "https://sh.rustup.rs" | sh -s -- --default-toolchain none -y
    
    # Resolve the correct CARGO_HOME path depending on OS
    if [[ "$RUNNER_OS" == "Windows" ]]; then
      echo "${CARGO_HOME:-$USERPROFILE/.cargo}/bin" | sed 's|/|\\|g' >> $GITHUB_PATH
    else
      echo "${CARGO_HOME:-$HOME/.cargo}/bin" >> $GITHUB_PATH
    fi
  fi
  shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0}
  env:
    BIN_NAME: netsuke
    VERSION: 0.1.0
    MAN_ARCH: amd64
    UV_CACHE_DIR: /home/runner/work/_temp/setup-uv-cache
    RBR_TOOLCHAIN: 1.89.0
    CARGO_INCREMENTAL: 0
    CARGO_PROFILE_DEV_DEBUG: 0
    CARGO_TERM_COLOR: always
    RUST_BACKTRACE: short
    RUSTFLAGS: -D warnings
    CARGO_UNSTABLE_SPARSE_REGISTRY: true
    CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
    RUNNER_OS: Linux
Run if [[ -z "$toolchain" && ( -f "rust-toolchain" || -f "rust-toolchain.toml" ) ]]
  if [[ -z "$toolchain" && ( -f "rust-toolchain" || -f "rust-toolchain.toml" ) ]]
  then
    # Install the toolchain as specified in the file
    # rustup show is the old way that implicitly installed a toolchain
    # rustup toolchain install is the new explicit way
    # https://github.com/rust-lang/rustup/issues/3635#issuecomment-2343511297
    rustup show active-toolchain || rustup toolchain install
    if [[ -n $components ]]; then
      rustup component add ${components//,/ }
    fi
    if [[ -n $targets ]]; then
      rustup target add ${targets//,/ }
    fi
  else
    if [[ -z "$toolchain" ]]
    then
      toolchain=stable
    fi
    rustup toolchain install ${toolchain//,/ }  --component rustfmt --component clippy --component llvm-tools-preview --profile minimal --no-self-update
    # Take the last element from the list
    if [[ "$override" == "true" ]]
    then
      rustup override set ${toolchain//*,/ }
    fi
  fi
  shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0}
  env:
    BIN_NAME: netsuke
    VERSION: 0.1.0
    MAN_ARCH: amd64
    UV_CACHE_DIR: /home/runner/work/_temp/setup-uv-cache
    RBR_TOOLCHAIN: 1.89.0
info: syncing channel updates for 1.89.0-x86_64-unknown-linux-gnu
info: latest update on 2025-08-07 for version 1.89.0 (29483883e 2025-08-04)
info: component clippy is up to date
info: component rustfmt is up to date
info: downloading component llvm-tools

  1.89.0-x86_64-unknown-linux-gnu updated - rustc 1.89.0 (29483883e 2025-08-04) (from rustc 1.89.0 (29483883e 2025-08-04))

info: override toolchain for /home/runner/work/netsuke/netsuke set to 1.89.0-x86_64-unknown-linux-gnu
Run echo "rustc-version=$(rustc --version)" >> $GITHUB_OUTPUT
rustc 1.89.0 (29483883e 2025-08-04)
binary: rustc
commit-hash: 29483883eed69d5fb4db01964cdf2af4d86e9cb2
commit-date: 2025-08-04
host: x86_64-unknown-linux-gnu
release: 1.89.0
LLVM version: 20.1.7
cargo 1.89.0 (c24e10642 2025-06-23)
release: 1.89.0
commit-hash: c24e1064277fe51ab72011e2612e556ac56addf7
commit-date: 2025-06-23
host: x86_64-unknown-linux-gnu
libgit2: 1.9.0 (sys:0.20.2 vendored)
libcurl: 8.12.1-DEV (sys:0.4.80+curl-8.12.1 vendored ssl:OpenSSL/3.5.0)
ssl: OpenSSL 3.5.0 8 Apr 2025
os: Ubuntu 24.4.0 (noble) [64-bit]
info: This is the version for the rustup toolchain manager, not the rustc compiler.
info: the currently active `rustc` version is `rustc 1.89.0 (29483883e 2025-08-04)`
info: This is the version for the rustup toolchain manager, not the rustc compiler.
rustup 1.29.0 (28d1352db 2026-03-05)
info: the currently active `rustc` version is `rustc 1.89.0 (29483883e 2025-08-04)`
Run # Not all versions support setting CARGO_REGISTRIES_CRATES_IO_PROTOCOL
  # Not all versions support setting CARGO_REGISTRIES_CRATES_IO_PROTOCOL
  # On versions 1.66, 1.67, and 1.68.0-nightly the value "sparse" is still unstable.
  # https://github.com/dtolnay/rust-toolchain/pull/69#discussion_r1107268108
  # If we detect an incompatible value, set it to "git" which is always supported.
  if [[ "rustc 1.89.0 (29483883e 2025-08-04)" =~ ^rustc\ (1\.6[67]\.|1\.68\.0-nightly) && "${CARGO_REGISTRIES_CRATES_IO_PROTOCOL}" == "sparse" ]]; then
    echo "Downgrade cargo registry protocol to git"
    echo "CARGO_REGISTRIES_CRATES_IO_PROTOCOL=git" >> $GITHUB_ENV
  fi
  shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0}
  env:
    BIN_NAME: netsuke
    VERSION: 0.1.0
    MAN_ARCH: amd64
    UV_CACHE_DIR: /home/runner/work/_temp/setup-uv-cache
    RBR_TOOLCHAIN: 1.89.0
    CARGO_INCREMENTAL: 0
    CARGO_PROFILE_DEV_DEBUG: 0
    CARGO_TERM_COLOR: always
    RUST_BACKTRACE: short
    RUSTFLAGS: -D warnings
    CARGO_UNSTABLE_SPARSE_REGISTRY: true
    CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
Run set -euo pipefail
  set -euo pipefail
  # Keep BINSTALL_VERSION and BINSTALL_SHA256 in sync; update both together.
  # To refresh the checksum: curl -fsSL "$INSTALLER_URL" | shasum -a 256 | awk '{print $1}'
  BINSTALL_VERSION="v1.16.6"
  BINSTALL_SHA256="c2e963fbab3bdd8653b59c28d349bf85740cf4998e5e398d250dcd2884cd667d"
  INSTALLER_URL="https://raw.githubusercontent.com/cargo-bins/cargo-binstall/${BINSTALL_VERSION}/install-from-binstall-release.sh"
  INSTALLER_PATH="$(mktemp)"
  trap 'rm -f "$INSTALLER_PATH"' EXIT
  curl -fsSL --proto '=https' --tlsv1.2 "$INSTALLER_URL" -o "$INSTALLER_PATH"
  if [ ! -s "$INSTALLER_PATH" ]; then
    echo "cargo-binstall installer download failed or empty" >&2
    exit 1
  fi
  if command -v sha256sum >/dev/null 2>&1; then
    ACTUAL_SHA256="$(sha256sum "$INSTALLER_PATH" | awk '{print $1}')"
  else
    ACTUAL_SHA256="$(shasum -a 256 "$INSTALLER_PATH" | awk '{print $1}')"
  fi
  if [ "$ACTUAL_SHA256" != "$BINSTALL_SHA256" ]; then
    echo "cargo-binstall install script checksum mismatch: $ACTUAL_SHA256" >&2
    exit 1
  fi
  bash "$INSTALLER_PATH"
  shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0}
  env:
    BIN_NAME: netsuke
    VERSION: 0.1.0
    MAN_ARCH: amd64
    UV_CACHE_DIR: /home/runner/work/_temp/setup-uv-cache
    RBR_TOOLCHAIN: 1.89.0
    CARGO_INCREMENTAL: 0
    CARGO_PROFILE_DEV_DEBUG: 0
    CARGO_TERM_COLOR: always
    RUST_BACKTRACE: short
    RUSTFLAGS: -D warnings
    CARGO_UNSTABLE_SPARSE_REGISTRY: true
    CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
+ set -o pipefail
+ set -o pipefail
+ case "${BINSTALL_VERSION:-}" in
++ mktemp -d
+ cd /tmp/tmp.iUzcKTU7bm
+ '[' -z '' ']'
+ base_url=https://github.com/cargo-bins/cargo-binstall/releases/latest/download/cargo-binstall-
++ uname -s
+ os=Linux
+ '[' Linux = Darwin ']'
+ '[' Linux = Linux ']'
++ uname -m
+ machine=x86_64
+ '[' x86_64 = armv7l ']'
+ target=x86_64-unknown-linux-musl
+ '[' x86_64 = armv7 ']'
+ url=https://github.com/cargo-bins/cargo-binstall/releases/latest/download/cargo-binstall-x86_64-unknown-linux-musl.tgz
+ do_curl https://github.com/cargo-bins/cargo-binstall/releases/latest/download/cargo-binstall-x86_64-unknown-linux-musl.tgz
+ curl --retry 10 -A 'Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/81.0' -L --proto =https --tlsv1.2 -sSf https://github.com/cargo-bins/cargo-binstall/releases/latest/download/cargo-binstall-x86_64-unknown-linux-musl.tgz
+ tar -xvzf -
cargo-binstall
+ ./cargo-binstall --self-install
+ CARGO_HOME=/home/runner/.cargo
+ case ":$PATH:" in
+ '[' -n '' ']'
Run astral-sh/setup-uv@e92bafb6253dcd438e0484186d7669ea7a8ca1cc
  with:
    cache-dependency-glob: **/pyproject.toml
  **/uv.lock
  **/scripts/*.py
  
    activate-environment: false
    working-directory: /home/runner/work/netsuke/netsuke
    server-url: https://github.com
    github-token: ***
    enable-cache: auto
    prune-cache: true
    ignore-nothing-to-cache: false
    ignore-empty-workdir: false
  env:
    BIN_NAME: netsuke
    VERSION: 0.1.0
    MAN_ARCH: amd64
    UV_CACHE_DIR: /home/runner/work/_temp/setup-uv-cache
    RBR_TOOLCHAIN: 1.89.0
    CARGO_INCREMENTAL: 0
    CARGO_PROFILE_DEV_DEBUG: 0
    CARGO_TERM_COLOR: always
    RUST_BACKTRACE: short
    RUSTFLAGS: -D warnings
    CARGO_UNSTABLE_SPARSE_REGISTRY: true
    CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
Trying to find version for uv in: /home/runner/work/netsuke/netsuke/uv.toml
Could not find file: /home/runner/work/netsuke/netsuke/uv.toml
Trying to find version for uv in: /home/runner/work/netsuke/netsuke/pyproject.toml
Could not find file: /home/runner/work/netsuke/netsuke/pyproject.toml
Could not determine uv version from uv.toml or pyproject.toml. Falling back to latest.
Found uv in tool-cache for 0.11.11
Added /home/runner/.local/bin to the path
Added /opt/hostedtoolcache/uv/0.11.11/x86_64 to the path
Set UV_CACHE_DIR to /home/runner/work/_temp/setup-uv-cache
Successfully installed uv version 0.11.11
Searching files using cache dependency glob: /home/runner/work/netsuke/netsuke/**/pyproject.toml,/home/runner/work/netsuke/netsuke/**/uv.lock,/home/runner/work/netsuke/netsuke/**/scripts/*.py
No matches found for glob
Warning: No file matched to [/home/runner/work/netsuke/netsuke/**/pyproject.toml,/home/runner/work/netsuke/netsuke/**/uv.lock,/home/runner/work/netsuke/netsuke/**/scripts/*.py]. The cache will never get invalidated. Make sure you have checked out the target repository and configured the cache-dependency-glob input correctly.
Trying to restore uv cache from GitHub Actions cache with key: setup-uv-1-x86_64-unknown-linux-gnu-3.12.3-pruned-no-dependency-glob
Cache hit for: setup-uv-1-x86_64-unknown-linux-gnu-3.12.3-pruned-no-dependency-glob
Received 133395 of 133395 (100.0%), 0.9 MBs/sec
Cache Size: ~0 MB (133395 B)
/usr/bin/tar -xf /home/runner/work/_temp/3940b306-49d8-4d56-89d2-4e69e0b571b1/cache.tzst -P -C /home/runner/work/netsuke/netsuke --use-compress-program unzstd
Cache restored successfully
uv cache restored from GitHub Actions cache with key: setup-uv-1-x86_64-unknown-linux-gnu-3.12.3-pruned-no-dependency-glob
Run actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830
  with:
    path: ~/.cargo/registry
  ~/.cargo/git
  target/
  
    key: Linux-cargo--215c930b9ba91c629d891c6a226f6e629eb114074380448a321b42582fd5c15b
    restore-keys: Linux-cargo--
  
    enableCrossOsArchive: false
    fail-on-cache-miss: false
    lookup-only: false
    save-always: false
  env:
    BIN_NAME: netsuke
    VERSION: 0.1.0
    MAN_ARCH: amd64
    UV_CACHE_DIR: /home/runner/work/_temp/setup-uv-cache
    RBR_TOOLCHAIN: 1.89.0
    CARGO_INCREMENTAL: 0
    CARGO_PROFILE_DEV_DEBUG: 0
    CARGO_TERM_COLOR: always
    RUST_BACKTRACE: short
    RUSTFLAGS: -D warnings
    CARGO_UNSTABLE_SPARSE_REGISTRY: true
    CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
Cache hit for: Linux-cargo--215c930b9ba91c629d891c6a226f6e629eb114074380448a321b42582fd5c15b
Received 71303168 of 171178197 (41.7%), 68.0 MBs/sec
Received 171178197 of 171178197 (100.0%), 100.5 MBs/sec
Cache Size: ~163 MB (171178197 B)
/usr/bin/tar -xf /home/runner/work/_temp/dd2f82c1-67db-4d7d-8762-a8b6bd0f2d3b/cache.tzst -P -C /home/runner/work/netsuke/netsuke --use-compress-program unzstd
Cache restored successfully
Cache restored from key: Linux-cargo--215c930b9ba91c629d891c6a226f6e629eb114074380448a321b42582fd5c15b
Run mozilla-actions/sccache-action@7d986dd989559c6ecdb630a3fd2557667be217ad
  with:
    token: ***
    disable_annotations: false
  env:
    BIN_NAME: netsuke
    VERSION: 0.1.0
    MAN_ARCH: amd64
    UV_CACHE_DIR: /home/runner/work/_temp/setup-uv-cache
    RBR_TOOLCHAIN: 1.89.0
    CARGO_INCREMENTAL: 0
    CARGO_PROFILE_DEV_DEBUG: 0
    CARGO_TERM_COLOR: always
    RUST_BACKTRACE: short
    RUSTFLAGS: -D warnings
    CARGO_UNSTABLE_SPARSE_REGISTRY: true
    CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
try to setup sccache version: v0.15.0
sccache download from url: https://github.com/mozilla/sccache/releases/download/v0.15.0/sccache-v0.15.0-x86_64-unknown-linux-musl.tar.gz
Correct checksum: 782d2b5dd7ae0a55ebe368ab258114d0928d019ac2d949ab85d5d02f3926709e
/usr/bin/tar xz --warning=no-unknown-keyword --overwrite -C /home/runner/work/_temp/77bc32c9-bb6d-4fe3-9bae-fa61f672e41b -f /home/runner/work/_temp/59ab7592-15d4-4686-b069-09bba1983231
sccache extracted to: /home/runner/work/_temp/77bc32c9-bb6d-4fe3-9bae-fa61f672e41b
sccache cached to: /opt/hostedtoolcache/sccache/0.15.0/x64
Run set -euo pipefail
  set -euo pipefail
  uv run --script "$GITHUB_ACTION_PATH/src/main.py"
  shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0}
  env:
    BIN_NAME: netsuke
    VERSION: 0.1.0
    MAN_ARCH: amd64
    UV_CACHE_DIR: /home/runner/work/_temp/setup-uv-cache
    RBR_TOOLCHAIN: 1.89.0
    CARGO_INCREMENTAL: 0
    CARGO_PROFILE_DEV_DEBUG: 0
    CARGO_TERM_COLOR: always
    RUST_BACKTRACE: short
    RUSTFLAGS: -D warnings
    CARGO_UNSTABLE_SPARSE_REGISTRY: true
    CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
    SCCACHE_PATH: /opt/hostedtoolcache/sccache/0.15.0/x64/sccache
    ACTIONS_CACHE_SERVICE_V2: on
    ACTIONS_RESULTS_URL: https://results-receiver.actions.githubusercontent.com/
    ACTIONS_RUNTIME_TOKEN: ***
    RBR_TARGET: x86_64-unknown-linux-gnu
    RBR_MANIFEST_PATH: Cargo.toml
    RBR_FEATURES: 
Installed 11 packages in 12ms
$ /home/runner/.cargo/bin/rustup toolchain list
$ /home/runner/.cargo/bin/rustup target add --toolchain 1.89.0-x86_64-unknown-linux-gnu x86_64-unknown-linux-gnu
Installing cross (not found)...
$ /home/runner/.cargo/bin/cargo install cross --locked --version 0.2.5
$ /home/runner/.cargo/bin/cross --version
$ /usr/bin/docker info
$ /usr/bin/podman info
$ /usr/bin/podman info --format {{json .Host.Security}}
Warning:  podman missing CAP_SYS_ADMIN; treating runtime as unavailable
Building with cross (0.2.5)
$ cross build --manifest-path Cargo.toml --release --target x86_64-unknown-linux-gnu
Run set -euo pipefail
  set -euo pipefail
  case "x86_64-unknown-linux-gnu" in
    x86_64-unknown-linux-*)
      os=linux
      arch=amd64
      ;;
    x86_64-unknown-illumos)
      os=illumos
      arch=amd64
      ;;
    aarch64-unknown-linux-*)
      os=linux
      arch=arm64
      ;;
    i686-unknown-linux-*)
      os=linux
      arch=i386
      ;;
    armv7-unknown-linux-gnueabihf|arm-unknown-linux-gnueabihf|armv7-unknown-linux-musleabihf|arm-unknown-linux-musleabihf)
      os=linux
      arch=armhf
      ;;
    riscv64*-unknown-linux-*)
      os=linux
      arch=riscv64
      ;;
    powerpc64le-unknown-linux-*|ppc64le-unknown-linux-*)
      os=linux
      arch=ppc64el
      ;;
    *)
      echo "::error:: unsupported target x86_64-unknown-linux-gnu"
      exit 1
      ;;
  esac
  mkdir -p "dist/netsuke_${os}_${arch}"
  bin_src="target/x86_64-unknown-linux-gnu/release/netsuke"
  if [[ ! -f "${bin_src}" ]]; then
    echo "::error:: binary not found at ${bin_src}"
    exit 1
  fi
  stable_man_path="target/generated-man/x86_64-unknown-linux-gnu/release/netsuke.1"
  man_path="${stable_man_path}"
  if [[ ! -f "${man_path}" ]]; then
    man_matches=()
    while IFS= read -r -d $'\0' _match; do
      man_matches+=("$_match")
    done < <(
      find "target/x86_64-unknown-linux-gnu/release/build" \
        -path "*/out/netsuke.1" \
Error:  man page not found at target/generated-man/x86_64-unknown-linux-gnu/release/netsuke.1 or under target/x86_64-unknown-linux-gnu/release/build/*/out/
Error: Process completed with exit code 1.

@leynos
Copy link
Copy Markdown
Owner

leynos commented May 8, 2026

@coderabbitai Please investigate the cause of the following issue using codegraph exploration and research, identify a fix and provide an AI coding agent prompt for the fix:

Run scripts/generate-release-help.sh "x86_64-pc-windows-msvc" "netsuke" "target/orthohelp/x86_64-pc-windows-msvc/release"
  scripts/generate-release-help.sh "x86_64-pc-windows-msvc" "netsuke" "target/orthohelp/x86_64-pc-windows-msvc/release"
  shell: C:\Program Files\Git\bin\bash.EXE --noprofile --norc -e -o pipefail {0}
  env:
    BIN_NAME: netsuke
    VERSION: 0.1.0
    MAN_ARCH: unknown
    UV_TOOL_BIN_DIR: D:\a\_temp\uv-tool-bin-dir
    UV_TOOL_DIR: D:\a\_temp\uv-tool-dir
    UV_CACHE_DIR: D:\a\_temp\setup-uv-cache
    RBR_TOOLCHAIN: 1.89.0
    CARGO_INCREMENTAL: 0
    CARGO_PROFILE_DEV_DEBUG: 0
    CARGO_TERM_COLOR: always
    RUST_BACKTRACE: short
    RUSTFLAGS: -D warnings
    CARGO_UNSTABLE_SPARSE_REGISTRY: true
    CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
    SCCACHE_PATH: C:\hostedtoolcache\windows\sccache\0.15.0\x64/sccache
    ACTIONS_CACHE_SERVICE_V2: on
    ACTIONS_RESULTS_URL: https://results-receiver.actions.githubusercontent.com/
    ACTIONS_RUNTIME_TOKEN: ***
Error: BridgeBuildFailure { status: 101, message: "\u{1b}[1m\u{1b}[32m    Updating\u{1b}[0m crates.io index\n\u{1b}[1m\u{1b}[32m     Locking\u{1b}[0m 287 packages to latest Rust 1.89.0 compatible versions\n\u{1b}[1m\u{1b}[36m      Adding\u{1b}[0m generic-array v0.14.7 \u{1b}[1m\u{1b}[33m(available: v0.14.9)\u{1b}[0m\n\u{1b}[1m\u{1b}[32m Downloading\u{1b}[0m crates ...\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m crypto-common v0.1.7\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m anstyle-query v1.1.5\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m winapi-util v0.1.11\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m fastrand v2.4.1\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m zmij v1.0.21\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m zerovec-derive v0.11.3\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m zerotrie v0.2.4\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m typenum v1.20.0\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m winnow v1.0.2\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m unicode-width v0.2.2\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m minijinja v2.19.0\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m libc v0.2.186\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m url v2.5.8\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m zerovec v0.11.6\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m winnow v0.7.15\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m webpki-roots v1.0.7\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m time v0.3.47\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m tracing-subscriber v0.3.23\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m syn v2.0.117\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m tracing v0.1.44\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m time-macros v0.2.27\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m yoke-derive v0.8.2\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m find-msvc-tools v0.1.9\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m clap v4.6.1\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m anstream v1.0.0\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m rustls v0.23.40\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m icu_properties_data v2.2.0\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m serde_json v1.0.149\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m memchr v2.8.0\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m icu_normalizer_data v2.2.0\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m hashbrown v0.15.5\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m clap_builder v4.6.0\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m hashbrown v0.17.0\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m cc v1.2.61\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m tracing-core v0.1.36\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m toml v0.9.12+spec-1.1.0\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m ryu v1.0.23\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m rustls-webpki v0.103.13\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m rustls-pki-types v1.14.1\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m log v0.4.29\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m indexmap v2.14.0\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m icu_provider v2.2.0\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m icu_properties v2.2.0\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m icu_locale_core v2.2.0\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m icu_collections v2.2.0\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m flate2 v1.1.9\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m console v0.16.3\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m backtrace v0.3.76\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m yoke v0.8.2\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m unicode-ident v1.0.24\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m tracing-attributes v0.1.31\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m tinystr v0.8.3\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m tempfile v3.27.0\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m semver v1.0.28\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m proc-macro2 v1.0.106\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m pin-project-lite v0.2.17\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m owo-colors v4.3.0\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m once_cell v1.21.4\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m nu-ansi-term v0.50.3\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m lru v0.16.4\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m deranged v0.5.8\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m clap_derive v4.6.1\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m camino v1.2.2\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m bitflags v2.11.1\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m anstyle v1.0.14\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m writeable v0.6.3\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m toml_writer v1.1.1+spec-1.1.0\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m toml_parser v1.1.2+spec-1.1.0\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m thiserror v2.0.18\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m terminal_size v0.4.4\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m smallvec v2.0.0-alpha.12\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m simd-adler32 v0.3.9\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m serde_json_canonicalizer v0.3.2\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m self_cell v1.2.2\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m rustc-demangle v0.1.27\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m potential_utf v0.1.5\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m litemap v0.8.2\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m ipnet v2.12.0\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m idna_adapter v1.2.2\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m getrandom v0.2.17\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m anyhow v1.0.102\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m zerofrom-derive v0.1.7\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m zerofrom v0.1.7\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m time-core v0.1.8\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m supports-hyperlinks v3.2.0\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m rustc-hash v2.1.2\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m icu_normalizer v2.2.0\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m anstyle-parse v1.0.0\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m anstyle-wincon v3.0.11\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m thiserror-impl v2.0.18\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m serde_spanned v1.1.1\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m num-conv v0.2.1\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m itoa v1.0.18\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m getrandom v0.4.2\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m colorchoice v1.0.5\n\u{1b}[1m\u{1b}[32m  Downloaded\u{1b}[0m clap_lex v1.1.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m proc-macro2 v1.0.106\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m unicode-ident v1.0.24\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m quote v1.0.45\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m windows-link v0.2.1\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m serde_core v1.0.228\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m cfg-if v1.0.4\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m version_check v0.9.5\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m stable_deref_trait v1.2.1\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m windows-sys v0.61.2\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m proc-macro-hack v0.5.20+deprecated\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m equivalent v1.0.2\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m syn v2.0.117\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m serde v1.0.228\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m hashbrown v0.17.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m once_cell v1.21.4\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m windows_x86_64_msvc v0.52.6\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m once_cell_polyfill v1.70.2\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m anstyle v1.0.14\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m parking_lot_core v0.9.12\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m memchr v2.8.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m utf8parse v0.2.2\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m winnow v0.7.15\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m smallvec v1.15.1\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m anstyle-parse v1.0.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m windows-targets v0.52.6\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m proc-macro2-diagnostics v0.10.1\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m zmij v1.0.21\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m is_terminal_polyfill v1.70.2\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m colorchoice v1.0.5\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m getrandom v0.4.2\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m toml_write v0.1.2\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m synstructure v0.13.2\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m option-ext v0.2.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m io-lifetimes v2.0.4\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m windows_x86_64_msvc v0.48.5\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m windows-sys v0.59.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m heck v0.5.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m scopeguard v1.2.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m itoa v1.0.18\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m thiserror v2.0.18\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m yansi v1.0.1\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m rustc-hash v2.1.2\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m type-map v0.5.1\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m lock_api v0.4.14\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m uncased v0.9.10\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m clap_lex v1.1.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m shlex v1.3.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m fastrand v2.4.1\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m strsim v0.11.1\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m find-msvc-tools v0.1.9\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m displaydoc v0.2.5\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m zerofrom-derive v0.1.7\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m yoke-derive v0.8.2\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m zerovec-derive v0.11.3\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m tinystr v0.8.3\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m unic-langid-impl v0.9.6\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m zerofrom v0.1.7\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m serde_derive v1.0.228\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m unic-langid-macros-impl v0.9.6\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m yoke v0.8.2\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m thiserror-impl v2.0.18\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m zerovec v0.11.6\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m unic-langid-macros v0.9.6\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m io-extras v0.18.4\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m litemap v0.8.2\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m writeable v0.6.3\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m unic-langid v0.9.6\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m zerotrie v0.2.4\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m potential_utf v0.1.5\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m icu_locale_core v2.2.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m cc v1.2.61\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m pear_codegen v0.2.9\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m windows-targets v0.48.5\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m indexmap v2.14.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m figment v0.10.19\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m icu_properties_data v2.2.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m bitflags v2.11.1\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m cap-primitives v3.4.5\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m utf8_iter v1.0.4\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m icu_normalizer_data v2.2.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m inlinable_string v0.1.15\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m camino v1.2.2\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m pear v0.2.9\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m serde_spanned v0.6.9\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m toml_datetime v0.6.11\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m icu_collections v2.2.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m winx v0.36.4\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m ring v0.17.14\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m windows-sys v0.48.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m icu_provider v2.2.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m fluent-syntax v0.12.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m fs-set-times v0.20.3\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m clap_derive v4.6.1\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m tracing-attributes v0.1.31\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m anstyle-wincon v3.0.11\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m anstyle-query v1.1.5\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m generic-array v0.14.7\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m pin-project-lite v0.2.17\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m zeroize v1.8.2\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m maybe-owned v0.3.4\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m ambient-authority v0.0.2\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m self_cell v1.2.2\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m cap-std v3.4.5\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m ipnet v2.12.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m winnow v1.0.2\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m dirs-sys v0.4.1\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m toml_parser v1.1.2+spec-1.1.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m rustls-pki-types v1.14.1\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m anstream v1.0.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m toml_edit v0.22.27\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m serde_spanned v1.1.1\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m toml_datetime v0.7.5+spec-1.1.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m typenum v1.20.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m serde_json v1.0.149\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m toml_writer v1.1.1+spec-1.1.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m toml v0.9.12+spec-1.1.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m toml v0.8.23\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m parking_lot v0.12.5\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m icu_normalizer v2.2.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m icu_properties v2.2.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m clap_builder v4.6.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m dirs v5.0.1\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m intl-memoizer v0.5.3\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m fluent-langneg v0.13.1\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m intl_pluralrules v7.0.2\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m ortho_config_macros v0.8.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m clap-dispatch v0.1.1\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m tempfile v3.27.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m dirs-sys v0.5.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m tracing-core v0.1.36\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m getrandom v0.2.17\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m dunce v1.0.5\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m untrusted v0.9.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m foldhash v0.1.5\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m unicode-width v0.2.2\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m autocfg v1.5.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m crc32fast v1.5.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m libc v0.2.186\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m thiserror v1.0.69\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m log v0.4.29\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m num-traits v0.2.19\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m hashbrown v0.15.5\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m tracing v0.1.44\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m clap v4.6.1\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m directories v6.0.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m idna_adapter v1.2.2\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m fluent-bundle v0.16.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m thiserror-impl v1.0.69\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m rustc-demangle v0.1.27\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m portable-atomic v1.13.1\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m simd-adler32 v0.3.9\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m owo-colors v4.3.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m adler2 v2.0.1\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m rustls v0.23.40\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m percent-encoding v2.3.2\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m miniz_oxide v0.8.9\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m form_urlencoded v1.2.2\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m backtrace v0.3.76\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m ortho_config v0.8.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m rustls-webpki v0.103.13\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m idna v1.1.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m hashlink v0.10.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m crypto-common v0.1.7\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m block-buffer v0.10.4\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m webpki-roots v1.0.7\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m winapi-util v0.1.11\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m subtle v2.6.1\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m is_ci v1.2.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m arraydeque v0.5.1\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m powerfmt v0.2.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m time-core v0.1.8\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m unicode-linebreak v0.1.5\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m base64 v0.22.1\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m anyhow v1.0.102\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m encode_unicode v1.0.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m lazy_static v1.5.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m allocator-api2 v0.2.21\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m num-conv v0.2.1\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m foldhash v0.2.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m console v0.16.3\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m time-macros v0.2.27\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m hashbrown v0.16.1\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m sharded-slab v0.1.7\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m textwrap v0.16.2\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m deranged v0.5.8\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m saphyr-parser v0.0.6\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m supports-color v3.0.2\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m same-file v1.0.6\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m webpki-roots v0.26.11\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m netsuke v0.1.0 (D:\\a\\netsuke\\netsuke)\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m digest v0.10.7\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m flate2 v1.1.9\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m url v2.5.8\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m backtrace-ext v0.2.1\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m tracing-log v0.2.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m miette-derive v7.6.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m terminal_size v0.4.4\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m nu-ansi-term v0.50.3\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m thread_local v1.1.9\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m nohash-hasher v0.2.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m ryu-js v1.0.2\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m cpufeatures v0.2.17\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m supports-hyperlinks v3.2.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m either v1.15.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m unit-prefix v0.5.2\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m unicode-width v0.1.14\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m supports-unicode v3.0.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m memo-map v0.3.3\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m smallvec v2.0.0-alpha.12\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m ryu v1.0.23\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m minijinja v2.19.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m miette v7.6.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m serde-saphyr v0.0.6\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m itertools v0.12.1\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m indicatif v0.18.4\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m serde_json_canonicalizer v0.3.2\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m sha2 v0.10.9\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m tracing-subscriber v0.3.23\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m ureq v2.12.1\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m time v0.3.47\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m walkdir v2.5.0\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m lru v0.16.4\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m semver v1.0.28\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m glob v0.3.3\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m ninja_env v0.1.0 (D:\\a\\netsuke\\netsuke\\ninja_env)\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m wait-timeout v0.2.1\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m sys-locale v0.3.2\n\u{1b}[1m\u{1b}[32m   Compiling\u{1b}[0m shell-quote v0.7.2\n\u{1b}[0m\u{1b}[1m\u{1b}[38;5;9merror\u{1b}[0m\u{1b}[0m\u{1b}[1m\u{1b}[38;5;15m: use of deprecated method `minijinja::Template::<'env, 'source>::eval_to_state`: use render_captured instead\u{1b}[0m\n\u{1b}[0m   \u{1b}[0m\u{1b}[0m\u{1b}[1m\u{1b}[38;5;14m--> \u{1b}[0m\u{1b}[0mD:\\a\\netsuke\\netsuke\\src\\manifest\\jinja_macros\\cache.rs:132:30\u{1b}[0m\n\u{1b}[0m    \u{1b}[0m\u{1b}[0m\u{1b}[1m\u{1b}[38;5;14m|\u{1b}[0m\n\u{1b}[0m\u{1b}[1m\u{1b}[38;5;14m132\u{1b}[0m\u{1b}[0m \u{1b}[0m\u{1b}[0m\u{1b}[1m\u{1b}[38;5;14m|\u{1b}[0m\u{1b}[0m \u{1b}[0m\u{1b}[0m        let state = template.eval_to_state(()).with_context(|| {\u{1b}[0m\n\u{1b}[0m    \u{1b}[0m\u{1b}[0m\u{1b}[1m\u{1b}[38;5;14m|\u{1b}[0m\u{1b}[0m                              \u{1b}[0m\u{1b}[0m\u{1b}[1m\u{1b}[38;5;9m^^^^^^^^^^^^^\u{1b}[0m\n\u{1b}[0m    \u{1b}[0m\u{1b}[0m\u{1b}[1m\u{1b}[38;5;14m|\u{1b}[0m\n\u{1b}[0m    \u{1b}[0m\u{1b}[0m\u{1b}[1m\u{1b}[38;5;14m= \u{1b}[0m\u{1b}[0m\u{1b}[1m\u{1b}[38;5;15mnote\u{1b}[0m\u{1b}[0m: `-D deprecated` implied by `-D warnings`\u{1b}[0m\n\u{1b}[0m    \u{1b}[0m\u{1b}[0m\u{1b}[1m\u{1b}[38;5;14m= \u{1b}[0m\u{1b}[0m\u{1b}[1m\u{1b}[38;5;15mhelp\u{1b}[0m\u{1b}[0m: to override `-D warnings` add `#[allow(deprecated)]`\u{1b}[0m\n\n\u{1b}[1m\u{1b}[31merror\u{1b}[0m\u{1b}[1m:\u{1b}[0m could not compile `netsuke` (lib) due to 1 previous error\n" }
Error: Process completed with exit code 1.

@coderabbitai

This comment was marked as resolved.

@coderabbitai

This comment was marked as resolved.

@leynos
Copy link
Copy Markdown
Owner

leynos commented May 8, 2026

@coderabbitai will the clap_mangen flow still be supported after this change? If not, please ensure that the instructions give the option of using the clap_mangen flow where cargo orthohelp is not yet available.

## Fix: remove embedded man-page discovery from `rust-build-release` in `leynos/shared-actions`

### Context

The Netsuke release workflow (`build-and-package.yml`) migrated from `clap_mangen`
(which wrote to `target/generated-man/<target>/release/`) to `cargo-orthohelp`
(which writes to `target/orthohelp/<target>/release/man/man1/`). `build.rs` no
longer generates man pages.

The composite action `leynos/shared-actions/.github/actions/rust-build-release`
at the commit currently pinned in `build-and-package.yml` contains an inline
shell step — executed immediately after `cross build` — that searches for the
man page at the OLD `target/generated-man/` and Cargo `OUT_DIR` paths. Because
neither exists any more, the step fails with:

```
Error:  man page not found at target/generated-man/x86_64-unknown-linux-gnu/release/netsuke.1
        or under target/x86_64-unknown-linux-gnu/release/build/*/out/
```

This failure occurs **before** the workflow's `Generate release help` step runs,
so the new `target/orthohelp/…/man/man1/netsuke.1` is never created in time.

### Required changes

#### 1. `leynos/shared-actions/.github/actions/rust-build-release/action.yml`
   (or whichever file within that composite action holds the inline shell step)

Locate the shell step that:
- constructs `stable_man_path="target/generated-man/<target>/release/<bin>.1"`
- falls back to searching `target/<target>/release/build/*/out/`
- errors out with "man page not found"

**Remove the entire man-page discovery block from this step.** The composite
action's responsibility is to produce the release binary. Man-page location,
staging, and validation are the workflow's responsibility (via
`generate-release-help.sh` and `stage-release-artefacts`).

If the step also copies the man page to a `dist/` directory or exports a
`man-path` output, remove that behaviour too. Callers that need a staged
man-page path must use `stage-release-artefacts`.

After removal the step should only:
- identify `os` and `arch` from the target triple
- verify the release binary exists at `target/<target>/release/<bin>`
- create the `dist/<bin>_<os>_<arch>/` staging directory
- copy the binary into it

#### 2. `leynos/netsuke/.github/workflows/build-and-package.yml`

Update the SHA pin on every `uses:` line that references
`leynos/shared-actions/.github/actions/rust-build-release` (and,
if also updated in the same shared-actions commit,
`stage-release-artefacts`, `linux-packages`, `windows-package`, and
`macos-package`) to the new commit hash produced by step 1.

Keep all other workflow structure (generate-release-help step order,
`stage-release-artefacts` inputs) unchanged.

#### 3. Validate in `leynos/shared-actions`

In `leynos/shared-actions`, confirm there are no other composite actions or
reusable workflows that reference `target/generated-man` or
`target/<target>/release/build/*/out/` as a man-page source. Remove any
remaining references.

#### 4. Validate in `leynos/netsuke`

Run the following gates sequentially after updating the pin:

```bash
make check-fmt 2>&1 | tee /tmp/check-fmt-shared-actions-pin.out
make markdownlint 2>&1 | tee /tmp/markdownlint-shared-actions-pin.out
make lint 2>&1 | tee /tmp/lint-shared-actions-pin.out
make test 2>&1 | tee /tmp/test-shared-actions-pin.out
```

All four must pass. In particular, confirm that the tests in
`tests/workflow_build_and_package.rs` that assert `target/generated-man` is
absent from the workflow still pass, and that the contract tests asserting
`"target/orthohelp/${{ inputs.target }}/release"` is present still pass.

codescene-delta-analysis[bot]

This comment was marked as outdated.

@coderabbitai

This comment was marked as resolved.

codescene-delta-analysis[bot]

This comment was marked as outdated.

codescene-delta-analysis[bot]

This comment was marked as outdated.

@leynos
Copy link
Copy Markdown
Owner

leynos commented May 10, 2026

@coderabbitai Please suggest a fix for this issue and supply a prompt for an AI coding agent to enable it to apply the fix. Include the file and symbol names indicated in the issue at the head of your response.

tests/workflow_build_and_package.rs

Comment on lines +41 to +64

fn rust_build_release_step_blocks(contents: &str) -> Vec<String> {
    let mut blocks = Vec::new();
    let mut current_block = Vec::new();

    for line in contents.lines() {
        if line.starts_with("      - ") && !current_block.is_empty() {
            let block = current_block.join("\n");
            if block.contains("rust-build-release@") {
                blocks.push(block);
            }
            current_block.clear();
        }
        current_block.push(line);
    }

    if !current_block.is_empty() {
        let block = current_block.join("\n");
        if block.contains("rust-build-release@") {
            blocks.push(block);
        }
    }

    blocks
}

❌ New issue: Bumpy Road Ahead
rust_build_release_step_blocks has 2 blocks with nested conditional logic. Any nesting of 2 or deeper is considered. Threshold is 2 blocks per function

@coderabbitai

This comment was marked as resolved.

@leynos
Copy link
Copy Markdown
Owner

leynos commented May 10, 2026

@coderabbitai are the cargo orthohelp generated manpage and MAML help correctly bundled in the Linux .deb/.rpm packages and Windows .msi respectively?

@coderabbitai

This comment was marked as resolved.

codescene-delta-analysis[bot]

This comment was marked as outdated.

codescene-delta-analysis[bot]

This comment was marked as outdated.

@leynos
Copy link
Copy Markdown
Owner

leynos commented May 12, 2026

@coderabbitai re:

Windows MSI — MAML help

By the execplan's own decision, MAML is not bundled in the MSI. The windows-package shared action accepts no PowerShell help inputs. Instead, MAML files are intended as sidecar release artefacts uploaded via ${{ steps.stage_paths.outputs.artifact_dir }}. That path is also sourced from the missing release-staging.toml, so the MAML sidecars are likewise not reaching the release artefacts.

Is this something we should add to shared-actions? If so, please provide a detailed agent prompt for support of this for an agent working in the leynos/shared-actions repository.

@coderabbitai

This comment was marked as resolved.

leynos added 11 commits May 17, 2026 20:28
Expose `make typecheck` as a warning-denying `cargo check` wrapper across
all targets and features. This gives the post-rebase validation set a
stable Makefile target alongside `check-fmt`, `test`, and `lint`.

Record the rebase result and validation-target decision in the
cargo-orthohelp ExecPlan.
Update the orthohelp ExecPlan with the latest successful rebase onto
`origin/main`, including the absence of conflicts and the new config
precedence work now present on the branch.

Remove the extra blank line in the users guide so the rebased branch passes
Markdown linting.
Call `cargo-orthohelp` from the release-help script instead of using Cargo
external subcommand dispatch, which injects an unsupported `orthohelp`
positional argument.

Update the release-help script tests to fake `cargo-orthohelp` directly and
record the invocation decision in the orthohelp ExecPlan.
Use `render_captured` for manifest macro state retention so newer
MiniJinja releases compile cleanly with warnings denied.
Keep manifest macro examples and safety notes aligned with
`Template::render_captured`, which replaces the deprecated
`eval_to_state` API in MiniJinja.

Avoid an unfulfilled Clippy expectation on the macro state guard so the
strict warning policy remains clean.
Pin Netsuke workflows to the shared-actions commit that adds `skip-man-page-discovery` and pass the opt-out to the `rust-build-release` call.

Extend the build-and-package workflow test so every `rust-build-release` step must opt out of embedded man-page discovery while release help remains generated under `target/orthohelp`.
Pin every `leynos/shared-actions` workflow reference to
`67025f53e79b821327d2f4d48a2af488cca42803` so CI, packaging, and release
jobs use the same shared action revision.
Move the repeated rust-build-release step block flush logic into a small
helper so the workflow contract test keeps the same behaviour with less
nested conditional logic.
Add the release staging configuration consumed by the shared staging
action so Linux and macOS targets publish the generated man page and
Windows targets upload PowerShell help sidecars.

Teach GoReleaser to gzip the orthohelp man page when a pre-staged copy
is not already present, and extend workflow/staging contract tests for
the generated help outputs.
Update shared-action pins to the revision that exposes
`powershell_help_dir` from `stage-release-artefacts`.

Wire Netsuke's Windows staging through `ps-module-name` and stage the
PowerShell sidecar module at the module directory root so downstream steps
can consume the new output without passing it into `windows-package`.
@lodyai lodyai Bot force-pushed the cargo-orthohelp-adoption branch from f79ef8f to f513162 Compare May 17, 2026 18:30
codescene-delta-analysis[bot]

This comment was marked as outdated.

@leynos
Copy link
Copy Markdown
Owner

leynos commented May 19, 2026

@coderabbitai okay, leynos/shared-actions now has the requested change at SHA e4c6b0e200a057edf927c45c298e7ddf229b3934. What now?

@coderabbitai

This comment was marked as resolved.

Update the reusable build-and-package workflow for the shared-actions
release artefact staging contract at
`e4c6b0e200a057edf927c45c298e7ddf229b3934`.

Generate release help with the explicit `cargo-orthohelp` script path,
pass staged artefact outputs through packaging, and keep every
shared-actions workflow call on the same approved pin so the workflow pin
contract remains coherent.

Clean up Markdown lint defects in the release-help documentation so the
required documentation gate passes with the workflow change.
@leynos leynos marked this pull request as ready for review May 19, 2026 23:23
Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @leynos, you have reached your weekly rate limit of 2500000 diff characters.

Please try again later or upgrade to continue using Sourcery

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f513162c16

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .goreleaser.yaml Outdated
set -euo pipefail
# Accept a pre-staged gzip (legacy) or produce one from the orthohelp output.
if [ ! -s dist/netsuke.1.gz ]; then
SRC="target/orthohelp/${GOOS}-${GOARCH}/release/man/man1/netsuke.1"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Resolve orthohelp source from Rust target triples

When dist/netsuke.1.gz is absent, this fallback looks under target/orthohelp/${GOOS}-${GOARCH}/..., but the release workflow and scripts/generate-release-help.sh write help files under Rust target-triple directories (for example target/orthohelp/x86_64-unknown-linux-gnu/release/...). In runs that rely on this fallback, GoReleaser will fail with a missing manpage error even though the man page was generated, because it is checking the wrong path shape.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@coderabbitai Has this now been resolved in the latest commit?

Use codegraph analysis to determine your answer.

If this comment is now resolved, please mark it as such using the API. Otherwise, please provide an AI agent prompt for the remaining work to be done to address this comment.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check the actual path format written by generate-release-help.sh
echo "=== scripts/generate-release-help.sh ==="
cat scripts/generate-release-help.sh

echo ""
echo "=== .goreleaser.yaml before hook ==="
head -25 .goreleaser.yaml

echo ""
echo "=== release.yml matrix target_key values ==="
grep -n "target_key\|stage-target\|GOOS\|GOARCH\|orthohelp" .github/workflows/release.yml

echo ""
echo "=== build-and-package.yml orthohelp paths ==="
grep -n "orthohelp\|target_key\|stage-target\|GOOS\|GOARCH" .github/workflows/build-and-package.yml

Length of output: 4520


@leynos — No, this has not been resolved in the latest commit.

Root cause confirmed: build-and-package.yml (line 98) writes orthohelp output to target/orthohelp/${{ inputs.target }}/release, where inputs.target is the full Rust target triple (e.g. x86_64-unknown-linux-gnu). The GoReleaser hook, however, constructs the fallback path as target/orthohelp/${GOOS}-${GOARCH}/release/..., where GoReleaser expands those variables to its own format (e.g. linux/amd64), yielding target/orthohelp/linux-amd64/release/.... The two path shapes are irreconcilable without an explicit mapping.


AI agent prompt:

Fix the GoReleaser before-hook fallback path in `.goreleaser.yaml` to use the Rust
target-triple directory layout that `scripts/generate-release-help.sh` actually
writes to, rather than the `${GOOS}-${GOARCH}` format that GoReleaser interpolates.

## Problem

The current hook constructs:

    SRC="target/orthohelp/${GOOS}-${GOARCH}/release/man/man1/netsuke.1"

GoReleaser expands `${GOOS}` and `${GOARCH}` as its own OS/arch tokens (e.g.
`linux`/`amd64`), producing `target/orthohelp/linux-amd64/release/...`.

`scripts/generate-release-help.sh` writes to the path supplied via `--out-dir`,
which `.github/workflows/build-and-package.yml` sets to:

    target/orthohelp/${{ inputs.target }}/release

where `inputs.target` is the full Rust target triple, e.g.
`x86_64-unknown-linux-gnu`.

These two path shapes are incompatible; the fallback will always fail.

## Required change

Replace the single `SRC=` assignment with an explicit GOOS/GOARCH → Rust target
triple lookup table covering every target in the GoReleaser matrix (see the
`goos`/`goarch` and `ignore` stanzas in `.goreleaser.yaml`):

| GOOS    | GOARCH | Rust triple                    |
|---------|--------|--------------------------------|
| linux   | amd64  | x86_64-unknown-linux-gnu       |
| linux   | arm64  | aarch64-unknown-linux-gnu      |
| darwin  | amd64  | x86_64-apple-darwin            |
| darwin  | arm64  | aarch64-apple-darwin           |
| freebsd | amd64  | x86_64-unknown-freebsd         |

The `freebsd`/`arm64` combination is already excluded by the `ignore` stanza, so
no entry is needed for it.

Apply a diff similar to the following to `.goreleaser.yaml`:

```diff
-          SRC="target/orthohelp/${GOOS}-${GOARCH}/release/man/man1/netsuke.1"
+          case "${GOOS}-${GOARCH}" in
+            linux-amd64)   RUST_TARGET="x86_64-unknown-linux-gnu" ;;
+            linux-arm64)   RUST_TARGET="aarch64-unknown-linux-gnu" ;;
+            darwin-amd64)  RUST_TARGET="x86_64-apple-darwin" ;;
+            darwin-arm64)  RUST_TARGET="aarch64-apple-darwin" ;;
+            freebsd-amd64) RUST_TARGET="x86_64-unknown-freebsd" ;;
+            *)
+              echo "::error title=Manpage missing::No Rust target triple known for ${GOOS}-${GOARCH}."
+              exit 1
+              ;;
+          esac
+          SRC="target/orthohelp/${RUST_TARGET}/release/man/man1/netsuke.1"
```

## Tests to update / add

1. **`tests/workflow_build_and_package.rs`** — add (or extend) an assertion that
   the `.goreleaser.yaml` before hook does **not** reference the raw
   `${GOOS}-${GOARCH}` pattern in an `orthohelp` path, and does contain at least
   one of the expected Rust target triples (e.g. `x86_64-unknown-linux-gnu`).

2. **`tests/release_help_script_tests.rs`** — no changes needed; that suite tests
   the shell script, not the GoReleaser hook.

## Validation

After applying the change:

```bash
grep -E '\$\{GOOS\}-\$\{GOARCH\}' .goreleaser.yaml
# Must produce no output (the raw pattern must be gone from orthohelp paths).

grep 'x86_64-unknown-linux-gnu' .goreleaser.yaml
# Must match the lookup table entry.

cargo test --test workflow_build_and_package
```

@coderabbitai coderabbitai Bot added the Roadmap label May 19, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/release.yml (1)

116-139: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Declare explicit least-privilege permissions for reusable build jobs.

Set explicit permissions for this caller job instead of inheriting defaults. Line 116 currently leaves token scopes implicit, which triggers the excessive-permissions warning and broadens risk unnecessarily.

🔧 Proposed fix
   build-linux:
     needs: metadata
+    permissions:
+      contents: read
     strategy:
       matrix:
         include:

Apply the same pattern to build-windows and build-macos in this workflow.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release.yml around lines 116 - 139, Add an explicit
minimal permissions block to the build-linux job (named build-linux) instead of
inheriting defaults: declare only the GitHub token scopes the reusable workflow
needs (for example contents: read, packages: write, id-token: write and actions:
read) and remove implicit broad scopes; add the same permissions block to the
other build jobs (build-windows and build-macos) that call uses:
./.github/workflows/build-and-package.yml so the reusable workflow runs with
least privilege.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.goreleaser.yaml:
- Around line 11-18: The current .goreleaser.yaml uses the literal
${GOOS}-${GOARCH} to build SRC which doesn't match the Rust-generated help
directories; update the SRC resolution to map GOOS/GOARCH tuples to the
corresponding Rust target triples produced by scripts/generate-release-help.sh
(e.g., map linux-amd64 -> x86_64-unknown-linux-gnu, linux-arm64 ->
aarch64-unknown-linux-gnu, darwin-amd64 -> x86_64-apple-darwin, darwin-arm64 ->
aarch64-apple-darwin, etc.), and then use that mapped TRIPLE variable when
constructing SRC; keep a fallback that checks both the mapped path and the
original dist/netsuke.1.gz so the script still fails cleanly if neither is
found.

In `@docs/developers-guide.md`:
- Around line 29-31: Update the documentation line that currently references the
tool as `cargo orthohelp` to the correct binary name `cargo-orthohelp`; edit the
text near the header "Release help tooling" (the sentence "Release builds
generate help artefacts explicitly with `cargo orthohelp`,") so it reads
`cargo-orthohelp` to match the PR objectives/execplan and avoid invoking Cargo
subcommand dispatch.

In `@docs/netsuke-cli-design-document.md`:
- Around line 298-300: The CLI help text contains a malformed URL punctuation
sequence "<https://netsuke.dev/docs">) — fix the punctuation in that string by
moving the closing double-quote after the closing angle bracket so it reads
"<https://netsuke.dev/docs>") (or remove the unnecessary quotes if the help text
format prefers bare angle-bracketed links); update the string in the
docs/netsuke-cli-design-document.md occurrence where the CLI help example is
defined to ensure the angle-bracketed URL and surrounding punctuation are
correctly ordered.
- Around line 290-292: Replace the incorrect tool name "cargo orthohelp" with
the correct binary name "cargo-orthohelp" wherever it appears (e.g., the
sentence that currently mentions `cargo orthohelp`), ensuring the documentation
string matches the developers' guide and execplan; search for other occurrences
of the tool name in the same doc and update them for consistency.

In `@docs/netsuke-design.md`:
- Around line 402-418: Remove the duplicated "### 2.7 Table: Netsuke Manifest
vs. Makefile" header and its subsequent Markdown table block (the entire
duplicate showing Makefile vs. Netsukefile examples including the
Variables/Macros/Rule Definition/Target Build/Readability rows), leaving only
the original table that appears later after section 2.6; ensure the duplicate
block beginning with that exact header is deleted so section numbering flows
correctly.

---

Outside diff comments:
In @.github/workflows/release.yml:
- Around line 116-139: Add an explicit minimal permissions block to the
build-linux job (named build-linux) instead of inheriting defaults: declare only
the GitHub token scopes the reusable workflow needs (for example contents: read,
packages: write, id-token: write and actions: read) and remove implicit broad
scopes; add the same permissions block to the other build jobs (build-windows
and build-macos) that call uses: ./.github/workflows/build-and-package.yml so
the reusable workflow runs with least privilege.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 8d3e1b44-d588-48cf-915d-7019fc6a6de9

📥 Commits

Reviewing files that changed from the base of the PR and between 8f3565a and f513162.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (27)
  • .github/release-staging.toml
  • .github/workflows/build-and-package.yml
  • .github/workflows/ci.yml
  • .github/workflows/netsukefile-test.yml
  • .github/workflows/release.yml
  • .goreleaser.yaml
  • Cargo.toml
  • Makefile
  • README.md
  • build.rs
  • docs/developers-guide.md
  • docs/execplans/cargo-orthohelp-adoption.md
  • docs/netsuke-cli-design-document.md
  • docs/netsuke-design.md
  • docs/users-guide.md
  • scripts/generate-release-help.sh
  • scripts/package-artifact.sh
  • src/manifest/jinja_macros/cache.rs
  • src/manifest/jinja_macros/mod.rs
  • src/manifest/tests/macros.rs
  • tests/bdd/steps/mod.rs
  • tests/bdd/steps/release_help_generation.rs
  • tests/features/release_help_generation.feature
  • tests/release_help_script_tests.rs
  • tests/release_staging_tests.rs
  • tests/workflow_build_and_package.rs
  • tests/workflow_release.rs

Comment thread .goreleaser.yaml Outdated
Comment thread docs/developers-guide.md Outdated
Comment thread docs/netsuke-cli-design-document.md Outdated
Comment thread docs/netsuke-cli-design-document.md Outdated
Comment thread docs/netsuke-design.md Outdated
Map GoReleaser `GOOS` and `GOARCH` values to the Rust target triples used
by `scripts/generate-release-help.sh` before looking up generated manual
pages.

This keeps the fallback path aligned with the release workflow output when
`dist/netsuke.1.gz` has not already been staged.
@leynos
Copy link
Copy Markdown
Owner

leynos commented May 19, 2026

@coderabbitai re:

Correct the tool name to cargo-orthohelp.

Line 31 refers to the tool as cargo orthohelp (without hyphen), but the correct binary name is cargo-orthohelp. The PR objectives and execplan clarify that cargo-orthohelp must be invoked directly because Cargo external subcommand dispatch would inject an extra orthohelp token, causing an error.

Is this something we should raise as an issue against ortho-config? If so, please draft an issue ticket and I will pass it onto the maintainer (me. lol)

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 19, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

Yes, this is worth raising as an upstream issue. The netsuke workaround (invoking cargo-orthohelp directly) is correct for now, but the tool should either:

  1. Follow the standard Cargo external subcommand protocol — wrap the top-level CLI as cargo with an orthohelp subcommand so that cargo-orthohelp orthohelp [OPTIONS] (what Cargo dispatches) and cargo orthohelp [OPTIONS] (what users type) both work; or
  2. Document explicitly that the tool must be invoked directly as cargo-orthohelp and cannot be used via cargo orthohelp.

Let me find the right repository and file it.


🏁 Script executed:

#!/bin/bash
# Find the ortho-config / cargo-orthohelp repository owned by leynos
gh repo list leynos --limit 50 --json name,description | jq '.[] | select(.name | test("ortho"; "i"))'

Length of output: 85


🏁 Script executed:

#!/bin/bash
gh issue create \
  --repo leynos/ortho-config \
  --assignee leynos \
  --title "cargo-orthohelp fails when invoked via \`cargo orthohelp\` due to Cargo external-subcommand argument injection" \
  --body "## Summary

When a user installs \`cargo-orthohelp\` and invokes it as \`cargo orthohelp [OPTIONS]\`, Cargo follows its external-subcommand protocol and executes:

\`\`\`
cargo-orthohelp orthohelp [OPTIONS]
\`\`\`

That is, Cargo injects the subcommand name (\`orthohelp\`) as the first positional argument. Because \`cargo-orthohelp\`'s top-level clap interface is \`cargo-orthohelp [OPTIONS]\` with no \`orthohelp\` subcommand, clap rejects the injected token immediately:

\`\`\`
error: unexpected argument 'orthohelp' found

Usage: cargo-orthohelp [OPTIONS]

For more information, try '--help'.
\`\`\`

This was discovered during the Netsuke \`cargo-orthohelp\` adoption (leynos/netsuke#288). The workaround applied there is to invoke \`cargo-orthohelp\` directly in CI scripts, bypassing Cargo dispatch entirely.

## Cargo external-subcommand protocol

Per the Cargo reference, \`cargo <name>\` resolves to \`cargo-<name>\` on \`PATH\` and invokes it as:

\`\`\`
cargo-<name> <name> [user-args...]
\`\`\`

The injected first argument is intentional: it allows clap-based tools to register both \`cargo <name>\` and \`cargo-<name> <name>\` as valid entry points by structuring the CLI as a \`cargo\` top-level command with a \`<name>\` subcommand.

## Remediation options

**Option A — Adopt the standard Cargo external-subcommand pattern (preferred)**

Restructure the clap \`Command\` so that the binary is named \`cargo-orthohelp\` but the top level is a \`cargo\` command with an \`orthohelp\` subcommand:

\`\`\`rust
Command::new(\"cargo\")
    .bin_name(\"cargo-orthohelp\")
    .subcommand(
        Command::new(\"orthohelp\")
            // … existing options …
    )
\`\`\`

With this structure, both \`cargo orthohelp --format man\` (via Cargo dispatch) and \`cargo-orthohelp orthohelp --format man\` (direct invocation with injected token) work correctly.

**Option B — Document direct-invocation-only requirement**

If restructuring the CLI is undesirable, document prominently in the README and \`cargo install\` instructions that \`cargo-orthohelp\` must be invoked directly:

\`\`\`sh
cargo-orthohelp --format man --out-dir target/man
\`\`\`

and that \`cargo orthohelp\` is **not** a supported invocation form.

## References

- leynos/netsuke#288 — PR where the workaround was applied
- [Cargo external subcommands reference](https://doc.rust-lang.org/cargo/reference/external-tools.html#custom-subcommands)
- [clap external subcommand example](https://docs.rs/clap/latest/clap/_derive/_cookbook/cargo_example_derive/index.html)

/cc `@leynos`"

Length of output: 77


🏁 Script executed:

#!/bin/bash
gh issue list --repo leynos/ortho-config --limit 5 --json number,title,url

Length of output: 798


@leynos: Issue filed at leynos/ortho-config#326. The assignee could not be set automatically due to a GraphQL integration permission limitation — assign it to yourself manually.

The issue documents:

  • Root cause — Cargo's external-subcommand protocol injects the subcommand name as argv[1], which clap rejects because cargo-orthohelp [OPTIONS] declares no orthohelp subcommand.
  • Option A (preferred) — Restructure the clap Command as cargoorthohelp subcommand, so both cargo orthohelp and direct cargo-orthohelp orthohelp invocations work.
  • Option B — Document that cargo-orthohelp must be invoked directly and cargo orthohelp is unsupported.
  • Backlink to this PR (#288) for context.

leynos added 3 commits May 20, 2026 01:49
Fix remaining release-help documentation references so they use the
cargo-orthohelp binary name and correct the CLI docs URL punctuation.
Add explicit least-privilege permissions to reusable release build jobs.
Update the remaining user-facing documentation to refer to
`cargo-orthohelp` consistently. The previously reported malformed URL and
duplicate-table issues are not present in the current sources, so no further
markdown edits were necessary.
Avoid the deprecated Cargo subcommand spelling in the adoption plan while
preserving the note about why release automation calls cargo-orthohelp directly.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/release-staging.toml:
- Around line 35-36: Replace hardcoded target triples in manpage source paths
with the {target} placeholder: change occurrences of source =
"target/orthohelp/aarch64-unknown-linux-gnu/release/man/man1/{bin_name}.1",
source = "target/orthohelp/x86_64-apple-darwin/release/man/man1/{bin_name}.1",
and source =
"target/orthohelp/aarch64-apple-darwin/release/man/man1/{bin_name}.1" to source
= "target/orthohelp/{target}/release/man/man1/{bin_name}.1" so all
target-specific manpage sources use the {target} template and stay consistent
with the targets table.

In @.goreleaser.yaml:
- Around line 11-22: The hook uses unset shell variables GOOS and GOARCH
(referenced in the case statement and used to set RUST_TARGET and SRC) which
will fail under set -u when run in the global before.hooks context; either
declare GOOS and GOARCH explicitly in the global env: section of
.goreleaser.yaml so they are always defined, or move this case-to-RUST_TARGET
mapping into the per-build hook (builds[].hooks.pre) where GoReleaser provides
GOOS/GOARCH, ensuring RUST_TARGET and SRC are computed only in that per-build
context.

In `@docs/ortho-config-users-guide.md`:
- Around line 995-996: The sentence "When multiple sources fail, the errors are
collected into the `Aggregate` variant so callers can inspect each individual
failure." is missing a comma before "so"; edit the docs text (the sentence
containing the `Aggregate` variant) to insert a comma before "so" so it reads
"...`Aggregate` variant, so callers can inspect each individual failure." to
conform to en-GB-oxendict grammar.

In `@README.md`:
- Around line 52-53: The sentence in the README contains a hard-coded year
("This is 2025.") which will become stale; replace that fragment with
year-agnostic wording (e.g., change "This is 2025." to "This is the modern era."
or "This is the present day.") so the promotional line (the sentence containing
"Yes, it’s just YAML. ... You deserve better.") remains evergreen.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: cdd375ef-3176-492d-ae58-a22356d6f8d5

📥 Commits

Reviewing files that changed from the base of the PR and between f513162 and 76f7039.

📒 Files selected for processing (13)
  • .github/release-staging.toml
  • .github/workflows/build-and-package.yml
  • .github/workflows/ci.yml
  • .github/workflows/netsukefile-test.yml
  • .github/workflows/release.yml
  • .goreleaser.yaml
  • README.md
  • docs/developers-guide.md
  • docs/execplans/cargo-orthohelp-adoption.md
  • docs/netsuke-cli-design-document.md
  • docs/netsuke-design.md
  • docs/ortho-config-users-guide.md
  • tests/release_staging_tests.rs

Comment on lines +35 to +36
source = "target/orthohelp/aarch64-unknown-linux-gnu/release/man/man1/{bin_name}.1"
destination = "man/man1/{bin_name}.1"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Use {target} placeholders for all target-specific manpage sources.

Eliminate hardcoded target triples in source paths. Keep path templating consistent with the target table to prevent drift during future target renames.

Patch
- source = "target/orthohelp/aarch64-unknown-linux-gnu/release/man/man1/{bin_name}.1"
+ source = "target/orthohelp/{target}/release/man/man1/{bin_name}.1"
@@
- source = "target/orthohelp/x86_64-apple-darwin/release/man/man1/{bin_name}.1"
+ source = "target/orthohelp/{target}/release/man/man1/{bin_name}.1"
@@
- source = "target/orthohelp/aarch64-apple-darwin/release/man/man1/{bin_name}.1"
+ source = "target/orthohelp/{target}/release/man/man1/{bin_name}.1"

Also applies to: 98-99, 109-110

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/release-staging.toml around lines 35 - 36, Replace hardcoded target
triples in manpage source paths with the {target} placeholder: change
occurrences of source =
"target/orthohelp/aarch64-unknown-linux-gnu/release/man/man1/{bin_name}.1",
source = "target/orthohelp/x86_64-apple-darwin/release/man/man1/{bin_name}.1",
and source =
"target/orthohelp/aarch64-apple-darwin/release/man/man1/{bin_name}.1" to source
= "target/orthohelp/{target}/release/man/man1/{bin_name}.1" so all
target-specific manpage sources use the {target} template and stay consistent
with the targets table.

Comment thread .goreleaser.yaml
Comment on lines +11 to +22
case "${GOOS}/${GOARCH}" in
linux/amd64) RUST_TARGET="x86_64-unknown-linux-gnu" ;;
linux/arm64) RUST_TARGET="aarch64-unknown-linux-gnu" ;;
darwin/amd64) RUST_TARGET="x86_64-apple-darwin" ;;
darwin/arm64) RUST_TARGET="aarch64-apple-darwin" ;;
freebsd/amd64) RUST_TARGET="x86_64-unknown-freebsd" ;;
*)
echo "::error title=Unsupported manpage target::No Rust target mapping for ${GOOS}/${GOARCH}."
exit 1
;;
esac
SRC="target/orthohelp/${RUST_TARGET}/release/man/man1/netsuke.1"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🔍 Additional research query:

`Search for GoReleaser documentation on before.hooks execution context, specifically regarding:

  1. What environment variables are available in before.hooks
  2. Whether GOOS and GOARCH are guaranteed to be set
  3. What shell options (like set -u) are applied to the hook execution
  4. Whether these variables are set by GoReleaser automatically or need to be defined by the user
    Source: Context7 for GoReleaser library documentation`

💡 Result:

Let me search for more specific documentation about before.hooks environment variables and runtime variables.Let me search for more specific information about GoReleaser's Runtime variables and build hook environment details.Based on my search results, I now have comprehensive information about GoReleaser's before.hooks execution context. Let me provide a detailed answer to your questions.

GoReleaser before.hooks Execution Context Documentation

1. Environment Variables Available in before.hooks

Global environment variables are passed down to all hooks and builds. before.hooks can access environment variables through template syntax like {{ .Env.FILE_TO_TOUCH }} and you can specify extra environment variables at the hook level using an env configuration section.

Template variables are available in hooks, including runtime GOOS and GOARCH accessible using {{ .Runtime.Goos }} and {{ .Runtime.Goarch }}.

2. GOOS and GOARCH Guarantee

For global before.hooks specifically, GOOS and GOARCH are NOT directly set as environment variables because global before hooks execute before any platform-specific build context is established. The Runtime.Goos variable is available in template conditionals like if: '{{ eq .Runtime.Goos "windows" }}', but this refers to the runtime/machine GOOS, not build targets.

For build-specific hooks (pre and post build hooks), there was a feature request to make .Os and .Arch template variables available or to actually set GOOS and GOARCH in the hook execution environments, but this applies to build hooks, not global before hooks.

3. Shell Options (like set -u)

The documentation does not explicitly specify what shell options are applied to before.hook execution. If you need to do anything more complex, it is recommended to create a shell script and call it instead of relying on inline shell commands.

4. Variable Assignment

Environment variables are set through the global env section in your .goreleaser.yaml config and are passed down to all hooks and builds, with both global environment variables and hook-level environment variables available. These are defined by the user in the configuration file, not automatically set by GoReleaser for before.hooks execution.

Important Note

Build-specific environment variables (from the builds.env section) are not available in before hooks, as before hooks execute before any build blocks are evaluated.

[::web_search::]


🌐 Web query:

GoReleaser before.hooks execution context GOOS GOARCH environment variables documentation

💡 Result:

GoReleaser “before” hooks execution context: there are two relevant “before” concepts in GoReleaser docs. 1) Global before hooks (configuration before: hooks:) - before.hooks run “before the release is started”; if any hook fails the release process is aborted. [1] - Global environment variables from the top-level env: are passed down to “all hooks and builds”, including your before hooks. [2] 2) Per-build before hooks (configuration builds[].hooks.pre:) - builds[].hooks.pre (and post) are run “for each build target” (i.e., for each OS/arch combination in a matrix). [3] - Hooks can have env: and dir:; hook env supports templates. [3] - GoReleaser exposes build details to both pre and post hooks, including .Target (example format like darwin_amd64). [3] - Environment variable inheritance/override order for hooks: global (env) -> build (builds[].env) -> hook (builds[].hooks.pre[].env / builds[].hooks.post[].env). [3] GOOS/GOARCH environment variables in that context (what’s documented) - In the sources retrieved here, the hook documentation clearly describes what’s available to hooks (template variables / build details like .Target) and how hook env inheritance works, but it does not explicitly document whether GoReleaser exports standard GOOS and GOARCH environment variables into the hook process. - What we can say with evidence: GoReleaser builds for configured goos: and goarch: combinations (and generates a matrix when multiple values are provided). [4] Best-supported answer for your question (“use GOOS/GOARCH in before.hooks”) - Don’t rely on undeclared GOOS/GOARCH being present in hook environment variables unless you verify in your environment. - Instead, use .Target (available to pre hooks) to determine which OS/arch combination the hook corresponds to. [3] - If you need explicit env vars, set them using GoReleaser’s documented env: mechanism (global env: for all hooks/builds, or builds[].env / builds[].hooks.pre[].env for narrower scope). [2][3] If you want, tell me whether you mean the global before.hooks block or builds[].hooks.pre; I can then do a second targeted search for the exact wording around GOOS/GOARCH being injected into hook commands (and cite the line if it exists).

Citations:


Define GOOS and GOARCH explicitly or move this logic to per-build hooks.

This code executes in a global before.hooks context where GOOS and GOARCH are not set as environment variables by GoReleaser. Under set -u, the hook will fail with an unset variable error. Either define these variables in the global env: section of .goreleaser.yaml, or move this target-mapping logic to per-build hooks (builds[].hooks.pre) where build context is available.

Are you using this in a global before.hooks context, or in per-build hooks (builds[].hooks.pre)? If the former, the issue is confirmed. If the latter, the fix differs.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.goreleaser.yaml around lines 11 - 22, The hook uses unset shell variables
GOOS and GOARCH (referenced in the case statement and used to set RUST_TARGET
and SRC) which will fail under set -u when run in the global before.hooks
context; either declare GOOS and GOARCH explicitly in the global env: section of
.goreleaser.yaml so they are always defined, or move this case-to-RUST_TARGET
mapping into the per-build hook (builds[].hooks.pre) where GoReleaser provides
GOOS/GOARCH, ensuring RUST_TARGET and SRC are computed only in that per-build
context.

Comment on lines +995 to +996
combined data is invalid. When multiple sources fail, the errors are collected
into the `Aggregate` variant so callers can inspect each individual failure.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Insert the missing comma in the compound sentence.

Add a comma before “so” at Line 996 to keep the sentence grammatically correct
and easier to scan.

Triage: [type:grammar] [type:docstyle]

As per coding guidelines, "Documentation must use en-GB-oxendict spelling and
grammar."

🧰 Tools
🪛 LanguageTool

[uncategorized] ~996-~996: Use a comma before ‘so’ if it connects two independent clauses (unless they are closely connected and short).
Context: ...e collected into the Aggregate variant so callers can inspect each individual fai...

(COMMA_COMPOUND_SENTENCE_2)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/ortho-config-users-guide.md` around lines 995 - 996, The sentence "When
multiple sources fail, the errors are collected into the `Aggregate` variant so
callers can inspect each individual failure." is missing a comma before "so";
edit the docs text (the sentence containing the `Aggregate` variant) to insert a
comma before "so" so it reads "...`Aggregate` variant, so callers can inspect
each individual failure." to conform to en-GB-oxendict grammar.

Comment thread README.md
Comment on lines +52 to +53
Yes, it’s just YAML. Yes, that’s a Jinja `foreach`. No, you don’t need to define
`.PHONY` or remember what `$@` means. This is 2025. You deserve better.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Remove the hard-coded year in the promotional sentence.

Replace “This is 2025.” with year-agnostic wording to prevent immediate
staleness and avoid avoidable drift in user-facing copy.

Triage: [type:docstyle]

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` around lines 52 - 53, The sentence in the README contains a
hard-coded year ("This is 2025.") which will become stale; replace that fragment
with year-agnostic wording (e.g., change "This is 2025." to "This is the modern
era." or "This is the present day.") so the promotional line (the sentence
containing "Yes, it’s just YAML. ... You deserve better.") remains evergreen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant