awesome/.github/workflows/main.yml

386 lines
14 KiB
YAML

name: Build & Test
on:
# Trigger on push to branches `master` and `3.5`.
push:
branches: [ master, 3.5 ]
# Trigger on pull request events for PRs that have `master` as their target branch
pull_request:
branches: [ master ]
# Allow running the workflow manually
workflow_dispatch:
defaults:
run:
# GitHub Actions adds `errexit` and `pipefail` by default, but we add `xtrace`
# to improve debugging some of the longer scripts.
shell: /bin/bash -o errexit -o pipefail -o xtrace {0}
jobs:
main:
# The type of runner that the job will run on
runs-on: ubuntu-20.04
name: ${{ matrix.test_name }}
strategy:
# Let other jobs continue even if one of them fails
fail-fast: false
matrix:
include:
- test_name: "lua5.4"
lua_version: "5.4"
lua_name: "lua5.4"
lua_include: "/usr/local/include"
manual_screens: true
- test_name: "codecov-lua5.3"
lua_version: "5.3"
lua_name: "lua5.3"
coverage: "codecov"
manual_screens: true
- test_name: "lua5.2"
lua_version: "5.2"
lua_name: "lua5.2"
manual_screens: true
- test_name: "lua5.1"
lua_version: "5.1"
lua_name: "lua5.1"
- test_name: "luajit"
lua_version: "5.1"
lua_name: "luajit"
lua_library: "/usr/lib/x86_64-linux-gnu/libluajit-5.1.so"
lua_include: "/usr/include/luajit-2.1"
luarocks_args: "--lua-suffix=jit-2.1.0-beta3"
# Lua 5.2 with fixed lgi version and screen size not divisible by 2.
- test_name: "fixed-lgi-lua5.2"
lua_version: "5.2"
lua_name: "lua5.2"
lgi_version: "0.9.2"
tests_screen_size: "1921x1079"
check_qa: true
empty_theme_while_loading: true
test_prev_commits: true
env:
LUA: ${{ matrix.lua_version }}
LUAINCLUDE: ${{ matrix.lua_include || format('/usr/include/lua{0}', matrix.lua_version) }}
LUALIBRARY: ${{ matrix.lua_library || format('/usr/lib/x86_64-linux-gnu/liblua{0}.so', matrix.lua_version) }}
TESTS_SCREEN_SIZE: ${{ matrix.tests_screen_size }}
TEST_TIMEOUT: '100'
CI: 'true'
steps:
# Create a cache invalidation key based on the current year + week.
# This way, packages will be checked for updates once every week.
- name: Get Date
id: get-date
run: echo "::set-output name=date::$(/bin/date -u "+%Y%W")"
- name: Cache apt packages
id: cache-apt
uses: actions/cache@v2
with:
path: /var/cache/apt/archives
# The trailing number serves as a version flag that can be incremented
# to invalidate the cache after changing the list of packages.
key: ${{ github.workflow }}-${{ runner.os }}-${{ steps.get-date.outputs.date }}-apt-4
- name: Download apt packages
if: steps.cache-apt.outputs.cache-hit != 'true'
run: |
sudo apt-get update
sudo apt-get install --download-only -y --no-install-recommends \
asciidoctor \
cmake \
dbus-x11 \
gettext \
gir1.2-gtk-3.0 \
gir1.2-pango-1.0 \
git \
libdbus-1-dev \
libgirepository1.0-dev \
libnotify-bin \
libpango1.0-dev \
libstartup-notification0-dev \
libx11-xcb-dev \
libxcb-cursor-dev \
libxcb-icccm4-dev \
libxcb-keysyms1-dev \
libxcb-randr0-dev \
libxcb-shape0-dev \
libxcb-util0-dev \
libxcb-xfixes0-dev \
libxcb-xinerama0-dev \
libxcb-xkb-dev \
libxcb-xrm-dev \
libxcb-xtest0-dev \
libxdg-basedir-dev \
libxkbcommon-dev \
libxkbcommon-x11-dev \
wmctrl \
x11-apps \
xcb-proto \
xdotool \
xorg \
xserver-xephyr \
xterm \
xutils-dev \
xvfb \
zsh \
lua-discount \
fonts-noto-core \
fonts-dejavu-core \
fonts-roboto-unhinted \
fonts-open-sans
- name: Install downloaded packages
run: sudo dpkg -i /var/cache/apt/archives/*.deb
- name: Install Lua packages
run: |
if [ "${{ matrix.lua_name }}" = "luajit" ]; then
sudo apt-get install libluajit-5.1-dev luajit
fi
sudo apt-get install liblua${{ matrix.lua_version }}-dev lua${{ matrix.lua_version }}
- name: Cache luarocks
id: cache-luarocks
uses: actions/cache@v2
with:
path: /tmp/luarocks
# The build input for luarocks changes per test, so we need separate caches
key: ${{ github.workflow }}-${{ runner.os }}-${{ matrix.test_name }}-luarocks-3.5.0
- name: Install fresh Luarocks
if: steps.cache-luarocks.outputs.cache-hit != 'true'
run: |
wget -O /tmp/luarocks.tar.gz https://github.com/luarocks/luarocks/archive/v3.5.0.tar.gz
mkdir /tmp/luarocks
tar -xf /tmp/luarocks.tar.gz -C /tmp/luarocks --strip-components=1
cd /tmp/luarocks
./configure --lua-version=${{ matrix.lua_version }} --with-lua-include=${LUAINCLUDE} ${{ matrix.luarocks_args }}
make build
sudo make install
- name: Install cached Luarocks
if: steps.cache-luarocks.outputs.cache-hit == 'true'
run: |
cd /tmp/luarocks
sudo make install
- name: Cache xcb-errors
id: cache-xcb-errors
uses: actions/cache@v2
with:
path: /tmp/xcb-errors
key: ${{ github.workflow }}-${{ runner.os }}-xcb-errors-1.0
- name: Install fresh xcb-errors
if: steps.cache-xcb-errors.outputs.cache-hit != 'true'
run: |
git clone --recursive --depth 1 --branch 1.0 https://gitlab.freedesktop.org/xorg/lib/libxcb-errors.git /tmp/xcb-errors
cd /tmp/xcb-errors
./autogen.sh --prefix=/usr
make
sudo make install
- name: Install cached xcb-errors
if: steps.cache-xcb-errors.outputs.cache-hit == 'true'
run: |
cd /tmp/xcb-errors
sudo make install
- name: Install rocks
run: |
sudo -H luarocks install lgi ${{ matrix.lgi_version }}
sudo -H luarocks install ldoc
sudo -H luarocks install busted
- name: Install QA check rocks
if: matrix.check_qa
run: |
sudo -H luarocks install luacheck
sudo -H luarocks install depgraph
- name: Install cluacov rock
if: matrix.coverage
run: sudo -H luarocks install cluacov
- name: Install codecov.io uploader
if: matrix.coverage == 'codecov'
run: wget -O /tmp/codecov-bash https://codecov.io/bash
# Check out repository to ${{ github.workspace }}
# Automatically picks the current branch/PR
- uses: actions/checkout@v2
- name: Create Build Environment
run: cmake -E make_directory -B "${{ github.workspace }}/build"
- name: Build Awesome version string
run: |
# If this workflow is triggered by a pull request, we get a base branch.
# Otherwise, check if the current commit has a meaningful name.
if [ -n "${{ github.base_ref }}" ]; then
AWESOME_VERSION="${{ github.base_ref }}"
else
AWESOME_VERSION="$(git rev-parse --abbrev-ref HEAD)"
fi
AWESOME_VERSION="${AWESOME_VERSION}-g$(git rev-parse --short HEAD)"
if [ "${{ github.event_name }}" == "pull_request" && -n "${{ matrix.test_prev_commits }}" ]; then
AWESOME_VERSION="${AWESOME_VERSION}-PR${{ github.event.number }}"
elif [ "${{ github.event_name }}" == "pull_request" ]; then
AWESOME_VERSION="v9999-PR${{ github.event.number }}"
fi
echo "AWESOME_VERSION=${AWESOME_VERSION}" >> ${GITHUB_ENV}
- name: Configure CMake
run: |
cmake -S ${{ github.workspace }} -B "${{ github.workspace}}/build" \
-DAWESOME_VERSION=$AWESOME_VERSION \
-DLUA_LIBRARY=$LUALIBRARY \
-DLUA_INCLUDE_DIR=$LUAINCLUDE \
-DGENERATE_DOC=OFF \
-DGENERATE_MANPAGES=OFF \
-DDO_COVERAGE=${{ matrix.coverage }} \
-DTEST_MANUAL_SCREENS=${{ matrix.manual_screens }} \
-DSTRICT_TESTS=true \
-DCMAKE_C_FLAGS="-Werror"
# Break beautiful so that trying to access the theme before `beautiful.init()` causes an error
- name: Patch beautiful for an empty default theme
if: matrix.empty_theme_while_loading
run: |
sed -i -e 's/theme = {}/theme = setmetatable({}, { __index = function() error("May not access theme before beautiful.init()") end })/' lib/beautiful/init.lua
grep -q 'May not access' lib/beautiful/init.lua
- name: Build
run: cd "${{ github.workspace }}/build" && make -j3
# Executable needs to be run once to provide coverage results
- name: Install and run
run: |
cd "${{ github.workspace }}/build"
sudo make install
awesome --version
- name: Run integration tests
run: cd "${{ github.workspace }}/build" && make check-integration
- name: Run unit tests
run: cd "${{ github.workspace }}/build" && make check-unit
- name: Run examples tests
if: matrix.coverage
run: cd "${{ github.workspace }}/build" && make check-examples
- name: Run requires tests
if: matrix.coverage
run: cd "${{ github.workspace }}/build" && make check-requires
- name: Run themes tests
run: cd "${{ github.workspace }}/build" && make check-themes
- name: Upload Lua code coverage report
if: matrix.coverage == 'codecov'
run: |
luacov
bash /tmp/codecov-bash -f build/luacov.report.out -X gcov -X coveragepy -F luacov
- name: Upload C code coverage report
if: matrix.coverage == 'codecov'
run: |
# Report coverage for each .gcno file separately.
# gcov will create .gcov files for the same source (e.g. for
# globalconf.h from awesome.c.gcno and event.c.gcno).
i=0
cd "${{ github.workspace }}/build"
find -path "*/lgi-check.dir" -prune -o \( -name '*.gcno' -print \) | while read -r gcno; do
gcov -pb "$gcno"
mkdir gcov.$(( ++i ))
mv *.gcov "gcov.$i"
# Delete any files for /usr.
# They are not relevant and might cause "Invalid path part" errors
# with Code Climate.
find "gcov.$i" -maxdepth 1 -type f -name '#usr#*.gcov' -delete
done
# Upload to Codecov.
bash /tmp/codecov-bash -X gcov -X coveragepy -F gcov
# `check-qa` is the only test that doesn't get a coverage report, so it has to run after all of that.
- name: Run qa tests
if: matrix.check_qa
run: cd "${{ github.workspace }}/build" && make check-qa
# Check each commit separately (to make git-bisect less annoying).
- name: Test previous commits
if: matrix.test_prev_commits && github.event_name == 'pull_request'
run: |
git remote add fork "${{ github.event.pull_request.head.repo.git_url }}"
# `actions/checkout` creates a shallow repo (`--depth 1`) by default,
# which is fine for everything up until now. But we need individual commits now.
# And we only want to unshallow now, to not slow down the checkout for other jobs.
git fetch --unshallow --all
rev_list="$(git rev-list --bisect-all origin/${{ github.base_ref }}..fork/${{ github.head_ref }})"
# The most recent commit has already been tested. So if that's the
# only commit in the PR, we can stop here.
if [[ $(echo "$rev_list" | wc -l) -lt 2 ]]; then
exit 0
fi
commits="$(echo "$rev_list" | grep -v 'dist=0' | cut -d' ' -f 1)"
n="$(echo "$commits" | wc -l)"
echo "Testing $n commits:"
echo "$commits" | xargs -I{} git log -1 --pretty='%h %s' {}
failed=""
for commit in $commits; do
echo "Testing commit $commit"
# Some files are updated when compiling...
git checkout --force "$commit"
git show --stat --oneline
cmake -S ${{ github.workspace }} -B "${{ github.workspace}}/build" \
-DAWESOME_VERSION=$AWESOME_VERSION \
-DLUA_LIBRARY=$LUALIBRARY \
-DLUA_INCLUDE_DIR=$LUAINCLUDE \
-DGENERATE_DOC=OFF \
-DGENERATE_MANPAGES=OFF \
-DDO_COVERAGE=OFF \
-DTEST_MANUAL_SCREENS=${{ matrix.manual_screens }} \
-DSTRICT_TESTS=true \
-DCMAKE_C_FLAGS="-Werror"
cd "${{ github.workspace}}/build"
if ! ( make && make check-unit ); then
failed="$failed $commit"
fi
done
git checkout --quiet --force fork/${{ github.head_ref }}
if [ -n "$failed" ]; then
echo "Checks failed for these commits:"
for c in $failed; do
git show --no-patch --pretty="%h %s (%an, %ad)" "$c"
done
exit 1
fi
# vim: filetype=yaml:expandtab:shiftwidth=2:tabstop=2