Skip to content

Commit ee208ea

Browse files
committed
feat: add ReleaseBox scaffolding
1 parent ed6ab4f commit ee208ea

8 files changed

Lines changed: 138 additions & 3 deletions

File tree

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,9 @@ StackForge is local-first and review-friendly:
7171
- `next-app`: Next.js application
7272
- `python-api`: Python API service
7373

74-
Generated repositories include `scripts/validate.sh` as the default local verification path. It runs the repo's normal local package checks when they exist and only runs `agent-qc ready` when `agent-qc` is installed, so `agent-qc` stays optional.
74+
Generated repositories include `scripts/validate.sh` as the default local verification path. It runs the repo's normal local package checks when they exist, including `release:check`, and only runs `agent-qc ready` when `agent-qc` is installed, so `agent-qc` stays optional.
75+
76+
`oss-cli` projects also include ReleaseBox by default: `releasebox.config.json`, reviewed/tag-gated GitHub release workflows, and package smoke scripts. The generated release path creates GitHub Releases with attached tarballs while leaving npm and Homebrew publishing disabled until explicitly enabled.
7577

7678
## Local planning docs
7779

scripts/smoke-init.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,18 @@ test -f smoke-app/docs/PRD.md
105105
test -f smoke-app/docs/TASKS.md
106106
test -f smoke-app/.github/dependabot.yml
107107
test -f smoke-app/.github/workflows/ci.yml
108+
test -f smoke-app/.github/workflows/release-dry-run.yml
109+
test -f smoke-app/.github/workflows/release.yml
110+
test -f smoke-app/releasebox.config.json
108111
test -f smoke-app/scripts/validate.sh
109112
grep -q "# smoke-app" smoke-app/README.md
110113
grep -q "bash scripts/validate.sh" smoke-app/README.md
111114
grep -q "agent-qc" smoke-app/README.md
112115
grep -q "Smoke Tester" smoke-app/package.json
116+
grep -q "release:check" smoke-app/package.json
117+
grep -q '"publishNpm": false' smoke-app/releasebox.config.json
118+
grep -q "ReleaseBox readiness check" smoke-app/.github/workflows/release-dry-run.yml
119+
grep -q "ReleaseBox readiness check" smoke-app/.github/workflows/release.yml
113120
grep -q "This is a copied PRD" smoke-app/docs/PRD.md
114121
grep -q -- "- \[ \] Ship it" smoke-app/docs/TASKS.md
115122
(
@@ -118,6 +125,7 @@ grep -q -- "- \[ \] Ship it" smoke-app/docs/TASKS.md
118125
)
119126
grep -q "agent-qc not installed; skipping optional agent check" validate-without-agent-qc.log
120127
grep -q "PASS: package script: test" validate-without-agent-qc.log
128+
grep -q "PASS: package script: release:check" validate-without-agent-qc.log
121129
cat <<'EOF' > "$tmp_dir/agent-qc"
122130
#!/usr/bin/env bash
123131
set -euo pipefail

src/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,12 @@ const templateScaffolds: Record<TemplateKey, TemplateScaffold> = {
9595
{ source: 'templates/security/SECURITY.template.md', destination: 'SECURITY.md' },
9696
{ source: 'templates/release/CHANGELOG.template.md', destination: 'CHANGELOG.md' },
9797
{ source: 'templates/release/ROADMAP.template.md', destination: 'ROADMAP.md' },
98+
{ source: 'templates/release/releasebox.config.json.template', destination: 'releasebox.config.json' },
9899
{ source: 'templates/github/pull_request_template.md', destination: '.github/pull_request_template.md' },
99100
{ source: 'templates/github/dependabot.yml', destination: '.github/dependabot.yml' },
100101
{ source: 'templates/github/workflows/ci.yml', destination: '.github/workflows/ci.yml' },
102+
{ source: 'templates/github/workflows/release-dry-run.yml', destination: '.github/workflows/release-dry-run.yml' },
103+
{ source: 'templates/github/workflows/release.yml', destination: '.github/workflows/release.yml' },
101104
{ source: 'templates/agents/AGENTS.template.md', destination: 'AGENTS.md' },
102105
{ source: 'templates/repo-docs/README.md', destination: 'docs/README.md' },
103106
{ source: 'templates/repo-validate/validate.sh', destination: 'scripts/validate.sh' }
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
name: Release dry run
2+
3+
on:
4+
workflow_dispatch:
5+
pull_request:
6+
paths:
7+
- releasebox.config.json
8+
- package.json
9+
- package-lock.json
10+
- .github/workflows/release*.yml
11+
12+
permissions:
13+
contents: read
14+
15+
env:
16+
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
17+
RELEASEBOX_REF: v0.1.0
18+
19+
jobs:
20+
dry-run:
21+
runs-on: ubuntu-latest
22+
steps:
23+
- uses: actions/checkout@v5
24+
with:
25+
fetch-depth: 0
26+
- uses: actions/setup-node@v5
27+
with:
28+
node-version: 22
29+
cache: npm
30+
- name: Install dependencies
31+
run: npm ci
32+
- name: Install ReleaseBox
33+
run: |
34+
set -euo pipefail
35+
git clone --depth 1 --branch "$RELEASEBOX_REF" https://github.com/rogerchappel/releasebox.git /tmp/releasebox
36+
npm --prefix /tmp/releasebox ci
37+
npm --prefix /tmp/releasebox run build
38+
- name: ReleaseBox readiness check
39+
run: node /tmp/releasebox/bin/releasebox.js check .
40+
- name: Run release checks
41+
run: npm run release:check
42+
- name: Release notes preview
43+
run: |
44+
node /tmp/releasebox/bin/releasebox.js notes . > release-notes-preview.md
45+
cat release-notes-preview.md
46+
- name: Publish release notes summary
47+
run: cat release-notes-preview.md >> "$GITHUB_STEP_SUMMARY"
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*.*.*'
7+
8+
permissions:
9+
contents: write
10+
id-token: write
11+
12+
env:
13+
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
14+
RELEASEBOX_REF: v0.1.0
15+
16+
jobs:
17+
release:
18+
runs-on: ubuntu-latest
19+
steps:
20+
- uses: actions/checkout@v5
21+
with:
22+
fetch-depth: 0
23+
- uses: actions/setup-node@v5
24+
with:
25+
node-version: 22
26+
cache: npm
27+
registry-url: https://registry.npmjs.org
28+
- name: Install dependencies
29+
run: npm ci
30+
- name: Install ReleaseBox
31+
run: |
32+
set -euo pipefail
33+
git clone --depth 1 --branch "$RELEASEBOX_REF" https://github.com/rogerchappel/releasebox.git /tmp/releasebox
34+
npm --prefix /tmp/releasebox ci
35+
npm --prefix /tmp/releasebox run build
36+
- name: ReleaseBox readiness check
37+
run: node /tmp/releasebox/bin/releasebox.js check .
38+
- name: Run release checks
39+
run: npm run release:check
40+
- name: Build package
41+
run: npm pack
42+
- name: Generate release notes
43+
run: node /tmp/releasebox/bin/releasebox.js notes . > RELEASE_NOTES.md
44+
- name: Create GitHub release
45+
env:
46+
GH_TOKEN: ${{ github.token }}
47+
run: gh release create "${GITHUB_REF_NAME}" --notes-file RELEASE_NOTES.md *.tgz

templates/npm-package/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
"README.md"
1313
],
1414
"scripts": {
15-
"test": "node --test"
15+
"test": "node --test",
16+
"package:smoke": "npm pack --dry-run",
17+
"release:check": "npm test && npm run package:smoke"
1618
},
1719
"keywords": [],
1820
"author": "{{AUTHOR_NAME}}",
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"projectType": "node-cli",
3+
"packageManagers": [
4+
"npm",
5+
"github-release"
6+
],
7+
"smoke": {
8+
"commands": [
9+
[
10+
"npm",
11+
"test"
12+
],
13+
[
14+
"npm",
15+
"pack",
16+
"--dry-run"
17+
]
18+
]
19+
},
20+
"release": {
21+
"mode": "reviewed",
22+
"createGithubRelease": true,
23+
"publishNpm": false,
24+
"updateHomebrew": false
25+
}
26+
}

templates/repo-validate/validate.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ if [ -f "package.json" ]; then
141141
if package_manager="$(choose_package_manager)"; then
142142
note "using package manager: $package_manager"
143143

144-
for script_name in check lint test build; do
144+
for script_name in check lint test build release:check; do
145145
if package_script_exists "$script_name"; then
146146
run_check "package script: $script_name" run_package_script "$package_manager" "$script_name"
147147
fi

0 commit comments

Comments
 (0)