Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
239aec5
npmjs release specified
DawMatt Jun 16, 2026
1066d5f
Scoped npmjs publish feature
DawMatt Jun 16, 2026
5ef910b
Implement initial phases of npmjs publication
DawMatt Jun 16, 2026
f0af79b
Added AI support goal
Jun 17, 2026
f00908e
Updated constitution to match the CI quality gate requirements.
DawMatt Jun 17, 2026
28a4a57
Convert publication method to trusted publisher.
DawMatt Jun 17, 2026
bb7b67c
Manual setup steps for package release
DawMatt Jun 17, 2026
60330ca
CI quality expectations now codified
DawMatt Jun 17, 2026
4a1631c
Uplifted to meet minimum CI standards
DawMatt Jun 17, 2026
c89c94e
After implement hook to enforce new quality-gate skill
DawMatt Jun 17, 2026
d5763db
Packages documented ready for publication at npmjs
DawMatt Jun 17, 2026
fe6e8cd
chore: release v0.1.2
DawMatt Jun 17, 2026
ab16783
Initial setup steps removed from general release process
DawMatt Jun 18, 2026
718ce6a
chore: release v0.1.3
DawMatt Jun 18, 2026
7d02456
Release pipeline extra steps to ensure dependencies are available
DawMatt Jun 18, 2026
62d0a6b
chore: release v0.1.4
DawMatt Jun 18, 2026
b3200c4
Resolved CI test failure due to missing dependency
DawMatt Jun 18, 2026
842de13
chore: release v0.1.5
DawMatt Jun 18, 2026
b511d82
Resolved failed publish step
DawMatt Jun 18, 2026
d326fc0
chore: release v0.1.6
DawMatt Jun 18, 2026
4cf0a51
fix: add --provenance flag to npm publish commands to enable OIDC aut…
DawMatt Jun 18, 2026
e30e2ef
chore: release v0.1.7
DawMatt Jun 18, 2026
d4c308a
Another CI pipeline tweak
DawMatt Jun 18, 2026
b374f12
chore: release v0.1.8
DawMatt Jun 18, 2026
be63db4
Manually tried to resolve CI issues
DawMatt Jun 18, 2026
67719ff
chore: release v0.1.9
DawMatt Jun 18, 2026
8bd9327
Removed alternate permissions location
DawMatt Jun 18, 2026
020bc95
chore: release v0.1.10
DawMatt Jun 18, 2026
0427412
Stubborn Claude CI changes
DawMatt Jun 18, 2026
8e0b4ed
chore: release v0.1.11
DawMatt Jun 18, 2026
43aa7fa
Manually applying CI workaround from npm issue 1960
DawMatt Jun 18, 2026
8fa315c
chore: release v0.1.12
DawMatt Jun 18, 2026
13c5405
Add CI debug step
DawMatt Jun 18, 2026
2e73bcc
chore: release v0.1.13
DawMatt Jun 18, 2026
812be7e
Revised CI debug and revised bug workaround approach
DawMatt Jun 18, 2026
b253e49
chore: release v0.1.14
DawMatt Jun 18, 2026
6ce5e46
Removed CI debug step
DawMatt Jun 18, 2026
065cafc
chore: release v0.1.15
DawMatt Jun 18, 2026
bb2a16a
CI Debug
DawMatt Jun 18, 2026
2535320
chore: release v0.1.16
DawMatt Jun 18, 2026
3400197
Check environment versions
DawMatt Jun 18, 2026
86da4b1
chore: release v0.1.17
DawMatt Jun 18, 2026
2ad073f
Update CI's npm to version supporting Trusted Publisher
DawMatt Jun 18, 2026
ad84b44
chore: release v0.1.18
DawMatt Jun 18, 2026
db07029
Cleaned up CI environment overrides
DawMatt Jun 18, 2026
9c9c0cb
chore: release v0.1.19
DawMatt Jun 18, 2026
adb0593
Tidied up task and issues lists
DawMatt Jun 18, 2026
91f5bc7
Tighten CI pipeline and process
DawMatt Jun 18, 2026
5977b5c
Tightened CI pipeline
DawMatt Jun 18, 2026
5cc2de9
chore: release v0.1.20
DawMatt Jun 18, 2026
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
77 changes: 77 additions & 0 deletions .claude/skills/speckit-quality-gate/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
---
name: speckit-quality-gate
description: Run the full CI quality gate. Blocks /speckit-implement from completing if any stage fails.
compatibility: Requires Node.js project with npm/yarn scripts defined in package.json
metadata:
author: local
source: local
---

# CI Quality Gate

This skill is a **mandatory blocking gate**. It runs after every `/speckit-implement` execution and enforces the project's publication-readiness standards. Implementation is not complete until this gate passes entirely.

## Behaviour

Run ALL six stages below in order from the repository root. A non-zero exit from any stage is a **gate failure**.

### Stage 1 — Dependency audit
```sh
npm audit --audit-level=high --omit=dev
```
Pass condition: zero high-severity vulnerabilities in production dependencies.

### Stage 2 — Lint
```sh
npm run lint
```
Pass condition: zero ESLint violations.

### Stage 3 — Type check
```sh
npm run typecheck --workspaces --if-present
```
Pass condition: zero TypeScript errors across all packages.

### Stages 4–5 — Tests + coverage
Run all four coverage commands. Each must exit 0 and meet the ≥ 80 % line threshold:
```sh
npm run test:coverage
yarn workspace @dawmatt/api-grade-core run test:coverage
yarn workspace @dawmatt/backstage-plugin-api-grade run test:coverage
yarn workspace @dawmatt/backstage-plugin-api-grade-backend run test:coverage
```
Pass condition: all tests pass; all packages report ≥ 80 % line coverage.

### Stage 6 — Build
```sh
npm run build
```
Pass condition: all workspace packages and root CLI build without errors.

---

## On Gate Failure

If any stage exits non-zero:

1. Output a clear failure report:
```
QUALITY GATE FAILED
Stage: <stage name>
Error: <exact error output>
```
2. **Stop immediately** — do NOT proceed to the git-commit hook and do NOT write a Completion Report.
3. Fix every failure in the source files (do not suppress errors with `@ts-ignore`, `eslint-disable`, or similar unless there is no correct alternative).
4. After fixing, re-run the gate **from Stage 1**. Only when all six stages pass may you proceed.

The Completion Report MUST NOT be written while this gate is failing. Saying "done" when the gate is red is not permitted by the project constitution.

## On Gate Success

Output:
```
QUALITY GATE PASSED — all 6 CI stages exit 0.
```

Proceed to any remaining post-execution hooks (e.g. git commit) and then write the Completion Report.
8 changes: 8 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# CODEOWNERS — release-critical paths require maintainer review

.github/workflows/ @DawMatt
scripts/ @DawMatt
package.json @DawMatt
packages/api-grade-core/package.json @DawMatt
packages/backstage-plugin-api-grade/package.json @DawMatt
packages/backstage-plugin-api-grade-backend/package.json @DawMatt
75 changes: 75 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
quality-gate:
name: Quality Gate
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'yarn'

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

# Stage 1: Dependency audit (production deps only; devDep vulns don't affect published packages)
- name: Audit dependencies
run: npm audit --audit-level=high --omit=dev

# Stage 2: Lint
- name: Lint
run: npm run lint

# Stage 3: Build internal workspace dependencies so their dist/index.d.ts
# exists before TypeScript resolves cross-package imports during typecheck.
# Yarn workspaces symlinks packages into node_modules but TypeScript reads
# the `types` field (./dist/index.d.ts) which is absent pre-build.
- name: Build api-grade-core (required for cross-package type checking)
run: npm run build
working-directory: packages/api-grade-core

- name: Build backstage-plugin-api-grade-backend (required for frontend plugin type checking)
run: npm run build
working-directory: packages/backstage-plugin-api-grade-backend

- name: Type check
run: npm run typecheck --workspaces --if-present && npm run typecheck

# Stage 4: Build CLI so dist/cli/index.js exists before integration tests run.
# Integration tests spawn the compiled CLI binary directly; without this
# build step they fail with Cannot find module '.../dist/cli/index.js'.
- name: Build CLI (required for integration tests)
run: npm run build

# Stage 4: Tests + coverage (root)
- name: Test (root) with coverage
run: npm run test:coverage

# Stage 4: Tests + coverage (workspaces)
- name: Test (api-grade-core) with coverage
run: npm run test:coverage
working-directory: packages/api-grade-core

- name: Test (backstage-plugin-api-grade) with coverage
run: npm run test:coverage
working-directory: packages/backstage-plugin-api-grade

- name: Test (backstage-plugin-api-grade-backend) with coverage
run: npm run test:coverage
working-directory: packages/backstage-plugin-api-grade-backend

# Stage 5: Build
- name: Build
run: npm run build
171 changes: 171 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
name: Release

on:
push:
tags:
- 'v[0-9]*.[0-9]*.[0-9]*'

# As per https://docs.npmjs.com/trusted-publishers
permissions:
id-token: write # Required for OIDC
contents: write # Required for gh release create

jobs:
release:
name: Publish to npmjs
runs-on: ubuntu-latest
environment: npm-publish

steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0 # full history required for branch reachability check and release notes

- name: Verify tag is on main branch
run: |
git fetch origin main
if ! git merge-base --is-ancestor "${{ github.sha }}" origin/main; then
echo "Error: The tagged commit is not reachable from the main branch."
echo "Push the tag only after the feature branch has been merged to main."
exit 1
fi

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
registry-url: 'https://registry.npmjs.org'
cache: 'yarn'
package-manager-cache: false # never use caching in release builds

- name: Show npmrc file content
run: cat /home/runner/work/_temp/.npmrc

# via https://github.com/npm/documentation/issues/1960
#
# `setup-node` with `registry-url` writes an `_authToken` line in
# `.npmrc` that expands to empty when `NODE_AUTH_TOKEN` is unset.
# Empty auth tokens prevent npm CLI from initiating OIDC. Strip
# the line so the OIDC flow kicks in.
- name: Strip empty _authToken from .npmrc
run: |
npmrc="${NPM_CONFIG_USERCONFIG:-$HOME/.npmrc}"
sed -i '/_authToken/d' "$npmrc"

- name: Show npmrc file content
run: cat /home/runner/work/_temp/.npmrc

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

# ── Quality Gate (same stages as CI) ──────────────────────────────────

- name: Audit dependencies
run: npm audit --audit-level=high --omit=dev

- name: Lint
run: npm run lint

- name: Build api-grade-core (required for cross-package type checking)
run: npm run build
working-directory: packages/api-grade-core

- name: Build backstage-plugin-api-grade-backend (required for frontend plugin type checking)
run: npm run build
working-directory: packages/backstage-plugin-api-grade-backend

- name: Type check
run: npm run typecheck --workspaces --if-present && npm run typecheck

# Build CLI so dist/cli/index.js exists before integration tests run.
# Integration tests spawn the compiled CLI binary directly; without this
# build step they fail with Cannot find module '.../dist/cli/index.js'.
- name: Build CLI (required for integration tests)
run: npm run build

- name: Test (root) with coverage
run: npm run test:coverage

- name: Test (api-grade-core) with coverage
run: npm run test:coverage
working-directory: packages/api-grade-core

- name: Test (backstage-plugin-api-grade) with coverage
run: npm run test:coverage
working-directory: packages/backstage-plugin-api-grade

- name: Test (backstage-plugin-api-grade-backend) with coverage
run: npm run test:coverage
working-directory: packages/backstage-plugin-api-grade-backend

- name: Build
run: npm run build

# ── Publish ───────────────────────────────────────────────────────────

- name: Check npm version (must be >=11.5.1 for OIDC support)
run: npm --version

- name: Check node version (must be >=22.14.0 for OIDC support)
run: node --version

- name: Upgrade npm to latest (must be >=11.5.1 for OIDC support)
run: npm install -g npm@latest

- name: Rewrite workspace dependencies for publish
run: node scripts/pre-publish.mjs

- name: Publish @dawmatt/api-grade-core
run: npm publish --access public --provenance
working-directory: packages/api-grade-core

- name: Publish @dawmatt/backstage-plugin-api-grade
run: npm publish --access public --provenance
working-directory: packages/backstage-plugin-api-grade

- name: Publish @dawmatt/backstage-plugin-api-grade-backend
run: npm publish --access public --provenance
working-directory: packages/backstage-plugin-api-grade-backend

- name: Publish @dawmatt/api-grade (CLI)
run: npm publish --access public --provenance

- name: Restore workspace dependencies
if: always()
run: node scripts/post-publish.mjs

# ── Release Record ────────────────────────────────────────────────────

- name: Create GitHub Release
env:
GH_TOKEN: ${{ github.token }}
run: |
VERSION="${GITHUB_REF_NAME}"
PREV_TAG=$(git tag --sort=-version:refname | sed -n '2p')
if [ -n "${PREV_TAG}" ]; then
CHANGES=$(git log "${PREV_TAG}..${VERSION}" --pretty=format:"- %s" \
| grep -v '^- chore: release' \
| grep -v '^- chore: bump version')
else
CHANGES=$(git log "${VERSION}" --pretty=format:"- %s" \
| grep -v '^- chore: release' \
| grep -v '^- chore: bump version')
fi
if [ -z "${CHANGES}" ]; then
CHANGES="- No user-facing changes in this release."
fi
gh release create "${VERSION}" \
--title "${VERSION}" \
--notes "## What's Changed

${CHANGES}

---
**Released by**: @${{ github.actor }}
**Source commit**: ${{ github.sha }}
**Packages published**:
- \`@dawmatt/api-grade-core@${VERSION#v}\`
- \`@dawmatt/backstage-plugin-api-grade@${VERSION#v}\`
- \`@dawmatt/backstage-plugin-api-grade-backend@${VERSION#v}\`
- \`@dawmatt/api-grade@${VERSION#v}\`"
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.local/
node_modules/
dist/
coverage/
Expand Down
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@dawmatt:registry=https://registry.npmjs.org
9 changes: 8 additions & 1 deletion .specify/extensions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,19 @@ hooks:
description: Auto-commit after task generation
condition: null
after_implement:
- extension: local
command: speckit.quality-gate
enabled: true
optional: false
prompt: Run CI quality gate?
description: Enforce CI quality gate — blocks completion if any stage fails
condition: null
- extension: git
command: speckit.git.commit
enabled: true
optional: true
prompt: Commit implementation changes?
description: Auto-commit after implementation
description: Auto-commit after implementation (runs only if quality gate passes)
condition: null
after_checklist:
- extension: git
Expand Down
2 changes: 1 addition & 1 deletion .specify/feature.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"feature_directory": "specs/004-backstage-api-page"
"feature_directory": "specs/006-publish-npmjs"
}
Loading
Loading