Skip to content

Commit c151395

Browse files
committed
Refactor review create script to Python.
1 parent 650f534 commit c151395

16 files changed

Lines changed: 1283 additions & 1959 deletions

.github/skills/create-api-review-pr/SKILL.md

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,19 @@ description: Create a GitHub PR for API review by comparing a baseline API surfa
55

66
# Create API Review PR
77

8-
Creates a dedicated API review PR that shows the diff between a baseline release and a target tag or branch's API surface using `scripts/api_md_workflow/create_api_review_pr.js`.
8+
Creates a dedicated API review PR that shows the diff between a baseline release and a target tag or branch's API surface using `scripts/api_md_workflow/create_api_review_pr.py`.
99

1010
## Unsupported Requests
1111

12-
If the user asks to create an API review PR for a new package, explain that new packages do not use API review PRs and stop. Do not gather script inputs or run `create_api_review_pr.js` for new packages.
12+
If the user asks to create an API review PR for a new package, explain that new packages do not use API review PRs and stop. Do not gather script inputs or run `create_api_review_pr.py` for new packages.
1313

1414
## Prerequisites
1515

1616
1. The user must have `gh` CLI installed and authenticated (`gh auth login`), or `GITHUB_TOKEN`/`GH_TOKEN` set with permission to create and update pull requests in this repository.
1717
2. The working tree must be clean (no uncommitted changes).
18-
3. The latest Node.js LTS must be installed.
19-
4. API.md workflow Node dependencies must be installed (`npm ci` from `scripts/api_md_workflow`).
20-
5. `azpysdk` must be installed (`pip install -e ./eng/tools/azure-sdk-tools`).
21-
6. ApiView stub generator dependencies must be installed (`pip install -r ./eng/apiview_reqs.txt`).
18+
3. Python 3.10 or later must be available.
19+
4. `azpysdk` must be installed (`pip install -e ./eng/tools/azure-sdk-tools`).
20+
5. ApiView stub generator dependencies must be installed (`pip install -r ./eng/apiview_reqs.txt`).
2221

2322
## Information to Gather
2423

@@ -52,31 +51,31 @@ Before running the script:
5251

5352
This is a long-running operation. The script may take several minutes because it generates API surfaces for both the baseline and target, creates or reuses review branches, pushes branches, and then opens the draft PR. Do not treat quiet terminal periods during `apistub` generation as failure unless the command exits, prints an error, or waits for input.
5453

55-
If `create_api_review_pr.js` fails while running this skill, do not patch the script, modify package files, retry with workaround edits, or try to manually complete branch/PR creation. Stop the workflow, report the failure clearly, include the relevant error details, and suggest practical next steps.
54+
If `create_api_review_pr.py` fails while running this skill, do not patch the script, modify package files, retry with workaround edits, or try to manually complete branch/PR creation. Stop the workflow, report the failure clearly, include the relevant error details, and suggest practical next steps.
5655

5756
If the script reports that there are no API differences, relay that message to the user and stop. Do not create branches or a PR manually.
5857

5958
Run the following command from the repository root:
6059

6160
```bash
62-
node scripts/api_md_workflow/create_api_review_pr.js --package-name <package-name> --base <tag> [--target <target>]
61+
python scripts/api_md_workflow/create_api_review_pr.py --package-name <package-name> --base <tag> [--target <target>]
6362
```
6463

6564
### Examples
6665

6766
**Standard review (comparing a release tag to a PR branch):**
6867
```bash
69-
node scripts/api_md_workflow/create_api_review_pr.js --package-name azure-storage-blob --base azure-storage-blob_12.29.0 --target someone:feature-branch
68+
python scripts/api_md_workflow/create_api_review_pr.py --package-name azure-storage-blob --base azure-storage-blob_12.29.0 --target someone:feature-branch
7069
```
7170

7271
**Release-to-release review (comparing two package tags):**
7372
```bash
74-
node scripts/api_md_workflow/create_api_review_pr.js --package-name azure-ai-projects --base azure-ai-projects_2.1.0 --target azure-ai-projects_2.2.0
73+
python scripts/api_md_workflow/create_api_review_pr.py --package-name azure-ai-projects --base azure-ai-projects_2.1.0 --target azure-ai-projects_2.2.0
7574
```
7675

7776
**Review against main (no target specified):**
7877
```bash
79-
node scripts/api_md_workflow/create_api_review_pr.js --package-name azure-cosmos --base azure-cosmos_4.14.0
78+
python scripts/api_md_workflow/create_api_review_pr.py --package-name azure-cosmos --base azure-cosmos_4.14.0
8079
```
8180

8281
## Post-Execution
File renamed without changes.
File renamed without changes.

.github/workflows/src/api-md-consistency/api-md-consistency.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ function formatIssueSection(title, apiFiles) {
7979
module.exports = async function apiMdConsistency({ core }) {
8080
const workspace = process.env.GITHUB_WORKSPACE || process.cwd();
8181

82-
await runNode("scripts/api_md_workflow/find_affected.js", workspace, core);
82+
await runNode(".github/workflows/src/api-md-consistency/find_affected.js", workspace, core);
8383

8484
const affected = readLines(process.env.API_MD_PACKAGES_FILE, workspace);
8585
const changedCount = affected.length;
@@ -97,8 +97,8 @@ module.exports = async function apiMdConsistency({ core }) {
9797
};
9898
}
9999

100-
await runNode("scripts/api_md_workflow/regenerate.js", workspace, core);
101-
await runNode("scripts/api_md_workflow/find_mismatches.js", workspace, core);
100+
await runNode(".github/workflows/src/api-md-consistency/regenerate.js", workspace, core);
101+
await runNode(".github/workflows/src/api-md-consistency/find_mismatches.js", workspace, core);
102102

103103
const mismatches = readLines(process.env.API_MD_MISMATCHES_FILE, workspace);
104104
const missing = readLines(process.env.API_MD_MISSING_FILE, workspace);

scripts/api_md_workflow/api_md_workflow.config.json renamed to .github/workflows/src/api-md-consistency/api_md_workflow.config.json

File renamed without changes.

scripts/api_md_workflow/common.js renamed to .github/workflows/src/api-md-consistency/common.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const fs = require("fs");
44
const path = require("path");
55
const { pathToFileURL } = require("url");
66

7-
const REPO_ROOT = path.resolve(__dirname, "..", "..");
7+
const REPO_ROOT = path.resolve(__dirname, "..", "..", "..", "..");
88
const SHARED_SRC_ROOT = path.join(REPO_ROOT, ".github", "shared", "src");
99
const sharedModuleCache = new Map();
1010

File renamed without changes.
File renamed without changes.
File renamed without changes.

scripts/api_md_workflow/README.md

Lines changed: 8 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1,111 +1,21 @@
1-
# api.md Workflow Helpers
1+
# API Review PR Helper
22

3-
This folder contains the helper scripts used by the GitHub Actions workflows that validate and update `api.md` files for changed SDK packages.
3+
This folder contains the standalone Python helper used to create API review PRs from generated `api.md` files.
44

55
## Purpose
66

7-
The workflow validates that when a pull request changes one or more SDK packages, the committed `api.md` files are still up to date.
8-
`api.md` content is diff-gated by this workflow, and `api.metadata.yml` must be committed alongside it.
9-
The workflow also validates adapter-selected metadata fields, such as `apiMdSha256` and `parserVersion`, so metadata differences can affect pass/fail.
7+
`create_api_review_pr.py` compares a baseline package release tag with a target API surface, creates or reuses dedicated API review branches, and opens a draft PR that shows the `api.md` diff.
108

11-
The logic is split between GitHub workflow YAML files and helper scripts in Python and JavaScript.
9+
The API consistency workflow helpers live under `.github/workflows/src/api-md-consistency`.
1210

13-
## Workflow Files
11+
## Usage
1412

15-
### `.github/workflows/api-consistency.yml`
13+
The script includes Python package discovery, version parsing, `api.md` generation, git branch orchestration, and GitHub PR creation in one file.
1614

17-
This is the main workflow.
18-
19-
It runs on pull requests for changes under `sdk/**`.
20-
21-
- Detects affected package directories from the PR diff.
22-
- Regenerates `api.md` for those packages.
23-
- Fails if the generated files differ from the committed files.
24-
- Fails if an affected package does not have a committed `api.md`.
25-
- Prints the mismatched or missing packages and the `azpysdk apistub --md --extract-metadata <package-name> --dest-dir .` command needed to regenerate each `api.md` file from the repository root.
26-
27-
## Script Layout
28-
29-
### `common.js`
30-
31-
Shared helpers used by the other scripts:
32-
33-
- repository root resolution
34-
- subprocess execution
35-
- reading/writing line-based artifact files
36-
- writing GitHub Actions outputs
37-
- GitHub REST API helpers for listing/updating comments
38-
39-
### `find_affected.js`
40-
41-
Used by the `consistency` job.
42-
43-
Reads `API_MD_BASE_REF`, compares the PR branch to `origin/<base>`, and writes:
44-
45-
- changed package directories to `API_MD_CHANGED_FILE`
46-
- valid package roots to `API_MD_PACKAGES_FILE`
47-
48-
Also writes `count=<n>` to `GITHUB_OUTPUT`.
49-
50-
### `regenerate.js`
51-
52-
Reads package directories from `API_MD_PACKAGES_FILE` and runs `azpysdk apistub --md --extract-metadata <package-name> --dest-dir <package-dir>` for each package from the repository root.
53-
54-
This script is used by the consistency check.
55-
56-
### `find_mismatches.js`
57-
58-
Reads package directories from `API_MD_PACKAGES_FILE`, checks whether `<package>/api.md` is missing/untracked or differs from git, and writes:
59-
60-
- mismatched files to `API_MD_MISMATCHES_FILE`
61-
- missing files to `API_MD_MISSING_FILE`
62-
63-
Also writes `mismatch_count=<n>`, `missing_count=<n>`, and `issue_count=<n>` to `GITHUB_OUTPUT`.
64-
65-
`api.metadata.yml` is also required and selected metadata fields are mismatch-checked according to the active adapter.
66-
67-
### `create_api_review_pr.js` and adapters
68-
69-
API review PR creation now uses a shared JavaScript orchestrator with a language adapter boundary:
70-
71-
- `create_api_review_pr.js`: shared git/branch/PR orchestration logic.
72-
- `adapters/python.js`: Python-specific package discovery, version parsing, and `api.md` generation.
73-
74-
This split allows the core workflow to be reused across other language repos while keeping generation behavior language-specific.
75-
76-
`create_api_review_pr.js` compares a baseline package release tag with a target API surface. The target can be a package release tag, an `origin` branch, or an `owner:branch` fork reference. When the target is a tag, the generated PR body identifies it as a target tag instead of a working branch.
15+
`create_api_review_pr.py` compares a baseline package release tag with a target API surface. The target can be a package release tag, an `origin` branch, or an `owner:branch` fork reference. When the target is a tag, the generated PR body identifies it as a target tag instead of a working branch.
7716

7817
Example comparing two package release tags:
7918

8019
```bash
81-
node scripts/api_md_workflow/create_api_review_pr.js --package-name azure-ai-projects --base azure-ai-projects_2.1.0 --target azure-ai-projects_2.2.0
20+
python scripts/api_md_workflow/create_api_review_pr.py --package-name azure-ai-projects --base azure-ai-projects_2.1.0 --target azure-ai-projects_2.2.0
8221
```
83-
84-
### `api_md_workflow.config.json`
85-
86-
Shared configuration for adapter selection across `api_md_workflow` scripts.
87-
88-
- `adapter`: default adapter name (for this repo: `python`)
89-
90-
Both `create_api_review_pr.js` and `find_affected.js` read this file for adapter selection.
91-
92-
## Environment Variables Used
93-
94-
The scripts are intentionally simple and read inputs from environment variables set by the workflow steps.
95-
96-
Common variables include:
97-
98-
- `API_MD_BASE_REF`
99-
- `API_MD_PACKAGES_FILE`
100-
- `API_MD_CHANGED_FILE`
101-
- `API_MD_MISMATCHES_FILE`
102-
- `API_MD_MISSING_FILE`
103-
104-
## End-to-End Flow
105-
106-
1. A PR changes files under `sdk/**`.
107-
2. `consistency.yml` runs.
108-
3. `find_affected.js` determines which packages were touched.
109-
4. `regenerate.js` rebuilds `api.md` for those packages.
110-
5. `find_mismatches.js` records any `api.md` drift, including missing or untracked `api.md` files.
111-
6. If drift is found, the workflow fails and prints the affected packages plus the `azpysdk apistub --md --extract-metadata <package-name> --dest-dir .` command to regenerate each `api.md` file locally from the repository root.

0 commit comments

Comments
 (0)