@@ -3,6 +3,9 @@ name: Integration tests
33on :
44 schedule :
55 - cron : " 0 9 * * *" # 9am UTC = 1am PST / 2am PDT
6+ pull_request :
7+ types : [ labeled ]
8+
69 workflow_dispatch :
710 inputs :
811 platforms :
3942 required : true
4043 test_packaged_sdk :
4144 description : ' Optional: Packaging run # to build against?'
45+ env :
46+ triggerLabelPrefix : " tests-requested: "
47+ triggerLabelFull : " tests-requested: full"
48+ triggerLabelQuick : " tests-requested: quick"
49+ statusLabelInProgress : " tests: in-progress"
50+ statusLabelFailed : " tests: failed"
51+ statusLabelSucceeded : " tests: succeeded"
52+ statusCommentIdentifier : " integration-test-status-comment"
4253
4354jobs :
55+ check_trigger :
56+ # ## This job only runs when the workflow was triggered by a PR getting labeled.
57+ # ## It checks whether the label is a test-request trigger (cancelling
58+ # ## the workflow if not), and then sets the in-progress label. It sets
59+ # ## outputs to control the test matrix (full or quick) and to tell
60+ # ## subsequent steps to update the labels as well.
61+ runs-on : ubuntu-latest
62+ if : github.event_name == 'pull_request' && github.event.action == 'labeled'
63+ outputs :
64+ should_update_labels : ${{ steps.set_outputs.outputs.should_update_labels }}
65+ requested_tests : ${{ steps.set_outputs.outputs.requested_tests }}
66+ steps :
67+ # ## If the label isn't one of the test-request triggers, cancel the workflow.
68+ - name : cancel workflow if label is irrelevant
69+ if : ${{ !startsWith(github.event.label.name, env.triggerLabelPrefix) }}
70+ uses : andymckay/cancel-action@0.2
71+ - name : wait for above cancellation if label is irrelevant
72+ if : ${{ !startsWith(github.event.label.name, env.triggerLabelPrefix) }}
73+ run : |
74+ sleep 300
75+ exit 1 # fail out if the cancellation above somehow failed.
76+ # ## Below this line, the label is one of the test-request triggers.
77+ - name : cancel previous runs on the same PR
78+ uses : styfle/cancel-workflow-action@0.8.0
79+ with :
80+ access_token : ${{ github.token }}
81+ - name : remove triggering label
82+ uses : buildsville/add-remove-label@v1
83+ with :
84+ token : ${{ github.token }}
85+ label : " ${{ github.event.label.name }}"
86+ type : remove
87+ # ## Fail the workflow if the user does not have admin access to run the tests.
88+ - name : check if user has permission to trigger tests
89+ uses : lannonbr/repo-permission-check-action@2.0.0
90+ with :
91+ permission : " admin"
92+ env :
93+ GITHUB_TOKEN : ${{ github.token }}
94+ - id : set_outputs
95+ run : |
96+ echo "::set-output name=should_update_labels::1"
97+ if [[ "${{ github.event.label.name }}" == "${{ env.triggerLabelFull }}" ]]; then
98+ echo "::set-output name=requested_tests::full"
99+ elif [[ "${{ github.event.label.name }}" == "${{ env.triggerLabelQuick }}" ]]; then
100+ echo "::set-output name=requested_tests::auto"
101+ fi
102+ # ## Add the in-progress label and remove any previous success/fail labels.
103+ - name : add in-progress label
104+ uses : buildsville/add-remove-label@v1
105+ with :
106+ token : ${{ github.token }}
107+ label : " ${{ env.statusLabelInProgress }}"
108+ type : add
109+ - name : remove previous success label
110+ uses : buildsville/add-remove-label@v1
111+ with :
112+ token : ${{ github.token }}
113+ label : " ${{ env.statusLabelSucceeded }}"
114+ type : remove
115+ - name : remove previous failure label
116+ uses : buildsville/add-remove-label@v1
117+ with :
118+ token : ${{ github.token }}
119+ label : " ${{ env.statusLabelFailed }}"
120+ type : remove
121+ - name : find old status comment, if any
122+ uses : peter-evans/find-comment@v1
123+ id : find-comment
124+ with :
125+ issue-number : ${{github.event.number}}
126+ body-includes : ${{ env.statusCommentIdentifier }}
127+ token : ${{github.token}}
128+ - name : delete old status comment
129+ if : ${{ steps.find-comment.outputs.comment-id != 0 }}
130+ uses : jungwinter/comment@v1
131+ with :
132+ type : delete
133+ comment_id : ${{ steps.find-comment.outputs.comment-id }}
134+ token : ${{ github.token }}
135+ - name : get current time for status comment
136+ id : get-time
137+ shell : bash
138+ run : |
139+ echo -n "::set-output name=time::"
140+ TZ=America/Los_Angeles date
141+ - name : add in progress status comment
142+ uses : phulsechinmay/rewritable-pr-comment@v0.2.1
143+ with :
144+ message : |
145+ ### ⏳ Integration test in progress...
146+ Requested by @${{github.actor}} on commit ${{github.event.pull_request.head.sha}}
147+ Last updated: ${{ steps.get-time.outputs.time }}
148+ **[View integration test run](https://github.com/${{github.repository}}/actions/runs/${{github.run_id}})**
149+ GITHUB_TOKEN : ${{ github.token }}
150+ COMMENT_IDENTIFIER : ${{ env.statusCommentIdentifier }}
151+
44152 # To feed input into the job matrix, we first need to convert to a JSON
45153 # list. Then we can use fromJson to define the field in the matrix for the tests job.
46154 prepare_matrix :
47155 runs-on : ubuntu-latest
156+ needs : check_trigger
157+ if : ${{ !cancelled() && !failure() }} # Run even if check_trigger was skipped.
48158 outputs :
49159 matrix_platform : ${{ steps.export-result.outputs.matrix_platform }}
50160 matrix_os : ${{ steps.export-result.outputs.matrix_os }}
@@ -57,17 +167,24 @@ jobs:
57167 steps :
58168 - uses : actions/checkout@v2
59169 with :
170+ fetch-depth : 0
60171 submodules : false
61172 - name : Use expanded matrix
62- if : github.event_name == 'schedule' || github.event.inputs.use_expanded_matrix == '1'
173+ if : github.event_name == 'schedule' || github.event.inputs.use_expanded_matrix == '1' || needs.check_trigger.outputs.requested_tests == 'full'
63174 run : |
64175 echo "EXPANDED_MATRIX_PARAM=-e=1" >> $GITHUB_ENV
65-
176+ - name : Set auto-diff option if specified.
177+ if : needs.check_trigger.outputs.requested_tests == 'auto'
178+ run : |
179+ echo "Autodetecting which tests to run."
180+ echo "AUTO_DIFF_PARAM=--auto_diff ${{github.event.pull_request.base.sha}}" >> $GITHUB_ENV
181+
66182 - id : export-result
67183 # e.g. 'ubuntu-latest,macos-latest' -> '["ubuntu-latest","macos-latest"]'
68184 run : |
69- echo "::set-output name=matrix_platform::$( python scripts/gha/print_matrix_configuration.py -w integration_tests ${EXPANDED_MATRIX_PARAM} -k platform -o "${{github.event.inputs.platforms}}" )"
70- echo "::set-output name=matrix_os::$( python scripts/gha/print_matrix_configuration.py -w integration_tests ${EXPANDED_MATRIX_PARAM} -k os -o "${{github.event.inputs.operating_systems}}" )"
185+ echo "::set-output name=apis::$( python scripts/gha/print_matrix_configuration.py -c -w integration_tests -k apis -o "${{github.event.inputs.apis}}" ${AUTO_DIFF_PARAM})"
186+ echo "::set-output name=matrix_platform::$( python scripts/gha/print_matrix_configuration.py -w integration_tests ${EXPANDED_MATRIX_PARAM} -k platform -o "${{github.event.inputs.platforms}}" ${AUTO_DIFF_PARAM})"
187+ echo "::set-output name=matrix_os::$( python scripts/gha/print_matrix_configuration.py -w integration_tests ${EXPANDED_MATRIX_PARAM} -k os -o "${{github.event.inputs.operating_systems}}" ${AUTO_DIFF_PARAM})"
71188 # If building against a packaged SDK, only use boringssl.
72189 if [[ -n "${{ github.event.inputs.test_packaged_sdk }}" ]]; then
73190 echo "::warning ::Downloading SDK package from previous run: https://github.com/firebase/firebase-cpp-sdk/actions/runs/${{ github.event.inputs.test_packaged_sdk }}"
@@ -76,16 +193,18 @@ jobs:
76193 else
77194 echo "::set-output name=matrix_ssl::$( python scripts/gha/print_matrix_configuration.py -w integration_tests ${EXPANDED_MATRIX_PARAM} -k ssl_lib -o "${{github.event.inputs.desktop_ssl_variants}}" )"
78195 fi
79- echo "::set-output name=apis::$( python scripts/gha/print_matrix_configuration.py -c -w integration_tests -k apis -o "${{github.event.inputs.apis}}" )"
80196 echo "::set-output name=android_device::$( python scripts/gha/print_matrix_configuration.py -c -w integration_tests -k android_device -o "${{github.event.inputs.android_device}}" )"
81197 echo "::set-output name=android_api::$( python scripts/gha/print_matrix_configuration.py -c -w integration_tests -k android_api -o "${{github.event.inputs.android_api}}" )"
82198 echo "::set-output name=ios_device::$( python scripts/gha/print_matrix_configuration.py -c -w integration_tests -k ios_device -o "${{github.event.inputs.ios_device}}" )"
83199 echo "::set-output name=ios_version::$( python scripts/gha/print_matrix_configuration.py -c -w integration_tests -k ios_version -o "${{github.event.inputs.ios_version}}" )"
84200
85201 tests :
86202 name : ${{ matrix.os }}-${{ matrix.target_platform }}-${{ matrix.ssl_variant }}
87- needs : prepare_matrix
203+ needs : [ prepare_matrix, check_trigger]
88204 runs-on : ${{ matrix.os }}
205+ # Skip this if there is an empty matrix (which can happen if "auto" was set above).
206+ # But check cancelled() && !failure() so it runs even if check_trigger was skipped.
207+ if : needs.prepare_matrix.outputs.matrix_platform != '[]' && needs.prepare_matrix.outputs.apis != '' && !cancelled() && !failure()
89208 strategy :
90209 fail-fast : false
91210 matrix :
@@ -139,7 +258,7 @@ jobs:
139258 with :
140259 path : /tmp/android-ndk-r16b
141260 key : android-ndk-${{ matrix.os }}-r16b
142-
261+
143262 - name : Setup python
144263 uses : actions/setup-python@v2
145264 with :
@@ -240,6 +359,36 @@ jobs:
240359 if : matrix.target_platform != 'Desktop' && !cancelled()
241360 run : |
242361 python scripts/gha/test_lab.py --android_model ${{ needs.prepare_matrix.outputs.android_device }} --android_api ${{ needs.prepare_matrix.outputs.android_api }} --ios_model ${{ needs.prepare_matrix.outputs.ios_device }} --ios_version ${{ needs.prepare_matrix.outputs.ios_version }} --testapp_dir testapps --code_platform cpp --key_file scripts/gha-encrypted/gcs_key_file.json
362+
363+ # ## The below allow us to set the failure label and comment early, when the first failure
364+ # ## in the matrix occurs. It'll be cleaned up in a subsequent job.
365+ - name : add failure label
366+ # We can do mark a failure as soon as any one test fails.
367+ if : ${{ needs.check_trigger.outputs.should_update_labels && failure() && !cancelled() }}
368+ uses : buildsville/add-remove-label@v1
369+ with :
370+ token : ${{ github.token }}
371+ label : " ${{ env.statusLabelFailed }}"
372+ type : add
373+ - name : get current time for status comment
374+ id : get-time
375+ if : ${{ needs.check_trigger.outputs.should_update_labels && failure() && !cancelled() }}
376+ shell : bash
377+ run : |
378+ echo -n "::set-output name=time::"
379+ TZ=America/Los_Angeles date
380+ - name : add failure status comment
381+ uses : phulsechinmay/rewritable-pr-comment@v0.2.1
382+ if : ${{ needs.check_trigger.outputs.should_update_labels && failure() && !cancelled() }}
383+ with :
384+ message : |
385+ ### ❌ Integration test FAILED (but still ⏳ in progress)
386+ Requested by @${{github.actor}} on commit ${{github.event.pull_request.head.sha}}
387+ Last updated: ${{ steps.get-time.outputs.time }}
388+ **[View integration test results](https://github.com/${{github.repository}}/actions/runs/${{github.run_id}})**
389+ GITHUB_TOKEN : ${{ github.token }}
390+ COMMENT_IDENTIFIER : ${{ env.statusCommentIdentifier }}
391+
243392 - name : Summarize build and test results
244393 if : ${{ !cancelled() }}
245394 shell : bash
@@ -248,3 +397,83 @@ jobs:
248397 if [[ "${{ job.status }}" != "success" ]]; then
249398 exit 1
250399 fi
400+
401+ add_success_label :
402+ name : " add-success-label"
403+ needs : [check_trigger, tests]
404+ runs-on : ubuntu-latest
405+ if : ${{ needs.check_trigger.outputs.should_update_labels && !cancelled() && !failure() }}
406+ steps :
407+ - name : add success label
408+ uses : buildsville/add-remove-label@v1
409+ with :
410+ token : ${{github.token}}
411+ label : " ${{ env.statusLabelSucceeded }}"
412+ type : add
413+ - name : get current time for status comment
414+ id : get-time
415+ shell : bash
416+ run : |
417+ echo -n "::set-output name=time::"
418+ TZ=America/Los_Angeles date
419+ - name : add success status comment
420+ uses : phulsechinmay/rewritable-pr-comment@v0.2.1
421+ with :
422+ message : |
423+ ### ✅ Integration test succeeded!
424+ Requested by @${{github.actor}} on commit ${{github.event.pull_request.head.sha}}
425+ Last updated: ${{ steps.get-time.outputs.time }}
426+ **[View integration test results](https://github.com/${{github.repository}}/actions/runs/${{github.run_id}})**
427+ GITHUB_TOKEN : ${{ github.token }}
428+ COMMENT_IDENTIFIER : ${{ env.statusCommentIdentifier }}
429+
430+ add_failure_label :
431+ name : " add-failure-label"
432+ needs : [check_trigger, tests]
433+ runs-on : ubuntu-latest
434+ if : ${{ needs.check_trigger.outputs.should_update_labels && !cancelled() && failure() }}
435+ steps :
436+ - name : add failure label
437+ uses : buildsville/add-remove-label@v1
438+ with :
439+ token : ${{ github.token }}
440+ label : " ${{ env.statusLabelFailed }}"
441+ type : add
442+ - name : get current time for status comment
443+ id : get-time
444+ shell : bash
445+ run : |
446+ echo -n "::set-output name=time::"
447+ TZ=America/Los_Angeles date
448+ - name : add failure status comment
449+ uses : phulsechinmay/rewritable-pr-comment@v0.2.1
450+ with :
451+ message : |
452+ ### ❌ Integration test FAILED
453+ Requested by @${{github.actor}} on commit ${{github.event.pull_request.head.sha}}
454+ Last updated: ${{ steps.get-time.outputs.time }}
455+ **[View integration test results](https://github.com/${{github.repository}}/actions/runs/${{github.run_id}})**
456+ GITHUB_TOKEN : ${{ github.token }}
457+ COMMENT_IDENTIFIER : ${{ env.statusCommentIdentifier }}
458+
459+ remove_in_progress_label :
460+ name : " remove-in-progress-label"
461+ needs : [check_trigger, tests]
462+ runs-on : ubuntu-latest
463+ if : ${{ needs.check_trigger.outputs.should_update_labels && !cancelled() }}
464+ steps :
465+ # Use a different token to remove the "in-progress" label,
466+ # to allow the removal to trigger the "Check Labels" workflow.
467+ - name : Generate token for GitHub API
468+ uses : tibdex/github-app-token@v1
469+ id : generate-token
470+ with :
471+ app_id : ${{ secrets.WORKFLOW_TRIGGER_APP_ID }}
472+ private_key : ${{ secrets.WORKFLOW_TRIGGER_APP_PRIVATE_KEY }}
473+ - name : remove in progress label
474+ uses : buildsville/add-remove-label@v1
475+ with :
476+ token : ${{steps.generate-token.outputs.token}}
477+ label : " ${{ env.statusLabelInProgress }}"
478+ type : remove
479+
0 commit comments