Skip to content

Commit 415448f

Browse files
authored
feat: add approval-gated npm release workflows (#12)
* feat: add approval-gated npm releases [policy] Change-Id: Iae0db1a40fac3bbdaa4d1dfc2e0c41b0d05c4dba * chore: retrigger external security scan Change-Id: I55834659f8cafc4c199e94aa4fadd3e1c4f0de92 * fix: avoid dynamic release regex [policy] Change-Id: Ia846e22c36e72d433eec8e00c4a2321cce9b731e * fix: assign repository code ownership [policy] Change-Id: I4d796f9766189138b4356c16d0b504822e8eac1e
1 parent 8924d8d commit 415448f

17 files changed

Lines changed: 521 additions & 188 deletions

File tree

.changeset/pre.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"mode": "pre",
2+
"mode": "exit",
33
"tag": "beta",
44
"initialVersions": {
55
"@openagentpack/server": "0.0.1",

.github/CODEOWNERS

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
# Core infrastructure requires maintainer review.
2-
/.github/ @modelstudioai/openagentpack-maintainers
3-
/scripts/ @modelstudioai/openagentpack-maintainers
4-
/package.json @modelstudioai/openagentpack-maintainers
5-
/bun.lock @modelstudioai/openagentpack-maintainers
2+
/.github/ @heimanba
3+
/scripts/ @heimanba
4+
/package.json @heimanba
5+
/bun.lock @heimanba
66

77
# Workspace package boundaries.
8-
/packages/sdk/src/internal/providers/interface.ts @modelstudioai/openagentpack-maintainers
9-
/packages/sdk/src/internal/providers/capabilities.ts @modelstudioai/openagentpack-maintainers
10-
/packages/sdk/src/internal/providers/registry.ts @modelstudioai/openagentpack-maintainers
11-
/packages/sdk/src/internal/providers/base-client.ts @modelstudioai/openagentpack-maintainers
12-
/packages/sdk/src/internal/types/ @modelstudioai/openagentpack-maintainers
8+
/packages/sdk/src/internal/providers/interface.ts @heimanba
9+
/packages/sdk/src/internal/providers/capabilities.ts @heimanba
10+
/packages/sdk/src/internal/providers/registry.ts @heimanba
11+
/packages/sdk/src/internal/providers/base-client.ts @heimanba
12+
/packages/sdk/src/internal/types/ @heimanba

.github/workflows/prepare-beta.yml

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
name: Prepare Beta Release
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
version:
7+
description: Stable SemVer series, for example 0.1.0
8+
required: true
9+
type: string
10+
11+
concurrency:
12+
group: prepare-beta-${{ inputs.version }}
13+
cancel-in-progress: false
14+
15+
jobs:
16+
prepare:
17+
if: github.ref_name == 'main'
18+
runs-on: ubuntu-latest
19+
permissions:
20+
contents: write
21+
steps:
22+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
23+
with:
24+
fetch-depth: 0
25+
26+
- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
27+
with:
28+
bun-version: "1.3.5"
29+
30+
- name: Validate requested version
31+
env:
32+
VERSION: ${{ inputs.version }}
33+
run: |
34+
if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
35+
echo "::error::version must be a stable SemVer such as 0.1.0"
36+
exit 1
37+
fi
38+
39+
- name: Prepare isolated beta branch
40+
env:
41+
VERSION: ${{ inputs.version }}
42+
run: |
43+
branch="release/${VERSION}-beta"
44+
git config user.name "github-actions[bot]"
45+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
46+
git fetch origin main
47+
if git ls-remote --exit-code --heads origin "${branch}" >/dev/null 2>&1; then
48+
git fetch origin "${branch}"
49+
git checkout --branch "${branch}" --track "origin/${branch}"
50+
git merge --no-edit origin/main
51+
else
52+
git checkout --branch "${branch}" origin/main
53+
bunx changeset pre enter beta
54+
fi
55+
56+
- name: Install dependencies
57+
run: bun install --frozen-lockfile
58+
59+
- name: Calculate next beta version
60+
run: bun run release:version
61+
62+
- name: Validate calculated beta version
63+
id: release
64+
run: >-
65+
bun run scripts/release/channel.ts validate
66+
--channel beta
67+
--ref "release/${{ inputs.version }}-beta"
68+
--expected "${{ inputs.version }}"
69+
--output "$GITHUB_OUTPUT"
70+
71+
- name: Commit and push beta branch
72+
env:
73+
VERSION: ${{ steps.release.outputs.version }}
74+
run: |
75+
if git diff --quiet && git diff --cached --quiet; then
76+
echo "::error::No unreleased changesets are available for the next beta."
77+
exit 1
78+
fi
79+
git add --all
80+
git commit --message "chore: prepare ${VERSION}"
81+
git push origin HEAD

.github/workflows/release-pr.yml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
name: Release PR
2+
3+
on:
4+
push:
5+
branches: [main]
6+
7+
concurrency:
8+
group: release-pr
9+
cancel-in-progress: false
10+
11+
jobs:
12+
version:
13+
runs-on: ubuntu-latest
14+
permissions:
15+
contents: write
16+
pull-requests: write
17+
steps:
18+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
19+
with:
20+
fetch-depth: 0
21+
22+
- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
23+
with:
24+
bun-version: "1.3.5"
25+
26+
- name: Install dependencies
27+
run: bun install --frozen-lockfile
28+
29+
- name: Create or update stable Release PR
30+
uses: changesets/action@a45c4d594aa4e2c509dc14a9f2b3b67ba3780d0d # v1.9.0
31+
with:
32+
version: bun run release:version
33+
commit: "chore: release packages"
34+
title: "chore: release packages"
35+
env:
36+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/release.yml

Lines changed: 58 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,34 @@
1-
name: Release
1+
name: Publish npm
22

33
on:
44
workflow_dispatch:
5-
push:
6-
branches: [main]
5+
inputs:
6+
channel:
7+
description: npm channel to publish
8+
required: true
9+
type: choice
10+
options:
11+
- beta
12+
- stable
13+
confirm:
14+
description: Type PUBLISH to confirm
15+
required: true
16+
type: string
717

818
concurrency:
9-
group: ${{ github.workflow }}-${{ github.ref }}
1019
# Publishing three packages is not atomic. Never cancel a run after the first
11-
# package may already have reached npm; the publish script is also idempotent
12-
# so a failed run can safely be retried.
20+
# package may already have reached npm; exact versions are safe to retry.
21+
group: npm-publish
1322
cancel-in-progress: false
1423

1524
jobs:
16-
release:
17-
# Missing repository variables resolve to an empty string, so a newly
18-
# created repository cannot publish until maintainers explicitly opt in.
19-
if: vars.NPM_RELEASE_ENABLED == 'true'
25+
publish:
26+
if: vars.NPM_RELEASE_ENABLED == 'true' && inputs.confirm == 'PUBLISH'
2027
runs-on: ubuntu-latest
28+
environment: npm-release
2129
permissions:
2230
contents: write
2331
id-token: write
24-
pull-requests: write
2532
steps:
2633
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
2734
with:
@@ -43,22 +50,48 @@ jobs:
4350
- name: Install dependencies
4451
run: bun install --frozen-lockfile
4552

53+
- name: Validate channel, branch, and package versions
54+
id: release
55+
run: >-
56+
bun run scripts/release/channel.ts validate
57+
--channel "${{ inputs.channel }}"
58+
--ref "${{ github.ref_name }}"
59+
--output "$GITHUB_OUTPUT"
60+
4661
- name: Verify release
47-
env:
48-
BASE: ${{ github.event.before }}
4962
run: bun run verify:release
5063

51-
- name: Create Release PR or Publish
52-
uses: changesets/action@a45c4d594aa4e2c509dc14a9f2b3b67ba3780d0d # v1.9.0
53-
with:
54-
version: bun run release:version
55-
publish: bun run release:publish
56-
commit: "chore: release packages"
57-
title: "chore: release packages"
64+
- name: Publish packages with npm Trusted Publishing
5865
env:
59-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
60-
# Bootstrap only: set this secret for the first publication, then remove
61-
# and revoke it after npm Trusted Publishers are configured. With the
62-
# secret absent, npm authenticates through OIDC trusted publishing.
63-
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
6466
NPM_CONFIG_PROVENANCE: "true"
67+
run: bun run release:publish
68+
69+
- name: Create immutable Git tag
70+
env:
71+
VERSION: ${{ steps.release.outputs.version }}
72+
run: |
73+
tag="v${VERSION}"
74+
if git rev-parse --verify --quiet "refs/tags/${tag}"; then
75+
test "$(git rev-list -n 1 "${tag}")" = "$GITHUB_SHA" || {
76+
echo "::error::${tag} already points to another commit"
77+
exit 1
78+
}
79+
else
80+
git tag --annotate "${tag}" --message "${tag}"
81+
git push origin "${tag}"
82+
fi
83+
84+
- name: Create GitHub Release
85+
env:
86+
GH_TOKEN: ${{ github.token }}
87+
VERSION: ${{ steps.release.outputs.version }}
88+
CHANNEL: ${{ steps.release.outputs.channel }}
89+
run: |
90+
tag="v${VERSION}"
91+
if gh release view "${tag}" >/dev/null 2>&1; then
92+
echo "GitHub Release ${tag} already exists; nothing to do."
93+
elif test "${CHANNEL}" = beta; then
94+
gh release create "${tag}" --verify-tag --generate-notes --prerelease --title "${tag}"
95+
else
96+
gh release create "${tag}" --verify-tag --generate-notes --title "${tag}"
97+
fi

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Thanks for your interest in improving OpenAgentPack. By participating you agree
88
|-------|-----|
99
| Dev setup, verification, package boundaries | [docs/contributing/development.md](./docs/contributing/development.md) |
1010
| Adding a new provider | [docs/contributing/provider-development.md](./docs/contributing/provider-development.md) |
11-
| npm release workflow | [docs/contributing/release.md](./docs/contributing/release.md) |
11+
| npm release workflow | [English](./docs/contributing/release.md) · [简体中文](./docs/contributing/release.zh-CN.md) |
1212
| Architecture and how it works | [docs/architecture/how-it-works.md](./docs/architecture/how-it-works.md) |
1313

1414
## Quick start

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ npm install -g @openagentpack/cli
136136
```
137137

138138
This provides the `agents` command. To run from source instead, see [Contributing](./CONTRIBUTING.md).
139+
Beta testers can install `@openagentpack/cli@beta`; see the [release guide](./docs/contributing/release.md#what-users-install) for version pinning and switching back to stable.
139140

140141
## Provider support
141142

README.zh-CN.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ npm install -g @openagentpack/cli
136136
```
137137

138138
安装后即可使用 `agents` 命令。若想从源码运行,见 [贡献指南](./CONTRIBUTING.md)。
139+
Beta 用户可以安装 `@openagentpack/cli@beta`;固定版本及切回稳定版的方法见 [发布指南](./docs/contributing/release.zh-CN.md#用户如何安装)。
139140

140141
## Provider 支持
141142

0 commit comments

Comments
 (0)