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
17 changes: 17 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,23 @@ jobs:
- name: Check out repository
uses: actions/checkout@v6

- name: Set up pnpm
uses: pnpm/action-setup@v4
with:
version: 10.13.1

- name: Set up Node
uses: actions/setup-node@v6
with:
node-version: '22'
cache: pnpm

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Run package verification
run: pnpm run release:check

- name: Validate required top-level files
shell: bash
run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
- name: Set up pnpm
uses: pnpm/action-setup@v4
with:
version: 9
version: 10.13.1

- name: Set up Node
uses: actions/setup-node@v6
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release-dry-run.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
node-version: 22
- uses: pnpm/action-setup@v4
with:
version: 10
version: 10.13.1
run_install: false
- name: Install dependencies
run: pnpm install --frozen-lockfile
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
registry-url: https://registry.npmjs.org
- uses: pnpm/action-setup@v4
with:
version: 10
version: 10.13.1
run_install: false
- name: Install dependencies
run: pnpm install --frozen-lockfile
Expand Down
9 changes: 9 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,15 @@ Keep the review pack factual. It should say what changed, how it was verified, w

Every contribution needs verification appropriate to the change.

Use Node.js 22 and the exact pnpm version declared by `packageManager` in
`package.json`. Enable Corepack, then install dependencies non-interactively:

```sh
corepack enable
CI=true corepack pnpm install --frozen-lockfile
pnpm run release:check
```

Use the smallest relevant verification first:

- Documentation-only changes: review the rendered Markdown or inspect the diff.
Expand Down
5 changes: 5 additions & 0 deletions docs/release-process.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ uses generated release notes and maintainers have reviewed them.

Choose the smallest verification that gives confidence for the release:

- Use Node.js 22 and the exact pnpm version in `package.json#packageManager`;
Corepack and CI workflows use this pin rather than a floating pnpm major.
- Run `CI=true corepack pnpm install --frozen-lockfile` from a clean checkout.
- Run `pnpm run release:check`, which also verifies the pnpm pin, required
esbuild build-script policy, and workflow version alignment.
- Documentation-only release: markdown review, link check if available, and
spell or formatting checks when configured.
- Library or package release: targeted tests, typecheck, lint, build, and
Expand Down
9 changes: 8 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"name": "@rogerchappel/stackforge",
"version": "0.1.0",
"private": true,
"packageManager": "pnpm@10.13.1",
"description": "Agent-friendly software project scaffolding CLI for apps, APIs, CLIs, and OSS packages.",
"type": "module",
"bin": {
Expand All @@ -12,11 +13,12 @@
"build": "tsc",
"dev": "tsx src/index.ts",
"check": "tsc --noEmit",
"package-manager:check": "node scripts/check-package-manager.mjs",
"docs:check": "node scripts/check-docs.mjs",
"start": "node dist/index.js",
"check:templates": "pnpm build && node scripts/check-template-registry.mjs",
"smoke:init": "bash scripts/smoke-init.sh",
"release:check": "pnpm run docs:check && pnpm run build && pnpm test && pnpm run smoke && pnpm run package:smoke",
"release:check": "pnpm run package-manager:check && pnpm run docs:check && pnpm run build && pnpm test && pnpm run smoke && pnpm run package:smoke",
"test": "pnpm run build && node scripts/check-template-registry.mjs",
"smoke": "pnpm run smoke:init",
"package:smoke": "pnpm run build && node scripts/package-smoke.mjs"
Expand All @@ -32,6 +34,11 @@
"engines": {
"node": ">=20"
},
"pnpm": {
"onlyBuiltDependencies": [
"esbuild"
]
},
"repository": {
"type": "git",
"url": "git+https://github.com/rogerchappel/stackforge.git"
Expand Down
45 changes: 45 additions & 0 deletions scripts/check-package-manager.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { readFileSync, readdirSync } from 'node:fs';
import { join } from 'node:path';

const root = process.cwd();
const packageJson = JSON.parse(readFileSync(join(root, 'package.json'), 'utf8'));
const match = /^pnpm@(\d+\.\d+\.\d+)$/.exec(packageJson.packageManager ?? '');

if (!match) {
throw new Error('package.json packageManager must pin an exact pnpm version');
}

if (!packageJson.pnpm?.onlyBuiltDependencies?.includes('esbuild')) {
throw new Error('package.json must allow the required esbuild install script');
}

const expectedVersion = match[1];
const workflowDir = join(root, '.github', 'workflows');
const workflowFiles = readdirSync(workflowDir).filter((file) => file.endsWith('.yml'));
let setupCount = 0;

for (const file of workflowFiles) {
const lines = readFileSync(join(workflowDir, file), 'utf8').split('\n');

for (let index = 0; index < lines.length; index += 1) {
if (!lines[index].includes('uses: pnpm/action-setup@')) {
continue;
}

setupCount += 1;
const block = lines.slice(index + 1, index + 6).join('\n');
const version = /^\s+version:\s*['"]?([^'"\s]+)['"]?\s*$/m.exec(block)?.[1];

if (version !== expectedVersion) {
throw new Error(
`${file} pnpm/action-setup version ${version ?? '(missing)'} must match packageManager ${expectedVersion}`,
);
}
}
}

if (setupCount === 0) {
throw new Error('Expected at least one pnpm/action-setup workflow');
}

console.log(`Validated pnpm ${expectedVersion}, esbuild build policy, and ${setupCount} workflow setup(s).`);
Loading