Skip to content

Commit 56f48bb

Browse files
committed
Add changeset release workflow and fix docs links
1 parent 1912cae commit 56f48bb

15 files changed

Lines changed: 1405 additions & 21 deletions

File tree

.changeset/config.json

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"$schema": "https://unpkg.com/@changesets/config/schema.json",
3+
"access": "restricted",
4+
"baseBranch": "main",
5+
"changelog": [
6+
"@changesets/changelog-github",
7+
{
8+
"repo": "optiflow/agent-memory-os"
9+
}
10+
],
11+
"commit": false,
12+
"fixed": [],
13+
"ignore": [
14+
"@agent-memory-os/cli",
15+
"@agent-memory-os/core",
16+
"@agent-memory-os/docs",
17+
"@agent-memory-os/docs-guard",
18+
"@agent-memory-os/evals",
19+
"@agent-memory-os/sqlite"
20+
],
21+
"linked": [],
22+
"privatePackages": {
23+
"tag": false,
24+
"version": true
25+
},
26+
"updateInternalDependencies": "patch"
27+
}

.changeset/release-pipeline.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"agent-memory-os": minor
3+
---
4+
5+
Add an automated Changesets and GitHub Actions pipeline for repository releases.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: Release Metadata
2+
3+
on:
4+
pull_request:
5+
6+
permissions:
7+
contents: read
8+
pull-requests: read
9+
10+
jobs:
11+
release-metadata:
12+
name: Release metadata warning
13+
runs-on: ubuntu-latest
14+
15+
steps:
16+
- name: Checkout
17+
uses: actions/checkout@v4
18+
with:
19+
fetch-depth: 0
20+
21+
- name: Set up pnpm
22+
uses: pnpm/action-setup@v4
23+
with:
24+
version: 11.5.1
25+
run_install: false
26+
27+
- name: Set up Node
28+
uses: actions/setup-node@v4
29+
with:
30+
node-version: "24"
31+
cache: pnpm
32+
33+
- name: Install dependencies
34+
run: pnpm install --frozen-lockfile
35+
36+
- name: Check release metadata
37+
run: pnpm release:check

.github/workflows/release.yml

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
name: Release
2+
3+
on:
4+
workflow_run:
5+
workflows:
6+
- CI
7+
types:
8+
- completed
9+
branches:
10+
- main
11+
12+
permissions:
13+
contents: write
14+
issues: read
15+
pull-requests: write
16+
17+
concurrency:
18+
group: release-main
19+
cancel-in-progress: false
20+
21+
jobs:
22+
release:
23+
name: Changesets release
24+
if: >-
25+
${{
26+
github.event.workflow_run.conclusion == 'success' &&
27+
github.event.workflow_run.event == 'push'
28+
}}
29+
runs-on: ubuntu-latest
30+
31+
steps:
32+
- name: Checkout
33+
uses: actions/checkout@v4
34+
with:
35+
fetch-depth: 0
36+
ref: ${{ github.event.workflow_run.head_sha }}
37+
38+
- name: Set up pnpm
39+
uses: pnpm/action-setup@v4
40+
with:
41+
version: 11.5.1
42+
run_install: false
43+
44+
- name: Set up Node
45+
uses: actions/setup-node@v4
46+
with:
47+
node-version: "24"
48+
cache: pnpm
49+
50+
- name: Install dependencies
51+
run: pnpm install --frozen-lockfile
52+
53+
- name: Create version PR or GitHub Release
54+
uses: changesets/action@v1
55+
with:
56+
commit: Version Agent Memory OS
57+
createGithubReleases: false
58+
publish: pnpm release:github
59+
title: Version Agent Memory OS
60+
version: pnpm changeset:version
61+
env:
62+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

AGENTS.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@
102102
## Commands
103103

104104
- Install: `pnpm install`
105+
- Create a changeset: `pnpm changeset`
106+
- Apply pending changesets to versions and changelogs:
107+
`pnpm changeset:version`
105108
- Lint: `pnpm lint`
106109
- Package lint: `pnpm lint:packages`
107110
- Repo-wide lint: `pnpm lint:repo`
@@ -119,6 +122,29 @@
119122
- Full local gate: `pnpm run ci`
120123
- Hermes adapter compile and unit tests: `pnpm adapter:check`
121124
- Install git hooks: `pnpm hooks:install`
125+
- Release metadata warning check: `pnpm release:check`
126+
- Create GitHub release from `CHANGELOG.md`: `pnpm release:github`
127+
128+
## Release Workflow
129+
130+
- Releases are repository-level GitHub Releases only. Do not add npm publishing
131+
or `NPM_TOKEN` requirements unless explicitly requested.
132+
- Significant changes or improvements require a changeset targeting
133+
`agent-memory-os`. Use `pnpm changeset`, then choose the smallest valid semver
134+
bump: patch for fixes and docs/tooling polish, minor for new capabilities, and
135+
major only for breaking public behavior.
136+
- Non-release PRs should include `[no release]` in the PR title or body. Use it
137+
for chore-only changes, CI experiments, or edits that should not become release
138+
notes.
139+
- The release metadata workflow is warning-only. Treat warnings as review input,
140+
not a failing gate.
141+
- The release workflow runs after the `CI` workflow succeeds on `main`.
142+
`changesets/action` opens or updates the `Version Agent Memory OS` PR while
143+
changesets are pending. After that version PR merges, the workflow runs
144+
`pnpm release:github` and creates `Agent Memory OS vX.Y.Z` from the matching
145+
root `CHANGELOG.md` section.
146+
- Do not manually edit generated version PR contents unless fixing the release
147+
metadata itself. Prefer adding or amending changesets in feature PRs.
122148

123149
## Verification
124150

apps/docs/src/content/docs/index.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@ architecture, contracts, verification, and roadmap boundaries live in detail.
1111

1212
| If you need to... | Read |
1313
| --- | --- |
14-
| Run the repo from a fresh checkout | [Getting Started](./start/getting-started.md) |
15-
| Confirm local runtime expectations | [Environment](./start/environment.md) |
16-
| Understand the system shape | [Architecture](./architecture/architecture.md) |
17-
| Inspect stored objects and projections | [Data Model](./architecture/data-model.md) |
18-
| Call the JSON CLI bridge | [CLI Reference](./reference/cli-reference.md) |
19-
| Verify quality gates and evals | [Evaluation](./reference/evaluation.md) |
20-
| Install or inspect the Hermes boundary | [Hermes Install Notes](./integrations/hermes-install.md) |
21-
| Check phase boundaries | [Roadmap](./roadmap/v1-v2-roadmap.md) |
14+
| Run the repo from a fresh checkout | [Getting Started](./start/getting-started/) |
15+
| Confirm local runtime expectations | [Environment](./start/environment/) |
16+
| Understand the system shape | [Architecture](./architecture/architecture/) |
17+
| Inspect stored objects and projections | [Data Model](./architecture/data-model/) |
18+
| Call the JSON CLI bridge | [CLI Reference](./reference/cli-reference/) |
19+
| Verify quality gates and evals | [Evaluation](./reference/evaluation/) |
20+
| Install or inspect the Hermes boundary | [Hermes Install Notes](./integrations/hermes-install/) |
21+
| Check phase boundaries | [Roadmap](./roadmap/v1-v2-roadmap/) |
2222

2323
## Current Shape
2424

apps/docs/src/content/docs/reference/evaluation.md

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ pnpm build
4646
pnpm adapter:check
4747
pnpm docs:check
4848
pnpm docs:build
49+
pnpm release:check
4950
```
5051

5152
## Documentation Freshness
@@ -59,7 +60,7 @@ pnpm docs:check
5960
The guard fails when code, adapter, tooling, workflow, or policy changes land
6061
without the matching documentation surface in the same diff. It checks changed
6162
paths, validates `.devin/wiki.json`, and rejects stale canonical references to
62-
deleted root `docs/*.md` files.
63+
deleted root `docs/*.md` files or Starlight links to source-file URLs.
6364

6465
Expected behavior:
6566

@@ -71,13 +72,40 @@ Expected behavior:
7172
adapter or install docs;
7273
- tooling and docs-guard policy changes require `AGENTS.md`, environment docs,
7374
or this evaluation page;
75+
- Starlight content links must use published route paths, not `.md` source-file
76+
URLs or related typo variants;
7477
- `.devin/wiki.json` must stay valid, use unique page titles, and reference
7578
existing priority files.
7679

7780
The guard does not update DeepWiki. DeepWiki is a generated external index: keep
7881
`.devin/wiki.json` current, then audit the refreshed wiki after merge before
7982
claiming the public DeepWiki page is current.
8083

84+
## Release Automation
85+
86+
Releases are Changesets-gated repository releases. Feature, fix, docs, adapter,
87+
or tooling improvements that should appear in release notes need a changeset for
88+
the root `agent-memory-os` package:
89+
90+
```bash
91+
pnpm changeset
92+
```
93+
94+
Use patch for fixes and docs/tooling polish, minor for new capabilities, and
95+
major only for breaking public behavior. PRs that intentionally should not
96+
produce a release can use `[no release]` in the PR title or body.
97+
98+
The `Release Metadata` workflow runs `pnpm release:check` on pull requests. It
99+
emits warnings for release-relevant changes without a changeset, but it does not
100+
fail CI.
101+
102+
After the `CI` workflow succeeds on `main`, the `Release` workflow runs
103+
`changesets/action`. Pending changesets create or update the `Version Agent
104+
Memory OS` PR. When that version PR merges, `pnpm release:github` reads the root
105+
`CHANGELOG.md`, uses the current root `package.json` version, and creates a
106+
single GitHub Release titled `Agent Memory OS vX.Y.Z`. The repo does not publish
107+
packages to npm.
108+
81109
## CLI Smoke Test
82110

83111
```bash

apps/docs/src/content/docs/start/getting-started.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ The full gate runs documentation freshness checks, linting, typechecking,
3232
tests, builds, adapter-boundary checks, deterministic evals, and report-only
3333
benchmarks.
3434

35-
For narrower checks, see [Evaluation](../reference/evaluation.md).
35+
For narrower checks, see [Evaluation](../../reference/evaluation/).
3636

3737
## CLI Smoke Test
3838

@@ -71,7 +71,7 @@ skills Bundled Hermes setup runbook
7171

7272
## Next Reads
7373

74-
- [CLI Reference](../reference/cli-reference.md) for command contracts.
75-
- [Architecture](../architecture/architecture.md) for memory planes and routing.
76-
- [Hermes Install Notes](../integrations/hermes-install.md) for adapter setup.
77-
- [Evaluation](../reference/evaluation.md) for local acceptance gates.
74+
- [CLI Reference](../../reference/cli-reference/) for command contracts.
75+
- [Architecture](../../architecture/architecture/) for memory planes and routing.
76+
- [Hermes Install Notes](../../integrations/hermes-install/) for adapter setup.
77+
- [Evaluation](../../reference/evaluation/) for local acceptance gates.

package.json

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@
88
"adapter:check": "python3 -m py_compile __init__.py adapters/hermes/plugins/memory/meta_memory/__init__.py adapters/hermes/plugins/memory/meta_memory/test/test_provider.py && python3 -m unittest discover adapters/hermes/plugins/memory/meta_memory/test",
99
"bench": "turbo run bench --filter @agent-memory-os/evals",
1010
"bench:ci": "turbo run bench:ci --filter @agent-memory-os/evals",
11-
"build": "turbo run build",
11+
"build": "turbo run build --filter='!agent-memory-os'",
12+
"changeset": "changeset",
13+
"changeset:version": "changeset version",
1214
"ci": "pnpm docs:check && pnpm lint && pnpm typecheck && pnpm test && pnpm build && pnpm adapter:check && pnpm eval && pnpm bench:ci",
13-
"clean": "turbo run clean",
15+
"clean": "turbo run clean --filter='!agent-memory-os'",
1416
"docs:check": "pnpm --filter @agent-memory-os/docs-guard build && node packages/docs-guard/dist/index.js",
1517
"docs:build": "pnpm --filter @agent-memory-os/docs build",
1618
"docs:dev": "pnpm --filter @agent-memory-os/docs dev",
@@ -19,14 +21,18 @@
1921
"format": "biome format --write .",
2022
"hooks:install": "lefthook install",
2123
"lint": "pnpm lint:packages && pnpm lint:repo",
22-
"lint:packages": "turbo run lint",
24+
"lint:packages": "turbo run lint --filter='!agent-memory-os'",
2325
"lint:repo": "biome check .",
2426
"prepare": "lefthook install",
25-
"test": "turbo run test",
26-
"typecheck": "turbo run typecheck"
27+
"release:check": "node scripts/check-release-metadata.mjs",
28+
"release:github": "node scripts/create-github-release.mjs",
29+
"test": "turbo run test --filter='!agent-memory-os'",
30+
"typecheck": "turbo run typecheck --filter='!agent-memory-os'"
2731
},
2832
"devDependencies": {
2933
"@biomejs/biome": "2.4.16",
34+
"@changesets/changelog-github": "^0.7.0",
35+
"@changesets/cli": "^2.31.0",
3036
"@types/node": "24.12.4",
3137
"lefthook": "2.1.9",
3238
"turbo": "2.9.16",

packages/docs-guard/src/docsGuard.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export function runDocsGuard(options: DocsGuardOptions): DocsGuardResult {
3838
...validateChangedFileRules(changedFiles),
3939
...validateWikiJson(options.repoRoot),
4040
...validateRootDocsReferences(options.repoRoot),
41+
...validateStarlightSourceLinks(options.repoRoot),
4142
];
4243

4344
return {
@@ -304,6 +305,35 @@ function validateRootDocsReferences(repoRoot: string): string[] {
304305
return errors;
305306
}
306307

308+
function validateStarlightSourceLinks(repoRoot: string): string[] {
309+
const docsPath = join(repoRoot, STARLIGHT_DOCS_PREFIX);
310+
if (!existsSync(docsPath)) {
311+
return [];
312+
}
313+
314+
const errors: string[] = [];
315+
const markdownLinkPattern = /(?<!!)\[[^\]\n]+\]\(([^)\s]+)(?:\s+["'][^"']*["'])?\)/g;
316+
317+
for (const filePath of walkFiles(docsPath, repoRoot).filter((file) => file.endsWith(".md"))) {
318+
const content = readFileSync(join(repoRoot, filePath), "utf8");
319+
for (const match of content.matchAll(markdownLinkPattern)) {
320+
const rawTarget = match[1]?.trim().replace(/^<|>$/g, "");
321+
if (!rawTarget || isExternalLink(rawTarget) || rawTarget.startsWith("#")) {
322+
continue;
323+
}
324+
325+
const targetPath = rawTarget.split("#")[0]?.split("?")[0] ?? "";
326+
if (/\.(md|mdb)$/i.test(targetPath)) {
327+
errors.push(
328+
`Starlight source link "${rawTarget}" in ${filePath} points at a source file. Use the published route path instead.`,
329+
);
330+
}
331+
}
332+
}
333+
334+
return errors;
335+
}
336+
307337
function docsReferenceScanFiles(repoRoot: string): string[] {
308338
const files: string[] = [];
309339

@@ -388,6 +418,10 @@ function isToolingOrPolicyChange(file: string): boolean {
388418
);
389419
}
390420

421+
function isExternalLink(linkTarget: string): boolean {
422+
return /^[a-z][a-z0-9+.-]*:/i.test(linkTarget) || linkTarget.startsWith("//");
423+
}
424+
391425
function isObject(value: unknown): value is Record<string, unknown> {
392426
return typeof value === "object" && value !== null && !Array.isArray(value);
393427
}

0 commit comments

Comments
 (0)