Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions .github/workflows/code-connect.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
name: 'Figma Code Connect'

# Keeps the Figma Code Connect mappings (libs/figma/*.figma.ts) in sync with
# Figma. Previously this was only ever run by hand — `@figma/code-connect` isn't
# even a declared dependency — so Dev Mode was only as fresh as the last person
# who remembered to run `figma connect publish` locally with a personal token.
#
# - On PRs touching the mappings: `parse` (validate every file locally, no
# token, no publish) so a broken mapping fails the PR instead of silently
# shipping stale code snippets.
# - On merge to main (or manual dispatch): `publish` the mappings to Figma so
# each connected component emits its `pds-*` example in Dev Mode.

on:
pull_request:
branches: ['**']
paths:
- 'libs/figma/**'
- 'figma.config.json'
- '.github/workflows/code-connect.yml'
push:
branches: [main]
paths:
- 'libs/figma/**'
- 'figma.config.json'
- '.github/workflows/code-connect.yml'
workflow_dispatch:

concurrency:
group: code-connect-${{ github.ref }}
cancel-in-progress: true

env:
# Bump to upgrade the Code Connect CLI. Kept as an npx pin (not a package.json
# dependency) so this workflow stays self-contained and matches how the CLI is
# run today; promote to a pinned devDependency if it ever needs to run inside
# the normal build/lint pipeline.
#
# Minimum 1.4.4: `--exit-on-unreadable-files` is only respected for .figma.ts /
# .figma.js templates (our parser is `html`) from 1.4.4 onward. Below that the
# flag is a no-op and an unparseable mapping is silently skipped — the exact
# green-but-stale failure this workflow guards against.
CODE_CONNECT_VERSION: '1.5.3'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nonexistent CLI version pin

High Severity

CODE_CONNECT_VERSION is pinned to @figma/code-connect@1.5.3, but that release is not on npm — latest is 1.5.2. Both npx steps resolve that package, so validate and publish fail on every run instead of parsing or publishing mappings.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 1ca1f25. Configure here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

False positive — 1.5.3 is live on npm. npm view @figma/code-connect@1.5.3 resolves (published 2026-08-12, tarball present) and dist-tags.latest1.5.3. The "latest is 1.5.2" appears to be a stale index; 1.5.2 shipped 2026-08-03, 1.5.3 nine days later. Keeping the pin at 1.5.3 (also comfortably ≥ the 1.4.4 required for --exit-on-unreadable-files to apply to .figma.ts).


jobs:
# PR gate: parse the *.figma.ts files against figma.config.json. Local only —
# no Figma access, no token — so it's safe to run on forks and validates that
# every mapping still compiles and resolves its imports/substitutions.
validate:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Set up Node.js (pinned npm)
uses: ./.github/workflows/actions/setup-node-with-pinned-npm
with:
node-version-file: '.nvmrc'
- name: Parse Code Connect files (validate, no publish)
shell: bash
# --exit-on-unreadable-files: fail instead of silently skipping a file the
# CLI can't parse — otherwise a broken mapping passes the gate green.
run: npx -y --package=@figma/code-connect@${CODE_CONNECT_VERSION} figma connect parse --exit-on-unreadable-files
Comment thread
cursor[bot] marked this conversation as resolved.

# Publish on merge to main or manual dispatch. Requires the FIGMA_ACCESS_TOKEN
# secret (a Figma personal access token with Code Connect write scope).
publish:
if: github.event_name != 'pull_request'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Set up Node.js (pinned npm)
uses: ./.github/workflows/actions/setup-node-with-pinned-npm
with:
node-version-file: '.nvmrc'
- name: Guard — require FIGMA_ACCESS_TOKEN
shell: bash
env:
FIGMA_ACCESS_TOKEN: ${{ secrets.FIGMA_ACCESS_TOKEN }}
run: |
if [ -z "${FIGMA_ACCESS_TOKEN}" ]; then
echo "::error::FIGMA_ACCESS_TOKEN secret is not set — cannot publish Code Connect. Add a Figma personal access token (Code Connect write scope) under repo Settings → Secrets and variables → Actions."
exit 1
fi
- name: Publish Code Connect to Figma
shell: bash
env:
FIGMA_ACCESS_TOKEN: ${{ secrets.FIGMA_ACCESS_TOKEN }}
# --exit-on-unreadable-files: fail the publish rather than shipping a
# partial set and leaving stale Dev Mode snippets for the skipped files.
run: npx -y --package=@figma/code-connect@${CODE_CONNECT_VERSION} figma connect publish --exit-on-unreadable-files
20 changes: 18 additions & 2 deletions libs/figma/CODE_CONNECT_COVERAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

This file tracks which Pine `pds-*` components have a matching Code Connect file under `libs/figma/`. Update this list when you add or remove mappings.

## How mappings reach Figma

The `.figma.ts` files are published to Figma by the **Figma Code Connect** workflow (`.github/workflows/code-connect.yml`):

- **PRs** touching `libs/figma/**` or `figma.config.json` run `figma connect parse` — a local validation that every mapping compiles and resolves, no token, no publish.
- **Merges to `main`** (and manual dispatch) run `figma connect publish`, which requires the `FIGMA_ACCESS_TOKEN` secret (a Figma PAT with Code Connect write scope).

Before this workflow, publishing was a manual, undocumented local step — Dev Mode was only as fresh as the last person who remembered to run it.

## Mapped (Code Connect present)

| Pine component / pattern | Code Connect file |
Expand Down Expand Up @@ -37,7 +46,6 @@ Use `figma.config.json` at the repo root (`documentUrlSubstitutions`) when addin
| Pine component | Notes |
| --- | --- |
| `pds-accordion` | Add `components/pds-accordion.figma.ts` when the Figma node is ready. |
| `pds-box` | Layout primitive; may map to layout frames rather than a single component node. |
| `pds-combobox` | |
| `pds-container` | |
| `pds-copytext` | |
Expand All @@ -49,5 +57,13 @@ Use `figma.config.json` at the repo root (`documentUrlSubstitutions`) when addin
| `pds-row` | Often used with `pds-box`; may share layout documentation. |
| `pds-sortable` | Figma substitutions exist for sortable list patterns; wire a `pds-sortable.figma.ts` when aligned. |
| `pds-table` | Composite; consider per-subcomponent mappings (row, cell, head) if needed. |
| `pds-text` | |
| `pds-tooltip` | |

## Primitives — not Code-Connectable (no component node)

`pds-box` and `pds-text` **cannot** take a `.figma.ts` file: Code Connect's `figma.connect()` attaches to a Figma **component node**, and neither exists as one in the Pine Figma file:

- **`pds-text`** — text is represented by **text styles** (`✳ Pine styles`: `typography/heading/1..6`, `typography/body`, `typography/body-sm`, …), not a "Text" component.
- **`pds-box`** — layout is **auto-layout + bound spacing/radius variables**, not a "Box"/"Stack"/"Container" component.

Their relationship to code is instead carried as a **style/variable → code map** in the `pine-figma` authoring skill (`skills/pine-figma/reference/primitives.md`): text-style → `pds-text` and auto-layout → `pds-box`. Do not open Code Connect files for these — there is no node to bind to.
Loading