From d18f97ea109632098f2e0b460b061471c6598e25 Mon Sep 17 00:00:00 2001 From: haiyuan_zhang Date: Tue, 28 Jul 2026 14:25:50 +0800 Subject: [PATCH 1/5] Enable client SDK rules in benchmarks Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 69a89a25-1dfb-49ad-8531-961ad52b80f6 --- packages/benchmark/README.md | 1 + packages/benchmark/external-spec/compute/tspconfig.yaml | 1 + packages/benchmark/external-spec/network/tspconfig.yaml | 1 + packages/benchmark/external-spec/web/tspconfig.yaml | 1 + .../benchmark/specs/azure-arm-resource-manager/tspconfig.yaml | 1 + packages/benchmark/specs/azure-core-dataplane/tspconfig.yaml | 1 + packages/benchmark/specs/azure-full/tspconfig.yaml | 1 + 7 files changed, 7 insertions(+) diff --git a/packages/benchmark/README.md b/packages/benchmark/README.md index db520ed454..c8b51d17af 100644 --- a/packages/benchmark/README.md +++ b/packages/benchmark/README.md @@ -176,6 +176,7 @@ emit: linter: extends: - "@azure-tools/typespec-azure-rulesets/resource-manager" + - "@azure-tools/typespec-azure-rulesets/client-sdk" ``` Run the external specs (fewer iterations, since they are heavy): diff --git a/packages/benchmark/external-spec/compute/tspconfig.yaml b/packages/benchmark/external-spec/compute/tspconfig.yaml index f562b813f2..7f0ee9b0a0 100644 --- a/packages/benchmark/external-spec/compute/tspconfig.yaml +++ b/packages/benchmark/external-spec/compute/tspconfig.yaml @@ -3,3 +3,4 @@ emit: linter: extends: - "@azure-tools/typespec-azure-rulesets/resource-manager" + - "@azure-tools/typespec-azure-rulesets/client-sdk" diff --git a/packages/benchmark/external-spec/network/tspconfig.yaml b/packages/benchmark/external-spec/network/tspconfig.yaml index f562b813f2..7f0ee9b0a0 100644 --- a/packages/benchmark/external-spec/network/tspconfig.yaml +++ b/packages/benchmark/external-spec/network/tspconfig.yaml @@ -3,3 +3,4 @@ emit: linter: extends: - "@azure-tools/typespec-azure-rulesets/resource-manager" + - "@azure-tools/typespec-azure-rulesets/client-sdk" diff --git a/packages/benchmark/external-spec/web/tspconfig.yaml b/packages/benchmark/external-spec/web/tspconfig.yaml index f562b813f2..7f0ee9b0a0 100644 --- a/packages/benchmark/external-spec/web/tspconfig.yaml +++ b/packages/benchmark/external-spec/web/tspconfig.yaml @@ -3,3 +3,4 @@ emit: linter: extends: - "@azure-tools/typespec-azure-rulesets/resource-manager" + - "@azure-tools/typespec-azure-rulesets/client-sdk" diff --git a/packages/benchmark/specs/azure-arm-resource-manager/tspconfig.yaml b/packages/benchmark/specs/azure-arm-resource-manager/tspconfig.yaml index 908847b1c7..847bd3ca4b 100644 --- a/packages/benchmark/specs/azure-arm-resource-manager/tspconfig.yaml +++ b/packages/benchmark/specs/azure-arm-resource-manager/tspconfig.yaml @@ -11,3 +11,4 @@ options: linter: extends: - "@azure-tools/typespec-azure-rulesets/resource-manager" + - "@azure-tools/typespec-azure-rulesets/client-sdk" diff --git a/packages/benchmark/specs/azure-core-dataplane/tspconfig.yaml b/packages/benchmark/specs/azure-core-dataplane/tspconfig.yaml index 5c18ca0802..f4b411ca7f 100644 --- a/packages/benchmark/specs/azure-core-dataplane/tspconfig.yaml +++ b/packages/benchmark/specs/azure-core-dataplane/tspconfig.yaml @@ -12,3 +12,4 @@ options: linter: extends: - "@azure-tools/typespec-azure-rulesets/data-plane" + - "@azure-tools/typespec-azure-rulesets/client-sdk" diff --git a/packages/benchmark/specs/azure-full/tspconfig.yaml b/packages/benchmark/specs/azure-full/tspconfig.yaml index 30c5d09e52..d85cbcbac8 100644 --- a/packages/benchmark/specs/azure-full/tspconfig.yaml +++ b/packages/benchmark/specs/azure-full/tspconfig.yaml @@ -13,3 +13,4 @@ options: linter: extends: - "@azure-tools/typespec-azure-rulesets/data-plane" + - "@azure-tools/typespec-azure-rulesets/client-sdk" From cad9da6fd066a2a6fb0f187e9b3de7c8805bc128 Mon Sep 17 00:00:00 2001 From: haiyuan_zhang Date: Tue, 28 Jul 2026 15:01:22 +0800 Subject: [PATCH 2/5] Add benchmark linter rule selector Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 69a89a25-1dfb-49ad-8531-961ad52b80f6 --- .../benchmarks/benchmark-dashboard.css | 4 + .../benchmarks/benchmark-dashboard.tsx | 85 +++++++++++++++++-- 2 files changed, 81 insertions(+), 8 deletions(-) diff --git a/website/src/components/benchmarks/benchmark-dashboard.css b/website/src/components/benchmarks/benchmark-dashboard.css index 088f7cd906..fb6363a14a 100644 --- a/website/src/components/benchmarks/benchmark-dashboard.css +++ b/website/src/components/benchmarks/benchmark-dashboard.css @@ -128,6 +128,10 @@ position: relative; } +.chartControls { + margin-bottom: 0.5rem; +} + /* Emitter sections */ .emitterSection { margin-bottom: 2rem; diff --git a/website/src/components/benchmarks/benchmark-dashboard.tsx b/website/src/components/benchmarks/benchmark-dashboard.tsx index f75c4f6862..1acbd6705e 100644 --- a/website/src/components/benchmarks/benchmark-dashboard.tsx +++ b/website/src/components/benchmarks/benchmark-dashboard.tsx @@ -105,6 +105,7 @@ function shortLabel(label: string): string { .replace(/^emit\//, "") .replace(/@azure-tools\/typespec-azure-core\//, "azure-core/") .replace(/@azure-tools\/typespec-azure-resource-manager\//, "arm/") + .replace(/@azure-tools\/typespec-client-generator-core\//, "tcgc/") .replace(/@azure-tools\/typespec-autorest/, "autorest") .replace(/@typespec\/openapi3/, "openapi3") .replace(/@typespec\//, ""); @@ -121,19 +122,27 @@ function seriesColors(count: number): string[] { } /** Parse URL search params to get initial state */ -function getInitialParams(): { tab: Tab; spec: string; range: TimeRange; dataset: Dataset } { +function getInitialParams(): { + tab: Tab; + spec: string; + range: TimeRange; + dataset: Dataset; + rule: string; +} { if (typeof window === "undefined") - return { tab: "stages", spec: "all", range: "all", dataset: "main" }; + return { tab: "stages", spec: "all", range: "all", dataset: "main", rule: "" }; const params = new URLSearchParams(window.location.search); const tab = (params.get("tab") as Tab) || "stages"; const spec = params.get("spec") || "all"; const range = (params.get("range") as TimeRange) || "all"; const dataset = (params.get("dataset") as Dataset) || "main"; + const rule = params.get("rule") || ""; return { tab: TABS.some((t) => t.key === tab) ? tab : "stages", spec, range: TIME_RANGES.some((r) => r.key === range) ? range : "all", dataset: dataset === "external" ? "external" : "main", + rule, }; } @@ -308,12 +317,41 @@ interface ChartSection { filter: (label: string) => boolean; } -function BenchmarkChart({ data, section }: { data: FilteredData; section: ChartSection }) { +function BenchmarkChart({ + data, + section, + selectedMetric, + onSelectedMetric, +}: { + data: FilteredData; + section: ChartSection; + selectedMetric?: string; + onSelectedMetric?: (metric: string) => void; +}) { const metricLabels = useMemo( () => data.labels.filter(section.filter).sort(), [data, section.filter], ); + const effectiveSelectedMetric = + selectedMetric && metricLabels.includes(selectedMetric) ? selectedMetric : metricLabels[0]; + + useEffect(() => { + if ( + onSelectedMetric && + effectiveSelectedMetric && + effectiveSelectedMetric !== selectedMetric + ) { + onSelectedMetric(effectiveSelectedMetric); + } + }, [effectiveSelectedMetric, onSelectedMetric, selectedMetric]); + + const displayedMetricLabels = onSelectedMetric + ? effectiveSelectedMetric + ? [effectiveSelectedMetric] + : [] + : metricLabels; + const points = useMemo( () => data.entries.map((e) => ({ commit: e.commit, timestamp: e.timestamp })), [data], @@ -321,16 +359,38 @@ function BenchmarkChart({ data, section }: { data: FilteredData; section: ChartS const series = useMemo( () => - metricLabels.map((label) => ({ + displayedMetricLabels.map((label) => ({ label: shortLabel(label), data: data.entries.map((e) => e.metrics[label] ?? null), })), - [data, metricLabels], + [data, displayedMetricLabels], ); if (metricLabels.length === 0) return null; - return ; + return ( + <> + {onSelectedMetric && effectiveSelectedMetric && ( +
+
+ Rule: + +
+
+ )} + + + ); } function MetricSummary({ data }: { data: FilteredData }) { @@ -614,6 +674,7 @@ export function BenchmarkDashboard() { const [selectedSpec, setSelectedSpec] = useState(initialParams.spec); const [timeRange, setTimeRange] = useState(initialParams.range); const [dataset, setDataset] = useState(initialParams.dataset); + const [selectedLinterRule, setSelectedLinterRule] = useState(initialParams.rule); const historyUrl = useMemo(() => getHistoryUrl(dataset), [dataset]); @@ -642,8 +703,14 @@ export function BenchmarkDashboard() { // Sync state to URL useEffect(() => { - updateUrlParams({ tab: activeTab, spec: selectedSpec, range: timeRange, dataset }); - }, [activeTab, selectedSpec, timeRange, dataset]); + updateUrlParams({ + tab: activeTab, + spec: selectedSpec, + range: timeRange, + dataset, + rule: selectedLinterRule, + }); + }, [activeTab, selectedSpec, timeRange, dataset, selectedLinterRule]); // Derive filtered data const filteredData: FilteredData | null = useMemo(() => { @@ -813,6 +880,8 @@ export function BenchmarkDashboard() { {activeTab === "linter" && ( l.startsWith("linter/") && l !== "linter", From b21ac7e2a9ce1ce2bd6e82039c59a13f546adf91 Mon Sep 17 00:00:00 2001 From: haiyuan_zhang Date: Tue, 28 Jul 2026 15:06:38 +0800 Subject: [PATCH 3/5] Format benchmark rule selector Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 69a89a25-1dfb-49ad-8531-961ad52b80f6 --- website/src/components/benchmarks/benchmark-dashboard.tsx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/website/src/components/benchmarks/benchmark-dashboard.tsx b/website/src/components/benchmarks/benchmark-dashboard.tsx index 1acbd6705e..6279498cb4 100644 --- a/website/src/components/benchmarks/benchmark-dashboard.tsx +++ b/website/src/components/benchmarks/benchmark-dashboard.tsx @@ -337,11 +337,7 @@ function BenchmarkChart({ selectedMetric && metricLabels.includes(selectedMetric) ? selectedMetric : metricLabels[0]; useEffect(() => { - if ( - onSelectedMetric && - effectiveSelectedMetric && - effectiveSelectedMetric !== selectedMetric - ) { + if (onSelectedMetric && effectiveSelectedMetric && effectiveSelectedMetric !== selectedMetric) { onSelectedMetric(effectiveSelectedMetric); } }, [effectiveSelectedMetric, onSelectedMetric, selectedMetric]); From 41a66ef2750b5641a80c747c8e8cbb2965632d1e Mon Sep 17 00:00:00 2001 From: haiyuan_zhang Date: Tue, 28 Jul 2026 16:41:50 +0800 Subject: [PATCH 4/5] Revert "Format benchmark rule selector" This reverts commit b21ac7e2a9ce1ce2bd6e82039c59a13f546adf91. --- website/src/components/benchmarks/benchmark-dashboard.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/website/src/components/benchmarks/benchmark-dashboard.tsx b/website/src/components/benchmarks/benchmark-dashboard.tsx index 6279498cb4..1acbd6705e 100644 --- a/website/src/components/benchmarks/benchmark-dashboard.tsx +++ b/website/src/components/benchmarks/benchmark-dashboard.tsx @@ -337,7 +337,11 @@ function BenchmarkChart({ selectedMetric && metricLabels.includes(selectedMetric) ? selectedMetric : metricLabels[0]; useEffect(() => { - if (onSelectedMetric && effectiveSelectedMetric && effectiveSelectedMetric !== selectedMetric) { + if ( + onSelectedMetric && + effectiveSelectedMetric && + effectiveSelectedMetric !== selectedMetric + ) { onSelectedMetric(effectiveSelectedMetric); } }, [effectiveSelectedMetric, onSelectedMetric, selectedMetric]); From a2e089199cab19bf342d8d094563491b30162129 Mon Sep 17 00:00:00 2001 From: haiyuan_zhang Date: Tue, 28 Jul 2026 16:41:50 +0800 Subject: [PATCH 5/5] Revert "Add benchmark linter rule selector" This reverts commit cad9da6fd066a2a6fb0f187e9b3de7c8805bc128. --- .../benchmarks/benchmark-dashboard.css | 4 - .../benchmarks/benchmark-dashboard.tsx | 85 ++----------------- 2 files changed, 8 insertions(+), 81 deletions(-) diff --git a/website/src/components/benchmarks/benchmark-dashboard.css b/website/src/components/benchmarks/benchmark-dashboard.css index fb6363a14a..088f7cd906 100644 --- a/website/src/components/benchmarks/benchmark-dashboard.css +++ b/website/src/components/benchmarks/benchmark-dashboard.css @@ -128,10 +128,6 @@ position: relative; } -.chartControls { - margin-bottom: 0.5rem; -} - /* Emitter sections */ .emitterSection { margin-bottom: 2rem; diff --git a/website/src/components/benchmarks/benchmark-dashboard.tsx b/website/src/components/benchmarks/benchmark-dashboard.tsx index 1acbd6705e..f75c4f6862 100644 --- a/website/src/components/benchmarks/benchmark-dashboard.tsx +++ b/website/src/components/benchmarks/benchmark-dashboard.tsx @@ -105,7 +105,6 @@ function shortLabel(label: string): string { .replace(/^emit\//, "") .replace(/@azure-tools\/typespec-azure-core\//, "azure-core/") .replace(/@azure-tools\/typespec-azure-resource-manager\//, "arm/") - .replace(/@azure-tools\/typespec-client-generator-core\//, "tcgc/") .replace(/@azure-tools\/typespec-autorest/, "autorest") .replace(/@typespec\/openapi3/, "openapi3") .replace(/@typespec\//, ""); @@ -122,27 +121,19 @@ function seriesColors(count: number): string[] { } /** Parse URL search params to get initial state */ -function getInitialParams(): { - tab: Tab; - spec: string; - range: TimeRange; - dataset: Dataset; - rule: string; -} { +function getInitialParams(): { tab: Tab; spec: string; range: TimeRange; dataset: Dataset } { if (typeof window === "undefined") - return { tab: "stages", spec: "all", range: "all", dataset: "main", rule: "" }; + return { tab: "stages", spec: "all", range: "all", dataset: "main" }; const params = new URLSearchParams(window.location.search); const tab = (params.get("tab") as Tab) || "stages"; const spec = params.get("spec") || "all"; const range = (params.get("range") as TimeRange) || "all"; const dataset = (params.get("dataset") as Dataset) || "main"; - const rule = params.get("rule") || ""; return { tab: TABS.some((t) => t.key === tab) ? tab : "stages", spec, range: TIME_RANGES.some((r) => r.key === range) ? range : "all", dataset: dataset === "external" ? "external" : "main", - rule, }; } @@ -317,41 +308,12 @@ interface ChartSection { filter: (label: string) => boolean; } -function BenchmarkChart({ - data, - section, - selectedMetric, - onSelectedMetric, -}: { - data: FilteredData; - section: ChartSection; - selectedMetric?: string; - onSelectedMetric?: (metric: string) => void; -}) { +function BenchmarkChart({ data, section }: { data: FilteredData; section: ChartSection }) { const metricLabels = useMemo( () => data.labels.filter(section.filter).sort(), [data, section.filter], ); - const effectiveSelectedMetric = - selectedMetric && metricLabels.includes(selectedMetric) ? selectedMetric : metricLabels[0]; - - useEffect(() => { - if ( - onSelectedMetric && - effectiveSelectedMetric && - effectiveSelectedMetric !== selectedMetric - ) { - onSelectedMetric(effectiveSelectedMetric); - } - }, [effectiveSelectedMetric, onSelectedMetric, selectedMetric]); - - const displayedMetricLabels = onSelectedMetric - ? effectiveSelectedMetric - ? [effectiveSelectedMetric] - : [] - : metricLabels; - const points = useMemo( () => data.entries.map((e) => ({ commit: e.commit, timestamp: e.timestamp })), [data], @@ -359,38 +321,16 @@ function BenchmarkChart({ const series = useMemo( () => - displayedMetricLabels.map((label) => ({ + metricLabels.map((label) => ({ label: shortLabel(label), data: data.entries.map((e) => e.metrics[label] ?? null), })), - [data, displayedMetricLabels], + [data, metricLabels], ); if (metricLabels.length === 0) return null; - return ( - <> - {onSelectedMetric && effectiveSelectedMetric && ( -
-
- Rule: - -
-
- )} - - - ); + return ; } function MetricSummary({ data }: { data: FilteredData }) { @@ -674,7 +614,6 @@ export function BenchmarkDashboard() { const [selectedSpec, setSelectedSpec] = useState(initialParams.spec); const [timeRange, setTimeRange] = useState(initialParams.range); const [dataset, setDataset] = useState(initialParams.dataset); - const [selectedLinterRule, setSelectedLinterRule] = useState(initialParams.rule); const historyUrl = useMemo(() => getHistoryUrl(dataset), [dataset]); @@ -703,14 +642,8 @@ export function BenchmarkDashboard() { // Sync state to URL useEffect(() => { - updateUrlParams({ - tab: activeTab, - spec: selectedSpec, - range: timeRange, - dataset, - rule: selectedLinterRule, - }); - }, [activeTab, selectedSpec, timeRange, dataset, selectedLinterRule]); + updateUrlParams({ tab: activeTab, spec: selectedSpec, range: timeRange, dataset }); + }, [activeTab, selectedSpec, timeRange, dataset]); // Derive filtered data const filteredData: FilteredData | null = useMemo(() => { @@ -880,8 +813,6 @@ export function BenchmarkDashboard() { {activeTab === "linter" && ( l.startsWith("linter/") && l !== "linter",