-
Notifications
You must be signed in to change notification settings - Fork 7
315 lines (315 loc) · 12.4 KB
/
build-reusable.yml
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
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
# Environment variables defined in a calling workflow are not accessible to this reusable workflow. Refer to the documentation for further details on this limitation.
name: pypi_build_test_deploy
on:
workflow_call:
secrets:
CODECOV_TOKEN:
required: true
ACTIONS_RUNNER_DEBUG:
required: false
ACTIONS_STEP_DEBUG:
required: false
inputs:
Pure:
required: false
default: true
type: boolean
PyVersionLatest:
required: true
type: string
PySourceFolder:
required: true
type: string
PkgName:
required: true
type: string
PkgRootFolder:
# Relative to github.workspace
required: false
type: string
default: ""
CIBWBEFOREALLLINUX:
required: false
default: ''
type: string
CIBWBEFOREALLWINDOWS:
required: false
default: ''
type: string
permissions:
contents: read
jobs:
CodeQualityAnalysis-Test:
# TODO: Only debugging
if: github.event_name != 'push'
name: Static Analysis and Tests
runs-on: windows-2019
outputs:
pypi_released: ${{ steps.pythonsemanticrelease.outputs.released }}
pypi_version: ${{ steps.pythonsemanticrelease.outputs.version }}
pypi_tag: ${{ steps.pythonsemanticrelease.outputs.tag }}
steps:
- uses: actions/[email protected]
with:
lfs: true
submodules: recursive
# Python Semantic Release needs access to the full history to determine whether a release should be made.
fetch-depth: 0
- name: Use Python ${{inputs.PyVersionLatest}}
uses: actions/[email protected]
with:
python-version: "${{inputs.PyVersionLatest}}"
architecture: x64
- name: Python Semantic Release Setup
run: python -m pip install --upgrade python-semantic-release
working-directory: "${{ github.workspace }}/${{inputs.PkgRootFolder}}"
- name: Python Semantic Release
id: pythonsemanticrelease
working-directory: "${{ github.workspace }}/${{inputs.PkgRootFolder}}"
# TODO: Patch only for testing
run: semantic-release -vv -c python-semantic-release.json version --patch --changelog --no-commit --no-tag --no-push --no-vcs-release --skip-build
- name: Environment Setup
run: python -m pip install --upgrade --requirement requirements_test.txt
working-directory: "${{ github.workspace }}/${{inputs.PkgRootFolder}}"
- name: Check Python Versions Consistency
# Only specify tox.ini and setup.py since .yml uses cibuildwheel
run: check-python-versions ${{ github.workspace }}\${{inputs.PkgRootFolder}} --only tox.ini,setup.py
- name: Black Static Analysis
if: success() || failure()
run: black -v --line-length 120 --safe --check --diff --color .
working-directory: "${{ github.workspace }}/${{inputs.PySourceFolder}}"
- name: Flake8 Static Analysis
if: success() || failure()
run: flake8 -v --config ${{ github.workspace }}\${{inputs.PkgRootFolder}}\setup.cfg .
working-directory: "${{ github.workspace }}/${{inputs.PySourceFolder}}"
- name: Pylint Static Analysis
if: success() || failure()
run: pylint_runner -v --rcfile ${{ github.workspace }}\${{inputs.PkgRootFolder}}\setup.cfg
working-directory: "${{ github.workspace }}/${{inputs.PySourceFolder}}"
- name: Mypy Static Analysis
if: success() || failure()
run: mypy -v --config-file ${{ github.workspace }}\${{inputs.PkgRootFolder}}\setup.cfg .
working-directory: "${{ github.workspace }}/${{inputs.PySourceFolder}}"
- name: Bandit Static Analysis
if: success() || failure()
run: bandit -v -r -c ${{ github.workspace }}\${{inputs.PkgRootFolder}}\bandit.yaml .
working-directory: "${{ github.workspace }}/${{inputs.PySourceFolder}}"
- name: Set TEMP to ${{ runner.temp }}
if: success() || failure()
run: echo "TEMP=${{ runner.temp }}" >> "$GITHUB_ENV"
shell: bash
- name: Set TMP to ${{ runner.temp }}
if: success() || failure()
run: echo "TMP=${{ runner.temp }}" >> "$GITHUB_ENV"
shell: bash
- name: Set TMPDIR to ${{ runner.temp }}
if: success() || failure()
run: echo "TMPDIR=${{ runner.temp }}" >> "$GITHUB_ENV"
shell: bash
- name: Unit and Integration Tests
if: success() || failure()
run: tox -vv -r -s false
working-directory: "${{ github.workspace }}/${{inputs.PkgRootFolder}}"
env:
CovResultsPath: "${{ runner.temp }}\\cov_results\\cov.xml"
TestResultsPath: "${{ runner.temp }}\\results"
- name: List files
run: dir
working-directory: "${{ runner.temp }}\\cov_results"
- name: Upload Coverage
if: success() || failure()
uses: codecov/codecov-action@v3
with:
# Hard copy from step above due to https://github.com/actions/runner/issues/2204
directory: ${{ runner.temp }}/cov_results
files: cov.xml
fail_ci_if_error: true
verbose: true
# Only one flag to be safe with
# https://docs.codecov.com/docs/flags#one-to-one-relationship-of-flags-to-uploads
flags: ${{matrix.OS}}
token: ${{ secrets.CODECOV_TOKEN }}
PackageWheelsNonPure:
name: Package Non-pure Wheels for ${{ matrix.config.OS }}
runs-on: ${{ matrix.config.PoolImage }}
strategy:
matrix:
config:
- {
PoolImage: ubuntu-latest,
OS: Linux,
CIBWBEFOREALL: '${{inputs.CIBWBEFOREALLLINUX}}',
}
- {
PoolImage: windows-2019,
OS: Windows,
CIBWBEFOREALL: '${{inputs.CIBWBEFOREALLWindows}}',
}
steps:
- uses: actions/[email protected]
with:
lfs: true
submodules: recursive
- uses: "./.github/actions/steps_package"
with:
PyVersionLatest: "${{inputs.PyVersionLatest}}"
PkgRootFolder: "${{ github.workspace }}/${{inputs.PkgRootFolder}}"
OS: "${{matrix.config.OS}}"
CIBWBEFOREALL: "${{matrix.config.CIBWBEFOREALL}}"
if: inputs.Pure == false && github.event_name != 'push' # TODO: Only debugging
PackageWheelsPure:
name: Package Pure Wheels
runs-on: windows-2019
if: inputs.Pure == true && github.event_name != 'push' # TODO: Only debugging
steps:
- uses: actions/[email protected]
with:
lfs: true
submodules: recursive
- name: Use Python ${{inputs.PyVersionLatest}}
uses: actions/[email protected]
with:
python-version: "${{inputs.PyVersionLatest}}"
architecture: x64
- name: Environment Setup
run: python -m pip install --upgrade --requirement requirements_deploy.txt
working-directory: "${{ github.workspace }}/${{inputs.PkgRootFolder}}"
- name: Build Distribution
run: python setup.py bdist_wheel
working-directory: "${{ github.workspace }}/${{inputs.PkgRootFolder}}"
- name: Publish Wheel for Python ${{inputs.PyVersionLatest}}
uses: actions/[email protected]
with:
name: Wheel${{inputs.PyVersionLatest}}
path: "${{ github.workspace }}\\${{inputs.PkgRootFolder}}\\dist"
PackageSDist:
if: github.event_name != 'push' # TODO: Only debugging
name: Package Source Distribution
runs-on: windows-2019
steps:
- uses: actions/[email protected]
with:
lfs: true
submodules: recursive
- name: Use Python ${{inputs.PyVersionLatest}}
uses: actions/[email protected]
with:
python-version: "${{inputs.PyVersionLatest}}"
architecture: x64
- name: Environment Setup
run: python -m pip install --upgrade --requirement requirements_deploy.txt
working-directory: "${{ github.workspace }}/${{inputs.PkgRootFolder}}"
- name: Build Distribution
run: python setup.py sdist
working-directory: "${{ github.workspace }}/${{inputs.PkgRootFolder}}"
- name: Publish Sdist
uses: actions/[email protected]
with:
name: Sdist
path: "${{ github.workspace }}\\${{inputs.PkgRootFolder}}\\dist"
DownloadTestWheelsPure:
# No need to re-test wheels for non-pure wheels produced through cibuildwheel since already tested there
# Can be tested anywhere since it is pure
name: Test Wheel on windows-2019
runs-on: windows-2019
steps:
- uses: actions/[email protected]
with:
lfs: true
- uses: "./.github/actions/steps_download"
with:
PyVersionLatest: "${{inputs.PyVersionLatest}}"
ArtifactName: Wheel${{inputs.PyVersionLatest}}
PkgRootFolder: "${{ github.workspace }}/${{inputs.PkgRootFolder}}"
RunShell: cmd
if: inputs.Pure == true && github.event_name != 'push' # TODO: Only debugging
needs: PackageWheelsPure
DownloadTestSdist:
if: github.event_name != 'push' # TODO: Only debugging
strategy:
matrix:
config:
- {
OS: ubuntu-latest,
RunShell: bash,
}
- {
OS: windows-2019,
RunShell: cmd,
}
runs-on: ${{ matrix.config.OS }}
steps:
- uses: actions/[email protected]
with:
lfs: true
- uses: "./.github/actions/steps_download"
with:
PyVersionLatest: "${{inputs.PyVersionLatest}}"
ArtifactName: Sdist
PkgRootFolder: "${{ github.workspace }}/${{inputs.PkgRootFolder}}"
RunShell: ${{ matrix.config.RunShell }}
needs: PackageSDist
Upload:
permissions:
contents: read
# IMPORTANT: this permission is mandatory for trusted publishing
id-token: write
needs:
- CodeQualityAnalysis-Test
- DownloadTestSdist
- DownloadTestWheelsPure
- PackageWheelsNonPure
- PackageWheelsPure
- PackageSdist
runs-on: windows-2019
if: contains(fromJSON('["skipped", "success"]'), needs.DownloadTestSdist.result) && contains(fromJSON('["skipped", "success"]'), needs.DownloadTestWheelsPure.result) && contains(fromJSON('["skipped", "success"]'), needs.PackageWheelsNonPure.result) && contains(fromJSON('["skipped", "success"]'), needs.PackageWheelsPure.result) && contains(fromJSON('["skipped", "success"]'), needs.PackageSdist.result) && github.event_name != 'pull_request' && contains(fromJSON('["skipped", "success"]'), needs.CodeQualityAnalysis-Test.result) # && needs.CodeQualityAnalysis-Test.result == 'success' && needs.CodeQualityAnalysis-Test.outputs.pypi_released == 'true'
environment:
# TODO: Only for testing purposes
# name: pypi
# url: https://pypi.org/project/pylibCZIrw/${{needs.CodeQualityAnalysis-Test.outputs.pypi_version}}
name: testpypi
url: https://test.pypi.org/p/pylibCZIrw/${{needs.CodeQualityAnalysis-Test.outputs.pypi_version}}
steps:
- uses: actions/[email protected]
- name: Use Python ${{inputs.PyVersionLatest}}
uses: actions/[email protected]
with:
python-version: "${{inputs.PyVersionLatest}}"
architecture: x64
- name: Environment Setup
run: python -m pip install --upgrade --requirement requirements_deploy.txt
working-directory: "${{ github.workspace }}/${{inputs.PkgRootFolder}}"
- name: Download Wheels and Source Distribution
uses: actions/[email protected]
- name: Collect Wheels and Source Distribution
run: New-Item -Path "." -Name "dist" -ItemType "directory"; Get-ChildItem -Path ".\*.whl",".\*.tar.gz" -Recurse | Move-Item -Destination ".\dist"
shell: powershell
- name: Check Rendering
run: twine check dist/*
- name: Upload to PyPI
# As of 06/2024, trusted publishing does not work within reusable workflows located in a different repo
# Tracked in:
# https://github.com/pypa/gh-action-pypi-publish/issues/166
# https://github.com/pypi/warehouse/issues/11096
# https://docs.pypi.org/trusted-publishers/troubleshooting/#reusable-workflows-on-github
uses: pypa/gh-action-pypi-publish@release/v1
with:
# TODO: Only for testing purposes
repository-url: https://test.pypi.org/legacy/
Tag:
permissions:
contents: write
needs: Upload
runs-on: windows-2019
steps:
- uses: actions/[email protected]
- name: Tag with PyPI version
uses: actions/github-script@v7
with:
script: |
github.rest.git.createRef({
owner: context.repo.owner,
repo: context.repo.repo,
ref: 'refs/tags/${{needs.CodeQualityAnalysis-Test.outputs.pypi_tag}}',
sha: context.sha
})