Skip to content

Commit

Permalink
Merge branch 'main' into osp/e2e-staggered
Browse files Browse the repository at this point in the history
  • Loading branch information
ospfranco committed Nov 8, 2023
2 parents 1e430e7 + 24184e4 commit 7ea652d
Show file tree
Hide file tree
Showing 66 changed files with 1,134 additions and 979 deletions.
3 changes: 3 additions & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
# Every PR gets a review from an internal Expensify engineer
* @Expensify/pullerbear

# Every PR that touches redirects gets reviewed by ring0
docs/redirects.csv @Expensify/infra
125 changes: 125 additions & 0 deletions .github/scripts/createHelpRedirects.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
#!/bin/bash
#
# Adds new routes to the Cloudflare Bulk Redirects list for communityDot to helpDot
# pages. Does some basic sanity checking.

set -e

source scripts/shellUtils.sh

info "Adding any new redirects from communityDot to helpDot"

declare -r LIST_ID="20eb13215038446a98fd69ccf6d1026d"
declare -r ZONE_ID="$CLOUDFLARE_ACCOUNT_ID"
declare -r REDIRECTS_FILE="docs/redirects.csv"

function checkCloudflareResult {
RESULTS=$1
RESULT_MESSAGE=$(echo "$RESULTS" | jq .success)

if ! [[ "$RESULT_MESSAGE" == "true" ]]; then
ERROR_MESSAGE=$(echo "$RESULTS" | jq .errors)
error "Error calling Cloudfalre API: $ERROR_MESSAGE"
exit 1
fi
}

declare -a ITEMS_TO_ADD

while read -r line; do
# Split each line of the file into a source and destination so we can sanity check
# and compare against the current list.
read -r -a LINE_PARTS < <(echo "$line" | tr ',' ' ')
SOURCE_URL=${LINE_PARTS[0]}
DEST_URL=${LINE_PARTS[1]}

# Make sure the format of the line is as execpted.
if [[ "${#LINE_PARTS[@]}" -gt 2 ]]; then
error "Found a line with more than one comma: $line"
exit 1
fi

# Basic sanity checking to make sure that the source and destination are in expected
# subdomains.
if ! [[ $SOURCE_URL =~ ^https://community\.expensify\.com ]]; then
error "Found source URL that is not a community URL: $SOURCE_URL"
exit 1
fi

if ! [[ $DEST_URL =~ ^https://help\.expensify\.com ]]; then
error "Found destination URL that is not a help URL: $DEST_URL"
exit 1
fi

info "Source: $SOURCE_URL and destination: $DEST_URL appear to be formatted correctly."

ITEMS_TO_ADD+=("$line")

# This line skips the first line in the csv because the first line is a header row.
done <<< "$(tail +2 $REDIRECTS_FILE)"

# Sanity check that we should actually be running this and we aren't about to delete
# every single redirect.
if [[ "${#ITEMS_TO_ADD[@]}" -lt 1 ]]; then
error "No items found to add, why are we running?"
exit 1
fi

# This block builds a single JSON object with all of our updates so we can
# reduce the number of API calls we make. You cannot add any logging or anything
# that prints to std out to this block or it will break. We capture all of the std out
# from this loop and pass it to jq to build the json object. Any non-json will break the
# jq call at the end.
PUT_JSON=$(for new in "${ITEMS_TO_ADD[@]}"; do
read -r -a LINE_PARTS < <(echo "$new" | tr ',' ' ')
SOURCE_URL=${LINE_PARTS[0]}
DEST_URL=${LINE_PARTS[1]}
# We strip the prefix here so that the rule will match both http and https. Since vanilla will eventially be removed,
# we need to catch both because we will not have the http > https redirect done by vanilla anymore.
NO_PREFIX_SOURCE_URL=${SOURCE_URL/https:\/\//}
jq -n --arg source "$NO_PREFIX_SOURCE_URL" --arg dest "$DEST_URL" '{"redirect": {source_url: $source, target_url: $dest}}'
done | jq -n '. |= [inputs]')

info "Adding redirects for $PUT_JSON"

# We use PUT here instead of POST so that we replace the entire list in place. This has many benefits:
# 1. We don't have to check if items are already in the list, allowing this script to run faster
# 2. We can support deleting redirects this way by simply removing them from the list
# 3. We can support updating redirects this way, in the case of typos or moved destinations.
#
# Additionally this API call is async, so after we finish it, we must poll to wait for it to finish to
# to know that it was actually completed.
PUT_RESULT=$(curl -s --request PUT --url "https://api.cloudflare.com/client/v4/accounts/$ZONE_ID/rules/lists/$LIST_ID/items" \
--header 'Content-Type: application/json' \
--header "Authorization: Bearer $CLOUDFLARE_LIST_TOKEN" \
--data "$PUT_JSON")

checkCloudflareResult "$PUT_RESULT"
OPERATION_ID=$(echo "$PUT_RESULT" | jq -r .result.operation_id)

DONE=false

# Poll for completition
while [[ $DONE == false ]]; do
CHECK_RESULT=$(curl -s --request GET --url "https://api.cloudflare.com/client/v4/accounts/$ZONE_ID/rules/lists/bulk_operations/$OPERATION_ID" \
--header 'Content-Type: application/json' \
--header "Authorization: Bearer $CLOUDFLARE_LIST_TOKEN")
checkCloudflareResult "$CHECK_RESULT"

STATUS=$(echo "$CHECK_RESULT" | jq -r .result.status)

# Exit on completed or failed, other options are pending or running, in both cases
# we want to keep polling.
if [[ $STATUS == "completed" ]]; then
DONE=true
fi

if [[ $STATUS == "failed" ]]; then
ERROR_MESSAGE=$(echo "$CHECK_RESULT" | jq .result.error)
error "List update failed with error: $ERROR_MESSAGE"
exit 1
fi
done

success "Updated lists successfully"
31 changes: 31 additions & 0 deletions .github/workflows/updateHelpDotRedirects.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Update Redirects to ExpensifyHelp

on:
# Run on any push to main that has changes to the redirects file
push:
branches:
- main
paths:
- 'docs/redirects.csv'

# Run on any manual trigger
workflow_dispatch:

# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
group: "redirects"
cancel-in-progress: false

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8

- name: Create help dot redirect
env:
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
CLOUDFLARE_LIST_TOKEN: ${{ secrets.CLOUDFLARE_LIST_TOKEN }}
run: ./.github/scripts/createHelpRedirects.sh
4 changes: 2 additions & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ android {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
multiDexEnabled rootProject.ext.multiDexEnabled
versionCode 1001039603
versionName "1.3.96-3"
versionCode 1001039606
versionName "1.3.96-6"
}

flavorDimensions "default"
Expand Down
25 changes: 13 additions & 12 deletions assets/emojis/common.js → assets/emojis/common.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import Smiley from '../images/emoji.svg';
import Flags from '../images/emojiCategoryIcons/flag.svg';
import FoodAndDrink from '../images/emojiCategoryIcons/hamburger.svg';
import Objects from '../images/emojiCategoryIcons/light-bulb.svg';
import Symbols from '../images/emojiCategoryIcons/peace-sign.svg';
import TravelAndPlaces from '../images/emojiCategoryIcons/plane.svg';
import AnimalsAndNature from '../images/emojiCategoryIcons/plant.svg';
import Activities from '../images/emojiCategoryIcons/soccer-ball.svg';
import FrequentlyUsed from '../images/history.svg';
import Smiley from '@assets/images/emoji.svg';
import Flags from '@assets/images/emojiCategoryIcons/flag.svg';
import FoodAndDrink from '@assets/images/emojiCategoryIcons/hamburger.svg';
import Objects from '@assets/images/emojiCategoryIcons/light-bulb.svg';
import Symbols from '@assets/images/emojiCategoryIcons/peace-sign.svg';
import TravelAndPlaces from '@assets/images/emojiCategoryIcons/plane.svg';
import AnimalsAndNature from '@assets/images/emojiCategoryIcons/plant.svg';
import Activities from '@assets/images/emojiCategoryIcons/soccer-ball.svg';
import FrequentlyUsed from '@assets/images/history.svg';
import {HeaderEmoji, PickerEmojis} from './types';

const skinTones = [
{
Expand All @@ -33,9 +34,9 @@ const skinTones = [
code: '🖐🏿',
skinTone: 0,
},
];
] as const;

const emojis = [
const emojis: PickerEmojis = [
{
header: true,
icon: Smiley,
Expand Down Expand Up @@ -7619,7 +7620,7 @@ const emojis = [
},
];

const categoryFrequentlyUsed = {
const categoryFrequentlyUsed: HeaderEmoji = {
header: true,
code: 'frequentlyUsed',
icon: FrequentlyUsed,
Expand Down
5 changes: 4 additions & 1 deletion assets/emojis/en.js → assets/emojis/en.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
const enEmojis = {
import {EmojisList} from './types';

/* eslint-disable @typescript-eslint/naming-convention */
const enEmojis: EmojisList = {
'😀': {
keywords: ['smile', 'happy', 'face', 'grin'],
},
Expand Down
5 changes: 4 additions & 1 deletion assets/emojis/es.js → assets/emojis/es.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
const esEmojis = {
import {EmojisList} from './types';

/* eslint-disable @typescript-eslint/naming-convention */
const esEmojis: EmojisList = {
'😀': {
name: 'sonriendo',
keywords: ['cara', 'divertido', 'feliz', 'sonrisa', 'cara sonriendo'],
Expand Down
41 changes: 0 additions & 41 deletions assets/emojis/index.js

This file was deleted.

35 changes: 35 additions & 0 deletions assets/emojis/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import emojis from './common';
import enEmojis from './en';
import esEmojis from './es';
import {Emoji} from './types';

type EmojiTable = Record<string, Emoji>;

const emojiNameTable = emojis.reduce<EmojiTable>((prev, cur) => {
const newValue = prev;
if (!('header' in cur) && cur.name) {
newValue[cur.name] = cur;
}
return newValue;
}, {});

const emojiCodeTableWithSkinTones = emojis.reduce<EmojiTable>((prev, cur) => {
const newValue = prev;
if (!('header' in cur)) {
newValue[cur.code] = cur;
}
if ('types' in cur && cur.types) {
cur.types.forEach((type) => {
newValue[type] = cur;
});
}
return newValue;
}, {});

const localeEmojis = {
en: enEmojis,
es: esEmojis,
} as const;

export {emojiNameTable, emojiCodeTableWithSkinTones, localeEmojis};
export {skinTones, categoryFrequentlyUsed, default} from './common';
19 changes: 19 additions & 0 deletions assets/emojis/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import {SvgProps} from 'react-native-svg';

type Emoji = {
code: string;
name: string;
types?: string[];
};

type HeaderEmoji = {
header: true;
icon: React.FC<SvgProps>;
code: string;
};

type PickerEmojis = Array<Emoji | HeaderEmoji>;

type EmojisList = Record<string, {keywords: string[]; name?: string}>;

export type {Emoji, HeaderEmoji, EmojisList, PickerEmojis};
2 changes: 1 addition & 1 deletion babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ const metro = {
],
env: {
production: {
plugins: ['transform-remove-console', {exclude: ['error', 'warn']}],
plugins: [['transform-remove-console', {exclude: ['error', 'warn']}]],
},
},
};
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ Removing a member from a workspace disables their ability to use the workspace.
3. Select the member you'd like to remove and click the **Remove** button at the top of the Members table.
4. If this member was an approver, make sure that reports are not routing to them in the workflow.

![image of members table in a workspace]({{site.url}}/assets/images/ExpensifyHelp_RemovingMembers.png){:width="100%"}

# FAQ

## Will reports from this member on this workspace still be available?
Expand Down
2 changes: 2 additions & 0 deletions docs/redirects.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
sourceURL,targetURL
https://community.expensify.com/discussion/5634/deep-dive-how-long-will-it-take-for-me-to-receive-my-reimbursement,https://help.expensify.com/articles/expensify-classic/get-paid-back/reports/Reimbursements
2 changes: 1 addition & 1 deletion ios/NewExpensify/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>1.3.96.3</string>
<string>1.3.96.6</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSApplicationQueriesSchemes</key>
Expand Down
2 changes: 1 addition & 1 deletion ios/NewExpensifyTests/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.3.96.3</string>
<string>1.3.96.6</string>
</dict>
</plist>
Loading

0 comments on commit 7ea652d

Please sign in to comment.