Skip to content

Commit 1deea3a

Browse files
committed
fix(ci): harmonize LLVM toolchain, rename plugin packages to AMD64/ARM64 and auto-deploy independent models
1 parent 4fb1264 commit 1deea3a

6 files changed

Lines changed: 89 additions & 46 deletions

File tree

‎.github/workflows/build-release.yml‎

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,7 @@ jobs:
2929
submodules: recursive
3030
fetch-depth: 0
3131

32-
- name: Install Toolchain
33-
run: choco install llvm -y
32+
# Note: Visual Studio on GitHub Actions runner already includes matched LLVM/Clang-cl/lld-link
3433

3534
- name: Setup Ninja
3635
uses: seanmiddleditch/gha-setup-ninja@master
@@ -65,7 +64,7 @@ jobs:
6564
- name: Prepare Portable Version
6665
shell: pwsh
6766
run: |
68-
$archUpper = if ("${{ matrix.platform }}" -eq "x64") { "X64" } else { "ARM64" }
67+
$archUpper = if ("${{ matrix.platform }}" -eq "x64") { "AMD64" } else { "ARM64" }
6968
7069
# Path for CMake build artifact (Ninja puts it in root)
7170
$exePath = "${{ github.workspace }}/out/build/${{ matrix.preset }}/QuickView.exe"
@@ -87,13 +86,12 @@ jobs:
8786
$zipName = "QuickView_${tag}_${archUpper}.zip"
8887
Compress-Archive -Path $exePath -DestinationPath "Release/dist/$zipName" -Force
8988
90-
# Package standalone QVX plugin artifact (sr_ncnn_vulkan + models + manifest)
89+
# Package standalone QVX plugin artifact (sr_ncnn_vulkan + models)
9190
$pluginDir = "${{ github.workspace }}/out/build/${{ matrix.preset }}/plugins/sr/sr_ncnn_vulkan"
9291
if (Test-Path "$pluginDir/sr_ncnn_vulkan.qvx") {
9392
$pluginZip = "Release/dist/sr_ncnn_vulkan_${archUpper}.zip"
9493
Compress-Archive -Path "$pluginDir/*" -DestinationPath $pluginZip -Force
9594
if ("${{ matrix.platform }}" -eq "x64") {
96-
Copy-Item -Path $pluginZip -Destination "Release/dist/sr_ncnn_vulkan.zip" -Force
9795
Copy-Item -Path "${{ github.workspace }}/plugins/plugins_manifest.json" -Destination "Release/dist/plugins_manifest.json" -Force
9896
}
9997
}
@@ -102,7 +100,7 @@ jobs:
102100
shell: pwsh
103101
run: |
104102
$arch = "${{ matrix.platform }}".ToLower()
105-
$archUpper = if ("${{ matrix.platform }}" -eq "x64") { "X64" } else { "ARM64" }
103+
$archUpper = if ("${{ matrix.platform }}" -eq "x64") { "AMD64" } else { "ARM64" }
106104
$tag = "${{ env.DETECTED_TAG }}"
107105
$version = $tag.TrimStart('v')
108106

‎.github/workflows/publish_version.yml‎

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,26 +23,43 @@ jobs:
2323
VERSION=${TAG_NAME#v}
2424
DATE=$(date +'%Y-%m-%d')
2525
26-
mkdir -p public
26+
mkdir -p public/models
27+
mkdir -p public/plugins
2728
if [ -f "plugins/plugins_manifest.json" ]; then
2829
cp plugins/plugins_manifest.json public/
30+
cp plugins/plugins_manifest.json public/plugins/
31+
fi
32+
33+
# Package independent SR models to public/models/*.zip for CDN download
34+
if [ -d "plugins/sr/sr_ncnn_vulkan/models" ]; then
35+
echo "Packaging independent SR models for GitHub Pages CDN..."
36+
for param_file in plugins/sr/sr_ncnn_vulkan/models/*.param; do
37+
if [ -f "$param_file" ]; then
38+
base_name=$(basename "$param_file" .param)
39+
bin_file="plugins/sr/sr_ncnn_vulkan/models/${base_name}.bin"
40+
if [ -f "$bin_file" ]; then
41+
zip -j -9 "public/models/${base_name}.zip" "$param_file" "$bin_file"
42+
echo "Created public/models/${base_name}.zip"
43+
fi
44+
fi
45+
done
2946
fi
3047
3148
# 1. Get all assets in JSON
3249
ASSETS=$(gh release view "$TAG_NAME" --json assets -q '.assets')
3350
34-
# 2. Identify ARM64 portable asset (.zip only, exclude installer .exe)
35-
URL_ARM64=$(echo "$ASSETS" | jq -r 'map(select(.name | ascii_downcase | (contains("arm64") and test("\\.zip$")))) | .[0].url // ""')
36-
NAME_ARM64=$(echo "$ASSETS" | jq -r 'map(select(.name | ascii_downcase | (contains("arm64") and test("\\.zip$")))) | .[0].name // ""')
51+
# 2. Identify ARM64 portable asset (QuickView .zip only, exclude installer .exe and plugins)
52+
URL_ARM64=$(echo "$ASSETS" | jq -r 'map(select(.name | ascii_downcase | (contains("quickview") and contains("arm64") and test("\\.zip$")))) | .[0].url // ""')
53+
NAME_ARM64=$(echo "$ASSETS" | jq -r 'map(select(.name | ascii_downcase | (contains("quickview") and contains("arm64") and test("\\.zip$")))) | .[0].name // ""')
3754
38-
# 3. Identify X64 portable asset (.zip only, exclude installer .exe)
39-
URL_X64=$(echo "$ASSETS" | jq -r 'map(select(.name | ascii_downcase | ((contains("x64") or contains("amd64")) and test("\\.zip$")))) | .[0].url // ""')
40-
NAME_X64=$(echo "$ASSETS" | jq -r 'map(select(.name | ascii_downcase | ((contains("x64") or contains("amd64")) and test("\\.zip$")))) | .[0].name // ""')
55+
# 3. Identify X64/AMD64 portable asset (QuickView .zip only, exclude installer .exe and plugins)
56+
URL_X64=$(echo "$ASSETS" | jq -r 'map(select(.name | ascii_downcase | (contains("quickview") and (contains("x64") or contains("amd64")) and test("\\.zip$")))) | .[0].url // ""')
57+
NAME_X64=$(echo "$ASSETS" | jq -r 'map(select(.name | ascii_downcase | (contains("quickview") and (contains("x64") or contains("amd64")) and test("\\.zip$")))) | .[0].name // ""')
4158
42-
# Fallback: if no explicit x64 .zip found, take the first .zip that isn't ARM64
59+
# Fallback: if no explicit x64 .zip found, take the first QuickView .zip that isn't ARM64
4360
if [ -z "$URL_X64" ]; then
44-
URL_X64=$(echo "$ASSETS" | jq -r 'map(select((.name | ascii_downcase | contains("arm64") | not) and (.name | ascii_downcase | test("\\.zip$")))) | .[0].url // ""')
45-
NAME_X64=$(echo "$ASSETS" | jq -r 'map(select((.name | ascii_downcase | contains("arm64") | not) and (.name | ascii_downcase | test("\\.zip$")))) | .[0].name // ""')
61+
URL_X64=$(echo "$ASSETS" | jq -r 'map(select((.name | ascii_downcase | (contains("quickview") and (contains("arm64") | not) and test("\\.zip$"))))) | .[0].url // ""')
62+
NAME_X64=$(echo "$ASSETS" | jq -r 'map(select((.name | ascii_downcase | (contains("quickview") and (contains("arm64") | not) and test("\\.zip$"))))) | .[0].name // ""')
4663
fi
4764
4865
SHA_X64=""
@@ -60,6 +77,15 @@ jobs:
6077
SHA_ARM64=$(sha256sum arm64_pkg | awk '{print $1}')
6178
fi
6279
80+
# Sync plugin zip packages from Release to public/plugins/
81+
for p_arch in "AMD64" "ARM64"; do
82+
P_NAME=$(echo "$ASSETS" | jq -r --arg a "$p_arch" 'map(select(.name | ascii_downcase | (contains("sr_ncnn_vulkan") and contains($a | ascii_downcase) and test("\\.zip$")))) | .[0].name // ""')
83+
if [ -n "$P_NAME" ] && [ "$P_NAME" != "null" ]; then
84+
echo "Syncing plugin package $P_NAME to public/plugins/..."
85+
gh release download "$TAG_NAME" -p "$P_NAME" -O "public/plugins/${P_NAME}" || true
86+
fi
87+
done
88+
6389
# Fallback URL for legacy clients (pointing to X64)
6490
URL=$URL_X64
6591

‎QuickView/Plugin/PluginHost.cpp‎

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,14 @@ std::vector<RemotePluginItem> PluginHost::GetCachedRemoteManifest() const {
9999
}
100100

101101
// Default built-in manifest fallback to ensure offline / initial launch availability
102+
#if defined(_M_ARM64) || defined(__aarch64__)
103+
const char* defaultPkgUrl = "https://justnullname.github.io/QuickView/plugins/sr_ncnn_vulkan_ARM64.zip";
104+
const char* defaultPkgFile = "sr_ncnn_vulkan_ARM64.zip";
105+
#else
106+
const char* defaultPkgUrl = "https://justnullname.github.io/QuickView/plugins/sr_ncnn_vulkan_AMD64.zip";
107+
const char* defaultPkgFile = "sr_ncnn_vulkan_AMD64.zip";
108+
#endif
109+
102110
std::vector<RemotePluginItem> defaultList;
103111
defaultList.push_back({
104112
"com.quickview.sr.ncnn_vulkan",
@@ -107,8 +115,8 @@ std::vector<RemotePluginItem> PluginHost::GetCachedRemoteManifest() const {
107115
"QuickView Core Team",
108116
"SuperResolution",
109117
"High-Performance In-Process Vulkan Compute Neural Super-Resolution Engine (0-Copy, 0 Disk I/O).",
110-
"https://justnullname.github.io/QuickView/plugins/sr_ncnn_vulkan.zip",
111-
"sr_ncnn_vulkan.zip",
118+
defaultPkgUrl,
119+
defaultPkgFile,
112120
2600000,
113121
"0.1.0",
114122
""
@@ -1261,20 +1269,13 @@ bool PluginHost::DownloadPlugin(const std::wstring& pluginName, const std::strin
12611269

12621270
if (ok) {
12631271
std::lock_guard<std::recursive_mutex> lock(m_srMutex);
1264-
if (isZip) {
1265-
std::wstring baseName = pluginName;
1266-
if (baseName.ends_with(L".zip")) baseName = baseName.substr(0, baseName.size() - 4);
1267-
std::wstring isolatedRel = L"plugins\\sr\\" + baseName + L"\\" + baseName + L".qvx";
1268-
std::wstring legacyRel = L"plugins\\" + baseName + L".qvx";
1269-
wchar_t combined[MAX_PATH];
1270-
PathCombineW(combined, exePath, isolatedRel.c_str());
1271-
if (GetFileAttributesW(combined) != INVALID_FILE_ATTRIBUTES) {
1272-
m_srPluginPath = isolatedRel;
1273-
} else {
1274-
m_srPluginPath = legacyRel;
1275-
}
1272+
m_srPluginPath.clear();
1273+
std::wstring relForIni;
1274+
std::wstring effective = ResolveEffectiveSrPluginPath(&relForIni);
1275+
if (!effective.empty()) {
1276+
m_srPluginPath = relForIni;
12761277
} else {
1277-
m_srPluginPath = L"plugins\\" + pluginName;
1278+
m_srPluginPath = L"plugins\\sr\\sr_ncnn_vulkan\\sr_ncnn_vulkan.qvx";
12781279
}
12791280
UnloadSrPlugin();
12801281
EnsureSrModuleLoaded();
@@ -1511,10 +1512,25 @@ void PluginHost::FetchRemoteManifestAsync(ManifestCallback callback, void* userD
15111512
if (v && yyjson_get_str(v)) r.interfaceName = yyjson_get_str(v);
15121513
v = yyjson_obj_get(item, "description");
15131514
if (v && yyjson_get_str(v)) r.description = yyjson_get_str(v);
1514-
v = yyjson_obj_get(item, "download_url");
1515+
// Architecture-aware URL and file name selection
1516+
#if defined(_M_ARM64) || defined(__aarch64__)
1517+
v = yyjson_obj_get(item, "download_url_arm64");
1518+
if (!v || !yyjson_get_str(v)) v = yyjson_obj_get(item, "download_url");
15151519
if (v && yyjson_get_str(v)) r.downloadUrl = yyjson_get_str(v);
1516-
v = yyjson_obj_get(item, "file_name");
1520+
1521+
v = yyjson_obj_get(item, "file_name_arm64");
1522+
if (!v || !yyjson_get_str(v)) v = yyjson_obj_get(item, "file_name");
15171523
if (v && yyjson_get_str(v)) r.fileName = yyjson_get_str(v);
1524+
#else
1525+
v = yyjson_obj_get(item, "download_url_amd64");
1526+
if (!v || !yyjson_get_str(v)) v = yyjson_obj_get(item, "download_url_x64");
1527+
if (!v || !yyjson_get_str(v)) v = yyjson_obj_get(item, "download_url");
1528+
if (v && yyjson_get_str(v)) r.downloadUrl = yyjson_get_str(v);
1529+
1530+
v = yyjson_obj_get(item, "file_name_amd64");
1531+
if (!v || !yyjson_get_str(v)) v = yyjson_obj_get(item, "file_name");
1532+
if (v && yyjson_get_str(v)) r.fileName = yyjson_get_str(v);
1533+
#endif
15181534
v = yyjson_obj_get(item, "file_size");
15191535
if (v) r.fileSize = yyjson_get_uint(v);
15201536
v = yyjson_obj_get(item, "min_app_version");

‎QuickView/QuickView.rc‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212

1313
// Version Information - This sets the display name in Windows
1414
VS_VERSION_INFO VERSIONINFO
15-
FILEVERSION 6,46,0,0
16-
PRODUCTVERSION 6,46,0,0
15+
FILEVERSION 6,46,0,1
16+
PRODUCTVERSION 6,46,0,1
1717
FILEFLAGSMASK 0x3fL
1818
FILEFLAGS 0x0L
1919
FILEOS 0x40004L
@@ -26,12 +26,12 @@ BEGIN
2626
BEGIN
2727
VALUE "CompanyName", "QuickView"
2828
VALUE "FileDescription", "QuickView"
29-
VALUE "FileVersion", "6.46.0.0"
29+
VALUE "FileVersion", "6.46.0.1"
3030
VALUE "InternalName", "QuickView.exe"
3131
VALUE "LegalCopyright", "Copyright (C) 2026"
3232
VALUE "OriginalFilename", "QuickView.exe"
3333
VALUE "ProductName", "QuickView"
34-
VALUE "ProductVersion", "6.46.0.0"
34+
VALUE "ProductVersion", "6.46.0.1"
3535
END
3636
END
3737
BLOCK "VarFileInfo"

‎cmake/lld-link-wrapper.bat‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,15 +72,15 @@ echo [QuickViewLinker] LIB After = "!LIB!" >&2
7272
:: 3. Locate lld-link.exe dynamically
7373
set "LLVM_LINKER_EXE="
7474

75-
:: Priority 1: Standalone LLVM in standard locations
76-
if exist "C:\Program Files\LLVM\bin\lld-link.exe" set "LLVM_LINKER_EXE=C:\Program Files\LLVM\bin\lld-link.exe"
77-
if not defined LLVM_LINKER_EXE if exist "D:\Program Files\LLVM\bin\lld-link.exe" set "LLVM_LINKER_EXE=D:\Program Files\LLVM\bin\lld-link.exe"
78-
if not defined LLVM_LINKER_EXE if exist "C:\Program Files (x86)\LLVM\bin\lld-link.exe" set "LLVM_LINKER_EXE=C:\Program Files (x86)\LLVM\bin\lld-link.exe"
79-
80-
:: Priority 2: Visual Studio internal LLVM tools
75+
:: Priority 1: Visual Studio internal LLVM tools (guarantees bitcode version match with clang-cl)
8176
if not defined LLVM_LINKER_EXE if exist "!VS_PATH!\VC\Tools\Llvm\x64\bin\lld-link.exe" set "LLVM_LINKER_EXE=!VS_PATH!\VC\Tools\Llvm\x64\bin\lld-link.exe"
8277
if not defined LLVM_LINKER_EXE if exist "!VS_PATH!\VC\Tools\Llvm\bin\lld-link.exe" set "LLVM_LINKER_EXE=!VS_PATH!\VC\Tools\Llvm\bin\lld-link.exe"
8378

79+
:: Priority 2: Standalone LLVM in standard locations
80+
if not defined LLVM_LINKER_EXE if exist "C:\Program Files\LLVM\bin\lld-link.exe" set "LLVM_LINKER_EXE=C:\Program Files\LLVM\bin\lld-link.exe"
81+
if not defined LLVM_LINKER_EXE if exist "D:\Program Files\LLVM\bin\lld-link.exe" set "LLVM_LINKER_EXE=D:\Program Files\LLVM\bin\lld-link.exe"
82+
if not defined LLVM_LINKER_EXE if exist "C:\Program Files (x86)\LLVM\bin\lld-link.exe" set "LLVM_LINKER_EXE=C:\Program Files (x86)\LLVM\bin\lld-link.exe"
83+
8484
:: Priority 3: System PATH
8585
if not defined LLVM_LINKER_EXE (
8686
for /f "tokens=*" %%i in ('where lld-link.exe 2^>nul') do (

‎plugins/plugins_manifest.json‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"schema_version": "2.0",
3-
"updated_at": "2026-08-24",
3+
"updated_at": "2026-08-25",
44
"plugins": [
55
{
66
"id": "com.quickview.sr.ncnn_vulkan",
@@ -9,8 +9,11 @@
99
"author": "QuickView Core Team",
1010
"interface": "super_resolution",
1111
"description": "High-Performance In-Process Vulkan Compute Neural Super-Resolution Engine.",
12-
"download_url": "https://justnullname.github.io/QuickView/plugins/sr_ncnn_vulkan.zip",
13-
"file_name": "sr_ncnn_vulkan.zip",
12+
"download_url": "https://justnullname.github.io/QuickView/plugins/sr_ncnn_vulkan_AMD64.zip",
13+
"download_url_amd64": "https://justnullname.github.io/QuickView/plugins/sr_ncnn_vulkan_AMD64.zip",
14+
"download_url_arm64": "https://justnullname.github.io/QuickView/plugins/sr_ncnn_vulkan_ARM64.zip",
15+
"file_name": "sr_ncnn_vulkan_AMD64.zip",
16+
"file_name_arm64": "sr_ncnn_vulkan_ARM64.zip",
1417
"file_size": 2600000,
1518
"min_app_version": "0.1.0"
1619
}

0 commit comments

Comments
 (0)