From f830338640973b62e2997c2a531948852f6254b4 Mon Sep 17 00:00:00 2001 From: Mattermost Build Date: Wed, 12 Mar 2025 04:41:02 +0200 Subject: [PATCH] Automated cherry pick of #8646 (#8662) * MM-62896 Keyboard blocks input (#8646) * WIP * fix keyboard blocking text input for interactive dialog * do not use extra keyboard and windowSoftInputMode:adjustNothing on Android 10 and under --------- Co-authored-by: Devin Binnie (cherry picked from commit 1c8770c74d0fc976e60293a07968e295a068a4f1) * Bump the github-actions-updates group across 5 directories with 6 updates (#8613) Bumps the github-actions-updates group with 1 update in the /.github/actions/prepare-android-build directory: [actions/checkout](https://github.com/actions/checkout). Bumps the github-actions-updates group with 1 update in the /.github/actions/prepare-ios-build directory: [actions/cache](https://github.com/actions/cache). Bumps the github-actions-updates group with 2 updates in the /.github/actions/prepare-mobile-build directory: [actions/cache](https://github.com/actions/cache) and [ruby/setup-ruby](https://github.com/ruby/setup-ruby). Bumps the github-actions-updates group with 2 updates in the /.github/actions/prepare-node-deps directory: [actions/cache](https://github.com/actions/cache) and [actions/setup-node](https://github.com/actions/setup-node). Bumps the github-actions-updates group with 4 updates in the /.github/workflows directory: [actions/checkout](https://github.com/actions/checkout), [ruby/setup-ruby](https://github.com/ruby/setup-ruby), [actions/upload-artifact](https://github.com/actions/upload-artifact) and [github/codeql-action](https://github.com/github/codeql-action). Updates `actions/checkout` from 3.3.0 to 4.2.2 - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/ac593985615ec2ede58e132d2e21d2b1cbd6127c...11bd71901bbe5b1630ceea73d27597364c9af683) Updates `actions/cache` from 4.0.2 to 4.2.1 - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/0c45773b623bea8c8e75f6c82b208c3cf94ea4f9...0c907a75c2c80ebcb7f088228285e798b750cf8f) Updates `actions/cache` from 4.0.2 to 4.2.1 - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/0c45773b623bea8c8e75f6c82b208c3cf94ea4f9...0c907a75c2c80ebcb7f088228285e798b750cf8f) Updates `ruby/setup-ruby` from 1.180.0 to 1.221.0 - [Release notes](https://github.com/ruby/setup-ruby/releases) - [Changelog](https://github.com/ruby/setup-ruby/blob/master/release.rb) - [Commits](https://github.com/ruby/setup-ruby/compare/ff740bc00a01b3a50fffc55a1071b1060eeae9dc...32110d4e311bd8996b2a82bf2a43b714ccc91777) Updates `actions/cache` from 4.0.2 to 4.2.1 - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/0c45773b623bea8c8e75f6c82b208c3cf94ea4f9...0c907a75c2c80ebcb7f088228285e798b750cf8f) Updates `actions/setup-node` from 4.0.2 to 4.2.0 - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/60edb5dd545a775178f52524783378180af0d1f8...1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a) Updates `actions/checkout` from 3 to 4 - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/ac593985615ec2ede58e132d2e21d2b1cbd6127c...11bd71901bbe5b1630ceea73d27597364c9af683) Updates `ruby/setup-ruby` from 1.180.0 to 1.221.0 - [Release notes](https://github.com/ruby/setup-ruby/releases) - [Changelog](https://github.com/ruby/setup-ruby/blob/master/release.rb) - [Commits](https://github.com/ruby/setup-ruby/compare/ff740bc00a01b3a50fffc55a1071b1060eeae9dc...32110d4e311bd8996b2a82bf2a43b714ccc91777) Updates `actions/upload-artifact` from 4.3.1 to 4.6.0 - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v4.3.1...65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08) Updates `github/codeql-action` from 2 to 3 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major dependency-group: github-actions-updates - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions-updates - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions-updates - dependency-name: ruby/setup-ruby dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions-updates - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions-updates - dependency-name: actions/setup-node dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions-updates - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major dependency-group: github-actions-updates - dependency-name: ruby/setup-ruby dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions-updates - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions-updates - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-major dependency-group: github-actions-updates ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --------- Signed-off-by: dependabot[bot] Co-authored-by: Elias Nahum Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../actions/prepare-android-build/action.yaml | 2 +- .github/actions/prepare-ios-build/action.yaml | 2 +- .../actions/prepare-mobile-build/action.yaml | 4 +- .github/actions/prepare-node-deps/action.yaml | 4 +- .github/workflows/build-android-beta.yml | 6 +- .github/workflows/build-android-release.yml | 6 +- .github/workflows/build-ios-beta.yml | 10 +- .github/workflows/build-ios-release.yml | 10 +- .github/workflows/build-pr.yml | 10 +- .github/workflows/ci.yml | 2 +- .github/workflows/codeql-analysis.yml | 8 +- .../compatibility-matrix-testing.yml | 8 +- .github/workflows/e2e-android-template.yml | 295 ++++++++++++++++++ .github/workflows/e2e-detox-pr.yml | 46 ++- .github/workflows/e2e-detox-release.yml | 54 +++- .github/workflows/e2e-detox-scheduled.yml | 54 +++- .github/workflows/e2e-detox-template.yml | 10 +- .github/workflows/github-release.yml | 14 +- app/context/extra_keyboard/index.tsx | 36 ++- app/hooks/device.ts | 9 + app/screens/interactive_dialog/index.tsx | 27 +- .../mattermost/rnutils/RNUtilsModuleImpl.kt | 7 + ...ive-keyboard-aware-scroll-view+0.9.5.patch | 74 +++++ 23 files changed, 635 insertions(+), 63 deletions(-) create mode 100644 .github/workflows/e2e-android-template.yml create mode 100644 patches/react-native-keyboard-aware-scroll-view+0.9.5.patch diff --git a/.github/actions/prepare-android-build/action.yaml b/.github/actions/prepare-android-build/action.yaml index cb0650869..5c534d3eb 100644 --- a/.github/actions/prepare-android-build/action.yaml +++ b/.github/actions/prepare-android-build/action.yaml @@ -27,7 +27,7 @@ runs: - name: ci/checkout-private-repo if: ${{ inputs.sign == 'true' }} - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: repository: mattermost/mattermost-mobile-private token: ${{ env.MATTERMOST_BUILD_GH_TOKEN }} diff --git a/.github/actions/prepare-ios-build/action.yaml b/.github/actions/prepare-ios-build/action.yaml index 57d8f026a..3b3d74c0e 100644 --- a/.github/actions/prepare-ios-build/action.yaml +++ b/.github/actions/prepare-ios-build/action.yaml @@ -16,7 +16,7 @@ runs: echo "::endgroup::" - name: Cache Pods - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 + uses: actions/cache@0c907a75c2c80ebcb7f088228285e798b750cf8f # v4.2.1 with: path: Pods key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }} diff --git a/.github/actions/prepare-mobile-build/action.yaml b/.github/actions/prepare-mobile-build/action.yaml index cf0031450..6bd6f7406 100644 --- a/.github/actions/prepare-mobile-build/action.yaml +++ b/.github/actions/prepare-mobile-build/action.yaml @@ -5,7 +5,7 @@ runs: using: composite steps: # The required ruby version is mentioned in '.ruby-version' - - uses: ruby/setup-ruby@ff740bc00a01b3a50fffc55a1071b1060eeae9dc # v1.180.0 + - uses: ruby/setup-ruby@32110d4e311bd8996b2a82bf2a43b714ccc91777 # v1.221.0 - name: ci/setup-fastlane-dependencies shell: bash @@ -16,7 +16,7 @@ runs: working-directory: ./fastlane - name: Cache Ruby gems - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 + uses: actions/cache@0c907a75c2c80ebcb7f088228285e798b750cf8f # v4.2.1 with: path: vendor/bundle key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }} diff --git a/.github/actions/prepare-node-deps/action.yaml b/.github/actions/prepare-node-deps/action.yaml index c50ce3bb5..187982588 100644 --- a/.github/actions/prepare-node-deps/action.yaml +++ b/.github/actions/prepare-node-deps/action.yaml @@ -5,7 +5,7 @@ runs: using: composite steps: - name: ci/setup-node - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0 with: node-version-file: ".nvmrc" cache: "npm" @@ -22,7 +22,7 @@ runs: echo "::endgroup::" - name: Cache Node.js modules - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 + uses: actions/cache@0c907a75c2c80ebcb7f088228285e798b750cf8f # v4.2.1 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} diff --git a/.github/workflows/build-android-beta.yml b/.github/workflows/build-android-beta.yml index e24d6c663..d7a720e7d 100644 --- a/.github/workflows/build-android-beta.yml +++ b/.github/workflows/build-android-beta.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-22.04 steps: - name: ci/checkout-repo - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: ci/test uses: ./.github/actions/test @@ -26,7 +26,7 @@ jobs: - test steps: - name: ci/checkout-repo - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: ci/prepare-android-build uses: ./.github/actions/prepare-android-build @@ -54,7 +54,7 @@ jobs: working-directory: ./fastlane - name: ci/upload-android-beta-build - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: name: android-build-beta-${{ github.run_id }} path: "*.apk" diff --git a/.github/workflows/build-android-release.yml b/.github/workflows/build-android-release.yml index cfdefb84b..2fe85f2bc 100644 --- a/.github/workflows/build-android-release.yml +++ b/.github/workflows/build-android-release.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-22.04 steps: - name: ci/checkout-repo - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: ci/test uses: ./.github/actions/test @@ -26,7 +26,7 @@ jobs: - test steps: - name: ci/checkout-repo - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: ci/prepare-android-build uses: ./.github/actions/prepare-android-build @@ -54,7 +54,7 @@ jobs: working-directory: ./fastlane - name: ci/upload-android-release-build - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: name: android-build-release-${{ github.run_id }} path: "*.apk" diff --git a/.github/workflows/build-ios-beta.yml b/.github/workflows/build-ios-beta.yml index da4d289bd..4781ba5d4 100644 --- a/.github/workflows/build-ios-beta.yml +++ b/.github/workflows/build-ios-beta.yml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-22.04 steps: - name: ci/checkout-repo - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: ci/test uses: ./.github/actions/test @@ -28,7 +28,7 @@ jobs: - test steps: - name: ci/checkout-repo - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: ci/prepare-ios-build uses: ./.github/actions/prepare-ios-build @@ -44,7 +44,7 @@ jobs: working-directory: ./fastlane - name: ci/upload-ios-pr-simulator - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: name: ios-build-simulator-${{ github.run_id }} path: Mattermost-simulator-x86_64.app.zip @@ -56,7 +56,7 @@ jobs: - test steps: - name: ci/checkout-repo - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: ci/output-ssh-private-key shell: bash @@ -93,7 +93,7 @@ jobs: working-directory: ./fastlane - name: ci/upload-ios-beta-build - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: name: ios-build-beta-${{ github.run_id }} path: "*.ipa" diff --git a/.github/workflows/build-ios-release.yml b/.github/workflows/build-ios-release.yml index ad1009e08..4c596491e 100644 --- a/.github/workflows/build-ios-release.yml +++ b/.github/workflows/build-ios-release.yml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-22.04 steps: - name: ci/checkout-repo - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: ci/test uses: ./.github/actions/test @@ -28,7 +28,7 @@ jobs: - test steps: - name: ci/checkout-repo - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: ci/prepare-ios-build uses: ./.github/actions/prepare-ios-build @@ -65,7 +65,7 @@ jobs: working-directory: ./fastlane - name: ci/upload-ios-release-build - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: name: ios-build-release-${{ github.run_id }} path: "*.ipa" @@ -77,7 +77,7 @@ jobs: - test steps: - name: ci/checkout-repo - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: ci/prepare-ios-build uses: ./.github/actions/prepare-ios-build @@ -93,7 +93,7 @@ jobs: working-directory: ./fastlane - name: ci/upload-ios-pr-simulator - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: name: ios-build-simulator-${{ github.run_id }} path: Mattermost-simulator-x86_64.app.zip diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index 98757478d..177a22dec 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -15,7 +15,7 @@ jobs: if: ${{ github.event.label.name == 'Build Apps for PR' || github.event.label.name == 'Build App for iOS' || github.event.label.name == 'Build App for Android' }} steps: - name: ci/checkout-repo - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: ref: ${{ github.event.pull_request.head.sha }} - name: ci/test @@ -28,7 +28,7 @@ jobs: - test steps: - name: ci/checkout-repo - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: ref: ${{ github.event.pull_request.head.sha }} @@ -60,7 +60,7 @@ jobs: working-directory: ./fastlane - name: ci/upload-ios-pr-build - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: name: ios-build-pr-${{ github.run_id }} path: "*.ipa" @@ -72,7 +72,7 @@ jobs: - test steps: - name: ci/checkout-repo - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: ref: ${{ github.event.pull_request.head.sha }} @@ -94,7 +94,7 @@ jobs: working-directory: ./fastlane - name: ci/upload-android-pr-build - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: name: android-build-pr-${{ github.run_id }} path: "*.apk" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b9cecf7ec..4a4e84af4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,6 +16,6 @@ jobs: runs-on: ubuntu-22.04 steps: - name: ci/checkout-repo - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: ci/test uses: ./.github/actions/test diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index c49e51154..8fe7c9859 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -26,17 +26,17 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} config-file: ./.github/codeql/codeql-config.yml # Autobuild attempts to build any compiled languages - name: Autobuild - uses: github/codeql-action/autobuild@v2 + uses: github/codeql-action/autobuild@v3 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/compatibility-matrix-testing.yml b/.github/workflows/compatibility-matrix-testing.yml index 7b7cac9e2..199369498 100644 --- a/.github/workflows/compatibility-matrix-testing.yml +++ b/.github/workflows/compatibility-matrix-testing.yml @@ -20,7 +20,7 @@ jobs: run: echo '${{ inputs.CMT_MATRIX }}' > instance-details.json - name: cmt/upload-instance-details - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: name: instance-details.json path: instance-details.json @@ -32,7 +32,7 @@ jobs: MOBILE_SHA: ${{ steps.repo.outputs.MOBILE_SHA }} steps: - name: cmt/checkout-mobile - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: ref: ${{ inputs.MOBILE_VERSION }} @@ -74,7 +74,7 @@ jobs: - update-initial-status steps: - name: Checkout Repository - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: ref: ${{ inputs.MOBILE_VERSION }} @@ -91,7 +91,7 @@ jobs: working-directory: ./fastlane - name: Upload iOS Simulator Build - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: name: ios-build-simulator-${{ github.run_id }} path: Mattermost-simulator-x86_64.app.zip diff --git a/.github/workflows/e2e-android-template.yml b/.github/workflows/e2e-android-template.yml new file mode 100644 index 000000000..9f1fd7c7b --- /dev/null +++ b/.github/workflows/e2e-android-template.yml @@ -0,0 +1,295 @@ +name: Detox Android E2E Tests Template + +on: + workflow_call: + inputs: + MM_TEST_SERVER_URL: + description: "The test server URL" + required: false + type: string + MM_TEST_USER_NAME: + description: "The admin username of the test instance" + required: false + type: string + MM_TEST_PASSWORD: + description: "The admin password of the test instance" + required: false + type: string + MOBILE_VERSION: + description: "The mobile version to test" + required: false + default: ${{ github.head_ref || github.ref }} + type: string + run-android-tests: + description: "Run Android tests" + required: true + type: boolean + run-type: + type: string + required: false + default: "PR" + testcase_failure_fatal: + description: "Should failures be considered fatal" + required: false + type: boolean + default: false + record_tests_in_zephyr: + description: "Record test results in Zephyr, typically for nightly and release runs" + required: false + type: string + default: 'false' + low_bandwidth_mode: + description: "Enable low bandwidth mode" + required: false + type: boolean + default: false + android_avd_name: + description: "Android Emulator name" + required: false + type: string + default: "detox_pixel_4_xl" + android_api_level: + description: "Android API level" + required: false + type: string + default: "33" + outputs: + STATUS: + value: ${{ jobs.generate-report.outputs.STATUS }} + TARGET_URL: + value: ${{ jobs.generate-report.outputs.TARGET_URL }} + FAILURES: + value: ${{ jobs.generate-report.outputs.FAILURES }} + +env: + AWS_REGION: "us-east-1" + ADMIN_EMAIL: ${{ secrets.MM_MOBILE_E2E_ADMIN_EMAIL }} + ADMIN_USERNAME: ${{ secrets.MM_MOBILE_E2E_ADMIN_USERNAME }} + ADMIN_PASSWORD: ${{ secrets.MM_MOBILE_E2E_ADMIN_PASSWORD }} + BRANCH: ${{ github.event_name == 'pull_request' && github.head_ref || github.ref_name }} + COMMIT_HASH: ${{ github.sha }} + DEVICE_NAME: ${{ inputs.android_avd_name }} # This is needed to split tests as same code is used in iOS job + DEVICE_OS_VERSION: ${{ inputs.android_api_level }} + DETOX_AWS_S3_BUCKET: "mattermost-detox-report" + HEADLESS: "true" + TYPE: ${{ inputs.run-type }} + PULL_REQUEST: "https://github.com/mattermost/mattermost-mobile/pull/${{ github.event.number }}" + SITE_1_URL: ${{ inputs.MM_TEST_SERVER_URL || 'https://mobile-e2e-site-1.test.mattermost.cloud' }} + SITE_2_URL: "https://mobile-e2e-site-2.test.mattermost.cloud" + SITE_3_URL: "https://mobile-e2e-site-3.test.mattermost.cloud" + ZEPHYR_ENABLE: ${{ inputs.record_tests_in_zephyr }} + JIRA_PROJECT_KEY: "MM" + ZEPHYR_API_KEY: ${{ secrets.MM_MOBILE_E2E_ZEPHYR_API_KEY }} + ZEPHYR_FOLDER_ID: "3233873" + TEST_CYCLE_LINK_PREFIX: ${{ secrets.MM_MOBILE_E2E_TEST_CYCLE_LINK_PREFIX }} + WEBHOOK_URL: ${{ secrets.MM_MOBILE_E2E_WEBHOOK_URL }} + FAILURE_MESSAGE: "Something has failed" + IOS: "false" + RUNNING_E2E: "true" + AVD_NAME: ${{ inputs.android_avd_name }} + SDK_VERSION: ${{ inputs.android_api_level }} + +jobs: + generate-specs: + runs-on: ubuntu-22.04 + outputs: + specs: ${{ steps.generate-specs.outputs.specs }} + build_id: ${{ steps.resolve-device.outputs.BUILD_ID }} + mobile_sha: ${{ steps.resolve-device.outputs.MOBILE_SHA }} + mobile_ref: ${{ steps.resolve-device.outputs.MOBILE_REF }} + workflow_hash: ${{ steps.resolve-device.outputs.WORKFLOW_HASH }} + steps: + - name: Checkout Repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + ref: ${{ inputs.MOBILE_VERSION }} + + - name: Set Build ID + id: resolve-device + run: | + BUILD_ID="${{ github.run_id }}-${{ env.AVD_NAME }}-${{ env.SDK_VERSION}}" + WORKFLOW_HASH=$(tr -dc a-z0-9 > ${GITHUB_OUTPUT} + + echo "BUILD_ID=$(echo ${BUILD_ID} | sed 's/ /_/g')" >> ${GITHUB_OUTPUT} + echo "MOBILE_SHA=$(git rev-parse HEAD)" >> ${GITHUB_OUTPUT} + echo "MOBILE_REF=$(git rev-parse --abbrev-ref HEAD)" >> ${GITHUB_OUTPUT} + + - name: Generate Test Specs + id: generate-specs + uses: ./.github/actions/generate-specs + with: + parallelism: 10 + search_path: detox/e2e/test + device_name: ${{ env.AVD_NAME }} + device_os_version: ${{ env.SDK_VERSION }} + + e2e-android: + name: android-detox-e2e-${{ matrix.runId }}-${{ matrix.deviceName }}-${{ matrix.deviceOsVersion }} + runs-on: ubuntu-latest-8-cores + continue-on-error: true + timeout-minutes: 150 + env: + ANDROID_HOME: /usr/local/lib/android/sdk + ANDROID_SDK_ROOT: /usr/local/lib/android/sdk + needs: + - generate-specs + strategy: + fail-fast: false + matrix: ${{ fromJSON(needs.generate-specs.outputs.specs) }} + steps: + - name: Checkout Repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + ref: ${{ inputs.MOBILE_VERSION }} + + - name: Install Dependencies + run: | + sudo apt-get update + sudo apt-get install -y libpulse0 + sudo apt-get install -y scrot ffmpeg xvfb + + - name: Enable KVM + run: | + echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules + sudo udevadm control --reload-rules + sudo udevadm trigger --name-match=kvm + + - name: Prepare Android Build + uses: ./.github/actions/prepare-android-build + env: + STORE_FILE: "${{ secrets.MM_MOBILE_STORE_FILE }}" + STORE_ALIAS: "${{ secrets.MM_MOBILE_STORE_ALIAS }}" + STORE_PASSWORD: "${{ secrets.MM_MOBILE_STORE_PASSWORD }}" + MATTERMOST_BUILD_GH_TOKEN: "${{ secrets.MATTERMOST_BUILD_GH_TOKEN }}" + + - name: Install Detox Dependencies + run: | + cd detox + npm install + + - name: Create destination path + run: mkdir -p android/app/build + + - name: Download APK artifact + uses: actions/download-artifact@v4 + with: + name: android-build-files-${{ github.run_id }} + path: android/app/build + + - name: Set up Android SDK + run: | + export ANDROID_HOME=/usr/local/lib/android/sdk + export PATH=$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/emulator:$ANDROID_HOME/tools/bin:$ANDROID_HOME/platform-tools:$PATH + echo "ANDROID_HOME=$ANDROID_HOME" >> $GITHUB_ENV + echo "PATH=$PATH" >> $GITHUB_ENV + + - name: Start Xvfb + run: | + Xvfb :99 -screen 0 1920x1080x24 & + export DISPLAY=:99 + echo "DISPLAY=:99" >> $GITHUB_ENV + + - name: Accept Android licenses + run: | + yes | sdkmanager --licenses || true + + - name: Install Android system image + run: | + sdkmanager "system-images;android-34;default;x86_64" + sdkmanager "platform-tools" "emulator" + + - name: Create and run Android Emulator + run: | + cd detox + chmod +x ./create_android_emulator.sh + ./create_android_emulator.sh ${{ env.SDK_VERSION }} ${{ env.AVD_NAME }} ${{ matrix.specs }} + continue-on-error: true # We want to run all the tests + + - name: Upload Android Test Report + if: always() + uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 + with: + name: android-results-${{ needs.generate-specs.outputs.workflow_hash }}-${{ matrix.runId }} + path: detox/artifacts/ + + generate-report: + runs-on: ubuntu-22.04 + needs: + - generate-specs + - e2e-android + outputs: + TARGET_URL: ${{ steps.set-url.outputs.TARGET_URL }} + STATUS: ${{ steps.determine-status.outputs.STATUS }} + FAILURES: ${{ steps.summary.outputs.FAILURES }} + steps: + - name: Checkout Repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + ref: ${{ inputs.MOBILE_VERSION }} + + - name: ci/prepare-node-deps + uses: ./.github/actions/prepare-node-deps + + - name: Download Android Artifacts + uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 + with: + path: detox/artifacts/ + pattern: android-results-${{ needs.generate-specs.outputs.workflow_hash }}-* + continue-on-error: true + + - name: Generate Report Path + id: s3 + run: | + path="${{ needs.generate-specs.outputs.build_id }}-${{ needs.generate-specs.outputs.mobile_sha }}-${{ needs.generate-specs.outputs.mobile_ref }}" + echo "path=$(echo "${path}" | sed 's/\./-/g')" >> ${GITHUB_OUTPUT} + + - name: Save report Detox Dependencies + id: report-link + run: | + cd detox + npm ci + npm run e2e:save-report + env: + DETOX_AWS_ACCESS_KEY_ID: ${{ secrets.MM_MOBILE_DETOX_AWS_ACCESS_KEY_ID }} + DETOX_AWS_SECRET_ACCESS_KEY: ${{ secrets.MM_MOBILE_DETOX_AWS_SECRET_ACCESS_KEY }} + BUILD_ID: ${{ needs.generate-specs.outputs.build_id }} + REPORT_PATH: ${{ steps.s3.outputs.path }} + ## These are needed for the MM Webhook report + COMMIT_HASH: ${{ needs.generate-specs.outputs.mobile_sha }} + BRANCH: ${{ needs.generate-specs.outputs.mobile_ref }} + + - name: Calculate failures + id: summary + run: | + echo "FAILURES=$(cat detox/artifacts/summary.json | jq .stats.failures)" >> ${GITHUB_OUTPUT} + echo "PASSES=$(cat detox/artifacts/summary.json | jq .stats.passes)" >> ${GITHUB_OUTPUT} + echo "SKIPPED=$(cat detox/artifacts/summary.json | jq .stats.skipped)" >> ${GITHUB_OUTPUT} + echo "TOTAL=$(cat detox/artifacts/summary.json | jq .stats.tests)" >> ${GITHUB_OUTPUT} + echo "ERRORS=$(cat detox/artifacts/summary.json | jq .stats.errors)" >> ${GITHUB_OUTPUT} + echo "PERCENTAGE=$(cat detox/artifacts/summary.json | jq .stats.passPercent)" >> ${GITHUB_OUTPUT} + + - name: Set Target URL + id: set-url + run: | + echo "TARGET_URL=https://${{ env.DETOX_AWS_S3_BUCKET }}.s3.amazonaws.com/${{ steps.s3.outputs.path }}/jest-stare/android-report.html" >> ${GITHUB_OUTPUT} + + - name: Determine Status + id: determine-status + run: | + if [[ ${{ steps.summary.outputs.failures }} -gt 0 && "${{ inputs.testcase_failure_fatal }}" == "true" ]]; then + echo "STATUS=failure" >> ${GITHUB_OUTPUT} + else + echo "STATUS=success" >> ${GITHUB_OUTPUT} + fi + + - name: Generate Summary + run: | + echo "| Tests | Passed :white_check_mark: | Failed :x: | Skipped :fast_forward: | Errors :warning: | " >> ${GITHUB_STEP_SUMMARY} + echo "|:---:|:---:|:---:|:---:|:---:|" >> ${GITHUB_STEP_SUMMARY} + echo "| ${{ steps.summary.outputs.TOTAL }} | ${{ steps.summary.outputs.PASSES }} | ${{ steps.summary.outputs.FAILURES }} | ${{ steps.summary.outputs.SKIPPED }} | ${{ steps.summary.outputs.ERRORS }} |" >> ${GITHUB_STEP_SUMMARY} + echo "" >> ${GITHUB_STEP_SUMMARY} + echo "You can check the full report [here](${{ steps.set-url.outputs.TARGET_URL }})" >> ${GITHUB_STEP_SUMMARY} + echo "There was **${{ steps.summary.outputs.PERCENTAGE }}%** success rate." >> ${GITHUB_STEP_SUMMARY} diff --git a/.github/workflows/e2e-detox-pr.yml b/.github/workflows/e2e-detox-pr.yml index 41429ecb2..bc9e241a7 100644 --- a/.github/workflows/e2e-detox-pr.yml +++ b/.github/workflows/e2e-detox-pr.yml @@ -34,7 +34,7 @@ jobs: - update-initial-status steps: - name: Checkout Repository - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Prepare iOS Build uses: ./.github/actions/prepare-ios-build @@ -49,11 +49,53 @@ jobs: working-directory: ./fastlane - name: Upload iOS Simulator Build - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: name: ios-build-simulator-${{ github.run_id }} path: Mattermost-simulator-x86_64.app.zip + build-android-apk: + runs-on: ubuntu-latest-8-cores + if: contains(github.event.label.name, 'E2E Android tests for PR') + needs: + - update-initial-status-android + env: + ORG_GRADLE_PROJECT_jvmargs: -Xmx8g + steps: + - name: Prune Docker to free up space + run: docker system prune -af + + - name: Remove npm Temporary Files + run: | + rm -rf ~/.npm/_cacache + + - name: Checkout Repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Prepare Android Build + uses: ./.github/actions/prepare-android-build + env: + STORE_FILE: "${{ secrets.MM_MOBILE_STORE_FILE }}" + STORE_ALIAS: "${{ secrets.MM_MOBILE_STORE_ALIAS }}" + STORE_PASSWORD: "${{ secrets.MM_MOBILE_STORE_PASSWORD }}" + MATTERMOST_BUILD_GH_TOKEN: "${{ secrets.MATTERMOST_BUILD_GH_TOKEN }}" + + - name: Install Dependencies + run: sudo apt-get clean && sudo apt-get update && sudo apt-get install -y default-jdk + + - name: Detox build + run: | + cd detox + npm install + npm install -g detox-cli + npm run e2e:android-build + + - name: Upload Android Build + uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 + with: + name: android-build-files-${{ github.run_id }} + path: "android/app/build/**/*" + run-ios-tests-on-pr: name: iOS Mobile Tests on PR uses: ./.github/workflows/e2e-detox-template.yml diff --git a/.github/workflows/e2e-detox-release.yml b/.github/workflows/e2e-detox-release.yml index bb604de60..0b074c8c8 100644 --- a/.github/workflows/e2e-detox-release.yml +++ b/.github/workflows/e2e-detox-release.yml @@ -25,7 +25,7 @@ jobs: - update-initial-status steps: - name: Checkout Repository - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Prepare iOS Build uses: ./.github/actions/prepare-ios-build @@ -40,11 +40,61 @@ jobs: working-directory: ./fastlane - name: Upload iOS Simulator Build - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: name: ios-build-simulator-${{ github.run_id }} path: Mattermost-simulator-x86_64.app.zip + build-android-apk: + runs-on: ubuntu-latest-8-cores + needs: + - update-initial-status-android + env: + ORG_GRADLE_PROJECT_jvmargs: -Xmx8g + steps: + - name: Prune Docker to free up space + run: docker system prune -af + + - name: Remove npm Temporary Files + run: | + rm -rf ~/.npm/_cacache + + - name: Checkout Repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + ref: ${{ inputs.MOBILE_VERSION }} + + - name: Prepare Android Build + uses: ./.github/actions/prepare-android-build + env: + STORE_FILE: "${{ secrets.MM_MOBILE_STORE_FILE }}" + STORE_ALIAS: "${{ secrets.MM_MOBILE_STORE_ALIAS }}" + STORE_PASSWORD: "${{ secrets.MM_MOBILE_STORE_PASSWORD }}" + MATTERMOST_BUILD_GH_TOKEN: "${{ secrets.MATTERMOST_BUILD_GH_TOKEN }}" + + - name: Install Dependencies + run: sudo apt-get clean && sudo apt-get update && sudo apt-get install -y default-jdk + + - name: Cache Gradle dependencies + uses: actions/cache@v4 + with: + path: ~/.gradle/caches/modules-2/ + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: ${{ runner.os }}-gradle- + + - name: Detox build + run: | + cd detox + npm install + npm install -g detox-cli + npm run e2e:android-build + + - name: Upload Android Build + uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 + with: + name: android-build-files-${{ github.run_id }} + path: "android/app/build/**/*" + run-ios-tests-on-release: name: iOS Mobile Tests on Release uses: ./.github/workflows/e2e-detox-template.yml diff --git a/.github/workflows/e2e-detox-scheduled.yml b/.github/workflows/e2e-detox-scheduled.yml index 10786f4d6..ea692aaef 100644 --- a/.github/workflows/e2e-detox-scheduled.yml +++ b/.github/workflows/e2e-detox-scheduled.yml @@ -24,7 +24,7 @@ jobs: - update-initial-status steps: - name: Checkout Repository - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Prepare iOS Build uses: ./.github/actions/prepare-ios-build @@ -39,11 +39,61 @@ jobs: working-directory: ./fastlane - name: Upload iOS Simulator Build - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: name: ios-build-simulator-${{ github.run_id }} path: Mattermost-simulator-x86_64.app.zip + build-android-apk: + runs-on: ubuntu-latest-8-cores + needs: + - update-initial-status-android + env: + ORG_GRADLE_PROJECT_jvmargs: -Xmx8g + steps: + - name: Prune Docker to free up space + run: docker system prune -af + + - name: Remove npm Temporary Files + run: | + rm -rf ~/.npm/_cacache + + - name: Checkout Repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + ref: ${{ inputs.MOBILE_VERSION }} + + - name: Prepare Android Build + uses: ./.github/actions/prepare-android-build + env: + STORE_FILE: "${{ secrets.MM_MOBILE_STORE_FILE }}" + STORE_ALIAS: "${{ secrets.MM_MOBILE_STORE_ALIAS }}" + STORE_PASSWORD: "${{ secrets.MM_MOBILE_STORE_PASSWORD }}" + MATTERMOST_BUILD_GH_TOKEN: "${{ secrets.MATTERMOST_BUILD_GH_TOKEN }}" + + - name: Install Dependencies + run: sudo apt-get clean && sudo apt-get update && sudo apt-get install -y default-jdk + + - name: Cache Gradle dependencies + uses: actions/cache@v4 + with: + path: ~/.gradle/caches/modules-2/ + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: ${{ runner.os }}-gradle- + + - name: Detox build + run: | + cd detox + npm install + npm install -g detox-cli + npm run e2e:android-build + + - name: Upload Android Build + uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 + with: + name: android-build-files-${{ github.run_id }} + path: "android/app/build/**/*" + run-ios-tests-on-main-scheduled: name: iOS Mobile Tests on Main (Scheduled) uses: ./.github/workflows/e2e-detox-template.yml diff --git a/.github/workflows/e2e-detox-template.yml b/.github/workflows/e2e-detox-template.yml index 9465a2ef0..554be8669 100644 --- a/.github/workflows/e2e-detox-template.yml +++ b/.github/workflows/e2e-detox-template.yml @@ -97,7 +97,7 @@ jobs: workflow_hash: ${{ steps.resolve-device.outputs.WORKFLOW_HASH }} steps: - name: Checkout Repository - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: ref: ${{ inputs.MOBILE_VERSION }} @@ -138,7 +138,7 @@ jobs: matrix: ${{ fromJSON(needs.generate-specs.outputs.specs) }} steps: - name: Checkout Repository - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: ref: ${{ inputs.MOBILE_VERSION }} @@ -208,7 +208,7 @@ jobs: - name: Upload mitmdump Flow Output if: ${{ inputs.low_bandwidth_mode }} - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: name: ios-mitmdump-flow-output-${{ needs.generate-specs.outputs.workflow_hash }}-${{ matrix.runId }} path: | @@ -217,7 +217,7 @@ jobs: - name: Upload iOS Test Report if: always() - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: name: ios-results-${{ needs.generate-specs.outputs.workflow_hash }}-${{ matrix.runId }} path: detox/artifacts/ @@ -234,7 +234,7 @@ jobs: FAILURES: ${{ steps.summary.outputs.FAILURES }} steps: - name: Checkout Repository - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: ref: ${{ inputs.MOBILE_VERSION }} diff --git a/.github/workflows/github-release.yml b/.github/workflows/github-release.yml index c3d1701df..845b9b020 100644 --- a/.github/workflows/github-release.yml +++ b/.github/workflows/github-release.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-22.04 steps: - name: ci/checkout-repo - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: ci/test uses: ./.github/actions/test @@ -20,7 +20,7 @@ jobs: - test steps: - name: ci/checkout-repo - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: ci/prepare-ios-build uses: ./.github/actions/prepare-ios-build @@ -42,7 +42,7 @@ jobs: working-directory: ./fastlane - name: ci/upload-ios-unsigned - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: path: Mattermost-unsigned.ipa name: Mattermost-unsigned.ipa @@ -53,7 +53,7 @@ jobs: - test steps: - name: ci/checkout-repo - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: ci/prepare-android-build uses: ./.github/actions/prepare-android-build @@ -68,7 +68,7 @@ jobs: working-directory: ./fastlane - name: ci/upload-android-unsigned-build - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: path: Mattermost-unsigned.apk name: Mattermost-unsigned.apk @@ -80,9 +80,9 @@ jobs: - build-android-unsigned steps: - name: ci/checkout-repo - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: ruby/setup-ruby@ff740bc00a01b3a50fffc55a1071b1060eeae9dc # v1.180.0 + - uses: ruby/setup-ruby@32110d4e311bd8996b2a82bf2a43b714ccc91777 # v1.221.0 - name: release/setup-fastlane-dependencies run: bundle install diff --git a/app/context/extra_keyboard/index.tsx b/app/context/extra_keyboard/index.tsx index cb14db6cc..69282bf08 100644 --- a/app/context/extra_keyboard/index.tsx +++ b/app/context/extra_keyboard/index.tsx @@ -54,6 +54,10 @@ export const ExtraKeyboardProvider = (({children}: {children: React.ReactElement const [isTextInputFocused, setIsTextInputFocused] = useState(false); const showExtraKeyboard = useCallback((newComponent: React.ReactElement|null) => { + // Do not use ExtraKeyboard on Android versions below 11 + if (Platform.OS === 'android' && Platform.Version < 30) { + return; + } setExtraKeyboardVisible(true); setComponent(newComponent); if (Keyboard.isVisible()) { @@ -62,6 +66,10 @@ export const ExtraKeyboardProvider = (({children}: {children: React.ReactElement }, []); const hideExtraKeyboard = useCallback(() => { + // Do not use ExtraKeyboard on Android versions below 11 + if (Platform.OS === 'android' && Platform.Version < 30) { + return; + } setExtraKeyboardVisible(false); setComponent(null); if (Keyboard.isVisible()) { @@ -70,6 +78,11 @@ export const ExtraKeyboardProvider = (({children}: {children: React.ReactElement }, []); const registerTextInputFocus = useCallback(() => { + // Do not use ExtraKeyboard on Android versions below 11 + if (Platform.OS === 'android' && Platform.Version < 30) { + return; + } + // If the extra keyboard is opened if we don't do this // we get a glitch in the UI that will animate the extra keyboard down // and immediately bring the keyboard, by doing this @@ -81,11 +94,21 @@ export const ExtraKeyboardProvider = (({children}: {children: React.ReactElement }, []); const registerTextInputBlur = useCallback(() => { + // Do not use ExtraKeyboard on Android versions below 11 + if (Platform.OS === 'android' && Platform.Version < 30) { + return; + } + setIsTextInputFocused(false); }, []); useEffect(() => { const keyboardHideListener = Keyboard.addListener('keyboardDidHide', () => { + // Do not use ExtraKeyboard on Android versions below 11 + if (Platform.OS === 'android' && Platform.Version < 30) { + return; + } + if (isTextInputFocused) { setExtraKeyboardVisible(false); } @@ -142,7 +165,7 @@ export const useHideExtraKeyboardIfNeeded = (callback: (...args: any) => void, d }), [keyboardContext, ...dependencies]); }; -export const ExtraKeyboard = () => { +const ExtraKeyboardComponent = () => { const keyb = useAnimatedKeyboard({isStatusBarTranslucentAndroid: true}); const defaultKeyboardHeight = Platform.select({ios: 291, default: 240}); const context = useExtraKeyboardContext(); @@ -181,3 +204,14 @@ export const ExtraKeyboard = () => { ); }; + +// Do not use ExtraKeyboard on Android versions below 11 +export const ExtraKeyboard = () => { + if (Platform.OS === 'android' && Platform.Version < 30) { + return null; + } + + return ( + + ); +}; diff --git a/app/hooks/device.ts b/app/hooks/device.ts index bf0313159..abca58490 100644 --- a/app/hooks/device.ts +++ b/app/hooks/device.ts @@ -61,10 +61,19 @@ export function useKeyboardHeightWithDuration() { useEffect(() => { const show = Keyboard.addListener(Platform.select({ios: 'keyboardWillShow', default: 'keyboardDidShow'}), async (event) => { + // Do not use set the height on Android versions below 11 + if (Platform.OS === 'android' && Platform.Version < 30) { + return; + } setKeyboardHeight({height: event.endCoordinates.height, duration: event.duration}); }); const hide = Keyboard.addListener(Platform.select({ios: 'keyboardWillHide', default: 'keyboardDidHide'}), (event) => { + // Do not use set the height on Android versions below 11 + if (Platform.OS === 'android' && Platform.Version < 30) { + return; + } + if (updateTimeout.current != null) { clearTimeout(updateTimeout.current); updateTimeout.current = null; diff --git a/app/screens/interactive_dialog/index.tsx b/app/screens/interactive_dialog/index.tsx index eaa2042e2..97daff23f 100644 --- a/app/screens/interactive_dialog/index.tsx +++ b/app/screens/interactive_dialog/index.tsx @@ -3,7 +3,8 @@ import React, {useCallback, useEffect, useMemo, useReducer, useRef, useState} from 'react'; import {useIntl} from 'react-intl'; -import {Keyboard, ScrollView} from 'react-native'; +import {Keyboard} from 'react-native'; +import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view'; import {type ImageResource, Navigation} from 'react-native-navigation'; import {SafeAreaView} from 'react-native-safe-area-context'; @@ -106,7 +107,7 @@ function InteractiveDialog({ const serverUrl = useServerUrl(); const intl = useIntl(); - const scrollView = useRef(null); + const scrollView = useRef(null); const onChange = useCallback((name: string, value: string | number | boolean) => { dispatchValues({name, value}); @@ -185,7 +186,7 @@ function InteractiveDialog({ if (data.error) { hasErrors = true; setError(data.error); - scrollView.current?.scrollTo({x: 0, y: 0}); + scrollView.current?.scrollToPosition(0, 0, true); } else { setError(''); } @@ -234,9 +235,19 @@ function InteractiveDialog({ testID='interactive_dialog.screen' style={style.container} > - {Boolean(error) && ( )} {Boolean(introductionText) && - + } {Boolean(elements) && elements.map((e) => { const value = secureGetFromRecord(values, e.name); @@ -271,7 +282,7 @@ function InteractiveDialog({ /> ); })} - + ); } diff --git a/libraries/@mattermost/rnutils/android/src/main/java/com/mattermost/rnutils/RNUtilsModuleImpl.kt b/libraries/@mattermost/rnutils/android/src/main/java/com/mattermost/rnutils/RNUtilsModuleImpl.kt index 60c2921e7..250ec3c45 100644 --- a/libraries/@mattermost/rnutils/android/src/main/java/com/mattermost/rnutils/RNUtilsModuleImpl.kt +++ b/libraries/@mattermost/rnutils/android/src/main/java/com/mattermost/rnutils/RNUtilsModuleImpl.kt @@ -2,6 +2,7 @@ package com.mattermost.rnutils import android.app.Activity import android.net.Uri +import android.os.Build import android.view.WindowManager import androidx.core.view.OnApplyWindowInsetsListener import com.facebook.react.bridge.Arguments @@ -128,6 +129,9 @@ class RNUtilsModuleImpl(private val reactContext: ReactApplicationContext) { fun setSoftKeyboardToAdjustNothing() { val currentActivity: Activity = reactContext.currentActivity ?: return + if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) { + return + } currentActivity.runOnUiThread { currentActivity.window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING) @@ -136,6 +140,9 @@ class RNUtilsModuleImpl(private val reactContext: ReactApplicationContext) { fun setSoftKeyboardToAdjustResize() { val currentActivity: Activity = reactContext.currentActivity ?: return + if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) { + return + } currentActivity.runOnUiThread { currentActivity.window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE) diff --git a/patches/react-native-keyboard-aware-scroll-view+0.9.5.patch b/patches/react-native-keyboard-aware-scroll-view+0.9.5.patch new file mode 100644 index 000000000..791a3260a --- /dev/null +++ b/patches/react-native-keyboard-aware-scroll-view+0.9.5.patch @@ -0,0 +1,74 @@ +diff --git a/node_modules/react-native-keyboard-aware-scroll-view/index.d.ts b/node_modules/react-native-keyboard-aware-scroll-view/index.d.ts +index bf03b26..e11063b 100644 +--- a/node_modules/react-native-keyboard-aware-scroll-view/index.d.ts ++++ b/node_modules/react-native-keyboard-aware-scroll-view/index.d.ts +@@ -69,6 +69,7 @@ interface KeyboardAwareProps { + * @memberof KeyboardAwareProps + */ + enableOnAndroid?: boolean ++ noPaddingBottomOnAndroid?: boolean + + /** + * Adds an extra offset when focusing the TextInputs. +diff --git a/node_modules/react-native-keyboard-aware-scroll-view/lib/KeyboardAwareHOC.js b/node_modules/react-native-keyboard-aware-scroll-view/lib/KeyboardAwareHOC.js +index 03f46af..f58175f 100644 +--- a/node_modules/react-native-keyboard-aware-scroll-view/lib/KeyboardAwareHOC.js ++++ b/node_modules/react-native-keyboard-aware-scroll-view/lib/KeyboardAwareHOC.js +@@ -57,6 +57,7 @@ export type KeyboardAwareHOCProps = { + update?: Function, + contentContainerStyle?: any, + enableOnAndroid?: boolean, ++ noPaddingBottomOnAndroid?: boolean, + innerRef?: Function, + ...keyboardAwareHOCTypeEvents + } +@@ -92,6 +93,7 @@ export type ScrollIntoViewOptions = ?{ + + export type KeyboardAwareHOCOptions = ?{ + enableOnAndroid: boolean, ++ noPaddingBottomOnAndroid: boolean, + contentContainerStyle: ?Object, + enableAutomaticScroll: boolean, + extraHeight: number, +@@ -113,6 +115,7 @@ function getDisplayName(WrappedComponent: React$Component) { + + const ScrollIntoViewDefaultOptions: KeyboardAwareHOCOptions = { + enableOnAndroid: false, ++ noPaddingBottomOnAndroid: false, + contentContainerStyle: undefined, + enableAutomaticScroll: true, + extraHeight: _KAM_EXTRA_HEIGHT, +@@ -181,6 +184,7 @@ function KeyboardAwareHOC( + update: PropTypes.func, + contentContainerStyle: PropTypes.any, + enableOnAndroid: PropTypes.bool, ++ noPaddingBottomOnAndroid: PropTypes.bool, + innerRef: PropTypes.func, + ...keyboardEventPropTypes + } +@@ -193,7 +197,8 @@ function KeyboardAwareHOC( + enableResetScrollToCoords: hocOptions.enableResetScrollToCoords, + keyboardOpeningTime: hocOptions.keyboardOpeningTime, + viewIsInsideTabBar: hocOptions.viewIsInsideTabBar, +- enableOnAndroid: hocOptions.enableOnAndroid ++ enableOnAndroid: hocOptions.enableOnAndroid, ++ noPaddingBottomOnAndroid: hocOptions.noPaddingBottomOnAndroid + } + + constructor(props: KeyboardAwareHOCProps) { +@@ -523,13 +528,13 @@ function KeyboardAwareHOC( + } + + render() { +- const { enableOnAndroid, contentContainerStyle, onScroll } = this.props ++ const { enableOnAndroid, contentContainerStyle, noPaddingBottomOnAndroid, onScroll } = this.props + let newContentContainerStyle + if (Platform.OS === 'android' && enableOnAndroid) { + newContentContainerStyle = [].concat(contentContainerStyle).concat({ + paddingBottom: + ((contentContainerStyle || {}).paddingBottom || 0) + +- this.state.keyboardSpace ++ noPaddingBottomOnAndroid ? 0 : this.state.keyboardSpace + }) + } + const refProps = { [hocOptions.refPropName]: this._handleRef }