Improve versioning #137
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# internal coverage with PR comment and badge v0.0.5 | |
# Note this works for public orgs but only for "internal" pull | |
# requests. In the case of fork PRs, there needs to be org-level | |
# github app with private key => ACCESS_TOKEN, with more job isolation | |
# and output passing in this workflow. | |
# | |
# This version has updated actions and coverage value regex, no fork isolation | |
# yet. Badge and comment job logic should be tuned for personal vs org use | |
# (fork PRs still needs the big refactor; see badge job comments below). | |
name: Coverage | |
on: | |
workflow_dispatch: | |
pull_request: | |
push: | |
branches: | |
- master | |
- develop | |
jobs: | |
pre_ci: | |
name: Prepare CI environment | |
runs-on: ubuntu-20.04 | |
outputs: | |
#commit_message: ${{ steps.get_commit_message.outputs.commit_message }} | |
branch: ${{ steps.extract_branch.outputs.branch }} | |
steps: | |
- name: Checkout Project | |
uses: actions/checkout@v4 | |
with: | |
# We need to fetch with a depth of 2 for pull_request so we can do HEAD^2 | |
fetch-depth: 2 | |
- name: Environment | |
run: | | |
bash -c set | |
#- name: "Get commit message" | |
#id: get_commit_message | |
#env: | |
#COMMIT_PUSH: ${{ github.event.head_commit.message }} | |
#run: | | |
#COMMIT_MESSAGE="${COMMIT_PUSH:-$(git log --format=%B -n 1 HEAD^2)}" | |
#echo "commit_message=${COMMIT_MESSAGE}" >> $GITHUB_OUTPUT | |
- name: Extract branch name | |
id: extract_branch | |
shell: bash | |
run: | | |
TMP_PULL_HEAD_REF="${{ github.head_ref }}" | |
TMP_GITHUB_REF="${GITHUB_REF#refs/heads/}" | |
EXPORT_VALUE="" | |
if [ "${TMP_PULL_HEAD_REF}" != "" ] | |
then | |
EXPORT_VALUE="${TMP_PULL_HEAD_REF}" | |
else | |
EXPORT_VALUE="${TMP_GITHUB_REF}" | |
fi | |
echo "branch=${EXPORT_VALUE}" >> $GITHUB_OUTPUT | |
base: | |
name: Base coverage | |
runs-on: ubuntu-20.04 | |
outputs: | |
base_branch: ${{ steps.get_base.outputs.base_branch }} | |
base_cov: ${{ steps.get_base.outputs.base_cov }} | |
steps: | |
- uses: actions/checkout@v3 | |
with: | |
ref: badges | |
path: badges | |
- name: Get base ref and coverage score | |
id: get_base | |
env: | |
FILE: 'test-coverage.txt' | |
working-directory: ./badges | |
shell: bash | |
run: | | |
TMP_PULL_BASE_REF="${{ github.base_ref }}" | |
TMP_GITHUB_REF="${GITHUB_REF#refs/heads/}" | |
EXPORT_VALUE="" | |
if [ "${TMP_PULL_BASE_REF}" != "" ] | |
then | |
EXPORT_VALUE="${TMP_PULL_BASE_REF}" | |
else | |
EXPORT_VALUE="${TMP_GITHUB_REF}" | |
fi | |
echo "base_branch=${EXPORT_VALUE}" >> $GITHUB_OUTPUT | |
if [ -f "${EXPORT_VALUE}/${FILE}" ] | |
then | |
echo "Base coverage found on ${EXPORT_VALUE}" | |
BASE_COV=$(cat "${EXPORT_VALUE}/${FILE}") | |
echo "Base coverage is: ${BASE_COV}" | |
echo "base_cov=${BASE_COV}" >> $GITHUB_OUTPUT | |
else | |
echo "Base coverage NOT found on ${EXPORT_VALUE}!!" | |
fi | |
check: | |
name: Pre CI check | |
runs-on: ubuntu-20.04 | |
needs: [pre_ci, base] | |
steps: | |
- name: Check github variables | |
# NOTE base coverage env var may be empty here | |
env: | |
#COMMIT_MESSAGE: ${{ needs.pre_ci.outputs.commit_message }} | |
EXPORT_VALUE: ${{ needs.pre_ci.outputs.branch }} | |
BASE_BRANCH: ${{ needs.base.outputs.base_branch }} | |
BASE_COVERAGE: ${{ needs.base.outputs.base_cov }} | |
run: | | |
#echo "Commit message: ${COMMIT_MESSAGE}" | |
echo "Export value (head_ref): ${EXPORT_VALUE}" | |
echo "Base value (base_ref): ${BASE_BRANCH}" | |
echo "Base coverage (percent): ${{ env.BASE_COVERAGE }}" | |
cov_data: | |
name: Generate test coverage data | |
runs-on: ubuntu-20.04 | |
needs: [check] | |
defaults: | |
run: | |
shell: bash | |
outputs: | |
coverage: ${{ steps.coverage.outputs.coverage }} | |
coverage-rounded-display: ${{ steps.coverage.outputs.coverage-rounded-display }} | |
env: | |
PLATFORM: ubuntu-20.04 | |
PYTHON: '3.11' | |
PYTHONIOENCODING: utf-8 | |
PIP_DOWNLOAD_CACHE: ${{ github.workspace }}/../.pip_download_cache | |
steps: | |
- uses: actions/checkout@v3 | |
with: | |
fetch-depth: 0 | |
- uses: actions/setup-python@v5 | |
with: | |
python-version: ${{ env.PYTHON }} | |
- name: Install redis (ubuntu) | |
run: | | |
sudo apt-get -qq update | |
sudo apt-get install -yqq redis-server | |
sudo systemctl stop redis | |
- name: Add python requirements | |
run: | | |
python -m pip install --upgrade pip | |
pip install tox | |
- name: Setup old python for test | |
uses: actions/setup-python@v5 | |
with: | |
python-version: 3.8 | |
- name: Generate coverage | |
run: | | |
tox -e coverage,py38,py311 | |
- name: Code Coverage Summary Report (data) | |
uses: irongut/[email protected] | |
with: | |
filename: coverage.xml | |
output: 'both' | |
- uses: actions/upload-artifact@v4 | |
with: | |
name: src_coverage_rpts | |
path: | | |
coverage.xml | |
code-coverage-results.txt | |
retention-days: 1 | |
- name: Check code coverage | |
id: coverage | |
env: | |
VALUE: "Branch Rate" | |
run: | | |
COVERAGE=$( cat code-coverage-results.txt | grep -e ^Summary | grep -o -E "${VALUE} = .{3}" | egrep -o '([0-9]+)' ) | |
echo "coverage=${COVERAGE}" >> $GITHUB_OUTPUT | |
echo "coverage-rounded-display=${COVERAGE}%" >> $GITHUB_OUTPUT | |
echo "Current coverage is: ${COVERAGE}%" | |
- name: Code Coverage Summary Report | |
uses: irongut/[email protected] | |
if: ${{ github.event_name == 'pull_request' }} | |
with: | |
filename: coverage.xml | |
format: 'markdown' | |
output: 'both' | |
- name: Add Coverage PR Comment | |
uses: marocchino/sticky-pull-request-comment@v2 | |
if: github.event_name == 'pull_request' && (github.event.pull_request.author_association == 'MEMBER' || github.actor == github.repository_owner) | |
with: | |
header: coverage | |
recreate: true | |
path: code-coverage-results.md | |
test: | |
name: Coverage check | |
runs-on: ubuntu-20.04 | |
needs: [cov_data, base] | |
outputs: | |
coverage: ${{ needs.cov_data.outputs.coverage }} | |
coverage-base: ${{ needs.base.outputs.base_cov }} | |
coverage-rounded-display: ${{ needs.cov_data.outputs.coverage-rounded-display }} | |
steps: | |
- name: Check test coverage | |
env: | |
COVERAGE: ${{ needs.cov_data.outputs.coverage }} | |
COVERAGE_ROUNDED: ${{ needs.cov_data.outputs.coverage-rounded-display }} | |
BASE_COVERAGE: ${{ needs.base.outputs.base_cov }} | |
MEMBER: ${{ github.event.pull_request.author_association }} | |
run: | | |
echo "Coverage: ${COVERAGE}" | |
echo "Coverage Rounded: ${COVERAGE_ROUNDED}" | |
echo "Coverage on Base Branch: ${BASE_COVERAGE}" | |
echo "Author assoc: ${MEMBER}" | |
comment_cov_change: | |
name: Comment on PR with coverage delta | |
runs-on: ubuntu-20.04 | |
needs: [test, base] | |
steps: | |
- name: Environment | |
run: | | |
bash -c set | |
- name: Set whether base coverage was found | |
shell: bash | |
env: | |
BASE: ${{ needs.test.outputs.coverage-base }} | |
run: | | |
if [ -n "${BASE}" ] | |
then | |
BASE_RESULT="true" | |
else | |
BASE_RESULT="false" | |
fi | |
echo "HAVE_BASE_COVERAGE is ${BASE_RESULT}" | |
echo "HAVE_BASE_COVERAGE=${BASE_RESULT}" >> $GITHUB_ENV | |
echo "BASE_COVERAGE=${BASE}" >> $GITHUB_ENV | |
- name: Collect variables and construct comment for delta message | |
if: env.HAVE_BASE_COVERAGE == 'true' | |
shell: bash | |
env: | |
BASE_BRANCH: ${{ needs.base.outputs.base_branch }} | |
COVERAGE: ${{ needs.test.outputs.coverage }} | |
BASE_COVERAGE: ${{ needs.test.outputs.coverage-base }} | |
DELTA_WORD: "not change" | |
RATE: "Branch Rate" | |
run: | | |
if [ "${COVERAGE}" -gt "${BASE_COVERAGE}" ] | |
then | |
DELTA_WORD="increase" | |
elif [ "${COVERAGE}" -lt "${BASE_COVERAGE}" ] | |
then | |
DELTA_WORD="decrease" | |
fi | |
CHG=$(( COVERAGE - BASE_COVERAGE )) | |
CHG="${CHG/-/}" | |
echo "" > coverage-delta.md | |
echo "Hello @${{ github.actor }}! Thanks for opening this PR. We found the following information based on analysis of the coverage report:" >> coverage-delta.md | |
echo "" >> coverage-delta.md | |
echo "__Base__ ${RATE} coverage is __${BASE_COVERAGE}%__" >> coverage-delta.md | |
if [ "${CHG}" = "0" ] | |
then | |
echo "Merging ${{ github.sha }} into ${BASE_BRANCH} will __${DELTA_WORD}__ coverage" >> coverage-delta.md | |
else | |
echo "Merging ${{ github.sha }} into ${BASE_BRANCH} will __${DELTA_WORD}__ coverage by __${CHG}%__" >> coverage-delta.md | |
fi | |
if ! [ "${DELTA_WORD}" = "decrease" ] | |
then | |
echo "" >> coverage-delta.md | |
echo "Nice work, @${{ github.actor }}. Cheers! :beers:" >> coverage-delta.md | |
fi | |
- name: Comment PR with test coverage delta | |
uses: marocchino/sticky-pull-request-comment@v2 | |
if: env.HAVE_BASE_COVERAGE == 'true' && (github.event.pull_request.author_association == 'MEMBER' || github.actor == github.repository_owner) | |
with: | |
header: delta | |
recreate: true | |
path: coverage-delta.md | |
badge: | |
# Only generate and publish if these conditions are met: | |
# - The test step ended successfully | |
# - One of these is met: | |
# - This is a push event and the push event is on branch 'main' or 'develop' | |
# Note: if this repo is personal (ie, not an org repo) then you can | |
# use the following to change the scope of the next 2 jobs | |
# instead of running on branch push as shown below: | |
# - This is a pull request event and the pull actor is the same as the repo owner | |
# if: ${{ ( github.event_name == 'pull_request' && github.actor == github.repository_owner ) || github.ref == 'refs/heads/main' }} | |
name: Generate badge image with test coverage value | |
runs-on: ubuntu-20.04 | |
needs: [test, pre_ci] | |
if: github.event_name == 'push' | |
outputs: | |
url: ${{ steps.url.outputs.url }} | |
markdown: ${{ steps.url.outputs.markdown }} | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
ref: badges | |
path: badges | |
# Use the output from the `coverage` step | |
- name: Generate the badge SVG image | |
uses: emibcn/[email protected] | |
id: badge | |
with: | |
label: 'Branch Coverage' | |
status: ${{ needs.test.outputs.coverage-rounded-display }} | |
color: ${{ | |
needs.test.outputs.coverage > 90 && 'green' || | |
needs.test.outputs.coverage > 80 && 'yellow,green' || | |
needs.test.outputs.coverage > 70 && 'yellow' || | |
needs.test.outputs.coverage > 60 && 'orange,yellow' || | |
needs.test.outputs.coverage > 50 && 'orange' || | |
needs.test.outputs.coverage > 40 && 'red,orange' || | |
needs.test.outputs.coverage > 30 && 'red,red,orange' || | |
needs.test.outputs.coverage > 20 && 'red,red,red,orange' || | |
'red' }} | |
path: badges/test-coverage.svg | |
- name: Commit badge and data | |
env: | |
BRANCH: ${{ needs.pre_ci.outputs.branch }} | |
COVERAGE: ${{ needs.test.outputs.coverage }} | |
FILE: 'test-coverage.svg' | |
DATA: 'test-coverage.txt' | |
working-directory: ./badges | |
run: | | |
git config --local user.email "[email protected]" | |
git config --local user.name "GitHub Action" | |
mkdir -p "${BRANCH}" | |
mv "${FILE}" "${BRANCH}" | |
echo "${COVERAGE}" > "${BRANCH}/${DATA}" | |
git add "${BRANCH}/${FILE}" "${BRANCH}/${DATA}" | |
# Will give error if badge has not changed | |
git commit -m "Add/Update badge" || true | |
- name: Push badge commit | |
uses: ad-m/github-push-action@master | |
with: | |
github_token: ${{ secrets.GITHUB_TOKEN }} | |
branch: badges | |
directory: badges |