feat(DEVA11Y-657): composite GitHub Action (v1 scan+report)#1
feat(DEVA11Y-657): composite GitHub Action (v1 scan+report)#1Crash0v3rrid3 wants to merge 4 commits into
Conversation
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>
…y 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>
Code reviewReviewed the composite action (bugs + security; no CLAUDE.md in this repo). Found 1 functional issue — now fixed in
Also corrected the preflight fork-safety comments: Verified clean: OIDC request URL separator ( No remaining high-confidence issues. Verdict: PASS (draft — placeholders for CLI version, service URL/audience, and the pinned action SHA remain, as expected pre-GA). 🤖 Generated with Claude Code |
- 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>
…-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>
| agent you already use, which then acts under _your_ credentials. BrowserStack runs no | ||
| AI model and never handles your AI keys. **v1 is scan + report**; whether the agent | ||
| reviews or fixes is up to that agent (see "Optional: agent hand-off" below for what | ||
| works today). |
There was a problem hiding this comment.
Remove the parts "Browserstack runs no...what works today"
| reviews or fixes is up to that agent (see "Optional: agent hand-off" below for what | ||
| works today). | ||
|
|
||
| Learn more: <https://browserstack.com> |
There was a problem hiding this comment.
| @@ -1,2 +1,166 @@ | |||
| # browserstack-accessibility-devtools-action | |||
| A package to support Accessibility Devtools Action | |||
| # BrowserStack Accessibility for GitHub | |||
There was a problem hiding this comment.
BrowserStack Accessibility DevTools for GitHub
| A Service Account is a non‑personal, admin‑managed key built for CI — it uses | ||
| no user license and can be rotated or revoked independently. (Enterprise plan.) |
| Add `.github/workflows/browserstack-a11y.yml`: | ||
|
|
||
| ```yaml | ||
| name: BrowserStack Accessibility |
There was a problem hiding this comment.
name: BrowserStack Accessibility DevTools
| steps: | ||
| # Use the v1 major tag for automatic patch/minor updates, or pin to a | ||
| # full commit SHA for supply-chain hardening (recommended for production). | ||
| - uses: browserstack/browserstack-accessibility-devtools-action@v1 |
There was a problem hiding this comment.
Can we avoid mentioning v1 here? So that it always uses the latest version of the action
|
|
||
| Add `.github/workflows/browserstack-a11y.yml`: | ||
|
|
||
| ```yaml |
There was a problem hiding this comment.
@Crash0v3rrid3 Can we add the ready to copy version here instead of a separate link?
|
|
||
| ## Inputs | ||
|
|
||
| | Input | Default | Description | |
There was a problem hiding this comment.
@Crash0v3rrid3 Are we supporting all of these inputs?
There was a problem hiding this comment.
Which input toggles line-by-line commenting?
| | `comment` | `true` | Post a summary findings comment on the PR. | | ||
| | `check-gate` | `true` | Publish a Check Run / commit status for the PR. | | ||
| | `fail-on-severity` | `error` | Fail the check at this severity and above: `error`, `warning`, or `none`. | | ||
| | `inline-suggestions` | `false` | Add one‑click suggestion blocks on offending lines. | |
There was a problem hiding this comment.
@Crash0v3rrid3 What do the suggestion blocks contain?
| ai-agent: coderabbitai # BrowserStack posts "@coderabbitai" | ||
| ``` | ||
|
|
||
| What works today (honest status — this is a preview, off by default): |
There was a problem hiding this comment.
This reads like an internal note. Instead of this section, let's just add a generic disclaimer that this feature will be supported if the AI agent accept triggers from a bot/App.
"- If your agent ignores bot authors by default, allow‑list the BrowserStack
Accessibility bot in its config." -> Add this as a pre-requisite under agent hand-off section.
| > **v1 is scan + report.** A guaranteed AI-_fix_ path is not part of v1; the hand-off | ||
| > above is a preview and is a **silent no-op** if the agent isn't configured to accept it. | ||
|
|
||
| ## Privacy & security |
| your runner. | ||
| - The scan reads only the pull request's changed files. | ||
|
|
||
| ## Support |
There was a problem hiding this comment.
Just add one link https://www.browserstack.com/support. Remove the others.
| - Product & docs: <https://browserstack.com> | ||
| - Accessibility API reference (including rate limits): <https://www.browserstack.com/docs/accessibility/api> | ||
|
|
||
| ## License |
DEVA11Y-657 — Composite GitHub Action (v1: scan + report)
Ships the public composite Action for the CI/CD accessibility flow (Epic DEVA11Y-463, ADR-0035/0036).
A developer comments
@AccessibilityDevToolson a PR → this Action runs the published@browserstack/accessibility-devtoolsCLI in PR-scan mode, authenticated by a BrowserStack Service Account key (zero GitHub credentials on the runner) → the CLI sends findings to linter-server, which normalizes + HMAC-signs them (scanProof) → the runner forwards{report, scanProof}(plus a best-effort Actions OIDC token) to the ci-review-service, which verifies and posts as the GitHub App.What's in this PR
action.yml— composite Action with the ADR-0035 Appendix A input surface (username,access-key,comment,check-gate,fail-on-severity,inline-suggestions,sarif,comment-mode,remediation,ai-agent) and outputs (result,error-count,warning-count,findings-count,comment-url,sarif-file).examples/browserstack-a11y.yml— reference consumer workflow (on: issue_comment,permissions: contents/pull-requests read + id-token write)..github/workflows/release.yml— versioned release/bundle pipeline (SHA-pinned CLI, taggeddist).README.md,LICENSE,.gitignore.Fork-PR safety
"Diff, don't build" — no
npm install/postinstallof untrusted head code; degrades to skip when OIDC/secrets are restricted.Status / dependencies
🤖 Generated with Claude Code