Some cleanups in GitHub Actions CI
authorKirill Isakov <is-kir@ya.ru>
Mon, 19 Jul 2021 19:03:06 +0000 (01:03 +0600)
committerKirill Isakov <is-kir@ya.ru>
Tue, 20 Jul 2021 15:14:27 +0000 (21:14 +0600)
  - run tests on more Linux distributions
  - add test runs with clang sanitizers (TSAN / UBSAN for now)
  - check code formatting only once
  - check test scripts formatting (shfmt)
  - static analysis for test scripts (shellcheck)
  - save more test logs and other debug info
  - add missing pieces to Ubuntu packages
  - test .debs on clean machine before publishing
  - git clone full history for changelog generation
  - support old versions of git on Linux
  - rename some steps

17 files changed:
.github/workflows/deb/debian/compat [new file with mode: 0644]
.github/workflows/deb/debian/control [new file with mode: 0644]
.github/workflows/deb/debian/copyright [new file with mode: 0644]
.github/workflows/deb/debian/doc-base.tinc [new file with mode: 0644]
.github/workflows/deb/debian/info [new file with mode: 0644]
.github/workflows/deb/debian/preinst [new file with mode: 0644]
.github/workflows/deb/debian/rules [new file with mode: 0755]
.github/workflows/deb/debian/tinc.default [new file with mode: 0644]
.github/workflows/deb/prepare.sh [new file with mode: 0755]
.github/workflows/sanitizers/build.sh [new file with mode: 0755]
.github/workflows/sanitizers/ignore.txt [new file with mode: 0644]
.github/workflows/sanitizers/run.sh [new file with mode: 0755]
.github/workflows/test.yml
.github/workflows/test/run.sh [new file with mode: 0644]
Makefile.am
test/security.test
test/testlib.sh.in

diff --git a/.github/workflows/deb/debian/compat b/.github/workflows/deb/debian/compat
new file mode 100644 (file)
index 0000000..b4de394
--- /dev/null
@@ -0,0 +1 @@
+11
diff --git a/.github/workflows/deb/debian/control b/.github/workflows/deb/debian/control
new file mode 100644 (file)
index 0000000..38b23dd
--- /dev/null
@@ -0,0 +1,22 @@
+Source: tinc
+Section: net
+Priority: optional
+Maintainer: none <none@notsupported>
+Standards-Version: 4.2.1
+Build-Depends: libssl-dev (>>1.0.0), debhelper (>= 11), texinfo, zlib1g-dev, liblzo2-dev, libncurses5-dev, libreadline-dev, libminiupnpc-dev
+Homepage: https://www.tinc-vpn.org/
+Vcs-Browser: https://github.com/gsliepen/tinc
+Vcs-Git: https://github.com/gsliepen/tinc.git
+Rules-Requires-Root: no
+
+Package: tinc
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Description: Virtual Private Network daemon
+ tinc is a daemon with which you can create a virtual private network
+ (VPN). One daemon can handle multiple connections, so you can
+ create an entire (moderately sized) VPN with only one daemon per
+ participating computer.
+ This is an automated build and is not supported by upstream. It has
+ gone through automated testing before being published, but may or may
+ not work on your system. Use at your own risk.
diff --git a/.github/workflows/deb/debian/copyright b/.github/workflows/deb/debian/copyright
new file mode 100644 (file)
index 0000000..c8a6fb8
--- /dev/null
@@ -0,0 +1,34 @@
+This package was debianized by Ivo Timmermans <ivo@debian.org> on
+Fri, 21 Apr 2000 17:07:50 +0200.
+
+It was downloaded from http://www.tinc-vpn.org/
+
+Upstream Authors:
+ Guus Sliepen <guus@tinc-vpn.org>
+ Ivo Timmermans <ivo@tinc-vpn.org>
+
+Copyright (C) 1998-2005 Ivo Timmermans
+              1998-2008 Guus Sliepen <guus@tinc-vpn.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+On Debian GNU/Linux systems, the complete text of the GNU General Public
+License version 2 can be found in /usr/share/common-licenses/GPL-2.
+
+The following applies to tinc:
+
+This program is released under the GPL with the additional exemption
+that compiling, linking, and/or using OpenSSL is allowed.  You may
+provide binary packages linked to the OpenSSL libraries, provided that
+all other requirements of the GPL are met.
+
+The following applies to the LZO library:
+
+Hereby I grant a special exception to the tinc VPN project
+(http://tinc.nl.linux.org/) to link the LZO library with the OpenSSL library
+(http://www.openssl.org).
+
+Markus F.X.J. Oberhumer
diff --git a/.github/workflows/deb/debian/doc-base.tinc b/.github/workflows/deb/debian/doc-base.tinc
new file mode 100644 (file)
index 0000000..a37f46a
--- /dev/null
@@ -0,0 +1,10 @@
+Document: tinc
+Title: tinc Manual
+Author: Ivo Timmermans, Guus Sliepen
+Abstract: This manual describes how to set up a Virtual Private
+ Network with tinc.
+Section: System/Security
+
+Format: HTML
+Files: /usr/share/doc/tinc/tinc.html/*
+Index: /usr/share/doc/tinc/tinc.html/index.html
diff --git a/.github/workflows/deb/debian/info b/.github/workflows/deb/debian/info
new file mode 100644 (file)
index 0000000..5468d6c
--- /dev/null
@@ -0,0 +1 @@
+doc/tinc.info
diff --git a/.github/workflows/deb/debian/preinst b/.github/workflows/deb/debian/preinst
new file mode 100644 (file)
index 0000000..030c1d0
--- /dev/null
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+NETSFILE="/etc/tinc/nets.boot"
+SYSTEM="/lib/systemd/system"
+WANTS="/etc/systemd/system/multi-user.target.wants"
+
+set -e
+
+case "$1" in
+       upgrade)
+               if dpkg --compare-versions "$2" '<<' "1.1~pre11-1"; then
+                       if [ -f "$NETSFILE" ]; then
+                               echo -n "Creating systemd service instances from nets.boot:"
+                               mkdir -p "$WANTS"
+                               egrep '^[ ]*[a-zA-Z0-9_-]+' $NETSFILE | while read net args; do
+                                       echo -n " $net"
+                                       ln -s "$SYSTEM/tinc@.service" "$WANTS/tinc@$net.service" 2>/dev/null || true
+                               done
+                               echo "."
+                       fi
+               fi
+       ;;
+
+       *)
+       ;;
+esac
+
+#DEBHELPER#
diff --git a/.github/workflows/deb/debian/rules b/.github/workflows/deb/debian/rules
new file mode 100755 (executable)
index 0000000..e1cbc60
--- /dev/null
@@ -0,0 +1,21 @@
+#!/usr/bin/make -f
+
+%:
+       dh $@
+
+override_dh_auto_configure:
+       dh_auto_configure -- --enable-uml --enable-miniupnpc \
+               --with-systemd=/lib/systemd/system/
+       $(MAKE) clean
+
+override_dh_auto_install:
+       dh_auto_install -- install-html
+       # Remove info dir file
+       rm -f debian/tinc/usr/share/info/dir
+
+override_dh_auto_test:
+       # Don't run the tests, it involves starting tinc daemons and making network connections.
+       # I don't think the autobuilders will like this.
+
+override_dh_installinit:
+       dh_installinit -r
diff --git a/.github/workflows/deb/debian/tinc.default b/.github/workflows/deb/debian/tinc.default
new file mode 100644 (file)
index 0000000..bca2432
--- /dev/null
@@ -0,0 +1,7 @@
+# Extra options to be passed to tincd.
+# EXTRA="-d"
+
+# Limits to be configured for the tincd process. Please read your shell
+# (pointed by /bin/sh) documentation for ulimit. You probably want to raise the
+# max locked memory value if using both --mlock and --user flags.
+# LIMITS="-l 1024"
diff --git a/.github/workflows/deb/prepare.sh b/.github/workflows/deb/prepare.sh
new file mode 100755 (executable)
index 0000000..34eccbc
--- /dev/null
@@ -0,0 +1,37 @@
+#!/bin/bash
+
+set -euo pipefail
+
+bail() {
+  echo >&2 "$@"
+  exit 1
+}
+
+find_tag() {
+  git describe --abbrev=0 --always --tags --match='release-*' "$@"
+}
+
+templates=.github/workflows/deb/debian
+
+# get latest tag name
+curr=$(find_tag HEAD)
+[[ -z $curr ]] && bail 'could not determine release version'
+
+# get previous tag name
+prev=$(find_tag "$curr"^)
+[[ -z $curr ]] && bail 'could not determine previous release version'
+
+# strip release prefix to get the current version number
+version=${curr//release-/}
+
+# prepare a new debian directory
+dh_make --yes --single --createorig --copyright gpl2 --packagename "tinc_$version-$JOB_DISTRIBUTION"
+
+# write all commit messages between two most recent tags to the changelog
+gbp dch --since "$prev" --ignore-branch --spawn-editor=never --release
+
+# replace placeholders with files copied from https://packages.debian.org/experimental/tinc
+cp "$templates/"* debian/
+
+# remove useless READMEs created by dh_make
+rm -f debian/README.*
diff --git a/.github/workflows/sanitizers/build.sh b/.github/workflows/sanitizers/build.sh
new file mode 100755 (executable)
index 0000000..63da2cd
--- /dev/null
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+set -euo pipefail
+
+dir=$(realpath "$(dirname "$0")")
+
+case "$SANITIZER" in
+undefined)
+  flags='-fsanitize=integer -fsanitize=nullability'
+  ;;
+
+address)
+  flags='-fsanitize-address-use-after-scope -fsanitize=pointer-compare -fsanitize=pointer-subtract'
+  ;;
+
+*)
+  flags=''
+  ;;
+esac
+
+export CPPFLAGS='-DDEBUG'
+export CFLAGS="-O0 -g -fsanitize=$SANITIZER -fno-omit-frame-pointer -fno-common -fsanitize-blacklist=$dir/ignore.txt $flags"
+
+autoreconf -fsi
+./configure --enable-{uml,vde,miniupnpc}
+make -j"$(nproc)" all
diff --git a/.github/workflows/sanitizers/ignore.txt b/.github/workflows/sanitizers/ignore.txt
new file mode 100644 (file)
index 0000000..7295aeb
--- /dev/null
@@ -0,0 +1,2 @@
+src:ed25519/*
+src:chacha-poly1305/*
diff --git a/.github/workflows/sanitizers/run.sh b/.github/workflows/sanitizers/run.sh
new file mode 100755 (executable)
index 0000000..de12a2b
--- /dev/null
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+set -euo pipefail
+
+logs="$GITHUB_WORKSPACE/sanitizer"
+mkdir -p "$logs"
+
+case "$SANITIZER" in
+address)
+  export ASAN_OPTIONS="log_path=$logs/asan:detect_invalid_pointer_pairs=2:strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1"
+  ;;
+
+thread)
+  export TSAN_OPTIONS="log_path=$logs/tsan"
+  ;;
+
+undefined)
+  export UBSAN_OPTIONS="log_path=$logs/ubsan:print_stacktrace=1"
+  ;;
+
+*)
+  echo >&2 "unknown sanitizer $SANITIZER"
+  exit 1
+  ;;
+esac
+
+sudo --preserve-env=ASAN_OPTIONS,TSAN_OPTIONS,UBSAN_OPTIONS \
+  make check VERBOSE=1
index 214dd1d..1b819a6 100644 (file)
@@ -1,4 +1,4 @@
-name: Build and test
+name: Test
 
 on:
   push:
@@ -8,119 +8,181 @@ on:
       - synchronize
 
 jobs:
-  test-linux:
+  code-style:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Checkout code
+        uses: actions/checkout@v2
+
+      - name: Install code formatting tools
+        run: |
+          sudo apt-get install -y astyle
+          curl -OL 'https://github.com/koalaman/shellcheck/releases/download/v0.7.2/shellcheck-v0.7.2.linux.x86_64.tar.xz'
+          tar -C ~ --strip-components=1 --wildcards -xf ./shellcheck-*.tar.xz 'shellcheck-*/shellcheck'
+          curl -o ~/shfmt -L 'https://github.com/mvdan/sh/releases/download/v3.3.0/shfmt_v3.3.0_linux_amd64'
+          chmod 755 ~/shfmt ~/shellcheck
+
+      - name: Check code formatting
+        run: "! astyle -r --options=.astylerc --dry-run --formatted '*.c' '*.h' | grep '^Formatted'"
+
+      - name: Check scripts formatting
+        run: find -type f -regextype egrep -regex '.+\.(sh|sh\.in|test)$' -exec ~/shfmt -d -i 2 -s '{}' +
+        if: always()
+
+      - name: Run static analysis on scripts
+        run: find -type f -regextype egrep -regex '.+\.sh(\.in)?$' -exec shellcheck -x '{}' +
+        if: always()
+
+      - name: Prepare test library and run static analysis on tests
+        run: |
+          autoreconf -fsi
+          ./configure --disable-{lzo,readline,zlib,curses}
+          find -type f -name '*.test' -execdir shellcheck -x '{}' +
+        if: always()
+
+  sanitizer:
+    runs-on: ubuntu-latest
     strategy:
-      matrix:
-        os: [ubuntu-18.04, ubuntu-20.04]
-        compiler: [clang, gcc]
-        legacy_protocol: ["", --disable-legacy-protocol]
       fail-fast: false
-
-    runs-on: ${{ matrix.os }}
+      matrix:
+        sanitizer:
+          - thread
+          - undefined
     env:
-      CC: ${{ matrix.compiler }}
+      SANITIZER: "${{ matrix.sanitizer }}"
 
     steps:
       - name: Checkout code
         uses: actions/checkout@v2
+        with:
+          fetch-depth: 0
 
-      - name: Install Artistic Style and build deps
-        run: >
-          sudo apt-get install -y --no-install-{recommends,suggests}
-          zlib1g-dev
-          liblzo2-dev
-          libncurses-dev
-          libreadline-dev
-          libminiupnpc-dev
-          libvdeplug-dev
-          astyle
-          socket
-
-      - name: Install OpenSSL
-        run: sudo apt-get install -y libssl-dev
-        if: ${{ matrix.legacy_protocol == '' }}
-
-      - name: Run autoreconf
-        run: autoreconf -fsi
-
-      - name: Run ./configure
+      - name: Install deps
+        shell: bash
         run: >
-          ./configure 
-          --enable-{miniupnpc,uml,vde}
-          ${{ matrix.legacy_protocol }}
-
-      - name: Check code formatting
-        run: make check-style
+          sudo apt-get install -y
+          git binutils make autoconf automake diffutils texinfo netcat
+          zlib1g-dev lib{ssl,lzo2,ncurses,readline,vdeplug,miniupnpc}-dev
 
-      - name: Compile project
-        run: make -j$(nproc)
+      - name: Configure and compile
+        shell: bash
+        run: bash .github/workflows/sanitizers/build.sh
+        env:
+          CC: clang-12
 
       - name: Run tests
-        # root is required for some tests
-        run: sudo make check-recursive
-        timeout-minutes: 20
+        run: bash .github/workflows/sanitizers/run.sh
+
+      - name: Archive test results
+        run: sudo tar -c -z -f test-results.tar.gz test/ sanitizer/
+        if: always()
 
       - name: Upload test results
         uses: actions/upload-artifact@v2
         with:
-          name: tests_${{ matrix.os }}_${{ matrix.compiler }}
-          path: test/test-suite.log
-        if: failure()
+          name: tests_sanitizer_${{ matrix.sanitizer }}
+          path: test-results.tar.gz
+        if: always()
 
-  build-windows:
-    runs-on: windows-latest
+  linux:
+    runs-on: ubuntu-latest
+    strategy:
+      fail-fast: false
+      matrix:
+        os:
+          - alpine:3.13
+          - centos:7 # aka RHEL 7
+          - almalinux:8 # aka RHEL 8
+          - debian:oldstable
+          - debian:stable
+          - debian:testing
+          - debian:unstable
+          - ubuntu:18.04 # previous LTS
+          - ubuntu:20.04 # current LTS
+          - opensuse/leap # aka SLES
+    container:
+      image: ${{ matrix.os }}
+      options: --privileged
 
     steps:
+      - name: Install deps (Alpine)
+        run: >
+          apk add git binutils make autoconf automake gcc linux-headers libtool
+          diffutils texinfo procps openssl-dev zlib-dev lzo-dev ncurses-dev
+          readline-dev musl-dev lz4-dev socat
+        if: startsWith(matrix.os, 'alpine')
+
+      - name: Install deps (Debian and Ubuntu)
+        shell: bash
+        run: |
+          apt-get update
+          apt-get install -y git binutils make autoconf automake gcc diffutils \
+            texinfo netcat procps socat zlib1g-dev lib{ssl,lzo2,lz4,ncurses,readline}-dev
+        env:
+          DEBIAN_FRONTEND: noninteractive
+        if: startsWith(matrix.os, 'debian') || startsWith(matrix.os, 'ubuntu')
+
+      - name: Install deps (RHEL)
+        shell: bash
+        run: |
+          if type dnf 2>/dev/null; then
+            dnf install -y 'dnf-command(config-manager)'
+            dnf config-manager --enable powertools
+          fi
+          yum install -y epel-release
+          yum install -y git binutils make autoconf automake gcc diffutils \
+            texinfo netcat procps socat {lzo,zlib,lz4,openssl,ncurses,readline}-devel
+        if: startsWith(matrix.os, 'centos') || startsWith(matrix.os, 'alma')
+
+      - name: Install deps (SUSE)
+        shell: bash
+        run: >
+          zypper install -y tar git binutils make autoconf automake gcc procps
+          makeinfo diffutils gzip socat {openssl,zlib,lzo,liblz4,ncurses,readline}-devel
+        if: startsWith(matrix.os, 'opensuse')
+
       - name: Checkout code
         uses: actions/checkout@v2
-
-      - name: Install msys2
-        uses: msys2/setup-msys2@v2
         with:
-          update: true
-          # https://packages.msys2.org/package/
-          install: >-
-            base-devel
-            mingw-w64-x86_64-gcc
-            mingw-w64-x86_64-openssl
-            mingw-w64-x86_64-zlib
-            mingw-w64-x86_64-lzo2
-            mingw-w64-x86_64-ncurses
-            mingw-w64-x86_64-miniupnpc
-            git
+          fetch-depth: 0
 
-      - name: Build the project
-        shell: msys2 {0}
-        run: |
-          autoreconf -fsi
-          ./configure --with-curses-include=/mingw64/include/ncurses --disable-readline
-          make -j$(nproc)
+      - name: Assign name for test results artifact
+        run: echo TEST_ARTIFACT="$(echo '${{ matrix.os }}' | sed 's|[:/]|_|g')" >>"$GITHUB_ENV"
 
-      - name: Check that tinc can be started
-        shell: msys2 {0}
-        run: ./src/tinc --version
+      - name: Run tests with default settings
+        run: sh .github/workflows/test/run.sh default
 
-      - name: Check that tincd can be started
-        shell: msys2 {0}
-        run: ./src/tincd --version
+      - name: Run tests without legacy protocol
+        run: sh .github/workflows/test/run.sh nolegacy
 
-  release-deb:
+      - name: Upload test results
+        uses: actions/upload-artifact@v2
+        with:
+          name: tests_${{ env.TEST_ARTIFACT }}
+          path: /tmp/tests.*.tar.gz
+        if: always()
+
+  deb-build:
     if: startsWith(github.ref, 'refs/tags/release-')
-    needs: test-linux
+    needs: linux
 
     strategy:
       matrix:
-        os: ["ubuntu-18.04", ubuntu-20.04]
+        os: [ubuntu-18.04, ubuntu-20.04]
 
     runs-on: ${{ matrix.os }}
 
     steps:
       - name: Checkout code
         uses: actions/checkout@v2
+        with:
+          fetch-depth: 0
 
       - name: Install build deps
         run: >
           sudo apt-get install -y --no-install-{recommends,suggests}
+          devscripts
+          git-buildpackage
           dh-make
           texinfo
           libssl-dev
@@ -128,70 +190,157 @@ jobs:
           liblzo2-dev
           libncurses-dev
           libreadline-dev
+          libminiupnpc-dev
 
-      - name: Run autoreconf
+      - name: Configure project
         run: autoreconf -fsi
 
-      - name: Run ./configure
-        run: >
-          ./configure 
-          --prefix=/usr
-          --sbindir=/usr/sbin
-          --sysconfdir=/etc
-          --localstatedir=/var
-          --with-systemd=/usr/lib/systemd/system
-
       - name: Prepare debian directory
-        run: >
-          dh_make
-          --yes
-          --single
-          --createorig
-          --copyright gpl2
-          --packagename "tinc_$(git describe --tags --always | sed 's/release-//')-${{ matrix.os }}"
+        run: bash .github/workflows/deb/prepare.sh
         env:
-          DEBFULLNAME: Automated Builds
+          JOB_DISTRIBUTION: ${{ matrix.os }}
 
       - name: Build deb package
-        run: dpkg-buildpackage -d -us -uc
+        run: |
+          dpkg-buildpackage -d -us -uc
+          mv ../*.deb .
+
+      - name: Upload packages
+        uses: actions/upload-artifact@v2
+        with:
+          name: deb-${{ matrix.os }}
+          path: "*.deb"
+
+  deb-publish:
+    needs: deb-build
+
+    strategy:
+      matrix:
+        os: [ubuntu-18.04, ubuntu-20.04]
+
+    runs-on: ${{ matrix.os }}
+
+    steps:
+      - name: Download built packages
+        uses: actions/download-artifact@v2
+        with:
+          name: deb-${{ matrix.os }}
+
+      - name: Install package
+        run: sudo apt-get install -y ./*.deb
+
+      - name: Prepare tinc configs
+        run: |
+          set -eu
+          sudo mkdir -p /etc/tinc/test/hosts
+          sudo tinc -b -n test generate-ed25519-keys
+          echo "Name test" | sudo tee /etc/tinc/test/tinc.conf
+
+      - name: Enable and start tincd
+        run: |
+          sudo systemctl start tinc@test
+          sudo tinc -n test dump reachable nodes
 
       - name: Publish deb package
         uses: softprops/action-gh-release@v1
         with:
-          files: |
-            ../*.deb
+          files: "*.deb"
         env:
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
 
-  test-macos:
-    runs-on: macos-10.15
+  macos:
+    runs-on: macos-latest
+
+    strategy:
+      fail-fast: false
+      matrix:
+        legacy_protocol: ["", --disable-legacy-protocol]
 
     steps:
       - name: Checkout code
         uses: actions/checkout@v2
+        with:
+          fetch-depth: 0
 
-      - name: Install dependencies
-        run: brew install coreutils netcat automake lzo miniupnpc
-
-      - name: Run autoreconf
-        run: autoreconf -fsi
+      - name: Install build deps
+        run: brew install coreutils netcat automake lzo lz4 miniupnpc
 
-      - name: Run ./configure
-        run: >
-          ./configure
-          --with-openssl=/usr/local/opt/openssl@1.1
-          --enable-{tunemu,miniupnpc}
+      - name: Configure project
+        run: |
+          autoreconf -fsi
+          ./configure --with-openssl=/usr/local/opt/openssl@1.1 --enable-{tunemu,miniupnpc} ${{ matrix.legacy_protocol }}
 
-      - name: Compile application
+      - name: Compile project
         run: make -j$(sysctl -n hw.ncpu)
 
       - name: Run tests
-        run: make check-recursive
-        timeout-minutes: 20
+        run: make check-recursive VERBOSE=1
+
+      - name: Archive test results
+        run: sudo tar -c -z -f test-results.tar.gz test/
+        if: always()
+
+      - name: Upload test results
+        uses: actions/upload-artifact@v2
+        with:
+          name: tests_${{ runner.os }}_${{ matrix.legacy_protocol }}
+          path: test-results.tar.gz
+        if: always()
+
+  windows:
+    runs-on: windows-latest
+
+    strategy:
+      fail-fast: false
+      matrix:
+        legacy_protocol: ["", --disable-legacy-protocol]
+
+    steps:
+      - name: Checkout code
+        uses: actions/checkout@v2
+        with:
+          fetch-depth: 0
+
+      - name: Install msys2
+        uses: msys2/setup-msys2@v2
+        with:
+          update: true
+          # https://packages.msys2.org/package/
+          install: >-
+            base-devel
+            mingw-w64-x86_64-gcc
+            mingw-w64-x86_64-openssl
+            mingw-w64-x86_64-zlib
+            mingw-w64-x86_64-lzo2
+            mingw-w64-x86_64-lz4
+            mingw-w64-x86_64-ncurses
+            mingw-w64-x86_64-miniupnpc
+            git
+            netcat
+            procps
+
+      - name: Configure project
+        shell: msys2 {0}
+        run: |
+          autoreconf -fsi
+          ./configure --enable-miniupnpc --disable-readline --with-curses-include=/mingw64/include/ncurses ${{ matrix.legacy_protocol }}
+
+      - name: Compile project
+        shell: msys2 {0}
+        run: make -j$(nproc)
+
+      - name: Run tests
+        shell: msys2 {0}
+        run: make check-recursive VERBOSE=1
+
+      - name: Archive test results
+        shell: msys2 {0}
+        run: tar -c -z -f test-results.tar.gz test/
+        if: always()
 
       - name: Upload test results
         uses: actions/upload-artifact@v2
         with:
-          name: tests_${{ runner.os }}
-          path: test/test-suite.log
-        if: failure()
+          name: tests_${{ runner.os }}_${{ matrix.legacy_protocol }}
+          path: test-results.tar.gz
+        if: always()
diff --git a/.github/workflows/test/run.sh b/.github/workflows/test/run.sh
new file mode 100644 (file)
index 0000000..74bb8bd
--- /dev/null
@@ -0,0 +1,61 @@
+#!/bin/sh
+
+set -eu
+
+bail() {
+  echo >&2 "@"
+  exit 1
+}
+
+header() {
+  echo '################################################################################'
+  echo "# $*"
+  echo '################################################################################'
+}
+
+run_tests() {
+  flavor="$1"
+  shift
+
+  header "Cleaning up leftovers from previous runs"
+
+  for name in tinc tincd; do
+    pkill -TERM -x "$name" || true
+    pkill -KILL -x "$name" || true
+  done
+
+  git clean -dfx
+
+  header "Running test flavor $flavor"
+
+  autoreconf -fsi
+  ./configure "$@"
+  make -j"$(nproc)"
+
+  code=0
+  make check -j2 VERBOSE=1 || code=$?
+
+  tar -c -z -f "/tmp/tests.$flavor.tar.gz" test/
+
+  return $code
+}
+
+# GitHub Checkout action supports git 2.18+.
+# If we're running in a container with an older version,
+# create our own local repository to make `git clean` work.
+if ! [ -e .git ]; then
+  git init
+  git add .
+fi
+
+case "$1" in
+default)
+  run_tests default ''
+  ;;
+nolegacy)
+  run_tests nolegacy --disable-legacy-protocol
+  ;;
+*)
+  bail "unknown test flavor $1"
+  ;;
+esac
index 568d548..6f0f687 100644 (file)
@@ -36,8 +36,5 @@ release:
        /usr/bin/editor $(srcdir)/NEWS
        $(MAKE) dist
 
-check-style:
-       astyle --options=.astylerc --dry-run -nQ src/*.[ch] src/*/*.[ch]
-
 astyle:
        astyle --options=.astylerc -nQ src/*.[ch] src/*/*.[ch]
index 815825e..76b825d 100755 (executable)
@@ -5,8 +5,8 @@
 
 echo [STEP] Skip this test if tools are missing
 
-which nc >/dev/null || exit $EXIT_SKIP_TEST
-which timeout >/dev/null || exit $EXIT_SKIP_TEST
+command -v nc >/dev/null || exit $EXIT_SKIP_TEST
+command -v timeout >/dev/null || exit $EXIT_SKIP_TEST
 
 foo_port=30050
 bar_port=30051
index 185aec0..14192ea 100644 (file)
@@ -19,10 +19,13 @@ realdir() {
 tincd_path=$(realdir "../src/tincd@EXEEXT@")
 tinc_path=$(realdir "../src/tinc@EXEEXT@")
 
+# shellcheck disable=SC2034
 SPTPS_TEST=$(realdir "../src/sptps_test@EXEEXT@")
+# shellcheck disable=SC2034
 SPTPS_KEYPAIR=$(realdir "../src/sptps_keypair@EXEEXT@")
 
 # Exit status list
+# shellcheck disable=SC2034
 EXIT_SKIP_TEST=77
 
 # The list of the environment variables that tinc injects into the scripts it calls.
@@ -60,8 +63,10 @@ is_busybox() {
 
 # busybox timeout returns 128 + signal number (which is TERM by default)
 if is_busybox; then
+  # shellcheck disable=SC2034
   EXIT_TIMEOUT=$((128 + 15))
 else
+  # shellcheck disable=SC2034
   EXIT_TIMEOUT=124
 fi