Repository navigation
Commit f7f1412
feat(DEVA11Y-657): composite GitHub Action (v1 scan+report) (#1)
* feat(DEVA11Y-463): composite GitHub Action (v1 scan+report)
Scaffold the public browserstack-accessibility-devtools-action repo per
ADR-0035 Appendix A (GitHub App + Service Account model).
- action.yml: composite action. Inputs username/access-key (required, secret),
comment, check-gate, fail-on-severity, inline-suggestions, sarif, comment-mode,
remediation, ai-agent (validated ^[A-Za-z0-9-]+(\[bot\])?$). Outputs result,
error-count, warning-count, findings-count, comment-url, sarif-file. Hardcoded:
@AccessibilityDevTools trigger, diff scope, deva11y.config.* inference, commenter
write/maintain/admin permission gate. Steps implement fork-PR "diff, don't build"
safety (no install/postinstall of head code; skip when OIDC/secrets restricted),
pinned npx CLI (placeholder 1.3.0), Actions OIDC mint (aud placeholder
browserstack-accessibility-devtools), and POST to ci-review-service /v1/findings
with {platform,repo,prNumber,headSha,findings,scanProof,oidcToken} + X-CI-Platform
header. The Action holds no GitHub write credential; the App posts server-side.
- examples/browserstack-a11y.yml: reference consumer workflow (issue_comment,
read-only token + id-token: write, concurrency, if-guard).
- .github/workflows/release.yml: release stub (esbuild dist build guard, action.yml
validation, manual org-admin Marketplace publish note).
- README.md: public customer README (v1 = scan + report; agent hand-off preview
off by default; homepage browserstack.com).
- LICENSE (MIT), .gitignore.
Placeholders pending provisioning: CLI version 1.3.0, OIDC audience and service URL
(https://devtools-a11y-linter.browserstack.com), GitHub App. Draft PR.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* fix(DEVA11Y-657): don't hard-fail the commenter gate under a read-only token
The commenter permission pre-check called GET /collaborators/{user}/permission,
which requires push access. The documented least-privilege workflow token
(contents: read) cannot call it, so the request 403s, the `|| echo none`
fallback yielded "none", and the action refused to scan for EVERY commenter —
non-functional under its own recommended setup.
Make the client-side check best-effort: fast-refuse only on a DEFINITIVE
non-privileged role; on an inconclusive call (the read-only-token case) proceed
and rely on the authoritative server-side fail-closed permission gate in the
ci-review-service (ADR-0035 §5). The runner is the customer's and was never the
security boundary.
Also correct the preflight fork-safety comments: issue_comment workflows run in
base-repo context with secrets available even for fork PRs, so cred-absence is
not what protects fork PRs — the permission gate + "diff, don't build" are.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* chore(DEVA11Y-657): ready action for merge — @v1 refs + PR CI gate
- example workflow + README now reference @v1 (with a note to SHA-pin for
production) instead of the @<commit-sha> placeholder
- add .github/workflows/ci.yml: PR gate validating action.yml structure +
YAML well-formedness (the repo previously had no PR checks)
CLI version pin (action.yml) stays a documented release-time value — no
pr-scan CLI version is published to npm yet; the release step pins the real
version. GitHub App id / service URL remain provisioning placeholders.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* feat(DEVA11Y-657): pin CLI to published 1.5.0; finalize audience/base-URL comments
@browserstack/accessibility-devtools 1.5.0 is published (npmjs `latest`) and
includes PR-scan mode, so pin CLI_VERSION 1.3.0 -> 1.5.0. The OIDC audience
(browserstack-accessibility-devtools) already matches the deployed
ci-review-service verifier config, and SERVICE_URL is the real global ingress;
drop the stale PLACEHOLDER comments accordingly.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* docs(DEVA11Y-657): address @aveek-bs README review
- Title -> "BrowserStack Accessibility DevTools for GitHub"; workflow name ->
"BrowserStack Accessibility DevTools".
- Learn-more link -> /docs/accessibility-dev-tools/features/remediate-github.
- Drop the internal-sounding "BrowserStack runs no AI model…what works today"
copy from the intro bullet.
- Remove the Service-Account "no user license…Enterprise plan" aside.
- Inline the full ready-to-copy workflow in Quick start; drop the separate
examples/ link.
- Agent hand-off: replace the "what works today" internal note with a generic
preview disclaimer, and add the bot allow-list as a prerequisite.
- Remove Privacy & security and License sections.
- Support -> single https://www.browserstack.com/support link.
- examples/: use @main (always latest) instead of @v1; match workflow name.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* fix(DEVA11Y-657): use CLI 1.5.0 --pr-scan contract (fixes 'unknown option --head')
The action called a nonexistent `scan` subcommand with --head/--changed-files/
--output and then minted OIDC + POSTed itself. Published CLI 1.5.0 does the whole
PR-scan via `--pr-scan`: resolves the base..head diff locally (git), gets
linter-server to normalize + HMAC-sign, mints the Actions OIDC token, and submits
to the ci-review-service (POST <ci-service-url>/v1/findings) which posts as the App.
- scan step -> `--pr-scan --include '**/*' --base <sha> --head-sha <sha> --repo
<owner/name> --pr-number <n> --ci-service-url https://devtools-a11y-linter.browserstack.com`
(--head-sha, not --head; drop --changed-files/--output/--format — the CLI derives
the diff and submits itself). fail-on-severity=none -> --non-strict.
- Remove the now-redundant `oidc` and `submit` steps (the CLI does both).
- `report` gates on the CLI exit code (0 pass; 1/3/4/other fail).
Known 1.5.0 limits (documented inline): --pr-scan does not forward the comment/
inline/sarif/remediation options or return per-severity counts / comment URL — the
ci-review-service applies defaults; those outputs need a CLI enhancement.
NOTE: --ci-service-url uses the shared host, so POST /v1/findings must be routed to
ci-review-service on devtools-a11y-linter.browserstack.com (currently only /github
is routed) for the submit to land.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* feat(DEVA11Y-657): automatic PR trigger, honest inputs, real outputs + severity gate
Addresses review feedback (inputs must be real, not for show; guide users to the
automatic detection flow; VS Code output format) and the flag audit.
action.yml:
- Automatic flow (primary): trigger on pull_request opened/synchronize/reopened/
ready_for_review (actor = PR author, no commenter gate). Manual @mention stays
as the secondary flow (with the commenter permission pre-check).
- Trim inputs to the ones that do something: username, access-key,
fail-on-severity. Removed comment / check-gate / comment-mode /
inline-suggestions / sarif (now always-on server defaults) and
remediation / ai-agent (deferred preview). check-gate is folded into
fail-on-severity (none = never fail).
- Real gate + outputs: parse the CLI's `[deva11y-result]` line into
error-count / warning-count / findings-count / comment-url, and fail the run
per fail-on-severity (a real `warning` gate, and `error` actually fails now —
previously --pr-scan always exited 0 so the check never failed). Operational
errors (FUP/permission/error) always fail. Dropped the sarif-file output
(SARIF is uploaded server-side; there is no local file).
README + example:
- Automatic-first quick start (on: pull_request + issue_comment), @main (no v1 pin).
- Inputs/outputs tables reflect reality; describe what actually gets posted
(sticky comment, inline comments in VS Code format, Check Run, SARIF).
- Inline are review comments, not one-click suggestion blocks (findings carry
how-to-fix text, not literal replacement code) — corrected the earlier claim.
- Single support link; removed the internal-note remediation section.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* feat(DEVA11Y-657): re-add AI remediation hand-off via a single ai-agent input
Per review: keep remediation with a generic disclaimer (rather than dropping it).
- action.yml: `ai-agent` input (optional, bare name); a validate-agent step
(charset ^[A-Za-z0-9-]+(\[bot\])?$, fail fast); passes `--ai-agent` to the CLI
only when set. Single input — presence enables the hand-off (no separate
`remediation` boolean).
- README: ai-agent row + a short "AI remediation hand-off (preview)" section with
the generic disclaimer (supported if your agent accepts bot/App triggers).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* chore(DEVA11Y-657): bump pinned CLI to 1.5.1
1.5.1 ships the --pr-scan additions consumed by this action: the machine-readable
[deva11y-result] stdout line (populates the error/warning/findings-count +
comment-url outputs) and --ai-agent forwarding. Bumps the CLI_VERSION pin from
1.5.0 so the action's outputs and the ai-agent mention activate.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* docs(action): remove internal references from action.yml comments
Public repo — drop internal-only terms from the action source: ADR-#### design
references, the DEVA11Y-### ticket, and internal component/mechanism names
(scanProof, ci-review-service, linter-server). Reworded the header and step
comments in plain, customer-facing language; kept the product term 'Service
Account' and the functional [deva11y-result] CLI stdout token (the published CLI
emits it and the action must grep it verbatim).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* docs(action): drop the (preview) label from the ai-agent feature (review)
Resolves Aveek's two README review comments — remove 'preview' from the ai-agent
input row and the AI remediation hand-off heading.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>1 parent 1e67b1f commit f7f1412
7 files changed
Lines changed: 668 additions & 2 deletions
File tree
- .github/workflows
- examples
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
2 | | - | |
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
0 commit comments