-
Notifications
You must be signed in to change notification settings - Fork 0
ci: automate npm publishing of the portable skill #4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,80 @@ | ||
| name: Publish skill to npm | ||
|
|
||
| # Automatically publishes the portable skill (skill/infographic-agent) to npm. | ||
| # | ||
| # How it works — "automagic" releases: | ||
| # 1. Bump `version` in skill/infographic-agent/package.json (and update CHANGELOG.md). | ||
| # 2. Merge to main. | ||
| # 3. This workflow runs, sees the new version is not yet on npm, and publishes it. | ||
| # | ||
| # It is safe and idempotent: unrelated edits to the skill (docs, script tweaks) | ||
| # re-run the workflow but publish nothing, because the version already exists on | ||
| # npm. Only a version bump triggers an actual publish. You can also run it | ||
| # manually from the Actions tab (workflow_dispatch) — handy for the very first | ||
| # release once the package lands on main. | ||
| # | ||
| # Required secret: NPM_TOKEN — an npm "Automation" access token with publish | ||
| # rights for the `infographic-agent` package (Settings → Secrets and variables | ||
| # → Actions). Publishes include npm provenance for supply-chain attestation. | ||
|
|
||
| on: | ||
| push: | ||
| branches: [main] | ||
| paths: | ||
| - 'skill/infographic-agent/**' | ||
| workflow_dispatch: | ||
|
|
||
| concurrency: | ||
| group: publish-skill | ||
| cancel-in-progress: false | ||
|
Comment on lines
+27
to
+29
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This release workflow publishes immutable npm versions, but this concurrency block leaves GitHub Actions at the default Useful? React with 👍 / 👎. |
||
|
|
||
| permissions: | ||
| contents: write # push the release tag | ||
| id-token: write # npm provenance (OIDC attestation) | ||
|
|
||
| jobs: | ||
| publish: | ||
| runs-on: ubuntu-latest | ||
| defaults: | ||
| run: | ||
| working-directory: skill/infographic-agent | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: "20" | ||
| registry-url: "https://registry.npmjs.org" | ||
|
|
||
| - name: Sanity-check the package | ||
| run: | | ||
| node --check bin/infographic-agent.js | ||
| python3 -m py_compile portable_infographic.py | ||
| npm pack --dry-run | ||
|
|
||
| - name: Resolve version & publish state | ||
| id: v | ||
| run: | | ||
| VERSION="$(node -p "require('./package.json').version")" | ||
| echo "version=$VERSION" >> "$GITHUB_OUTPUT" | ||
| if npm view "infographic-agent@$VERSION" version >/dev/null 2>&1; then | ||
| echo "exists=true" >> "$GITHUB_OUTPUT" | ||
| echo "::notice::infographic-agent@$VERSION is already on npm — nothing to publish." | ||
| else | ||
| echo "exists=false" >> "$GITHUB_OUTPUT" | ||
| echo "::notice::infographic-agent@$VERSION is new — publishing." | ||
| fi | ||
|
|
||
| - name: Publish to npm | ||
| if: steps.v.outputs.exists == 'false' | ||
| run: npm publish --provenance --access public | ||
| env: | ||
| NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} | ||
|
|
||
| - name: Tag the release | ||
| if: steps.v.outputs.exists == 'false' | ||
| working-directory: . | ||
| run: | | ||
| TAG="skill-v${{ steps.v.outputs.version }}" | ||
| git tag "$TAG" | ||
| git push origin "$TAG" | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| # Releasing the portable skill to npm | ||
|
|
||
| The portable skill in [`skill/infographic-agent/`](../skill/infographic-agent/) is | ||
| published to npm as [`infographic-agent`](https://www.npmjs.com/package/infographic-agent) | ||
| so anyone can run it with `npx infographic-agent "..."`. | ||
|
|
||
| Releases are **automated** by | ||
| [`.github/workflows/publish-skill.yml`](../.github/workflows/publish-skill.yml). | ||
|
|
||
| ## Cutting a release (the automagic path) | ||
|
|
||
| 1. Make your changes under `skill/infographic-agent/`. | ||
| 2. Bump `version` in `skill/infographic-agent/package.json` following | ||
| [SemVer](https://semver.org/) (patch for fixes, minor for features, major for | ||
| breaking changes). | ||
| 3. Add a matching entry to [`CHANGELOG.md`](../CHANGELOG.md). | ||
| 4. Open a PR and merge it to `main`. | ||
|
|
||
| On merge, the workflow: | ||
|
|
||
| - sanity-checks the package (`node --check`, `py_compile`, `npm pack --dry-run`), | ||
| - checks whether that version is already on npm, | ||
| - if it's new, runs `npm publish --provenance --access public`, and | ||
| - pushes a `skill-v<version>` git tag. | ||
|
|
||
| If the version is unchanged, the workflow still runs but publishes nothing — so | ||
| doc-only or script-only edits are safe no-ops. To publish the very first version | ||
| after this workflow lands, trigger it once manually from the **Actions** tab | ||
| (**Publish skill to npm → Run workflow**). | ||
|
|
||
| ## One-time setup: the `NPM_TOKEN` secret | ||
|
|
||
| The workflow authenticates to npm with a repository secret named `NPM_TOKEN`. | ||
|
|
||
| 1. On [npmjs.com](https://www.npmjs.com/), go to **Access Tokens → Generate New | ||
| Token → Granular Access Token** (or a classic **Automation** token). Grant it | ||
| **read + write** for the `infographic-agent` package. Automation/granular | ||
| tokens bypass 2FA, which CI requires. | ||
| 2. In GitHub: **Settings → Secrets and variables → Actions → New repository | ||
| secret**, name it `NPM_TOKEN`, and paste the token. | ||
|
|
||
| Publishes include [npm provenance](https://docs.npmjs.com/generating-provenance-statements) | ||
| via GitHub OIDC (`id-token: write`), which cryptographically links each published | ||
| version back to the exact commit and workflow that built it. | ||
|
|
||
| ## Manual publish (fallback) | ||
|
|
||
| If you ever need to publish by hand: | ||
|
|
||
| ```bash | ||
| cd skill/infographic-agent | ||
| npm publish --dry-run # verify contents first | ||
| npm publish --access public | ||
| ``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The manual trigger is not guarded by branch, and GitHub's manual-run flow allows selecting a branch/ref to run the workflow on. In that scenario a maintainer can accidentally publish and tag a package version from an unmerged feature branch even though the push trigger is main-only, because the publish/tag steps do not re-check
github.ref. Add a job or publish-step condition forrefs/heads/mainbefore exposing the npm token.Useful? React with 👍 / 👎.