Skip to content

Build viewer

Build viewer #97

Workflow file for this run

name: Build viewer
on:
workflow_dispatch:
inputs:
include_tracy:
description: 'Include tracy profiling builds'
required: false
default: 'false'
push:
branches:
- "Firestorm*.*.*"
- "*alpha"
- "*nightly"
- "*preview"
schedule:
- cron: '00 03 * * *' # Run every day at 3am UTC
env:
AUTOBUILD_VARIABLES_FILE: ${{github.workspace}}/build-variables/variables
EXTRA_ARGS: -DUSE_FMODSTUDIO=ON -DUSE_KDU=ON --crashreporting
build_secrets_checkout: ${{github.workspace}}/signing
XZ_DEFAULTS: -T0
FS_RELEASE_TYPE: Unknown
platform: Unknown
addrsize: 64
fallback_platform: ${platform}
FS_RELEASE_CHAN: ${FS_RELEASE_TYPE}x64
FS_GRID: "GRID FLAGS NOT SET"
PYTHON:
jobs:
build_matrix:
strategy:
matrix:
os: [macos-14,ubuntu-22.04,windows-2022]
grid: [sl,os]
variant: [regular, avx]
runs-on: ${{ matrix.os }}
outputs:
viewer_channel: ${{ steps.channel.outputs.viewer_channel }}
viewer_version: ${{ steps.version.outputs.viewer_version }}
viewer_variant: ${{ matrix.variant }}
viewer_build: ${{ steps.version.outputs.viewer_build }}
viewer_release_type: ${{ steps.version.outputs.viewer_release_type }}
steps:
- name: Install Bash 4 and GNU sed on Mac
if: runner.os == 'macOS'
run: |
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
brew update
brew install bash
brew install gnu-sed
echo "/usr/local/bin" >> $GITHUB_PATH
echo "$(brew --prefix)/opt/gnu-sed/libexec/gnubin" >> $GITHUB_PATH
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
id: py311
with:
python-version: '3.11'
- name: Set PYTHON environment for CMake
run: |
echo "PYTHON=${{ steps.py311.outputs.python-path }}" >> $GITHUB_ENV
shell: bash
- name: Install python requirements
run: |
python3 -m pip install -r requirements.txt
python -m pip install -r requirements.txt
# export the new python to the environment var $PYTHON
- name: Check python version
run: python -V
- name: Check python3 version
run: python3 -V
- name: Test python llsd
run: |
python - <<EOF
import llsd
print("Hello from inline Python script!")
EOF
shell: bash
- name: Test python3 llsd
run: |
python3 - <<EOF
import llsd
print("Hello from inline Python script!")
EOF
shell: bash
- name: Free Disk Space (Ubuntu)
if: runner.os == 'Linux'
uses: jlumbroso/free-disk-space@main
with:
swap-storage: false
# - name: Set gcc version on Linux
# if: runner.os == 'Linux'
# run: |
# echo "CC=gcc-10" >> $GITHUB_ENV
# echo "CXX=g++-10" >> $GITHUB_ENV
- name: Setup rclone and download the folder
uses: beqjanus/setup-rclone@main
with:
rclone_config: ${{ secrets.RCLONE_CONFIG }}
- name: Set OS/SL flags
run: echo "FS_GRID=-DOPENSIM:BOOL=$([ "${{ matrix.grid }}" == "os" ] && echo "ON" || echo "OFF") -DHAVOK_TPV:BOOL=$([ "${{ matrix.grid }}" == "sl" ] && echo "ON" || echo "OFF")" >> $GITHUB_ENV
shell: bash
- name: find channel from Branch name
id: channel
run: |
if [[ "${{ github.ref_name }}" == Firestorm* ]]; then
FS_RELEASE_TYPE=Release
elif [[ "${{ github.ref_name }}" == *review* ]]; then
FS_RELEASE_TYPE=Beta
elif [[ "${{ github.ref_name }}" == *alpha* ]]; then
FS_RELEASE_TYPE=Alpha
elif [[ "${{ github.ref_name }}" == *nightly* ]] || [[ "${{ github.event_name }}" == 'schedule' ]]; then
FS_RELEASE_TYPE=Nightly
elif [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
if [[ "${{ github.event.inputs.include_tracy }}" == "false" ]]; then
FS_RELEASE_TYPE=Manual
elif [[ "${{ github.event.inputs.include_tracy }}" == "true" ]]; then
FS_RELEASE_TYPE=Profiling
fi
fi
if [[ "${{ matrix.variant }}" == "avx" ]]; then
FS_RELEASE_CHAN="${FS_RELEASE_TYPE}x64"
else
FS_RELEASE_CHAN=${FS_RELEASE_TYPE}
fi
echo "FS_RELEASE_TYPE=${FS_RELEASE_TYPE}" >> $GITHUB_ENV
echo "FS_RELEASE_CHAN=${FS_RELEASE_CHAN}" >> $GITHUB_ENV
echo "Building for channel ${FS_RELEASE_CHAN}"
viewer_channel=${FS_RELEASE_CHAN}
shell: bash
- name: Get the code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Checkout build vars (after the main code)
uses: actions/checkout@v4
with:
repository: FirestormViewer/fs-build-variables
path: build-variables
- name: Define platform variable(s)
run: |
declare -A os_map
os_map=( ["Windows"]="windows" ["Linux"]="linux" ["macOS"]="darwin" )
platform="${os_map[${{ runner.os}}]}"
echo "fallback_platform=${platform}" >> $GITHUB_ENV
platform+=${addrsize}
echo "platform=${platform}" >> $GITHUB_ENV
shell: bash
- name: rclone the private 3p packages for this platform (both 64 & 32)
run: 'rclone copy fs_bundles: --filter "- Alpha/*" --filter "+ *${{ env.fallback_platform }}*bz2" .'
- name: rclone any extra private 3p packages for Alpha (allows library updates not in the main repo)
if: env.FS_RELEASE_TYPE == 'Alpha'
run: 'rclone copy fs_bundles:Alpha --include "*${{ env.fallback_platform }}*bz2" .'
- name: set VSVER for Windows builds
if: runner.os == 'Windows'
run: echo "AUTOBUILD_VSVER=170" >> $GITHUB_ENV
shell: bash
- name: Install certificate
if: runner.os == 'macOS'
env:
FS_CERT: ${{ secrets.FS_CERT }}
FS_CERT_PASS: ${{ secrets.FS_CERT_PASS }}
FS_KEYCHAIN_PASS: ${{ secrets.FS_KEYCHAIN_PASS }}
NOTARIZE_CREDS: ${{ secrets.NOTARIZE_CREDS }}
run: |
mkdir -p ${build_secrets_checkout}/code-signing-osx
echo -n "$FS_CERT" | base64 --decode --output ${build_secrets_checkout}/code-signing-osx/fs-cert.p12
echo -n "$FS_CERT_PASS" >${build_secrets_checkout}/code-signing-osx/password.txt
echo -n "$NOTARIZE_CREDS" | base64 --decode --output ${build_secrets_checkout}/code-signing-osx/notarize_creds.sh
security create-keychain -p "$FS_KEYCHAIN_PASS" ~/Library/Keychains/viewer.keychain
# notarize tool uses a specific database keychain by default we need to override this to ours.
security default-keychain -s viewer.keychain
security set-keychain-settings -lut 21600 ~/Library/Keychains/viewer.keychain
security unlock-keychain -p "$FS_KEYCHAIN_PASS" ~/Library/Keychains/viewer.keychain
security import ${build_secrets_checkout}/code-signing-osx/fs-cert.p12 -P "$FS_CERT_PASS" -A -t cert -f pkcs12 -k ~/Library/Keychains/viewer.keychain
security set-key-partition-list -S apple-tool:,apple:, -s -k "$FS_KEYCHAIN_PASS" -t private ~/Library/Keychains/viewer.keychain
security list-keychain -d user -s ~/Library/Keychains/viewer.keychain
- name: Install required Ubuntu packages and release some space.
if: runner.os == 'Linux'
run: |
dependencies=("python3-setuptools" "mesa-common-dev" "libgl1-mesa-dev" "libxinerama-dev" "libxrandr-dev" "libpulse-dev" "libglu1-mesa-dev" "libfreetype6-dev" "libfontconfig1")
sudo apt-get update
sudo apt-get install -y "${dependencies[@]}"
sudo apt-get install -y wget apt-transport-https software-properties-common
sudo apt-get autoremove --purge
sudo apt-get clean
- name: Install Microsoft repository GPG keys
if: runner.os == 'Linux'
run: |
wget -q "https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/packages-microsoft-prod.deb" -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
rm packages-microsoft-prod.deb
sudo apt-get update
sudo apt-get install -y powershell
pwsh -c '$PSVersionTable'
- name: test macOS bundles are present
if: runner.os == 'MacOS'
run: |
dirlisting="$(ls -l ${{ github.workspace }}${path_sep}${pattern})"
echo "${dirlisting}"
shell: bash
- name: edit installables
run: |
path_sep="/"
if [[ "${{ runner.os }}" == "Windows" ]]; then
path_sep="\\"
fi
function find_most_recent_bundle() {
local pattern="$1-.*$2[-_]+.*"
local most_recent_file=$(ls -t "${{ github.workspace }}" | egrep "$pattern" | head -1)
if [ -z "$most_recent_file" ]; then
echo ""
else
echo "$most_recent_file"
fi
}
packages=("fmodstudio" "llphysicsextensions_tpv" "kdu")
for package in "${packages[@]}"; do
package_file=$(find_most_recent_bundle $package ${{ env.platform }})
full_package_path="${{ github.workspace }}${path_sep}${package_file}"
if [ -n "$package_file" ]; then
echo "Installing ${package_file}"
autobuild installables remove ${package}
autobuild installables add ${package} platform=${{ env.platform }} url="file:///${full_package_path}"
else
echo "No bundle found for ${package} on ${{ env.platform }}"
package_file=$(find_most_recent_bundle $package ${{ env.fallback_platform }})
full_package_path="${{ github.workspace }}${path_sep}${package_file}"
if [ -n "$package_file" ]; then
echo "Installing ${package_file}"
autobuild installables remove ${package}
autobuild installables add ${package} platform=${{ env.fallback_platform }} url="file:///${full_package_path}"
else
echo "No bundle found for ${package} on ${{ env.fallback_platform }}. Package will not be available for build."
fi
fi
done
shell: bash
- name: Set expiration days based on FS_RELEASE_TYPE
run: |
case "${{ env.FS_RELEASE_TYPE }}" in
"Nightly" | "Manual" | "Profiling")
EXPIRE_DAYS=14
;;
"Alpha")
EXPIRE_DAYS=28
;;
"Beta")
EXPIRE_DAYS=60
;;
*)
EXPIRE_DAYS=""
;;
esac
if [ -n "$EXPIRE_DAYS" ]; then
echo "This ${{ env.FS_RELEASE_TYPE }} build will expire in $EXPIRE_DAYS"
echo "EXTRA_ARGS=${{ env.EXTRA_ARGS}} --testbuild=$EXPIRE_DAYS" >> $GITHUB_ENV
else
echo "This ${{ env.FS_RELEASE_TYPE }} has no built in expiry"
echo "EXTRA_ARGS=${{ env.EXTRA_ARGS}}" >> $GITHUB_ENV
fi
shell: bash
- name: Add tracy builds for dev use if selected (manual builds only).
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.include_tracy == 'true' }}
shell: bash
run: echo "EXTRA_ARGS=${{ env.EXTRA_ARGS }} --tracy" >> $GITHUB_ENV
- name: Add flags for AVX2 builds
if: ${{ matrix.variant == 'avx' }}
shell: bash
run: echo "EXTRA_ARGS=${{ env.EXTRA_ARGS }} --avx2" >> $GITHUB_ENV
- name: Clean up packages to give more space
run: rm *${{ env.fallback_platform }}*bz2
shell: bash
- name: Configure
run: |
autobuild configure -c ReleaseFS -A${addrsize} -- --package --chan ${{env.FS_RELEASE_CHAN}} ${{env.EXTRA_ARGS}} ${{env.FS_GRID}}
echo "BUGSPLAT_DB=$BUGSPLAT_DB" >> $GITHUB_ENV
shell: bash
- name: build
id: build
run: autobuild build -c ReleaseFS -A${addrsize} --no-configure
shell: bash
- name: Extract version number
id: version
shell: bash
run: |
if [ -r "indra/newview/VIEWER_VERSION.txt" ]
then
viewer_version="$(<"indra/newview/VIEWER_VERSION.txt")"
echo "viewer_version=$viewer_version" >> "$GITHUB_OUTPUT"
fi
viewer_build=$(git rev-list --count HEAD)
echo "viewer_build=$viewer_build" >> "$GITHUB_OUTPUT"
echo "viewer_channel=${{ env.FS_RELEASE_CHAN }}" >> "$GITHUB_OUTPUT"
echo "viewer_release_type=${{ env.FS_RELEASE_TYPE }}" >> "$GITHUB_OUTPUT"
- name: Unzip xcarchive.zip files
if: runner.os == 'macOS'
run: |
find . -name '*.xcarchive.zip' -exec sh -c 'unzip -o "{}" -d "$(dirname "{}")"' \;
- name: Post Bugsplat Symbols
uses: BugSplat-Git/symbol-upload@main
with:
clientId: ${{
steps.version.outputs.viewer_release_type == 'Release' && secrets.BUGSPLAT_RELEASE_ID ||
steps.version.outputs.viewer_release_type == 'Nightly' && secrets.BUGSPLAT_NIGHTLY_ID ||
steps.version.outputs.viewer_release_type == 'Manual' && secrets.BUGSPLAT_MANUAL_ID ||
steps.version.outputs.viewer_release_type == 'Beta' && secrets.BUGSPLAT_PREVIEW_ID ||
steps.version.outputs.viewer_release_type == 'Alpha' && secrets.BUGSPLAT_ALPHA_ID ||
secrets.BUGSPLAT_DEFAULT_ID }}
clientSecret: ${{
steps.version.outputs.viewer_release_type == 'Release' && secrets.BUGSPLAT_RELEASE_SECRET ||
steps.version.outputs.viewer_release_type == 'Nightly' && secrets.BUGSPLAT_NIGHTLY_SECRET ||
steps.version.outputs.viewer_release_type == 'Manual' && secrets.BUGSPLAT_MANUAL_SECRET ||
steps.version.outputs.viewer_release_type == 'Beta' && secrets.BUGSPLAT_PREVIEW_SECRET ||
steps.version.outputs.viewer_release_type == 'Alpha' && secrets.BUGSPLAT_ALPHA_SECRET ||
secrets.BUGSPLAT_DEFAULT_SECRET }}
database: ${{
steps.version.outputs.viewer_release_type == 'Release' && secrets.BUGSPLAT_RELEASE_DB ||
steps.version.outputs.viewer_release_type == 'Nightly' && secrets.BUGSPLAT_NIGHTLY_DB ||
steps.version.outputs.viewer_release_type == 'Manual' && secrets.BUGSPLAT_MANUAL_DB ||
steps.version.outputs.viewer_release_type == 'Beta' && secrets.BUGSPLAT_PREVIEW_DB ||
steps.version.outputs.viewer_release_type == 'Alpha' && secrets.BUGSPLAT_ALPHA_DB ||
secrets.BUGSPLAT_DEFAULT_DB }}
application: "Firestorm-${{ steps.version.outputs.viewer_channel}}"
version: ${{ steps.version.outputs.viewer_version }}.${{ steps.version.outputs.viewer_build }}
files: ${{ runner.os == 'Windows' && '**/Release/*.{pdb,exe,dll}' || runner.os == 'macOS' && '**/Release/{Firestorm,*.dSYM}' || '**/{do-not-run-directly-firestorm-bin,*.sym}' }}
directory: "build-*"
node-version: "20"
dumpSyms: false
- name: Publish artifacts
if: runner.os == 'Windows'
uses: actions/upload-artifact@v4
with:
name: ${{ env.FS_RELEASE_TYPE }}-${{ matrix.os }}-${{ matrix.variant }}-${{ matrix.grid }}-artifacts.zip
path: |
build-*/newview/Release/*Setup.exe
build-*/newview/Release/*.xz
- name: publish Linux artifacts
if: runner.os == 'Linux'
uses: actions/upload-artifact@v4
with:
name: ${{ env.FS_RELEASE_TYPE }}-${{ matrix.os }}-${{ matrix.variant }}-${{matrix.grid}}-artifacts.zip
path: |
build-linux-*/newview/*.xz
build-linux-*/newview/*.bz2
- name: publish MacOS artifacts
if: runner.os == 'macOS'
uses: actions/upload-artifact@v4
with:
name: ${{ env.FS_RELEASE_TYPE }}-${{ matrix.os }}-${{ matrix.variant }}-${{matrix.grid}}-artifacts.zip
path: |
build-darwin-*/newview/*.dmg
build-darwin-*/newview/*.bz2
deploy:
runs-on: ubuntu-latest
needs: build_matrix
env:
FS_BUILD_WEBHOOK_URL:
FS_RELEASE_FOLDER:
if: always()
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
sparse-checkout: |
fsutils/download_list.py
fsutils/build_config.json
fsutils/build_config.py
sparse-checkout-cone-mode: false
ref: ${{ github.head_ref || github.ref_name || 'master' }}
fetch-depth: 1
- name: Install discord-webhook library
run: pip install discord-webhook
- name: Download artifacts
uses: actions/download-artifact@v4
id: download
with:
path: to_deploy
- name: find channel and webhook from build_matrix outputs
run: |
viewer_release_type=${{ needs.build_matrix.outputs.viewer_release_type }}
if [[ "$viewer_release_type" == "Release" ]]; then
FS_RELEASE_FOLDER=release
FS_BUILD_WEBHOOK_URL=${{ secrets.RELEASE_WEBHOOK_URL }}
elif [[ "$viewer_release_type" == "Beta" ]]; then
FS_RELEASE_FOLDER=preview
FS_BUILD_WEBHOOK_URL=${{ secrets.BETA_WEBHOOK_URL }}
elif [[ "$viewer_release_type" == "Alpha" ]]; then
FS_RELEASE_FOLDER=test
FS_BUILD_WEBHOOK_URL=${{ secrets.BETA_WEBHOOK_URL }}
elif [[ "$viewer_release_type" == "Nightly" ]] || [[ "${{ github.event_name }}" == 'schedule' ]]; then
FS_RELEASE_FOLDER=nightly
FS_BUILD_WEBHOOK_URL=${{ secrets.NIGHTLY_WEBHOOK_URL }}
elif [[ "$viewer_release_type" == "Manual" ]]; then
FS_RELEASE_FOLDER=test
FS_BUILD_WEBHOOK_URL=${{ secrets.MANUAL_WEBHOOK_URL }}
else
FS_RELEASE_TYPE=Unknown
fi
echo "FS_RELEASE_FOLDER=${FS_RELEASE_FOLDER}" >> $GITHUB_ENV
echo "FS_BUILD_WEBHOOK_URL=${FS_BUILD_WEBHOOK_URL}" >> $GITHUB_ENV
- name: List artifacts download
run: ls -R
working-directory: ${{steps.download.outputs.download-path}}
- name: Create Build Info artifact
env:
FS_VIEWER_VERSION:
FS_VIEWER_BUILD:
FS_VIEWER_RELEASE_TYPE:
id: create_build_info
run: |
cat <<EOF > build_info.json
{
"build_run_number": "${{ github.run_number }}",
"release_type": "${{ needs.build_matrix.outputs.viewer_release_type }}",
"viewer_version": "${{ needs.build_matrix.outputs.viewer_version }}",
"viewer_build": "${{ needs.build_matrix.outputs.viewer_build }}"
}
EOF
echo "Build info created: $(cat build_info.json)"
# Upload Build Info Artifact (note that this file is expected to be identical for each matrix run, so items like OS and VARIANT cannot be in this file.)
- name: Upload Tag Info
uses: actions/upload-artifact@v4
with:
name: build_info
path: build_info.json
- name: Reorganise artifacts ready for server upload.
env:
FS_VIEWER_VERSION: ${{ needs.build_matrix.outputs.viewer_version }}
FS_VIEWER_BUILD: ${{ needs.build_matrix.outputs.viewer_build }}
FS_VIEWER_RELEASE_TYPE: ${{ needs.build_matrix.outputs.viewer_release_type }}
FS_VERSION_MGR_KEY: ${{ secrets.FS_VERSION_MGR_KEY }}
run: python ./fsutils/download_list.py ${{steps.download.outputs.download-path}} -w ${{ env.FS_BUILD_WEBHOOK_URL }}
- name: Setup rclone and download the folder
uses: beqjanus/setup-rclone@main
with:
rclone_config: ${{ secrets.RCLONE_CONFIG }}
- name: Copy files to remote host
run: rclone copy ${{steps.download.outputs.download-path}}/${{ env.FS_RELEASE_FOLDER }} fs_r2_deploy:viewerdownloads/${{ env.FS_RELEASE_FOLDER }}