Skip to content

Commit 5c1f1ac

Browse files
authored
Add Code Coverage Report. (#7357)
Create coverage reports for PRs when PRs are updated.
1 parent 81138eb commit 5c1f1ac

File tree

9 files changed

+510
-18
lines changed

9 files changed

+510
-18
lines changed

.github/workflows/test_coverage.yml

Lines changed: 45 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
name: test_coverage
22

3-
on: [pull_request]
4-
#run specific jobs when specific files are updated.
5-
#https://github.community/t/how-to-execute-jobs-if-folder-updated-recursive/117344/5
3+
on:
4+
pull_request:
5+
# synchronize will be triggered when a pull request has new commits.
6+
# closed will be triggered when a pull request is closed.
7+
types: [synchronize, closed]
68

79
jobs:
810
check:
11+
if: github.repository == 'Firebase/firebase-ios-sdk' && github.event.action == 'synchronize'
912
name: Check changed files
1013
outputs:
1114
database_run_job: ${{ steps.check_files.outputs.database_run_job }}
1215
functions_run_job: ${{ steps.check_files.outputs.functions_run_job }}
16+
base_commit: ${{ steps.check_files.outputs.base_commit }}
1317
runs-on: ubuntu-latest
1418
steps:
1519
- name: Checkout code
@@ -21,37 +25,34 @@ jobs:
2125
env:
2226
pr_branch: ${{ github.event.pull_request.head.ref }}
2327
run: ./scripts/code_coverage_report/get_updated_files.sh
28+
2429
pod-lib-lint-database:
2530
# Don't run on private repo unless it is a PR.
31+
if: github.repository == 'Firebase/firebase-ios-sdk' && (needs.check.outputs.database_run_job == 'true' || github.event.pull_request.merged == true)
2632
needs: check
27-
if: github.repository == 'Firebase/firebase-ios-sdk' && needs.check.outputs.database_run_job == 'true'
2833
runs-on: macOS-latest
29-
3034
strategy:
3135
matrix:
32-
target: [ios, tvos, macos]
36+
target: [ios]
3337
steps:
3438
- uses: actions/checkout@v2
3539
- name: Setup Bundler
3640
run: scripts/setup_bundler.sh
3741
- name: Build and test
38-
env:
39-
SDK: database
4042
run: ./scripts/code_coverage_report/pod_test_code_coverage_report.sh FirebaseDatabase "${{ matrix.target }}"
4143
- uses: actions/upload-artifact@v2
4244
with:
43-
name: database-codecoverage
45+
name: codecoverage
4446
path: /Users/runner/*.xcresult
4547

4648
pod-lib-lint-functions:
4749
# Don't run on private repo unless it is a PR.
50+
if: github.repository == 'Firebase/firebase-ios-sdk' && (needs.check.outputs.functions_run_job == 'true' || github.event.pull_request.merged == true)
4851
needs: check
49-
if: github.repository == 'Firebase/firebase-ios-sdk' && needs.check.outputs.functions_run_job == 'true'
5052
runs-on: macOS-latest
51-
5253
strategy:
5354
matrix:
54-
target: [ios, tvos, macos]
55+
target: [ios]
5556
steps:
5657
- uses: actions/checkout@v2
5758
- name: Setup Bundler
@@ -60,20 +61,48 @@ jobs:
6061
run: ./scripts/code_coverage_report/pod_test_code_coverage_report.sh FirebaseFunctions "${{ matrix.target }}"
6162
- uses: actions/upload-artifact@v2
6263
with:
63-
name: functions-codecoverage
64+
name: codecoverage
6465
path: /Users/runner/*.xcresult
6566

6667
create_report:
67-
needs: [pod-lib-lint-functions, pod-lib-lint-database]
68+
needs: [check, pod-lib-lint-functions, pod-lib-lint-database]
69+
env:
70+
metrics_service_secret: ${{ secrets.GHASecretsGPGPassphrase1 }}
6871
if: always()
6972
runs-on: macOS-latest
7073
steps:
74+
- uses: actions/checkout@v2
75+
- name: Access to Metrics Service
76+
run: |
77+
# Install gcloud sdk
78+
curl https://sdk.cloud.google.com > install.sh
79+
bash install.sh --disable-prompts
80+
echo "${HOME}/google-cloud-sdk/bin/" >> $GITHUB_PATH
81+
export PATH="${HOME}/google-cloud-sdk/bin/:${PATH}"
82+
83+
# Activate the service account for Metrics Service.
84+
scripts/decrypt_gha_secret.sh scripts/gha-encrypted/metrics_service_access.json.gpg \
85+
metrics-access.json "$metrics_service_secret"
86+
gcloud auth activate-service-account --key-file metrics-access.json
7187
- uses: actions/download-artifact@v2
7288
id: download
7389
with:
7490
path: /Users/runner/test
75-
- name: display results
91+
- name: Compare Diff and Post a Report
92+
if: github.event_name == 'pull_request'
93+
env:
94+
base_commit: ${{ needs.check.outputs.base_commit }}
95+
run: |
96+
# Get Head commit of the branch, instead of a merge commit created by actions/checkout.
97+
GITHUB_SHA=$(cat $GITHUB_EVENT_PATH | jq -r .pull_request.head.sha)
98+
if [ -d "${{steps.download.outputs.download-path}}" ]; then
99+
cd scripts/code_coverage_report/generate_code_coverage_report
100+
swift run CoverageReportGenerator --presubmit "firebase/firebase-ios-sdk" --commit "${GITHUB_SHA}" --token $(gcloud auth print-identity-token) --xcresult-dir "/Users/runner/test/codecoverage" --log-link "https://github.com/firebase/firebase-ios-sdk/actions/runs/${GITHUB_RUN_ID}" --pull-request-num ${{github.event.pull_request.number}} --base-commit "$base_commit"
101+
fi
102+
- name: Update New Coverage Data
103+
if: github.event.pull_request.merged == true
76104
run: |
77105
if [ -d "${{steps.download.outputs.download-path}}" ]; then
78-
find "/Users/runner/test" -print -regex ".*/.*\.xcresult" -exec xcrun xccov view --report {} \;
106+
cd scripts/code_coverage_report/generate_code_coverage_report
107+
swift run CoverageReportGenerator --merge "firebase/firebase-ios-sdk" --commit "${GITHUB_SHA}" --token $(gcloud auth print-identity-token) --xcresult-dir "/Users/runner/test/codecoverage" --log-link "https://github.com/firebase/firebase-ios-sdk/actions/runs/${GITHUB_RUN_ID}" --branch "${GITHUB_REF##*/}"
79108
fi

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ DerivedData
6969
ReleaseTooling/Packages
7070
ReleaseTooling/*.xcodeproj
7171
ReleaseTooling/Package.resolved
72+
scripts/code_coverage_report/generate_code_coverage_report/Package.resolved
73+
scripts/code_coverage_report/generate_code_coverage_report/.build
7274

7375
# Mint package manager
7476
Mint
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// swift-tools-version:5.3
2+
// The swift-tools-version declares the minimum version of Swift required to build this package.
3+
/*
4+
* Copyright 2021 Google LLC
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
import PackageDescription
20+
21+
let package = Package(
22+
name: "CoverageReportGenerator",
23+
products: [
24+
// Products define the executables and libraries a package produces, and make them visible to other packages.
25+
.executable(
26+
name: "CoverageReportGenerator",
27+
targets: ["CoverageReportGenerator"]
28+
),
29+
],
30+
dependencies: [
31+
// Dependencies declare other packages that this package depends on.
32+
// .package(url: /* package url */, from: "1.0.0"),
33+
.package(url: "https://github.com/apple/swift-argument-parser", from: "0.2.0"),
34+
],
35+
targets: [
36+
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
37+
// Targets can depend on other targets in this package, and on products in packages this package depends on.
38+
.target(
39+
name: "CoverageReportGenerator",
40+
dependencies: [
41+
.product(name: "ArgumentParser", package: "swift-argument-parser"),
42+
]
43+
),
44+
]
45+
)
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# coverage_report_parser
2+
3+
This is a tool to read test coverages of xcresult bundle and generate a json report. This json
4+
report will be sent to Metrics Service to create a coverage report as a comment in a PR or to update
5+
the coverage database.
6+
7+
## Usage
8+
9+
This is tool will be used for both pull_request and merge. Common flags are shown below.
10+
11+
```
12+
swift run CoverageReportGenerator --presubmit "${REPO}" --commit "${GITHUB_SHA}" --token "${TOKEN}" \
13+
--xcresult-dir "${XCRESULT_DIR}" --log-link "${}" --pull-request-num "${PULL_REQUEST_NUM}" \
14+
--base-commit "${BASE_COMMIT}" --branch "${BRANCH}"
15+
```
16+
Common parameters for both pull_request and merge:
17+
- `presubmit/merge`: A required flag to know if the request is for pull requests or merge.
18+
- `REPO`: A required argument for a repo where coverage data belong.
19+
- `commit`: The current commit sha.
20+
- `token`: A token to access a service account of Metrics Service
21+
- `xcresult-dir`: A directory containing all xcresult bundles.
22+
23+
### Create a report in a pull request
24+
25+
In a workflow, this will run for each pull request update. The command below will generate a report
26+
in a PR. After a workflow of test coverage is done, a new coverage report will be posted on a
27+
comment of a pull request. If such comment has existed, this comment will be overriden by the latest
28+
report.
29+
30+
Since the flag is `presubmit` here, the following options are required for a PR request:
31+
- `log-link`: Log link to unit tests. This is generally a actions/runs/ link in Github Actions.
32+
- `pull-request-num`: A report will be posted in this pull request.
33+
- `base-commit`: The commit sha used to compare the diff of the current`commit`.
34+
35+
An example in a Github Actions workflow:
36+
```
37+
swift run CoverageReportGenerator --presubmit "firebase/firebase-ios-sdk" --commit "${GITHUB_SHA}" \
38+
--token $(gcloud auth print-identity-token) --xcresult-dir "/Users/runner/test/codecoverage" \
39+
--log-link "https://github.com/firebase/firebase-ios-sdk/actions/runs/${GITHUB_RUN_ID}" \
40+
--pull-request-num ${{github.event.pull_request.number}} --base-commit "$base_commit"
41+
42+
```
43+
44+
### Add new coverage data to the storage of Metrics Service
45+
46+
In a workflow, this will run in merge events or postsubmit tests. After each merge, all pod tests
47+
will run to add a new commit and its corresponding coverage data.
48+
```
49+
swift run CoverageReportGenerator --merge "firebase/firebase-ios-sdk" --commit "${GITHUB_SHA}" \
50+
--token $(gcloud auth print-identity-token) --xcresult-dir "/Users/runner/test/codecoverage" \
51+
--log-link "https://github.com/firebase/firebase-ios-sdk/actions/runs/${GITHUB_RUN_ID}" --branch \
52+
"${GITHUB_REF##*/}"
53+
```
54+
- `branch`: this is for merge and the new commit with coverage data will be linked with the branch
55+
in the database of Metrics Service.
56+
57+
### Details
58+
59+
More details in go/firebase-ios-sdk-test-coverage-metrics. Can also run
60+
`swift run CoverageReportGenerator -h` for help info.

0 commit comments

Comments
 (0)