fix(openspec): always upgrade to latest and retry without --profile #160
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: [master] | |
| pull_request: | |
| branches: [master] | |
| jobs: | |
| build-and-test: | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| node-version: [20, 22] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install pnpm | |
| uses: pnpm/action-setup@v4 | |
| - name: Setup Node ${{ matrix.node-version }} | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ matrix.node-version }} | |
| cache: pnpm | |
| - run: pnpm install --frozen-lockfile | |
| - run: pnpm build | |
| - run: pnpm lint | |
| - run: pnpm format:check | |
| - run: pnpm test:coverage | |
| shellcheck: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Run shellcheck | |
| uses: ludeeus/action-shellcheck@2.0.0 | |
| with: | |
| scandir: ./assets/skills/comet/scripts | |
| bats-tests: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install bats | |
| run: sudo apt-get install -y bats | |
| - name: Run shell tests | |
| run: bats test/shell/*.bats | |
| script-smoke: | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| matrix: | |
| os: [ubuntu-latest, macos-latest, windows-latest] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install pnpm | |
| uses: pnpm/action-setup@v4 | |
| - name: Setup Node 20 | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| cache: pnpm | |
| - run: pnpm install --frozen-lockfile | |
| - name: Run Comet script smoke tests | |
| run: pnpm test -- test/ts/comet-scripts.test.ts | |
| - name: Run portable shell tests | |
| run: pnpm test:shell | |
| init-e2e: | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest, windows-latest] | |
| node-version: [20, 22] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install pnpm | |
| uses: pnpm/action-setup@v4 | |
| - name: Setup Node ${{ matrix.node-version }} | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ matrix.node-version }} | |
| cache: pnpm | |
| - run: pnpm install --frozen-lockfile | |
| - run: pnpm build | |
| - name: Install OpenSpec CLI | |
| run: npm install -g @fission-ai/openspec@latest | |
| - name: Create temp project directory | |
| run: mkdir -p "$RUNNER_TEMP/comet-e2e-project" | |
| shell: bash | |
| - name: Run comet init (project scope) | |
| run: | | |
| node bin/comet.js init "$RUNNER_TEMP/comet-e2e-project" --yes --json \ | |
| | tee "$RUNNER_TEMP/comet-init-project.json" | |
| shell: bash | |
| - name: Verify Comet skills installed (project) | |
| run: | | |
| PROJ="$RUNNER_TEMP/comet-e2e-project" | |
| check_file() { | |
| if [ ! -f "$1" ]; then | |
| echo "Missing file: $1" >&2 | |
| exit 1 | |
| fi | |
| } | |
| for sd in .claude/skills .cursor/skills .codex/skills .opencode/skills \ | |
| .windsurf/skills .cline/skills .roo/skills .continue/skills \ | |
| .gemini/skills .amazonq/skills .qwen/skills .kilocode/skills \ | |
| .augment/skills .kiro/skills .lingma/skills .junie/skills \ | |
| .codebuddy/skills .cospec/skills .crush/skills .factory/skills \ | |
| .iflow/skills .pi/skills .qoder/skills .agents/skills \ | |
| .bob/skills .forge/skills .trae/skills .github/skills; do | |
| check_file "$PROJ/$sd/comet/SKILL.md" | |
| check_file "$PROJ/$sd/comet/scripts/comet-guard.sh" | |
| check_file "$PROJ/$sd/comet/scripts/comet-state.sh" | |
| check_file "$PROJ/$sd/comet/scripts/comet-handoff.sh" | |
| check_file "$PROJ/$sd/comet/scripts/comet-yaml-validate.sh" | |
| check_file "$PROJ/$sd/comet/scripts/comet-archive.sh" | |
| done | |
| echo "All 28 platforms project Comet skills: OK" | |
| shell: bash | |
| - name: Verify external installer status (project) | |
| run: | | |
| node - "$RUNNER_TEMP/comet-init-project.json" <<'NODE' | |
| const fs = require('fs'); | |
| function extractJsonPayload(raw) { | |
| const start = raw.indexOf('{'); | |
| if (start < 0) { | |
| throw new Error('No JSON payload found in init output'); | |
| } | |
| return raw.slice(start); | |
| } | |
| const raw = fs.readFileSync(process.argv[2], 'utf8'); | |
| const data = JSON.parse(extractJsonPayload(raw)); | |
| const allowed = new Set(['installed', 'skipped', 'failed']); | |
| const components = ['openspec', 'superpowers']; | |
| const malformed = data.results.flatMap((r) => | |
| components | |
| .filter((component) => !allowed.has(r[component])) | |
| .map((component) => `${r.platform}: ${component}=${r[component]}`), | |
| ); | |
| if (malformed.length > 0) { | |
| console.error('External installers returned unexpected status values:'); | |
| for (const item of malformed) { | |
| console.error(`- ${item}`); | |
| } | |
| process.exit(1); | |
| } | |
| const failed = data.results.flatMap((r) => | |
| components | |
| .filter((component) => r[component] === 'failed') | |
| .map((component) => `${r.platform}: ${component}=${r[component]}`), | |
| ); | |
| if (failed.length > 0) { | |
| console.warn('External installers reported failed for:'); | |
| for (const item of failed) { | |
| console.warn(`- ${item}`); | |
| } | |
| } | |
| console.log(`External installer statuses validated for ${data.results.length} platforms`); | |
| NODE | |
| shell: bash | |
| - name: Verify OpenSpec and working directories (project) | |
| run: | | |
| test -d "$RUNNER_TEMP/comet-e2e-project/openspec" | |
| test -d "$RUNNER_TEMP/comet-e2e-project/docs/superpowers/specs" | |
| test -d "$RUNNER_TEMP/comet-e2e-project/docs/superpowers/plans" | |
| echo "OpenSpec + working dirs: OK" | |
| shell: bash | |
| - name: Create temp global home | |
| run: mkdir -p "$RUNNER_TEMP/comet-e2e-global" | |
| shell: bash | |
| - name: Run comet init (global scope) | |
| run: | | |
| export HOME="$RUNNER_TEMP/comet-e2e-global" | |
| export USERPROFILE="$RUNNER_TEMP/comet-e2e-global" | |
| node bin/comet.js init "$RUNNER_TEMP/comet-e2e-global" --yes --scope global --json \ | |
| | tee "$RUNNER_TEMP/comet-init-global.json" | |
| shell: bash | |
| - name: Verify Comet skills installed (global) | |
| run: | | |
| HOME_DIR="$RUNNER_TEMP/comet-e2e-global" | |
| check_file() { | |
| if [ ! -f "$1" ]; then | |
| echo "Missing file: $1" >&2 | |
| exit 1 | |
| fi | |
| } | |
| for sd in .claude/skills .cursor/skills .codex/skills .config/opencode/skills \ | |
| .windsurf/skills .cline/skills .roo/skills .continue/skills \ | |
| .gemini/skills .amazonq/skills .qwen/skills .kilocode/skills \ | |
| .augment/skills .kiro/skills .lingma/skills .junie/skills \ | |
| .codebuddy/skills .cospec/skills .crush/skills .factory/skills \ | |
| .iflow/skills .pi/skills .qoder/skills .gemini/antigravity/skills \ | |
| .bob/skills .forge/skills .trae/skills .github/skills; do | |
| check_file "$HOME_DIR/$sd/comet/SKILL.md" | |
| check_file "$HOME_DIR/$sd/comet/scripts/comet-guard.sh" | |
| check_file "$HOME_DIR/$sd/comet/scripts/comet-state.sh" | |
| check_file "$HOME_DIR/$sd/comet/scripts/comet-handoff.sh" | |
| check_file "$HOME_DIR/$sd/comet/scripts/comet-yaml-validate.sh" | |
| check_file "$HOME_DIR/$sd/comet/scripts/comet-archive.sh" | |
| done | |
| echo "All 28 platforms global Comet skills: OK" | |
| shell: bash | |
| - name: Verify external installer status (global) | |
| run: | | |
| node - "$RUNNER_TEMP/comet-init-global.json" <<'NODE' | |
| const fs = require('fs'); | |
| function extractJsonPayload(raw) { | |
| const start = raw.indexOf('{'); | |
| if (start < 0) { | |
| throw new Error('No JSON payload found in init output'); | |
| } | |
| return raw.slice(start); | |
| } | |
| const raw = fs.readFileSync(process.argv[2], 'utf8'); | |
| const data = JSON.parse(extractJsonPayload(raw)); | |
| const allowed = new Set(['installed', 'skipped', 'failed']); | |
| const components = ['openspec', 'superpowers']; | |
| const malformed = data.results.flatMap((r) => | |
| components | |
| .filter((component) => !allowed.has(r[component])) | |
| .map((component) => `${r.platform}: ${component}=${r[component]}`), | |
| ); | |
| if (malformed.length > 0) { | |
| console.error('External installers returned unexpected status values:'); | |
| for (const item of malformed) { | |
| console.error(`- ${item}`); | |
| } | |
| process.exit(1); | |
| } | |
| const failed = data.results.flatMap((r) => | |
| components | |
| .filter((component) => r[component] === 'failed') | |
| .map((component) => `${r.platform}: ${component}=${r[component]}`), | |
| ); | |
| if (failed.length > 0) { | |
| console.warn('External installers reported failed for:'); | |
| for (const item of failed) { | |
| console.warn(`- ${item}`); | |
| } | |
| } | |
| console.log(`External installer statuses validated for ${data.results.length} platforms`); | |
| NODE | |
| shell: bash | |
| - name: Verify no working directories (global) | |
| run: | | |
| test ! -d "$RUNNER_TEMP/comet-e2e-global/docs/superpowers/specs" | |
| echo "Global scope has no working dirs: OK" | |
| shell: bash |