-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add GitHub Actions workflow to build releases
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
Showing
1 changed file
with
177 additions
and
0 deletions.
There are no files selected for viewing
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
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 |