CI #1474
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 }}.* |