Skip to content

ci: tag-triggered npm release workflow for code and pm - #57

Merged
danii1 merged 3 commits into
mainfrom
feat/npm-release-workflow
Aug 24, 2026
Merged

ci: tag-triggered npm release workflow for code and pm#57
danii1 merged 3 commits into
mainfrom
feat/npm-release-workflow

Conversation

@danii1

@danii1 danii1 commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds .github/workflows/npm-release.yml, publishing @getdevintern/code and @getdevintern/pm to npm, modeled on pm-desktop-release.yml.

How to release:

git tag code-v2.4.1 && git push origin code-v2.4.1   # publishes @getdevintern/code
git tag pm-v2.4.1 && git push origin pm-v2.4.1       # publishes @getdevintern/pm

Or run manually via workflow_dispatch (choose code, pm, or both).

Behavior:

  • Matrix job per package; a tag push publishes only the tagged package
  • Guard step fails the release when the tag doesn't match the package's package.json version
  • Builds + typechecks with Bun (bun install --frozen-lockfilebun run build → typecheck → bun publish --access public)
  • Creates a GitHub release with generated notes for tag pushes

Secrets/variables used (already configured unless noted):

Name Type Purpose
NPM_TOKEN secret (add) npm automation token with publish rights to both scopes
POSTHOG_API_KEY secret (exists) Baked into the @getdevintern/code bundle at build time
POSTHOG_HOST variable/secret (optional) PostHog ingest host, defaults to https://us.i.posthog.com

Note: POSTHOG_API_KEY/POSTHOG_HOST are set at job level so that any rebuild triggered by prepublishOnly during bun publish still bakes the key into dist/index.js (verified locally: bun publish --dry-run re-runs the build).

Test plan

  • YAML parses cleanly
  • bun publish --dry-run verified for both packages from this repo layout (correct files packed: dist/index.js + dashboard UI assets for code, dist/lib/prompts for pm)
  • After merge: add the NPM_TOKEN secret, then do a dry release (workflow_dispatch) before cutting a real tag

danii1 added 2 commits August 24, 2026 17:10
Publishes @getdevintern/code and @getdevintern/pm to npm when a
code-v* / pm-v* tag is pushed (or via workflow_dispatch). Mirrors the
pm-desktop release workflow style: matrix job per package, Bun toolchain,
tag/version guard, GitHub release with generated notes.

- POSTHOG_API_KEY/POSTHOG_HOST injected at job level so any rebuild
  during publish still bakes the analytics key into dist/index.js
- NPM_TOKEN secret written to ~/.npmrc for bun publish
- Add id-token: write permission; publish with the official npm CLI
  (>= 11.5.1 required for the OIDC exchange) instead of bun publish,
  which does not support trusted publishing yet
- Document per-package trusted-publisher setup on npmjs.com and the
  first-publish bootstrap (OIDC requires an existing package)
- Provenance attestations are attached automatically
@danii1

danii1 commented Aug 24, 2026

Copy link
Copy Markdown
Contributor Author

Switched publishing to npm Trusted Publishing (OIDC) per npm's recommendation — no NPM_TOKEN secret needed anymore.

One-time setup per package on npmjs.com (@getdevintern/code and @getdevintern/pm → Settings → Trusted Publisher → GitHub Actions):

  • Organization/Repository: getdevintern/devintern
  • Workflow filename: npm-release.yml
  • Environment: leave empty

Bootstrap caveat: OIDC can't publish a package that doesn't exist yet — if either package has never been published, do the very first publish manually (bun publish from the package dir), then configure the trusted publisher above.

Implementation notes:

  • Job gets id-token: write; publish runs via the official npm CLI (npm install -g npm@latest && npm publish) since bun publish doesn't perform the OIDC exchange yet
  • Provenance attestations are attached automatically
  • Build/typecheck stay on Bun

The test relied on real timers: 10ms heartbeats against a 40ms lease
gave the event loop only a few scheduling slots, so under CI load one
delayed beat let the lease expire and the second acquirer steal the
claim.

- Inject setInterval/clearInterval into AutomationAcquirer alongside
  the existing now/setTimer DI hooks
- Drive the lease/heartbeat timeline manually with a fake clock; no
  real timing dependencies remain
@danii1
danii1 merged commit 3c75daa into main Aug 24, 2026
1 check passed
@danii1

danii1 commented Aug 24, 2026

Copy link
Copy Markdown
Contributor Author

The failing runs (example) were a workflow-file parse error: I had used ${{ matrix.* }} in the job-level if, but the matrix context isn't available there (only github, inputs, needs, vars), so GitHub rejected the whole file and no jobs ever started — that's why those runs show up named .github/workflows/npm-release.yml with zero jobs.

Fixed by replacing the matrix with two explicit jobs (release-code / release-pm), each with its own simple condition. Also switched the dispatch input to two booleans (code / pm) so manual selection stays obvious. Validated locally with actionlint; CI on this PR now exercises the fixed file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant