Skip to content

Commit 45d1039

Browse files
committed
Merge remote-tracking branch 'microsoft/main' into commits
2 parents a19ece1 + 0b24d03 commit 45d1039

File tree

441 files changed

+75101
-45675
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

441 files changed

+75101
-45675
lines changed

.changeset/spicy-grapes-leave.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
"@fluidframework/tree": minor
3+
"fluid-framework": minor
4+
"__section": tree
5+
---
6+
Fixed bug in sending of revert edits after an aborted transaction
7+
8+
Aborting a transaction used to put the tree in a state that would trigger an assert when sending some undo/redo edits to peers.
9+
This would prevent some undo/redo edits from being sent and would put the tree in a broken state that prevented any further edits.
10+
This issue could not have caused document corruption, so reopening the document was a possible remedy.
11+
Aborting a transaction no longer puts the tree in such a state, so it is safe to perform undo/redo edits after that.

PACKAGES.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ The dependencies between layers are enforced by the layer-check command._
183183

184184
| Packages | Layer Dependencies |
185185
| --- | --- |
186-
| - [@fluidframework/azure-client](/packages/service-clients/azure-client)</br>- [@fluidframework/odsp-client](/packages/service-clients/odsp-client)</br>- [@fluidframework/tinylicious-client](/packages/service-clients/tinylicious-client)</br>&nbsp;</br>&nbsp;</br>&nbsp;</br>&nbsp;</br>&nbsp;</br>&nbsp;</br>&nbsp;</br>&nbsp;</br>&nbsp; | - [Core-Interfaces](#Core-Interfaces)</br>- [Driver-Definitions](#Driver-Definitions)</br>- [Container-Definitions](#Container-Definitions)</br>- [Core-Utils](#Core-Utils)</br>- [Telemetry-Utils](#Telemetry-Utils)</br>- [Driver-Utils](#Driver-Utils)</br>- [Other-Utils](#Other-Utils)</br>- [Driver](#Driver)</br>- [Loader](#Loader)</br>- [Runtime](#Runtime)</br>- [Framework](#Framework)</br>- [Routerlicious-Driver](#Routerlicious-Driver) |
186+
| - [@fluidframework/azure-client](/packages/service-clients/azure-client)</br>- [@fluidframework/odsp-client](/packages/service-clients/odsp-client)</br>- [@fluidframework/tinylicious-client](/packages/service-clients/tinylicious-client)</br>&nbsp;</br>&nbsp;</br>&nbsp;</br>&nbsp;</br>&nbsp;</br>&nbsp;</br>&nbsp;</br>&nbsp;</br>&nbsp;</br>&nbsp; | - [Core-Interfaces](#Core-Interfaces)</br>- [Driver-Definitions](#Driver-Definitions)</br>- [Container-Definitions](#Container-Definitions)</br>- [Core-Utils](#Core-Utils)</br>- [Client-Utils](#Client-Utils)</br>- [Telemetry-Utils](#Telemetry-Utils)</br>- [Driver-Utils](#Driver-Utils)</br>- [Other-Utils](#Other-Utils)</br>- [Driver](#Driver)</br>- [Loader](#Loader)</br>- [Runtime](#Runtime)</br>- [Framework](#Framework)</br>- [Routerlicious-Driver](#Routerlicious-Driver) |
187187

188188
### Examples
189189

build-tools/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "build-tools-release-group-root",
3-
"version": "0.61.0",
3+
"version": "0.62.0",
44
"private": true,
55
"homepage": "https://fluidframework.com",
66
"repository": {

build-tools/packages/build-cli/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@fluid-tools/build-cli",
3-
"version": "0.61.0",
3+
"version": "0.62.0",
44
"description": "Build tools for the Fluid Framework",
55
"homepage": "https://fluidframework.com",
66
"repository": {

build-tools/packages/build-cli/src/library/repoPolicyCheck/copyrightFileHeader.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ export const handlers: Handler[] = [
117117
},
118118
{
119119
name: "js-ts-copyright-file-header",
120-
match: /(^|\/)[^/]+\.c?[jt]sx?$/i,
120+
match: /(^|\/)[^/]+\.[cm]?[jt]sx?$/i,
121121
handler: makeHandler({
122122
type: "JavaScript/TypeScript",
123123
headerStart: /(#![^\n]*\r?\n)?\/\*!\r?\n/, // Begins with optional hashbang followed by '/*!'

build-tools/packages/build-infrastructure/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@fluid-tools/build-infrastructure",
3-
"version": "0.61.0",
3+
"version": "0.62.0",
44
"description": "Fluid build infrastructure",
55
"homepage": "https://fluidframework.com",
66
"repository": {

build-tools/packages/build-tools/package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@fluidframework/build-tools",
3-
"version": "0.61.0",
3+
"version": "0.62.0",
44
"description": "Fluid Build tools",
55
"homepage": "https://fluidframework.com",
66
"repository": {
@@ -75,7 +75,6 @@
7575
"@types/lodash.isequal": "^4.5.8",
7676
"@types/mocha": "^10.0.10",
7777
"@types/node": "^22.19.1",
78-
7978
"@types/semver": "^7.7.1",
8079
"eslint": "~8.57.0",
8180
"json-schema-to-typescript": "^15.0.4",

build-tools/packages/build-tools/src/fluidBuild/tasks/leaf/leafTask.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import crypto from "crypto";
1111
import * as path from "path";
1212
import type { AsyncPriorityQueue } from "async";
1313
import registerDebug from "debug";
14-
import globby from "globby";
1514
import chalk from "picocolors";
1615

1716
import { defaultLogger } from "../../../common/logging";
@@ -30,6 +29,7 @@ import {
3029
} from "../../fluidBuildConfig";
3130
import { options } from "../../options";
3231
import { Task, type TaskExec } from "../task";
32+
import { globWithGitignore } from "../taskUtils";
3333

3434
const { log } = defaultLogger;
3535
const traceTaskTrigger = registerDebug("fluid-build:task:trigger");
@@ -738,13 +738,10 @@ export abstract class LeafWithGlobInputOutputDoneFileTask extends LeafWithFileSt
738738
const globs = mode === "input" ? await this.getInputGlobs() : await this.getOutputGlobs();
739739
const excludeGitIgnoredFiles: boolean = this.gitIgnore.includes(mode);
740740

741-
const files = await globby(globs, {
741+
return globWithGitignore(globs, {
742742
cwd: this.node.pkg.directory,
743-
// file paths returned from getInputFiles and getOutputFiles should always be absolute
744-
absolute: true,
745743
gitignore: excludeGitIgnoredFiles,
746744
});
747-
return files;
748745
}
749746
}
750747

build-tools/packages/build-tools/src/fluidBuild/tasks/taskUtils.ts

Lines changed: 94 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { readFile, readdir } from "node:fs/promises";
88
import { pathToFileURL } from "node:url";
99
import * as path from "path";
1010
import * as glob from "glob";
11+
import globby from "globby";
1112

1213
import type { PackageJson } from "../../common/npmPackage";
1314
import { lookUpDirSync } from "../../common/utils";
@@ -75,15 +76,35 @@ export function getApiExtractorConfigFilePath(commandLine: string): string {
7576
}
7677

7778
export function toPosixPath(s: string) {
78-
return path.sep === "\\" ? s.replace(/\\/g, "/") : s;
79+
return s.replace(/\\/g, "/");
7980
}
8081

82+
/**
83+
* Promisified wrapper around the glob library.
84+
*
85+
* @param pattern - Glob pattern to match files
86+
* @param options - Options to pass to glob
87+
* @returns Promise resolving to array of matched file paths
88+
*
89+
* @remarks
90+
* When the environment variable `FLUID_BUILD_TEST_RANDOM_ORDER` is set to "true", results will be
91+
* randomly shuffled to expose code that incorrectly depends on glob result ordering. This should only
92+
* be used in test/CI environments.
93+
*/
8194
export async function globFn(pattern: string, options: glob.IOptions = {}): Promise<string[]> {
8295
return new Promise((resolve, reject) => {
8396
glob.default(pattern, options, (err, matches) => {
8497
if (err) {
8598
reject(err);
99+
return;
86100
}
101+
102+
// Test mode: randomize order to expose ordering dependencies
103+
if (isRandomOrderTestMode()) {
104+
resolve(shuffleArray([...matches]));
105+
return;
106+
}
107+
87108
resolve(matches);
88109
});
89110
});
@@ -97,3 +118,75 @@ export async function loadModule(modulePath: string, moduleType?: string) {
97118
}
98119
return require(modulePath);
99120
}
121+
122+
/**
123+
* Shuffles an array in place using Fisher-Yates algorithm.
124+
* Used for testing order-independence when FLUID_BUILD_TEST_RANDOM_ORDER is set to "true".
125+
*
126+
* @param array - The array to shuffle
127+
* @returns The shuffled array (same reference, modified in place)
128+
*/
129+
function shuffleArray<T>(array: T[]): T[] {
130+
for (let i = array.length - 1; i > 0; i--) {
131+
const j = Math.floor(Math.random() * (i + 1));
132+
[array[i], array[j]] = [array[j], array[i]];
133+
}
134+
return array;
135+
}
136+
137+
/**
138+
* Returns true if runtime order randomization is enabled for testing.
139+
* When enabled, glob functions will randomize their results to expose order dependencies.
140+
*/
141+
function isRandomOrderTestMode(): boolean {
142+
return process.env.FLUID_BUILD_TEST_RANDOM_ORDER === "true";
143+
}
144+
145+
/**
146+
* Options for {@link globWithGitignore}.
147+
*/
148+
export interface GlobWithGitignoreOptions {
149+
/**
150+
* The working directory to use for relative patterns.
151+
*/
152+
cwd: string;
153+
154+
/**
155+
* Whether to apply gitignore rules to exclude files.
156+
* @defaultValue true
157+
*/
158+
gitignore?: boolean;
159+
}
160+
161+
/**
162+
* Glob files with optional gitignore support. This function is used by LeafWithGlobInputOutputDoneFileTask
163+
* to get input and output files for tasks.
164+
*
165+
* @param patterns - Glob patterns to match files. Patterns should be relative paths (e.g., "src/**\/*.ts").
166+
* Absolute patterns are not recommended as they may behave unexpectedly with the cwd option.
167+
* @param options - Options for the glob operation.
168+
* @returns An array of absolute paths to all files that match the globs.
169+
*
170+
* @remarks
171+
* When the environment variable `FLUID_BUILD_TEST_RANDOM_ORDER` is set to "true", results will be
172+
* randomly shuffled to expose code that incorrectly depends on glob result ordering. This should only
173+
* be used in test/CI environments.
174+
*/
175+
export async function globWithGitignore(
176+
patterns: readonly string[],
177+
options: GlobWithGitignoreOptions,
178+
): Promise<string[]> {
179+
const { cwd, gitignore = true } = options;
180+
const results = await globby([...patterns], {
181+
cwd,
182+
absolute: true,
183+
gitignore,
184+
});
185+
186+
// Test mode: randomize order to expose ordering dependencies
187+
if (isRandomOrderTestMode()) {
188+
return shuffleArray([...results]);
189+
}
190+
191+
return results;
192+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Test gitignore
2+
# The entries here don't exist in the repo, they are created by tests when they run.
3+
gitignored/
4+
*.ignored

0 commit comments

Comments
 (0)