diff --git a/.github/package-lock.json b/.github/package-lock.json index 6b29afcbb949..14d3bdd70e5d 100644 --- a/.github/package-lock.json +++ b/.github/package-lock.json @@ -646,9 +646,9 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.2.tgz", - "integrity": "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==", + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.20.0.tgz", + "integrity": "sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -721,9 +721,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.23.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.23.0.tgz", - "integrity": "sha512-35MJ8vCPU0ZMxo7zfev2pypqTwWTofFZO6m4KAtdoFhRpLJUpHTZZ+KB3C7Hb1d7bULYwO4lJXGCi5Se+8OMbw==", + "version": "9.24.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.24.0.tgz", + "integrity": "sha512-uIY/y3z0uvOGX8cp1C2fiC4+ZmBhp6yZWkojtHL1YEMnRt1Y63HB9TM17proGEmeG7HeUY+UP36F0aknKYTpYA==", "dev": true, "license": "MIT", "engines": { @@ -1963,19 +1963,19 @@ } }, "node_modules/eslint": { - "version": "9.23.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.23.0.tgz", - "integrity": "sha512-jV7AbNoFPAY1EkFYpLq5bslU9NLNO8xnEeQXwErNibVryjk67wHVmddTBilc5srIttJDBrB0eMHKZBFbSIABCw==", + "version": "9.24.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.24.0.tgz", + "integrity": "sha512-eh/jxIEJyZrvbWRe4XuVclLPDYSYYYgLy5zXGGxD6j8zjSAxFEzI2fL/8xNq6O2yKqVt+eF2YhV+hxjV6UKXwQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.19.2", + "@eslint/config-array": "^0.20.0", "@eslint/config-helpers": "^0.2.0", "@eslint/core": "^0.12.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.23.0", + "@eslint/js": "9.24.0", "@eslint/plugin-kit": "^0.2.7", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", @@ -3311,9 +3311,9 @@ } }, "node_modules/vite": { - "version": "6.2.4", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.4.tgz", - "integrity": "sha512-veHMSew8CcRzhL5o8ONjy8gkfmFJAd5Ac16oxBUjlwgX3Gq2Wqr+qNC3TjPIpy7TPV/KporLga5GT9HqdrCizw==", + "version": "6.2.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.5.tgz", + "integrity": "sha512-j023J/hCAa4pRIUH6J9HemwYfjB5llR2Ps0CWeikOtdR8+pAURAk0DoJC5/mm9kd+UgdnIy7d6HE4EAvlYhPhA==", "dev": true, "license": "MIT", "dependencies": { diff --git a/.github/workflows/_reusable-verify-run-status.yaml b/.github/workflows/_reusable-verify-run-status.yaml new file mode 100644 index 000000000000..4609526e78ef --- /dev/null +++ b/.github/workflows/_reusable-verify-run-status.yaml @@ -0,0 +1,42 @@ +# Prefix with "~" to sort last in Actions list +name: ~Templates - Verify Run Status + +on: + workflow_call: + inputs: + check_run_name: + description: Name of the check run to verify + required: true + type: string + workflow_name: + description: Name of the workflow to verify + required: true + type: string + +permissions: + checks: read + contents: read + +jobs: + check-run-status: + if: | + (github.event_name == 'workflow_run') || + (github.event_name == 'check_suite' && github.event.check_suite.app.name == 'openapi-pipeline-app') || + (github.event_name == 'check_run' && github.event.check_run.name == inputs.check_run_name) + runs-on: ubuntu-24.04 + + steps: + - uses: actions/checkout@v4 + with: + sparse-checkout: | + .github + + - name: Verify matching status + uses: actions/github-script@v7 + with: + script: | + const { verifyRunStatus } = await import('${{ github.workspace }}/.github/workflows/src/verify-run-status.js'); + return await verifyRunStatus({ github, context, core }); + env: + CHECK_RUN_NAME: ${{ inputs.check_run_name }} + WORKFLOW_NAME: ${{ inputs.workflow_name }} diff --git a/.github/workflows/src/checks.js b/.github/workflows/src/checks.js new file mode 100644 index 000000000000..89121020281d --- /dev/null +++ b/.github/workflows/src/checks.js @@ -0,0 +1,25 @@ +import { PER_PAGE_MAX } from "./github.js"; + +/** + * @param {import('github-script').AsyncFunctionArguments['github']} github + * @param {{ + * owner: string; + * repo: string; + * ref: string; + * name?: string; + * status?: "queued" | "in_progress" | "completed"; + * }} params + * @returns {Promise} + */ +export async function listChecksForRef(github, { owner, repo, ref, name, status}) { + const options = { + owner, + repo, + ref, + ...(name && { check_name: name }), + ...(status && { status }), + per_page: PER_PAGE_MAX, + }; + + return await github.paginate(github.rest.checks.listForRef, options); +} diff --git a/.github/workflows/src/verify-run-status.js b/.github/workflows/src/verify-run-status.js new file mode 100644 index 000000000000..2a0770c46dfb --- /dev/null +++ b/.github/workflows/src/verify-run-status.js @@ -0,0 +1,180 @@ +import { extractInputs } from "./context.js"; +import { PER_PAGE_MAX } from "./github.js"; + +const SUPPORTED_EVENTS = ["workflow_run", "check_run", "check_suite"]; + +/** + * @typedef {import('@octokit/plugin-rest-endpoint-methods').RestEndpointMethodTypes} RestEndpointMethodTypes + * @typedef {RestEndpointMethodTypes["checks"]["listForRef"]["response"]["data"]["check_runs"]} CheckRuns + * @typedef {RestEndpointMethodTypes["actions"]["listWorkflowRunsForRepo"]["response"]["data"]["workflow_runs"]} WorkflowRuns + */ + +/* v8 ignore start */ +/** + * Given the name of a completed check run name and a completed workflow, verify + * that both have the same conclusion. If conclusions are different, fail the + * action. + * @param {import('github-script').AsyncFunctionArguments} AsyncFunctionArguments + */ +export async function verifyRunStatus({ github, context, core }) { + const checkRunName = process.env.CHECK_RUN_NAME; + if (!checkRunName) { + throw new Error("CHECK_RUN_NAME is not set"); + } + + const workflowName = process.env.WORKFLOW_NAME; + if (!workflowName) { + throw new Error("WORKFLOW_NAME is not set"); + } + + if (!SUPPORTED_EVENTS.some((e) => e === context.eventName)) { + throw new Error( + `Unsupported event: ${context.eventName}. Supported events: ${SUPPORTED_EVENTS.join(", ")}`, + ); + } + + if (context.eventName === "check_suite" && context.payload.check_suite.status !== "completed") { + core.setFailed(`Check suite ${context.payload.check_suite.app.name} is not completed. Cannot evaluate incomplete check suite.`); + return; + } + + return await verifyRunStatusImpl({ github, context, core , checkRunName, workflowName}); +} +/* v8 ignore stop */ + +/** + * @param {Object} params + * @param {import('github-script').AsyncFunctionArguments["github"]} params.github + * @param {import('github-script').AsyncFunctionArguments["context"]} params.context + * @param {import('github-script').AsyncFunctionArguments["core"]} params.core + * @param {string} params.checkRunName + * @param {string} params.workflowName + */ +export async function verifyRunStatusImpl({github, context, core, checkRunName, workflowName}) { + if (context.eventName == "check_run") { + const contextRunName = context.payload.check_run.name; + if (contextRunName !== checkRunName) { + core.setFailed(`Check run name (${contextRunName}) does not match input: ${checkRunName}. Ensure job is filtering by github.event.check_run.name.`); + return; + } + } + + const { head_sha } = await extractInputs(github, context, core); + + let checkRun; + if (context.eventName == "check_run") { + checkRun = context.payload.check_run; + } else { + const checkRuns = await getCheckRuns(github, context, checkRunName, head_sha); + if (checkRuns.length === 0) { + if (context.eventName === "check_suite") { + const message = `Could not locate check run ${checkRunName} in check suite ${context.payload.check_suite.app.name}. Ensure job is filtering by github.event.check_suite.app.name.`; + core.setFailed(message); + return; + } + + core.notice(`No completed check run with name: ${checkRunName}. Not enough information to judge success or failure. Ending with success status.`); + return; + } + + // Use the most recent check run + checkRun = checkRuns[0]; + } + + core.info( + `Check run name: ${checkRun.name}, conclusion: ${checkRun.conclusion}, URL: ${checkRun.html_url}`, + ); + core.debug(`Check run: ${JSON.stringify(checkRun)}`); + + let workflowRun; + if (context.eventName == "workflow_run") { + workflowRun = context.payload.workflow_run; + } else { + const workflowRuns = await getWorkflowRuns(github, context, workflowName, head_sha); + if (workflowRuns.length === 0) { + core.notice(`No completed workflow run with name: ${workflowName}. Not enough information to judge success or failure. Ending with success status.`); + return; + } + + // Use the most recent workflow run + workflowRun = workflowRuns[0]; + } + + core.info( + `Workflow run name: ${workflowRun.name}, conclusion: ${workflowRun.conclusion}, URL: ${workflowRun.html_url}`, + ); + core.debug(`Workflow run: ${JSON.stringify(workflowRun)}`); + + if (checkRun.conclusion !== workflowRun.conclusion) { + core.setFailed( + `Check run conclusion (${checkRun.conclusion}) does not match workflow run conclusion (${workflowRun.conclusion})`, + ); + return; + } + + core.notice(`Conclusions match for check run ${checkRunName} and workflow run ${workflowName}`); +} + +/** + * Returns the check with the given checkRunName for the given ref. + * @param {import('github-script').AsyncFunctionArguments['github']} github + * @param {import('github-script').AsyncFunctionArguments['context']} context + * @param {string} checkRunName + * @param {string} ref + * @returns {Promise} + */ +export async function getCheckRuns( + github, + context, + checkRunName, + ref, +) { + const result = await github.paginate(github.rest.checks.listForRef, { + ...context.repo, + ref: ref, + check_name: checkRunName, + status: "completed", + per_page: PER_PAGE_MAX, + }); + + // a and b will never be null because status is "completed" + /* v8 ignore next */ + return result.sort((a, b) => compareDatesDescending(a.completed_at || '', b.completed_at || '')); +} + +/** + * Returns the workflow run with the given workflowName for the given ref. + * @param {import('github-script').AsyncFunctionArguments['github']} github + * @param {import('github-script').AsyncFunctionArguments['context']} context + * @param {string} workflowName + * @param {string} ref + * @returns {Promise} + */ +export async function getWorkflowRuns( + github, + context, + workflowName, + ref, +) { + const result = await github.paginate( + github.rest.actions.listWorkflowRunsForRepo, + { + ...context.repo, + head_sha: ref, + status: "completed", + per_page: PER_PAGE_MAX, + }, + ); + + return result.filter((run) => run.name === workflowName).sort((a, b) => compareDatesDescending(a.updated_at, b.updated_at)); +} + +/** + * Compares two date strings in descending order. + * @param {string} a date string of the form "YYYY-MM-DDTHH:mm:ssZ" + * @param {string} b date string of the form "YYYY-MM-DDTHH:mm:ssZ" + * @returns + */ +export function compareDatesDescending(a, b) { + return new Date(b).getTime() - new Date(a).getTime(); +} \ No newline at end of file diff --git a/.github/workflows/src/workflows.js b/.github/workflows/src/workflows.js new file mode 100644 index 000000000000..139f388cf4e0 --- /dev/null +++ b/.github/workflows/src/workflows.js @@ -0,0 +1,23 @@ +import { PER_PAGE_MAX } from "./github.js"; + +/** + * @param {import('github-script').AsyncFunctionArguments['github']} github + * @param {{ + * owner: string; + * repo: string; + * head_sha?: string; + * status?: "completed" | "in_progress" | "queued"; + * event?: string; + * }} params + * @returns {Promise} + */ +export async function listWorkflowRunsForRepo(github, { owner, repo, head_sha, status, event}) { + return await github.paginate(github.rest.actions.listWorkflowRunsForRepo, { + owner, + repo, + ...(head_sha && { head_sha }), + ...(status && { status }), + ...(event && { event }), + per_page: PER_PAGE_MAX, + }); +} diff --git a/.github/workflows/test/mocks.js b/.github/workflows/test/mocks.js index ed845f6f8d5b..797d21c7a541 100644 --- a/.github/workflows/test/mocks.js +++ b/.github/workflows/test/mocks.js @@ -48,12 +48,14 @@ export function createMockCore() { return { debug: vi.fn(console.debug), info: vi.fn(console.log), + notice: vi.fn(console.log), error: vi.fn(console.error), warning: vi.fn(console.warn), isDebug: vi.fn().mockReturnValue(true), setOutput: vi.fn((name, value) => console.log(`setOutput('${name}', '${value}')`), ), + setFailed: vi.fn((msg) => console.log(`setFailed('${msg}')`)), }; } diff --git a/.github/workflows/test/verify-run-status.test.js b/.github/workflows/test/verify-run-status.test.js new file mode 100644 index 000000000000..b08a6c31c4ac --- /dev/null +++ b/.github/workflows/test/verify-run-status.test.js @@ -0,0 +1,408 @@ +import { describe, expect, it, vi } from "vitest"; +import { + createMockGithub, + createMockContext, + createMockCore, +} from "./mocks.js"; +import { + getCheckRuns, + getWorkflowRuns, + verifyRunStatusImpl, +} from "../src/verify-run-status.js"; + +vi.mock("../src/context.js", () => { + return { + extractInputs: vi.fn().mockResolvedValue({ + head_sha: "head_sha", + }), + }; +}); + +describe("getCheckRuns", () => { + it("returns matching check_run", async () => { + const githubMock = createMockGithub(); + githubMock.rest.checks.listForRef = vi.fn().mockResolvedValue({ + data: { + check_runs: [ + { + name: "checkRunName", + status: "completed", + conclusion: "success", + }, + ], + }, + }); + + const actual = await getCheckRuns( + githubMock, + createMockContext(), + createMockCore(), + "checkRunName", + "head_sha", + ); + + expect(actual).toEqual([ + expect.objectContaining({ + name: "checkRunName", + status: "completed", + conclusion: "success", + }), + ]); + }); + + it("returns null when no check matches", async () => { + const githubMock = createMockGithub(); + githubMock.rest.checks.listForRef = vi.fn().mockResolvedValue({ + data: { + check_runs: [], + }, + }); + + const actual = await getCheckRuns( + githubMock, + createMockContext(), + "checkRunName", + "head_sha", + ); + + expect(actual).toEqual([]); + }); + + it("throws when multiple checks match", async () => { + const githubMock = createMockGithub(); + const earlierDate = "2025-04-01T00:00:00Z"; + const laterDate = "2025-04-02T00:00:00Z"; + githubMock.rest.checks.listForRef = vi.fn().mockResolvedValue({ + data: { + check_runs: [ + { + name: "checkRunName", + status: "completed", + conclusion: "success", + completed_at: earlierDate, + }, + { + name: "checkRunName", + status: "completed", + conclusion: "success", + completed_at: laterDate, + }, + ], + }, + }); + + const actual = await await getCheckRuns( + githubMock, + createMockContext(), + "checkRunName", + "head_sha", + ); + + expect(actual).toEqual([ + expect.objectContaining({ + name: "checkRunName", + status: "completed", + conclusion: "success", + completed_at: laterDate, + }), + expect.objectContaining({ + name: "checkRunName", + status: "completed", + conclusion: "success", + completed_at: earlierDate, + }), + ]); + }); +}); + +describe("getWorkflowRuns", () => { + it("returns matching workflow_run", async () => { + const githubMock = createMockGithub(); + githubMock.rest.actions.listWorkflowRunsForRepo = vi + .fn() + .mockResolvedValue({ + data: { + workflow_runs: [ + { + name: "workflowName", + status: "completed", + conclusion: "success", + }, + ], + }, + }); + + const actual = await getWorkflowRuns( + githubMock, + createMockContext(), + "workflowName", + "head_sha", + ); + + expect(actual).toEqual([ + expect.objectContaining({ + name: "workflowName", + status: "completed", + conclusion: "success", + }), + ]); + }); + + it("returns null when no workflow matches", async () => { + const githubMock = createMockGithub(); + githubMock.rest.actions.listWorkflowRunsForRepo = vi + .fn() + .mockResolvedValue({ + data: { + workflow_runs: [ + { + name: "otherWorkflowName", + }, + ], + }, + }); + + const actual = await getWorkflowRuns( + githubMock, + createMockContext(), + "workflowName", + "head_sha", + ); + + expect(actual).toEqual([]); + }); + + it("returns latest when multiple workflows match", async () => { + const githubMock = createMockGithub(); + const earlyDate = "2025-04-01T00:00:00Z"; + const laterDate = "2025-04-02T00:00:00Z"; + githubMock.rest.actions.listWorkflowRunsForRepo = vi + .fn() + .mockResolvedValue({ + data: { + workflow_runs: [ + { + name: "workflowName", + status: "completed", + conclusion: "success", + updated_at: earlyDate, + }, + { + name: "workflowName", + status: "completed", + conclusion: "success", + updated_at: laterDate, + }, + ], + }, + }); + + const actual = await getWorkflowRuns( + githubMock, + createMockContext(), + "workflowName", + "head_sha", + ); + + expect(actual).toEqual([ + expect.objectContaining({ + updated_at: laterDate, + }), + expect.objectContaining({ + updated_at: earlyDate, + }), + ]); + }); +}); + +describe("verifyRunStatusImpl", () => { + it("verifies status when check_run event fires", async () => { + const github = createMockGithub(); + github.rest.actions.listWorkflowRunsForRepo = vi.fn().mockResolvedValue({ + data: { + workflow_runs: [ + { + name: "workflowName", + status: "completed", + conclusion: "success", + }, + ], + }, + }); + + const context = { + eventName: "check_run", + payload: { + check_run: { + name: "checkRunName", + conclusion: "success", + }, + }, + }; + + const core = createMockCore(); + + vi.stubEnv("CHECK_RUN_NAME", "checkRunName"); + vi.stubEnv("WORKFLOW_NAME", "workflowName"); + await verifyRunStatusImpl({ github, context, core, checkRunName: "checkRunName", workflowName: "workflowName" }); + + expect(core.setFailed).not.toHaveBeenCalled(); + expect(core.notice).toHaveBeenCalledWith("Conclusions match for check run checkRunName and workflow run workflowName"); + }); + + it("verifies status when workflow_run event fires", async () => { + const github = createMockGithub(); + github.rest.checks.listForRef = vi.fn().mockResolvedValue({ + data: { + check_runs: [ + { + name: "checkRunName", + status: "completed", + conclusion: "success", + }, + ], + }, + }); + + const context = { + eventName: "workflow_run", + payload: { + workflow_run: { + name: "workflowName", + conclusion: "success", + }, + }, + }; + + const core = createMockCore(); + + vi.stubEnv("CHECK_RUN_NAME", "checkRunName"); + vi.stubEnv("WORKFLOW_NAME", "workflowName"); + await verifyRunStatusImpl({ github, context, core, checkRunName: "checkRunName", workflowName: "workflowName" }); + + expect(core.setFailed).not.toHaveBeenCalled(); + }); + + it("returns early during workflow_run event when no matching check_run is found", async () => { + const github = createMockGithub(); + github.rest.checks.listForRef = vi.fn().mockResolvedValue({ + data: { + check_runs: [], + }, + }); + + const context = { + eventName: "workflow_run", + payload: { + workflow_run: { + name: "workflowName", + conclusion: "success", + }, + }, + }; + const core = createMockCore(); + await verifyRunStatusImpl({ github, context, core, checkRunName: "checkRunName", workflowName: "workflowName" }); + expect(core.setFailed).not.toHaveBeenCalled(); + expect(core.notice).toHaveBeenCalledWith( + "No completed check run with name: checkRunName. Not enough information to judge success or failure. Ending with success status.", + ); + }); + + it("returns early during check_run event when no matching workflow_run is found", async () => { + const github = createMockGithub(); + github.rest.actions.listWorkflowRunsForRepo = vi.fn().mockResolvedValue({ + data: { + workflow_runs: [], + }, + }); + + const context = { + eventName: "check_run", + payload: { + check_run: { + name: "checkRunName", + conclusion: "success", + }, + }, + }; + const core = createMockCore(); + await verifyRunStatusImpl({ github, context, core, checkRunName: "checkRunName", workflowName: "workflowName" }); + expect(core.setFailed).not.toHaveBeenCalled(); + expect(core.notice).toHaveBeenCalledWith( + "No completed workflow run with name: workflowName. Not enough information to judge success or failure. Ending with success status.", + ); + }); + + it("returns early if event is check_run but does not match input name", async () => { + const github = createMockGithub(); + const context = { + eventName: "check_run", + payload: { + check_run: { + name: "checkRunName", + conclusion: "success", + }, + }, + }; + const core = createMockCore(); + await verifyRunStatusImpl({ github, context, core, checkRunName: "otherCheckRunName", workflowName: "workflowName" }); + expect(core.setFailed).toHaveBeenCalledWith( + "Check run name (checkRunName) does not match input: otherCheckRunName. Ensure job is filtering by github.event.check_run.name.", + ); + }); + + it("throws if check_run conclusion does not match workflow_run conclusion", async () => { + const github = createMockGithub(); + github.rest.actions.listWorkflowRunsForRepo = vi.fn().mockResolvedValue({ + data: { + workflow_runs: [ + { + name: "workflowName", + status: "completed", + conclusion: "failure", + }, + ], + }, + }); + + const context = { + eventName: "check_run", + payload: { + check_run: { + name: "checkRunName", + conclusion: "success", + }, + }, + }; + const core = createMockCore(); + await verifyRunStatusImpl({ github, context, core, checkRunName: "checkRunName", workflowName: "workflowName" }); + expect(core.setFailed).toHaveBeenCalledWith( + "Check run conclusion (success) does not match workflow run conclusion (failure)", + ); + }); + + it ("throws when in check_suite event but no check_run with name is found", async () => { + const github = createMockGithub(); + github.rest.checks.listForRef = vi.fn().mockResolvedValue({ + data: { + check_runs: [], + }, + }); + + const context = { + eventName: "check_suite", + payload: { + check_suite: { + app: { + name: "checkRunName", + }, + }, + }, + }; + const core = createMockCore(); + await verifyRunStatusImpl({ github, context, core, checkRunName: "checkRunName", workflowName: "workflowName" }); + expect(core.setFailed).toHaveBeenCalledWith( + "Could not locate check run checkRunName in check suite checkRunName. Ensure job is filtering by github.event.check_suite.app.name.", + ); + }); +}); \ No newline at end of file diff --git a/.github/workflows/watch-lintdiff.yaml b/.github/workflows/watch-lintdiff.yaml new file mode 100644 index 000000000000..a4c9f115430a --- /dev/null +++ b/.github/workflows/watch-lintdiff.yaml @@ -0,0 +1,25 @@ +# Use ~ to sort the workflow to the bottom of the list +name: "~Watch - LintDiff" + +on: + # check_suite is preferred over check_run to avoid triggering on all check + # runs. In some cases, check_run must be used in testing environments. + check_run: + types: completed + + workflow_run: + types: completed + workflows: + - "\\[TEST-IGNORE\\] Swagger LintDiff" + +permissions: + checks: read + contents: read + +jobs: + LintDiff: + name: Watch LintDiff + uses: ./.github/workflows/_reusable-verify-run-status.yaml + with: + check_run_name: "Swagger LintDiff" + workflow_name: "[TEST-IGNORE] Swagger LintDiff" diff --git a/specification/apicenter/resource-manager/readme.typescript.md b/specification/apicenter/resource-manager/readme.typescript.md index d8f1f79d4bdd..a15f6651e8d9 100644 --- a/specification/apicenter/resource-manager/readme.typescript.md +++ b/specification/apicenter/resource-manager/readme.typescript.md @@ -9,6 +9,5 @@ typescript: package-name: "@azure/arm-apicenter" output-folder: "$(typescript-sdks-folder)/sdk/apicenter/arm-apicenter" payload-flattening-threshold: 1 - clear-output-folder: true generate-metadata: true ``` diff --git a/specificationRepositoryConfiguration.json b/specificationRepositoryConfiguration.json index 0b2c1930d549..fbb51a455ca3 100644 --- a/specificationRepositoryConfiguration.json +++ b/specificationRepositoryConfiguration.json @@ -23,7 +23,8 @@ }, "azure-sdk-for-python": { "integrationRepository": "azure-sdk/azure-sdk-for-python", - "mainRepository": "Azure/azure-sdk-for-python" + "mainRepository": "Azure/azure-sdk-for-python", + "mainBranch": "fix-pipeline-2025-04-09-2" }, "azure-powershell": { "integrationRepository": "azure-sdk/azure-powershell",