Skip to content

Commit

Permalink
Add GitHub Actions workflow to build releases
Browse files Browse the repository at this point in the history
Will automatically build and release versions when tags like 'x.x.x' are
pushed. Can also be run manually to produce a build artifact.

Note that the build is a bit hacky:
 - It uses the Ubuntu image provided by GitHub, but adds the Debian
   bullseye repo in order to get more recent packages.
 - It edits some of the files that `cmake` generates so that the host's
   `qt` system's `moc` and `rcc` build tools are used instead of the
   mingw-provided ones (which are win32 executables).
 - It builds and installs `pacman` so it can use it to download and
   install the required mingw packages.
  • Loading branch information
pR0Ps committed Oct 18, 2020
1 parent d091442 commit 7237737
Showing 1 changed file with 177 additions and 0 deletions.
177 changes: 177 additions & 0 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
name: build

# Run manually or each time a version tag is pushed
on:
workflow_dispatch:
push:
tags:
- '[0-9]+.[0-9]+.[0-9]+'

jobs:
build:
name: "Build Invader"
runs-on: ubuntu-20.04
# Repos contain:
# - cmake v3.16.3
# - mingw-w64 v7.0.0 (gcc/g++ v9.3.0)
# - python3 v3.8.2

steps:
- name: "Checkout Invader"
uses: actions/checkout@v2

- name: "Install deps"
run: |-
# Make apt retry
echo 'Acquire::Retries "5";' | sudo tee -a /etc/apt/apt.conf.d/80-retries >/dev/null
# Add Debian bullseye repo to get:
# - cmake v3.18.2
# - mingw-w64 v8.0.0 (gcc/g++ v10.1.0)
# - python3 v3.8.6
sudo apt-get update
sudo apt-get install -y gnupg
echo "deb http://http.us.debian.org/debian/ bullseye contrib main" | sudo tee -a /etc/apt/sources.list >/dev/null
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 04EE7237B7D453EC
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 648ACFD622F3D138
sudo apt-get update
sudo apt-get install -y build-essential cmake mingw-w64 python3 git zip
# Tools to download and extract mingw-w64 packages
sudo apt-get install -y curl zstd xz-utils
# Install qt meta-compilation tools (moc and rcc) to build invader-edit-qt_autogen
sudo apt-get install -y qtbase5-dev-tools
# Install deps for building pacman
sudo apt-get install -y pkg-config m4 libarchive-dev libssl-dev libcurl4-openssl-dev
- name: "Build and install pacman for downloading mingw deps"
run: |-
mkdir pacman
curl --silent --location 'https://sources.archlinux.org/other/pacman/pacman-5.2.2.tar.gz' | tar --extract --gzip --strip-components=1 --directory=pacman
cd pacman
./configure --disable-doc --sysconfdir=/etc
make
sudo make install
# Make libalpm load properly
sudo ldconfig
sudo mkdir -p /usr/local/var/lib/pacman/
# Configure mingw64 repo
echo '[mingw64]' | sudo tee -a /etc/pacman.conf >/dev/null
echo 'Server = https://repo.msys2.org/mingw/x86_64/' | sudo tee -a /etc/pacman.conf >/dev/null
- name: "Download and install mingw deps"
run: |-
tmp="$(mktemp -d)"
# Download the deps
sudo pacman --sync --refresh --noconfirm --downloadonly --cachedir="$tmp" \
mingw-w64-x86_64-libarchive \
mingw-w64-x86_64-libogg \
mingw-w64-x86_64-flac \
mingw-w64-x86_64-libsamplerate \
mingw-w64-x86_64-libvorbis \
mingw-w64-x86_64-zlib \
mingw-w64-x86_64-freetype \
mingw-w64-x86_64-zstd \
mingw-w64-x86_64-libtiff \
mingw-w64-x86_64-qt5
# Extract deps to the mingw directory
for x in "${tmp}"/*; do
sudo tar --extract --file="$x" --strip-components=1 --directory=/usr/x86_64-w64-mingw32/
done
rm -rf "$tmp"
- name: "Build Invader"
run: |-
cmake . \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_SYSTEM_NAME=Windows \
-DCMAKE_FIND_ROOT_PATH=/usr/x86_64-w64-mingw32 \
-DCMAKE_C_COMPILER=/usr/bin/x86_64-w64-mingw32-gcc-posix \
-DCMAKE_CXX_COMPILER=/usr/bin/x86_64-w64-mingw32-g++-posix \
-DCMAKE_RC_COMPILER=/usr/bin/x86_64-w64-mingw32-windres \
-DCMAKE_AR=/usr/bin/x86_64-w64-mingw32-gcc-ar-posix \
-DCMAKE_RANLIB=/usr/bin/x86_64-w64-mingw32-gcc-ranlib-posix
# Gross hacks to the generated files to use the host qt's meta-compilation tools
# Have to change the minor version to match so moc's 'output-dep-file' option (new in 5.15) isn't used
qtminver=$(/usr/bin/moc -v | cut --delimiter=' ' --fields=2 | cut --delimiter='.' --fields=2)
sed --in-place \
--expression='s#"[^"]*\(moc\|rcc\)\.exe"#"/usr/bin/\1"#g' \
--expression="s#\(\"QT_VERSION_MINOR\"[^0-9]\+\)[0-9]\+#\1${qtminver}#g" \
$(find CMakeFiles -iname "*.json")
make -j$(nproc)
- name: "Package Invader"
run: |-
# Resolve mingw deps and copy them into the package directory
shopt -s nullglob
while true; do
new=0
while read dll; do
[ -f "${dll,,}" ] && continue
while read f; do
cp "$f" .
touch "$(basename "${f,,}")"
new=1
done < <(find /usr/x86_64-w64-mingw32 -iname "$dll")
done < <( objdump --private-headers *.{exe,dll} | grep -oP "DLL Name: \K.*" | sort -u )
(( $new )) || break
done
find . -name "*.dll" -size 0 -delete
# Copy files into the package directory and make the zip file to release
mkdir package
mv *.dll *.exe package/
cp -r /usr/x86_64-w64-mingw32/share/qt5/plugins/{platforms,styles,audio} package/
cd package
zip ../package.zip -r *
# Push an artifact if this was a manually-started build
- name: "Get short sha"
id: get_sha
if: "!startsWith(github.ref, 'refs/tags/')"
run: echo ::set-output name=SHA::${GITHUB_SHA::8}

- name: Upload artifact
if: "!startsWith(github.ref, 'refs/tags/')"
uses: actions/upload-artifact@v2
with:
name: invader-${{ steps.get_sha.outputs.SHA }}.zip
path: ./package.zip

# Make a release and upload the build if this is a tagged commit
- name: "Get version from tag"
id: get_version
if: startsWith(github.ref, 'refs/tags/')
run: echo ::set-output name=VERSION::${GITHUB_REF#refs/tags/}

- name: "Create release"
id: create_release
if: startsWith(github.ref, 'refs/tags/')
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ steps.get_version.outputs.VERSION }}
release_name: Invader v${{ steps.get_version.outputs.VERSION }}
draft: false
prerelease: false

- name: "Upload build"
uses: actions/upload-release-asset@v1
if: startsWith(github.ref, 'refs/tags/')
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./package.zip
asset_name: invader-${{ steps.get_version.outputs.VERSION }}.zip
asset_content_type: application/zip

0 comments on commit 7237737

Please sign in to comment.