CI: cross-compilation; build packages on every push.
authorKirill Isakov <is-kir@ya.ru>
Sun, 8 Aug 2021 16:57:42 +0000 (22:57 +0600)
committerKirill Isakov <is-kir@ya.ru>
Tue, 10 Aug 2021 07:02:32 +0000 (13:02 +0600)
Build tinc for two architectures frequently seen in cheap routers,
and run tests using qemu user virtualization.

Also build deb + rpm packages and a Windows installer on every push to
the main branch (currently it's 1.1), and publish them as a pre-release.

27 files changed:
.builds/freebsd.yml
.ci/README.md [new file with mode: 0644]
.ci/conf.sh [new file with mode: 0644]
.ci/deps.sh [new file with mode: 0755]
.ci/package/build.sh [new file with mode: 0755]
.ci/package/deb/build.sh [moved from .github/workflows/deb/prepare.sh with 73% similarity]
.ci/package/deb/debian/compat [moved from .github/workflows/deb/debian/compat with 100% similarity]
.ci/package/deb/debian/control [moved from .github/workflows/deb/debian/control with 100% similarity]
.ci/package/deb/debian/copyright [moved from .github/workflows/deb/debian/copyright with 100% similarity]
.ci/package/deb/debian/doc-base.tinc [moved from .github/workflows/deb/debian/doc-base.tinc with 100% similarity]
.ci/package/deb/debian/info [moved from .github/workflows/deb/debian/info with 100% similarity]
.ci/package/deb/debian/preinst [moved from .github/workflows/deb/debian/preinst with 100% similarity]
.ci/package/deb/debian/rules [moved from .github/workflows/deb/debian/rules with 100% similarity]
.ci/package/deb/debian/tinc.default [moved from .github/workflows/deb/debian/tinc.default with 100% similarity]
.ci/package/rpm/build.sh [new file with mode: 0755]
.ci/package/rpm/tinc.spec [new file with mode: 0644]
.ci/package/win/build.sh [new file with mode: 0755]
.ci/package/win/installer.nsi [new file with mode: 0644]
.ci/sanitizers/build.sh [moved from .github/workflows/sanitizers/build.sh with 85% similarity]
.ci/sanitizers/ignore.txt [moved from .github/workflows/sanitizers/ignore.txt with 100% similarity]
.ci/sanitizers/run.sh [moved from .github/workflows/sanitizers/run.sh with 100% similarity]
.ci/test/prepare.sh [new file with mode: 0755]
.ci/test/run.sh [moved from .github/workflows/test/run.sh with 50% similarity]
.ci/tidy/run.sh [new file with mode: 0755]
.ci/warn/run.sh [moved from .github/workflows/warn/run.sh with 71% similarity]
.github/workflows/test.yml
.gitignore

index 547032c..26829cc 100644 (file)
@@ -35,14 +35,9 @@ tasks:
       make check-recursive VERBOSE=1
 
   - lint: |
-      export PATH=$PATH:$HOME/.local/bin
+      mkdir -p ~/.local/bin
+      ln -f -s "$(which clang-tidy12)" ~/.local/bin/clang-tidy
       pip install --user compiledb
       cd tinc
-      compiledb -n make check
-      find src \
-        ! '(' -path src/solaris -prune ')' \
-        ! '(' -path src/mingw   -prune ')' \
-        ! '(' -path src/linux   -prune ')' \
-        ! -name tunemu.c \
-        -name '*.c' \
-        -exec clang-tidy12 --header-filter='.*' '{}' +
+      export PATH=$PATH:$HOME/.local/bin
+      sh .ci/tidy/run.sh
diff --git a/.ci/README.md b/.ci/README.md
new file mode 100644 (file)
index 0000000..3b7f081
--- /dev/null
@@ -0,0 +1,6 @@
+# Continuous Integration
+
+This directory contains scripts and other files used by the continuous integration system.
+
+You probably should not run them manually.
+
diff --git a/.ci/conf.sh b/.ci/conf.sh
new file mode 100644 (file)
index 0000000..ab50277
--- /dev/null
@@ -0,0 +1,67 @@
+#!/bin/sh
+
+set -eu
+
+add_flag() {
+  printf ' %s ' "$@"
+}
+
+conf_linux() {
+  . /etc/os-release
+
+  if type rpm >&2; then
+    # CentOS 7 has OpenSSL 1.1 installed in a non-default location.
+    if [ -d /usr/include/openssl11 ]; then
+      add_flag --with-openssl-include=/usr/include/openssl11
+    fi
+
+    if [ -d /usr/lib64/openssl11 ]; then
+      add_flag --with-openssl-lib=/usr/lib64/openssl11
+    fi
+
+    # RHEL 8 does not ship miniupnpc.
+    if rpm -q miniupnpc-devel >&2; then
+      add_flag --enable-miniupnpc
+    fi
+  else
+    # vde2 is available everywhere except the RHEL family.
+    add_flag --enable-vde
+  fi
+
+  # Cross-compilation.
+  if [ -n "${HOST:-}" ]; then
+    case "$HOST" in
+    armhf) triplet=arm-linux-gnueabihf ;;
+    mips) triplet=mips-linux-gnu ;;
+    *) exit 1 ;;
+    esac
+
+    add_flag --host="$triplet"
+  fi
+
+  add_flag --enable-uml "$@"
+}
+
+conf_windows() {
+  add_flag \
+    --enable-miniupnpc \
+    --disable-readline \
+    --with-curses-include=/mingw64/include/ncurses \
+    "$@"
+}
+
+conf_macos() {
+  add_flag \
+    --with-openssl="$(brew --prefix openssl)" \
+    --with-miniupnpc="$(brew --prefix miniupnpc)" \
+    --enable-tunemu \
+    --enable-miniupnpc \
+    "$@"
+}
+
+case "$(uname -s)" in
+Linux) conf_linux "$@" ;;
+MINGW*) conf_windows "$@" ;;
+Darwin) conf_macos "$@" ;;
+*) exit 1 ;;
+esac
diff --git a/.ci/deps.sh b/.ci/deps.sh
new file mode 100755 (executable)
index 0000000..4906384
--- /dev/null
@@ -0,0 +1,100 @@
+#!/bin/sh
+
+set -eu
+
+deps_linux_alpine() {
+  apk upgrade
+
+  apk add \
+    git binutils make autoconf automake gcc linux-headers diffutils texinfo \
+    procps socat shadow sudo \
+    openssl-dev zlib-dev lzo-dev ncurses-dev readline-dev musl-dev lz4-dev vde2-dev
+}
+
+deps_linux_debian() {
+  export DEBIAN_FRONTEND=noninteractive
+
+  HOST=${HOST:-}
+
+  if [ -n "$HOST" ]; then
+    dpkg --add-architecture "$HOST"
+  fi
+
+  apt-get update
+  apt-get upgrade -y
+
+  apt-get install -y \
+    git binutils make autoconf automake gcc diffutils sudo texinfo netcat procps socat \
+    zlib1g-dev:"$HOST" \
+    libssl-dev:"$HOST" \
+    liblzo2-dev:"$HOST" \
+    liblz4-dev:"$HOST" \
+    libncurses-dev:"$HOST" \
+    libreadline-dev:"$HOST" \
+    libgcrypt-dev:"$HOST" \
+    libminiupnpc-dev:"$HOST" \
+    libvdeplug-dev:"$HOST" \
+    "$@"
+
+  if [ -n "$HOST" ]; then
+    apt-get install -y crossbuild-essential-"$HOST" qemu-user
+  fi
+}
+
+deps_linux_rhel() {
+  if [ "$ID" != fedora ]; then
+    yum install -y epel-release
+
+    if type dnf; then
+      dnf install -y 'dnf-command(config-manager)'
+      dnf config-manager --enable powertools
+    fi
+  fi
+
+  yum upgrade -y
+
+  yum install -y \
+    git binutils make autoconf automake gcc diffutils sudo texinfo netcat procps systemd \
+    findutils socat lzo-devel zlib-devel lz4-devel ncurses-devel readline-devel "$@"
+
+  if yum info openssl11-devel; then
+    yum install -y openssl11-devel
+  else
+    dnf install -y openssl-devel
+  fi
+
+  if yum info miniupnpc-devel; then
+    yum install -y miniupnpc-devel
+  fi
+}
+
+deps_linux() {
+  . /etc/os-release
+
+  case "$ID" in
+  alpine)
+    deps_linux_alpine "$@"
+    ;;
+
+  debian | ubuntu)
+    deps_linux_debian "$@"
+    ;;
+
+  centos | almalinux | fedora)
+    deps_linux_rhel "$@"
+    ;;
+
+  *) exit 1 ;;
+  esac
+}
+
+deps_macos() {
+  brew install coreutils netcat automake lzo lz4 miniupnpc "$@"
+  pip3 install --user compiledb
+}
+
+case "$(uname -s)" in
+Linux) deps_linux "$@" ;;
+Darwin) deps_macos "$@" ;;
+*) exit 1 ;;
+esac
diff --git a/.ci/package/build.sh b/.ci/package/build.sh
new file mode 100755 (executable)
index 0000000..9c3748b
--- /dev/null
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+set -eu
+
+build_linux() {
+  . /etc/os-release
+
+  case "$ID" in
+  debian | ubuntu)
+    bash .ci/package/deb/build.sh
+    ;;
+  almalinux | centos | fedora)
+    bash .ci/package/rpm/build.sh
+    ;;
+  esac
+}
+
+case "$(uname -s)" in
+Linux)
+  build_linux
+  ;;
+MINGW*)
+  bash .ci/package/win/build.sh
+  ;;
+esac
similarity index 73%
rename from .github/workflows/deb/prepare.sh
rename to .ci/package/deb/build.sh
index 34eccbc..86b363d 100755 (executable)
@@ -2,16 +2,25 @@
 
 set -euo pipefail
 
+. /etc/os-release
+
 bail() {
   echo >&2 "$@"
   exit 1
 }
 
 find_tag() {
-  git describe --abbrev=0 --always --tags --match='release-*' "$@"
+  git describe --always --tags --match='release-*' "$@"
 }
 
-templates=.github/workflows/deb/debian
+apt-get install -y devscripts git-buildpackage dh-make
+
+export USER=${USER:-$(whoami)}
+
+os="$ID-$VERSION_ID"
+templates=$(dirname "$0")/debian
+
+git clean -dfx
 
 # get latest tag name
 curr=$(find_tag HEAD)
@@ -25,7 +34,7 @@ prev=$(find_tag "$curr"^)
 version=${curr//release-/}
 
 # prepare a new debian directory
-dh_make --yes --single --createorig --copyright gpl2 --packagename "tinc_$version-$JOB_DISTRIBUTION"
+dh_make --yes --single --createorig --copyright gpl2 --packagename "tinc_$version-$os"
 
 # write all commit messages between two most recent tags to the changelog
 gbp dch --since "$prev" --ignore-branch --spawn-editor=never --release
@@ -35,3 +44,6 @@ cp "$templates/"* debian/
 
 # remove useless READMEs created by dh_make
 rm -f debian/README.*
+
+dpkg-buildpackage -d -us -uc
+mv ../*.deb .
diff --git a/.ci/package/rpm/build.sh b/.ci/package/rpm/build.sh
new file mode 100755 (executable)
index 0000000..b07df47
--- /dev/null
@@ -0,0 +1,37 @@
+#!/bin/bash
+
+set -euo pipefail
+
+find_tag() {
+  git describe --always --tags --match='release-*' "$@"
+}
+
+# CentOS 7 has OpenSSL 1.1 installed in a non-default location.
+if [ -d /usr/include/openssl11 ]; then
+  set -- "$@" --with-openssl-include=/usr/include/openssl11
+fi
+
+if [ -d /usr/lib64/openssl11 ]; then
+  set -- "$@" --with-openssl-lib=/usr/lib64/openssl11
+fi
+
+spec=$HOME/rpmbuild/SPECS/tinc.spec
+configure=$(sh .ci/conf.sh)
+
+version=$(find_tag HEAD | sed 's/-/_/g')
+version=${version//release_/}
+
+export CONFIG_SHELL=bash
+
+yum install -y rpmdevtools
+rpmdev-setuptree
+
+cp "$(dirname "$0")/tinc.spec" "$spec"
+sed -i "s/__VERSION__/$version/" "$spec"
+sed -i "s#__CONFIGURE_ARGS__#$configure#" "$spec"
+
+git clean -dfx
+autoreconf -fsi
+cp -a . ~/rpmbuild/BUILD
+
+rpmbuild -bb "$spec"
diff --git a/.ci/package/rpm/tinc.spec b/.ci/package/rpm/tinc.spec
new file mode 100644 (file)
index 0000000..707587d
--- /dev/null
@@ -0,0 +1,53 @@
+Name:           tinc
+Version:        __VERSION__
+Release:        3%{?dist}
+Summary:        A virtual private network daemon
+
+License:        GPLv2+
+URL:            https://www.tinc-vpn.org/
+
+BuildRequires: systemd
+
+Requires(post):   systemd
+Requires(preun):  systemd
+Requires(postun): systemd
+
+%description
+tinc is a Virtual Private Network (VPN) daemon that uses tunnelling
+and encryption to create a secure private network between hosts on
+the Internet. Because the tunnel appears to the IP level network
+code as a normal network device, there is no need to adapt any
+existing software. This tunnelling allows VPN sites to share
+information with each other over the Internet without exposing any
+information to others.
+
+%define debug_package %{nil}
+
+%prep
+
+%build
+%configure --with-systemd=%{_unitdir} __CONFIGURE_ARGS__
+%make_build
+
+%install
+%make_install
+rm -f %{buildroot}%{_infodir}/dir
+
+%post
+%systemd_post %{name}@.service
+
+%preun
+%systemd_preun %{name}@.service
+
+%postun
+%systemd_postun_with_restart %{name}@.service
+
+%files
+%doc AUTHORS COPYING.README NEWS README THANKS doc/sample* doc/*.tex
+%license COPYING
+%{_mandir}/man*/%{name}*.*
+%{_infodir}/%{name}.info.*
+%{_sbindir}/%{name}
+%{_sbindir}/%{name}d
+%{_unitdir}/%{name}*.service
+%{_datadir}/bash-completion/completions/%{name}
diff --git a/.ci/package/win/build.sh b/.ci/package/win/build.sh
new file mode 100755 (executable)
index 0000000..098f455
--- /dev/null
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+set -euo pipefail
+
+curl -o wintap.exe -L 'https://build.openvpn.net/downloads/releases/latest/tap-windows-latest-stable.exe'
+
+makensis .ci/package/win/installer.nsi
diff --git a/.ci/package/win/installer.nsi b/.ci/package/win/installer.nsi
new file mode 100644 (file)
index 0000000..4c4dd35
--- /dev/null
@@ -0,0 +1,31 @@
+!include "MUI.nsh"
+
+!define MUI_ABORTWARNING
+!insertmacro MUI_PAGE_WELCOME
+!insertmacro MUI_PAGE_LICENSE "..\..\..\COPYING"
+!insertmacro MUI_PAGE_DIRECTORY
+!insertmacro MUI_PAGE_INSTFILES
+!insertmacro MUI_PAGE_FINISH
+
+!insertmacro MUI_LANGUAGE "English"
+
+Name "tinc"
+OutFile "tinc-x64.exe"
+InstallDir "$PROGRAMFILES64\tinc"
+ShowInstDetails show
+RequestExecutionLevel admin
+
+Section "Tinc"
+  SetOutPath $INSTDIR
+
+  File ..\..\..\src\tinc.exe
+  File ..\..\..\src\tincd.exe
+  File ..\..\..\wintap.exe
+
+  CreateDirectory "$SMPROGRAMS\Tinc"
+  CreateShortCut "$SMPROGRAMS\Tinc.lnk" "$INSTDIR\tinc.exe"
+
+  ExecWait "wintap.exe"
+
+  CreateDirectory "$SMPROGRAMS\tinc"
+SectionEnd
similarity index 85%
rename from .github/workflows/sanitizers/build.sh
rename to .ci/sanitizers/build.sh
index 63da2cd..9276f12 100755 (executable)
@@ -22,5 +22,6 @@ 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
+# shellcheck disable=SC2046
+./configure $(sh .ci/conf.sh)
+make -j2 all extra
diff --git a/.ci/test/prepare.sh b/.ci/test/prepare.sh
new file mode 100755 (executable)
index 0000000..8a01a3f
--- /dev/null
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+set -eu
+
+if [ "$(id -u)" != 0 ] && sudo --preserve-env --non-interactive true; then
+  echo >&2 "sudo already configured"
+  exit 0
+fi
+
+useradd --user-group build
+
+echo 'build ALL=(ALL) NOPASSWD: ALL' >/etc/sudoers.d/build
+chmod 440 /etc/sudoers.d/build
+visudo --check
similarity index 50%
rename from .github/workflows/test/run.sh
rename to .ci/test/run.sh
index 9f397f9..a6a38b7 100644 (file)
@@ -25,42 +25,52 @@ run_tests() {
   done
 
   sudo git clean -dfx
-  sudo chown -R build:build .
+  sudo chown -R "${USER:-$(whoami)}" .
 
   header "Running test flavor $flavor"
 
-  # CentOS 7 has OpenSSL 1.1 installed in a non-default location.
-  if test -d /usr/include/openssl11; then
-    set -- "$@" --with-openssl-include=/usr/include/openssl11
-  fi
-
-  if test -d /usr/lib64/openssl11; then
-    set -- "$@" --with-openssl-lib=/usr/lib64/openssl11
-  fi
-
   autoreconf -fsi
-  ./configure "$@"
-  make -j"$(nproc)"
+  # shellcheck disable=SC2046
+  ./configure $(sh .ci/conf.sh "$@")
+  make -j"$(nproc)" all extra
 
   code=0
   make check -j2 VERBOSE=1 || code=$?
 
-  sudo tar -c -z -f "/tmp/tests.$flavor.tar.gz" test/
+  mkdir -p /tmp/logs
+  sudo tar -c -z -f "/tmp/logs/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
+echo "system name $(uname -s)"
+echo "full $(uname -a)"
+echo "o $(uname -o)"
+
+case "$(uname -s)" in
+Linux)
+  if [ -n "${HOST:-}" ]; then
+    # Needed for cross-compilation for 32-bit targets.
+    export CPPFLAGS='-D_FILE_OFFSET_BITS=64'
+  fi
+  ;;
+
+MINGW*)
+  # No-op.
+  sudo() { "$@"; }
+  ;;
+
+Darwin)
+  nproc() { sysctl -n hw.ncpu; }
+  gcrypt=$(brew --prefix libgcrypt)
+  openssl=$(brew --prefix openssl)
+  export CPPFLAGS="-I/usr/local/include -I$gcrypt/include -I$openssl/include -I$gcrypt/include"
+  ;;
+esac
 
 case "$1" in
 default)
-  run_tests default ''
+  run_tests default
   ;;
 nolegacy)
   run_tests nolegacy --disable-legacy-protocol
diff --git a/.ci/tidy/run.sh b/.ci/tidy/run.sh
new file mode 100755 (executable)
index 0000000..8af4767
--- /dev/null
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+set -eu
+
+# Which paths to ignore.
+paths='src/solaris src/mingw'
+
+case "$(uname -s)" in
+Linux)
+  paths="$paths src/bsd"
+  ;;
+
+FreeBSD)
+  paths="$paths src/linux src/bsd/tunemu.c"
+  ;;
+
+Darwin)
+  paths="$paths src/linux src/vde_device.c"
+  ;;
+
+*) exit 1 ;;
+esac
+
+path_filters=''
+for path in $paths; do
+  path_filters=" $path_filters ! ( -path $path -prune ) "
+done
+
+if ! [ -f compile_commands.json ]; then
+  # Running compiledb directly on this doesn't work on FreeBSD for some reason.
+  make -j2 all extra
+  compiledb -n make check
+fi
+
+echo >&2 "Running clang-tidy without $paths"
+
+# This is fine, our paths are relative and do not contain any whitespace.
+# shellcheck disable=SC2086
+find src \
+  $path_filters \
+  -name '*.c' \
+  -exec clang-tidy --header-filter='.*' '{}' +
similarity index 71%
rename from .github/workflows/warn/run.sh
rename to .ci/warn/run.sh
index f3b06db..65f46eb 100755 (executable)
@@ -1,6 +1,6 @@
-#!/bin/sh
+#!/bin/bash
 
-set -eu
+set -euo pipefail
 
 test -n "$CC"
 export CFLAGS="${CFLAGS:-} -Werror"
@@ -11,8 +11,8 @@ check_warnings() {
   git clean -dfx
 
   autoreconf -fsi
-  ./configure --enable-uml --enable-vde --enable-miniupnpc "$@"
-
+  # shellcheck disable=SC2046
+  ./configure $(sh .ci/conf.sh)
   make -j"$(nproc)" all extra || result=$?
 }
 
index 6db9ea5..05670b7 100644 (file)
@@ -8,12 +8,51 @@ on:
       - synchronize
 
 jobs:
+  cross:
+    runs-on: ubuntu-latest
+    timeout-minutes: 15
+    strategy:
+      fail-fast: false
+      matrix:
+        arch:
+          - armhf
+          - mips
+
+    container:
+      image: debian:stable
+      options: --privileged
+
+    steps:
+      - name: Checkout code
+        uses: actions/checkout@v1
+
+      - name: Install deps
+        run: HOST=${{ matrix.arch }} sh .ci/deps.sh
+
+      - name: Prepare the system
+        run: |
+          sh .ci/test/prepare.sh
+          rm -f /dev/net/tun
+
+      - name: Run tests with default settings
+        run: sudo -u build CI=1 HOST=${{ matrix.arch }} sh .ci/test/run.sh default
+
+      - name: Run tests without legacy protocol
+        run: sudo -u build CI=1 HOST=${{ matrix.arch }} sh .ci/test/run.sh nolegacy
+
+      - name: Upload test results
+        uses: actions/upload-artifact@v2
+        with:
+          name: tests_cross_${{ env.ARTIFACT }}
+          path: /tmp/logs/tests.*.tar.gz
+        if: always()
+
   static-analysis:
     runs-on: ubuntu-latest
     timeout-minutes: 10
     steps:
       - name: Checkout code
-        uses: actions/checkout@v2
+        uses: actions/checkout@v1
 
       - name: Install tools
         run: |
@@ -30,17 +69,16 @@ jobs:
           SHFMT: 3.3.0
 
       - name: Install deps
-        run: >
-          sudo apt-get install -y
-          git binutils make autoconf automake diffutils texinfo netcat
-          zlib1g-dev lib{ssl,lzo2,ncurses,readline,vdeplug,miniupnpc,gcrypt}-dev
+        run: sudo sh .ci/deps.sh
 
       - name: Configure and compile
         run: |
           autoreconf -fsi
-          ./configure --enable-{uml,vde,miniupnpc}
-          make -j$(nproc)
-          compiledb -n make check
+          ./configure $(sh .ci/conf.sh)
+
+      - name: Run clang-tidy
+        run: sh .ci/tidy/run.sh
+        if: always()
 
       - name: Check code formatting
         run: "! astyle -r --options=.astylerc --dry-run --formatted '*.c' '*.h' | grep '^Formatted'"
@@ -58,24 +96,14 @@ jobs:
         run: find -type f -name '*.test' -execdir shellcheck -x '{}' +
         if: always()
 
-      - name: Run clang-tidy
-        run: |
-          find src \
-            ! '(' -path src/solaris -prune ')' \
-            ! '(' -path src/mingw   -prune ')' \
-            ! '(' -path src/bsd     -prune ')' \
-            -name '*.c' \
-            -exec clang-tidy --header-filter='.*' '{}' +
-        if: always()
-
       - name: Check warnings (gcc)
-        run: bash .github/workflows/warn/run.sh
+        run: bash .ci/warn/run.sh
         env:
           CC: gcc
         if: always()
 
       - name: Check warnings (clang)
-        run: bash .github/workflows/warn/run.sh
+        run: bash .ci/warn/run.sh
         env:
           CC: clang
         if: always()
@@ -95,25 +123,19 @@ jobs:
 
     steps:
       - name: Checkout code
-        uses: actions/checkout@v2
-        with:
-          fetch-depth: 0
+        uses: actions/checkout@v1
 
       - name: Install deps
-        shell: bash
-        run: >
-          sudo apt-get install -y
-          git binutils make autoconf automake diffutils texinfo netcat
-          zlib1g-dev lib{ssl,lzo2,ncurses,readline,vdeplug,miniupnpc}-dev
+        run: sudo sh .ci/deps.sh
 
       - name: Configure and compile
         shell: bash
-        run: bash .github/workflows/sanitizers/build.sh
+        run: bash .ci/sanitizers/build.sh
         env:
           CC: clang-12
 
       - name: Run tests
-        run: bash .github/workflows/sanitizers/run.sh
+        run: bash .ci/sanitizers/run.sh
 
       - name: Archive test results
         run: sudo tar -c -z -f test-results.tar.gz test/ sanitizer/
@@ -128,258 +150,131 @@ jobs:
 
   linux:
     runs-on: ubuntu-latest
-    timeout-minutes: 10
+    timeout-minutes: 20
     strategy:
       fail-fast: false
       matrix:
         os:
-          - alpine:3.13
+          - alpine
           - centos:7 # aka RHEL 7
           - almalinux:8 # aka RHEL 8
-          - debian:oldstable
+          - fedora
           - debian:stable
           - debian:testing
-          - debian:unstable
-          - ubuntu:18.04 # previous LTS
-          - ubuntu:20.04 # current LTS
-          - opensuse/leap # aka SLES
+          - ubuntu # current LTS
+          - ubuntu:rolling # latest
     container:
       image: ${{ matrix.os }}
       options: --privileged
       env:
         CI: 1
     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 shadow sudo
-        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 sudo \
-            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 sudo \
-            texinfo netcat procps socat {lzo,zlib,lz4,ncurses,readline}-devel
-          yum install -y openssl11-devel || yum install -y openssl-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 sudo
-          makeinfo diffutils gzip socat {openssl,zlib,lzo,liblz4,ncurses,readline}-devel
-        if: startsWith(matrix.os, 'opensuse')
-
       - name: Checkout code
-        uses: actions/checkout@v2
-        with:
-          fetch-depth: 0
+        uses: actions/checkout@v1
+
+      - name: Install deps
+        run: sh .ci/deps.sh
 
       - name: Assign name for test results artifact
-        run: echo TEST_ARTIFACT="$(echo '${{ matrix.os }}' | sed 's|[:/]|_|g')" >>"$GITHUB_ENV"
+        run: echo ARTIFACT="$(echo '${{ matrix.os }}' | sed 's|[:/]|_|g')" >>"$GITHUB_ENV"
 
       - name: Create a non-privileged user
-        run: |
-          useradd --user-group build
-          chown -R build:build .
-          echo 'build ALL=(ALL) NOPASSWD: ALL' >/etc/sudoers.d/build
+        run: sh .ci/test/prepare.sh
 
       - name: Run tests with default settings
-        run: sudo -u build CI=1 sh .github/workflows/test/run.sh default
+        run: sudo -u build CI=1 sh .ci/test/run.sh default
 
       - name: Run tests without legacy protocol
-        run: sudo -u build CI=1 sh .github/workflows/test/run.sh nolegacy
+        run: sudo -u build CI=1 sh .ci/test/run.sh nolegacy
 
       - name: Upload test results
         uses: actions/upload-artifact@v2
         with:
-          name: tests_${{ env.TEST_ARTIFACT }}
-          path: /tmp/tests.*.tar.gz
+          name: tests_${{ env.ARTIFACT }}
+          path: /tmp/logs/tests.*.tar.gz
         if: always()
 
-  deb-build:
-    if: startsWith(github.ref, 'refs/tags/release-')
-    needs: linux
-
-    strategy:
-      matrix:
-        os: [ubuntu-18.04, ubuntu-20.04]
-
-    runs-on: ${{ matrix.os }}
-    timeout-minutes: 5
-
-    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
-          zlib1g-dev
-          liblzo2-dev
-          libncurses-dev
-          libreadline-dev
-          libminiupnpc-dev
-
-      - name: Configure project
-        run: autoreconf -fsi
-
-      - name: Prepare debian directory
-        run: bash .github/workflows/deb/prepare.sh
-        env:
-          JOB_DISTRIBUTION: ${{ matrix.os }}
-
-      - name: Build deb package
-        run: |
-          dpkg-buildpackage -d -us -uc
-          mv ../*.deb .
+      - name: Build package
+        run: sh .ci/package/build.sh
+        if: github.ref == 'refs/heads/1.1' || startsWith(github.ref, 'refs/tags/release-')
 
-      - name: Upload packages
+      - name: Upload package
         uses: actions/upload-artifact@v2
         with:
-          name: deb-${{ matrix.os }}
-          path: "*.deb"
-
-  deb-publish:
-    needs: deb-build
+          name: pkg-${{ env.ARTIFACT }}
+          path: |
+            *.deb
+            ~/rpmbuild/RPMS/*/*.rpm
 
-    strategy:
-      matrix:
-        os: [ubuntu-18.04, ubuntu-20.04]
-
-    runs-on: ${{ matrix.os }}
-    timeout-minutes: 5
+  pkg-publish:
+    if: always() && (github.ref == 'refs/heads/1.1' || startsWith(github.ref, 'refs/tags/release-'))
+    runs-on: ubuntu-latest
+    needs:
+      - linux
+      - windows
 
     steps:
-      - name: Download built packages
+      - name: Create artifact directory
+        run: mkdir -p /tmp/artifacts
+
+      - name: Download 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
+          path: /tmp/artifacts
 
-      - name: Enable and start tincd
-        run: |
-          sudo systemctl start tinc@test
-          sudo tinc -n test dump reachable nodes
-
-      - name: Publish deb package
+      - name: Publish packages (dev)
+        uses: marvinpinto/action-automatic-releases@latest
+        with:
+          repo_token: ${{ secrets.GITHUB_TOKEN }}
+          automatic_release_tag: latest
+          title: Development release
+          prerelease: true
+          files: /tmp/artifacts/**/*.(deb|rpm|exe)
+        if: startsWith(github.ref, 'refs/heads/')
+
+      - name: Publish packages (release)
         uses: softprops/action-gh-release@v1
         with:
-          files: "*.deb"
-        env:
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+          files: |
+            /tmp/artifacts/**/*.deb
+            /tmp/artifacts/**/*.rpm
+            /tmp/artifacts/**/*.exe
+        if: startsWith(github.ref, 'refs/tags/')
 
   macos:
     runs-on: macos-latest
-    timeout-minutes: 10
-
-    strategy:
-      fail-fast: false
-      matrix:
-        legacy_protocol: ["", --disable-legacy-protocol]
+    timeout-minutes: 15
 
     steps:
       - name: Checkout code
-        uses: actions/checkout@v2
-        with:
-          fetch-depth: 0
+        uses: actions/checkout@v1
 
       - name: Install build deps
-        run: |
-          brew install coreutils netcat automake lzo lz4 miniupnpc
-          pip3 install --user compiledb
-
-      - name: Configure and compile
-        run: |
-          export CPPFLAGS="-I/usr/local/include"
-          export CPPFLAGS="$CPPFLAGS -I$(brew --prefix libgcrypt)/include"
-          export CPPFLAGS="$CPPFLAGS -I$(brew --prefix openssl)/include"
-          export CPPFLAGS="$CPPFLAGS -I$(brew --prefix libgcrypt)/include"
-
-          autoreconf -fsi
-          ./configure \
-            --with-openssl="$(brew --prefix openssl)" \
-            --with-miniupnpc="$(brew --prefix miniupnpc)" \
-            --enable-{tunemu,miniupnpc} \
-            ${{ matrix.legacy_protocol }}
+        run: sh .ci/deps.sh
 
-          make -j$(sysctl -n hw.ncpu)
-
-      - name: Run tests
-        run: |
-          export PATH="$PATH:$HOME/Library/Python/3.9/bin"
-          compiledb make -j$(sysctl -n hw.ncpu) check VERBOSE=1
+      - name: Run tests with default settings
+        run: sh .ci/test/run.sh default
 
       - name: Run clang-tidy
         run: |
-          export PATH="$PATH:$(brew --prefix llvm)/bin/"
-          find src \
-            ! '(' -path src/solaris -prune ')' \
-            ! '(' -path src/mingw   -prune ')' \
-            ! '(' -path src/linux   -prune ')' \
-            ! -name vde_device.c \
-            -name '*.c' \
-            -exec clang-tidy --header-filter='.*' '{}' +
-        if: ${{ matrix.legacy_protocol == '' }}
+          export PATH="$PATH:$(brew --prefix llvm)/bin:$HOME/Library/Python/3.9/bin"
+          sh .ci/tidy/run.sh
 
-      - name: Archive test results
-        run: sudo tar -c -z -f test-results.tar.gz test/
-        if: always()
+      - name: Run tests without legacy protocol
+        run: sh .ci/test/run.sh nolegacy
 
       - name: Upload test results
         uses: actions/upload-artifact@v2
         with:
-          name: tests_${{ runner.os }}_${{ matrix.legacy_protocol }}
-          path: test-results.tar.gz
+          name: tests_macos
+          path: /tmp/logs/tests.*.tar.gz
         if: always()
 
   windows:
     runs-on: windows-latest
     timeout-minutes: 20
 
-    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:
@@ -394,32 +289,36 @@ jobs:
             mingw-w64-x86_64-lz4
             mingw-w64-x86_64-ncurses
             mingw-w64-x86_64-miniupnpc
+            mingw-w64-x86_64-nsis
             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: Checkout code
+        uses: actions/checkout@v1
 
-      - name: Compile project
+      - name: Run tests with default settings
         shell: msys2 {0}
-        run: make -j$(nproc)
+        run: sh .ci/test/run.sh default
 
-      - name: Run tests
+      - name: Create installer
         shell: msys2 {0}
-        run: make check-recursive VERBOSE=1
+        run: sh .ci/package/build.sh
+        if: github.ref == 'refs/heads/1.1' || startsWith(github.ref, 'refs/tags/release-')
 
-      - name: Archive test results
+      - name: Upload package
+        uses: actions/upload-artifact@v2
+        with:
+          name: pkg-windows
+          path: .ci/package/win/tinc-*.exe
+
+      - name: Run tests without legacy protocol
         shell: msys2 {0}
-        run: tar -c -z -f test-results.tar.gz test/
-        if: always()
+        run: sh .ci/test/run.sh nolegacy
 
       - name: Upload test results
         uses: actions/upload-artifact@v2
         with:
-          name: tests_${{ runner.os }}_${{ matrix.legacy_protocol }}
-          path: test-results.tar.gz
+          name: tests_windows
+          path: /tmp/logs/tests.*.tar.gz
         if: always()
index b6910c9..cb9bf5c 100644 (file)
@@ -1,5 +1,6 @@
 .*
 !.github/
+!.ci/
 !.builds/
 !.gitignore
 !.astylerc