Skip to content

Commit 72caced

Browse files
committed
Merge branch 'main' into fix/77699
2 parents 12dd146 + 0d9c788 commit 72caced

2,096 files changed

Lines changed: 12856 additions & 8530 deletions

File tree

Some content is hidden

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

.github/actions/javascript/getPullRequestIncrementalChanges/index.js

Lines changed: 109 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12539,6 +12539,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
1253912539
Object.defineProperty(exports, "__esModule", ({ value: true }));
1254012540
const github_1 = __nccwpck_require__(5438);
1254112541
const child_process_1 = __nccwpck_require__(2081);
12542+
const fs_1 = __importDefault(__nccwpck_require__(7147));
12543+
const path_1 = __importDefault(__nccwpck_require__(1017));
1254212544
const util_1 = __nccwpck_require__(3837);
1254312545
const CONST_1 = __importDefault(__nccwpck_require__(9873));
1254412546
const GithubUtils_1 = __importDefault(__nccwpck_require__(9296));
@@ -12591,20 +12593,31 @@ class Git {
1259112593
* @returns Structured diff result with line numbers and change information
1259212594
* @throws Error when git command fails (invalid refs, not a git repo, file not found, etc.)
1259312595
*/
12594-
static diff(fromRef, toRef, filePaths) {
12596+
static diff(fromRef, toRef, filePaths, shouldIncludeUntrackedFiles = false) {
1259512597
// Build git diff command (with 0 context lines for easier parsing)
1259612598
let command = `git diff -U0 ${fromRef}`;
1259712599
if (toRef) {
1259812600
command += ` ${toRef}`;
1259912601
}
1260012602
if (filePaths) {
1260112603
const pathsArray = Array.isArray(filePaths) ? filePaths : [filePaths];
12602-
const quotedPaths = pathsArray.map((path) => `"${path}"`).join(' ');
12604+
const quotedPaths = pathsArray.map((filePath) => `"${filePath}"`).join(' ');
1260312605
command += ` -- ${quotedPaths}`;
1260412606
}
1260512607
// Execute git diff with unified format - let errors bubble up
1260612608
const diffOutput = execSync(command);
12607-
return Git.parseDiff(diffOutput);
12609+
const diffResult = Git.parseDiff(diffOutput);
12610+
// Include untracked files when diffing against working directory
12611+
if (!toRef && shouldIncludeUntrackedFiles) {
12612+
const untrackedFiles = Git.getUntrackedFiles(filePaths);
12613+
const untrackedFileDiffs = Git.createFileDiffsForUntrackedFiles(untrackedFiles);
12614+
// Merge untracked files into the diff result
12615+
if (untrackedFileDiffs.length > 0) {
12616+
diffResult.files.push(...untrackedFileDiffs);
12617+
diffResult.hasChanges = true;
12618+
}
12619+
}
12620+
return diffResult;
1260812621
}
1260912622
/**
1261012623
* Parse git diff output into structured format.
@@ -12892,7 +12905,7 @@ class Git {
1289212905
return false;
1289312906
}
1289412907
}
12895-
static async getChangedFileNames(fromRef, toRef) {
12908+
static async getChangedFileNames(fromRef, toRef, shouldIncludeUntrackedFiles = false) {
1289612909
if (IS_CI) {
1289712910
const { data: changedFiles } = await GithubUtils_1.default.octokit.pulls.listFiles({
1289812911
owner: CONST_1.default.GITHUB_OWNER,
@@ -12903,10 +12916,101 @@ class Git {
1290312916
return changedFiles.map((file) => file.filename);
1290412917
}
1290512918
// Get the diff output and check status
12906-
const diffResult = this.diff(fromRef, toRef);
12919+
const diffResult = this.diff(fromRef, toRef, undefined, shouldIncludeUntrackedFiles);
1290712920
const files = diffResult.files.map((file) => file.filePath);
1290812921
return files;
1290912922
}
12923+
/**
12924+
* Get list of untracked files from git.
12925+
*
12926+
* @param filePaths - Optional specific file path(s) to filter by (relative to git repo root)
12927+
* @returns Array of untracked file paths
12928+
*/
12929+
static getUntrackedFiles(filePaths) {
12930+
try {
12931+
// Get all untracked files
12932+
const untrackedOutput = execSync('git ls-files --others --exclude-standard', {
12933+
stdio: 'pipe',
12934+
});
12935+
if (!untrackedOutput.trim()) {
12936+
return [];
12937+
}
12938+
let untrackedFiles = untrackedOutput
12939+
.trim()
12940+
.split('\n')
12941+
.filter((file) => file.length > 0);
12942+
// Filter by filePaths if provided
12943+
if (filePaths) {
12944+
const pathsArray = Array.isArray(filePaths) ? filePaths : [filePaths];
12945+
const normalizedPaths = pathsArray.map((p) => path_1.default.normalize(p));
12946+
untrackedFiles = untrackedFiles.filter((file) => {
12947+
const normalizedFile = path_1.default.normalize(file);
12948+
return normalizedPaths.some((p) => normalizedFile === p || normalizedFile.startsWith(p + path_1.default.sep));
12949+
});
12950+
}
12951+
return untrackedFiles;
12952+
}
12953+
catch (error) {
12954+
// If command fails, return empty array (e.g., not a git repo)
12955+
return [];
12956+
}
12957+
}
12958+
/**
12959+
* Create FileDiff entries for untracked files by reading their content and treating all lines as added.
12960+
*
12961+
* @param untrackedFiles - Array of untracked file paths (relative to git repo root)
12962+
* @returns Array of FileDiff entries for untracked files
12963+
*/
12964+
static createFileDiffsForUntrackedFiles(untrackedFiles) {
12965+
const fileDiffs = [];
12966+
for (const filePath of untrackedFiles) {
12967+
const absolutePath = path_1.default.join(process.cwd(), filePath);
12968+
// Check if file exists and is readable
12969+
if (!fs_1.default.existsSync(absolutePath) || !fs_1.default.statSync(absolutePath).isFile()) {
12970+
continue;
12971+
}
12972+
let fileContent;
12973+
try {
12974+
fileContent = fs_1.default.readFileSync(absolutePath, 'utf8');
12975+
}
12976+
catch (error) {
12977+
// Skip files that can't be read
12978+
continue;
12979+
}
12980+
// Split content into lines
12981+
const lines = fileContent.split('\n');
12982+
const addedLines = new Set();
12983+
// Create a single hunk with all lines as added
12984+
const diffLines = [];
12985+
for (let i = 0; i < lines.length; i++) {
12986+
const lineNumber = i + 1;
12987+
addedLines.add(lineNumber);
12988+
diffLines.push({
12989+
number: lineNumber,
12990+
type: 'added',
12991+
content: lines.at(i) ?? '',
12992+
});
12993+
}
12994+
// Create a single hunk for the entire file
12995+
const hunk = {
12996+
oldStart: 0,
12997+
oldCount: 0,
12998+
newStart: 1,
12999+
newCount: lines.length,
13000+
lines: diffLines,
13001+
};
13002+
const fileDiff = {
13003+
filePath,
13004+
diffType: 'added',
13005+
hunks: [hunk],
13006+
addedLines,
13007+
removedLines: new Set(),
13008+
modifiedLines: new Set(),
13009+
};
13010+
fileDiffs.push(fileDiff);
13011+
}
13012+
return fileDiffs;
13013+
}
1291013014
}
1291113015
exports["default"] = Git;
1291213016

.github/workflows/androidBump.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@ jobs:
2121
with:
2222
bundler-cache: true
2323

24-
- name: Install 1Password CLI
25-
# v1
26-
uses: 1password/install-cli-action@143a85f84a90555d121cde2ff5872e393a47ab9f
24+
- name: Setup 1Password CLI and certificates
25+
uses: Expensify/GitHub-Actions/setup-certificate-1p@main
26+
with:
27+
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
28+
SHOULD_LOAD_SSL_CERTIFICATES: 'false'
2729

2830
- name: Load files from 1Password
2931
working-directory: android/app

.github/workflows/buildAndroid.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,11 @@ jobs:
9696
with:
9797
bundler-cache: true
9898

99-
- name: Install 1Password CLI
100-
# v1
101-
uses: 1password/install-cli-action@143a85f84a90555d121cde2ff5872e393a47ab9f
99+
- name: Setup 1Password CLI and certificates
100+
uses: Expensify/GitHub-Actions/setup-certificate-1p@main
101+
with:
102+
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
103+
SHOULD_LOAD_SSL_CERTIFICATES: 'false'
102104

103105
- name: Load files from 1Password
104106
working-directory: android/app

.github/workflows/cspell.yml

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: 🧙 Check spell
1+
name: Spell check
22

33
on:
44
pull_request:
@@ -8,15 +8,48 @@ on:
88
jobs:
99
spellcheck:
1010
runs-on: ubuntu-latest
11-
name: 🔍 spellcheck
1211
steps:
1312
- uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493
14-
- uses: streetsidesoftware/cspell-action@72ae91e90fa38f2335a60e233a847a6d00a9f221
13+
14+
- name: Setup Node
15+
uses: ./.github/actions/composite/setupNode
16+
17+
- name: Remove E/App version from package-lock.json
18+
shell: bash
19+
run: jq 'del(.version, .packages[""].version)' package-lock.json > normalized-package-lock.json
20+
21+
- name: Restore cspell cache
22+
# v4
23+
uses: actions/cache/restore@1bd1e32a3bdc45362d1e726936510720a7c30a57
24+
with:
25+
path: .cspellcache
26+
key: cspell-${{ runner.os }}-${{ hashFiles('cspell.json', 'normalized-package-lock.json') }}-${{ github.sha }}
27+
restore-keys: |
28+
cspell-${{ runner.os }}-${{ hashFiles('cspell.json', 'normalized-package-lock.json') }}-
29+
cspell-${{ runner.os }}-
30+
31+
- name: Get changed files
32+
id: changed-files
33+
env:
34+
GH_TOKEN: ${{ github.token }}
35+
run: |
36+
FILES=$(gh api repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files --jq '.[].filename' | tr '\n' ' ')
37+
echo "files=$FILES" >> "$GITHUB_OUTPUT"
38+
39+
- name: Filter out dot files
40+
id: filtered-files
41+
run: |
42+
FILES=$(echo "${{ steps.changed-files.outputs.files }}" | tr ' ' '\n' | grep -v '^\.' | xargs)
43+
echo "files=$FILES" >> "$GITHUB_OUTPUT"
44+
45+
- name: Spell check
46+
if: steps.filtered-files.outputs.files != ''
47+
run: npm run spell-changed -- ${{ steps.filtered-files.outputs.files }}
48+
49+
- name: Save cspell cache
50+
# v4
51+
uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57
52+
if: always()
1553
with:
16-
files: "**/*"
17-
root: "."
18-
config: "./cspell.json"
19-
inline: error
20-
strict: true
21-
use_cspell_files: false
22-
incremental_files_only: true
54+
path: .cspellcache
55+
key: cspell-${{ runner.os }}-${{ hashFiles('cspell.json', 'normalized-package-lock.json') }}-${{ github.sha }}

.github/workflows/deploy.yml

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,11 @@ jobs:
129129
- name: Install New Expensify Gems
130130
run: bundle install
131131

132-
- name: Install 1Password CLI
133-
# v1
134-
uses: 1password/install-cli-action@143a85f84a90555d121cde2ff5872e393a47ab9f
132+
- name: Setup 1Password CLI and certificates
133+
uses: Expensify/GitHub-Actions/setup-certificate-1p@main
134+
with:
135+
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
136+
SHOULD_LOAD_SSL_CERTIFICATES: 'false'
135137

136138
- name: Load files from 1Password
137139
env:
@@ -408,9 +410,11 @@ jobs:
408410
max_attempts: 5
409411
command: npm run pod-install
410412

411-
- name: Install 1Password CLI
412-
# v1
413-
uses: 1password/install-cli-action@143a85f84a90555d121cde2ff5872e393a47ab9f
413+
- name: Setup 1Password CLI and certificates
414+
uses: Expensify/GitHub-Actions/setup-certificate-1p@main
415+
with:
416+
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
417+
SHOULD_LOAD_SSL_CERTIFICATES: 'false'
414418

415419
- name: Load files from 1Password
416420
env:

.github/workflows/lint-changed.yml

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,28 @@ jobs:
5656
uses: ./.github/actions/composite/setupNode
5757
with:
5858
IS_DESKTOP_BUILD: true
59-
59+
60+
- name: Remove E/App version from package-lock.json
61+
shell: bash
62+
run: jq 'del(.version, .packages[""].version)' package-lock.json > normalized-package-lock.json
63+
64+
- name: Restore ESLint cache
65+
# v4
66+
uses: actions/cache/restore@1bd1e32a3bdc45362d1e726936510720a7c30a57
67+
with:
68+
path: node_modules/.cache/eslint-changed
69+
key: ${{ runner.os }}-eslint-changed-${{ hashFiles('eslint.changed.config.*', 'normalized-package-lock.json') }}-${{ github.sha }}
70+
restore-keys: |
71+
${{ runner.os }}-eslint-changed-${{ hashFiles('eslint.changed.config.*', 'normalized-package-lock.json') }}-
72+
${{ runner.os }}-eslint-changed-
73+
6074
- name: Run ESLint to check for deprecation warnings
61-
run: |
62-
# shellcheck disable=SC2046
63-
npm run lint-changed
75+
run: npm run lint-changed
76+
77+
- name: Save ESLint cache
78+
# v4
79+
uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57
80+
if: always()
81+
with:
82+
path: node_modules/.cache/eslint-changed
83+
key: ${{ runner.os }}-eslint-changed-${{ hashFiles('eslint.changed.config.*', 'normalized-package-lock.json') }}-${{ github.sha }}

.github/workflows/lint.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,29 @@ jobs:
2626
with:
2727
IS_DESKTOP_BUILD: true
2828

29+
- name: Remove E/App version from package-lock.json
30+
shell: bash
31+
run: jq 'del(.version, .packages[""].version)' package-lock.json > normalized-package-lock.json
32+
33+
- name: Restore ESLint cache
34+
# v4
35+
uses: actions/cache/restore@1bd1e32a3bdc45362d1e726936510720a7c30a57
36+
with:
37+
path: node_modules/.cache/eslint
38+
key: ${{ runner.os }}-eslint-${{ hashFiles('eslint.config.*', 'normalized-package-lock.json') }}-${{ github.sha }}
39+
restore-keys: |
40+
${{ runner.os }}-eslint-${{ hashFiles('eslint.config.*', 'normalized-package-lock.json') }}-
41+
${{ runner.os }}-eslint-
42+
2943
- name: Lint JavaScript and Typescript with ESLint
3044
run: npm run lint
3145
env:
3246
CI: true
47+
48+
- name: Save ESLint cache
49+
# v4
50+
uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57
51+
if: always()
52+
with:
53+
path: node_modules/.cache/eslint
54+
key: ${{ runner.os }}-eslint-${{ hashFiles('eslint.config.*', 'normalized-package-lock.json') }}-${{ github.sha }}

.github/workflows/react-compiler-compliance.yml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,7 @@ jobs:
2525
uses: ./.github/actions/composite/setupNode
2626

2727
- name: Run React Compiler Compliance Check
28-
# In phase 0 of the React Compiler compliance check rollout,
29-
# we want to report failures but don't fail the check.
30-
# See https://github.com/Expensify/App/issues/68765#issuecomment-3487317881
31-
run: npm run react-compiler-compliance-check check-changed -- --filterByDiff --enforceNewComponents
28+
run: npm run react-compiler-compliance-check check-changed
3229
env:
3330
CI: true
3431
GITHUB_TOKEN: ${{ github.token }}

0 commit comments

Comments
 (0)