summaryrefslogtreecommitdiff
path: root/.github/workflows
diff options
context:
space:
mode:
Diffstat (limited to '.github/workflows')
-rw-r--r--.github/workflows/build-macos.yml123
-rw-r--r--.github/workflows/build-windows.yml225
-rw-r--r--.github/workflows/build.yaml469
-rw-r--r--.github/workflows/cla.yaml26
-rw-r--r--.github/workflows/label.yaml15
-rw-r--r--.github/workflows/pre-commit.yaml18
-rw-r--r--.github/workflows/qatest.yaml174
-rw-r--r--.github/workflows/stale.yaml25
-rw-r--r--.github/workflows/tag-release.yaml52
9 files changed, 348 insertions, 779 deletions
diff --git a/.github/workflows/build-macos.yml b/.github/workflows/build-macos.yml
new file mode 100644
index 0000000000..d1efde8ce9
--- /dev/null
+++ b/.github/workflows/build-macos.yml
@@ -0,0 +1,123 @@
+name: macOS Build
+
+on:
+ pull_request:
+ branches: [ main ]
+ push:
+ tags:
+ - 'test/*'
+ - 'build/*'
+ - 'v*'
+ workflow_dispatch:
+
+permissions:
+ contents: write
+
+jobs:
+ build-macos:
+ name: macOS (arm64)
+ runs-on: macos-15
+
+ steps:
+ - name: Checkout source
+ uses: actions/checkout@v5
+
+ - name: Set up MacPorts (installs cached deps from parameter file)
+ uses: melusina-org/setup-macports@v1
+ with:
+ parameters: .github/parameters/setup-macports.yaml
+
+ - name: Dump MacPorts logs on failure
+ if: failure()
+ shell: bash
+ run: |
+ echo "=== searching for MacPorts main.log files ==="
+ LOGDIR="/opt/local/var/macports/logs"
+ find "$LOGDIR" -name "main.log" 2>/dev/null | while read -r log; do
+ echo ""
+ echo "######################################################"
+ echo "### $log"
+ echo "######################################################"
+ tail -n 80 "$log"
+ done
+
+ - name: Configure
+ shell: bash
+ run: |
+ SDKPATH="$(xcrun --show-sdk-path)"
+ export LL_BUILD="-O3 -gdwarf-2 -stdlib=libc++ -mmacosx-version-min=12 -iwithsysroot $SDKPATH -std=c++20 -fPIC -DLL_RELEASE=1 -DLL_RELEASE_FOR_DOWNLOAD=1 -DNDEBUG -DPIC -DLL_DARWIN=1"
+
+ mkdir build-macos && cd build-macos
+ cmake \
+ -DCMAKE_BUILD_TYPE:STRING=Release \
+ -DADDRESS_SIZE:STRING=64 \
+ -DUSE_OPENAL:BOOL=ON \
+ -DUSE_FMODSTUDIO:BOOL=OFF \
+ -DENABLE_MEDIA_PLUGINS:BOOL=ON \
+ -DLL_TESTS:BOOL=OFF \
+ -DNDOF:BOOL=OFF \
+ -DROOT_PROJECT_NAME:STRING=Megapahit \
+ -DVIEWER_CHANNEL:STRING=Megapahit \
+ -DVIEWER_BINARY_NAME:STRING=megapahit \
+ -DBUILD_SHARED_LIBS:BOOL=OFF \
+ -DINSTALL:BOOL=ON \
+ -DPACKAGE:BOOL=OFF \
+ -DCMAKE_INSTALL_PREFIX:PATH=newview/Megapahit.app/Contents/Resources \
+ -DCMAKE_OSX_ARCHITECTURES:STRING=$(uname -m) \
+ -DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=12 \
+ -DENABLE_SIGNING:BOOL=ON \
+ -DSIGNING_IDENTITY:STRING=- \
+ ../indra
+
+ - name: Build
+ shell: bash
+ run: |
+ cd build-macos
+ make -j$(sysctl -n hw.ncpu)
+
+ - name: Install into app bundle
+ shell: bash
+ run: |
+ cd build-macos
+ make install
+
+ - name: Read version
+ id: version
+ shell: bash
+ run: echo "version=$(cat indra/newview/viewer_version.txt)" >> "$GITHUB_OUTPUT"
+
+ - name: Package .app into a .zip
+ shell: bash
+ run: |
+ cd build-macos/newview
+ ditto -c -k --keepParent "Megapahit.app" \
+ "Megapahit-${{ steps.version.outputs.version }}-macos-$(uname -m).zip"
+
+ - name: Verify signature survived packaging
+ shell: bash
+ run: |
+ cd build-macos/newview
+ mkdir -p verify-tmp
+ ditto -x -k Megapahit-*-macos-*.zip verify-tmp/
+ codesign --verify --deep --strict --verbose=2 verify-tmp/Megapahit.app || {
+ echo "Signature verification FAILED"
+ rm -rf verify-tmp
+ exit 1
+ }
+ rm -rf verify-tmp
+ echo "Signature verified intact."
+
+ - name: Upload app artifact
+ uses: actions/upload-artifact@v6
+ with:
+ name: megapahit-macos-${{ steps.version.outputs.version }}
+ path: build-macos/newview/Megapahit-*-macos-*.zip
+ if-no-files-found: error
+
+ - name: Upload to release
+ if: startsWith(github.ref, 'refs/tags/')
+ uses: softprops/action-gh-release@v3
+ with:
+ name: ${{ github.ref_name }}
+ files: build-macos/newview/Megapahit-*-macos-*.zip
+ prerelease: ${{ startsWith(github.ref_name, 'test/') || startsWith(github.ref_name, 'build/') }}
diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml
new file mode 100644
index 0000000000..8be2d33802
--- /dev/null
+++ b/.github/workflows/build-windows.yml
@@ -0,0 +1,225 @@
+name: Windows Build
+
+on:
+ pull_request:
+ branches: [ main ]
+ push:
+ tags:
+ - 'test/*'
+ - 'build/*'
+ - 'v*'
+ workflow_dispatch:
+
+permissions:
+ contents: write
+
+jobs:
+ build-windows-x64:
+ name: Windows x64
+ runs-on: windows-2025-vs2026
+
+ steps:
+ - name: Set VCPKG_ROOT
+ shell: bash
+ run: echo "VCPKG_ROOT=$VCPKG_INSTALLATION_ROOT" >> "$GITHUB_ENV"
+
+ - name: Add MSBuild to PATH
+ uses: microsoft/setup-msbuild@v3
+
+ - name: Checkout source
+ uses: actions/checkout@v5
+
+ - name: Install vcpkg dependencies (x64)
+ shell: bash
+ run: |
+ vcpkg install \
+ python3:x64-windows \
+ freealut:x64-windows \
+ apr-util:x64-windows \
+ boost:x64-windows \
+ freetype:x64-windows \
+ glm:x64-windows \
+ hunspell:x64-windows \
+ libjpeg-turbo:x64-windows \
+ meshoptimizer:x64-windows \
+ minizip:x64-windows \
+ nanosvg:x64-windows \
+ nghttp2:x64-windows \
+ openjpeg:x64-windows \
+ libvorbis:x64-windows \
+ "libxml2[tools]:x64-windows" \
+ xxhash:x64-windows
+
+ - name: Configure (x64)
+ shell: bash
+ env:
+ LL_BUILD: "/MD /O2 /Ob2 /std:c++20 /Zc:wchar_t- /Zi /GR /DLL_RELEASE=1 /DLL_RELEASE_FOR_DOWNLOAD=1 /DNDEBUG /D_SECURE_STL=0 /D_HAS_ITERATOR_DEBUGGING=0 /DWIN32 /D_WINDOWS /DLL_WINDOWS=1 /DUNICODE /D_UNICODE /DWINVER=0x0602 /D_WIN32_WINNT=0x0602"
+ run: |
+ export PYTHON="$VCPKG_ROOT/installed/x64-windows/tools/python3/python.exe"
+ CMAKE_BIN=$(find "$VCPKG_ROOT/downloads/tools" -name "cmake.exe" -path "*/x86_64/*" | head -1)
+ if [ -z "$CMAKE_BIN" ]; then
+ CMAKE_BIN=cmake
+ fi
+ mkdir build-windows-x86_64
+ cd build-windows-x86_64
+ "$CMAKE_BIN" \
+ -DCMAKE_BUILD_TYPE:STRING=Release \
+ -DADDRESS_SIZE:STRING=64 \
+ -DUSE_OPENAL:BOOL=ON \
+ -DUSE_FMODSTUDIO:BOOL=OFF \
+ -DENABLE_MEDIA_PLUGINS:BOOL=ON \
+ -DLL_TESTS:BOOL=OFF \
+ -DNDOF:BOOL=OFF \
+ -DROOT_PROJECT_NAME:STRING=Megapahit \
+ -DVIEWER_CHANNEL:STRING=Megapahit \
+ -DVIEWER_BINARY_NAME:STRING=Megapahit \
+ -DBUILD_SHARED_LIBS:BOOL=OFF \
+ -DINSTALL:BOOL=ON \
+ -DPACKAGE:BOOL=ON \
+ "-DCMAKE_TOOLCHAIN_FILE:FILEPATH=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" \
+ -DVS_DISABLE_FATAL_WARNINGS:BOOL=ON \
+ ../indra
+
+ - name: Build (x64)
+ shell: bash
+ run: |
+ cd build-windows-x86_64
+ MSBuild.exe Megapahit.slnx -p:Configuration=Release -m
+
+ - name: Install NSIS (x64)
+ shell: pwsh
+ run: |
+ choco install nsis --no-progress -y
+ "C:\Program Files (x86)\NSIS" | Out-File -FilePath $env:GITHUB_PATH -Append
+
+ - name: Package (x64)
+ shell: bash
+ run: |
+ cd build-windows-x86_64
+ cpack -G NSIS
+
+ - name: Read version
+ id: version
+ shell: bash
+ run: echo "version=$(cat indra/newview/viewer_version.txt)" >> "$GITHUB_OUTPUT"
+
+ - name: Upload installer artifact (x64)
+ uses: actions/upload-artifact@v6
+ with:
+ name: megapahit-windows-x64-${{ steps.version.outputs.version }}
+ path: build-windows-x86_64/Megapahit-*-win64.exe
+ if-no-files-found: error
+
+ - name: Upload to release (x64)
+ if: startsWith(github.ref, 'refs/tags/')
+ uses: softprops/action-gh-release@v3
+ with:
+ name: ${{ github.ref_name }}
+ files: build-windows-x86_64/Megapahit-*-win64.exe
+ prerelease: ${{ startsWith(github.ref_name, 'test/') || startsWith(github.ref_name, 'build/') }}
+
+ build-windows-arm64:
+ name: Windows arm64
+ if: false
+ runs-on: windows-2022
+
+ steps:
+ - name: Set VCPKG_ROOT
+ shell: bash
+ run: echo "VCPKG_ROOT=$VCPKG_INSTALLATION_ROOT" >> "$GITHUB_ENV"
+
+ - name: Add MSBuild to PATH
+ uses: microsoft/setup-msbuild@v3
+
+ - name: Checkout source
+ uses: actions/checkout@v5
+
+ - name: Install vcpkg dependencies (arm64)
+ shell: bash
+ run: |
+ vcpkg install \
+ python3:arm64-windows \
+ freealut:arm64-windows \
+ apr-util:arm64-windows \
+ boost:arm64-windows \
+ curl:arm64-windows \
+ freetype:arm64-windows \
+ glm:arm64-windows \
+ hunspell:arm64-windows \
+ libjpeg-turbo:arm64-windows \
+ meshoptimizer:arm64-windows \
+ minizip:arm64-windows \
+ nanosvg:arm64-windows \
+ nghttp2:arm64-windows \
+ openjpeg:arm64-windows \
+ sse2neon:arm64-windows \
+ libvorbis:arm64-windows \
+ "libxml2[tools]:arm64-windows" \
+ xxhash:arm64-windows
+ vcpkg install boost-fiber:arm64-windows --allow-unsupported || true
+
+ - name: Configure (arm64)
+ shell: bash
+ env:
+ LL_BUILD: "/MD /O2 /Ob2 /std:c++20 /Zc:wchar_t- /Zi /GR /DLL_RELEASE=1 /DLL_RELEASE_FOR_DOWNLOAD=1 /DNDEBUG /D_SECURE_STL=0 /D_HAS_ITERATOR_DEBUGGING=0 /DWIN32 /D_WINDOWS /DLL_WINDOWS=1 /DUNICODE /D_UNICODE /DWINVER=0x0602 /D_WIN32_WINNT=0x0602 /Zc:preprocessor"
+ run: |
+ export PYTHON="$VCPKG_ROOT/installed/arm64-windows/tools/python3/python.exe"
+ CMAKE_BIN=$(find "$VCPKG_ROOT/downloads/tools" -name "cmake.exe" -path "*/arm64/*" | head -1)
+ if [ -z "$CMAKE_BIN" ]; then
+ CMAKE_BIN=$(find "$VCPKG_ROOT/downloads/tools" -name "cmake.exe" | head -1)
+ fi
+ if [ -z "$CMAKE_BIN" ]; then
+ CMAKE_BIN=cmake
+ fi
+ mkdir build-windows-aarch64
+ cd build-windows-aarch64
+ "$CMAKE_BIN" \
+ -DCMAKE_BUILD_TYPE:STRING=Release \
+ -DADDRESS_SIZE:STRING=64 \
+ -DUSE_OPENAL:BOOL=ON \
+ -DUSE_FMODSTUDIO:BOOL=OFF \
+ -DENABLE_MEDIA_PLUGINS:BOOL=OFF \
+ -DLL_TESTS:BOOL=OFF \
+ -DNDOF:BOOL=OFF \
+ -DROOT_PROJECT_NAME:STRING=Megapahit \
+ -DVIEWER_CHANNEL:STRING=Megapahit \
+ -DVIEWER_BINARY_NAME:STRING=Megapahit \
+ -DBUILD_SHARED_LIBS:BOOL=OFF \
+ -DINSTALL:BOOL=ON \
+ -DPACKAGE:BOOL=ON \
+ "-DCMAKE_TOOLCHAIN_FILE:FILEPATH=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" \
+ -DVCPKG_TARGET_TRIPLET:STRING=arm64-windows \
+ -DVS_DISABLE_FATAL_WARNINGS:BOOL=ON \
+ ../indra
+
+ - name: Build (arm64)
+ shell: bash
+ run: |
+ cd build-windows-aarch64
+ MSBuild.exe Megapahit.slnx -p:Configuration=Release -m
+
+ - name: Package (arm64)
+ shell: bash
+ run: |
+ cd build-windows-aarch64
+ cpack -G NSIS
+
+ - name: Read version
+ id: version
+ shell: bash
+ run: echo "version=$(cat indra/newview/viewer_version.txt)" >> "$GITHUB_OUTPUT"
+
+ - name: Upload installer artifact (arm64)
+ uses: actions/upload-artifact@v6
+ with:
+ name: megapahit-windows-arm64-${{ steps.version.outputs.version }}
+ path: build-windows-aarch64/Megapahit-*-win64.exe
+ if-no-files-found: error
+
+ - name: Upload to release (arm64)
+ if: startsWith(github.ref, 'refs/tags/')
+ uses: softprops/action-gh-release@v3
+ with:
+ name: ${{ github.ref_name }}
+ files: build-windows-aarch64/Megapahit-*-win64.exe
+ prerelease: ${{ startsWith(github.ref_name, 'test/') || startsWith(github.ref_name, 'build/') }}
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
deleted file mode 100644
index 50b0cf02bc..0000000000
--- a/.github/workflows/build.yaml
+++ /dev/null
@@ -1,469 +0,0 @@
-name: Build
-
-on:
- pull_request:
- push:
- branches: ["main", "release/*", "project/*"]
- tags: ["Second_Life*"]
-
-jobs:
- # The whole point of the setup job is that we want to set variables once
- # that will be consumed by multiple subsequent jobs.
- setup:
- runs-on: ubuntu-latest
- outputs:
- release_run: ${{ steps.setvar.outputs.release_run }}
- configurations: ${{ steps.setvar.outputs.configurations }}
- bugsplat_db: ${{ steps.setvar.outputs.bugsplat_db }}
- env:
- # Build with a tag like "Second_Life#abcdef0" to generate a release page
- # (used for builds we are planning to deploy).
- # When you want to use a string variable as a workflow YAML boolean, it's
- # important to ensure it's the empty string when false. If you omit || '',
- # its value when false is "false", which is interpreted as true.
- RELEASE_RUN: ${{ (github.event.inputs.release_run || github.ref_type == 'tag' && startsWith(github.ref_name, 'Second_Life')) && 'Y' || '' }}
- FROM_FORK: ${{ github.event.pull_request.head.repo.fork }}
- steps:
- - name: Set Variables
- id: setvar
- shell: bash
- run: |
- echo "release_run=$RELEASE_RUN" >> "$GITHUB_OUTPUT"
-
- if [[ "$FROM_FORK" == "true" ]]; then
- # PR from fork; don't build with Bugsplat, proprietary libs
- echo 'configurations=["ReleaseOS"]' >> $GITHUB_OUTPUT
- echo "bugsplat_db=" >> $GITHUB_OUTPUT
- else
- echo 'configurations=["Release"]' >> $GITHUB_OUTPUT
- echo "bugsplat_db=SecondLife_Viewer_2018" >> $GITHUB_OUTPUT
- fi
- build:
- needs: setup
- strategy:
- matrix:
- runner: ${{ fromJson((github.ref_type == 'tag' && startsWith(github.ref, 'refs/tags/Second_Life')) && '["windows-large","macos-15-xlarge"]' || '["windows-latest","macos-15"]') }}
- configuration: ${{ fromJson(needs.setup.outputs.configurations) }}
- runs-on: ${{ matrix.runner }}
- outputs:
- viewer_channel: ${{ steps.build.outputs.viewer_channel }}
- viewer_version: ${{ steps.build.outputs.viewer_version }}
- viewer_branch: ${{ steps.which-branch.outputs.branch }}
- relnotes: ${{ steps.which-branch.outputs.relnotes }}
- imagename: ${{ steps.build.outputs.imagename }}
- configuration: ${{ matrix.configuration }}
- env:
- AUTOBUILD_ADDRSIZE: 64
- AUTOBUILD_BUILD_ID: ${{ github.run_id }}
- AUTOBUILD_CONFIGURATION: ${{ matrix.configuration }}
- # authorizes fetching private constituent packages
- AUTOBUILD_GITHUB_TOKEN: ${{ secrets.SHARED_AUTOBUILD_GITHUB_TOKEN }}
- AUTOBUILD_INSTALLABLE_CACHE: ${{ github.workspace }}/.autobuild-installables
- AUTOBUILD_VARIABLES_FILE: ${{ github.workspace }}/.build-variables/variables
- # Direct autobuild to store vcs_url, vcs_branch and vcs_revision in
- # autobuild-package.xml.
- AUTOBUILD_VCS_INFO: "true"
- AUTOBUILD_VSVER: "170"
- DEVELOPER_DIR: "/Applications/Xcode_16.1.app/Contents/Developer"
- # Ensure that Linden viewer builds engage Bugsplat.
- BUGSPLAT_DB: ${{ needs.setup.outputs.bugsplat_db }}
- build_coverity: false
- build_log_dir: ${{ github.workspace }}/.logs
- build_viewer: true
- BUILDSCRIPTS_SHARED: ${{ github.workspace }}/.shared
- # extracted and committed to viewer repo
- BUILDSCRIPTS_SUPPORT_FUNCTIONS: ${{ github.workspace }}/buildscripts_support_functions
- GIT_REF: ${{ github.head_ref || github.ref }}
- LL_SKIP_REQUIRE_SYSROOT: 1
- # Setting this variable directs Linden's TUT test driver code to capture
- # test-program log output at the specified level, but to display it only if
- # the individual test fails.
- LOGFAIL: DEBUG
- master_message_template_checkout: ${{ github.workspace }}/.master-message-template
- # Only set variants to the one configuration: don't let build.sh loop
- # over variants, let GitHub distribute variants over multiple hosts.
- variants: ${{ matrix.configuration }}
- steps:
- - name: Checkout code
- uses: actions/checkout@v4
- with:
- ref: ${{ github.event.pull_request.head.sha || github.sha }}
-
- - name: Setup python
- uses: actions/setup-python@v5
- with:
- python-version: "3.11"
-
- - name: Checkout build variables
- uses: actions/checkout@v4
- with:
- repository: secondlife/build-variables
- ref: master
- path: .build-variables
-
- - name: Checkout master-message-template
- uses: actions/checkout@v4
- with:
- repository: secondlife/master-message-template
- path: .master-message-template
-
- - name: Install autobuild and python dependencies
- run: pip3 install autobuild llsd
-
- - name: Cache autobuild packages
- id: cache-installables
- uses: actions/cache@v4
- with:
- path: .autobuild-installables
- key: ${{ runner.os }}-64-${{ matrix.configuration }}-${{ hashFiles('autobuild.xml') }}
- restore-keys: |
- ${{ runner.os }}-64-${{ matrix.configuration }}-
- ${{ runner.os }}-64-
-
- - name: Determine source branch
- id: which-branch
- uses: secondlife/viewer-build-util/which-branch@v2
- with:
- token: ${{ github.token }}
-
- - name: Build
- id: build
- shell: bash
- env:
- AUTOBUILD_VCS_BRANCH: ${{ steps.which-branch.outputs.branch }}
- RUNNER_OS: ${{ runner.os }}
- run: |
- # set up things the viewer's build.sh script expects
- set -x
- mkdir -p "$build_log_dir"
- mkdir -p "$BUILDSCRIPTS_SHARED/packages/lib/python"
- source "$BUILDSCRIPTS_SUPPORT_FUNCTIONS"
- if [[ "$OSTYPE" =~ cygwin|msys ]]
- then
- native_path() { cygpath --windows "$1"; }
- shell_path() { cygpath --unix "$1"; }
- else
- native_path() { echo "$1"; }
- shell_path() { echo "$1"; }
- fi
- finalize()
- {
- case "$1" in
- true|0)
- record_success "Build Succeeded"
- ;;
- *)
- record_failure "Build Failed with $1"
- ;;
- esac
- }
- initialize_build()
- {
- echo "initialize_build"
- }
- initialize_version()
- {
- export revision="$AUTOBUILD_BUILD_ID"
- }
- python_cmd()
- {
- if [[ "x${1:0:1}" == "x-" ]] # -m, -c, etc.
- then # if $1 is a switch, don't try to twiddle paths
- "$(shell_path "$PYTHON_COMMAND")" "$@"
- elif [[ "$(basename "$1")" == "codeticket.py" ]]
- then # ignore any attempt to contact codeticket
- echo "## $@"
- else # running a script at an explicit path: fix path for Python
- local script="$1"
- shift
- "$(shell_path "$PYTHON_COMMAND")" "$(native_path "$script")" "$@"
- fi
- }
- repo_branch()
- {
- echo "$AUTOBUILD_VCS_BRANCH"
- }
- record_dependencies_graph()
- {
- echo "TODO: generate and post dependency graph"
- }
- # Since we're not uploading to codeticket, DO NOT sleep for minutes.
- sleep()
- {
- echo "Not sleeping for $1 seconds"
- }
- export -f native_path shell_path finalize initialize_build initialize_version
- export -f python_cmd repo_branch record_dependencies_graph sleep
- ## Useful for diagnosing Windows LLProcess/LLLeap test failures
- ##export APR_LOG="${RUNNER_TEMP}/apr.log"
- export arch=$(uname | cut -b-6)
- # Surprise! GH Windows runner's MINGW6 is a $arch value we've never
- # seen before, so numerous tests don't know about it.
- [[ "$arch" == "MINGW6" ]] && arch=CYGWIN
- export AUTOBUILD="$(which autobuild)"
-
- # determine the viewer channel from the branch or tag name
- # trigger an EDU build by including "edu" in the tag
- edu=${{ github.ref_type == 'tag' && contains(github.ref_name, 'edu') }}
- echo "ref_type=${{ github.ref_type }}, ref_name=${{ github.ref_name }}, edu='$edu'"
- branch=$AUTOBUILD_VCS_BRANCH
- if [[ "$edu" == "true" ]]
- then
- export viewer_channel="Second Life Release edu"
- elif [[ "$branch" == "develop" ]];
- then
- export viewer_channel="Second Life Develop"
- else
- IFS='/' read -ra ba <<< "$branch"
- prefix=${ba[0]}
- if [ "$prefix" == "project" ]; then
- IFS='_' read -ra prj <<< "${ba[1]}"
- # uppercase first letter of each word
- export viewer_channel="Second Life Project ${prj[*]^}"
- elif [[ "$prefix" == "release" || "$prefix" == "main" ]];
- then
- export viewer_channel="Second Life Release"
- else
- export viewer_channel="Second Life Test"
- fi
- fi
- echo "viewer_channel=$viewer_channel"
- echo "viewer_channel=$viewer_channel" >> "$GITHUB_OUTPUT"
- # On windows we need to point the build to the correct python
- # as neither CMake's FindPython nor our custom Python.cmake module
- # will resolve the correct interpreter location.
- if [[ "$RUNNER_OS" == "Windows" ]]; then
- export PYTHON="$(native_path "$(which python)")"
- echo "Python location: $PYTHON"
- export PYTHON_COMMAND="$PYTHON"
- else
- export PYTHON_COMMAND="python3"
- fi
- export PYTHON_COMMAND_NATIVE="$(native_path "$PYTHON_COMMAND")"
-
- ./build.sh
-
- # Each artifact is downloaded as a distinct .zip file. Multiple jobs
- # (per the matrix above) writing the same filepath to the same
- # artifact name will *overwrite* that file. Moreover, they can
- # interfere with each other, causing the upload to fail.
- # https://github.com/actions/upload-artifact#uploading-to-the-same-artifact
- # Given the size of our installers, and the fact that we typically
- # only want to download just one instead of a single zip containing
- # several, generate a distinct artifact name for each installer.
- # If the matrix above can run multiple builds on the same
- # platform, we must disambiguate on more than the platform name.
- # e.g. if we were still running Windows 32-bit builds, we'd need to
- # qualify the artifact with bit width.
- if [[ "$AUTOBUILD_CONFIGURATION" == "ReleaseOS" ]]
- then cfg_suffix='OS'
- else cfg_suffix=''
- fi
- echo "artifact=$RUNNER_OS$cfg_suffix" >> $GITHUB_OUTPUT
-
- - name: Upload executable
- if: steps.build.outputs.viewer_app
- uses: actions/upload-artifact@v4
- with:
- name: "${{ steps.build.outputs.artifact }}-app"
- path: |
- ${{ steps.build.outputs.viewer_app }}
-
- # The other upload of nontrivial size is the symbol file. Use a distinct
- # artifact for that too.
- - name: Upload symbol file
- if: steps.build.outputs.symbolfile
- uses: actions/upload-artifact@v4
- with:
- name: "${{ steps.build.outputs.artifact }}-symbols"
- path: ${{ steps.build.outputs.symbolfile }}
-
- - name: Upload metadata
- uses: actions/upload-artifact@v4
- with:
- name: "${{ steps.build.outputs.artifact }}-metadata"
- # emitted by build.sh, possibly multiple lines
- path: |
- ${{ steps.build.outputs.metadata }}
-
- - name: Upload physics package
- uses: actions/upload-artifact@v4
- # should only be set for viewer-private
- if: matrix.configuration == 'Release' && steps.build.outputs.physicstpv
- with:
- name: "${{ steps.build.outputs.artifact }}-physics"
- # emitted by build.sh, zero or one lines
- path: |
- ${{ steps.build.outputs.physicstpv }}
-
- sign-and-package-windows:
- env:
- AZURE_KEY_VAULT_URI: ${{ secrets.AZURE_KEY_VAULT_URI }}
- AZURE_CERT_NAME: ${{ secrets.AZURE_CERT_NAME }}
- AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
- AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }}
- AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
- needs: build
- runs-on: windows-large
- steps:
- - name: Sign and package Windows viewer
- if: env.AZURE_KEY_VAULT_URI && env.AZURE_CERT_NAME && env.AZURE_CLIENT_ID && env.AZURE_CLIENT_SECRET && env.AZURE_TENANT_ID
- uses: secondlife/viewer-build-util/sign-pkg-windows@v2
- with:
- vault_uri: "${{ env.AZURE_KEY_VAULT_URI }}"
- cert_name: "${{ env.AZURE_CERT_NAME }}"
- client_id: "${{ env.AZURE_CLIENT_ID }}"
- client_secret: "${{ env.AZURE_CLIENT_SECRET }}"
- tenant_id: "${{ env.AZURE_TENANT_ID }}"
-
- sign-and-package-mac:
- env:
- NOTARIZE_CREDS_MACOS: ${{ secrets.NOTARIZE_CREDS_MACOS }}
- SIGNING_CERT_MACOS: ${{ secrets.SIGNING_CERT_MACOS }}
- SIGNING_CERT_MACOS_IDENTITY: ${{ secrets.SIGNING_CERT_MACOS_IDENTITY }}
- SIGNING_CERT_MACOS_PASSWORD: ${{ secrets.SIGNING_CERT_MACOS_PASSWORD }}
- needs: build
- runs-on: macos-latest
- steps:
- - name: Unpack Mac notarization credentials
- if: env.NOTARIZE_CREDS_MACOS
- id: note-creds
- shell: bash
- run: |
- # In NOTARIZE_CREDS_MACOS we expect to find:
- # USERNAME="..."
- # PASSWORD="..."
- # TEAM_ID="..."
- eval "${{ env.NOTARIZE_CREDS_MACOS }}"
- echo "::add-mask::$USERNAME"
- echo "::add-mask::$PASSWORD"
- echo "::add-mask::$TEAM_ID"
- echo "note_user=$USERNAME" >> "$GITHUB_OUTPUT"
- echo "note_pass=$PASSWORD" >> "$GITHUB_OUTPUT"
- echo "note_team=$TEAM_ID" >> "$GITHUB_OUTPUT"
- # If we didn't manage to retrieve all of these credentials, better
- # find out sooner than later.
- [[ -n "$USERNAME" && -n "$PASSWORD" && -n "$TEAM_ID" ]]
-
- - name: Sign and package Mac viewer
- if: env.SIGNING_CERT_MACOS && env.SIGNING_CERT_MACOS_IDENTITY && env.SIGNING_CERT_MACOS_PASSWORD && steps.note-creds.outputs.note_user && steps.note-creds.outputs.note_pass && steps.note-creds.outputs.note_team
- uses: secondlife/viewer-build-util/sign-pkg-mac@v2
- with:
- channel: ${{ needs.build.outputs.viewer_channel }}
- imagename: ${{ needs.build.outputs.imagename }}
- cert_base64: ${{ env.SIGNING_CERT_MACOS }}
- cert_name: ${{ env.SIGNING_CERT_MACOS_IDENTITY }}
- cert_pass: ${{ env.SIGNING_CERT_MACOS_PASSWORD }}
- note_user: ${{ steps.note-creds.outputs.note_user }}
- note_pass: ${{ steps.note-creds.outputs.note_pass }}
- note_team: ${{ steps.note-creds.outputs.note_team }}
-
- post-windows-symbols:
- env:
- BUGSPLAT_USER: ${{ secrets.BUGSPLAT_USER }}
- BUGSPLAT_PASS: ${{ secrets.BUGSPLAT_PASS }}
- needs: build
- if: needs.build.outputs.configuration == 'Release'
- runs-on: ubuntu-latest
- steps:
- - name: Download viewer exe
- uses: actions/download-artifact@v4
- with:
- name: Windows-app
- path: _artifacts
- - name: Download Windows Symbols
- if: env.BUGSPLAT_USER && env.BUGSPLAT_PASS
- uses: actions/download-artifact@v4
- with:
- name: Windows-symbols
- - name: Extract viewer pdb
- if: env.BUGSPLAT_USER && env.BUGSPLAT_PASS
- shell: bash
- run: |
- tar -xJf "${{ needs.build.outputs.viewer_channel }}.sym.tar.xz" -C _artifacts
- - name: Post Windows symbols
- if: env.BUGSPLAT_USER && env.BUGSPLAT_PASS
- uses: secondlife-3p/symbol-upload@v10
- with:
- username: ${{ env.BUGSPLAT_USER }}
- password: ${{ env.BUGSPLAT_PASS }}
- database: "SecondLife_Viewer_2018"
- application: ${{ needs.build.outputs.viewer_channel }}
- version: ${{ needs.build.outputs.viewer_version }}
- directory: _artifacts
- files: "**/{SecondLifeViewer.exe,llwebrtc.dll,*.pdb}"
-
- post-mac-symbols:
- env:
- BUGSPLAT_USER: ${{ secrets.BUGSPLAT_USER }}
- BUGSPLAT_PASS: ${{ secrets.BUGSPLAT_PASS }}
- needs: build
- if: needs.build.outputs.configuration == 'Release'
- runs-on: ubuntu-latest
- steps:
- - name: Download Mac Symbols
- if: env.BUGSPLAT_USER && env.BUGSPLAT_PASS
- uses: actions/download-artifact@v4
- with:
- name: macOS-symbols
- - name: Post Mac symbols
- if: env.BUGSPLAT_USER && env.BUGSPLAT_PASS
- uses: secondlife-3p/symbol-upload@v10
- with:
- username: ${{ env.BUGSPLAT_USER }}
- password: ${{ env.BUGSPLAT_PASS }}
- database: "SecondLife_Viewer_2018"
- application: ${{ needs.build.outputs.viewer_channel }}
- version: ${{ needs.build.outputs.viewer_version }} (${{ needs.build.outputs.viewer_version }})
- directory: .
- files: "**/*.xcarchive.zip"
-
- release:
- needs: [setup, build, sign-and-package-windows, sign-and-package-mac]
- runs-on: ubuntu-latest
- if: needs.setup.outputs.release_run
- steps:
- - uses: actions/download-artifact@v4
- with:
- pattern: "*-installer"
-
- - uses: actions/download-artifact@v4
- with:
- pattern: "*-metadata"
-
- - name: Rename metadata
- run: |
- cp Windows-metadata/autobuild-package.xml Windows-autobuild-package.xml
- cp Windows-metadata/newview/viewer_version.txt Windows-viewer_version.txt
- cp macOS-metadata/autobuild-package.xml macOS-autobuild-package.xml
- cp macOS-metadata/newview/viewer_version.txt macOS-viewer_version.txt
-
- # forked from softprops/action-gh-release
- - name: Create GitHub release
- id: release
- uses: secondlife-3p/action-gh-release@v1
- with:
- # name the release page for the branch
- name: "${{ needs.build.outputs.viewer_branch }}"
- # SL-20546: want the channel and version to be visible on the
- # release page
- body: |
- Build ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
- ${{ needs.build.outputs.viewer_channel }}
- ${{ needs.build.outputs.viewer_version }}
- ${{ needs.build.outputs.relnotes }}
- prerelease: true
- generate_release_notes: true
- target_commitish: ${{ github.sha }}
- previous_tag: release
- append_body: true
- fail_on_unmatched_files: true
- files: |
- macOS-installer/*.dmg
- Windows-installer/*.exe
- *-autobuild-package.xml
- *-viewer_version.txt
-
- - name: post release URL
- run: |
- echo "::notice::Release ${{ steps.release.outputs.url }}"
diff --git a/.github/workflows/cla.yaml b/.github/workflows/cla.yaml
deleted file mode 100644
index 7866f943b5..0000000000
--- a/.github/workflows/cla.yaml
+++ /dev/null
@@ -1,26 +0,0 @@
-name: Check CLA
-
-on:
- issue_comment:
- types: [created]
- pull_request_target:
- types: [opened, closed, synchronize]
-
-jobs:
- cla:
- name: Check CLA
- runs-on: ubuntu-latest
- steps:
- - name: CLA Assistant
- if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target'
- uses: secondlife-3p/contributor-assistant@v2.6.1
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- PERSONAL_ACCESS_TOKEN: ${{ secrets.SHARED_CLA_TOKEN }}
- with:
- branch: main
- path-to-document: https://github.com/secondlife/cla/blob/main/CLA.md
- path-to-signatures: signatures.json
- remote-organization-name: secondlife
- remote-repository-name: cla-signatures
- allowlist: callum@mbp.localdomain,rye@lindenlab.com
diff --git a/.github/workflows/label.yaml b/.github/workflows/label.yaml
deleted file mode 100644
index 6e41d8aa2d..0000000000
--- a/.github/workflows/label.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-name: Pull Request Labeler
-on:
- - pull_request_target
-
-jobs:
- triage:
- permissions:
- contents: read
- pull-requests: write
- runs-on: ubuntu-latest
- steps:
- - uses: actions/labeler@v4
- with:
- configuration-path: .github/labeler.yaml
- repo-token: "${{ secrets.GITHUB_TOKEN }}"
diff --git a/.github/workflows/pre-commit.yaml b/.github/workflows/pre-commit.yaml
deleted file mode 100644
index d626eef38d..0000000000
--- a/.github/workflows/pre-commit.yaml
+++ /dev/null
@@ -1,18 +0,0 @@
-name: pre-commit
-
-on:
- pull_request:
- push:
- branches: [main, contribute]
- tags: [v*]
-
-
-jobs:
- pre-commit:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-python@v4
- with:
- python-version: 3.x
- - uses: pre-commit/action@v3.0.0
diff --git a/.github/workflows/qatest.yaml b/.github/workflows/qatest.yaml
deleted file mode 100644
index 4892cfaae3..0000000000
--- a/.github/workflows/qatest.yaml
+++ /dev/null
@@ -1,174 +0,0 @@
-name: Run QA Test # Runs automated tests on a self-hosted QA machine
-permissions:
- contents: read
- #pull-requests: write # maybe need to re-add this later
-
-on:
- workflow_run:
- workflows: ["Build"]
- types:
- - completed
-
-concurrency:
- group: qa-test-run
- cancel-in-progress: true # Cancels any queued job when a new one starts
-
-jobs:
- debug-workflow:
- runs-on: ubuntu-latest
- steps:
- - name: Debug Workflow Variables
- env:
- HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }}
- HEAD_COMMIT_MSG: ${{ github.event.workflow_run.head_commit.message }}
- run: |
- echo "Workflow Conclusion: ${{ github.event.workflow_run.conclusion }}"
- echo "Workflow Head Branch: $HEAD_BRANCH"
- echo "Workflow Run ID: ${{ github.event.workflow_run.id }}"
- echo "Head Commit Message: $HEAD_COMMIT_MSG"
- echo "GitHub Ref: ${{ github.ref }}"
- echo "GitHub Ref Name: ${{ github.ref_name }}"
- echo "GitHub Event Name: ${{ github.event_name }}"
- echo "GitHub Workflow Name: ${{ github.workflow }}"
-
- install-viewer-and-run-tests:
- runs-on: [self-hosted, qa-machine]
- # Run test only on successful builds of Second_Life_X branches
- if: >
- github.event.workflow_run.conclusion == 'success' &&
- (
- startsWith(github.event.workflow_run.head_branch, 'Second_Life')
- )
-
- steps:
- - name: Temporarily Allow PowerShell Scripts (Process Scope)
- run: |
- Set-ExecutionPolicy RemoteSigned -Scope Process -Force
-
- - name: Verify viewer-sikulix-main Exists
- run: |
- if (-Not (Test-Path -Path 'C:\viewer-sikulix-main')) {
- Write-Host '❌ Error: viewer-sikulix not found on runner!'
- exit 1
- }
- Write-Host '✅ viewer-sikulix is already available.'
-
- - name: Fetch & Download Windows Installer Artifact
- shell: pwsh
- run: |
- $BUILD_ID = "${{ github.event.workflow_run.id }}"
- $ARTIFACTS_URL = "https://api.github.com/repos/secondlife/viewer/actions/runs/$BUILD_ID/artifacts"
-
- # Fetch the correct artifact URL
- $response = Invoke-RestMethod -Headers @{Authorization="token ${{ secrets.GITHUB_TOKEN }}" } -Uri $ARTIFACTS_URL
- $ARTIFACT_NAME = ($response.artifacts | Where-Object { $_.name -eq "Windows-installer" }).archive_download_url
-
- if (-Not $ARTIFACT_NAME) {
- Write-Host "❌ Error: Windows-installer artifact not found!"
- exit 1
- }
-
- Write-Host "✅ Artifact found: $ARTIFACT_NAME"
-
- # Secure download path
- $DownloadPath = "$env:TEMP\secondlife-build-$BUILD_ID"
- New-Item -ItemType Directory -Path $DownloadPath -Force | Out-Null
- $InstallerPath = "$DownloadPath\installer.zip"
-
- # Download the ZIP
- Invoke-WebRequest -Uri $ARTIFACT_NAME -Headers @{Authorization="token ${{ secrets.GITHUB_TOKEN }}"} -OutFile $InstallerPath
-
- # Ensure download succeeded
- if (-Not (Test-Path $InstallerPath)) {
- Write-Host "❌ Error: Failed to download Windows-installer.zip"
- exit 1
- }
-
- - name: Extract Installer & Locate Executable
- shell: pwsh
- run: |
- # Explicitly set BUILD_ID again (since it does not appear to persist across steps)
- $BUILD_ID = "${{ github.event.workflow_run.id }}"
- $ExtractPath = "$env:TEMP\secondlife-build-$BUILD_ID"
- $InstallerZip = "$ExtractPath\installer.zip"
-
- # Print paths for debugging
- Write-Host "Extract Path: $ExtractPath"
- Write-Host "Installer ZIP Path: $InstallerZip"
-
- # Verify ZIP exists before extracting
- if (-Not (Test-Path $InstallerZip)) {
- Write-Host "❌ Error: ZIP file not found at $InstallerZip!"
- exit 1
- }
-
- Write-Host "✅ ZIP file exists and is valid. Extracting..."
-
- Expand-Archive -Path $InstallerZip -DestinationPath $ExtractPath -Force
-
- # Find installer executable
- $INSTALLER_PATH = (Get-ChildItem -Path $ExtractPath -Filter '*.exe' -Recurse | Select-Object -First 1).FullName
-
- if (-Not $INSTALLER_PATH -or $INSTALLER_PATH -eq "") {
- Write-Host "❌ Error: No installer executable found in the extracted files!"
- Write-Host "📂 Extracted Files:"
- Get-ChildItem -Path $ExtractPath -Recurse | Format-Table -AutoSize
- exit 1
- }
-
- Write-Host "✅ Installer found: $INSTALLER_PATH"
- echo "INSTALLER_PATH=$INSTALLER_PATH" | Out-File -FilePath $env:GITHUB_ENV -Append
-
- - name: Install Second Life Using Task Scheduler (Bypass UAC)
- shell: pwsh
- run: |
- $action = New-ScheduledTaskAction -Execute "${{ env.INSTALLER_PATH }}" -Argument "/S"
- $principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest
- $task = New-ScheduledTask -Action $action -Principal $principal
- Register-ScheduledTask -TaskName "SilentSLInstaller" -InputObject $task -Force
- Start-ScheduledTask -TaskName "SilentSLInstaller"
-
- - name: Wait for Installation to Complete
- shell: pwsh
- run: |
- Write-Host "Waiting for the Second Life installer to finish..."
- do {
- Start-Sleep -Seconds 5
- $installerProcess = Get-Process | Where-Object { $_.Path -eq "${{ env.INSTALLER_PATH }}" }
- } while ($installerProcess)
-
- Write-Host "✅ Installation completed!"
-
- - name: Cleanup Task Scheduler Entry
- shell: pwsh
- run: |
- Unregister-ScheduledTask -TaskName "SilentSLInstaller" -Confirm:$false
- Write-Host "✅ Task Scheduler entry removed."
-
- - name: Delete Installer ZIP
- shell: pwsh
- run: |
- # Explicitly set BUILD_ID again
- $BUILD_ID = "${{ github.event.workflow_run.id }}"
- $DeletePath = "$env:TEMP\secondlife-build-$BUILD_ID\installer.zip"
-
- Write-Host "Checking if installer ZIP exists: $DeletePath"
-
- # Ensure the ZIP file exists before trying to delete it
- if (Test-Path $DeletePath) {
- Remove-Item -Path $DeletePath -Force
- Write-Host "✅ Successfully deleted: $DeletePath"
- } else {
- Write-Host "⚠️ Warning: ZIP file does not exist, skipping deletion."
- }
-
- - name: Run QA Test Script
- run: |
- Write-Host "Running QA Test script..."
- python C:\viewer-sikulix-main\runTests.py
-
- # - name: Upload Test Results
- # uses: actions/upload-artifact@v3
- # with:
- # name: test-results
- # path: C:\viewer-sikulix-main\regressionTest\test_results.html
diff --git a/.github/workflows/stale.yaml b/.github/workflows/stale.yaml
deleted file mode 100644
index f77151a815..0000000000
--- a/.github/workflows/stale.yaml
+++ /dev/null
@@ -1,25 +0,0 @@
-name: Stale PRs
-on:
- workflow_dispatch:
- schedule:
- - cron: 0 0 * * *
-
-permissions:
- issues: write
- pull-requests: write
-
-jobs:
- stale:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/stale@v6
- id: stale
- with:
- stale-pr-message: This pull request is stale because it has been open 30 days with no activity. Remove stale label or comment or it will be closed in 7 days
- days-before-stale: 30
- days-before-close: 7
- days-before-issue-close: -1
- exempt-pr-labels: blocked,must,should,keep
- stale-pr-label: stale
- - name: Print outputs
- run: echo ${{ join(steps.stale.outputs.*, ',') }}
diff --git a/.github/workflows/tag-release.yaml b/.github/workflows/tag-release.yaml
deleted file mode 100644
index 24ee2de794..0000000000
--- a/.github/workflows/tag-release.yaml
+++ /dev/null
@@ -1,52 +0,0 @@
-name: Tag a Build
-
-on:
- # schedule event triggers always run on the default branch
- # https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#schedule
- schedule:
- # run "nightly" builds on default branch every mon/wed/fri
- - cron: "21 2 * * 2,4,6" # 2:21am UTC tues/thurs/sat == 7:21pm PDT mon/wed/fri -- see https://crontab.guru/#21_01_*_*_2,4,6
- workflow_dispatch:
- inputs:
- channel:
- description: "Channel to configure the build"
- required: true
- type: choice
- default: "Test"
- options:
- - "Test"
- - "Develop"
- - "Project"
- - "Release"
- project:
- description: "Project Name (used for channel name in project builds, and tag name for all builds)"
- default: "hippo"
- # TODO - add an input for selecting another sha to build other than head of branch
-
-jobs:
- tag-release:
- runs-on: ubuntu-latest
- steps:
- - name: Setup Env Vars
- run: |
- CHANNEL="${{ inputs.channel }}"
- echo VIEWER_CHANNEL="Second_Life_${CHANNEL:-Develop}" >> ${GITHUB_ENV}
- NIGHTLY_DATE=$(date --rfc-3339=date)
- echo NIGHTLY_DATE=${NIGHTLY_DATE} >> ${GITHUB_ENV}
- echo TAG_ID="$(echo ${{ github.sha }} | cut -c1-8)-${{ inputs.project || '${NIGHTLY_DATE}' }}" >> ${GITHUB_ENV}
- - name: Update Tag
- uses: actions/github-script@v7.0.1
- with:
- # use a real access token instead of GITHUB_TOKEN default.
- # required so that the results of this tag creation can trigger the build workflow
- # https://stackoverflow.com/a/71372524
- # https://docs.github.com/en/actions/using-workflows/triggering-a-workflow#triggering-a-workflow-from-a-workflow
- # this token will need to be renewed anually in January
- github-token: ${{ secrets.LL_TAG_RELEASE_TOKEN }}
- script: |
- github.rest.git.createRef({
- owner: context.repo.owner,
- repo: context.repo.repo,
- ref: "refs/tags/${{ env.VIEWER_CHANNEL }}#${{ env.TAG_ID }}",
- sha: context.sha
- })