Add test coverage comments to PRs (#15183)
* add test coverage comments to PRs * [skip ci] update test coverage * [skip ci] add .gitattributes to avoid merge conflicts with test coverage * exempt main and release branches from coverage job * [skip ci] update test coverage * [skip ci] update test coverage * clean up debug line, exit early if missing files * [skip ci] update test coverage * extract repository into variable to make porting to ENT easier * [skip ci] update test coverage Co-authored-by: hc-github-team-consul-core <github-team-consul-core@hashicorp.com>
This commit is contained in:
parent
ee56e06f22
commit
958c9dd905
|
@ -56,7 +56,6 @@ steps:
|
||||||
url=https://github.com/gotestyourself/gotestsum/releases/download
|
url=https://github.com/gotestyourself/gotestsum/releases/download
|
||||||
curl -sSL "${url}/v${GOTESTSUM_RELEASE}/gotestsum_${GOTESTSUM_RELEASE}_linux_${ARCH}.tar.gz" | \
|
curl -sSL "${url}/v${GOTESTSUM_RELEASE}/gotestsum_${GOTESTSUM_RELEASE}_linux_${ARCH}.tar.gz" | \
|
||||||
sudo tar -xz --overwrite -C /usr/local/bin gotestsum
|
sudo tar -xz --overwrite -C /usr/local/bin gotestsum
|
||||||
|
|
||||||
get-aws-cli: &get-aws-cli
|
get-aws-cli: &get-aws-cli
|
||||||
run:
|
run:
|
||||||
name: download and install AWS CLI
|
name: download and install AWS CLI
|
||||||
|
@ -67,7 +66,6 @@ steps:
|
||||||
gpg --verify awscliv2.sig awscliv2.zip
|
gpg --verify awscliv2.sig awscliv2.zip
|
||||||
unzip awscliv2.zip
|
unzip awscliv2.zip
|
||||||
sudo ./aws/install
|
sudo ./aws/install
|
||||||
|
|
||||||
# This step MUST be at the end of any set of steps due to the 'when' condition
|
# This step MUST be at the end of any set of steps due to the 'when' condition
|
||||||
notify-slack-failure: ¬ify-slack-failure
|
notify-slack-failure: ¬ify-slack-failure
|
||||||
name: notify-slack-failure
|
name: notify-slack-failure
|
||||||
|
@ -94,7 +92,6 @@ steps:
|
||||||
else
|
else
|
||||||
echo "Not posting slack failure notifications for non-main branch"
|
echo "Not posting slack failure notifications for non-main branch"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
commands:
|
commands:
|
||||||
assume-role:
|
assume-role:
|
||||||
description: "Assume role to an ARN"
|
description: "Assume role to an ARN"
|
||||||
|
@ -121,7 +118,6 @@ commands:
|
||||||
echo "export AWS_SECRET_ACCESS_KEY=$(echo $CREDENTIALS | jq -r '.SecretAccessKey')" >> $BASH_ENV
|
echo "export AWS_SECRET_ACCESS_KEY=$(echo $CREDENTIALS | jq -r '.SecretAccessKey')" >> $BASH_ENV
|
||||||
echo "export AWS_SESSION_TOKEN=$(echo $CREDENTIALS | jq -r '.SessionToken')" >> $BASH_ENV
|
echo "export AWS_SESSION_TOKEN=$(echo $CREDENTIALS | jq -r '.SessionToken')" >> $BASH_ENV
|
||||||
fi
|
fi
|
||||||
|
|
||||||
run-go-test-full:
|
run-go-test-full:
|
||||||
parameters:
|
parameters:
|
||||||
go_test_flags:
|
go_test_flags:
|
||||||
|
@ -134,15 +130,13 @@ commands:
|
||||||
- run:
|
- run:
|
||||||
name: go test
|
name: go test
|
||||||
command: |
|
command: |
|
||||||
mkdir -p $TEST_RESULTS_DIR /tmp/jsonfile
|
mkdir -p $TEST_RESULTS_DIR /tmp/jsonfile /tmp/coverage
|
||||||
PACKAGE_NAMES=$(go list -tags "$GOTAGS" ./... | circleci tests split --split-by=timings --timings-type=classname)
|
PACKAGE_NAMES=$(go list -tags "$GOTAGS" ./... | circleci tests split --split-by=timings --timings-type=classname)
|
||||||
echo "Running $(echo $PACKAGE_NAMES | wc -w) packages"
|
echo "Running $(echo $PACKAGE_NAMES | wc -w) packages"
|
||||||
echo $PACKAGE_NAMES
|
echo $PACKAGE_NAMES
|
||||||
# some tests expect this umask, and arm images have a different default
|
# some tests expect this umask, and arm images have a different default
|
||||||
umask 0022
|
umask 0022
|
||||||
|
|
||||||
<< parameters.go_test_flags >>
|
<< parameters.go_test_flags >>
|
||||||
|
|
||||||
gotestsum \
|
gotestsum \
|
||||||
--format=short-verbose \
|
--format=short-verbose \
|
||||||
--jsonfile /tmp/jsonfile/go-test-${CIRCLE_NODE_INDEX}.log \
|
--jsonfile /tmp/jsonfile/go-test-${CIRCLE_NODE_INDEX}.log \
|
||||||
|
@ -154,14 +148,17 @@ commands:
|
||||||
--junitfile $TEST_RESULTS_DIR/gotestsum-report.xml -- \
|
--junitfile $TEST_RESULTS_DIR/gotestsum-report.xml -- \
|
||||||
-tags="$GOTAGS" -p 2 \
|
-tags="$GOTAGS" -p 2 \
|
||||||
${GO_TEST_FLAGS-} \
|
${GO_TEST_FLAGS-} \
|
||||||
-cover -coverprofile=coverage.txt
|
-cover -coverprofile=/tmp/coverage/test-coverage-$CIRCLE_NODE_INDEX || true
|
||||||
|
|
||||||
- store_test_results:
|
- store_test_results:
|
||||||
path: *TEST_RESULTS_DIR
|
path: *TEST_RESULTS_DIR
|
||||||
- store_artifacts:
|
- store_artifacts:
|
||||||
path: *TEST_RESULTS_DIR
|
path: *TEST_RESULTS_DIR
|
||||||
- store_artifacts:
|
- store_artifacts:
|
||||||
path: /tmp/jsonfile
|
path: /tmp/jsonfile
|
||||||
|
- persist_to_workspace:
|
||||||
|
root: /tmp
|
||||||
|
paths:
|
||||||
|
- coverage
|
||||||
- run: &rerun-fails-report
|
- run: &rerun-fails-report
|
||||||
name: "Re-run fails report"
|
name: "Re-run fails report"
|
||||||
command: |
|
command: |
|
||||||
|
@ -280,7 +277,6 @@ jobs:
|
||||||
echo "Generated code was not updated correctly"
|
echo "Generated code was not updated correctly"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
go-test-arm64:
|
go-test-arm64:
|
||||||
machine:
|
machine:
|
||||||
image: *UBUNTU_CI_IMAGE
|
image: *UBUNTU_CI_IMAGE
|
||||||
|
@ -355,7 +351,6 @@ jobs:
|
||||||
-tags="$GOTAGS" -p 2 \
|
-tags="$GOTAGS" -p 2 \
|
||||||
-race -gcflags=all=-d=checkptr=0 \
|
-race -gcflags=all=-d=checkptr=0 \
|
||||||
$pkgs
|
$pkgs
|
||||||
|
|
||||||
- store_test_results:
|
- store_test_results:
|
||||||
path: *TEST_RESULTS_DIR
|
path: *TEST_RESULTS_DIR
|
||||||
- store_artifacts:
|
- store_artifacts:
|
||||||
|
@ -396,7 +391,6 @@ jobs:
|
||||||
--junitfile $TEST_RESULTS_DIR/gotestsum-report.xml -- \
|
--junitfile $TEST_RESULTS_DIR/gotestsum-report.xml -- \
|
||||||
-tags="$GOTAGS" -p 2 \
|
-tags="$GOTAGS" -p 2 \
|
||||||
-short
|
-short
|
||||||
|
|
||||||
- store_test_results:
|
- store_test_results:
|
||||||
path: *TEST_RESULTS_DIR
|
path: *TEST_RESULTS_DIR
|
||||||
- store_artifacts:
|
- store_artifacts:
|
||||||
|
@ -433,7 +427,6 @@ jobs:
|
||||||
--junitfile $TEST_RESULTS_DIR/gotestsum-report.xml -- \
|
--junitfile $TEST_RESULTS_DIR/gotestsum-report.xml -- \
|
||||||
-tags="$GOTAGS" -cover -coverprofile=coverage.txt \
|
-tags="$GOTAGS" -cover -coverprofile=coverage.txt \
|
||||||
./...
|
./...
|
||||||
|
|
||||||
- store_test_results:
|
- store_test_results:
|
||||||
path: *TEST_RESULTS_DIR
|
path: *TEST_RESULTS_DIR
|
||||||
- store_artifacts:
|
- store_artifacts:
|
||||||
|
@ -458,7 +451,6 @@ jobs:
|
||||||
target="./pkg/bin/${GOOS}_${GOARCH}/"
|
target="./pkg/bin/${GOOS}_${GOARCH}/"
|
||||||
GOOS="$os" CGO_ENABLED=0 go build -o "${target}" -ldflags "${GOLDFLAGS}" -tags "${GOTAGS}"
|
GOOS="$os" CGO_ENABLED=0 go build -o "${target}" -ldflags "${GOLDFLAGS}" -tags "${GOTAGS}"
|
||||||
done
|
done
|
||||||
|
|
||||||
# save dev build to CircleCI
|
# save dev build to CircleCI
|
||||||
- store_artifacts:
|
- store_artifacts:
|
||||||
path: ./pkg/bin
|
path: ./pkg/bin
|
||||||
|
@ -530,7 +522,6 @@ jobs:
|
||||||
make dev
|
make dev
|
||||||
mkdir -p /home/circleci/go/bin
|
mkdir -p /home/circleci/go/bin
|
||||||
cp ./bin/consul /home/circleci/go/bin/consul
|
cp ./bin/consul /home/circleci/go/bin/consul
|
||||||
|
|
||||||
# save dev build to pass to downstream jobs
|
# save dev build to pass to downstream jobs
|
||||||
- persist_to_workspace:
|
- persist_to_workspace:
|
||||||
root: /home/circleci/go/bin
|
root: /home/circleci/go/bin
|
||||||
|
@ -722,11 +713,9 @@ jobs:
|
||||||
if ! git diff --quiet --exit-code HEAD^! ui/; then
|
if ! git diff --quiet --exit-code HEAD^! ui/; then
|
||||||
git config --local user.email "github-team-consul-core@hashicorp.com"
|
git config --local user.email "github-team-consul-core@hashicorp.com"
|
||||||
git config --local user.name "hc-github-team-consul-core"
|
git config --local user.name "hc-github-team-consul-core"
|
||||||
|
|
||||||
# -B resets the CI branch to main which may diverge history
|
# -B resets the CI branch to main which may diverge history
|
||||||
# but we will force push anyways.
|
# but we will force push anyways.
|
||||||
git checkout -B ci/main-assetfs-build main
|
git checkout -B ci/main-assetfs-build main
|
||||||
|
|
||||||
short_sha=$(git rev-parse --short HEAD)
|
short_sha=$(git rev-parse --short HEAD)
|
||||||
git add agent/uiserver/dist/
|
git add agent/uiserver/dist/
|
||||||
git commit -m "auto-updated agent/uiserver/dist/ from commit ${short_sha}"
|
git commit -m "auto-updated agent/uiserver/dist/ from commit ${short_sha}"
|
||||||
|
@ -989,7 +978,6 @@ jobs:
|
||||||
fi
|
fi
|
||||||
echo "export LOCAL_COMMIT_SHA=${LOCAL_COMMIT_SHA}" >> $BASH_ENV
|
echo "export LOCAL_COMMIT_SHA=${LOCAL_COMMIT_SHA}" >> $BASH_ENV
|
||||||
git checkout ${LOCAL_COMMIT_SHA}
|
git checkout ${LOCAL_COMMIT_SHA}
|
||||||
|
|
||||||
short_ref=$(git rev-parse --short ${LOCAL_COMMIT_SHA})
|
short_ref=$(git rev-parse --short ${LOCAL_COMMIT_SHA})
|
||||||
echo "export TF_VAR_ami_owners=$LOAD_TEST_AMI_OWNERS" >> $BASH_ENV
|
echo "export TF_VAR_ami_owners=$LOAD_TEST_AMI_OWNERS" >> $BASH_ENV
|
||||||
echo "export TF_VAR_vpc_name=$short_ref" >> $BASH_ENV
|
echo "export TF_VAR_vpc_name=$short_ref" >> $BASH_ENV
|
||||||
|
@ -1036,6 +1024,83 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- run: "echo ok"
|
- run: "echo ok"
|
||||||
|
|
||||||
|
show-coverage:
|
||||||
|
docker:
|
||||||
|
- image: *GOLANG_IMAGE
|
||||||
|
steps:
|
||||||
|
- checkout
|
||||||
|
- attach_workspace:
|
||||||
|
at: /tmp
|
||||||
|
- run:
|
||||||
|
name: collate coverage output into single file and convert to readable format
|
||||||
|
command: |
|
||||||
|
mkdir -p /tmp/output
|
||||||
|
echo "mode: set" > cov.txt
|
||||||
|
for f in /tmp/coverage/*; do tail -n +2 $f >> cov.txt; done
|
||||||
|
go tool cover -func=cov.txt -o /tmp/output/coverage_by_function.txt
|
||||||
|
cp cov.txt /tmp/output/cov.txt
|
||||||
|
- run: sudo apt-get install jq
|
||||||
|
- run:
|
||||||
|
name: get diff of test coverage from changes
|
||||||
|
command: |
|
||||||
|
repository="consul"
|
||||||
|
file_url_response=$(curl --location --request GET "https://api.github.com/repos/hashicorp/$repository/contents/.github/cover.out?ref=$TEST_COVERAGE_GOLDEN_BRANCH" \
|
||||||
|
-u $GH_USER:$GH_TOKEN)
|
||||||
|
if [ $(echo $file_url_response | jq length) -eq 0 ]; then
|
||||||
|
echo "No coverage report file found"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
file_download_url=$(echo $file_url_response | jq -r '.download_url')
|
||||||
|
fi
|
||||||
|
echo "Downloading $file_download_url"
|
||||||
|
curl "$file_download_url" > main_cov.txt
|
||||||
|
echo "mode: set" > diff_cov.txt
|
||||||
|
comm -13 <(sort main_cov.txt) <(sort cov.txt) >> diff_cov.txt
|
||||||
|
go tool cover -html=diff_cov.txt -o /tmp/output/diff_coverage_heatmap.html
|
||||||
|
- store_artifacts:
|
||||||
|
path: /tmp/output
|
||||||
|
- run:
|
||||||
|
name: post results to GitHub PR
|
||||||
|
command: |
|
||||||
|
repository="consul"
|
||||||
|
pr_response=$(curl --location --request GET "https://api.github.com/repos/hashicorp/$repository/pulls?head=hashicorp:$CIRCLE_BRANCH&state=open" \
|
||||||
|
-u $GH_USER:$GH_TOKEN)
|
||||||
|
if [ $(echo $pr_response | jq length) -eq 0 ]; then
|
||||||
|
echo "No PR found to update"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
pr_comment_url=$(echo $pr_response | jq -r ".[]._links.comments.href")
|
||||||
|
fi
|
||||||
|
|
||||||
|
new_cov_percent=$(tail -1 /tmp/output/coverage_by_function.txt | awk -F' ' '{print $NF}')
|
||||||
|
go tool cover -func=main_cov.txt -o main_cov_by_func.txt
|
||||||
|
main_go_test_cov_percent=$(tail -1 main_cov_by_func.txt | awk -F' ' '{print $NF}')
|
||||||
|
artifacts=$(curl -X GET "https://circleci.com/api/v2/project/github/hashicorp/$repository/$CIRCLE_BUILD_NUM/artifacts" \
|
||||||
|
-H "Accept: application/json" \
|
||||||
|
-u "$CIRCLE_API_TOKEN:")
|
||||||
|
|
||||||
|
heatmap_url=$(echo $artifacts | jq -r '.items|.[]|select(.path | endswith("heatmap.html"))|.url')
|
||||||
|
|
||||||
|
message="All unit tests passed! Your changes bring test coverage over affected code to $new_cov_percent. Total coverage in main is $main_go_test_cov_percent. [See coverage delta for your changes]($heatmap_url)"
|
||||||
|
|
||||||
|
curl --location --request POST "$pr_comment_url" \
|
||||||
|
-u hc-github-team-consul-core:$HC_GITHUB_TEAM_CONSUL_CORE_GITHUB_TOKEN \
|
||||||
|
--header 'Content-Type: application/json' \
|
||||||
|
--data-raw '{
|
||||||
|
"body": "'"$message"'"
|
||||||
|
}'
|
||||||
|
- add_ssh_keys:
|
||||||
|
fingerprints:
|
||||||
|
- "b1:4d:ed:a5:4f:e1:39:28:37:ab:bd:4d:06:e5:24:ca"
|
||||||
|
- run:
|
||||||
|
name: push latest coverage results to github
|
||||||
|
command: |
|
||||||
|
cp cov.txt .github/go_test_coverage.txt
|
||||||
|
git config user.email "github-team-consul-core@hashicorp.com"
|
||||||
|
git config user.name "hc-github-team-consul-core"
|
||||||
|
git add .github/go_test_coverage.txt
|
||||||
|
git commit -m "[skip ci] update test coverage"
|
||||||
|
git push --set-upstream origin $CIRCLE_BRANCH
|
||||||
workflows:
|
workflows:
|
||||||
version: 2
|
version: 2
|
||||||
# verify-ci is a no-op workflow that must run on every PR. It is used in a
|
# verify-ci is a no-op workflow that must run on every PR. It is used in a
|
||||||
|
@ -1089,6 +1154,15 @@ workflows:
|
||||||
<<: *filter-ignore-non-go-branches
|
<<: *filter-ignore-non-go-branches
|
||||||
- go-test-race: *filter-ignore-non-go-branches
|
- go-test-race: *filter-ignore-non-go-branches
|
||||||
- go-test-32bit: *filter-ignore-non-go-branches
|
- go-test-32bit: *filter-ignore-non-go-branches
|
||||||
|
- show-coverage:
|
||||||
|
requires:
|
||||||
|
- go-test
|
||||||
|
filters:
|
||||||
|
branches:
|
||||||
|
ignore:
|
||||||
|
- main # we don't want tests run in main to overwrite coverage reports from the latest merge
|
||||||
|
- /^release\/.*$/ # we don't want to compare coverage on release branches
|
||||||
|
|
||||||
- noop
|
- noop
|
||||||
build-distros:
|
build-distros:
|
||||||
unless: << pipeline.parameters.trigger-load-test >>
|
unless: << pipeline.parameters.trigger-load-test >>
|
||||||
|
@ -1202,4 +1276,4 @@ workflows:
|
||||||
only:
|
only:
|
||||||
- main
|
- main
|
||||||
jobs:
|
jobs:
|
||||||
- load-test
|
- load-test
|
|
@ -0,0 +1 @@
|
||||||
|
go_test_coverage.txt binary
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue