Skip to content
Closed
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
25 changes: 25 additions & 0 deletions .github/workflows/commitlint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Commitlint

on:
pull_request:
branches: [main]

jobs:
commitlint:
name: Lint PR commits
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6.0.2
with:
fetch-depth: 0
- uses: actions/setup-node@v6.3.0
with:
node-version: 22
cache: npm
- run: npm ci
- name: Validate commits in PR
run: |
npx commitlint \
--from "${{ github.event.pull_request.base.sha }}" \
--to "${{ github.event.pull_request.head.sha }}" \
--verbose
25 changes: 0 additions & 25 deletions .github/workflows/publish.yml

This file was deleted.

69 changes: 69 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
name: Release

on:
push:
tags:
- 'agent@v*'
- 'render@v*'
- 'chat@v*'
workflow_dispatch:
inputs:
version-spec:
description: 'Version spec (e.g., "patch", "minor", "major", "1.0.0"). Omit to use conventional commits.'
required: false
default: ''
dry-run:
description: 'Dry run (no publish, no tag push)'
required: false
type: boolean
default: false

permissions:
contents: write # push tags + create GitHub Release
id-token: write # npm provenance via OIDC

jobs:
publish:
name: Publish to npm
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6.0.2
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}

- uses: actions/setup-node@v6.3.0
with:
node-version: 22
cache: npm
registry-url: https://registry.npmjs.org

- run: npm ci

- name: Git identity (for version commits)
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"

# ── Manual dispatch: run version + changelog, create tags ────────────
- name: Nx release version (manual dispatch)
if: github.event_name == 'workflow_dispatch'
run: |
SPEC="${{ github.event.inputs.version-spec }}"
DRY="${{ github.event.inputs.dry-run }}"
ARGS=""
if [ -n "$SPEC" ]; then ARGS="$ARGS $SPEC"; fi
if [ "$DRY" = "true" ]; then ARGS="$ARGS --dry-run"; fi
npx nx release $ARGS --yes

# ── Tag-push: build + publish the tagged packages ────────────────────
- name: Build libs (tag push)
if: github.event_name == 'push'
run: npx nx run-many -t build -p agent,render,chat

- name: Nx release publish (tag push)
if: github.event_name == 'push'
run: npx nx release publish --yes
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
NPM_CONFIG_PROVENANCE: 'true'
1 change: 1 addition & 0 deletions .husky/commit-msg
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
npx --no-install commitlint --edit "$1"
28 changes: 28 additions & 0 deletions commitlint.config.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
// Require a scope on every commit (paired with scope-enum below).
'scope-empty': [2, 'never'],
// Require a scope on every commit. Allowlist maps to the monorepo's public
// surface area; `repo` and `deps` are escape hatches for cross-cutting or
// dependency-bump commits.
'scope-enum': [
2,
'always',
[
'agent',
'render',
'chat',
'website',
'cockpit',
'release',
'deps',
'ci',
'docs',
'repo',
],
],
// Override upstream default (warn) to enforce as an error at the same limit.
'header-max-length': [2, 'always', 100],
},
};
107 changes: 107 additions & 0 deletions docs/release-runbook.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Release Runbook

How to cut a new release of `@cacheplane/angular`, `@cacheplane/render`, or `@cacheplane/chat`.

## Prerequisites

- Clean working tree on `main` (pull latest)
- `NPM_TOKEN` configured in GitHub repo secrets (for CI)
- Local login to npm (`npm login`) if doing a manual publish (not the default path)

## Standard release (preferred)

1. **Pre-flight smoke against local registry:**

```bash
./scripts/verify-release-local.sh
```

Fix any failures before proceeding.

2. **Version + changelog locally:**

```bash
npm run release:version
npm run release:changelog
```

Nx analyzes conventional commits since the last `<pkg>@v*` tag for each project and:
- bumps `libs/<pkg>/package.json` version
- updates `libs/<pkg>/CHANGELOG.md`
- creates one commit + one tag per bumped package

**First release:** if this is the very first release (no prior `<pkg>@v*` tags), pass `--first-release` to both commands so Nx seeds the initial version and changelog:

```bash
npx nx release version --first-release
npx nx release changelog --first-release
```

3. **Review the generated commit + tags:**

```bash
git log -5 --oneline
git tag --contains HEAD
```

Expected: one commit per bumped package (e.g., `chore(release): publish @cacheplane/angular@1.0.0`) and matching tags like `agent@v1.0.0`.

4. **Push commits + tags:**

```bash
git push origin main --follow-tags
```

Pushing the tag triggers `.github/workflows/release.yml`, which runs `nx release publish` with npm provenance.

5. **Verify on npm:**

- https://www.npmjs.com/package/@cacheplane/angular
- https://www.npmjs.com/package/@cacheplane/render
- https://www.npmjs.com/package/@cacheplane/chat

Each published version should have a "Provenance" badge.

## Manual dispatch (recovery path)

Use GitHub Actions → Release → "Run workflow" when:
- A previous release failed mid-publish
- You need to publish without running `nx release` locally

Provide `version-spec` (e.g., `patch`, `1.0.1`) or leave empty to use conventional commits. Check `dry-run` to preview.

## Troubleshooting

**Tag pushed but nothing published:**
- Check the Release workflow run in GitHub Actions
- Common cause: `NPM_TOKEN` expired or missing

**Provenance missing from published package:**
- Confirm the workflow ran on a tag push (not a manual `npm publish`)
- Confirm `permissions: id-token: write` is present in `.github/workflows/release.yml`

**Wrong version bumped:**
- Commit messages since last tag determined the bump. Review with:
```bash
git log <pkg>@v<prev>..HEAD --oneline -- libs/<pkg>
```
- To override, use manual dispatch with explicit `version-spec`

**Rolled back release:**
- `npm` publishes are immutable. To "roll back," publish a new patch version.
- If a tag was pushed but the publish failed, delete the tag locally and remote before retrying:
```bash
git tag -d agent@v1.0.0
git push origin :refs/tags/agent@v1.0.0
```

## Version policy

- `@cacheplane/angular`, `@cacheplane/render`, `@cacheplane/chat` follow semver independently.
- Breaking changes to any public export = major bump.
- New exports or non-breaking API additions = minor bump.
- Bug fixes with no API change = patch bump.
- Conventional commit types drive bumps:
- `feat(<scope>):` → minor
- `fix(<scope>):` → patch
- `BREAKING CHANGE:` footer or `!` suffix → major
8 changes: 8 additions & 0 deletions libs/agent/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Changelog

All notable changes to `@cacheplane/angular` will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
4 changes: 4 additions & 0 deletions libs/agent/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
{
"name": "@cacheplane/angular",
"version": "0.0.1",
"publishConfig": {
"access": "public",
"provenance": true
},
"peerDependencies": {
"@angular/core": "^20.0.0 || ^21.0.0",
"@langchain/core": "^1.1.33",
Expand Down
8 changes: 8 additions & 0 deletions libs/chat/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Changelog

All notable changes to `@cacheplane/chat` will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
4 changes: 4 additions & 0 deletions libs/chat/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
{
"name": "@cacheplane/chat",
"version": "0.0.1",
"publishConfig": {
"access": "public",
"provenance": true
},
"peerDependencies": {
"@angular/core": "^20.0.0 || ^21.0.0",
"@angular/common": "^20.0.0 || ^21.0.0",
Expand Down
8 changes: 8 additions & 0 deletions libs/render/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Changelog

All notable changes to `@cacheplane/render` will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
4 changes: 4 additions & 0 deletions libs/render/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
{
"name": "@cacheplane/render",
"version": "0.0.1",
"publishConfig": {
"access": "public",
"provenance": true
},
"peerDependencies": {
"@angular/core": "^20.0.0 || ^21.0.0",
"@angular/common": "^20.0.0 || ^21.0.0",
Expand Down
20 changes: 19 additions & 1 deletion nx.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,26 @@
}
},
"release": {
"projects": ["agent", "render", "chat"],
"projectsRelationship": "independent",
"releaseTagPattern": "{projectName}@v{version}",
"version": {
"preVersionCommand": "npx nx run-many -t build"
"preVersionCommand": "npx nx run-many -t build -p agent,render,chat",
"conventionalCommits": true,
"preserveMatchingDependencyRanges": false,
"updateDependents": "always",
"generatorOptions": {
"packageRoot": "{projectRoot}",
"currentVersionResolver": "git-tag",
"fallbackCurrentVersionResolver": "disk"
}
},
"changelog": {
"projectChangelogs": {
"createRelease": "github",
"file": "{projectRoot}/CHANGELOG.md"
},
"workspaceChangelog": false
}
},
"generators": {
Expand Down
Loading
Loading