Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 24, 2025

Description

The release prepare command was missing the compatibility layer generation check that runs in the main release command.

This PR adds the missing check by creating shared logic that both commands can use, using direct function calls instead of shell commands for better efficiency and maintainability.

Changes

  • Created shared library module - Created library/layerCompatibility.ts containing shared layer compatibility functions (maybeGetNewGeneration, isCurrentPackageVersionPatch, and constants)
  • Extracted shared logic - Created runCompatLayerGenerationCheck() helper in releasePrepChecks.ts that directly calls the shared layer compatibility functions to check if packages need updates
  • Added check to prepare command - Implemented CheckCompatLayerGeneration following existing check patterns and added to allChecks map in prepare.ts
  • Refactored release command - Updated checkCompatLayerGeneration in checkFunctions.ts to use shared helper, reducing duplication and properly scoping to the release group or package being released
  • Refactored generate command - Updated commands/generate/compatLayerGeneration.ts to import shared functions from the library instead of defining them locally (the command was renamed from layerCompatGeneration.ts to compatLayerGeneration.ts in main branch)
  • Improved testability and maintainability:
    • Made logger parameter optional in maybeGetNewGeneration
    • Added currentDate parameter for testability (defaults to new Date())
    • Renamed daysInMonthApproximation to DAYS_IN_MONTH_APPROXIMATION (constant naming convention)
    • Moved DEFAULT_MINIMUM_COMPAT_WINDOW_MONTHS to shared library
    • Refactored runCompatLayerGenerationCheck to accept a list of packages instead of context
    • Updated CheckCompatLayerGeneration to use releaseGroupOrPackage parameter for better scoping
    • Updated checkCompatLayerGeneration to check only packages in the specific release group or individual package being released, not all packages in the repository
  • Updated fixCommand - Changed from "pnpm run -r layerGeneration:gen" to "pnpm run layerGeneration:gen" to delegate to root package.json script, allowing implementation changes without modifying the fix command
  • Merged main branch - Merged latest main branch and resolved conflicts with renamed command file (layerCompatGeneration.tscompatLayerGeneration.ts), updating all references and documentation comments accordingly
  • Documentation - Added comprehensive documentation explaining how to set up new packages for layer compatibility and how the generation command works

Both commands now run identical compatibility layer generation checks via shared logic in the library directory, following proper code organization patterns and best practices for testability.

The check function validates only packages that already have fluidCompatMetadata configured, skipping packages without metadata since not all packages need layer compatibility. This approach uses the fluidCompatMetadata field as an opt-in signal, which aligns with the intended design where packages explicitly opt into layer compatibility tracking.

// Shared helper used by both commands
export async function runCompatLayerGenerationCheck(
  packages: Iterable<Package>,
): Promise<boolean> {
  for (const pkg of packages) {
    const { fluidCompatMetadata } = pkg.packageJson;
    
    // Skip packages without metadata - not all packages need layer compatibility
    if (fluidCompatMetadata === undefined) {
      continue;
    }
    
    // Check if package needs generation update (no logger for checks)
    const newGeneration = maybeGetNewGeneration(
      pkg.version,
      fluidCompatMetadata,
      DEFAULT_MINIMUM_COMPAT_WINDOW_MONTHS,
    );
    
    if (newGeneration !== undefined) {
      return false; // Updates needed
    }
  }
  
  return true; // All packages up to date
}

How layer compatibility generation works

The flub generate compatLayerGeneration command:

  • Processes selected packages based on flags (--dir, --all, --packages, etc.)
  • Skips patch versions (e.g., 2.0.1) - only minor/major versions trigger updates
  • For packages without fluidCompatMetadata: initializes with generation 1
  • For packages with metadata: calculates if generation needs updating based on version changes and time elapsed
  • Updates are triggered only on minor/major version changes, with generation incremented by months since last release (capped at minimumCompatWindowMonths - 1, default 2)

The command uses fluidCompatMetadata as the opt-in signal - packages with this field are considered opted in for layer compatibility tracking.

Setting up layer compatibility for a package

Current approach using pnpm workspace scripts:

  1. Add a layerGeneration:gen script to package.json: "layerGeneration:gen": "flub generate compatLayerGeneration --dir . -v"
  2. Run pnpm run layerGeneration:gen to initialize the package
  3. The command creates the fluidCompatMetadata field and generates the layer generation file

Packages opt out by not including the layerGeneration:gen script. When running pnpm run -r layerGeneration:gen, only packages with the script defined will have the command executed.

Note: Future improvements to the generate command (tracked separately) may include adding an --init flag to bootstrap packages without existing metadata, while maintaining the fluidCompatMetadata field as the opt-in signal for regular operation.

Breaking Changes

None.

Reviewer Guidance

  • The implementation now uses direct function calls instead of running shell commands, making it more efficient
  • Shared layer compatibility functions are in library/layerCompatibility.ts following proper code organization
  • Functions have been made more testable:
    • Logger is now optional (no need for noop logger)
    • Date can be injected for testing
    • Check function accepts a list of packages for better testability and scoping
  • Constants follow naming conventions (DAYS_IN_MONTH_APPROXIMATION, DEFAULT_MINIMUM_COMPAT_WINDOW_MONTHS)
  • The check validates only packages in the specific release group or individual package being released, not all packages in the repository
    • For release groups: uses context.packagesInReleaseGroup(releaseGroup) to get the correct package set
    • For individual packages: uses context.fullPackageMap.get(releasePackage) to get the specific package
  • Packages without metadata are skipped since not all packages need layer compatibility - the fluidCompatMetadata field serves as the opt-in signal
  • The fixCommand delegates to root package.json ("pnpm run layerGeneration:gen") which can call pnpm run -r layerGeneration:gen, allowing the implementation to be easily changed later
  • Both call sites (prepare command and release state machine) use the same implementation by importing directly from the library
  • Existing unit tests have been updated to import from the new shared library location
  • The command file was renamed from layerCompatGeneration.ts to compatLayerGeneration.ts in the main branch merge, and all imports and documentation comments have been updated to reference the correct command name
Original prompt

In the build-tools build-cli project, there is a release command that runs a number of checks. There is also a release prepare command that runs some checks. The prepare command is missing some of the checks, so update the prepare command to run the additional checks. As much of the check logic itself should be shared as possible.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI changed the title [WIP] Update release prepare command to include additional checks Add CheckCompatLayerGeneration to release prepare command Nov 24, 2025
Copilot finished work on behalf of tylerbutler November 24, 2025 19:30
Copilot AI requested a review from tylerbutler November 24, 2025 19:30
Copilot AI requested a review from tylerbutler December 2, 2025 21:09
Copilot finished work on behalf of tylerbutler December 2, 2025 21:09
@tylerbutler
Copy link
Member

@copilot when is onlyConfiguredPackages set to false?

This comment was marked as outdated.

Copilot finished work on behalf of tylerbutler December 2, 2025 21:14
@tylerbutler

This comment was marked as outdated.

This comment was marked as outdated.

Copilot finished work on behalf of tylerbutler December 2, 2025 22:15
…te fixCommand

- Update checkCompatLayerGeneration to check only packages in the release group or individual package being released, not all packages in repo
- Change fixCommand from "pnpm run -r layerGeneration:gen" to "pnpm run layerGeneration:gen" to allow root package.json to handle the -r flag
- Add Package import to checkFunctions.ts

Co-authored-by: tylerbutler <[email protected]>
Copilot AI requested a review from tylerbutler December 3, 2025 20:08
Copilot finished work on behalf of tylerbutler December 3, 2025 20:08
@tylerbutler

This comment was marked as outdated.

…to copilot/update-release-prepare-command

# Conflicts:
#	build-tools/packages/build-cli/src/test/commands/generate/compatLayerGeneration.test.ts

This comment was marked as outdated.

Copilot finished work on behalf of tylerbutler December 3, 2025 20:56
@tylerbutler
Copy link
Member

/azp run Build - protocol-definitions,Build - test-tools,server-gitrest,server-gitssh,server-historian,server-routerlicious,Build - client packages,repo-policy-check

@tylerbutler
Copy link
Member

/azp run Build - api-markdown-documenter,Build - benchmark-tool,Build - build-common,Build - build-tools,Build - common-utils,Build - eslint-config-fluid,Build - eslint-plugin-fluid

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

1 similar comment
@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@tylerbutler
Copy link
Member

/azp run Build - protocol-definitions,Build - test-tools,server-gitrest,server-gitssh,server-routerlicious,Build - client packages,repo-policy-check,Build - build-tools

@azure-pipelines
Copy link

Azure Pipelines successfully started running 2 pipeline(s).

@tylerbutler
Copy link
Member

/azp run Build - protocol-definitions,Build - test-tools,server-gitrest,server-gitssh,server-routerlicious,Build - client packages,repo-policy-check,Build - build-tools

@azure-pipelines
Copy link

Azure Pipelines successfully started running 2 pipeline(s).

@tylerbutler
Copy link
Member

@copilot Looks like there are some build or lint failures. Try to reproduce them locally and fix them

Copy link
Contributor Author

Copilot AI commented Dec 3, 2025

@copilot Looks like there are some build or lint failures. Try to reproduce them locally and fix them

Updated comments in commit 43b8af4 to reference the correct command name (compatLayerGeneration instead of layerCompatGeneration) after the file rename during the main branch merge. The code itself was already correct - this was just updating documentation comments to match the renamed command.

Copilot finished work on behalf of tylerbutler December 3, 2025 22:31
@tylerbutler
Copy link
Member

/azp run Build - protocol-definitions,Build - test-tools,server-gitrest,server-gitssh,server-routerlicious,Build - client packages,repo-policy-check,Build - build-tools

@tylerbutler
Copy link
Member

/azp run Build - api-markdown-documenter,Build - benchmark-tool,Build - build-common,Build - build-tools,Build - common-utils,Build - eslint-config-fluid,Build - eslint-plugin-fluid,server-historian

@azure-pipelines
Copy link

Azure Pipelines successfully started running 2 pipeline(s).

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

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.

2 participants