mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-04-10 04:19:25 -07:00
Fix Windows release follow-up review items
This commit is contained in:
3
.github/workflows/release.yml
vendored
3
.github/workflows/release.yml
vendored
@@ -354,7 +354,7 @@ jobs:
|
|||||||
- name: Generate checksums
|
- name: Generate checksums
|
||||||
run: |
|
run: |
|
||||||
shopt -s nullglob
|
shopt -s nullglob
|
||||||
files=(release/*.AppImage release/*.dmg release/*.zip release/*.tar.gz dist/launcher/subminer)
|
files=(release/*.AppImage release/*.dmg release/*.exe release/*.zip release/*.tar.gz dist/launcher/subminer)
|
||||||
if [ "${#files[@]}" -eq 0 ]; then
|
if [ "${#files[@]}" -eq 0 ]; then
|
||||||
echo "No release artifacts found for checksum generation."
|
echo "No release artifacts found for checksum generation."
|
||||||
exit 1
|
exit 1
|
||||||
@@ -392,6 +392,7 @@ jobs:
|
|||||||
artifacts=(
|
artifacts=(
|
||||||
release/*.AppImage
|
release/*.AppImage
|
||||||
release/*.dmg
|
release/*.dmg
|
||||||
|
release/*.exe
|
||||||
release/*.zip
|
release/*.zip
|
||||||
release/*.tar.gz
|
release/*.tar.gz
|
||||||
release/SHA256SUMS.txt
|
release/SHA256SUMS.txt
|
||||||
|
|||||||
3
Makefile
3
Makefile
@@ -117,6 +117,7 @@ build:
|
|||||||
@case "$(PLATFORM)" in \
|
@case "$(PLATFORM)" in \
|
||||||
linux) $(MAKE) --no-print-directory build-linux ;; \
|
linux) $(MAKE) --no-print-directory build-linux ;; \
|
||||||
macos) $(MAKE) --no-print-directory build-macos ;; \
|
macos) $(MAKE) --no-print-directory build-macos ;; \
|
||||||
|
windows) printf '%s\n' "[INFO] Windows builds run via: bun run build:win" ;; \
|
||||||
*) printf '%s\n' "[ERROR] Unsupported OS for this Makefile target: $(PLATFORM)"; exit 1 ;; \
|
*) printf '%s\n' "[ERROR] Unsupported OS for this Makefile target: $(PLATFORM)"; exit 1 ;; \
|
||||||
esac
|
esac
|
||||||
|
|
||||||
@@ -236,7 +237,7 @@ install-plugin:
|
|||||||
@cp -R ./plugin/subminer/. "$(MPV_SCRIPTS_DIR)/subminer/"
|
@cp -R ./plugin/subminer/. "$(MPV_SCRIPTS_DIR)/subminer/"
|
||||||
@install -m 0644 "./$(PLUGIN_CONF)" "$(MPV_SCRIPT_OPTS_DIR)/subminer.conf"
|
@install -m 0644 "./$(PLUGIN_CONF)" "$(MPV_SCRIPT_OPTS_DIR)/subminer.conf"
|
||||||
@if [ "$(PLATFORM)" = "windows" ]; then \
|
@if [ "$(PLATFORM)" = "windows" ]; then \
|
||||||
node ./scripts/configure-plugin-binary-path.mjs "$(MPV_SCRIPT_OPTS_DIR)/subminer.conf" "$(CURDIR)" win32; \
|
bun ./scripts/configure-plugin-binary-path.mjs "$(MPV_SCRIPT_OPTS_DIR)/subminer.conf" "$(CURDIR)" win32; \
|
||||||
fi
|
fi
|
||||||
@printf '%s\n' "Installed to:" " $(MPV_SCRIPTS_DIR)/subminer/main.lua" " $(MPV_SCRIPTS_DIR)/subminer/" " $(MPV_SCRIPT_OPTS_DIR)/subminer.conf"
|
@printf '%s\n' "Installed to:" " $(MPV_SCRIPTS_DIR)/subminer/main.lua" " $(MPV_SCRIPTS_DIR)/subminer/" " $(MPV_SCRIPT_OPTS_DIR)/subminer.conf"
|
||||||
|
|
||||||
|
|||||||
@@ -249,17 +249,20 @@ try {
|
|||||||
local program_files_x86 = os.getenv("ProgramFiles(x86)") or "C:\\Program Files (x86)"
|
local program_files_x86 = os.getenv("ProgramFiles(x86)") or "C:\\Program Files (x86)"
|
||||||
local search_paths = {}
|
local search_paths = {}
|
||||||
|
|
||||||
add_search_path(search_paths, "/Applications/SubMiner.app/Contents/MacOS/SubMiner")
|
if environment.is_windows() then
|
||||||
add_search_path(search_paths, utils.join_path(home, "Applications", "SubMiner.app", "Contents", "MacOS", "SubMiner"))
|
add_search_path(search_paths, utils.join_path(app_data_local, "Programs", "SubMiner", "SubMiner.exe"))
|
||||||
add_search_path(search_paths, utils.join_path(app_data_local, "Programs", "SubMiner", "SubMiner.exe"))
|
add_search_path(search_paths, utils.join_path(local_app_data, "Programs", "SubMiner", "SubMiner.exe"))
|
||||||
add_search_path(search_paths, utils.join_path(local_app_data, "Programs", "SubMiner", "SubMiner.exe"))
|
add_search_path(search_paths, utils.join_path(program_files, "SubMiner", "SubMiner.exe"))
|
||||||
add_search_path(search_paths, utils.join_path(program_files, "SubMiner", "SubMiner.exe"))
|
add_search_path(search_paths, utils.join_path(program_files_x86, "SubMiner", "SubMiner.exe"))
|
||||||
add_search_path(search_paths, utils.join_path(program_files_x86, "SubMiner", "SubMiner.exe"))
|
add_search_path(search_paths, "C:\\SubMiner\\SubMiner.exe")
|
||||||
add_search_path(search_paths, "C:\\SubMiner\\SubMiner.exe")
|
else
|
||||||
add_search_path(search_paths, utils.join_path(home, ".local", "bin", "SubMiner.AppImage"))
|
add_search_path(search_paths, "/Applications/SubMiner.app/Contents/MacOS/SubMiner")
|
||||||
add_search_path(search_paths, "/opt/SubMiner/SubMiner.AppImage")
|
add_search_path(search_paths, utils.join_path(home, "Applications", "SubMiner.app", "Contents", "MacOS", "SubMiner"))
|
||||||
add_search_path(search_paths, "/usr/local/bin/SubMiner")
|
add_search_path(search_paths, utils.join_path(home, ".local", "bin", "SubMiner.AppImage"))
|
||||||
add_search_path(search_paths, "/usr/bin/SubMiner")
|
add_search_path(search_paths, "/opt/SubMiner/SubMiner.AppImage")
|
||||||
|
add_search_path(search_paths, "/usr/local/bin/SubMiner")
|
||||||
|
add_search_path(search_paths, "/usr/bin/SubMiner")
|
||||||
|
end
|
||||||
|
|
||||||
for _, path in ipairs(search_paths) do
|
for _, path in ipairs(search_paths) do
|
||||||
if file_exists(path) then
|
if file_exists(path) then
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ public static class SubMinerWindowsHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$matches = New-Object System.Collections.Generic.List[object]
|
$mpvMatches = New-Object System.Collections.Generic.List[object]
|
||||||
$foregroundWindow = [SubMinerWindowsHelper]::GetForegroundWindow()
|
$foregroundWindow = [SubMinerWindowsHelper]::GetForegroundWindow()
|
||||||
$callback = [SubMinerWindowsHelper+EnumWindowsProc]{
|
$callback = [SubMinerWindowsHelper+EnumWindowsProc]{
|
||||||
param([IntPtr]$hWnd, [IntPtr]$lParam)
|
param([IntPtr]$hWnd, [IntPtr]$lParam)
|
||||||
@@ -136,7 +136,7 @@ public static class SubMinerWindowsHelper {
|
|||||||
return $true
|
return $true
|
||||||
}
|
}
|
||||||
|
|
||||||
$matches.Add([PSCustomObject]@{
|
$mpvMatches.Add([PSCustomObject]@{
|
||||||
HWnd = $hWnd
|
HWnd = $hWnd
|
||||||
X = $bounds.X
|
X = $bounds.X
|
||||||
Y = $bounds.Y
|
Y = $bounds.Y
|
||||||
@@ -151,14 +151,14 @@ public static class SubMinerWindowsHelper {
|
|||||||
|
|
||||||
[void][SubMinerWindowsHelper]::EnumWindows($callback, [IntPtr]::Zero)
|
[void][SubMinerWindowsHelper]::EnumWindows($callback, [IntPtr]::Zero)
|
||||||
|
|
||||||
$focusedMatch = $matches | Where-Object { $_.IsForeground } | Select-Object -First 1
|
$focusedMatch = $mpvMatches | Where-Object { $_.IsForeground } | Select-Object -First 1
|
||||||
if ($null -ne $focusedMatch) {
|
if ($null -ne $focusedMatch) {
|
||||||
[Console]::Error.WriteLine('focus=focused')
|
[Console]::Error.WriteLine('focus=focused')
|
||||||
} else {
|
} else {
|
||||||
[Console]::Error.WriteLine('focus=not-focused')
|
[Console]::Error.WriteLine('focus=not-focused')
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($matches.Count -eq 0) {
|
if ($mpvMatches.Count -eq 0) {
|
||||||
Write-Output 'not-found'
|
Write-Output 'not-found'
|
||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
@@ -166,7 +166,7 @@ public static class SubMinerWindowsHelper {
|
|||||||
$bestMatch = if ($null -ne $focusedMatch) {
|
$bestMatch = if ($null -ne $focusedMatch) {
|
||||||
$focusedMatch
|
$focusedMatch
|
||||||
} else {
|
} else {
|
||||||
$matches | Sort-Object -Property Area, Width, Height -Descending | Select-Object -First 1
|
$mpvMatches | Sort-Object -Property Area, Width, Height -Descending | Select-Object -First 1
|
||||||
}
|
}
|
||||||
Write-Output "$($bestMatch.X),$($bestMatch.Y),$($bestMatch.Width),$($bestMatch.Height)"
|
Write-Output "$($bestMatch.X),$($bestMatch.Y),$($bestMatch.Width),$($bestMatch.Height)"
|
||||||
} catch {
|
} catch {
|
||||||
|
|||||||
@@ -203,3 +203,47 @@ test('setup service reflects detected Windows mpv shortcuts before preferences a
|
|||||||
assert.equal(snapshot.windowsMpvShortcuts.desktopInstalled, true);
|
assert.equal(snapshot.windowsMpvShortcuts.desktopInstalled, true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('setup service persists Windows mpv shortcut preferences and status with one state write', async () => {
|
||||||
|
await withTempDir(async (root) => {
|
||||||
|
const configDir = path.join(root, 'SubMiner');
|
||||||
|
fs.mkdirSync(configDir, { recursive: true });
|
||||||
|
fs.writeFileSync(path.join(configDir, 'config.jsonc'), '{}');
|
||||||
|
const stateChanges: string[] = [];
|
||||||
|
|
||||||
|
const service = createFirstRunSetupService({
|
||||||
|
platform: 'win32',
|
||||||
|
configDir,
|
||||||
|
getYomitanDictionaryCount: async () => 0,
|
||||||
|
detectPluginInstalled: () => false,
|
||||||
|
installPlugin: async () => ({
|
||||||
|
ok: true,
|
||||||
|
pluginInstallStatus: 'installed',
|
||||||
|
pluginInstallPathSummary: null,
|
||||||
|
message: 'ok',
|
||||||
|
}),
|
||||||
|
applyWindowsMpvShortcuts: async () => ({
|
||||||
|
ok: true,
|
||||||
|
status: 'installed',
|
||||||
|
message: 'shortcuts updated',
|
||||||
|
}),
|
||||||
|
onStateChanged: (state) => {
|
||||||
|
stateChanges.push(state.windowsMpvShortcutLastStatus);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await service.ensureSetupStateInitialized();
|
||||||
|
stateChanges.length = 0;
|
||||||
|
|
||||||
|
const snapshot = await service.configureWindowsMpvShortcuts({
|
||||||
|
startMenuEnabled: false,
|
||||||
|
desktopEnabled: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.equal(snapshot.windowsMpvShortcuts.startMenuEnabled, false);
|
||||||
|
assert.equal(snapshot.windowsMpvShortcuts.desktopEnabled, true);
|
||||||
|
assert.equal(snapshot.state.windowsMpvShortcutLastStatus, 'installed');
|
||||||
|
assert.equal(snapshot.message, 'shortcuts updated');
|
||||||
|
assert.deepEqual(stateChanges, ['installed']);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -294,20 +294,23 @@ export function createFirstRunSetupService(deps: {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
configureWindowsMpvShortcuts: async (preferences) => {
|
configureWindowsMpvShortcuts: async (preferences) => {
|
||||||
const nextState = writeState({
|
|
||||||
...readState(),
|
|
||||||
windowsMpvShortcutPreferences: {
|
|
||||||
startMenuEnabled: preferences.startMenuEnabled,
|
|
||||||
desktopEnabled: preferences.desktopEnabled,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
if (!isWindows || !deps.applyWindowsMpvShortcuts) {
|
if (!isWindows || !deps.applyWindowsMpvShortcuts) {
|
||||||
return refreshWithState(nextState, null);
|
return refreshWithState(
|
||||||
|
writeState({
|
||||||
|
...readState(),
|
||||||
|
windowsMpvShortcutPreferences: {
|
||||||
|
startMenuEnabled: preferences.startMenuEnabled,
|
||||||
|
desktopEnabled: preferences.desktopEnabled,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
null,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
const result = await deps.applyWindowsMpvShortcuts(preferences);
|
const result = await deps.applyWindowsMpvShortcuts(preferences);
|
||||||
|
const latestState = readState();
|
||||||
return refreshWithState(
|
return refreshWithState(
|
||||||
writeState({
|
writeState({
|
||||||
...readState(),
|
...latestState,
|
||||||
windowsMpvShortcutPreferences: {
|
windowsMpvShortcutPreferences: {
|
||||||
startMenuEnabled: preferences.startMenuEnabled,
|
startMenuEnabled: preferences.startMenuEnabled,
|
||||||
desktopEnabled: preferences.desktopEnabled,
|
desktopEnabled: preferences.desktopEnabled,
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import { resolve } from 'node:path';
|
|||||||
|
|
||||||
const releaseWorkflowPath = resolve(__dirname, '../.github/workflows/release.yml');
|
const releaseWorkflowPath = resolve(__dirname, '../.github/workflows/release.yml');
|
||||||
const releaseWorkflow = readFileSync(releaseWorkflowPath, 'utf8');
|
const releaseWorkflow = readFileSync(releaseWorkflowPath, 'utf8');
|
||||||
|
const makefilePath = resolve(__dirname, '../Makefile');
|
||||||
|
const makefile = readFileSync(makefilePath, 'utf8');
|
||||||
|
|
||||||
test('publish release leaves prerelease unset so gh creates a normal release', () => {
|
test('publish release leaves prerelease unset so gh creates a normal release', () => {
|
||||||
assert.ok(!releaseWorkflow.includes('--prerelease'));
|
assert.ok(!releaseWorkflow.includes('--prerelease'));
|
||||||
@@ -18,3 +20,13 @@ test('release workflow generates release notes from committed changelog output',
|
|||||||
assert.match(releaseWorkflow, /bun run changelog:release-notes/);
|
assert.match(releaseWorkflow, /bun run changelog:release-notes/);
|
||||||
assert.ok(!releaseWorkflow.includes('git log --pretty=format:"- %s"'));
|
assert.ok(!releaseWorkflow.includes('git log --pretty=format:"- %s"'));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('release workflow includes the Windows installer in checksums and uploaded assets', () => {
|
||||||
|
assert.match(releaseWorkflow, /files=\(release\/\*\.AppImage release\/\*\.dmg release\/\*\.exe release\/\*\.zip release\/\*\.tar\.gz dist\/launcher\/subminer\)/);
|
||||||
|
assert.match(releaseWorkflow, /artifacts=\([\s\S]*release\/\*\.exe[\s\S]*release\/SHA256SUMS\.txt[\s\S]*\)/);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Makefile routes Windows install-plugin setup through bun and documents Windows builds', () => {
|
||||||
|
assert.match(makefile, /windows\) printf '%s\\n' "\[INFO\] Windows builds run via: bun run build:win" ;;/);
|
||||||
|
assert.match(makefile, /bun \.\/scripts\/configure-plugin-binary-path\.mjs/);
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user