Skip to content

Multiplatform build and upload #451

Multiplatform build and upload

Multiplatform build and upload #451

Workflow file for this run

name: Multiplatform build and upload
on:
workflow_dispatch:
env:
GH_TOKEN: ${{ secrets.GNUS_TOKEN_1 }}
jobs:
build:
env:
GRPC_BUILD_ENABLE_CCACHE: "ON"
runs-on: ${{matrix.host}}
strategy:
fail-fast: false
matrix:
target: [Android, iOS, OSX, Linux, Windows]
build-type: [Release]
include:
- target: Linux
host: ubuntu-latest
- target: Windows
host: windows-latest
- target: OSX
host: macos-latest
- target: Android
host: ubuntu-latest
abi: arm64-v8a
- target: iOS
host: macos-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: "recursive"
- name: Configure Linux host
if: ${{ matrix.host == 'ubuntu-latest'}}
run: |
sudo update-alternatives --install /usr/bin/cc cc $(which clang) 100
sudo update-alternatives --install /usr/bin/c++ c++ $(which clang++) 100
sudo update-alternatives --set cc $(which clang)
sudo update-alternatives --set c++ $(which clang++)
sudo apt install ccache libvulkan-dev ninja-build ripgrep -y
echo "CMAKE_GENERATOR=Ninja" >> $GITHUB_ENV
- name: Configure Windows host
if: ${{ matrix.host == 'windows-latest'}}
run: |
choco install ccache ripgrep -A
- name: Configure macOS host
if: ${{ matrix.host == 'macos-latest'}}
run: |
brew install ccache ninja ripgrep bash
echo "CMAKE_GENERATOR=Ninja" >> $GITHUB_ENV
- name: Add Darwin toolchain
if: ${{ matrix.target == 'OSX'}}
run: rustup target add x86_64-apple-darwin
- name: Add iOS toolchain
if: ${{ matrix.target == 'iOS' }}
run: |
rustup toolchain install nightly-aarch64-apple-darwin
rustup component add rust-src --toolchain nightly-aarch64-apple-darwin
rustup target add aarch64-apple-ios
- name: Add Android toolchain
if: ${{ matrix.target == 'Android' }}
run: |
NDK_VERSION="r27b"
wget https://dl.google.com/android/repository/android-ndk-$NDK_VERSION-linux.zip -O ndk.zip
unzip ndk.zip -d $HOME
echo "ANDROID_NDK_HOME=$HOME/android-ndk-$NDK_VERSION" >> $GITHUB_ENV
rustup target add aarch64-linux-android
- name: Install bindgen
run: cargo install cbindgen
- name: Add wasm Rust target
run: rustup target add wasm32-unknown-emscripten
- name: Set build directory
run: |
if [ '${{matrix.target}}' == 'Android' ] ; then
BUILD_DIRECTORY=build/${{matrix.target}}/${{matrix.build-type}}/${{matrix.abi}}
else
BUILD_DIRECTORY=build/${{matrix.target}}/${{matrix.build-type}}
fi
echo "BUILD_DIRECTORY=$BUILD_DIRECTORY" >> $GITHUB_ENV
shell: bash
- name: Configure CMake for Mac x86
if: ${{ matrix.target == 'OSX'}}
run: cmake -S build/${{matrix.target}} -B $BUILD_DIRECTORY -DCMAKE_BUILD_TYPE=${{matrix.build-type}} -DPLATFORM=MAC
- name: Configure CMake for iOS
if: ${{ matrix.target == 'iOS'}}
run: cmake -S build/${{matrix.target}} -B $BUILD_DIRECTORY -DCMAKE_BUILD_TYPE=${{matrix.build-type}} -DPLATFORM=OS64
- name: Configure SuperGenius CMake for Android
if: ${{ matrix.target == 'Android'}}
run: cmake -S build/${{matrix.target}} -B $BUILD_DIRECTORY -DCMAKE_BUILD_TYPE=${{matrix.build-type}} -DANDROID_ABI=${{matrix.abi}}
- name: Configure CMake for Windows
if: ${{ matrix.target == 'Windows' }}
run: cmake -S build/${{matrix.target}} -B $env:BUILD_DIRECTORY -DCMAKE_BUILD_TYPE=${{matrix.build-type}}
- name: Configure CMake for Linux
if: ${{ matrix.target == 'Linux' }}
run: cmake -S build/${{matrix.target}} -B $BUILD_DIRECTORY -DCMAKE_BUILD_TYPE=${{matrix.build-type}}
- name: Creating release tag
id: create-release-tag
run: |
RELEASE_TAG='${{matrix.target}}-${{ github.ref_name }}-${{matrix.build-type}}'
echo "RELEASE_TAG=${RELEASE_TAG}" >> $GITHUB_ENV
echo "Check if GitHub release tag $RELEASE_TAG available."
set +e
gh release view $RELEASE_TAG
releaseFound=$?
set -e
if [[ $releaseFound -ne 0 ]]; then
echo "Release not found, creating with tag: $RELEASE_TAG"
RELEASE_TYPE="--latest"
if [ '${{ matrix.build-type }}' != 'Release' ]; then
RELEASE_TYPE="--prerelease"
fi
# Create release on GitHub
gh release create $RELEASE_TAG \
-n '${{ github.ref_name }} branch' \
--target '${{ github.ref_name }}' \
${RELEASE_TYPE} \
-t '${{ matrix.target }} ${{ github.ref_name }} branch ${{ matrix.build-type }} build'
fi
shell: bash
- name: Check which targets need updating
working-directory: ${{env.BUILD_DIRECTORY}}
run: |
declare -A target_shas
declare -A target_build_directories
while IFS=':' read -r file src_dir; do
target="${file%-source_dirinfo.txt}"
target="${target##*/}"
sha=$(git -C ./${src_dir} rev-parse HEAD)
target_shas[$target]=$sha
build_directory="${file%%*/}"
target_build_directories[$target]=$build_directory
done < <(rg 'source_dir=(.*)' -u -r '$1' -g '*-source_dirinfo.txt' .)
echo "Downloading release.json file"
set +e
gh release download $RELEASE_TAG --pattern "release.json" --clobber
set -e
declare -A release_shas
if [[ -f "release.json" ]]; then
while IFS="=" read -r target sha; do
release_shas[$target]=$sha
done < <(jq -r '.[] | "\(.name)=\(.sha)"' release.json)
fi
targets_to_update=()
sha_of_targets_to_update=()
build_directories_of_targets_to_update=()
skipped_targets=()
for target in "${!target_shas[@]}"; do
if [[ -v release_shas["$target"] && "${target_shas[$target]}" == "${release_shas[$target]}" ]]; then
echo "Skipping $target due to same SHA from release"
skipped_targets+=("${target}")
else
echo "Adding $target to the update list"
targets_to_update+=("${target}")
sha_of_targets_to_update+=("${target_shas[$target]}")
build_directories_of_targets_to_update+=("${target_build_directories[$target]}")
fi
done
echo "TARGETS_TO_UPDATE=${targets_to_update[@]}" >>$GITHUB_ENV
echo "SHA_OF_TARGETS_TO_UPDATE=${sha_of_targets_to_update[@]}" >>$GITHUB_ENV
echo "BUILD_DIRECTORIES_OF_TARGETS_TO_UPDATE=${build_directories_of_targets_to_update[@]}" >>$GITHUB_ENV
echo "SKIPPED_TARGETS=${skipped_targets}" >>$GITHUB_ENV
shell: bash
- name: Build targets in POSIX hosts
working-directory: ${{env.BUILD_DIRECTORY}}
if: ${{matrix.host != 'Windows'}}
run: |
targets_to_update=($TARGETS_TO_UPDATE)
for target in "${targets_to_update[@]}"; do
echo Building ${target}
cmake --build . --target ${target} -j
done
- name: Build targets in Windows host
working-directory: ${{env.BUILD_DIRECTORY}}
if: ${{matrix.host == 'Windows'}}
run: |
$targets_to_update = $TARGETS_TO_UPDATE -split ' '
foreach ($target in $targets_to_update) {
Write-Host "Building $target"
cmake --build . --target $target -j
}
- name: Compress and upload targets
working-directory: ${{env.BUILD_DIRECTORY}}
run: |
targets_to_update=($TARGETS_TO_UPDATE)
build_directories=($BUILD_DIRECTORIES_OF_TARGETS_TO_UPDATE)
sha_of_targets=($SHA_OF_TARGETS_TO_UPDATE)
declare -A release_shas
if [[ -f "release.json" ]]; then
while IFS="=" read -r target sha; do
release_shas[$target]=$sha
done < <(jq -r '.[] | "\(.name)=\(.sha)"' release.json)
fi
for i in "${!targets_to_update[@]}"; do
target=${targets_to_update[$i]}
compressed_file="${target}-lib.tar.gz"
directory_to_compress="${build_directories[$i]}"
echo Compressing ${target}
tar --exclude="${directory_to_compress}/src" --exclude="${directory_to_compress}/tmp" -czf ${compressed_file} ${directory_to_compress}
echo -e "Uploading ${compressed_file}\n"
gh release upload --clobber ${RELEASE_TAG} ${compressed_file}
release_shas[${target}]="${sha_of_targets[i]}"
done
json_data=$(for key in "${!release_shas[@]}"; do
printf '{"name": "%s", "sha": "%s"}\n' "$key" "${release_shas[$key]}"
done | jq -s '.')
echo "$json_data" >release.json
gh release upload --clobber ${RELEASE_TAG} release.json
shell: bash