Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions .github/workflows/publish-skill.yml
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:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Restrict manual publishes to main

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 for refs/heads/main before exposing the npm token.

Useful? React with 👍 / 👎.


concurrency:
group: publish-skill
cancel-in-progress: false
Comment on lines +27 to +29

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Queue all pending release runs

This release workflow publishes immutable npm versions, but this concurrency block leaves GitHub Actions at the default queue: single behavior; GitHub documents that a newly queued run cancels and replaces an existing pending run in the same group. If several skill/infographic-agent version-bump pushes land while one publish is still running, an earlier pending version can be canceled and never published or tagged. Add queue: max or another queueing strategy so every release run is processed.

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"
54 changes: 54 additions & 0 deletions docs/releasing.md
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
```
Loading