Skip to content

ci: skip CJS api-extractor checks on PR builds#26596

Open
frankmueller-msft wants to merge 1 commit intomainfrom
ci/skip-cjs-api-extractor-on-prs
Open

ci: skip CJS api-extractor checks on PR builds#26596
frankmueller-msft wants to merge 1 commit intomainfrom
ci/skip-cjs-api-extractor-on-prs

Conversation

@frankmueller-msft
Copy link
Contributor

@frankmueller-msft frankmueller-msft commented Mar 1, 2026

Summary

Skip redundant CJS api-extractor invocations 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:commonjs removed from build:test, build:test:cjs, api dependency arrays (~65 invocations, ~6 min CPU)
  • check:exports becomes a no-op — the package's concurrently script would fail without CJS entry points (~159 invocations, ~16 min CPU)
  • check:are-the-types-wrong becomes a no-op — attw checks CJS+ESM type resolution
  • AreTheTypesWrong pipeline job excluded from PR runs (runs via pnpm, not fluid-build)

What does NOT change

  • Non-PR builds (main, release branches) run full CJS+ESM checks exactly as before
  • No package.json modifications — all packages keep existing scripts
  • No config file deletionsapi-extractor-lint-*.cjs.json files stay
  • Local npm run build is unaffected (env var not set)

Files changed

File What
fluidBuild.config.cjs Conditional ternaries for api, build:test, build:test:cjs, check:exports, check:are-the-types-wrong based on SKIP_CJS_CHECKS env var
tools/pipelines/templates/include-vars.yml Add skipCjsChecks pipeline variable (true on PR builds)
tools/pipelines/templates/include-build-lint.yml Pass SKIP_CJS_CHECKS env var to ci:build and lint steps
tools/pipelines/build-client.yml Conditionally exclude AreTheTypesWrong job on PR builds

Test plan

  • PR CI passes — all checks green
  • Build Stage Build: 16m18s (vs 18m40s baseline)
  • Verify main CI still runs full CJS checks after merge

Closes #26592

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings March 1, 2026 06:36
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

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 skipCjsChecks and pass it as SKIP_CJS_CHECKS to build/lint steps.
  • Update fluidBuild.config.cjs to conditionally remove api-extractor:commonjs from key dependency chains when SKIP_CJS_CHECKS is enabled.
  • Override check:exports behavior under SKIP_CJS_CHECKS to 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";
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

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

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.

Suggested change
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");

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

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.

Comment on lines +137 to +141
"check:exports": skipCjsChecks
? {
dependsOn: [
"check:exports:bundle-release-tags",
"check:exports:esm:public",
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

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:

  1. 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.
  2. Fluid-build's script field is boolean (true/false) — no custom command override to substitute e.g. concurrently "npm:check:exports:esm:*".
  3. Only 2 packages use direct api-extractor instead of concurrently (devtools-view, example-utils), and both have typeValidation: { 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>
@frankmueller-msft frankmueller-msft force-pushed the ci/skip-cjs-api-extractor-on-prs branch from 815dde0 to dd025bd Compare March 2, 2026 23:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ci: skip redundant CJS api-extractor lint checks in ci:build

2 participants