Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
33 changes: 25 additions & 8 deletions .claude/skills/review-dep-pr/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ allowed-tools:
- AskUserQuestion
- Agent
- Task
- Skill
---

# Review Dependency PR
Expand All @@ -36,9 +37,11 @@ Comprehensive review of dependency update PRs — whether CI actions, Python pac
4. Also fetch CI status:

```bash
gh pr checks <number> --json name,status,conclusion
gh pr checks <number> --json name,state
```

Note: `gh pr checks` uses `state` (not `status` or `conclusion`). Values: `SUCCESS`, `FAILURE`, `PENDING`, `NEUTRAL`, `SKIPPED`.

5. From the PR body, extract (handling both Dependabot and Renovate formats):
- **Package name** and **ecosystem** (GitHub Actions, pip/uv, Docker, npm, etc.)
- **Version range**: from → to
Expand Down Expand Up @@ -104,6 +107,8 @@ gh api repos/<owner>/<repo>/releases --paginate --jq '.[] | {tag: .tag_name, bod

After fetching, apply semver-aware filtering in your reasoning step: parse each tag into numeric (major, minor, patch) components and select only releases within the from→to range. Do not rely on jq string comparison for version filtering — `"v2.10.0" >= "v2.9.0"` is false lexicographically but true semantically.

**Detect missing intermediate releases:** Dependabot PR bodies often truncate release notes for multi-version jumps. Compare the tags in the from→to range against what's already in the PR body. Fetch individual release notes for any versions NOT covered in the PR body — these may contain important changes (features, deprecations, bugfixes) that were omitted from the truncated view.

### Strategy 3: WebFetch

If the PR body has links to release notes or changelogs, fetch them:
Expand All @@ -115,13 +120,15 @@ If the PR body has links to release notes or changelogs, fetch them:

If release notes are incomplete, search for `"<package> <version> changelog"` or `"<package> migration guide"`.

### For major version bumps: ALWAYS fetch the migration guide
### For major version bumps: check for a migration guide

Major bumps almost always have breaking changes. Search for and fetch:
Major bumps often have breaking changes. Check if a migration guide exists:
- Migration/upgrade guide
- Breaking changes document
- Any "what's new in vN" blog post

If all breaking changes are clearly internal API that we don't import or use (e.g., handler development API when we only configure via YAML), note this and skip the fetch. If any breaking change is ambiguous or potentially affects our usage, ALWAYS fetch and review the migration guide.

### Analysis

For each version in the range, categorize every change as:
Expand Down Expand Up @@ -258,17 +265,27 @@ For each PR based on user's choice:
1. Re-verify CI is passing right before merge (time may have passed since Phase 5):

```bash
gh pr checks <number> --json name,conclusion --jq '.[] | select(.conclusion != "success" and .conclusion != "skipped")'
gh pr checks <number> --json name,state
```

If any checks are not passing, inform the user and switch to the "Fix CI and merge" flow instead.
Inspect the JSON output — all checks should have `state: "SUCCESS"`, `"SKIPPED"`, or `"NEUTRAL"`. Do NOT use jq filters with `!=` (escaping breaks on Windows bash). If any checks are failing, inform the user and switch to the "Fix CI and merge" flow instead.
2. Merge:

```bash
gh pr merge <number> --squash --auto
```

Note: `--auto` may succeed silently with no stdout. Track which path was used: `auto` or `immediate`.

If `--auto` fails (auto-merge not enabled on the repo or branch protection requirements not met), fall back to `gh pr merge <number> --squash` for immediate merge. If that also fails (e.g., required reviews not met), inform the user that manual approval is needed.
3. Verify the merge:

```bash
gh pr view <number> --json state,autoMergeRequest --jq '{state: .state, autoMerge: .autoMergeRequest}'
```

- If **immediate** merge was used: confirm `state` is `MERGED`. If not, inform the user.
- If **auto** merge was enabled: `state` will be `OPEN` with `autoMergeRequest` present (auto-merge is asynchronous — it fires after required checks pass). Inform the user: "Auto-merge has been enabled; the PR will merge automatically when all required checks pass." No immediate state verification needed.

### Improve and merge

Expand Down Expand Up @@ -300,17 +317,17 @@ For each PR based on user's choice:
gh pr close <number> --comment "Skipping: <reason from user>"
```

After all merges complete, if any PRs were merged, remind the user to run `/post-merge-cleanup`.
After all merges complete, if any PRs were merged, automatically run `/post-merge-cleanup` (do NOT just remind the user — execute it).

---

## Rules

- **NEVER skip changelog review** — every dependency update, regardless of type (CI action, Python package, Docker image), gets a full changelog analysis between the old and new versions.
- **Be specific about what affects us** — don't just list changelog items, cross-reference each one against our actual config and code usage.
- **Major version bumps get extra scrutiny** — always look for a migration guide.
- **Major version bumps get extra scrutiny** — check for a migration guide. Always fetch it if breaking changes are ambiguous or potentially affect our usage; skip only when all breaking changes are clearly in internal APIs we don't use.
- **Don't merge with failing CI** — if CI fails, investigate and fix first.
- **Grouped updates (Dependabot groups)**: analyze each package in the group separately, then present as one combined report.
- **Preserve existing config** — when making improvements, don't refactor unrelated config. Only touch what's relevant to the update.
- **If you can't fetch release notes** (private repo, deleted releases, etc.), say so explicitly and recommend the user check manually before merging.
- **After merging**: remind user to run `/post-merge-cleanup` to sync local branches.
- **After merging**: automatically run `/post-merge-cleanup` to sync local branches — do not just remind the user.
12 changes: 10 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,23 @@ jobs:
# Codecov upload is best-effort — CI should not fail on Codecov outages
# or missing tokens. Coverage enforcement is handled by --cov-fail-under.
- name: Upload coverage to Codecov
if: always()
if: ${{ !cancelled() }}
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: coverage.xml
fail_ci_if_error: false

- name: Upload test results to Codecov
if: ${{ !cancelled() }}
uses: codecov/test-results-action@0fa95f0e1eeaafde2c782583b36b28ad0d8c77d3 # v1.2.1
with:
token: ${{ secrets.CODECOV_TOKEN }}
Comment thread
greptile-apps[bot] marked this conversation as resolved.
Comment thread
greptile-apps[bot] marked this conversation as resolved.
files: junit.xml
fail_ci_if_error: false

Comment on lines +87 to +93
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This new Codecov test-results upload step isn’t marked best-effort (unlike the coverage upload above with fail_ci_if_error: false). If Codecov is down or the token is unavailable/empty (common on forks), this step may fail the whole job. Consider making this step non-blocking as well (e.g., continue-on-error: true, and/or skip when secrets.CODECOV_TOKEN is not set, or use an equivalent fail_ci_if_error: false input if supported by this action).

Suggested change
if: ${{ !cancelled() }}
uses: codecov/test-results-action@0fa95f0e1eeaafde2c782583b36b28ad0d8c77d3 # v1.2.1
with:
token: ${{ secrets.CODECOV_TOKEN }}
if: ${{ !cancelled() && secrets.CODECOV_TOKEN != '' }}
continue-on-error: true
uses: codecov/test-results-action@0fa95f0e1eeaafde2c782583b36b28ad0d8c77d3 # v1.2.1
with:
token: ${{ secrets.CODECOV_TOKEN }}

Copilot uses AI. Check for mistakes.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
- name: Upload test results
if: always()
if: ${{ !cancelled() }}
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
with:
name: test-results-${{ matrix.python-version }}
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/pages-preview.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ on:
- "docs/**"
- "site/**"
- "mkdocs.yml"
- "pyproject.toml"
- "uv.lock"
- "src/ai_company/**"
- ".github/workflows/pages-preview.yml"

Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ on:
- "docs/**"
- "site/**"
- "mkdocs.yml"
- "pyproject.toml"
- "uv.lock"
- "src/ai_company/**"
- ".github/workflows/pages.yml"
workflow_dispatch:
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ src/ai_company/
- **Dependabot**: daily uv + github-actions + docker updates, grouped minor/patch, no auto-merge. Use `/review-dep-pr` to review Dependabot PRs before merging
- **Secret scanning**: gitleaks workflow on push/PR + weekly schedule
- **Dependency review**: license allow-list (permissive only), PR comment summaries
- **Coverage**: Codecov integration (replaces artifact-only uploads)
- **Coverage**: Codecov integration — coverage upload via `codecov-action` + test results analytics via `test-results-action` (both best-effort, CI not gated on Codecov availability)
- **Workflow security**: `.github/workflows/zizmor.yml` — zizmor static analysis of GitHub Actions workflows on push to main and PRs (triggers only when workflow files change), SARIF upload to Security tab on push events only (fork PRs lack `security-events: write`)
- **Release**: `.github/workflows/release.yml` — Release Please (Google) auto-creates a release PR on every push to main. Merging the release PR creates a git tag (`vX.Y.Z`) + GitHub Release with changelog. Tag push triggers the Docker workflow to build version-tagged images. Uses `RELEASE_PLEASE_TOKEN` secret (PAT/GitHub App token) so tag creation triggers downstream workflows (GITHUB_TOKEN cannot). Config in `.github/release-please-config.json` and `.github/.release-please-manifest.json`.

Expand Down
Loading