build: Build system overhaul #2464
Workflow file for this run
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: Build | |
on: | |
push: | |
branches: [ master ] | |
tags: [ 'v*' ] | |
pull_request: | |
branches: [ master ] | |
jobs: | |
build: | |
strategy: | |
fail-fast: false | |
matrix: | |
program: | |
- ares | |
platform: | |
- name: windows | |
os: windows-latest | |
compiler: clang++ | |
windres: windres | |
shell: 'msys2 {0}' | |
msystem: clang64 | |
install: mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-pkgconf mingw-w64-clang-x86_64-SDL2 | |
- name: windows-arm64 | |
os: windows-latest | |
compiler: clang++ --target=aarch64-w64-windows-gnu --sysroot=/clangarm64 -resource-dir=/clangarm64/lib/clang/$(basename "$(clang++ -print-resource-dir)") | |
windres: windres --target=aarch64-w64-windows-gnu | |
shell: 'msys2 {0}' | |
msystem: clang64 | |
install: mingw-w64-clang-x86_64-clang mingw-w64-clang-aarch64-clang mingw-w64-clang-aarch64-pkgconf mingw-w64-clang-aarch64-SDL2 | |
- name: windows-msvc-x64 | |
os: windows-latest | |
compiler: clang++ | |
windres: llvm-rc | |
shell: bash | |
msvc-arch: x64 | |
- name: windows-msvc-arm64 | |
os: windows-latest | |
compiler: clang++ --target=aarch64-w64-windows-msvc | |
windres: llvm-rc | |
shell: bash | |
msvc-arch: x64_arm64 | |
- name: windows-cl-x64 | |
os: windows-latest | |
compiler: cl | |
windres: rc | |
shell: bash | |
msvc-arch: x64 | |
- name: windows-cl-arm64 | |
os: windows-latest | |
compiler: cl | |
windres: rc | |
shell: bash | |
msvc-arch: x64_arm64 | |
- name: macos-compat | |
os: macos-12 | |
compiler: clang++ | |
shell: sh | |
- name: macos-latest | |
os: macos-latest | |
compiler: clang++ | |
shell: sh | |
- name: ubuntu | |
os: ubuntu-latest | |
compiler: g++ | |
shell: sh | |
name: ${{ matrix.program }}-${{ matrix.platform.name }} | |
runs-on: ${{ matrix.platform.os }} | |
defaults: | |
run: | |
shell: ${{ matrix.platform.shell }} | |
steps: | |
- name: Install MSYS2 Dependencies | |
if: matrix.platform.shell == 'msys2 {0}' | |
uses: msys2/setup-msys2@v2 | |
with: | |
msystem: ${{ matrix.platform.msystem }} | |
install: make ${{ matrix.platform.install }} | |
- name: Install Linux Dependencies | |
if: runner.os == 'Linux' | |
run: | | |
sudo apt-get update -y -qq | |
sudo apt-get install libsdl2-dev libgtk-3-dev libao-dev libopenal-dev | |
- name: "macOS: Import Certificate" | |
if: runner.os == 'macOS' && github.event_name != 'pull_request' | |
continue-on-error: ${{ github.repository != 'ares-emulator/ares' }} | |
uses: wpilibsuite/import-signing-certificate@2ac4f44d28045073d23153256efbb4c4b2d8aa22 # Don't use rolling branch for security reasons | |
with: | |
certificate-data: ${{ secrets.MACOS_CERTIFICATE_DATA }} | |
certificate-passphrase: ${{ secrets.MACOS_CERTIFICATE_PASSPHRASE }} | |
keychain-name: ares-macos-keychain | |
keychain-password: ${{ secrets.MACOS_KEYCHAIN_PASSWORD }} | |
- name: Checkout source code | |
uses: actions/checkout@v4 | |
- name: Install Windows Dependencies | |
if: runner.os == 'Windows' | |
run: | | |
export PATH="/c/Users/runneradmin/.cargo/bin:$PATH" # correct on windows-latest as of 2024-02-19 | |
if [[ ${{ matrix.platform.name }} == *-arm64 ]]; then | |
rustup toolchain install nightly | |
rustup default nightly | |
rustup target add aarch64-pc-windows-msvc | |
pushd thirdparty/librashader | |
./build-librashader.sh aarch64-pc-windows-msvc | |
popd | |
else | |
rustup toolchain install nightly | |
rustup default nightly | |
pushd thirdparty/librashader | |
./build-librashader.sh | |
popd | |
fi | |
- name: "macOS: recover MoltenVK cache" | |
if: runner.os == 'macOS' | |
uses: actions/cache@v4 | |
env: | |
cache-name: moltenvk | |
with: | |
path: thirdparty/MoltenVK/MoltenVK | |
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('thirdparty/MoltenVK/HEAD') }} | |
- name: Install macOS Dependencies | |
if: runner.os == 'macOS' | |
run: | | |
if [ $ImageOS == "macos14" ]; then | |
sudo xcode-select -s /Applications/Xcode_15.2.app/Contents/Developer | |
export MACOSX_DEPLOYMENT_TARGET=10.13 | |
echo "Set Xcode version to 15.2 for macos-latest build." | |
elif [ $ImageOS == "macos12" ]; then | |
sudo xcode-select -s /Applications/Xcode_13.4.app/Contents/Developer | |
export MACOSX_DEPLOYMENT_TARGET=10.9 | |
echo "Set Xcode version to 13.4 for macos-compat build." | |
fi | |
brew install make ninja cmake | |
pip install --no-input setuptools | |
rustup toolchain install nightly | |
rustup default nightly | |
rustup target add x86_64-apple-darwin | |
rustup target add aarch64-apple-darwin | |
echo "MAKE=gmake" >> $GITHUB_ENV | |
pushd thirdparty/SDL | |
./build-SDL.sh | |
popd | |
pushd thirdparty/MoltenVK | |
./build-moltenvk.sh | |
popd | |
export MACOSX_DEPLOYMENT_TARGET=10.15 | |
pushd thirdparty/librashader | |
./build-librashader.sh | |
popd | |
- name: Set up MSVC environment | |
if: matrix.platform.msvc-arch != '' | |
uses: ilammy/msvc-dev-cmd@v1 | |
with: | |
arch: ${{ matrix.platform.msvc-arch }} | |
- name: Make | |
if: runner.os != 'macOS' | |
run: ${MAKE:-make} -j4 -C desktop-ui build=optimized local=false compiler="${{ matrix.platform.compiler }}" windres="${{ matrix.platform.windres }}" | |
- name: "macOS: Make universal app" | |
if: runner.os == 'macOS' | |
run: scripts/macos-make-universal.sh build=optimized local=false | |
env: | |
MAKEFLAGS: -j3 | |
MACOS_CERTIFICATE_NAME: ${{ secrets.MACOS_CERTIFICATE_NAME }} | |
MACOS_KEYCHAIN_NAME: ares-macos-keychain | |
MACOS_KEYCHAIN_PASSWORD: ${{ secrets.MACOS_KEYCHAIN_PASSWORD }} | |
- name: "Windows: sign" | |
if: runner.os == 'Windows' && github.event_name != 'pull_request' | |
uses: DanaBear/code-sign-action@98c79121b376beab8d6a9484f445089db4461bca | |
with: | |
certificate: '${{ secrets.WIN_CERTIFICATE }}' | |
password: '${{ secrets.WIN_PASSWORD }}' | |
certificatesha1: '${{ secrets.WIN_CERTHASH }}' | |
certificatename: '${{ secrets.WIN_CERTNAME }}' | |
folder: 'desktop-ui/out' | |
timestampUrl: 'http://timestamp.digicert.com' | |
- name: "macOS: notarize" | |
if: runner.os == 'macOS' && github.event_name != 'pull_request' | |
continue-on-error: ${{ github.repository != 'ares-emulator/ares' }} | |
run: | | |
ditto -c -k --keepParent desktop-ui/out/ares.app /tmp/ares.zip | |
xcrun notarytool submit /tmp/ares.zip --apple-id "$MACOS_NOTARIZATION_USERNAME" --password "$MACOS_NOTARIZATION_PASSWORD" --team-id "$MACOS_NOTARIZATION_TEAMID" --wait | |
xcrun stapler staple desktop-ui/out/ares.app | |
env: | |
MACOS_NOTARIZATION_USERNAME: ${{ secrets.MACOS_NOTARIZATION_USERNAME }} | |
MACOS_NOTARIZATION_PASSWORD: ${{ secrets.MACOS_NOTARIZATION_PASSWORD }} | |
MACOS_NOTARIZATION_TEAMID: ${{ secrets.MACOS_NOTARIZATION_TEAMID }} | |
- name: Upload | |
uses: actions/upload-artifact@v4 | |
with: | |
name: ${{ matrix.program }}-${{ matrix.platform.name }} | |
path: desktop-ui/out/* | |
release: | |
if: github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/') | |
runs-on: ubuntu-latest | |
needs: | |
- build | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
path: 'src' | |
- name: Download Artifacts | |
uses: actions/download-artifact@v4 | |
with: | |
path: 'bin' | |
- name: Package Artifacts | |
run: | | |
set -eu | |
case ${GITHUB_REF} in | |
refs/tags/*) suffix="-${GITHUB_REF#refs/tags/}" ;; | |
refs/heads/master) suffix="-nightly" ;; | |
*) suffix="" ;; | |
esac | |
srcdir="${GITHUB_WORKSPACE}/src" | |
bindir="${GITHUB_WORKSPACE}/bin" | |
# Hack: Workaround for GitHub artifacts losing attributes. | |
chmod +x ${bindir}/ares-macos-latest/ares.app/Contents/MacOS/ares | |
chmod +x ${bindir}/ares-macos-compat/ares.app/Contents/MacOS/ares | |
for package in windows windows-msvc-arm64 macos-latest macos-compat | |
do | |
mkdir "${package}" | |
cd "${package}" | |
# Package ares. | |
outdir=ares${suffix} | |
mkdir ${outdir} | |
cp -ar ${bindir}/ares-${package}/* ${outdir} | |
zip -r ../ares-${package}.zip ${outdir} | |
cd - | |
done | |
- name: Create Release | |
id: release | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
run: | | |
set -eu | |
github_rest() | |
{ | |
local method="${1}" | |
local url="https://api.github.com${2}" | |
shift 2 | |
>&2 echo "${method} ${url}" | |
curl \ | |
--fail \ | |
-H "Accept: application/vnd.github.v3+json" \ | |
-H "Authorization: token ${GITHUB_TOKEN}" \ | |
-X "${method}" \ | |
"${url}" \ | |
"$@" | |
} | |
github_get_release_id_for_tag() | |
{ | |
payload=$(github_rest GET "/repos/${GITHUB_REPOSITORY}/releases/tags/${1}") || return | |
echo "${payload}" | jq .id | |
} | |
github_delete_release_by_id() | |
{ | |
github_rest DELETE "/repos/${GITHUB_REPOSITORY}/releases/${1}" | |
} | |
github_create_release() | |
{ | |
local payload="{ | |
\"tag_name\": \"${1}\", | |
\"target_commitish\": \"${2}\", | |
\"name\": \"${3}\", | |
\"body\": \"${4}\", | |
\"draft\": ${5}, | |
\"prerelease\": ${6} | |
}" | |
github_rest POST "/repos/${GITHUB_REPOSITORY}/releases" -d "${payload}" | |
} | |
make_nightly_release() | |
{ | |
github_create_release \ | |
nightly \ | |
"${GITHUB_SHA}" \ | |
"ares nightly $(date +"%Y-%m-%d")" \ | |
"Auto-generated nightly release on $(date -u +"%Y-%m-%d %T %Z")" \ | |
false \ | |
true | |
} | |
make_version_release() | |
{ | |
github_create_release \ | |
"${1}" \ | |
"${GITHUB_SHA}" \ | |
"ares ${1}" \ | |
"This is ares ${1}, released on $(date +"%Y-%m-%d")." \ | |
false \ | |
false | |
} | |
case ${GITHUB_REF} in | |
refs/tags/*) | |
# Create a new version release using the current revision. | |
echo "UPLOAD_URL=$(make_version_release ${GITHUB_REF#refs/tags/} | jq -r .upload_url)" >> $GITHUB_ENV | |
;; | |
refs/heads/master) | |
# Check for an existing nightly release. | |
{ release_id=$(github_get_release_id_for_tag nightly); status=$?; } || true | |
# Delete existing nightly release if it exists. | |
case ${status} in | |
0) github_delete_release_by_id "${release_id}" ;; | |
22) >&2 echo "No current nightly release; skipping tag deletion." ;; | |
*) >&2 echo "API call failed unexpectedly." && exit 1 ;; | |
esac | |
# Create a new nightly release using the current revision. | |
echo "UPLOAD_URL=$(make_nightly_release | jq -r .upload_url)" >> $GITHUB_ENV | |
;; | |
esac | |
- name: Upload ares-windows | |
uses: actions/upload-release-asset@v1 | |
env: { GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' } | |
with: { upload_url: '${{ env.UPLOAD_URL }}', asset_path: 'ares-windows.zip', asset_name: 'ares-windows.zip', asset_content_type: 'application/zip' } | |
- name: Upload ares-windows-msvc-arm64 | |
uses: actions/upload-release-asset@v1 | |
env: { GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' } | |
with: { upload_url: '${{ env.UPLOAD_URL }}', asset_path: 'ares-windows-msvc-arm64.zip', asset_name: 'ares-windows-msvc-arm64.zip', asset_content_type: 'application/zip' } | |
- name: Upload ares-macos-latest | |
uses: actions/upload-release-asset@v1 | |
env: { GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' } | |
with: { upload_url: '${{ env.UPLOAD_URL }}', asset_path: 'ares-macos-latest.zip', asset_name: 'ares-macos-latest.zip', asset_content_type: 'application/zip' } | |
- name: Upload ares-macos-compat | |
uses: actions/upload-release-asset@v1 | |
env: { GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' } | |
with: { upload_url: '${{ env.UPLOAD_URL }}', asset_path: 'ares-macos-compat.zip', asset_name: 'ares-macos-compat.zip', asset_content_type: 'application/zip' } | |
# - name: Upload ares-ubuntu | |
# uses: actions/upload-release-asset@v1 | |
# env: { GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' } | |
# with: { upload_url: '${{ env.UPLOAD_URL }}', asset_path: 'ares-ubuntu.zip', asset_name: 'ares-ubuntu.zip', asset_content_type: 'application/zip' } | |