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
114 changes: 114 additions & 0 deletions .agents/skills/prepare-package-release/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
---
name: prepare-package-release
description: Prepare and validate Rudder plugin version bumps, including synchronized package/plugin manifests and a CodeAlmanac wiki refresh. Use whenever changing the version in package.json, package-lock.json, .codex-plugin/plugin.json, .claude-plugin/plugin.json, or .claude-plugin/marketplace.json; when asked to bump, cut, or prepare a Rudder release; or when reviewing a branch that already contains a version bump.
---

# Prepare Package Release

Keep the release version synchronized, update the repository wiki from the
complete release diff, and leave tag and artifact creation to the publish
workflow.

## Follow the workflow

1. Inspect `git status`, the branch diff against `origin/main`, `package.json`,
the plugin manifests, and the current release guidance:

```bash
git fetch origin main --tags
git diff --stat origin/main...HEAD
codealmanac show guides/release/prepare-package-release
```

2. Confirm the intended semantic version.
Treat `package.json` as the release version source of truth.
Ask the user if the task does not establish the bump level.

3. Run npm's version command without creating a commit or tag:

```bash
npm version <patch|minor|major|version> --no-git-tag-version
```

Synchronize that exact version in:

- `package-lock.json` at the root `version` and `packages[""].version`;
- `.codex-plugin/plugin.json`;
- `.claude-plugin/plugin.json`;
Comment on lines +33 to +37

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Already-bumped versions advance again

When this skill reviews a branch that already contains the intended version bump, step 3 still runs npm version; a bump-level argument advances the version again, while the unchanged explicit version is rejected by npm, preventing the documented review workflow from completing with the confirmed release version.

Fix in Cursor Fix in Conductor

- `.claude-plugin/marketplace.json` at both the plugin version and npm source
version.

Do not create or push a release tag.
The publish workflow creates the tag and GitHub Release after merge.

4. Find the previous release tag after the manifests are synchronized:

```bash
previous_release_tag="$(
git describe --tags --match 'rudder-plugin-v*' --abbrev=0
)"
release_range="${previous_release_tag}..HEAD"
```

Stop and ask the user if no previous release tag exists.
Do not use `origin/main` as the source boundary.
Merged changes since the previous tag still belong to the release.

5. Run CodeAlmanac Ingest for every version bump.
Give it the complete committed release range plus staged and unstaged edits:

```bash
guidance="Update durable release knowledge and version claims."
guidance+=" A no-op is valid."
codealmanac ingest "git:range:${release_range}" git:diff \
--title "Document Rudder release <version>" \
--guidance "$guidance"
```

Wait for the ingest job to finish.
Use `codealmanac jobs attach <run-id>` if the command returns early.

6. Run Garden after Ingest.
Ingest defines the release source boundary.
Garden reconciles that knowledge with the rest of the wiki:

```bash
codealmanac garden \
--title "Garden after Rudder release <version>" \
--guidance "Reconcile the wiki after ingesting ${release_range}."
```

Wait for the Garden job to finish or attach to its run ID.
Review all resulting `almanac/**/*.md` and `almanac/topics.yaml` changes.
Accept a no-op when the release adds no durable knowledge.
Do not manufacture a wiki edit solely to record a version number.

7. Validate the wiki and package:

```bash
codealmanac validate
npm run typecheck
npm test
npm run build
```

Also run `npm run format:markdown:check` when CodeAlmanac changed Markdown.

8. Review the complete diff:

```bash
git diff --check
git diff --stat origin/main...HEAD
Comment on lines +92 to +101

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 Release validation omits publish gates

The new workflow reports package validation without running the changed-line coverage check or package dry run required by the publishing workflow, so contributors can receive a successful preparation report only for CI or post-merge publishing to reject the same revision.

Fix in Cursor Fix in Conductor

git diff
```

Confirm all version-bearing manifests match `package.json`, CodeAlmanac
completed successfully or explicitly made a valid no-op, no local release
tag was created, and generated `dist/` output is not included.

## Report the result

State the old and new versions, list synchronized manifests, summarize the
CodeAlmanac outcome and any wiki pages changed, report wiki/package validation,
and note that publishing, tagging, and GitHub Release creation occur after
merge.
4 changes: 4 additions & 0 deletions .agents/skills/prepare-package-release/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
interface:
display_name: "Prepare Package Release"
short_description: "Bump package versions and refresh Almanac docs"
default_prompt: "Use $prepare-package-release to prepare this version bump and refresh the CodeAlmanac wiki."
13 changes: 11 additions & 2 deletions almanac/architecture/automation/contributor-automation.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ sources:
- id: comments-skill
type: file
path: .agents/skills/address-pr-comments/SKILL.md
- id: release-skill
type: file
path: .agents/skills/prepare-package-release/SKILL.md
- id: package
type: file
path: package.json
Expand All @@ -26,7 +29,7 @@ sources:
path: dangerfile.ts
---

Rudder's contributor automation is a set of local and CI gates for a repository that currently has one root plugin package and centralized agent workflows. `.agents/skills/` is the only reusable-workflow source, with `.claude/skills` and `.codex/skills` as compatibility symlinks [@agents-readme]. The `check-changed-folders` skill compares the branch with `origin/main`, verifies the centralized agent-instruction layout, verifies agent attribution, runs the package checks, and then invokes PR-comment remediation when a PR exists [@check-skill]. GitHub Actions repeats package validation on branch pushes, while the Danger workflow enforces protected paths and inline agent guards for agent-authored pull requests [@test-workflow] [@danger-workflow] [@dangerfile].
Rudder's contributor automation is a set of local and CI gates for a repository that currently has one root plugin package and centralized agent workflows. `.agents/skills/` is the only reusable-workflow source, with `.claude/skills` and `.codex/skills` as compatibility symlinks [@agents-readme]. The `check-changed-folders` skill validates branches, verifies layout and attribution, runs local package checks, and delegates PR-comment remediation when a PR exists [@check-skill]. The `prepare-package-release` skill synchronizes package and plugin versions, ingests the complete range since the previous release, Gardens the whole CodeAlmanac wiki, and validates the prepared release [@release-skill]. GitHub Actions repeats package validation on branch pushes, while the Danger workflow enforces protected paths and inline agent guards for agent-authored pull requests [@test-workflow] [@danger-workflow] [@dangerfile].

## Local Check Surface

Expand All @@ -38,14 +41,20 @@ Before package checks, the local flow also checks that each coding agent represe

## Package Checks

After layout and attribution checks, the local flow installs dependencies with `npm install` only when `node_modules/` is missing, then runs `npm run typecheck`, `npm test`, and `npm run build` [@check-skill]. The Test workflow uses the CI equivalent plus layout and Markdown checks: checkout, Node 24 setup, `npm ci`, `npm run check:agent-layout`, `npm run format:markdown:check`, `npm run typecheck`, `npm test`, and `npm run build` on Ubuntu [@test-workflow]. The exact command meanings are listed in [Package Scripts](../../reference/tooling/package-scripts), while [GitHub Workflows](../../reference/automation/github-workflows) records CI triggers and permissions.
After layout and attribution checks, the local flow installs dependencies with `npm install` only when `node_modules/` is missing, then runs `npm run typecheck`, `npm test`, and `npm run build` [@check-skill]. The Test workflow adds the CI coverage boundary: it checks out full history, sets up Node 24, runs `npm ci`, checks agent layout and Markdown, typechecks, runs `npm run test:coverage` with a 90% changed-line threshold, and rebuilds on Ubuntu [@test-workflow] [@package]. The exact command meanings are listed in [Package Scripts](../../reference/tooling/package-scripts), while [GitHub Workflows](../../reference/automation/github-workflows) records CI triggers and permissions.

## PR Comment Remediation

The check flow delegates open PR feedback to a separate `address-pr-comments` skill [@check-skill]. That skill locates the current branch PR with `gh pr view`, fetches top-level issue comments and inline review comments through GitHub API endpoints, de-duplicates by path, line, author, and body hash, and ignores deploy-bot noise [@comments-skill]. Each remaining comment is verified against the current `HEAD`, then either fixed, declined with a reason, or deferred to the user when it needs a judgment call [@comments-skill].

That remediation flow has its own validation boundary. If it applies any fixes, it reruns `npm run typecheck`, `npm test`, and `npm run build`, but it does not invoke the full check flow again because that would re-enter the PR-comment workflow [@comments-skill]. The [Address PR Comments](../../guides/contributor/address-pr-comments) guide gives the operational procedure without duplicating the architecture here.

## Release Preparation

Release preparation has a dedicated workflow because one package version is repeated across the npm package, lockfile, Codex and Claude plugin manifests, and Claude marketplace metadata [@release-skill]. The skill treats `package.json` as authoritative, uses npm's no-tag version command, copies the exact result into every version-bearing manifest, and leaves tag creation to post-merge release automation [@release-skill].

The workflow finds the previous `rudder-plugin-v*` tag and uses the range from that tag through `HEAD` as Ingest's committed source boundary, alongside staged and unstaged changes [@release-skill]. This includes already-merged work that an `origin/main` branch diff would omit. Garden then reconciles the ingested release knowledge across the whole wiki [@release-skill]. Either job may validly produce no wiki changes when the release contains no durable knowledge. The prepared release is complete only after both the package checks and `codealmanac validate` pass [@release-skill]. The [Prepare Package Release](../../guides/release/prepare-package-release) guide provides the operational sequence.

## Agent Guards

`dangerfile.ts` protects `README.md`, `CONTRIBUTING.md`, `CODE_OF_CONDUCT.md`, `LICENSE`, `CLAUDE.md`, `docs/**`, `assets/**`, `.claude/**`, `.codex/**`, and `.cursor/**` from agent-authored pull request changes [@dangerfile]. It detects agent authorship from the PR author, commit author names and emails, and `Co-authored-by` trailers [@dangerfile]. The Danger workflow runs `npm run danger:ci` on pull requests to `main` after installing dependencies on Node 24 [@danger-workflow] [@package].
Expand Down
2 changes: 1 addition & 1 deletion almanac/architecture/release/release-automation.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ The publish workflow runs on pushes to `main` and on manual dispatch, with a sin

Those checks create separate flags for each artifact. A missing npmjs.org version enables npm publishing, a missing tag enables tag creation, and a missing GitHub Release enables release creation [@publish-workflow]. When any artifact is missing, the job upgrades npm, installs dependencies with `npm ci`, writes release telemetry defaults into `src/telemetry-build-config.ts`, validates the plugin package with `DO_NOT_TRACK=1`, publishes to npmjs.org when needed with Trusted Publishing, pushes the plugin tag when needed, and creates the GitHub Release with generated notes when needed [@publish-workflow].

The package scripts are part of that path because the publish workflow validates with `npm run check:agent-layout`, `npm run typecheck`, `npm test`, `npm run build`, and `npm pack --dry-run`, while `npm publish` also uses the package lifecycle in `package.json` [@publish-workflow] [@package-json]. The GitHub Release title is `Rudder v<version>` even though the tag remains `rudder-plugin-v<version>` [@publish-workflow]. The exact scripts are listed in [Package Scripts](../../reference/tooling/package-scripts).
The package scripts are part of that path because the publish workflow validates with `npm run check:agent-layout`, `npm run typecheck`, `npm run test:coverage`, `npm run build`, and `npm pack --dry-run`, while `npm publish` also uses the package lifecycle in `package.json` [@publish-workflow] [@package-json]. `test:coverage` runs the full suite and requires 90% coverage on changed and untracked source lines before any release artifact is created [@package-json] [@publish-workflow]. The GitHub Release title is `Rudder v<version>` even though the tag remains `rudder-plugin-v<version>` [@publish-workflow]. The exact scripts are listed in [Package Scripts](../../reference/tooling/package-scripts).

## Release Alert Job

Expand Down
8 changes: 4 additions & 4 deletions almanac/architecture/runtime/local-state.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: "Local State"
summary: "Rudder keeps runtime state in a user-scoped home directory that owns the SQLite database, telemetry identity, update-check cache, backups, and dashboard port defaults."
summary: "Rudder keeps runtime state in a user-scoped home directory that owns the SQLite database, telemetry identity, update-check cache, backups, and exported port defaults."
topics: [architecture, runtime, local-state, sqlite, prompt-capture]
sources:
- id: db-client
Expand Down Expand Up @@ -34,10 +34,10 @@ The source tree does not carry a repo-local state directory convention. The repo

Migration application is deliberately part of the open flow. `openDb()` derives the migration directory from `RUDDER_MIGRATIONS_PATH` when that variable is set, otherwise it resolves the repository `drizzle/` directory relative to `src/db/client.ts`; it closes the raw SQLite handle if migration application fails [@db-client]. That means code using the [Prompt Branch Store](prompt-branch-store) can call `rudderDb()` without running a separate migration command first; `rudderDb()` opens the database if the Drizzle singleton is still missing [@db-client].

## Dashboard Port
## Port Helper

`rudderPort()` is a small local-state helper for the dashboard daemon. It converts `RUDDER_PORT` with `Number()`, accepts only integer ports greater than zero and less than `65536`, and falls back to `41789` for unset, non-numeric, fractional, zero, negative, or out-of-range values [@db-client]. The exact environment contract is listed in [Environment Variables](../../reference/configuration/environment-variables).
`rudderPort()` is a small exported local-state helper for a future or host-owned port consumer. It converts `RUDDER_PORT` with `Number()`, accepts only integer ports greater than zero and less than `65536`, and falls back to `41789` for unset, non-numeric, fractional, zero, negative, or out-of-range values [@db-client]. The exact environment contract is listed in [Environment Variables](../../reference/configuration/environment-variables).

## Shared Boundary

Local state currently covers the SQLite database path, the telemetry identity file, the update-check cache, skill backup directories, and the dashboard port default. Telemetry builds `identity.json` under `rudderHome()`, reads an existing `{ id }` value when present, and writes a generated UUID there on a best-effort basis when it needs a new anonymous installation identity [@telemetry]. The update helper writes `update-state.json` atomically through a temporary file with mode `0600` after creating the Rudder home with mode `0700` [@update-script]. The important invariant is that runtime code should derive persistent paths from `rudderHome()` instead of inventing new repository-local locations. That keeps [Telemetry](telemetry), [Prompt Branch Store](prompt-branch-store), the update helper, and the environment-variable reference aligned around the same state root [@db-client] [@telemetry] [@update-script].
Local state currently covers the SQLite database path, the telemetry identity file, the update-check cache, skill backup directories, and the exported port default. Telemetry builds `identity.json` under `rudderHome()`, preserves an existing anonymous UUID, and adds a random local-only pseudonymization key when either field is missing [@telemetry]. It creates the state root with mode `0700`, writes the identity file with mode `0600`, reapplies those permissions when an existing complete identity is loaded, and treats all persistence and permission changes as best-effort [@telemetry]. The update helper writes `update-state.json` atomically through a temporary file with mode `0600` after creating the Rudder home with mode `0700` [@update-script]. The important invariant is that runtime code should derive persistent paths from `rudderHome()` instead of inventing new repository-local locations. That keeps [Telemetry](telemetry), [Prompt Branch Store](prompt-branch-store), the update helper, and the environment-variable reference aligned around the same state root [@db-client] [@telemetry] [@update-script].
Loading
Loading