mirror of
https://github.com/openprose/prose.git
synced 2026-09-19 05:55:05 +08:00
f9c84b834e
* Fix CLI workflows for the pnpm-workspace consolidation The Reactor consolidation moved the CLI into the pnpm workspace, but the npm-to-pnpm workflow conversion was incomplete and broke CI on main. - Add the missing pnpm/action-setup step before every setup-node that sets cache: pnpm (cli-real-harness-smoke, cli-release-check, release). Without pnpm on PATH, setup-node fails: "Unable to locate executable file: pnpm". - Rework the npm-package-smoke job to pack with pnpm. npm pack does not rewrite the workspace: protocol dependency on @openprose/reactor; pnpm pack does. The install smoke now resolves that dependency from a locally packed reactor tarball so it does not depend on the registry. * Build the Reactor dependency before the CLI compiles in CI After the workspace consolidation the CLI typechecks and builds against @openprose/reactor, which must be built first. - Add a "Build workspace" step before every CLI typecheck/build step (node-checks, release-tarball-smoke, cli-real-harness-smoke, and the release workflow's verify-cli and release-assets jobs). - Drop the deleted tools/cli/package-lock.json entries from .version-bump.json so bump-version.sh --check no longer fails. * Drop Node 18 from the CLI check matrix The CLI now requires Node 20+ (engines.node >=20.0.0, enforced by install.sh). The Node 18 matrix leg fails install.sh's version gate.
309 lines
9.1 KiB
YAML
309 lines
9.1 KiB
YAML
name: CLI Release Check
|
|
|
|
on:
|
|
pull_request:
|
|
paths:
|
|
- "tools/cli/**"
|
|
- ".github/workflows/cli-release-check.yml"
|
|
- ".github/workflows/cli-real-harness-smoke.yml"
|
|
- ".github/workflows/cli-skills-smoke.yml"
|
|
- ".github/workflows/openprose-smoke.yml"
|
|
- ".github/workflows/release.yml"
|
|
- ".github/scripts/openprose-smoke/**"
|
|
- "scripts/release-preflight.sh"
|
|
- "scripts/bump-version.sh"
|
|
- ".version-bump.json"
|
|
push:
|
|
branches:
|
|
- main
|
|
paths:
|
|
- "tools/cli/**"
|
|
- ".github/workflows/cli-release-check.yml"
|
|
- ".github/workflows/cli-real-harness-smoke.yml"
|
|
- ".github/workflows/cli-skills-smoke.yml"
|
|
- ".github/workflows/openprose-smoke.yml"
|
|
- ".github/workflows/release.yml"
|
|
- ".github/scripts/openprose-smoke/**"
|
|
- "scripts/release-preflight.sh"
|
|
- "scripts/bump-version.sh"
|
|
- ".version-bump.json"
|
|
workflow_dispatch:
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
concurrency:
|
|
group: cli-release-check-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
lint-shell-and-actions:
|
|
name: Lint shell and workflow files
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 10
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Setup Go for actionlint
|
|
uses: actions/setup-go@v5
|
|
with:
|
|
go-version: stable
|
|
cache: false
|
|
|
|
- name: Install actionlint
|
|
run: go install github.com/rhysd/actionlint/cmd/actionlint@v1.7.7
|
|
|
|
- name: Lint GitHub Actions workflows
|
|
run: actionlint .github/workflows/cli-*.yml .github/workflows/plugin-manifest.yml .github/workflows/openprose-smoke.yml .github/workflows/release.yml
|
|
|
|
- name: Check installer shell syntax
|
|
run: bash -n tools/cli/install.sh
|
|
|
|
- name: Check release helper syntax
|
|
run: node --check tools/cli/scripts/build-release-tarball.mjs
|
|
|
|
- name: Check harness smoke helper syntax
|
|
run: node --check tools/cli/scripts/smoke-harness.mjs
|
|
|
|
- name: Check release shell syntax
|
|
run: |
|
|
bash -n scripts/bump-version.sh
|
|
bash -n scripts/release-preflight.sh
|
|
|
|
- name: OpenProse versions in sync
|
|
run: ./scripts/bump-version.sh --check
|
|
|
|
node-checks:
|
|
name: Node ${{ matrix.node-version }} checks
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 20
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
node-version:
|
|
- 20
|
|
- 22
|
|
defaults:
|
|
run:
|
|
working-directory: tools/cli
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Setup pnpm
|
|
uses: pnpm/action-setup@v4
|
|
|
|
- name: Setup Node
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: ${{ matrix.node-version }}
|
|
cache: pnpm
|
|
cache-dependency-path: pnpm-lock.yaml
|
|
|
|
- name: Install dependencies
|
|
run: corepack enable && pnpm install --frozen-lockfile --dir ../..
|
|
|
|
- name: Build workspace
|
|
run: pnpm --dir ../.. run build
|
|
|
|
- name: Typecheck
|
|
run: npm run typecheck
|
|
|
|
- name: Test
|
|
run: npm test
|
|
|
|
- name: Build
|
|
run: npm run build
|
|
|
|
- name: Smoke built CLI
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
node dist/index.js --help
|
|
node dist/index.js help
|
|
node dist/index.js run hello.prose.md --harness mock
|
|
PROSE_HARNESS=mock node dist/index.js status
|
|
|
|
npm-package-smoke:
|
|
name: npm package smoke
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 20
|
|
defaults:
|
|
run:
|
|
working-directory: tools/cli
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Setup pnpm
|
|
uses: pnpm/action-setup@v4
|
|
|
|
- name: Setup Node
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 22
|
|
cache: pnpm
|
|
cache-dependency-path: pnpm-lock.yaml
|
|
|
|
- name: Install dependencies
|
|
run: corepack enable && pnpm install --frozen-lockfile --dir ../..
|
|
|
|
- name: Build workspace
|
|
run: pnpm --dir ../.. run build
|
|
|
|
- name: Pack CLI and reactor artifacts
|
|
run: |
|
|
set -euo pipefail
|
|
pack_dir="$RUNNER_TEMP/npm-pack"
|
|
mkdir -p "$pack_dir"
|
|
# pnpm pack rewrites the workspace: protocol dependency on
|
|
# @openprose/reactor to a concrete version; npm pack does not.
|
|
pnpm pack --pack-destination "$pack_dir"
|
|
pnpm --dir ../../packages/reactor pack --pack-destination "$pack_dir"
|
|
ls -1 "$pack_dir"
|
|
|
|
- name: Validate npm package manifest
|
|
run: |
|
|
set -euo pipefail
|
|
cli_tarball="$(find "$RUNNER_TEMP/npm-pack" -maxdepth 1 -name 'openprose-prose-cli-*.tgz' -print -quit)"
|
|
tar -tzf "$cli_tarball" | sed 's#^package/##' | sed '/^$/d' | sort -u > "$RUNNER_TEMP/cli-pack-files.txt"
|
|
node --input-type=module <<'EOF'
|
|
import { readFileSync } from "node:fs";
|
|
|
|
const paths = new Set(
|
|
readFileSync(`${process.env.RUNNER_TEMP}/cli-pack-files.txt`, "utf8")
|
|
.split("\n")
|
|
.filter(Boolean),
|
|
);
|
|
const required = ["package.json", "README.md", "LICENSE", "dist/index.js", "dist/index.d.ts"];
|
|
const forbiddenPrefixes = ["src/", "tests/", "node_modules/"];
|
|
|
|
for (const path of required) {
|
|
if (!paths.has(path)) {
|
|
throw new Error(`npm package is missing ${path}`);
|
|
}
|
|
}
|
|
|
|
for (const path of paths) {
|
|
if (forbiddenPrefixes.some((prefix) => path.startsWith(prefix))) {
|
|
throw new Error(`npm package includes ${path}`);
|
|
}
|
|
if (path.endsWith(".map")) {
|
|
throw new Error(`npm package includes sourcemap ${path}`);
|
|
}
|
|
}
|
|
console.log("ok: npm package manifest");
|
|
EOF
|
|
|
|
- name: Smoke npm package artifact
|
|
run: |
|
|
set -euo pipefail
|
|
pack_dir="$RUNNER_TEMP/npm-pack"
|
|
cli_tarball="$(find "$pack_dir" -maxdepth 1 -name 'openprose-prose-cli-*.tgz' -print -quit)"
|
|
reactor_tarball="$(find "$pack_dir" -maxdepth 1 -name 'openprose-reactor-*.tgz' -print -quit)"
|
|
prefix="$RUNNER_TEMP/npm-prefix"
|
|
|
|
# The packed CLI depends on @openprose/reactor by exact version;
|
|
# install the locally packed reactor tarball alongside it so the
|
|
# smoke does not depend on the registry.
|
|
npm install --global --prefix "$prefix" "$reactor_tarball" "$cli_tarball"
|
|
"$prefix/bin/prose" --version
|
|
"$prefix/bin/prose" run hello.prose.md --harness mock
|
|
|
|
import_dir="$RUNNER_TEMP/npm-import-smoke"
|
|
mkdir -p "$import_dir"
|
|
cd "$import_dir"
|
|
npm init -y
|
|
npm install "$reactor_tarball" "$cli_tarball"
|
|
node --input-type=module -e "await import('@openprose/prose-cli')"
|
|
|
|
release-tarball-smoke:
|
|
name: Release tarball smoke on ${{ matrix.os }}
|
|
runs-on: ${{ matrix.os }}
|
|
timeout-minutes: 25
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
os:
|
|
- ubuntu-latest
|
|
- macos-latest
|
|
defaults:
|
|
run:
|
|
working-directory: tools/cli
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Setup pnpm
|
|
uses: pnpm/action-setup@v4
|
|
|
|
- name: Setup Node
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 22
|
|
cache: pnpm
|
|
cache-dependency-path: pnpm-lock.yaml
|
|
|
|
- name: Install dependencies
|
|
run: corepack enable && pnpm install --frozen-lockfile --dir ../..
|
|
|
|
- name: Build workspace
|
|
run: pnpm --dir ../.. run build
|
|
|
|
- name: Build
|
|
run: npm run build
|
|
|
|
- name: Build and smoke release tarball
|
|
run: |
|
|
set -euo pipefail
|
|
release_dir="$RUNNER_TEMP/prose-release"
|
|
install_dir="$RUNNER_TEMP/prose-install"
|
|
bin_dir="$RUNNER_TEMP/prose-bin"
|
|
|
|
npm run release:tarball -- --out-dir "$release_dir" --skip-build
|
|
|
|
env \
|
|
PROSE_VERSION="$(node -p 'require("./package.json").version')" \
|
|
PROSE_BASE_URL="file://$release_dir" \
|
|
PROSE_INSTALL_DIR="$install_dir" \
|
|
PROSE_BIN_DIR="$bin_dir" \
|
|
sh install.sh
|
|
|
|
"$bin_dir/prose" --version
|
|
"$bin_dir/prose" run hello.prose.md --harness mock
|
|
|
|
- name: Upload release tarball
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: cli-release-${{ runner.os }}-${{ runner.arch }}
|
|
path: ${{ runner.temp }}/prose-release/*
|
|
if-no-files-found: error
|
|
|
|
production-audit:
|
|
name: Production dependency audit
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 15
|
|
defaults:
|
|
run:
|
|
working-directory: tools/cli
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Setup pnpm
|
|
uses: pnpm/action-setup@v4
|
|
|
|
- name: Setup Node
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 22
|
|
cache: pnpm
|
|
cache-dependency-path: pnpm-lock.yaml
|
|
|
|
- name: Install dependencies
|
|
run: corepack enable && pnpm install --frozen-lockfile --dir ../..
|
|
|
|
- name: Audit production dependencies
|
|
run: npm run audit:policy
|