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
31 changes: 19 additions & 12 deletions .github/PUBLISHING.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ Pull request workflows are skipped for changes only in:

### What Changed

Publishing logic has been moved to a dedicated `publish.yml` workflow file to support npm's [Trusted Publishing](https://docs.npmjs.com/trusted-publishers) feature.
Publishing now uses npm's [Trusted Publishing](https://docs.npmjs.com/trusted-publishers) feature with OIDC authentication. All publishing logic is consolidated in a single `publish.yml` workflow that handles both canary releases (on PRs) and production releases (on push to main). This is required because npm only allows one trusted publisher configuration per package.

### Benefits

Expand All @@ -76,12 +76,10 @@ Publishing logic has been moved to a dedicated `publish.yml` workflow file to su

## Manual Setup Steps

Complete these steps **before** merging the trusted publishing changes:
> ⚠️ **CRITICAL**: Complete Step 1 **BEFORE** any workflow runs. The workflow will fail with `ENEEDAUTH` error if the trusted publisher is not configured first!

### Step 1: Configure Trusted Publisher on npmjs.com

> ⚠️ **Important**: This must be done BEFORE the first publish attempt with the new workflow.

1. Log in to [npmjs.com](https://www.npmjs.com) with an account that has publish access
2. Go to: https://www.npmjs.com/package/@cube-dev/ui-kit/settings
3. Scroll to the **"Trusted Publisher"** section
Expand All @@ -90,12 +88,14 @@ Complete these steps **before** merging the trusted publishing changes:

| Field | Value |
|-------|-------|
| Organization or user | `cube-js` |
| Owner | `cube-js` |
| Repository | `cube-ui-kit` |
| Workflow filename | `publish.yml` |
| Environment name | _(leave empty)_ |
| Environment | _(leave empty)_ |

6. Click **Save**

6. Click **Save** (or the equivalent button)
> **Note**: The `publish.yml` workflow handles both canary releases (on PRs) and production releases (on push to main). npm only allows one trusted publisher configuration, so all publishing logic is consolidated in this single workflow file.

### Step 2: Verify the Setup with a Test PR

Expand Down Expand Up @@ -140,9 +140,8 @@ Once everything is working:

| File | Purpose |
|------|---------|
| `publish.yml` | Reusable workflow for npm publishing (canary and release) |
| `main.yml` | Release workflow triggered on push to main |
| `pull-request.yml` | PR workflow for tests, canary releases, and Chromatic |
| `publish.yml` | Handles all npm publishing (canary on PRs, releases on main) and Chromatic deployment |
| `pull-request.yml` | PR workflow for tests and Chromatic staging |
| `size-limit.yml` | Bundle size measurement |
| `codeql-analysis.yml` | Security analysis |

Expand All @@ -153,13 +152,21 @@ Once everything is working:
Before merging the trusted publishing PR, verify:

- [ ] You have maintainer access to the package on npmjs.com (to configure trusted publisher)
- [ ] Trusted publisher configured on npmjs.com for `publish.yml`
- [ ] Configuration matches exactly: `cube-js/cube-ui-kit/publish.yml`
- [ ] Trusted publisher configured for `publish.yml`
- [ ] Configuration matches exactly: `cube-js` / `cube-ui-kit` / `publish.yml`

---

## Troubleshooting

### `ENEEDAUTH` / "need auth" / "You need to authorize this machine" error

This is the most common error when first setting up trusted publishing:

1. **Trusted publisher not configured yet** — Go to npmjs.com and configure the trusted publisher (Step 1 above)
2. **Configuration mismatch** — Double-check that Owner, Repository, and Workflow filename match EXACTLY: `cube-js` / `cube-ui-kit` / `publish.yml`
3. **Environment mismatch** — If you specified an environment on npmjs.com, the workflow must use the same environment name (we leave it empty by default)

### "Unable to authenticate" error

- Verify the workflow filename matches **exactly** (`publish.yml`, not `Publish.yml`)
Expand Down
81 changes: 0 additions & 81 deletions .github/workflows/main.yml

This file was deleted.

136 changes: 94 additions & 42 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -1,40 +1,30 @@
name: Publish

on:
workflow_call:
inputs:
publish-type:
description: 'Type of publish: "canary" or "release"'
required: true
type: string
pr-number:
description: 'PR number for canary releases'
required: false
type: number
outputs:
published:
description: 'Whether a release was published'
value: ${{ jobs.publish-release.outputs.published || 'false' }}
version:
description: 'Published version'
value: ${{ jobs.publish-canary.outputs.version || jobs.publish-release.outputs.version || '' }}
pull_request:
paths-ignore:
- '.changeset/**'
- '.husky/**'
push:
branches:
- main

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

permissions:
contents: write
pull-requests: write
id-token: write # Required for trusted publishing (OIDC)

jobs:
publish-canary:
name: 'Publish canary'
if: inputs.publish-type == 'canary'
name: 'Build & canary release'
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
id-token: write # Required for trusted publishing (OIDC)
environment:
name: Canary package in NPM
url: https://www.npmjs.com/package/@cube-dev/ui-kit/v/${{ steps.version.outputs.version }}
env:
NODE_OPTIONS: --max-old-space-size=4096
outputs:
version: ${{ steps.version.outputs.version }}
steps:
- uses: actions/checkout@v4

Expand Down Expand Up @@ -64,6 +54,11 @@ jobs:
- name: Update npm for trusted publishing
run: npm install -g npm@latest

- name: Verify npm version and OIDC availability
run: |
echo "npm version: $(npm --version)"
echo "OIDC available: ${{ env.ACTIONS_ID_TOKEN_REQUEST_URL != '' }}"
Copy link

Choose a reason for hiding this comment

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

Bug: OIDC availability check always evaluates to false

The OIDC verification step uses ${{ env.ACTIONS_ID_TOKEN_REQUEST_URL != '' }} to check OIDC availability, but this will always evaluate to false. The ACTIONS_ID_TOKEN_REQUEST_URL is a runtime environment variable injected by GitHub Actions infrastructure, not accessible via the workflow's env context (which only includes variables defined in env: blocks). To check this variable, shell syntax like $ACTIONS_ID_TOKEN_REQUEST_URL must be used instead of the expression context. The diagnostic output will always show "OIDC available: false" regardless of actual OIDC availability, providing misleading information during troubleshooting.

Additional Locations (1)

Fix in Cursor Fix in Web


- name: Install dependencies
run: pnpm install

Expand All @@ -81,9 +76,12 @@ jobs:
- name: Build project
run: pnpm build

- name: Clear .npmrc auth token (use OIDC instead)
run: npm config delete //registry.npmjs.org/:_authToken || true

- name: Publish canary to npm
working-directory: ./dist
run: npm publish --access public --tag pr_${{ inputs.pr-number }}
run: npm publish --access public --tag pr_${{ github.event.number }} --provenance

- name: Comment PR
uses: actions/github-script@v6
Expand All @@ -97,22 +95,17 @@ jobs:
body: 'Deployed canary version [${{ steps.version.outputs.version }}](https://www.npmjs.com/package/@cube-dev/ui-kit/v/${{ steps.version.outputs.version }}).',
github,
repo: context.repo,
prNumber: ${{ inputs.pr-number }}
prNumber: ${{ github.event.number }}
})

publish-release:
name: 'Publish release'
if: inputs.publish-type == 'release'
if: github.event_name == 'push'
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
id-token: write # Required for trusted publishing (OIDC)
env:
NODE_OPTIONS: --max-old-space-size=4096
outputs:
published: ${{ steps.changesets.outputs.published }}
Copy link

Choose a reason for hiding this comment

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

Bug: Missing fallback for published output may skip Chromatic

The old workflow had a defensive fallback ${{ jobs.publish-release.outputs.published || 'false' }} ensuring that if the published output wasn't set, it would default to 'false'. The new code directly passes ${{ steps.changesets.outputs.published }} without this fallback. If the changesets action fails to set the output for any reason, needs.publish-release.outputs.published would be empty, causing the condition == 'false' to evaluate to false, and deploy-chromatic-release would silently be skipped instead of running as expected when no release was published.

Additional Locations (1)

Fix in Cursor Fix in Web

version: ${{ steps.get-version.outputs.version }}
steps:
- uses: actions/checkout@v4

Expand Down Expand Up @@ -142,9 +135,17 @@ jobs:
- name: Update npm for trusted publishing
run: npm install -g npm@latest

- name: Verify npm version and OIDC availability
run: |
echo "npm version: $(npm --version)"
echo "OIDC available: ${{ env.ACTIONS_ID_TOKEN_REQUEST_URL != '' }}"

- name: Install Dependencies
run: pnpm install

- name: Clear .npmrc auth token (use OIDC instead)
run: npm config delete //registry.npmjs.org/:_authToken || true

- name: Create Release Pull Request or Publish to npm
id: changesets
uses: changesets/action@v1
Expand All @@ -155,9 +156,60 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# NPM_TOKEN not needed - using trusted publishing (OIDC)

- name: Get published version
id: get-version
if: steps.changesets.outputs.published == 'true'
run: |
VERSION=$(node -p "require('./package.json').version")
echo "version=$VERSION" >> $GITHUB_OUTPUT
deploy-chromatic-release:
name: 'Deploy storybook to Chromatic'
needs: publish-release
if: github.event_name == 'push' && needs.publish-release.outputs.published == 'false'
runs-on: ubuntu-latest
environment:
name: Chromatic Production
url: ${{ steps.publish_chromatic.outputs.url }}
env:
NODE_OPTIONS: --max-old-space-size=4096
CHROMATIC_RETRIES: 5
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Update Corepack
run: npm i -g corepack@latest

- name: Enable Corepack (pre)
run: corepack enable

- name: Prepare pnpm (pre)
run: corepack prepare [email protected] --activate

- uses: actions/cache@v4
name: Download storybook cache
with:
path: |
**/node_modules/.cache
key: ${{ runner.os }}-storybook-${{ github.run_id }}
restore-keys: |
${{ runner.os }}-storybook

- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'pnpm'

- name: Enable Corepack
run: corepack enable

- name: Prepare pnpm
run: corepack prepare [email protected] --activate

- name: Install dependencies
run: pnpm install

- name: Publish to Chromatic
id: publish_chromatic
uses: chromaui/action@v11
with:
exitZeroOnChanges: true
exitOnceUploaded: true
autoAcceptChanges: true
onlyChanged: true
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
18 changes: 10 additions & 8 deletions .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,22 @@ concurrency:
cancel-in-progress: true

permissions:
contents: write # Required for reusable workflow validation (not used by canary job)
contents: read
issues: write
pull-requests: write
statuses: write
id-token: write # Required for trusted publishing (OIDC)

# Note: Canary publishing is handled by publish.yml workflow

jobs:
publish-canary:
# This job exists only to satisfy branch protection rules that expect this check name
# The actual publishing is done in publish.yml
build-canary-status:
name: 'Build & canary release'
uses: ./.github/workflows/publish.yml
with:
publish-type: canary
pr-number: ${{ github.event.number }}
secrets: inherit
runs-on: ubuntu-latest
steps:
- name: Publishing handled by publish.yml
run: echo "Canary publishing is handled by the Publish workflow (publish.yml)"

tests:
name: 'Tests & lint'
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"description": "UIKit for Cube Projects",
"repository": {
"type": "git",
"url": "https://github.com/cube-js/cube-ui-kit.git"
"url": "git+https://github.com/cube-js/cube-ui-kit.git"
},
"module": "dist/es/index.js",
"types": "dist/types/index.d.ts",
Expand Down
Loading