Skip to content

Commit

Permalink
workflows: restrict coverage testing to changed packages
Browse files Browse the repository at this point in the history
This commit improves the code-cover-gen workflow to only run tests for
the changed packages; other packages won't show up in the review so
coverage data is not useful. This should speed up the build
significantly.
  • Loading branch information
RaduBerinde committed Aug 26, 2023
1 parent 1253033 commit 0b401ee
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 18 deletions.
42 changes: 24 additions & 18 deletions .github/workflows/code-cover-gen.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ jobs:
env:
PR: ${{ github.event.pull_request.number }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
GH_TOKEN: ${{ github.token }}
steps:
- uses: actions/checkout@v3
with:
Expand All @@ -30,33 +31,38 @@ jobs:
with:
go-version: "1.20"

- name: Get list of changed packages
shell: bash
run: |
set -euxo pipefail
# To get the base commit, we get the number of commits in the PR.
# Note that github.event.pull_request.base.sha is not what we want,
# that is the tip of master and not necessarily the PR fork point.
NUM_COMMITS=$(gh pr view $PR --json commits --jq '.commits | length')
BASE_SHA=$(git rev-parse HEAD~${NUM_COMMITS})
CHANGED_PKGS=$(scripts/changed-go-pkgs.sh ${BASE_SHA} ${HEAD_SHA})
echo "BASE_SHA=${BASE_SHA}" >> "${GITHUB_ENV}"
echo "CHANGED_PKGS=${CHANGED_PKGS}" >> "${GITHUB_ENV}"
- name: Generate "after" coverage
shell: bash
run: |
set -e
set -euxo pipefail
CHANGED_PKGS='${{ env.CHANGED_PKGS }}'
mkdir -p artifacts
make testcoverage COVER_PROFILE=artifacts/cover-after.out
go run github.com/cockroachdb/code-cov-utils/gocover2json@latest \
--trim-prefix github.com/cockroachdb/pebble/ \
artifacts/cover-after.out artifacts/cover-${PR}-${HEAD_SHA}.json
# Make a copy of the script so that the "before" run below uses the
# same version.
cp scripts/pr-codecov-run-tests.sh ${RUNNER_TEMP}/
${RUNNER_TEMP}/pr-codecov-run-tests.sh artifacts/cover-${PR}-${HEAD_SHA}.json "${CHANGED_PKGS}"
# Running the "before" coverage for each PR (rather than in a job that
# runs on push) is a little odd, but it allows restricting the packages on
# a per-PR basis (if it becomes necessary in the future).
- name: Generate "before" coverage
shell: bash
run: |
set -e
# Note that github.event.pull_request.base.sha is not what we want -
# it is the current master tip, not the commit this PR is actually
# based on.
BASE_SHA=$(git merge-base origin/master ${HEAD_SHA})
set -euxo pipefail
BASE_SHA='${{ env.BASE_SHA }}'
CHANGED_PKGS='${{ env.CHANGED_PKGS }}'
git checkout -f ${BASE_SHA}
make testcoverage COVER_PROFILE=artifacts/cover-before.out
SHA=$(git rev-parse HEAD)
go run github.com/cockroachdb/code-cov-utils/gocover2json@latest \
--trim-prefix github.com/cockroachdb/pebble/ \
artifacts/cover-before.out artifacts/cover-${PR}-${BASE_SHA}.json
${RUNNER_TEMP}/pr-codecov-run-tests.sh artifacts/cover-${PR}-${BASE_SHA}.json "${CHANGED_PKGS}"
- name: Upload artifacts
uses: actions/upload-artifact@v2
Expand Down
14 changes: 14 additions & 0 deletions scripts/changed-go-pkgs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env bash

BASE_SHA="$1"
HEAD_SHA="$2"

if [ -z "$HEAD_SHA" ];then
echo "Usage: $0 <base-sha> <head-sha>"
exit 1
fi

git diff --name-only "${BASE_SHA}..${HEAD_SHA}" -- "*.go" \
| xargs -rn1 dirname \
| sort -u \
| xargs echo
44 changes: 44 additions & 0 deletions scripts/pr-codecov-run-tests.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#!/usr/bin/env bash

# This script runs unit tests with coverage enabled for a specific list of
# package paths and outputs the coverage to a json file.
#
# Package paths that are not valid in this tree are tolerated.

set -xeuo pipefail

output_json_file="$1"
packages="$2"

# Find the targets. We need to convert from, e.g.
# . objstorage objstorage/objstorageprovider
# to
# . ./objstorage ./objstorage/objstorageprovider

paths=""
sep=""

for p in ${packages}; do
# Check that the path exists and contains Go files.
if ls "${p}"/*.go >/dev/null 2>&1; then
if [[ $p != "." ]]; then
p="./$p"
fi
paths="${paths}${sep}${p}"
sep=" "
fi
done

if [ -z "${paths}" ]; then
echo "Skipping"
touch "${output_json_file}"
exit 0
fi

tmpfile=$(mktemp --suffix -coverprofile)
trap 'rm -f "${tmpfile}"' EXIT

make testcoverage COVER_PROFILE="${tmpfile}" PKG="$paths"
go run github.com/cockroachdb/code-cov-utils/[email protected] \
--trim-prefix github.com/cockroachdb/pebble/ \
"${tmpfile}" "${output_json_file}"

0 comments on commit 0b401ee

Please sign in to comment.