Repository navigation
v0.1.11 #11
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # ───────────────────────────────────────────────────────────────────────────── | |
| # Publish a release to npm: the engine packages, then @axiomcode/code-graph. | |
| # | |
| # @axiomcode/engine-<os>-<cpu> is one package per platform holding every | |
| # language's engine. @axiomcode/code-graph lists them as optionalDependencies | |
| # pinned to its own version, so `npm install` fetches exactly the one for the | |
| # machine — no Soufflé, no compiler. The engines therefore go first: publishing | |
| # the root before them would leave a window where the version it pins is not | |
| # on the registry. | |
| # | |
| # Runs when: | |
| # • a GitHub release is PUBLISHED (release.yml drafts one for each new version | |
| # on main; publishing the draft is the release decision). Real publish. | |
| # • manually (Actions → publish-npm → Run workflow) with dry_run, which packs | |
| # every package and prints exactly what would be uploaded, uploading nothing. | |
| # | |
| # Needs the CLI_BINARY_PUBLISH secret (an npm token with publish rights on @axiomcode) | |
| # for a real publish; a dry run needs nothing. | |
| # | |
| # Re-running is safe: a package whose version is already on the registry is | |
| # skipped, so a run that failed half way can simply be run again. | |
| # ───────────────────────────────────────────────────────────────────────────── | |
| name: publish-npm | |
| on: | |
| release: | |
| types: [published] | |
| workflow_dispatch: | |
| inputs: | |
| dry_run: | |
| description: pack and print, publish nothing | |
| type: boolean | |
| default: true | |
| concurrency: | |
| group: publish-npm-${{ github.ref }} | |
| cancel-in-progress: false | |
| permissions: | |
| contents: read | |
| jobs: | |
| # Fails in seconds, before any engine is compiled, when the tag and the tree | |
| # disagree about the version. | |
| check: | |
| runs-on: ubuntu-24.04 | |
| outputs: | |
| version: ${{ steps.v.outputs.version }} | |
| dist_tag: ${{ steps.v.outputs.dist_tag }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: '22' | |
| - id: v | |
| run: | | |
| set -euo pipefail | |
| if [ "${{ github.event_name }}" = release ]; then | |
| node .github/scripts/version.mjs check "${{ github.event.release.tag_name }}" | |
| else | |
| node .github/scripts/version.mjs check | |
| fi | |
| version="$(node .github/scripts/version.mjs get)" | |
| # A prerelease never becomes `latest`: 0.2.0-rc.1 goes out as `next`. | |
| case "$version" in *-*) dist_tag=next;; *) dist_tag=latest;; esac | |
| echo "version=$version" >> "$GITHUB_OUTPUT" | |
| echo "dist_tag=$dist_tag" >> "$GITHUB_OUTPUT" | |
| echo "publishing $version as '$dist_tag'" | |
| # Nothing is compiled here. The push that landed this version on main built every platform's | |
| # engines, packed @axiomcode/code-graph and ran the five-platform e2e on exactly those files; | |
| # release.yml drafted this release only after that run was green. Publishing ships that build, | |
| # so what was tested is what users install, and a release costs one build, not three (#1350). | |
| publish: | |
| needs: [check] | |
| runs-on: ubuntu-24.04 | |
| permissions: | |
| contents: write # attach the tarballs to the release | |
| actions: read # the release's CI run and its artifacts | |
| env: | |
| VERSION: ${{ needs.check.outputs.version }} | |
| DIST_TAG: ${{ needs.check.outputs.dist_tag }} | |
| DRY: ${{ github.event_name == 'workflow_dispatch' && inputs.dry_run }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: '22' | |
| registry-url: 'https://registry.npmjs.org' | |
| - name: the green CI run that built and tested this commit | |
| id: run | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| set -euo pipefail | |
| sha="$(git rev-parse HEAD)" | |
| run="$(gh run list --workflow ci.yml --commit "$sha" --event push --branch main --status success \ | |
| --limit 1 --json databaseId --jq '.[0].databaseId // empty')" | |
| if [ -z "$run" ]; then | |
| echo "::error::no green CI run of a push to main for ${sha::8}: nothing built and tested this commit, so nothing is published" | |
| exit 1 | |
| fi | |
| echo "id=$run" >> "$GITHUB_OUTPUT" | |
| echo "shipping the build of CI run $run ($GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$run)" | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| pattern: engines-* | |
| path: artifacts | |
| run-id: ${{ steps.run.outputs.id }} | |
| github-token: ${{ github.token }} | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: code-graph-tgz | |
| path: artifacts/tgz | |
| run-id: ${{ steps.run.outputs.id }} | |
| github-token: ${{ github.token }} | |
| # A real release ships every platform the root package pins. Missing one | |
| # means some machine installs a version whose engine does not exist. | |
| - name: every pinned platform was built | |
| run: | | |
| set -euo pipefail | |
| missing=0 | |
| for name in $(node -p "Object.keys(require('./package.json').optionalDependencies||{}).join(' ')"); do | |
| platform="${name#@axiomcode/engine-}" | |
| if [ ! -d "artifacts/engines-$platform" ]; then | |
| echo "::warning::no engines were built for $platform" | |
| missing=1 | |
| fi | |
| # and every query program the CLI runs, or impact/path need soufflé there (#1330) | |
| for dl in plugins/axiomcode/skills/axiomcode/scripts/dl/*.dl; do | |
| q="$(basename "$dl" .dl)" | |
| if ! cmp -s <(python3 plugins/axiomcode/skills/axiomcode/scripts/dl_program.py --print-id "$dl") \ | |
| <(cat "artifacts/engines-$platform/queries/$q.id" 2>/dev/null; echo); then | |
| echo "::warning::$platform has no query program for these $q.dl rules" | |
| missing=1 | |
| fi | |
| done | |
| done | |
| if [ "$missing" = 1 ] && [ "$DRY" != true ]; then | |
| echo "::error::a real publish needs every platform package.json pins"; exit 1 | |
| fi | |
| - name: assemble one engine package per platform | |
| run: | | |
| set -euo pipefail | |
| for d in artifacts/engines-*; do | |
| platform="${d#artifacts/engines-}" | |
| bash packaging/assemble-engine-package.sh "$platform" "$VERSION" "$d" "packages/engine-$platform" | |
| cat "packages/engine-$platform/package.json" | |
| done | |
| - name: the tested @axiomcode/code-graph tarball is this version | |
| run: | | |
| set -euo pipefail | |
| tgz="$(ls artifacts/tgz/*.tgz)" | |
| got="$(tar -xOzf "$tgz" package/package.json | node -e 'let s="";process.stdin.on("data",d=>s+=d).on("end",()=>console.log(JSON.parse(s).version))')" | |
| [ "$got" = "$VERSION" ] || { echo "::error::the tested tarball is $got, this release is $VERSION"; exit 1; } | |
| echo "TGZ=$tgz" >> "$GITHUB_ENV" | |
| - name: publish (or dry-run) | |
| env: | |
| NODE_AUTH_TOKEN: ${{ secrets.CLI_BINARY_PUBLISH }} | |
| run: | | |
| set -euo pipefail | |
| flag=""; [ "$DRY" = true ] && flag="--dry-run" | |
| mkdir -p tarballs | |
| publish() { | |
| local dir="$1" name | |
| name="$(node -p "require('./$dir/package.json').name")" | |
| if [ -z "$flag" ] && npm view "$name@$VERSION" version >/dev/null 2>&1; then | |
| echo "══ $name@$VERSION is already on the registry — skipped" | |
| return | |
| fi | |
| echo "══ $name@$VERSION tag=$DIST_TAG $flag" | |
| ( cd "$dir" && npm pack --pack-destination "$GITHUB_WORKSPACE/tarballs" >/dev/null \ | |
| && npm publish --access public --tag "$DIST_TAG" $flag ) | |
| } | |
| for p in packages/engine-*; do publish "$p"; done | |
| # the tarball the e2e installed, published as it is rather than packed again | |
| if [ -z "$flag" ] && npm view "@axiomcode/code-graph@$VERSION" version >/dev/null 2>&1; then | |
| echo "══ @axiomcode/code-graph@$VERSION is already on the registry — skipped" | |
| else | |
| echo "══ @axiomcode/code-graph@$VERSION tag=$DIST_TAG $flag" | |
| cp "$TGZ" tarballs/ | |
| npm publish "$TGZ" --access public --tag "$DIST_TAG" $flag | |
| fi | |
| ls -la tarballs | |
| if [ "$DRY" = true ]; then | |
| echo "DRY RUN — nothing was uploaded." | |
| else | |
| echo "published $VERSION" | |
| fi | |
| - name: attach the tarballs to the release | |
| if: github.event_name == 'release' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: gh release upload "${{ github.event.release.tag_name }}" tarballs/*.tgz --clobber | |
| - uses: actions/upload-artifact@v4 | |
| if: github.event_name == 'workflow_dispatch' | |
| with: { name: npm-tarballs, path: tarballs, retention-days: 7 } |