|
1 | | -# Release workflow for @loop-engine/* OSS packages (under packages/* and packages/adapters/*) |
| 1 | +# Release workflow for @loop-engine/* OSS packages |
2 | 2 | # |
3 | | -# Trigger: |
4 | | -# - Push a semver tag: git tag v0.2.0 && git push origin v0.2.0 |
5 | | -# - Or Actions → "RC tag release" → Run workflow (default: publish --dry-run only; uncheck dry_run to test a real publish) |
| 3 | +# Normal publish trigger: |
| 4 | +# git tag v0.2.0 && git push --tags |
| 5 | +# → workflow fires automatically, no manual dispatch needed |
6 | 6 | # |
7 | | -# Prerequisites before tagging: |
8 | | -# 1. Run `pnpm build && pnpm validate:publish` locally — confirm no workspace:* refs in packed manifests |
9 | | -# 2. Bump versions in package.json files (or use changesets) so the tag matches what npm will publish |
10 | | -# 3. Update CHANGELOG / draft a GitHub Release as needed |
| 7 | +# Pipeline test (dry run): |
| 8 | +# GitHub → Actions → RC tag release → Run workflow |
| 9 | +# → leave dry_run CHECKED → run |
| 10 | +# → exercises install, build, validate:publish, and pnpm publish --dry-run |
11 | 11 | # |
12 | | -# Auth: setup-node with registry-url configures ~/.npmrc; the env var MUST be NODE_AUTH_TOKEN |
13 | | -# (map the GitHub Actions repository secret named NPM_TOKEN to NODE_AUTH_TOKEN in the publish steps below). |
| 12 | +# Manual dispatch with dry_run UNCHECKED: |
| 13 | +# Only allowed from main or a version tag — workflow will hard-fail otherwise. |
| 14 | +# Use only as an emergency escape hatch, not as a routine publish path. |
14 | 15 | # |
15 | | -# Provenance: id-token: write lets npm attach provenance linking the tarball to this GitHub Actions run. |
| 16 | +# Tag pushes: inputs.dry_run is undefined; guard step uses if: ${{ !inputs.dry_run }} so it still |
| 17 | +# runs, and startsWith(github.ref, 'refs/tags/') passes immediately — do not change that behavior. |
16 | 18 | # |
17 | 19 | # Token rotation: |
18 | | -# NPM_TOKEN secret expires ~April 2027. |
19 | | -# Rotate at: npmjs.com → Account Settings → Access Tokens |
20 | | -# Update at: GitHub → Settings → Secrets and variables → Actions → NPM_TOKEN |
| 20 | +# NPM_TOKEN secret expires July 15, 2026. |
| 21 | +# Rotate at: npmjs.com → Account Settings → Access Tokens → Automation token |
| 22 | +# Update at: GitHub → loopengine/loop-engine → Settings → Secrets → NPM_TOKEN |
| 23 | +# Set calendar reminder for July 1, 2026. |
| 24 | +# |
| 25 | +# Auth: setup-node with registry-url configures ~/.npmrc; the env var MUST be NODE_AUTH_TOKEN |
| 26 | +# (map the GitHub Actions repository secret named NPM_TOKEN to NODE_AUTH_TOKEN below). |
21 | 27 |
|
22 | 28 | name: RC tag release |
23 | 29 |
|
|
28 | 34 | workflow_dispatch: |
29 | 35 | inputs: |
30 | 36 | dry_run: |
31 | | - description: "If true, run pnpm publish --dry-run only (no registry upload)" |
| 37 | + description: "Dry run only — does not publish to npm. Uncheck only from main with a version tag pushed." |
32 | 38 | type: boolean |
33 | 39 | default: true |
| 40 | + required: true |
34 | 41 |
|
35 | 42 | env: |
36 | 43 | FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true |
@@ -68,15 +75,31 @@ jobs: |
68 | 75 | - name: Validate no workspace:* in publish targets |
69 | 76 | run: pnpm validate:publish |
70 | 77 |
|
71 | | - - name: Publish to npm |
72 | | - if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && github.event.inputs.dry_run == 'false') |
73 | | - run: pnpm publish -r --access public --no-git-checks --provenance |
74 | | - env: |
75 | | - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} |
| 78 | + - name: Enforce main or tag for real publish |
| 79 | + if: ${{ !inputs.dry_run }} |
| 80 | + run: | |
| 81 | + IS_TAG=${{ startsWith(github.ref, 'refs/tags/') }} |
| 82 | + IS_MAIN=${{ github.ref_name == 'main' }} |
| 83 | +
|
| 84 | + if [ "$IS_TAG" != "true" ] && [ "$IS_MAIN" != "true" ]; then |
| 85 | + echo "❌ Real publish is only allowed from main or a version tag." |
| 86 | + echo " Current ref: ${{ github.ref }}" |
| 87 | + echo " To test the pipeline safely, re-run with dry_run checked." |
| 88 | + exit 1 |
| 89 | + fi |
| 90 | +
|
| 91 | + echo "✅ Ref check passed: ${{ github.ref }}" |
76 | 92 |
|
77 | | - - name: Publish dry run |
78 | | - if: github.event_name == 'workflow_dispatch' && github.event.inputs.dry_run == 'true' |
79 | | - run: pnpm publish -r --access public --no-git-checks --dry-run |
| 93 | + - name: Publish to npm |
| 94 | + run: | |
| 95 | + FLAGS="--access public --no-git-checks" |
| 96 | + if [ "${{ inputs.dry_run }}" = "true" ]; then |
| 97 | + FLAGS="$FLAGS --dry-run" |
| 98 | + echo "ℹ️ Dry run mode — no packages will be published" |
| 99 | + else |
| 100 | + FLAGS="$FLAGS --provenance" |
| 101 | + fi |
| 102 | + pnpm publish -r $FLAGS |
80 | 103 | env: |
81 | 104 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} |
82 | 105 |
|
|
0 commit comments