diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..1c0de0a --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,75 @@ +name: Release + +on: + push: + tags: + - "v*" + +permissions: + contents: read + id-token: write + +concurrency: + group: release-${{ github.ref_name }} + cancel-in-progress: false + +jobs: + publish: + runs-on: ubuntu-latest + timeout-minutes: 20 + steps: + - uses: actions/checkout@v5 + with: + fetch-depth: 0 + + - name: Verify tag is on main + run: | + git fetch origin main:refs/remotes/origin/main + git merge-base --is-ancestor "$GITHUB_SHA" origin/main + + - uses: actions/setup-node@v5 + with: + node-version: 24 + registry-url: https://registry.npmjs.org + + - name: Ensure npm supports trusted publishing + run: npm install -g npm@^11.5.1 + + - run: npm ci + + - name: Verify package version matches tag + run: | + node --input-type=module <<'EOF' + import { readFileSync } from "node:fs"; + + const tag = process.env.GITHUB_REF_NAME; + const prefix = "v"; + if (!tag?.startsWith(prefix)) { + throw new Error(`Expected tag to start with ${prefix}, got ${tag}`); + } + + const tagVersion = tag.slice(prefix.length); + const pkg = JSON.parse(readFileSync("package.json", "utf8")); + if (pkg.version !== tagVersion) { + throw new Error(`Tag version ${tagVersion} does not match ${pkg.name} package.json version ${pkg.version}`); + } + + console.log(`${pkg.name}@${pkg.version}`); + EOF + + - run: npm run build + - run: npm run typecheck + + - name: Pack tarball + run: npm pack --pack-destination "$RUNNER_TEMP" + + - name: ESM import smoke test + run: | + SMOKE_DIR=$(mktemp -d) + cd "$SMOKE_DIR" + npm init -y > /dev/null + npm install "$RUNNER_TEMP"/onkernel-eve-extension-*.tgz eve@^0.25 + node --input-type=module -e "import('@onkernel/eve-extension').then((m) => { if (typeof m.default !== 'function') process.exit(1); })" + + - name: Publish to npm + run: npm publish --access public