Skip to content

cge-docker-unstable-changed #655

cge-docker-unstable-changed

cge-docker-unstable-changed #655

Workflow file for this run

# ----------------------------------------------------------------------------
# GitHub Actions workflow to build and package this project
# using Castle Game Engine.
#
# Details:
#
# - Builds and packages: creates release packages (zip,tar.gz)
# for all platforms we support.
#
# - Tests compilation in some ways we don't need for releasing,
# but still we support (in case devs want to build this application in these
# ways): Delphi, Lazarus using lazbuild (not using CGE build tool + FPC).
#
# - Uploads the release packages as GitHub release of "snapshot" tag,
# https://github.com/castle-engine/castle-model-viewer/releases/tag/snapshot
#
# - Updates the "snapshot" tag to point to the build commit.
# ----------------------------------------------------------------------------
name: Build
on:
push:
pull_request:
repository_dispatch:
types: [cge-docker-unstable-changed]
env:
# To which GitHub release tag should we upload artifacts.
# Can be "snapshot" or "vX.Y.Z" (latter when we make stable release).
release_tag: snapshot
#release_tag: vX.Y.Z
defaults:
run:
shell: bash
# We need "id-token: write, contents: read" to allow Azure federated login.
# Some jobs will need "contents: write" to allow uploading artifacts.
permissions:
contents: read
id-token: write
jobs:
# Test build in Docker.
# This does not archive artifacts anymore (because Windows builds
# need to be signed in Windows runner, in the future they may also need InnoSetup).
# It is only useful as a test, of this project and of our Docker image
# having cross-compile tools.
build_docker:
name: Build From Docker
runs-on: ubuntu-latest
container: kambi/castle-engine-cloud-builds-tools:cge-unstable
steps:
- uses: actions/checkout@v7
# Package application:
# - castle-model-converter first, it will be packaged in castle-model-viewer CastleEngineManifest.xml
# - then build and package castle-model-viewer
- name: Package Windows / x86_64
run: |
castle-engine compile --os=win64 --cpu=x86_64 --manifest-name=CastleEngineManifest.converter.xml
castle-engine package --os=win64 --cpu=x86_64
- name: Package Windows / i386
run: |
# We need "make clean" to be sure to remove previous build artifacts, e.g. castle-model-converter.exe
make clean
castle-engine compile --os=win32 --cpu=i386 --manifest-name=CastleEngineManifest.converter.xml
castle-engine package --os=win32 --cpu=i386
- name: Package Linux / x86_64
run: |
# We need "make clean" to be sure to remove previous build artifacts, e.g. castle-model-converter.exe
make clean
castle-engine compile --os=linux --cpu=x86_64 --manifest-name=CastleEngineManifest.converter.xml
castle-engine package --os=linux --cpu=x86_64
# Build on a few runners with native OS/CPU (not cross-compiling, not in Docker).
build_runner_native:
name: Build on Native Runner (target OS/CPU = source OS/CPU)
strategy:
matrix:
# Names correspond to target OS/CPU as called by FPC and CGE.
job-name: [
darwin-x86_64,
darwin-aarch64,
win32-i386,
win64-x86_64,
linux-x86_64
]
include:
- job-name: darwin-x86_64
runner: macos-15-intel # last macOS with Intel
build_os: darwin
build_cpu: x86_64
- job-name: darwin-aarch64
runner: macos-latest
build_os: darwin
build_cpu: aarch64
- job-name: win32-i386
runner: windows-latest
build_os: win32
build_cpu: i386
- job-name: win64-x86_64
runner: windows-latest
build_os: win64
build_cpu: x86_64
- job-name: linux-x86_64
runner: ubuntu-latest
build_os: linux
build_cpu: x86_64
runs-on: ${{ matrix.runner }}
steps:
- uses: actions/checkout@v7
# Use https://github.com/castle-engine/castle-build-ci to get FPC and CGE
- name: Setup Castle Game Engine
run: |
cd /tmp/ # temporary directory, to be separate from the current project files
git clone https://github.com/castle-engine/castle-build-ci.git \
--depth=1 --single-branch --branch=master
castle-build-ci/install_dependencies
castle-build-ci/setup_castle_engine --os=${{ matrix.build_os }} --cpu=${{ matrix.build_cpu }}
# Compile application (separate from packaging,
# to allow later signing before packaging on macOS and Windows)
- name: Compile
run: |
castle-engine compile --manifest-name=CastleEngineManifest.converter.xml --os=${{ matrix.build_os }} --cpu=${{ matrix.build_cpu }}
castle-engine compile --os=${{ matrix.build_os }} --cpu=${{ matrix.build_cpu }}
# Sign for Windows, see castle-build-ci/windows/README.md for details.
- name: Azure Login (Windows)
if: ${{ runner.os == 'Windows' && github.ref == 'refs/heads/master' }}
uses: azure/login@v3
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: Sign (Windows)
if: ${{ runner.os == 'Windows' && github.ref == 'refs/heads/master' }}
env:
AZURE_ENDPOINT: ${{ vars.AZURE_ENDPOINT }}
AZURE_CODESIGNING_ACCOUNT_NAME: ${{ vars.AZURE_CODESIGNING_ACCOUNT_NAME }}
AZURE_CERTIFICATE_PROFILE_NAME: ${{ vars.AZURE_CERTIFICATE_PROFILE_NAME }}
run: |
export AZURE_SIGNING_CLIENT_PARENT="$RUNNER_TEMP/sign-tools/"
/tmp/castle-build-ci/windows/setup_signing
/tmp/castle-build-ci/windows/sign_executables \
"$(castle-engine output executable-name).exe" \
"$(castle-engine output --manifest-name=CastleEngineManifest.converter.xml executable-name).exe"
- name: Package (not macOS)
if: ${{ runner.os != 'macOS' }}
run: castle-engine package --assume-compiled --os=${{ matrix.build_os }} --cpu=${{ matrix.build_cpu }}
- name: Package to Bundle (macOS)
if: ${{ runner.os == 'macOS' }}
# Special order for macOS:
# - First package castle-model-viewer, it will be a bundle.
# - Add 2nd exe "castle-model-converter" to the bundle.
#
# We will zip it manually (after signing and notarization),
# so we don't do plain "castle-engine package" (to zip) for macOS
# at any point.
run: |
castle-engine package --package-format=mac-app-bundle --assume-compiled --os=${{ matrix.build_os }} --cpu=${{ matrix.build_cpu }}
cp castle-model-converter "`castle-engine output caption`.app/Contents/MacOS/"
- name: Sign and Notarize (macOS)
if: ${{ runner.os == 'macOS' }}
env:
# for codesigning
APPLE_IDENTITY: ${{ vars.APPLE_IDENTITY }}
APPLE_BUILD_CERTIFICATE_BASE64: ${{ secrets.APPLE_BUILD_CERTIFICATE_BASE64 }}
APPLE_P12_PASSWORD: ${{ secrets.APPLE_P12_PASSWORD }}
APPLE_KEYCHAIN_PASSWORD: ${{ secrets.APPLE_KEYCHAIN_PASSWORD }}
# for notarization
APPLE_ID: ${{ vars.APPLE_ID }}
APPLE_TEAM_ID: ${{ vars.APPLE_TEAM_ID }}
APPLE_APP_PASSWORD: ${{ secrets.APPLE_APP_PASSWORD }}
run: |
/tmp/castle-build-ci/apple/setup_signing
/tmp/castle-build-ci/apple/sign_executables \
"`castle-engine output caption`.app/Contents/MacOS/castle-model-converter"
/tmp/castle-build-ci/apple/sign_notarize_bundle \
"`castle-engine output caption`.app" \
"`castle-engine output executable-name`"
- name: Package to Zip (macOS)
if: ${{ runner.os == 'macOS' }}
run: |
zip -r "`castle-engine output package-name`" "`castle-engine output caption`.app/"
- name: Archive Artifacts
uses: actions/upload-artifact@v7
with:
name: ${{ matrix.job-name }}-build
path: |
*.zip
*.tar.gz
if-no-files-found: error
# Raspberry Pi builds are special, using pguyot/arm-runner-action
build_arm_runner:
name: Build on ARM Runner (for Raspberry Pi)
runs-on: ubuntu-latest
strategy:
matrix:
arch: [raspberry-pi-32, raspberry-pi-64]
include:
# Raspberry Pi 32-bit (Arm)
- arch: raspberry-pi-32
cpu: cortex-a7
base_image: raspios_lite:latest
# Raspberry Pi 64-bit (Aarch64)
- arch: raspberry-pi-64
cpu: cortex-a53
base_image: raspios_lite_arm64:latest
steps:
- uses: actions/checkout@v7
- uses: pguyot/arm-runner-action@v2
with:
base_image: ${{ matrix.base_image }}
cpu: ${{ matrix.cpu }}
shell: /bin/bash -eo pipefail
image_additional_mb: 6000
# Avoids the need for copy_artifact_path later.
bind_mount_repository: true
commands: |
# Useful string to grep logs, because log of script execution is somewhat buried in the middle of pguyot/arm-runner-action log
echo 'CGE script starts here'
# Install Linux dependencies
sudo apt-get update
sudo apt-get --no-install-recommends -y install libgl-dev git make unzip sed zip
# Install FPC and CGE
pushd /tmp/
git clone https://github.com/castle-engine/castle-build-ci.git \
--depth=1 --single-branch --branch=master
castle-build-ci/install_dependencies
castle-build-ci/setup_castle_engine
source setup_castle_engine_env.sh
popd
# Check versions (and availability) of our requirements early
fpc -iV
make --version
sed --version
# Package application
castle-engine compile --manifest-name=CastleEngineManifest.converter.xml
castle-engine package
- name: Archive Artifacts
uses: actions/upload-artifact@v7
with:
name: raspberry-pi-${{ matrix.arch }}-build
path: |
*.zip
*.tar.gz
if-no-files-found: error
# Build also with Delphi, just to make sure it goes OK.
# We don't build releases with Delphi, but we make sure that if someone downloads
# sources -- they can build with Delphi as well as with FPC.
build_delphi:
name: Build Using Delphi
strategy:
matrix:
host-label: [
delphi_10_2,
delphi_12_2
]
runs-on: ${{ matrix.host-label }}
steps:
- uses: actions/checkout@v7
with:
# Use subdirectory, to not collide with castle-build-ci
# in subdirectory too.
# Usually we just put castle-build-ci in /tmp/, but this is not
# ephemeral runner.
path: app
# To write multi-line scripts in steps below,
# we have to set SHELLOPTS=igncr, otherwise Cygwin/MinGW bash
# fails because GitHub Actions create temp scripts with CRLF
# line endings.
# See https://github.com/cygwinports/bash for docs of "igncr".
- name: Make bash multi-line scripts execute OK on Windows
if: ${{ runner.os == 'Windows' }}
run: echo "SHELLOPTS=igncr" >> $GITHUB_ENV
# Use https://github.com/castle-engine/castle-build-ci to get FPC and CGE.
#
# Note that we don't execute castle-build-ci/install_dependencies ,
# this is self-hosted runner ->
# 1. no permissions for castle-build-ci/install_dependencies ,
# 2. and the dependencies should be already there.
#
# Also, because this is not ephemeral runner and workspace may
# contain leftovers from previous run, we do cleanup at start
# by "rm -Rf castle-build-ci/".
- name: Setup Castle Game Engine
run: |
rm -Rf castle-build-ci/
git clone https://github.com/castle-engine/castle-build-ci.git --depth=1 --single-branch --branch=master
castle-build-ci/setup_castle_engine
- name: Delphi Build (Win32)
run: cd app && castle-engine compile --compiler=delphi --os=win32 --cpu=i386
- name: Delphi Build Converter (Win32)
run: cd app && castle-engine compile --compiler=delphi --os=win32 --cpu=i386 --manifest-name=CastleEngineManifest.converter.xml
- name: Delphi Build (Win64)
run: cd app && castle-engine compile --compiler=delphi --os=win64 --cpu=x86_64
- name: Delphi Build Converter (Win64)
run: cd app && castle-engine compile --compiler=delphi --os=win64 --cpu=x86_64 --manifest-name=CastleEngineManifest.converter.xml
# Build using Lazarus LPI, just to test it is OK.
# We don't actually release such version -- you don't need Lazarus
# (only compiler, like FPC or Delphi) to build CGE applications.
test_lazarus:
name: Test Lazarus Compilation
strategy:
matrix:
runner: [
ubuntu-latest,
windows-latest,
macos-15-intel,
macos-latest
]
runs-on: ${{ matrix.runner }}
steps:
- uses: actions/checkout@v7
- name: Setup Castle Game Engine
run: |
cd /tmp/ # temporary directory, to be separate from the current project files
git clone https://github.com/castle-engine/castle-build-ci.git \
--depth=1 --single-branch --branch=master
castle-build-ci/install_dependencies
castle-build-ci/setup_castle_engine --install-lazarus=true
- name: Build engine packages using Lazarus
run: |
lazbuild $CASTLE_ENGINE_PATH/packages/lazarus/castle_engine_base.lpk
lazbuild $CASTLE_ENGINE_PATH/packages/lazarus/castle_engine_window.lpk
- name: Build using Lazarus
run: lazbuild castle_model_viewer.lpi
release:
name: Release
runs-on: ubuntu-latest
# Only upload release if all builds, on all runners, succeeded.
#
# Note that some things below (that don't make artifacts) are not strictly
# necessary as dependency here but we still want failure there to
# cause workflow failure, so that we have to fix it.
needs: [
build_docker,
build_runner_native,
build_arm_runner,
build_delphi,
test_lazarus
]
permissions:
contents: write
steps:
- name: Download packaged releases
uses: actions/download-artifact@v8
with:
merge-multiple: true
- name: List downloaded files
run: ls -R
- name: GH CLI status
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: gh auth status
# Releases files in the GitHub release.
- name: Release Artifacts
if: ${{ github.ref == 'refs/heads/master' }}
run: gh release --repo ${{ github.repository }} upload ${{ env.release_tag }} --clobber *.zip *.tar.gz
env:
GH_TOKEN: ${{ github.token }}
update-release-tag:
name: Update Release Tag (make release tag point to the build commit on master branch)
runs-on: ubuntu-latest
needs: [release]
permissions:
contents: write
steps:
- uses: actions/checkout@v7
- name: Update Release Tag
if: ${{ github.ref == 'refs/heads/master' }}
run: |
# --force allows to overwrite previous tag
git tag --force ${{ env.release_tag }}
# --force allows to push with overwritten tag
git push --force origin ${{ env.release_tag }}