Skip to content

Commit aab15e5

Browse files
Merge branch 'main' of github.com:Expensify/App into fix/56077-company-card-scroll-on-select
2 parents 2da0ede + 717b77a commit aab15e5

140 files changed

Lines changed: 2340 additions & 2110 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/getDeployPullRequestList/getDeployPullRequestList.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ async function run() {
2525
({data}, done) => {
2626
// For production deploys, look only at other production deploys.
2727
// staging deploys can be compared with other staging deploys or production deploys.
28-
// The reason is that the final staging release in each deploy cycle will BECOME a production release
2928
const filteredData = isProductionDeploy ? data.filter((release) => !release.prerelease) : data;
3029

3130
// Release was in the last page, meaning the previous release is the first item in this page

.github/actions/javascript/getDeployPullRequestList/index.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11518,7 +11518,6 @@ async function run() {
1151811518
}, ({ data }, done) => {
1151911519
// For production deploys, look only at other production deploys.
1152011520
// staging deploys can be compared with other staging deploys or production deploys.
11521-
// The reason is that the final staging release in each deploy cycle will BECOME a production release
1152211521
const filteredData = isProductionDeploy ? data.filter((release) => !release.prerelease) : data;
1152311522
// Release was in the last page, meaning the previous release is the first item in this page
1152411523
if (foundCurrentRelease) {

.github/workflows/cherryPick.yml

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ name: Cherry-pick a pull request
33
on:
44
workflow_dispatch:
55
inputs:
6-
PULL_REQUEST_NUMBER:
7-
description: The number of a pull request to CP
6+
PULL_REQUEST_URL:
7+
description: The full URL of the Expensify/App pull request to cherry-pick
88
required: true
99

1010
jobs:
@@ -15,9 +15,6 @@ jobs:
1515
cherryPick:
1616
needs: createNewVersion
1717
runs-on: ubuntu-latest
18-
env:
19-
# The name of the branch created if there are conflicts when CPing the PR.
20-
CONFLICT_BRANCH_NAME: cherry-pick-staging-${{ github.event.inputs.PULL_REQUEST_NUMBER }}-${{ github.run_id }}-${{ github.run_attempt }}
2118
steps:
2219
- name: Checkout staging branch
2320
# v4
@@ -27,6 +24,23 @@ jobs:
2724
token: ${{ secrets.OS_BOTIFY_TOKEN }}
2825
submodules: true
2926

27+
- name: Extract PR information
28+
id: getPRInfo
29+
run: |
30+
echo "REPO_FULL_NAME=$(echo '${{ github.event.inputs.PULL_REQUEST_URL }}' | sed -E 's|https://github.com/([^/]+/[^/]+)/pull/.*|\1|')" >> "$GITHUB_OUTPUT"
31+
echo "PR_NUMBER=$(echo '${{ github.event.inputs.PULL_REQUEST_URL }}' | sed -E 's|.*/pull/([0-9]+).*|\1|')" >> "$GITHUB_OUTPUT"
32+
33+
- name: Verify repository
34+
run: |
35+
if [ "${{ steps.getPRInfo.outputs.REPO_FULL_NAME }}" != "Expensify/App" ]; then
36+
echo "::error::❌ Cherry picks are only supported for the Expensify/App repository. Found: ${{ steps.getPRInfo.outputs.REPO_FULL_NAME }}"
37+
exit 1
38+
fi
39+
40+
- name: Set conflict branch name
41+
id: getBranchName
42+
run: echo "CONFLICT_BRANCH_NAME=cherry-pick-staging-${{ steps.getPRInfo.outputs.PR_NUMBER }}-${{ github.run_id }}-${{ github.run_attempt }}" >> "$GITHUB_OUTPUT"
43+
3044
# This command is necessary to fetch any branch other than main in the submodule.
3145
# See https://github.com/actions/checkout/issues/1815#issuecomment-2777836442 for further context.
3246
- name: Enable branch-switching in submodules
@@ -100,7 +114,7 @@ jobs:
100114
with:
101115
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
102116
USER: ${{ github.actor }}
103-
PULL_REQUEST_NUMBER: ${{ github.event.inputs.PULL_REQUEST_NUMBER }}
117+
PULL_REQUEST_NUMBER: ${{ steps.getPRInfo.outputs.PR_NUMBER }}
104118

105119
- name: Cherry-pick the Mobile-Expensify version bump to Mobile-Expensify staging
106120
working-directory: Mobile-Expensify
@@ -137,8 +151,8 @@ jobs:
137151
- name: Push changes
138152
run: |
139153
if [[ ${{steps.cherryPick.outputs.HAS_CONFLICTS}} == 'true' ]]; then
140-
git checkout -b ${{ env.CONFLICT_BRANCH_NAME }}
141-
git push --set-upstream origin ${{ env.CONFLICT_BRANCH_NAME }}
154+
git checkout -b ${{ steps.getBranchName.outputs.CONFLICT_BRANCH_NAME }}
155+
git push --set-upstream origin ${{ steps.getBranchName.outputs.CONFLICT_BRANCH_NAME }}
142156
else
143157
git push origin staging
144158
fi
@@ -150,13 +164,13 @@ jobs:
150164
AUTHOR_CHECKLIST=$(sed -n '/### PR Author Checklist/,$p' .github/PULL_REQUEST_TEMPLATE.md)
151165
152166
PR_DESCRIPTION=$(cat <<EOF
153-
🍒 Cherry pick https://github.com/Expensify/App/pull/${{ github.event.inputs.PULL_REQUEST_NUMBER }} to staging 🍒
167+
🍒 Cherry pick ${{ github.event.inputs.PULL_REQUEST_URL }} to staging 🍒
154168
155169
This PR had conflicts when we tried to cherry-pick it to staging. You'll need to manually perform the cherry-pick, using the following steps:
156170
157171
\`\`\`bash
158172
git fetch
159-
git checkout ${{ env.CONFLICT_BRANCH_NAME }}
173+
git checkout ${{ steps.getBranchName.outputs.CONFLICT_BRANCH_NAME }}
160174
git cherry-pick -S -x --mainline 1 ${{ steps.getCPMergeCommit.outputs.MERGE_COMMIT_SHA }}
161175
\`\`\`
162176
@@ -166,7 +180,7 @@ jobs:
166180
git commit --amend -m "\$(git log -1 --pretty=%B)" -m "(CP triggered by ${{ github.actor }})"
167181
\`\`\`
168182
169-
That will help us keep track of who triggered this CP. Once all that's done, push your changes with \`git push origin ${{ env.CONFLICT_BRANCH_NAME }}\`, and then open this PR for review.
183+
That will help us keep track of who triggered this CP. Once all that's done, push your changes with \`git push origin ${{ steps.getBranchName.outputs.CONFLICT_BRANCH_NAME }}\`, and then open this PR for review.
170184
171185
Note that you **must** test this PR, and both the author and reviewer checklist should be completed, just as if you were merging the PR to main.
172186
@@ -178,7 +192,7 @@ jobs:
178192
179193
# Create PR
180194
gh pr create \
181-
--title "🍒 Cherry pick PR #${{ github.event.inputs.PULL_REQUEST_NUMBER }} to staging 🍒" \
195+
--title "🍒 Cherry pick PR #${{ steps.getPRInfo.outputs.PR_NUMBER }} to staging 🍒" \
182196
--body "$PR_DESCRIPTION" \
183197
--label "Engineering,Hourly" \
184198
--base "staging"
@@ -190,15 +204,15 @@ jobs:
190204
if: fromJSON(steps.cherryPick.outputs.HAS_CONFLICTS)
191205
run: |
192206
gh pr edit --add-assignee "${{ github.actor }},${{ steps.getCPMergeCommit.outputs.MERGE_ACTOR }}"
193-
ORIGINAL_PR_AUTHOR="$(gh pr view ${{ github.event.inputs.PULL_REQUEST_NUMBER }} --json author --jq .author.login)"
207+
ORIGINAL_PR_AUTHOR="$(gh pr view ${{ github.event.inputs.PULL_REQUEST_URL }} --json author --jq .author.login)"
194208
gh pr edit --add-assignee "$ORIGINAL_PR_AUTHOR"
195209
env:
196210
GITHUB_TOKEN: ${{ steps.setupGitForOSBotify.outputs.OS_BOTIFY_API_TOKEN }}
197211
# In cases when the original PR author is outside the org, the `gh pr edit` command will fail. But we don't want to fail the workflow in that case.
198212
continue-on-error: true
199213

200214
- name: Label original PR with CP Staging
201-
run: gh pr edit ${{ inputs.PULL_REQUEST_NUMBER }} --add-label 'CP Staging'
215+
run: gh pr edit ${{ github.event.inputs.PULL_REQUEST_URL }} --add-label 'CP Staging'
202216
env:
203217
GITHUB_TOKEN: ${{ github.token }}
204218

@@ -214,7 +228,7 @@ jobs:
214228
attachments: [{
215229
color: "#DB4545",
216230
pretext: `<!subteam^S4TJJ3PSL>`,
217-
text: `💥 Failed to CP https://github.com/Expensify/App/pull/${{ github.event.inputs.PULL_REQUEST_NUMBER }} to staging 💥`,
231+
text: `💥 Failed to CP ${{ github.event.inputs.PULL_REQUEST_URL }} to staging 💥`,
218232
}]
219233
}
220234
env:

.github/workflows/deploy.yml

Lines changed: 43 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,11 @@ jobs:
4545
id: getAppVersion
4646
run: echo "VERSION=$(jq -r .version < package.json)" >> "$GITHUB_OUTPUT"
4747

48-
- name: Get tag name
48+
- name: Get tag
4949
id: getTagName
5050
run: echo "TAG=${{ fromJSON(env.SHOULD_DEPLOY_PRODUCTION) && steps.getAppVersion.outputs.VERSION || format('{0}-staging', steps.getAppVersion.outputs.VERSION) }}" >> "$GITHUB_OUTPUT"
5151

5252
- name: Create and push tag
53-
if: ${{ !fromJSON(env.SHOULD_DEPLOY_PRODUCTION) }}
5453
run: |
5554
git tag ${{ steps.getTagName.outputs.TAG }}
5655
git push origin --tags
@@ -286,14 +285,14 @@ jobs:
286285
# v4
287286
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
288287
with:
289-
name: ${{ fromJSON(env.SHOULD_DEPLOY_PRODUCTION) && 'desktop-sourcemaps-artifact' || 'desktop-staging-sourcemaps-artifact' }}
288+
name: desktop-sourcemaps-artifact
290289
path: ./desktop/dist/www/merged-source-map.js.map
291290

292291
- name: Upload desktop build artifact
293292
# v4
294293
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
295294
with:
296-
name: ${{ fromJSON(env.SHOULD_DEPLOY_PRODUCTION) && 'desktop-build-artifact' || 'desktop-staging-build-artifact' }}
295+
name: desktop-build-artifact
297296
path: ./desktop-build/NewExpensify.dmg
298297

299298
ios:
@@ -517,7 +516,7 @@ jobs:
517516
# v4
518517
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
519518
with:
520-
name: ${{ fromJSON(env.SHOULD_DEPLOY_PRODUCTION) && 'web' || 'web-staging' }}-sourcemaps-artifact
519+
name: web-sourcemaps-artifact
521520
path: ./dist/merged-source-map.js.map
522521

523522
- name: Compress web build .tar.gz and .zip
@@ -529,14 +528,14 @@ jobs:
529528
# v4
530529
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
531530
with:
532-
name: ${{ fromJSON(env.SHOULD_DEPLOY_PRODUCTION) && 'web' || 'web-staging' }}-build-tar-gz-artifact
531+
name: web-build-tar-gz-artifact
533532
path: ./webBuild.tar.gz
534533

535534
- name: Upload .zip web build artifact
536535
# v4
537536
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
538537
with:
539-
name: ${{ fromJSON(env.SHOULD_DEPLOY_PRODUCTION) && 'web' || 'web-staging' }}-build-zip-artifact
538+
name: web-build-zip-artifact
540539
path: ./webBuild.zip
541540

542541
postSlackMessageOnFailure:
@@ -589,97 +588,32 @@ jobs:
589588
echo "IS_ALL_PLATFORMS_DEPLOYED=$isAllPlatformsDeployed" >> "$GITHUB_OUTPUT"
590589
echo "IS_ALL_PLATFORMS_DEPLOYED is $isAllPlatformsDeployed"
591590
592-
createPrerelease:
591+
createRelease:
593592
runs-on: ubuntu-latest
594-
if: ${{ always() && github.ref == 'refs/heads/staging' && fromJSON(needs.checkDeploymentSuccess.outputs.IS_AT_LEAST_ONE_PLATFORM_DEPLOYED) }}
593+
if: ${{ always() && fromJSON(needs.checkDeploymentSuccess.outputs.IS_AT_LEAST_ONE_PLATFORM_DEPLOYED) }}
595594
needs: [prep, checkDeploymentSuccess]
596595
steps:
596+
# v4.2.1
597597
- name: Download all workflow run artifacts
598-
# v4
599598
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e
600599

601-
- name: 🚀 Create prerelease 🚀
600+
- name: 🚀 Create release 🚀
602601
run: |
603-
gh release create ${{ needs.prep.outputs.TAG }} --repo ${{ github.repository }} --title ${{ needs.prep.outputs.APP_VERSION }} --generate-notes --prerelease --verify-tag --target staging
602+
gh release create ${{ needs.prep.outputs.TAG }} ${{ github.ref == 'refs/heads/staging' && '--prerelease' }} \
603+
--repo ${{ github.repository }} \
604+
--title ${{ needs.prep.outputs.TAG }} \
605+
--generate-notes \
606+
--verify-tag \
607+
--target ${{ github.ref }}
604608
RETRIES=0
605-
MAX_RETRIES=10
609+
readonly MAX_RETRIES=10
606610
until [[ $(gh release view ${{ needs.prep.outputs.TAG }} --repo ${{ github.repository }}) || $RETRIES -ge $MAX_RETRIES ]]; do
607-
echo "release not found, retrying $((MAX_RETRIES - RETRIES++)) times"
611+
echo "Release not found, retrying $((MAX_RETRIES - RETRIES++)) times"
608612
sleep 1
609613
done
610614
env:
611615
GITHUB_TOKEN: ${{ github.token }}
612616

613-
- name: Rename web and desktop sourcemaps artifacts before assets upload in order to have unique ReleaseAsset.name
614-
continue-on-error: true
615-
run: |
616-
mv ./desktop-staging-sourcemaps-artifact/merged-source-map.js.map ./desktop-staging-sourcemaps-artifact/desktop-staging-merged-source-map.js.map
617-
mv ./web-staging-sourcemaps-artifact/merged-source-map.js.map ./web-staging-sourcemaps-artifact/web-staging-merged-source-map.js.map
618-
619-
- name: Upload artifacts to GitHub Release
620-
continue-on-error: true
621-
run: |
622-
# Release asset name should follow the template: [platform]-[staging, production or blank]-[sourcemap or blank].[file extension]
623-
files=(
624-
"./android-build-artifact/Expensify-release.aab#android.aab"
625-
"./android-apk-artifact/Expensify.apk#android.apk"
626-
"./android-sourcemap-artifact/index.android.bundle.map#android-sourcemap.js.map"
627-
"./desktop-staging-sourcemaps-artifact/desktop-staging-merged-source-map.js.map#desktop-staging-sourcemap.js.map"
628-
"./desktop-staging-build-artifact/NewExpensify.dmg#desktop-staging.dmg"
629-
"./ios-build-artifact/Expensify.ipa#ios.ipa"
630-
"./ios-sourcemap-artifact/main.jsbundle.map#ios-sourcemap.js.map"
631-
"./web-staging-sourcemaps-artifact/web-staging-merged-source-map.js.map#web-staging-sourcemap.js.map"
632-
"./web-staging-build-tar-gz-artifact/webBuild.tar.gz#web-staging.tar.gz"
633-
"./web-staging-build-zip-artifact/webBuild.zip#web-staging.zip"
634-
)
635-
636-
# Loop through each file and upload individually (so if one fails, we still have other platforms uploaded)
637-
for file_entry in "${files[@]}"; do
638-
gh release upload ${{ needs.prep.outputs.TAG }} --repo ${{ github.repository }} --clobber "$file_entry" || {
639-
echo "Failed to upload $file_entry. Continuing with the next file."
640-
continue
641-
}
642-
echo "Successfully uploaded $file_entry."
643-
done
644-
env:
645-
GITHUB_TOKEN: ${{ github.token }}
646-
647-
- name: Warn deployers if staging deploy failed
648-
if: ${{ failure() }}
649-
# v3
650-
uses: 8398a7/action-slack@1750b5085f3ec60384090fb7c52965ef822e869e
651-
with:
652-
status: custom
653-
custom_payload: |
654-
{
655-
channel: '#deployer',
656-
attachments: [{
657-
color: "#DB4545",
658-
pretext: `<!subteam^S4TJJ3PSL>`,
659-
text: `💥 NewDot staging deploy failed. 💥`,
660-
}]
661-
}
662-
env:
663-
GITHUB_TOKEN: ${{ github.token }}
664-
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}
665-
666-
finalizeRelease:
667-
runs-on: ubuntu-latest
668-
if: ${{ always() && github.ref == 'refs/heads/production' && fromJSON(needs.checkDeploymentSuccess.outputs.IS_AT_LEAST_ONE_PLATFORM_DEPLOYED) }}
669-
needs: [prep, checkDeploymentSuccess]
670-
steps:
671-
- name: Download all workflow run artifacts
672-
# v4
673-
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e
674-
675-
- name: 🚀 Edit the release to be no longer a prerelease 🚀
676-
run: |
677-
LATEST_RELEASE="$(gh release list --repo ${{ github.repository }} --exclude-pre-releases --json tagName,isLatest --jq '.[] | select(.isLatest) | .tagName')"
678-
gh api --method POST /repos/Expensify/App/releases/generate-notes -f "tag_name=${{ needs.prep.outputs.TAG }}" -f "previous_tag_name=$LATEST_RELEASE" | jq -r '.body' >> releaseNotes.md
679-
gh release edit ${{ needs.prep.outputs.TAG }} --repo ${{ github.repository }} --prerelease=false --latest --notes-file releaseNotes.md
680-
env:
681-
GITHUB_TOKEN: ${{ github.token }}
682-
683617
- name: Rename web and desktop sourcemaps artifacts before assets upload in order to have unique ReleaseAsset.name
684618
continue-on-error: true
685619
run: |
@@ -689,27 +623,33 @@ jobs:
689623
- name: Upload artifacts to GitHub Release
690624
continue-on-error: true
691625
run: |
692-
# Release asset name should follow the template: [platform]-[staging, production or blank]-[sourcemap or blank].[file extension]
693-
files=(
694-
"./desktop-sourcemaps-artifact/desktop-merged-source-map.js.map#desktop-production-sourcemap.js.map"
695-
"./desktop-build-artifact/NewExpensify.dmg#desktop-production.dmg"
696-
"./web-sourcemaps-artifact/web-merged-source-map.js.map#web-production-sourcemap.js.map"
697-
"./web-build-tar-gz-artifact/webBuild.tar.gz#web-production.tar.gz"
698-
"./web-build-zip-artifact/webBuild.zip#web-production.zip"
699-
)
626+
# Release asset name should follow the template: fileNameOnRunner#fileNameInRelease
627+
files="
628+
./android-build-artifact/Expensify-release.aab#android.aab
629+
./android-apk-artifact/Expensify.apk#android.apk
630+
./android-sourcemap-artifact/index.android.bundle.map#android-sourcemap.js.map
631+
./desktop-sourcemaps-artifact/desktop-merged-source-map.js.map#desktop-sourcemap.js.map
632+
./desktop-build-artifact/NewExpensify.dmg#desktop.dmg
633+
./ios-build-artifact/Expensify.ipa#ios.ipa
634+
./ios-sourcemap-artifact/main.jsbundle.map#ios-sourcemap.js.map
635+
./web-sourcemaps-artifact/web-merged-source-map.js.map#web-sourcemap.js.map
636+
./web-build-tar-gz-artifact/webBuild.tar.gz#web.tar.gz
637+
./web-build-zip-artifact/webBuild.zip#web.zip
638+
"
700639
701640
# Loop through each file and upload individually (so if one fails, we still have other platforms uploaded)
702-
for file_entry in "${files[@]}"; do
703-
gh release upload ${{ needs.prep.outputs.TAG }} --repo ${{ github.repository }} --clobber "$file_entry" || {
704-
echo "Failed to upload $file_entry. Continuing with the next file."
705-
continue
706-
}
707-
echo "Successfully uploaded $file_entry."
708-
done
641+
# Note: Not all of these files are present for production releases, because we don't build the native apps for prod deploys. That's expected.
642+
echo -e "$files" | xargs -I {} --max-procs=4 bash -c '
643+
if gh release upload ${{ needs.prep.outputs.TAG }} --repo ${{ github.repository }} --clobber {}; then
644+
echo "✅ Successfully uploaded {}"
645+
else
646+
echo "❌ Failed to upload {}"
647+
fi
648+
'
709649
env:
710650
GITHUB_TOKEN: ${{ github.token }}
711651

712-
- name: Warn deployers if production deploy failed
652+
- name: Warn deployers if deploy failed
713653
if: ${{ failure() }}
714654
# v3
715655
uses: 8398a7/action-slack@1750b5085f3ec60384090fb7c52965ef822e869e
@@ -721,7 +661,7 @@ jobs:
721661
attachments: [{
722662
color: "#DB4545",
723663
pretext: `<!subteam^S4TJJ3PSL>`,
724-
text: `💥 NewDot production deploy failed. 💥`,
664+
text: `💥 NewDot ${{ github.ref == 'refs/heads/staging' && 'staging' || 'production' }} deploy failed. 💥`,
725665
}]
726666
}
727667
env:
@@ -732,7 +672,7 @@ jobs:
732672
name: Post a Slack message when all platforms deploy successfully
733673
runs-on: ubuntu-latest
734674
if: ${{ always() && fromJSON(needs.checkDeploymentSuccess.outputs.IS_ALL_PLATFORMS_DEPLOYED) }}
735-
needs: [prep, android, desktop, ios, web, checkDeploymentSuccess, createPrerelease, finalizeRelease]
675+
needs: [prep, android, desktop, ios, web, checkDeploymentSuccess, createRelease]
736676
steps:
737677
- name: 'Announces the deploy in the #announce Slack room'
738678
# v3
@@ -789,7 +729,7 @@ jobs:
789729
postGithubComments:
790730
uses: ./.github/workflows/postDeployComments.yml
791731
if: ${{ always() && fromJSON(needs.checkDeploymentSuccess.outputs.IS_AT_LEAST_ONE_PLATFORM_DEPLOYED) }}
792-
needs: [prep, android, desktop, ios, web, checkDeploymentSuccess, createPrerelease, finalizeRelease]
732+
needs: [prep, android, desktop, ios, web, checkDeploymentSuccess, createRelease]
793733
with:
794734
version: ${{ needs.prep.outputs.APP_VERSION }}
795735
env: ${{ github.ref == 'refs/heads/production' && 'production' || 'staging' }}

.github/workflows/finishReleaseCycle.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Prepare production deploy
1+
name: Finish release cycle
22

33
on:
44
issues:

0 commit comments

Comments
 (0)