Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into feat-55873
Browse files Browse the repository at this point in the history
  • Loading branch information
hungvu193 committed Feb 7, 2025
2 parents 2e89de9 + d687284 commit d9a2b1a
Show file tree
Hide file tree
Showing 162 changed files with 2,949 additions and 1,842 deletions.
20 changes: 10 additions & 10 deletions .github/actions/composite/setupGitForOSBotify/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,25 @@ name: 'Setup Git for OSBotify'
description: 'Setup Git for OSBotify'

inputs:
GPG_PASSPHRASE:
description: 'Passphrase used to decrypt GPG key'
OP_SERVICE_ACCOUNT_TOKEN:
description: "1Password service account token"
required: true

runs:
using: composite
steps:
- name: Decrypt OSBotify GPG key
run: cd .github/workflows && gpg --quiet --batch --yes --decrypt --passphrase=${{ inputs.GPG_PASSPHRASE }} --output OSBotify-private-key.asc OSBotify-private-key.asc.gpg
- name: Install 1Password CLI
uses: 1password/install-cli-action@v1

- name: Load files from 1Password
shell: bash
env:
OP_SERVICE_ACCOUNT_TOKEN: ${{ inputs.OP_SERVICE_ACCOUNT_TOKEN }}
run: op read "op://Mobile-Deploy-CI/OSBotify-private-key.asc/OSBotify-private-key.asc" --force --out-file ./OSBotify-private-key.asc

- name: Import OSBotify GPG Key
shell: bash
run: cd .github/workflows && gpg --import OSBotify-private-key.asc
run: gpg --import OSBotify-private-key.asc

- name: Set up git for OSBotify
shell: bash
Expand All @@ -24,8 +29,3 @@ runs:
git config --global commit.gpgsign true
git config --global user.name OSBotify
git config --global user.email [email protected]
- name: Enable debug logs for git
shell: bash
if: runner.debug == '1'
run: echo "GIT_TRACE=true" >> "$GITHUB_ENV"
33 changes: 9 additions & 24 deletions .github/actions/composite/setupGitForOSBotifyApp/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ name: "Setup Git for OSBotify"
description: "Setup Git for OSBotify"

inputs:
GPG_PASSPHRASE:
description: "Passphrase used to decrypt GPG key"
OP_SERVICE_ACCOUNT_TOKEN:
description: "1Password service account token"
required: true
OS_BOTIFY_APP_ID:
description: "Application ID for OS Botify"
Expand All @@ -24,28 +24,18 @@ outputs:
runs:
using: composite
steps:
- name: Check if gpg encrypted private key is present
id: key_check
shell: bash
run: |
if [[ -f .github/workflows/OSBotify-private-key.asc.gpg ]]; then
echo "key_exists=true" >> "$GITHUB_OUTPUT"
fi
- name: Checkout
uses: actions/checkout@v4
if: steps.key_check.outputs.key_exists != 'true'
with:
sparse-checkout: |
.github
- name: Install 1Password CLI
uses: 1password/install-cli-action@v1

- name: Decrypt OSBotify GPG key
run: cd .github/workflows && gpg --quiet --batch --yes --decrypt --passphrase=${{ inputs.GPG_PASSPHRASE }} --output OSBotify-private-key.asc OSBotify-private-key.asc.gpg
- name: Load files from 1Password
shell: bash
env:
OP_SERVICE_ACCOUNT_TOKEN: ${{ inputs.OP_SERVICE_ACCOUNT_TOKEN }}
run: op read "op://Mobile-Deploy-CI/OSBotify-private-key.asc/OSBotify-private-key.asc" --force --out-file ./OSBotify-private-key.asc

- name: Import OSBotify GPG Key
shell: bash
run: cd .github/workflows && gpg --import OSBotify-private-key.asc
run: gpg --import OSBotify-private-key.asc

- name: Set up git for OSBotify
shell: bash
Expand All @@ -55,11 +45,6 @@ runs:
git config user.name OSBotify
git config user.email [email protected]
- name: Enable debug logs for git
shell: bash
if: runner.debug == '1'
run: echo "GIT_TRACE=true" >> "$GITHUB_ENV"

- name: Sync clock
shell: bash
run: sudo sntp -sS time.windows.com
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ GithubUtils.octokit.pulls
.then(({data: PR}) => {
if (!isEmptyObject(PR)) {
console.log(`Found matching pull request: ${PR.html_url}`);
console.log(`Pull request details: ${JSON.stringify(PR)}}`);
core.setOutput('MERGE_COMMIT_SHA', PR.merge_commit_sha);
core.setOutput('HEAD_COMMIT_SHA', PR.head?.sha);
core.setOutput('IS_MERGED', PR.merged);
Expand Down
1 change: 1 addition & 0 deletions .github/actions/javascript/getPullRequestDetails/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11502,6 +11502,7 @@ GithubUtils_1.default.octokit.pulls
.then(({ data: PR }) => {
if (!(0, EmptyObject_1.isEmptyObject)(PR)) {
console.log(`Found matching pull request: ${PR.html_url}`);
console.log(`Pull request details: ${JSON.stringify(PR)}}`);
core.setOutput('MERGE_COMMIT_SHA', PR.merge_commit_sha);
core.setOutput('HEAD_COMMIT_SHA', PR.head?.sha);
core.setOutput('IS_MERGED', PR.merged);
Expand Down
Binary file removed .github/workflows/OSBotify-private-key.asc.gpg
Binary file not shown.
15 changes: 6 additions & 9 deletions .github/workflows/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,6 @@ git fetch origin tag 1.0.1-0 --no-tags --shallow-exclude=1.0.0-0 # This will fet

## Secrets
The GitHub workflows require a large list of secrets to deploy, notify and test the code:
1. `LARGE_SECRET_PASSPHRASE` - decrypts secrets stored in various encrypted files stored in GitHub repository. To create updated versions of these encrypted files, refer to steps 1-4 of [this encrypted secrets help page](https://docs.github.com/en/actions/reference/encrypted-secrets#limits-for-secrets) using the `LARGE_SECRET_PASSPHRASE`.
1. `android/app/my-upload-key.keystore.gpg`
1. `android/app/android-fastlane-json-key.json.gpg`
1. `ios/NewApp_AdHoc.mobileprovision`
1. `ios/NewApp_AdHoc_Notification_Service.mobileprovision`
1. `ios/NewApp_AppStore.mobileprovision.gpg`
1. `ios/NewApp_AppStore_Notification_Service.mobileprovision.gpg`
1. `ios/Certificates.p12.gpg`
1. `SLACK_WEBHOOK` - Sends Slack notifications via Slack WebHook https://expensify.slack.com/services/B01AX48D7MM
1. `OS_BOTIFY_TOKEN` - Personal access token for @OSBotify user in GitHub
1. `CLA_BOTIFY_TOKEN` - Personal access token for @CLABotify user in GitHub
Expand All @@ -105,10 +97,15 @@ The GitHub workflows require a large list of secrets to deploy, notify and test
1. `APPLE_DEMO_PASSWORD` - Demo account password used for https://appstoreconnect.apple.com/
1. `BROWSERSTACK` - Used to access Browserstack's API

We use 1Password for many secrets and in general use two different actions from 1Password to fetch secrets:

1. `1password/install-cli-action` - This action is used to install 1Password cli `op` and is used to grab **files** using the `op read` command.
1. `1password/load-secrets-action` - This action is used to fetch **strings** from 1Password.

### Important note about Secrets
Secrets are available by default in most workflows. The exception to the rule is callable workflows. If a workflow is triggered by the `workflow_call` event, it will only have access to repo secrets if the workflow that called it passed in the secrets explicitly (for example, using `secrets: inherit`).

Furthermore, secrets are not accessible in actions. If you need to access a secret in an action, you must declare it as an input and pass it in. GitHub _should_ still obfuscate the value of the secret in workflow run logs.
Furthermore, secrets are not accessible in actions. If you need to access a secret in an action, _you must declare it as an input and pass it in_. GitHub _should_ still obfuscate the value of the secret in workflow run logs.

## Actions

Expand Down
11 changes: 8 additions & 3 deletions .github/workflows/cherryPick.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
id: setupGitForOSBotify
uses: ./.github/actions/composite/setupGitForOSBotifyApp
with:
GPG_PASSPHRASE: ${{ secrets.LARGE_SECRET_PASSPHRASE }}
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
OS_BOTIFY_APP_ID: ${{ secrets.OS_BOTIFY_APP_ID }}
OS_BOTIFY_PRIVATE_KEY: ${{ secrets.OS_BOTIFY_PRIVATE_KEY }}

Expand All @@ -56,14 +56,19 @@ jobs:
SEMVER_LEVEL: "PATCH"

- name: Fetch history of relevant refs
run: |
git fetch origin main staging --no-tags --shallow-exclude ${{ steps.getPreviousVersion.outputs.PREVIOUS_VERSION }}
run: git fetch origin main staging --no-tags --shallow-exclude ${{ steps.getPreviousVersion.outputs.PREVIOUS_VERSION }}

- name: Get version bump commit
id: getVersionBumpCommit
run: |
git switch main
VERSION_BUMP_COMMIT="$(git log --format='%H' --author='OSBotify' --grep 'Update version to ${{ needs.createNewVersion.outputs.NEW_VERSION }}')"
if [ -z "$VERSION_BUMP_COMMIT" ]; then
echo "::error::❌ Could not find version bump commit for ${{ needs.createNewVersion.outputs.NEW_VERSION }}"
git log --oneline
else
echo "::notice::👀 Found version bump commit $VERSION_BUMP_COMMIT"
fi
echo "VERSION_BUMP_SHA=$VERSION_BUMP_COMMIT" >> "$GITHUB_OUTPUT"
- name: Get merge commit for pull request to CP
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/createNewVersion.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ on:
value: ${{ jobs.createNewVersion.outputs.NEW_VERSION }}

secrets:
LARGE_SECRET_PASSPHRASE:
description: Passphrase used to decrypt GPG key
required: true
SLACK_WEBHOOK:
description: Webhook used to comment in slack
required: true
OS_BOTIFY_COMMIT_TOKEN:
description: OSBotify personal access token, used to workaround committing to protected branch
required: true
OP_SERVICE_ACCOUNT_TOKEN:
description: 1Password service account token
required: true

jobs:
validateActor:
Expand Down Expand Up @@ -74,7 +74,7 @@ jobs:
uses: ./.github/actions/composite/setupGitForOSBotify
id: setupGitForOSBotify
with:
GPG_PASSPHRASE: ${{ secrets.LARGE_SECRET_PASSPHRASE }}
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}

- name: Generate new E/App version
id: bumpVersion
Expand Down
17 changes: 11 additions & 6 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
uses: ./.github/actions/composite/setupGitForOSBotifyApp
id: setupGitForOSBotify
with:
GPG_PASSPHRASE: ${{ secrets.LARGE_SECRET_PASSPHRASE }}
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
OS_BOTIFY_APP_ID: ${{ secrets.OS_BOTIFY_APP_ID }}
OS_BOTIFY_PRIVATE_KEY: ${{ secrets.OS_BOTIFY_PRIVATE_KEY }}

Expand Down Expand Up @@ -301,10 +301,15 @@ jobs:
- name: Setup Node
uses: ./.github/actions/composite/setupNode

- name: Decrypt Developer ID Certificate
run: cd desktop && gpg --quiet --batch --yes --decrypt --passphrase="$DEVELOPER_ID_SECRET_PASSPHRASE" --output developer_id.p12 developer_id.p12.gpg
- name: Load Desktop credentials from 1Password
id: load-credentials
uses: 1password/load-secrets-action@v2
with:
export-env: false
env:
DEVELOPER_ID_SECRET_PASSPHRASE: ${{ secrets.DEVELOPER_ID_SECRET_PASSPHRASE }}
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
DESKTOP_CERTIFICATE_BASE64: "op://Mobile-Deploy-CI/Desktop Certificates.p12/CSC_LINK"
DESKTOP_CERTIFICATE_PASSWORD: "op://Mobile-Deploy-CI/Desktop Certificates.p12/CSC_KEY_PASSWORD"

- name: Build desktop app
run: |
Expand All @@ -314,8 +319,8 @@ jobs:
npm run desktop-build-staging
fi
env:
CSC_LINK: ${{ secrets.CSC_LINK }}
CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }}
CSC_LINK: ${{ steps.load-credentials.outputs.DESKTOP_CERTIFICATE_BASE64 }}
CSC_KEY_PASSWORD: ${{ steps.load-credentials.outputs.DESKTOP_CERTIFICATE_PASSWORD }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/finishReleaseCycle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
uses: ./.github/actions/composite/setupGitForOSBotifyApp
id: setupGitForOSBotify
with:
GPG_PASSPHRASE: ${{ secrets.LARGE_SECRET_PASSPHRASE }}
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
OS_BOTIFY_APP_ID: ${{ secrets.OS_BOTIFY_APP_ID }}
OS_BOTIFY_PRIVATE_KEY: ${{ secrets.OS_BOTIFY_PRIVATE_KEY }}

Expand Down Expand Up @@ -87,7 +87,7 @@ jobs:
id: setupGitForOSBotify
uses: ./.github/actions/composite/setupGitForOSBotifyApp
with:
GPG_PASSPHRASE: ${{ secrets.LARGE_SECRET_PASSPHRASE }}
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
OS_BOTIFY_APP_ID: ${{ secrets.OS_BOTIFY_APP_ID }}
OS_BOTIFY_PRIVATE_KEY: ${{ secrets.OS_BOTIFY_PRIVATE_KEY }}

Expand Down Expand Up @@ -128,7 +128,7 @@ jobs:
- name: Setup git for OSBotify
uses: ./.github/actions/composite/setupGitForOSBotifyApp
with:
GPG_PASSPHRASE: ${{ secrets.LARGE_SECRET_PASSPHRASE }}
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
OS_BOTIFY_APP_ID: ${{ secrets.OS_BOTIFY_APP_ID }}
OS_BOTIFY_PRIVATE_KEY: ${{ secrets.OS_BOTIFY_PRIVATE_KEY }}

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/preDeploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ jobs:
- name: Setup Git for OSBotify
uses: ./.github/actions/composite/setupGitForOSBotifyApp
with:
GPG_PASSPHRASE: ${{ secrets.LARGE_SECRET_PASSPHRASE }}
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
OS_BOTIFY_APP_ID: ${{ secrets.OS_BOTIFY_APP_ID }}
OS_BOTIFY_PRIVATE_KEY: ${{ secrets.OS_BOTIFY_PRIVATE_KEY }}

Expand Down
15 changes: 10 additions & 5 deletions .github/workflows/testBuild.yml
Original file line number Diff line number Diff line change
Expand Up @@ -242,10 +242,15 @@ jobs:
- name: Setup Node
uses: ./.github/actions/composite/setupNode

- name: Decrypt Developer ID Certificate
run: cd desktop && gpg --quiet --batch --yes --decrypt --passphrase="$DEVELOPER_ID_SECRET_PASSPHRASE" --output developer_id.p12 developer_id.p12.gpg
- name: Load Desktop credentials from 1Password
id: load-credentials
uses: 1password/load-secrets-action@v2
with:
export-env: false
env:
DEVELOPER_ID_SECRET_PASSPHRASE: ${{ secrets.DEVELOPER_ID_SECRET_PASSPHRASE }}
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
DESKTOP_CERTIFICATE_BASE64: "op://Mobile-Deploy-CI/Desktop Certificates.p12/CSC_LINK"
DESKTOP_CERTIFICATE_PASSWORD: "op://Mobile-Deploy-CI/Desktop Certificates.p12/CSC_KEY_PASSWORD"

- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
Expand All @@ -257,8 +262,8 @@ jobs:
- name: Build desktop app for testing
run: npm run desktop-build-adhoc
env:
CSC_LINK: ${{ secrets.CSC_LINK }}
CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }}
CSC_LINK: ${{ steps.load-credentials.outputs.DESKTOP_CERTIFICATE_BASE64 }}
CSC_KEY_PASSWORD: ${{ steps.load-credentials.outputs.DESKTOP_CERTIFICATE_PASSWORD }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
Expand Down
2 changes: 1 addition & 1 deletion Mobile-Expensify
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,15 @@ The primary difference is that the native code, which runs React Native, is loca
The `Mobile-Expensify` directory is a **Git submodule**. This means it points to a specific commit on the `Mobile-Expensify` repository.
If you'd like to fetch the submodule while executing the `git pull` command in `Expensify/App` instead of updating it manually you can run this command in the root of the project:

```
git config submodule.recurse true
```

> [!WARNING]
> Please, remember that the submodule will get updated automatically only after executing the `git pull` command - if you switch between branches it is still recommended to execute `git submodule update` to make sure you're working on a compatible submodule version!

If you'd like to download the most recent changes from the `main` branch, please use the following command:
```bash
git submodule update --remote
Expand Down
4 changes: 2 additions & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ android {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
multiDexEnabled rootProject.ext.multiDexEnabled
versionCode 1009009408
versionName "9.0.94-8"
versionCode 1009009500
versionName "9.0.95-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
2 changes: 1 addition & 1 deletion android/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx512m -XX:MaxMetaspaceSize=256m
org.gradle.jvmargs=-Xmx6g -XX:MaxMetaspaceSize=512m
org.gradle.jvmargs=-Xmx8g -XX:MaxMetaspaceSize=2048m

# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
Expand Down
6 changes: 6 additions & 0 deletions assets/images/export.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed desktop/developer_id.p12.gpg
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ This dictates when reimbursable expenses will export, according to your preferre

**Journal Entries:** Non-reimbursable expenses will be posted to the Journal Entries posting account selected in your workspace's connection settings. If you centrally manage your company cards through Domains, you can export expenses from each card to a specific account in NetSuite.

- Expensify Card expenses will always export as Journal Entries, even if you have Expense Reports or Vendor Bills configured for non-reimbursable expenses on the Export tab
- When [automatic reconciliation](https://help.expensify.com/articles/expensify-classic/expensify-card/Expensify-Card-Reconciliation) is enabled, Expensify Card expenses will always export as individual, itemized Journal Entries, regardless of Expense Reports or Vendor Bills settings configured for non-reimbursable expenses on the Export tab.
- Without automatic reconciliation, Expensify Card expenses will export using the export type configured for non-reimbursable expenses on the Export tab.
- Expensify Card expenses exported as Journal Entries will always export as individual, itemized Journal Entries, regardless of whether the "one journal entry for all items on report" setting is enabled.
- Journal entry forms do not contain a customer column, so it is not possible to export customers or projects with this export option
- The credit line and header level classifications are pulled from the employee record

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,6 @@ To add your Expensify Card to a digital wallet, follow the steps below:
- **Restricted Country**: Transactions from restricted countries will be declined.

{% include faq-begin.md %}
## Can I use Smart Limits with a free Expensify account?
If you're on the Free plan, you won't have the option to use Smart Limits. Your card limit will simply reset at the end of each calendar month.

## I still haven't received my Expensify Card. What should I do?
For more information on why your card hasn't arrived, you can check out this resource on [Requesting a Card](https://help.expensify.com/articles/expensify-classic/expensify-card/Request-the-Card#what-if-i-havent-received-my-card-after-multiple-weeks).
Expand Down
12 changes: 12 additions & 0 deletions docs/articles/new-expensify/connect-credit-cards/Personal-Cards.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
title: Personal Cards
description: Learn how to track and manage your personal credit card expenses in Expensify through automatic imports or manual uploads.
---

# Overview

Expensify makes it easy to track expenses and get reimbursed by linking your personal credit card. Once connected, transactions can be imported automatically, or you can upload a CSV file for manual entry. These transactions will be merged with SmartScanned receipts and, if enabled, can generate IRS-compliant eReceipts.

---

We are currently developing the personal card connection feature for New Expensify. Once available, we will update this article with step-by-step instructions on how to connect your card. Stay tuned!
Loading

0 comments on commit d9a2b1a

Please sign in to comment.