diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 83f99496a1a..5e463f8a9ed 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -1,5 +1,9 @@ # Try to get a short workflow name and a job name that start with Python # version to make it easier to check the status inside GitHub UI. +# +# When using external actions check that the external repos are permitted via +# the GitHub configuration at https://github.com/twisted/twisted/settings/actions +# name: CI on: @@ -10,6 +14,13 @@ on: pull_request: branches: [ trunk ] + workflow_dispatch: + inputs: + debug_enabled: + type: boolean + description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)' + required: false + default: false # Only have a run a single parallel for each branch. # Runs for trunk are queues. @@ -24,22 +35,48 @@ defaults: run: shell: bash +env: + # Set to 'yes' to open a tunnel to GitHub's VMs through tmate on failures. + # You can also trigger it via manual workflow trigger. + # https://github.com/mxschmitt/action-tmate#manually-triggered-debug + TMATE_DEBUG: 'no' + # The default values in the job generated by the matrix. + DEFAULT_PYTHON_VERSION: '3.10' jobs: testing: - runs-on: ubuntu-20.04 + # We can't use `env.*` in the job name, only in the steps. + name: ${{ matrix.python-version }}-${{ matrix.job-name || 'default-tests' }} + # We have Ubuntu as the base for running agains multiple Python versions. + runs-on: "${{ matrix.runs-on || 'ubuntu-20.04' }}" env: - TOXENV: "${{ matrix.tox-env }}" + # By default we run all tests with all deps with coverage. + TOXENV: "${{ matrix.tox-env || 'alldeps-withcov-posix' }}" # As of April 2021 GHA VM have 2 CPUs - Azure Standard_DS2_v2 # Trial distributed jobs enabled to speed up the CI jobs. - TRIAL_ARGS: "-j 4" - name: ${{ matrix.python-version }}${{ matrix.noipv6 }}-${{ matrix.tox-env }} + # On Windows, we don't yet enable distributed tests as is not yet + # supported. + TRIAL_ARGS: "${{ matrix.trial-args || '-j 4' }}" strategy: fail-fast: false + # The matrix is designed to not expand into any job. + # It is used to document the test environement variations. + # The actual job enviroment are defined in the `include` section. matrix: - # Run on latest minor release of each major python version. - python-version: ['3.8', '3.9', '3.10'] - tox-env: ['alldeps-withcov-posix'] + # The Python version on which the job is executed. + # We need at least one value here, so we go with latest Python version + # that we support.. + python-version: ['3.10'] + # Just use the default OS. + runs-on: [''] + # Human readable short description for this job. + job-name: [''] + # This is the main tox target. + # It is later extended with more jobs that should run in a specific + # OS + Python version configuration. + tox-env: [''] + # We just go with the default arguments. + trial-args: [''] # By default, tests are executed without disabling IPv6. noipv6: [''] # By default, tests are executed without extra platform dependencies. @@ -48,14 +85,13 @@ jobs: tox-wrapper: [''] # Tests are executed with the default target which is the full test suite. trial-target: [''] + # By default the coverage is not skipped. + skip-coverage: [''] + # Here the matrix is extended with variations of the default + # value. include: - # `noipv6` is created to make sure all is OK on an OS which doesn't - # have IPv6 available. - # Any supported Python version is OK for this job. - - python-version: '3.7' - tox-env: alldeps-withcov-posix - noipv6: -noipv6 + # `nodeps` is created to make sure we don't have import errors in the # runtime and production code. # The minimum supported Python version should be used to maximize @@ -65,24 +101,64 @@ jobs: # When updating the minimum Python version here, also update the # `python_requires` from `setup.cfg`. - python-version: '3.7.1' - tox-env: nodeps-withcov-posix + tox-env: 'nodeps-withcov-posix' + job-name: 'nodeps-test' + + # `noipv6` is created to make sure all is OK on an OS which doesn't + # have IPv6 available. + # Any supported Python version is OK for this job. + # We go with latest micro release for the smallest minor release + # that we support. + - python-version: '3.7' + noipv6: '-noipv6' + job-name: 'default-tests-noipv6' + + # Just Python 3.8 with default settings. + - python-version: '3.8' + + # Just Python 3.9 with default settings. + - python-version: '3.9' + + # Windows, minimum Python version with select reactor. + - python-version: '3.7' + runs-on: 'windows-2022' + tox-env: 'alldeps-withcov-windows' + job-name: 'win-default-tests-select' + # Distributed trial is not yet suported on Windows so we overwrite + # the default trial-args to remove concurrent runs and to + # select a reactor. + trial-args: '--reactor=select' + + # Windows, newest Python supported version with iocp reactor. + - python-version: '3.10' + runs-on: 'windows-2022' + tox-env: 'alldeps-withcov-windows' + job-name: 'win-default-tests-iocp' + # Distributed trial is not yet suported on Windows. + trial-args: '--reactor=iocp' + # On PYPY coverage is very slow (5min vs 30min) as there is no C # extension. # There is very little PYPY specific code so there is not much to # gain from reporting coverage. - - python-version: pypy-3.7 - tox-env: alldeps-nocov-posix + - python-version: 'pypy-3.7' + tox-env: 'alldeps-nocov-posix' + job-name: 'no-coverage' + skip-coverage: yes + # We still run some tests with coverage, # as there are test with specific code branches for pypy. - - python-version: pypy-3.7 - tox-env: alldeps-withcov-posix - trial-target: twisted.test.test_compat twisted.test.test_defer twisted.internet.test.test_socket twisted.trial.test.test_tests + - python-version: 'pypy-3.7' + trial-target: 'twisted.test.test_compat twisted.test.test_defer twisted.internet.test.test_socket twisted.trial.test.test_tests' + job-name: 'with-coverage' + # We run selected test for GTK reactor inside X virtual framebuffer. - python-version: '3.7' - tox-env: alldeps-gtk-withcov-posix - trial-target: twisted.internet.test + tox-env: 'alldeps-gtk-withcov-posix' + trial-target: 'twisted.internet.test' platform-deps: 'gtk_platform' tox-wrapper: 'xvfb-run -a' + job-name: 'gtk-tests' steps: @@ -99,7 +175,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: pip cache - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ${{ steps.pip-cache.outputs.dir }} key: @@ -108,6 +184,8 @@ jobs: restore-keys: | ${{ runner.os }}-pip- + # Make sure the matrix is defined in such a way that this is triggered + # only on Linux. - name: Disable IPv6 if: matrix.noipv6 run: | @@ -121,6 +199,8 @@ jobs: run: | python -m pip install --upgrade pip tox coverage + # Make sure the matrix is defined in such a way that this is triggered + # only on Linux. - name: Install GTK system deps if: matrix.platform-deps == 'gtk_platform' run: | @@ -139,8 +219,16 @@ jobs: run: | ${{ matrix.tox-wrapper }} tox ${{ matrix.trial-target }} + # If one of the above steps fails, fire up tmate for remote debugging. + # This is fired for manual trigger or via the environment variable. + - name: Tmate debug session + if: ${{ !cancelled() && (env.TMATE_DEBUG == 'yes' || github.event_name == 'workflow_dispatch' && inputs.debug_enabled ) }} + uses: mxschmitt/action-tmate@v3 + with: + limit-access-to-actor: true + - name: Prepare coverage - if: ${{ !cancelled() && contains(matrix['tox-env'], 'withcov') }} + if: ${{ !cancelled() && !matrix.skip-coverage }} run: | # sub-process coverage are generated in separate files so we combine them # to get an unified coverage for the local run. @@ -149,11 +237,11 @@ jobs: python -m coverage xml -o coverage.xml -i python -m coverage report --skip-covered - - uses: codecov/codecov-action@v2 - if: ${{ !cancelled() && contains(matrix['tox-env'], 'withcov') }} + - uses: codecov/codecov-action@v3 + if: ${{ !cancelled() && !matrix['skip-coverage'] }} with: files: coverage.xml - name: lnx-${{ matrix.python-version }}-${{ matrix.tox-env }}${{ matrix.noipv6 }} + name: ${{ matrix.python-version || env.DEFAULT_PYTHON_VERSION }}-${{matrix.job-name || 'default-tests' }} fail_ci_if_error: true @@ -172,7 +260,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v2 with: - python-version: '3.9' + python-version: '${{ env.DEFAULT_PYTHON_VERSION }}' - name: Install dependencies run: | @@ -218,7 +306,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v2 with: - python-version: '3.10' + python-version: ${{ env.DEFAULT_PYTHON_VERSION }} - name: Install dependencies run: | python -m pip install --upgrade pip tox @@ -235,7 +323,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v2 with: - python-version: '3.10' + python-version: ${{ env.DEFAULT_PYTHON_VERSION }} - name: Install dependencies run: | python -m pip install --upgrade pip tox @@ -252,14 +340,14 @@ jobs: # The files are published only when a tag is created. release-publish: name: Check release and publish on twisted-* tag - runs-on: ubuntu-20.04 + runs-on: 'ubuntu-20.04' steps: - uses: actions/checkout@v2 - name: Set up Python uses: actions/setup-python@v2 with: - python-version: 3.9 + python-version: '${{ env.DEFAULT_PYTHON_VERSION }}' - name: Test run: | @@ -270,7 +358,8 @@ jobs: - uses: twisted/python-info-action@v1 - name: Files to be pushed to PyPi - run: ls -R dist/ + run: | + ls -R dist/ - name: Check matched tag version and branch version - on tag if: startsWith(github.ref, 'refs/tags/twisted-') @@ -278,14 +367,14 @@ jobs: - name: Publish to PyPI - on tag if: startsWith(github.ref, 'refs/tags/twisted-') - uses: pypa/gh-action-pypi-publish@v1.3.1 + uses: pypa/gh-action-pypi-publish@v1.5.1 with: password: ${{ secrets.PYPI_UPLOAD_TOKEN }} - name: Update stable branch - on stable tag if: startsWith(github.ref, 'refs/tags/twisted-') env: - STABLE_BRANCH: stable + STABLE_BRANCH: 'stable' STABLE_REF_RE: '.*twisted-[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+$' run: | if [[ $GITUB_REF =~ $STABLE_REF_RE ]]; then diff --git a/azure-pipelines/run_test_steps.yml b/azure-pipelines/run_test_steps.yml index 45bb34f2d30..039d2c7dbe7 100644 --- a/azure-pipelines/run_test_steps.yml +++ b/azure-pipelines/run_test_steps.yml @@ -65,7 +65,7 @@ steps: displayName: 'Run tests' continueOnError: ${{ parameters.allowFailure }} env: - TWISTED_REACTOR: ${{ parameters.windowsReactor }} + TRIAL_ARGS: --reactor=${{ parameters.windowsReactor }} - bash: | # sub-process coverage are generated in separate files so we combine them diff --git a/azure-pipelines/tests_pipeline.yml b/azure-pipelines/tests_pipeline.yml index 03d35041b66..c07ac11b31c 100644 --- a/azure-pipelines/tests_pipeline.yml +++ b/azure-pipelines/tests_pipeline.yml @@ -31,17 +31,3 @@ jobs: parameters: pythonVersions: py39: "3.10" - -# Run Windows select reactor on the oldest CPython that we support. -- template: 'windows_test_jobs.yml' - parameters: - pythonVersions: - py37: "3.7" - reactor: select - -# Run Windows iocp reactor on the newest CPython that we support. -- template: 'windows_test_jobs.yml' - parameters: - pythonVersions: - py39: "3.10" - reactor: iocp diff --git a/azure-pipelines/windows_test_jobs.yml b/azure-pipelines/windows_test_jobs.yml deleted file mode 100644 index 563f3485864..00000000000 --- a/azure-pipelines/windows_test_jobs.yml +++ /dev/null @@ -1,37 +0,0 @@ -# -# This is just a template, and not a main pipeline definition. -# -parameters: -- name: imageName - type: string - default: 'windows-latest' -# Must be a mapping of id-suitable-name -> actual version number with dot -- name: pythonVersions - type: object -- name: reactor - type: string - values: - - select - - iocp - -jobs: -- ${{ each pyver in parameters.pythonVersions }}: - - job: ${{ format('windows_{0}_{1}reactor', pyver.key, parameters.reactor) }} - displayName: ${{ format('Windows Py{0} {1}reactor', pyver.value, parameters.reactor) }} - pool: - vmImage: ${{ parameters.imageName }} - variables: - # Set PYTHONUTF8 environment variable to force UTF-8 mode on Python 3.7+ - # on Windows. - # - # Set PYTHONIOENCODING to force UTF-8 encoding on Python 3.6. - # This allows people with non-ASCII characters in their names to file pull requests - # and not trigger CI errors. - PYTHONUTF8: 1 - PYTHONIOENCODING: "utf-8:surrogateescape" - steps: - - template: 'run_test_steps.yml' - parameters: - platform: windows - pythonVersion: ${{ pyver.value }} - windowsReactor: ${{ parameters.reactor }} diff --git a/src/twisted/newsfragments/11628.misc b/src/twisted/newsfragments/11628.misc new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tox.ini b/tox.ini index 453c58dc3bd..8488971ff12 100644 --- a/tox.ini +++ b/tox.ini @@ -93,12 +93,12 @@ commands = posix: python -c "print('Running on POSIX (no special dependencies)')" ; Run tests without wrapping them using coverage. - nocov: python -m twisted.trial --temp-directory={envtmpdir}/_trial_temp --reactor={env:TWISTED_REACTOR:default} --reporter={env:TRIAL_REPORTER:verbose} {env:TRIAL_ARGS:} {posargs:twisted} + nocov: python -m twisted.trial --temp-directory={envtmpdir}/_trial_temp --reporter={env:TRIAL_REPORTER:verbose} {env:TRIAL_ARGS:} {posargs:twisted} ; Run the tests wrapped using coverage. withcov: python {toxinidir}/admin/_copy.py {toxinidir}/admin/zz_coverage.pth {envsitepackagesdir}/zz_coverage.pth withcov: coverage erase - withcov: coverage run -p --rcfile={toxinidir}/.coveragerc -m twisted.trial --temp-directory={envtmpdir}/_trial_temp --reactor={env:TWISTED_REACTOR:default} --reporter={env:TRIAL_REPORTER:verbose} {env:TRIAL_ARGS:} {posargs:twisted} + withcov: coverage run -p --rcfile={toxinidir}/.coveragerc -m twisted.trial --temp-directory={envtmpdir}/_trial_temp --reporter={env:TRIAL_REPORTER:verbose} {env:TRIAL_ARGS:} {posargs:twisted} lint: pre-commit {posargs:run --all-files --show-diff-on-failure}