Repository navigation
137 lines (121 loc) · 5.03 KB
/
Copy pathrelease.yml
File metadata and controls
137 lines (121 loc) · 5.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
name: Release
# Publishes `@norbix.ai/cli` to npm via semantic-release on every push to `main`
# (and prerelease branches `next` / `beta`). The next version comes from
# conventional commits since the last `v*` tag: `feat:` → minor, `fix:` → patch,
# breaking → minor too until the public launch (major frozen; see README
# "Versioning"). `chore:`, `ci:`, `test:` don't release.
#
# Authentication:
# - npm: trusted publishing (OIDC) first — npmjs.com trusts this repo +
# workflow file (package Settings → Trusted Publisher). npm requires 2FA for
# token-based publishes, which CI cannot do, so NPM_TOKEN is only a fallback.
# Trusted publishing needs `id-token: write` and npm >= 11.5.1.
# - GITHUB_TOKEN: provided by Actions; pushes the release tag and creates the
# GitHub Release.
#
# `main` is protected (changes only through pull requests), so the release does
# NOT commit back: `version` in package.json on main stays stale. The git tag is
# the source of truth for the version; release notes live on GitHub Releases.
on:
push:
branches: [main, next, beta]
workflow_dispatch:
inputs:
republish:
description: >-
Recovery mode — skip semantic-release and publish the version of the
latest git tag to npm, then create its GitHub Release if missing (use
when a tag exists but npm publish failed).
type: boolean
default: false
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: false
permissions:
contents: write
issues: write
pull-requests: write
id-token: write # trusted publishing + npm provenance
jobs:
release:
name: semantic-release
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v7
with:
# semantic-release needs the full history and tags.
fetch-depth: 0
persist-credentials: false
- name: Sync branch tip
# A run checks out its triggering SHA. When several merges land close
# together that SHA is already behind origin, and semantic-release
# refuses to release ("local branch main is behind the remote one").
# Release from the remote tip instead so a quick follow-up merge never
# swallows a release.
if: github.event_name != 'workflow_dispatch' || inputs.republish != true
run: |
git fetch origin "${GITHUB_REF_NAME}"
git checkout "${GITHUB_REF_NAME}"
git reset --hard "origin/${GITHUB_REF_NAME}"
- name: Setup Node
uses: actions/setup-node@v7
with:
node-version: 22
cache: npm
- name: Use npm 11 (trusted publishing needs >= 11.5.1)
# Node 22 bundles npm 10, which cannot publish via OIDC.
run: |
npm install -g npm@^11.6.2
npm --version
- name: Install deps
run: npm ci --no-audit --no-fund
- name: Typecheck
run: npm run typecheck
- name: Test
run: npm test
- name: Smoke test
run: node ./bin/run.js --help
- name: npm audit (production deps only)
run: npm audit --omit=dev --audit-level=high
- name: Release
if: github.event_name != 'workflow_dispatch' || inputs.republish != true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
NPM_CONFIG_PROVENANCE: 'true'
run: npx semantic-release
- name: Republish to npm (recovery)
if: github.event_name == 'workflow_dispatch' && inputs.republish == true
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
NPM_CONFIG_PROVENANCE: 'true'
run: |
NAME=$(node -pe "require('./package.json').name")
TAG=$(git describe --tags --abbrev=0 --match 'v[0-9]*')
VERSION="${TAG#v}"
echo "Recovery publish: ${NAME}@${VERSION} (from tag ${TAG})"
if npm view "${NAME}@${VERSION}" version 2>/dev/null; then
echo "Already published on npm — nothing to do."
else
git checkout --detach "${TAG}"
npm ci --no-audit --no-fund
npm version "${VERSION}" --no-git-tag-version --allow-same-version
# Trusted publishing (OIDC) when configured; NPM_TOKEN as a fallback.
if [ -n "$NPM_TOKEN" ]; then
npm config set //registry.npmjs.org/:_authToken "$NPM_TOKEN"
fi
npm publish --access public
fi
if ! gh release view "${TAG}" >/dev/null 2>&1; then
gh release create "${TAG}" --verify-tag --title "${TAG}" --generate-notes
fi
- name: Summary
if: always()
run: |
echo "### Release · ${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY
TAG=$(git describe --tags --abbrev=0 --match 'v[0-9]*' 2>/dev/null || true)
if [ -n "$TAG" ]; then
echo "Latest tag: \`${TAG}\` — notes: ${{ github.server_url }}/${{ github.repository }}/releases/tag/${TAG}" >> $GITHUB_STEP_SUMMARY
fi