Skip to content

Commit 70c7627

Browse files
feat: publish dev builds as GitHub pre-releases instead of npm
Split the publish workflow so dev builds (push to main) create GitHub pre-releases with tarballs instead of publishing to npm. This stops polluting the npm registry with transient dev versions. - Add publish-dev job: npm pack + gh release create --prerelease - Auto-prune old dev releases, keeping only the last 5 - Simplify dev version computation (no more npm registry query) - Stable publish job unchanged (still publishes to npm with OIDC)
1 parent 6eef6b3 commit 70c7627

File tree

1 file changed

+136
-46
lines changed

1 file changed

+136
-46
lines changed

.github/workflows/publish.yml

Lines changed: 136 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -66,25 +66,9 @@ jobs:
6666
echo "Stable release (manual retry): $VERSION"
6767
else
6868
IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT"
69-
BASE_PATCH=$((PATCH + 1))
69+
DEV_PATCH=$((PATCH + 1))
7070
SHORT_SHA=$(echo "${{ github.sha }}" | cut -c1-7)
71-
72-
# Query npm for the highest dev patch number published so far
73-
LATEST_DEV=$(npm view "@optave/codegraph" versions --json 2>/dev/null \
74-
| node -e "
75-
const versions = JSON.parse(require('fs').readFileSync(0,'utf8'));
76-
const prefix = '${MAJOR}.${MINOR}.';
77-
let maxPatch = ${BASE_PATCH} - 1;
78-
for (const v of (Array.isArray(versions) ? versions : [versions])) {
79-
if (v.startsWith(prefix) && v.includes('-dev.')) {
80-
const patch = parseInt(v.split('.')[2], 10);
81-
if (patch > maxPatch) maxPatch = patch;
82-
}
83-
}
84-
console.log(maxPatch + 1);
85-
" 2>/dev/null) || LATEST_DEV="$BASE_PATCH"
86-
87-
VERSION="${MAJOR}.${MINOR}.${LATEST_DEV}-dev.${SHORT_SHA}"
71+
VERSION="${MAJOR}.${MINOR}.${DEV_PATCH}-dev.${SHORT_SHA}"
8872
NPM_TAG="dev"
8973
echo "Dev release: $VERSION"
9074
fi
@@ -152,7 +136,141 @@ jobs:
152136
path: crates/codegraph-core/*.node
153137
if-no-files-found: error
154138

139+
# ── Dev builds: GitHub pre-release with tarballs ──
140+
141+
publish-dev:
142+
if: github.event_name == 'push'
143+
needs: [compute-version, build-native]
144+
runs-on: ubuntu-latest
145+
permissions:
146+
contents: write
147+
148+
steps:
149+
- uses: actions/checkout@v4
150+
151+
- uses: actions/setup-node@v4
152+
with:
153+
node-version: "22"
154+
155+
- run: npm install
156+
157+
- name: Set version
158+
env:
159+
VERSION: ${{ needs.compute-version.outputs.version }}
160+
run: |
161+
npm version "$VERSION" --no-git-tag-version --allow-same-version
162+
node scripts/sync-native-versions.js
163+
echo "Packaging version $VERSION"
164+
165+
- name: Disable prepublishOnly
166+
run: npm pkg delete scripts.prepublishOnly
167+
168+
- name: Download native artifacts
169+
uses: actions/download-artifact@v4
170+
with:
171+
path: ${{ runner.temp }}/artifacts/
172+
173+
- name: Pack main package
174+
run: npm pack
175+
176+
- name: Pack platform packages
177+
env:
178+
VERSION: ${{ needs.compute-version.outputs.version }}
179+
shell: bash
180+
run: |
181+
declare -A PACKAGES=(
182+
["linux-x64"]="@optave/codegraph-linux-x64-gnu"
183+
["darwin-arm64"]="@optave/codegraph-darwin-arm64"
184+
["darwin-x64"]="@optave/codegraph-darwin-x64"
185+
["win32-x64"]="@optave/codegraph-win32-x64-msvc"
186+
)
187+
188+
ARTIFACTS="${RUNNER_TEMP}/artifacts"
189+
PKG_DIR="${RUNNER_TEMP}/pkg"
190+
191+
for artifact_dir in "${ARTIFACTS}"/native-*/; do
192+
platform=$(basename "$artifact_dir" | sed 's/^native-//')
193+
pkg_name=${PACKAGES[$platform]}
194+
node_os=${platform%%-*}
195+
node_arch=${platform##*-}
196+
197+
mkdir -p "${PKG_DIR}/$platform"
198+
cp "$artifact_dir"/*.node "${PKG_DIR}/$platform/codegraph-core.node"
199+
200+
cat > "${PKG_DIR}/$platform/package.json" <<PKGJSON
201+
{
202+
"name": "${pkg_name}",
203+
"version": "${VERSION}",
204+
"description": "Native codegraph-core binary for ${node_os}-${node_arch}",
205+
"os": ["${node_os}"],
206+
"cpu": ["${node_arch}"],
207+
"main": "codegraph-core.node",
208+
"files": ["codegraph-core.node"],
209+
"license": "Apache-2.0",
210+
"repository": {
211+
"type": "git",
212+
"url": "https://github.com/optave/codegraph.git"
213+
}
214+
}
215+
PKGJSON
216+
217+
npm pack "${PKG_DIR}/$platform"
218+
done
219+
220+
- name: Create GitHub pre-release
221+
env:
222+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
223+
VERSION: ${{ needs.compute-version.outputs.version }}
224+
run: |
225+
TAG="dev-v${VERSION}"
226+
gh release create "$TAG" \
227+
--prerelease \
228+
--title "Dev build ${VERSION}" \
229+
--notes "Dev build from commit \`${{ github.sha }}\` on \`main\`." \
230+
*.tgz
231+
232+
- name: Prune old dev releases
233+
env:
234+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
235+
run: |
236+
# List dev releases sorted newest-first, skip the first 5, delete the rest
237+
gh release list --limit 100 --json tagName,isPrerelease,createdAt \
238+
| jq -r '
239+
[ .[] | select(.isPrerelease and (.tagName | startswith("dev-v"))) ]
240+
| sort_by(.createdAt) | reverse
241+
| .[5:]
242+
| .[].tagName
243+
' \
244+
| while read -r tag; do
245+
echo "Deleting old dev release: $tag"
246+
gh release delete "$tag" --yes --cleanup-tag
247+
done
248+
249+
- name: Summary
250+
env:
251+
VERSION: ${{ needs.compute-version.outputs.version }}
252+
run: |
253+
TAG="dev-v${VERSION}"
254+
cat >> "$GITHUB_STEP_SUMMARY" <<EOF
255+
## Dev Build Published
256+
257+
**Version:** \`${VERSION}\`
258+
**Commit:** \`${{ github.sha }}\`
259+
260+
### Download
261+
262+
Tarballs attached to [GitHub release \`${TAG}\`](${{ github.server_url }}/${{ github.repository }}/releases/tag/${TAG}).
263+
264+
\`\`\`bash
265+
# Install the main package from the release tarball:
266+
npm install ${{ github.server_url }}/${{ github.repository }}/releases/download/${TAG}/optave-codegraph-${VERSION}.tgz
267+
\`\`\`
268+
EOF
269+
270+
# ── Stable releases: publish to npm ──
271+
155272
publish:
273+
if: github.event_name != 'push'
156274
needs: [compute-version, build-native]
157275
runs-on: ubuntu-latest
158276
environment: npm-publish
@@ -179,7 +297,6 @@ jobs:
179297
- run: npm install
180298

181299
- name: Set version
182-
id: version
183300
env:
184301
VERSION: ${{ needs.compute-version.outputs.version }}
185302
run: |
@@ -270,20 +387,15 @@ jobs:
270387
NPM_TAG: ${{ needs.compute-version.outputs.npm_tag }}
271388
run: npm publish --access public --provenance --tag "$NPM_TAG"
272389

273-
# ── Stable-only: version bump PR and tag ──
274-
275390
- name: Configure git
276-
if: github.event_name != 'push'
277391
run: |
278392
git config user.name "github-actions[bot]"
279393
git config user.email "github-actions[bot]@users.noreply.github.com"
280394
281395
- name: Generate DEPENDENCIES.json
282-
if: github.event_name != 'push'
283396
run: mkdir -p generated && npm ls --json --all --omit=dev > generated/DEPENDENCIES.json 2>/dev/null || true
284397

285398
- name: Push version bump via PR
286-
if: github.event_name != 'push'
287399
env:
288400
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
289401
VERSION: ${{ needs.compute-version.outputs.version }}
@@ -313,25 +425,3 @@ jobs:
313425
git tag -a "$TAG" -m "release: $TAG"
314426
git push origin "$TAG"
315427
fi
316-
317-
# ── Dev-only: summary with install instructions ──
318-
319-
- name: Summary
320-
if: github.event_name == 'push'
321-
env:
322-
VERSION: ${{ needs.compute-version.outputs.version }}
323-
run: |
324-
cat >> "$GITHUB_STEP_SUMMARY" <<EOF
325-
## Dev Release Published
326-
327-
**Version:** \`${VERSION}\`
328-
**Commit:** \`${{ github.sha }}\`
329-
330-
### Install
331-
332-
\`\`\`bash
333-
npm install @optave/codegraph@dev
334-
# or pin this exact version:
335-
npm install @optave/codegraph@${VERSION}
336-
\`\`\`
337-
EOF

0 commit comments

Comments
 (0)