Skip to content

Add install-whitaker shared action - #361

Open
leynos wants to merge 3 commits into
mainfrom
install-whitaker-action
Open

Add install-whitaker shared action#361
leynos wants to merge 3 commits into
mainfrom
install-whitaker-action

Conversation

@leynos

@leynos leynos commented Jul 19, 2026

Copy link
Copy Markdown
Owner

Summary

This branch adds a reusable install-whitaker composite action based on the installation flow used by Frankie CI. It caches whitaker-installer, prefers cargo-binstall when available, falls back to cargo install --locked, and installs the Whitaker Dylint suite.

The installer version is configurable through installer-version, with 0.2.6 as the source-compatible default.

Review walkthrough

Validation

  • make check-fmt: passed
  • make typecheck: passed
  • make lint: passed
  • Focused install-whitaker tests: 4 passed
  • make test: all four new tests passed within the full suite; the repository-wide command remained non-zero with 1 unrelated failure, 948 passes, 14 skips, and 46 unrelated setup errors. The existing failures were a transient .hypothesis/tmp copy race in a Linux-packages test and missing repository-root release scripts expected by release-to-pypi-uv tests.

References

https://lody.ai/leynos/sessions/fb9d4255-76f9-427d-a587-89983e2d88c9

Cache and run `whitaker-installer`, preferring cargo-binstall when it is
available and falling back to a locked Cargo build otherwise.

Document the action and cover its cache, preferred installation path, and
fallback behaviour with deterministic contract tests.

@sourcery-ai sourcery-ai Bot left a 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.

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

Please try again later or upgrade to continue using Sourcery

@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Summary

  • Added a reusable install-whitaker composite action with cached installer support.
  • Prefers cargo-binstall, falling back to cargo install --locked.
  • Supports configurable installer-version (default 0.2.6) and installs the Whitaker Dylint suite.
  • Added deterministic contract tests for cached, binstall, and Cargo installation paths.
  • Added documentation, changelog entry, root action catalogue entry, and .coverage to .gitignore.
  • Formatting, type checking, linting, and focused tests passed; full test execution reported unrelated existing failures and setup errors.

Walkthrough

Changes

Whitaker installation

Layer / File(s) Summary
Define the cached installation flow
.github/actions/install-whitaker/action.yml, .github/actions/install-whitaker/README.md, .github/actions/install-whitaker/CHANGELOG.md, README.md
Add the composite action, versioned installer and cargo-binstall caches, binstall-first installation, cargo fallback, suite execution, and repository documentation.
Validate installation and cache behaviour
.github/actions/install-whitaker/tests/test_action.py, .gitignore
Test manifest metadata, cache configuration, both installation paths, cached installer reuse, and coverage-file exclusion.

Sequence Diagram(s)

sequenceDiagram
  participant GitHubActions
  participant CargoBinstall
  participant Cargo
  participant WhitakerInstaller
  GitHubActions->>GitHubActions: Restore installer and cargo-binstall caches
  GitHubActions->>CargoBinstall: Check cargo binstall availability
  CargoBinstall-->>GitHubActions: Report availability
  GitHubActions->>CargoBinstall: Install whitaker-installer when available
  GitHubActions->>Cargo: Install whitaker-installer as fallback
  GitHubActions->>WhitakerInstaller: Install the Whitaker Dylint suite
Loading

Possibly related PRs

  • leynos/corbusier#141: Implements the same binstall-first and cargo-fallback acquisition flow for whitaker-installer.
  • leynos/limela#17: Updates another CI workflow to use whitaker-installer version 0.2.6.

Poem

Whitaker arrives on a cached flight,
Binstall first, then Cargo’s might.
The suite is launched, the logs confirm,
Tests guard each path and cache return.


Caution

Pre-merge checks failed

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

  • Ignore

❌ Failed checks (2 errors, 4 warnings)

Check name Status Explanation Resolution
Testing (Overall) ❌ Error The new contract tests cover only happy paths and cached reuse; they miss failure cases and PATH-discovery regressions, so plausible broken implementations would still pass. Add non-vacuous failure-path tests for cargo-binstall, cargo install, and restored-installer resolution, and simulate a runner where ~/.cargo/bin is absent from PATH.
Unit Architecture ❌ Error install-whitaker still relies on ambient PATH to discover and run whitaker-installer, hiding a deployment dependency; the sibling setup-rust action makes this explicit. Export ${CARGO_HOME:-$HOME/.cargo}/bin before command -v and the final invocation, or resolve the installer by absolute path, then update tests to assert it.
User-Facing Documentation ⚠️ Warning No docs/users-guide.md exists; Install Whitaker is only documented in the action README and root catalogue, so the required user-guide update is missing. Add docs/users-guide.md (or the repo’s equivalent user guide) covering Install Whitaker, its inputs, usage, and fallback behaviour, and link it from the action README/root catalogue.
Developer Documentation ⚠️ Warning docs/developers-guide.md has no Whitaker/install-whitaker guidance, and no ADR or execplan records the new composite action. Add a developer-guide section for install-whitaker, or capture the cache/path/install decisions in an ADR or execplan, then keep the catalogue in sync.
Testing (Unit And Behavioural) ⚠️ Warning Tests stub cargo and the installer and execute an extracted run fragment, so they exercise an internal seam; no failure-path or end-to-end coverage is added. Add tests against the public action boundary and cover install failures, cached reuse, and actionable stderr for binstall, cargo, and installer errors.
Observability ⚠️ Warning Only one fallback echo exists; there are no success/failure logs, metrics, traces, or alerts, so install-path diagnostics stay opaque. Add logs at cache-hit, binstall fallback, cargo install, and installer failure boundaries; add metrics only if you expose external reliability signals.
✅ Passed checks (14 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarises the addition of the install-whitaker shared action.
Description check ✅ Passed The description directly matches the composite action, tests, docs, and fallback install flow.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
Module-Level Documentation ✅ Passed The only added module, test_action.py, starts with a clear module docstring describing its purpose and relation to the install-whitaker action.
Testing (Property / Proof) ✅ Passed The action’s behaviour is a small, exhaustively covered state split; the new contract tests already exercise the meaningful branches, so no property/proof test is warranted.
Testing (Compile-Time / Ui) ✅ Passed No Rust/TS compile-time path or UI snapshot target exists here; the PR uses behavioural contract tests for the shell action instead.
Domain Architecture ✅ Passed PASS: The change is confined to a GitHub Action manifest, contract tests, and docs; it introduces no domain model, repository, or transport code.
Security And Privacy ✅ Passed Approve: the manifest, tests, and docs only handle a version input and cache paths; no secrets, auth changes, or unsafe sinks appear.
Performance And Resource Use ✅ Passed The new action does one cache lookup and at most one cargo/binstall install before invoking the installer; no unbounded loops, retries, or heavy allocations appear.
Concurrency And State ✅ Passed PASS: The action is a single-threaded shell flow with per-job cache keying; no locks, tasks, or shared mutable state. Tests isolate state and cover cached-installer reuse.
Architectural Complexity And Maintainability ✅ Passed PASS: The change is a self-contained composite action with explicit cache/install steps and direct contract tests; it adds no new layer, registry, or hidden lifecycle.
Rust Compiler Lint Integrity ✅ Passed PASS: The PR only touches action YAML, docs, tests, and .gitignore; no Rust sources, lint suppressions, or suspicious clone patterns were added.
✨ 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 install-whitaker-action

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

codescene-access[bot]

This comment was marked as outdated.

Match the repository's aligned Markdown table style so the action guide
passes the Markdown lint gate.
codescene-access[bot]

This comment was marked as outdated.

Keep coverage-enabled validation from leaving an untracked `.coverage`
artefact after the Markdown and spelling gates run.
codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

@buzzybee-df12
buzzybee-df12 marked this pull request as ready for review July 21, 2026 17:19

@coderabbitai coderabbitai Bot left a 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.

Actionable comments posted: 6

🤖 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/actions/install-whitaker/action.yml:
- Around line 28-36: Update the installer setup around the command -v
whitaker-installer check to prepend ${CARGO_HOME:-$HOME/.cargo}/bin to PATH
before resolving or invoking whitaker-installer. Preserve the existing
installation fallback logic and ensure both restored and newly installed
binaries are discoverable by the final whitaker-installer command.

In @.github/actions/install-whitaker/README.md:
- Around line 22-27: Update the Install Whitaker usage example to use the
mandated local action reference `./.github/actions/install-whitaker@v1` instead
of the repository-qualified path, while preserving the surrounding setup steps.
- Around line 16-18: Replace the prose under the Outputs section with the
required outputs table format, including a row explicitly stating that this
action exposes no outputs. Keep the existing README structure and document style
otherwise unchanged.

In @.github/actions/install-whitaker/tests/test_action.py:
- Around line 136-174: Add failure-path coverage alongside
test_installs_with_cargo_binstall_when_available,
test_falls_back_to_cargo_install, and test_reuses_cached_installer by extending
the command stubs to fail cargo binstall, cargo install, and whitaker-installer
independently. Assert each scenario exits non-zero and writes actionable stderr,
while preserving the existing success and cached-installer contracts.
- Around line 102-109: Update the subprocess.run call in the test helper to
explicitly pass check=False, preserving the existing returncode-based assertions
and all other invocation options.

In `@README.md`:
- Line 17: Update the “Install Whitaker” catalogue row to show its published
latest major version instead of “unreleased” once v1 is available; if it remains
unpublished, remove the row. Keep the table limited to published actions and
their latest major versions.
🪄 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: 67485f07-b88d-4695-8922-39400b84b222

📥 Commits

Reviewing files that changed from the base of the PR and between c3141c3 and 10e3bd5.

📒 Files selected for processing (6)
  • .github/actions/install-whitaker/CHANGELOG.md
  • .github/actions/install-whitaker/README.md
  • .github/actions/install-whitaker/action.yml
  • .github/actions/install-whitaker/tests/test_action.py
  • .gitignore
  • README.md
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • leynos/polythene (auto-detected)

Comment on lines +28 to +36
if ! command -v whitaker-installer >/dev/null 2>&1; then
if cargo binstall --version >/dev/null 2>&1; then
cargo binstall --no-confirm --locked "whitaker-installer@${WHITAKER_INSTALLER_VERSION}"
else
echo "cargo-binstall unavailable; building whitaker-installer from crates.io"
cargo install --locked whitaker-installer --version "${WHITAKER_INSTALLER_VERSION}"
fi
fi
whitaker-installer

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.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Export Cargo’s bin directory before resolving the installer.

Add ${CARGO_HOME:-$HOME/.cargo}/bin to PATH before command -v and the final invocation. A runner can provide cargo without exposing ~/.cargo/bin, causing both a restored installer and a newly installed installer to remain undiscoverable.

Proposed fix
         set -euo pipefail
+        export PATH="${CARGO_HOME:-$HOME/.cargo}/bin:${PATH}"
         if ! command -v whitaker-installer >/dev/null 2>&1; then
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if ! command -v whitaker-installer >/dev/null 2>&1; then
if cargo binstall --version >/dev/null 2>&1; then
cargo binstall --no-confirm --locked "whitaker-installer@${WHITAKER_INSTALLER_VERSION}"
else
echo "cargo-binstall unavailable; building whitaker-installer from crates.io"
cargo install --locked whitaker-installer --version "${WHITAKER_INSTALLER_VERSION}"
fi
fi
whitaker-installer
set -euo pipefail
export PATH="${CARGO_HOME:-$HOME/.cargo}/bin:${PATH}"
if ! command -v whitaker-installer >/dev/null 2>&1; then
if cargo binstall --version >/dev/null 2>&1; then
cargo binstall --no-confirm --locked "whitaker-installer@${WHITAKER_INSTALLER_VERSION}"
else
echo "cargo-binstall unavailable; building whitaker-installer from crates.io"
cargo install --locked whitaker-installer --version "${WHITAKER_INSTALLER_VERSION}"
fi
fi
whitaker-installer
🤖 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/actions/install-whitaker/action.yml around lines 28 - 36, Update the
installer setup around the command -v whitaker-installer check to prepend
${CARGO_HOME:-$HOME/.cargo}/bin to PATH before resolving or invoking
whitaker-installer. Preserve the existing installation fallback logic and ensure
both restored and newly installed binaries are discoverable by the final
whitaker-installer command.

Comment on lines +16 to +18
## Outputs

This action has no outputs.

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.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Document outputs in the required table format.

Replace the prose statement with an outputs table, including a row that states that no outputs are exposed. As per coding guidelines, each action README must include “input and output tables”.

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 @.github/actions/install-whitaker/README.md around lines 16 - 18, Replace the
prose under the Outputs section with the required outputs table format,
including a row explicitly stating that this action exposes no outputs. Keep the
existing README structure and document style otherwise unchanged.

Sources: Coding guidelines, Path instructions

Comment on lines +22 to +27
```yaml
- name: Set up Rust
uses: leynos/shared-actions/.github/actions/setup-rust@v1

- name: Install Whitaker
uses: leynos/shared-actions/.github/actions/install-whitaker@v1

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.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Use the mandated local action reference in the usage example.

Replace the repository-qualified reference with uses: ./.github/actions/install-whitaker@v1. As per coding guidelines, each action README must include “a usage example using uses: ./.github/actions/<name>@<major>”.

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 @.github/actions/install-whitaker/README.md around lines 22 - 27, Update the
Install Whitaker usage example to use the mandated local action reference
`./.github/actions/install-whitaker@v1` instead of the repository-qualified
path, while preserving the surrounding setup steps.

Sources: Coding guidelines, Path instructions

Comment on lines +102 to +109
return subprocess.run( # noqa: S603,TID251 - exercise the Bash fragment.
[bash, "-c", _install_script()],
cwd=tmp_path,
env=env,
capture_output=True,
text=True,
timeout=30,
)

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.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Declare the intentional non-raising subprocess behaviour.

Set check=False because these tests inspect returncode directly. This resolves the reported Ruff warning without changing the failure assertions.

Proposed fix
         capture_output=True,
+        check=False,
         text=True,
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
return subprocess.run( # noqa: S603,TID251 - exercise the Bash fragment.
[bash, "-c", _install_script()],
cwd=tmp_path,
env=env,
capture_output=True,
text=True,
timeout=30,
)
return subprocess.run( # noqa: S603,TID251 - exercise the Bash fragment.
[bash, "-c", _install_script()],
cwd=tmp_path,
env=env,
capture_output=True,
check=False,
text=True,
timeout=30,
)
🧰 Tools
🪛 Ruff (0.15.21)

[warning] 102-102: subprocess.run without explicit check argument

Add explicit check=False

(PLW1510)

🤖 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/actions/install-whitaker/tests/test_action.py around lines 102 -
109, Update the subprocess.run call in the test helper to explicitly pass
check=False, preserving the existing returncode-based assertions and all other
invocation options.

Source: Linters/SAST tools

Comment on lines +136 to +174
def test_installs_with_cargo_binstall_when_available(tmp_path: Path) -> None:
"""cargo-binstall should be preferred when its subcommand is available."""
result = _run_install_script(tmp_path, binstall_available=True)

assert result.returncode == 0, result.stderr
assert (tmp_path / "cargo.log").read_text(encoding="utf-8").splitlines() == [
"binstall --version",
"binstall --no-confirm --locked whitaker-installer@0.2.6",
]
assert (tmp_path / "installer.log").read_text(encoding="utf-8") == (
"suite installed\n"
)


def test_falls_back_to_cargo_install(tmp_path: Path) -> None:
"""Cargo should build whitaker-installer when cargo-binstall is unavailable."""
result = _run_install_script(tmp_path, binstall_available=False)

assert result.returncode == 0, result.stderr
assert (tmp_path / "cargo.log").read_text(encoding="utf-8").splitlines() == [
"binstall --version",
"install --locked whitaker-installer --version 0.2.6",
]
assert "cargo-binstall unavailable" in result.stdout


def test_reuses_cached_installer(tmp_path: Path) -> None:
"""A restored installer should avoid both Cargo installation paths."""
result = _run_install_script(
tmp_path,
binstall_available=False,
installer_present=True,
)

assert result.returncode == 0, result.stderr
assert not (tmp_path / "cargo.log").exists()
assert (tmp_path / "installer.log").read_text(encoding="utf-8") == (
"suite installed\n"
)

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.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Add failure-path contract tests.

Extend the stubs to fail cargo binstall, cargo install, and whitaker-installer, then assert that the action exits non-zero with actionable stderr. Current tests cover only successful acquisition and reuse. As per coding guidelines, action tests “must cover the happy path, common edge cases, and failure modes with clear error messages”.

🤖 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/actions/install-whitaker/tests/test_action.py around lines 136 -
174, Add failure-path coverage alongside
test_installs_with_cargo_binstall_when_available,
test_falls_back_to_cargo_install, and test_reuses_cached_installer by extending
the command stubs to fail cargo binstall, cargo install, and whitaker-installer
independently. Assert each scenario exits non-zero and writes actionable stderr,
while preserving the existing success and cached-installer contracts.

Sources: Coding guidelines, Learnings

Comment thread README.md
| Export Cargo metadata | `.github/actions/export-cargo-metadata` | v1 |
| Export Postgres URL | `.github/actions/export-postgres-url` | v1 |
| Generate coverage | `.github/actions/generate-coverage` | v1 |
| Install Whitaker | `.github/actions/install-whitaker` | unreleased |

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.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Publish the v1 label or omit this unreleased action from the catalogue.

Replace unreleased with the published latest major version once released; otherwise remove the row until publication. The table must list published actions and their latest major versions.

Triage: [type:docstyle]

🧰 Tools
🪛 LanguageTool

[uncategorized] ~17-~17: The official name of this software platform is spelled with a capital “H”.
Context: ... | | Install Whitaker | .github/actions/install-whitaker ...

(GITHUB)

🤖 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` at line 17, Update the “Install Whitaker” catalogue row to show
its published latest major version instead of “unreleased” once v1 is available;
if it remains unpublished, remove the row. Keep the table limited to published
actions and their latest major versions.

Sources: Coding guidelines, Path instructions

@codescene-access codescene-access Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

No quality gates enabled for this code.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant