Refactor CI (#74014)

This commit is contained in:
Franck Nijhof 2022-07-07 18:53:24 +02:00 committed by GitHub
parent 1dd9e705f2
commit 68ccb96089
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 241 additions and 245 deletions

View File

@ -20,8 +20,8 @@ on:
type: boolean type: boolean
env: env:
CACHE_VERSION: 10 CACHE_VERSION: 0
PIP_CACHE_VERSION: 4 PIP_CACHE_VERSION: 0
HA_SHORT_VERSION: 2022.8 HA_SHORT_VERSION: 2022.8
DEFAULT_PYTHON: 3.9 DEFAULT_PYTHON: 3.9
PRE_COMMIT_CACHE: ~/.cache/pre-commit PRE_COMMIT_CACHE: ~/.cache/pre-commit
@ -35,24 +35,38 @@ concurrency:
cancel-in-progress: true cancel-in-progress: true
jobs: jobs:
changes: info:
name: Determine what has changed name: Collect information & changes data
outputs: outputs:
# In case of issues with the partial run, use the following line instead: # In case of issues with the partial run, use the following line instead:
# test_full_suite: 'true' # test_full_suite: 'true'
test_full_suite: ${{ steps.info.outputs.test_full_suite }}
core: ${{ steps.core.outputs.changes }} core: ${{ steps.core.outputs.changes }}
integrations: ${{ steps.integrations.outputs.changes }}
integrations_glob: ${{ steps.info.outputs.integrations_glob }} integrations_glob: ${{ steps.info.outputs.integrations_glob }}
tests: ${{ steps.info.outputs.tests }} integrations: ${{ steps.integrations.outputs.changes }}
tests_glob: ${{ steps.info.outputs.tests_glob }} pre-commit_cache_key: ${{ steps.generate_pre-commit_cache_key.outputs.key }}
test_groups: ${{ steps.info.outputs.test_groups }} python_cache_key: ${{ steps.generate_python_cache_key.outputs.key }}
test_group_count: ${{ steps.info.outputs.test_group_count }}
requirements: ${{ steps.core.outputs.requirements }} requirements: ${{ steps.core.outputs.requirements }}
runs-on: ubuntu-latest 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 }}
runs-on: ubuntu-20.04
steps: steps:
- name: Check out code from GitHub - name: Check out code from GitHub
uses: actions/checkout@v3.0.2 uses: actions/checkout@v3.0.2
- name: Generate partial Python venv restore key
id: generate_python_cache_key
run: >-
echo "::set-output name=key::venv-${{ env.CACHE_VERSION }}-${{
hashFiles('requirements_test.txt') }}-${{
hashFiles('requirements_all.txt') }}-${{
hashFiles('homeassistant/package_constraints.txt') }}"
- name: Generate partial pre-commit restore key
id: generate_pre-commit_cache_key
run: >-
echo "::set-output name=key::${{ env.CACHE_VERSION }}-${{ env.DEFAULT_PYTHON }}-${{
hashFiles('.pre-commit-config.yaml') }}"
- name: Filter for core changes - name: Filter for core changes
uses: dorny/paths-filter@v2.10.2 uses: dorny/paths-filter@v2.10.2
id: core id: core
@ -142,15 +156,11 @@ jobs:
echo "tests_glob: ${tests_glob}" echo "tests_glob: ${tests_glob}"
echo "::set-output name=tests_glob::${tests_glob}" echo "::set-output name=tests_glob::${tests_glob}"
# Separate job to pre-populate the base dependency cache pre-commit:
# This prevent upcoming jobs to do the same individually name: Prepare pre-commit base
prepare-base: runs-on: ubuntu-20.04
name: Prepare base dependencies needs:
runs-on: ubuntu-latest - info
timeout-minutes: 20
outputs:
python-key: ${{ steps.generate-python-key.outputs.key }}
pre-commit-key: ${{ steps.generate-pre-commit-key.outputs.key }}
steps: steps:
- name: Check out code from GitHub - name: Check out code from GitHub
uses: actions/checkout@v3.0.2 uses: actions/checkout@v3.0.2
@ -159,67 +169,26 @@ jobs:
uses: actions/setup-python@v4.0.0 uses: actions/setup-python@v4.0.0
with: with:
python-version: ${{ env.DEFAULT_PYTHON }} python-version: ${{ env.DEFAULT_PYTHON }}
- name: Generate partial Python venv restore key cache: "pip"
id: generate-python-key
run: >-
echo "::set-output name=key::base-venv-${{ env.CACHE_VERSION }}-${{
hashFiles('requirements.txt') }}-${{
hashFiles('requirements_test.txt') }}-${{
hashFiles('homeassistant/package_constraints.txt') }}"
- name: Generate partial pip restore key
id: generate-pip-key
run: >-
echo "::set-output name=key::base-pip-${{ env.PIP_CACHE_VERSION }}-${{
env.HA_SHORT_VERSION }}-$(date -u '+%Y-%m-%dT%H:%M:%s')"
- name: Restore base Python virtual environment - name: Restore base Python virtual environment
id: cache-venv id: cache-venv
uses: actions/cache@v3.0.4 uses: actions/cache@v3.0.4
with: with:
path: venv path: venv
key: >- key: ${{ runner.os }}-venv-${{ needs.info.outputs.pre-commit_cache_key }}
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
steps.generate-python-key.outputs.key }}
# Temporary disabling the restore of environments when bumping
# a dependency. It seems that we are experiencing issues with
# restoring environments in GitHub Actions, although unclear why.
# First attempt: https://github.com/home-assistant/core/pull/62383
#
# restore-keys: |
# ${{ runner.os }}-${{ steps.python.outputs.python-version }}-base-venv-${{ env.CACHE_VERSION }}-${{ hashFiles('requirements.txt') }}-${{ hashFiles('requirements_test.txt') }}-
# ${{ runner.os }}-${{ steps.python.outputs.python-version }}-base-venv-${{ env.CACHE_VERSION }}-${{ hashFiles('requirements.txt') }}-
# ${{ runner.os }}-${{ steps.python.outputs.python-version }}-base-venv-${{ env.CACHE_VERSION }}-
- name: Restore pip wheel cache
if: steps.cache-venv.outputs.cache-hit != 'true'
uses: actions/cache@v3.0.4
with:
path: ${{ env.PIP_CACHE }}
key: >-
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
steps.generate-pip-key.outputs.key }}
restore-keys: |
${{ runner.os }}-${{ steps.python.outputs.python-version }}-base-pip-${{ env.PIP_CACHE_VERSION }}-${{ env.HA_SHORT_VERSION }}-
- name: Create Python virtual environment - name: Create Python virtual environment
if: steps.cache-venv.outputs.cache-hit != 'true' if: steps.cache-venv.outputs.cache-hit != 'true'
run: | run: |
python -m venv venv python -m venv venv
. venv/bin/activate . venv/bin/activate
python --version python --version
pip install --cache-dir=$PIP_CACHE -U "pip>=21.0,<22.2" setuptools wheel pip install "$(cat requirements_test.txt | grep pre-commit)"
pip install --cache-dir=$PIP_CACHE -r requirements.txt -r requirements_test.txt --use-deprecated=legacy-resolver
- name: Generate partial pre-commit restore key
id: generate-pre-commit-key
run: >-
echo "::set-output name=key::pre-commit-${{ env.CACHE_VERSION }}-${{
hashFiles('.pre-commit-config.yaml') }}"
- name: Restore pre-commit environment from cache - name: Restore pre-commit environment from cache
id: cache-precommit id: cache-precommit
uses: actions/cache@v3.0.4 uses: actions/cache@v3.0.4
with: with:
path: ${{ env.PRE_COMMIT_CACHE }} path: ${{ env.PRE_COMMIT_CACHE }}
key: >- key: ${{ runner.os }}-pre-commit-${{ needs.info.outputs.pre-commit_cache_key }}
${{ runner.os }}-${{ steps.generate-pre-commit-key.outputs.key }}
restore-keys: |
${{ runner.os }}-pre-commit-${{ env.CACHE_VERSION }}-
- name: Install pre-commit dependencies - name: Install pre-commit dependencies
if: steps.cache-precommit.outputs.cache-hit != 'true' if: steps.cache-precommit.outputs.cache-hit != 'true'
run: | run: |
@ -228,10 +197,10 @@ jobs:
lint-black: lint-black:
name: Check black name: Check black
runs-on: ubuntu-latest runs-on: ubuntu-20.04
needs: needs:
- changes - info
- prepare-base - pre-commit
steps: steps:
- name: Check out code from GitHub - name: Check out code from GitHub
uses: actions/checkout@v3.0.2 uses: actions/checkout@v3.0.2
@ -245,8 +214,7 @@ jobs:
uses: actions/cache@v3.0.4 uses: actions/cache@v3.0.4
with: with:
path: venv path: venv
key: ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{ key: ${{ runner.os }}-venv-${{ needs.info.outputs.pre-commit_cache_key }}
needs.prepare-base.outputs.python-key }}
- name: Fail job if Python cache restore failed - name: Fail job if Python cache restore failed
if: steps.cache-venv.outputs.cache-hit != 'true' if: steps.cache-venv.outputs.cache-hit != 'true'
run: | run: |
@ -257,31 +225,31 @@ jobs:
uses: actions/cache@v3.0.4 uses: actions/cache@v3.0.4
with: with:
path: ${{ env.PRE_COMMIT_CACHE }} path: ${{ env.PRE_COMMIT_CACHE }}
key: ${{ runner.os }}-${{ needs.prepare-base.outputs.pre-commit-key }} key: ${{ runner.os }}-pre-commit-${{ needs.info.outputs.pre-commit_cache_key }}
- name: Fail job if pre-commit cache restore failed - name: Fail job if pre-commit cache restore failed
if: steps.cache-precommit.outputs.cache-hit != 'true' if: steps.cache-precommit.outputs.cache-hit != 'true'
run: | run: |
echo "Failed to restore pre-commit environment from cache" echo "Failed to restore pre-commit environment from cache"
exit 1 exit 1
- name: Run black (fully) - name: Run black (fully)
if: needs.changes.outputs.test_full_suite == 'true' if: needs.info.outputs.test_full_suite == 'true'
run: | run: |
. venv/bin/activate . venv/bin/activate
pre-commit run --hook-stage manual black --all-files --show-diff-on-failure pre-commit run --hook-stage manual black --all-files --show-diff-on-failure
- name: Run black (partially) - name: Run black (partially)
if: needs.changes.outputs.test_full_suite == 'false' if: needs.info.outputs.test_full_suite == 'false'
shell: bash shell: bash
run: | run: |
. venv/bin/activate . venv/bin/activate
shopt -s globstar shopt -s globstar
pre-commit run --hook-stage manual black --files {homeassistant,tests}/components/${{ needs.changes.outputs.integrations_glob }}/**/* --show-diff-on-failure pre-commit run --hook-stage manual black --files {homeassistant,tests}/components/${{ needs.info.outputs.integrations_glob }}/**/* --show-diff-on-failure
lint-flake8: lint-flake8:
name: Check flake8 name: Check flake8
runs-on: ubuntu-latest runs-on: ubuntu-20.04
needs: needs:
- changes - info
- prepare-base - pre-commit
steps: steps:
- name: Check out code from GitHub - name: Check out code from GitHub
uses: actions/checkout@v3.0.2 uses: actions/checkout@v3.0.2
@ -295,8 +263,7 @@ jobs:
uses: actions/cache@v3.0.4 uses: actions/cache@v3.0.4
with: with:
path: venv path: venv
key: ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{ key: ${{ runner.os }}-venv-${{ needs.info.outputs.pre-commit_cache_key }}
needs.prepare-base.outputs.python-key }}
- name: Fail job if Python cache restore failed - name: Fail job if Python cache restore failed
if: steps.cache-venv.outputs.cache-hit != 'true' if: steps.cache-venv.outputs.cache-hit != 'true'
run: | run: |
@ -307,7 +274,7 @@ jobs:
uses: actions/cache@v3.0.4 uses: actions/cache@v3.0.4
with: with:
path: ${{ env.PRE_COMMIT_CACHE }} path: ${{ env.PRE_COMMIT_CACHE }}
key: ${{ runner.os }}-${{ needs.prepare-base.outputs.pre-commit-key }} key: ${{ runner.os }}-pre-commit-${{ needs.info.outputs.pre-commit_cache_key }}
- name: Fail job if pre-commit cache restore failed - name: Fail job if pre-commit cache restore failed
if: steps.cache-precommit.outputs.cache-hit != 'true' if: steps.cache-precommit.outputs.cache-hit != 'true'
run: | run: |
@ -317,22 +284,24 @@ jobs:
run: | run: |
echo "::add-matcher::.github/workflows/matchers/flake8.json" echo "::add-matcher::.github/workflows/matchers/flake8.json"
- name: Run flake8 (fully) - name: Run flake8 (fully)
if: needs.changes.outputs.test_full_suite == 'true' if: needs.info.outputs.test_full_suite == 'true'
run: | run: |
. venv/bin/activate . venv/bin/activate
pre-commit run --hook-stage manual flake8 --all-files pre-commit run --hook-stage manual flake8 --all-files
- name: Run flake8 (partially) - name: Run flake8 (partially)
if: needs.changes.outputs.test_full_suite == 'false' if: needs.info.outputs.test_full_suite == 'false'
shell: bash shell: bash
run: | run: |
. venv/bin/activate . venv/bin/activate
shopt -s globstar shopt -s globstar
pre-commit run --hook-stage manual flake8 --files {homeassistant,tests}/components/${{ needs.changes.outputs.integrations_glob }}/**/* pre-commit run --hook-stage manual flake8 --files {homeassistant,tests}/components/${{ needs.info.outputs.integrations_glob }}/**/*
lint-isort: lint-isort:
name: Check isort name: Check isort
runs-on: ubuntu-latest runs-on: ubuntu-20.04
needs: prepare-base needs:
- info
- pre-commit
steps: steps:
- name: Check out code from GitHub - name: Check out code from GitHub
uses: actions/checkout@v3.0.2 uses: actions/checkout@v3.0.2
@ -346,8 +315,7 @@ jobs:
uses: actions/cache@v3.0.4 uses: actions/cache@v3.0.4
with: with:
path: venv path: venv
key: ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{ key: ${{ runner.os }}-venv-${{ needs.info.outputs.pre-commit_cache_key }}
needs.prepare-base.outputs.python-key }}
- name: Fail job if Python cache restore failed - name: Fail job if Python cache restore failed
if: steps.cache-venv.outputs.cache-hit != 'true' if: steps.cache-venv.outputs.cache-hit != 'true'
run: | run: |
@ -358,7 +326,7 @@ jobs:
uses: actions/cache@v3.0.4 uses: actions/cache@v3.0.4
with: with:
path: ${{ env.PRE_COMMIT_CACHE }} path: ${{ env.PRE_COMMIT_CACHE }}
key: ${{ runner.os }}-${{ needs.prepare-base.outputs.pre-commit-key }} key: ${{ runner.os }}-pre-commit-${{ needs.info.outputs.pre-commit_cache_key }}
- name: Fail job if pre-commit cache restore failed - name: Fail job if pre-commit cache restore failed
if: steps.cache-precommit.outputs.cache-hit != 'true' if: steps.cache-precommit.outputs.cache-hit != 'true'
run: | run: |
@ -371,10 +339,10 @@ jobs:
lint-other: lint-other:
name: Check other linters name: Check other linters
runs-on: ubuntu-latest runs-on: ubuntu-20.04
needs: needs:
- changes - info
- prepare-base - pre-commit
steps: steps:
- name: Check out code from GitHub - name: Check out code from GitHub
uses: actions/checkout@v3.0.2 uses: actions/checkout@v3.0.2
@ -388,8 +356,7 @@ jobs:
uses: actions/cache@v3.0.4 uses: actions/cache@v3.0.4
with: with:
path: venv path: venv
key: ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{ key: ${{ runner.os }}-venv-${{ needs.info.outputs.pre-commit_cache_key }}
needs.prepare-base.outputs.python-key }}
- name: Fail job if Python cache restore failed - name: Fail job if Python cache restore failed
if: steps.cache-venv.outputs.cache-hit != 'true' if: steps.cache-venv.outputs.cache-hit != 'true'
run: | run: |
@ -400,7 +367,7 @@ jobs:
uses: actions/cache@v3.0.4 uses: actions/cache@v3.0.4
with: with:
path: ${{ env.PRE_COMMIT_CACHE }} path: ${{ env.PRE_COMMIT_CACHE }}
key: ${{ runner.os }}-${{ needs.prepare-base.outputs.pre-commit-key }} key: ${{ runner.os }}-pre-commit-${{ needs.info.outputs.pre-commit_cache_key }}
- name: Fail job if pre-commit cache restore failed - name: Fail job if pre-commit cache restore failed
if: steps.cache-precommit.outputs.cache-hit != 'true' if: steps.cache-precommit.outputs.cache-hit != 'true'
run: | run: |
@ -408,17 +375,17 @@ jobs:
exit 1 exit 1
- name: Run pyupgrade (fully) - name: Run pyupgrade (fully)
if: needs.changes.outputs.test_full_suite == 'true' if: needs.info.outputs.test_full_suite == 'true'
run: | run: |
. venv/bin/activate . venv/bin/activate
pre-commit run --hook-stage manual pyupgrade --all-files --show-diff-on-failure pre-commit run --hook-stage manual pyupgrade --all-files --show-diff-on-failure
- name: Run pyupgrade (partially) - name: Run pyupgrade (partially)
if: needs.changes.outputs.test_full_suite == 'false' if: needs.info.outputs.test_full_suite == 'false'
shell: bash shell: bash
run: | run: |
. venv/bin/activate . venv/bin/activate
shopt -s globstar shopt -s globstar
pre-commit run --hook-stage manual pyupgrade --files {homeassistant,tests}/components/${{ needs.changes.outputs.integrations_glob }}/**/* --show-diff-on-failure pre-commit run --hook-stage manual pyupgrade --files {homeassistant,tests}/components/${{ needs.info.outputs.integrations_glob }}/**/* --show-diff-on-failure
- name: Register yamllint problem matcher - name: Register yamllint problem matcher
run: | run: |
@ -437,17 +404,17 @@ jobs:
pre-commit run --hook-stage manual check-json --all-files pre-commit run --hook-stage manual check-json --all-files
- name: Run prettier (fully) - name: Run prettier (fully)
if: needs.changes.outputs.test_full_suite == 'true' if: needs.info.outputs.test_full_suite == 'true'
run: | run: |
. venv/bin/activate . venv/bin/activate
pre-commit run --hook-stage manual prettier --all-files pre-commit run --hook-stage manual prettier --all-files
- name: Run prettier (partially) - name: Run prettier (partially)
if: needs.changes.outputs.test_full_suite == 'false' if: needs.info.outputs.test_full_suite == 'false'
shell: bash shell: bash
run: | run: |
. venv/bin/activate . venv/bin/activate
pre-commit run --hook-stage manual prettier --files {homeassistant,tests}/components/${{ needs.changes.outputs.integrations_glob }}/**/* pre-commit run --hook-stage manual prettier --files {homeassistant,tests}/components/${{ needs.info.outputs.integrations_glob }}/**/*
- name: Register check executables problem matcher - name: Register check executables problem matcher
run: | run: |
@ -478,36 +445,105 @@ jobs:
args: hadolint Dockerfile.dev args: hadolint Dockerfile.dev
- name: Run bandit (fully) - name: Run bandit (fully)
if: needs.changes.outputs.test_full_suite == 'true' if: needs.info.outputs.test_full_suite == 'true'
run: | run: |
. venv/bin/activate . venv/bin/activate
pre-commit run --hook-stage manual bandit --all-files --show-diff-on-failure pre-commit run --hook-stage manual bandit --all-files --show-diff-on-failure
- name: Run bandit (partially) - name: Run bandit (partially)
if: needs.changes.outputs.test_full_suite == 'false' if: needs.info.outputs.test_full_suite == 'false'
shell: bash shell: bash
run: | run: |
. venv/bin/activate . venv/bin/activate
shopt -s globstar shopt -s globstar
pre-commit run --hook-stage manual bandit --files {homeassistant,tests}/components/${{ needs.changes.outputs.integrations_glob }}/**/* --show-diff-on-failure pre-commit run --hook-stage manual bandit --files {homeassistant,tests}/components/${{ needs.info.outputs.integrations_glob }}/**/* --show-diff-on-failure
hassfest: base:
name: Check hassfest name: Prepare dependencies
runs-on: ubuntu-latest runs-on: ubuntu-20.04
needs: prepare-tests needs: info
timeout-minutes: 60
strategy: strategy:
matrix: matrix:
python-version: [3.9] python-version: ["3.9", "3.10"]
container: homeassistant/ci-azure:${{ matrix.python-version }}
steps: steps:
- name: Check out code from GitHub - name: Check out code from GitHub
uses: actions/checkout@v3.0.2 uses: actions/checkout@v3.0.2
- name: Restore full Python ${{ matrix.python-version }} virtual environment - name: Set up Python ${{ matrix.python-version }}
id: python
uses: actions/setup-python@v4.0.0
with:
python-version: ${{ matrix.python-version }}
- name: Generate partial pip restore key
id: generate-pip-key
run: >-
echo "::set-output name=key::pip-${{ env.PIP_CACHE_VERSION }}-${{
env.HA_SHORT_VERSION }}-$(date -u '+%Y-%m-%dT%H:%M:%s')"
- name: Restore base Python virtual environment
id: cache-venv id: cache-venv
uses: actions/cache@v3.0.4 uses: actions/cache@v3.0.4
with: with:
path: venv path: venv
key: ${{ runner.os }}-${{ matrix.python-version }}-${{ key: >-
needs.prepare-tests.outputs.python-key }} ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
needs.info.outputs.python_cache_key }}
- name: Restore pip wheel cache
if: steps.cache-venv.outputs.cache-hit != 'true'
uses: actions/cache@v3.0.4
with:
path: ${{ env.PIP_CACHE }}
key: >-
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
steps.generate-pip-key.outputs.key }}
restore-keys: |
${{ runner.os }}-${{ steps.python.outputs.python-version }}-pip-${{ env.PIP_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 --cache-dir=$PIP_CACHE -U "pip>=21.0,<22.2" setuptools wheel
pip install --cache-dir=$PIP_CACHE -r requirements_all.txt --use-deprecated=legacy-resolver
pip install --cache-dir=$PIP_CACHE -r requirements_test.txt --use-deprecated=legacy-resolver
pip install -e .
hassfest:
name: Check hassfest
runs-on: ubuntu-20.04
needs:
- info
- base
steps:
- name: Check out code from GitHub
uses: actions/checkout@v3.0.2
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v4.0.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
- name: Restore full Python ${{ env.DEFAULT_PYTHON }} virtual environment
id: cache-venv
uses: actions/cache@v3.0.4
with:
path: venv
key: >-
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
needs.info.outputs.python_cache_key }}
- name: Fail job if Python cache restore failed - name: Fail job if Python cache restore failed
if: steps.cache-venv.outputs.cache-hit != 'true' if: steps.cache-venv.outputs.cache-hit != 'true'
run: | run: |
@ -520,14 +556,16 @@ jobs:
gen-requirements-all: gen-requirements-all:
name: Check all requirements name: Check all requirements
runs-on: ubuntu-latest runs-on: ubuntu-20.04
needs: prepare-base needs:
- info
- base
steps: steps:
- name: Check out code from GitHub - name: Check out code from GitHub
uses: actions/checkout@v3.0.2 uses: actions/checkout@v3.0.2
- name: Set up Python ${{ env.DEFAULT_PYTHON }} - name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v4.0.0
id: python id: python
uses: actions/setup-python@v4.0.0
with: with:
python-version: ${{ env.DEFAULT_PYTHON }} python-version: ${{ env.DEFAULT_PYTHON }}
- name: Restore base Python virtual environment - name: Restore base Python virtual environment
@ -535,8 +573,9 @@ jobs:
uses: actions/cache@v3.0.4 uses: actions/cache@v3.0.4
with: with:
path: venv path: venv
key: ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{ key: >-
needs.prepare-base.outputs.python-key }} ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
needs.info.outputs.python_cache_key }}
- name: Fail job if Python cache restore failed - name: Fail job if Python cache restore failed
if: steps.cache-venv.outputs.cache-hit != 'true' if: steps.cache-venv.outputs.cache-hit != 'true'
run: | run: |
@ -547,94 +586,29 @@ jobs:
. venv/bin/activate . venv/bin/activate
python -m script.gen_requirements_all validate python -m script.gen_requirements_all validate
prepare-tests:
name: Prepare tests for Python ${{ matrix.python-version }}
runs-on: ubuntu-latest
timeout-minutes: 60
strategy:
matrix:
python-version: ["3.9", "3.10"]
outputs:
python-key: ${{ steps.generate-python-key.outputs.key }}
container: homeassistant/ci-azure:${{ matrix.python-version }}
steps:
- name: Check out code from GitHub
uses: actions/checkout@v3.0.2
- name: Generate partial Python venv restore key
id: generate-python-key
run: >-
echo "::set-output name=key::venv-${{ env.CACHE_VERSION }}-${{
hashFiles('requirements_test.txt') }}-${{
hashFiles('requirements_all.txt') }}-${{
hashFiles('homeassistant/package_constraints.txt') }}"
- name: Generate partial pip restore key
id: generate-pip-key
run: >-
echo "::set-output name=key::pip-${{ env.PIP_CACHE_VERSION }}-${{
env.HA_SHORT_VERSION }}-$(date -u '+%Y-%m-%dT%H:%M:%s')"
- name: Restore full Python ${{ matrix.python-version }} virtual environment
id: cache-venv
uses: actions/cache@v3.0.4
with:
path: venv
key: >-
${{ runner.os }}-${{ matrix.python-version }}-${{
steps.generate-python-key.outputs.key }}
# Temporary disabling the restore of environments when bumping
# a dependency. It seems that we are experiencing issues with
# restoring environments in GitHub Actions, although unclear why.
# First attempt: https://github.com/home-assistant/core/pull/62383
#
# restore-keys: |
# ${{ runner.os }}-${{ matrix.python-version }}-venv-${{ env.CACHE_VERSION }}-${{ hashFiles('requirements_test.txt') }}-${{ hashFiles('requirements_all.txt') }}-
# ${{ runner.os }}-${{ matrix.python-version }}-venv-${{ env.CACHE_VERSION }}-${{ hashFiles('requirements_test.txt') }}-
# ${{ runner.os }}-${{ matrix.python-version }}-venv-${{ env.CACHE_VERSION }}-
- name: Restore pip wheel cache
if: steps.cache-venv.outputs.cache-hit != 'true'
uses: actions/cache@v3.0.4
with:
path: ${{ env.PIP_CACHE }}
key: >-
${{ runner.os }}-${{ matrix.python-version }}-${{
steps.generate-pip-key.outputs.key }}
restore-keys: |
${{ runner.os }}-${{ matrix.python-version }}-pip-${{ env.PIP_CACHE_VERSION }}-${{ env.HA_SHORT_VERSION }}-
- name: Create full Python ${{ matrix.python-version }} virtual environment
if: steps.cache-venv.outputs.cache-hit != 'true'
run: |
# Temporary addition of cmake, needed to build some Python 3.9 packages
apt-get update
apt-get -y install cmake
python -m venv venv
. venv/bin/activate
python --version
pip install --cache-dir=$PIP_CACHE -U "pip>=21.0,<22.2" setuptools wheel
pip install --cache-dir=$PIP_CACHE -r requirements_all.txt --use-deprecated=legacy-resolver
pip install --cache-dir=$PIP_CACHE -r requirements_test.txt --use-deprecated=legacy-resolver
pip install -e .
pylint: pylint:
name: Check pylint name: Check pylint
runs-on: ubuntu-latest runs-on: ubuntu-20.04
timeout-minutes: 20 timeout-minutes: 20
needs: needs:
- changes - info
- prepare-tests - base
strategy:
matrix:
python-version: [3.9]
container: homeassistant/ci-azure:${{ matrix.python-version }}
steps: steps:
- name: Check out code from GitHub - name: Check out code from GitHub
uses: actions/checkout@v3.0.2 uses: actions/checkout@v3.0.2
- name: Restore full Python ${{ matrix.python-version }} virtual environment - name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v4.0.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
- name: Restore full Python ${{ env.DEFAULT_PYTHON }} virtual environment
id: cache-venv id: cache-venv
uses: actions/cache@v3.0.4 uses: actions/cache@v3.0.4
with: with:
path: venv path: venv
key: ${{ runner.os }}-${{ matrix.python-version }}-${{ key: >-
needs.prepare-tests.outputs.python-key }} ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
needs.info.outputs.python_cache_key }}
- name: Fail job if Python cache restore failed - name: Fail job if Python cache restore failed
if: steps.cache-venv.outputs.cache-hit != 'true' if: steps.cache-venv.outputs.cache-hit != 'true'
run: | run: |
@ -644,39 +618,41 @@ jobs:
run: | run: |
echo "::add-matcher::.github/workflows/matchers/pylint.json" echo "::add-matcher::.github/workflows/matchers/pylint.json"
- name: Run pylint (fully) - name: Run pylint (fully)
if: needs.changes.outputs.test_full_suite == 'true' if: needs.info.outputs.test_full_suite == 'true'
run: | run: |
. venv/bin/activate . venv/bin/activate
python --version python --version
pylint --ignore-missing-annotations=y homeassistant pylint --ignore-missing-annotations=y homeassistant
- name: Run pylint (partially) - name: Run pylint (partially)
if: needs.changes.outputs.test_full_suite == 'false' if: needs.info.outputs.test_full_suite == 'false'
shell: bash shell: bash
run: | run: |
. venv/bin/activate . venv/bin/activate
python --version python --version
pylint --ignore-missing-annotations=y homeassistant/components/${{ needs.changes.outputs.integrations_glob }} pylint --ignore-missing-annotations=y homeassistant/components/${{ needs.info.outputs.integrations_glob }}
mypy: mypy:
name: Check mypy name: Check mypy
runs-on: ubuntu-latest runs-on: ubuntu-20.04
needs: needs:
- changes - info
- prepare-tests - base
strategy:
matrix:
python-version: [3.9]
container: homeassistant/ci-azure:${{ matrix.python-version }}
steps: steps:
- name: Check out code from GitHub - name: Check out code from GitHub
uses: actions/checkout@v3.0.2 uses: actions/checkout@v3.0.2
- name: Restore full Python ${{ matrix.python-version }} virtual environment - name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v4.0.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
- name: Restore full Python ${{ env.DEFAULT_PYTHON }} virtual environment
id: cache-venv id: cache-venv
uses: actions/cache@v3.0.4 uses: actions/cache@v3.0.4
with: with:
path: venv path: venv
key: ${{ runner.os }}-${{ matrix.python-version }}-${{ key: >-
needs.prepare-tests.outputs.python-key }} ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
needs.info.outputs.python_cache_key }}
- name: Fail job if Python cache restore failed - name: Fail job if Python cache restore failed
if: steps.cache-venv.outputs.cache-hit != 'true' if: steps.cache-venv.outputs.cache-hit != 'true'
run: | run: |
@ -686,41 +662,46 @@ jobs:
run: | run: |
echo "::add-matcher::.github/workflows/matchers/mypy.json" echo "::add-matcher::.github/workflows/matchers/mypy.json"
- name: Run mypy (fully) - name: Run mypy (fully)
if: needs.changes.outputs.test_full_suite == 'true' if: needs.info.outputs.test_full_suite == 'true'
run: | run: |
. venv/bin/activate . venv/bin/activate
python --version python --version
mypy homeassistant pylint mypy homeassistant pylint
- name: Run mypy (partially) - name: Run mypy (partially)
if: needs.changes.outputs.test_full_suite == 'false' if: needs.info.outputs.test_full_suite == 'false'
shell: bash shell: bash
run: | run: |
. venv/bin/activate . venv/bin/activate
python --version python --version
mypy homeassistant/components/${{ needs.changes.outputs.integrations_glob }} mypy homeassistant/components/${{ needs.info.outputs.integrations_glob }}
pip-check: pip-check:
runs-on: ubuntu-latest runs-on: ubuntu-20.04
if: needs.changes.outputs.requirements == 'true' || github.event.inputs.full == 'true' if: needs.info.outputs.requirements == 'true' || github.event.inputs.full == 'true'
needs: needs:
- changes - info
- prepare-tests - base
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
python-version: [3.9] python-version: ["3.9", "3.10"]
name: Run pip check ${{ matrix.python-version }} name: Run pip check ${{ matrix.python-version }}
container: homeassistant/ci-azure:${{ matrix.python-version }}
steps: steps:
- name: Check out code from GitHub - name: Check out code from GitHub
uses: actions/checkout@v3.0.2 uses: actions/checkout@v3.0.2
- name: Set up Python ${{ matrix.python-version }}
id: python
uses: actions/setup-python@v4.0.0
with:
python-version: ${{ matrix.python-version }}
- name: Restore full Python ${{ matrix.python-version }} virtual environment - name: Restore full Python ${{ matrix.python-version }} virtual environment
id: cache-venv id: cache-venv
uses: actions/cache@v3.0.4 uses: actions/cache@v3.0.4
with: with:
path: venv path: venv
key: ${{ runner.os }}-${{ matrix.python-version }}-${{ key: >-
needs.prepare-tests.outputs.python-key }} ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
needs.info.outputs.python_cache_key }}
- name: Fail job if Python cache restore failed - name: Fail job if Python cache restore failed
if: steps.cache-venv.outputs.cache-hit != 'true' if: steps.cache-venv.outputs.cache-hit != 'true'
run: | run: |
@ -732,38 +713,48 @@ jobs:
./script/pip_check $PIP_CACHE ./script/pip_check $PIP_CACHE
pytest: pytest:
runs-on: ubuntu-latest runs-on: ubuntu-20.04
if: | if: |
(github.event_name != 'push' || github.event.repository.full_name == 'home-assistant/core') (github.event_name != 'push' || github.event.repository.full_name == 'home-assistant/core')
&& github.event.inputs.lint-only != 'true' && github.event.inputs.lint-only != 'true'
&& (needs.changes.outputs.test_full_suite == 'true' || needs.changes.outputs.tests_glob) && (needs.info.outputs.test_full_suite == 'true' || needs.info.outputs.tests_glob)
needs: needs:
- changes - info
- base
- gen-requirements-all - gen-requirements-all
- hassfest - hassfest
- lint-black - lint-black
- lint-other - lint-other
- lint-isort - lint-isort
- mypy - mypy
- prepare-tests
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
group: ${{ fromJson(needs.changes.outputs.test_groups) }} group: ${{ fromJson(needs.info.outputs.test_groups) }}
python-version: ["3.9", "3.10"] python-version: ["3.9", "3.10"]
name: >- name: >-
Run tests Python ${{ matrix.python-version }} (${{ matrix.group }}) Run tests Python ${{ matrix.python-version }} (${{ matrix.group }})
container: homeassistant/ci-azure:${{ matrix.python-version }}
steps: steps:
- name: Install additional OS dependencies
run: |
sudo apt-get update
sudo apt-get -y install \
bluez \
ffmpeg
- name: Check out code from GitHub - name: Check out code from GitHub
uses: actions/checkout@v3.0.2 uses: actions/checkout@v3.0.2
- name: Set up Python ${{ matrix.python-version }}
id: python
uses: actions/setup-python@v4.0.0
with:
python-version: ${{ matrix.python-version }}
- name: Restore full Python ${{ matrix.python-version }} virtual environment - name: Restore full Python ${{ matrix.python-version }} virtual environment
id: cache-venv id: cache-venv
uses: actions/cache@v3.0.4 uses: actions/cache@v3.0.4
with: with:
path: venv path: venv
key: ${{ runner.os }}-${{ matrix.python-version }}-${{ key: ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
needs.prepare-tests.outputs.python-key }} needs.info.outputs.python_cache_key }}
- name: Fail job if Python cache restore failed - name: Fail job if Python cache restore failed
if: steps.cache-venv.outputs.cache-hit != 'true' if: steps.cache-venv.outputs.cache-hit != 'true'
run: | run: |
@ -783,7 +774,7 @@ jobs:
run: | run: |
echo "::add-matcher::.github/workflows/matchers/pytest-slow.json" echo "::add-matcher::.github/workflows/matchers/pytest-slow.json"
- name: Run pytest (fully) - name: Run pytest (fully)
if: needs.changes.outputs.test_full_suite == 'true' if: needs.info.outputs.test_full_suite == 'true'
timeout-minutes: 60 timeout-minutes: 60
run: | run: |
. venv/bin/activate . venv/bin/activate
@ -794,7 +785,7 @@ jobs:
--durations=10 \ --durations=10 \
-n auto \ -n auto \
--dist=loadfile \ --dist=loadfile \
--test-group-count ${{ needs.changes.outputs.test_group_count }} \ --test-group-count ${{ needs.info.outputs.test_group_count }} \
--test-group=${{ matrix.group }} \ --test-group=${{ matrix.group }} \
--cov="homeassistant" \ --cov="homeassistant" \
--cov-report=xml \ --cov-report=xml \
@ -802,8 +793,8 @@ jobs:
-p no:sugar \ -p no:sugar \
tests tests
- name: Run pytest (partially) - name: Run pytest (partially)
if: needs.changes.outputs.test_full_suite == 'false' if: needs.info.outputs.test_full_suite == 'false'
timeout-minutes: 20 timeout-minutes: 10
shell: bash shell: bash
run: | run: |
. venv/bin/activate . venv/bin/activate
@ -838,9 +829,9 @@ jobs:
coverage: coverage:
name: Upload test coverage to Codecov name: Upload test coverage to Codecov
runs-on: ubuntu-latest runs-on: ubuntu-20.04
needs: needs:
- changes - info
- pytest - pytest
steps: steps:
- name: Check out code from GitHub - name: Check out code from GitHub
@ -848,10 +839,10 @@ jobs:
- name: Download all coverage artifacts - name: Download all coverage artifacts
uses: actions/download-artifact@v3 uses: actions/download-artifact@v3
- name: Upload coverage to Codecov (full coverage) - name: Upload coverage to Codecov (full coverage)
if: needs.changes.outputs.test_full_suite == 'true' if: needs.info.outputs.test_full_suite == 'true'
uses: codecov/codecov-action@v3.1.0 uses: codecov/codecov-action@v3.1.0
with: with:
flags: full-suite flags: full-suite
- name: Upload coverage to Codecov (partial coverage) - name: Upload coverage to Codecov (partial coverage)
if: needs.changes.outputs.test_full_suite == 'false' if: needs.info.outputs.test_full_suite == 'false'
uses: codecov/codecov-action@v3.1.0 uses: codecov/codecov-action@v3.1.0

View File

@ -501,7 +501,6 @@ async def test_camera_stream_source_configured_and_copy_codec(hass, run_driver,
): ):
await _async_start_streaming(hass, acc) await _async_start_streaming(hass, acc)
await _async_reconfigure_stream(hass, acc, session_info, {}) await _async_reconfigure_stream(hass, acc, session_info, {})
await _async_stop_stream(hass, acc, session_info)
await _async_stop_all_streams(hass, acc) await _async_stop_all_streams(hass, acc)
expected_output = ( expected_output = (

View File

@ -265,12 +265,12 @@ async def test_get_stream_from_camera(aiohttp_server: Any, hass: HomeAssistant)
client = create_mock_motioneye_client() client = create_mock_motioneye_client()
client.get_camera_stream_url = Mock( client.get_camera_stream_url = Mock(
return_value=f"http://localhost:{stream_server.port}/" return_value=f"http://127.0.0.1:{stream_server.port}/"
) )
config_entry = create_mock_motioneye_config_entry( config_entry = create_mock_motioneye_config_entry(
hass, hass,
data={ data={
CONF_URL: f"http://localhost:{stream_server.port}", CONF_URL: f"http://127.0.0.1:{stream_server.port}",
# The port won't be used as the client is a mock. # The port won't be used as the client is a mock.
CONF_SURVEILLANCE_USERNAME: TEST_SURVEILLANCE_USERNAME, CONF_SURVEILLANCE_USERNAME: TEST_SURVEILLANCE_USERNAME,
}, },
@ -351,13 +351,13 @@ async def test_camera_option_stream_url_template(
config_entry = create_mock_motioneye_config_entry( config_entry = create_mock_motioneye_config_entry(
hass, hass,
data={ data={
CONF_URL: f"http://localhost:{stream_server.port}", CONF_URL: f"http://127.0.0.1:{stream_server.port}",
# The port won't be used as the client is a mock. # The port won't be used as the client is a mock.
CONF_SURVEILLANCE_USERNAME: TEST_SURVEILLANCE_USERNAME, CONF_SURVEILLANCE_USERNAME: TEST_SURVEILLANCE_USERNAME,
}, },
options={ options={
CONF_STREAM_URL_TEMPLATE: ( CONF_STREAM_URL_TEMPLATE: (
f"http://localhost:{stream_server.port}/" "{{ name }}/{{ id }}" f"http://127.0.0.1:{stream_server.port}/" "{{ name }}/{{ id }}"
) )
}, },
) )

View File

@ -71,7 +71,7 @@ async def test_record_stream(hass, filename, h264_video):
assert os.path.exists(filename) assert os.path.exists(filename)
async def test_record_lookback(hass, h264_video): async def test_record_lookback(hass, filename, h264_video):
"""Exercise record with loopback.""" """Exercise record with loopback."""
stream = create_stream(hass, h264_video, {}) stream = create_stream(hass, h264_video, {})
@ -81,7 +81,7 @@ async def test_record_lookback(hass, h264_video):
await stream.start() await stream.start()
with patch.object(hass.config, "is_allowed_path", return_value=True): with patch.object(hass.config, "is_allowed_path", return_value=True):
await stream.async_record("/example/path", lookback=4) await stream.async_record(filename, lookback=4)
# This test does not need recorder cleanup since it is not fully exercised # This test does not need recorder cleanup since it is not fully exercised
@ -245,10 +245,10 @@ async def test_record_stream_audio(
await hass.async_block_till_done() await hass.async_block_till_done()
async def test_recorder_log(hass, caplog): async def test_recorder_log(hass, filename, caplog):
"""Test starting a stream to record logs the url without username and password.""" """Test starting a stream to record logs the url without username and password."""
stream = create_stream(hass, "https://abcd:efgh@foo.bar", {}) stream = create_stream(hass, "https://abcd:efgh@foo.bar", {})
with patch.object(hass.config, "is_allowed_path", return_value=True): with patch.object(hass.config, "is_allowed_path", return_value=True):
await stream.async_record("/example/path") await stream.async_record(filename)
assert "https://abcd:efgh@foo.bar" not in caplog.text assert "https://abcd:efgh@foo.bar" not in caplog.text
assert "https://****:****@foo.bar" in caplog.text assert "https://****:****@foo.bar" in caplog.text

View File

@ -71,6 +71,12 @@ SEGMENTS_PER_PACKET = PACKET_DURATION / SEGMENT_DURATION
TIMEOUT = 15 TIMEOUT = 15
@pytest.fixture
def filename(tmpdir):
"""Use this filename for the tests."""
return f"{tmpdir}/test.mp4"
@pytest.fixture(autouse=True) @pytest.fixture(autouse=True)
def mock_stream_settings(hass): def mock_stream_settings(hass):
"""Set the stream settings data in hass before each test.""" """Set the stream settings data in hass before each test."""
@ -895,7 +901,7 @@ async def test_h265_video_is_hvc1(hass, worker_finished_stream):
} }
async def test_get_image(hass): async def test_get_image(hass, filename):
"""Test that the has_keyframe metadata matches the media.""" """Test that the has_keyframe metadata matches the media."""
await async_setup_component(hass, "stream", {"stream": {}}) await async_setup_component(hass, "stream", {"stream": {}})
@ -909,7 +915,7 @@ async def test_get_image(hass):
stream = create_stream(hass, source, {}) stream = create_stream(hass, source, {})
with patch.object(hass.config, "is_allowed_path", return_value=True): with patch.object(hass.config, "is_allowed_path", return_value=True):
make_recording = hass.async_create_task(stream.async_record("/example/path")) make_recording = hass.async_create_task(stream.async_record(filename))
await make_recording await make_recording
assert stream._keyframe_converter._image is None assert stream._keyframe_converter._image is None