From: Manuel Nickschas Date: Thu, 18 Jun 2020 17:28:27 +0000 (+0200) Subject: ci: Replace Travis and Appveyor CIs by a GitHub Workflow X-Git-Tag: test-01~1 X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=commitdiff_plain;h=8c0f742c0d1732cde866011b56fa5d1725e0d668;ds=sidebyside ci: Replace Travis and Appveyor CIs by a GitHub Workflow Replace the previous CI systems by a GitHub Workflow for all supported platforms. This unifies the full CI setup in a single place, and provides better integration into GitHub itself via the checks API. Additionally, GitHub provides us with more resources than the other systems, enabling more parallel and faster build jobs. As a result, we can afford a larger build matrix than before, and now cover additional Linux baselines. Unlike Appveyor, GitHub also parallelizes Windows build jobs, which resolves the huge bottleneck we had when pushing multiple PRs or branches. The total turnaround time is still dominated by the Windows build, but at around 15 minutes it is much faster than before. GitHub also has a sane retention policy that keeps temporary artifacts around for several months, and won't run out of space during active development times like Appyevor did. For tagged commits, a draft release is automatically created and the source archive as well as packages for Windows and macOS are attached. The tag annotation is used for the release notes. Releasing as a draft allows for final, manual changes before publishing the release. Note that this change should also enable CI runs in forks, so contributors can enjoy CI feedback while developing, prior to creating a pull request. --- diff --git a/.appveyor.ini b/.appveyor.ini deleted file mode 100644 index b785aac6..00000000 --- a/.appveyor.ini +++ /dev/null @@ -1,34 +0,0 @@ -[General] -Command = craft -Branch = master -ShallowClone = True - -# Variables defined here override the default value -# The variable names are case sensitive -[Variables] -#Root = D:\qt-sdk -APPVEYOR_BUILD_FOLDER = ${Variables:Root} - -# Settings applicable for all Crafts matrices -# Settings are Category/key=value -# Category is case sensitive -[GeneralSettings] -Paths/Python = C:\Python36 -Paths/Python27 = C:\Python27 -ShortPath/Enabled = False -Compile/BuildType = Release -ContinuousIntegration/Enabled = True -Packager/Destination = ${Variables:APPVEYOR_BUILD_FOLDER}/binaries - -# the version of the config -Version/ConfigVersion = 6 - -[BlueprintSettings] -quassel/quassel.version = master - -libs/dbus.ignored = True -binary/mysql.ignored = True -libs/llvm-meta.ignored = True - -[windows-msvc2017_64-cl] -General/ABI = windows-msvc2017_64-cl diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index 39aa5351..00000000 --- a/.appveyor.yml +++ /dev/null @@ -1,39 +0,0 @@ -version: '{build}' - -image: Visual Studio 2017 - -init: -- ps: | - function craft() { - & C:\python36\python.exe "C:\CraftMaster\$env:TARGET\craft\bin\craft.py" $args - if($LASTEXITCODE -ne 0) {exit $LASTEXITCODE} - } - -install: -- ps: | - #use cmd to silence powershell behaviour for stderr - & cmd /C "git clone -q --depth=1 git://anongit.kde.org/craftmaster.git C:\CraftMaster\CraftMaster 2>&1" - & C:\python36\python.exe C:\CraftMaster\CraftMaster\CraftMaster.py --config $env:APPVEYOR_BUILD_FOLDER\.appveyor.ini --variables "APPVEYOR_BUILD_FOLDER=$env:APPVEYOR_BUILD_FOLDER" --target $env:TARGET - craft --add-blueprint-repository https://github.com/quassel/craft-blueprints-quassel.git - craft -p quassel/quassel - craft nsis - craft --install-deps quassel/quassel - -build_script: -- ps: | - craft --no-cache --src-dir $env:APPVEYOR_BUILD_FOLDER quassel/quassel - -after_build: -- ps: | - craft --src-dir $env:APPVEYOR_BUILD_FOLDER --package quassel/quassel - -test_script: -- ps: | - craft --src-dir $env:APPVEYOR_BUILD_FOLDER --test quassel/quassel - -environment: - matrix: - - TARGET: windows-msvc2017_64-cl - -artifacts: - - path: binaries\* diff --git a/.craftsettings.ini b/.craftsettings.ini new file mode 100644 index 00000000..a69c2db9 --- /dev/null +++ b/.craftsettings.ini @@ -0,0 +1,28 @@ +[General] +Command = craft +Branch = master +ShallowClone = True + +[GeneralSettings] +Version/ConfigVersion = 6 + +Paths/Python = C:\hostedtoolcache\windows\Python\3.7.7\x64 +Paths/Python27 = C:\hostedtoolcache\windows\Python\2.7.18\x64 +Paths/Msys = C:\msys64 +ShortPath/Enabled = False +Compile/BuildType = Release +ContinuousIntegration/Enabled = True +Packager/Destination = ${Variables:WORKSPACE}/packages +Packager/PackageDebugSymbols = False + +[BlueprintSettings] +quassel/quassel.version = master + +binary/mysql.ignored = True +libs/dbus.ignored = True +libs/llvm-meta.ignored = True +dev-utils/msys.ignored = True +dev-utils/perl.ignored = True + +[windows-msvc2019_64-cl] +General/ABI = windows-msvc2019_64-cl diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 00000000..9c589fd2 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,257 @@ +# Workflow that builds Quassel on various Linux distros, and creates packages for both Windows and macOS. +# For tagged pushes, a draft release is automatically created, using the tag message as release description +# and attaching Windows and macOS builds, as well as the source archive. +name: Quassel CI + +on: [ push, pull_request ] + +defaults: + run: + shell: bash + +jobs: + +# ------------------------------------------------------------------------------------------------------------------------------------------ + build-linux: + name: Linux + runs-on: ubuntu-latest + container: quassel/quassel-build-env:${{ matrix.dist }} + strategy: + matrix: + dist: [ debian-stable, debian-testing, ubuntu-xenial, ubuntu-bionic, ubuntu-eoan, ubuntu-focal ] + cxx: [ gcc, clang++ ] + with-kde: [ -DWITH_KDE=ON ] + extra-options: [ -DWITH_WEBENGINE=ON ] + include: + # Baseline, test more combinations + - dist: ubuntu-xenial + with-kde: -DWITH_KDE=OFF + extra-options: -DWITH_WEBKIT=ON + - dist: ubuntu-xenial + with-kde: -DWITH_KDE=ON + extra-options: -DWITH_WEBKIT=ON + exclude: + # QtWebEngine is not available on Xenial + - dist: ubuntu-xenial + extra-options: -DWITH_WEBENGINE=ON + env: + CCACHE_BASEDIR: ${{ github.workspace }} + CCACHE_DIR: ${{ github.workspace }}/ccache + CCACHE_MAXSIZE: 100M + + steps: + - name: Check out source code + uses: actions/checkout@v2 + + - name: Get timestamp + id: get-timestamp + run: echo "::set-output name=timestamp::$(date -u "+%F-%R")" + + - name: Setup ccache + uses: actions/cache@v2 + with: + path: ${{ github.workspace }}/ccache + key: ${{ matrix.dist }}-ccache-${{ steps.get-timestamp.outputs.timestamp }} + restore-keys: | + ${{ matrix.dist }}-ccache- + + - name: Zero ccache stats + run: ccache -z + + - name: Configure + run: | + mkdir build + cd build && cmake $GITHUB_WORKSPACE \ + -GNinja \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_TESTING=ON \ + -DFATAL_WARNINGS=ON \ + ${{ matrix.with-kde }} \ + ${{ matrix.extra-options }} + + - name: Build + run: cd build && ninja + + - name: Run tests + run: cd build && ctest + + - name: Install + run: cd build && DESTDIR=$GITHUB_WORKSPACE/image ninja install + + - name: Print ccache stats + run: ccache -s + +# ------------------------------------------------------------------------------------------------------------------------------------------ + build-macos: + name: macOS + runs-on: macos-latest + env: + CCACHE_BASEDIR: ${{ github.workspace }} + CCACHE_DIR: ${{ github.workspace }}/ccache + CCACHE_MAXSIZE: 100M + + steps: + - name: Check out source code + uses: actions/checkout@v2 + with: + fetch-depth: 0 # so git-describe works + + - name: Fetch tag information + if: startsWith(github.ref, 'refs/tags/') + run: git fetch -f origin $GITHUB_REF:$GITHUB_REF + + - name: Install dependencies + run: brew update && brew install boost ccache ninja qca qt5 + + - name: Get timestamp + id: get-timestamp + run: echo "::set-output name=timestamp::$(date -u "+%F-%R")" + + - name: Setup ccache + uses: actions/cache@v2 + with: + path: ${{ github.workspace }}/ccache + key: macos-ccache-${{ steps.get-timestamp.outputs.timestamp }} + restore-keys: | + macos-ccache- + + - name: Zero ccache stats + run: ccache -z + + - name: Configure + run: | + mkdir build + cd build && cmake $GITHUB_WORKSPACE \ + -GNinja \ + -DCMAKE_PREFIX_PATH=/usr/local/opt/qt/lib/cmake \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_TESTING=ON \ + -DFATAL_WARNINGS=OFF \ + -DDEPLOY=ON \ + -DENABLE_SHARED=OFF + + - name: Build + run: | + # Deploy scripts require qmake in the path + export PATH=$PATH:/usr/local/opt/qt5/bin + cd build && ninja + + - name: Run tests + run: cd build && ctest + + - name: Install + run: cd build && DESTDIR=$GITHUB_WORKSPACE/image ninja install + + - name: Print ccache stats + run: ccache -s + + - name: Upload artifacts + uses: actions/upload-artifact@v2 + with: + name: macOS + path: ${{ github.workspace }}/build/*.dmg + +# ------------------------------------------------------------------------------------------------------------------------------------------ + build-windows: + name: Windows + runs-on: windows-latest + env: + WORKSPACE: ${{ github.workspace }} + CRAFT: /C/CraftMaster/windows-msvc2019_64-cl/craft/bin/craft.py + + steps: + - name: Check out source code + uses: actions/checkout@v2 + with: + fetch-depth: 0 # so git-describe works + + - name: Fetch tag information + if: startsWith(github.ref, 'refs/tags/') + run: git fetch -f origin $GITHUB_REF:$GITHUB_REF + + - name: Clone CraftMaster + run: git clone --depth=1 https://invent.kde.org/kde/craftmaster.git /C/CraftMaster/CraftMaster + + - name: Configure CraftMaster + run: python /C/CraftMaster/CraftMaster/CraftMaster.py --config $WORKSPACE/.craftsettings.ini --variables "WORKSPACE=$WORKSPACE" + + - name: Add Quassel blueprint + run: python $CRAFT --add-blueprint-repository https://github.com/quassel/craft-blueprints-quassel.git + + - name: Install NSIS + run: python $CRAFT dev-utils/nsis + + - name: Install dependencies + run: python $CRAFT --install-deps quassel/quassel + + - name: Build + run: python $CRAFT --no-cache --src-dir $WORKSPACE quassel/quassel + + - name: Run tests + run: python $CRAFT --no-cache --src-dir $WORKSPACE --test quassel/quassel + + - name: Package + run: python $CRAFT --no-cache --src-dir $WORKSPACE --package quassel/quassel + + - name: Upload artifacts + uses: actions/upload-artifact@v2 + with: + name: Windows + path: ${{ github.workspace }}/packages/* + +# ------------------------------------------------------------------------------------------------------------------------------------------ + create-release: + name: Create release + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/') + needs: [ build-linux, build-macos, build-windows ] + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + steps: + - name: Check out source code + uses: actions/checkout@v2 + + - name: Fetch tag information + run: git fetch -f origin $GITHUB_REF:$GITHUB_REF + + - name: Create release notes + run: | + # Use the tag's annotation as release notes + TAGNAME=$(git rev-parse --abbrev-ref $GITHUB_REF) + MESSAGE=$(git tag -l --format='%(contents)' $TAGNAME | perl -ne 'print if not /-----BEGIN PGP SIGNATURE-----/../-----END PGP SIGNATURE-----/') + echo -e "Quassel $TAGNAME\n\n$MESSAGE" > release_notes.txt + + - name: Download artifacts + uses: actions/download-artifact@v2 + with: + path: artifacts + + - name: List artifacts + run: ls -lhR artifacts + + - name: Prepare source archive + run: | + mkdir assets + TAGNAME=$(git rev-parse --abbrev-ref $GITHUB_REF) + git archive --format=tar --prefix=quassel-$TAGNAME/ $TAGNAME | xz > assets/quassel-$TAGNAME.tar.xz + + - name: Prepare packages for release + run: | + TAGNAME=$(git rev-parse --abbrev-ref $GITHUB_REF) + for type in Client Core Mono; do + mv artifacts/macOS/Quassel$type*.dmg assets/Quassel$type-macOS-$TAGNAME.dmg + done + mv artifacts/Windows/quassel-*.exe assets/quassel-windows-setup-$TAGNAME.exe + mv artifacts/Windows/quassel-*.7z assets/quassel-windows-$TAGNAME.7z + + - name: Create checksums for release assets + run: find assets/ -type f -execdir sh -c 'sha256sum "$1" > "$1.sha256sum"' _ {} \; + + - name: Create draft release + run: | + # The stock upload-release-asset action can only handle single files + # Instead, use the hub utility so we can upload all assets at once + assets=() + for asset in assets/*; do assets+=("-a" "$asset"); done + hub release create -d "${assets[@]}" -F release_notes.txt `git rev-parse --abbrev-ref $GITHUB_REF` diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index d123f18d..00000000 --- a/.travis.yml +++ /dev/null @@ -1,97 +0,0 @@ -sudo: required - -services: - - docker - -# Define build matrix for Linux -os: linux -dist: bionic -language: generic # No host compilation - -env: - - DIST=ubuntu-xenial CXX=g++ CMAKE_OPTIONS="-DWITH_KDE=OFF -DWITH_WEBKIT=OFF" - - DIST=ubuntu-xenial CXX=clang++ CMAKE_OPTIONS="-DWITH_KDE=OFF -DWITH_WEBKIT=OFF" - - DIST=ubuntu-xenial CXX=g++ CMAKE_OPTIONS="-DWITH_KDE=ON -DWITH_WEBKIT=ON" - - DIST=ubuntu-xenial CXX=clang++ CMAKE_OPTIONS="-DWITH_KDE=ON -DWITH_WEBKIT=ON" - - DIST=ubuntu-bionic CXX=g++ CMAKE_OPTIONS="-DWITH_KDE=ON -DWITH_WEBKIT=ON" - - DIST=ubuntu-bionic CXX=clang++ CMAKE_OPTIONS="-DWITH_KDE=ON -DWITH_WEBENGINE=ON" - - DIST=ubuntu-eoan CXX=g++ CMAKE_OPTIONS="-DWITH_KDE=ON -DWITH_WEBENGINE=ON" - - DIST=ubuntu-eoan CXX=clang++ CMAKE_OPTIONS="-DWITH_KDE=ON -DWITH_WEBENGINE=ON" - - DIST=ubuntu-focal CXX=g++ CMAKE_OPTIONS="-DWITH_KDE=ON -DWITH_WEBENGINE=ON" - - DIST=ubuntu-focal CXX=clang++ CMAKE_OPTIONS="-DWITH_KDE=ON -DWITH_WEBENGINE=ON" - - DIST=debian-stable CXX=g++ CMAKE_OPTIONS="-DWITH_KDE=ON -DWITH_WEBENGINE=ON" - - DIST=debian-stable CXX=clang++ CMAKE_OPTIONS="-DWITH_KDE=OFF -DWITH_WEBENGINE=ON" - - DIST=debian-testing CXX=g++ CMAKE_OPTIONS="-DWITH_KDE=OFF -DWITH_WEBENGINE=ON" - - DIST=debian-testing CXX=clang++ CMAKE_OPTIONS="-DWITH_KDE=ON -DWITH_WEBENGINE=ON" - -# Set up cache -cache: - directories: - - $TRAVIS_BUILD_DIR/ccache - -# Prepare -before_install: - - docker pull quassel/quassel-build-env:$DIST - - docker images - - mkdir build - -# Build inside the docker image -# Source, build and ccache directories are bind-mounted into the container -script: - - | - docker run -t -w /build --rm \ - -v "$(readlink -f .):/src" \ - -v "$(readlink -f build):/build" \ - -v "$(readlink -f ccache):/ccache" \ - -e CCACHE_DIR=/ccache \ - -e CCACHE_MAXSIZE=1G \ - -e CXX=$CXX \ - quassel/quassel-build-env:$DIST \ - sh -c "cmake /src $CMAKE_OPTIONS \ - -GNinja \ - -DCMAKE_BUILD_TYPE=RelWithDebInfo \ - -DBUILD_TESTING=ON \ - -DFATAL_WARNINGS=ON \ - && ninja install \ - && ccache -s \ - && ctest -VV \ - " - -# Define a separate job for OSX -jobs: - include: - - os: osx - language: cpp - compiler: clang - env: - cache: - directories: - - $HOME/.ccache - - $HOME/Library/Caches/Homebrew - before_install: - - brew update && brew install ccache ninja qca qt5 - script: - - export CCACHE_MAXSIZE=1G - - mkdir build && cd build - - | - PATH=$PATH:/usr/local/opt/qt5/bin - DEPLOY=OFF - if [[ "$TRAVIS_TAG" != "" && "$GH_TOKEN" != "" ]]; then - DEPLOY=ON - fi - cmake -GNinja .. -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=ON -DDEPLOY=$DEPLOY - ninja install - - ccache -s - - ctest -VV - deploy: - provider: releases - api_key: "${GH_TOKEN}" - file_glob: true - file: - - "QuasselClient_MacOSX-x86_64_*.dmg" - - "QuasselCore_MacOSX-x86_64_*.dmg" - - "QuasselMono_MacOSX-x86_64_*.dmg" - skip_cleanup: true - on: - tags: true - condition: "$GH_TOKEN != ''"