From 89eb1568c11793d6ca46643cbfa029fafabe5f8b Mon Sep 17 00:00:00 2001 From: Dylan Jeffers Date: Wed, 7 Jan 2026 15:50:27 -0800 Subject: [PATCH 01/18] Migrate mobile ci to github actions --- .circleci/config.yml | 22 +- .circleci/src/workflows/mobile.yml | 2 + .github/workflows/mobile.yml | 557 +++++++++++++++++++++++++++++ 3 files changed, 570 insertions(+), 11 deletions(-) create mode 100644 .github/workflows/mobile.yml diff --git a/.circleci/config.yml b/.circleci/config.yml index 552ee7dec9b..fadca98fcc9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -219,7 +219,7 @@ workflows: .circleci/.* run-protocol-dashboard-workflow true .circleci/.* run-sdk-workflow true .circleci/.* run-web-workflow false - .circleci/.* run-mobile-workflow true + .circleci/.* run-mobile-workflow false .circleci/.* run-embed-workflow true package-lock.json run-sdk-workflow true .* run-integration-workflow true @@ -227,24 +227,24 @@ workflows: packages/discovery-provider/.* run-discovery-workflow true packages/web/.* run-web-workflow false packages/web/e2e/.* run-integration-workflow true - packages/mobile/.* run-mobile-workflow true + packages/mobile/.* run-mobile-workflow false packages/embed/.* run-embed-workflow true packages/common/.* run-common-workflow true packages/common/.* run-web-workflow false - packages/common/.* run-mobile-workflow true + packages/common/.* run-mobile-workflow false packages/common/.* run-protocol-dashboard-workflow true packages/protocol-dashboard/.* run-protocol-dashboard-workflow true packages/harmony/.* run-web-workflow false packages/harmony/.* run-protocol-dashboard-workflow true packages/harmony/.* run-embed-workflow true packages/eslint-config-audius/.* run-web-workflow false - packages/eslint-config-audius/.* run-mobile-workflow true + packages/eslint-config-audius/.* run-mobile-workflow false packages/sdk/.* run-sdk-workflow true packages/sdk/.* run-create-audius-app-workflow true packages/create-audius-app/.* run-create-audius-app-workflow true packages/fixed-decimal/.* run-sdk-workflow true packages/fixed-decimal/.* run-web-workflow false - packages/fixed-decimal/.* run-mobile-workflow true + packages/fixed-decimal/.* run-mobile-workflow false packages/fixed-decimal/.* run-common-workflow true packages/spl/.* run-sdk-workflow true packages/spl/.* run-identity-workflow true @@ -270,33 +270,33 @@ workflows: .circleci/.* run-protocol-dashboard-workflow true .circleci/.* run-sdk-workflow true .circleci/.* run-web-workflow false - .circleci/.* run-mobile-workflow true + .circleci/.* run-mobile-workflow false .circleci/.* run-embed-workflow true package-lock.json run-sdk-workflow true .* run-integration-workflow true .* run-release-workflow false packages/discovery-provider/.* run-discovery-workflow true packages/web/.* run-web-workflow false - packages/mobile/.* run-mobile-workflow true + packages/mobile/.* run-mobile-workflow false packages/embed/.* run-embed-workflow true packages/common/.* run-common-workflow true packages/common/.* run-web-workflow false - packages/common/.* run-mobile-workflow true + packages/common/.* run-mobile-workflow false packages/protocol-dashboard/.* run-protocol-dashboard-workflow true packages/harmony/.* run-web-workflow false packages/eslint-config-audius/.* run-web-workflow false - packages/eslint-config-audius/.* run-mobile-workflow true + packages/eslint-config-audius/.* run-mobile-workflow false packages/sdk/.* run-sdk-workflow true packages/sdk/.* run-create-audius-app-workflow true packages/create-audius-app/.* run-create-audius-app-workflow true packages/fixed-decimal/.* run-sdk-workflow true packages/fixed-decimal/.* run-web-workflow false - packages/fixed-decimal/.* run-mobile-workflow true + packages/fixed-decimal/.* run-mobile-workflow false packages/fixed-decimal/.* run-common-workflow true packages/spl/.* run-sdk-workflow true packages/spl/.* run-identity-workflow true .* run-web-workflow false - .* run-mobile-workflow true + .* run-mobile-workflow false requires: - generate-config - init diff --git a/.circleci/src/workflows/mobile.yml b/.circleci/src/workflows/mobile.yml index 5f8b9e39746..bb734bbb1ef 100644 --- a/.circleci/src/workflows/mobile.yml +++ b/.circleci/src/workflows/mobile.yml @@ -1,3 +1,5 @@ +# NOTE: Mobile CI/CD has been migrated to GitHub Actions (.github/workflows/mobile.yml) +# This workflow is disabled via path filtering in config.yml when: << pipeline.parameters.run-mobile-workflow >> jobs: - mobile-init: diff --git a/.github/workflows/mobile.yml b/.github/workflows/mobile.yml new file mode 100644 index 00000000000..e91b63a6038 --- /dev/null +++ b/.github/workflows/mobile.yml @@ -0,0 +1,557 @@ +name: Mobile CI/CD + +on: + push: + branches: + - main + paths: + - 'packages/mobile/**' + - 'packages/common/**' + - 'packages/harmony/**' + - 'packages/libs/**' + - 'packages/sdk/**' + - 'package-lock.json' + - '.github/workflows/mobile.yml' + - '.circleci/**' + pull_request: + paths: + - 'packages/mobile/**' + - 'packages/common/**' + - 'packages/harmony/**' + - 'packages/libs/**' + - 'packages/sdk/**' + - 'package-lock.json' + - '.github/workflows/mobile.yml' + - '.circleci/**' + workflow_dispatch: + +env: + NODE_VERSION: '22.21.1' + +jobs: + # Initialize: Install dependencies, lint & typecheck + mobile-init: + name: Mobile Init (Install, Lint & Typecheck) + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'npm' + cache-dependency-path: package-lock.json + + - name: Create concatenated patch file + id: patch-file + run: | + ls -d -- packages/*/patches/*.patch 2>/dev/null | xargs cat > combined-patch-file.txt || touch combined-patch-file.txt + echo "patch_checksum=$(sha256sum combined-patch-file.txt | cut -d' ' -f1)" >> $GITHUB_OUTPUT + + - name: Cache node modules + id: cache-node-modules + uses: actions/cache@v4 + with: + path: | + node_modules + packages/mobile/node_modules + packages/common/node_modules + packages/libs/node_modules + packages/libs/dist + packages/sdk/node_modules + packages/sdk/dist + packages/harmony/node_modules + key: npm-cache-mobile-${{ runner.os }}-node-${{ env.NODE_VERSION }}-${{ hashFiles('package-lock.json') }}-${{ steps.patch-file.outputs.patch_checksum }} + restore-keys: | + npm-cache-mobile-${{ runner.os }}-node-${{ env.NODE_VERSION }}-${{ hashFiles('package-lock.json') }}- + npm-cache-mobile-${{ runner.os }}-${{ hashFiles('package-lock.json') }}- + + - name: Copy production env + run: | + cd packages/mobile + echo -e "\nAMPLITUDE_WRITE_KEY=${{ secrets.AMPLITUDE_WRITE_KEY_PROD }}" >> .env.prod + + - name: Install dependencies + env: + CI: true + NODE_OPTIONS: --max-old-space-size=8192 + run: | + if [[ -d node_modules ]]; then + echo "Using cached node_modules, running postinstall..." + npm run postinstall + else + echo "No cache found, running fresh install..." + npm ci --prefer-offline + fi + + - name: Lint & Typecheck + run: npx turbo run verify --filter=@audius/mobile + + # iOS Release Candidate: Build and upload + mobile-build-upload-releasecandidate-ios: + name: iOS Release Candidate Build & Upload + runs-on: macos-15 + needs: mobile-init + if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request' + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'npm' + cache-dependency-path: package-lock.json + + - name: Create concatenated patch file + id: patch-file + run: | + ls -d -- packages/*/patches/*.patch 2>/dev/null | xargs cat > combined-patch-file.txt || touch combined-patch-file.txt + echo "patch_checksum=$(sha256sum combined-patch-file.txt | cut -d' ' -f1)" >> $GITHUB_OUTPUT + + - name: Cache node modules + id: cache-node-modules + uses: actions/cache@v4 + with: + path: | + node_modules + packages/mobile/node_modules + packages/common/node_modules + packages/libs/node_modules + packages/libs/dist + packages/sdk/node_modules + packages/sdk/dist + packages/harmony/node_modules + key: npm-cache-mobile-${{ runner.os }}-node-${{ env.NODE_VERSION }}-${{ hashFiles('package-lock.json') }}-${{ steps.patch-file.outputs.patch_checksum }} + restore-keys: | + npm-cache-mobile-${{ runner.os }}-node-${{ env.NODE_VERSION }}-${{ hashFiles('package-lock.json') }}- + npm-cache-mobile-${{ runner.os }}-${{ hashFiles('package-lock.json') }}- + + - name: Cache iOS gems + uses: actions/cache@v4 + with: + path: packages/mobile/ios/vendor/bundle + key: gems-ios-${{ hashFiles('packages/mobile/ios/Gemfile.lock') }} + restore-keys: | + gems-ios- + + - name: Install gems + run: | + cd packages/mobile/ios + sudo gem install bundler:2.5.16 + bundle check || bundle install --path vendor/bundle + + - name: Install CocoaPods dependencies + run: | + cd packages/mobile/ios + bundle exec pod install + + - name: Install Sentry CLI + run: | + curl -sL https://sentry.io/get-cli/ | bash + echo "$HOME/.sentry-cli/bin" >> $GITHUB_PATH + + - name: Build dependencies + timeout-minutes: 60 + run: npx turbo run build --filter=@audius/mobile + + - name: Create iOS bundle + run: cd packages/mobile && npx turbo run bundle:ios + + - name: Update fastlane + run: cd packages/mobile/ios && sudo bundle update fastlane + + - name: Copy production env + run: cp packages/mobile/.env.prod packages/mobile/ios/ + + - name: Build and upload iOS (Release Candidate) + timeout-minutes: 60 + env: + FASTLANE_USER: ${{ secrets.FASTLANE_USER }} + FASTLANE_PASSWORD: ${{ secrets.FASTLANE_PASSWORD }} + FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD: ${{ secrets.FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD }} + FASTLANE_SESSION: ${{ secrets.FASTLANE_SESSION }} + MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }} + SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} + SENTRY_ORG: ${{ secrets.SENTRY_ORG }} + SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }} + run: | + cd packages/mobile/ios + bundle exec fastlane build_and_upload bundle_id:co.audius.audiusmusic.releasecandidate + + - name: Slack notification + if: success() + uses: slackapi/slack-github-action@v1 + with: + webhook-url: ${{ secrets.SLACK_DAILY_DEPLOY_WEBHOOK }} + payload: | + { + "blocks": [ + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "Deployed co.audius.audiusmusic.releasecandidate <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|v$(jq -r '.version' packages/mobile/package.json)> to mobile ios" + } + } + ] + } + + # Android Release Candidate: Build and upload + mobile-build-upload-releasecandidate-android: + name: Android Release Candidate Build & Upload + runs-on: ubuntu-latest + needs: mobile-init + if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request' + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'npm' + cache-dependency-path: package-lock.json + + - name: Setup Java + uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '17' + + - name: Setup Android SDK + uses: android-actions/setup-android@v3 + + - name: Create concatenated patch file + id: patch-file + run: | + ls -d -- packages/*/patches/*.patch 2>/dev/null | xargs cat > combined-patch-file.txt || touch combined-patch-file.txt + echo "patch_checksum=$(sha256sum combined-patch-file.txt | cut -d' ' -f1)" >> $GITHUB_OUTPUT + + - name: Cache node modules + id: cache-node-modules + uses: actions/cache@v4 + with: + path: | + node_modules + packages/mobile/node_modules + packages/common/node_modules + packages/libs/node_modules + packages/libs/dist + packages/sdk/node_modules + packages/sdk/dist + packages/harmony/node_modules + key: npm-cache-mobile-${{ runner.os }}-node-${{ env.NODE_VERSION }}-${{ hashFiles('package-lock.json') }}-${{ steps.patch-file.outputs.patch_checksum }} + restore-keys: | + npm-cache-mobile-${{ runner.os }}-node-${{ env.NODE_VERSION }}-${{ hashFiles('package-lock.json') }}- + npm-cache-mobile-${{ runner.os }}-${{ hashFiles('package-lock.json') }}- + + - name: Cache Android libs + uses: actions/cache@v4 + with: + path: packages/mobile/android/libs + key: ffmpeg-aar-${{ hashFiles('packages/mobile/android/build.gradle') }} + restore-keys: | + ffmpeg-aar- + + - name: Cache Android gems + uses: actions/cache@v4 + with: + path: packages/mobile/android/vendor/bundle + key: gems-android-${{ hashFiles('packages/mobile/android/Gemfile.lock') }} + restore-keys: | + gems-android- + + - name: Install dependencies + env: + CI: true + NODE_OPTIONS: --max-old-space-size=8192 + run: | + if [[ -d node_modules ]]; then + echo "Using cached node_modules, running postinstall..." + npm run postinstall + else + echo "No cache found, running fresh install..." + npm ci --prefer-offline + fi + + - name: Update bundler + run: sudo gem install bundler:1.17.3 + + - name: Install pip and ninja + run: | + sudo apt update + sudo apt install -y python3-pip ninja-build + + - name: Install Android gems + run: | + cd packages/mobile/android + bundle check || bundle install --path vendor/bundle + + - name: Update fastlane + run: cd packages/mobile/android && sudo bundle update fastlane + + - name: Migrate support libraries for AndroidX + run: cd packages/mobile && npm run jetifier + + - name: Install ffmpeg-aar + run: | + cd packages/mobile/android + ./gradlew :app:downloadAar + + - name: Setup Play Store API + run: | + echo "${{ secrets.FASTLANE_PLAYSTORE_JSON }}" | base64 --decode > packages/mobile/android/app/api.json + + - name: Build dependencies + timeout-minutes: 60 + run: npx turbo run build --filter=@audius/mobile + + - name: Release Android (Release Candidate) + timeout-minutes: 60 + env: + FASTLANE_PLAYSTORE_JSON: ${{ secrets.FASTLANE_PLAYSTORE_JSON }} + run: | + cd packages/mobile/android + bundle exec fastlane releaseCandidate track:internal + + - name: Slack notification + if: success() + uses: slackapi/slack-github-action@v1 + with: + webhook-url: ${{ secrets.SLACK_DAILY_DEPLOY_WEBHOOK }} + payload: | + { + "blocks": [ + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "Deployed releaseCandidate <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|v$(jq -r '.version' packages/mobile/package.json)> to mobile android" + } + } + ] + } + + # iOS Production: Build and upload (requires approval) + mobile-build-upload-production-ios-main: + name: iOS Production Build & Upload + runs-on: macos-15 + needs: mobile-init + if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request' + environment: + name: mobile-production-ios + url: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'npm' + cache-dependency-path: package-lock.json + + - name: Create concatenated patch file + id: patch-file + run: | + ls -d -- packages/*/patches/*.patch 2>/dev/null | xargs cat > combined-patch-file.txt || touch combined-patch-file.txt + echo "patch_checksum=$(sha256sum combined-patch-file.txt | cut -d' ' -f1)" >> $GITHUB_OUTPUT + + - name: Cache node modules + id: cache-node-modules + uses: actions/cache@v4 + with: + path: | + node_modules + packages/mobile/node_modules + packages/common/node_modules + packages/libs/node_modules + packages/libs/dist + packages/sdk/node_modules + packages/sdk/dist + packages/harmony/node_modules + key: npm-cache-mobile-${{ runner.os }}-node-${{ env.NODE_VERSION }}-${{ hashFiles('package-lock.json') }}-${{ steps.patch-file.outputs.patch_checksum }} + restore-keys: | + npm-cache-mobile-${{ runner.os }}-node-${{ env.NODE_VERSION }}-${{ hashFiles('package-lock.json') }}- + npm-cache-mobile-${{ runner.os }}-${{ hashFiles('package-lock.json') }}- + + - name: Cache iOS gems + uses: actions/cache@v4 + with: + path: packages/mobile/ios/vendor/bundle + key: gems-ios-${{ hashFiles('packages/mobile/ios/Gemfile.lock') }} + restore-keys: | + gems-ios- + + - name: Install gems + run: | + cd packages/mobile/ios + sudo gem install bundler:2.5.16 + bundle check || bundle install --path vendor/bundle + + - name: Install CocoaPods dependencies + run: | + cd packages/mobile/ios + bundle exec pod install + + - name: Install Sentry CLI + run: | + curl -sL https://sentry.io/get-cli/ | bash + echo "$HOME/.sentry-cli/bin" >> $GITHUB_PATH + + - name: Build dependencies + timeout-minutes: 60 + run: npx turbo run build --filter=@audius/mobile + + - name: Create iOS bundle + run: cd packages/mobile && npx turbo run bundle:ios + + - name: Update fastlane + run: cd packages/mobile/ios && sudo bundle update fastlane + + - name: Copy production env + run: cp packages/mobile/.env.prod packages/mobile/ios/ + + - name: Build and upload iOS (Production) + timeout-minutes: 60 + env: + FASTLANE_USER: ${{ secrets.FASTLANE_USER }} + FASTLANE_PASSWORD: ${{ secrets.FASTLANE_PASSWORD }} + FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD: ${{ secrets.FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD }} + FASTLANE_SESSION: ${{ secrets.FASTLANE_SESSION }} + MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }} + SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} + SENTRY_ORG: ${{ secrets.SENTRY_ORG }} + SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }} + run: | + cd packages/mobile/ios + bundle exec fastlane build_and_upload bundle_id:co.audius.audiusmusic + + # Android Production: Build and upload (requires approval) + mobile-build-upload-production-android-main: + name: Android Production Build & Upload + runs-on: ubuntu-latest + needs: mobile-init + if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request' + environment: + name: mobile-production-android + url: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'npm' + cache-dependency-path: package-lock.json + + - name: Setup Java + uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '17' + + - name: Setup Android SDK + uses: android-actions/setup-android@v3 + + - name: Create concatenated patch file + id: patch-file + run: | + ls -d -- packages/*/patches/*.patch 2>/dev/null | xargs cat > combined-patch-file.txt || touch combined-patch-file.txt + echo "patch_checksum=$(sha256sum combined-patch-file.txt | cut -d' ' -f1)" >> $GITHUB_OUTPUT + + - name: Cache node modules + id: cache-node-modules + uses: actions/cache@v4 + with: + path: | + node_modules + packages/mobile/node_modules + packages/common/node_modules + packages/libs/node_modules + packages/libs/dist + packages/sdk/node_modules + packages/sdk/dist + packages/harmony/node_modules + key: npm-cache-mobile-${{ runner.os }}-node-${{ env.NODE_VERSION }}-${{ hashFiles('package-lock.json') }}-${{ steps.patch-file.outputs.patch_checksum }} + restore-keys: | + npm-cache-mobile-${{ runner.os }}-node-${{ env.NODE_VERSION }}-${{ hashFiles('package-lock.json') }}- + npm-cache-mobile-${{ runner.os }}-${{ hashFiles('package-lock.json') }}- + + - name: Cache Android libs + uses: actions/cache@v4 + with: + path: packages/mobile/android/libs + key: ffmpeg-aar-${{ hashFiles('packages/mobile/android/build.gradle') }} + restore-keys: | + ffmpeg-aar- + + - name: Cache Android gems + uses: actions/cache@v4 + with: + path: packages/mobile/android/vendor/bundle + key: gems-android-${{ hashFiles('packages/mobile/android/Gemfile.lock') }} + restore-keys: | + gems-android- + + - name: Install dependencies + env: + CI: true + NODE_OPTIONS: --max-old-space-size=8192 + run: | + if [[ -d node_modules ]]; then + echo "Using cached node_modules, running postinstall..." + npm run postinstall + else + echo "No cache found, running fresh install..." + npm ci --prefer-offline + fi + + - name: Update bundler + run: sudo gem install bundler:1.17.3 + + - name: Install pip and ninja + run: | + sudo apt update + sudo apt install -y python3-pip ninja-build + + - name: Install Android gems + run: | + cd packages/mobile/android + bundle check || bundle install --path vendor/bundle + + - name: Update fastlane + run: cd packages/mobile/android && sudo bundle update fastlane + + - name: Migrate support libraries for AndroidX + run: cd packages/mobile && npm run jetifier + + - name: Install ffmpeg-aar + run: | + cd packages/mobile/android + ./gradlew :app:downloadAar + + - name: Setup Play Store API + run: | + echo "${{ secrets.FASTLANE_PLAYSTORE_JSON }}" | base64 --decode > packages/mobile/android/app/api.json + + - name: Build dependencies + timeout-minutes: 60 + run: npx turbo run build --filter=@audius/mobile + + - name: Release Android (Production) + timeout-minutes: 60 + env: + FASTLANE_PLAYSTORE_JSON: ${{ secrets.FASTLANE_PLAYSTORE_JSON }} + run: | + cd packages/mobile/android + bundle exec fastlane prod track:alpha + From 184e594efaaaf983dff8aba0f639de09d9a3dc17 Mon Sep 17 00:00:00 2001 From: Dylan Jeffers Date: Fri, 9 Jan 2026 10:55:51 -0800 Subject: [PATCH 02/18] Testing RC deploy --- .github/workflows/mobile.yml | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/.github/workflows/mobile.yml b/.github/workflows/mobile.yml index e91b63a6038..e3a36899a9b 100644 --- a/.github/workflows/mobile.yml +++ b/.github/workflows/mobile.yml @@ -2,8 +2,9 @@ name: Mobile CI/CD on: push: - branches: - - main + # TODO: Restrict to main branch after testing + # branches: + # - main paths: - 'packages/mobile/**' - 'packages/common/**' @@ -94,7 +95,9 @@ jobs: name: iOS Release Candidate Build & Upload runs-on: macos-15 needs: mobile-init - if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request' + # TODO: Re-enable main branch restriction after testing + # if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request' + if: github.event_name != 'pull_request' steps: - name: Checkout code uses: actions/checkout@v4 @@ -205,7 +208,9 @@ jobs: name: Android Release Candidate Build & Upload runs-on: ubuntu-latest needs: mobile-init - if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request' + # TODO: Re-enable main branch restriction after testing + # if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request' + if: github.event_name != 'pull_request' steps: - name: Checkout code uses: actions/checkout@v4 From 1f6746d2f7466a2bcfeddab77ae6e979388ee1fa Mon Sep 17 00:00:00 2001 From: Dylan Jeffers Date: Fri, 9 Jan 2026 11:44:41 -0800 Subject: [PATCH 03/18] Update ios step to install on mac box --- .github/workflows/mobile.yml | 42 ++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/.github/workflows/mobile.yml b/.github/workflows/mobile.yml index e3a36899a9b..128abd5082e 100644 --- a/.github/workflows/mobile.yml +++ b/.github/workflows/mobile.yml @@ -133,6 +133,25 @@ jobs: npm-cache-mobile-${{ runner.os }}-node-${{ env.NODE_VERSION }}-${{ hashFiles('package-lock.json') }}- npm-cache-mobile-${{ runner.os }}-${{ hashFiles('package-lock.json') }}- + - name: Copy production env + run: | + cd packages/mobile + echo -e "\nAMPLITUDE_WRITE_KEY=${{ secrets.AMPLITUDE_WRITE_KEY_PROD }}" >> .env.prod + + - name: Install dependencies + env: + CI: true + SKIP_POD_INSTALL: true + NODE_OPTIONS: --max-old-space-size=8192 + run: | + if [[ -d node_modules ]]; then + echo "Using cached node_modules, running postinstall..." + npm run postinstall + else + echo "No cache found, running fresh install..." + npm ci --prefer-offline + fi + - name: Cache iOS gems uses: actions/cache@v4 with: @@ -167,7 +186,7 @@ jobs: - name: Update fastlane run: cd packages/mobile/ios && sudo bundle update fastlane - - name: Copy production env + - name: Copy production env to iOS run: cp packages/mobile/.env.prod packages/mobile/ios/ - name: Build and upload iOS (Release Candidate) @@ -386,6 +405,25 @@ jobs: npm-cache-mobile-${{ runner.os }}-node-${{ env.NODE_VERSION }}-${{ hashFiles('package-lock.json') }}- npm-cache-mobile-${{ runner.os }}-${{ hashFiles('package-lock.json') }}- + - name: Copy production env + run: | + cd packages/mobile + echo -e "\nAMPLITUDE_WRITE_KEY=${{ secrets.AMPLITUDE_WRITE_KEY_PROD }}" >> .env.prod + + - name: Install dependencies + env: + CI: true + SKIP_POD_INSTALL: true + NODE_OPTIONS: --max-old-space-size=8192 + run: | + if [[ -d node_modules ]]; then + echo "Using cached node_modules, running postinstall..." + npm run postinstall + else + echo "No cache found, running fresh install..." + npm ci --prefer-offline + fi + - name: Cache iOS gems uses: actions/cache@v4 with: @@ -420,7 +458,7 @@ jobs: - name: Update fastlane run: cd packages/mobile/ios && sudo bundle update fastlane - - name: Copy production env + - name: Copy production env to iOS run: cp packages/mobile/.env.prod packages/mobile/ios/ - name: Build and upload iOS (Production) From 6ef568fd8972d27b38c9d2b4e8809daccef8ed05 Mon Sep 17 00:00:00 2001 From: Dylan Jeffers Date: Fri, 9 Jan 2026 13:02:06 -0800 Subject: [PATCH 04/18] dot-env thing --- .github/workflows/mobile.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/mobile.yml b/.github/workflows/mobile.yml index 128abd5082e..c6aba6d6f97 100644 --- a/.github/workflows/mobile.yml +++ b/.github/workflows/mobile.yml @@ -64,6 +64,7 @@ jobs: packages/sdk/node_modules packages/sdk/dist packages/harmony/node_modules + packages/dotenv-linter/bin key: npm-cache-mobile-${{ runner.os }}-node-${{ env.NODE_VERSION }}-${{ hashFiles('package-lock.json') }}-${{ steps.patch-file.outputs.patch_checksum }} restore-keys: | npm-cache-mobile-${{ runner.os }}-node-${{ env.NODE_VERSION }}-${{ hashFiles('package-lock.json') }}- @@ -82,6 +83,11 @@ jobs: if [[ -d node_modules ]]; then echo "Using cached node_modules, running postinstall..." npm run postinstall + # Ensure dotenv-linter binary is installed (install script downloads it) + if [[ ! -f packages/dotenv-linter/bin/dotenv-linter ]]; then + echo "dotenv-linter binary missing, running install script..." + (cd packages/dotenv-linter && npm run install) + fi else echo "No cache found, running fresh install..." npm ci --prefer-offline From b9b633eff483113dbe323988123c62181cac620f Mon Sep 17 00:00:00 2001 From: Dylan Jeffers Date: Fri, 9 Jan 2026 13:49:35 -0800 Subject: [PATCH 05/18] Update python version --- .github/workflows/mobile.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/.github/workflows/mobile.yml b/.github/workflows/mobile.yml index c6aba6d6f97..f0006194339 100644 --- a/.github/workflows/mobile.yml +++ b/.github/workflows/mobile.yml @@ -144,6 +144,11 @@ jobs: cd packages/mobile echo -e "\nAMPLITUDE_WRITE_KEY=${{ secrets.AMPLITUDE_WRITE_KEY_PROD }}" >> .env.prod + - name: Install Python build dependencies + run: | + # Python 3.12+ doesn't include distutils, but setuptools provides it + python3 -m pip install --upgrade setuptools + - name: Install dependencies env: CI: true @@ -153,6 +158,11 @@ jobs: if [[ -d node_modules ]]; then echo "Using cached node_modules, running postinstall..." npm run postinstall + # Ensure dotenv-linter binary is installed (install script downloads it) + if [[ ! -f packages/dotenv-linter/bin/dotenv-linter ]]; then + echo "dotenv-linter binary missing, running install script..." + (cd packages/dotenv-linter && npm run install) + fi else echo "No cache found, running fresh install..." npm ci --prefer-offline @@ -416,6 +426,11 @@ jobs: cd packages/mobile echo -e "\nAMPLITUDE_WRITE_KEY=${{ secrets.AMPLITUDE_WRITE_KEY_PROD }}" >> .env.prod + - name: Install Python build dependencies + run: | + # Python 3.12+ doesn't include distutils, but setuptools provides it + python3 -m pip install --upgrade setuptools + - name: Install dependencies env: CI: true @@ -425,6 +440,11 @@ jobs: if [[ -d node_modules ]]; then echo "Using cached node_modules, running postinstall..." npm run postinstall + # Ensure dotenv-linter binary is installed (install script downloads it) + if [[ ! -f packages/dotenv-linter/bin/dotenv-linter ]]; then + echo "dotenv-linter binary missing, running install script..." + (cd packages/dotenv-linter && npm run install) + fi else echo "No cache found, running fresh install..." npm ci --prefer-offline From 44ae9d93480f1bcbcb60202da1e1f8de6395d383 Mon Sep 17 00:00:00 2001 From: Dylan Jeffers Date: Fri, 9 Jan 2026 14:10:04 -0800 Subject: [PATCH 06/18] Update python stuff again --- .github/workflows/mobile.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/mobile.yml b/.github/workflows/mobile.yml index f0006194339..542a8f28f1e 100644 --- a/.github/workflows/mobile.yml +++ b/.github/workflows/mobile.yml @@ -147,7 +147,8 @@ jobs: - name: Install Python build dependencies run: | # Python 3.12+ doesn't include distutils, but setuptools provides it - python3 -m pip install --upgrade setuptools + # Use --user flag to avoid externally-managed-environment error + python3 -m pip install --user --upgrade setuptools - name: Install dependencies env: @@ -429,7 +430,8 @@ jobs: - name: Install Python build dependencies run: | # Python 3.12+ doesn't include distutils, but setuptools provides it - python3 -m pip install --upgrade setuptools + # Use --user flag to avoid externally-managed-environment error + python3 -m pip install --user --upgrade setuptools - name: Install dependencies env: From 7cd29f7396b118adfd3cd870eec8feb5d06a0698 Mon Sep 17 00:00:00 2001 From: Dylan Jeffers Date: Fri, 9 Jan 2026 16:17:00 -0800 Subject: [PATCH 07/18] Try again --- .github/workflows/mobile.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/mobile.yml b/.github/workflows/mobile.yml index 542a8f28f1e..7dbabc8301c 100644 --- a/.github/workflows/mobile.yml +++ b/.github/workflows/mobile.yml @@ -147,8 +147,8 @@ jobs: - name: Install Python build dependencies run: | # Python 3.12+ doesn't include distutils, but setuptools provides it - # Use --user flag to avoid externally-managed-environment error - python3 -m pip install --user --upgrade setuptools + # Use --break-system-packages for CI (safe since runner is ephemeral) + python3 -m pip install --break-system-packages --upgrade setuptools - name: Install dependencies env: @@ -430,8 +430,8 @@ jobs: - name: Install Python build dependencies run: | # Python 3.12+ doesn't include distutils, but setuptools provides it - # Use --user flag to avoid externally-managed-environment error - python3 -m pip install --user --upgrade setuptools + # Use --break-system-packages for CI (safe since runner is ephemeral) + python3 -m pip install --break-system-packages --upgrade setuptools - name: Install dependencies env: From 533871461746590fd4c0ea8c2eb89937ca12097e Mon Sep 17 00:00:00 2001 From: Dylan Jeffers Date: Fri, 9 Jan 2026 18:05:31 -0800 Subject: [PATCH 08/18] Fixes ssh stuff --- .github/workflows/mobile.yml | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/.github/workflows/mobile.yml b/.github/workflows/mobile.yml index 7dbabc8301c..9806bb18531 100644 --- a/.github/workflows/mobile.yml +++ b/.github/workflows/mobile.yml @@ -206,6 +206,24 @@ jobs: - name: Copy production env to iOS run: cp packages/mobile/.env.prod packages/mobile/ios/ + - name: Set up SSH for Fastlane Match + run: | + # Set up SSH agent + eval "$(ssh-agent -s)" + + # Add GitHub to known_hosts + mkdir -p ~/.ssh + echo 'github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==' >> ~/.ssh/known_hosts + + # Add SSH private key for accessing certs-and-profiles repository + echo "${{ secrets.GITHUB_SSH_PRIVATE_KEY }}" | tr -d '\r' > ~/.ssh/id_rsa + chmod 600 ~/.ssh/id_rsa + ssh-add ~/.ssh/id_rsa + + # Configure git to use SSH + git config --global user.email "audius-infra@audius.co" + git config --global user.name "audius-infra" + - name: Build and upload iOS (Release Candidate) timeout-minutes: 60 env: @@ -489,6 +507,24 @@ jobs: - name: Copy production env to iOS run: cp packages/mobile/.env.prod packages/mobile/ios/ + - name: Set up SSH for Fastlane Match + run: | + # Set up SSH agent + eval "$(ssh-agent -s)" + + # Add GitHub to known_hosts + mkdir -p ~/.ssh + echo 'github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==' >> ~/.ssh/known_hosts + + # Add SSH private key for accessing certs-and-profiles repository + echo "${{ secrets.GITHUB_SSH_PRIVATE_KEY }}" | tr -d '\r' > ~/.ssh/id_rsa + chmod 600 ~/.ssh/id_rsa + ssh-add ~/.ssh/id_rsa + + # Configure git to use SSH + git config --global user.email "audius-infra@audius.co" + git config --global user.name "audius-infra" + - name: Build and upload iOS (Production) timeout-minutes: 60 env: From 5c13e171eb0b872981bdaf5d57541dbbd33c9f80 Mon Sep 17 00:00:00 2001 From: Dylan Jeffers Date: Mon, 12 Jan 2026 08:50:01 -0800 Subject: [PATCH 09/18] Updates --- .github/workflows/mobile.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/.github/workflows/mobile.yml b/.github/workflows/mobile.yml index 9806bb18531..32161be585d 100644 --- a/.github/workflows/mobile.yml +++ b/.github/workflows/mobile.yml @@ -213,11 +213,22 @@ jobs: # Add GitHub to known_hosts mkdir -p ~/.ssh + chmod 700 ~/.ssh echo 'github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==' >> ~/.ssh/known_hosts + chmod 644 ~/.ssh/known_hosts # Add SSH private key for accessing certs-and-profiles repository + # Write key and remove any carriage returns (works on both macOS and Linux) echo "${{ secrets.GITHUB_SSH_PRIVATE_KEY }}" | tr -d '\r' > ~/.ssh/id_rsa chmod 600 ~/.ssh/id_rsa + + # Verify key is valid before adding to agent + if ! ssh-keygen -l -f ~/.ssh/id_rsa > /dev/null 2>&1; then + echo "Error: SSH key format is invalid" + exit 1 + fi + + # Add key to agent ssh-add ~/.ssh/id_rsa # Configure git to use SSH @@ -514,11 +525,22 @@ jobs: # Add GitHub to known_hosts mkdir -p ~/.ssh + chmod 700 ~/.ssh echo 'github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==' >> ~/.ssh/known_hosts + chmod 644 ~/.ssh/known_hosts # Add SSH private key for accessing certs-and-profiles repository + # Write key and remove any carriage returns (works on both macOS and Linux) echo "${{ secrets.GITHUB_SSH_PRIVATE_KEY }}" | tr -d '\r' > ~/.ssh/id_rsa chmod 600 ~/.ssh/id_rsa + + # Verify key is valid before adding to agent + if ! ssh-keygen -l -f ~/.ssh/id_rsa > /dev/null 2>&1; then + echo "Error: SSH key format is invalid" + exit 1 + fi + + # Add key to agent ssh-add ~/.ssh/id_rsa # Configure git to use SSH From f277e13453a5487572d29d22b2710f5608b43b91 Mon Sep 17 00:00:00 2001 From: Dylan Jeffers Date: Mon, 12 Jan 2026 16:35:51 -0800 Subject: [PATCH 10/18] Updates --- .github/workflows/mobile.yml | 116 +++++++++++++++++------------------ 1 file changed, 58 insertions(+), 58 deletions(-) diff --git a/.github/workflows/mobile.yml b/.github/workflows/mobile.yml index 32161be585d..f5eda1d9e2e 100644 --- a/.github/workflows/mobile.yml +++ b/.github/workflows/mobile.yml @@ -108,6 +108,35 @@ jobs: - name: Checkout code uses: actions/checkout@v4 + - name: Set up SSH for Fastlane Match (test early) + run: | + # Set up SSH agent + eval "$(ssh-agent -s)" + + # Add GitHub to known_hosts + mkdir -p ~/.ssh + chmod 700 ~/.ssh + echo 'github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==' >> ~/.ssh/known_hosts + chmod 644 ~/.ssh/known_hosts + + # Add SSH private key for accessing certs-and-profiles repository + # Check if secret is set + if [[ -z "${{ secrets.GITHUB_SSH_PRIVATE_KEY }}" ]]; then + echo "Error: GITHUB_SSH_PRIVATE_KEY secret is not set" + exit 1 + fi + + # Write key and remove any carriage returns (works on both macOS and Linux) + echo "${{ secrets.GITHUB_SSH_PRIVATE_KEY }}" | tr -d '\r' > ~/.ssh/id_rsa + chmod 600 ~/.ssh/id_rsa + + # Add key to agent (will provide detailed error if format is wrong) + ssh-add ~/.ssh/id_rsa + + # Configure git to use SSH + git config --global user.email "audius-infra@audius.co" + git config --global user.name "audius-infra" + - name: Setup Node.js uses: actions/setup-node@v4 with: @@ -206,35 +235,6 @@ jobs: - name: Copy production env to iOS run: cp packages/mobile/.env.prod packages/mobile/ios/ - - name: Set up SSH for Fastlane Match - run: | - # Set up SSH agent - eval "$(ssh-agent -s)" - - # Add GitHub to known_hosts - mkdir -p ~/.ssh - chmod 700 ~/.ssh - echo 'github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==' >> ~/.ssh/known_hosts - chmod 644 ~/.ssh/known_hosts - - # Add SSH private key for accessing certs-and-profiles repository - # Write key and remove any carriage returns (works on both macOS and Linux) - echo "${{ secrets.GITHUB_SSH_PRIVATE_KEY }}" | tr -d '\r' > ~/.ssh/id_rsa - chmod 600 ~/.ssh/id_rsa - - # Verify key is valid before adding to agent - if ! ssh-keygen -l -f ~/.ssh/id_rsa > /dev/null 2>&1; then - echo "Error: SSH key format is invalid" - exit 1 - fi - - # Add key to agent - ssh-add ~/.ssh/id_rsa - - # Configure git to use SSH - git config --global user.email "audius-infra@audius.co" - git config --global user.name "audius-infra" - - name: Build and upload iOS (Release Candidate) timeout-minutes: 60 env: @@ -420,6 +420,35 @@ jobs: - name: Checkout code uses: actions/checkout@v4 + - name: Set up SSH for Fastlane Match (test early) + run: | + # Set up SSH agent + eval "$(ssh-agent -s)" + + # Add GitHub to known_hosts + mkdir -p ~/.ssh + chmod 700 ~/.ssh + echo 'github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==' >> ~/.ssh/known_hosts + chmod 644 ~/.ssh/known_hosts + + # Add SSH private key for accessing certs-and-profiles repository + # Check if secret is set + if [[ -z "${{ secrets.GITHUB_SSH_PRIVATE_KEY }}" ]]; then + echo "Error: GITHUB_SSH_PRIVATE_KEY secret is not set" + exit 1 + fi + + # Write key and remove any carriage returns (works on both macOS and Linux) + echo "${{ secrets.GITHUB_SSH_PRIVATE_KEY }}" | tr -d '\r' > ~/.ssh/id_rsa + chmod 600 ~/.ssh/id_rsa + + # Add key to agent (will provide detailed error if format is wrong) + ssh-add ~/.ssh/id_rsa + + # Configure git to use SSH + git config --global user.email "audius-infra@audius.co" + git config --global user.name "audius-infra" + - name: Setup Node.js uses: actions/setup-node@v4 with: @@ -518,35 +547,6 @@ jobs: - name: Copy production env to iOS run: cp packages/mobile/.env.prod packages/mobile/ios/ - - name: Set up SSH for Fastlane Match - run: | - # Set up SSH agent - eval "$(ssh-agent -s)" - - # Add GitHub to known_hosts - mkdir -p ~/.ssh - chmod 700 ~/.ssh - echo 'github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==' >> ~/.ssh/known_hosts - chmod 644 ~/.ssh/known_hosts - - # Add SSH private key for accessing certs-and-profiles repository - # Write key and remove any carriage returns (works on both macOS and Linux) - echo "${{ secrets.GITHUB_SSH_PRIVATE_KEY }}" | tr -d '\r' > ~/.ssh/id_rsa - chmod 600 ~/.ssh/id_rsa - - # Verify key is valid before adding to agent - if ! ssh-keygen -l -f ~/.ssh/id_rsa > /dev/null 2>&1; then - echo "Error: SSH key format is invalid" - exit 1 - fi - - # Add key to agent - ssh-add ~/.ssh/id_rsa - - # Configure git to use SSH - git config --global user.email "audius-infra@audius.co" - git config --global user.name "audius-infra" - - name: Build and upload iOS (Production) timeout-minutes: 60 env: From d4a945428fb407da42e7c162576c880b3f4d03f3 Mon Sep 17 00:00:00 2001 From: Dylan Jeffers Date: Wed, 14 Jan 2026 09:28:37 -0800 Subject: [PATCH 11/18] Add key --- .github/workflows/mobile.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/mobile.yml b/.github/workflows/mobile.yml index f5eda1d9e2e..044742dec21 100644 --- a/.github/workflows/mobile.yml +++ b/.github/workflows/mobile.yml @@ -121,13 +121,13 @@ jobs: # Add SSH private key for accessing certs-and-profiles repository # Check if secret is set - if [[ -z "${{ secrets.GITHUB_SSH_PRIVATE_KEY }}" ]]; then - echo "Error: GITHUB_SSH_PRIVATE_KEY secret is not set" + if [[ -z "${{ secrets.AUDIUS_INFRA_SSH_KEY }}" ]]; then + echo "Error: AUDIUS_INFRA_SSH_KEY secret is not set" exit 1 fi # Write key and remove any carriage returns (works on both macOS and Linux) - echo "${{ secrets.GITHUB_SSH_PRIVATE_KEY }}" | tr -d '\r' > ~/.ssh/id_rsa + echo "${{ secrets.AUDIUS_INFRA_SSH_KEY }}" | tr -d '\r' > ~/.ssh/id_rsa chmod 600 ~/.ssh/id_rsa # Add key to agent (will provide detailed error if format is wrong) @@ -433,13 +433,13 @@ jobs: # Add SSH private key for accessing certs-and-profiles repository # Check if secret is set - if [[ -z "${{ secrets.GITHUB_SSH_PRIVATE_KEY }}" ]]; then - echo "Error: GITHUB_SSH_PRIVATE_KEY secret is not set" + if [[ -z "${{ secrets.AUDIUS_INFRA_SSH_KEY }}" ]]; then + echo "Error: AUDIUS_INFRA_SSH_KEY secret is not set" exit 1 fi # Write key and remove any carriage returns (works on both macOS and Linux) - echo "${{ secrets.GITHUB_SSH_PRIVATE_KEY }}" | tr -d '\r' > ~/.ssh/id_rsa + echo "${{ secrets.AUDIUS_INFRA_SSH_KEY }}" | tr -d '\r' > ~/.ssh/id_rsa chmod 600 ~/.ssh/id_rsa # Add key to agent (will provide detailed error if format is wrong) From d3cbc28f9f801f2d5a006f77d2fa37770fde863a Mon Sep 17 00:00:00 2001 From: Dylan Jeffers Date: Wed, 14 Jan 2026 09:44:39 -0800 Subject: [PATCH 12/18] Some changes --- packages/mobile/ios/Podfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/mobile/ios/Podfile.lock b/packages/mobile/ios/Podfile.lock index 53e079ad184..4d10400ee3c 100644 --- a/packages/mobile/ios/Podfile.lock +++ b/packages/mobile/ios/Podfile.lock @@ -1369,7 +1369,7 @@ PODS: - React - react-native-google-cast/NoBluetoothArm (= 4.6.2) - react-native-google-cast/NoBluetoothArm (4.6.2): - - google-cast-sdk-dynamic-xcframework-no-bluetooth (= 4.7.1) + - google-cast-sdk-dynamic-xcframework-no-bluetooth - React - react-native-google-cast/RNGoogleCast - react-native-google-cast/RNGoogleCast (4.6.2): @@ -2872,7 +2872,7 @@ SPEC CHECKSUMS: react-native-document-picker: 9fe3cd3187a2995d78d1f34d3a52eac1b68df245 react-native-fast-crypto: b30594570dab23aca7e74e206b2c03e28a006216 react-native-get-random-values: 384787fd76976f5aec9465aff6fa9e9129af1e74 - react-native-google-cast: 0a82cf63114470403e41e04ffa2b13d6448b6112 + react-native-google-cast: 18b9b2fc518caabfa65d309409e160b3fc6d1733 react-native-image-picker: 42e3b160d82fb168288345db3b9a2a99aad02afe react-native-in-app-review: db8bb167a5f238e7ceca5c242d6b36ce8c4404a4 react-native-keyboard-controller: 3aaba4f7015628ca833ce7ad889754571cef6455 From eca4cda9708b0f63b7abc6e5818541c88d87dd7c Mon Sep 17 00:00:00 2001 From: Dylan Jeffers Date: Wed, 14 Jan 2026 09:58:18 -0800 Subject: [PATCH 13/18] Fixes --- .github/workflows/mobile.yml | 25 +++++++++++++++++----- .github/workflows/web.yml | 40 ++++++++++++++++++++++++++++-------- 2 files changed, 52 insertions(+), 13 deletions(-) diff --git a/.github/workflows/mobile.yml b/.github/workflows/mobile.yml index 044742dec21..c7e9a065419 100644 --- a/.github/workflows/mobile.yml +++ b/.github/workflows/mobile.yml @@ -90,7 +90,10 @@ jobs: fi else echo "No cache found, running fresh install..." - npm ci --prefer-offline + # Clear npm cache to avoid EEXIST conflicts + npm cache clean --force || true + # Try npm ci first, fallback to npm install if lock file is out of sync + npm ci --prefer-offline || npm install --prefer-offline fi - name: Lint & Typecheck @@ -195,7 +198,10 @@ jobs: fi else echo "No cache found, running fresh install..." - npm ci --prefer-offline + # Clear npm cache to avoid EEXIST conflicts + npm cache clean --force || true + # Try npm ci first, fallback to npm install if lock file is out of sync + npm ci --prefer-offline || npm install --prefer-offline fi - name: Cache iOS gems @@ -346,7 +352,10 @@ jobs: npm run postinstall else echo "No cache found, running fresh install..." - npm ci --prefer-offline + # Clear npm cache to avoid EEXIST conflicts + npm cache clean --force || true + # Try npm ci first, fallback to npm install if lock file is out of sync + npm ci --prefer-offline || npm install --prefer-offline fi - name: Update bundler @@ -507,7 +516,10 @@ jobs: fi else echo "No cache found, running fresh install..." - npm ci --prefer-offline + # Clear npm cache to avoid EEXIST conflicts + npm cache clean --force || true + # Try npm ci first, fallback to npm install if lock file is out of sync + npm ci --prefer-offline || npm install --prefer-offline fi - name: Cache iOS gems @@ -641,7 +653,10 @@ jobs: npm run postinstall else echo "No cache found, running fresh install..." - npm ci --prefer-offline + # Clear npm cache to avoid EEXIST conflicts + npm cache clean --force || true + # Try npm ci first, fallback to npm install if lock file is out of sync + npm ci --prefer-offline || npm install --prefer-offline fi - name: Update bundler diff --git a/.github/workflows/web.yml b/.github/workflows/web.yml index 2885c3e3b30..fe4b40453f3 100644 --- a/.github/workflows/web.yml +++ b/.github/workflows/web.yml @@ -78,7 +78,10 @@ jobs: npm run postinstall else echo "No cache found, running fresh install..." - npm ci --prefer-offline + # Clear npm cache to avoid EEXIST conflicts + npm cache clean --force || true + # Try npm ci first, fallback to npm install if lock file is out of sync + npm ci --prefer-offline || npm install --prefer-offline fi web-lint: @@ -127,7 +130,10 @@ jobs: NODE_OPTIONS: --max-old-space-size=8192 run: | mkdir -p /tmp/android-sdk-dummy - npm ci --prefer-offline + # Clear npm cache to avoid EEXIST conflicts + npm cache clean --force || true + # Try npm ci first, fallback to npm install if lock file is out of sync + npm ci --prefer-offline || npm install --prefer-offline - name: Cache for Turbo uses: rharkor/caching-for-turbo@v2.2.1 @@ -184,7 +190,10 @@ jobs: NODE_OPTIONS: --max-old-space-size=8192 run: | mkdir -p /tmp/android-sdk-dummy - npm ci --prefer-offline + # Clear npm cache to avoid EEXIST conflicts + npm cache clean --force || true + # Try npm ci first, fallback to npm install if lock file is out of sync + npm ci --prefer-offline || npm install --prefer-offline - name: Cache for Turbo uses: rharkor/caching-for-turbo@v2.2.1 @@ -238,7 +247,10 @@ jobs: NODE_OPTIONS: --max-old-space-size=8192 run: | mkdir -p /tmp/android-sdk-dummy - npm ci --prefer-offline + # Clear npm cache to avoid EEXIST conflicts + npm cache clean --force || true + # Try npm ci first, fallback to npm install if lock file is out of sync + npm ci --prefer-offline || npm install --prefer-offline - name: Cache for Turbo uses: rharkor/caching-for-turbo@v2.2.1 @@ -308,7 +320,10 @@ jobs: NODE_OPTIONS: --max-old-space-size=8192 run: | mkdir -p /tmp/android-sdk-dummy - npm ci --prefer-offline + # Clear npm cache to avoid EEXIST conflicts + npm cache clean --force || true + # Try npm ci first, fallback to npm install if lock file is out of sync + npm ci --prefer-offline || npm install --prefer-offline - name: Run postinstall (if cache hit) if: steps.cache-node-modules.outputs.cache-hit == 'true' @@ -393,7 +408,10 @@ jobs: NODE_OPTIONS: --max-old-space-size=8192 run: | mkdir -p /tmp/android-sdk-dummy - npm ci --prefer-offline + # Clear npm cache to avoid EEXIST conflicts + npm cache clean --force || true + # Try npm ci first, fallback to npm install if lock file is out of sync + npm ci --prefer-offline || npm install --prefer-offline - name: Run postinstall (if cache hit) if: steps.cache-node-modules.outputs.cache-hit == 'true' @@ -465,7 +483,10 @@ jobs: NODE_OPTIONS: --max-old-space-size=8192 run: | mkdir -p /tmp/android-sdk-dummy - npm ci --prefer-offline + # Clear npm cache to avoid EEXIST conflicts + npm cache clean --force || true + # Try npm ci first, fallback to npm install if lock file is out of sync + npm ci --prefer-offline || npm install --prefer-offline - name: Run postinstall (if cache hit) if: steps.cache-node-modules.outputs.cache-hit == 'true' @@ -618,7 +639,10 @@ jobs: NODE_OPTIONS: --max-old-space-size=8192 run: | mkdir -p /tmp/android-sdk-dummy - npm ci --prefer-offline + # Clear npm cache to avoid EEXIST conflicts + npm cache clean --force || true + # Try npm ci first, fallback to npm install if lock file is out of sync + npm ci --prefer-offline || npm install --prefer-offline - name: Run postinstall (if cache hit) if: steps.cache-node-modules.outputs.cache-hit == 'true' From bf4012d888528f27d353bbe1def9b37137f4ba23 Mon Sep 17 00:00:00 2001 From: Dylan Jeffers Date: Wed, 14 Jan 2026 12:18:37 -0800 Subject: [PATCH 14/18] retrigger --- packages/web/src/app/App.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/web/src/app/App.tsx b/packages/web/src/app/App.tsx index 38dcf591b40..6f87c8223c5 100644 --- a/packages/web/src/app/App.tsx +++ b/packages/web/src/app/App.tsx @@ -1,4 +1,5 @@ // @refresh reset + // App component - routing is now handled by data router in AppProviders import { AppProviders } from './AppProviders' From 39541215cfeb42df15504c8fa11ff18ed54b7e40 Mon Sep 17 00:00:00 2001 From: Dylan Jeffers Date: Wed, 14 Jan 2026 12:50:07 -0800 Subject: [PATCH 15/18] retrigger mobile --- packages/mobile/src/app/App.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/mobile/src/app/App.tsx b/packages/mobile/src/app/App.tsx index b6796060f3a..0c9adcf4a60 100644 --- a/packages/mobile/src/app/App.tsx +++ b/packages/mobile/src/app/App.tsx @@ -33,6 +33,7 @@ import { Drawers } from './Drawers' import ErrorBoundary from './ErrorBoundary' import { ThemeProvider } from './ThemeProvider' import { initSentry, navigationIntegration } from './sentry' +// hello initSentry() From 761ede4deddc62cd1255bd37215b1f0a0dae2685 Mon Sep 17 00:00:00 2001 From: Dylan Jeffers Date: Wed, 14 Jan 2026 14:41:49 -0800 Subject: [PATCH 16/18] Fix app-store stuff --- .github/workflows/mobile.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/mobile.yml b/.github/workflows/mobile.yml index c7e9a065419..c8027675a6e 100644 --- a/.github/workflows/mobile.yml +++ b/.github/workflows/mobile.yml @@ -249,6 +249,9 @@ jobs: FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD: ${{ secrets.FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD }} FASTLANE_SESSION: ${{ secrets.FASTLANE_SESSION }} MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }} + APP_STORE_CONNECT_API_KEY_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_KEY_ID }} + APP_STORE_CONNECT_API_KEY_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ISSUER_ID }} + APP_STORE_CONNECT_API_KEY_KEY: ${{ secrets.APP_STORE_CONNECT_API_KEY_KEY }} SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} SENTRY_ORG: ${{ secrets.SENTRY_ORG }} SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }} @@ -567,6 +570,9 @@ jobs: FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD: ${{ secrets.FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD }} FASTLANE_SESSION: ${{ secrets.FASTLANE_SESSION }} MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }} + APP_STORE_CONNECT_API_KEY_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_KEY_ID }} + APP_STORE_CONNECT_API_KEY_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ISSUER_ID }} + APP_STORE_CONNECT_API_KEY_KEY: ${{ secrets.APP_STORE_CONNECT_API_KEY_KEY }} SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} SENTRY_ORG: ${{ secrets.SENTRY_ORG }} SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }} From 75abd1ab87611055986f44be0a00269c05b0f5a6 Mon Sep 17 00:00:00 2001 From: Dylan Jeffers Date: Wed, 14 Jan 2026 16:56:49 -0800 Subject: [PATCH 17/18] Fix --- packages/mobile/ios/fastlane/Fastfile | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/mobile/ios/fastlane/Fastfile b/packages/mobile/ios/fastlane/Fastfile index fa27e216768..f3d38766608 100644 --- a/packages/mobile/ios/fastlane/Fastfile +++ b/packages/mobile/ios/fastlane/Fastfile @@ -87,6 +87,7 @@ platform :ios do codesigning_identity: "iPhone Distribution", scheme: scheme, configuration: configuration, + output_directory: "./output/gym", xcargs: settings_to_override, export_method: "app-store", export_options: { From 4d064b23bbf916779bf7ddd932457166b0312727 Mon Sep 17 00:00:00 2001 From: Dylan Jeffers Date: Wed, 14 Jan 2026 21:45:40 -0800 Subject: [PATCH 18/18] Finalize --- .github/workflows/mobile.yml | 44 ++++++++++++------------------------ 1 file changed, 14 insertions(+), 30 deletions(-) diff --git a/.github/workflows/mobile.yml b/.github/workflows/mobile.yml index c8027675a6e..cc83ab1546f 100644 --- a/.github/workflows/mobile.yml +++ b/.github/workflows/mobile.yml @@ -261,21 +261,13 @@ jobs: - name: Slack notification if: success() - uses: slackapi/slack-github-action@v1 - with: - webhook-url: ${{ secrets.SLACK_DAILY_DEPLOY_WEBHOOK }} - payload: | - { - "blocks": [ - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "Deployed co.audius.audiusmusic.releasecandidate <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|v$(jq -r '.version' packages/mobile/package.json)> to mobile ios" - } - } - ] - } + env: + SLACK_WEBHOOK: ${{ secrets.SLACK_DAILY_DEPLOY_WEBHOOK }} + run: | + deploying_version=$(jq -r '.version' packages/mobile/package.json) + job_url="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" + json_content="{ \"blocks\": [{ \"type\": \"section\", \"text\": { \"type\": \"mrkdwn\", \"text\": \"Deployed co.audius.audiusmusic.releasecandidate <${job_url}|v${deploying_version}> to mobile ios\" } }]}" + curl -f -X POST -H 'Content-type: application/json' --data "$json_content" $SLACK_WEBHOOK # Android Release Candidate: Build and upload mobile-build-upload-releasecandidate-android: @@ -403,21 +395,13 @@ jobs: - name: Slack notification if: success() - uses: slackapi/slack-github-action@v1 - with: - webhook-url: ${{ secrets.SLACK_DAILY_DEPLOY_WEBHOOK }} - payload: | - { - "blocks": [ - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "Deployed releaseCandidate <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|v$(jq -r '.version' packages/mobile/package.json)> to mobile android" - } - } - ] - } + env: + SLACK_WEBHOOK: ${{ secrets.SLACK_DAILY_DEPLOY_WEBHOOK }} + run: | + deploying_version=$(jq -r '.version' packages/mobile/package.json) + job_url="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" + json_content="{ \"blocks\": [{ \"type\": \"section\", \"text\": { \"type\": \"mrkdwn\", \"text\": \"Deployed releaseCandidate <${job_url}|v${deploying_version}> to mobile android\" } }]}" + curl -f -X POST -H 'Content-type: application/json' --data "$json_content" $SLACK_WEBHOOK # iOS Production: Build and upload (requires approval) mobile-build-upload-production-ios-main: