900af01f7805267048b61898acc1cd120405a690
[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   static-analysis:
12     runs-on: ubuntu-latest
13     timeout-minutes: 10
14     steps:
15       - name: Checkout code
16         uses: actions/checkout@v2
17
18       - name: Install tools
19         run: |
20           sudo apt-get install -y astyle clang-tidy-$CLANG
21           sudo update-alternatives --install /usr/bin/clang-tidy clang-tidy /usr/bin/clang-tidy-$CLANG 100
22           curl -OL "https://github.com/koalaman/shellcheck/releases/download/v$SHELLCHECK/shellcheck-v${SHELLCHECK}.linux.x86_64.tar.xz"
23           tar -C ~ --strip-components=1 --wildcards -xf ./shellcheck-*.tar.xz 'shellcheck-*/shellcheck'
24           curl -o ~/shfmt -L "https://github.com/mvdan/sh/releases/download/v$SHFMT/shfmt_v${SHFMT}_linux_amd64"
25           chmod 755 ~/shfmt ~/shellcheck
26           pip3 install --user compiledb
27         env:
28           CLANG: 11
29           SHELLCHECK: 0.7.2
30           SHFMT: 3.3.0
31
32       - name: Install deps
33         run: >
34           sudo apt-get install -y
35           git binutils make autoconf automake diffutils texinfo netcat
36           zlib1g-dev lib{ssl,lzo2,ncurses,readline,vdeplug,miniupnpc,gcrypt}-dev
37
38       - name: Configure and compile
39         run: |
40           autoreconf -fsi
41           ./configure --enable-{uml,vde,miniupnpc}
42           make -j$(nproc)
43           compiledb -n make check
44
45       - name: Check code formatting
46         run: "! astyle -r --options=.astylerc --dry-run --formatted '*.c' '*.h' | grep '^Formatted'"
47         if: always()
48
49       - name: Check scripts formatting
50         run: find -type f -regextype egrep -regex '.+\.(sh|sh\.in|test)$' -exec ~/shfmt -d -i 2 -s '{}' +
51         if: always()
52
53       - name: Run static analysis on scripts
54         run: find -type f -regextype egrep -regex '.+\.sh(\.in)?$' -exec shellcheck -x '{}' +
55         if: always()
56
57       - name: Run static analysis on tests
58         run: find -type f -name '*.test' -execdir shellcheck -x '{}' +
59         if: always()
60
61       - name: Run clang-tidy
62         run: |
63           find src \
64             ! '(' -path src/solaris -prune ')' \
65             ! '(' -path src/mingw   -prune ')' \
66             ! '(' -path src/bsd     -prune ')' \
67             -name '*.c' \
68             -exec clang-tidy --header-filter='.*' '{}' +
69         if: always()
70
71   sanitizer:
72     runs-on: ubuntu-latest
73     timeout-minutes: 10
74     strategy:
75       fail-fast: false
76       matrix:
77         sanitizer:
78           - address
79           - thread
80           - undefined
81     env:
82       SANITIZER: "${{ matrix.sanitizer }}"
83
84     steps:
85       - name: Checkout code
86         uses: actions/checkout@v2
87         with:
88           fetch-depth: 0
89
90       - name: Install deps
91         shell: bash
92         run: >
93           sudo apt-get install -y
94           git binutils make autoconf automake diffutils texinfo netcat
95           zlib1g-dev lib{ssl,lzo2,ncurses,readline,vdeplug,miniupnpc}-dev
96
97       - name: Configure and compile
98         shell: bash
99         run: bash .github/workflows/sanitizers/build.sh
100         env:
101           CC: clang-12
102
103       - name: Run tests
104         run: bash .github/workflows/sanitizers/run.sh
105
106       - name: Archive test results
107         run: sudo tar -c -z -f test-results.tar.gz test/ sanitizer/
108         if: always()
109
110       - name: Upload test results
111         uses: actions/upload-artifact@v2
112         with:
113           name: tests_sanitizer_${{ matrix.sanitizer }}
114           path: test-results.tar.gz
115         if: always()
116
117   linux:
118     runs-on: ubuntu-latest
119     timeout-minutes: 10
120     strategy:
121       fail-fast: false
122       matrix:
123         os:
124           - alpine:3.13
125           - centos:7 # aka RHEL 7
126           - almalinux:8 # aka RHEL 8
127           - debian:oldstable
128           - debian:stable
129           - debian:testing
130           - debian:unstable
131           - ubuntu:18.04 # previous LTS
132           - ubuntu:20.04 # current LTS
133           - opensuse/leap # aka SLES
134     container:
135       image: ${{ matrix.os }}
136       options: --privileged
137       env:
138         CI: 1
139     steps:
140       - name: Install deps (Alpine)
141         run: >
142           apk add git binutils make autoconf automake gcc linux-headers libtool
143           diffutils texinfo procps openssl-dev zlib-dev lzo-dev ncurses-dev
144           readline-dev musl-dev lz4-dev socat shadow sudo
145         if: startsWith(matrix.os, 'alpine')
146
147       - name: Install deps (Debian and Ubuntu)
148         shell: bash
149         run: |
150           apt-get update
151           apt-get install -y git binutils make autoconf automake gcc diffutils sudo \
152             texinfo netcat procps socat zlib1g-dev lib{ssl,lzo2,lz4,ncurses,readline}-dev
153         env:
154           DEBIAN_FRONTEND: noninteractive
155         if: startsWith(matrix.os, 'debian') || startsWith(matrix.os, 'ubuntu')
156
157       - name: Install deps (RHEL)
158         shell: bash
159         run: |
160           if type dnf 2>/dev/null; then
161             dnf install -y 'dnf-command(config-manager)'
162             dnf config-manager --enable powertools
163           fi
164           yum install -y epel-release
165           yum install -y git binutils make autoconf automake gcc diffutils sudo \
166             texinfo netcat procps socat {lzo,zlib,lz4,ncurses,readline}-devel
167           yum install -y openssl11-devel || yum install -y openssl-devel
168         if: startsWith(matrix.os, 'centos') || startsWith(matrix.os, 'alma')
169
170       - name: Install deps (SUSE)
171         shell: bash
172         run: >
173           zypper install -y tar git binutils make autoconf automake gcc procps sudo
174           makeinfo diffutils gzip socat {openssl,zlib,lzo,liblz4,ncurses,readline}-devel
175         if: startsWith(matrix.os, 'opensuse')
176
177       - name: Checkout code
178         uses: actions/checkout@v2
179         with:
180           fetch-depth: 0
181
182       - name: Assign name for test results artifact
183         run: echo TEST_ARTIFACT="$(echo '${{ matrix.os }}' | sed 's|[:/]|_|g')" >>"$GITHUB_ENV"
184
185       - name: Create a non-privileged user
186         run: |
187           useradd --user-group build
188           chown -R build:build .
189           echo 'build ALL=(ALL) NOPASSWD: ALL' >/etc/sudoers.d/build
190
191       - name: Run tests with default settings
192         run: sudo -u build CI=1 sh .github/workflows/test/run.sh default
193
194       - name: Run tests without legacy protocol
195         run: sudo -u build CI=1 sh .github/workflows/test/run.sh nolegacy
196
197       - name: Upload test results
198         uses: actions/upload-artifact@v2
199         with:
200           name: tests_${{ env.TEST_ARTIFACT }}
201           path: /tmp/tests.*.tar.gz
202         if: always()
203
204   deb-build:
205     if: startsWith(github.ref, 'refs/tags/release-')
206     needs: linux
207
208     strategy:
209       matrix:
210         os: [ubuntu-18.04, ubuntu-20.04]
211
212     runs-on: ${{ matrix.os }}
213     timeout-minutes: 5
214
215     steps:
216       - name: Checkout code
217         uses: actions/checkout@v2
218         with:
219           fetch-depth: 0
220
221       - name: Install build deps
222         run: >
223           sudo apt-get install -y --no-install-{recommends,suggests}
224           devscripts
225           git-buildpackage
226           dh-make
227           texinfo
228           libssl-dev
229           zlib1g-dev
230           liblzo2-dev
231           libncurses-dev
232           libreadline-dev
233           libminiupnpc-dev
234
235       - name: Configure project
236         run: autoreconf -fsi
237
238       - name: Prepare debian directory
239         run: bash .github/workflows/deb/prepare.sh
240         env:
241           JOB_DISTRIBUTION: ${{ matrix.os }}
242
243       - name: Build deb package
244         run: |
245           dpkg-buildpackage -d -us -uc
246           mv ../*.deb .
247
248       - name: Upload packages
249         uses: actions/upload-artifact@v2
250         with:
251           name: deb-${{ matrix.os }}
252           path: "*.deb"
253
254   deb-publish:
255     needs: deb-build
256
257     strategy:
258       matrix:
259         os: [ubuntu-18.04, ubuntu-20.04]
260
261     runs-on: ${{ matrix.os }}
262     timeout-minutes: 5
263
264     steps:
265       - name: Download built packages
266         uses: actions/download-artifact@v2
267         with:
268           name: deb-${{ matrix.os }}
269
270       - name: Install package
271         run: sudo apt-get install -y ./*.deb
272
273       - name: Prepare tinc configs
274         run: |
275           set -eu
276           sudo mkdir -p /etc/tinc/test/hosts
277           sudo tinc -b -n test generate-ed25519-keys
278           echo "Name test" | sudo tee /etc/tinc/test/tinc.conf
279
280       - name: Enable and start tincd
281         run: |
282           sudo systemctl start tinc@test
283           sudo tinc -n test dump reachable nodes
284
285       - name: Publish deb package
286         uses: softprops/action-gh-release@v1
287         with:
288           files: "*.deb"
289         env:
290           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
291
292   macos:
293     runs-on: macos-latest
294     timeout-minutes: 10
295
296     strategy:
297       fail-fast: false
298       matrix:
299         legacy_protocol: ["", --disable-legacy-protocol]
300
301     steps:
302       - name: Checkout code
303         uses: actions/checkout@v2
304         with:
305           fetch-depth: 0
306
307       - name: Install build deps
308         run: |
309           brew install coreutils netcat automake lzo lz4 miniupnpc
310           pip3 install --user compiledb
311
312       - name: Configure and compile
313         run: |
314           export CPPFLAGS="-I/usr/local/include"
315           export CPPFLAGS="$CPPFLAGS -I$(brew --prefix libgcrypt)/include"
316           export CPPFLAGS="$CPPFLAGS -I$(brew --prefix openssl)/include"
317           export CPPFLAGS="$CPPFLAGS -I$(brew --prefix libgcrypt)/include"
318
319           autoreconf -fsi
320           ./configure \
321             --with-openssl="$(brew --prefix openssl)" \
322             --with-miniupnpc="$(brew --prefix miniupnpc)" \
323             --enable-{tunemu,miniupnpc} \
324             ${{ matrix.legacy_protocol }}
325
326           make -j$(sysctl -n hw.ncpu)
327
328       - name: Run tests
329         run: |
330           export PATH="$PATH:$HOME/Library/Python/3.9/bin"
331           compiledb make -j$(sysctl -n hw.ncpu) check VERBOSE=1
332
333       - name: Run clang-tidy
334         run: |
335           export PATH="$PATH:$(brew --prefix llvm)/bin/"
336           find src \
337             ! '(' -path src/solaris -prune ')' \
338             ! '(' -path src/mingw   -prune ')' \
339             ! '(' -path src/linux   -prune ')' \
340             ! -name vde_device.c \
341             -name '*.c' \
342             -exec clang-tidy --header-filter='.*' '{}' +
343         if: ${{ matrix.legacy_protocol == '' }}
344
345       - name: Archive test results
346         run: sudo tar -c -z -f test-results.tar.gz test/
347         if: always()
348
349       - name: Upload test results
350         uses: actions/upload-artifact@v2
351         with:
352           name: tests_${{ runner.os }}_${{ matrix.legacy_protocol }}
353           path: test-results.tar.gz
354         if: always()
355
356   windows:
357     runs-on: windows-latest
358     timeout-minutes: 20
359
360     strategy:
361       fail-fast: false
362       matrix:
363         legacy_protocol: ["", --disable-legacy-protocol]
364
365     steps:
366       - name: Checkout code
367         uses: actions/checkout@v2
368         with:
369           fetch-depth: 0
370
371       - name: Install msys2
372         uses: msys2/setup-msys2@v2
373         with:
374           update: true
375           # https://packages.msys2.org/package/
376           install: >-
377             base-devel
378             mingw-w64-x86_64-gcc
379             mingw-w64-x86_64-openssl
380             mingw-w64-x86_64-zlib
381             mingw-w64-x86_64-lzo2
382             mingw-w64-x86_64-lz4
383             mingw-w64-x86_64-ncurses
384             mingw-w64-x86_64-miniupnpc
385             git
386             netcat
387             procps
388
389       - name: Configure project
390         shell: msys2 {0}
391         run: |
392           autoreconf -fsi
393           ./configure --enable-miniupnpc --disable-readline --with-curses-include=/mingw64/include/ncurses ${{ matrix.legacy_protocol }}
394
395       - name: Compile project
396         shell: msys2 {0}
397         run: make -j$(nproc)
398
399       - name: Run tests
400         shell: msys2 {0}
401         run: make check-recursive VERBOSE=1
402
403       - name: Archive test results
404         shell: msys2 {0}
405         run: tar -c -z -f test-results.tar.gz test/
406         if: always()
407
408       - name: Upload test results
409         uses: actions/upload-artifact@v2
410         with:
411           name: tests_${{ runner.os }}_${{ matrix.legacy_protocol }}
412           path: test-results.tar.gz
413         if: always()