Skip to content

Commit c44767a

Browse files
author
Xiting Zhang
committed
Merge remote-tracking branch 'upstream/main'
2 parents a254ba6 + 173f41c commit c44767a

File tree

130 files changed

+13196
-2691
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

130 files changed

+13196
-2691
lines changed

.vscode/cspell.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,8 @@
197197
"avroencoder",
198198
"Avs",
199199
"azcmagent",
200+
"azpysdk",
201+
"pyenv",
200202
"azsdk",
201203
"azurecr",
202204
"azuremgmtcore",
@@ -245,6 +247,7 @@
245247
"dpkg",
246248
"dtlk",
247249
"dtlksd",
250+
"duckdb",
248251
"DWORD",
249252
"eastus",
250253
"Easm",

CONTRIBUTING.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ We utilize a variety of tools to ensure smooth development, testing, and code qu
1515

1616
- Virtualenv: [Virtualenv](https://virtualenv.pypa.io/en/latest/) is leveraged by Tox to create isolated environments for each test suite, ensuring consistent dependencies and reducing conflicts.
1717

18+
- UV: [UV](https://docs.astral.sh/uv/) is a fast package manager that can manage Python versions, run and install Python packages, and be used instead of pip, virtualenv, and more.
19+
1820
- Pytest: [Pytest](https://docs.pytest.org/en/stable/) is the test framework we use for writing and running our unit tests. It supports fixtures, parameterized tests, and other features that make testing more powerful and flexible.
1921

2022
- Pylint: [Pylint](https://pylint.readthedocs.io/en/stable/) is used for code linting to enforce coding standards and catch potential issues early. Maintaining a consistent code style is important, and Pylint helps achieve that goal.

doc/dev/mgmt/mgmt_release.md

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@
22

33
## General Release Process Overview
44

5-
Once Swagger PR is merged, SDK automation will create pull request to Azure SDK for Python repository, and here are steps that you need to do in order to release a new package:
5+
Once Swagger PR is merged and a release plan/request is submitted, here are steps that you need to do in order to release a new package:
66

7-
- open PR that was merged in swagger repository and find the link to the PR createted in Azure SDK for Python
8-
- reopen generated SDK PR and make sure the CI passes
7+
- create SDK pull request with code generation
8+
- identify and resolve breaking changes
99
- verify that generated code was generated correctly, make sure right version was generated with right configuration
10+
- verify the release notes match actual changes (CHANGELOG.md)
11+
- verify the version accordingly to changes that were made (_version.py)
12+
- generate samples and develop tests
13+
- make sure the CI passes
1014
- merge the PR if everything looks good
11-
- create another PR manually in order to add release notest and update version (this is currently not done by automation)
12-
- generate release notes as described below, verify they match actual changes (HISTORY.rst)
13-
- update version accordingly to changes that were made (version.py)
14-
- merge the PR
1515
- run release pipeline
1616

1717
Once you have a PR that contains accurate with correct tests (or no tests at all, but CI is green), this page explains how to prepare for a release.
@@ -20,8 +20,8 @@ IMPORTANT NOTE: All the commands in this page assumes you have loaded the [dev_s
2020

2121
## Manual generation
2222

23-
If the automation is not doing its job to create an auto PR, Python has a SwaggerToSdk CLI that can be used to generate a specific Readme. You need
24-
a virtual environment loaded with at least `eng/tools/azure-sdk-tools` installed.
23+
If the automation is not doing its job to create an auto PR, Python has a SwaggerToSdk CLI that can be used to generate SDK by a specific Readme. You need
24+
a virtual environment loaded with at least `eng/tools/azure-sdk-tools` installed. And to manually create a package from Typespec, here's the full direction https://github.com/Azure/azure-sdk-for-python/wiki/Generate-Python-Mgmt-SDK-from-Typespec.
2525

2626
```shell
2727
# Using default configuration (this can be a Github raw link)
@@ -43,16 +43,16 @@ If not, you can execute this command (replace the last part by your package name
4343
python -m packaging_tools --build-conf azure-mgmt-web
4444
```
4545

46-
If the file sdk_packaging.toml didn't exist, now one is created with default values. Update this file and update the default values to the one from this service. Once it's done, restart the same script.
46+
If the file pyproject.toml didn't exist, now one is created with default values. Update this file and update the default values to the one from this service. Once it's done, restart the same script.
4747

4848
Your packaging info are up-to-date
4949

5050
## Building the ChangeLog
5151

52-
For all packages, you need to update the `HISTORY.rst` file
52+
For all packages, you need to update the `CHANGELOG.md` file
5353

5454
```
55-
/azure-mgmt-myservice/HISTORY.rst
55+
/azure-mgmt-myservice/CHANGELOG.md
5656
```
5757

5858
For all **autorest generated packages**, there is a tool that allows you to auto-build the ChangeLog.
@@ -71,17 +71,17 @@ python -m packaging_tools.code_report --last-pypi azure-mgmt-trafficmanager
7171
Output will look like this:
7272
```shell
7373
INFO:__main__:Download versions of azure-mgmt-trafficmanager on PyPI
74-
INFO:__main__:Got ['0.30.0rc5', '0.30.0rc6', '0.30.0', '0.40.0', '0.50.0', '0.51.0']
74+
INFO:__main__:Got ['0.30.0rc5', '0.30.0rc6', '0.30.0', '0.40.0', '0.50.0', '0.51.0', '1.0.0b1', '1.0.0', '1.1.0b1', '1.1.0']
7575
INFO:__main__:Only keep last PyPI version
76-
INFO:__main__:Installing version 0.51.0 of azure-mgmt-trafficmanager in a venv
76+
INFO:__main__:Installing version 1.1.0 of azure-mgmt-trafficmanager in a venv
7777
INFO:__main__:Looking for Autorest generated package in azure.mgmt.trafficmanager
7878
INFO:__main__:Found azure.mgmt.trafficmanager
7979
INFO:__main__:Working on azure.mgmt.trafficmanager
80-
INFO:__main__:Report written to sdk/trafficmanager/azure-mgmt-trafficmanager/code_reports/0.51.0/report.json
80+
INFO:__main__:Report written to sdk\trafficmanager\azure-mgmt-trafficmanager\code_reports\1.1.0\report.json
8181
```
8282
8383
Note the output path of the report:
84-
`sdk/trafficmanager/azure-mgmt-trafficmanager/code_reports/0.51.0/report.json`
84+
`sdk\trafficmanager\azure-mgmt-trafficmanager\code_reports\1.1.0\report.json`
8585
8686
#### Build the report from the current code.
8787
@@ -112,10 +112,10 @@ Note the output path of the report:
112112
113113
You call the changelog tool with these report as input:
114114
```shell
115-
python -m packaging_tools.change_log sdk/trafficmanager/azure-mgmt-trafficmanager/code_reports/0.51.0/report.json sdk/trafficmanager/azure-mgmt-trafficmanager/code_reports/latest/report.json
115+
python -m packaging_tools.change_log sdk\trafficmanager\azure-mgmt-trafficmanager\code_reports\1.1.0\report.json sdk/trafficmanager/azure-mgmt-trafficmanager/code_reports/latest/report.json
116116
```
117117
118-
Output will Markdown syntax that you can copy/paste directly into the HISTORY.txt
118+
Output will Markdown syntax that you can copy/paste directly into the CHANGELOG.md
119119
Example:
120120
```shell
121121
**Features**
@@ -145,13 +145,10 @@ You need to check the version in:
145145
146146
Python SDK _strictly_ follows [semver](https://semver.org/). A few notes:
147147
148-
- First release should always use 0.1.0, unless asked explicitly by service team
149-
- If a version is 0.5.2:
150-
- Next breaking / feature version is 0.6.0
151-
- Next bug fix is 0.5.3
148+
- First release should always use 1.0.0b1, unless asked explicitly by service team
152149
- If a version is 2.1.0:
153-
- Next preview breaking is 3.0.0rc1
150+
- Next preview breaking is 2.2.0b1
154151
- Next stable breaking is 3.0.0
155-
- Next preview feature is 2.2.0rc1
152+
- Next preview feature is 2.2.0b1
156153
- Next stable feature is 2.2.0
157-
- Next patch is 2.1.1
154+
- Next patch is 2.1.1

doc/tool_usage_guide.md

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# Tool Usage Guide
2+
3+
As part of shipping SDKs that can be trusted by customers, the azure-sdk-for-python dev team maintains a suite of `checks` that can be utilized by developers to ensure predictable quality measures. These checks help determine whether a package meets the required quality standards for release or needs further work before it can be shipped. These `checks` are implemented in a single entrypoint within the local development package `eng/tools/azure-sdk-tools`. This package provides:
4+
5+
- Templated package generation for mgmt packages
6+
- The test-framework that all packages within this monorepo use (including record/playback integration)
7+
- A ton of CI related tasks and boilerplate
8+
- Static analysis code
9+
10+
A `tool` in this context is merely a single entrypoint provided by the `azpysdk` entrypoint in the `eng/tools/azure-sdk-tools` package.
11+
12+
## Available Tools
13+
14+
This repo is currently migrating all checks from a slower `tox`-based framework, to a lightweight implementation that uses `asyncio` to simultaneously run checks. This tools list is the current set that has been migrated from `tox` to the `azpysdk` entrypoint.
15+
16+
|tool|description|invocation|
17+
|---|---|---|
18+
|`pylint`| Runs `pylint` checks or `next-pylint` checks. (based on presence of `--next` argument) | `azpysdk pylint .` |
19+
|`mypy`| Runs `mypy` checks or `next-mypy` checks. (based on presence of `--next` argument) | `azpysdk mypy --next=True .` |
20+
|`sphinx`| Generates a documentation website for the targeted packages. Runs `sphinx` or `next-sphinx` (based on presence of `--next` argument). | `azpysdk sphinx .` |
21+
|`pyright`| Runs `pyright` checks or `next-pyright` checks. (based on presence of `--next` argument) | `azpysdk pyright .` |
22+
|`black`| Runs `black` checks. | `azpysdk black .` |
23+
|`verifytypes`| Runs `verifytypes` checks. | `azpysdk verifytypes .` |
24+
|`ruff`| Runs `ruff` checks. | `azpysdk ruff .` |
25+
|`import_all`| Installs the package w/ default dependencies, then attempts to `import *` from the base namespace. Ensures that all imports will resolve after a base install and import. | `azpysdk import_all .` |
26+
27+
## Common arguments
28+
29+
### Globbing
30+
The azpysdk is intended to be used from within the azure-sdk-for-python repository. A user can invoke
31+
32+
```
33+
/azure-sdk-for-python/> azpysdk import_all azure-storage* # will run import_all for all packages starting with `azure-storage`
34+
35+
/azure-sdk-for-python/> azpysdk import_all azure-storage-blob,azure-core # invoke import_all for two packages
36+
37+
/azure-sdk-for-python/sdk/core/azure-core/> azpysdk import_all . # invoke import_all for the local package only
38+
```
39+
40+
### Automatically isolating the environment
41+
42+
The targeted tool should be able to run in an isolated environment for a couple reasons:
43+
- When attempting to diagnose an issue, sometimes a user is best served by completely wiping their `venv` and starting over from scratch. Issues may stem from having additional deps downloaded that normally wouldn't be installed with the package.
44+
- In `CI`, we _have_ to run in isolated virtual environments for some checks to allow processes like `multiple pytest` runs to invoke without accidentally stomping on each other's progress or hitting file contention errors. CI passes this flag by default from `dispatch_checks.py`.
45+
46+
To utilize this feature, add `--isolate` to any `azpysdk` invocation:
47+
48+
```bash
49+
/> azpysdk import_all azure-storage-blob --isolate
50+
# will install and run within a venv in `sdk/storage/azure-storage-blob/.venv_import_all/
51+
```
52+
53+
## Prerequisite
54+
55+
- You need to have Python installed
56+
- The monorepo requires a minimum of `python 3.9`, but `>=3.11` is required for the `sphinx` check due to compatibility constraints with external processes.
57+
- You may optionally use the ["uv"](https://docs.astral.sh/uv/) tool, which is fast and handles Python version and venv creation automatically.
58+
59+
## Initial setup
60+
61+
- Go to the folder of the package you're working on, for instance `sdk/contoso/azure-contoso`
62+
63+
### Setup with uv
64+
65+
`uv venv`
66+
67+
```bash
68+
# for WSL
69+
source .venv/bin/activate
70+
71+
# for Windows
72+
.venv\Scripts\activate
73+
```
74+
75+
`uv pip install -r dev_requirements.txt`
76+
77+
### Setup with pip/python
78+
79+
`python -m venv .venv`
80+
81+
```bash
82+
# for WSL
83+
source .venv/bin/activate
84+
85+
# for Windows
86+
.venv\Scripts\activate
87+
```
88+
89+
`pip install -r dev_requirements.txt`
90+
91+
## Using the CLI
92+
93+
```bash
94+
# You can call the command directly if you activated the venv
95+
azpysdk <tool_name>
96+
```
97+
98+
## Advanced scenario
99+
100+
### Using different Python version
101+
102+
You can locally test different Python versions to check compatibility with all the required Python versions.
103+
104+
Note that this is optional, and you can rely on CI to test python versions.
105+
106+
#### With uv
107+
108+
You can specify a Python version upon venv creation:
109+
`uv venv --python 3.11`
110+
111+
#### With Python
112+
113+
You need to install [pyenv](https://github.com/pyenv/pyenv?tab=readme-ov-file#installation), which lets you easily switch between multiple versions of Python.
114+
115+
To switch Python versions:
116+
```
117+
pyenv install 3.10
118+
pyenv global 3.10
119+
```

eng/common/instructions/azsdk-tools/create-release-plan.instructions.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1+
> **Important Note for LLM**
2+
> Backend processes may use Azure DevOps work item data as needed. However, do **not** mention or display the work item link/URL, or any reference to Azure DevOps work item resources directly in conversation with the user.
3+
> All manual updates to an existing release plan must be made through the [Release Planner Tool](https://aka.ms/sdk-release-planner) to ensure proper tracking and validation.
4+
> Only provide release plan details such as **Release Plan Link** and **Release Plan ID** to the user
5+
16
# Release Plan Creation Process
2-
You goal is to create a valid release plan. You must prompt user to provide all required information and all input must match the format and requirement mentioned in step 3 below.
7+
Your goal is to create a valid release plan. You must prompt user to provide all required information and all input must match the format and requirement mentioned in step 3 below.
38
Follow these steps in order to create or manage a release plan for an API specification pull request:
49

510
## Step 1: Validate Prerequisites

eng/tools/azure-sdk-tools/azpysdk/black.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,13 @@ def run(self, args: argparse.Namespace) -> int:
4646
executable, staging_directory = self.get_executable(args.isolate, args.command, sys.executable, package_dir)
4747
logger.info(f"Processing {package_name} for black check")
4848

49+
self.install_dev_reqs(executable, args, package_dir)
50+
4951
# install black
5052
try:
5153
install_into_venv(executable, [f"black=={BLACK_VERSION}"], package_dir)
5254
except CalledProcessError as e:
53-
logger.error("Failed to install black:", e)
55+
logger.error(f"Failed to install black: {e}")
5456
return e.returncode
5557

5658
logger.info(f"Running black against {package_name}")

eng/tools/azure-sdk-tools/azpysdk/import_all.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ def run(self, args: argparse.Namespace) -> int:
5555
pkg = parsed.folder
5656
executable, staging_directory = self.get_executable(args.isolate, args.command, sys.executable, pkg)
5757

58+
self.install_dev_reqs(executable, args, pkg)
59+
5860
create_package_and_install(
5961
distribution_directory=staging_directory,
6062
target_setup=pkg,

eng/tools/azure-sdk-tools/azpysdk/main.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,16 @@
1515
from .whl import whl
1616
from .import_all import import_all
1717
from .mypy import mypy
18+
from .next_mypy import next_mypy
1819
from .pylint import pylint
20+
from .next_pylint import next_pylint
1921
from .sphinx import sphinx
22+
from .next_sphinx import next_sphinx
2023
from .black import black
24+
from .pyright import pyright
25+
from .next_pyright import next_pyright
26+
from .ruff import ruff
27+
from .verifytypes import verifytypes
2128

2229
from ci_tools.logging import configure_logging, logger
2330

@@ -75,10 +82,17 @@ def build_parser() -> argparse.ArgumentParser:
7582
whl().register(subparsers, [common])
7683
import_all().register(subparsers, [common])
7784
mypy().register(subparsers, [common])
85+
next_mypy().register(subparsers, [common])
7886
pylint().register(subparsers, [common])
87+
next_pylint().register(subparsers, [common])
7988
sphinx().register(subparsers, [common])
89+
next_sphinx().register(subparsers, [common])
8090
black().register(subparsers, [common])
81-
91+
pyright().register(subparsers, [common])
92+
next_pyright().register(subparsers, [common])
93+
ruff().register(subparsers, [common])
94+
verifytypes().register(subparsers, [common])
95+
8296
return parser
8397

8498
def main(argv: Optional[Sequence[str]] = None) -> int:

eng/tools/azure-sdk-tools/azpysdk/mypy.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
PYTHON_VERSION = "3.9"
1818
MYPY_VERSION = "1.14.1"
19-
2019
ADDITIONAL_LOCKED_DEPENDENCIES = [
2120
"types-chardet==5.0.4.6",
2221
"types-requests==2.31.0.6",
@@ -68,7 +67,7 @@ def run(self, args: argparse.Namespace) -> int:
6867
else:
6968
install_into_venv(executable, [f"mypy=={MYPY_VERSION}"] + additional_requirements, package_dir)
7069
except CalledProcessError as e:
71-
logger.error("Failed to install mypy:", e)
70+
logger.error(f"Failed to install mypy: {e}")
7271
return e.returncode
7372

7473
logger.info(f"Running mypy against {package_name}")
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import argparse
2+
3+
from typing import Optional, List
4+
5+
from .mypy import mypy
6+
7+
class next_mypy(mypy):
8+
def __init__(self):
9+
super().__init__()
10+
11+
def register(self, subparsers: "argparse._SubParsersAction", parent_parsers: Optional[List[argparse.ArgumentParser]] = None) -> None:
12+
"""Register the next-mypy check. The next-mypy check installs the next version of mypy and runs mypy against the target package.
13+
"""
14+
parents = parent_parsers or []
15+
p = subparsers.add_parser("next-mypy", parents=parents, help="Run the mypy check with the next version of mypy")
16+
p.set_defaults(func=self.run)
17+
18+
def run(self, args: argparse.Namespace) -> int:
19+
"""Run the next-mypy check command."""
20+
args.next = True
21+
return super().run(args)
22+

0 commit comments

Comments
 (0)