release.yml 3.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. name: Release
  2. # Manually triggered ("Run workflow"). On trigger it:
  3. # 1. reads the version from package.json,
  4. # 2. builds a self-contained bundle for every platform (one runner — there's no
  5. # native compilation, so cross-packaging is fine),
  6. # 3. creates the GitHub Release (tag v<version>) with all archives, using the
  7. # release notes from CHANGELOG.md,
  8. # 4. publishes the npm thin-installer (shim + per-platform packages).
  9. #
  10. # Before triggering: bump package.json and make sure CHANGELOG.md has the matching
  11. # section (## [<version>], or ## [Unreleased]). Set the NPM_TOKEN repo secret.
  12. on:
  13. workflow_dispatch: {}
  14. permissions:
  15. contents: write # create the GitHub Release + tag
  16. jobs:
  17. release:
  18. runs-on: ubuntu-latest
  19. steps:
  20. - uses: actions/checkout@v4
  21. - uses: actions/setup-node@v4
  22. with:
  23. node-version: 22
  24. registry-url: https://registry.npmjs.org
  25. - run: npm ci
  26. - name: Ensure zip/unzip
  27. run: sudo apt-get update -qq && sudo apt-get install -y -qq zip unzip
  28. - name: Build all platform bundles
  29. run: |
  30. for t in darwin-arm64 darwin-x64 linux-x64 linux-arm64 win32-x64 win32-arm64; do
  31. bash scripts/build-bundle.sh "$t"
  32. done
  33. ls -lh release
  34. - name: Resolve version
  35. id: ver
  36. run: echo "version=$(node -p "require('./package.json').version")" >> "$GITHUB_OUTPUT"
  37. - name: Release notes from CHANGELOG.md
  38. run: |
  39. V="${{ steps.ver.outputs.version }}"
  40. node scripts/extract-release-notes.mjs "$V" > notes.md 2>/dev/null \
  41. || node scripts/extract-release-notes.mjs Unreleased > notes.md 2>/dev/null || true
  42. if [ ! -s notes.md ]; then
  43. echo "::error::No release notes in CHANGELOG.md for [$V] or [Unreleased]."
  44. exit 1
  45. fi
  46. echo "----- release notes -----"; cat notes.md
  47. - name: Create GitHub Release
  48. env:
  49. GH_TOKEN: ${{ github.token }}
  50. run: |
  51. TAG="v${{ steps.ver.outputs.version }}"
  52. # Idempotent: create the release once, otherwise (re-run) refresh assets.
  53. if gh release view "$TAG" >/dev/null 2>&1; then
  54. gh release upload "$TAG" release/codegraph-* --clobber
  55. else
  56. gh release create "$TAG" release/codegraph-* --title "$TAG" --notes-file notes.md
  57. fi
  58. - name: Publish to npm
  59. env:
  60. NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
  61. run: |
  62. V="${{ steps.ver.outputs.version }}"
  63. bash scripts/pack-npm.sh "$V"
  64. # Platform packages first, then the main shim (which depends on them).
  65. # Skip any already on the registry so a re-run only fills in gaps.
  66. for dir in release/npm/codegraph-* release/npm/main; do
  67. name=$(node -p "require('./$dir/package.json').name")
  68. if npm view "$name@$V" version >/dev/null 2>&1; then
  69. echo "skip $name@$V (already published)"
  70. else
  71. echo "publishing $name@$V"
  72. ( cd "$dir" && npm publish --access public )
  73. fi
  74. done
  75. - name: Verify every package is actually on the registry
  76. run: |
  77. V="${{ steps.ver.outputs.version }}"
  78. # npm publish can print success without persisting; confirm against the
  79. # registry (with retries for propagation) so green means really shipped.
  80. for dir in release/npm/codegraph-* release/npm/main; do
  81. name=$(node -p "require('./$dir/package.json').name")
  82. ok=
  83. for i in 1 2 3 4 5 6; do
  84. if npm view "$name@$V" version >/dev/null 2>&1; then ok=1; break; fi
  85. echo "waiting for $name@$V to appear ($i)…"; sleep 10
  86. done
  87. [ -n "$ok" ] || { echo "::error::$name@$V never appeared on the registry"; exit 1; }
  88. echo "verified $name@$V"
  89. done