@@ -12,7 +12,7 @@ description: >
1212# Emitter Prep for PR
1313
1414Prepares language emitter changes for pull request by running build/format/lint,
15- creating a changeset with an appropriate message , and pushing to the remote branch.
15+ checking for a changeset, and pushing to the remote branch.
1616
1717** This skill is for language emitter packages only:**
1818
@@ -24,276 +24,121 @@ Do NOT use this skill for core TypeSpec packages (compiler, http, openapi3, etc.
2424
2525## Workflow
2626
27- ### Step 1: Identify changed language emitter packages
27+ ### Step 1: Determine the emitter package
2828
29- Determine which language emitter packages have changes:
29+ Figure out which emitter package the user is working on from context (cwd, recent
30+ changes, or ask). The package will be under ` packages/<package-name>/ ` .
3031
31- ``` bash
32- cd ~ /Desktop/github/typespec
33-
34- # Compare against upstream/main (microsoft/typespec) if available, otherwise main
35- BASE_BRANCH=$( git rev-parse --verify upstream/main 2> /dev/null && echo " upstream/main" || echo " main" )
36-
37- # Filter for language emitter packages only
38- git diff " $BASE_BRANCH " --name-only | grep " ^packages/http-client-" | cut -d' /' -f2 | sort -u
39- ```
40-
41- This filters for ` http-client-python ` , ` http-client-csharp ` , ` http-client-java ` , etc.
42-
43- ### Step 2: Validate each changed emitter package
44-
45- For each changed emitter package (e.g., ` http-client-python ` , ` http-client-csharp ` , ` http-client-java ` ):
32+ ### Step 2: Build, format, and lint the emitter package
4633
4734``` bash
4835cd ~ /Desktop/github/typespec/packages/PACKAGE_NAME
4936
5037# Build
5138npm run build
52- if [ $? -ne 0 ]; then
53- echo " Build failed for PACKAGE_NAME"
54- exit 1
55- fi
5639
57- # Format
40+ # Format (includes both TypeScript and Python formatting)
5841npm run format
59- if [ $? -ne 0 ]; then
60- echo " Format failed for PACKAGE_NAME"
61- exit 1
62- fi
6342
64- # Lint (if available )
65- npm run lint 2> /dev/null || echo " No lint script for PACKAGE_NAME "
43+ # Lint (emitter-only is fine for quick validation )
44+ npm run lint -- --emitter
6645```
6746
68- If any step fails, report the error and stop. Do not proceed to changeset.
69-
70- ### Step 3: Run format and spell check at repo root
47+ If any step fails, report the error and stop. Do not proceed.
7148
72- After validating individual packages, run format and spell check at the repo root:
49+ ### Step 3: Run format at repo root
7350
7451``` bash
7552cd ~ /Desktop/github/typespec
76-
77- # Format all files
7853pnpm format
79-
80- # Spell check
81- pnpm cspell
8254```
8355
84- If spell check fails, either fix the typos or add words to the cspell dictionary.
56+ ** Important:** ` pnpm format ` may touch files outside the emitter package (e.g.,
57+ ` .devcontainer/ ` , other packages). When staging changes in Step 6, ** only stage
58+ files within the emitter package directory** (` packages/PACKAGE_NAME/ ` ) and
59+ ` .chronus/changes/ ` and ` .github/skills/ ` . Discard any formatting changes to
60+ unrelated files with ` git checkout -- <file> ` .
8561
86- ### Step 4: Analyze changes for changeset message
62+ ### Step 4: Check for existing changeset
8763
88- Examine the changes to determine an appropriate changeset message :
64+ Check if a changeset already exists for the current branch :
8965
9066``` bash
9167cd ~ /Desktop/github/typespec
92-
93- # Determine base branch
94- BASE_BRANCH=$( git rev-parse --verify upstream/main 2> /dev/null && echo " upstream/main" || echo " main" )
95-
96- # Get commit messages on this branch
97- git log " $BASE_BRANCH " ..HEAD --oneline
98-
99- # Get changed files
100- git diff " $BASE_BRANCH " --name-only
101-
102- # Get the actual code changes (for understanding intent)
103- git diff " $BASE_BRANCH " --stat
68+ BRANCH=$( git rev-parse --abbrev-ref HEAD)
69+ ls .chronus/changes/ | grep -i " $BRANCH " || echo " NO_CHANGESET"
10470```
10571
106- ### Step 5: Determine changeset parameters
107-
108- Based on the changes, determine:
109-
110- 1 . ** changeKind** - one of:
111- - ` internal ` - Internal changes not user-facing (tests, docs, refactoring)
112- - ` fix ` - Bug fixes (patch version bump)
113- - ` feature ` - New features (minor version bump)
114- - ` deprecation ` - Deprecating existing features (minor version bump)
115- - ` breaking ` - Breaking changes (major version bump)
116- - ` dependencies ` - Dependency bumps (patch version bump)
72+ - If a changeset ** exists** : Skip to Step 6 (no need to create one).
73+ - If ** NO_CHANGESET** : Proceed to Step 5 to create one.
11774
118- 2 . ** packages** - affected packages, e.g.:
119- - ` @typespec/http-client-python `
120- - ` @typespec/http-client-csharp `
121- - ` @typespec/http-client-java `
75+ ### Step 5: Create changeset (only if none exists)
12276
123- 3 . ** message ** - concise description of the change
77+ Ask the user what kind of change this is, or infer from context:
12478
125- ### Step 6: Create changeset file
79+ 1 . ** changeKind** - one of: ` internal ` , ` fix ` , ` feature ` , ` deprecation ` , ` breaking ` , ` dependencies `
80+ 2 . ** message** - concise user-focused description
12681
127- Create a changeset file in ` .chronus/changes/ ` :
82+ Then create the file:
12883
12984``` bash
13085cd ~ /Desktop/github/typespec
131-
132- # Generate filename with timestamp
86+ BRANCH=$( git rev-parse --abbrev-ref HEAD)
13387TIMESTAMP=$( date +" %Y-%m-%d-%H-%M-%S" )
134- FILENAME=" .chronus/changes/BRANCH_NAME-${TIMESTAMP} .md"
88+ FILENAME=" .chronus/changes/${BRANCH} -${TIMESTAMP} .md"
89+ ```
13590
136- cat > " $FILENAME " << ' EOF '
91+ ``` markdown
13792---
13893changeKind: <KIND >
13994packages:
14095 - "<PACKAGE >"
14196---
14297
14398<MESSAGE >
144- EOF
145- ```
146-
147- ### Step 7: Show changes and prompt user
148-
149- Display all changes to the user:
150-
151- ``` bash
152- cd ~ /Desktop/github/typespec
153- git status
154- git diff --stat
15599```
156100
157- Then use AskUserQuestion to confirm:
158-
159- - Show the changeset that will be added
160- - Show the files that will be committed
161- - Show which remote will be used: "Will push to ` origin ` "
162- - Ask: "Do these changes look good to push to origin?"
163-
164- Options:
165-
166- - "Yes, push to origin" - proceed with commit and push to origin
167- - "Push to different remote" - ask which remote to use instead
168- - "Edit changeset" - let user modify the changeset message/kind
169- - "Cancel" - abort without pushing
170-
171- If user selects "Push to different remote", ask which remote name to use and push to that instead of origin.
172-
173- ### Step 8: Commit and push (if approved)
174-
175- If user approves, commit the changes:
101+ ### Step 6: Stage, commit, and push
176102
177103``` bash
178104cd ~ /Desktop/github/typespec
179-
180- # Stage all changes
181105git add -A
182-
183- # Commit with descriptive message
184- git commit -m " $(
185- cat << 'EOF '
186- <COMMIT_MESSAGE>
187-
188- Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
189- EOF
190- ) "
106+ git status
191107```
192108
193- Then push to the user's fork. ** Default to ` origin ` ** , but if the user specified a different remote, use that instead :
109+ Show the user what will be committed and ask for confirmation. Then :
194110
195111``` bash
196- # Get current branch name
197112BRANCH=$( git rev-parse --abbrev-ref HEAD)
113+ git commit -m " <COMMIT_MESSAGE>
198114
199- # Push to origin by default (or user-specified remote)
200- git push -u origin " $BRANCH "
201- ```
202-
203- ### Asking about remote
204-
205- When prompting the user in Step 7, include the remote that will be used:
206-
207- - Show: "Will push to ` origin ` (your fork)"
208- - If the user says to use a different remote (e.g., "push to ` my_fork ` "), use that instead
209-
210- ** Important:** Never push directly to the ` microsoft/typespec ` remote (usually named ` upstream ` ).
211-
212- ## Changeset Message Guidelines
213-
214- Write changeset messages that are:
115+ Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>"
215116
216- 1 . ** User-focused** - Describe the impact on users, not implementation details
217- 2 . ** Concise** - One sentence, starting with a verb (Add, Fix, Update, Remove)
218- 3 . ** Specific** - Mention the feature/fix clearly
219-
220- ### Examples by changeKind:
221-
222- ** internal:**
223-
224- - "Refactor namespace resolution logic for clarity"
225- - "Add mock API tests for paging scenarios"
226- - "Update development tooling and skills"
227-
228- ** fix:**
229-
230- - "Fix incorrect deserialization of nullable enum properties"
231- - "Fix client initialization when using custom endpoints"
232-
233- ** feature:**
117+ # Always push to origin (user's fork), never upstream
118+ git push origin " $BRANCH "
119+ ```
234120
235- - "Add support for XML serialization in request bodies"
236- - "Add ` @clientOption ` decorator for customizing client behavior"
121+ ## Changeset Guidelines
237122
238- ** deprecation: **
123+ ### changeKind reference
239124
240- - "Deprecate ` legacyMode ` option in favor of ` compatibilityMode ` "
125+ - ** internal** : Tests, CI/CD, refactoring, docs, skills — not user-facing
126+ - ** fix** : Bug fixes users would notice
127+ - ** feature** : New user-facing capabilities
128+ - ** deprecation** : Marking something as deprecated
129+ - ** breaking** : Removing or changing behavior incompatibly
130+ - ** dependencies** : Dependency version bumps
241131
242- ** breaking: **
132+ ### Message examples
243133
244- - "Remove deprecated ` v1 ` client generation mode"
245- - "Change default serialization format from XML to JSON"
134+ - ` internal ` : "Improve CI pipeline performance and test infrastructure"
135+ - ` fix ` : "Fix incorrect deserialization of nullable enum properties"
136+ - ` feature ` : "Add support for XML serialization in request bodies"
246137
247- ## Language Emitter Package Names
138+ ### Package names
248139
249140| Folder | Package Name |
250141| -------------------- | ------------------------------ |
251142| ` http-client-python ` | ` @typespec/http-client-python ` |
252143| ` http-client-csharp ` | ` @typespec/http-client-csharp ` |
253144| ` http-client-java ` | ` @typespec/http-client-java ` |
254-
255- ## Notes
256-
257- ### When to use each changeKind
258-
259- - ** internal** : Tests, documentation, refactoring, CI/CD changes, skill updates
260- - ** fix** : Bug fixes that users would notice
261- - ** feature** : New capabilities users can use
262- - ** deprecation** : Marking something as deprecated (still works, but discouraged)
263- - ** breaking** : Removing or changing behavior in incompatible ways
264-
265- ### Multiple packages
266-
267- If changes affect multiple packages ** with the same change kind** , list all of them in a single changeset:
268-
269- ``` yaml
270- packages :
271- - " @typespec/http-client-python"
272- - " @typespec/http-client-csharp"
273- ` ` `
274-
275- **If packages have different change kinds, create separate changeset files for each.** For example, if the PR adds a feature to ` @typespec/http-client-python` and fixes a bug in `@typespec/http-client-csharp`, create two files:
276-
277- ` ` ` yaml
278- # File 1: feature for python
279- changeKind: feature
280- packages:
281- - "@typespec/http-client-python"
282- ` ` `
283-
284- ` ` ` yaml
285- # File 2: fix for csharp
286- changeKind: fix
287- packages:
288- - "@typespec/http-client-csharp"
289- ` ` `
290-
291- # ## Skipping changeset
292-
293- Some changes don't need a changeset :
294-
295- - Changes only to `.github/skills/` (CI will allow this)
296- - Changes only to test files (if marked in `changedFiles` config)
297- - Changes only to markdown files (if marked in `changedFiles` config)
298-
299- Check `.chronus/config.yaml` for `changedFiles` patterns that are excluded.
0 commit comments