argus-reviewer-e2e 0.1.3 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +86 -49
- package/action/action.yml +155 -61
- package/action/approval-review.mjs +393 -0
- package/action/bootstrap.mjs +102 -0
- package/action/cli.mjs +36 -0
- package/action/emit-review.mjs +336 -0
- package/action/runtime.mjs +154 -0
- package/action/sticky-comment.cjs +870 -0
- package/dist/api.d.ts +2 -0
- package/dist/api.js +4 -0
- package/dist/cache/store.d.ts +2 -0
- package/dist/cache/store.js +10 -3
- package/dist/cli.d.ts +137 -0
- package/dist/cli.js +677 -60
- package/dist/config.d.ts +67 -2
- package/dist/config.js +138 -7
- package/dist/debug.d.ts +1 -0
- package/dist/debug.js +9 -3
- package/dist/engine/loop.d.ts +12 -0
- package/dist/engine/loop.js +55 -6
- package/dist/evidence/ci.d.ts +3 -0
- package/dist/evidence/ci.js +3 -1
- package/dist/pipeline/budget.d.ts +11 -0
- package/dist/pipeline/budget.js +48 -0
- package/dist/pipeline/contracts.d.ts +12 -0
- package/dist/pipeline/contracts.js +16 -0
- package/dist/pipeline/verify.d.ts +27 -0
- package/dist/pipeline/verify.js +197 -0
- package/dist/probe/queue.d.ts +4 -1
- package/dist/probe/queue.js +46 -8
- package/dist/report/manifest.d.ts +87 -0
- package/dist/report/manifest.js +143 -0
- package/dist/report/run.d.ts +9 -0
- package/dist/report/run.js +6 -0
- package/dist/review/adjudicate.d.ts +63 -0
- package/dist/review/adjudicate.js +111 -0
- package/dist/review/secrets.d.ts +90 -0
- package/dist/review/secrets.js +224 -0
- package/dist/review/triage.d.ts +76 -0
- package/dist/review/triage.js +163 -0
- package/dist/trust.d.ts +50 -0
- package/dist/trust.js +103 -0
- package/dist/vision/cost.d.ts +14 -1
- package/dist/vision/cost.js +13 -0
- package/dist/vision/decisions.d.ts +95 -0
- package/dist/vision/decisions.js +232 -0
- package/package.json +9 -8
- package/action/sticky-comment.mjs +0 -404
package/README.md
CHANGED
|
@@ -1,81 +1,118 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Argus
|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
4
|
<img src="docs/assets/social.png" alt="Argus — vision-model E2E testing" width="640" />
|
|
5
5
|
</p>
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="https://www.npmjs.com/package/argus-reviewer-e2e"><img src="https://img.shields.io/npm/v/argus-reviewer-e2e" alt="npm version" /></a>
|
|
9
|
+
<a href="https://github.com/duketopceo/Argus/actions/workflows/ci.yml"><img src="https://github.com/duketopceo/Argus/actions/workflows/ci.yml/badge.svg" alt="CI" /></a>
|
|
10
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue" alt="MIT license" /></a>
|
|
11
|
+
<a href="https://github.com/duketopceo/Argus/security/policy"><img src="https://img.shields.io/badge/security-policy-orange" alt="security policy" /></a>
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
**The hundred-eyed watcher for your pull requests.** Argus reviews your diff, then goes further: it starts your real app, clicks through it like a user, and executes probes against suspected bugs — then posts a verdict on the PR with the exact dollar cost. Self-hosted, MIT-licensed, bring-your-own OpenRouter key. No SaaS middleman, no telemetry, no per-seat pricing.
|
|
15
|
+
|
|
16
|
+
## Get started in 60 seconds
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm i -D argus-reviewer-e2e # the npm package; the command it installs is `argus-reviewer`
|
|
20
|
+
npx argus-reviewer init # writes config + smoke test + GitHub workflow
|
|
21
|
+
```
|
|
8
22
|
|
|
9
|
-
|
|
10
|
-
- **Cache-first**: replay costs zero vision calls on an unchanged UI; heals re-spend only on drift and show up as reviewable cache diffs.
|
|
11
|
-
- **Cost-explicit**: every call is metered from OpenRouter's per-call cost and rolled into a per-run dollar figure on the PR.
|
|
12
|
-
- **Grounding specialist**: a `grounding_model` (e.g. a ui-tars-class model) can drive element location with its native coordinate output, verified against the DOM before any click executes.
|
|
13
|
-
- **Execution-backed review**: `code-review` findings carry CI evidence, and with the opt-in sandbox lane (`sandbox: { enabled: true }`) Argus authors a test probe for unexercised findings and runs it in a hardened, network-less Docker container — a finding that fails on head and passes on base is stamped **reproduced**, not just suspected.
|
|
23
|
+
Add `OPENROUTER_API_KEY` to your environment (and repo secrets for CI). Then:
|
|
14
24
|
|
|
15
25
|
```bash
|
|
16
|
-
|
|
17
|
-
npx argus-reviewer
|
|
18
|
-
npx argus-reviewer run # replays + asserts, zero-cost on cache hit
|
|
26
|
+
npx argus-reviewer record "sign in and open the dashboard" --url http://localhost:3000
|
|
27
|
+
npx argus-reviewer run # replays + asserts — free on cache hit
|
|
19
28
|
```
|
|
20
29
|
|
|
30
|
+
That's it. `init` drops a ready-to-run GitHub workflow; every PR from then on gets a review comment with findings, flow results, video evidence, and spend.
|
|
31
|
+
|
|
32
|
+
## What lands on your PR
|
|
33
|
+
|
|
34
|
+
A sticky comment that updates on every push:
|
|
35
|
+
|
|
36
|
+
- **Verdict** — `APPROVE` / `NEEDS_CHANGES` with findings linked to concrete source lines
|
|
37
|
+
- **Inline comments on every severity** — one batched PR review, severity-sorted; each finding can carry a committable `suggestion` block you apply in one click
|
|
38
|
+
- **Blocks only on proof** — the review escalates to `REQUEST_CHANGES` only for reproduced or adjudicated blockers; everything else stays advisory. Stale request-changes reviews are dismissed automatically, and `requestChanges: false` keeps it advisory forever
|
|
39
|
+
- **Flow results** — which recorded user-journeys passed, healed, or broke
|
|
40
|
+
- **Reproduced, not suspected** — opt-in sandbox lane runs authored regression probes; a probe that fails on head and passes on base stamps the finding as *proven*
|
|
41
|
+
- **Cost** — every model call metered from OpenRouter's per-call pricing, totaled in dollars
|
|
42
|
+
|
|
43
|
+
That comment is **not a review**. `require_approving_reviews` reads reviews only, so on a protected branch the verdict alone leaves the gate unsatisfied. Supply `approval-token` — a GitHub App installation token, or a PAT from an account that is not the PR author — and Argus also submits a real review whose event follows the verdict. `github.token` cannot do this; GitHub refuses it outright. A token alone is **not** enough: an `APPROVE` also needs `approval-evidence` naming the test command, and `approval-check` naming a check run that has completed green on the pull request's head commit, produced by the App named in `approval-check-app` (`github-actions` by default). Details, the measured refusals, and the review-discipline rules: [`docs/approval-token.md`](docs/approval-token.md).
|
|
44
|
+
|
|
21
45
|
<p align="center">
|
|
22
46
|
<img src="docs/assets/demo.gif" alt="argus-reviewer run — live vision call, PASS, $0.0005 spend" width="900" />
|
|
23
47
|
</p>
|
|
24
48
|
|
|
25
|
-
|
|
49
|
+
## Why it's different
|
|
26
50
|
|
|
27
|
-
|
|
51
|
+
| | Argus |
|
|
52
|
+
|---|---|
|
|
53
|
+
| **Selectors** | None. A vision model looks at a screenshot and decides where to click. |
|
|
54
|
+
| **Maintenance** | Fingerprint cache replays at zero model cost; when the UI drifts, self-healing re-grounds and the heal shows up as a reviewable diff. |
|
|
55
|
+
| **Review depth** | Beyond the diff: full-source evidence linkage, CI evidence, executed probes, real browser runs. |
|
|
56
|
+
| **Spend** | You pick the models per lane (`model`, `grounding_model`, `code_model`, `escalation_model`) and set `budgetUsd`. Cache hits cost nothing. |
|
|
57
|
+
| **Data** | Yours. Keys, journals, videos, and reports stay on your infra. |
|
|
28
58
|
|
|
29
|
-
|
|
59
|
+
## Configuration
|
|
30
60
|
|
|
31
|
-
|
|
61
|
+
`argus-reviewer.config.ts`:
|
|
32
62
|
|
|
33
63
|
```ts
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
64
|
+
import { defineConfig } from 'argus-reviewer-e2e'
|
|
65
|
+
|
|
66
|
+
export default defineConfig({
|
|
67
|
+
model: 'google/gemini-2.5-flash-lite', // vision grounding + actions
|
|
68
|
+
code_model: 'deepseek/deepseek-v4.1-flash', // diff review
|
|
69
|
+
escalation_model: 'anthropic/claude-sonnet-4', // risky/complex findings
|
|
70
|
+
budgetUsd: 1.0,
|
|
71
|
+
target: { url: 'https://your-app.example.com' },
|
|
72
|
+
testsDir: 'e2e',
|
|
73
|
+
})
|
|
40
74
|
```
|
|
41
75
|
|
|
42
|
-
|
|
76
|
+
Point `provider.order` at fast OpenRouter backends (`cerebras`, `groq`) for sub-second review calls — speed is a routing choice, not a pricing tier. Full shape: [`src/config.ts`](src/config.ts) (a legacy `vision-e2e.config.*` is still accepted). Setup walkthrough: [`docs/quickstart.md`](docs/quickstart.md).
|
|
77
|
+
|
|
78
|
+
## The execution ladder
|
|
79
|
+
|
|
80
|
+
Argus does more as you grant it more access — each rung is opt-in:
|
|
81
|
+
|
|
82
|
+
1. **API review** — GitHub token only. Reviews the PR diff and posts the verdict.
|
|
83
|
+
2. **Trusted checkout** — findings get verified against the full source tree.
|
|
84
|
+
3. **Browser flows** — Playwright drives your real app through recorded journeys.
|
|
85
|
+
4. **Sandbox probes** — suspected findings get authored regression tests, executed in a hardened container (no network, no secrets, read-only FS). Fork PRs stay behind an `argus-probe` label gate.
|
|
86
|
+
5. **Agent Zero delegation** — `argus-reviewer delegate "find the checkout bug"` hands exploratory work to your own A0 instance.
|
|
87
|
+
|
|
88
|
+
## Cost attribution
|
|
89
|
+
|
|
90
|
+
Every OpenRouter call carries a trace tag. The action auto-sets `ARGUS_REVIEWER_TRACE` (repo, PR, commit, run id) so spend is attributable per review — or set it yourself for custom fields. See [`docs/quickstart.md`](docs/quickstart.md) for the `openrouter` config block.
|
|
91
|
+
|
|
92
|
+
## Security model
|
|
43
93
|
|
|
44
|
-
|
|
94
|
+
Reviews run against hostile input by design: untrusted checkouts never execute config code, fork PRs are label-gated, secrets are filtered from model context and comment output, and the sandbox probe lane runs network-less with a read-only filesystem. Threat model: [`SECURITY.md`](SECURITY.md).
|
|
45
95
|
|
|
46
96
|
## File structure
|
|
47
97
|
|
|
48
98
|
```text
|
|
49
99
|
argus-reviewer/
|
|
50
100
|
├── action/ # GitHub Actions composite action + sticky PR comment
|
|
51
|
-
│ ├── action.yml
|
|
52
|
-
│ └── sticky-comment.mjs
|
|
53
101
|
├── runner/ # Self-hosted runner registration docs + script
|
|
54
|
-
|
|
55
|
-
│ └── register-runner.sh
|
|
102
|
+
├── electron/ # Local observability dashboard (`npm run app`)
|
|
56
103
|
├── src/
|
|
57
|
-
│ ├── api.ts # Test-facing `test`/`td` API + generated test
|
|
58
|
-
│ ├── cli.ts #
|
|
59
|
-
│ ├── config.ts # `argus-reviewer.config.*` loader
|
|
60
|
-
│ ├──
|
|
61
|
-
│
|
|
62
|
-
│
|
|
63
|
-
│ ├──
|
|
64
|
-
│
|
|
65
|
-
│
|
|
66
|
-
│
|
|
67
|
-
│
|
|
68
|
-
|
|
69
|
-
│ │ └── store.ts # Flow cache read/write
|
|
70
|
-
│ ├── report/
|
|
71
|
-
│ │ ├── comment.ts # Markdown PR comment + commit-status rendering
|
|
72
|
-
│ │ ├── junit.ts # JUnit XML output
|
|
73
|
-
│ │ └── run.ts # JSON run report consumed by the action
|
|
74
|
-
│ └── vision/
|
|
75
|
-
│ ├── cost.ts # OpenRouter cost parsing per call
|
|
76
|
-
│ ├── ledger.ts # Per-run USD budget tracking
|
|
77
|
-
│ └── openrouter.ts # OpenRouter chat-completion client + schema parsing
|
|
78
|
-
└── tests/ # Unit tests + small Playwright fixture page
|
|
104
|
+
│ ├── api.ts # Test-facing `test`/`td` API + generated test renderer
|
|
105
|
+
│ ├── cli.ts # record · run · code-review · delegate · cache · index · init
|
|
106
|
+
│ ├── config.ts # `argus-reviewer.config.*` loader
|
|
107
|
+
│ ├── cache/ # Per-step fingerprint + flow store
|
|
108
|
+
│ ├── driver/ # Playwright browser + dev-server target
|
|
109
|
+
│ ├── engine/ # Vision record/replay + healing loop
|
|
110
|
+
│ ├── evidence/ # PR/CI context, fork trust gate, finding linkage
|
|
111
|
+
│ ├── executor/ # Agent Zero delegation + hardened probe sandbox
|
|
112
|
+
│ ├── probe/ # Model-authored regression probes
|
|
113
|
+
│ ├── report/ # PR comment, JUnit XML, run.json
|
|
114
|
+
│ └── vision/ # OpenRouter client, cost parsing, budget ledger
|
|
115
|
+
└── tests/ # Unit tests + Playwright fixture page
|
|
79
116
|
```
|
|
80
117
|
|
|
81
|
-
License: MIT.
|
|
118
|
+
License: [MIT](LICENSE).
|
package/action/action.yml
CHANGED
|
@@ -5,9 +5,13 @@ inputs:
|
|
|
5
5
|
openrouter-api-key:
|
|
6
6
|
description: OpenRouter API key (BYOK). All vision calls are billed through this key.
|
|
7
7
|
required: true
|
|
8
|
+
argus-version:
|
|
9
|
+
description: Optional pinned argus-reviewer-e2e npm version. Empty installs the CLI package from this action ref with lifecycle scripts disabled.
|
|
10
|
+
default: ''
|
|
11
|
+
required: false
|
|
8
12
|
cli:
|
|
9
|
-
description:
|
|
10
|
-
default:
|
|
13
|
+
description: Optional executable plus arguments for a trusted local CLI override. Shell operators are rejected; empty installs the CLI package from this action ref.
|
|
14
|
+
default: ''
|
|
11
15
|
required: false
|
|
12
16
|
config:
|
|
13
17
|
description: Path to the argus-reviewer config file
|
|
@@ -35,118 +39,208 @@ inputs:
|
|
|
35
39
|
description: Playwright browser engine to install and run (chromium, firefox, or webkit). Should match config.browser.
|
|
36
40
|
default: 'chromium'
|
|
37
41
|
required: false
|
|
38
|
-
cache-dependency-path:
|
|
39
|
-
description: npm lockfile path for setup-node cache (defaults to <working-directory>/package-lock.json)
|
|
40
|
-
required: false
|
|
41
42
|
report-dir:
|
|
42
|
-
description: Report output dir, passed to both run and code-review so the post step can find
|
|
43
|
+
description: Report output dir, passed to both run and code-review so the post step can find artifacts
|
|
43
44
|
default: argus-reviewer-report
|
|
44
45
|
required: false
|
|
45
46
|
sandbox:
|
|
46
47
|
description: Enable the B.2 probe lane — authored test probes for unexercised findings run in a hardened Docker container (no network, no secrets, read-only fs). Enable-only — 'false' does not override a config-enabled lane. Requires Docker on the runner; forced off on pull_request_target.
|
|
47
48
|
default: 'false'
|
|
48
49
|
required: false
|
|
50
|
+
max-comments:
|
|
51
|
+
description: Cap on inline review comments posted per run; overflow is summarized in the sticky. Overrides review.maxComments when set.
|
|
52
|
+
default: ''
|
|
53
|
+
required: false
|
|
54
|
+
install-consumer-dependencies:
|
|
55
|
+
description: Explicitly install the consumer project's dependencies for a trusted runtime lane. Disabled by default so code review never runs PR-controlled lifecycle scripts beside secrets.
|
|
56
|
+
default: 'false'
|
|
57
|
+
required: false
|
|
58
|
+
run:
|
|
59
|
+
description: Run the browser-flow lane (`argus-reviewer run`). Disabled by default for public code-review-only repositories. Requires an explicit target and a trusted runtime path.
|
|
60
|
+
default: 'false'
|
|
61
|
+
required: false
|
|
62
|
+
approval-token:
|
|
63
|
+
description: >-
|
|
64
|
+
Optional token that lets Argus submit a *formal* pull request review, which
|
|
65
|
+
is what `require_approving_reviews` reads. `github.token` cannot be used:
|
|
66
|
+
GitHub refuses it with 422 "GitHub Actions is not permitted to approve
|
|
67
|
+
pull requests", and no permission scope changes that. Supply a GitHub App
|
|
68
|
+
installation token, or a PAT belonging to an account that is not the PR
|
|
69
|
+
author. Empty (the default) keeps Argus to the sticky comment only. See
|
|
70
|
+
docs/approval-token.md.
|
|
71
|
+
default: ''
|
|
72
|
+
required: false
|
|
73
|
+
approval-evidence:
|
|
74
|
+
description: >-
|
|
75
|
+
The test command(s) an approval stands on, cited verbatim in the review
|
|
76
|
+
body — e.g. 'python -m unittest discover -s tests && ruff check .'.
|
|
77
|
+
Required whenever approval-token is supplied: the lane refuses to submit
|
|
78
|
+
an approval that cites no command, so an approver is always re-runnable.
|
|
79
|
+
Ignored when approval-token is empty.
|
|
80
|
+
default: ''
|
|
81
|
+
required: false
|
|
82
|
+
approval-check:
|
|
83
|
+
description: >-
|
|
84
|
+
Name of a check run that must have completed successfully on the head
|
|
85
|
+
commit before Argus will submit an APPROVE, e.g. 'test (22)' or 'lint'.
|
|
86
|
+
This is what makes the cited test command evidence rather than a claim:
|
|
87
|
+
the review cites the real run. An APPROVE with no green run of this name
|
|
88
|
+
is refused. Ignored on the REQUEST_CHANGES and COMMENT paths, so a
|
|
89
|
+
negative review still goes out while CI is red.
|
|
90
|
+
default: ''
|
|
91
|
+
required: false
|
|
92
|
+
approval-check-app:
|
|
93
|
+
description: >-
|
|
94
|
+
App slug that is allowed to produce the approval-check run, e.g.
|
|
95
|
+
'github-actions'. A check name is not a producer: a fork can add a
|
|
96
|
+
workflow that reports a green run with the expected name, so the match is
|
|
97
|
+
pinned to one App. Set this to your own App slug if your CI is not GitHub
|
|
98
|
+
Actions. Empty accepts any producer and is not the default.
|
|
99
|
+
default: 'github-actions'
|
|
100
|
+
required: false
|
|
101
|
+
emit-review:
|
|
102
|
+
description: >-
|
|
103
|
+
Submit the formal review when `approval-token` is supplied. 'false' keeps
|
|
104
|
+
the token out of the review lane entirely. A `true` value without a token
|
|
105
|
+
is a no-op, not an error.
|
|
106
|
+
default: 'true'
|
|
107
|
+
required: false
|
|
49
108
|
outputs:
|
|
50
109
|
conclusion:
|
|
51
110
|
description: 'Run conclusion: success, failure, or neutral'
|
|
52
111
|
value: ${{ steps.post.outputs.conclusion }}
|
|
112
|
+
review-event:
|
|
113
|
+
description: 'GitHub review event submitted: APPROVE, REQUEST_CHANGES, COMMENT, or none'
|
|
114
|
+
value: ${{ steps.approve.outputs.review-event }}
|
|
115
|
+
review-state:
|
|
116
|
+
description: 'State of the submitted review, or why none was submitted'
|
|
117
|
+
value: ${{ steps.approve.outputs.review-state }}
|
|
118
|
+
stale-dismissed:
|
|
119
|
+
description: 'Stale approvals by this identity that were dismissed because they no longer describe the head. "unknown" if the existing reviews could not be read.'
|
|
120
|
+
value: ${{ steps.approve.outputs.stale-dismissed }}
|
|
53
121
|
runs:
|
|
54
122
|
using: composite
|
|
55
123
|
steps:
|
|
56
|
-
- uses: actions/setup-node@v4
|
|
124
|
+
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
|
57
125
|
with:
|
|
58
126
|
node-version: ${{ inputs.node-version }}
|
|
59
|
-
cache: npm
|
|
60
|
-
cache-dependency-path: ${{ inputs.cache-dependency-path || format('{0}/package-lock.json', inputs.working-directory || '.') }}
|
|
61
127
|
|
|
62
|
-
- name:
|
|
128
|
+
- name: Prepare pinned Argus runtime
|
|
129
|
+
id: bootstrap
|
|
63
130
|
shell: bash
|
|
64
|
-
|
|
65
|
-
|
|
131
|
+
env:
|
|
132
|
+
ARGUS_ACTION_PATH: ${{ github.action_path }}
|
|
133
|
+
ARGUS_CLI: ${{ inputs.cli }}
|
|
134
|
+
ARGUS_ARGUS_VERSION: ${{ inputs.argus-version }}
|
|
135
|
+
ARGUS_CONFIG_PATH: ${{ inputs.config }}
|
|
136
|
+
ARGUS_WORKING_DIRECTORY: ${{ inputs.working-directory }}
|
|
137
|
+
ARGUS_REPORT_DIR: ${{ inputs.report-dir }}
|
|
138
|
+
ARGUS_BROWSER: ${{ inputs.browser }}
|
|
139
|
+
ARGUS_BUDGET_USD: ${{ inputs.budget-usd }}
|
|
140
|
+
ARGUS_MAX_COMMENTS: ${{ inputs.max-comments }}
|
|
141
|
+
run: node "$ARGUS_ACTION_PATH/bootstrap.mjs"
|
|
66
142
|
|
|
67
|
-
- name:
|
|
143
|
+
- name: Reject executable lanes on untrusted pull requests
|
|
144
|
+
if: inputs.run != 'false' || inputs.install-consumer-dependencies == 'true'
|
|
68
145
|
shell: bash
|
|
69
|
-
working-directory: ${{ inputs.working-directory }}
|
|
70
146
|
env:
|
|
71
|
-
|
|
147
|
+
EVENT_NAME: ${{ github.event_name }}
|
|
148
|
+
HEAD_FORK: ${{ github.event.pull_request.head.repo.fork }}
|
|
72
149
|
run: |
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
150
|
+
if [ "$EVENT_NAME" = "pull_request_target" ]; then
|
|
151
|
+
echo "Argus runtime lanes are disabled for pull_request_target." >&2
|
|
152
|
+
exit 1
|
|
153
|
+
fi
|
|
154
|
+
if [ "$EVENT_NAME" = "pull_request" ] && [ "$HEAD_FORK" != "false" ]; then
|
|
155
|
+
echo "Argus runtime lanes require a same-repository PR or an explicitly trusted workflow." >&2
|
|
156
|
+
exit 1
|
|
157
|
+
fi
|
|
158
|
+
if [ "$EVENT_NAME" != "pull_request" ] && [ "$EVENT_NAME" != "" ]; then
|
|
159
|
+
echo "Argus runtime lanes are disabled for unlisted CI events: $EVENT_NAME" >&2
|
|
160
|
+
exit 1
|
|
161
|
+
fi
|
|
162
|
+
|
|
163
|
+
- name: Install consumer dependencies for explicit runtime lanes
|
|
164
|
+
if: inputs.install-consumer-dependencies == 'true'
|
|
165
|
+
shell: bash
|
|
166
|
+
working-directory: ${{ inputs.working-directory || '.' }}
|
|
167
|
+
run: npm ci
|
|
78
168
|
|
|
79
|
-
- name:
|
|
169
|
+
- name: Install Playwright browser for explicit runtime lanes
|
|
170
|
+
if: inputs.run != 'false'
|
|
80
171
|
shell: bash
|
|
81
|
-
working-directory: ${{ inputs.working-directory }}
|
|
172
|
+
working-directory: ${{ inputs.working-directory || '.' }}
|
|
173
|
+
env:
|
|
174
|
+
ARGUS_BROWSER: ${{ inputs.browser }}
|
|
82
175
|
run: |
|
|
83
|
-
|
|
84
|
-
ext="${{ inputs.config }}"
|
|
85
|
-
ext="${ext##*.}"
|
|
86
|
-
case "$ext" in
|
|
87
|
-
ts|json) cp "${{ inputs.config }}" "argus-reviewer.config.$ext" ;;
|
|
88
|
-
*) echo "unsupported config extension: $ext" >&2; exit 1 ;;
|
|
89
|
-
esac
|
|
90
|
-
fi
|
|
176
|
+
npx playwright install --with-deps "$ARGUS_BROWSER" || npx playwright install "$ARGUS_BROWSER"
|
|
91
177
|
|
|
92
178
|
- name: Build repo index
|
|
93
179
|
if: inputs.index == 'true'
|
|
94
180
|
shell: bash
|
|
95
|
-
working-directory: ${{ inputs.working-directory }}
|
|
96
|
-
run: ${{ inputs.cli }} index
|
|
97
|
-
|
|
98
|
-
- name: Run argus-reviewer code review
|
|
99
|
-
id: code-review
|
|
100
|
-
shell: bash
|
|
101
|
-
working-directory: ${{ inputs.working-directory }}
|
|
102
|
-
continue-on-error: true
|
|
181
|
+
working-directory: ${{ inputs.working-directory || '.' }}
|
|
103
182
|
env:
|
|
104
|
-
|
|
183
|
+
ARGUS_ACTION_PATH: ${{ github.action_path }}
|
|
105
184
|
GITHUB_TOKEN: ${{ github.token }}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
{"repo":"${{ github.repository }}",
|
|
110
|
-
"pr":"${{ github.event.pull_request.number }}",
|
|
111
|
-
"commit":"${{ github.sha }}",
|
|
112
|
-
"run_id":"${{ github.run_id }}",
|
|
113
|
-
"run_attempt":"${{ github.run_attempt }}",
|
|
114
|
-
"workflow":"${{ github.workflow }}"}
|
|
115
|
-
run: ${{ inputs.cli }} code-review --report-dir "${{ inputs.report-dir }}"
|
|
185
|
+
ARGUS_CLI_JSON: ${{ steps.bootstrap.outputs.cli-json }}
|
|
186
|
+
ARGUS_WORKING_DIRECTORY: ${{ steps.bootstrap.outputs.working-directory }}
|
|
187
|
+
run: node "$ARGUS_ACTION_PATH/cli.mjs" index
|
|
116
188
|
|
|
117
|
-
- name: Run
|
|
118
|
-
id:
|
|
189
|
+
- name: Run selected Argus lanes
|
|
190
|
+
id: verify
|
|
119
191
|
shell: bash
|
|
120
|
-
working-directory: ${{ inputs.working-directory }}
|
|
192
|
+
working-directory: ${{ inputs.working-directory || '.' }}
|
|
121
193
|
continue-on-error: true
|
|
122
194
|
env:
|
|
195
|
+
ARGUS_ACTION_PATH: ${{ github.action_path }}
|
|
123
196
|
OPENROUTER_API_KEY: ${{ inputs.openrouter-api-key }}
|
|
197
|
+
GITHUB_TOKEN: ${{ github.token }}
|
|
198
|
+
ARGUS_CLI_JSON: ${{ steps.bootstrap.outputs.cli-json }}
|
|
199
|
+
ARGUS_WORKING_DIRECTORY: ${{ steps.bootstrap.outputs.working-directory }}
|
|
200
|
+
ARGUS_REPORT_DIR: ${{ inputs.report-dir }}
|
|
201
|
+
ARGUS_VERIFY_FLOW: ${{ inputs.run != 'false' && '1' || '' }}
|
|
202
|
+
ARGUS_SANDBOX: ${{ inputs.sandbox == 'true' && '1' || '' }}
|
|
203
|
+
ARGUS_MAX_COMMENTS: ${{ inputs.max-comments }}
|
|
124
204
|
ARGUS_DEBUG: '1'
|
|
125
205
|
ARGUS_DIFF_BASE: ${{ inputs.diff-base }}
|
|
126
206
|
ARGUS_BUDGET_USD: ${{ inputs.budget-usd }}
|
|
127
207
|
ARGUS_REVIEWER_TRACE: >-
|
|
128
208
|
{"repo":"${{ github.repository }}",
|
|
129
209
|
"pr":"${{ github.event.pull_request.number }}",
|
|
130
|
-
"commit":"${{ github.sha }}",
|
|
210
|
+
"commit":"${{ github.event.pull_request.head.sha || github.sha }}",
|
|
131
211
|
"run_id":"${{ github.run_id }}",
|
|
132
212
|
"run_attempt":"${{ github.run_attempt }}",
|
|
133
213
|
"workflow":"${{ github.workflow }}"}
|
|
134
|
-
run: $
|
|
214
|
+
run: node "$ARGUS_ACTION_PATH/cli.mjs" verify --report-dir "$ARGUS_REPORT_DIR"
|
|
135
215
|
|
|
136
216
|
- name: Post or update sticky PR comment
|
|
137
217
|
id: post
|
|
138
|
-
|
|
218
|
+
if: always()
|
|
219
|
+
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7
|
|
139
220
|
env:
|
|
221
|
+
ARGUS_ACTION_PATH: ${{ github.action_path }}
|
|
140
222
|
OPENROUTER_API_KEY: ${{ inputs.openrouter-api-key }}
|
|
141
223
|
VISION_E2E_WORKING_DIR: ${{ inputs.working-directory }}
|
|
142
224
|
ARGUS_REPORT_DIR: ${{ inputs.report-dir }}
|
|
225
|
+
ARGUS_RUN_DISABLED: ${{ inputs.run == 'false' && '1' || '' }}
|
|
143
226
|
with:
|
|
144
227
|
github-token: ${{ github.token }}
|
|
145
228
|
script: |
|
|
146
|
-
const fs = require('fs');
|
|
147
229
|
const path = require('path');
|
|
148
|
-
const actionPath = process.env.
|
|
149
|
-
const
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
230
|
+
const actionPath = process.env.ARGUS_ACTION_PATH;
|
|
231
|
+
const { run } = require(path.join(actionPath, 'sticky-comment.cjs'));
|
|
232
|
+
return await run({ github, context, core });
|
|
233
|
+
|
|
234
|
+
- name: Submit formal approval review
|
|
235
|
+
id: approve
|
|
236
|
+
if: always() && inputs.emit-review != 'false'
|
|
237
|
+
shell: bash
|
|
238
|
+
env:
|
|
239
|
+
ARGUS_APPROVAL_TOKEN: ${{ inputs.approval-token }}
|
|
240
|
+
ARGUS_APPROVAL_EVIDENCE: ${{ inputs.approval-evidence }}
|
|
241
|
+
ARGUS_APPROVAL_CHECK: ${{ inputs.approval-check }}
|
|
242
|
+
ARGUS_APPROVAL_CHECK_APP: ${{ inputs.approval-check-app }}
|
|
243
|
+
ARGUS_REPORT_DIR: ${{ inputs.report-dir }}
|
|
244
|
+
VISION_E2E_WORKING_DIR: ${{ inputs.working-directory }}
|
|
245
|
+
ARGUS_HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
|
|
246
|
+
run: node "${{ github.action_path }}/emit-review.mjs"
|