mirror of
https://github.com/Heretek-AI/heretek-actions.git
synced 2026-10-12 02:03:46 +00:00
Tier 1.1 of the quality expansion design. Adds the lint-ultimate composite action that runs MegaLinter (or Super-Linter) over the repo and emits a per-linter checks[] plus per-finding findings[] envelope, matching the standard .agent/output.json contract. ## Changes ### Action - .github/actions/lint-ultimate/action.yml: composite action, runs oxsecurity/megalinter:v7 via Docker, uploads the JSON report and stdout as lint-ultimate-reports artifact, uploads the envelope as agent-output-lint for downstream consumers. - .github/actions/lint-ultimate/build-envelope.sh: parses megalinter-report.json, maps each linter category to a check[] entry and each finding to a findings[] entry. Falls back to an empty envelope when the report is missing or unreadable. ### Library - .github/actions/agent-envelope.sh: add add_finding() helper mirroring add_check(). Optional fields (rule, file, line, column, suggested_fix) default to null; numbers coerce when non-empty. ### Library fixes (pre-existing bugs surfaced by the new test) - GITHUB_REPOSITORY default and owner/repo prefix strip now set -u safe. Previously the original --arg repo_name reference threw on unbound-variable in any non-GitHub runner. - GITHUB_RUN_ID now passed as --argjson (numeric or null) instead of --arg with tonumber? in the filter. The prior form silently produced empty output when run_id was unset (jq 1.8.2 quirk where tonumber? on null returns Empty and jq emits no output). ### Schema - .agent/schema.json: enum agent_action extended with all twelve new values from the quality-check expansion design (lint-ultimate, coverage, actionlint, codeql, lefthook-ci, test-matrix, reviewdog, quality-gate, semantic-release, dependabot, docker-ci). Future Tier 1/2/3 PRs pick the right value. ### Tests - tests/: ship the previously untracked harness (run-action.sh, run-all.sh, README.md, fixtures for all CI actions) plus the new megalinter-passing and megalinter-failing fixtures. - tests/unit/test-lint-ultimate-parser.sh: parser unit test that runs build-envelope.sh against a fabricated megalinter-report.json and asserts the envelope shape. No Docker required. - tests/golden/lint-ultimate/README.md: documents that goldens are generated on first real-CI run (per tests/README.md first-run convention) and provides a no-Docker local check. ### Matrix - tests/run-all.sh: megalinter-passing and megalinter-failing added to MATRIX (paired with lint-ultimate action). ### Docs - README.md: lint-ultimate row added to the CI Composite Actions table; full example block added between python-ci and ---. ## Risk - Pre-existing agent-envelope.sh changes affect all envelope-writing callers; the same fixes apply everywhere (none had a green test before). Behavior is unchanged when GITHUB_* env vars are set (real CI). - No existing tests to regress against (tests/ was untracked). Unit test added in this PR exercises the new parser path. Refs: docs/superpowers/specs/2026-07-30-code-quality-expansion-design.md
3.4 KiB
3.4 KiB
Test Harness
Composite actions in .github/actions/ are notoriously hard to test in
isolation. This harness uses act to run
each action against a fixture repo and diff the produced .agent/output.json
against a golden snapshot.
Layout
tests/
├── run-action.sh # Runner — invokes act on a fixture
├── run-all.sh # Run all action/fixture pairs in parallel
├── fixtures/ # Tiny repos with intentional state
│ ├── rust-passing/ # cargo test passes
│ ├── rust-failing/ # cargo test fails on purpose
│ ├── js-passing/ # eslint + vitest green
│ ├── js-failing/ # vitest fails
│ ├── python-passing/ # ruff + pytest green
│ ├── python-failing/ # pytest fails
│ ├── docker-passing/ # clean Dockerfile
│ └── docker-failing/ # bad Dockerfile (hadolint warnings)
├── golden/ # Expected envelopes, keyed by action/fixture
│ ├── rust-ci/
│ │ ├── rust-passing.json
│ │ └── rust-failing.json
│ └── ...
└── work/ # Sandboxes — gitignored, transient
Usage
# Run a single action against a fixture
tests/run-action.sh rust-passing rust-ci
# First run with no golden: writes the snapshot
tests/run-action.sh rust-failing rust-ci # creates golden/rust-ci/rust-failing.json
# Subsequent runs diff against golden — non-zero exit on mismatch
tests/run-action.sh rust-passing rust-ci
CI Integration
tests/run-all.sh iterates over all action/fixture pairs and reports a summary:
tests/run-all.sh # parallel (default jobs = nproc)
tests/run-all.sh --serial # sequential
tests/run-all.sh --dry-run # print matrix, don't execute
tests/run-all.sh --only rust-ci # run only matching actions
tests/run-all.sh --jobs 4 # cap parallel workers
Wire it into a ci workflow:
name: Action Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: |
curl -fsSL https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash
- run: tests/run-all.sh
Conventions
- One fixture per scenario, not per language.
rust-failingis the same fixture reused forrust-cifailing-case and (later) forcoveragefailing-coverage-case. - Goldens strip volatile fields —
created_at,duration_ms,repository.sha,repository.run_id. Don't add those to golden files. - First-run creates the golden. On any schema change, delete goldens to regenerate. Review the diff carefully before committing.
- Fixtures stay tiny. A passing rust fixture is ~10 lines of Cargo.toml + one test file. If a fixture grows past 50 lines, split it.
Known Limitations
actdoes not perfectly emulate GitHub-hosted runners — network, secrets, and someGITHUB_*env vars behave differently. Envelope schema validation is the main check; behavioral testing requires real runners.- Docker-in-Docker (
docker buildinsideact) is slow. Fordocker-ci, preferdocker buildx build --load=falseor skip image builds in tests. - No full JSON-schema validator — the harness only checks that
agent_actionis in the schema enum. Addajv/jsonschemaif you need exhaustive validation.