Skip to content

Add lower bound for all direct dependencies #1427

Add lower bound for all direct dependencies

Add lower bound for all direct dependencies #1427

Workflow file for this run

name: Code Coverage Assessment
# Run in addition to unit tests without coverage assessment in case of weirdness around
# parallelised code. Also regenerates coverage badge.
on:
push:
branches:
- main
pull_request:
branches:
- "**"
jobs:
coverage:
runs-on: ubuntu-latest
outputs:
percentage_int: ${{ steps.cov.outputs.percentage_int }}
percentage_float: ${{ steps.cov.outputs.percentage_float }}
steps:
- uses: actions/checkout@v4
- name: Set up base Python
uses: actions/setup-python@v5
with:
# Note that this is just the version of Python that we use to run `uv` with.
# `uv` manages its own version of Python.
# For speed, we use the same version for both, but in principle these could differ.
python-version: 3.12
- name: Set up uv cache directory location (Linux/Mac)
run: echo "UV_CACHE_DIR=${{ runner.temp }}/.uv-cache" >> $GITHUB_ENV
if: runner.os != 'Windows'
- name: Set up uv cache directory location (Windows)
run: echo "UV_CACHE_DIR=${{ runner.temp }}/.uv-cache" >> $env:GITHUB_ENV
if: runner.os == 'Windows'
- name: Restore uv cache
uses: actions/cache@v4
with:
path: ${{ env.UV_CACHE_DIR }}
key: uv-${{ runner.os }}-${{ hashFiles('uv.lock') }}-${{ matrix.python-version }}-test
restore-keys: |
uv-${{ runner.os }}-${{ hashFiles('uv.lock') }}-${{ matrix.python-version }}
uv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
uv-${{ runner.os }}
- name: Install latest versions of pip and uv
run: python -m pip install --upgrade pip uv
- name: Install test dependencies
run: uv sync --extra test --no-dev --locked
- name: Debug - uv pip freeze
run: uv pip freeze
- name: Assess coverage of unit tests
run: uv run pytest tests/unit --cov
- name: Extract total coverage percentage
id: cov
run: |
echo "percentage_int=$( uv run coverage report --format=total )" >> $GITHUB_OUTPUT
echo "percentage_float=$( uv run coverage report --format=total --precision=8 )" >> $GITHUB_OUTPUT
cat $GITHUB_OUTPUT
- name: Check out metadata repo
if: github.event_name == 'pull_request'
uses: actions/checkout@v4
with:
repository: gchq/coreax-metadata
# GitHub Actions require check out destination to be within coreax/coreax. To
# save checking out the main repo into coreax/coreax/coreax, check out the
# metadata repo to a nested location inside coreax/coreax. Pick a folder name
# that is very unlikely to clash with any current or future folder name
# committed to the main coreax repo.
path: tmp_coreax-metadata
- name: Check for reduction in coverage
if: github.event_name == 'pull_request'
env:
HISTORIC: tmp_coreax-metadata/coverage
run: |
# Create directory if it doesn't exist yet
mkdir -p $HISTORIC
uv run tests/coverage/compare.py \
${{ steps.cov.outputs.percentage_float }} \
$HISTORIC
- name: Minimize UV cache
run: uv cache prune --ci
if: always()
coverage-badge:
name: Update coverage badge
# Keep as a separate job to avoid clashes between meta and main repos
if: github.event_name == 'push'
# Push coverage badge config to coreax-metadata repo.
needs:
- coverage
env:
percentage_int: ${{ needs.coverage.outputs.percentage_int }}
percentage_float: ${{ needs.coverage.outputs.percentage_float }}
runs-on: ubuntu-latest
steps:
- name: Generate a GitHub token
id: generate-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ vars.WRITE_CONTENTS_PR_APP }}
private-key: ${{ secrets.WRITE_CONTENTS_PR_KEY }}
repositories: coreax-metadata
- name: Check out metadata repo
uses: actions/checkout@v4
with:
repository: gchq/coreax-metadata
- name: Generate high-precision coverage JSON
run: |
echo "{\"total\": ${{ env.percentage_float }}}" > $RUNNER_TEMP/coverage.json
- name: Save high-precision coverage data
env:
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
run: |
export message="chore: update precise coverage data for $GITHUB_SHA"
export content=$( base64 -i $RUNNER_TEMP/coverage.json )
OUT_NAME="coverage/coverage-$(date --utc +%Y-%m-%d--%H-%M-%S)--$GITHUB_SHA--v1.json"
gh api --method PUT \
/repos/:owner/coreax-metadata/contents/$OUT_NAME \
-f message="$message" \
-f content="$content"
- name: Choose badge colour
id: design
run: |
echo "colour=${{
env.percentage_int >= 90 && 'brightgreen' ||
env.percentage_int >= 70 && 'yellow' ||
env.percentage_int >= 50 && 'orange' ||
'red'
}}" >> $GITHUB_OUTPUT
- name: Generate badge config JSON
# Display an integer percentage
run: |
echo "coverage = ${{ env.percentage_int }}%"
echo "colour = ${{ steps.design.outputs.colour }}"
{
echo "{"
echo " \"schemaVersion\": 1,"
echo " \"label\": \"Coverage\","
echo " \"message\": \"${{ env.percentage_int }}%\","
echo " \"color\": \"${{ steps.design.outputs.colour }}\""
echo "}"
} > $RUNNER_TEMP/badge.json
- name: Commit badge (with signature)
# If another workflow is running in parallel, a race condition may occur. Try to
# push the updated badge three times before failing.
# Disable fail fast on shell and ensure script always returns an exit code.
shell: bash {0}
env:
BADGE_PATH: coverage/coreax_coverage.json
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
run: |
export message="chore: update coverage badge for $GITHUB_SHA"
export content=$( base64 -i $RUNNER_TEMP/badge.json )
# Create new file if does not exist yet (or did not exist at checkout)
if [ ! -f $BADGE_PATH ]; then
gh api --method PUT /repos/:owner/coreax-metadata/contents/$BADGE_PATH \
-f message="$message" \
-f content="$content"
if [ $? -eq 0 ]; then
echo "Coverage badge created."
exit 0
fi
# Failed to create, probably because a file of this name now exists, so
# continue
fi
# Update existing file, trying 3 times in case another job updates the
# coverage badge almost concurrently, which invalidates old SHA
for i in {1..3}; do
# Check whether file has changed
diff $BADGE_PATH $RUNNER_TEMP/badge.json
if [ $? -eq 0 ]; then
echo "Coverage badge unchanged."
exit 0
fi
# Changed: replace existing file
export sha=$( git rev-parse main:$BADGE_PATH )
gh api --method PUT /repos/:owner/coreax-metadata/contents/$BADGE_PATH \
-f message="$message" \
-f content="$content" \
-f sha="$sha"
if [ $? -eq 0 ]; then
echo "Coverage badge updated."
exit 0
fi
# Failed: remote has probably updated, so pull latest again
git pull
done
echo "Failed to update coverage badge after 3 attempts."
exit 1