Skip to content

Commit ad105d4

Browse files
iscai-msftCopilot
andcommitted
docs: update http-client-python CONTRIBUTING with end-to-end release workflow
Update the downstream testing and post-release sections to reflect the new CI and regeneration infrastructure: - Branded emitter CI runs automatically on unbranded PRs - Manual regeneration workflow supports both branded/unbranded emitters - Post-release steps for updating azure-sdk-for-python - Generated code location in azure-sdk-for-python Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 694bb79 commit ad105d4

3 files changed

Lines changed: 76 additions & 39 deletions

File tree

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
changeKind: internal
3+
packages:
4+
- "@typespec/http-client-python"
5+
---
6+
7+
Fix transient mypy CI failures on Windows with retry logic and update CONTRIBUTING docs to reflect the new end-to-end release workflow

packages/http-client-python/CONTRIBUTING.md

Lines changed: 43 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -105,37 +105,58 @@ Before creating a pull request:
105105

106106
## Downstream Testing
107107

108-
Due to the integration with `@azure-tools/typespec-python`, we require downstream testing to ensure compatibility.
108+
This package (`@typespec/http-client-python`) is the **unbranded emitter**. It is wrapped by the **branded emitter** (`@azure-tools/typespec-python`), which lives in [Azure/typespec-azure](https://github.com/Azure/typespec-azure/tree/main/packages/typespec-python).
109109

110-
### Automatic Downstream PR Creation
110+
### How CI Works
111111

112-
After your PR is created and CI passes:
112+
When you open a PR against this package:
113113

114-
1. **Get the build artifact URL**:
115-
- In your PR's CI results, click on "5 published; 1 consumed" (or similar)
116-
- Navigate to: `Published artifacts``build_artifacts_python``packages``typespec-http-client-python-x.x.x.tgz`
117-
- Click the three dots and select "Copy download url"
114+
1. **Unbranded emitter CI** runs automatically (build, lint, test, regenerate).
115+
2. **Branded emitter CI** also runs automatically — it builds `@azure-tools/typespec-python` from [`Azure/typespec-azure`](https://github.com/Azure/typespec-azure/tree/main/packages/typespec-python) against your PR's version of `@typespec/http-client-python` to verify compatibility.
118116

119-
2. **Trigger downstream testing**:
120-
- Run [this pipeline](https://dev.azure.com/azure-sdk/internal/_build?definitionId=7257) with:
121-
- `PULL-REQUEST-URL`: Your PR URL from step 1
122-
- `ARTIFACTS_URL`: The artifact URL from step 1
117+
Both must pass before your PR can be merged.
123118

124-
3. **Review downstream changes**:
125-
- The pipeline will create a PR in [autorest.python](https://github.com/Azure/autorest.python)
126-
- Follow the [autorest.python CONTRIBUTING.md](https://github.com/Azure/autorest.python/blob/main/CONTRIBUTING.md) for any additional changes needed
119+
### Manual Regeneration Testing
127120

128-
4. **Merge process**:
129-
- Ensure the downstream PR passes all tests
130-
- Merge your original TypeSpec PR once downstream testing is complete
121+
You can manually trigger the [TypeSpec Python Regenerate Tests](https://github.com/Azure/azure-sdk-for-python/actions/workflows/typespec-python-regenerate.yml) workflow in `azure-sdk-for-python` to regenerate tests with either emitter:
131122

132-
### Post-Release Updates
123+
- **Branded** (`@azure-tools/typespec-python`): Select "branded" and optionally specify a version. If no version is given, it uses the version from [`eng/emitter-package.json`](https://github.com/Azure/azure-sdk-for-python/blob/main/eng/emitter-package.json).
124+
- **Unbranded** (`@typespec/http-client-python`): Select "unbranded" and optionally specify a version. If no version is given, it uses the latest published version on npm.
133125

134-
After your changes are released:
126+
The workflow checks out `microsoft/typespec` (at the ref you specify, defaulting to `main`), builds the regeneration infrastructure, installs the target emitter from npm, and runs the full regeneration.
135127

136-
1. Update the [autorest.python](https://github.com/Azure/autorest.python) repository to use the released version
137-
2. Run `pnpm install` to update dependency mappings
138-
3. Release the autorest emitters with your changes
128+
### Post-Release: Updating azure-sdk-for-python
129+
130+
Once a new version of the branded emitter (`@azure-tools/typespec-python`) is released, follow these steps to update `azure-sdk-for-python`:
131+
132+
1. **Update `eng/emitter-package.json`** in [Azure/azure-sdk-for-python](https://github.com/Azure/azure-sdk-for-python):
133+
134+
Update the `@azure-tools/typespec-python` version to the newly released version:
135+
136+
```json
137+
{
138+
"dependencies": {
139+
"@azure-tools/typespec-python": "<new-version>"
140+
}
141+
}
142+
```
143+
144+
2. **Regenerate config files** using `tsp-client`:
145+
146+
```bash
147+
tsp-client generate-config-files \
148+
--package-json=<path-to-local-typespec-azure>/packages/typespec-python/package.json
149+
```
150+
151+
This updates the `devDependencies` in `eng/emitter-package.json` to match the branded emitter's peer dependencies.
152+
153+
3. **Create a PR** with the updated `eng/emitter-package.json` and submit it to `azure-sdk-for-python`.
154+
155+
4. **Automatic regeneration**: Once the PR merges to `main`, the [TypeSpec Python Regenerate Tests](https://github.com/Azure/azure-sdk-for-python/actions/workflows/typespec-python-regenerate.yml) workflow triggers automatically (it watches for changes to `eng/emitter-package.json`). It regenerates all test code and creates a follow-up PR with the updated generated files.
156+
157+
5. **Generated code location**: The regenerated tests are checked in at [`eng/tools/azure-sdk-tools/emitter/generated/`](https://github.com/Azure/azure-sdk-for-python/tree/main/eng/tools/azure-sdk-tools/emitter/generated) in `azure-sdk-for-python`, split into:
158+
- `azure/` — Tests generated with the branded emitter (Azure SDK specs)
159+
- `unbranded/` — Tests generated with the unbranded emitter (TypeSpec HTTP specs)
139160

140161
## Getting Help
141162

packages/http-client-python/eng/scripts/ci/run_mypy.py

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,27 +26,36 @@ def get_config_file_location():
2626
return os.path.join(os.path.dirname(__file__), "config/mypy.ini")
2727

2828

29-
def _single_dir_mypy(mod):
29+
def _single_dir_mypy(mod, retries=2):
3030
inner_class = get_package_namespace_dir(mod)
3131
if not inner_class:
3232
logging.info(f"No package directory found in {mod}, skipping")
3333
return True
34-
try:
35-
check_call(
36-
[
37-
sys.executable,
38-
"-m",
39-
"mypy",
40-
"--config-file",
41-
get_config_file_location(),
42-
"--ignore-missing",
43-
str(inner_class.absolute()),
44-
]
45-
)
46-
return True
47-
except CalledProcessError as e:
48-
logging.error("{} exited with mypy error {}".format(inner_class.stem, e.returncode))
49-
return False
34+
for attempt in range(1, retries + 2):
35+
try:
36+
check_call(
37+
[
38+
sys.executable,
39+
"-m",
40+
"mypy",
41+
"--config-file",
42+
get_config_file_location(),
43+
"--ignore-missing",
44+
str(inner_class.absolute()),
45+
]
46+
)
47+
return True
48+
except CalledProcessError as e:
49+
if attempt <= retries:
50+
logging.warning(
51+
"{} mypy attempt {} failed (exit {}), retrying...".format(
52+
inner_class.stem, attempt, e.returncode
53+
)
54+
)
55+
else:
56+
logging.error("{} exited with mypy error {}".format(inner_class.stem, e.returncode))
57+
return False
58+
return False
5059

5160

5261
if __name__ == "__main__":

0 commit comments

Comments
 (0)