Skip to content

Commit 82e0b24

Browse files
committed
Merge branch 'main' into optimize-use-search-highlight-and-scroll
2 parents 74ac6bb + 89306d6 commit 82e0b24

File tree

334 files changed

+8089
-4851
lines changed

Some content is hidden

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

334 files changed

+8089
-4851
lines changed

.github/actions/composite/announceFailedWorkflowInSlack/action.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ inputs:
1313
runs:
1414
using: composite
1515
steps:
16-
- uses: 8398a7/action-slack@v3
16+
- uses: 8398a7/action-slack@1750b5085f3ec60384090fb7c52965ef822e869e
1717
name: Job failed Slack notification
1818
with:
1919
status: custom

.github/actions/composite/setupNode/action.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ runs:
2323
shell: bash
2424
run: jq 'del(.version, .packages[""].version)' package-lock.json > normalized-package-lock.json
2525

26-
- uses: actions/setup-node@v4
26+
- uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e #v4
2727
with:
2828
node-version-file: '.nvmrc'
2929
cache: npm

.github/workflows/androidBump.yml

+20-2
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,8 @@ on:
99
jobs:
1010
android_bump:
1111
runs-on: ubuntu-latest
12-
1312
steps:
14-
- uses: actions/checkout@v4
13+
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4
1514

1615
- name: Setup Node
1716
uses: ./.github/actions/composite/setupNode
@@ -47,3 +46,22 @@ jobs:
4746
echo "HALTED: ${{ steps.checkAndroidStatus.outputs.HALTED }}"
4847
echo "ROLLOUT_PERCENTAGE: ${{ steps.checkAndroidStatus.outputs.ROLLOUT_PERCENTAGE }}"
4948
bundle exec fastlane android update_hybrid_rollout rollout:${{ steps.checkAndroidStatus.outputs.ROLLOUT_PERCENTAGE }}
49+
50+
- name: Warn deployers if Android rollout percentage could not be updated
51+
if: ${{ failure() }}
52+
# v3
53+
uses: 8398a7/action-slack@1750b5085f3ec60384090fb7c52965ef822e869e
54+
with:
55+
status: custom
56+
custom_payload: |
57+
{
58+
channel: '#deployer',
59+
attachments: [{
60+
color: "#DB4545",
61+
pretext: `<!subteam^S4TJJ3PSL>`,
62+
text: `💥 Android rollout percentage could not be updated. <https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}|View Run> 💥`,
63+
}]
64+
}
65+
env:
66+
GITHUB_TOKEN: ${{ github.token }}
67+
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}

.github/workflows/deploy.yml

+21-6
Original file line numberDiff line numberDiff line change
@@ -201,18 +201,33 @@ jobs:
201201
env:
202202
BROWSERSTACK: ${{ secrets.BROWSERSTACK }}
203203

204+
- name: Install bundletool
205+
run: |
206+
readonly BUNDLETOOL_VERSION="1.18.1"
207+
readonly BUNDLETOOL_URL="https://github.com/google/bundletool/releases/download/${BUNDLETOOL_VERSION}/bundletool-all-${BUNDLETOOL_VERSION}.jar"
208+
209+
# Download jar from GitHub Release
210+
curl -L -o bundletool.jar "$BUNDLETOOL_URL"
211+
212+
# Validate checksum
213+
readonly EXPECTED_SHA="675786493983787ffa11550bdb7c0715679a44e1643f3ff980a529e9c822595c"
214+
SHA="$(sha256sum bundletool.jar | cut -d ' ' -f1)"
215+
if [[ "$SHA" != "$EXPECTED_SHA" ]]; then
216+
echo "SHA mismatch: expected $EXPECTED_SHA but got $ACTUAL_SHA"
217+
exit 1
218+
fi
219+
204220
- name: Generate APK from AAB
205221
run: |
206-
json=$(curl -s https://api.github.com/repos/google/bundletool/releases/latest)
207-
downloadUrl=$(echo "$json" | jq -r ".assets | .[].browser_download_url")
208-
curl "$downloadUrl" -4 -sL -o 'bundletool.jar'
222+
# Generate apks using bundletool
209223
java -jar bundletool.jar build-apks --bundle=${{ env.aabPath }} --output=Expensify.apks \
210224
--mode=universal \
211225
--ks=upload-key.keystore \
212226
--ks-pass=pass:${{ steps.load-credentials.outputs.ANDROID_UPLOAD_KEYSTORE_PASSWORD }} \
213227
--ks-key-alias=${{ steps.load-credentials.outputs.ANDROID_UPLOAD_KEYSTORE_ALIAS }} \
214228
--key-pass=pass:${{ steps.load-credentials.outputs.ANDROID_UPLOAD_KEY_PASSWORD }}
215-
229+
230+
# Unzip just the universal apk
216231
unzip -p Expensify.apks universal.apk > Expensify.apk
217232
218233
- name: Upload Android APK build artifact
@@ -254,7 +269,7 @@ jobs:
254269
attachments: [{
255270
color: "#DB4545",
256271
pretext: `<!subteam^S4TJJ3PSL>`,
257-
text: `💥 Android HybridApp production deploy failed. No need to do anything, Jules will <https://stackoverflowteams.com/c/expensify/questions/5738|manually submit> ${{ needs.prep.outputs.APP_VERSION }} in the <https://play.google.com/console/u/0/developers/8765590895836334604/app/4974129597497161901/releases/overview|Google Play Store>. 💥`,
272+
text: `💥 Android HybridApp production <https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}|deploy run> failed. Please <https://stackoverflowteams.com/c/expensify/questions/5738|manually submit> ${{ needs.prep.outputs.APP_VERSION }} in the <https://play.google.com/console/u/0/developers/8765590895836334604/app/4974129597497161901/releases/overview|Google Play Store>. 💥 But first check the workflow, it's likely that the release was successful and <https://github.com/Expensify/Expensify/issues/488492|this error> is occuring)`,
258273
}]
259274
}
260275
env:
@@ -623,7 +638,7 @@ jobs:
623638
gh release create ${{ needs.prep.outputs.TAG }} ${{ github.ref == 'refs/heads/staging' && '--prerelease' || '' }} \
624639
--repo ${{ github.repository }} \
625640
--title ${{ needs.prep.outputs.TAG }} \
626-
--notes-start-tag ${{ steps.get_last_prod_version.outputs.LAST_PROD_VERSION }} \
641+
${{ github.ref == 'refs/heads/production' && format('--notes-start-tag {0}', steps.get_last_prod_version.outputs.LAST_PROD_VERSION) || '' }} \
627642
--generate-notes \
628643
--verify-tag \
629644
--target ${{ github.ref }}

.github/workflows/e2ePerformanceTests.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ jobs:
2828
DELTA_REF: ${{ steps.getDeltaRef.outputs.DELTA_REF }}
2929
IS_PR_MERGED: ${{ steps.getPullRequestDetails.outputs.IS_MERGED }}
3030
steps:
31-
- uses: actions/checkout@v4
31+
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4
3232
with:
3333
fetch-depth: 0 # Fetches the entire history
3434

@@ -106,7 +106,7 @@ jobs:
106106
if: ${{ always() }}
107107
name: Run E2E tests in AWS device farm
108108
steps:
109-
- uses: actions/checkout@v4
109+
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4
110110
with:
111111
# The OS_BOTIFY_COMMIT_TOKEN is a personal access token tied to osbotify (we need a PAT to access the artifact API)
112112
token: ${{ secrets.OS_BOTIFY_COMMIT_TOKEN }}
@@ -315,7 +315,7 @@ jobs:
315315
if: ${{ always() && needs.prep.outputs.IS_PR_MERGED != 'true' }}
316316
runs-on: ubuntu-latest
317317
steps:
318-
- uses: actions/checkout@v4
318+
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4
319319

320320
- name: Delete temporary merge branch created for delta ref
321321
run: git push -d origin ${{ needs.prep.outputs.DELTA_REF }}

.github/workflows/preDeploy.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ jobs:
2525
if: ${{ always() }}
2626

2727
steps:
28-
- uses: actions/checkout@v4
28+
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4
2929

3030
- name: Announce failed workflow in Slack
3131
if: ${{ needs.typecheck.result == 'failure' || needs.lint.result == 'failure' || needs.test.result == 'failure' }}
@@ -47,7 +47,7 @@ jobs:
4747
SHOULD_DEPLOY: ${{ fromJSON(steps.shouldDeploy.outputs.SHOULD_DEPLOY) }}
4848

4949
steps:
50-
- uses: actions/checkout@v4
50+
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4
5151

5252
- name: Get merged pull request
5353
id: getMergedPullRequest

.github/workflows/proposalPolice.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ jobs:
88
runs-on: ubuntu-latest
99
if: "!contains(fromJSON('[\"OSBotify\", \"imgbot[bot]\", \"melvin-bot[bot]\"]'), github.actor)"
1010
steps:
11-
- uses: actions/checkout@v4
11+
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4
1212

1313
# Checks if the comment is created and follows the template OR
1414
# if the comment is edited and if proposal template is followed.

.github/workflows/remote-build-android.yml

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ name: Remote Build Android
22

33
on:
44
workflow_dispatch:
5+
push:
6+
branches-ignore: [staging, production]
57

68
concurrency:
79
group: ${{ github.workflow }}-${{ github.ref }}

.github/workflows/reviewerChecklist.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ jobs:
99
runs-on: ubuntu-latest
1010
if: github.actor != 'OSBotify' && github.actor != 'imgbot[bot]'
1111
steps:
12-
- uses: actions/checkout@v4
12+
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4
1313

1414
- name: reviewerChecklist.js
1515
uses: ./.github/actions/javascript/reviewerChecklist

.github/workflows/test.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ jobs:
5050
runs-on: ubuntu-latest
5151
name: Storybook tests
5252
steps:
53-
- uses: actions/checkout@v4
53+
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4
5454

5555
- uses: ./.github/actions/composite/setupNode
5656

.github/workflows/typecheck.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
if: ${{ github.actor != 'OSBotify' || github.event_name == 'workflow_call' }}
1717
runs-on: ubuntu-latest
1818
steps:
19-
- uses: actions/checkout@v4
19+
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4
2020

2121
- uses: ./.github/actions/composite/setupNode
2222
with:

.github/workflows/validateDocsRoutes.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
if: github.actor != 'OSBotify' && github.actor != 'imgbot[bot]'
1212
runs-on: ubuntu-latest
1313
steps:
14-
- uses: actions/checkout@v4
14+
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4
1515

1616
- uses: ./.github/actions/composite/setupNode
1717

.github/workflows/verifySignedCommits.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ jobs:
99
verifySignedCommits:
1010
runs-on: ubuntu-latest
1111
steps:
12-
- uses: actions/checkout@v4
12+
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4
1313

1414
- name: Verify signed commits
1515
uses: ./.github/actions/javascript/verifySignedCommits

Mobile-Expensify

README.md

+25
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
* [Security](#Security)
2121
* [Internationalization](#Internationalization)
2222
* [Deploying](#deploying)
23+
* [Onyx derived values](#onyx-derived-values)
24+
* [canBeMissing onyx param](#canbemissing-onyx-param)
2325

2426
#### Additional Reading
2527
* [API Details](contributingGuides/API.md)
@@ -941,3 +943,26 @@ Onyx derived values are special Onyx keys which contain values derived from othe
941943
3. **Document derived values**
942944
- Explain the purpose and dependencies
943945
- Document any special cases or performance considerations
946+
947+
# canBeMissing onyx param
948+
949+
Context https://expensify.slack.com/archives/C03TQ48KC/p1741208342513379
950+
951+
## What is this param and lint error for?
952+
953+
The idea of the param is to indicate if the component connecting to onyx expects the data to be there (and thus does not need to handle the case when it is not) or not (and thus has to handle the case when it is not).
954+
955+
It was added because in some places we are assuming some data will be there, but actually we never load it, which leads to hard to debug bugs.
956+
957+
The linter error is there till we add the param to all callers, once that happens we can make the param mandatory and remove the linter.
958+
959+
960+
## How do I determine if the param should be false or true?
961+
962+
The main things to look at for the `canBeMissing` param are:
963+
- Where/who loads the data? If the data is always ensured to be loaded before this component renders, then `canBeMissing` would be set to `false`. So any data that is always returned by `OpenApp` used in a component where we have a user (so not in the homepage for example) will have `canBeMissing` set to `false`
964+
- Will the user always have data? Maybe we always try to load a piece of data, but the data can be missing/empty, in this case `canBeMissing` would be set to `false`
965+
- If neither of above, then the param should probably be `true`, but additionally we need to make sure that the code using the data manages correctly the fact that the data might be missing
966+
967+
968+

__mocks__/reportData/policies.ts

-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ const policy420A: Policy = {
9393
},
9494
areRulesEnabled: false,
9595
eReceipts: true,
96-
shouldShowCustomReportTitleOption: false,
9796
shouldShowAutoApprovalOptions: false,
9897
shouldShowAutoReimbursementLimitOption: false,
9998
maxExpenseAmountNoReceipt: 100000,

android/app/build.gradle

+2-2
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,8 @@ android {
114114
minSdkVersion rootProject.ext.minSdkVersion
115115
targetSdkVersion rootProject.ext.targetSdkVersion
116116
multiDexEnabled rootProject.ext.multiDexEnabled
117-
versionCode 1009014001
118-
versionName "9.1.40-1"
117+
versionCode 1009014307
118+
versionName "9.1.43-7"
119119
// Supported language variants must be declared here to avoid from being removed during the compilation.
120120
// This also helps us to not include unnecessary language variants in the APK.
121121
resConfigs "en", "es"

docs/articles/expensify-classic/bank-accounts-and-payments/payments/Global-Reimbursement-UK.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,9 @@ If your business operates out of the U.K., you can enable global reimbursements
5454
This is a signed document authorizing a client’s bank to pull payments via direct debit.
5555

5656
1. Expensify will send you a **Direct Debit Authorization** form to sign.
57-
3. Send the signed authorization form to your bank.
58-
4. Return the signed authorization form to Expensify.
59-
5. Once the account is set up for direct debits (typically takes 10 to 12 business days to complete), communicate to Expensify support that is complete.
57+
2. Send the signed authorization form to your bank.
58+
3. Return the signed authorization form to Expensify.
59+
4. Once the account is set up for direct debits (typically takes 10 to 12 business days to complete), communicate to Expensify support that is complete.
6060

6161
---
6262

docs/articles/expensify-classic/connections/Workday.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ To create an **Advanced Custom Report** in Workday:
9797
- `lastName`
9898
- `employeeEmail`
9999
- `managerEmail`
100-
- `workspaceID`
100+
- `policyID`
101101
- `domainGroupID`
102102
- `approvesTo`
103103

Original file line numberDiff line numberDiff line change
@@ -1,25 +1,34 @@
11
---
22
title: Set Time and Distance Rates
3-
description: Set rates for hourly and Distance expenses
4-
keywords: [Expensify Classic, distance rates, time rates]
3+
description: Configure default hourly and mileage reimbursement rates at the workspace level for consistent billing and expense tracking.
4+
keywords: [Expensify Classic, distance rates, mileage rates, time tracking, hourly rates, workspace settings]
55
---
66
<div id="expensify-classic" markdown="1">
77

8-
You can set default rates at the workspace level to track employees' billable time and mileage expenses. Configuring these settings will ensure consistent reimbursement calculations and accurate billing for your team.
8+
Set default rates at the workspace level to track billable time and mileage expenses. This ensures accurate and consistent reimbursement for your team.
99

1010
---
1111

12-
# Set Time and Distance Rates
13-
14-
Head to **Settings > Workspace > [Workspace Name] > Distance rates:**
15-
- **For distance:**
16-
- If desired, adjust your **unit** (miles or kilometers) and your **default category**. These options will apply to all of your distance rates.
17-
- To add a new rate, click **Add a Mileage Rate**.
18-
- To edit an existing rate:
19-
- Click the toggle to enable or disable the rate.
20-
- Click the **name** or **rate** field to make changes.
21-
- **For time:**
22-
- Click the **enable** toggle to enable hourly rate expenses.
23-
- Enter the **default hourly rate**.
12+
# Distance Rates
13+
14+
To configure mileage reimbursement:
15+
16+
1. Go to **Settings > Workspaces > [Workspace Name] > Distance rates**
17+
2. Adjust your **unit** (miles or kilometers) and your **default category**—these apply to all distance rates.
18+
3. Click **Add a Mileage Rate** to create a new rate.
19+
20+
## Edit an Existing Rate
21+
1. Toggle the switch to enable or disable the rate.
22+
2. Click the **name** or **rate** field to make changes.
23+
24+
---
25+
26+
# Time Expenses
27+
28+
To enable hourly rate reimbursement:
29+
30+
1. Go to **Settings > Workspaces > [Workspace Name] > Distance rates**
31+
2. Toggle **Enable hourly rate expenses**
32+
3. Enter the **default hourly rate**
2433

2534
</div>

0 commit comments

Comments
 (0)