Skip to content

Actions workflow to auto-remove unnecessary entries from .coveragerc #2

Actions workflow to auto-remove unnecessary entries from .coveragerc

Actions workflow to auto-remove unnecessary entries from .coveragerc #2

Workflow file for this run

name: Prune Codecov .coveragerc
on: # yamllint disable-line rule:truthy
pull_request:
branches:
- dev
paths:
- .github/workflows/codecov.yml
- script/check_coveragerc.py
schedule:
# Every Monday at 4am UTC
- cron: 0 4 * * 1
workflow_dispatch:
env:
GH_TOKEN: ${{ github.token }}
BRANCH_NAME: "prune_coveragerc_1"
USER_EMAIL: "41898282+github-actions[bot]@users.noreply.github.com"
USER_NAME: "github-actions[bot]"
PR_BODY: |
*This is an automatically generated pull request created by /.github/workflows/codecov.yml*
Hi! When analysing '.coveragerc', I found that some files were omitted from pytest coverage checks that didn't need to be.
This usually happens when those files already have a high or 100% coverage.
I created a branch to remove these entries. Please review and merge the branch if you agree.
Next time this workflow runs, it will automatically update the branch under the same PR, or recreate the branch or PR if they have been deleted.
CACHE_VERSION: 5
UV_CACHE_VERSION: 1
DEFAULT_PYTHON: "3.12"
ALL_PYTHON_VERSIONS: "['3.12']"
UV_CACHE_DIR: /tmp/uv-cache
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
info:
# This is a duplicate of the 'info' job in ci.yaml
name: Collect information & changes data
outputs:
# In case of issues with the partial run, use the following line instead:
# test_full_suite: 'true'
core: ${{ steps.core.outputs.changes }}
integrations_glob: ${{ steps.info.outputs.integrations_glob }}
integrations: ${{ steps.integrations.outputs.changes }}
pre-commit_cache_key: ${{ steps.generate_pre-commit_cache_key.outputs.key }}
python_cache_key: ${{ steps.generate_python_cache_key.outputs.key }}
requirements: ${{ steps.core.outputs.requirements }}
mariadb_groups: ${{ steps.info.outputs.mariadb_groups }}
postgresql_groups: ${{ steps.info.outputs.postgresql_groups }}
python_versions: ${{ steps.info.outputs.python_versions }}
test_full_suite: ${{ steps.info.outputs.test_full_suite }}
test_group_count: ${{ steps.info.outputs.test_group_count }}
test_groups: ${{ steps.info.outputs.test_groups }}
tests_glob: ${{ steps.info.outputs.tests_glob }}
tests: ${{ steps.info.outputs.tests }}
skip_coverage: ${{ steps.info.outputs.skip_coverage }}
runs-on: ubuntu-22.04
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.1.2
- name: Generate partial Python venv restore key
id: generate_python_cache_key
run: >-
echo "key=venv-${{ env.CACHE_VERSION }}-${{
hashFiles('requirements_test.txt') }}-${{
hashFiles('requirements_all.txt') }}-${{
hashFiles('homeassistant/package_constraints.txt') }}" >> $GITHUB_OUTPUT
- name: Generate partial pre-commit restore key
id: generate_pre-commit_cache_key
run: >-
echo "key=pre-commit-${{ env.CACHE_VERSION }}-${{
hashFiles('.pre-commit-config.yaml') }}" >> $GITHUB_OUTPUT
- name: Filter for core changes
uses: dorny/paths-filter@v3.0.2
id: core
with:
filters: .core_files.yaml
- name: Create a list of integrations to filter for changes
run: |
integrations=$(ls -Ad ./homeassistant/components/[!_]* | xargs -n 1 basename)
touch .integration_paths.yaml
for integration in $integrations; do
echo "${integration}: [homeassistant/components/${integration}/**, tests/components/${integration}/**]" \
>> .integration_paths.yaml;
done
echo "Result:"
cat .integration_paths.yaml
- name: Filter for integration changes
uses: dorny/paths-filter@v3.0.2
id: integrations
with:
filters: .integration_paths.yaml
- name: Collect additional information
id: info
run: |
# Defaults
integrations_glob=""
mariadb_groups=${MARIADB_VERSIONS}
postgresql_groups=${POSTGRESQL_VERSIONS}
test_full_suite="true"
test_groups="[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]"
test_group_count=10
tests="[]"
tests_glob=""
skip_coverage=""
if [[ "${{ steps.integrations.outputs.changes }}" != "[]" ]];
then
# Create a file glob for the integrations
integrations_glob=$(echo '${{ steps.integrations.outputs.changes }}' | jq -cSr '. | join(",")')
[[ "${integrations_glob}" == *","* ]] && integrations_glob="{${integrations_glob}}"
# Create list of testable integrations
possible_integrations=$(echo '${{ steps.integrations.outputs.changes }}' | jq -cSr '.[]')
tests=$(
for integration in ${possible_integrations};
do
if [[ -d "tests/components/${integration}" ]]; then
echo -n "\"${integration}\",";
fi;
done
)
[[ ! -z "${tests}" ]] && tests="${tests::-1}"
tests="[${tests}]"
test_groups="${tests}"
# Test group count should be 1, we don't split partial tests
test_group_count=1
# Create a file glob for the integrations tests
tests_glob=$(echo "${tests}" | jq -cSr '. | join(",")')
[[ "${tests_glob}" == *","* ]] && tests_glob="{${tests_glob}}"
mariadb_groups="[]"
postgresql_groups="[]"
test_full_suite="false"
fi
# We need to run the full suite on certain branches.
# Or, in case core files are touched, for the full suite as well.
if [[ "${{ github.ref }}" == "refs/heads/dev" ]] \
|| [[ "${{ github.ref }}" == "refs/heads/master" ]] \
|| [[ "${{ github.ref }}" == "refs/heads/rc" ]] \
|| [[ "${{ steps.core.outputs.any }}" == "true" ]] \
|| [[ "${{ github.event.inputs.full }}" == "true" ]] \
|| [[ "${{ contains(github.event.pull_request.labels.*.name, 'ci-full-run') }}" == "true" ]];
then
mariadb_groups=${MARIADB_VERSIONS}
postgresql_groups=${POSTGRESQL_VERSIONS}
test_groups="[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]"
test_group_count=10
test_full_suite="true"
fi
if [[ "${{ github.event.inputs.skip-coverage }}" == "true" ]] \
|| [[ "${{ contains(github.event.pull_request.labels.*.name, 'ci-skip-coverage') }}" == "true" ]];
then
skip_coverage="true"
fi
# Output & sent to GitHub Actions
echo "mariadb_groups: ${mariadb_groups}"
echo "mariadb_groups=${mariadb_groups}" >> $GITHUB_OUTPUT
echo "postgresql_groups: ${postgresql_groups}"
echo "postgresql_groups=${postgresql_groups}" >> $GITHUB_OUTPUT
echo "python_versions: ${ALL_PYTHON_VERSIONS}"
echo "python_versions=${ALL_PYTHON_VERSIONS}" >> $GITHUB_OUTPUT
echo "test_full_suite: ${test_full_suite}"
echo "test_full_suite=${test_full_suite}" >> $GITHUB_OUTPUT
echo "integrations_glob: ${integrations_glob}"
echo "integrations_glob=${integrations_glob}" >> $GITHUB_OUTPUT
echo "test_group_count: ${test_group_count}"
echo "test_group_count=${test_group_count}" >> $GITHUB_OUTPUT
echo "test_groups: ${test_groups}"
echo "test_groups=${test_groups}" >> $GITHUB_OUTPUT
echo "tests: ${tests}"
echo "tests=${tests}" >> $GITHUB_OUTPUT
echo "tests_glob: ${tests_glob}"
echo "tests_glob=${tests_glob}" >> $GITHUB_OUTPUT
echo "skip_coverage: ${skip_coverage}"
echo "skip_coverage=${skip_coverage}" >> $GITHUB_OUTPUT
base:
# This is a duplicate of the 'base' job in ci.yaml
name: Prepare dependencies
outputs:
python_version: ${{ steps.python.outputs.python-version }}
runs-on: ubuntu-22.04
needs: info
timeout-minutes: 60
strategy:
matrix:
python-version: ${{ fromJSON(needs.info.outputs.python_versions) }}
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.1.2
- name: Set up Python ${{ matrix.python-version }}
id: python
uses: actions/setup-python@v5.1.0
with:
python-version: ${{ matrix.python-version }}
check-latest: true
- name: Generate partial uv restore key
id: generate-uv-key
run: >-
echo "key=uv-${{ env.UV_CACHE_VERSION }}-${{
env.HA_SHORT_VERSION }}-$(date -u '+%Y-%m-%dT%H:%M:%s')" >> $GITHUB_OUTPUT
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache@v4.0.2
with:
path: venv
lookup-only: true
key: >-
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
needs.info.outputs.python_cache_key }}
- name: Restore uv wheel cache
if: steps.cache-venv.outputs.cache-hit != 'true'
uses: actions/cache@v4.0.2
with:
path: ${{ env.UV_CACHE_DIR }}
key: >-
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
steps.generate-uv-key.outputs.key }}
restore-keys: |
${{ runner.os }}-${{ steps.python.outputs.python-version }}-uv-${{ env.UV_CACHE_VERSION }}-${{ env.HA_SHORT_VERSION }}-
- name: Install additional OS dependencies
if: steps.cache-venv.outputs.cache-hit != 'true'
run: |
sudo apt-get update
sudo apt-get -y install \
bluez \
ffmpeg \
libavcodec-dev \
libavdevice-dev \
libavfilter-dev \
libavformat-dev \
libavutil-dev \
libswresample-dev \
libswscale-dev \
libudev-dev
- name: Create Python virtual environment
if: steps.cache-venv.outputs.cache-hit != 'true'
run: |
python -m venv venv
. venv/bin/activate
python --version
pip install "$(grep '^uv' < requirements_test.txt)"
uv pip install -U "pip>=21.3.1" setuptools wheel
uv pip install -r requirements_all.txt
uv pip install -r requirements_test.txt
uv pip install -e . --config-settings editable_mode=compat
prune-coveragerc-check:
name: Check and prune .coveragerc
runs-on: ubuntu-22.04
needs:
- info
- base
outputs:
changes: ${{ steps.detect.outputs.changes }}
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.1.2
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.0.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
- name: Restore full Python ${{ env.DEFAULT_PYTHON }} virtual environment
id: cache-venv
uses: actions/cache/restore@v4.0.2
with:
path: venv
fail-on-cache-miss: true
key: ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{ needs.info.outputs.python_cache_key }}
- name: Run pytest followed by coveragerc prune
run: |
. venv/bin/activate
python3 -m script.check_coveragerc
- name: Detect if anything was pruned
id: detect
run: |
change_count=$(git diff --numstat | wc -l)
echo "$change_count files changed"
echo "changes=$change_count" >> $GITHUB_OUTPUT
# Note: the steps below require GH actions permission to write to the repository
# (Settings > Actions > General > Workflow)
- name: Create branch and add ${{ steps.detect.outputs.changes }} files
if: steps.detect.outputs.changes > 0
run: |
git checkout -B ${{ env.BRANCH_NAME }}
git config --local user.email ${{ env.USER_EMAIL }}
git config --local user.name ${{ env.USER_NAME }}
git fetch origin dev
git add .coveragerc
git commit -m "Remove unnecessary .coveragerc entries"
git push --force --set-upstream origin ${{ env.BRANCH_NAME }}
- name: Check if PR already exists
id: check-pr
if: steps.detect.outputs.changes > 0
run: |
prs=$(gh pr list \
--head ${{ env.BRANCH_NAME }} \
--base dev \
--json title \
--jq 'length')
if ((prs > 0)); then
echo "skip=true" >> "$GITHUB_OUTPUT"
fi
- name: Create pull request
if: steps.detect.outputs.changes > 0 && steps.check-pr.outputs.skip != 'true'
# This step skips if the PR already exists, and correctly leaves
# the existing PR pointing the to branch we just made.
run: |
gh pr create \
--head ${{ env.BRANCH_NAME }} \
--base dev \
--title "Remove unnecessary .coveragerc entries" \
--body "${{ env.PR_BODY }}"