Skip to content

Commit

Permalink
Merge branch 'main' into eslint_dots
Browse files Browse the repository at this point in the history
  • Loading branch information
ShridharGoel authored Apr 29, 2024
2 parents 2373860 + ab93eb7 commit 83ba368
Show file tree
Hide file tree
Showing 482 changed files with 12,099 additions and 7,750 deletions.
8 changes: 1 addition & 7 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -261,13 +261,7 @@ module.exports = {
'no-restricted-imports': [
'error',
{
paths: [
...restrictedImportPaths,
{
name: 'underscore',
message: 'Please use the corresponding method from lodash instead',
},
],
paths: restrictedImportPaths,
patterns: restrictedImportPatterns,
},
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {promiseDoWhile} from '@github/libs/promiseWhile';
type CurrentStagingDeploys = Awaited<ReturnType<typeof GitHubUtils.octokit.actions.listWorkflowRuns>>['data']['workflow_runs'];

function run() {
console.info('[awaitStagingDeploys] POLL RATE', CONST.POLL_RATE);
console.info('[awaitStagingDeploys] run()');
console.info('[awaitStagingDeploys] getStringInput', getStringInput);
console.info('[awaitStagingDeploys] GitHubUtils', GitHubUtils);
Expand Down
8 changes: 7 additions & 1 deletion .github/actions/javascript/awaitStagingDeploys/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12131,6 +12131,7 @@ const CONST_1 = __importDefault(__nccwpck_require__(9873));
const GithubUtils_1 = __importDefault(__nccwpck_require__(9296));
const promiseWhile_1 = __nccwpck_require__(9438);
function run() {
console.info('[awaitStagingDeploys] POLL RATE', CONST_1.default.POLL_RATE);
console.info('[awaitStagingDeploys] run()');
console.info('[awaitStagingDeploys] getStringInput', ActionUtils_1.getStringInput);
console.info('[awaitStagingDeploys] GitHubUtils', GithubUtils_1.default);
Expand Down Expand Up @@ -12742,7 +12743,12 @@ function promiseWhile(condition, action) {
resolve();
return;
}
Promise.resolve(actionResult).then(loop).catch(reject);
Promise.resolve(actionResult)
.then(() => {
// Set a timeout to delay the next loop iteration
setTimeout(loop, 1000); // 1000 ms delay
})
.catch(reject);
}
};
loop();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const run = () => {

// Initialize string to store Graphite metrics
let graphiteString = '';
let timestamp: number;

// Iterate over each entry
regressionEntries.forEach((entry) => {
Expand All @@ -26,7 +27,9 @@ const run = () => {
const current = JSON.parse(entry);

// Extract timestamp, Graphite accepts timestamp in seconds
const timestamp = current.metadata?.creationDate ? Math.floor(new Date(current.metadata.creationDate).getTime() / 1000) : '';
if (current.metadata?.creationDate) {
timestamp = Math.floor(new Date(current.metadata.creationDate).getTime() / 1000);
}

if (current.name && current.meanDuration && current.meanCount && timestamp) {
const formattedName = current.name.split(' ').join('-');
Expand Down
5 changes: 4 additions & 1 deletion .github/actions/javascript/getGraphiteString/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2735,6 +2735,7 @@ const run = () => {
const regressionEntries = regressionFile.split('\n');
// Initialize string to store Graphite metrics
let graphiteString = '';
let timestamp;
// Iterate over each entry
regressionEntries.forEach((entry) => {
// Skip empty lines
Expand All @@ -2744,7 +2745,9 @@ const run = () => {
try {
const current = JSON.parse(entry);
// Extract timestamp, Graphite accepts timestamp in seconds
const timestamp = current.metadata?.creationDate ? Math.floor(new Date(current.metadata.creationDate).getTime() / 1000) : '';
if (current.metadata?.creationDate) {
timestamp = Math.floor(new Date(current.metadata.creationDate).getTime() / 1000);
}
if (current.name && current.meanDuration && current.meanCount && timestamp) {
const formattedName = current.name.split(' ').join('-');
const renderDurationString = `${GRAPHITE_PATH}.${formattedName}.renderDuration ${current.meanDuration} ${timestamp}`;
Expand Down
7 changes: 6 additions & 1 deletion .github/libs/promiseWhile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@ function promiseWhile(condition: () => boolean, action: (() => Promise<void>) |
return;
}

Promise.resolve(actionResult).then(loop).catch(reject);
Promise.resolve(actionResult)
.then(() => {
// Set a timeout to delay the next loop iteration
setTimeout(loop, 1000); // 1000 ms delay
})
.catch(reject);
}
};
loop();
Expand Down
64 changes: 64 additions & 0 deletions .github/scripts/detectRedirectCycle.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import {parse} from 'csv-parse';
import fs from 'fs';

const parser = parse();

const adjacencyList: Record<string, string[]> = {};
const visited: Map<string, boolean> = new Map<string, boolean>();
const backEdges: Map<string, boolean> = new Map<string, boolean>();

function addEdge(source: string, target: string) {
if (!adjacencyList[source]) {
adjacencyList[source] = [];
}
adjacencyList[source].push(target);
}

function isCyclic(currentNode: string): boolean {
visited.set(currentNode, true);
backEdges.set(currentNode, true);

// Do a depth first search for all the neighbours. If a node is found in backedge, a cycle is detected.
const neighbours = adjacencyList[currentNode];
if (neighbours) {
for (const node of neighbours) {
if (!visited.has(node)) {
if (isCyclic(node)) {
return true;
}
} else if (backEdges.has(node)) {
return true;
}
}
}

backEdges.delete(currentNode);

return false;
}

function detectCycle(): boolean {
for (const [node] of Object.entries(adjacencyList)) {
if (!visited.has(node)) {
if (isCyclic(node)) {
const cycle = Array.from(backEdges.keys());
console.log(`Infinite redirect found in the cycle: ${cycle.join(' -> ')} -> ${node}`);
return true;
}
}
}
return false;
}

fs.createReadStream(`${process.cwd()}/docs/redirects.csv`)
.pipe(parser)
.on('data', (row) => {
// Create a directed graph of sourceURL -> targetURL
addEdge(row[0], row[1]);
})
.on('end', () => {
if (detectCycle()) {
process.exit(1);
}
process.exit(0);
});
19 changes: 15 additions & 4 deletions .github/scripts/verifyRedirect.sh
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,22 @@

declare -r REDIRECTS_FILE="docs/redirects.csv"

declare -r RED='\033[0;31m'
declare -r GREEN='\033[0;32m'
declare -r NC='\033[0m'

duplicates=$(awk -F, 'a[$1]++{print $1}' $REDIRECTS_FILE)
if [[ -n "$duplicates" ]]; then
echo "${RED}duplicate redirects are not allowed: $duplicates ${NC}"
exit 1
fi

if [[ -z "$duplicates" ]]; then
exit 0
npm run detectRedirectCycle
DETECT_CYCLE_EXIT_CODE=$?
if [[ DETECT_CYCLE_EXIT_CODE -eq 1 ]]; then
echo -e "${RED}The redirects.csv has a cycle. Please remove the redirect cycle because it will cause an infinite redirect loop ${NC}"
exit 1
fi

echo "duplicate redirects are not allowed: $duplicates"
exit 1
echo -e "${GREEN}The redirects.csv is valid!${NC}"
exit 0
12 changes: 8 additions & 4 deletions .github/workflows/deployExpensifyHelp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ concurrency:

jobs:
build:
env:
IS_PR_FROM_FORK: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork }}
runs-on: ubuntu-latest
steps:
- name: Checkout
Expand All @@ -36,8 +38,8 @@ jobs:

- name: Create docs routes file
run: ./.github/scripts/createDocsRoutes.sh
- name: Check duplicates in redirect.csv

- name: Check for duplicates and cycles in redirects.csv
run: ./.github/scripts/verifyRedirect.sh

- name: Build with Jekyll
Expand All @@ -49,24 +51,26 @@ jobs:
- name: Deploy to Cloudflare Pages
uses: cloudflare/pages-action@f0a1cd58cd66095dee69bfa18fa5efd1dde93bca
id: deploy
if: github.event_name != 'pull_request' || (github.event_name == 'pull_request' && !github.event.pull_request.head.repo.fork)
if: env.IS_PR_FROM_FORK != 'true'
with:
apiToken: ${{ secrets.CLOUDFLARE_PAGES_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
projectName: helpdot
directory: ./docs/_site

- name: Setup Cloudflare CLI
if: env.IS_PR_FROM_FORK != 'true'
run: pip3 install cloudflare==2.19.0

- name: Purge Cloudflare cache
if: env.IS_PR_FROM_FORK != 'true'
run: /home/runner/.local/bin/cli4 --verbose --delete hosts=["help.expensify.com"] /zones/:9ee042e6cfc7fd45e74aa7d2f78d617b/purge_cache
env:
CF_API_KEY: ${{ secrets.CLOUDFLARE_TOKEN }}

- name: Leave a comment on the PR
uses: actions-cool/maintain-one-comment@de04bd2a3750d86b324829a3ff34d47e48e16f4b
if: ${{ github.event_name == 'pull_request' }}
if: ${{ github.event_name == 'pull_request' && env.IS_PR_FROM_FORK != 'true' }}
with:
token: ${{ secrets.OS_BOTIFY_TOKEN }}
body: ${{ format('A preview of your ExpensifyHelp changes have been deployed to {0} ⚡️', steps.deploy.outputs.alias) }}
Expand Down
11 changes: 5 additions & 6 deletions .github/workflows/platformDeploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,11 @@ jobs:
MYAPP_UPLOAD_STORE_PASSWORD: ${{ secrets.MYAPP_UPLOAD_STORE_PASSWORD }}
MYAPP_UPLOAD_KEY_PASSWORD: ${{ secrets.MYAPP_UPLOAD_KEY_PASSWORD }}

# Note: Android production deploys are temporarily disabled until https://github.com/Expensify/App/issues/40108 is resolved
# - name: Run Fastlane production
# if: ${{ fromJSON(env.SHOULD_DEPLOY_PRODUCTION) }}
# run: bundle exec fastlane android production
# env:
# VERSION: ${{ env.VERSION_CODE }}
- name: Run Fastlane production
if: ${{ fromJSON(env.SHOULD_DEPLOY_PRODUCTION) }}
run: bundle exec fastlane android production
env:
VERSION: ${{ env.VERSION_CODE }}

- name: Archive Android sourcemaps
uses: actions/upload-artifact@v3
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/typecheck.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
# - git diff is used to see the files that were added on this branch
# - gh pr view is used to list files touched by this PR. Git diff may give false positives if the branch isn't up-to-date with main
# - wc counts the words in the result of the intersection
count_new_js=$(comm -1 -2 <(git diff --name-only --diff-filter=A origin/main HEAD -- 'src/*.js' '__mocks__/*.js' '.storybook/*.js' 'assets/*.js' 'config/*.js' 'desktop/*.js' 'jest/*.js' 'scripts/*.js' 'tests/*.js' 'web/*.js' 'workflow_tests/*.js' '.github/libs/*.js' '.github/scripts/*.js') <(gh pr view ${{ github.event.pull_request.number }} --json files | jq -r '.files | map(.path) | .[]') | wc -l)
count_new_js=$(comm -1 -2 <(git diff --name-only --diff-filter=A origin/main HEAD -- 'src/*.js' '__mocks__/*.js' '.storybook/*.js' 'assets/*.js' 'config/*.js' 'desktop/*.js' 'jest/*.js' 'scripts/*.js' 'tests/*.js' 'workflow_tests/*.js' '.github/libs/*.js' '.github/scripts/*.js') <(gh pr view ${{ github.event.pull_request.number }} --json files | jq -r '.files | map(.path) | .[]') | wc -l)
if [ "$count_new_js" -gt "0" ]; then
echo "ERROR: Found new JavaScript files in the project; use TypeScript instead."
exit 1
Expand Down
8 changes: 8 additions & 0 deletions .well-known/apple-app-site-association
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@
"/": "/split/*",
"comment": "Split Expense"
},
{
"/": "/submit/*",
"comment": "Submit Expense"
},
{
"/": "/request/*",
"comment": "Submit Expense"
Expand All @@ -76,6 +80,10 @@
"/": "/search/*",
"comment": "Search"
},
{
"/": "/pay/*",
"comment": "Pay someone"
},
{
"/": "/send/*",
"comment": "Pay someone"
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

#### Table of Contents
* [Local Development](#local-development)
* [Testing on browsers on simulators and emulators](#testing-on-browsers-on-simulators-and-emulators)
* [Testing on browsers in simulators and emulators](#testing-on-browsers-in-simulators-and-emulators)
* [Running The Tests](#running-the-tests)
* [Debugging](#debugging)
* [App Structure and Conventions](#app-structure-and-conventions)
Expand Down Expand Up @@ -60,6 +60,7 @@ If you're using another operating system, you will need to ensure `mkcert` is in
For an M1 Mac, read this [SO](https://stackoverflow.com/questions/64901180/how-to-run-cocoapods-on-apple-silicon-m1) for installing cocoapods.

* If you haven't already, install Xcode tools and make sure to install the optional "iOS Platform" package as well. This installation may take awhile.
* After installation, check in System Settings that there's no update for Xcode. Otherwise, you may encounter issues later that don't explain that you solve them by updating Xcode.
* Install project gems, including cocoapods, using bundler to ensure everyone uses the same versions. In the project root, run: `bundle install`
* If you get the error `Could not find 'bundler'`, install the bundler gem first: `gem install bundler` and try again.
* If you are using MacOS and get the error `Gem::FilePermissionError` when trying to install the bundler gem, you're likely using system Ruby, which requires administrator permission to modify. To get around this, install another version of Ruby with a version manager like [rbenv](https://github.com/rbenv/rbenv#installation).
Expand Down
4 changes: 2 additions & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ android {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
multiDexEnabled rootProject.ext.multiDexEnabled
versionCode 1001046307
versionName "1.4.63-7"
versionCode 1001046700
versionName "1.4.67-0"
// Supported language variants must be declared here to avoid from being removed during the compilation.
// This also helps us to not include unnecessary language variants in the APK.
resConfigs "en", "es"
Expand Down
4 changes: 4 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
<data android:scheme="https" android:host="new.expensify.com" android:pathPrefix="/bank-account"/>
<data android:scheme="https" android:host="new.expensify.com" android:pathPrefix="/iou"/>
<data android:scheme="https" android:host="new.expensify.com" android:pathPrefix="/request"/>
<data android:scheme="https" android:host="new.expensify.com" android:pathPrefix="/submit"/>
<data android:scheme="https" android:host="new.expensify.com" android:pathPrefix="/enable-payments"/>
<data android:scheme="https" android:host="new.expensify.com" android:pathPrefix="/statements"/>
<data android:scheme="https" android:host="new.expensify.com" android:pathPrefix="/concierge"/>
Expand All @@ -70,6 +71,7 @@
<data android:scheme="https" android:host="new.expensify.com" android:pathPrefix="/new"/>
<data android:scheme="https" android:host="new.expensify.com" android:pathPrefix="/search"/>
<data android:scheme="https" android:host="new.expensify.com" android:pathPrefix="/send"/>
<data android:scheme="https" android:host="new.expensify.com" android:pathPrefix="/pay"/>
<data android:scheme="https" android:host="new.expensify.com" android:pathPrefix="/money2020"/>

<!-- Staging URLs -->
Expand All @@ -81,6 +83,7 @@
<data android:scheme="https" android:host="staging.new.expensify.com" android:pathPrefix="/bank-account"/>
<data android:scheme="https" android:host="staging.new.expensify.com" android:pathPrefix="/iou"/>
<data android:scheme="https" android:host="staging.new.expensify.com" android:pathPrefix="/request"/>
<data android:scheme="https" android:host="staging.new.expensify.com" android:pathPrefix="/submit"/>
<data android:scheme="https" android:host="staging.new.expensify.com" android:pathPrefix="/enable-payments"/>
<data android:scheme="https" android:host="staging.new.expensify.com" android:pathPrefix="/statements"/>
<data android:scheme="https" android:host="staging.new.expensify.com" android:pathPrefix="/concierge"/>
Expand All @@ -89,6 +92,7 @@
<data android:scheme="https" android:host="staging.new.expensify.com" android:pathPrefix="/new"/>
<data android:scheme="https" android:host="staging.new.expensify.com" android:pathPrefix="/search"/>
<data android:scheme="https" android:host="staging.new.expensify.com" android:pathPrefix="/send"/>
<data android:scheme="https" android:host="staging.new.expensify.com" android:pathPrefix="/pay"/>
<data android:scheme="https" android:host="staging.new.expensify.com" android:pathPrefix="/money2020"/>
</intent-filter>
</activity>
Expand Down
1 change: 1 addition & 0 deletions assets/images/all.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 10 additions & 1 deletion assets/images/arrow-right.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 10 additions & 1 deletion assets/images/back-left.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
Loading

0 comments on commit 83ba368

Please sign in to comment.