-
Notifications
You must be signed in to change notification settings - Fork 0
Add install-whitaker shared action #361
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| # Changelog | ||
|
|
||
| All notable changes to the `install-whitaker` action will be documented in | ||
| this file. | ||
|
|
||
| ## v1.0.0 (Unreleased) | ||
|
|
||
| - Add cached installation of the Whitaker Dylint suite | ||
| - Prefer cargo-binstall with a `cargo install` fallback |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| # Install Whitaker | ||
|
|
||
| Install the Whitaker Dylint suite with a cached `whitaker-installer`. | ||
|
|
||
| The action restores the installer and cargo-binstall cache before installation. | ||
| When the installer is not cached, it prefers `cargo binstall` and falls back to | ||
| `cargo install` when cargo-binstall is unavailable. It then runs | ||
| `whitaker-installer` to install the suite. | ||
|
|
||
| ## Inputs | ||
|
|
||
| | Name | Description | Required | Default | | ||
| | ------------------- | ------------------------------------------ | -------- | ------- | | ||
| | `installer-version` | Version of `whitaker-installer` to install | no | `0.2.6` | | ||
|
|
||
| ## Outputs | ||
|
|
||
| This action has no outputs. | ||
|
|
||
| ## Usage | ||
|
|
||
| ```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 | ||
|
Comment on lines
+22
to
+27
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 Triage: 🤖 Prompt for AI AgentsSources: Coding guidelines, Path instructions |
||
|
|
||
| - name: Lint | ||
| run: make lint | ||
| ``` | ||
|
|
||
| The runner must have Cargo available. If `cargo binstall --version` succeeds, | ||
| the action installs the requested version with `cargo binstall --locked`. | ||
| Otherwise, it builds the same version from crates.io with | ||
| `cargo install --locked`. | ||
|
|
||
| ## Release history | ||
|
|
||
| See the [changelog](CHANGELOG.md). | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,36 @@ | ||||||||||||||||||||||||||||||||||||||||||
| name: Install Whitaker | ||||||||||||||||||||||||||||||||||||||||||
| description: Install the Whitaker Dylint suite with a cached installer | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| inputs: | ||||||||||||||||||||||||||||||||||||||||||
| installer-version: | ||||||||||||||||||||||||||||||||||||||||||
| description: Version of whitaker-installer to install | ||||||||||||||||||||||||||||||||||||||||||
| required: false | ||||||||||||||||||||||||||||||||||||||||||
| default: "0.2.6" | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| runs: | ||||||||||||||||||||||||||||||||||||||||||
| using: composite | ||||||||||||||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||||||||||||||
| - name: Cache Whitaker installer | ||||||||||||||||||||||||||||||||||||||||||
| uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | ||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||
| path: | | ||||||||||||||||||||||||||||||||||||||||||
| ~/.cargo/bin/whitaker-installer | ||||||||||||||||||||||||||||||||||||||||||
| ~/.cache/cargo-binstall | ||||||||||||||||||||||||||||||||||||||||||
| key: >- | ||||||||||||||||||||||||||||||||||||||||||
| whitaker-installer-${{ runner.os }}-${{ runner.arch }}-${{ inputs.installer-version }} | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| - name: Install Whitaker Dylint suite | ||||||||||||||||||||||||||||||||||||||||||
| shell: bash | ||||||||||||||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||||||||||||||
| WHITAKER_INSTALLER_VERSION: ${{ inputs.installer-version }} | ||||||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||||||
| set -euo pipefail | ||||||||||||||||||||||||||||||||||||||||||
| 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 | ||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+28
to
+36
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 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
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,174 @@ | ||||||||||||||||||||||||||||||||||||
| """Contract tests for the install-whitaker composite action.""" | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| from __future__ import annotations | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| import os | ||||||||||||||||||||||||||||||||||||
| import shutil | ||||||||||||||||||||||||||||||||||||
| import subprocess | ||||||||||||||||||||||||||||||||||||
| import typing as typ | ||||||||||||||||||||||||||||||||||||
| from pathlib import Path | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| import pytest | ||||||||||||||||||||||||||||||||||||
| import yaml | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| ACTION_PATH = Path(__file__).resolve().parents[1] / "action.yml" | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| def _load_manifest() -> dict[str, object]: | ||||||||||||||||||||||||||||||||||||
| """Load the action manifest.""" | ||||||||||||||||||||||||||||||||||||
| return typ.cast( | ||||||||||||||||||||||||||||||||||||
| "dict[str, object]", | ||||||||||||||||||||||||||||||||||||
| yaml.safe_load(ACTION_PATH.read_text(encoding="utf-8")), | ||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| def _install_script() -> str: | ||||||||||||||||||||||||||||||||||||
| """Return the suite installation shell fragment.""" | ||||||||||||||||||||||||||||||||||||
| manifest = _load_manifest() | ||||||||||||||||||||||||||||||||||||
| runs = manifest["runs"] | ||||||||||||||||||||||||||||||||||||
| assert isinstance(runs, dict) | ||||||||||||||||||||||||||||||||||||
| steps = typ.cast("list[dict[str, object]]", runs["steps"]) | ||||||||||||||||||||||||||||||||||||
| step = next( | ||||||||||||||||||||||||||||||||||||
| (item for item in steps if item.get("name") == "Install Whitaker Dylint suite"), | ||||||||||||||||||||||||||||||||||||
| None, | ||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||
| assert step is not None | ||||||||||||||||||||||||||||||||||||
| script = step.get("run") | ||||||||||||||||||||||||||||||||||||
| assert isinstance(script, str) | ||||||||||||||||||||||||||||||||||||
| return script | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| def _write_executable(path: Path, content: str) -> None: | ||||||||||||||||||||||||||||||||||||
| """Write an executable test stub.""" | ||||||||||||||||||||||||||||||||||||
| path.write_text(content, encoding="utf-8") | ||||||||||||||||||||||||||||||||||||
| path.chmod(0o755) | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| def _write_cargo_stub(bin_dir: Path) -> None: | ||||||||||||||||||||||||||||||||||||
| """Write a Cargo stub that records and simulates installer commands.""" | ||||||||||||||||||||||||||||||||||||
| _write_executable( | ||||||||||||||||||||||||||||||||||||
| bin_dir / "cargo", | ||||||||||||||||||||||||||||||||||||
| """#!/usr/bin/env bash | ||||||||||||||||||||||||||||||||||||
| set -euo pipefail | ||||||||||||||||||||||||||||||||||||
| printf '%s\n' "$*" >> "$CARGO_LOG" | ||||||||||||||||||||||||||||||||||||
| if [ "${1:-}" = "binstall" ] && [ "${2:-}" = "--version" ]; then | ||||||||||||||||||||||||||||||||||||
| [ "$BINSTALL_AVAILABLE" = "true" ] | ||||||||||||||||||||||||||||||||||||
| exit | ||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||
| cat > "$FAKE_BIN_DIR/whitaker-installer" <<'INSTALLER' | ||||||||||||||||||||||||||||||||||||
| #!/usr/bin/env bash | ||||||||||||||||||||||||||||||||||||
| set -euo pipefail | ||||||||||||||||||||||||||||||||||||
| printf '%s\n' "suite installed" >> "$INSTALLER_LOG" | ||||||||||||||||||||||||||||||||||||
| INSTALLER | ||||||||||||||||||||||||||||||||||||
| chmod +x "$FAKE_BIN_DIR/whitaker-installer" | ||||||||||||||||||||||||||||||||||||
| """, | ||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| def _run_install_script( | ||||||||||||||||||||||||||||||||||||
| tmp_path: Path, | ||||||||||||||||||||||||||||||||||||
| *, | ||||||||||||||||||||||||||||||||||||
| binstall_available: bool, | ||||||||||||||||||||||||||||||||||||
| installer_present: bool = False, | ||||||||||||||||||||||||||||||||||||
| ) -> subprocess.CompletedProcess[str]: | ||||||||||||||||||||||||||||||||||||
| """Run the installation fragment with deterministic command stubs.""" | ||||||||||||||||||||||||||||||||||||
| bash = shutil.which("bash") | ||||||||||||||||||||||||||||||||||||
| if bash is None: | ||||||||||||||||||||||||||||||||||||
| pytest.skip("bash not found on PATH") | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| bin_dir = tmp_path / "bin" | ||||||||||||||||||||||||||||||||||||
| bin_dir.mkdir() | ||||||||||||||||||||||||||||||||||||
| cargo_log = tmp_path / "cargo.log" | ||||||||||||||||||||||||||||||||||||
| installer_log = tmp_path / "installer.log" | ||||||||||||||||||||||||||||||||||||
| _write_cargo_stub(bin_dir) | ||||||||||||||||||||||||||||||||||||
| if installer_present: | ||||||||||||||||||||||||||||||||||||
| _write_executable( | ||||||||||||||||||||||||||||||||||||
| bin_dir / "whitaker-installer", | ||||||||||||||||||||||||||||||||||||
| """#!/usr/bin/env bash | ||||||||||||||||||||||||||||||||||||
| set -euo pipefail | ||||||||||||||||||||||||||||||||||||
| printf '%s\n' "suite installed" >> "$INSTALLER_LOG" | ||||||||||||||||||||||||||||||||||||
| """, | ||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| env = { | ||||||||||||||||||||||||||||||||||||
| **os.environ, | ||||||||||||||||||||||||||||||||||||
| "PATH": f"{bin_dir}{os.pathsep}/usr/bin{os.pathsep}/bin", | ||||||||||||||||||||||||||||||||||||
| "BINSTALL_AVAILABLE": str(binstall_available).lower(), | ||||||||||||||||||||||||||||||||||||
| "CARGO_LOG": cargo_log.as_posix(), | ||||||||||||||||||||||||||||||||||||
| "FAKE_BIN_DIR": bin_dir.as_posix(), | ||||||||||||||||||||||||||||||||||||
| "INSTALLER_LOG": installer_log.as_posix(), | ||||||||||||||||||||||||||||||||||||
| "WHITAKER_INSTALLER_VERSION": "0.2.6", | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| 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, | ||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||
|
Comment on lines
+102
to
+109
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 Proposed fix capture_output=True,
+ check=False,
text=True,📝 Committable suggestion
Suggested change
🧰 Tools🪛 Ruff (0.15.21)[warning] 102-102: Add explicit (PLW1510) 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| def test_manifest_exposes_version_and_cache_contract() -> None: | ||||||||||||||||||||||||||||||||||||
| """The manifest should expose the pin and cache the installer artefacts.""" | ||||||||||||||||||||||||||||||||||||
| manifest = _load_manifest() | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| assert manifest["inputs"] == { | ||||||||||||||||||||||||||||||||||||
| "installer-version": { | ||||||||||||||||||||||||||||||||||||
| "description": "Version of whitaker-installer to install", | ||||||||||||||||||||||||||||||||||||
| "required": False, | ||||||||||||||||||||||||||||||||||||
| "default": "0.2.6", | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| runs = manifest["runs"] | ||||||||||||||||||||||||||||||||||||
| assert isinstance(runs, dict) | ||||||||||||||||||||||||||||||||||||
| steps = typ.cast("list[dict[str, object]]", runs["steps"]) | ||||||||||||||||||||||||||||||||||||
| cache_step = steps[0] | ||||||||||||||||||||||||||||||||||||
| assert cache_step["uses"] == ( | ||||||||||||||||||||||||||||||||||||
| "actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9" | ||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||
| cache_config = typ.cast("dict[str, str]", cache_step["with"]) | ||||||||||||||||||||||||||||||||||||
| assert "~/.cargo/bin/whitaker-installer" in cache_config["path"] | ||||||||||||||||||||||||||||||||||||
| assert "~/.cache/cargo-binstall" in cache_config["path"] | ||||||||||||||||||||||||||||||||||||
| assert "${{ inputs.installer-version }}" in cache_config["key"] | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| 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" | ||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||
|
Comment on lines
+136
to
+174
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 🤖 Prompt for AI AgentsSources: Coding guidelines, Learnings |
||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -145,6 +145,7 @@ __pycache__/ | |
| venv/ | ||
| .env.* | ||
| .pytest_cache/ | ||
| .coverage | ||
| .mypy_cache/ | ||
| *.egg-info/ | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,6 +14,7 @@ GitHub Actions | |
| | 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 | | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 Triage: 🧰 Tools🪛 LanguageTool[uncategorized] ~17-~17: The official name of this software platform is spelled with a capital “H”. (GITHUB) 🤖 Prompt for AI AgentsSources: Coding guidelines, Path instructions |
||
| | Linux packages | `.github/actions/linux-packages` | v1 | | ||
| | macOS package | `.github/actions/macos-package` | v1 | | ||
| | Ratchet coverage | `.github/actions/ratchet-coverage` | v1 | | ||
|
|
||
There was a problem hiding this comment.
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
Sources: Coding guidelines, Path instructions