Skip to content

Commit

Permalink
Add incremental-typespec WF
Browse files Browse the repository at this point in the history
  • Loading branch information
mikeharder committed Feb 12, 2025
1 parent 0f25cae commit b6afb13
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 0 deletions.
35 changes: 35 additions & 0 deletions .github/workflows/arm-incremental-typespec-preview.yaml
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 }}
99 changes: 99 additions & 0 deletions .github/workflows/src/arm-incremental-typespec-preview.js
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;
}

0 comments on commit b6afb13

Please sign in to comment.