diff --git a/.github/actions/find-or-create-comment/action.yml b/.github/actions/find-or-create-comment/action.yml new file mode 100644 index 000000000..5d435abb0 --- /dev/null +++ b/.github/actions/find-or-create-comment/action.yml @@ -0,0 +1,41 @@ +# Creates a comment to show native preview build status +# Or finds the comment if it exists +# Exposes the comment id in env in either case +name: Find or create comment +description: 'Finds the comment of build status or create one. Outputs the comment id.' + +inputs: + github-token: + description: 'Github token' + required: true + +runs: + using: 'composite' + steps: + - name: Find or create comment + uses: actions/github-script@v6 + with: + github-token: ${{ inputs.github-token }} + script: | + const buildName = '${{ env.build-name }}'; + const commentMagicPrefix = '${{ env.comment-unique-magic-prefix }}'; + const comments = await github.rest.issues.listComments({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + }); + + const existingComment = comments.data.find(comment => comment.body.startsWith(commentMagicPrefix)); + + if (existingComment) { + core.exportVariable('comment_id', existingComment.id) + } else { + const commentBody = `${commentMagicPrefix}\nšŸš€ ${buildName} build has started... Please wait for the results! šŸ•`; + const { data: { id: commentId } } = await github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: commentBody + }); + core.exportVariable('comment_id', commentId) + } diff --git a/.github/actions/update-native-preview-build-status/action.yml b/.github/actions/update-native-preview-build-status/action.yml new file mode 100644 index 000000000..66c42cdbd --- /dev/null +++ b/.github/actions/update-native-preview-build-status/action.yml @@ -0,0 +1,39 @@ +name: Update build status +description: 'Updates build status comment with the build results' + +inputs: + github-token: + description: 'Github token' + required: true + build-outcome: + description: 'Build outcome' + required: true + +runs: + using: 'composite' + steps: + - name: Update build status + uses: actions/github-script@v6 + with: + github-token: ${{ inputs.github-token }} + script: | + const commentId = '${{ env.comment_id }}'; + const buildOutcome = '${{ inputs.build-outcome }}'; + const buildStatus = buildOutcome == 'success' ? 'completed' : 'failed'; + const buildName = '${{ env.build-name }}'; + const workflowUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`; + + let commentBody = `${{ env.comment-unique-magic-prefix }}\n${buildName} build ${buildStatus}!`; + + if (buildOutcome == 'success') { + commentBody += `\nYou can download the ${buildName} from the following link:\n${workflowUrl}#artifacts`; + } else { + commentBody += '\nPlease check the workflow logs for more details on the build failure.'; + } + + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: commentId, + body: commentBody + }); \ No newline at end of file diff --git a/.github/workflows/android-build-manual.yml b/.github/workflows/android-build-manual.yml deleted file mode 100644 index 3aa325482..000000000 --- a/.github/workflows/android-build-manual.yml +++ /dev/null @@ -1,53 +0,0 @@ -name: android build manual - -on: - workflow_dispatch: - inputs: - name: - description: 'Build manually' - default: 'World' - required: true - type: string - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - update: - name: EAS Android Preview Build - runs-on: ubuntu-latest - permissions: - contents: read - pull-requests: write - steps: - - name: Check for EXPO_TOKEN - run: | - if [ -z "${{ secrets.EXPO_TOKEN }}" ]; then - echo "You must provide an EXPO_TOKEN secret linked to this project's Expo account in this repo's secrets. Learn more: https://docs.expo.dev/eas-update/github-actions" - exit 1 - fi - - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Setup Node - uses: actions/setup-node@v3 - with: - node-version: 20.x - cache: yarn - - - name: Setup EAS - uses: expo/expo-github-action@v8 - with: - eas-version: latest - token: ${{ secrets.EXPO_TOKEN }} - - - name: Install dependencies - uses: ./.github/actions/install-deps - - - name: Create preview - uses: expo/expo-github-action/preview@v8 - with: - working-directory: apps/expo - command: eas build --platform android --profile preview \ No newline at end of file diff --git a/.github/workflows/android-preview-build-local.yml b/.github/workflows/android-preview-build-local.yml deleted file mode 100644 index a528f8e8d..000000000 --- a/.github/workflows/android-preview-build-local.yml +++ /dev/null @@ -1,138 +0,0 @@ -name: android-preview-build-local -on: - push: - branches: ['**'] - pull_request: - branches: ['**'] - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - - -jobs: - update: - name: EAS Android Build Local - runs-on: ubuntu-latest - permissions: - contents: read - pull-requests: write - steps: - - name: Check for EXPO_TOKEN - run: | - if [ -z "${{ secrets.EXPO_TOKEN }}" ]; then - echo "You must provide an EXPO_TOKEN secret linked to this project's Expo account in this repo's secrets." - exit 1 - fi - - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Setup Node - uses: actions/setup-node@v3 - with: - node-version: 20.x - cache: yarn - - - name: Set up JDK 17 - uses: actions/setup-java@v3 - with: - java-version: '17' - distribution: 'temurin' - - - name: Setup EAS - uses: expo/expo-github-action@v8 - with: - eas-version: latest - token: ${{ secrets.EXPO_TOKEN }} - - - name: Export secrets as environment variables - env: - JSON_SECRETS: '${{ toJSON(secrets) }}' - run: | - eval "$(jq -r 'to_entries | map("export \(.key)=\(.value|tostring)") | .[]' <<< "$JSON_SECRETS")" - - - name: Install dependencies - uses: ./.github/actions/install-deps - - - name: Prebuild - run: | - echo "Using Mapbox Token: $MAPBOX_DOWNLOADS_TOKEN" - export MAPBOX_DOWNLOADS_TOKEN=${{ secrets.MAPBOX_DOWNLOADS_TOKEN }} - yarn run prebuild:expo - - - name: Create preview - id: build - run: | - echo "Using Mapbox Token: $MAPBOX_DOWNLOADS_TOKEN" - export MAPBOX_DOWNLOADS_TOKEN=${{ secrets.MAPBOX_DOWNLOADS_TOKEN }} - eas build --platform android --profile preview --local - apk_path=$(find . -name '*.apk') - echo "APK Path: ${apk_path}" - echo "apk_path=${apk_path}" >> $GITHUB_ENV - working-directory: apps/expo - env: - DEBUG: 'true' - continue-on-error: true - - - name: Upload APK - uses: actions/upload-artifact@v3 - with: - name: android-apk - path: /home/runner/work/PackRat/PackRat/apps/expo/build-*.apk - - - name: Find or create comment - if: github.event_name == 'pull_request' - uses: actions/github-script@v6 - id: find_or_create_comment - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const commentIdentifier = ''; - const comments = await github.rest.issues.listComments({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - }); - - const existingComment = comments.data.find(comment => comment.body.startsWith(commentIdentifier)); - - if (existingComment) { - core.setOutput('comment_id', existingComment.id); - } else { - const commentBody = `${commentIdentifier}\nšŸš€ Android APK build started... Please wait for the results! šŸ•`; - const { data: { id: commentId } } = await github.rest.issues.createComment({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - body: commentBody - }); - core.setOutput('comment_id', commentId); - } - - - name: Update PR comment - if: always() && github.event_name == 'pull_request' - uses: actions/github-script@v6 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const commentIdentifier = ''; - const commentId = '${{ steps.find_or_create_comment.outputs.comment_id }}'; - const buildOutcome = '${{ steps.build.outcome }}'; - const buildStatus = buildOutcome == 'success' ? 'completed' : 'failed'; - const workflowUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`; - - let commentBody = `${commentIdentifier}\nAndroid APK build ${buildStatus}!`; - - if (buildOutcome == 'success') { - commentBody += `\nYou can download the APK file from the following link:\n${workflowUrl}#artifacts`; - } else { - commentBody += '\nPlease check the workflow logs for more details on the build failure.'; - } - - await github.rest.issues.updateComment({ - owner: context.repo.owner, - repo: context.repo.repo, - comment_id: commentId, - body: commentBody - }); diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index b21e90816..000000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,39 +0,0 @@ -name: android-build-apk-gradlew - -on: - push: - branches: ['**'] - pull_request: - branches: ['**'] - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - build-android-gradlew: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - - name: Setup Standard Environment - uses: ./.github/actions/setup-standard-environment - with: - expo-token: ${{ secrets.EXPO_TOKEN }} - - - name: Prebuild - run: | - echo "Using Mapbox Token: $MAPBOX_DOWNLOADS_TOKEN" - export MAPBOX_DOWNLOADS_TOKEN=${{ secrets.MAPBOX_DOWNLOADS_TOKEN }} - yarn run prebuild:expo - - - name: Build Android Release - run: | - cd apps/expo/android && ./gradlew assembleRelease - - - name: Upload Artifact - uses: actions/upload-artifact@v1 - - with: - name: app-release.apk - path: android/app/build/outputs/apk/release/ diff --git a/.github/workflows/eas-build-manual.yml b/.github/workflows/eas-build-manual.yml deleted file mode 100644 index 2e541c7b8..000000000 --- a/.github/workflows/eas-build-manual.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: EAS Build Manual - -on: - workflow_dispatch: - inputs: - platform: - description: 'Platform (android or ios)' - required: true - default: 'android' - type: choice - options: - - android - - ios - build-type: - description: 'Build type (preview or local)' - required: true - default: 'preview' - type: choice - options: - - preview - - local - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - - -jobs: - update: - name: EAS ${{ github.event.inputs.platform }} ${{ github.event.inputs.build-type }} Build - runs-on: ubuntu-latest - permissions: - contents: read - pull-requests: write - - steps: - - name: Setup EAS - uses: ./.github/actions/setup-eas - with: - expo-token: ${{ secrets.EXPO_TOKEN }} - node-version: '20.x' - - - name: Create build - uses: expo/expo-github-action/preview@v8 - with: - working-directory: apps/expo - command: | - eas build --platform ${{ github.event.inputs.platform }} --profile preview \ - ${{ github.event.inputs.build-type == 'local' && '--local' || '' }} \ No newline at end of file diff --git a/.github/workflows/eas-cloud.yml b/.github/workflows/eas-cloud.yml new file mode 100644 index 000000000..c9a0e63fe --- /dev/null +++ b/.github/workflows/eas-cloud.yml @@ -0,0 +1,36 @@ +# Native production pipeline +# Builds on EAS Cloud with auto submission +name: EAS Build & Submit + +on: + workflow_dispatch: + push: + branches: + - main + paths: + - 'packages/app/**' + - 'apps/expo/**' + - 'packages/ui/**' + - 'packages/shared-types/**' + - 'packages/config/**' + - 'packages/crosspath/**' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Setup EAS + uses: ./.github/actions/setup-eas + with: + expo-token: ${{ secrets.EXPO_TOKEN }} + + - name: Build on EAS + working-directory: ./apps/expo + run: eas build --platform all --profile production --non-interactive --no-wait --auto-submit \ No newline at end of file diff --git a/.github/workflows/expo.build.yml b/.github/workflows/eas-local.yml similarity index 55% rename from .github/workflows/expo.build.yml rename to .github/workflows/eas-local.yml index ea9210d73..fe2803618 100644 --- a/.github/workflows/expo.build.yml +++ b/.github/workflows/eas-local.yml @@ -1,10 +1,25 @@ name: EAS Local Build on: + workflow_dispatch: push: branches: [ "**" ] + paths: + - 'packages/app/**' + - 'apps/expo/**' + - 'packages/ui/**' + - 'packages/shared-types/**' + - 'packages/config/**' + - 'packages/crosspath/**' pull_request: branches: [ "**" ] + paths: + - 'packages/app/**' + - 'apps/expo/**' + - 'packages/ui/**' + - 'packages/shared-types/**' + - 'packages/config/**' + - 'packages/crosspath/**' concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -19,10 +34,23 @@ env: # Define a shared environment variable for android and ios build. jobs: build-android: runs-on: ubuntu-latest + + # will be used in find_or_create_comment + # and update_native_build_preview action + env: + build-name: Android APK + comment-unique-magic-prefix: '' + steps: - name: Checkout code uses: actions/checkout@v2 + - name: Find or create comment for build status + if: github.event_name == 'pull_request' + uses: ./.github/actions/find-or-create-comment + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + - name: Setup Standard Environment uses: ./.github/actions/setup-standard-environment with: @@ -35,6 +63,7 @@ jobs: distribution: 'adopt' - name: Run Local Build for Android + id: build working-directory: ./apps/expo run: | eas build --profile preview --platform android --local --non-interactive @@ -46,13 +75,32 @@ jobs: with: name: android-apk path: /home/runner/work/PackRat/PackRat/apps/expo/build-*.apk + + - name: Update build status + if: always() && github.event_name == 'pull_request' + uses: ./.github/actions/update-native-preview-build-status + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + build-outcome: ${{ steps.build.outcome }} + build-ios: runs-on: macos-latest + + env: + build-name: iOS IPA + comment-unique-magic-prefix: '' + steps: - name: Checkout code uses: actions/checkout@v2 + - name: Find or create comment for build status + if: github.event_name == 'pull_request' + uses: ./.github/actions/find-or-create-comment + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + - name: Setup Standard Environment uses: ./.github/actions/setup-standard-environment with: @@ -64,6 +112,7 @@ jobs: # xcode-version: latest-stable - name: Run Local Build for iOS + id: build working-directory: ./apps/expo run: | export MAPBOX_DOWNLOADS_TOKEN=${{ secrets.MAPBOX_DOWNLOADS_TOKEN }} @@ -75,4 +124,12 @@ jobs: uses: actions/upload-artifact@v3 with: name: ios-ipa - path: /home/runner/work/PackRat/PackRat/apps/expo/build-*.ipa + path: /Users/runner/work/PackRat/PackRat/apps/expo/build-*.ipa + + - name: Update build status + if: always() && github.event_name == 'pull_request' + uses: ./.github/actions/update-native-preview-build-status + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + build-outcome: ${{ steps.build.outcome }} + diff --git a/.github/workflows/ios-build-local.yml b/.github/workflows/ios-build-local.yml deleted file mode 100644 index 5e6254dcc..000000000 --- a/.github/workflows/ios-build-local.yml +++ /dev/null @@ -1,116 +0,0 @@ -name: iOS App Release Build - -on: - push: - branches: ['**'] - pull_request: - branches: ['**'] - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - - -jobs: - build: - runs-on: macos-latest - - steps: - - name: Setup repo - uses: actions/checkout@v4 - - - name: Setup Node - uses: actions/setup-node@v3 - with: - node-version: 18.x - cache: 'yarn' - - - name: Setup EAS - uses: expo/expo-github-action@v8 - with: - eas-version: latest - token: ${{ secrets.EXPO_TOKEN }} - - - name: Install dependencies - run: yarn install - - - name: Setup environment variables - run: | - echo "MAPBOX_DOWNLOADS_TOKEN=$MAPBOX_DOWNLOADS_TOKEN" >> $GITHUB_ENV - - - name: Prebuild - run: | - echo "Using Mapbox Token: $MAPBOX_DOWNLOADS_TOKEN" - export MAPBOX_DOWNLOADS_TOKEN=${{ secrets.MAPBOX_DOWNLOADS_TOKEN }} - yarn run prebuild:expo - - - name: Build iOS app - id: build - run: | - echo "Using Mapbox Token: $MAPBOX_DOWNLOADS_TOKEN" - export MAPBOX_DOWNLOADS_TOKEN=${{ secrets.MAPBOX_DOWNLOADS_TOKEN }} - eas build --platform ios --profile preview --local --non-interactive --output ${{ github.workspace }}/app-release.ipa - env: - DEBUG: 'true' - continue-on-error: true - - - name: Upload IPA artifact - uses: actions/upload-artifact@v3 - with: - name: app-release - path: ${{ github.workspace }}/app-release.ipa - - - name: Find or create comment - if: github.event_name == 'pull_request' - uses: actions/github-script@v6 - id: find_or_create_comment - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const commentIdentifier = ''; - const comments = await github.rest.issues.listComments({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - }); - - const existingComment = comments.data.find(comment => comment.body.startsWith(commentIdentifier)); - - if (existingComment) { - core.setOutput('comment_id', existingComment.id); - } else { - const commentBody = `${commentIdentifier}\nšŸš€ iOS app build started... Please wait for the results! šŸ•`; - const { data: { id: commentId } } = await github.rest.issues.createComment({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - body: commentBody - }); - core.setOutput('comment_id', commentId); - } - - name: Update PR comment - if: always() && github.event_name == 'pull_request' - uses: actions/github-script@v6 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const commentIdentifier = ''; - const commentId = '${{ steps.find_or_create_comment.outputs.comment_id }}'; - const buildOutcome = '${{ steps.build.outcome }}'; - const buildStatus = buildOutcome == 'success' ? 'completed' : 'failed'; - const workflowUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`; - - let commentBody = `${commentIdentifier}\niOS app build ${buildStatus}!`; - - if (buildOutcome == 'success') { - commentBody += `\nYou can download the IPA file from the following link:\n${workflowUrl}#artifacts`; - } else { - commentBody += '\nPlease check the workflow logs for more details on the build failure.'; - } - - await github.rest.issues.updateComment({ - owner: context.repo.owner, - repo: context.repo.repo, - comment_id: commentId, - body: commentBody - });