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
56 changes: 56 additions & 0 deletions .github/workflows/release-please.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: Release Please

# Automates versioning and publishing from conventional commits:
# 1. Every push to main updates a "Release PR" (version bump + CHANGELOG).
# 2. Merging that PR creates the vX.Y.Z tag and GitHub Release, then this same
# run publishes to npm and attaches the tarball. Publishing lives HERE because
# tags created with GITHUB_TOKEN never trigger other workflows (release.yml).
# Only fix:/feat: (and breaking) commits produce a release; never bump package.json by hand.
on:
push:
branches: [main]

permissions:
contents: write
pull-requests: write

jobs:
release:
name: Release PR or publish
runs-on: ubuntu-latest
steps:
- uses: googleapis/release-please-action@v4
id: release
with:
config-file: release-please-config.json
manifest-file: .release-please-manifest.json
- if: ${{ steps.release.outputs.release_created }}
uses: actions/checkout@v4
- if: ${{ steps.release.outputs.release_created }}
uses: pnpm/action-setup@v4
- if: ${{ steps.release.outputs.release_created }}
uses: actions/setup-node@v4
with:
node-version: "22"
registry-url: "https://registry.npmjs.org"
cache: pnpm
- if: ${{ steps.release.outputs.release_created }}
run: pnpm install --frozen-lockfile
env:
ASKNEWS_NO_AGENT_SKILLS: "1"
# Bundle from the committed OpenAPI snapshot (deterministic, no network).
- if: ${{ steps.release.outputs.release_created }}
run: pnpm build:bundle
- if: ${{ steps.release.outputs.release_created }}
run: pnpm package:tarball
- if: ${{ steps.release.outputs.release_created }}
name: Publish to npm
uses: JS-DevTools/npm-publish@v3
with:
token: ${{ secrets.NPM_TOKEN }}
access: public
- if: ${{ steps.release.outputs.release_created }}
name: Attach tarball and checksum to the GitHub Release
env:
GH_TOKEN: ${{ github.token }}
run: gh release upload "${{ steps.release.outputs.tag_name }}" release/*.tgz release/*.tgz.sha256
3 changes: 3 additions & 0 deletions .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
".": "0.2.3"
}
6 changes: 5 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,11 @@ pnpm build # generate and bundle dist/bin.js
generated files.
- Non-interactive commands must never prompt. Respect `CI`, non-TTY streams, and explicit flags.
- Destructive or billable live tests require both the live-test gate and an operation-specific gate.
- Publishing the npm package happens through the release workflow on a `v*` tag; do not publish by hand.
- Releases are automated by release-please (`.github/workflows/release-please.yml`): merging to `main`
updates a Release PR; merging that PR tags, publishes to npm, and creates the GitHub Release.
Never bump `package.json` version by hand and never push `v*` tags by hand (`release.yml` is only
an emergency fallback). Only `fix:`/`feat:`/breaking commits trigger a release — use `fix:` (not
`chore:`) for user-visible schema refreshes so they ship.

## Docs map

Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# AskNews CLI

[![npm version](https://img.shields.io/npm/v/%40emergentmethods%2Fasknews-cli?label=npm)](https://www.npmjs.com/package/@emergentmethods/asknews-cli)

The official AskNews command-line interface for humans, scripts, CI, and AI agents.

## Install
Expand Down
43 changes: 25 additions & 18 deletions docs/runbooks/release.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
# Release

The CLI is published to npm as [`@emergentmethods/asknews-cli`](https://www.npmjs.com/package/@emergentmethods/asknews-cli)
and distributed from GitHub. Releases are automated: pushing a `v*` tag runs
[`.github/workflows/release.yml`](../../.github/workflows/release.yml), which publishes to npm and
creates a GitHub Release with the package tarball and checksum.
and distributed from GitHub. Releases are automated by release-please
([`.github/workflows/release-please.yml`](../../.github/workflows/release-please.yml)):

1. every push to `main` creates or updates a **Release PR** that bumps `package.json`, updates
`CHANGELOG.md`, and lists the changes since the last release (from conventional commits);
2. merging the Release PR creates the `vX.Y.Z` tag and the GitHub Release, and the same workflow run
publishes to npm and attaches the tarball + checksum.

Only `fix:`, `feat:`, and breaking-change commits produce a release; `chore:`/`docs:` commits are
collected but do not trigger one on their own — use `fix:` for user-visible schema refreshes.
Never bump `package.json` by hand and never push `v*` tags by hand.
[`release.yml`](../../.github/workflows/release.yml) (tag-triggered) remains only as an emergency
fallback if the automation is broken.

## Preconditions

- The public OpenAPI snapshot and generated command reference are current (`pnpm sync:openapi:check`).
- `pnpm check` and `pnpm build` pass; opt-in live checks pass if relevant.
- The version in `package.json` is bumped and the changelog/release notes are reviewed.
- The Release PR's version bump and generated notes look right (edit the PR body to adjust notes).
- The `asknews-cli` public OAuth client is registered for the target environment.

## Local package verification
Expand All @@ -31,24 +41,21 @@ embedded AskNews skill. It must not contain credentials, `.env` files, tests, or

## Cut a release

```bash
# after the version bump lands on main
git tag v0.1.0
git push origin v0.1.0
```

The release workflow then:
Merge the open Release PR (title `chore(main): release X.Y.Z`). The workflow then:

1. installs dependencies and bundles `dist/` from the committed OpenAPI snapshot;
2. builds the versioned tarball and `.sha256`;
3. publishes to npm with `access: public` (using the `NPM_TOKEN` repository secret);
4. creates a GitHub Release with the tarball and checksum attached.
1. creates the tag and GitHub Release with the changelog notes;
2. installs dependencies and bundles `dist/` from the committed OpenAPI snapshot;
3. builds the versioned tarball and `.sha256`;
4. publishes to npm with `access: public` (using the `NPM_TOKEN` repository secret);
5. attaches the tarball and checksum to the GitHub Release.

`JS-DevTools/npm-publish` is a no-op if the `package.json` version is already on npm, so re-running a
tag is safe.
`JS-DevTools/npm-publish` is a no-op if the `package.json` version is already on npm, so re-running
the workflow is safe. The npm badge in the README reflects the published version.

## One-time setup

- Create an automation token in the `@emergentmethods` npm org and add it as the `NPM_TOKEN`
repository secret.
- Validate the pipeline with a pre-release tag (for example `v0.0.1-rc.0`) before the first real tag.
- The `NPM_TOKEN` must be an npm **Automation** token (classic Publish tokens fail with EOTP in CI).
- The GitHub organization must allow GitHub Actions to create pull requests (Org Settings → Actions →
General → Workflow permissions), or release-please cannot open the Release PR.
9 changes: 9 additions & 0 deletions release-please-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
"release-type": "node",
"bump-minor-pre-major": true,
"include-component-in-tag": false,
"packages": {
".": {}
}
}
Loading