Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
e9dc816
Add logic to auto-signoff open-api-specs with trivial changes
Nov 12, 2025
b9618b0
Updates based on comments, Refactor trivial check
Dec 4, 2025
71db523
Merge origin/main
Dec 4, 2025
be72bbb
Fix references with file move
Dec 4, 2025
056a31b
Fix invalid chars in upload artifact step
Dec 4, 2025
177dab9
Fix tests
Dec 5, 2025
422cd6a
Address comments, Add more tests
Dec 9, 2025
495559e
whitespace
mikeharder Dec 9, 2025
cf58b5d
Merge with main, Resolve conflicts
Dec 10, 2025
1a584be
Resolve merge conflict
Dec 10, 2025
189eaa8
minor changes based on comments
Dec 10, 2025
99b3e9c
rename step
mikeharder Dec 11, 2025
b55614c
Revert workflow title
mikeharder Dec 11, 2025
0cd5fdd
Revert workflow title
mikeharder Dec 11, 2025
6f96b9a
revert step title
mikeharder Dec 11, 2025
dfc2e2b
Refcatoring based on comments
Dec 11, 2025
d3f0d6a
Pull remote
Dec 11, 2025
40ae297
Merge branch 'main' into ailla/auto_signoff_trivial_changes
mikeharder Dec 11, 2025
7a97f5d
fix missing token error
Dec 11, 2025
46dbf3d
Merge branch 'ailla/auto_signoff_trivial_changes' of https://github.c…
Dec 11, 2025
ac95780
Merge branch 'main' into ailla/auto_signoff_trivial_changes
mikeharder Dec 11, 2025
9e903c0
Merge branch 'ailla/auto_signoff_trivial_changes' of https://github.c…
Dec 11, 2025
072d824
resolve merge conflict
mikeharder Dec 11, 2025
c653cde
Delete documentation/trivial-changes-auto-signoff.md
mikeharder Dec 11, 2025
ace0e72
Merge branch 'ailla/auto_signoff_trivial_changes' of https://github.c…
Dec 11, 2025
8370e9e
Merge branch 'main' into ailla/auto_signoff_trivial_changes
mikeharder Dec 11, 2025
9c07141
remove unhelpful comment
mikeharder Dec 11, 2025
55e2999
revert names
mikeharder Dec 11, 2025
8562b2a
Merge branch 'main' of https://github.com/Azure/azure-rest-api-specs …
Dec 11, 2025
839b12e
whitespace
mikeharder Dec 11, 2025
f1daaf8
ARM auto-signoff: trivial changes + managed label actions
Dec 16, 2025
6e7211a
Merge branch 'main' of https://github.com/Azure/azure-rest-api-specs …
Dec 16, 2025
52c85df
formatting
mikeharder Dec 16, 2025
9c77e73
yaml: "if" before "name"
mikeharder Dec 16, 2025
1146025
Refactor dryrun mode and just add trivial-test label, Update PRChange…
Dec 17, 2025
ef4eea1
Pull remote changes
Dec 17, 2025
710184e
Refactor, updates based on PR comments
Dec 19, 2025
0028fc2
Merge branch 'main' into ailla/auto_signoff_trivial_changes
mikeharder Jan 6, 2026
55ac6a5
Refactor pr-changes from struct to class, update the use cases, tests
Jan 6, 2026
d24335b
Merge branch 'ailla/auto_signoff_trivial_changes' of https://github.c…
Jan 6, 2026
827dffd
Merge branch 'main' of https://github.com/Azure/azure-rest-api-specs …
Jan 6, 2026
8b5b83a
Refactor naming, Fix lint errors
Jan 7, 2026
bef163e
Fix prettier errors
Jan 7, 2026
57cca4b
Fix prettier errors, Refactor trivial changes, minor updates
Jan 10, 2026
afa86d0
Merge branch 'main' of https://github.com/Azure/azure-rest-api-specs …
Jan 13, 2026
c9a2907
Fix prettier failures
Jan 13, 2026
902d29d
Merge branch 'main' of https://github.com/Azure/azure-rest-api-specs …
Jan 14, 2026
1816f7b
Merge branch 'main' of https://github.com/Azure/azure-rest-api-specs …
Jan 14, 2026
d8d3b38
Update log statements, Fix auto sign off label list
Jan 14, 2026
539cc10
Update trivial changes logic to evaluate functional changes
Jan 20, 2026
c5e62f8
Remove updated timeouts in test
Jan 20, 2026
f1bb347
Merge branch 'main' of https://github.com/Azure/azure-rest-api-specs …
Jan 21, 2026
41e4df1
Updates made to address feedback
Jan 22, 2026
e349a36
Fix prettier issue
Jan 22, 2026
8219f65
Merge branch 'main' of https://github.com/Azure/azure-rest-api-specs …
Jan 22, 2026
cccd378
fix space
Jan 22, 2026
b46058a
fix prettier issue
Jan 22, 2026
4977cd3
Merge branch 'main' into ailla/auto_signoff_trivial_changes
AkhilaIlla Jan 23, 2026
f940d86
Merge branch 'main' into ailla/auto_signoff_trivial_changes
AkhilaIlla Jan 26, 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
25 changes: 16 additions & 9 deletions .github/workflows/arm-auto-signoff-code.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
name: ARM Auto SignOff - Analyze Code

on:
Expand Down Expand Up @@ -28,7 +28,8 @@
steps:
- uses: actions/checkout@v6
with:
# Required to detect changed files in PR
# We compare HEAD (PR merge commit) against HEAD^ (base) via git diff,
# so we only need enough history to include the merge commit and its parent.
fetch-depth: 2
# Check only needs to view contents of changed files as a string, so can use
# "git show" on specific files instead of cloning whole repo
Expand All @@ -38,19 +39,25 @@
- name: Install dependencies for github-script actions
uses: ./.github/actions/install-deps-github-script

# Output is "true" if PR contains only incremental changes to an existing TypeSpec RP
- id: incremental-typespec
- id: arm-auto-signoff-code
name: ARM Auto SignOff - Analyze Code
uses: actions/github-script@v8
with:
result-encoding: string
result-encoding: json
script: |
const { default: incrementalTypeSpec } =
await import('${{ github.workspace }}/.github/workflows/src/arm-auto-signoff/arm-incremental-typespec.js');
return await incrementalTypeSpec({ github, context, core });
const { default: armAutoSignoffCode } =
await import('${{ github.workspace }}/.github/workflows/src/arm-auto-signoff/arm-auto-signoff-code.js');
return await armAutoSignoffCode({ github, context, core });

- name: Upload artifact with results
# Upload artifacts with individual results
- name: Upload artifact - ARM Auto Signoff Code Result (incremental)
uses: ./.github/actions/add-empty-artifact
with:
name: "incremental-typespec"
value: ${{ steps.incremental-typespec.outputs.result }}
value: ${{ fromJSON(steps.arm-auto-signoff-code.outputs.result).incremental }}

- name: Upload artifact - ARM Auto Signoff Code Result (trivial)
uses: ./.github/actions/add-empty-artifact
with:
name: "trivial-changes"
value: ${{ fromJSON(steps.arm-auto-signoff-code.outputs.result).trivial }}
42 changes: 26 additions & 16 deletions .github/workflows/arm-auto-signoff-status.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
name: ARM Auto SignOff - Set Status

on:
Expand Down Expand Up @@ -45,6 +45,8 @@
github.event.action == 'unlabeled') &&
(github.event.label.name == 'Approved-Suppression' ||
github.event.label.name == 'ARMAutoSignedOff' ||
github.event.label.name == 'ARMAutoSignedOff-IncrementalTSP' ||
github.event.label.name == 'ARMAutoSignedOff-Trivial-Test' ||
github.event.label.name == 'ARMReview' ||
github.event.label.name == 'ARMSignedOff' ||
github.event.label.name == 'NotReadyForARMReview' ||
Expand All @@ -69,8 +71,13 @@

# Output:
# {
# labelAction: LabelAction, ("none" for no-op, "add" to add label, and "remove" to remove label)
# issueNumber: number
# headSha: string,
# issueNumber: number,
# labelActions: {
# 'ARMSignedOff': 'none'|'add'|'remove',
# 'ARMAutoSignedOff-IncrementalTSP': 'none'|'add'|'remove',
# 'ARMAutoSignedOff-Trivial-Test': 'none'|'add'|'remove'
# }
# }
- id: get-label-action
name: ARM Auto SignOff - Set Status
Expand All @@ -81,25 +88,28 @@
await import('${{ github.workspace }}/.github/workflows/src/arm-auto-signoff/arm-auto-signoff-status.js');
return await getLabelAction({ github, context, core });

- if: |
fromJson(steps.get-label-action.outputs.result).labelAction == 'add' ||
fromJson(steps.get-label-action.outputs.result).labelAction == 'remove'
name: Upload artifact with results
# Add/remove specific auto sign-off labels based on analysis results.
# The action is explicit: 'add' | 'remove' | 'none'.
- if: fromJson(steps.get-label-action.outputs.result).labelActions['ARMSignedOff'] != 'none'
name: Upload artifact for ARMSignedOff label
uses: ./.github/actions/add-label-artifact
with:
name: "ARMAutoSignedOff"
# Convert "add/remove" to "true/false"
value: "${{ fromJson(steps.get-label-action.outputs.result).labelAction == 'add' }}"
name: "ARMSignedOff"
value: "${{ fromJson(steps.get-label-action.outputs.result).labelActions['ARMSignedOff'] == 'add' }}"

- if: |
fromJson(steps.get-label-action.outputs.result).labelAction == 'add' ||
fromJson(steps.get-label-action.outputs.result).labelAction == 'remove'
name: Upload artifact with results
- if: fromJson(steps.get-label-action.outputs.result).labelActions['ARMAutoSignedOff-IncrementalTSP'] != 'none'
name: Upload artifact for ARMAutoSignedOff-IncrementalTSP label
uses: ./.github/actions/add-label-artifact
with:
name: "ARMSignedOff"
# Convert "add/remove" to "true/false"
value: "${{ fromJson(steps.get-label-action.outputs.result).labelAction == 'add' }}"
name: "ARMAutoSignedOff-IncrementalTSP"
value: "${{ fromJson(steps.get-label-action.outputs.result).labelActions['ARMAutoSignedOff-IncrementalTSP'] == 'add' }}"

- if: fromJson(steps.get-label-action.outputs.result).labelActions['ARMAutoSignedOff-Trivial-Test'] != 'none'
name: Upload artifact for ARMAutoSignedOff-Trivial-Test label
uses: ./.github/actions/add-label-artifact
with:
name: "ARMAutoSignedOff-Trivial-Test"
value: "${{ fromJson(steps.get-label-action.outputs.result).labelActions['ARMAutoSignedOff-Trivial-Test'] == '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,
Expand Down
46 changes: 46 additions & 0 deletions .github/workflows/src/arm-auto-signoff/arm-auto-signoff-code.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { incrementalTypeSpec } from "./arm-incremental-typespec.js";
import { checkTrivialChanges } from "./trivial-changes-check.js";

/** @typedef {import("./pr-changes.js").PullRequestChanges} PullRequestChanges */

/**
* Main entry point for ARM Auto Signoff Code workflow.
*
* This module orchestrates all checks to determine if a PR qualifies for auto sign-off.
* It combines results from:
* - Incremental TypeSpec check
* - Trivial changes check
*
* @param {import("@actions/github-script").AsyncFunctionArguments} args
* @returns {Promise<{ incremental: boolean, trivial: boolean }>}
*/
export default async function armAutoSignoffCode({ core }) {
core.info("Starting ARM Auto Signoff Code analysis.");

// Run incremental TypeSpec check
core.startGroup("Checking for incremental TypeSpec changes");
const incrementalTypeSpecResult = await incrementalTypeSpec(core);
core.info(`Incremental TypeSpec result: ${incrementalTypeSpecResult}`);
core.endGroup();

// Run trivial changes check
core.startGroup("Checking for trivial changes");
const trivialChangesResult = await checkTrivialChanges(core);
core.endGroup();

const isTrivial = trivialChangesResult.isTrivial();

// Combine results
const combined = {
incrementalTypeSpec: incrementalTypeSpecResult,
trivialChanges: trivialChangesResult,
};

core.info(`Combined result: ${JSON.stringify(combined, null, 2)}`);

// Return a JSON object for downstream workflow logic.
return {
incremental: incrementalTypeSpecResult,
trivial: isTrivial,
};
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @AkhilaIlla , @mikeharder , @raosuhas, could the incremental TypeSpec detection be extended to support PRs that only modify .tsp files?

Currently, arm-incremental-typespec.js maps changed files to spec directories using only swagger(), example() and readme() filters, so .tsp-only PRs always result in an empty changedSpecDirs and return false. This means TypeSpec-only changes to an existing TypeSpec RP can't receive ARMAutoSignedOff-IncrementalTSP and must wait for manual ARM review.

Adding .tsp files (via the existing typespec() filter) to the changedSpecDirs computation would address this, and the existing base-branch check (verifying TypeSpec-generated swagger already exists) would still guard against false positives.

This would significantly reduce review wait times for teams working in TypeSpec. We recently migrated from raw swagger to TypeSpec, and we're working on refactoring the tsp files to resolve some FIXMEs left by the auto conversion tool. These updates will not alter the generated swagger, ensuring we don't introduce any unintended changes. For instance, this is PR #40221, along with the current outcome from 'Checking for incremental TypeSpec changes'.

2026-02-09T02:57:36.268Z simple-git [GitExecutor] [SPAWN] git [ 'diff', '--name-status', 'HEAD^', 'HEAD' ]
Could not map changed files to any spec directories
Incremental TypeSpec result: false

Created an issue #40384 to track this and thanks for considering!

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* ARM auto-signoff label names.
* @readonly
* @enum {string}
*/
export const ArmAutoSignoffLabel = Object.freeze({
ArmSignedOff: "ARMSignedOff",
ArmAutoSignedOff: "ARMAutoSignedOff",
ArmAutoSignedOffIncrementalTSP: "ARMAutoSignedOff-IncrementalTSP",
ArmAutoSignedOffTrivialTest: "ARMAutoSignedOff-Trivial-Test",
});
Loading