Skip to content

LuxCore Samples Builder #15

LuxCore Samples Builder

LuxCore Samples Builder #15

# SPDX-FileCopyrightText: 2025 Howetuft
#
# SPDX-License-Identifier: Apache-2.0
name: LuxCore Samples Builder
on:
workflow_dispatch:
workflow_call:
inputs:
repository:
description: 'Repository to check out'
required: false
default: ''
type: string
ref:
description: 'The branch, tag or SHA to checkout.'
required: false
default: ''
type: string
version:
description: 'The version to build - must comply to semver, or blank for default'
type: string
outputs:
commit:
description: "The commit that has been checked out"
value: ${{ jobs.build-wheels.outputs.commit }}
branch:
description: "The branch that has been checked out"
value: ${{ jobs.build-wheels.outputs.branch }}
attestation-url:
description: "The url to the attestations"
value: ${{ jobs.attest-wheels.outputs.attestation-url }}
version:
description: "The version actually built"
value: ${{ jobs.build-wheels.outputs.version }}
jobs:
build-samples:
name: Build samples ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-13, macos-14]
env:
BUILD_TYPE: Release
#CXX_VERSION: 20
#GCC_VERSION: 14
#GLIBC_VERSION: 2_28
PYTHON_MINOR: ${{ matrix.python-minor }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
OWNER: ${{ github.repository_owner }}
REPO: ${{ github.event.repository.name }}
outputs:
commit: ${{ steps.current-commit.outputs.commit }}
branch: ${{ steps.current-commit.outputs.branch }}
version: ${{ steps.output-version.outputs.version }}
steps:
- name: Configure git for long paths
shell: bash
if: runner.os == 'Windows'
run: git config --system core.longpaths true
- name: Checkout main repository (standard context)
if: ${{ !env.ACT }}
uses: actions/checkout@v4
with:
repository: ${{ inputs.repository }}
ref: ${{ inputs.ref }}
- name: Checkout main repository (act context)
if: env.ACT
uses: actions/checkout@v4
- name: Get current commit
id: current-commit
run: |
echo "commit=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
echo "branch=$(git symbolic-ref HEAD)" >> $GITHUB_OUTPUT
echo "commit=$(git rev-parse HEAD)"
echo "branch=$(git symbolic-ref HEAD)"
- name: Find workspace
shell: bash
run: |
case ${{ runner.os }} in
Linux) _workspace="/project";;
Windows) _workspace=$(cygpath -u $GITHUB_WORKSPACE);;
macOS) _workspace="$GITHUB_WORKSPACE";;
*) echo "Unhandled os ${{ runner.os }}";exit 64;;
esac
echo "WORKSPACE=${_workspace}" >> $GITHUB_ENV
- name: Set Conan parameters
shell: bash
run: |
_build_type=$(echo "${{ env.BUILD_TYPE }}" | tr '[:upper:]' '[:lower:]')
_conan_home="${{ env.WORKSPACE }}/.conan2"
echo "CONAN_PRESET=conan-${_build_type}" >> $GITHUB_ENV
echo "CONAN_HOME=${_conan_home}" >> $GITHUB_ENV
- name: Configure ccache
uses: actions/github-script@v7
with:
script: |
const workspace = String.raw`${{ github.workspace }}`;
const envVariables = {
'cache-variant': String.raw`ccache`,
'CMAKE_CXX_COMPILER_LAUNCHER': String.raw`ccache`,
'CMAKE_C_COMPILER_LAUNCHER': String.raw`ccache`,
'CCACHE_CONFIGPATH': String.raw`${workspace}/ccache.conf`,
'CCACHE_DIR': String.raw`${workspace}/.ccache`,
'CCACHE_DEBUGDIR': String.raw`${workspace}/ccache-debug`,
'CCACHE_LOGFILE': String.raw`${workspace}/ccache.log`
};
for (const [key, value] of Object.entries(envVariables)) {
core.exportVariable(key, value);
}
- uses: actions/setup-python@v5
with:
python-version: 3.13
- name: Install GH CLI
uses: dev-hanz-ops/[email protected]
with:
gh-cli-version: 2.67.0
# Update apt: needed to install ccache-action
- name: Update apt (Linux)
if: runner.os == 'Linux'
shell: bash
run: |
sudo apt-get update -y
- name: ccache
uses: hendrikmuhs/[email protected]
with:
create-symlink: false
variant: ${{ env.cache-variant }}
key: samples-${{ matrix.os }}-
restore-keys: samples-${{ matrix.os }}-
max-size: 5G
verbose: 1
- name: Prepare msvc
if: runner.os == 'Windows'
uses: ilammy/msvc-dev-cmd@v1
- name: Set MacOS deployment target
if: runner.os == 'macOS'
uses: actions/github-script@v7
with:
script: |
if ('${{ runner.arch }}' == 'X64') {
target = '10.15';
arch='x86_64';
}
else if ('${{ env.PYTHON_MINOR }}' != '8') {
target = '11.0';
arch='armv8';
}
else {
target = '12.0';
arch='armv8';
}
core.exportVariable('MACOSX_DEPLOYMENT_TARGET', target);
core.exportVariable('PKG_ARCH', arch);
- name: Export version
shell: python
run: |
import json
if (input_version := "${{ inputs.release-version }}"):
result = input_version
else:
with open("luxcore.json") as in_file:
default_version = json.load(in_file)["DefaultVersion"]
result = ".".join(default_version[i] for i in ("major", "minor", "patch"))
if (prerelease := default_version["prerelease"]):
result = f"{result}-{prerelease}"
print(f"Version: {result}")
with open("SKVERSION", "w+") as out_file:
out_file.write(result)
- name: Output version
id: output-version
shell: bash
run: |
_version=$(cat SKVERSION)
echo "version=${_version}" >> "$GITHUB_OUTPUT"
- name: Build (Windows)
if: runner.os == 'Windows'
shell: cmd
env:
CONAN_HOME: ${{ github.workspace }}\.conan2
run: |
pip install conan && make deps && make && make package
- name: Build (MacOS)
if: runner.os == 'macOS'
shell: bash
run: |
/Users/runner/hostedtoolcache/gh-cli/2.67.0/x64/bin/gh --version
pip install conan
make deps
make luxcoreui
make luxcoreconsole
make package
# Build for Linux is containerized in manylinux_2_28_x86_64
- name: Build (Linux)
if: runner.os == 'Linux'
shell: bash
env:
# COMMAND contains code that'll be executed in container
COMMAND: |
# Set Python
manylinux-interpreters ensure cp313-cp313
PATH=/opt/python/cp313-cp313/bin:$PATH
which python
python -m pip install conan
# Install toolchain (gcc, ccache...)
#dnf install -y epel-release
#dnf install -y almalinux-release-devel
#dnf install -y perl-IPC-Cmd perl-Digest-SHA
CC=/opt/rh/gcc-toolset-14/root/usr/bin/gcc
CXX=/opt/rh/gcc-toolset-14/root/usr/bin/g++
export CMAKE_C_COMPILER_LAUNCHER=ccache
export CMAKE_CXX_COMPILER_LAUNCHER=ccache
export VERBOSE=1
#export CLICOLOR_FORCE=1
# Install conda
dnf install -y wget
mkdir -p miniconda3
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh \
-O miniconda3/miniconda.sh
bash miniconda3/miniconda.sh -b -u -p miniconda3
rm miniconda3/miniconda.sh
source miniconda3/bin/activate
conda init --all
# Install gh
conda install conda-forge::gh --channel conda-forge -y
echo ${{ secrets.GITHUB_TOKEN }} | gh auth login --with-token
# Install ccache
conda install conda-forge::ccache -y
export CCACHE_CONFIGPATH=/project/ccache.conf
ccache -o cache_dir=/project/.ccache
ccache -o depend_mode=false
echo "ccache configuration:"
ccache -p
# Build
make deps
make luxcoreui
make luxcoreconsole
make package
# Re-inspect ccache
echo "ccache results:"
ccache -sv
# run contains code that'll be executed on host side
run: |
# Clean (remove container if it exists)
CONTAINER=manylinux
CONTAINER_LIST=$(docker container ps -a)
if [[ ${CONTAINER_LIST} == *${CONTAINER}* ]]; then
echo "Removing existing container '${CONTAINER}'"
docker rm --force ${CONTAINER}
fi
# Start
echo ""
echo "******** LAUCHING MANYLINUX CONTAINER ********"
echo ""
docker create \
-t \
--name ${CONTAINER} \
quay.io/pypa/manylinux_2_28_x86_64
docker start ${CONTAINER}
docker exec ${CONTAINER} env
# Copy source tree
docker exec ${CONTAINER} sh -c "echo Copying source tree"
docker cp ${{ github.workspace }} ${CONTAINER}:/project
# Copy ccache
echo "Copying ${{ env.CCACHE_DIR }} to container"
docker cp ${{ env.CCACHE_DIR }}/. ${CONTAINER}:/root/.ccache
# Execute COMMAND in container
docker exec --workdir=/project ${CONTAINER} sh -c '${{ env.COMMAND }}'
# Copy ccache back
docker cp ${CONTAINER}:/root/.ccache/. ${{ env.CCACHE_DIR }}
# Get artifact
mkdir -p ${{ github.workspace }}/out/build
docker cp ${CONTAINER}:/project/out ${{ github.workspace }}
# Stop container
docker stop ${CONTAINER}
#- name: Setup tmate session (debug)
#if: ${{ failure() }}
#uses: mxschmitt/action-tmate@v3
# Upload artifacts
- uses: actions/upload-artifact@v4
id: upload
with:
name: LuxCore-${{ runner.os }}
path: ${{ github.workspace }}/out/build/LuxCore-*.zip
attest-samples:
needs: [build-samples]
runs-on: ubuntu-latest
permissions:
attestations: write
id-token: write
outputs:
attestation-url: ${{ steps.attestation-step.outputs.attestation-url }}
steps:
- uses: actions/download-artifact@v4
if: ${{ !env.ACT }}
with:
pattern: LuxCore-*
path: ${{ github.workspace }}/dist
merge-multiple: false
- name: Generate artifact attestations
id: attestation-step
if: ${{ !env.ACT }}
uses: actions/attest-build-provenance@v2
with:
subject-path: ${{ github.workspace }}/dist/*