Merge pull request #97365 from cretadn22/refactor/66419-createDraftTr… #12
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
| name: Publish React Native Artifacts | |
| # Single entry point for building + publishing our prebuilt React Native artifacts. | |
| # Runs the platform-independent phases (verify patches / validate request / resolve refs) ONCE, | |
| # then fans out to the iOS and Android publish workflows in parallel. Always builds both platforms. | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| build_standalone: | |
| description: 'Build Standalone artifacts' | |
| required: false | |
| type: boolean | |
| build_hybridapp: | |
| description: 'Build HybridApp artifacts' | |
| required: false | |
| type: boolean | |
| app_pull_request_url: | |
| description: 'The Expensify/App pull request URL.' | |
| required: false | |
| default: '' | |
| mobile_expensify_pull_request_url: | |
| description: 'The Expensify/Mobile-Expensify pull request URL to check out the submodule.' | |
| required: false | |
| default: '' | |
| reviewed_code: | |
| description: I reviewed this pull request and verified that it does not contain any malicious code. | |
| type: boolean | |
| required: true | |
| default: false | |
| push: | |
| branches: | |
| - main | |
| paths: | |
| - package.json | |
| - patches/react-native+*.patch | |
| - patches/@react-native+*.patch | |
| - patches/react-native/react-native+*.patch | |
| - patches/react-native/@react-native+*.patch | |
| - Mobile-Expensify | |
| - scripts/compute-patches-hash.sh | |
| jobs: | |
| verifyPatches: | |
| name: Verify React Native Patches | |
| runs-on: blacksmith-4vcpu-ubuntu-2404 | |
| env: | |
| BUILD_STANDALONE: ${{ github.event_name == 'workflow_dispatch' && inputs.build_standalone || false }} | |
| BUILD_HYBRIDAPP: ${{ github.event_name == 'workflow_dispatch' && inputs.build_hybridapp || false }} | |
| outputs: | |
| build_targets: ${{ steps.getArtifactBuildTargets.outputs.BUILD_TARGETS }} | |
| steps: | |
| - name: Checkout | |
| # v1 | |
| uses: useblacksmith/checkout@1c9394c220d293645707b625ba9d79685f093a8f | |
| with: | |
| submodules: true | |
| ref: ${{ github.event.before || 'main' }} | |
| token: ${{ secrets.OS_BOTIFY_TOKEN }} | |
| - name: Get previous patches hash | |
| if: ${{ github.event.after != '' }} | |
| id: getOldPatchesHash | |
| run: | | |
| echo "HYBRID_APP_HASH=$(./scripts/compute-patches-hash.sh patches Mobile-Expensify/patches)" >> "$GITHUB_OUTPUT" | |
| echo "STANDALONE_APP_HASH=$(./scripts/compute-patches-hash.sh patches)" >> "$GITHUB_OUTPUT" | |
| - name: Get previous react-native version | |
| if: ${{ github.event.after != '' }} | |
| id: getOldVersion | |
| run: echo "VERSION=$(jq -r '.dependencies["react-native"]' package.json)" >> "$GITHUB_OUTPUT" | |
| - name: Checkout new ref | |
| if: ${{ github.event.after != '' }} | |
| run: | | |
| git fetch origin ${{ github.event.after }} --depth=1 | |
| git checkout ${{ github.event.after }} | |
| git submodule update | |
| - name: Get new patches hash | |
| id: getNewPatchesHash | |
| run: | | |
| echo "HYBRID_APP_HASH=$(./scripts/compute-patches-hash.sh patches Mobile-Expensify/patches)" >> "$GITHUB_OUTPUT" | |
| echo "STANDALONE_APP_HASH=$(./scripts/compute-patches-hash.sh patches)" >> "$GITHUB_OUTPUT" | |
| - name: Get new react-native version | |
| if: ${{ github.event.after != '' }} | |
| id: getNewVersion | |
| run: echo "VERSION=$(jq -r '.dependencies["react-native"]' package.json)" >> "$GITHUB_OUTPUT" | |
| - name: Check if version changed | |
| if: ${{ github.event.after != '' }} | |
| id: didVersionChange | |
| run: | | |
| readonly DID_VERSION_CHANGE=${{ steps.getOldVersion.outputs.VERSION != steps.getNewVersion.outputs.VERSION && 'true' || 'false' }} | |
| echo "DID_VERSION_CHANGE=$DID_VERSION_CHANGE" >> "$GITHUB_OUTPUT" | |
| if [[ "$DID_VERSION_CHANGE" == 'true' ]]; then | |
| echo "::notice::Detected react-native version bump (${{ steps.getOldVersion.outputs.VERSION }} -> ${{ steps.getNewVersion.outputs.VERSION }})" | |
| fi | |
| - name: Check if patches changed | |
| if: ${{ github.event.after != '' }} | |
| id: didPatchesChange | |
| run: | | |
| readonly DID_HYBRID_APP_PATCHES_CHANGE=${{ steps.getOldPatchesHash.outputs.HYBRID_APP_HASH != steps.getNewPatchesHash.outputs.HYBRID_APP_HASH && 'true' || 'false' }} | |
| readonly DID_STANDALONE_APP_PATCHES_CHANGE=${{ steps.getOldPatchesHash.outputs.STANDALONE_APP_HASH != steps.getNewPatchesHash.outputs.STANDALONE_APP_HASH && 'true' || 'false' }} | |
| echo "DID_HYBRID_APP_PATCHES_CHANGE=$DID_HYBRID_APP_PATCHES_CHANGE" >> "$GITHUB_OUTPUT" | |
| echo "DID_STANDALONE_APP_PATCHES_CHANGE=$DID_STANDALONE_APP_PATCHES_CHANGE" >> "$GITHUB_OUTPUT" | |
| if [[ "$DID_HYBRID_APP_PATCHES_CHANGE" == 'true' ]]; then | |
| echo "::notice::Detected changes in HybridApp patches (${{ steps.getOldPatchesHash.outputs.HYBRID_APP_HASH }} -> ${{ steps.getNewPatchesHash.outputs.HYBRID_APP_HASH }})" | |
| fi | |
| if [[ "$DID_STANDALONE_APP_PATCHES_CHANGE" == 'true' ]]; then | |
| echo "::notice::Detected changes in Standalone NewDot patches (${{ steps.getOldPatchesHash.outputs.STANDALONE_APP_HASH }} -> ${{ steps.getNewPatchesHash.outputs.STANDALONE_APP_HASH }})" | |
| fi | |
| - name: Get artifact build targets | |
| id: getArtifactBuildTargets | |
| run: | | |
| # workflow_dispatch path: no push ref, so build from the explicit toggles. | |
| if [[ '${{ github.event.after }}' == '' ]]; then | |
| BUILD_TARGETS=() | |
| if [[ "$BUILD_STANDALONE" == 'true' ]]; then | |
| BUILD_TARGETS+=(false) | |
| fi | |
| if [[ "$BUILD_HYBRIDAPP" == 'true' ]]; then | |
| BUILD_TARGETS+=(true) | |
| fi | |
| if [[ ${#BUILD_TARGETS[@]} -ne 0 ]]; then | |
| echo "BUILD_TARGETS=$(printf '%s\n' "${BUILD_TARGETS[@]}" | jq -R . | jq -c -s .)" >> "$GITHUB_OUTPUT" | |
| fi | |
| exit 0 | |
| fi | |
| # push path: derive targets from what actually changed between github.event.before and github.event.after. | |
| # Version change or standalone patch change forces a full rebuild of both hybrid and standalone. | |
| if [[ '${{ steps.didVersionChange.outputs.DID_VERSION_CHANGE }}' == 'true' || '${{ steps.didPatchesChange.outputs.DID_STANDALONE_APP_PATCHES_CHANGE }}' == 'true' ]]; then | |
| echo "BUILD_TARGETS=[\"true\", \"false\"]" >> "$GITHUB_OUTPUT" | |
| elif [[ '${{ steps.didPatchesChange.outputs.DID_HYBRID_APP_PATCHES_CHANGE }}' == 'true' ]]; then | |
| echo "BUILD_TARGETS=[\"true\"]" >> "$GITHUB_OUTPUT" | |
| fi | |
| # Validates the actor and that they reviewed the PR before any token is used or untrusted App PR code is checked out. | |
| prep: | |
| uses: ./.github/workflows/validateBuildRequest.yml | |
| with: | |
| REVIEWED_CODE: ${{ inputs.reviewed_code || false }} | |
| secrets: | |
| OS_BOTIFY_COMMIT_TOKEN: ${{ secrets.OS_BOTIFY_COMMIT_TOKEN }} | |
| resolveRefs: | |
| name: Resolve build refs | |
| needs: [prep] | |
| uses: ./.github/workflows/resolveBuildRefs.yml | |
| with: | |
| APP_PULL_REQUEST_URL: ${{ inputs.app_pull_request_url }} | |
| MOBILE_EXPENSIFY_PULL_REQUEST_URL: ${{ inputs.mobile_expensify_pull_request_url }} | |
| secrets: | |
| OS_BOTIFY_TOKEN: ${{ secrets.OS_BOTIFY_TOKEN }} | |
| # Fail-fast: a manual dispatch that ticks neither variant yields no build targets. Without this the run | |
| # would be a confusing green no-op. On push an empty build_targets is a legitimate "nothing changed". | |
| assertHasTargets: | |
| needs: [verifyPatches] | |
| if: github.event_name == 'workflow_dispatch' && needs.verifyPatches.outputs.build_targets == '' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Fail when nothing was selected to build | |
| run: | | |
| echo "::error::No build targets selected — tick build_standalone and/or build_hybridapp." | |
| exit 1 | |
| ios: | |
| name: iOS | |
| needs: [verifyPatches, prep, resolveRefs] | |
| if: needs.verifyPatches.outputs.build_targets != '' | |
| uses: ./.github/workflows/publishReactNativeiOSArtifacts.yml | |
| with: | |
| build_targets: ${{ needs.verifyPatches.outputs.build_targets }} | |
| app_ref: ${{ needs.resolveRefs.outputs.APP_REF }} | |
| mobile_expensify_ref: ${{ needs.resolveRefs.outputs.MOBILE_EXPENSIFY_REF }} | |
| secrets: inherit | |
| android: | |
| name: Android | |
| needs: [verifyPatches, prep, resolveRefs] | |
| if: needs.verifyPatches.outputs.build_targets != '' | |
| uses: ./.github/workflows/publishReactNativeAndroidArtifacts.yml | |
| with: | |
| build_targets: ${{ needs.verifyPatches.outputs.build_targets }} | |
| app_ref: ${{ needs.resolveRefs.outputs.APP_REF }} | |
| mobile_expensify_ref: ${{ needs.resolveRefs.outputs.MOBILE_EXPENSIFY_REF }} | |
| secrets: inherit |