52dd0ef75f04ad3f29667296d5e50ac3b5b098d4
[tinc] / .github / workflows / test.yml
1 name: Test
2
3 on:
4   push:
5   pull_request:
6     types:
7       - opened
8       - synchronize
9
10 jobs:
11   cross:
12     runs-on: ubuntu-latest
13     timeout-minutes: 30
14     strategy:
15       fail-fast: false
16       matrix:
17         arch:
18           - armhf
19           - mipsel
20           - mingw
21
22     container:
23       image: debian:bullseye
24       options: --privileged
25
26     steps:
27       - name: Checkout code
28         uses: actions/checkout@v1
29
30       - name: Install deps
31         run: HOST=${{ matrix.arch }} sh .ci/deps.sh
32
33       - name: Prepare the system
34         run: HOST=${{ matrix.arch }} sh .ci/test/prepare.sh
35
36       - name: Run tests with default settings
37         run: sudo -u build CI=1 HOST=${{ matrix.arch }} sh .ci/test/run.sh default
38
39       - name: Run tests without legacy protocol
40         run: sudo -u build CI=1 HOST=${{ matrix.arch }} sh .ci/test/run.sh nolegacy
41         if: always()
42
43       - name: Run tests with libgcrypt
44         run: sudo -u build CI=1 HOST=${{ matrix.arch }} sh .ci/test/run.sh gcrypt
45         if: always()
46
47       - name: Upload test results
48         uses: actions/upload-artifact@v2
49         with:
50           name: tests_cross_${{ matrix.arch }}
51           path: /tmp/logs/tests.*.tar.gz
52         if: always()
53
54   static-analysis:
55     runs-on: ubuntu-latest
56     timeout-minutes: 30
57     steps:
58       - name: Checkout code
59         uses: actions/checkout@v1
60
61       - name: Install tools
62         run: |
63           sudo apt-get install -y astyle clang-tidy-$CLANG
64           sudo update-alternatives --install /usr/bin/clang-tidy     clang-tidy     /usr/bin/clang-tidy-$CLANG     100
65           sudo update-alternatives --install /usr/bin/run-clang-tidy run-clang-tidy /usr/bin/run-clang-tidy-$CLANG 100
66           curl -OL "https://github.com/koalaman/shellcheck/releases/download/v$SHELLCHECK/shellcheck-v${SHELLCHECK}.linux.x86_64.tar.xz"
67           tar -C ~ --strip-components=1 --wildcards -xf ./shellcheck-*.tar.xz 'shellcheck-*/shellcheck'
68           curl -o ~/shfmt -L "https://github.com/mvdan/sh/releases/download/v$SHFMT/shfmt_v${SHFMT}_linux_amd64"
69           chmod 755 ~/shfmt ~/shellcheck
70           python3 -m venv /tmp/venv
71           . /tmp/venv/bin/activate
72           pip3 install black pylint mypy
73         env:
74           CLANG: 11
75           SHELLCHECK: 0.7.2
76           SHFMT: 3.3.0
77
78       - name: Install deps
79         run: sudo SKIP_OPENSSL3=1 sh .ci/deps.sh
80
81       - name: Lint/typecheck/check formatting on C/shell/Python code
82         run: |
83           . /tmp/venv/bin/activate
84           PATH=$PATH:$HOME ./lint.py
85         if: always()
86
87       - name: Check warnings (clang)
88         run: bash .ci/warn/run.sh
89         env:
90           CC: clang-12
91         if: always()
92
93       - name: Check warnings (gcc)
94         run: bash .ci/warn/run.sh
95         env:
96           CC: gcc-10
97         if: always()
98
99   sanitizer:
100     runs-on: ubuntu-latest
101     timeout-minutes: 30
102     strategy:
103       fail-fast: false
104       matrix:
105         sanitizer:
106           - address
107           - thread
108           - undefined
109     env:
110       SANITIZER: "${{ matrix.sanitizer }}"
111
112     steps:
113       - name: Checkout code
114         uses: actions/checkout@v1
115
116       - name: Install deps
117         run: sudo sh .ci/deps.sh
118
119       - name: Run tests with OpenSSL 3
120         run: bash .ci/sanitizers/run.sh openssl3
121         if: always()
122
123       - name: Sanitize tests with default settings
124         run: bash .ci/sanitizers/run.sh default
125         if: always()
126
127       - name: Sanitize tests without legacy protocol
128         run: bash .ci/sanitizers/run.sh nolegacy
129         if: always()
130
131       - name: Run tests with libgcrypt
132         run: bash .ci/sanitizers/run.sh gcrypt
133         if: always()
134
135       - name: Upload test results
136         uses: actions/upload-artifact@v2
137         with:
138           name: tests_sanitizer_${{ matrix.sanitizer }}
139           path: /tmp/logs/tests.*.tar.gz
140         if: always()
141
142   linux:
143     runs-on: ubuntu-latest
144     timeout-minutes: 30
145     strategy:
146       fail-fast: false
147       matrix:
148         os:
149           - alpine
150           - alpine:edge
151           - centos:7 # aka RHEL 7
152           - almalinux:8 # aka RHEL 8
153           - almalinux:9 # aka RHEL 9
154           - fedora
155           - debian:buster
156           - debian:bullseye
157           - debian:testing
158           - ubuntu # current LTS
159           - ubuntu:rolling # latest
160     container:
161       image: ${{ matrix.os }}
162       options: --privileged
163       env:
164         CI: 1
165     steps:
166       - name: Checkout code
167         uses: actions/checkout@v1
168
169       - name: Install deps
170         run: sh .ci/deps.sh
171
172       - name: Assign name for test results artifact
173         run: echo ARTIFACT="$(echo '${{ matrix.os }}' | sed 's|[:/]|_|g')" >>"$GITHUB_ENV"
174
175       - name: Create a non-privileged user
176         run: sh .ci/test/prepare.sh
177
178       - name: Run tests with OpenSSL 3
179         run: sudo -u build CI=1 sh .ci/test/run.sh openssl3
180
181       - name: Run tests with default settings
182         run: sudo -u build CI=1 sh .ci/test/run.sh default
183         if: always()
184
185       - name: Run tests without legacy protocol
186         run: sudo -u build CI=1 sh .ci/test/run.sh nolegacy
187         if: always()
188
189       - name: Run tests with libgcrypt
190         run: sudo -u build CI=1 sh .ci/test/run.sh gcrypt
191         if: always()
192
193       - name: Upload test results
194         uses: actions/upload-artifact@v2
195         with:
196           name: tests_${{ env.ARTIFACT }}
197           path: /tmp/logs/tests.*.tar.gz
198         if: always()
199
200       - name: Build package
201         run: sh .ci/package/build.sh
202         if: github.ref == 'refs/heads/1.1' || startsWith(github.ref, 'refs/tags/release-')
203         continue-on-error: true
204
205       - name: Upload package
206         uses: actions/upload-artifact@v2
207         with:
208           name: pkg-${{ env.ARTIFACT }}
209           path: |
210             *.deb
211             ~/rpmbuild/RPMS/*/*.rpm
212         continue-on-error: true
213
214   pkg-publish:
215     if: always() && (github.ref == 'refs/heads/1.1' || startsWith(github.ref, 'refs/tags/release-'))
216     runs-on: ubuntu-latest
217     continue-on-error: true
218     needs:
219       - linux
220       - mingw
221
222     steps:
223       - name: Create artifact directory
224         run: mkdir -p /tmp/artifacts
225
226       - name: Download packages
227         uses: actions/download-artifact@v2
228         with:
229           path: /tmp/artifacts
230
231       - name: Publish packages (dev)
232         uses: marvinpinto/action-automatic-releases@latest
233         with:
234           repo_token: ${{ secrets.GITHUB_TOKEN }}
235           automatic_release_tag: latest
236           title: Development release
237           prerelease: true
238           files: /tmp/artifacts/**/*.(deb|rpm|exe)
239         if: startsWith(github.ref, 'refs/heads/')
240
241       - name: Publish packages (release)
242         uses: softprops/action-gh-release@v1
243         with:
244           files: |
245             /tmp/artifacts/**/*.deb
246             /tmp/artifacts/**/*.rpm
247             /tmp/artifacts/**/*.exe
248         if: startsWith(github.ref, 'refs/tags/')
249
250   macos:
251     runs-on: macos-latest
252     timeout-minutes: 20
253
254     steps:
255       - name: Checkout code
256         uses: actions/checkout@v1
257
258       - name: Install build deps
259         run: sh .ci/deps.sh
260
261       - name: Run tests with default settings
262         run: sh .ci/test/run.sh default
263
264       - name: Run tests without legacy protocol
265         run: sh .ci/test/run.sh nolegacy
266         if: always()
267
268       - name: Run tests with libgcrypt
269         run: sh .ci/test/run.sh gcrypt
270         if: always()
271
272       - name: Upload test results
273         uses: actions/upload-artifact@v2
274         with:
275           name: tests_macos
276           path: /tmp/logs/tests.*.tar.gz
277         if: always()
278
279   mingw:
280     runs-on: windows-latest
281     timeout-minutes: 30
282
283     steps:
284       - name: Install msys2
285         uses: msys2/setup-msys2@v2
286         with:
287           update: true
288           # https://packages.msys2.org/package/
289           install: >-
290             base-devel
291             mingw-w64-x86_64-meson
292             mingw-w64-x86_64-pkgconf
293             mingw-w64-x86_64-gcc
294             mingw-w64-x86_64-openssl
295             mingw-w64-x86_64-libgcrypt
296             mingw-w64-x86_64-zlib
297             mingw-w64-x86_64-lzo2
298             mingw-w64-x86_64-lz4
299             mingw-w64-x86_64-ncurses
300             mingw-w64-x86_64-miniupnpc
301             mingw-w64-x86_64-nsis
302             git
303             openbsd-netcat
304             procps
305
306       - name: Checkout code
307         uses: actions/checkout@v1
308
309       - name: Run tests with default settings
310         shell: msys2 {0}
311         run: sh .ci/test/run.sh default
312
313       - name: Create installer
314         shell: msys2 {0}
315         run: sh .ci/package/build.sh
316         if: github.ref == 'refs/heads/1.1' || startsWith(github.ref, 'refs/tags/release-')
317         continue-on-error: true
318
319       - name: Upload package
320         uses: actions/upload-artifact@v2
321         with:
322           name: pkg-windows
323           path: .ci/package/win/tinc-*.exe
324         continue-on-error: true
325
326       - name: Run tests without legacy protocol
327         shell: msys2 {0}
328         run: sh .ci/test/run.sh nolegacy
329         if: always()
330
331       - name: Run tests with libgcrypt
332         shell: msys2 {0}
333         run: sh .ci/test/run.sh gcrypt
334         if: always()
335
336       - name: Upload test results
337         uses: actions/upload-artifact@v2
338         with:
339           name: tests_windows
340           path: /tmp/logs/tests.*.tar.gz
341         if: always()
342
343   msvc:
344     runs-on: windows-latest
345     timeout-minutes: 30
346
347     strategy:
348       fail-fast: false
349       matrix:
350         target:
351           - { build: amd64, host: amd64, test: test }
352           - { build: amd64, host: x86, test: test }
353           - { build: amd64, host: arm64, test: notest }
354
355     env:
356       HOST_ARCH: ${{ matrix.target.host }}
357       BUILD_ARCH: ${{ matrix.target.build }}
358
359     steps:
360       - name: Install meson
361         run: pip3 install meson
362
363       - name: Checkout code
364         uses: actions/checkout@v1
365
366       - name: Activate dev environment
367         uses: ilammy/msvc-dev-cmd@v1
368         with:
369           arch: ${{ matrix.target.build == matrix.target.host && matrix.target.host || format('{0}_{1}', matrix.target.build, matrix.target.host) }}
370
371       - name: Build (nolegacy)
372         run: .ci\windows\build.cmd nolegacy
373
374       - name: Test (nolegacy)
375         run: .ci\windows\test.cmd nolegacy
376         if: always() && matrix.target.test == 'test'
377
378       - name: Build (OpenSSL)
379         run: .ci\windows\build.cmd openssl
380         if: always()
381
382       - name: Test (OpenSSL)
383         run: .ci\windows\test.cmd openssl
384         if: always() && matrix.target.test == 'test'