-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
0f25cae
commit b6afb13
Showing
2 changed files
with
134 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
name: ARM Incremental Typespec (Preview) | ||
|
||
on: pull_request | ||
|
||
permissions: | ||
contents: read | ||
|
||
jobs: | ||
arm-incremental-typespec-preview: | ||
name: ARM Incremental Typespec (Preview) | ||
|
||
runs-on: ubuntu-24.04 | ||
|
||
steps: | ||
- uses: actions/checkout@v4 | ||
with: | ||
# Required to detect changed files in PR | ||
fetch-depth: 2 | ||
|
||
# Output is "none" for no-op, "add" to add label, and "remove" to remove label | ||
- id: incremental-typespec | ||
name: ARM Incremental Typespec (Preview) | ||
uses: actions/github-script@v7 | ||
with: | ||
result-encoding: string | ||
script: | | ||
const { default: incrementalTypespec } = | ||
await import('${{ github.workspace }}/.github/workflows/src/arm-incremental-typespec-preview.js'); | ||
return await incrementalTypespec({ github, context, core }); | ||
- name: Upload artifact with results | ||
uses: ./.github/actions/add-empty-artifact | ||
with: | ||
name: "incremental-typespec" | ||
value: ${{ steps.incremental-typespec.outputs.result }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
// @ts-check | ||
|
||
import { readFile } from "fs/promises"; | ||
import { dirname, join } from "path"; | ||
import { getChangedResourceManagerSwaggerFiles } from "./changed-files.js"; | ||
import { lsTree, show } from "./git.js"; | ||
|
||
/** | ||
* @param {import('github-script').AsyncFunctionArguments} AsyncFunctionArguments | ||
* @returns {Promise<boolean>} | ||
*/ | ||
export default async function incrementalTypespec({ github, context, core }) { | ||
const changedRmSwaggerFiles = await getChangedResourceManagerSwaggerFiles( | ||
core, | ||
"HEAD^", | ||
"HEAD", | ||
"", | ||
); | ||
|
||
if (changedRmSwaggerFiles.length == 0) { | ||
core.info( | ||
"No changes to swagger files containing path '/resource-manager/'", | ||
); | ||
return false; | ||
} | ||
|
||
// If any changed file is not typespec-generated, return false | ||
for (const file of changedRmSwaggerFiles) { | ||
const swagger = await readFile( | ||
join(process.env.GITHUB_WORKSPACE || "", file), | ||
{ encoding: "utf8" }, | ||
); | ||
|
||
const swaggerObj = JSON.parse(swagger); | ||
|
||
if (!swaggerObj["info"]?.["x-typespec-generated"]) { | ||
core.info(`File "${file}" does not contain "info.x-typespec-generated"`); | ||
return false; | ||
} | ||
} | ||
|
||
const changedSpecDirs = new Set( | ||
changedRmSwaggerFiles.map((f) => dirname(dirname(dirname(f)))), | ||
); | ||
|
||
// Ensure that each changed spec dir contained at least one typespec-generated swagger in the base commitish | ||
for (const changedSpecDir of changedSpecDirs) { | ||
// TODO: Create helper to list RM specs in a given commitish | ||
const specFilesBaseBranch = await lsTree( | ||
"HEAD^", | ||
changedSpecDir, | ||
core, | ||
"-r --name-only", | ||
); | ||
|
||
// Filter files to only include RM *.json files | ||
const specRmSwaggerFilesBaseBranch = specFilesBaseBranch | ||
.split("\n") | ||
.filter( | ||
(file) => | ||
file.includes("/resource-manager/") && | ||
!file.includes("/examples/") && | ||
file.endsWith(".json"), | ||
); | ||
|
||
if (specRmSwaggerFilesBaseBranch.length === 0) { | ||
core.info( | ||
`Spec folder '${changedSpecDir}' in base branch does not exist or contains no swagger files`, | ||
); | ||
return false; | ||
} | ||
|
||
let containsTypespecGeneratedSwagger = false; | ||
// TODO: Add lint rule to prevent using "for...in" instead of "for...of" | ||
for (const file of specRmSwaggerFilesBaseBranch) { | ||
const baseSwagger = await show("HEAD^", file, core); | ||
const baseSwaggerObj = JSON.parse(baseSwagger); | ||
if (baseSwaggerObj["info"]?.["x-typespec-generated"]) { | ||
core.info( | ||
`Spec folder '${changedSpecDir}' in base branch contains typespec-generated swagger: '${file}'`, | ||
); | ||
containsTypespecGeneratedSwagger = true; | ||
continue; | ||
} | ||
} | ||
|
||
if (!containsTypespecGeneratedSwagger) { | ||
core.info( | ||
`Spec folder '${changedSpecDir}' in base branch does not contain any typespec-generated swagger. PR may be a TypeSpec conversion.`, | ||
); | ||
return false; | ||
} | ||
} | ||
|
||
core.info( | ||
"Appears to contain only incremental changes to existing TypeSpec RP(s)", | ||
); | ||
return true; | ||
} |