CI with GitHub Actions
The two commands that belong in every pipeline:
dta lintexits with 2 when it finds errors (dangling or circular aliases, default mode names, rules you set toerror). Warnings print but exit with 0.dta buildexits with 1 when the token files cannot be read or built, among them a dangling or circular alias, and then writes nothing; otherwise it writes the outputs.
All exit codes: Exit codes.
Workflow
Section titled “Workflow”design-token-authority is a dev dependency of your project (npm create dta adds it), so the workflow installs your dependencies and runs npx design-token-authority (Node.js 24 or newer). With pnpm or yarn, swap the install step and npx for pnpm exec or yarn.
name: tokenson: [push, pull_request]permissions: contents: readjobs: tokens: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 24 - run: npm ci - name: Lint tokens run: npx design-token-authority lint - name: Build outputs run: npx design-token-authority buildCommit the tokens/ folder, not the build output: CI rebuilds it, and dta clean removes it locally.
On pull requests
Section titled “On pull requests”- What changed in the tokens:
dta diff --tokens-only -f markdown -o token-changes.mdwrites the change set as a Markdown table for a comment or the job summary (>> $GITHUB_STEP_SUMMARY). - What it looks like: with a
diffsection in the config (dta initwrites it, and the workflow),dta diffrenders your stories at the base and the head and explains the differences by token. dta diff in pull requests has ready-made actions for the status check and the comment. - Pushing to Figma from CI (Enterprise):
dta push --yesskips the typed confirmation. Rundta push --dry-run --format markdownon the pull request and the real push only on the main branch.
The token diff needs the base commit: check out with fetch-depth: 0, or pass --base <ref|folder>.
Hard-coded values in code
Section titled “Hard-coded values in code”dta audit scans your source for colours, lengths and font families that equal a token and names the token to use (CSS, SCSS, JS/TS/JSX/TSX, the <style> blocks of Astro, Vue and Svelte files, and Tailwind arbitrary values such as bg-[#2f55d4]). It exits with 1 when it finds something. On the brand-ab test fixture:
$ dta auditsrc/Button.css 3:15 #0057b8 background → Colors.Brand.Primary var(--colors-brand-primary) 5:12 16px padding → Dimensions.spacing.4 var(--dimensions-spacing-4)
src/Card.tsx 3:30 #f3f4f6 bg-[…] → Colors.Surface.Muted var(--colors-surface-muted) 3:42 16px p-[…] → Dimensions.spacing.4 var(--dimensions-spacing-4) 3:71 Inter fontFamily → Typography.Body.Family var(--typography-body-family)
5 hard-coded values in 2 files could be tokens.Lengths are compared with the tokens of their kind only: spacing (margin, padding, gap, inset), radius, stroke (border and outline widths) and font size, recognised by Figma scope or by name. Comments, 0, percentages, var() fallbacks, @font-face, tests (*.test.*, *.spec.*), the token files and the build output are skipped; a deliberate value gets a dta-audit-ignore comment on its line or the line before. The scanned folders, ignore globs and languages are the audit section of the config (Configuration).
Add it as its own step, so its status is separate from lint and build. Start advisory, with today’s findings recorded as accepted, and tighten it once the count is down:
# Once, locally: dta audit --update-baseline, then commit .dta/audit-baseline.json- name: Audit hard-coded values run: npx design-token-authority audit --format markdown >> $GITHUB_STEP_SUMMARY continue-on-error: true # advisory; remove to make new findings fail the jobWith the baseline, later runs report only new findings (a finding is recognised by file, value and property, so moving lines does not make it new). --format json prints the findings for scripts and agents (schema).