Skip to content

CI

CI #1474

Workflow file for this run

name: CI
on:
pull_request:
push:
branches:
- master
tags:
- "v*"
schedule:
- cron: '5 4 * * 1'
workflow_dispatch:
jobs:
build-and-test:
name: ${{ matrix.os }}_${{ matrix.boost }}_${{ matrix.compiler }}_${{ matrix.geos }}
strategy:
matrix:
os: [ubuntu, macos, windows]
boost: ['1_66', 'latest']
geos: ['3.9.0', 'main', 'none']
compiler: ['g++', 'g++-10', 'clang++']
exclude:
- os: macos # Temporarily disable until fixed
- os: windows # Temporarily disable until fixed
- os: macos
boost: '1_66'
- os: ubuntu
boost: 'latest'
- os: macos
compiler: 'g++-10'
- os: windows
compiler: 'g++-10'
- os: windows
compiler: 'clang++'
- os: windows
boost: '1_66'
include:
- os: ubuntu
boost: 1_66
compiler: g++-10
geos: 'main'
code_coverage: "--enable-code-coverage"
#- os: windows
# shell: msys2 {0}
# local_install_path: '/d/a/pcb2gcode/.local'
- os: ubuntu
shell: '/usr/bin/bash -l -e -o pipefail {0}'
local_install_path: '$HOME/.local'
#- os: macos
# shell: '/bin/bash -l -e -o pipefail {0}'
# local_install_path: '$HOME/.local'
runs-on: ${{ matrix.os }}-latest
defaults:
run:
shell: ${{ matrix.shell }}
steps:
- name: Setup msys2
if: matrix.os == 'windows'
uses: msys2/setup-msys2@v2
with:
msystem: MINGW64
update: true
install: mingw-w64-x86_64-gtkmm git base-devel bash mingw-w64-x86_64-gcc mingw-w64-x86_64-boost mingw-w64-x86_64-cairo mingw-w64-x86_64-cmake autoconf automake libtool
- name: Checkout pcb2gcode source
uses: actions/checkout@v3
- name: Setup paths and env
run: |
mkdir -p ${{ matrix.local_install_path }}/bin
mkdir -p ${{ matrix.local_install_path }}/lib/pkgconfig
rm -f ~/.bash_profile
echo "export PKG_CONFIG_PATH='${{ matrix.local_install_path }}/lib/pkgconfig:$PKG_CONFIG_PATH'" >> ~/.bash_profile
echo "export LD_LIBRARY_PATH='${{ matrix.local_install_path }}/lib:$LD_LIBRARY_PATH'" >> ~/.bash_profile
echo "export PATH='${{ matrix.local_install_path }}/bin:$PATH'" >> ~/.bash_profile
echo "export LOCAL_INSTALL_PATH='${{ matrix.local_install_path }}'" >> ~/.bash_profile
echo $GITHUB_JSON
env:
GITHUB_JSON: ${{ toJSON(github) }}
- name: Windows specific setup
if: matrix.os == 'windows'
run: |
echo "export NUM_CPUS='$((`nproc --all`))'" >> ~/.bash_profile
- name: Ubuntu specific setup
if: matrix.os == 'ubuntu'
run: |
sudo apt-get update
sudo apt-get install libgtkmm-2.4-dev moreutils autopoint libc6-dbg
echo "export NUM_CPUS='$((`nproc --all` * 4))'" >> ~/.bash_profile
- name: Set clang as default compiler
if: matrix.compiler == 'clang++'
run: |
echo "export CC='`which clang`'" >> ~/.bash_profile
echo "export CXX='`which clang++`'" >> ~/.bash_profile
- name: g++-10 specific setup
if: matrix.compiler == 'g++-10'
run: |
sudo apt-get install g++-10
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 100 --slave /usr/bin/g++ g++ /usr/bin/g++-10 --slave /usr/bin/gcov gcov /usr/bin/gcov-10
sudo update-alternatives --set gcc /usr/bin/gcc-10
- name: Macos specific setup
if: matrix.os == 'macos'
run: |
brew update
rm /usr/local/bin/2to3
brew upgrade python@3
brew reinstall -s libtool
brew install boost gtkmm moreutils gettext librsvg automake pkg-config
brew upgrade wget
hash -r
ln -f -s `which glibtoolize` ${LOCAL_INSTALL_PATH}/bin/libtoolize
ln -f -s `which glibtool` ${LOCAL_INSTALL_PATH}/bin/libtool
hash -r
echo "export BOOST_ROOT='/usr/local/opt/boost'" >> ~/.bash_profile
echo "export NUM_CPUS='$((`sysctl -n hw.logicalcpu` * 4))'" >> ~/.bash_profile
echo "export PKG_CONFIG_PATH='$PKG_CONFIG_PATH:/usr/local/opt/libffi/lib/pkgconfig'" >> ~/.bash_profile
echo "export CPPFLAGS_gerbv='-DQUARTZ'" >> ~/.bash_profile
echo "export PATH='/usr/local/opt/gettext/bin:$PATH'" >> ~/.bash_profile
rm /usr/local/include/boost
- name: Macos geos
if: matrix.geos != 'none' && matrix.os == 'macos'
run:
brew install geos
- name: Display information about build environment
run: |
cat ~/.bash_profile
env
if command -v g++; then g++ --version; fi
if command -v clang++; then clang++ --version; fi
if command -v pkg-config; then pkg-config --version; fi
if command -v m4; then m4 --version; fi
- name: Sanitize cache key
id: sanitize-key
run: |
echo "key=$(echo '${{ matrix.os }}_${{ matrix.boost }}_${{ matrix.compiler }}_${{ matrix.geos }}' | sed 's/+/plus/g')" >> $GITHUB_OUTPUT
if command -v cygpath; then
echo "path=$(cygpath -w ${{ matrix.local_install_path }})" >> $GITHUB_OUTPUT
else
echo "path=${{ matrix.local_install_path }}" >> $GITHUB_OUTPUT
fi
- name: Cache local install path
uses: eyal0/cache@main
with:
path: ${{ steps.sanitize-key.outputs.path }}
key: ${{ steps.sanitize-key.outputs.key }}-${{ github.run_id }}-${{ github.run_attempt }}
restore-keys: |
${{ steps.sanitize-key.outputs.key }}-
update-env-variable: "UPDATE_CACHE"
- name: Default don't update cache
run: echo "UPDATE_CACHE=false" >> $GITHUB_ENV
- name: Build and install boost
if: matrix.os == 'ubuntu'
env:
BOOST: ${{ matrix.boost }}_0
run: |
if [ ! -d "${LOCAL_INSTALL_PATH}/include/boost" ]; then
echo "UPDATE_CACHE=true" >> $GITHUB_ENV
pushd ~
for i in {1..5}; do
wget -q -T20 -t1 -O "boost_${BOOST}.tar.bz2" "https://github.com/pcb2gcode/pcb2gcode/releases/download/v2.0.0/boost_${BOOST}.tar.bz2" && break;
done
tar xjf "boost_${BOOST}.tar.bz2"
pushd boost_${BOOST}
./bootstrap.sh --with-libraries=program_options --prefix=${LOCAL_INSTALL_PATH}
./b2 -j ${NUM_CPUS}
./b2 install
popd
popd
fi
echo "export BOOST_ROOT='$(echo ${LOCAL_INSTALL_PATH})'" >> ~/.bash_profile
- name: Build and install geos
if: matrix.os != 'macos' && matrix.geos != 'none'
run: |
if ! test -d "${LOCAL_INSTALL_PATH}/include/geos" || ! test -f ${LOCAL_INSTALL_PATH}/bin/geos.version || ! grep -qx "$(git ls-remote https://github.com/libgeos/geos.git ${{ matrix.geos }} )" ${LOCAL_INSTALL_PATH}/bin/geos.version; then
git ls-remote https://github.com/libgeos/geos.git ${{ matrix.geos }} > ${LOCAL_INSTALL_PATH}/bin/geos.version
echo "UPDATE_CACHE=true" >> $GITHUB_ENV
pushd ~
git clone --depth 1 --branch ${{ matrix.geos }} https://github.com/libgeos/geos.git
pushd geos
mkdir build
pushd build
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release .. -DCMAKE_INSTALL_PREFIX=${LOCAL_INSTALL_PATH}
make -j ${NUM_CPUS}
make install
popd
popd
popd
fi
- name: coverage specific setup
if: matrix.code_coverage
run: |
sudo apt-get install libperlio-gzip-perl libjson-perl libcapture-tiny-perl
pushd ~
git clone --branch=v1.16 --depth=1 https://github.com/linux-test-project/lcov.git
pushd lcov
make PREFIX=${LOCAL_INSTALL_PATH} install
hash -r
lcov --version
- name: Install gerbv
run: |
echo "gerbv/main commit sha is $(git ls-remote https://github.com/gerbv/gerbv.git heads/main)"
if ! gerbv --version || ! test -f ${LOCAL_INSTALL_PATH}/bin/gerbv.version || ! grep -qx "$(git ls-remote https://github.com/gerbv/gerbv.git heads/main)" ${LOCAL_INSTALL_PATH}/bin/gerbv.version; then
git ls-remote https://github.com/gerbv/gerbv.git heads/main > ${LOCAL_INSTALL_PATH}/bin/gerbv.version
echo "UPDATE_CACHE=true" >> $GITHUB_ENV
pushd ~
git clone --depth=1 --branch=main https://github.com/gerbv/gerbv.git
pushd gerbv
sh autogen.sh
./configure CPPFLAGS=$CPPFLAGS_gerbv --disable-update-desktop-database --prefix=${LOCAL_INSTALL_PATH}
make -j ${NUM_CPUS}
make install
popd
popd
fi
- name: Install valgrind
if: matrix.os == 'ubuntu'
run: |
if ! valgrind --version || ! grep -qx "$(git ls-remote https://github.com/eyal0/valgrind.git master)" ${LOCAL_INSTALL_PATH}/bin/valgrind.version; then
git ls-remote https://github.com/eyal0/valgrind.git master > ${LOCAL_INSTALL_PATH}/bin/valgrind.version
echo "UPDATE_CACHE=true" >> $GITHUB_ENV
pushd ~
git clone --depth=1 --branch=master https://github.com/eyal0/valgrind.git
pushd valgrind
sh autogen.sh
./configure --prefix=${LOCAL_INSTALL_PATH}
make -j ${NUM_CPUS}
make install
popd
popd
fi
- name: Install parallel
run: |
if ! parallel --version; then
echo "UPDATE_CACHE=true" >> $GITHUB_ENV
pushd ~
for i in {1..5}; do
wget -q -T5 -t1 -O "parallel-latest.tar.bz2" 'https://ftpmirror.gnu.org/parallel/parallel-latest.tar.bz2' && break;
done
mkdir parallel
pushd parallel
tar xjf "../parallel-latest.tar.bz2"
pushd parallel-*
./configure --prefix=${LOCAL_INSTALL_PATH}
make
make install
popd
popd
popd
fi
- name: Finalize setup
run: |
hash -r
- name: Autoreconf pcb2gcode
run: autoreconf -fvi
- name: Configure pcb2gcode
run: >-
./configure pcb2gcode_CPPFLAGS_EXTRA=-Werror
--disable-dependency-tracking
--disable-silent-rules
--enable-static-boost
--enable-static
${{ matrix.code_coverage }}
|| (cat config.log && false)
- name: Remove debug flags from coverage builds
if: matrix.code_coverage
run: sed -i 's/-g /-g0 /g' Makefile
- name: Make pcb2gcode
run: make -j ${NUM_CPUS}
- name: Run examples
if: '! matrix.code_coverage'
run: |
pushd testing/gerbv_example
ls | parallel -k -j ${NUM_CPUS} --halt soon,fail=1 '
{ echo "::group::Running on {}";
pushd {};
if [[ -f "no-valgrind" ]]; then
cat no-valgrind;
fi;
if [[ -f "no-valgrind" || "${{ matrix.os }}" != "ubuntu" ]]; then
time ../../../pcb2gcode || exit;
else
time valgrind --error-exitcode=127 --errors-for-leak-kinds=definite --leak-check=full -s --exit-on-first-error=yes --expensive-definedness-checks=yes -- ../../../pcb2gcode || exit;
fi;
popd;
echo "::endgroup::";
} 2>&1'
popd
- name: Reset coverage
if: matrix.code_coverage
continue-on-error: true
run: lcov --directory . -z
- name: Run unit tests
if: matrix.os != 'ubuntu'
env:
VERBOSE: 1
SKIP_GERBERIMPORTER_TESTS_PNG: 1
run: make -j ${NUM_CPUS} check || (cat test-suite.log && false)
- name: Run unit tests with valgrind
if: matrix.os == 'ubuntu'
env:
VERBOSE: 1
SKIP_GERBERIMPORTER_TESTS_PNG: 1
run: make -j ${NUM_CPUS} check-valgrind || (cat mem-test-suite.log && false)
- name: Run integration tests
if: matrix.boost == '1_66' && matrix.geos == 'main'
run: |
sudo apt-get install python3-setuptools
pip3 install --user wheel colour_runner unittest2 termcolor concurrencytest in_place
./integration_tests.py -j ${NUM_CPUS}
- name: Gather coverage
if: matrix.code_coverage
run: |
lcov --rc lcov_branch_coverage=1 -rc lcov_function_coverage --directory . --capture --no-external --output-file "pcb2gcode-lcov.info"
lcov --rc lcov_branch_coverage=1 -rc lcov_function_coverage -r "pcb2gcode-lcov.info" '*_tests.cpp' -o "pcb2gcode-lcov.info"
- name: Upload coverage artifact
if: matrix.code_coverage
uses: actions/upload-artifact@v3.1.1
with:
name: lcov-${{ steps.sanitize-key.outputs.key }}
path: pcb2gcode-lcov.info
- name: Prepare build for upload for Ubuntu and Macos
if: matrix.os != 'windows'
run: |
mkdir pcb2gcode-$(./pcb2gcode --version | head -1)
mkdir pcb2gcode-$(./pcb2gcode --version | head -1)/.libs
cp ./pcb2gcode pcb2gcode-$(./pcb2gcode --version | head -1)
if [[ -e ${LOCAL_INSTALL_PATH}/lib/libgerbv.so.1 ]]; then
cp -L ${LOCAL_INSTALL_PATH}/lib/libgerbv.so.1 pcb2gcode-$(./pcb2gcode --version | head -1)/.libs;
fi
if ls "${LOCAL_INSTALL_PATH}/lib/libgeos*" ]]; then
cp -L "${LOCAL_INSTALL_PATH}/lib/libgeos*" pcb2gcode-$(./pcb2gcode --version | head -1)/.libs;
fi
cat > pcb2gcode-$(./pcb2gcode --version | head -1)/pcb2gcode.sh << EOF
#!/bin/bash
if [[ \$EUID > 0 ]]; then MAYBE_SUDO=sudo; fi
export DEBIAN_FRONTEND=noninteractive
\$MAYBE_SUDO apt-get update -y
\$MAYBE_SUDO apt-get install -y libglib2.0-bin
\$MAYBE_SUDO apt-get install -y libgtkmm-2.4-1v5
LD_LIBRARY_PATH=\$PWD/.libs:\$LD_LIBRARY_PATH ./pcb2gcode "\$@"
EOF
chmod a+x pcb2gcode-$(./pcb2gcode --version | head -1)/pcb2gcode.sh
tar cvf pcb2gcode-${{ steps.sanitize-key.outputs.key }}.tar pcb2gcode-$(./pcb2gcode --version | head -1)
gzip pcb2gcode-${{ steps.sanitize-key.outputs.key }}.tar
- name: Prepare build for upload for Windows
if: matrix.os == 'windows'
run: |
mkdir pcb2gcode-$(./pcb2gcode --version | head -1)
pushd pcb2gcode-$(./pcb2gcode --version | head -1)
cp ../pcb2gcode.exe .
mkdir .libs
pushd .libs
cp ../../.libs/pcb2gcode.exe .
cp ../../../.local/bin/libgerbv-1.dll .
if [[ ${GEOS} != 'none' ]]; then
cp ../../../.local/bin/libgeos-${GEOS}.dll .
fi
cp /mingw64/bin/libboost_program_options-mt.dll .
cp /mingw64/bin/libbrotlicommon.dll .
cp /mingw64/bin/libbrotlidec.dll .
cp /mingw64/bin/libbz2-1.dll .
cp /mingw64/bin/libcairo-2.dll .
cp /mingw64/bin/libdatrie-1.dll .
cp /mingw64/bin/libexpat-1.dll .
cp /mingw64/bin/libffi-7.dll .
cp /mingw64/bin/libfontconfig-1.dll .
cp /mingw64/bin/libfreetype-6.dll .
cp /mingw64/bin/libfribidi-0.dll .
cp /mingw64/bin/libgcc_s_seh-1.dll .
cp /mingw64/bin/libgdk_pixbuf-2.0-0.dll .
cp /mingw64/bin/libgdk-win32-2.0-0.dll .
cp /mingw64/bin/libgio-2.0-0.dll .
cp /mingw64/bin/libglib-2.0-0.dll .
cp /mingw64/bin/libgmodule-2.0-0.dll .
cp /mingw64/bin/libgobject-2.0-0.dll .
cp /mingw64/bin/libgraphite2.dll .
cp /mingw64/bin/libharfbuzz-0.dll .
cp /mingw64/bin/libiconv-2.dll .
cp /mingw64/bin/libintl-8.dll .
cp /mingw64/bin/libpango-1.0-0.dll .
cp /mingw64/bin/libpangocairo-1.0-0.dll .
cp /mingw64/bin/libpangoft2-1.0-0.dll .
cp /mingw64/bin/libpangowin32-1.0-0.dll .
cp /mingw64/bin/libpcre-1.dll .
cp /mingw64/bin/libpixman-1-0.dll .
cp /mingw64/bin/libpng16-16.dll .
cp /mingw64/bin/libstdc++-6.dll .
cp /mingw64/bin/libthai-0.dll .
cp /mingw64/bin/libwinpthread-1.dll .
cp /mingw64/bin/zlib1.dll .
popd
popd
tar cvf pcb2gcode-${{ steps.sanitize-key.outputs.key }}.tar pcb2gcode-$(./pcb2gcode --version | head -1)
env:
GEOS: ${{ matrix.geos }}
- name: Upload build for Ubuntu and Macos
if: matrix.os != 'windows'
uses: actions/upload-artifact@v3.1.1
with:
name: pcb2gcode-${{ steps.sanitize-key.outputs.key }}
path: pcb2gcode-${{ steps.sanitize-key.outputs.key }}.tar.gz
- name: Upload build for Windows
if: matrix.os == 'windows'
uses: actions/upload-artifact@v3.1.1
with:
name: pcb2gcode-${{ steps.sanitize-key.outputs.key }}
path: pcb2gcode-${{ steps.sanitize-key.outputs.key }}.tar
- name: Upload coverage to coveralls
if: matrix.code_coverage
uses: eyal0/github-action@master
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
path-to-lcov: pcb2gcode-lcov.info
flag-name: ci-${{ steps.sanitize-key.outputs.key }}
parallel: true
- name: Save version number
if: matrix.code_coverage
run: echo "$(./pcb2gcode --version | head -1)" > version.txt
- name: Upload version artifact
if: matrix.code_coverage
uses: actions/upload-artifact@v3.1.1
with:
name: version
path: version.txt
finalize-coverage:
needs: [build-and-test]
name: Finalize coverage
runs-on: ubuntu-latest
steps:
- name: Finalize coverage
uses: eyal0/github-action@master
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
parallel-finished: true
release:
if: github.event_name == 'push' && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/v'))
needs: [build-and-test]
name: release
runs-on: ubuntu-latest
steps:
- name: Download the artifacts to release
uses: actions/download-artifact@v2
- run: echo "PCB2GCODE_VERSION=$(cat version/version.txt)" >> $GITHUB_ENV
- name: Prepare the windows artifacts
run: |
if [[ -f pcb2gcode-windows_latest_gplusplus_3.11.0/pcb2gcode-windows_latest_gplusplus_3.11.0.tar ]]; then
mkdir -p pcb2gcode-windows
mv pcb2gcode-windows_latest_gplusplus_3.11.0/pcb2gcode-windows_latest_gplusplus_3.11.0.tar pcb2gcode-windows/pcb2gcode-windows-${PCB2GCODE_VERSION}.tar
pushd pcb2gcode-windows
tar xvf pcb2gcode-windows-${PCB2GCODE_VERSION}.tar
zip -r pcb2gcode-windows-${PCB2GCODE_VERSION}.zip pcb2gcode-${PCB2GCODE_VERSION}
popd
fi
- name: Prepare the ubuntu artifacts
run: |
if [[ -f pcb2gcode-ubuntu_1_66_gplusplus_3.11.0/pcb2gcode-ubuntu_1_66_gplusplus_3.11.0.tar.gz ]]; then
mkdir -p pcb2gcode-ubuntu
mv pcb2gcode-ubuntu_1_66_gplusplus_3.11.0/pcb2gcode-ubuntu_1_66_gplusplus_3.11.0.tar.gz pcb2gcode-ubuntu/pcb2gcode-ubuntu-${PCB2GCODE_VERSION}.tar.gz
mkdir -p pcb2gcode-{windows,ubuntu,macos}
fi
- name: Prepare the macos artifacts
run: |
if [[ -f pcb2gcode-macos_latest_gplusplus_3.11.0/pcb2gcode-macos_latest_gplusplus_3.11.0.tar.gz ]]; then
mv pcb2gcode-macos_latest_gplusplus_3.11.0/pcb2gcode-macos_latest_gplusplus_3.11.0.tar.gz pcb2gcode-macos/pcb2gcode-macos-${PCB2GCODE_VERSION}.tar.gz
fi
- uses: "marvinpinto/action-automatic-releases@latest"
with:
repo_token: "${{ secrets.GITHUB_TOKEN }}"
automatic_release_tag: ${{ startsWith(github.ref, 'refs/heads') && 'latest' || null }}
prerelease: ${{ startsWith(github.ref, 'refs/heads') }}
title: ${{ startsWith(github.ref, 'refs/heads') && 'Development Build' || null }}
files: |
pcb2gcode-*/pcb2gcode-*-${{ env.PCB2GCODE_VERSION }}.*