diff --git a/.github/workflows/ack.yml b/.github/workflows/ack.yml index 5880add..958b0b6 100644 --- a/.github/workflows/ack.yml +++ b/.github/workflows/ack.yml @@ -1,4 +1,4 @@ -# See https://github.com/ansible-community/devtools/blob/main/.github/workflows/ack.yml +# See https://github.com/ansible/team-devtools/blob/main/.github/workflows/ack.yml name: ack on: pull_request_target: @@ -6,4 +6,4 @@ on: jobs: ack: - uses: ansible-community/devtools/.github/workflows/ack.yml@main + uses: ansible/team-devtools/.github/workflows/ack.yml@main diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index ceef4e3..5b400b4 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -1,4 +1,4 @@ -# See https://github.com/ansible-community/devtools/blob/main/.github/workflows/push.yml +# See https://github.com/ansible/team-devtools/blob/main/.github/workflows/push.yml name: push on: push: @@ -9,4 +9,4 @@ on: jobs: ack: - uses: ansible-community/devtools/.github/workflows/push.yml@main + uses: ansible/team-devtools/.github/workflows/push.yml@main diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index b66cea2..e1eb8ef 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -1,69 +1,128 @@ +--- name: tox - on: - create: # is used for publishing to PyPI and TestPyPI - tags: # any tag regardless of its name, no branches - push: # only publishes pushes to the main branch to TestPyPI - branches: # any integration branch but not tag - - "main" - tags-ignore: - - "**" + push: + branches: ["main"] pull_request: + branches: ["main"] + # Run the tox tests every 8 hours. + # This will help to identify faster if + # there is a CI failure related to a + # change in any dependency. schedule: - - cron: 1 0 * * * # Run daily at 0:01 UTC + - cron: "0 */8 * * *" + # Run on demand + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} + cancel-in-progress: true + +env: + FORCE_COLOR: 1 # tox, pytest + PY_COLORS: 1 jobs: - build: - name: ${{ matrix.tox_env }} + prepare: + name: prepare runs-on: ubuntu-24.04 - # limit potential endless looks like we had with build-containers - timeout-minutes: 20 + outputs: + matrix: ${{ steps.generate_matrix.outputs.matrix }} + steps: + - name: Determine matrix + id: generate_matrix + uses: coactions/dynamic-matrix@v2 + with: + min_python: "3.8" + max_python: "3.13" + default_python: "3.10" + other_names: | + lint + packaging + py38,py38-devel + py39,py39-devel + py310,py310-devel + py311,py311-devel + py312,py312-devel + py313,py313-devel + platforms: linux,macos + skip_explode: "1" + + build: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os || 'ubuntu-24.04' }} + continue-on-error: ${{ contains(matrix.name, 'integration') && true || false }} + needs: + - prepare + defaults: + run: + shell: ${{ matrix.shell || 'bash'}} strategy: fail-fast: false - matrix: - include: - - tox_env: lint - python-version: "3.10" - - tox_env: py38,py38-devel - python-version: 3.8 - - tox_env: py39,py39-devel - python-version: 3.9 - - tox_env: py310,py310-devel - python-version: "3.10" - - tox_env: py311,py311-devel - python-version: "3.11" - - tox_env: py312,py312-devel - python-version: "3.12" - - tox_env: py313,py313-devel - python-version: "3.13-dev" - - tox_env: packaging - python-version: "3.10" - + matrix: ${{ fromJson(needs.prepare.outputs.matrix) }} + # max-parallel: 5 + # The matrix testing goal is to cover the *most likely* environments + # which are expected to be used by users in production. Avoid adding a + # combination unless there are good reasons to test it, like having + # proof that we failed to catch a bug by not running it. Using + # distribution should be preferred instead of custom builds. steps: - uses: actions/checkout@v4 + with: + fetch-depth: 0 # needed by setuptools-scm + submodules: true - - name: Install a default Python + - name: Set pre-commit cache + uses: actions/cache@v4 + if: ${{ matrix.passed_name == 'lint' }} + with: + path: | + ~/.cache/pre-commit + key: pre-commit-${{ matrix.name || matrix.passed_name }}-${{ hashFiles('.pre-commit-config.yaml') }} + + - name: Set up Python ${{ matrix.python_version || '3.10' }} uses: actions/setup-python@v5 with: - python-version: ${{ matrix.python-version }} + cache: pip + python-version: ${{ matrix.python_version || '3.10' }} + # cache-dependency-path: "*requirements*.txt" + + - name: Install tox + run: | + python3 -m pip install --upgrade pip wheel tox - - name: Install dependencies - run: pip install "tox>=4.0.2" "coverage[toml]>=6.5.0" + - name: Initialize tox envs ${{ matrix.passed_name }} + run: python3 -m tox -n --skip-missing-interpreters false -vv -e ${{ matrix.passed_name }} + timeout-minutes: 5 # average is under 1, but macos can be over 3 - - name: Run tox -e ${{ matrix.tox_env }} - run: tox -e ${{ matrix.tox_env }} - continue-on-error: ${{ matrix.experimental || false }} + # sequential run improves browsing experience (almost no speed impact) + - name: tox -e ${{ matrix.passed_name }} + run: python3 -m tox -e ${{ matrix.passed_name }} - - name: Upload coverage data - uses: codecov/codecov-action@v4 + - name: Archive logs + uses: actions/upload-artifact@v4 with: - name: ${{ matrix.tox_env }} - token: ${{ secrets.CODECOV_TOKEN }} - verbose: true # optional (default = false) - if: ${{ startsWith(matrix.tox_env, 'py') }} + name: logs-${{ matrix.name }}.zip + if-no-files-found: error + path: | + .tox/**/log/ + .tox/**/.coverage* + .tox/**/coverage.xml + - name: Report failure if git reports dirty status + run: | + if [[ -n $(git status -s) ]]; then + # shellcheck disable=SC2016 + echo -n '::error file=git-status::' + printf '### Failed as git reported modified and/or untracked files\n```\n%s\n```\n' "$(git status -s)" | tee -a "$GITHUB_STEP_SUMMARY" + exit 99 + fi + # https://github.com/actions/toolkit/issues/193 check: if: always() + permissions: + id-token: write + checks: read needs: - build @@ -71,7 +130,56 @@ jobs: runs-on: ubuntu-24.04 steps: + # checkout needed for codecov action which needs codecov.yml file + - uses: actions/checkout@v4 + + - name: Set up Python # likely needed for coverage + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - run: pip3 install 'coverage>=7.5.1' + + - name: Merge logs into a single archive + uses: actions/upload-artifact/merge@v4 + with: + name: logs.zip + pattern: logs-*.zip + # artifacts like py312.zip and py312-macos do have overlapping files + separate-directories: true + + - name: Download artifacts + uses: actions/download-artifact@v4 + with: + name: logs.zip + path: . + + # - name: Check for expected number of coverage.xml reports + # run: | + # JOBS_PRODUCING_COVERAGE=8 + # if [ "$(find . -name coverage.xml | wc -l | bc)" -ne "${JOBS_PRODUCING_COVERAGE}" ]; then + # echo "::error::Number of coverage.xml files was not the expected one (${JOBS_PRODUCING_COVERAGE}): $(find . -name coverage.xml |xargs echo)" + # exit 1 + # fi + + # - name: Upload coverage data + # uses: codecov/codecov-action@v4 + # with: + # name: ${{ matrix.passed_name }} + # # verbose: true # optional (default = false) + # fail_ci_if_error: true + # use_oidc: true # cspell:ignore oidc + + # - name: Check codecov.io status + # if: github.event_name == 'pull_request' + # uses: coactions/codecov-status@main + - name: Decide whether the needed jobs succeeded or failed uses: re-actors/alls-green@release/v1 with: jobs: ${{ toJSON(needs) }} + + - name: Delete Merged Artifacts + uses: actions/upload-artifact/merge@v4 + with: + delete-merged: true