diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml new file mode 100644 index 00000000..05f04e11 --- /dev/null +++ b/.github/workflows/build.yaml @@ -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