Skip to content

Commit cf43288

Browse files
authored
ci: set up automatic beta releases for eds-tokens (#5180)
* ci: set up automatic beta releases for eds-tokens Every merged Tokens Studio release PR now cuts a pinned 3.0.0-beta.N release of @equinor/eds-tokens on the npm beta dist-tag, mirroring the eds-core-react-next machinery: - new eds-tokens-next release-please component rooted at packages/eds-tokens/src/tokens, using the prerelease versioning strategy (versioning: prerelease + prerelease: true) so fix, feat and even feat! commits only increment the beta counter — the base stays pinned at 3.0.0 until graduation - stable eds-tokens entry excludes src/tokens so pipeline commits never bump the 2.x line - tokens_studio_release.yaml PRs switch from chore: to fix: (unscoped) so release-please picks them up - publish_tokens.yaml gains a beta tag option: reads the version from src/tokens/version.txt and injects the generated src/tokens/{css,dtcg,ts} output into files/exports (temporary additive ./next/* subpaths) at publish time - trigger_publish.yml detects the new manifest key and dispatches the beta publish automatically Part of #5120 * ci: put the whole eds-tokens package in beta instead of a dual channel Rework after design discussion: eds-tokens needs no stable releases while the token system is rewritten on the Tokens Studio pipeline, so the stable/beta split (mirroring eds-core-react-next) is unnecessary. The single eds-tokens component is now the beta line itself: - packages/eds-tokens switches to release-type: simple with the pinned prerelease config; every fix/feat commit to the package cuts a 3.0.0-beta.N release on the beta dist-tag, and latest stays on 2.3.1 until graduation - the version lives in packages/eds-tokens/version.txt, not package.json: four packages depend on eds-tokens via workspace:^ and pnpm publish rewrites that to the package.json version, so it must stay on the last stable version - the separate eds-tokens-next component, its manifest key, seed files and the trigger_publish tokens-beta job are removed; trigger-tokens now dispatches npm-tag=beta during the transition Also addresses review feedback: exclude src/tokens/README.md from release detection, and document that ./next/ts/* ships raw TypeScript. Part of #5120 * ci: address review nits in publish workflows - note the prepublishOnly ordering dependency on the beta package.json edits in publish_tokens.yaml - read version.txt with input redirection instead of cat|tr in both beta version steps * ci: use feat for the automated Tokens Studio release PRs A Tokens Studio release delivers new or changed tokens — the package's user-facing deliverable — so the changelog entry belongs under Added, not Fixed. The commit type doesn't affect the version during the beta: the prerelease strategy pins the base and only increments the counter for fix and feat alike. * ci: match existing files glob style in beta injection
1 parent 6812d42 commit cf43288

11 files changed

Lines changed: 116 additions & 13 deletions

File tree

.github/release-please-config.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,14 @@
8181
]
8282
},
8383
"packages/eds-tokens": {
84-
"release-type": "node",
84+
"release-type": "simple",
8585
"package-name": "@equinor/eds-tokens",
8686
"component": "eds-tokens",
87+
"versioning": "prerelease",
88+
"prerelease": true,
89+
"prerelease-type": "beta",
8790
"exclude-paths": [
91+
"packages/eds-tokens/src/tokens/README.md",
8892
"packages/eds-tokens/tokens",
8993
"packages/eds-tokens/build-generate-variables",
9094
"packages/eds-tokens/scripts",

.github/release-please-config.md

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ We currently track these packages for releases:
5454
3. `@equinor/eds-data-grid-react` - Data grid component
5555
4. `@equinor/eds-icons` - Icon library
5656
5. `@equinor/eds-lab-react` - Experimental components
57-
6. `@equinor/eds-tokens` - Design tokens and variables
57+
6. `@equinor/eds-tokens` - Design tokens and variables (**entirely in beta** during the Tokens Studio rewrite — published with the `@beta` tag as a pinned `3.0.0-beta.N` series; `latest` stays on the last stable 2.x)
5858
7. `@equinor/eds-utils` - Shared utilities
5959

6060
### Dual Release Strategy for `@equinor/eds-core-react`
@@ -97,6 +97,29 @@ The `eds-core-react` package uses a **dual release strategy** to support both st
9797
- `prerelease-type: "beta"`: Adds `-beta.X` suffix to versions
9898
- `changelog-path`: Uses separate changelog for beta releases
9999

100+
### `@equinor/eds-tokens`: Whole Package in Beta
101+
102+
Unlike core-react, `eds-tokens` has **no stable/beta split** — the entire package is in beta while the token system is rewritten on the Tokens Studio pipeline (issue #5120). No stable releases are cut until the rework graduates as `3.0.0`; consumers on `latest` stay on the last stable 2.x:
103+
104+
```json
105+
"packages/eds-tokens": {
106+
"release-type": "simple",
107+
"package-name": "@equinor/eds-tokens",
108+
"component": "eds-tokens",
109+
"versioning": "prerelease",
110+
"prerelease": true,
111+
"prerelease-type": "beta",
112+
"exclude-paths": ["..."]
113+
}
114+
```
115+
116+
- Every release is a pinned `3.0.0-beta.N`, published to `@equinor/eds-tokens@beta` by `publish_tokens.yaml` (`trigger_publish.yml` dispatches it with `npm-tag=beta` during the transition)
117+
- Releases are cut by any `fix`/`feat` commit touching the package — in practice mostly the automated `feat: update tokens from Tokens Studio release` PRs from `tokens_studio_release.yaml`
118+
- **Why `release-type: "simple"` (version.txt) instead of `node` (package.json):** four packages depend on `@equinor/eds-tokens` via `workspace:^`, and `pnpm publish` rewrites that to the version in eds-tokens' `package.json`. Keeping `package.json` at the last stable version means stable releases of e.g. `eds-core-react` keep depending on stable tokens; the beta version lives in `version.txt` and is applied by the publish workflow at publish time
119+
- An urgent stable 2.x patch during the transition is a manual job (branch from the `eds-tokens@v2.3.1` tag and publish by hand) — accepted trade-off
120+
121+
**Why `versioning: "prerelease"` + `prerelease: true`:** `prerelease-type` alone does **not** increment the beta counter — the default versioning strategy bumps the base version and carries the prerelease suffix through unchanged, which is how the core-react beta line drifted `2.6.0-beta.0 → 2.7.0-beta.1 → 2.8.0-beta.1` (see issue #5141). With the `prerelease` versioning strategy and the base pinned at a major boundary (`3.0.0`), **every** commit type — `fix`, `feat`, even `feat!` — increments only the counter: `3.0.0-beta.1`, `3.0.0-beta.2`, … The `prerelease: true` flag is required (without it the strategy releases a stable `3.0.0`) and also marks the GitHub releases as Pre-release. At graduation, flip `prerelease` to `false` and the same configuration emits stable `3.0.0`.
122+
100123
### Exclude Paths
101124

102125
All packages use `exclude-paths` to prevent non-publishable files from triggering version bumps. This includes config files, test files, Storybook, documentation, and build tooling.
@@ -309,6 +332,8 @@ feat(next): redesign Input 2.0 API (breaking)
309332

310333
**Important:** Avoid using `!` (breaking change marker) for beta releases. Beta components are experimental and breaking changes are expected. Using `!` would trigger a major version bump (e.g., `2.0.1-beta.0``3.0.0-beta.0`), which is unnecessary for components under development.
311334

335+
This warning applies to the `eds-core-react-next` entry, which uses the default versioning strategy. The `eds-tokens` entry is immune: with `versioning: "prerelease"` and its base pinned at `3.0.0`, any commit type only increments the beta counter (see the whole-package-in-beta section above).
336+
312337
## Related Files
313338

314339
- **Config**: `.github/release-please-config.json` (this documentation)

.github/release-please-manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@
44
"packages/eds-data-grid-react": "1.3.0",
55
"packages/eds-icons": "1.5.1",
66
"packages/eds-lab-react": "0.11.0",
7-
"packages/eds-tokens": "2.3.1",
7+
"packages/eds-tokens": "3.0.0-beta.0",
88
"packages/eds-utils": "2.2.1"
99
}

.github/workflows/publish_core_react.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ jobs:
143143
if: github.event.inputs.npm-tag == 'beta'
144144
id: set-beta-version
145145
run: |
146-
BETA_VERSION=$(cat packages/eds-core-react/src/components/next/version.txt | tr -d '[:space:]')
146+
BETA_VERSION=$(tr -d '[:space:]' < packages/eds-core-react/src/components/next/version.txt)
147147
echo "Beta version: $BETA_VERSION"
148148
cd packages/eds-core-react
149149
npm version "$BETA_VERSION" --no-git-tag-version --allow-same-version

.github/workflows/publish_tokens.yaml

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@ on:
55
workflow_dispatch:
66
inputs:
77
npm-tag:
8-
description: 'Tag for npm package (next | latest)'
8+
description: 'Tag for npm package (next | latest | beta)'
99
required: true
1010
type: choice
1111
options:
1212
- next
1313
- latest
14+
- beta
1415
default: 'next'
1516
env:
1617
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
@@ -89,6 +90,48 @@ jobs:
8990
uses: pnpm/action-setup@v6
9091
with:
9192
run_install: false
93+
# Beta releases publish the pinned 3.0.0-beta.N version managed by
94+
# release-please in version.txt. package.json stays at the last
95+
# stable version in git so that pnpm's workspace:^ rewriting keeps
96+
# other packages' stable releases depending on stable tokens.
97+
- name: Set beta version from version.txt
98+
if: github.event.inputs.npm-tag == 'beta'
99+
id: set-beta-version
100+
run: |
101+
BETA_VERSION=$(tr -d '[:space:]' < packages/eds-tokens/version.txt)
102+
echo "Beta version: $BETA_VERSION"
103+
cd packages/eds-tokens
104+
npm version "$BETA_VERSION" --no-git-tag-version --allow-same-version
105+
echo "Updated package.json version to $BETA_VERSION"
106+
# The Tokens Studio pipeline output (src/tokens/{css,dtcg,ts}) is only
107+
# published on the beta line, additively under ./next/* subpaths. The
108+
# stable specifiers (./css/variables etc.) keep serving the legacy
109+
# build until the new output replaces it at graduation.
110+
# Ordering dependency: these package.json edits (and the version bump
111+
# above) happen before `pnpm publish` runs prepublishOnly (the build) —
112+
# if a build step ever starts generating package.json, it would
113+
# silently overwrite them.
114+
- name: Add Tokens Studio output for beta release
115+
if: github.event.inputs.npm-tag == 'beta'
116+
id: add-tokens-studio-output
117+
run: |
118+
cd packages/eds-tokens
119+
for dir in src/tokens/css src/tokens/dtcg src/tokens/ts; do
120+
if [ ! -d "$dir" ]; then
121+
echo "::error title=Missing Tokens Studio output::$dir does not exist — a beta cannot be published before the first tokens_studio_release PR has been merged"
122+
exit 1
123+
fi
124+
done
125+
node -e "
126+
const fs = require('fs');
127+
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
128+
pkg.files.push('src/tokens/css/*', 'src/tokens/dtcg/*', 'src/tokens/ts/*');
129+
pkg.exports['./next/css/*'] = './src/tokens/css/*';
130+
pkg.exports['./next/dtcg/*'] = './src/tokens/dtcg/*';
131+
pkg.exports['./next/ts/*'] = './src/tokens/ts/*';
132+
fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2));
133+
console.log('Added Tokens Studio output to files and exports');
134+
"
92135
- name: Publish to npm
93136
id: publish-to-npm
94137
working-directory: packages/eds-tokens

.github/workflows/tokens_studio_release.yaml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,14 @@ jobs:
9090
- name: Create Pull Request
9191
uses: peter-evans/create-pull-request@v8
9292
with:
93-
commit-message: 'chore: update tokens from Tokens Studio release'
94-
title: 'chore: update tokens from Tokens Studio release'
93+
# feat: so release-please cuts an eds-tokens beta (3.0.0-beta.N)
94+
# when the PR is squash-merged (chore: would not trigger a
95+
# release). During the beta the commit type doesn't affect the
96+
# version — the prerelease strategy pins the base and only
97+
# increments the counter — but feat lands the entry under
98+
# "Added" in the changelog, which is what a token update is.
99+
commit-message: 'feat: update tokens from Tokens Studio release'
100+
title: 'feat: update tokens from Tokens Studio release'
95101
body: 'Automated pull of the token state after a Tokens Studio release: raw token sets via `studio tokens pull` (sources in `packages/eds-tokens/.studio.json`), generated CSS (EDS-CSS export) into `packages/eds-tokens/src/tokens/css/`, DTCG (EDS-DTCG export) into `src/tokens/dtcg/`, and TypeScript modules generated from the two into `src/tokens/ts/`.'
96102
branch: tokens-studio-release
97103
# This workflow runs unattended (release-triggered) and the PR it

.github/workflows/trigger_publish.yml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,11 @@ jobs:
318318
echo "❌ Failed to trigger icons publish workflow" >> $GITHUB_STEP_SUMMARY
319319
320320
# Job 8: Trigger tokens publish workflow
321-
# Only runs if the Release Please manifest bumped tokens
321+
# Only runs if the Release Please manifest bumped tokens.
322+
# The whole eds-tokens package is in beta (pinned 3.0.0-beta.N) during
323+
# the Tokens Studio rewrite — every release publishes to the `beta`
324+
# dist-tag while `latest` stays on the last stable 2.x. Flip the tag
325+
# back to `latest` when the rework graduates as stable 3.0.0.
322326
trigger-tokens:
323327
needs: check-releases
324328
if: needs.check-releases.outputs.tokens == 'true'
@@ -332,7 +336,7 @@ jobs:
332336
gh workflow run publish_tokens.yaml \
333337
--repo ${{ github.repository }} \
334338
--ref main \
335-
-f npm-tag=latest
339+
-f npm-tag=beta
336340
continue-on-error: true
337341

338342
- name: Report failure
@@ -423,7 +427,7 @@ jobs:
423427
fi
424428
425429
if [ "${{ needs.check-releases.outputs.tokens }}" == "true" ]; then
426-
echo "- ✅ **@equinor/eds-tokens**: Publish workflow triggered" >> $GITHUB_STEP_SUMMARY
430+
echo "- ✅ **@equinor/eds-tokens**: Publish workflow triggered (beta dist-tag during the Tokens Studio transition)" >> $GITHUB_STEP_SUMMARY
427431
else
428432
echo "- ⏭️ **@equinor/eds-tokens**: No changes, skipped" >> $GITHUB_STEP_SUMMARY
429433
fi

documentation/how-to/BETA_RELEASE_GUIDE.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,21 @@ pnpm storybook
137137

138138
Beta versions follow this pattern: `2.0.1-beta.0`, `2.0.1-beta.1`, etc.
139139

140+
## `@equinor/eds-tokens`: Whole Package in Beta
141+
142+
The tokens package works differently from core-react's dual model: while the token system is rewritten on the Tokens Studio pipeline (issue #5120), the **entire package is in beta**. There is no stable release channel — no stable 2.x releases are cut until the rework graduates as `3.0.0`. Consumers on `latest` simply stay on the last stable 2.x.
143+
144+
| Action | Command |
145+
| ------------------- | ---------------------------------------------------- |
146+
| Install beta tokens | `npm install @equinor/eds-tokens@beta` |
147+
| View beta versions | `npm view @equinor/eds-tokens versions \| grep beta` |
148+
149+
- **Version scheme**: pinned `3.0.0-beta.N` — the base never moves. The entry uses release-please's `prerelease` versioning strategy (`versioning: "prerelease"`, `prerelease: true`), which at a `x.0.0` base increments only the counter for every commit type (`fix`, `feat`, even `feat!`). See `.github/release-please-config.md` for details, including why the version lives in `version.txt` rather than `package.json`.
150+
- **Automatic cadence**: each release in Tokens Studio triggers `tokens_studio_release.yaml`, which opens a `feat: update tokens from Tokens Studio release` PR. Merging it makes release-please add an `eds-tokens` bump to the release PR; merging *that* publishes `3.0.0-beta.N` to the `beta` dist-tag via `publish_tokens.yaml`. Any other `fix`/`feat` commit touching the package cuts a beta the same way.
151+
- **Package contents**: the beta ships everything 2.x ships **plus** the Tokens Studio output under temporary additive subpaths (`@equinor/eds-tokens/next/css/*`, `/next/dtcg/*`, `/next/ts/*`), injected at publish time. Repointing the stable specifiers (`./css/variables` etc.) to the new output is planned before graduation so consumers won't need to change imports.
152+
- **Urgent stable patch**: if a critical 2.x fix is needed during the transition, it's a manual publish from the `eds-tokens@v2.3.1` tag — the automated channel only produces betas.
153+
- **Graduation**: tokens graduate together with the components as part of the single `3.0.0` major — flip `prerelease` to `false` and switch the dist-tag in `trigger_publish.yml` back to `latest`.
154+
140155
## Graduation: Moving from Beta to Stable
141156

142157
Components graduate from `/next` to stable when they meet these criteria:

packages/eds-tokens/CLAUDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Design tokens package — CSS variables, JSON, and JS/TS outputs consumed by EDS
44

55
## Two pipelines coexist
66

7-
The **legacy pipeline** below (Figma REST sync + Style Dictionary) still owns everything the package *publishes* (`build/`, the `exports` map). The **new Tokens Studio pipeline** writes generated output to `src/tokens/{raw,css,dtcg,ts}` via `.github/workflows/tokens_studio_release.yaml` — those directories are **generated, never edit them by hand**, and are not yet wired into the `exports` map. The TS modules are produced by `pnpm run generate:ts-tokens` (`scripts/generate-ts-tokens.mjs` — DTCG export for structure + CSS export for evaluated values; the script header documents the mechanics). Canonical pipeline doc: [`documentation/agent-instructions/TOKENS_STUDIO.md`](../../documentation/agent-instructions/TOKENS_STUDIO.md).
7+
The **legacy pipeline** below (Figma REST sync + Style Dictionary) still owns everything in the published `exports` map (`build/`). The **new Tokens Studio pipeline** writes generated output to `src/tokens/{raw,css,dtcg,ts}` via `.github/workflows/tokens_studio_release.yaml` — those directories are **generated, never edit them by hand**. During the Tokens Studio rewrite the **whole package is in beta**: every release is a pinned `3.0.0-beta.N` on the npm `beta` dist-tag (no stable releases until the rework graduates as `3.0.0`; `latest` stays on the last 2.x). The version is release-please-managed in `version.txt` at the package root — `package.json` stays on the last stable version so pnpm's `workspace:^` rewriting keeps other packages' stable releases depending on stable tokens — and `publish_tokens.yaml` sets the beta version and injects the generated `src/tokens` directories into `files`/`exports` at publish time. The TS modules are produced by `pnpm run generate:ts-tokens` (`scripts/generate-ts-tokens.mjs` — DTCG export for structure + CSS export for evaluated values; the script header documents the mechanics). Canonical pipeline doc: [`documentation/agent-instructions/TOKENS_STUDIO.md`](../../documentation/agent-instructions/TOKENS_STUDIO.md).
88

99
## Build Pipeline (3 steps)
1010

packages/eds-tokens/src/tokens/README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,12 @@ changes. Fix token values in Tokens Studio instead.
1313
| `dtcg/` | DTCG interchange JSON | `studio exports run` (EDS-DTCG configuration) |
1414
| `ts/` | TypeScript modules | `pnpm run generate:ts-tokens` (combines `dtcg/` + `css/`) |
1515

16-
None of this is wired into the package `exports` map yet — the published
17-
artifacts still come from the legacy Style Dictionary build in `build/`.
16+
The generated output is published on the beta line
17+
(`@equinor/eds-tokens@beta`, injected at publish time by
18+
`.github/workflows/publish_tokens.yaml` under temporary additive
19+
`./next/{css,dtcg,ts}/*` subpaths) — the `exports` map in git still serves
20+
the legacy Style Dictionary build in `build/`. Note that `./next/ts/*`
21+
ships raw `.ts` modules (no compiled `.js`/`.d.ts`), so it requires a
22+
TypeScript-aware consumer.
1823

1924
Pipeline documentation: [`documentation/agent-instructions/TOKENS_STUDIO.md`](../../../../documentation/agent-instructions/TOKENS_STUDIO.md).

0 commit comments

Comments
 (0)