Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
81beaef
cutover PR
scbedd Aug 5, 2025
d3f1ca6
Updated tag value for the Timezone Service to conform to standards. (…
stevemunk Aug 5, 2025
04874ac
Updated tag value for the Spatial Service to conform to standards. (#…
stevemunk Aug 5, 2025
45b424c
Updated tag values for Weather Service to conform to standards. (#35979)
stevemunk Aug 5, 2025
9436152
Updated tag value for the Route Service to conform to standards. (#36…
stevemunk Aug 5, 2025
de5e378
Updated tag value for the Geolocation Service to conform to standards…
stevemunk Aug 5, 2025
4cf6f80
Flipped .net required settings to false (#36465)
raych1 Aug 5, 2025
585d408
Search readme (#36038)
stevemunk Aug 5, 2025
0706188
Updated tag values for the Data Registry Service to conform to standa…
stevemunk Aug 6, 2025
e9d78a9
Updated tag value for Creator services to conform to standards. (#36045)
stevemunk Aug 6, 2025
14258ac
Bump @azure-tools/typespec-client-generator-cli (#36471)
dependabot[bot] Aug 6, 2025
dfd89be
Bump zod from 4.0.14 to 4.0.15 in /.github (#36470)
dependabot[bot] Aug 6, 2025
2a6e9b6
[databoxedge][python] Convert to singleapi (#35688)
msyyc Aug 6, 2025
eb75e08
Fix Go SDK breaking changes for Nginx (#36328)
tadelesh Aug 6, 2025
d880151
Add github summary report (#36422)
pshao25 Aug 6, 2025
cee8b51
Update data-plane tspconfig is-modular-library (#35728)
v-jiaodi Aug 6, 2025
457a3dc
Add conditions to trigger TypeSpec Migration Validation (#36482)
melina5656 Aug 6, 2025
fd14567
Update the Nginx Typespec (#36473)
ArthurMa1978 Aug 6, 2025
0e32c07
Allow summarize-checks to handle huge number of triggered checkruns f…
scbedd Aug 6, 2025
04214f1
when extracting `Summarize PR Impact` workflowrunId, we should only e…
scbedd Aug 6, 2025
4901544
Source user object id directly instead of with graph (#36464)
azure-sdk Aug 6, 2025
881ba93
[context.js] Flow head-sha like issue-number (#36479)
mikeharder Aug 6, 2025
a07a5c2
Added more information to SDK PR description and updatedthe PR creati…
raych1 Aug 6, 2025
3bfc547
[BreakingChanges] Delete "watch" workflows (used for migration) (#36504)
mikeharder Aug 6, 2025
98c8aa1
[ARM Auto Signoff] Use statuses for LintDiff and Avocado (#36472)
mikeharder Aug 7, 2025
4b00173
Revert "Update the Nginx Typespec (#36473)" (#36508)
mikeharder Aug 7, 2025
54b1fe1
Bump @azure-tools/typespec-client-generator-core (#36505)
dependabot[bot] Aug 7, 2025
fb6e96b
[azurestackhcivm] Update tsp config (#35961)
ChenxiJiang333 Aug 7, 2025
5bbb162
[Azure Container Apps] Use OK response for code execution (#35488)
yitaopan Aug 7, 2025
18f2567
Add definition check to tsmv report (#36483)
pshao25 Aug 7, 2025
b88038e
java mgmt, add directive to fix search (#36239)
XiaofeiCao Aug 7, 2025
b5560b7
refactor(edgeorder): migrate to unified folder structure (#36171)
qiaozha Aug 7, 2025
9099120
Exclude "Automated merging requirements met" when getting list of req…
mikeharder Aug 7, 2025
64b80b1
Delete specification/maps/data-plane/Microsoft.Maps/Render/preview/2.…
FarazGIS Aug 7, 2025
8b4ba26
merge main
scbedd Aug 7, 2025
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
6 changes: 3 additions & 3 deletions .github/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions .github/shared/src/git.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// @ts-check

/**
* Returns true if a string is a possible full git SHA (40 hex chars, case insensitive)
*
* @param {string} string
* @returns {boolean}
*/
export function isFullGitSha(string) {
return /^[0-9a-f]{40}$/i.test(string);
}
2 changes: 2 additions & 0 deletions .github/shared/test/examples.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// @ts-check

export const fullGitSha = "abc123abc123abc123abc123abc123abc123abc1";

export const swaggerHandWritten = JSON.stringify("foo");

export const swaggerTypeSpecGenerated = JSON.stringify({
Expand Down
25 changes: 25 additions & 0 deletions .github/shared/test/git.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// @ts-check

import { describe, expect, it } from "vitest";
import { isFullGitSha } from "../src/git";
import { fullGitSha } from "./examples";

describe("git", () => {
it.each([
[undefined, false],
[null, false],
["", false],
// Short SHAs of 7 chars are not valid
["abc1234", false],
// Invalid hex chars
["aBcDeG0189".repeat(4), false],
["aBcDe 0189".repeat(4), false],
["aBcDe_0189".repeat(4), false],
// Valid
["aBcDeF0189".repeat(4), true],
[fullGitSha, true],
])("isFullGitSha(%o) => %o", (string, result) => {
// @ts-expect-error Testing invalid input types
expect(isFullGitSha(string)).toBe(result);
});
});
7 changes: 7 additions & 0 deletions .github/workflows/_reusable-set-check-status.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# Prefix with "~" to sort last in Actions list
name: ~Templates - Set Run Status

Expand Down Expand Up @@ -68,6 +68,13 @@
'${{ inputs.overriding_label }}'
);

- if: ${{ always() && steps.set-status.outputs.head_sha }}
name: Upload artifact with head SHA
uses: ./.github/actions/add-empty-artifact
with:
name: head-sha
value: ${{ steps.set-status.outputs.head_sha }}

- if: ${{ always() && steps.set-status.outputs.issue_number }}
name: Upload artifact with issue number
uses: ./.github/actions/add-empty-artifact
Expand Down
39 changes: 23 additions & 16 deletions .github/workflows/arm-auto-signoff.yaml
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
name: ARM Auto SignOff

on:
issue_comment:
types:
- edited
# Must run on pull_request_target instead of pull_request, since the latter cannot trigger on
# labels from bot accounts in fork PRs. pull_request_target is also more similar to the other
# triggers "issue_comment" and "workflow_run" -- they are all privileged# and run in the target
# branch and repo -- which simplifies implementation.
# trigger "workflow_run" -- they are both privileged and run in the target branch and repo --
# which simplifies implementation.
pull_request_target:
types:
# Depends on labels, so must re-evaluate whenever a relevant label is manually added or removed.
- labeled
- unlabeled
workflow_run:
workflows: ["ARM Incremental TypeSpec"]
workflows:
["ARM Incremental TypeSpec", "Swagger Avocado - Set Status", "Swagger LintDiff - Set Status"]
types: [completed]

permissions:
Expand All @@ -28,9 +26,8 @@
arm-auto-signoff:
name: ARM Auto SignOff

# workflow_run - already filtered by triggers above
# pull_request_target:labeled - filter to only the input and output labels
# issue_comment:edited - filter to only PR comments containing "next steps to merge",
# a signal that checks like "Swagger LintDiff" or "Swagger Avocado" status may have changed
if: |
github.event_name == 'workflow_run' ||
(github.event_name == 'pull_request_target' &&
Expand All @@ -41,10 +38,7 @@
github.event.label.name == 'ARMReview' ||
github.event.label.name == 'ARMSignedOff' ||
github.event.label.name == 'NotReadyForARMReview' ||
github.event.label.name == 'SuppressionReviewRequired')) ||
(github.event_name == 'issue_comment' &&
github.event.issue.pull_request &&
contains(github.event.comment.body, 'next steps to merge'))
github.event.label.name == 'SuppressionReviewRequired'))

runs-on: ubuntu-24.04

Expand Down Expand Up @@ -97,15 +91,28 @@
# Convert "add/remove" to "true/false"
value: "${{ fromJson(steps.get-label-action.outputs.result).labelAction == 'add' }}"

# Required for consumers to identify the head SHA associated with this workflow run.
# Output can be trusted, because it was uploaded from a workflow that is trusted,
# because "issue_comment", and "workflow_run" only trigger on workflows in the default branch.
# Consumers should verify the "event_name" before attempting to extract from the artifact name.
- if: |
always() &&
(github.event_name == 'issue_comment' || github.event_name == 'workflow_run') &&
fromJson(steps.get-label-action.outputs.result).headSha
name: Upload artifact with head SHA
uses: ./.github/actions/add-empty-artifact
with:
name: "head-sha"
value: "${{ fromJson(steps.get-label-action.outputs.result).headSha }}"

# Required for consumers to identify the PR associated with this workflow run.
# Output can be trusted, because it was uploaded from a workflow that is trusted,
# because "issue_comment", and "workflow_run" only trigger on workflows in the default branch.
# Consumers should verify the "event_name" before attempting to extract from the artifact name.
- if: |
(github.event_name == 'issue_comment' ||
github.event_name == 'workflow_run') &&
(fromJson(steps.get-label-action.outputs.result).labelAction == 'add' ||
fromJson(steps.get-label-action.outputs.result).labelAction == 'remove')
always() &&
(github.event_name == 'issue_comment' || github.event_name == 'workflow_run') &&
fromJson(steps.get-label-action.outputs.result).issueNumber > 0
name: Upload artifact with issue number
uses: ./.github/actions/add-empty-artifact
with:
Expand Down
7 changes: 7 additions & 0 deletions .github/workflows/breaking-change-add-label-artifacts.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
name: "Breaking Change - Add Label Artifacts"

on:
Expand Down Expand Up @@ -62,6 +62,13 @@
name: "${{ steps.get-label-actions.outputs.versioningReviewLabelName }}"
value: "${{ steps.get-label-actions.outputs.versioningReviewLabelValue == 'true' }}"

- if: ${{ always() && steps.get-label-actions.outputs.head_sha }}
name: Upload artifact with head SHA
uses: ./.github/actions/add-empty-artifact
with:
name: head-sha
value: ${{ steps.get-label-actions.outputs.head_sha }}

- if: ${{ always() && steps.get-label-actions.outputs.issue_number > 0 }}
name: Upload artifact with issue number
uses: ./.github/actions/add-empty-artifact
Expand Down
12 changes: 8 additions & 4 deletions .github/workflows/sdk-breaking-change-labels.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
name: SDK Breaking Change Labels

on:
Expand Down Expand Up @@ -58,10 +58,14 @@
# Convert "add/remove" to "true/false"
value: "${{ fromJson(steps.get-label-and-action.outputs.result).labelAction == 'add' }}"

- if: |
((fromJson(steps.get-label-and-action.outputs.result).labelAction == 'add' ||
fromJson(steps.get-label-and-action.outputs.result).labelAction == 'remove') &&
fromJson(steps.get-label-and-action.outputs.result).issueNumber > 0)
- if: ${{ always() && fromJson(steps.get-label-and-action.outputs.result).headSha }}
name: Upload artifact with issue number
uses: ./.github/actions/add-empty-artifact
with:
name: "head-sha"
value: "${{ fromJson(steps.get-label-and-action.outputs.result).headSha }}"

- if: ${{ always() && fromJson(steps.get-label-and-action.outputs.result).issueNumber > 0 }}
name: Upload artifact with issue number
uses: ./.github/actions/add-empty-artifact
with:
Expand Down
7 changes: 7 additions & 0 deletions .github/workflows/spec-gen-sdk-status.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
name: "SDK Validation Status"

on:
Expand Down Expand Up @@ -48,6 +48,13 @@
(await import('${{ github.workspace }}/.github/workflows/src/spec-gen-sdk-status.js')).default;
return await setStatus({ github, context, core });

- if: ${{ always() && steps.sdk-validation-status.outputs.head_sha }}
name: Upload artifact with head SHA
uses: ./.github/actions/add-empty-artifact
with:
name: head-sha
value: ${{ steps.sdk-validation-status.outputs.head_sha }}

- if: ${{ always() && steps.sdk-validation-status.outputs.issue_number }}
name: Upload artifact with issue number
uses: ./.github/actions/add-empty-artifact
Expand Down
71 changes: 43 additions & 28 deletions .github/workflows/src/arm-auto-signoff.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// @ts-check

import { setEquals } from "../../shared/src/equality.js";
import { PER_PAGE_MAX } from "../../shared/src/github.js";
import { CommitStatusState, PER_PAGE_MAX } from "../../shared/src/github.js";
import { byDate, invert } from "../../shared/src/sort.js";
import { extractInputs } from "./context.js";
import { LabelAction } from "./label.js";

Expand Down Expand Up @@ -33,20 +34,23 @@
* @param {string} params.head_sha
* @param {(import("@octokit/core").Octokit & import("@octokit/plugin-rest-endpoint-methods/dist-types/types.js").Api & { paginate: import("@octokit/plugin-paginate-rest").PaginateInterface; })} params.github
* @param {typeof import("@actions/core")} params.core
* @returns {Promise<{labelAction: LabelAction, issueNumber: number}>}
* @returns {Promise<{labelAction: LabelAction, headSha: string, issueNumber: number}>}
*/
export async function getLabelActionImpl({ owner, repo, issue_number, head_sha, github, core }) {
const labelActions = {
[LabelAction.None]: {
labelAction: LabelAction.None,
headSha: head_sha,
issueNumber: issue_number,
},
[LabelAction.Add]: {
labelAction: LabelAction.Add,
headSha: head_sha,
issueNumber: issue_number,
},
[LabelAction.Remove]: {
labelAction: LabelAction.Remove,
headSha: head_sha,
issueNumber: issue_number,
},
};
Expand Down Expand Up @@ -139,52 +143,63 @@
return removeAction;
}

const checkRuns = await github.paginate(github.rest.checks.listForRef, {
const statuses = await github.paginate(github.rest.repos.listCommitStatusesForRef, {
owner: owner,
repo: repo,
ref: head_sha,
per_page: PER_PAGE_MAX,
});

const requiredCheckNames = ["Swagger LintDiff", "Swagger Avocado"];
core.info("Statuses:");
statuses.forEach((status) => {
core.info(`- ${status.context}: ${status.state}`);
});

const requiredStatusNames = ["Swagger LintDiff", "Swagger Avocado"];

/**
* @type {typeof checkRuns.check_runs}
* @type {typeof statuses}
*/
let requiredCheckRuns = [];

for (const checkName of requiredCheckNames) {
const matchingRuns = checkRuns.filter((run) => run.name === checkName);

if (matchingRuns.length > 1) {
throw new Error(`Unexpected number of checks named '${checkName}': ${matchingRuns.length}`);
}

const matchingRun = matchingRuns.length === 1 ? matchingRuns[0] : undefined;

core.info(
`${checkName}: Status='${matchingRun?.status}', Conclusion='${matchingRun?.conclusion}'`,
);

if (matchingRun && matchingRun.status === "completed" && matchingRun.conclusion !== "success") {
core.info(`Check '${checkName}' did not succeed`);
let requiredStatuses = [];

for (const statusName of requiredStatusNames) {
// The "statuses" array may contain multiple statuses with the same "context" (aka "name"),
// but different states and update times. We only care about the latest.
const matchingStatuses = statuses
.filter((status) => status.context.toLowerCase() === statusName.toLowerCase())
.sort(invert(byDate((status) => status.updated_at)));

// undefined if matchingStatuses.length === 0 (which is OK)
const matchingStatus = matchingStatuses[0];

core.info(`${statusName}: State='${matchingStatus?.state}'`);

if (
matchingStatus &&
(matchingStatus.state === CommitStatusState.ERROR ||
matchingStatus.state === CommitStatusState.FAILURE)
) {
core.info(`Status '${matchingStatus}' did not succeed`);
return removeAction;
}

if (matchingRun) {
requiredCheckRuns.push(matchingRun);
if (matchingStatus) {
requiredStatuses.push(matchingStatus);
}
}

if (
setEquals(new Set(requiredCheckRuns.map((run) => run.name)), new Set(requiredCheckNames)) &&
requiredCheckRuns.every((run) => run.status === "completed" && run.conclusion === "success")
setEquals(
new Set(requiredStatuses.map((status) => status.context)),
new Set(requiredStatusNames),
) &&
requiredStatuses.every((status) => status.state === CommitStatusState.SUCCESS)
) {
core.info("All requirements met for auto-signoff");
return labelActions[LabelAction.Add];
}

// If any checks are missing or not completed, no-op to prevent frequent remove/add label as checks re-run
core.info("One or more checks are still in-progress");
// If any statuses are missing or pending, no-op to prevent frequent remove/add label as checks re-run
core.info("One or more statuses are still pending");
return labelActions[LabelAction.None];
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export default async function getLabelActions({ github, context, core }) {
})
).map((a) => a.name);

core.setOutput("head_sha", head_sha);
core.setOutput("issue_number", issue_number);

if (
Expand Down
Loading
Loading