summaryrefslogtreecommitdiffstats
path: root/.github/workflows/tox.yml
blob: 3966ef128b79af88c6cfcf494170951dba5d0d65 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
name: gh

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 branch but not tag
    - >-
      **
    tags-ignore:
    - >-
      **
  pull_request:
  schedule:
  - cron: 1 0 * * *  # Run daily at 0:01 UTC
  # Run every Friday at 18:02 UTC
  # https://crontab.guru/#2_18_*_*_5
  # - cron: 2 18 * * 5

jobs:
  linters:
    name: >-
      ${{ matrix.env.TOXENV }}
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        python-version:
        - 3.8
        os:
        - ubuntu-latest
        env:
        - TOXENV: lint
        - TOXENV: docs
        - TOXENV: build-dists,metadata-validation
    env:
      TOX_PARALLEL_NO_SPINNER: 1

    steps:
    - uses: actions/checkout@master
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v1
      with:
        python-version: ${{ matrix.python-version }}
    - name: set PY_SHA256
      run: echo "::set-env name=PY_SHA256::$(python -VV | sha256sum | cut -d' ' -f1)"
    - name: Pre-commit cache
      uses: actions/cache@v1
      with:
        path: ~/.cache/pre-commit
        key: ${{ runner.os }}-pre-commit-${{ env.PY_SHA256 }}-${{ hashFiles('setup.cfg') }}-${{ hashFiles('tox.ini') }}-${{ hashFiles('pyproject.toml') }}-${{ hashFiles('.pre-commit-config.yaml') }}-${{ hashFiles('pytest.ini') }}
    - name: Pip cache
      uses: actions/cache@v1
      with:
        path: ~/.cache/pip
        key: ${{ runner.os }}-pip-${{ env.PY_SHA256 }}-${{ hashFiles('setup.cfg') }}-${{ hashFiles('tox.ini') }}-${{ hashFiles('pyproject.toml') }}-${{ hashFiles('.pre-commit-config.yaml') }}-${{ hashFiles('pytest.ini') }}
        restore-keys: |
          ${{ runner.os }}-pip-
          ${{ runner.os }}-
    - name: Install tox
      run: |
        python -m pip install --upgrade tox
    - name: Log installed dists
      run: >-
        python -m pip freeze --all
    - name: >-
        Initialize tox envs
      run: >-
        python -m
        tox
        --parallel auto
        --parallel-live
        --notest
        --skip-missing-interpreters false
        -vv
      env: ${{ matrix.env }}
    - name: Test with tox
      run: |
        python -m tox --parallel auto --parallel-live
      env: ${{ matrix.env }}
    - name: Archive logs
      uses: actions/upload-artifact@v2
      with:
        name: logs.zip
        path: .tox/**/log/

  unit:
    name: >-
      py${{ matrix.python-version }}@${{ matrix.os }}
    runs-on: ${{ matrix.os }}
    strategy:
      # fail-fast: false
      # 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 prefferred instead of custom builds.
      matrix:
        python-version:
        # keep list sorted as it determines UI order too
        - 3.6
        - 3.7
        - 3.8
        # NOTE: Installing ansible under 3.10-dev is currently not
        # NOTE: possible because compiling cffi explodes.
        os:
        # https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners
        - ubuntu-latest  # 18.04
        # - windows-latest
        # - windows-2016
        include:
        - os: ubuntu-20.04
          python-version: 3.9-dev
        - os: macOS-latest
          python-version: 3.6
        - os: macOS-latest
          python-version: 3.8

    env:
      TOX_PARALLEL_NO_SPINNER: 1

    steps:
    - uses: actions/checkout@master
    - name: Get history and tags for SCM versioning to work
      run: |
        git fetch --prune --unshallow
        git fetch --depth=1 origin +refs/tags/*:refs/tags/*
    - name: Set up stock Python ${{ matrix.python-version }} from GitHub
      if: >-
        !endsWith(matrix.python-version, '-dev')
      uses: actions/setup-python@v2
      with:
        python-version: ${{ matrix.python-version }}
    - name: Set up Python ${{ matrix.python-version }} from deadsnakes
      if: >-
        endsWith(matrix.python-version, '-dev')
      uses: deadsnakes/action@v1.0.0
      with:
        python-version: ${{ matrix.python-version }}
    - name: >-
        Log the currently selected Python
        version info (${{ matrix.python-version }})
      run: |
        python --version --version
        which python
    - name: Pip cache
      uses: actions/cache@v1
      with:
        path: ~/.cache/pip
        key: ${{ runner.os }}-pip-${{ env.PY_SHA256 }}-${{ hashFiles('setup.cfg') }}-${{ hashFiles('tox.ini') }}-${{ hashFiles('pyproject.toml') }}-${{ hashFiles('.pre-commit-config.yaml') }}-${{ hashFiles('pytest.ini') }}
        restore-keys: |
          ${{ runner.os }}-pip-
          ${{ runner.os }}-
    - name: Install tox
      run: |
        python -m pip install --upgrade tox
    - name: Log installed dists
      run: >-
        python -m pip freeze --all
    - name: >-
        Initialize tox envs
      run: >-
        python -m
        tox
        --parallel auto
        --parallel-live
        --notest
        --skip-missing-interpreters false
        -vv
      env:
        TOXENV: ansible28,ansible29,ansible210,ansibledevel
    - name: "Test with tox: ansible28"
      run: |
        python -m tox
      env:
        TOXENV: ansible28
    # sequential run improves browsing experience (almost no speed impact)
    - name: "Test with tox: ansible29"
      run: |
        python -m tox
      env:
        TOXENV: ansible29
    - name: "Test with tox: ansible210"
      run: |
        python -m tox
      env:
        TOXENV: ansible210
    - name: "Test with tox: ansibledevel"
      run: |
        python -m tox
      env:
        TOXENV: ansibledevel
    - name: Archive logs
      uses: actions/upload-artifact@v2
      with:
        name: logs.zip
        path: .tox/**/log/
      # https://github.com/actions/upload-artifact/issues/123
      continue-on-error: true
    - name: Report junit failures
      uses: shyim/junit-report-annotations-action@3d2e5374f2b13e70f6f3209a21adfdbc42c466ae
      with:
        path: .tox/junit.*.xml
      if: always()

  publish:
    name: Publish to PyPI registry
    needs:
    - linters
    - unit
    runs-on: ubuntu-latest

    env:
      PY_COLORS: 1
      TOXENV: build-dists,metadata-validation
      TOX_PARALLEL_NO_SPINNER: 1

    steps:
    - name: Switch to using Python 3.8 by default
      uses: actions/setup-python@v2
      with:
        python-version: 3.8
    - name: Install tox
      run: >-
        python -m
        pip install
        --user
        tox
    - name: Check out src from Git
      uses: actions/checkout@v2
      with:
        # Get shallow Git history (default) for tag creation events
        # but have a complete clone for any other workflows.
        # Both options fetch tags but since we're going to remove
        # one from HEAD in non-create-tag workflows, we need full
        # history for them.
        fetch-depth: >-
          ${{
            (
              github.event_name == 'create' &&
              github.event.ref_type == 'tag'
            ) &&
            1 || 0
          }}
    - name: Drop Git tags from HEAD for non-tag-create events
      if: >-
        github.event_name != 'create' ||
        github.event.ref_type != 'tag'
      run: >-
        git tag --points-at HEAD
        |
        xargs git tag --delete
    - name: Instruct setuptools-scm not to add a local version part
      if: >-
        github.event_name == 'push' &&
        github.ref == format(
          'refs/heads/{0}', github.event.repository.default_branch
        )
      run: |
        echo 'local_scheme = "no-local-version"' >> pyproject.toml
        git update-index --assume-unchanged pyproject.toml
    - name: Pre-populate tox env
      run: >-
        python -m
        tox
        --parallel auto
        --parallel-live
        --notest
        --skip-missing-interpreters false
        -vvvv
    - name: Build dists
      run: python -m tox -p auto --parallel-live -vvvv
    - name: Publish to test.pypi.org
      if: >-
        (
          github.event_name == 'push' &&
          github.ref == format(
            'refs/heads/{0}', github.event.repository.default_branch
          )
        ) ||
        (
          github.event_name == 'create' &&
          github.event.ref_type == 'tag'
        )
      uses: pypa/gh-action-pypi-publish@master
      with:
        password: ${{ secrets.testpypi_password }}
        repository_url: https://test.pypi.org/legacy/
    - name: Publish to pypi.org
      if: >-  # "create" workflows run separately from "push" & "pull_request"
        github.event_name == 'create' &&
        github.event.ref_type == 'tag'
      uses: pypa/gh-action-pypi-publish@master
      with:
        password: ${{ secrets.pypi_password }}