diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4fd1b65..5ea17cf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,6 +11,11 @@ on: jobs: test: runs-on: ubuntu-latest + strategy: + matrix: + node-version: + - "20" + - "22" steps: - name: Checkout @@ -19,7 +24,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v4 with: - node-version: "20" + node-version: ${{ matrix.node-version }} - name: Install dependencies run: npm ci diff --git a/CHANGELOG.md b/CHANGELOG.md index 384bf01..38de5e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 0.1.0-alpha.6 - 2026-07-27 + - Add repository-local declarative Integration Profile v1 for structured planning sources beyond the built-in OpenSpec adapter. - Add safe file and bundle Source Units, Native Mapping, strict Sidecar Domain @@ -10,6 +12,10 @@ `opendomain prepare --profile `. - Add Profile-aware initialization, ERP examples, package installation smoke coverage, and complete usage documentation. +- Upgrade `minimatch` to the patched v10 line and align supported Node.js + releases to Node.js 20 or 22 and newer, with CI coverage for both LTS lines. +- Add a project-specific release runbook covering validation, npm dist-tags, + registry smoke tests, GitHub releases, and rollback. ## 0.1.0-alpha.5 - 2026-07-23 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5859ec1..b7666ff 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,7 +7,7 @@ Git-native, evidence-backed, and easy for AI agents to consume. Requirements: -- Node.js 20 or newer +- Node.js 20 or Node.js 22 and newer Useful commands: @@ -45,6 +45,8 @@ Keep the layers separate: - Do not treat `opendomain/generated/` or legacy `.opendomain/index.json` as authoritative domain knowledge. +Maintainer releases must follow `docs/releasing.md`. + ## Planning Artifacts OpenSpec is supported as an integration source, but this public repository does diff --git a/docs/releasing.md b/docs/releasing.md new file mode 100644 index 0000000..5731258 --- /dev/null +++ b/docs/releasing.md @@ -0,0 +1,108 @@ +# OpenDomain Release Runbook + +本文档是 OpenDomain 的项目专属发布清单。它适用于当前 npm alpha +发布流程,不替代未来的 Trusted Publishing 或稳定版发布策略。 + +## 发布边界 + +- 只从公开仓库已合并并通过 CI 的 `main` 发布。 +- npm alpha 版本使用 `alpha` dist-tag;不得隐式移动 `latest`。 +- npm 包不得包含私有 OpenSpec、Codex 配置、token、生成索引或本地缓存。 +- 本地 token 只能通过仓库外文件注入环境变量,不得写入 Git。 +- 当前使用本地 token 发布,因此显式关闭 provenance。启用 npm Trusted + Publishing 后再调整这一约束。 + +## 1. 发布前状态 + +1. 确认功能 PR 已合并,`main` 与 `origin/main` 对齐且工作树干净。 +2. 从 `main` 创建独立的 `codex/release-` 分支。 +3. 将 `package.json` 和 `package-lock.json` 更新为同一版本。 +4. 将 `CHANGELOG.md` 的 Unreleased 内容固化到带日期的版本章节。 +5. 确认 README、使用说明、Schema、示例和 CLI 帮助反映本次能力。 + +## 2. 本地验证 + +使用支持的最低 Node.js 主版本执行: + +```bash +volta run --node 20 npm test +volta run --node 20 npm run opendomain -- validate +volta run --node 20 npm run smoke:package +npm audit --json +npm pack --dry-run --json --ignore-scripts \ + --cache /tmp/opendomain-npm-cache +``` + +检查打包清单,确认: + +- 版本正确; +- 公开 Schema、运行时代码、示例和必要文档存在; +- `.npmrc`、OpenSpec、`.codex`、token 和生成内容不存在。 + +## 3. 发布提交 + +1. 检查 staged diff,只包含版本、Changelog 和发布治理内容。 +2. 提交并推送发布分支。 +3. 创建发布 PR,等待 CI 全部通过。 +4. 合并后重新同步本地 `main`,再次确认工作树干净。 + +## 4. npm 发布 + +项目级 `.npmrc` 必须保持 Git ignored,并通过 `${NPM_TOKEN}` 读取凭据。 +从仓库外的私有文件加载 token,不在命令输出或日志中打印: + +```bash +export NPM_TOKEN="$(cat /path/outside/repository/npm-token)" +npm whoami --userconfig .npmrc +npm publish --tag alpha --provenance=false --userconfig .npmrc +unset NPM_TOKEN +``` + +发布后确认: + +```bash +npm view @echopath-labs/opendomain@ version +npm view @echopath-labs/opendomain dist-tags --json +``` + +`alpha` 必须指向新版本;`latest` 必须保持发布前的值,除非另有经过审查的 +稳定版发布决策。 + +## 5. Registry Consumer Smoke + +在新的临时目录中从 npm registry 安装精确版本,并至少验证: + +```bash +npx --yes @echopath-labs/opendomain@ --help +``` + +对于改变初始化、校验、grounding 或 Profile Runtime 的版本,还必须执行对应 +的安装后端到端 smoke,不能只依赖仓库源码测试。 + +## 6. Git Tag 和 GitHub Release + +Registry 验证通过后: + +1. 在发布来源 `main` 提交上创建 annotated tag `v`。 +2. 推送该 tag,不得移动或复用已有 tag。 +3. 创建 GitHub prerelease,并使用 Changelog 版本章节作为发布说明基础。 +4. 核对 GitHub Release、Git tag、npm 版本和来源提交一致。 + +## 7. 失败与回滚 + +- npm 发布前失败:不要创建或推送发布 tag;修复后重新验证。 +- npm 发布后发现问题:不得覆盖已发布版本或强制移动 tag。 +- 将 `alpha` dist-tag 恢复到上一个已验证版本。 +- 对错误版本执行 `npm deprecate`,说明问题和替代版本。 +- 在 GitHub Release 中记录状态,并通过新的 prerelease 版本前向修复。 +- `latest` 不参与 alpha 回滚,除非它曾被明确移动。 + +## 8. 收尾记录 + +发布完成后记录: + +- 版本、日期、来源提交、PR、tag、GitHub Release 和 npm URL; +- 测试、校验、打包和 registry smoke 证据; +- dist-tag 状态; +- 已知风险、未覆盖平台和明确延期范围; +- 公开仓库与私有 OpenSpec 的最终分支和工作树状态。 diff --git a/package-lock.json b/package-lock.json index 5d611a6..0bac28a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,24 +1,24 @@ { "name": "@echopath-labs/opendomain", - "version": "0.1.0-alpha.5", + "version": "0.1.0-alpha.6", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@echopath-labs/opendomain", - "version": "0.1.0-alpha.5", + "version": "0.1.0-alpha.6", "license": "MIT", "dependencies": { "ajv": "^8.20.0", "ajv-formats": "^3.0.1", - "minimatch": "^9.0.9", + "minimatch": "^10.2.5", "yaml": "^2.9.0" }, "bin": { "opendomain": "bin/opendomain.mjs" }, "engines": { - "node": ">=20" + "node": "20 || >=22" } }, "node_modules/ajv": { @@ -55,18 +55,24 @@ } }, "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "license": "MIT" + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } }, "node_modules/brace-expansion": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.2.tgz", - "integrity": "sha512-w5JZcKgdhDOgOwm8H+KgbosopHMuGcl6qbulwjtz3SM7I7P3yW1eAjzMPLrIE+NQ9vjgANKHWeMHnrT0OXW1oA==", + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.8.tgz", + "integrity": "sha512-JZyDyq3D4AUifKTPOB7DELf6XsB3WdPuNxCtob1vFXPsSXhdAiHBWJ/tJ8HAc9aH84BK+5JFZLNkJKx3G9kzQg==", "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "20 || >=22" } }, "node_modules/fast-deep-equal": { @@ -98,15 +104,15 @@ "license": "MIT" }, "node_modules/minimatch": { - "version": "9.0.9", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", - "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", - "license": "ISC", + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^2.0.2" + "brace-expansion": "^5.0.5" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" diff --git a/package.json b/package.json index 4fe0da7..d20b5a7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@echopath-labs/opendomain", - "version": "0.1.0-alpha.5", + "version": "0.1.0-alpha.6", "description": "Git-native, evidence-backed domain semantics for AI agents.", "license": "MIT", "author": { @@ -67,12 +67,12 @@ "prepublishOnly": "npm test && npm run opendomain -- validate" }, "engines": { - "node": ">=20" + "node": "20 || >=22" }, "dependencies": { "ajv": "^8.20.0", "ajv-formats": "^3.0.1", - "minimatch": "^9.0.9", + "minimatch": "^10.2.5", "yaml": "^2.9.0" } }