ci: skip CJS api-extractor checks on PR builds#26596
ci: skip CJS api-extractor checks on PR builds#26596frankmueller-msft wants to merge 1 commit intomainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR reduces CI time on Pull Request builds by skipping redundant CommonJS api-extractor validation tasks when CJS entrypoints are identical to ESM, while keeping full checks on main/release branches.
Changes:
- Add PR-only pipeline variable
skipCjsChecksand pass it asSKIP_CJS_CHECKSto build/lint steps. - Update
fluidBuild.config.cjsto conditionally removeapi-extractor:commonjsfrom key dependency chains whenSKIP_CJS_CHECKSis enabled. - Override
check:exportsbehavior underSKIP_CJS_CHECKSto run ESM-only export-check subtasks.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| fluidBuild.config.cjs | Adds SKIP_CJS_CHECKS gating to omit CJS api-extractor tasks and alters check:exports execution plan on PR builds. |
| tools/pipelines/templates/include-vars.yml | Introduces skipCjsChecks variable (true on PR builds). |
| tools/pipelines/templates/include-build-lint.yml | Passes SKIP_CJS_CHECKS into ci:build and lint pipeline steps. |
| "tools/markdown-magic/package.json", | ||
| ]; | ||
|
|
||
| const skipCjsChecks = process.env.SKIP_CJS_CHECKS === "true"; |
There was a problem hiding this comment.
skipCjsChecks is derived via a strict process.env.SKIP_CJS_CHECKS === "true" check. In Azure Pipelines, boolean variables commonly come through as "True"/"False" (capitalized), so PR builds may not actually enable the skip behavior. Consider normalizing (e.g. case-insensitive) and/or accepting "1" to make the gate reliable.
| const skipCjsChecks = process.env.SKIP_CJS_CHECKS === "true"; | |
| const skipCjsChecks = | |
| typeof process.env.SKIP_CJS_CHECKS === "string" && | |
| (process.env.SKIP_CJS_CHECKS.toLowerCase() === "true" || process.env.SKIP_CJS_CHECKS === "1"); |
There was a problem hiding this comment.
Not an issue — the pipeline variable uses ${{ lower(eq(variables['Build.Reason'], 'PullRequest')) }} in include-vars.yml, which outputs lowercase "true" / "false". The === "true" check matches correctly.
fluidBuild.config.cjs
Outdated
| "check:exports": skipCjsChecks | ||
| ? { | ||
| dependsOn: [ | ||
| "check:exports:bundle-release-tags", | ||
| "check:exports:esm:public", |
There was a problem hiding this comment.
When skipCjsChecks is enabled, check:exports becomes a non-script task that only depends on a hard-coded list of check:exports:esm:* subtasks. This skips packages whose check:exports script isn’t implemented via those subtasks (e.g. @fluid-internal/devtools-view runs api-extractor directly and has no check:exports:esm:* scripts), reducing PR validation unintentionally. Consider preserving per-package check:exports execution while making the CJS subtasks no-ops (or otherwise filtered) so nonstandard packages still get checked.
There was a problem hiding this comment.
Correct that check:exports is fully disabled, not just the CJS subtasks. This is intentional — there's no clean way to skip only CJS subtasks because:
- 88 packages use
concurrently "npm:check:exports:*"which glob-matches both CJS and ESM subtasks. Concurrently runs via npm, not fluid-build, so fluid-build task overrides can't selectively suppress the CJS subtask invocations. - Fluid-build's
scriptfield is boolean (true/false) — no custom command override to substitute e.g.concurrently "npm:check:exports:esm:*". - Only 2 packages use direct api-extractor instead of concurrently (
devtools-view,example-utils), and both havetypeValidation: { disabled: true }.
Full check:exports validation (CJS + ESM) runs on main/release CI. The PR-only skip is a deliberate tradeoff: ~2 min wall-clock savings vs deferred ESM export lint to merge time.
CJS api-extractor output is byte-for-byte identical to ESM. On PR builds, skip CJS api-extractor invocations (~22 min CPU, ~2 min wall-clock) and defer CJS-dependent checks to main/release CI. When SKIP_CJS_CHECKS=true (set for PR builds via pipeline variable): - api-extractor:commonjs removed from build:test, build:test:cjs, api - check:exports becomes a no-op (concurrently script would fail without CJS entry points) - check:are-the-types-wrong becomes a no-op (attw checks CJS+ESM) - AreTheTypesWrong pipeline job excluded from PR runs Non-PR builds are unaffected — full CJS+ESM checks run as before. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
815dde0 to
dd025bd
Compare
Summary
Skip redundant CJS
api-extractorinvocations on PR builds to reduce build time. CJS entry point files are byte-for-byte identical to ESM — full CJS checks run on main/release CI where correctness matters.Measured impact: Build Stage dropped from 18m40s to 16m18s (~2m20s wall-clock improvement).
What changes on PR builds
When
SKIP_CJS_CHECKS=true(set automatically for PR builds):api-extractor:commonjsremoved frombuild:test,build:test:cjs,apidependency arrays (~65 invocations, ~6 min CPU)check:exportsbecomes a no-op — the package'sconcurrentlyscript would fail without CJS entry points (~159 invocations, ~16 min CPU)check:are-the-types-wrongbecomes a no-op —attwchecks CJS+ESM type resolutionAreTheTypesWrongpipeline job excluded from PR runs (runs viapnpm, not fluid-build)What does NOT change
api-extractor-lint-*.cjs.jsonfiles staynpm run buildis unaffected (env var not set)Files changed
fluidBuild.config.cjsapi,build:test,build:test:cjs,check:exports,check:are-the-types-wrongbased onSKIP_CJS_CHECKSenv vartools/pipelines/templates/include-vars.ymlskipCjsCheckspipeline variable (true on PR builds)tools/pipelines/templates/include-build-lint.ymlSKIP_CJS_CHECKSenv var toci:buildandlintstepstools/pipelines/build-client.ymlAreTheTypesWrongjob on PR buildsTest plan
Closes #26592
🤖 Generated with Claude Code