From db0949509c29118baa1144f18f076193adaa61bf Mon Sep 17 00:00:00 2001 From: bourgeoa Date: Wed, 18 Feb 2026 17:19:54 +0100 Subject: [PATCH 1/8] git fetch --all --- scripts/release-orchestrator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/release-orchestrator.js b/scripts/release-orchestrator.js index 4bfb474..e99af3a 100644 --- a/scripts/release-orchestrator.js +++ b/scripts/release-orchestrator.js @@ -75,7 +75,7 @@ function ensureClean(repoDir, dryRun) { function ensureBranch(repoDir, branch, dryRun) { // Fetch all remote branches - run(`git fetch origin --all`, repoDir, dryRun); + run(`git fetch --all`, repoDir, dryRun); // Only verify branch exists if not dry-run (actual fetch happened) if (!dryRun) { From aa334b41045e016531cd15dc589a1ce1600646c6 Mon Sep 17 00:00:00 2001 From: bourgeoa Date: Wed, 18 Feb 2026 19:31:57 +0100 Subject: [PATCH 2/8] update logic --- RELEASE-HOWTO.md | 101 ++++++++++++++++++++++++-------- scripts/release-orchestrator.js | 76 +++++++++++++++++++----- 2 files changed, 140 insertions(+), 37 deletions(-) diff --git a/RELEASE-HOWTO.md b/RELEASE-HOWTO.md index d2e6b74..528ecd7 100644 --- a/RELEASE-HOWTO.md +++ b/RELEASE-HOWTO.md @@ -30,22 +30,32 @@ solidos/ (main branch) **Workflow:** ``` -You click "Run workflow" button in GitHub Actions +You click "Run workflow" button in GitHub Actions (mode=test or mode=stable) ↓ release.yml starts ↓ -Runs: node scripts/release-orchestrator.js --mode stable ... +Runs: node scripts/release-orchestrator.js --mode ... ↓ Script reads release.config.json (list of repos to release) ↓ For each repo listed: - Clone if missing (optional) + - Checkout branch (dev for test, main for stable) - npm install + - afterInstall with @test or @latest tags (with fallback) + + [Stable mode only: Check skip logic] + - Compare origin/dev vs main + - If dev has new commits → merge origin/dev into main with [skip ci] + - If no changes and --branch not specified → skip this repo + + [Test mode: always continues] + - npm test - npm run build - - npm version (bump patch/minor/major) - - npm publish (to npm registry) - - git push + tags (for stable only) + - npm version (bump patch/minor/major/prerelease) + - npm publish (to npm registry with @test or @latest tag) + - git push + tags (stable only) ↓ Generates release-summary.json ``` @@ -88,21 +98,27 @@ node scripts/release-orchestrator.js --mode test --dry-run=true - Publishes to npm with `@test` tag - Does NOT create git tags - Results in GitHub Actions logs and artifacts -- **Use case:** Pre-release versions for testing +- **Always publishes** (no skip logic) +- **Use case:** Pre-release versions for testing from dev branch **Scenario 3: GitHub Stable Release** - Click Actions → "Solidos Release" → Run workflow - Inputs: mode=stable, dry_run=false +- Automatically merges origin/dev → main if dev has new commits - Publishes to npm with `@latest` tag - Creates git tags and pushes to GitHub - Results in GitHub Actions logs and artifacts -- **Use case:** Production releases +- Skips if dev has no new commits (unless --branch=main specified) +- **Use case:** Production releases to @latest Local dry-run - Show the exact commands without running them: node scripts/release-orchestrator.js --mode test --dry-run - Override the branch: node scripts/release-orchestrator.js --mode test --dry-run --branch develop +- Force stable publish regardless of changes: + node scripts/release-orchestrator.js --mode stable --branch main +- Dry-run allows untracked files (ignored for convenience) CI runs (GitHub Actions) - Trigger workflow "Solidos Release" with inputs: @@ -118,6 +134,7 @@ Command-line Options - --dry-run: true or false (default: false) - --clone-missing: true or false (default: false) - --branch: override branch for all repos (optional) + - Also disables skip logic in stable mode (forces publish) - --summary-path: path to output summary file (default: release-summary.json) Branch Configuration @@ -128,39 +145,60 @@ By default, both test and stable modes use the `main` branch. To use different b ```json { "defaultBranch": "main", - "modes": { - "test": { - "branch": "develop", + "modes": [ + { + "name": "test", + "branch": "dev", "versionBump": "prerelease", - "preid": "test" + "preid": "test", + "npmTag": "test" }, - "stable": { + { + "name": "stable", "branch": "main", - "versionBump": "patch" + "versionBump": "patch", + "npmTag": "latest" } - }, + ], "repos": [ { "name": "solid-panes", - "path": "./workspaces/solid-panes" + "path": "./workspaces/solid-panes", + "afterInstall": [ + "npm install profile-pane" + ] } ] } ``` -Now: -- Test releases pull from `develop` branch -- Stable releases pull from `main` branch +Behavior: +- **Test mode:** + - Pulls from `dev` branch + - Always publishes (no skip) + - afterInstall `npm install profile-pane` becomes `npm install profile-pane@test || npm install profile-pane@latest` +- **Stable mode:** + - Pulls from `main` branch + - Auto-merges origin/dev if it has new commits + - Skips if no changes (unless --branch=main specified) Publish modes - test: + - Runs on: dev branch (or configured branch) - npm version prerelease --preid test - npm publish --tag test - does NOT create git tags or push + - **Always publishes** (no skip check) + - afterInstall commands use @test tag with @latest fallback - stable: + - Runs on: main branch (or configured branch) + - Checks if origin/dev has commits that main doesn't + - If yes: auto-merges origin/dev → main (may fail on conflicts) - npm version patch (or configured bump) - npm publish (latest) - creates git tags and pushes by default + - Skips if no changes (unless --branch explicitly specified) + - afterInstall commands use @latest tag Multiple configs - Create additional config files (for example): @@ -170,15 +208,26 @@ Multiple configs - Use with: --config release.config.test.json Skip logic -- If there is no git diff vs origin/main (or configured branch), the repo is skipped. +- **Test mode:** Always publishes (no skip logic) +- **Stable mode:** + - Compares origin/dev vs main to detect unpublished changes + - If origin/dev has commits that main doesn't: merges and publishes + - If no changes: skips publishing + - Override: `--branch=main` forces publish regardless of changes + - Merge happens automatically before publish (fails if conflicts) + - Merge commit includes `[skip ci]` to prevent redundant ci.yml runs Summary output - A summary is printed at the end and written to release-summary.json. - Override with: --summary-path path/to/summary.json -npm install test builds -- npm install @test installs the latest package published under the "test" dist-tag. -- You can also install a specific test version by pinning it explicitly. +npm install with dist-tags +- **Test mode:** afterInstall commands automatically inject @test tags + - Example: `npm install solid-ui` becomes `npm install solid-ui@test` + - Fallback: If @test doesn't exist, tries @latest automatically + - Command: `npm install solid-ui@test || npm install solid-ui@latest` +- **Stable mode:** afterInstall commands use @latest tags (default npm behavior) +- Manual install: `npm install @test` to get test versions Config options (release.config.json) - defaultBranch: branch name used if repo does not override. @@ -225,6 +274,12 @@ Each workspace repo (solid-panes, folder-pane, etc.) has its own `ci.yml` workfl └─ [waiting for manual release trigger] └─ You click "Run workflow" in Actions └─ release.yml runs → publishes to npm + └─ (stable mode) auto-merges dev→main with [skip ci] + └─ pushes version tags and commits + └─ ci.yml does NOT run (prevented by [skip ci]) ``` -**Important:** Waiting PRs are NOT automatically published. You must manually trigger the release after merging. +**Important Notes:** +- Waiting PRs are NOT automatically published. You must manually trigger the release after merging. +- When stable mode merges dev→main automatically, it uses `[skip ci]` in the commit message to prevent redundant ci.yml runs in individual repos. +- Tests/builds already ran in the release orchestrator, so skipping ci.yml avoids duplicate work. diff --git a/scripts/release-orchestrator.js b/scripts/release-orchestrator.js index e99af3a..901fdf4 100644 --- a/scripts/release-orchestrator.js +++ b/scripts/release-orchestrator.js @@ -259,21 +259,69 @@ function main() { runSteps(repo.afterInstall, repoDir, dryRun, npmTag); } - // Check for changes AFTER install (which may have modified files) - // Skip this check in dry-run mode (to show full workflow) - const skipIfNoDiff = repo.skipIfNoDiff ?? config.skipIfNoDiff ?? true; - const shouldCheckDiff = !dryRun && skipIfNoDiff; + // Check for changes AFTER install (only for stable mode) + // Test mode always publishes + // Stable mode skips if no diff, unless branch was explicitly specified or dry-run + let shouldMergeDev = false; - if (shouldCheckDiff) { - const { ahead: aheadAfterInstall } = getAheadBehind(repoDir, branch); - if (aheadAfterInstall === 0) { - console.log('No changes vs origin after install. Skipping publish.'); - summary.push({ - name: repo.name, - status: 'skipped', - reason: 'no-diff' - }); - continue; + if (mode === 'stable') { + const skipIfNoDiff = repo.skipIfNoDiff ?? config.skipIfNoDiff ?? true; + const shouldCheckDiff = !dryRun && skipIfNoDiff && !branchOverride; + + if (shouldCheckDiff) { + // For stable mode: check if dev branch has changes that main doesn't + const devBranch = config.modes.find(m => m.name === 'test')?.branch || 'dev'; + + // Ensure we have latest dev refs + try { + runQuiet(`git fetch origin ${devBranch}:refs/remotes/origin/${devBranch}`, repoDir); + } catch (err) { + console.log(`Warning: Could not fetch ${devBranch}: ${err.message}`); + } + + // Count commits that dev has but main doesn't + const commitsAhead = parseInt(runQuiet(`git rev-list --count ${branch}..origin/${devBranch}`, repoDir)) || 0; + + if (commitsAhead === 0) { + console.log(`No changes in origin/${devBranch} vs ${branch}. Skipping publish.`); + summary.push({ + name: repo.name, + status: 'skipped', + reason: 'no-diff' + }); + continue; + } else { + console.log(`Found ${commitsAhead} commit(s) in ${devBranch} not in ${branch}. Will merge and publish.`); + shouldMergeDev = true; + } + } + } + + // For stable mode: check if we need to merge dev (even if skipIfNoDiff is disabled) + if (mode === 'stable' && !shouldMergeDev) { + const devBranch = config.modes.find(m => m.name === 'test')?.branch || 'dev'; + + try { + runQuiet(`git fetch origin ${devBranch}:refs/remotes/origin/${devBranch}`, repoDir); + const commitsAhead = parseInt(runQuiet(`git rev-list --count ${branch}..origin/${devBranch}`, repoDir)) || 0; + + if (commitsAhead > 0) { + console.log(`Found ${commitsAhead} commit(s) in ${devBranch} not in ${branch}. Will merge before publish.`); + shouldMergeDev = true; + } + } catch (err) { + console.log(`Warning: Could not check ${devBranch}: ${err.message}`); + } + } + + // Merge dev into main before publishing (stable mode only) + if (mode === 'stable' && shouldMergeDev) { + const devBranch = config.modes.find(m => m.name === 'test')?.branch || 'dev'; + console.log(`Merging origin/${devBranch} into ${branch}...`); + try { + run(`git merge origin/${devBranch} -m "Merge ${devBranch} into ${branch} for release [skip ci]"`, repoDir, dryRun); + } catch (err) { + throw new Error(`Failed to merge origin/${devBranch} into ${branch}. Please resolve conflicts manually.`); } } From ec2a0a9f802a9a4ffe0b70f3e34a89f7b4eb63d1 Mon Sep 17 00:00:00 2001 From: bourgeoa Date: Wed, 18 Feb 2026 19:54:04 +0100 Subject: [PATCH 3/8] ignore scripts --- RELEASE-HOWTO.md | 4 ++-- scripts/release-orchestrator.js | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/RELEASE-HOWTO.md b/RELEASE-HOWTO.md index 528ecd7..a59f206 100644 --- a/RELEASE-HOWTO.md +++ b/RELEASE-HOWTO.md @@ -186,7 +186,7 @@ Publish modes - test: - Runs on: dev branch (or configured branch) - npm version prerelease --preid test - - npm publish --tag test + - npm publish --tag test --ignore-scripts - does NOT create git tags or push - **Always publishes** (no skip check) - afterInstall commands use @test tag with @latest fallback @@ -195,7 +195,7 @@ Publish modes - Checks if origin/dev has commits that main doesn't - If yes: auto-merges origin/dev → main (may fail on conflicts) - npm version patch (or configured bump) - - npm publish (latest) + - npm publish (latest) with --ignore-scripts - creates git tags and pushes by default - Skips if no changes (unless --branch explicitly specified) - afterInstall commands use @latest tag diff --git a/scripts/release-orchestrator.js b/scripts/release-orchestrator.js index 901fdf4..3bf36e6 100644 --- a/scripts/release-orchestrator.js +++ b/scripts/release-orchestrator.js @@ -158,7 +158,8 @@ function publishStable(repoDir, modeConfig, dryRun) { const tag = modeConfig.npmTag && modeConfig.npmTag !== 'latest' ? `--tag ${modeConfig.npmTag}` : ''; - run(`npm publish ${tag}`.trim(), repoDir, dryRun); + // Ignore lifecycle scripts to avoid postpublish git pushes in CI. + run(`npm publish ${tag} --ignore-scripts`.trim(), repoDir, dryRun); if (modeConfig.gitPush !== false && modeConfig.gitTag !== false) { const branch = modeConfig.branch || 'main'; @@ -175,7 +176,8 @@ function publishTest(repoDir, modeConfig, dryRun) { const version = getPackageVersion(repoDir); const tag = modeConfig.npmTag || 'test'; - run(`npm publish --tag ${tag}`, repoDir, dryRun); + // Ignore lifecycle scripts to avoid postpublish git pushes in CI. + run(`npm publish --tag ${tag} --ignore-scripts`, repoDir, dryRun); console.log('Note: test publish updated package.json/package-lock.json.'); console.log(' Use git restore to clean if you do not want to keep it.'); From 89d46c6860f485ef1726e464e399a32c2e9dcd5c Mon Sep 17 00:00:00 2001 From: bourgeoa Date: Wed, 18 Feb 2026 20:07:28 +0100 Subject: [PATCH 4/8] resolve prerelease failure --- RELEASE-HOWTO.md | 1 + scripts/release-orchestrator.js | 45 +++++++++++++++++++++++++++++---- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/RELEASE-HOWTO.md b/RELEASE-HOWTO.md index a59f206..9629e3d 100644 --- a/RELEASE-HOWTO.md +++ b/RELEASE-HOWTO.md @@ -189,6 +189,7 @@ Publish modes - npm publish --tag test --ignore-scripts - does NOT create git tags or push - **Always publishes** (no skip check) + - If the prerelease version already exists, it auto-bumps again before publishing - afterInstall commands use @test tag with @latest fallback - stable: - Runs on: main branch (or configured branch) diff --git a/scripts/release-orchestrator.js b/scripts/release-orchestrator.js index 3bf36e6..6aa2f9e 100644 --- a/scripts/release-orchestrator.js +++ b/scripts/release-orchestrator.js @@ -145,6 +145,16 @@ function parseNpmInstallCmd(cmd, tag) { return mainCmd; } +function packageVersionExists(name, version, repoDir) { + if (!name || !version) return false; + try { + const output = runQuiet(`npm view ${name}@${version} version`, repoDir); + return output.trim() !== ''; + } catch (err) { + return false; + } +} + function publishStable(repoDir, modeConfig, dryRun) { const bump = modeConfig.versionBump || 'patch'; if (modeConfig.gitTag === false) { @@ -153,12 +163,15 @@ function publishStable(repoDir, modeConfig, dryRun) { run(`npm version ${bump} -m "Release %s"`, repoDir, dryRun); } + const pkg = getPackageJson(repoDir); + const packageName = pkg ? pkg.name : null; const version = getPackageVersion(repoDir); const tag = modeConfig.npmTag && modeConfig.npmTag !== 'latest' ? `--tag ${modeConfig.npmTag}` : ''; // Ignore lifecycle scripts to avoid postpublish git pushes in CI. + console.log(`Publishing ${packageName || 'package'}@${version} with tag ${modeConfig.npmTag || 'latest'}...`); run(`npm publish ${tag} --ignore-scripts`.trim(), repoDir, dryRun); if (modeConfig.gitPush !== false && modeConfig.gitTag !== false) { @@ -166,23 +179,41 @@ function publishStable(repoDir, modeConfig, dryRun) { run(`git push origin ${branch} --follow-tags`, repoDir, dryRun); } - return { version, tag: modeConfig.npmTag || 'latest' }; + return { packageName, version, tag: modeConfig.npmTag || 'latest' }; } function publishTest(repoDir, modeConfig, dryRun) { const preid = modeConfig.preid || 'test'; run(`npm version prerelease --preid ${preid} --no-git-tag-version`, repoDir, dryRun); - const version = getPackageVersion(repoDir); + const pkg = getPackageJson(repoDir); + const name = pkg ? pkg.name : null; + let version = getPackageVersion(repoDir); + let attempts = 0; + const maxAttempts = 5; + + if (!dryRun && name) { + while (attempts < maxAttempts && packageVersionExists(name, version, repoDir)) { + console.log(`Version ${version} already published. Bumping prerelease...`); + run(`npm version prerelease --preid ${preid} --no-git-tag-version`, repoDir, dryRun); + version = getPackageVersion(repoDir); + attempts += 1; + } + + if (attempts === maxAttempts && packageVersionExists(name, version, repoDir)) { + throw new Error(`Unable to find an unpublished prerelease version after ${maxAttempts} attempts.`); + } + } const tag = modeConfig.npmTag || 'test'; + console.log(`Publishing ${name || 'package'}@${version} with tag ${tag}...`); // Ignore lifecycle scripts to avoid postpublish git pushes in CI. run(`npm publish --tag ${tag} --ignore-scripts`, repoDir, dryRun); console.log('Note: test publish updated package.json/package-lock.json.'); console.log(' Use git restore to clean if you do not want to keep it.'); - return { version, tag }; + return { packageName: name, version, tag }; } function main() { @@ -356,16 +387,20 @@ function main() { summary.push({ name: repo.name, status: dryRun ? 'dry-run' : 'published', + packageName: result.packageName || null, version: result.version, - tag: result.tag + tag: result.tag, + publishedAs: result.packageName ? `${result.packageName}@${result.version}` : null }); } else if (mode === 'stable') { const result = publishStable(repoDir, effectiveModeConfig, dryRun); summary.push({ name: repo.name, status: dryRun ? 'dry-run' : 'published', + packageName: result.packageName || null, version: result.version, - tag: result.tag + tag: result.tag, + publishedAs: result.packageName ? `${result.packageName}@${result.version}` : null }); } else { throw new Error(`Unknown mode: ${mode}`); From 697221f3ad67cb6ff99353bf81e02c6d61da7d2a Mon Sep 17 00:00:00 2001 From: bourgeoa Date: Wed, 18 Feb 2026 20:24:10 +0100 Subject: [PATCH 5/8] disable pre/postversion --- RELEASE-HOWTO.md | 1 + scripts/release-orchestrator.js | 61 +++++++++++++++++++++++++++++---- 2 files changed, 56 insertions(+), 6 deletions(-) diff --git a/RELEASE-HOWTO.md b/RELEASE-HOWTO.md index 9629e3d..4b6ff86 100644 --- a/RELEASE-HOWTO.md +++ b/RELEASE-HOWTO.md @@ -190,6 +190,7 @@ Publish modes - does NOT create git tags or push - **Always publishes** (no skip check) - If the prerelease version already exists, it auto-bumps again before publishing + - Temporarily disables preversion/version/postversion scripts during version bump - afterInstall commands use @test tag with @latest fallback - stable: - Runs on: main branch (or configured branch) diff --git a/scripts/release-orchestrator.js b/scripts/release-orchestrator.js index 6aa2f9e..8a4d946 100644 --- a/scripts/release-orchestrator.js +++ b/scripts/release-orchestrator.js @@ -145,6 +145,40 @@ function parseNpmInstallCmd(cmd, tag) { return mainCmd; } +function disableVersionScripts(repoDir) { + const pkgPath = path.join(repoDir, 'package.json'); + if (!fs.existsSync(pkgPath)) return null; + const pkg = readJson(pkgPath); + if (!pkg.scripts) return null; + + const original = { ...pkg.scripts }; + const updated = { ...pkg.scripts }; + let changed = false; + + for (const key of Object.keys(updated)) { + if (key === 'preversion' || key === 'postversion' || key === 'version') { + updated[`ignore:${key}`] = updated[key]; + delete updated[key]; + changed = true; + } + } + + if (!changed) return null; + + pkg.scripts = updated; + fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n'); + return original; +} + +function restoreVersionScripts(repoDir, originalScripts) { + if (!originalScripts) return; + const pkgPath = path.join(repoDir, 'package.json'); + if (!fs.existsSync(pkgPath)) return; + const pkg = readJson(pkgPath); + pkg.scripts = originalScripts; + fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n'); +} + function packageVersionExists(name, version, repoDir) { if (!name || !version) return false; try { @@ -157,10 +191,15 @@ function packageVersionExists(name, version, repoDir) { function publishStable(repoDir, modeConfig, dryRun) { const bump = modeConfig.versionBump || 'patch'; - if (modeConfig.gitTag === false) { - run(`npm version ${bump} --no-git-tag-version`, repoDir, dryRun); - } else { - run(`npm version ${bump} -m "Release %s"`, repoDir, dryRun); + const originalScripts = disableVersionScripts(repoDir); + try { + if (modeConfig.gitTag === false) { + run(`npm version ${bump} --no-git-tag-version`, repoDir, dryRun); + } else { + run(`npm version ${bump} -m "Release %s"`, repoDir, dryRun); + } + } finally { + restoreVersionScripts(repoDir, originalScripts); } const pkg = getPackageJson(repoDir); @@ -184,7 +223,12 @@ function publishStable(repoDir, modeConfig, dryRun) { function publishTest(repoDir, modeConfig, dryRun) { const preid = modeConfig.preid || 'test'; - run(`npm version prerelease --preid ${preid} --no-git-tag-version`, repoDir, dryRun); + const originalScripts = disableVersionScripts(repoDir); + try { + run(`npm version prerelease --preid ${preid} --no-git-tag-version`, repoDir, dryRun); + } finally { + restoreVersionScripts(repoDir, originalScripts); + } const pkg = getPackageJson(repoDir); const name = pkg ? pkg.name : null; @@ -195,7 +239,12 @@ function publishTest(repoDir, modeConfig, dryRun) { if (!dryRun && name) { while (attempts < maxAttempts && packageVersionExists(name, version, repoDir)) { console.log(`Version ${version} already published. Bumping prerelease...`); - run(`npm version prerelease --preid ${preid} --no-git-tag-version`, repoDir, dryRun); + const retryOriginalScripts = disableVersionScripts(repoDir); + try { + run(`npm version prerelease --preid ${preid} --no-git-tag-version`, repoDir, dryRun); + } finally { + restoreVersionScripts(repoDir, retryOriginalScripts); + } version = getPackageVersion(repoDir); attempts += 1; } From c85897503aaed955b063cb75fcceefeee5b1758d Mon Sep 17 00:00:00 2001 From: bourgeoa Date: Wed, 18 Feb 2026 23:01:40 +0100 Subject: [PATCH 6/8] use OIDC trusted --- .github/workflows/release.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cc5273d..24888fe 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,6 +31,9 @@ on: jobs: release: runs-on: ubuntu-latest + permissions: + id-token: write # Required for OIDC + contents: read steps: - name: Checkout uses: actions/checkout@v4 @@ -41,9 +44,10 @@ jobs: node-version: 20 registry-url: https://registry.npmjs.org + - name: Update npm to latest (required for OIDC) + run: npm install -g npm@latest + - name: Run release orchestrator - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} run: | BRANCH_ARG="" if [ -n "${{ inputs.branch }}" ]; then From ae17c53b31d97cb60ce39963a403bdd46fad14c5 Mon Sep 17 00:00:00 2001 From: bourgeoa Date: Wed, 18 Feb 2026 23:39:21 +0100 Subject: [PATCH 7/8] use token --- .github/workflows/release.yml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 24888fe..cc5273d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,9 +31,6 @@ on: jobs: release: runs-on: ubuntu-latest - permissions: - id-token: write # Required for OIDC - contents: read steps: - name: Checkout uses: actions/checkout@v4 @@ -44,10 +41,9 @@ jobs: node-version: 20 registry-url: https://registry.npmjs.org - - name: Update npm to latest (required for OIDC) - run: npm install -g npm@latest - - name: Run release orchestrator + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} run: | BRANCH_ARG="" if [ -n "${{ inputs.branch }}" ]; then From 3405ef5e9bf17c1848050ef85430f87bb47c75d4 Mon Sep 17 00:00:00 2001 From: bourgeoa Date: Thu, 19 Feb 2026 00:14:02 +0100 Subject: [PATCH 8/8] --no-provenance --- .github/workflows/release.yml | 3 +++ scripts/release-orchestrator.js | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cc5273d..00d66f2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -40,6 +40,9 @@ jobs: with: node-version: 20 registry-url: https://registry.npmjs.org + + - name: Update npm to latest + run: npm install -g npm@latest - name: Run release orchestrator env: diff --git a/scripts/release-orchestrator.js b/scripts/release-orchestrator.js index 8a4d946..e90c577 100644 --- a/scripts/release-orchestrator.js +++ b/scripts/release-orchestrator.js @@ -211,7 +211,7 @@ function publishStable(repoDir, modeConfig, dryRun) { : ''; // Ignore lifecycle scripts to avoid postpublish git pushes in CI. console.log(`Publishing ${packageName || 'package'}@${version} with tag ${modeConfig.npmTag || 'latest'}...`); - run(`npm publish ${tag} --ignore-scripts`.trim(), repoDir, dryRun); + run(`npm publish ${tag} --ignore-scripts --no-provenance`.trim(), repoDir, dryRun); if (modeConfig.gitPush !== false && modeConfig.gitTag !== false) { const branch = modeConfig.branch || 'main'; @@ -257,7 +257,7 @@ function publishTest(repoDir, modeConfig, dryRun) { const tag = modeConfig.npmTag || 'test'; console.log(`Publishing ${name || 'package'}@${version} with tag ${tag}...`); // Ignore lifecycle scripts to avoid postpublish git pushes in CI. - run(`npm publish --tag ${tag} --ignore-scripts`, repoDir, dryRun); + run(`npm publish --tag ${tag} --ignore-scripts --no-provenance`, repoDir, dryRun); console.log('Note: test publish updated package.json/package-lock.json.'); console.log(' Use git restore to clean if you do not want to keep it.');