Skip to content

Commit c8ff2d0

Browse files
committed
Prepare DL Studio v1.0.7
- Add Delphi upload validation for manual uploads - Update Cloud repository filtering, date navigation, and status handling - Refresh release workflow for macOS x64/arm64 installers and v1.0.7
1 parent 3549161 commit c8ff2d0

19 files changed

Lines changed: 1195 additions & 212 deletions

.github/workflows/release-installers.yml

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ on:
99
tag:
1010
description: "Release tag to upload installers to"
1111
required: true
12-
default: "v1.0.6"
12+
default: "v1.0.7"
1313

1414
permissions:
1515
contents: write
@@ -34,11 +34,24 @@ jobs:
3434
--repo "${{ github.repository }}"
3535
3636
mac:
37-
name: macOS arm64 installers
38-
runs-on: macos-14
37+
name: macOS ${{ matrix.arch }} installers
38+
runs-on: ${{ matrix.runner }}
3939
needs: release
40+
strategy:
41+
fail-fast: false
42+
matrix:
43+
include:
44+
- arch: arm64
45+
runner: macos-14
46+
ffprobe: ffprobe-arm64
47+
ffprobe_match: "Mach-O 64-bit executable arm64"
48+
- arch: x64
49+
runner: macos-13
50+
ffprobe: ffprobe-x64
51+
ffprobe_match: "Mach-O 64-bit executable x86_64"
4052
env:
4153
RELEASE_TAG: ${{ github.event.inputs.tag || github.ref_name }}
54+
npm_config_arch: ${{ matrix.arch }}
4255
defaults:
4356
run:
4457
working-directory: Mac
@@ -51,30 +64,31 @@ jobs:
5164
cache-dependency-path: Mac/package-lock.json
5265
- run: npm ci
5366
- run: npm run build
54-
- run: npx electron-builder --mac dmg pkg --arm64 --config.directories.output=release-upload
67+
- run: npx electron-builder --mac dmg pkg --${{ matrix.arch }} --config.directories.output=release-upload
5568
- name: Verify macOS bundled binaries
5669
run: |
57-
file "release-upload/mac-arm64/DL Studio.app/Contents/Resources/bin/ffmpeg"
58-
file "release-upload/mac-arm64/DL Studio.app/Contents/Resources/bin/ffprobe-arm64" | tee /tmp/ffprobe-file.txt
59-
grep -q "Mach-O 64-bit executable arm64" /tmp/ffprobe-file.txt
70+
file "release-upload/mac-${{ matrix.arch }}/DL Studio.app/Contents/Resources/bin/ffmpeg" | tee /tmp/ffmpeg-file.txt
71+
grep -q "${{ matrix.ffprobe_match }}" /tmp/ffmpeg-file.txt
72+
file "release-upload/mac-${{ matrix.arch }}/DL Studio.app/Contents/Resources/bin/${{ matrix.ffprobe }}" | tee /tmp/ffprobe-file.txt
73+
grep -q "${{ matrix.ffprobe_match }}" /tmp/ffprobe-file.txt
6074
- name: Upload macOS assets
6175
env:
6276
GH_TOKEN: ${{ github.token }}
6377
run: |
6478
version="$(node -p "require('./package.json').version")"
6579
gh release upload "$RELEASE_TAG" \
66-
"release-upload/DL-Studio-Mac-${version}-arm64.dmg" \
67-
"release-upload/DL-Studio-Mac-${version}-arm64.pkg" \
68-
"release-upload/DL-Studio-Mac-${version}-arm64.dmg.blockmap" \
80+
"release-upload/DL-Studio-Mac-${version}-${{ matrix.arch }}.dmg" \
81+
"release-upload/DL-Studio-Mac-${version}-${{ matrix.arch }}.pkg" \
82+
"release-upload/DL-Studio-Mac-${version}-${{ matrix.arch }}.dmg.blockmap" \
6983
--clobber \
7084
--repo "${{ github.repository }}"
7185
- name: Upload macOS installer artifact
7286
uses: actions/upload-artifact@v4
7387
with:
74-
name: mac-installers
88+
name: mac-${{ matrix.arch }}-installers
7589
path: |
76-
Mac/release-upload/DL-Studio-Mac-*-arm64.dmg
77-
Mac/release-upload/DL-Studio-Mac-*-arm64.pkg
90+
Mac/release-upload/DL-Studio-Mac-*-${{ matrix.arch }}.dmg
91+
Mac/release-upload/DL-Studio-Mac-*-${{ matrix.arch }}.pkg
7892
if-no-files-found: error
7993

8094
windows:
@@ -230,7 +244,8 @@ jobs:
230244
if lower.endswith(".exe") or "windows" in lower:
231245
return "win32", "x64", "windows"
232246
if lower.endswith((".dmg", ".pkg")) or "mac" in lower:
233-
return "darwin", "arm64", "mac"
247+
arch = "x64" if "x64" in lower or "x86_64" in lower else "arm64"
248+
return "darwin", arch, "mac"
234249
return "", "", "unknown"
235250
236251
assets = []

Mac/package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Mac/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "dl-studio-mac",
3-
"version": "1.0.6",
3+
"version": "1.0.7",
44
"private": true,
55
"description": "Desktop batch video downsampler for macOS.",
66
"main": "src/main/main.js",

Mac/scripts/app-shell.test.cjs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,9 +187,23 @@ assert.match(app, /activeNav === "Editor"/);
187187
assert.match(app, /activeNav === "Cloud"/);
188188
assert.match(app, /CloudRepository/);
189189
assert.match(app, /loadCloudRepository/);
190-
assert.match(app, /\/device\/files\?limit=50&include_page=true/);
190+
assert.match(app, /const CLOUD_REPOSITORY_PAGE_SIZE = 100/);
191+
assert.match(app, /const CLOUD_REPOSITORY_DEFAULT_MEDIA_FILTER_ID = "all"/);
192+
assert.match(app, /const CLOUD_REPOSITORY_DEFAULT_STATUS_FILTER_ID = "all_status"/);
193+
assert.match(app, /function buildCloudRepositoryPagePath/);
194+
assert.match(app, /page_mode: "cursor"/);
195+
assert.match(app, /params\.set\("start_timestamp_ms"/);
196+
assert.match(app, /params\.set\("end_timestamp_ms"/);
197+
assert.match(app, /params\.set\("parse_status"/);
198+
assert.match(app, /function getCloudRepositoryParseStatusParam/);
199+
assert.match(app, /function getCloudMediaFiltersForSpace/);
200+
assert.match(app, /function getCloudStatusFiltersForSpace/);
201+
assert.match(app, /\["all", "video", "audio"\]/);
202+
assert.match(app, /\["all_status", "parsed", "processing", "failed"\]/);
191203
assert.match(app, /const RAW_DATA_LIST_PATH = "\/memory\/raw-data"/);
192204
assert.match(app, /const RAW_DATA_VIDEO_UPLOAD_PATH = "\/memory\/raw-data\/videos"/);
205+
assert.match(app, /const DELPHI_UPLOAD_MAX_BYTES = 2 \* 1024 \* 1024 \* 1024/);
206+
assert.ok(app.includes("const DELPHI_UPLOAD_FILE_NAME_PATTERN = /^\\d{4}_\\d{2}_\\d{2}_\\d{2}_\\d{2}_\\d{2}\\.mp4$/i;"));
193207
assert.match(app, /deleteRawDataArchive/);
194208
assert.match(app, /getRawDataId/);
195209
assert.match(app, /repositoryState/);
@@ -208,6 +222,10 @@ assert.match(app, /restartFailed = true/);
208222
assert.match(app, /restartFailed: false/);
209223
assert.match(app, /retryTransferTask/);
210224
assert.match(app, /createTransferTask/);
225+
assert.match(app, /getManualDelphiUploadValidationError/);
226+
assert.match(app, /getManualDelphiUploadErrorMessage/);
227+
assert.match(app, / 2GB/);
228+
assert.match(app, /yyyy_mm_dd_hh_mm_ss\.mp4/);
211229
assert.match(app, /createJobFromTransferTask/);
212230
assert.match(app, /getTransferTaskUploadOptions/);
213231
assert.match(app, /getPendingAutomationTransferKinds/);
@@ -299,7 +317,9 @@ assert.match(app, /const CLOUD_FILTERS/);
299317
assert.match(app, /getCloudRepositoryStats/);
300318
assert.match(app, /cloudQuery/);
301319
assert.match(app, /cloudViewMode/);
302-
assert.match(app, /activeCloudFilter/);
320+
assert.match(app, /activeMediaFilter/);
321+
assert.match(app, /activeStatusFilter/);
322+
assert.match(app, /className="cloud-nav-group"/);
303323
assert.match(app, /className="cloud-drive"/);
304324
assert.match(app, /className="cloud-sidebar"/);
305325
assert.match(app, /className="cloud-search"/);

Mac/scripts/update-checker.test.cjs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@ const release = {
1616
name: "DL-Studio-Mac-1.2.0-arm64.dmg",
1717
browser_download_url: "https://github.com/infera-AI/DL-Editor/releases/download/v1.2.0/dmg"
1818
},
19+
{
20+
name: "DL-Studio-Mac-1.2.0-x64.pkg",
21+
browser_download_url: "https://github.com/infera-AI/DL-Editor/releases/download/v1.2.0/x64-pkg"
22+
},
23+
{
24+
name: "DL-Studio-Mac-1.2.0-x64.dmg",
25+
browser_download_url: "https://github.com/infera-AI/DL-Editor/releases/download/v1.2.0/x64-dmg"
26+
},
1927
{
2028
name: "DL-Studio-Windows-Setup-1.2.0.exe",
2129
browser_download_url: "https://github.com/infera-AI/DL-Editor/releases/download/v1.2.0/exe"
@@ -31,18 +39,29 @@ assert.equal(compareVersions("1.2.0", "1.1.9"), 1);
3139
assert.equal(compareVersions("v1.0.0", "1.0.0"), 0);
3240
assert.equal(compareVersions("1.0.0", "1.0.1"), -1);
3341

34-
assert.equal(selectDownloadAsset(release, "darwin").name, "DL-Studio-Mac-1.2.0-arm64.dmg");
42+
assert.equal(selectDownloadAsset(release, "darwin", "arm64").name, "DL-Studio-Mac-1.2.0-arm64.dmg");
43+
assert.equal(selectDownloadAsset(release, "darwin", "x64").name, "DL-Studio-Mac-1.2.0-x64.dmg");
3544
assert.equal(selectDownloadAsset(release, "win32").name, "DL-Studio-Windows-Setup-1.2.0.exe");
3645

3746
const macUpdate = buildUpdateResult({
3847
currentVersion: "1.0.0",
3948
platform: "darwin",
49+
arch: "arm64",
4050
release
4151
});
4252
assert.equal(macUpdate.status, "available");
4353
assert.equal(macUpdate.latestVersion, "1.2.0");
4454
assert.equal(macUpdate.downloadUrl, "https://github.com/infera-AI/DL-Editor/releases/download/v1.2.0/dmg");
4555

56+
const intelMacUpdate = buildUpdateResult({
57+
currentVersion: "1.0.0",
58+
platform: "darwin",
59+
arch: "x64",
60+
release
61+
});
62+
assert.equal(intelMacUpdate.status, "available");
63+
assert.equal(intelMacUpdate.downloadUrl, "https://github.com/infera-AI/DL-Editor/releases/download/v1.2.0/x64-dmg");
64+
4665
const current = buildUpdateResult({
4766
currentVersion: "1.2.0",
4867
platform: "win32",

Mac/src/main/main.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2926,6 +2926,15 @@ ipcMain.handle("videos:select", async () => {
29262926
return Promise.all(result.filePaths.map(getFileMetadata));
29272927
});
29282928

2929+
ipcMain.handle("videos:get-metadata", async (_event, filePath) => {
2930+
const normalizedPath = String(filePath || "").trim();
2931+
if (!normalizedPath) {
2932+
return null;
2933+
}
2934+
2935+
return getFileMetadata(normalizedPath);
2936+
});
2937+
29292938
ipcMain.handle("output:select-directory", async () => {
29302939
const result = await dialog.showOpenDialog(mainWindow, {
29312940
title: "Choose output folder",
@@ -2942,7 +2951,8 @@ ipcMain.handle("system:get-usage", async () => latestUsage || buildUsageSnapshot
29422951
ipcMain.handle("updates:check", async () =>
29432952
checkForUpdate({
29442953
currentVersion: app.getVersion(),
2945-
platform: process.platform
2954+
platform: process.platform,
2955+
arch: process.arch
29462956
})
29472957
);
29482958

Mac/src/main/preload.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const on = (channel, listener) => {
99
contextBridge.exposeInMainWorld("dlEditor", {
1010
platform: process.platform,
1111
selectVideos: () => ipcRenderer.invoke("videos:select"),
12+
getVideoMetadata: (filePath) => ipcRenderer.invoke("videos:get-metadata", filePath),
1213
selectOutputDirectory: () => ipcRenderer.invoke("output:select-directory"),
1314
getCapabilities: () => ipcRenderer.invoke("system:get-capabilities"),
1415
getUsage: () => ipcRenderer.invoke("system:get-usage"),

Mac/src/main/updateChecker.cjs

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const INFERA_API_BASE_URL = process.env.INFERA_API_BASE_URL || process.env.VITE_
44
const CLIENT_RELEASES_URL = `${INFERA_API_BASE_URL.replace(/\/+$/, "")}/client/releases`;
55
const LATEST_RELEASE_API_URL = `${CLIENT_RELEASES_URL}/latest`;
66
const RELEASES_URL = `${CLIENT_RELEASES_URL}/latest`;
7+
const UPDATE_CHECK_TIMEOUT_MS = 60000;
78

89
function normalizeVersion(value) {
910
return String(value || "")
@@ -31,15 +32,36 @@ function getReleaseVersion(release) {
3132
return normalizeVersion(release?.tag_name || release?.name);
3233
}
3334

34-
function scoreAsset(asset, platform) {
35-
const name = String(asset?.name || "").toLowerCase();
36-
if (!asset?.browser_download_url || name.endsWith(".blockmap") || name.endsWith(".yml")) return 0;
35+
function getAssetName(asset) {
36+
return String(asset?.name || asset?.assetName || "").toLowerCase();
37+
}
38+
39+
function getAssetDownloadUrl(asset) {
40+
return asset?.browser_download_url || asset?.downloadUrl || "";
41+
}
42+
43+
function getAssetArch(asset) {
44+
const arch = String(asset?.arch || "").toLowerCase();
45+
if (arch === "x64" || arch === "x86_64") return "x64";
46+
if (arch === "arm64" || arch === "aarch64") return "arm64";
47+
48+
const name = getAssetName(asset);
49+
if (name.includes("x64") || name.includes("x86_64")) return "x64";
50+
if (name.includes("arm64") || name.includes("aarch64")) return "arm64";
51+
return "";
52+
}
53+
54+
function scoreAsset(asset, platform, arch = process.arch) {
55+
const name = getAssetName(asset);
56+
if (!getAssetDownloadUrl(asset) || name.endsWith(".blockmap") || name.endsWith(".yml")) return 0;
3757

3858
if (platform === "darwin") {
39-
if ((name.includes("dl-studio-mac") || name.includes("dl-editor-mac")) && name.endsWith(".dmg")) return 30;
40-
if ((name.includes("dl-studio-mac") || name.includes("dl-editor-mac")) && name.endsWith(".pkg")) return 20;
41-
if (name.endsWith(".dmg")) return 10;
42-
if (name.endsWith(".pkg")) return 5;
59+
const assetArch = getAssetArch(asset);
60+
const archScore = !assetArch ? 1 : assetArch === arch ? 20 : -100;
61+
if ((name.includes("dl-studio-mac") || name.includes("dl-editor-mac")) && name.endsWith(".dmg")) return 30 + archScore;
62+
if ((name.includes("dl-studio-mac") || name.includes("dl-editor-mac")) && name.endsWith(".pkg")) return 20 + archScore;
63+
if (name.endsWith(".dmg")) return 10 + archScore;
64+
if (name.endsWith(".pkg")) return 5 + archScore;
4365
}
4466

4567
if (platform === "win32") {
@@ -51,13 +73,13 @@ function scoreAsset(asset, platform) {
5173
return 0;
5274
}
5375

54-
function selectDownloadAsset(release, platform = process.platform) {
76+
function selectDownloadAsset(release, platform = process.platform, arch = process.arch) {
5577
const assets = Array.isArray(release?.assets) ? release.assets : [];
5678
let selected = null;
5779
let selectedScore = 0;
5880

5981
for (const asset of assets) {
60-
const assetScore = scoreAsset(asset, platform);
82+
const assetScore = scoreAsset(asset, platform, arch);
6183
if (assetScore > selectedScore) {
6284
selected = asset;
6385
selectedScore = assetScore;
@@ -67,7 +89,7 @@ function selectDownloadAsset(release, platform = process.platform) {
6789
return selected;
6890
}
6991

70-
function buildUpdateResult({ currentVersion, platform = process.platform, release }) {
92+
function buildUpdateResult({ currentVersion, platform = process.platform, arch = process.arch, release }) {
7193
const latestVersion = getReleaseVersion(release);
7294
if (!latestVersion) {
7395
throw new Error("更新数据缺少版本号。");
@@ -88,16 +110,16 @@ function buildUpdateResult({ currentVersion, platform = process.platform, releas
88110
return { ...base, status: "latest" };
89111
}
90112

91-
const asset = selectDownloadAsset(release, platform);
113+
const asset = selectDownloadAsset(release, platform, arch);
92114
if (!asset) {
93115
return { ...base, status: "no_asset" };
94116
}
95117

96118
return {
97119
...base,
98120
status: "available",
99-
assetName: asset.name,
100-
downloadUrl: asset.browser_download_url
121+
assetName: asset.name || asset.assetName || "",
122+
downloadUrl: getAssetDownloadUrl(asset)
101123
};
102124
}
103125

@@ -123,7 +145,7 @@ function requestJson(url) {
123145
Accept: "application/vnd.github+json",
124146
"User-Agent": "DL-Studio-Updater"
125147
},
126-
timeout: 15000
148+
timeout: UPDATE_CHECK_TIMEOUT_MS
127149
},
128150
(response) => {
129151
let body = "";
@@ -155,7 +177,7 @@ function requestJson(url) {
155177
});
156178
}
157179

158-
async function checkForUpdate({ currentVersion, platform = process.platform, apiUrl = LATEST_RELEASE_API_URL } = {}) {
180+
async function checkForUpdate({ currentVersion, platform = process.platform, arch = process.arch, apiUrl = LATEST_RELEASE_API_URL } = {}) {
159181
let release;
160182
try {
161183
release = await requestJson(apiUrl);
@@ -166,11 +188,12 @@ async function checkForUpdate({ currentVersion, platform = process.platform, api
166188
throw error;
167189
}
168190

169-
return buildUpdateResult({ currentVersion, platform, release });
191+
return buildUpdateResult({ currentVersion, platform, arch, release });
170192
}
171193

172194
module.exports = {
173195
LATEST_RELEASE_API_URL,
196+
UPDATE_CHECK_TIMEOUT_MS,
174197
buildNoReleaseResult,
175198
buildUpdateResult,
176199
checkForUpdate,

0 commit comments

Comments
 (0)