summaryrefslogtreecommitdiffhomepage
path: root/.github/workflows/ios-end-to-end-tests.yml
blob: 8c9a8d13d08e8d888b82ceb3c0d58a0256e61278 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
---
name: iOS end-to-end tests
env:
  TEST_DEVICE_UDID: 00008130-0019181022F3803A
permissions:
  contents: read
  issues: write
  pull-requests: write
on:
  workflow_call:
    inputs:
      arg_tests_json_key:
        type: string
        required: false
      commit_hash:
        type: string
        required: false
  workflow_dispatch:
    inputs:
      # Optionally specify a test case or suite to run.
      # Must be in the format MullvadVPNUITest/<test-suite-name>/<test-case-name> where test case name is optional.
      user_supplied_test_name:
        description: 'Only run test case/suite'
        required: false
      commit_hash:
        description: >
         Specifies the repository commit to use; defaults to the current event's commit if not provided.
        required: false
jobs:
  set-up-outputs-directory:
    name: Set up outputs directory
    runs-on: [self-hosted, macOS, ios-test]
    outputs:
      job_outputs_directory: ${{ steps.set-up-job-outputs-directory.outputs.job_outputs_directory }}
    steps:
      - name: Set up job outputs directory
        id: set-up-job-outputs-directory
        run: |
          job_outputs_directory="$HOME/workflow-outputs/job-outputs-${{ github.run_id }}"
          echo "job_outputs_directory=$job_outputs_directory" >> "$GITHUB_OUTPUT"
          mkdir -p "$job_outputs_directory"

        shell: bash

  # Define the set of tests to run based on the event type and input
  define-test-suites-matrix:
    name: Define test suites matrix
    runs-on: [self-hosted, macOS, ios-test]
    needs: set-up-outputs-directory
    steps:
      - name: Test runs to JSON
        id: test-runs-to-json
        run: |
          if [ -n "${{ inputs.arg_tests_json_key }}" ]; then
          # JSON key supplied by another workflow calling this reusable workflow
          echo "Using calling workflow supplied test suites JSON key: ${{ inputs.arg_tests_json_key }}"
            # Forcing the filesystem buffers to be flushed to ensure the
            # directory tree is updated
            sync
            test_suites_json=$(jq -r --compact-output '.tests."${{ inputs.arg_tests_json_key }}"' tests.json)
            echo "test_suites_json=$test_suites_json" >> $GITHUB_ENV
          elif [ -n "${{ inputs.user_supplied_test_name }}" ]; then
            # User specified test case/suite when manually triggering run
            echo "Using user supplied test name: ${{ inputs.user_supplied_test_name }}"
            test_suites_json="['${{ inputs.user_supplied_test_name }}']" >> $GITHUB_ENV
            echo "test_suites_json=$test_suites_json" >> $GITHUB_ENV
          else
            echo "Tests not specified, will fallback to running nightly(all) tests scope"
            test_suites_json=$(jq -r --compact-output '.tests.nightly' tests.json)
            echo "test_suites_json=$test_suites_json" >> $GITHUB_ENV
          fi

          echo "Test suites/cases to run: $test_suites_json"
        working-directory: ios/MullvadVPNUITests
    outputs:
      test_suites_json: ${{ env.test_suites_json }}

  # Build app and tests target
  build:
    name: Build for end to end testing
    runs-on: [self-hosted, macOS, ios-test]
    needs: set-up-outputs-directory
    timeout-minutes: 20
    steps:
      - name: Set commit hash or default to github.sha
        id: set-commit-hash
        run: |
          # If the input has a value, it is filled by that value; otherwise, use github.sha
          if [ -n "${{ inputs.commit_hash }}" ]; then
            echo "COMMIT_HASH=${{ inputs.commit_hash }}" >> $GITHUB_ENV
          else
            echo "COMMIT_HASH=${{ github.sha }}" >> $GITHUB_ENV
          fi
        shell: bash
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          clean: true
          ref: ${{ env.COMMIT_HASH }}

      - name: Checkout submodules
        run: |
          git config --global --add safe.directory '*'
          git submodule update --init --recursive ios/wireguard-apple

      - name: Configure Rust
        run: rustup target add aarch64-apple-ios

      - name: Build iOS end to end tests action
        uses: ./.github/actions/ios/build-ios-e2e-tests
        with:
          test_name: ${{ github.event.inputs.user_supplied_test_name }}
          ios_device_pin_code: ${{ secrets.IOS_DEVICE_PIN_CODE }}
          test_device_identifier_uuid: ${{ secrets.IOS_TEST_DEVICE_IDENTIFIER_UUID }}
          has_time_account_number: ${{ secrets.IOS_HAS_TIME_ACCOUNT_NUMBER_PRODUCTION }}
          no_time_account_number: ${{ secrets.IOS_NO_TIME_ACCOUNT_NUMBER_PRODUCTION }}
          test_device_udid: ${{ env.TEST_DEVICE_UDID }}
          partner_api_token: ${{ secrets.STAGEMOLE_PARTNER_AUTH }}
          outputs_path: ${{ needs.set-up-outputs-directory.outputs.job_outputs_directory }}

      - name: Debug print job output directory
        run: |
          echo "Job output directory: ${{ needs.set-up-outputs-directory.outputs.job_outputs_directory }}"
        shell: bash

      - name: Copy build output and project to output directory
        run: |
          mkdir -p "$JOB_OUTPUTS_DIRECTORY/derived-data"
          cp -R ios/derived-data "$JOB_OUTPUTS_DIRECTORY"
          cp -R . $JOB_OUTPUTS_DIRECTORY/mullvadvpn-app
        shell: bash
        env:
          JOB_OUTPUTS_DIRECTORY: ${{ needs.set-up-outputs-directory.outputs.job_outputs_directory }}

      - name: Clean up
        run: |
          rm -rf ios/Configurations/*.xcconfig
          rm -rf ios/derived-data
        shell: bash

  test:
    name: Run tests
    runs-on: [self-hosted, macOS, ios-test]
    needs: [build, define-test-suites-matrix, set-up-outputs-directory]
    timeout-minutes: 60
    strategy:
      fail-fast: false
      matrix:
        test_suite: ${{fromJson(needs.define-test-suites-matrix.outputs.test_suites_json)}}
    steps:
      - name: Run iOS end to end tests action
        uses: ./.github/actions/ios/run-ios-e2e-tests
        with:
          test_name: "MullvadVPNUITests/${{ matrix.test_suite }}"
          test_device_udid: ${{ env.TEST_DEVICE_UDID }}
          outputs_path: ${{ needs.set-up-outputs-directory.outputs.job_outputs_directory }}

  clean-up-outputs-directory:
    if: always()
    name: Clean up outputs directory
    runs-on: [self-hosted, macOS, ios-test]
    needs: [test, set-up-outputs-directory]
    steps:
      - name: Clean up outputs directory
        run: rm -rf ${{ needs.set-up-outputs-directory.outputs.job_outputs_directory }}
        shell: bash

  notify-on-failure:
    if: failure() && github.event_name == 'pull_request'
    name: Notify team on failure(if PR related)
    runs-on: [self-hosted, macOS, ios-test]
    needs: test
    timeout-minutes: 5
    steps:
      - name: Comment PR on test failure
        uses: actions/github-script@v7
        with:
          github-token: ${{secrets.GITHUB_TOKEN}}
          script: |
            const issue_number = context.issue.number;
            const run_id = context.runId;
            const run_url = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${run_id}`;
            github.rest.issues.createComment({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: issue_number,
              body: `🚨 End to end tests failed. Please check the [failed workflow run](${run_url}).`
            });