Skip to content

Commit 2a0a1d2

Browse files
markushiclaude
andcommitted
meta: Keep custom skills alongside dotagents-managed ones
Use a nested .gitignore in .claude/skills/ to ignore dotagents-managed skills while preserving repo-specific custom skills (create-java-pr, test). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 3cc54d5 commit 2a0a1d2

File tree

4 files changed

+277
-1
lines changed

4 files changed

+277
-1
lines changed

.claude/skills/.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Ignore dotagents-managed skills (synced from agents.toml)
2+
*
3+
# Keep custom repo-specific skills
4+
!.gitignore
5+
!create-java-pr/
6+
!create-java-pr/**
7+
!test/
8+
!test/**
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
---
2+
name: create-java-pr
3+
description: Create a pull request in sentry-java. Use when asked to "create pr", "prepare pr", "prep pr", "open pr", "ready for pr", "prepare for review", "finalize changes". Handles branch creation, code formatting, API dump, committing, pushing, PR creation, changelog, and stacked PRs.
4+
---
5+
6+
# Create Pull Request (sentry-java)
7+
8+
Prepare local changes and create a pull request for the sentry-java repo.
9+
10+
**Required reading:** Before proceeding, read `.cursor/rules/pr.mdc` for the full PR and stacked PR workflow details. That file is the source of truth for PR conventions, stack comment format, branch naming, and merge strategy.
11+
12+
## Step 0: Determine PR Type
13+
14+
Ask the user (or infer from context) whether this is:
15+
16+
- **Standalone PR** — a regular PR targeting `main`. Follow Steps 1–6 as written.
17+
- **First PR of a new stack** — ask for a topic name (e.g. "Global Attributes"). Create a collection branch from `main`, then branch the first PR off it. The first PR targets the collection branch.
18+
- **Next PR in an existing stack** — identify the previous stack branch and topic. This PR targets the previous stack branch.
19+
20+
If the user mentions "stack", "stacked PR", or provides a topic name with a number (e.g. `[Topic 2]`), treat it as a stacked PR. See `.cursor/rules/pr.mdc` § "Stacked PRs" for full details.
21+
22+
## Step 1: Ensure Feature Branch
23+
24+
```bash
25+
git branch --show-current
26+
```
27+
28+
If on `main` or `master`, create and switch to a new branch:
29+
30+
```bash
31+
git checkout -b <type>/<short-description>
32+
```
33+
34+
Derive the branch name from the changes being made. Use `feat/`, `fix/`, `ref/`, etc. matching the commit type conventions.
35+
36+
**For stacked PRs:** For the first PR in a new stack, first create and push the collection branch (see `.cursor/rules/pr.mdc` § "Creating the Collection Branch"), then branch the PR off it. For subsequent PRs, branch off the previous stack branch. Use the naming conventions from `.cursor/rules/pr.mdc` § "Branch Naming".
37+
38+
**CRITICAL: Never merge, fast-forward, or push commits into the collection branch.** It stays at its initial position until the user merges stack PRs through GitHub. Updating it will auto-merge and destroy the entire PR stack.
39+
40+
## Step 2: Format Code and Regenerate API Files
41+
42+
```bash
43+
./gradlew spotlessApply apiDump
44+
```
45+
46+
This is **required** before every PR in this repo. It formats all Java/Kotlin code via Spotless and regenerates the `.api` binary compatibility files.
47+
48+
If the command fails, diagnose and fix the issue before continuing.
49+
50+
## Step 3: Commit Changes
51+
52+
Check for uncommitted changes:
53+
54+
```bash
55+
git status --porcelain
56+
```
57+
58+
If there are uncommitted changes, invoke the `sentry-skills:commit` skill to stage and commit them following Sentry conventions.
59+
60+
**Important:** When staging, ignore changes that are only relevant for local testing and should not be part of the PR. Common examples:
61+
62+
| Ignore Pattern | Reason |
63+
|---|---|
64+
| Hardcoded booleans flipped for testing | Local debug toggles |
65+
| Sample app config changes (`sentry-samples/`) | Local testing configuration |
66+
| `.env` or credentials files | Secrets |
67+
68+
Restore these files before committing:
69+
70+
```bash
71+
git checkout -- <file-to-restore>
72+
```
73+
74+
## Step 4: Push the Branch
75+
76+
```bash
77+
git push -u origin HEAD
78+
```
79+
80+
If the push fails due to diverged history, ask the user how to proceed rather than force-pushing.
81+
82+
## Step 5: Create PR
83+
84+
Invoke the `sentry-skills:create-pr` skill to create a draft PR. When providing the PR body, use the repo's PR template structure from `.github/pull_request_template.md`:
85+
86+
```
87+
## :scroll: Description
88+
<Describe the changes in detail>
89+
90+
## :bulb: Motivation and Context
91+
<Why is this change required? What problem does it solve?>
92+
93+
## :green_heart: How did you test it?
94+
<Describe how you tested>
95+
96+
## :pencil: Checklist
97+
- [ ] I added GH Issue ID _&_ Linear ID
98+
- [ ] I added tests to verify the changes.
99+
- [ ] No new PII added or SDK only sends newly added PII if `sendDefaultPII` is enabled.
100+
- [ ] I updated the docs if needed.
101+
- [ ] I updated the wizard if needed.
102+
- [ ] Review from the native team if needed.
103+
- [ ] No breaking change or entry added to the changelog.
104+
- [ ] No breaking change for hybrid SDKs or communicated to hybrid SDKs.
105+
106+
## :crystal_ball: Next steps
107+
```
108+
109+
Fill in each section based on the changes being PR'd. Check any checklist items that apply.
110+
111+
**For stacked PRs:**
112+
113+
- Pass `--base <previous-stack-branch>` so the PR targets the previous branch (first PR in a stack targets the collection branch).
114+
- Use the stacked PR title format: `<type>(<scope>): [<Topic> <N>] <Subject>` (see `.cursor/rules/pr.mdc` § "PR Title Naming").
115+
- Include the stack list at the top of the PR body, before the `## :scroll: Description` section (see `.cursor/rules/pr.mdc` § "Stack List in PR Description" for the format).
116+
- Add a merge method reminder at the very end of the PR body (see `.cursor/rules/pr.mdc` § "Stack List in PR Description" for the exact text). This only applies to stack PRs, not the collection branch PR.
117+
118+
Then continue to Step 5.5 (stacked PRs only) or Step 6.
119+
120+
## Step 5.5: Update Stack List on All PRs (stacked PRs only)
121+
122+
Skip this step for standalone PRs.
123+
124+
After creating the PR, update the PR description on **every other PR in the stack — including the collection branch PR** — so all PRs have the same up-to-date stack list. Follow the format and commands in `.cursor/rules/pr.mdc` § "Stack List in PR Description".
125+
126+
**Important:** When updating PR bodies, never use shell redirects (`>`, `>>`) or pipes (`|`) or compound commands (`&&`). These create compound shell expressions that won't match permission patterns. Instead:
127+
- Use `gh pr view <NUMBER> --json body --jq '.body'` to get the body (output returned directly)
128+
- Use the `Write` tool to save it to a temp file
129+
- Use the `Edit` tool to modify the temp file
130+
- Use `gh pr edit <NUMBER> --body-file /tmp/pr-body.md` to update
131+
132+
## Step 6: Update Changelog
133+
134+
First, determine whether a changelog entry is needed. **Skip this step** (and go straight to "No changelog needed" below) if the changes are not user-facing, for example:
135+
136+
- Test-only changes (new tests, test refactors, test fixtures)
137+
- CI/CD or build configuration changes
138+
- Documentation-only changes
139+
- Code comments or formatting-only changes
140+
- Internal refactors with no behavior change visible to SDK users
141+
- Sample app changes
142+
143+
If unsure, ask the user.
144+
145+
### If changelog is needed
146+
147+
Add an entry to `CHANGELOG.md` under the `## Unreleased` section.
148+
149+
#### Determine the subsection
150+
151+
| Change Type | Subsection |
152+
|---|---|
153+
| New feature | `### Features` |
154+
| Bug fix | `### Fixes` |
155+
| Refactoring, internal cleanup | `### Internal` |
156+
| Dependency update | `### Dependencies` |
157+
158+
Create the subsection under `## Unreleased` if it does not already exist.
159+
160+
#### Entry format
161+
162+
```markdown
163+
- <Short description of the change> ([#<PR_NUMBER>](https://github.com/getsentry/sentry-java/pull/<PR_NUMBER>))
164+
```
165+
166+
Use the PR number returned by `sentry-skills:create-pr`. Match the style of existing entries — sentence case, ending with the PR link, no trailing period.
167+
168+
#### Commit and push
169+
170+
Stage `CHANGELOG.md`, commit with message `changelog`, and push:
171+
172+
```bash
173+
git add CHANGELOG.md
174+
git commit -m "changelog"
175+
git push
176+
```
177+
178+
### No changelog needed
179+
180+
If no changelog entry is needed, add `#skip-changelog` to the PR description to disable the changelog CI check:
181+
182+
1. Get the current body: `gh pr view <PR_NUMBER> --json body --jq '.body'`
183+
2. Use the `Write` tool to save the output to `/tmp/pr-body.md`, appending `\n#skip-changelog\n` at the end
184+
3. Update: `gh pr edit <PR_NUMBER> --body-file /tmp/pr-body.md`

.claude/skills/test/SKILL.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
---
2+
name: test
3+
description: Run tests for a specific SDK module. Use when asked to "run tests", "test module", "run unit tests", "run system tests", "run e2e tests", or test a specific class. Auto-detects unit vs system tests. Supports interactive mode.
4+
allowed-tools: Bash, Read, Glob, AskUserQuestion
5+
argument-hint: [interactive] <module-name-or-file-path> [test-class-filter]
6+
---
7+
8+
# Run Tests
9+
10+
Run tests for a specific module. Auto-detects whether to run unit tests or system tests.
11+
12+
## Step 0: Check for Interactive Mode
13+
14+
If `$ARGUMENTS` starts with `interactive` (e.g., `/test interactive sentry ScopesTest`), enable interactive mode. Strip the `interactive` keyword from the arguments before proceeding.
15+
16+
In interactive mode, use AskUserQuestion at decision points as described in the steps below.
17+
18+
## Step 1: Parse the Argument
19+
20+
The argument can be either:
21+
- A **file path** (e.g., `@sentry/src/test/java/io/sentry/ScopesTest.kt`)
22+
- A **module name** (e.g., `sentry-android-core`, `sentry-samples-spring-boot-4`)
23+
- A **module name + test filter** (e.g., `sentry ScopesTest`)
24+
25+
Extract the module name and optional test class filter from the argument.
26+
27+
**Interactive mode:** If the test filter is ambiguous (e.g., matches multiple test classes across modules), use AskUserQuestion to let the user pick which test class(es) to run.
28+
29+
## Step 2: Detect Test Type
30+
31+
| Signal | Test Type |
32+
|--------|-----------|
33+
| Path contains `sentry-samples/` | System test |
34+
| Module name starts with `sentry-samples-` | System test |
35+
| Everything else | Unit test |
36+
37+
## Step 3a: Run Unit Tests
38+
39+
Determine the Gradle test task:
40+
41+
| Module Pattern | Test Task |
42+
|---------------|-----------|
43+
| `sentry-android-*` | `testDebugUnitTest` |
44+
| `sentry-compose*` | `testDebugUnitTest` |
45+
| `*-android` | `testDebugUnitTest` |
46+
| Everything else | `test` |
47+
48+
**Interactive mode:** Before running, read the test class file and use AskUserQuestion to ask:
49+
- "Run all tests in this class, or a specific method?" — list the test method names as options.
50+
51+
If the user picks a specific method, use `--tests="*ClassName.methodName"` as the filter.
52+
53+
With a test class filter:
54+
```bash
55+
./gradlew ':<module>:<task>' --tests="*<filter>*" --info
56+
```
57+
58+
Without a filter:
59+
```bash
60+
./gradlew ':<module>:<task>' --info
61+
```
62+
63+
## Step 3b: Run System Tests
64+
65+
System tests require the Python-based test runner which manages a mock Sentry server and sample app lifecycle.
66+
67+
1. Ensure the Python venv exists:
68+
```bash
69+
test -d .venv || make setupPython
70+
```
71+
72+
2. Extract the sample module name. For file paths like `sentry-samples/<sample-module>/src/...`, the sample module is the directory name (e.g., `sentry-samples-spring`).
73+
74+
3. Run the system test:
75+
```bash
76+
.venv/bin/python test/system-test-runner.py test --module <sample-module>
77+
```
78+
79+
This starts the mock Sentry server, starts the sample app (Spring Boot/Tomcat/CLI), runs tests via `./gradlew :sentry-samples:<sample-module>:systemTest`, and cleans up afterwards.
80+
81+
## Step 4: Report Results
82+
83+
Summarize the test outcome:
84+
- Total tests run, passed, failed, skipped
85+
- For failures: show the failing test name and the assertion/error message

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,3 @@ spy.log
3737
# Auto-generated by dotagents — do not commit these files.
3838
agents.lock
3939
.agents/.gitignore
40-
.claude/skills/

0 commit comments

Comments
 (0)