diff --git a/.changeset/fix-changelog-gate.md b/.changeset/fix-changelog-gate.md new file mode 100644 index 000000000..1d84acec2 --- /dev/null +++ b/.changeset/fix-changelog-gate.md @@ -0,0 +1,5 @@ +--- +'@bradygaster/squad-cli': patch +--- + +Fix changelog-gate CI to accept .changeset/ files as alternative to direct CHANGELOG.md edits diff --git a/.changeset/fix-roster-sync.md b/.changeset/fix-roster-sync.md new file mode 100644 index 000000000..2fd31a766 --- /dev/null +++ b/.changeset/fix-roster-sync.md @@ -0,0 +1,5 @@ +--- +'@bradygaster/squad-sdk': patch +--- + +Sync squad.agent.md roster when agents added to team.md diff --git a/.github/workflows/squad-ci.yml b/.github/workflows/squad-ci.yml index 85819ab24..a7e7b9d0b 100644 --- a/.github/workflows/squad-ci.yml +++ b/.github/workflows/squad-ci.yml @@ -211,8 +211,7 @@ jobs: # 1. Identify the merge-base: git merge-base dev HEAD # 2. Check for SDK/CLI source changes: # git diff --name-only ...HEAD | grep -E '^packages/squad-(sdk|cli)/src/' - # 3. If any match, verify CHANGELOG.md is also in the diff: - # git diff --name-only ...HEAD | grep -E '^CHANGELOG\.md$' + # 3. If any match, verify an Added/Modified .changeset/*.md (excluding README) OR CHANGELOG.md: # ────────────────────────────────────────────────────────────────────── if: github.event_name == 'pull_request' runs-on: ubuntu-latest @@ -275,17 +274,60 @@ jobs: echo "SDK/CLI source files changed:" echo "$SDK_CLI_CHANGED" - # Regex: ^CHANGELOG\.md$ — exact match on root CHANGELOG.md only + # Accept EITHER a .changeset/*.md file OR a direct CHANGELOG.md edit. + # Changesets are the preferred workflow — they prevent merge conflicts + # when multiple PRs are open simultaneously. + # Use --diff-filter=AM to count only Added/Modified files (not deletions), + # and exclude .changeset/README.md which is repo documentation, not a changeset. + CHANGESET_ADDED=$(git diff --diff-filter=AM --name-only "$BASE"..."$HEAD" | grep -E '^\.changeset/[^/]+\.md$' | grep -vxF '.changeset/README.md' || true) CHANGELOG_CHANGED=$(echo "$CHANGED" | grep -E '^CHANGELOG\.md$' || true) - if [ -z "$CHANGELOG_CHANGED" ]; then - echo "" - echo "::error::CHANGELOG.md was not updated but SDK/CLI source files were changed." - echo "::error::Please add a CHANGELOG.md entry describing your changes." - echo "::error::If this is intentional, add the 'skip-changelog' label to your PR." - exit 1 + + if [ -n "$CHANGESET_ADDED" ]; then + echo "Changeset file(s) detected -- gate passed" + echo "$CHANGESET_ADDED" + exit 0 fi - echo "CHANGELOG.md updated -- gate passed" + if [ -n "$CHANGELOG_CHANGED" ]; then + echo "CHANGELOG.md updated -- gate passed" + exit 0 + fi + + echo "" + echo "::error::No changeset or CHANGELOG.md update found, but SDK/CLI source files were changed." + echo "::error::Preferred: run 'npx changeset add' to create a .changeset/*.md file." + echo "::error::Alternative: edit CHANGELOG.md directly." + echo "::error::Escape hatch: add the 'skip-changelog' label to your PR." + exit 1 + + changelog-protection: + name: CHANGELOG Write Protection + runs-on: ubuntu-latest + if: github.event_name == 'pull_request' + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Check CHANGELOG.md modifications + env: + APPROVED_AUTHORS: 'bradygaster github-actions[bot] copilot-swe-agent[bot]' + PR_AUTHOR: ${{ github.event.pull_request.user.login }} + run: | + CHANGED=$(git diff --name-only origin/${{ github.base_ref }}...HEAD | grep '^CHANGELOG.md$' || true) + if [ -n "$CHANGED" ]; then + if echo "$APPROVED_AUTHORS" | tr ' ' '\n' | grep -qxF "$PR_AUTHOR"; then + echo "✅ $PR_AUTHOR is approved to modify CHANGELOG.md" + else + echo "❌ $PR_AUTHOR is not approved to modify CHANGELOG.md directly" + echo "" + echo "CHANGELOG.md is managed by the release process." + echo "Use 'npx changeset add' to add a changeset file instead." + echo "See CONTRIBUTING.md for details." + exit 1 + fi + else + echo "✅ CHANGELOG.md not modified" + fi exports-map-check: # ── Local testing ────────────────────────────────────────────────────── diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7207345a0..e3d7ee08d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -203,9 +203,11 @@ npm unlink -w packages/squad-cli Squad uses [@changesets/cli](https://github.com/changesets/changesets) for independent package versioning. +**When your PR changes SDK or CLI source files** (`packages/squad-sdk/src/` or `packages/squad-cli/src/`), add a changeset file instead of editing `CHANGELOG.md` directly. Changesets prevent merge conflicts when multiple PRs are open simultaneously and are the preferred workflow. + ### Adding a Changeset -Before your PR is merged, add a changeset describing your changes: +**Option A — Interactive (recommended):** ```bash npx changeset add @@ -218,17 +220,39 @@ This prompts: Creates a file in `.changeset/` that's merged with your PR. -### Example Changeset +**Option B — Manual:** + +Create a file at `.changeset/your-change-name.md` with frontmatter specifying the package and bump type, followed by a description: ```markdown --- -"@bradygaster/squad-sdk": patch +'@bradygaster/squad-cli': patch +--- + +Fix help text rendering for the status command +``` + +### Changeset Format + +The frontmatter lists each affected package and its semver bump type. The body is a human-readable description that will appear in the generated CHANGELOG: + +```markdown +--- +"@bradygaster/squad-sdk": minor "@bradygaster/squad-cli": patch --- -Update help text and README for npm distribution. Add squad status command to docs. +Add streaming support to agent orchestration. Update CLI to display stream progress. ``` +### CI Changelog Gate + +The `changelog-gate` CI check enforces that PRs touching SDK/CLI source files include either: +- A `.changeset/*.md` file (preferred), **or** +- A direct `CHANGELOG.md` edit (backward-compatible) + +If neither is present, the check fails. You can bypass it with the `skip-changelog` label. + ### Release Workflow The team runs changesets on the `dev` branch (via GitHub Actions):