Token Migration #1
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| on: | ||
|
Check failure on line 1 in .github/workflows/reusable-lib-workflow.yaml
|
||
| workflow_call: | ||
| inputs: | ||
| lib: | ||
| required: true | ||
| type: string | ||
| is_pr: | ||
| type: boolean | ||
| default: false | ||
| jobs: | ||
| test-android: | ||
| runs-on: ubuntu-latest | ||
| env: | ||
| BUNDLE_GEMFILE: ${{ github.workspace }}/.github/DangerFiles/Gemfile | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| if: ${{ inputs.is_pr }} | ||
| with: | ||
| # We need a sufficient depth or Danger will occasionally run into issues checking which files were modified. | ||
| fetch-depth: 100 | ||
| ref: ${{ github.event.pull_request.head.sha }} | ||
| - uses: actions/checkout@v4 | ||
| if: ${{ ! inputs.is_pr }} | ||
| with: | ||
| ref: ${{ github.head_ref }} | ||
| - name: Install Dependencies | ||
| env: | ||
| TEST_CREDENTIALS: ${{ secrets.TEST_CREDENTIALS }} | ||
| run: | | ||
| ./install.sh | ||
| echo $TEST_CREDENTIALS > ./shared/test/test_credentials.json | ||
| - name: Hybrid Dependencies | ||
| if: ${{ inputs.lib == 'SalesforceHybrid' }} | ||
| run: | | ||
| npm install -g cordova | ||
| - name: React Native Dependencies | ||
| if: ${{ inputs.lib == 'SalesforceReact' }} | ||
| run: npm install -g typescript | ||
| - uses: actions/setup-java@v4 | ||
| with: | ||
| distribution: 'zulu' | ||
| java-version: '21' | ||
| - name: Setup Android SDK | ||
| uses: android-actions/setup-android@v3 | ||
| - uses: gradle/actions/setup-gradle@v4 | ||
| with: | ||
| # This is the actual Gradle version (not AGP), which can be found in the gradle-wrapper.properties file. | ||
| gradle-version: "8.14.3" | ||
| add-job-summary: on-failure | ||
| add-job-summary-as-pr-comment: on-failure | ||
| - name: Run Lint | ||
| if: ${{ inputs.is_pr }} | ||
| run: ./gradlew libs:${{ inputs.lib }}:lint | ||
| - uses: ruby/setup-ruby@v1 | ||
| if: ${{ inputs.is_pr }} | ||
| with: | ||
| ruby-version: '3.2' | ||
| bundler-cache: true | ||
| - name: Report Static Analysis | ||
| if: ${{ inputs.is_pr }} | ||
| env: | ||
| DANGER_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| LIB: ${{ inputs.lib }} | ||
| run: bundle exec danger --dangerfile=.github/DangerFiles/StaticAnalysis.rb --danger_id="${{ inputs.lib }}" | ||
| - name: Build for Testing | ||
| if: success() || failure() | ||
| run: | | ||
| ./gradlew libs:${{ inputs.lib }}:assembleAndroidTest | ||
| ./gradlew native:NativeSampleApps:RestExplorer:assembleDebug | ||
| - uses: 'google-github-actions/auth@v2' | ||
| if: success() || failure() | ||
| with: | ||
| credentials_json: '${{ secrets.GCLOUD_SERVICE_KEY }}' | ||
| - uses: 'google-github-actions/setup-gcloud@v2' | ||
| if: success() || failure() | ||
| - name: Validate Shard Config | ||
| if: success() || failure() | ||
| run: | | ||
| SHARD_CONFIG=".github/test-shards/${{ inputs.lib }}.json" | ||
| if [ -f "$SHARD_CONFIG" ]; then | ||
| # Extract sorted class names from non-remaining shards (strip "class " prefix) | ||
| CLASSES=$(jq -r '[.shards[] | select(.name != "remaining") | .targets[] | select(startswith("class ")) | ltrimstr("class ")] | sort | .[]' "$SHARD_CONFIG") | ||
| # Extract sorted notClass names from remaining shard (strip "notClass " prefix) | ||
| NOT_CLASSES=$(jq -r '[.shards[] | select(.name == "remaining") | .targets[] | select(startswith("notClass ")) | ltrimstr("notClass ")] | sort | .[]' "$SHARD_CONFIG") | ||
| if [ "$CLASSES" != "$NOT_CLASSES" ]; then | ||
| echo "::error::Shard config mismatch in $SHARD_CONFIG - classes in shards must exactly match notClass entries in remaining shard" | ||
| echo "Difference:" | ||
| diff <(echo "$CLASSES") <(echo "$NOT_CLASSES") || true | ||
| exit 1 | ||
| fi | ||
| echo "✓ Shard config valid for ${{ inputs.lib }} ($(echo "$CLASSES" | wc -l | tr -d ' ') classes)" | ||
| else | ||
| echo "No shard config for ${{ inputs.lib }}, skipping validation" | ||
| fi | ||
| - name: Run Tests | ||
| continue-on-error: true | ||
| if: success() || failure() | ||
| env: | ||
| # Most used according to https://gs.statcounter.com/android-version-market-share/mobile-tablet/worldwide | ||
| PR_API_VERSION: "35" | ||
| FULL_API_RANGE: "28 29 30 31 32 33 34 35 36" | ||
| IS_PR: ${{ inputs.is_pr }} | ||
| run: | | ||
| LEVELS_TO_TEST=$FULL_API_RANGE | ||
| RETRIES=0 | ||
| if $IS_PR ; then | ||
| LEVELS_TO_TEST=$PR_API_VERSION | ||
| RETRIES=1 | ||
| fi | ||
| # Build test-targets-for-shard arguments from config file | ||
| SHARD_CONFIG=".github/test-shards/${{ inputs.lib }}.json" | ||
| SHARD_ARGS=() | ||
| if [ -f "$SHARD_CONFIG" ]; then | ||
| NUM_SHARDS=$(jq '.shards | length' "$SHARD_CONFIG") | ||
| for i in $(seq 0 $((NUM_SHARDS - 1))); do | ||
| # Join targets with semicolons for this shard | ||
| TARGETS=$(jq -r ".shards[$i].targets | join(\";\")" "$SHARD_CONFIG") | ||
| SHARD_ARGS+=("--test-targets-for-shard=\"${TARGETS}\"") | ||
| done | ||
| else | ||
| SHARD_ARGS=("") | ||
| fi | ||
| mkdir firebase_results | ||
| gcloud components install beta --quiet | ||
| for LEVEL in $LEVELS_TO_TEST | ||
| do | ||
| GCLOUD_RESULTS_DIR=${{ inputs.lib }}-api-${LEVEL}-build-${{github.run_number}} | ||
| eval gcloud beta firebase test android run \ | ||
| --project mobile-apps-firebase-test \ | ||
| --type instrumentation \ | ||
| --app "native/NativeSampleApps/RestExplorer/build/outputs/apk/debug/RestExplorer-debug.apk" \ | ||
| --test=libs/${{ inputs.lib }}/build/outputs/apk/androidTest/debug/${{ inputs.lib }}-debug-androidTest.apk \ | ||
| --device model=MediumPhone.arm,version=${LEVEL},locale=en,orientation=portrait \ | ||
| --environment-variables coverage=true,coverageFile="/sdcard/coverage.ec" \ | ||
| --directories-to-pull=/sdcard \ | ||
| --results-dir=${GCLOUD_RESULTS_DIR} \ | ||
| --results-history-name=${{ inputs.lib }} \ | ||
| --timeout=30m --no-auto-google-login --no-record-video --no-performance-metrics \ | ||
| "${SHARD_ARGS[@]}" \ | ||
| --num-flaky-test-attempts=${RETRIES} || true | ||
| done | ||
| - name: Copy Test Results | ||
| continue-on-error: true | ||
| if: success() || failure() | ||
| env: | ||
| # Most used according to https://gs.statcounter.com/android-version-market-share/mobile-tablet/worldwide | ||
| PR_API_VERSION: "35" | ||
| FULL_API_RANGE: "28 29 30 31 32 33 34 35 36" | ||
| IS_PR: ${{ inputs.is_pr }} | ||
| run: | | ||
| LEVELS_TO_TEST=$FULL_API_RANGE | ||
| if $IS_PR ; then | ||
| LEVELS_TO_TEST=$PR_API_VERSION | ||
| fi | ||
| for LEVEL in $LEVELS_TO_TEST | ||
| do | ||
| GCLOUD_RESULTS_DIR=${{ inputs.lib }}-api-${LEVEL}-build-${{github.run_number}} | ||
| BUCKET_PATH="gs://test-lab-w87i9sz6q175u-kwp8ium6js0zw/${GCLOUD_RESULTS_DIR}" | ||
| gsutil ls ${BUCKET_PATH} > /dev/null 2>&1 | ||
| if [ $? == 0 ] ; then | ||
| # Copy XML file for test reporting | ||
| if gsutil ls "${BUCKET_PATH}/*test_results_merged.xml" > /dev/null 2>&1; then | ||
| # Sharded runs produce test_results_merged.xml at top level | ||
| gsutil cp "${BUCKET_PATH}/*test_results_merged.xml" firebase_results/api_${LEVEL}_test_result.xml | ||
| else | ||
| gsutil cp "${BUCKET_PATH}/*/test_result_1.xml" firebase_results/api_${LEVEL}_test_result.xml | ||
| fi | ||
| # Copy all shard data for code coverage (only needed for one level) | ||
| if [ "$LEVEL" == "$PR_API_VERSION" ] ; then | ||
| mkdir -p firebase | ||
| gsutil -m cp -r -U "${BUCKET_PATH}/*" ./firebase/ | ||
| fi | ||
| fi | ||
| done | ||
| - name: Test Report | ||
| uses: mikepenz/action-junit-report | ||
| if: success() || failure() | ||
| with: | ||
| check_name: ${{ inputs.lib }} Test Results | ||
| job_name: ${{ inputs.lib }} Test Results | ||
| require_tests: true | ||
| check_retries: true | ||
| flaky_summary: true | ||
| fail_on_failure: true | ||
| group_reports: false | ||
| include_passed: true | ||
| include_empty_in_summary: false | ||
| simplified_summary: true | ||
| report_paths: 'firebase_results/**.xml' | ||
| - name: Convert Code Coverage | ||
| if: success() || failure() | ||
| run: ./gradlew libs:${{ inputs.lib }}:convertCodeCoverage | ||
| - uses: codecov/codecov-action@v5 | ||
| if: success() || failure() | ||
| with: | ||
| files: libs/${{ inputs.lib }}/build/reports/jacoco/convertedCodeCoverage/convertedCodeCoverage.xml | ||
| flags: ${{ inputs.lib }} | ||
| env: | ||
| CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} | ||