Skip to content

Commit bd332a0

Browse files
authored
Updating instructions (#41249)
* wording * wording of mcp server * this? * update tox * stdin issue with tox * try to do the same for tsp-client * needs root dir
1 parent 3e7b7d4 commit bd332a0

File tree

4 files changed

+230
-84
lines changed

4 files changed

+230
-84
lines changed

.github/copilot-instructions.md

Lines changed: 86 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,44 +5,102 @@
55
- DO check this [website](https://azure.github.io/azure-sdk/python_design.html), and link to pages found there, if possible, when asked about guidelines, or guidance on how to write SDKs. The general guidelines for SDK in this repo are defined there.
66
- DO ensure folks have the appropriate setup when working with this repository. Use the verify_setup tool in the azure-sdk-validation server.
77

8-
When someone asks to run validation on their library, ask them what supported environments they would like to run, such as pylint or mypy. Use the tox tool to run these.
98

109
# Generating an SDK From TypeSpec
1110

11+
## Agent Context
12+
- Check if there are any TypeSpec project paths in the context. If there are, use those paths to locally generate the SDK from the tsp-config.yaml file. If there
13+
are no TypeSpec project paths in the context, ask the user for the path to the tsp-config.yaml file. If the user does not have a path, ask them to provide one.
1214

15+
## Prerequisites
16+
- The user should have a GitHub account and be logged in to GitHub using the GitHub CLI `gh auth login`.
17+
- The user should have a GitHub Personal Access Token (PAT) with the `repo` scope.
1318

14-
Initialize and validate a TypeSpec client library for Azure SDK for Python. Please:
19+
## Basic Rules:
20+
### When running tsp-client commands:
21+
- If syncing from a local repo, do not grab a commit hash.
22+
- Do not manually create directories. The command will create the directories for you.
23+
- If asked to sync or generate `package-name` we need to find the path to the package's tsp-location.yaml
24+
in the azure-sdk-for-python repo and run the command in the same directory.
25+
- If provided a url to a tspconfig.yaml ensure it has the most recent commit hash of the tspconfig.yaml file
26+
instead of a branch name like `main`. If the url does not have a commit hash, use the GitHub API to get the most recent commit hash of the tspconfig.yaml file.
27+
If you are unable to do this, ask the user to provide the correct url.
28+
`curl -s "https://api.github.com/repos/Azure/azure-rest-api-specs/commits?path=,path to tspconfig.yaml>&per_page=1"`
29+
- Ensure that node, python, tox, and the required dependencies are installed in your environment (@azure-tools/typespec-client-generator-cli)
1530

16-
1. If the typespec mcp tool is available use that for generating or initializing. If asked to update changes from local spec repo, lets find the path to that local azure-rest-api-specs repo for our tools. Otherwise please follow the instructions below to generate an SDK from TypeSpec.
17-
- Ensure that node, python, and the required dependencies are installed in your environment (@azure-tools/typespec-client-generator-cli)
18-
- If provided a url to a tspconfig.yaml ensure it has the most recent commit hash of the tspconfig.yaml file instead of a branch name like `main`. If the url does not have a commit hash, use the GitHub API to get the most recent commit hash of the tspconfig.yaml file. If you are unable to do this, ask the user to provide the correct url. `curl -s "https://api.github.com/repos/Azure/azure-rest-api-specs/commits?path=,path to tspconfig.yaml>&per_page=1"` helpful.
19-
- If prompted to initialize the SDK from a url or a local repo use the command `npx @azure-tools/typespec-client-generator-cli init --tsp-config [URL or local azure-rest-api-specs path to tspconfig.yaml]`. The tsp-client init command runs sync and generate under the hood, so generation is complete after the init concludes. If the tspconfig.yaml value is a path to a local file, you can mention that the user will have to populate the values in tsp-location.yaml themselves.
20-
- If prompted to update the SDK use the command `npx @azure-tools/typespec-client-generator-cli update`.
21-
- If prompted to generate the SDK use the command `npx @azure-tools/typespec-client-generator-cli generate`.
22-
- If prompted to sync the SDK use the command `npx @azure-tools/typespec-client-generator-cli sync`.
23-
- If prompted to sync with local code use the command `npx @azure-tools/typespec-client-generator-cli sync --local-spec-repo [path to local azure-rest-api-specs repo]`.
24-
- If syncing from a local repo, do not grab a commit hash.
25-
- Do not manually create directories. The command will create the directories for you.
26-
- If asked to sync or generate `package-name` we need to find the path to the package's tsp-location.yaml in the azure-sdk-for-python repo and run the command in the same directory.
2731

28-
2. After generation is complete, validate the output by:
29-
- Installing the newly generated package and its dev_requirements in a .venv and installing tox.
30-
- Running pylint validation using tox: `tox -e pylint -c [path to tox.ini] --root .`. Or use the tox mcp tool from the azure-sdk-validation server.
31-
- Running mypy type checking using tox: `tox -e mypy -c [path to tox.ini] --root .`. Or use the tox mcp tool from the azure-sdk-validation server.
32-
- Running pyright validation using tox: `tox -e pyright -c [path to tox.ini] --root .`. Or use the tox mcp tool from the azure-sdk-validation server.
33-
- Running verifytypes validation using tox: `tox -e verifytypes -c [path to tox.ini] --root .`. Or use the tox mcp tool from the azure-sdk-validation server.
34-
35-
3. If any errors or warnings are found, after running all validation checks provide guidance on fixing them following Azure SDK best practices.
32+
## Steps to Generate:
3633

37-
4. After the above steps, let's use the GitHub mcp tool to create a pull request with the changes. The pull request should include:
38-
- A title that describes the changes made.
39-
- A description that includes the following:
40-
- A summary of the changes made.
41-
- A list of any issues or warnings found during validation and how they were fixed.
42-
- Any additional notes or comments about the changes made.
34+
### Step 1: Validate the correct environment is set up
35+
- Check if the user has the correct environment set up. If not, guide them to set it up.
36+
- Using the `verify_setup` tool in the azure-sdk-validation server is a good way to do this.
4337

44-
Please use Python 3.9 for compatibility, and refer to the Azure SDK design guidelines (https://azure.github.io/azure-sdk/python_design.html) for any implementation decisions.
38+
### Step 2: Run the correct tsp-client command(s):
39+
- The typspec-python mcp server tools should be used to run the commands.
40+
- If any of the commands fail, check the error message and guide the user to fix the issue.
41+
- If a command fails due to a TypeSpec error, direct the user back to the TypeSpec to fix the error.
42+
- If the user is generating a new package, ensure that the package name is valid and follows the naming conventions for Python packages.
4543

44+
### Step 3: Validate the generated SDK and Fix the issues
45+
- Installing the newly generated package and its dev_requirements in a .venv and installing tox.
46+
- Use the tox mcp tool from the azure-sdk-validation server to run the following validations when possible:
47+
- Running pylint validation using tox: `tox -e pylint -c [path to tox.ini] --root .`
48+
- Running mypy type checking using tox: `tox -e mypy -c [path to tox.ini] --root .`
49+
- Running pyright validation using tox: `tox -e pyright -c [path to tox.ini] --root .`
50+
- Running verifytypes validation using tox: `tox -e verifytypes -c [path to tox.ini] --root .`
51+
- Fix issues found during validation.
52+
- If there are any issues that cannot be fixed, please ask the user to fix them and then come back to proceed with the next step.
53+
54+
### Step 4: Post-Processing of the SDK
55+
- Create a CHANGELOG.md entry for the changes made. If there is no CHANGELOG.md file, create one in the root directory of the package. If the package version is not correct, update it in _version.py and the CHANGELOG entry.
56+
- Confirm that the package version in the most recent CHANGELOG entry is correct based on the API spec version and the last released package version.
57+
58+
The CHANGELOG entry should look like:
59+
```markdown
60+
# Release History
61+
62+
## 1.0.0 (YYYY-MM-DD)
63+
64+
### Features Added
65+
- Added a new feature to do X.
66+
67+
### Breaking Changes
68+
- Changed the way Y is done, which may break existing code that relies on the old behavior.
69+
70+
### Bugs Fixed
71+
- Fixed a bug that caused Z to not work as expected.
72+
73+
### Other Changes
74+
- Updated the documentation to reflect the new changes.
75+
- Refactored the code to improve readability and maintainability.
76+
```
77+
78+
### Step 5: Commit and Push the Changes
79+
- Display the list of changed files in the repository and prompt the user to confirm the changes. Ignore uncommitted changes in .github and .vscode folders.
80+
- If the user confirms:
81+
- Prompt the user to commit the changes:
82+
- Run `git add <changed files>` to stage the changes.
83+
- Run `git commit -m "<commit message>"` to commit the changes.
84+
- Push the changes to the GitHub remote, ensuring the branch name is not "main."
85+
- Run `git push -u origin <branch name>` to push the changes.
86+
- If the push fails due to authentication, prompt the user to run `gh auth login` and retry the push command.
87+
- If the user does not confirm, prompt them to fix the changes and re-run validation.
88+
89+
### Step 6: Manage Pull Requests
90+
- Check if a pull request exists for the current branch:
91+
- If a pull request exists, inform the user and display its details.
92+
- If no pull request exists:
93+
- Ensure the current branch name is not "main." If it is, prompt the user to create a new branch using `git checkout -b <branch name>`.
94+
- Push the changes to the remote branch. If the branch does not exist on GitHub, create it and push the changes.
95+
- Generate a title and description for the pull request based on the changes. Prompt the user to confirm or edit them.
96+
- Prompt the user to select the target branch for the pull request, defaulting to "main."
97+
- Create the pull request in DRAFT mode with the specified project, target branch, title, and description.
98+
- Retrieve and display the pull request summary, including its status, checks, and comments. Highlight any action items.
99+
- Return the link to the pull request for the user to review.
100+
101+
### Step 7: Finalize the Process
102+
- Prompt the user to review the pull request and make any necessary changes.
103+
- If the user is satisfied with the pull request guide them to go back to the TypeSpec project and make any necessary changes.
46104

47105

48106
# Pylint

.vscode/mcp.json

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,5 @@
2929
"main.py"
3030
]
3131
},
32-
"github": {
33-
"command": "docker",
34-
"args": [
35-
"run",
36-
"-i",
37-
"--rm",
38-
"-e",
39-
"GITHUB_PERSONAL_ACCESS_TOKEN",
40-
"ghcr.io/github/github-mcp-server"
41-
],
42-
"env": {
43-
"GITHUB_PERSONAL_ACCESS_TOKEN": "${input:gh_token}"
44-
}
45-
}
4632
}
4733
}

tools/mcp/typespec-story/main.py

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -91,16 +91,35 @@ def run_typespec_cli_command(command: str, args: Dict[str, Any], root_dir: Optio
9191
logger.info(f"Running command: {' '.join(cli_args)}")
9292

9393
try:
94-
# TODO: maybe if we return and dont wait for output this will work
9594
# Run the command and capture the output
9695
if root_dir:
97-
result = subprocess.run(
98-
cli_args,
99-
capture_output=True,
100-
text=True,
101-
cwd=root_dir,
102-
)
96+
if os.name == "nt": # Windows
97+
result = subprocess.Popen(
98+
cli_args,
99+
stdout=subprocess.PIPE,
100+
stderr=subprocess.PIPE,
101+
stdin=subprocess.DEVNULL, # Explicitly close stdin
102+
text=True,
103+
cwd=root_dir,
104+
)
105+
result.wait() # Wait for it to complete
106+
else:
107+
result = subprocess.run(
108+
cli_args,
109+
capture_output=True,
110+
text=True,
111+
cwd=root_dir,
112+
)
103113
else:
114+
if os.name == "nt":
115+
result = subprocess.Popen(
116+
cli_args,
117+
stdout=subprocess.PIPE,
118+
stderr=subprocess.PIPE,
119+
stdin=subprocess.DEVNULL, # Explicitly close stdin
120+
text=True
121+
)
122+
result.wait()
104123
result = subprocess.run(
105124
cli_args,
106125
capture_output=True,
@@ -129,7 +148,7 @@ def run_typespec_cli_command(command: str, args: Dict[str, Any], root_dir: Optio
129148
# Register tools for each TypeSpec client generator CLI command
130149
@mcp.tool("init")
131150
def init_tool(tsp_config_url: str) -> Dict[str, Any]:
132-
"""Initialize a typespec client library directory given the url.
151+
"""Initializes and generates a typespec client library directory given the url.
133152
134153
Args:
135154
tsp_config_url: The URL to the tspconfig.yaml file.
@@ -153,7 +172,11 @@ def init_tool(tsp_config_url: str) -> Dict[str, Any]:
153172

154173
@mcp.tool("init_local")
155174
def init_local_tool(tsp_config_path: str) -> Dict[str, Any]:
156-
"""Initialize a typespec client library directory from a local azure-rest-api-specs repo.
175+
"""Initializes and subsequently generates a typespec client library directory from a local azure-rest-api-specs repo.
176+
177+
This command is used to generate a client library from a local azure-rest-api-specs repository. No additional
178+
commands are needed to generate the client library.
179+
157180
158181
Args:
159182
tsp_config_path: The path to the local tspconfig.yaml file.
@@ -173,7 +196,7 @@ def init_local_tool(tsp_config_path: str) -> Dict[str, Any]:
173196

174197
@mcp.tool("generate")
175198
def generate_tool(project_dir: Optional[str] = None) -> Dict[str, Any]:
176-
"""Generate a typespec client library given the url.
199+
"""Generates a typespec client library given the url.
177200
178201
Args:
179202
project_dir: The directory of the client library to be generated.
@@ -192,7 +215,7 @@ def generate_tool(project_dir: Optional[str] = None) -> Dict[str, Any]:
192215

193216
@mcp.tool("update")
194217
def update_tool(project_dir: Optional[str] = None) -> Dict[str, Any]:
195-
"""Update a typespec client library.
218+
"""Updates and generates a typespec client library.
196219
197220
This command looks for a tsp-location.yaml file in the current directory to sync a TypeSpec project
198221
and generate a client library. It calls sync and generate commands internally.
@@ -216,9 +239,9 @@ def update_tool(project_dir: Optional[str] = None) -> Dict[str, Any]:
216239
@mcp.tool("sync")
217240
def sync_tool(project_dir: Optional[str] = None) -> Dict[str, Any]:
218241
"""Sync a typespec client library from the remote repository.
219-
220242
This command looks for a tsp-location.yaml file to get the project details and sync them to a temporary directory.
221-
243+
A generate or update command is then needed to generate the client library.
244+
222245
Args:
223246
project_dir: The root directory where the client library will be synced.
224247
@@ -238,6 +261,9 @@ def sync_tool(project_dir: Optional[str] = None) -> Dict[str, Any]:
238261
@mcp.tool("sync_local")
239262
def sync_local_tool(local_spec_repo: str, project_dir: Optional[str] = None) -> Dict[str, Any]:
240263
"""Sync a typespec client library from a local repository.
264+
265+
This command looks for a tsp-location.yaml file to get the project details and sync them to a temporary directory.
266+
A generate or update command is then needed to generate the client library.
241267
242268
Args:
243269
local_spec_repo: The path to the local azure-rest-api-specs repository.

0 commit comments

Comments
 (0)