Designrail Add to Chrome

Updated

Designrail GitHub Action reference

The Designrail GitHub Action runs the designrail CLI in your workflows. In check mode it lints source files against DESIGN.md with annotations on the pull request diff and, given a URL, scores a preview deployment. In sync mode it rescans your production site and opens a pull request when the design has changed, so DESIGN.md and the agent rule files stay current.

Install

Reference the action from a workflow step after actions/checkout:

- uses: actions/checkout@v4
- uses: designrail/designrail/action@v0

It is a composite action. Each run sets up Node.js 22 (actions/setup-node@v4) and pnpm (pnpm/action-setup@v4), then runs pnpm dlx designrail@<version>, so nothing needs to be installed in your repository. If your root package.json pins pnpm with a packageManager field such as "pnpm@9.15.0", that version is installed; otherwise pnpm 10. Passing both would make pnpm/action-setup fail with "Multiple versions of pnpm specified". The repository needs a committed DESIGN.md for check mode; create one with designrail scan <url> --install or let sync mode create it.

Inputs

Input Default What it does
mode check check or sync
design DESIGN.md Path to DESIGN.md: read in check mode, written in sync mode
paths src Space-separated source paths for lint-code (check mode)
max-warnings empty Fail when lint-code reports more warnings than this; token-literal notices don't count; empty never fails (check mode)
url empty check: a preview or staging URL to render and score. sync: the production site to rescan
fail-under empty Fail when the rendered page scores below this, 0–100 (check mode with url)
site false Crawl same-origin pages too (url checks and sync)
pages 10 Page budget when site is true
version empty designrail version from npm; empty uses the CLI version released with the Action ref you use (packages/cli/package.json at that ref)
github-token ${{ github.token }} Token for opening the sync pull request (sync mode); needs contents and pull-requests write

Outputs

Output Set when Value
score check mode with url, when the report was written Score of the rendered page, 0–100
pr-url sync mode, when the design changed URL of the sync pull request (new or already open)

Give the step an id to read them, for example ${{ steps.design.outputs.score }}.

Mode: check

check is the default. It runs up to two steps.

Lint source. Always runs in check mode:

pnpm dlx designrail@<version> lint-code <paths> --design <design> --format github [--max-warnings <n>]

Findings appear as annotations on the changed files: ::warning for raw-color, palette-class, off-grid and unknown-font, and ::notice for token-literal. max-warnings counts warnings only, so max-warnings: 0 fails on an off-palette colour but not on a typed-out token value, which stays a notice. See the lint-code rules for what each rule finds. A line containing a designrail-ignore comment is skipped.

Score a rendered page. Runs only when url is set:

pnpm dlx designrail@<version> check <url> --design <design> --json design-check.json --fix design-fixes.md [--site --pages <n>] [--fail-under <n>]

The step runs with CI=true, so Chrome starts with --no-sandbox --disable-dev-shm-usage. When design-check.json was written, the step sets the score output and appends a "Design system check" section containing the fix list to the job summary, ready to paste into Claude Code, Cursor or Codex. It then exits with the CLI's status, so the job fails when the score is below fail-under or the check could not run. design-check.json and design-fixes.md are left in the workspace root if you want to upload them as artefacts.

A URL without a scheme gets https://, or http:// for localhost, 127.0.0.1, [::1], *.localhost and *.test. Preview deployments are HTTPS, so pass them in full.

Check every pull request

Save as .github/workflows/design-check.yml:

name: Design check
on: pull_request
jobs:
  design:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: designrail/designrail/action@v0
        with:
          paths: src app components
          max-warnings: 0

Score a preview deployment

With a preview deployment (Vercel, Netlify, Cloudflare Pages), pass its URL and a minimum score. Source linting still runs in the same step.

      - uses: designrail/designrail/action@v0
        id: design
        with:
          url: ${{ steps.preview.outputs.url }}
          fail-under: 90
      - run: echo "Design score ${{ steps.design.outputs.score }}"
        if: always()

Mode: sync

sync rescans a production site and opens a pull request when the extracted design differs from what is committed. It requires url and fails with "sync mode needs the url input" otherwise. It does not lint, and it ignores paths, max-warnings and fail-under.

What it does:

  1. Runs designrail scan <url> --install --out . (plus --site --pages <n> when site is true), writing AGENTS.md, .claude/skills/, .cursor/rules/, .github/instructions/ and design-system/ at the repository root, where agents look for them, and DESIGN.md at the design path. See scan --install for the file list. When design is not the root DESIGN.md, an existing root DESIGN.md is left as it was.
  2. Decides whether anything changed. Changes in the agent files and design-system/ count; for DESIGN.md, the two lines that carry the scan date are ignored, so a rescan with no design change opens no pull request. A DESIGN.md that is not yet tracked at the design path counts as a change.
  3. If something changed, commits as designrail[bot] to the branch designrail/sync-YYYYMMDD with the message "Update design system from <url>", pushes with --force-with-lease, and opens a pull request, or reuses the open one for that branch. The pr-url output is set.

If nothing changed it prints "Design system unchanged." and succeeds.

Keep DESIGN.md in sync with production

Save as .github/workflows/design-sync.yml. It runs every Monday at 06:00 UTC and on demand:

name: Design sync
on:
  schedule: [{ cron: '0 6 * * 1' }]
  workflow_dispatch:
permissions:
  contents: write
  pull-requests: write
jobs:
  sync:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: designrail/designrail/action@v0
        with:
          mode: sync
          url: https://www.example.com
          site: true

Review the token changes in DESIGN.md before merging: agents read these files.

Permissions

Mode Workflow permissions Notes
check Defaults (contents: read for checkout) Annotations and the job summary need no extra permissions
sync contents: write, pull-requests: write Needed to push the branch and open the pull request

For sync with the default GITHUB_TOKEN, the repository (or its organisation) must also allow it to open pull requests: Settings → Actions → General → Workflow permissions → "Allow GitHub Actions to create and approve pull requests". New personal repositories have this off. See GitHub's documentation.

Pull requests opened with GITHUB_TOKEN create pull_request workflow runs that wait for approval, so your design check will not start on the sync pull request by itself. To have it run automatically, pass a GitHub App installation token or a personal access token as github-token (GitHub's documentation). The branch push itself uses the credentials actions/checkout stored.

Runners and Chrome

lint-code needs no browser. The url check and sync need Chrome or Edge: GitHub-hosted Ubuntu runners include Google Chrome. On self-hosted runners, install Chrome or set CHROME_PATH to the browser executable in the job's env.

To give agents the same rules while they write code, before CI runs, use the MCP server.

FAQ

Does check mode fail the build by default?

No. With max-warnings and fail-under empty, findings are reported as annotations and in the job summary, but the step only fails if the CLI itself errors, for example when DESIGN.md cannot be read.

Can I pin the designrail version?

Yes. Set the version input to an npm version of designrail. Left empty, it uses the CLI version from packages/cli/package.json at the Action ref you reference (for example v0), so the Action and the CLI it runs are released together. Each run calls pnpm dlx designrail@<version>.

Why did sync open no pull request after a rescan?

Nothing in the extracted design changed. The scan date lines in DESIGN.md are ignored when comparing, so only real token or rule changes produce a pull request.

Where does sync write DESIGN.md?

At the design path, DESIGN.md at the repository root by default. The agent rule files and design-system/ always go to the repository root. Their text refers to "DESIGN.md at the repo root", so if you keep DESIGN.md elsewhere, say where in your own AGENTS.md notes outside the Designrail block.