Skip to content

Personal Release

Personal Release #9

name: Personal Release
on:
workflow_dispatch:
inputs:
tag:
description: Optional tag override; when empty, use v<package version>
required: false
default: ''
concurrency:
group: personal-release
cancel-in-progress: false
permissions:
contents: write
actions: read
jobs:
package:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: 22
cache: npm
- run: npm ci
- run: npm run check:release-metadata
- name: Require successful CI for this commit
env:
GH_TOKEN: ${{ github.token }}
shell: bash
run: |
set -euo pipefail
PASSED="$(gh run list --repo nk33-dev/codegraph --workflow CI --commit "$GITHUB_SHA" --event push \
--json status,conclusion --jq '[.[] | select(.status == "completed" and .conclusion == "success")] | length')"
[ "$PASSED" -gt 0 ] || {
echo "::error::CI has not succeeded for $GITHUB_SHA; release only after the personal branch CI is green"
exit 1
}
- run: npm run verify:personal-install
- name: Validate tag and build personal source package
id: package
shell: bash
run: |
set -euo pipefail
VERSION="$(node -p "require('./package.json').version")"
REQUESTED_TAG="${{ inputs.tag }}"
TAG="${REQUESTED_TAG:-v$VERSION}"
[ "$TAG" = "v$VERSION" ] || { echo "::error::tag $TAG does not match package version v$VERSION"; exit 1; }
NOTES="docs/person/releases/$TAG.md"
[ -f "$NOTES" ] || { echo "::error::missing release notes: $NOTES"; exit 1; }
PACKAGE_BASENAME="$(node -p 'const p=require("./package.json"); p.name.replace(/^@/, "").replace("/", "-") + "-" + p.version + ".tgz"')"
PACK_DIR="$RUNNER_TEMP/codegraph-personal-pack"
mkdir -p "$PACK_DIR"
npm pack --ignore-scripts --silent --pack-destination "$PACK_DIR" >/dev/null
ARCHIVE="$PACK_DIR/$PACKAGE_BASENAME"
[ -f "$ARCHIVE" ] || { echo "::error::npm pack did not create $ARCHIVE"; exit 1; }
sha256sum "$ARCHIVE" > SHA256SUMS
echo "archive=$ARCHIVE" >> "$GITHUB_OUTPUT"
echo "notes=$NOTES" >> "$GITHUB_OUTPUT"
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
- uses: actions/upload-artifact@v4
with:
name: codegraph-personal-${{ github.sha }}
path: |
${{ steps.package.outputs.archive }}
SHA256SUMS
if-no-files-found: error
retention-days: 14
- name: Create or refresh GitHub prerelease
env:
GH_TOKEN: ${{ github.token }}
TAG: ${{ steps.package.outputs.tag }}
ARCHIVE: ${{ steps.package.outputs.archive }}
NOTES: ${{ steps.package.outputs.notes }}
shell: bash
run: |
set -euo pipefail
if gh release view "$TAG" --repo nk33-dev/codegraph >/dev/null 2>&1; then
TAG_SHA="$(gh api "repos/nk33-dev/codegraph/git/ref/tags/$TAG" --jq '.object.sha')"
[ "$TAG_SHA" = "$GITHUB_SHA" ] || {
echo "::error::existing tag $TAG points to $TAG_SHA, not this workflow commit $GITHUB_SHA"
exit 1
}
gh release upload "$TAG" "$ARCHIVE" SHA256SUMS --clobber --repo nk33-dev/codegraph
gh release edit "$TAG" --notes-file "$NOTES" --prerelease --repo nk33-dev/codegraph
else
gh release create "$TAG" "$ARCHIVE" SHA256SUMS \
--target "$GITHUB_SHA" --title "CodeGraph $TAG" --notes-file "$NOTES" --prerelease \
--repo nk33-dev/codegraph
fi