Skip to content

Commit 2dbf073

Browse files
Merge branch 'main' of github.com:Expensify/App into fix/65041-uneditable-task-after-user-leaves-group
2 parents 9b1460c + 6fd55d9 commit 2dbf073

941 files changed

Lines changed: 54588 additions & 12174 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.

.eslintrc.changed.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ module.exports = {
88
'deprecation/deprecation': 'error',
99
'rulesdir/no-default-id-values': 'error',
1010
'rulesdir/provide-canBeMissing-in-useOnyx': 'error',
11+
'rulesdir/no-unstable-hook-defaults': 'error',
1112
'no-restricted-syntax': [
1213
'error',
1314
{

.eslintrc.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ module.exports = {
219219
'es/no-optional-chaining': 'off',
220220
'deprecation/deprecation': 'off',
221221
'arrow-body-style': 'off',
222+
'no-continue': 'off',
222223

223224
// Import specific rules
224225
'import/consistent-type-specifier-style': ['error', 'prefer-top-level'],
@@ -236,6 +237,7 @@ module.exports = {
236237
'react-native-a11y/has-accessibility-hint': ['off'],
237238
'react/require-default-props': 'off',
238239
'react/prop-types': 'off',
240+
'react/jsx-key': 'error',
239241
'react/jsx-no-constructed-context-values': 'error',
240242
'react-native-a11y/has-valid-accessibility-descriptors': [
241243
'error',

.github/actions/javascript/authorChecklist/index.js

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15560,6 +15560,13 @@ const CONST = {
1556015560
HELP_WANTED: 'Help Wanted',
1556115561
CP_STAGING: 'CP Staging',
1556215562
},
15563+
STATE: {
15564+
OPEN: 'open',
15565+
},
15566+
COMMENT: {
15567+
TYPE_BOT: 'Bot',
15568+
NAME_GITHUB_ACTIONS: 'github-actions',
15569+
},
1556315570
ACTIONS: {
1556415571
CREATED: 'created',
1556515572
EDITED: 'edited',
@@ -15578,6 +15585,7 @@ const CONST = {
1557815585
NO_ACTION: 'NO_ACTION',
1557915586
ACTION_EDIT: 'ACTION_EDIT',
1558015587
ACTION_REQUIRED: 'ACTION_REQUIRED',
15588+
ACTION_HIDE_DUPLICATE: 'ACTION_HIDE_DUPLICATE',
1558115589
};
1558215590
exports["default"] = CONST;
1558315591

@@ -15834,7 +15842,10 @@ class GithubUtils {
1583415842
const sortedDeployBlockers = [...new Set(deployBlockers)].sort((a, b) => GithubUtils.getIssueOrPullRequestNumberFromURL(a) - GithubUtils.getIssueOrPullRequestNumberFromURL(b));
1583515843
// Tag version and comparison URL
1583615844
// eslint-disable-next-line max-len
15837-
let issueBody = `**Release Version:** \`${tag}\`\r\n**Compare Changes:** https://github.com/${process.env.GITHUB_REPOSITORY}/compare/production...staging\r\n`;
15845+
let issueBody = `**Release Version:** \`${tag}\`\r\n**Compare Changes:** https://github.com/${process.env.GITHUB_REPOSITORY}/compare/production...staging\r\n\r\n`;
15846+
// Warn deployers about potential bugs with the new process
15847+
issueBody +=
15848+
'> 💡 **Deployer FYI:** This checklist was generated using a new process. PR list from original method and detail logging can be found in the most recent [deploy workflow](https://github.com/Expensify/App/actions/workflows/deploy.yml) labeled `staging`, in the `createChecklist` action. Please tag @Julesssss with any issues.\r\n\r\n';
1583815849
// PR list
1583915850
if (sortedPRList.length > 0) {
1584015851
issueBody += '\r\n**This release contains changes from the following pull requests:**\r\n';
@@ -15938,6 +15949,14 @@ class GithubUtils {
1593815949
per_page: 100,
1593915950
}, (response) => response.data.map((comment) => comment.body));
1594015951
}
15952+
static getAllCommentDetails(issueNumber) {
15953+
return this.paginate(this.octokit.issues.listComments, {
15954+
owner: CONST_1.default.GITHUB_OWNER,
15955+
repo: CONST_1.default.APP_REPO,
15956+
issue_number: issueNumber,
15957+
per_page: 100,
15958+
}, (response) => response.data);
15959+
}
1594115960
/**
1594215961
* Create comment on pull request
1594315962
*/
@@ -15964,6 +15983,17 @@ class GithubUtils {
1596415983
})
1596515984
.then((response) => response.data.workflow_runs.at(0)?.id ?? -1);
1596615985
}
15986+
/**
15987+
* List workflow runs for the repository.
15988+
*/
15989+
static async listWorkflowRunsForRepo(options = {}) {
15990+
return this.octokit.actions.listWorkflowRunsForRepo({
15991+
owner: CONST_1.default.GITHUB_OWNER,
15992+
repo: CONST_1.default.APP_REPO,
15993+
per_page: options.per_page ?? 50,
15994+
...(options.status && { status: options.status }),
15995+
});
15996+
}
1596715997
/**
1596815998
* Generate the URL of an New Expensify pull request given the PR number.
1596915999
*/

.github/actions/javascript/awaitStagingDeploys/index.js

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12278,7 +12278,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
1227812278
return result;
1227912279
};
1228012280
Object.defineProperty(exports, "__esModule", ({ value: true }));
12281-
exports.getStringInput = exports.getJSONInput = void 0;
12281+
exports.convertToNumber = exports.getStringInput = exports.getJSONInput = void 0;
1228212282
const core = __importStar(__nccwpck_require__(2186));
1228312283
/**
1228412284
* Safely parse a JSON input to a GitHub Action.
@@ -12307,6 +12307,23 @@ function getStringInput(name, options, defaultValue) {
1230712307
return input;
1230812308
}
1230912309
exports.getStringInput = getStringInput;
12310+
/**
12311+
* Converts a value to a number, returning 0 for non-numeric values.
12312+
*/
12313+
function convertToNumber(value) {
12314+
switch (typeof value) {
12315+
case 'number':
12316+
return value;
12317+
case 'string':
12318+
if (!Number.isNaN(Number(value))) {
12319+
return Number(value);
12320+
}
12321+
return 0;
12322+
default:
12323+
return 0;
12324+
}
12325+
}
12326+
exports.convertToNumber = convertToNumber;
1231012327

1231112328

1231212329
/***/ }),
@@ -12334,6 +12351,13 @@ const CONST = {
1233412351
HELP_WANTED: 'Help Wanted',
1233512352
CP_STAGING: 'CP Staging',
1233612353
},
12354+
STATE: {
12355+
OPEN: 'open',
12356+
},
12357+
COMMENT: {
12358+
TYPE_BOT: 'Bot',
12359+
NAME_GITHUB_ACTIONS: 'github-actions',
12360+
},
1233712361
ACTIONS: {
1233812362
CREATED: 'created',
1233912363
EDITED: 'edited',
@@ -12352,6 +12376,7 @@ const CONST = {
1235212376
NO_ACTION: 'NO_ACTION',
1235312377
ACTION_EDIT: 'ACTION_EDIT',
1235412378
ACTION_REQUIRED: 'ACTION_REQUIRED',
12379+
ACTION_HIDE_DUPLICATE: 'ACTION_HIDE_DUPLICATE',
1235512380
};
1235612381
exports["default"] = CONST;
1235712382

@@ -12608,7 +12633,10 @@ class GithubUtils {
1260812633
const sortedDeployBlockers = [...new Set(deployBlockers)].sort((a, b) => GithubUtils.getIssueOrPullRequestNumberFromURL(a) - GithubUtils.getIssueOrPullRequestNumberFromURL(b));
1260912634
// Tag version and comparison URL
1261012635
// eslint-disable-next-line max-len
12611-
let issueBody = `**Release Version:** \`${tag}\`\r\n**Compare Changes:** https://github.com/${process.env.GITHUB_REPOSITORY}/compare/production...staging\r\n`;
12636+
let issueBody = `**Release Version:** \`${tag}\`\r\n**Compare Changes:** https://github.com/${process.env.GITHUB_REPOSITORY}/compare/production...staging\r\n\r\n`;
12637+
// Warn deployers about potential bugs with the new process
12638+
issueBody +=
12639+
'> 💡 **Deployer FYI:** This checklist was generated using a new process. PR list from original method and detail logging can be found in the most recent [deploy workflow](https://github.com/Expensify/App/actions/workflows/deploy.yml) labeled `staging`, in the `createChecklist` action. Please tag @Julesssss with any issues.\r\n\r\n';
1261212640
// PR list
1261312641
if (sortedPRList.length > 0) {
1261412642
issueBody += '\r\n**This release contains changes from the following pull requests:**\r\n';
@@ -12712,6 +12740,14 @@ class GithubUtils {
1271212740
per_page: 100,
1271312741
}, (response) => response.data.map((comment) => comment.body));
1271412742
}
12743+
static getAllCommentDetails(issueNumber) {
12744+
return this.paginate(this.octokit.issues.listComments, {
12745+
owner: CONST_1.default.GITHUB_OWNER,
12746+
repo: CONST_1.default.APP_REPO,
12747+
issue_number: issueNumber,
12748+
per_page: 100,
12749+
}, (response) => response.data);
12750+
}
1271512751
/**
1271612752
* Create comment on pull request
1271712753
*/
@@ -12738,6 +12774,17 @@ class GithubUtils {
1273812774
})
1273912775
.then((response) => response.data.workflow_runs.at(0)?.id ?? -1);
1274012776
}
12777+
/**
12778+
* List workflow runs for the repository.
12779+
*/
12780+
static async listWorkflowRunsForRepo(options = {}) {
12781+
return this.octokit.actions.listWorkflowRunsForRepo({
12782+
owner: CONST_1.default.GITHUB_OWNER,
12783+
repo: CONST_1.default.APP_REPO,
12784+
per_page: options.per_page ?? 50,
12785+
...(options.status && { status: options.status }),
12786+
});
12787+
}
1274112788
/**
1274212789
* Generate the URL of an New Expensify pull request given the PR number.
1274312790
*/

.github/actions/javascript/checkAndroidStatus/index.js

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -737053,6 +737053,13 @@ const CONST = {
737053737053
HELP_WANTED: 'Help Wanted',
737054737054
CP_STAGING: 'CP Staging',
737055737055
},
737056+
STATE: {
737057+
OPEN: 'open',
737058+
},
737059+
COMMENT: {
737060+
TYPE_BOT: 'Bot',
737061+
NAME_GITHUB_ACTIONS: 'github-actions',
737062+
},
737056737063
ACTIONS: {
737057737064
CREATED: 'created',
737058737065
EDITED: 'edited',
@@ -737071,6 +737078,7 @@ const CONST = {
737071737078
NO_ACTION: 'NO_ACTION',
737072737079
ACTION_EDIT: 'ACTION_EDIT',
737073737080
ACTION_REQUIRED: 'ACTION_REQUIRED',
737081+
ACTION_HIDE_DUPLICATE: 'ACTION_HIDE_DUPLICATE',
737074737082
};
737075737083
exports["default"] = CONST;
737076737084

@@ -737327,7 +737335,10 @@ class GithubUtils {
737327737335
const sortedDeployBlockers = [...new Set(deployBlockers)].sort((a, b) => GithubUtils.getIssueOrPullRequestNumberFromURL(a) - GithubUtils.getIssueOrPullRequestNumberFromURL(b));
737328737336
// Tag version and comparison URL
737329737337
// eslint-disable-next-line max-len
737330-
let issueBody = `**Release Version:** \`${tag}\`\r\n**Compare Changes:** https://github.com/${process.env.GITHUB_REPOSITORY}/compare/production...staging\r\n`;
737338+
let issueBody = `**Release Version:** \`${tag}\`\r\n**Compare Changes:** https://github.com/${process.env.GITHUB_REPOSITORY}/compare/production...staging\r\n\r\n`;
737339+
// Warn deployers about potential bugs with the new process
737340+
issueBody +=
737341+
'> 💡 **Deployer FYI:** This checklist was generated using a new process. PR list from original method and detail logging can be found in the most recent [deploy workflow](https://github.com/Expensify/App/actions/workflows/deploy.yml) labeled `staging`, in the `createChecklist` action. Please tag @Julesssss with any issues.\r\n\r\n';
737331737342
// PR list
737332737343
if (sortedPRList.length > 0) {
737333737344
issueBody += '\r\n**This release contains changes from the following pull requests:**\r\n';
@@ -737431,6 +737442,14 @@ class GithubUtils {
737431737442
per_page: 100,
737432737443
}, (response) => response.data.map((comment) => comment.body));
737433737444
}
737445+
static getAllCommentDetails(issueNumber) {
737446+
return this.paginate(this.octokit.issues.listComments, {
737447+
owner: CONST_1.default.GITHUB_OWNER,
737448+
repo: CONST_1.default.APP_REPO,
737449+
issue_number: issueNumber,
737450+
per_page: 100,
737451+
}, (response) => response.data);
737452+
}
737434737453
/**
737435737454
* Create comment on pull request
737436737455
*/
@@ -737457,6 +737476,17 @@ class GithubUtils {
737457737476
})
737458737477
.then((response) => response.data.workflow_runs.at(0)?.id ?? -1);
737459737478
}
737479+
/**
737480+
* List workflow runs for the repository.
737481+
*/
737482+
static async listWorkflowRunsForRepo(options = {}) {
737483+
return this.octokit.actions.listWorkflowRunsForRepo({
737484+
owner: CONST_1.default.GITHUB_OWNER,
737485+
repo: CONST_1.default.APP_REPO,
737486+
per_page: options.per_page ?? 50,
737487+
...(options.status && { status: options.status }),
737488+
});
737489+
}
737460737490
/**
737461737491
* Generate the URL of an New Expensify pull request given the PR number.
737462737492
*/

.github/actions/javascript/checkDeployBlockers/index.js

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11617,6 +11617,13 @@ const CONST = {
1161711617
HELP_WANTED: 'Help Wanted',
1161811618
CP_STAGING: 'CP Staging',
1161911619
},
11620+
STATE: {
11621+
OPEN: 'open',
11622+
},
11623+
COMMENT: {
11624+
TYPE_BOT: 'Bot',
11625+
NAME_GITHUB_ACTIONS: 'github-actions',
11626+
},
1162011627
ACTIONS: {
1162111628
CREATED: 'created',
1162211629
EDITED: 'edited',
@@ -11635,6 +11642,7 @@ const CONST = {
1163511642
NO_ACTION: 'NO_ACTION',
1163611643
ACTION_EDIT: 'ACTION_EDIT',
1163711644
ACTION_REQUIRED: 'ACTION_REQUIRED',
11645+
ACTION_HIDE_DUPLICATE: 'ACTION_HIDE_DUPLICATE',
1163811646
};
1163911647
exports["default"] = CONST;
1164011648

@@ -11891,7 +11899,10 @@ class GithubUtils {
1189111899
const sortedDeployBlockers = [...new Set(deployBlockers)].sort((a, b) => GithubUtils.getIssueOrPullRequestNumberFromURL(a) - GithubUtils.getIssueOrPullRequestNumberFromURL(b));
1189211900
// Tag version and comparison URL
1189311901
// eslint-disable-next-line max-len
11894-
let issueBody = `**Release Version:** \`${tag}\`\r\n**Compare Changes:** https://github.com/${process.env.GITHUB_REPOSITORY}/compare/production...staging\r\n`;
11902+
let issueBody = `**Release Version:** \`${tag}\`\r\n**Compare Changes:** https://github.com/${process.env.GITHUB_REPOSITORY}/compare/production...staging\r\n\r\n`;
11903+
// Warn deployers about potential bugs with the new process
11904+
issueBody +=
11905+
'> 💡 **Deployer FYI:** This checklist was generated using a new process. PR list from original method and detail logging can be found in the most recent [deploy workflow](https://github.com/Expensify/App/actions/workflows/deploy.yml) labeled `staging`, in the `createChecklist` action. Please tag @Julesssss with any issues.\r\n\r\n';
1189511906
// PR list
1189611907
if (sortedPRList.length > 0) {
1189711908
issueBody += '\r\n**This release contains changes from the following pull requests:**\r\n';
@@ -11995,6 +12006,14 @@ class GithubUtils {
1199512006
per_page: 100,
1199612007
}, (response) => response.data.map((comment) => comment.body));
1199712008
}
12009+
static getAllCommentDetails(issueNumber) {
12010+
return this.paginate(this.octokit.issues.listComments, {
12011+
owner: CONST_1.default.GITHUB_OWNER,
12012+
repo: CONST_1.default.APP_REPO,
12013+
issue_number: issueNumber,
12014+
per_page: 100,
12015+
}, (response) => response.data);
12016+
}
1199812017
/**
1199912018
* Create comment on pull request
1200012019
*/
@@ -12021,6 +12040,17 @@ class GithubUtils {
1202112040
})
1202212041
.then((response) => response.data.workflow_runs.at(0)?.id ?? -1);
1202312042
}
12043+
/**
12044+
* List workflow runs for the repository.
12045+
*/
12046+
static async listWorkflowRunsForRepo(options = {}) {
12047+
return this.octokit.actions.listWorkflowRunsForRepo({
12048+
owner: CONST_1.default.GITHUB_OWNER,
12049+
repo: CONST_1.default.APP_REPO,
12050+
per_page: options.per_page ?? 50,
12051+
...(options.status && { status: options.status }),
12052+
});
12053+
}
1202412054
/**
1202512055
* Generate the URL of an New Expensify pull request given the PR number.
1202612056
*/

.github/actions/javascript/createOrUpdateStagingDeploy/createOrUpdateStagingDeploy.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,21 +57,39 @@ async function run(): Promise<IssuesCreateResponse | void> {
5757
// Find the list of PRs merged between the current checklist and the previous checklist
5858
const mergedPRs = await GitUtils.getPullRequestsDeployedBetween(previousChecklistData.tag, newStagingTag);
5959

60+
// mergedPRs includes cherry-picked PRs that have already been released with previous checklist, so we need to filter these out
61+
const previousPRNumbers = new Set(previousChecklistData.PRList.map((pr) => pr.number));
62+
core.startGroup('Filtering PRs:');
63+
core.info('mergedPRs includes cherry-picked PRs that have already been released with previous checklist, so we need to filter these out');
64+
core.info(`Found ${previousPRNumbers.size} PRs in the previous checklist:`);
65+
core.info(JSON.stringify(Array.from(previousPRNumbers)));
66+
const newPRNumbers = mergedPRs.filter((prNum) => !previousPRNumbers.has(prNum));
67+
core.info(`Found ${newPRNumbers.length} PRs deployed since the previous checklist:`);
68+
core.info(JSON.stringify(newPRNumbers));
69+
70+
// Log the PRs that were filtered out
71+
const removedPRs = mergedPRs.filter((prNum) => previousPRNumbers.has(prNum));
72+
if (removedPRs.length > 0) {
73+
core.info(`⚠️⚠️ Filtered out the following cherry-picked PRs that were released with the previous checklist: ${removedPRs.join(', ')} ⚠️⚠️`);
74+
}
75+
core.endGroup();
76+
console.info(`[api] Checklist PRs: ${newPRNumbers.join(', ')}`);
77+
6078
// Next, we generate the checklist body
6179
let checklistBody = '';
6280
let checklistAssignees: string[] = [];
6381
if (shouldCreateNewDeployChecklist) {
6482
const stagingDeployCashBodyAndAssignees = await GithubUtils.generateStagingDeployCashBodyAndAssignees(
6583
newVersion,
66-
mergedPRs.map((value) => GithubUtils.getPullRequestURLFromNumber(value)),
84+
newPRNumbers.map((value) => GithubUtils.getPullRequestURLFromNumber(value)),
6785
);
6886
if (stagingDeployCashBodyAndAssignees) {
6987
checklistBody = stagingDeployCashBodyAndAssignees.issueBody;
7088
checklistAssignees = stagingDeployCashBodyAndAssignees.issueAssignees.filter(Boolean) as string[];
7189
}
7290
} else {
7391
// Generate the updated PR list, preserving the previous state of `isVerified` for existing PRs
74-
const PRList = mergedPRs.map((prNum) => {
92+
const PRList = newPRNumbers.map((prNum) => {
7593
const indexOfPRInCurrentChecklist = currentChecklistData?.PRList.findIndex((pr) => pr.number === prNum) ?? -1;
7694
const isVerified = indexOfPRInCurrentChecklist >= 0 ? currentChecklistData?.PRList[indexOfPRInCurrentChecklist].isVerified : false;
7795
return {

0 commit comments

Comments
 (0)