Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
4dc59a8
Integrate Velopack installer and update framework
Geenz Dec 19, 2025
386316c
Try to get CI/CD working with velopack.
Geenz Dec 19, 2025
d4432c9
Update build.yaml
Geenz Dec 19, 2025
2bdd1c2
Update build.yaml
Geenz Dec 19, 2025
5baae4a
Update build.yaml
Geenz Dec 20, 2025
ad82d46
Add Velopack update support for macOS and VVM integration
Geenz Jan 21, 2026
a9d125f
Update Velopack version and dependencies
Geenz Jan 21, 2026
b2d4285
Update viewer_manifest.py
Geenz Jan 21, 2026
158fc84
Improve Velopack packaging for macOS
Geenz Jan 22, 2026
e6d2890
Update build.yaml
Geenz Jan 22, 2026
2906ad7
Update viewer_manifest.py
Geenz Jan 22, 2026
8fccef6
Update viewer_manifest.py
Geenz Jan 23, 2026
68be5c7
Update viewer_manifest.py
Geenz Jan 23, 2026
3acb531
Update viewer_manifest.py
Geenz Jan 23, 2026
85298eb
Update viewer_manifest.py
Geenz Jan 23, 2026
a6b978b
#5346 Uninstall older non-velopack viewer (#5363)
akleshchev Feb 10, 2026
276cef0
Merge branch 'release/2026.01' into project/one-click
Geenz Feb 24, 2026
1c8bb96
Use runtime viewer exe name, handle Velopack URL
Geenz Feb 24, 2026
dc1d755
Velopack download failure diagnostic (#5520)
akleshchev Mar 12, 2026
7e21cb0
Remove SLVersionChecker from the viewer with velopack. (#5528)
Geenz Mar 12, 2026
7c4f2a6
Merge pull request #5529 from secondlife/release/2026.01
Geenz Mar 12, 2026
209ab7f
Update lllogininstance_test.cpp
Geenz Mar 12, 2026
4704331
Don't produce shortcuts with VPK - we do this with our post install.
Geenz Mar 12, 2026
093a90c
Update llstartup.cpp
Geenz Mar 12, 2026
57dd238
Bump viewer version from 26.1.0 to 26.1.1
Geenz Mar 12, 2026
fecfcbe
Update viewer_manifest.py
Geenz Mar 12, 2026
0d8bbc0
Potential fix for uninstaller not being functional.
Geenz Mar 12, 2026
38e7165
Fix for UpdaterServiceSetting being ignored.
Geenz Mar 12, 2026
50e0919
Filter for release channel when generating shortcuts.
Geenz Mar 12, 2026
617c428
Update viewer_manifest.py
Geenz Mar 13, 2026
06fd3e7
Add some more logging for icons on Windows builds.
Geenz Mar 13, 2026
a581013
More VPK logging.
Geenz Mar 13, 2026
0a29d51
Move velopack packaging in CI to the sign and package step.
Geenz Mar 13, 2026
eb7d968
Update viewer_manifest.py
Geenz Mar 13, 2026
76236a7
Enable velopack downgrade and skip older updates
Geenz Mar 17, 2026
08439c6
Move the version required checking into velopack's checks.
Geenz Mar 17, 2026
6227691
Potential fix for downgrade prompts.
Geenz Mar 17, 2026
a611d22
Make sure our macOS flow mirrors Windows.
Geenz Mar 18, 2026
8bac218
Make sure to use the dev version of the mac sign and package.
Geenz Mar 18, 2026
62274ec
p#553 Only one of two uninstallers displayed
akleshchev Mar 18, 2026
1bd924f
#5346 Don't force user to shutdown velopack build for NSIS uninstall
akleshchev Mar 18, 2026
d1a4b31
#5346 Ignore option for the uninstall dialog
akleshchev Mar 18, 2026
adee09a
#5346 Fix early exit crash
akleshchev Mar 19, 2026
ebe25a7
#5346 Properly reset version flag.
akleshchev Mar 19, 2026
bbce47f
Add some autodetect logic on macOS.
Geenz Mar 20, 2026
e3592e5
Merge branch 'release/26.1.1' of https://github.com/secondlife/viewer…
Geenz Mar 20, 2026
4e2d576
Update notifications.xml
Geenz Mar 20, 2026
3946f0b
Update autobuild.xml
Geenz Mar 24, 2026
b46b000
p#564 Clear legacy links
akleshchev Mar 23, 2026
4c07660
p#553 Handle uninstall records
akleshchev Mar 24, 2026
8f1bca1
p#549 Permit testing release notes on a test build
akleshchev Mar 24, 2026
98bed7d
Update VIEWER_VERSION.txt
Geenz Mar 25, 2026
37f62d8
Update VIEWER_VERSION.txt
Geenz Mar 25, 2026
5fcf5a4
Update tag-release.yaml
Geenz Mar 25, 2026
e075a88
p#564 Remake nsis to velopack update flow
akleshchev Mar 26, 2026
372e899
p#564 Remake nsis to velopack update flow #2
akleshchev Mar 26, 2026
7c4c1e0
Merge pull request #5582 from secondlife/andreyk/p564_refining2
Geenz Mar 26, 2026
82a0532
Update README.md
Geenz Mar 26, 2026
4ffa3a5
p#564 Fix incorrect value type
akleshchev Mar 27, 2026
501ddff
Update README.md
Geenz Mar 27, 2026
d10e7f8
Update README.md
Geenz Mar 27, 2026
2d5ab87
Update README.md
Geenz Mar 27, 2026
6e77200
p#553 Clear velopack's own registry entry in favor of a custom one
akleshchev Mar 28, 2026
d438ef9
Merge pull request #5589 from secondlife/andreyk/p553_registry_cleanup2
Geenz Mar 31, 2026
97908c2
#5346 Resolve duplicated window class name
akleshchev Mar 31, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 57 additions & 3 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@ name: Build

on:
workflow_dispatch:
inputs:
installer_type:
description: 'Windows installer type'
type: choice
options:
- velopack
- nsis
default: 'velopack'
pull_request:
push:
branches: ["main", "release/*", "project/*"]
Expand Down Expand Up @@ -53,6 +61,20 @@ jobs:
relnotes: ${{ steps.which-branch.outputs.relnotes }}
imagename: ${{ steps.build.outputs.imagename }}
configuration: ${{ matrix.configuration }}
# Windows Velopack outputs (passed to sign-pkg-windows)
velopack_pack_id: ${{ steps.build.outputs.velopack_pack_id }}
velopack_pack_version: ${{ steps.build.outputs.velopack_pack_version }}
velopack_pack_title: ${{ steps.build.outputs.velopack_pack_title }}
velopack_main_exe: ${{ steps.build.outputs.velopack_main_exe }}
velopack_exclude: ${{ steps.build.outputs.velopack_exclude }}
velopack_icon: ${{ steps.build.outputs.velopack_icon }}
velopack_installer_base: ${{ steps.build.outputs.velopack_installer_base }}
# macOS Velopack outputs (passed to sign-pkg-mac)
velopack_mac_pack_id: ${{ steps.build.outputs.velopack_mac_pack_id }}
velopack_mac_pack_version: ${{ steps.build.outputs.velopack_mac_pack_version }}
velopack_mac_pack_title: ${{ steps.build.outputs.velopack_mac_pack_title }}
velopack_mac_main_exe: ${{ steps.build.outputs.velopack_mac_main_exe }}
velopack_mac_bundle_id: ${{ steps.build.outputs.velopack_mac_bundle_id }}
env:
AUTOBUILD_ADDRSIZE: 64
AUTOBUILD_BUILD_ID: ${{ github.run_id }}
Expand Down Expand Up @@ -84,6 +106,8 @@ jobs:
# 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 }}
# Pass USE_VELOPACK to CMake when using Velopack installer (default) - Windows and macOS
autobuild_configure_parameters: ${{ (contains(matrix.runner, 'windows') || contains(matrix.runner, 'macos')) && (github.event.inputs.installer_type || 'velopack') == 'velopack' && '-- -DUSE_VELOPACK:BOOL=ON' || '' }}
steps:
- name: Checkout code
uses: actions/checkout@v5
Expand Down Expand Up @@ -126,6 +150,17 @@ jobs:
with:
token: ${{ github.token }}

- name: Setup .NET for Velopack
if: (runner.os == 'Windows' || runner.os == 'macOS') && (github.event.inputs.installer_type || 'velopack') == 'velopack'
uses: actions/setup-dotnet@v4
with:
dotnet-version: '9.0.x'

- name: Install Velopack CLI
if: (runner.os == 'Windows' || runner.os == 'macOS') && (github.event.inputs.installer_type || 'velopack') == 'velopack'
shell: bash
run: dotnet tool install -g vpk

- name: Build
id: build
shell: bash
Expand Down Expand Up @@ -310,13 +345,21 @@ jobs:
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.0.4
uses: secondlife/viewer-build-util/sign-pkg-windows@geenz/velopack
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 }}"
installer_type: "${{ github.event.inputs.installer_type || 'velopack' }}"
velopack_pack_id: "${{ needs.build.outputs.velopack_pack_id }}"
velopack_pack_version: "${{ needs.build.outputs.velopack_pack_version }}"
velopack_pack_title: "${{ needs.build.outputs.velopack_pack_title }}"
velopack_main_exe: "${{ needs.build.outputs.velopack_main_exe }}"
velopack_exclude: "${{ needs.build.outputs.velopack_exclude }}"
velopack_icon: "${{ needs.build.outputs.velopack_icon }}"
velopack_installer_base: "${{ needs.build.outputs.velopack_installer_base }}"

sign-and-package-mac:
env:
Expand Down Expand Up @@ -349,7 +392,7 @@ jobs:

- 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
uses: secondlife/viewer-build-util/sign-pkg-mac@geenz/velopack
with:
channel: ${{ needs.build.outputs.viewer_channel }}
imagename: ${{ needs.build.outputs.imagename }}
Expand All @@ -359,6 +402,11 @@ jobs:
note_user: ${{ steps.note-creds.outputs.note_user }}
note_pass: ${{ steps.note-creds.outputs.note_pass }}
note_team: ${{ steps.note-creds.outputs.note_team }}
velopack_pack_id: "${{ needs.build.outputs.velopack_mac_pack_id }}"
velopack_pack_version: "${{ needs.build.outputs.velopack_mac_pack_version }}"
velopack_pack_title: "${{ needs.build.outputs.velopack_mac_pack_title }}"
velopack_main_exe: "${{ needs.build.outputs.velopack_mac_main_exe }}"
velopack_bundle_id: "${{ needs.build.outputs.velopack_mac_bundle_id }}"

post-windows-symbols:
env:
Expand Down Expand Up @@ -439,6 +487,10 @@ jobs:
with:
pattern: "*-metadata"

- uses: actions/download-artifact@v4
with:
pattern: "*-releases"

- name: Rename metadata
run: |
cp Windows-metadata/autobuild-package.xml Windows-autobuild-package.xml
Expand All @@ -464,12 +516,14 @@ jobs:
generate_release_notes: true
target_commitish: ${{ github.sha }}
append_body: true
fail_on_unmatched_files: true
fail_on_unmatched_files: false
files: |
macOS-installer/*.dmg
Windows-installer/*.exe
*-autobuild-package.xml
*-viewer_version.txt
Windows-releases/*
macOS-releases/*

- name: post release URL
run: |
Expand Down
36 changes: 28 additions & 8 deletions .github/workflows/tag-release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ on:
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
tag_override:
description: "Override the tag name (optional). If the tag already exists, a numeric suffix is appended."
required: false

jobs:
tag-release:
Expand All @@ -34,7 +36,7 @@ jobs:
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
- name: Create Tag
uses: actions/github-script@v8
with:
# use a real access token instead of GITHUB_TOKEN default.
Expand All @@ -44,9 +46,27 @@ jobs:
# 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
})
const override = `${{ inputs.tag_override }}`.trim();
const baseTag = override || `${{ env.VIEWER_CHANNEL }}#${{ env.TAG_ID }}`;

// Try the base tag first, then append -2, -3, etc. if it already exists
let tag = baseTag;
for (let attempt = 1; ; attempt++) {
try {
await github.rest.git.createRef({
owner: context.repo.owner,
repo: context.repo.repo,
ref: `refs/tags/${tag}`,
sha: context.sha
});
core.info(`Created tag: ${tag}`);
break;
} catch (e) {
if (e.status === 422 && attempt < 10) {
core.info(`Tag '${tag}' already exists, trying next suffix...`);
tag = `${baseTag}-${attempt + 1}`;
} else {
throw e;
}
}
}
50 changes: 50 additions & 0 deletions autobuild.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2914,6 +2914,56 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>description</key>
<string>Voxelized Hierarchical Approximate Convex Decomposition</string>
</map>
<key>velopack</key>
<map>
<key>platforms</key>
<map>
<key>windows64</key>
<map>
<key>archive</key>
<map>
<key>creds</key>
<string>github</string>
<key>hash</key>
<string>91abbc360640b5b2e0a4c001a36ad411a9a42602</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
<string>https://api.github.com/repos/secondlife-3p/3p-velopack/releases/assets/380583560</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
<key>darwin64</key>
<map>
<key>archive</key>
<map>
<key>creds</key>
<string>github</string>
<key>hash</key>
<string>05563a79bdeb83d66a72ac1e97587dc2a8f64511</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
<string>https://api.github.com/repos/secondlife-3p/3p-velopack/releases/assets/380583554</string>
</map>
<key>name</key>
<string>darwin64</string>
</map>
</map>
<key>license</key>
<string>MIT</string>
<key>license_file</key>
<string>LICENSES/velopack.txt</string>
<key>copyright</key>
<string>Velopack Ltd.</string>
<key>version</key>
<string>40232ef.23500976684</string>
<key>name</key>
<string>velopack</string>
<key>description</key>
<string>Velopack C/C++ Library</string>
</map>
</map>
<key>package_description</key>
<map>
Expand Down
1 change: 1 addition & 0 deletions indra/cmake/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ set(cmake_SOURCE_FILES
UI.cmake
UnixInstall.cmake
Variables.cmake
Velopack.cmake
VHACD.cmake
ViewerMiscLibs.cmake
VisualLeakDetector.cmake
Expand Down
2 changes: 1 addition & 1 deletion indra/cmake/Python.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ elseif (WINDOWS)
foreach(hive HKEY_CURRENT_USER HKEY_LOCAL_MACHINE)
# prefer more recent Python versions to older ones, if multiple versions
# are installed
foreach(pyver 3.13 3.12 3.11 3.10 3.9 3.8 3.7)
foreach(pyver 3.14 3.13 3.12 3.11 3.10 3.9 3.8 3.7)
list(APPEND regpaths "[${hive}\\SOFTWARE\\Python\\PythonCore\\${pyver}\\InstallPath]")
endforeach()
endforeach()
Expand Down
68 changes: 68 additions & 0 deletions indra/cmake/Velopack.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# -*- cmake -*-
# Velopack installer and update framework integration
# https://velopack.io/

include_guard()

# USE_VELOPACK controls whether to use Velopack for installer packaging (instead of NSIS/DMG)
option(USE_VELOPACK "Use Velopack for installer packaging" OFF)

if (WINDOWS)
include(Prebuilt)
use_prebuilt_binary(velopack)

add_library(ll::velopack INTERFACE IMPORTED)

target_include_directories(ll::velopack SYSTEM INTERFACE
${LIBS_PREBUILT_DIR}/include/velopack
)

target_link_libraries(ll::velopack INTERFACE
${ARCH_PREBUILT_DIRS_RELEASE}/velopack_libc.lib
)

# Windows system libraries required by Velopack
target_link_libraries(ll::velopack INTERFACE
winhttp
ole32
shell32
shlwapi
version
userenv
ws2_32
bcrypt
ntdll
)

target_compile_definitions(ll::velopack INTERFACE LL_VELOPACK=1)

elseif (DARWIN)
include(Prebuilt)
use_prebuilt_binary(velopack)

add_library(ll::velopack INTERFACE IMPORTED)

target_include_directories(ll::velopack SYSTEM INTERFACE
${LIBS_PREBUILT_DIR}/include/velopack
)

target_link_libraries(ll::velopack INTERFACE
${ARCH_PREBUILT_DIRS_RELEASE}/libvelopack_libc.a
)

# macOS system frameworks required by Velopack (Rust static library dependencies)
target_link_libraries(ll::velopack INTERFACE
"-framework Foundation"
"-framework Security"
"-framework SystemConfiguration"
"-framework AppKit"
"-framework CoreFoundation"
"-framework CoreServices"
"-framework IOKit"
"-liconv"
"-lresolv"
)

target_compile_definitions(ll::velopack INTERFACE LL_VELOPACK=1)

endif()
3 changes: 2 additions & 1 deletion indra/lib/python/indra/util/llmanifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,8 @@ def get_default_platform(dummy):
for use by a .bat file.""",
default=None),
dict(name='versionfile',
description="""The name of a file containing the full version number."""),
description="""The name of a file containing the full version number.""",
default=None),
]

def usage(arguments, srctree=""):
Expand Down
18 changes: 15 additions & 3 deletions indra/llcommon/workqueue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ LL::WorkQueueBase::WorkQueueBase(const std::string& name, bool auto_shutdown)
{
// Register for "LLApp" events so we can implicitly close() on viewer shutdown
std::string listener_name = "WorkQueue:" + getKey();
LLEventPumps::instance().obtain("LLApp").listen(
LLEventPumps* pump = LLEventPumps::getInstance();
pump->obtain("LLApp").listen(
listener_name,
[this](const LLSD& stat)
{
Expand All @@ -54,14 +55,25 @@ LL::WorkQueueBase::WorkQueueBase(const std::string& name, bool auto_shutdown)

// Store the listener name so we can unregister in the destructor
mListenerName = listener_name;
mPumpHandle = pump->getHandle();
}
}

LL::WorkQueueBase::~WorkQueueBase()
{
if (!mListenerName.empty() && !LLEventPumps::wasDeleted())
if (!mListenerName.empty() && !mPumpHandle.isDead())
{
LLEventPumps::instance().obtain("LLApp").stopListening(mListenerName);
// Due to shutdown order issues, use handle, not a singleton
// and ignore fiber issue.
try
{
LLEventPumps* pump = mPumpHandle.get();
pump->obtain("LLApp").stopListening(mListenerName);
}
catch (const boost::fibers::lock_error&)
{
// Likely mutex is down, ignore
}
}
}

Expand Down
Loading
Loading