Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
224 commits
Select commit Hold shift + click to select a range
abfcfcb
sdk breaking change analysis agentic workflow
chunyu3 Sep 3, 2026
cbf2614
add workflow run trigger
chunyu3 Sep 4, 2026
cf53c1a
Merge pull request #3 from chunyu3/breaking-change-workflow
chunyu3 Sep 4, 2026
c1e6718
remove feature to read ado pipeline artifacts
chunyu3 Sep 4, 2026
c067f56
Merge pull request #4 from chunyu3/breaking-change-workflow
chunyu3 Sep 4, 2026
a2dbdae
resolve js dependency issue
chunyu3 Sep 4, 2026
a600f13
Merge pull request #6 from chunyu3/breaking-change-workflow
chunyu3 Sep 4, 2026
4176201
Merge branch 'main' of https://github.com/Azure/azure-rest-api-specs …
chunyu3 Sep 7, 2026
91bd941
Merge branch 'Azure:main' into main
chunyu3 Sep 7, 2026
67da96f
fake sdk repo
chunyu3 Sep 7, 2026
3295967
Merge branch 'main' of https://github.com/chunyu3/azure-rest-api-spec…
chunyu3 Sep 7, 2026
1a5f93c
Merge pull request #9 from chunyu3/breaking-change-workflow
chunyu3 Sep 7, 2026
9487cc7
compile agentic workflow
chunyu3 Sep 7, 2026
32b5db7
Merge branch 'breaking-change-workflow' of https://github.com/chunyu3…
chunyu3 Sep 7, 2026
151669d
Merge pull request #10 from chunyu3/breaking-change-workflow
chunyu3 Sep 7, 2026
054a712
resolve run failure
chunyu3 Sep 7, 2026
779ce69
Merge pull request #11 from chunyu3/breaking-change-workflow
chunyu3 Sep 7, 2026
1c294b5
add sdk generation and build
chunyu3 Sep 7, 2026
7b05c21
Merge pull request #12 from chunyu3/breaking-change-workflow
chunyu3 Sep 7, 2026
0e7a5a0
config the spec and sdk repo path
chunyu3 Sep 7, 2026
e73c8dd
fake sdk repo
chunyu3 Sep 7, 2026
32fd798
Merge pull request #13 from chunyu3/breaking-change-workflow
chunyu3 Sep 7, 2026
49bf0d2
log intermediate result
chunyu3 Sep 7, 2026
19562d3
Merge pull request #14 from chunyu3/breaking-change-workflow
chunyu3 Sep 7, 2026
c82e265
config azsdk mcp server
chunyu3 Sep 7, 2026
b232bc8
Merge pull request #15 from chunyu3/breaking-change-workflow
chunyu3 Sep 7, 2026
8b24319
resolve the mount point in docker
chunyu3 Sep 7, 2026
bfbf611
Merge pull request #16 from chunyu3/breaking-change-workflow
chunyu3 Sep 7, 2026
c8c82e5
use azsdk cli to generate, build sdk and detect breaking change
chunyu3 Sep 7, 2026
1f61f1d
Merge pull request #17 from chunyu3/breaking-change-workflow
chunyu3 Sep 7, 2026
870b42f
add sdk environment setup
chunyu3 Sep 7, 2026
dc67c26
Merge pull request #18 from chunyu3/breaking-change-workflow
chunyu3 Sep 7, 2026
97e819a
correct language env
chunyu3 Sep 7, 2026
e2a637e
Merge pull request #19 from chunyu3/breaking-change-workflow
chunyu3 Sep 7, 2026
97a85f5
install go and .net
chunyu3 Sep 7, 2026
2583295
Merge pull request #20 from chunyu3/breaking-change-workflow
chunyu3 Sep 7, 2026
a53d5c7
install golangci-lint
chunyu3 Sep 7, 2026
a730522
Merge pull request #21 from chunyu3/breaking-change-workflow
chunyu3 Sep 7, 2026
511850e
remove azsdk cmd output format
chunyu3 Sep 7, 2026
b442482
Merge pull request #22 from chunyu3/breaking-change-workflow
chunyu3 Sep 7, 2026
1767e60
move generate and build SDK to pre-agent step
chunyu3 Sep 8, 2026
09575a4
Merge pull request #23 from chunyu3/breaking-change-workflow
chunyu3 Sep 8, 2026
36759ac
resolve the spec and sdk information
chunyu3 Sep 8, 2026
cb5528d
Merge pull request #24 from chunyu3/breaking-change-workflow
chunyu3 Sep 8, 2026
19c48e2
install copilot cli
chunyu3 Sep 8, 2026
97261e7
Merge pull request #25 from chunyu3/breaking-change-workflow
chunyu3 Sep 8, 2026
1a96c23
convert agentic workflow to normal workflow
chunyu3 Sep 8, 2026
58efb4b
Merge pull request #26 from chunyu3/breaking-change-workflow
chunyu3 Sep 8, 2026
6127a71
surface the breaking change result in PR comments
chunyu3 Sep 8, 2026
1f231a7
Merge pull request #27 from chunyu3/breaking-change-workflow
chunyu3 Sep 8, 2026
5e2e95c
updated the result in the trigger comment
chunyu3 Sep 8, 2026
4189574
Merge pull request #28 from chunyu3/breaking-change-workflow
chunyu3 Sep 8, 2026
0e9be73
remove unused agentic workflow change
chunyu3 Sep 8, 2026
a7dacf6
Merge pull request #29 from chunyu3/breaking-change-workflow
chunyu3 Sep 8, 2026
418bb2b
suppress cspell words
chunyu3 Sep 8, 2026
cf24fb6
format
chunyu3 Sep 8, 2026
a42e3a6
Merge pull request #30 from chunyu3/breaking-change-workflow
chunyu3 Sep 8, 2026
aa277a3
ignore unknown permission scope copilot-requests
chunyu3 Sep 9, 2026
31f89cf
Merge pull request #31 from chunyu3/breaking-change-workflow
chunyu3 Sep 9, 2026
ce4fd1a
upgrade go version to 1.26.*
chunyu3 Sep 9, 2026
000286b
Merge pull request #32 from chunyu3/breaking-change-workflow
chunyu3 Sep 9, 2026
8d634c4
support multiple project in one pr
chunyu3 Sep 9, 2026
b04755f
Merge pull request #33 from chunyu3/breaking-change-workflow
chunyu3 Sep 9, 2026
e71e191
support multiple project in one pr
chunyu3 Sep 9, 2026
7bc6bb7
Merge branch 'main' into breaking-change-workflow
chunyu3 Sep 9, 2026
1bfb68e
Merge pull request #35 from chunyu3/breaking-change-workflow
chunyu3 Sep 9, 2026
1b0325a
Update sdk-breaking-change-analysis.yaml
chunyu3 Sep 9, 2026
b0ac57c
refine the result folder structure
chunyu3 Sep 9, 2026
7328ce6
add breaking change details link for each project
chunyu3 Sep 9, 2026
ae4b0b0
Merge pull request #36 from chunyu3/breaking-change-workflow
chunyu3 Sep 9, 2026
1a5c45a
use the action run summary
chunyu3 Sep 11, 2026
fd2cc7f
Merge pull request #37 from chunyu3/breaking-change-workflow
chunyu3 Sep 11, 2026
06786b4
trigger workflow when edit comment
chunyu3 Sep 11, 2026
1b648d6
Merge pull request #38 from chunyu3/breaking-change-workflow
chunyu3 Sep 11, 2026
3e86d71
use table to display breaking changes
chunyu3 Sep 11, 2026
b3d636a
Merge pull request #39 from chunyu3/breaking-change-workflow
chunyu3 Sep 11, 2026
f3c28f8
link to the summary part of the summary page
chunyu3 Sep 11, 2026
f86837d
Merge pull request #40 from chunyu3/breaking-change-workflow
chunyu3 Sep 11, 2026
8157c4a
refine the checkbox
chunyu3 Sep 11, 2026
c3c9340
Merge pull request #41 from chunyu3/breaking-change-workflow
chunyu3 Sep 11, 2026
03b336e
refine the checkbox
chunyu3 Sep 11, 2026
f1e1efc
Merge branch 'main' into breaking-change-workflow
chunyu3 Sep 11, 2026
f4704e5
Merge pull request #42 from chunyu3/breaking-change-workflow
chunyu3 Sep 11, 2026
af670c1
refine the checkbox
chunyu3 Sep 11, 2026
8e57d9e
Merge branch 'main' into breaking-change-workflow
chunyu3 Sep 11, 2026
e7b1102
Merge pull request #43 from chunyu3/breaking-change-workflow
chunyu3 Sep 11, 2026
9f1a3db
update the comment if workflow failed
chunyu3 Sep 11, 2026
1db833e
Merge pull request #44 from chunyu3/breaking-change-workflow
chunyu3 Sep 11, 2026
5a667c9
update the comment if workflow failed
chunyu3 Sep 11, 2026
55fe0b0
Merge branch 'main' into breaking-change-workflow
chunyu3 Sep 11, 2026
676bb40
Merge pull request #45 from chunyu3/breaking-change-workflow
chunyu3 Sep 11, 2026
4ab61d5
update the comment if workflow failed
chunyu3 Sep 11, 2026
c1852b2
Merge branch 'main' into breaking-change-workflow
chunyu3 Sep 11, 2026
95413ad
Merge pull request #46 from chunyu3/breaking-change-workflow
chunyu3 Sep 11, 2026
7d55084
update the comment if workflow failed
chunyu3 Sep 11, 2026
766be1d
link the error log when workflow run failed
chunyu3 Sep 15, 2026
6de9173
breaking change mitigation flow
chunyu3 Sep 15, 2026
c154ade
Merge branch 'main' into breaking-change-workflow
chunyu3 Sep 15, 2026
e1d503d
support multiple trigger for mitigation workflow
chunyu3 Sep 15, 2026
7a672c6
Merge branch 'breaking-change-workflow' of https://github.com/chunyu3…
chunyu3 Sep 15, 2026
135d96d
Read analysis trigger metadata
chunyu3 Sep 15, 2026
8aa1ad6
add sdk repo and packagePath parameter in azsdk customize command
chunyu3 Sep 15, 2026
0812846
setup copilot cli
chunyu3 Sep 15, 2026
4170a26
config copilot cli
chunyu3 Sep 15, 2026
9635b1a
remove workflow_run trigger in mitigation workflow
chunyu3 Sep 17, 2026
ad8399a
add npm ci stage and display resolved breaking change in table
chunyu3 Sep 17, 2026
06b4dfa
install nodejs
chunyu3 Sep 17, 2026
890c234
add breaking change resolution result into summary
chunyu3 Sep 17, 2026
9407060
analysis workflow: add concurrnce guard, check the analysis result fr…
chunyu3 Sep 17, 2026
cf162ae
add ananlyzing progress info in comment when start the workflow
chunyu3 Sep 17, 2026
364e07a
concurrence guard in mitigation workflow
chunyu3 Sep 17, 2026
d9a7112
resolve ci failure
chunyu3 Sep 17, 2026
92e8521
check if the pull request is updated
chunyu3 Sep 18, 2026
ade96dd
Merge branch 'main' of https://github.com/Azure/azure-rest-api-specs …
chunyu3 Sep 18, 2026
e148da2
add ci-fix for SDK breaking changes
chunyu3 Sep 20, 2026
3bad289
surface code snippet in the result
chunyu3 Sep 20, 2026
10b08cf
checkout out PR source branch instead of sha, add failure step
chunyu3 Sep 20, 2026
2063ee5
use pnpm ci
chunyu3 Sep 20, 2026
d0442cd
mitigate all the breaking changes
chunyu3 Sep 20, 2026
c567b38
resolve SDK breaking changes one-by-one
chunyu3 Sep 20, 2026
566d625
record mitigation result and surface it in the comment
chunyu3 Sep 20, 2026
00cc234
report mitigation result for each project separately
chunyu3 Sep 20, 2026
f9e9e03
non case-sensitive compare
chunyu3 Sep 20, 2026
b09da89
resolve code scan ci failure
chunyu3 Sep 20, 2026
8e2634e
display first item of TypeSpecChangesSummary
chunyu3 Sep 21, 2026
6fb74c8
remove mitigation pull request creation
chunyu3 Sep 21, 2026
6e4f0a1
analysis workflow trigger mitigation
chunyu3 Sep 21, 2026
f87330e
remove comment-trigger and workflow-run trigger
chunyu3 Sep 22, 2026
e451872
separate analyze and result publish into two workflows
chunyu3 Sep 22, 2026
9e77f40
define trigger resolve as function
chunyu3 Sep 22, 2026
2e5fb30
Merge branch 'main' of https://github.com/Azure/azure-rest-api-specs …
chunyu3 Sep 22, 2026
1377e01
checkout the sha resolve-trigger identified
chunyu3 Sep 22, 2026
2f35131
resolve all inputs in resolve-trigger
chunyu3 Sep 23, 2026
4985a8d
resolve codeQL CI failure
chunyu3 Sep 23, 2026
548139a
trigger mitigation workflow by ananlysis workflow
chunyu3 Sep 23, 2026
dae5cf3
convert script to typescript function
chunyu3 Sep 23, 2026
b8e0cb9
separate publish mitigation result in PR in another workflow
chunyu3 Sep 23, 2026
afc2c50
move tspconfig resolve to resolve job
chunyu3 Sep 23, 2026
0611da4
format
chunyu3 Sep 23, 2026
0b3a902
Merge branch 'main' of https://github.com/Azure/azure-rest-api-specs …
chunyu3 Sep 23, 2026
db07c0c
checkout merge branch
chunyu3 Sep 23, 2026
d2817ee
write analyzeSdkProjects and mitigateBreakingChanges function
chunyu3 Sep 23, 2026
02a09e9
Merge branch 'main' of https://github.com/Azure/azure-rest-api-specs …
chunyu3 Sep 28, 2026
dcb691c
reuse existing node function
chunyu3 Sep 28, 2026
7c2c19b
define analysis and mitigation schema
chunyu3 Sep 28, 2026
93baff8
truncate changed-code ony in comment
chunyu3 Sep 28, 2026
f7f6734
remove unused code
chunyu3 Sep 28, 2026
c783a6b
consistent language name between workflow and the mcp tool
chunyu3 Sep 29, 2026
7698ec1
add waring or error icon for failued analysis result
chunyu3 Sep 29, 2026
ffdec92
propagate mitigation job running status to mitigation publisher
chunyu3 Sep 29, 2026
ae2ea56
resolve ci failure
chunyu3 Sep 30, 2026
306a5bf
Merge branch 'main' of https://github.com/Azure/azure-rest-api-specs …
chunyu3 Sep 30, 2026
203786b
resolve ci failure
chunyu3 Sep 30, 2026
096be9b
trigger mitigation by analysis workflow
chunyu3 Sep 30, 2026
69b42eb
reslove tspConfig for shared library
chunyu3 Sep 30, 2026
7f83e66
remove unused code
chunyu3 Sep 30, 2026
0b6a804
update doc
chunyu3 Sep 30, 2026
9bf02b0
Merge branch 'main' of https://github.com/Azure/azure-rest-api-specs …
chunyu3 Sep 30, 2026
12a57e1
resolve ci failure
chunyu3 Sep 30, 2026
39b3bac
Fix GitHub test workspace dependency checkout
chunyu3 Sep 30, 2026
085853b
propogate the analysis and mitigation job running status
chunyu3 Oct 8, 2026
8e10d34
always propagate mitigation status
chunyu3 Oct 8, 2026
02f3c18
consist the output variable name
chunyu3 Oct 8, 2026
8332dbc
Merge branch 'main' into yuc/breaking-change-workflow
chunyu3 Oct 9, 2026
5fd2c62
use generateTypeSpecMetadata to get the sdk package path
chunyu3 Oct 8, 2026
b3c87c3
Merge branch 'yuc/breaking-change-workflow' of https://github.com/Azu…
chunyu3 Oct 9, 2026
1678f8e
reuse commentOrUpdate to publish results in comments
chunyu3 Oct 9, 2026
971617d
resolve merge issue
chunyu3 Oct 9, 2026
9ae9e90
Merge branch 'main' into yuc/breaking-change-workflow
chunyu3 Oct 9, 2026
505d0c4
format and lint
chunyu3 Oct 9, 2026
a749c13
resolve the githubAction lint issue
chunyu3 Oct 9, 2026
f7eab9c
resolve testcase failure
chunyu3 Oct 9, 2026
016cdd4
resolve breaking change missing issue
chunyu3 Oct 9, 2026
7446e15
resolve gitAction lint failure
chunyu3 Oct 9, 2026
77b0bbc
resolve test ci failure
chunyu3 Oct 9, 2026
1c48318
resolve CodeQL issue
chunyu3 Oct 9, 2026
27e5de8
add pull-requst write permission
chunyu3 Oct 9, 2026
e791f4d
update doc
chunyu3 Oct 9, 2026
858db0a
resolve CodeQL issue in spec-gen-sdk-runner
chunyu3 Oct 9, 2026
9409c23
Merge branch 'main' of https://github.com/Azure/azure-rest-api-specs …
chunyu3 Oct 10, 2026
13517f8
correct the language to type-metadata lang map
chunyu3 Oct 10, 2026
1d5ad72
resolve analyze failure for other languages
chunyu3 Oct 10, 2026
3ee3740
Merge branch 'main' of https://github.com/Azure/azure-rest-api-specs …
chunyu3 Oct 14, 2026
87dee0d
inline suppress spell words in analysis
chunyu3 Oct 14, 2026
41a777e
use interface instead of type
chunyu3 Oct 14, 2026
7b25bc9
use markdown util to create table
chunyu3 Oct 14, 2026
77fc3e0
convert workflow summary publish as ts function
chunyu3 Oct 14, 2026
878db8b
update the test case
chunyu3 Oct 14, 2026
e11f73f
reuse the functions in spec-gen-sdk-runner
chunyu3 Oct 14, 2026
7c5f5cd
resolve parse issue in azsdk-adapter.ts
chunyu3 Oct 14, 2026
2b9c6e8
import from library
chunyu3 Oct 14, 2026
1a59ab5
update doc
chunyu3 Oct 14, 2026
abc33ed
merge workflow run status check and propagate in resolve step
chunyu3 Oct 15, 2026
4112d40
nullpointer exception
chunyu3 Oct 15, 2026
1a00747
add trigger flow into the doc
chunyu3 Oct 15, 2026
c43d229
resolve codeQL issue
chunyu3 Oct 15, 2026
2162adf
remove duplicate dependencies install step
chunyu3 Oct 15, 2026
f0699d9
integrate SDK breaking change into summary check
chunyu3 Oct 16, 2026
a39e8fa
Merge branch 'main' of https://github.com/Azure/azure-rest-api-specs …
chunyu3 Oct 16, 2026
5ee0748
consistent the sdkLables
chunyu3 Oct 16, 2026
ae7ecca
filter comments by github-actions[bot]
chunyu3 Oct 18, 2026
c2549f2
record analysis status for each project
chunyu3 Oct 18, 2026
7d9f4aa
Merge branch 'main' of https://github.com/Azure/azure-rest-api-specs …
chunyu3 Oct 18, 2026
dd2d73e
add comment
chunyu3 Oct 18, 2026
fa51d70
merge summary and analyze result into analyzeProject function
chunyu3 Oct 18, 2026
61c6027
remove unused createAnalysisResult and publishAnalysisSummary code
chunyu3 Oct 18, 2026
71cf5e6
update document
chunyu3 Oct 19, 2026
e7cdd21
provide markdown head anchor
chunyu3 Oct 19, 2026
a99e1e0
Merge branch 'main' of https://github.com/Azure/azure-rest-api-specs …
chunyu3 Oct 19, 2026
5db50de
add markdown testcase
chunyu3 Oct 19, 2026
4b40756
merge status workflow into analysis and mitigation workflow
chunyu3 Oct 20, 2026
59f65eb
UI update
chunyu3 Oct 20, 2026
2ad2802
update the doc
chunyu3 Oct 20, 2026
068856d
correct the mitigtion summary url and refine UI
chunyu3 Oct 21, 2026
c8506ae
reflect analysis status in result comment
chunyu3 Oct 21, 2026
b2dc19f
update doc
chunyu3 Oct 21, 2026
ce00535
typo
chunyu3 Oct 21, 2026
0badfc9
add comment for check-out PR branch
chunyu3 Oct 21, 2026
93e4491
Merge branch 'main' of https://github.com/Azure/azure-rest-api-specs …
chunyu3 Oct 22, 2026
7ad7ff1
install library from the main branch spec
chunyu3 Nov 2, 2026
cea6c7c
Merge branch 'main' of https://github.com/Azure/azure-rest-api-specs …
chunyu3 Nov 2, 2026
5224c8e
submit failure artifact
chunyu3 Nov 2, 2026
862ebe7
Merge branch 'main' into yuc/breaking-change-workflow
chunyu3 Nov 2, 2026
87c0832
Merge branch 'main' into yuc/breaking-change-workflow
chunyu3 Nov 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .github/actionlint.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
self-hosted-runner:
labels:
- 1ES.Pool=azsdk-pool-github-runners
Expand All @@ -15,6 +15,16 @@
ignore:
- ".+"

.github/workflows/sdk-breaking-change-analysis.yaml:
ignore:
# actionlint 1.7.12 predates GitHub's copilot-requests permission scope.
- 'unknown permission scope "copilot-requests"'
Comment thread
Copilot marked this conversation as resolved.
Resolved

.github/workflows/sdk-breaking-change-mitigate.yaml:
ignore:
# actionlint 1.7.12 predates GitHub's copilot-requests permission scope.
- 'unknown permission scope "copilot-requests"'

# Also generated by gh-aw
# cspell:ignore agentics
.github/workflows/agentics-maintenance.yml:
Expand Down
3 changes: 2 additions & 1 deletion .github/package.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"name": "azure-rest-api-specs-github",
"version": "0.0.0",
Expand All @@ -9,10 +9,12 @@
},
"dependencies": {
"@apidevtools/json-schema-ref-parser": "catalog:",
"@azure-tools/spec-gen-sdk-runner": "workspace:*",
Comment thread
chunyu3 marked this conversation as resolved.
Resolved
"@azure-tools/specs-shared": "workspace:*",
"@js-temporal/polyfill": "catalog:",
"cross-spawn": "catalog:",
"debug": "catalog:",
"fflate": "catalog:",
"marked": "catalog:",
"markdown-table": "catalog:",
"minimatch": "catalog:",
Expand All @@ -38,7 +40,6 @@
"@types/node": "catalog:",
"@types/semver": "catalog:",
"@vitest/utils": "catalog:",
"fflate": "catalog:",
"semver": "catalog:",
"tinybench": "catalog:"
},
Expand Down
5 changes: 4 additions & 1 deletion .github/shared/readme.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# `.github/shared`

Shared TypeScript helper library (`@azure-tools/specs-shared`) used by tooling and GitHub Actions
Expand Down Expand Up @@ -172,7 +172,8 @@
- `link(label, url)` — create a link from trusted inline Markdown and a trusted destination.
- `table([header, ...rows])` — render equal-width GFM rows, escaping pipes and preserving line breaks.
- `unorderedList(items)` — render Markdown list items, indenting continuation lines.
- `details(summary, body)` — create a collapsible block with a plain-text summary and Markdown body.
- `details(summary, body, open = false)` — create a collapsible block with a plain-text summary
and Markdown body; pass `true` to expand it by default.

Like [TypeSpec's Markdown helpers](https://github.com/microsoft/typespec/blob/main/packages/tspd/src/ref-doc/utils/markdown.ts),
callers describe the document structure rather than hand-joining every line. Strings are trusted
Expand Down Expand Up @@ -218,6 +219,8 @@
### `sdk-types` — SDK language types & schemas

- `SdkName` — frozen enum of SDK language identifiers (Go/Java/Js/Net/Python/Rust).
- `getSdkLanguage(repo)` — returns the SDK language name (for example, `JavaScript` for
`azure-sdk-for-js` and `DotNet` for `azure-sdk-for-net`); throws for unsupported repositories.
- `SdkNameSchema`, `APIViewRequestDataSchema`, `SpecGenSdkArtifactInfoSchema` — zod schemas (plus
inferred TypeScript types) for SDK tooling payloads.
- `sdkLabels` — per-language SDK label configuration.
Expand Down
24 changes: 19 additions & 5 deletions .github/shared/src/markdown.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
/** A document made of trusted Markdown blocks, nested sections, and optional content. */
export type MarkdownDoc = string | MarkdownSection | MarkdownDoc[] | undefined;

Expand All @@ -6,16 +6,18 @@
kind: "section";
title: string;
body: MarkdownDoc;
id?: string;
}

/** Groups trusted inline Markdown and body blocks under a heading. */
export function section(title: string, body: MarkdownDoc): MarkdownSection {
return { kind: "section", title, body };
/** Groups trusted inline Markdown and body blocks under a heading with an optional anchor ID. */
export function section(title: string, body: MarkdownDoc, id?: string): MarkdownSection {
return { kind: "section", title, body, ...(id === undefined ? {} : { id }) };
}

/** Renders document blocks with blank lines between them, omitting empty or absent blocks. */
export function renderMarkdownDoc(doc: MarkdownDoc, heading = 1): string {
const blocks: string[] = [];
const ids = new Set<string>();

/** Flattens content while keeping nested heading levels local to each section. */
function render(content: MarkdownDoc, level: number): void {
Expand All @@ -28,6 +30,18 @@
if (!Number.isInteger(level) || level < 1 || level > 6) {
throw new Error("Markdown headings must have a level from 1 to 6");
}
if (content.id !== undefined) {
if (!/^[A-Za-z0-9_-]+$/.test(content.id)) {
throw new Error(
"Markdown heading IDs must contain only letters, digits, underscores or hyphens",
);
}
if (ids.has(content.id)) {
throw new Error(`Duplicate Markdown heading ID: ${content.id}`);
}
ids.add(content.id);
blocks.push(`<a name="${content.id}"></a>`);
}
blocks.push(`${"#".repeat(level)} ${content.title}`);
render(content.body, level + 1);
}
Expand Down Expand Up @@ -105,9 +119,9 @@
}

/** Wraps a Markdown block in a GitHub details element with a plain-text summary. */
export function details(summary: string, body: string): string {
export function details(summary: string, body: string, open = false): string {
return [
`<details><summary>${escapeHtml(summary)}</summary>`,
`<details${open ? " open" : ""}><summary>${escapeHtml(summary)}</summary>`,
"",
...(body ? [body] : []),
"",
Expand Down
8 changes: 8 additions & 0 deletions .github/shared/src/sdk-types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import * as z from "zod";

/**
Expand Down Expand Up @@ -92,3 +92,11 @@
buildFailed: undefined,
},
};

export function getSdkLanguage(repo: SdkName): string {
const language = Object.entries(SdkName).find(([, repository]) => repository === repo)?.[0];
if (!language) {
throw new Error(`Unsupported SDK repository: ${repo}`);
}
return language === "Js" ? "JavaScript" : language === "Net" ? "DotNet" : language;
}
82 changes: 82 additions & 0 deletions .github/shared/test/markdown.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import { marked } from "marked";
import { describe, expect, it } from "vitest";
import {
Expand Down Expand Up @@ -47,6 +47,81 @@
expect(renderMarkdownDoc(section("Title", "Body"), 6)).toBe("###### Title\n\nBody");
});

it("preserves an explicit section ID and omits it when not supplied", () => {
expect(section("Title", "Body", "custom-id")).toEqual({
kind: "section",
title: "Title",
body: "Body",
id: "custom-id",
});
expect(section("Title", "Body")).not.toHaveProperty("id");
expect(section("Title", "Body", undefined)).not.toHaveProperty("id");
});

it("renders explicit anchors before headings without changing heading levels", () => {
const markdown = renderMarkdownDoc(
[
section(
"Analysis",
["Body", section("Details", "Changes", "details_123")],
"breaking-change",
),
section("Mitigation", undefined, "Mitigation"),
section("Without an ID", "Last"),
],
2,
);
expect(markdown).toBe(d`
<a name="breaking-change"></a>

## Analysis

Body

<a name="details_123"></a>

### Details

Changes

<a name="Mitigation"></a>

## Mitigation

## Without an ID

Last
`);
expect(marked.parse(markdown)).toContain(
'<p><a name="breaking-change"></a></p>\n<h2>Analysis</h2>',
);
});

it.each(["", "has space", 'quote"id', "<tag>", "with/slash", "line\nbreak"])(
"rejects invalid heading ID %j",
(id) => {
expect(() => renderMarkdownDoc(section("Title", "Body", id))).toThrow(
"Markdown heading IDs must contain only letters, digits, underscores or hyphens",
);
},
);

it.each([
{ doc: [section("First", "", "same-id"), section("Second", "", "same-id")] },
{ doc: section("Parent", section("Child", "", "same-id"), "same-id") },
])("rejects duplicate IDs across the document %#", ({ doc }) => {
expect(() => renderMarkdownDoc(doc)).toThrow("Duplicate Markdown heading ID: same-id");
});

it("allows repeated titles with distinct IDs and reuses IDs in separate renders", () => {
expect(renderMarkdownDoc([section("Title", "", "first"), section("Title", "", "second")])).toBe(
'<a name="first"></a>\n\n# Title\n\n<a name="second"></a>\n\n# Title',
);
const doc = section("Title", "", "reusable");
expect(renderMarkdownDoc(doc)).toBe('<a name="reusable"></a>\n\n# Title');
expect(renderMarkdownDoc(doc)).toBe('<a name="reusable"></a>\n\n# Title');
});

it.each([0, -1, 1.5, 7])("rejects invalid heading level %s", (level) => {
expect(() => renderMarkdownDoc(section("Title", ""), level)).toThrow("level from 1 to 6");
});
Expand Down Expand Up @@ -175,4 +250,11 @@
`);
expect(details("Empty", "")).toBe("<details><summary>Empty</summary>\n\n\n</details>");
});

it("supports expanded details without changing the default collapsed behavior", () => {
expect(details("<Changes>", "Body", true)).toBe(
"<details open><summary>&lt;Changes&gt;</summary>\n\nBody\n\n</details>",
);
expect(details("Changes", "Body", false)).toBe(details("Changes", "Body"));
});
});
24 changes: 23 additions & 1 deletion .github/shared/test/sdk-types.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,30 @@
import { describe, expect, it } from "vitest";
import { sdkLabels, SpecGenSdkArtifactInfoSchema } from "../src/sdk-types.ts";
import {
getSdkLanguage,
sdkLabels,
SdkName,
SpecGenSdkArtifactInfoSchema,
} from "../src/sdk-types.ts";
import { createMockSpecGenSdkArtifactInfo } from "./sdk-types.ts";

describe("sdk-types", () => {
it.each([
[SdkName.Go, "Go"],
[SdkName.Java, "Java"],
[SdkName.Js, "JavaScript"],
[SdkName.Net, "DotNet"],
[SdkName.Python, "Python"],
[SdkName.Rust, "Rust"],
])("returns the language name for %s", (repo, language) => {
expect(getSdkLanguage(repo)).toBe(language);
});

it("rejects unsupported SDK repositories", () => {
expect(() => getSdkLanguage("unknown-repository" as SdkName)).toThrow(
"Unsupported SDK repository: unknown-repository",
);
});

it("defines sdkLabels", () => {
// Ensures constant "sdkLabels" is considered "covered" by codecov
expect(sdkLabels).toBeDefined();
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/github-test.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
name: GitHub Actions - Test

on:
Expand All @@ -11,6 +11,7 @@
- pnpm-lock.yaml
- pnpm-workspace.yaml
- vitest.config.mts
- eng/tools/spec-gen-sdk-runner/**
- eng/tools/vitest.base.config.ts
- .npmrc
pull_request:
Expand All @@ -21,6 +22,7 @@
- pnpm-lock.yaml
- pnpm-workspace.yaml
- vitest.config.mts
- eng/tools/spec-gen-sdk-runner/**
- eng/tools/vitest.base.config.ts
- .npmrc
workflow_dispatch:
Expand Down Expand Up @@ -58,6 +60,7 @@
persist-credentials: false
sparse-checkout: |
.github
eng/tools/spec-gen-sdk-runner

- if: ${{ github.event_name == 'pull_request' && matrix.os == 'ubuntu' }}
name: Require compiled agentic workflow locks
Expand Down
Loading
Loading