From d8c1382ac4e2259d04517287591756b5dd9e199e Mon Sep 17 00:00:00 2001 From: Dina Berry Date: Thu, 2 Apr 2026 05:31:52 -0700 Subject: [PATCH 1/3] fix(ci): changelog-gate accepts changesets + CHANGELOG write protection - changelog-gate now passes when .changeset/*.md files are present - New changelog-protection gate blocks non-approved authors from editing CHANGELOG.md directly (approved: bradygaster, bots) - Updated CONTRIBUTING.md with changeset workflow documentation - Prevents merge conflicts when multiple PRs are open Closes #745 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .changeset/fix-changelog-gate.md | 5 +++ .changeset/fix-roster-sync.md | 5 +++ .github/workflows/squad-ci.yml | 61 ++++++++++++++++++++++++++------ CONTRIBUTING.md | 32 ++++++++++++++--- 4 files changed, 89 insertions(+), 14 deletions(-) create mode 100644 .changeset/fix-changelog-gate.md create mode 100644 .changeset/fix-roster-sync.md 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..2455bf590 100644 --- a/.github/workflows/squad-ci.yml +++ b/.github/workflows/squad-ci.yml @@ -211,8 +211,8 @@ 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 a changeset OR CHANGELOG.md is in the diff: + # git diff --name-only ...HEAD | grep -E '^\.changeset/.*\.md$|^CHANGELOG\.md$' # ────────────────────────────────────────────────────────────────────── if: github.event_name == 'pull_request' runs-on: ubuntu-latest @@ -275,17 +275,58 @@ 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. + CHANGESET_ADDED=$(git diff --name-only --diff-filter=AM origin/dev...HEAD -- '.changeset/*.md' | grep -v 'README.md' | head -1) 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' 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" | grep -qw "$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' 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): From 84148f1edd7ac78ee0a48fe90f5226c417111ff6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 2 Apr 2026 12:44:18 +0000 Subject: [PATCH 2/3] fix(ci): address changelog-gate edge cases and approved-authors security - CHANGESET_ADDED: use BASE...HEAD diff with --diff-filter=AM instead of hardcoded origin/dev...HEAD; use precise grep patterns and exclude .changeset/README.md to avoid false-positives from deleted files or repo documentation - approved-authors: replace grep -qw (regex, [bot] chars unsafe) with tr + grep -qxF for exact fixed-string per-line matching - Align npx changeset -> npx changeset add in error messages Agent-Logs-Url: https://github.com/bradygaster/squad/sessions/c82281d6-e434-4f43-96d9-2618923e7c9a Co-authored-by: diberry <41597107+diberry@users.noreply.github.com> --- .github/workflows/squad-ci.yml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/workflows/squad-ci.yml b/.github/workflows/squad-ci.yml index 2455bf590..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 a changeset OR CHANGELOG.md is in the diff: - # git diff --name-only ...HEAD | grep -E '^\.changeset/.*\.md$|^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 @@ -278,7 +277,9 @@ jobs: # 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. - CHANGESET_ADDED=$(git diff --name-only --diff-filter=AM origin/dev...HEAD -- '.changeset/*.md' | grep -v 'README.md' | head -1) + # 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 [ -n "$CHANGESET_ADDED" ]; then @@ -294,7 +295,7 @@ jobs: echo "" echo "::error::No changeset or CHANGELOG.md update found, but SDK/CLI source files were changed." - echo "::error::Preferred: run 'npx changeset' to create a .changeset/*.md file." + 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 @@ -314,13 +315,13 @@ jobs: run: | CHANGED=$(git diff --name-only origin/${{ github.base_ref }}...HEAD | grep '^CHANGELOG.md$' || true) if [ -n "$CHANGED" ]; then - if echo "$APPROVED_AUTHORS" | grep -qw "$PR_AUTHOR"; 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' to add a changeset file instead." + echo "Use 'npx changeset add' to add a changeset file instead." echo "See CONTRIBUTING.md for details." exit 1 fi From 8a55d018aed0d34c6dc5729973fbabf1424c1de0 Mon Sep 17 00:00:00 2001 From: Dina Berry Date: Thu, 2 Apr 2026 09:32:28 -0700 Subject: [PATCH 3/3] ci: retrigger checks