mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-03-21 00:11:27 -07:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
f09c91494d
|
|||
|
58ec9b76e0
|
75
.github/workflows/release.yml
vendored
75
.github/workflows/release.yml
vendored
@@ -104,8 +104,6 @@ jobs:
|
||||
|
||||
- name: Build AppImage
|
||||
run: bun run build:appimage
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build unversioned AppImage
|
||||
run: |
|
||||
@@ -182,7 +180,6 @@ jobs:
|
||||
- name: Build signed + notarized macOS artifacts
|
||||
run: bun run build:mac
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
CSC_LINK: ${{ secrets.CSC_LINK }}
|
||||
CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }}
|
||||
APPLE_ID: ${{ secrets.APPLE_ID }}
|
||||
@@ -255,8 +252,6 @@ jobs:
|
||||
|
||||
- name: Build unsigned Windows artifacts
|
||||
run: bun run build:win
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Upload unsigned Windows artifact for SignPath
|
||||
id: upload-unsigned-windows-artifact
|
||||
@@ -268,8 +263,9 @@ jobs:
|
||||
release/*.zip
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Submit Windows signing request
|
||||
id: signpath-sign
|
||||
- name: Submit Windows signing request (attempt 1)
|
||||
id: signpath-sign-attempt-1
|
||||
continue-on-error: true
|
||||
uses: signpath/github-action-submit-signing-request@v2
|
||||
with:
|
||||
api-token: ${{ secrets.SIGNPATH_API_TOKEN }}
|
||||
@@ -278,16 +274,72 @@ jobs:
|
||||
signing-policy-slug: ${{ secrets.SIGNPATH_SIGNING_POLICY_SLUG }}
|
||||
github-artifact-id: ${{ steps.upload-unsigned-windows-artifact.outputs.artifact-id }}
|
||||
wait-for-completion: true
|
||||
output-artifact-directory: signed-windows
|
||||
output-artifact-directory: signed-windows-attempt-1
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Upload signed Windows artifacts
|
||||
- name: Submit Windows signing request (attempt 2)
|
||||
id: signpath-sign-attempt-2
|
||||
if: steps.signpath-sign-attempt-1.outcome == 'failure'
|
||||
continue-on-error: true
|
||||
uses: signpath/github-action-submit-signing-request@v2
|
||||
with:
|
||||
api-token: ${{ secrets.SIGNPATH_API_TOKEN }}
|
||||
organization-id: ${{ secrets.SIGNPATH_ORGANIZATION_ID }}
|
||||
project-slug: ${{ secrets.SIGNPATH_PROJECT_SLUG }}
|
||||
signing-policy-slug: ${{ secrets.SIGNPATH_SIGNING_POLICY_SLUG }}
|
||||
github-artifact-id: ${{ steps.upload-unsigned-windows-artifact.outputs.artifact-id }}
|
||||
wait-for-completion: true
|
||||
output-artifact-directory: signed-windows-attempt-2
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Submit Windows signing request (attempt 3)
|
||||
id: signpath-sign-attempt-3
|
||||
if: steps.signpath-sign-attempt-1.outcome == 'failure' && steps.signpath-sign-attempt-2.outcome == 'failure'
|
||||
continue-on-error: true
|
||||
uses: signpath/github-action-submit-signing-request@v2
|
||||
with:
|
||||
api-token: ${{ secrets.SIGNPATH_API_TOKEN }}
|
||||
organization-id: ${{ secrets.SIGNPATH_ORGANIZATION_ID }}
|
||||
project-slug: ${{ secrets.SIGNPATH_PROJECT_SLUG }}
|
||||
signing-policy-slug: ${{ secrets.SIGNPATH_SIGNING_POLICY_SLUG }}
|
||||
github-artifact-id: ${{ steps.upload-unsigned-windows-artifact.outputs.artifact-id }}
|
||||
wait-for-completion: true
|
||||
output-artifact-directory: signed-windows-attempt-3
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Fail when all SignPath signing attempts fail
|
||||
if: steps.signpath-sign-attempt-1.outcome == 'failure' && steps.signpath-sign-attempt-2.outcome == 'failure' && steps.signpath-sign-attempt-3.outcome == 'failure'
|
||||
shell: bash
|
||||
run: |
|
||||
echo "All SignPath signing attempts failed; rerun the workflow when SignPath is healthy."
|
||||
exit 1
|
||||
|
||||
- name: Upload signed Windows artifacts (attempt 1)
|
||||
if: steps.signpath-sign-attempt-1.outcome == 'success'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: windows
|
||||
path: |
|
||||
signed-windows/*.exe
|
||||
signed-windows/*.zip
|
||||
signed-windows-attempt-1/*.exe
|
||||
signed-windows-attempt-1/*.zip
|
||||
|
||||
- name: Upload signed Windows artifacts (attempt 2)
|
||||
if: steps.signpath-sign-attempt-2.outcome == 'success'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: windows
|
||||
path: |
|
||||
signed-windows-attempt-2/*.exe
|
||||
signed-windows-attempt-2/*.zip
|
||||
|
||||
- name: Upload signed Windows artifacts (attempt 3)
|
||||
if: steps.signpath-sign-attempt-3.outcome == 'success'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: windows
|
||||
path: |
|
||||
signed-windows-attempt-3/*.exe
|
||||
signed-windows-attempt-3/*.zip
|
||||
|
||||
release:
|
||||
needs: [build-linux, build-macos, build-windows]
|
||||
@@ -380,6 +432,7 @@ jobs:
|
||||
if gh release view "${{ steps.version.outputs.VERSION }}" >/dev/null 2>&1; then
|
||||
# Do not pass the prerelease flag here; gh defaults to a normal release.
|
||||
gh release edit "${{ steps.version.outputs.VERSION }}" \
|
||||
--draft=false \
|
||||
--title "${{ steps.version.outputs.VERSION }}" \
|
||||
--notes-file release/release-notes.md
|
||||
else
|
||||
|
||||
12
CHANGELOG.md
12
CHANGELOG.md
@@ -1,5 +1,17 @@
|
||||
# Changelog
|
||||
|
||||
## v0.5.1 (2026-03-09)
|
||||
|
||||
### Changed
|
||||
- Launcher: Removed the YouTube subtitle generation mode switch so YouTube playback always preloads subtitles before mpv starts.
|
||||
|
||||
### Fixed
|
||||
- Launcher: Hardened YouTube AI subtitle fixing so fenced SRT output and text-only one-cue-per-block responses can still be applied without losing original cue timing.
|
||||
- Launcher: Skipped AniSkip lookup during URL playback and YouTube subtitle-preload playback, limiting AniSkip to local file targets where it can actually resolve anime metadata.
|
||||
- Launcher: Keep the background SubMiner process running after a launcher-managed mpv session exits so the next mpv instance can reconnect without restarting the app.
|
||||
- Launcher: Reuse prior tokenization readiness after the background app is already warm so reopening a video does not pause again waiting for duplicate warmup completion.
|
||||
- Windows: Acquire the app single-instance lock earlier so Windows overlay/video launches reuse the running background SubMiner process instead of booting a second full app and repeating startup warmups.
|
||||
|
||||
## v0.3.0 (2026-03-05)
|
||||
- Added keyboard-driven Yomitan navigation and popup controls, including optional auto-pause.
|
||||
- Added subtitle/jump keyboard handling fixes for smoother subtitle playback control.
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
---
|
||||
id: TASK-134
|
||||
title: Harden Windows release signing against transient SignPath failures
|
||||
status: Done
|
||||
assignee:
|
||||
- codex
|
||||
created_date: '2026-03-09 00:00'
|
||||
updated_date: '2026-03-08 20:23'
|
||||
labels:
|
||||
- ci
|
||||
- release
|
||||
- windows
|
||||
- signing
|
||||
dependencies: []
|
||||
references:
|
||||
- .github/workflows/release.yml
|
||||
- package.json
|
||||
- src/release-workflow.test.ts
|
||||
- https://github.com/ksyasuda/SubMiner/actions/runs/22836585479
|
||||
priority: high
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
The tag-driven Release workflow currently fails the Windows lane if the SignPath connector returns transient 502 errors during submission, and the tagged build scripts also allow electron-builder to implicitly publish unsigned artifacts before the final release job runs. Harden the workflow so transient SignPath outages get bounded retries and release packaging never auto-publishes unsigned assets.
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [ ] #1 Windows release signing retries transient SignPath submission failures within the release workflow before failing the job.
|
||||
- [ ] #2 Release packaging scripts disable electron-builder implicit publish so build jobs do not upload unsigned assets on tag builds.
|
||||
- [ ] #3 Regression coverage fails if SignPath retry scaffolding or publish suppression is removed.
|
||||
<!-- AC:END -->
|
||||
|
||||
## Implementation Plan
|
||||
|
||||
<!-- SECTION:PLAN:BEGIN -->
|
||||
1. Add a regression test for the release workflow/package script shape covering SignPath retries and `--publish never`.
|
||||
2. Patch the Windows release job to retry SignPath submission a bounded number of times and still fail hard if every attempt fails.
|
||||
3. Update tagged package build scripts to disable implicit electron-builder publishing during release builds.
|
||||
4. Run targeted release-workflow verification and capture any remaining manual release cleanup needed for `v0.5.0`.
|
||||
<!-- SECTION:PLAN:END -->
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
<!-- SECTION:NOTES:BEGIN -->
|
||||
The failed Windows signing step in GitHub Actions run `22836585479` was not caused by missing secrets or an artifact-shape mismatch. The SignPath GitHub action retried repeated `502` responses from the SignPath connector for several minutes and then failed the job.
|
||||
|
||||
Hardened `.github/workflows/release.yml` by replacing the single SignPath submission with three bounded attempts. The second and third submissions only run if the previous attempt failed, and the job now fails with an explicit rerun message only after all three attempts fail. Signed-artifact upload is keyed to the successful attempt so the release job still consumes the normal `windows` artifact name.
|
||||
|
||||
Also fixed a separate release regression exposed by the same run: `electron-builder` was implicitly publishing unsigned release assets during tag builds because the packaging scripts did not set `--publish never` and the workflow injected `GH_TOKEN` into build jobs. Updated the relevant package scripts to pass `--publish never`, removed `GH_TOKEN` from the packaging jobs, and made the final publish step force `--draft=false` when editing an existing tag release so previously-created draft releases get published.
|
||||
|
||||
Verification: `bun test src/release-workflow.test.ts`, `bun run typecheck`, and `bun run test:fast` all passed locally after restoring the missing local `libsql` install with `bun install --frozen-lockfile`.
|
||||
<!-- SECTION:NOTES:END -->
|
||||
|
||||
## Final Summary
|
||||
|
||||
<!-- SECTION:FINAL_SUMMARY:BEGIN -->
|
||||
Windows release signing is now resilient to transient SignPath connector outages. The release workflow retries the SignPath submission up to three times before failing, and only uploads the signed Windows artifact from the attempt that succeeded.
|
||||
|
||||
Release packaging also no longer auto-publishes unsigned assets on tag builds. The `electron-builder` scripts now force `--publish never`, the build jobs no longer pass `GH_TOKEN` into packaging steps, and the final GitHub release publish step explicitly clears draft state when updating an existing tag release.
|
||||
|
||||
Validation: `bun test src/release-workflow.test.ts`, `bun run typecheck`, `bun run test:fast`.
|
||||
Manual follow-up for the failed `v0.5.0` release: rerun the `Release` workflow after merging/pushing this fix, then clean up the stray draft/untagged release assets created by the failed run if they remain.
|
||||
<!-- SECTION:FINAL_SUMMARY:END -->
|
||||
@@ -0,0 +1,57 @@
|
||||
---
|
||||
id: TASK-135
|
||||
title: Cut patch release v0.5.1 for Windows signing fix
|
||||
status: Done
|
||||
assignee:
|
||||
- codex
|
||||
created_date: '2026-03-08 20:24'
|
||||
updated_date: '2026-03-08 20:28'
|
||||
labels:
|
||||
- release
|
||||
- patch
|
||||
dependencies:
|
||||
- TASK-134
|
||||
references:
|
||||
- package.json
|
||||
- CHANGELOG.md
|
||||
- release/release-notes.md
|
||||
priority: high
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Publish a patch release from the workflow-signing fix on `main` by bumping the app version, generating the committed changelog artifacts for the new version, and pushing a new `v0.5.1` tag instead of rewriting the failed `v0.5.0` tag.
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [ ] #1 Repository version metadata is updated to `0.5.1`.
|
||||
- [ ] #2 `CHANGELOG.md` and `release/release-notes.md` contain the committed `v0.5.1` section and released fragments are removed.
|
||||
- [ ] #3 New `v0.5.1` commit and tag are pushed to `origin`.
|
||||
<!-- AC:END -->
|
||||
|
||||
## Implementation Plan
|
||||
|
||||
<!-- SECTION:PLAN:BEGIN -->
|
||||
1. Bump the package version to `0.5.1`.
|
||||
2. Run the changelog builder so `CHANGELOG.md`/`release-notes.md` match the release workflow contract.
|
||||
3. Run the relevant verification commands.
|
||||
4. Commit the release-prep changes, create `v0.5.1`, and push both commit and tag.
|
||||
<!-- SECTION:PLAN:END -->
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
<!-- SECTION:NOTES:BEGIN -->
|
||||
Bumped `package.json` from `0.5.0` to `0.5.1`, then ran `bun run changelog:build` so the committed release artifacts match the release workflow contract. That prepended the `v0.5.1` section to `CHANGELOG.md`, regenerated `release/release-notes.md`, and removed the consumed changelog fragments from `changes/`.
|
||||
|
||||
Verification before tagging: `bun run changelog:lint`, `bun run changelog:check --version 0.5.1`, `bun run typecheck`, and `bun run test:fast`.
|
||||
<!-- SECTION:NOTES:END -->
|
||||
|
||||
## Final Summary
|
||||
|
||||
<!-- SECTION:FINAL_SUMMARY:BEGIN -->
|
||||
Prepared patch release `v0.5.1` from the signing-workflow fix on `main` instead of rewriting the failed `v0.5.0` tag. Repository version metadata, changelog, and committed release notes are all aligned with the new release tag, and the consumed changelog fragments were removed.
|
||||
|
||||
Validation: `bun run changelog:lint`, `bun run changelog:check --version 0.5.1`, `bun run typecheck`, `bun run test:fast`.
|
||||
<!-- SECTION:FINAL_SUMMARY:END -->
|
||||
@@ -1,4 +0,0 @@
|
||||
type: fixed
|
||||
area: launcher
|
||||
|
||||
- Hardened YouTube AI subtitle fixing so fenced SRT output and text-only one-cue-per-block responses can still be applied without losing original cue timing.
|
||||
@@ -1,4 +0,0 @@
|
||||
type: fixed
|
||||
area: launcher
|
||||
|
||||
- Skipped AniSkip lookup during URL playback and YouTube subtitle-preload playback, limiting AniSkip to local file targets where it can actually resolve anime metadata.
|
||||
@@ -1,5 +0,0 @@
|
||||
type: fixed
|
||||
area: launcher
|
||||
|
||||
- Keep the background SubMiner process running after a launcher-managed mpv session exits so the next mpv instance can reconnect without restarting the app.
|
||||
- Reuse prior tokenization readiness after the background app is already warm so reopening a video does not pause again waiting for duplicate warmup completion.
|
||||
@@ -1,4 +0,0 @@
|
||||
type: fixed
|
||||
area: windows
|
||||
|
||||
- Acquire the app single-instance lock earlier so Windows overlay/video launches reuse the running background SubMiner process instead of booting a second full app and repeating startup warmups.
|
||||
@@ -1,4 +0,0 @@
|
||||
type: changed
|
||||
area: launcher
|
||||
|
||||
- Removed the YouTube subtitle generation mode switch so YouTube playback always preloads subtitles before mpv starts.
|
||||
12
package.json
12
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "subminer",
|
||||
"version": "0.5.0",
|
||||
"version": "0.5.1",
|
||||
"description": "All-in-one sentence mining overlay with AnkiConnect and dictionary integration",
|
||||
"packageManager": "bun@1.3.5",
|
||||
"main": "dist/main-entry.js",
|
||||
@@ -56,11 +56,11 @@
|
||||
"dev": "bun run build && electron . --start --dev",
|
||||
"stop": "electron . --stop",
|
||||
"toggle": "electron . --toggle",
|
||||
"build:appimage": "bun run build && electron-builder --linux AppImage",
|
||||
"build:mac": "bun run build && electron-builder --mac dmg zip",
|
||||
"build:mac:unsigned": "bun run build && env -u APPLE_ID -u APPLE_APP_SPECIFIC_PASSWORD -u APPLE_TEAM_ID -u CSC_LINK -u CSC_KEY_PASSWORD CSC_IDENTITY_AUTO_DISCOVERY=false electron-builder --mac dmg zip",
|
||||
"build:mac:zip": "bun run build && electron-builder --mac zip",
|
||||
"build:win": "bun run build && electron-builder --win nsis zip"
|
||||
"build:appimage": "bun run build && electron-builder --linux AppImage --publish never",
|
||||
"build:mac": "bun run build && electron-builder --mac dmg zip --publish never",
|
||||
"build:mac:unsigned": "bun run build && env -u APPLE_ID -u APPLE_APP_SPECIFIC_PASSWORD -u APPLE_TEAM_ID -u CSC_LINK -u CSC_KEY_PASSWORD CSC_IDENTITY_AUTO_DISCOVERY=false electron-builder --mac dmg zip --publish never",
|
||||
"build:mac:zip": "bun run build && electron-builder --mac zip --publish never",
|
||||
"build:win": "bun run build && electron-builder --win nsis zip --publish never"
|
||||
},
|
||||
"keywords": [
|
||||
"anki",
|
||||
|
||||
22
release/release-notes.md
Normal file
22
release/release-notes.md
Normal file
@@ -0,0 +1,22 @@
|
||||
## Highlights
|
||||
### Changed
|
||||
- Launcher: Removed the YouTube subtitle generation mode switch so YouTube playback always preloads subtitles before mpv starts.
|
||||
|
||||
### Fixed
|
||||
- Launcher: Hardened YouTube AI subtitle fixing so fenced SRT output and text-only one-cue-per-block responses can still be applied without losing original cue timing.
|
||||
- Launcher: Skipped AniSkip lookup during URL playback and YouTube subtitle-preload playback, limiting AniSkip to local file targets where it can actually resolve anime metadata.
|
||||
- Launcher: Keep the background SubMiner process running after a launcher-managed mpv session exits so the next mpv instance can reconnect without restarting the app.
|
||||
- Launcher: Reuse prior tokenization readiness after the background app is already warm so reopening a video does not pause again waiting for duplicate warmup completion.
|
||||
- Windows: Acquire the app single-instance lock earlier so Windows overlay/video launches reuse the running background SubMiner process instead of booting a second full app and repeating startup warmups.
|
||||
|
||||
## Installation
|
||||
|
||||
See the README and docs/installation guide for full setup steps.
|
||||
|
||||
## Assets
|
||||
|
||||
- Linux: `SubMiner.AppImage`
|
||||
- macOS: `SubMiner-*.dmg` and `SubMiner-*.zip`
|
||||
- Optional extras: `subminer-assets.tar.gz` and the `subminer` launcher
|
||||
|
||||
Note: the `subminer` wrapper script uses Bun (`#!/usr/bin/env bun`), so `bun` must be installed and on `PATH`.
|
||||
@@ -7,11 +7,19 @@ const releaseWorkflowPath = resolve(__dirname, '../.github/workflows/release.yml
|
||||
const releaseWorkflow = readFileSync(releaseWorkflowPath, 'utf8');
|
||||
const makefilePath = resolve(__dirname, '../Makefile');
|
||||
const makefile = readFileSync(makefilePath, 'utf8');
|
||||
const packageJsonPath = resolve(__dirname, '../package.json');
|
||||
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8')) as {
|
||||
scripts: Record<string, string>;
|
||||
};
|
||||
|
||||
test('publish release leaves prerelease unset so gh creates a normal release', () => {
|
||||
assert.ok(!releaseWorkflow.includes('--prerelease'));
|
||||
});
|
||||
|
||||
test('publish release forces an existing draft tag release to become public', () => {
|
||||
assert.ok(releaseWorkflow.includes('--draft=false'));
|
||||
});
|
||||
|
||||
test('release workflow verifies a committed changelog section before publish', () => {
|
||||
assert.match(releaseWorkflow, /bun run changelog:check/);
|
||||
});
|
||||
@@ -26,6 +34,19 @@ test('release workflow includes the Windows installer in checksums and uploaded
|
||||
assert.match(releaseWorkflow, /artifacts=\([\s\S]*release\/\*\.exe[\s\S]*release\/SHA256SUMS\.txt[\s\S]*\)/);
|
||||
});
|
||||
|
||||
test('release package scripts disable implicit electron-builder publishing', () => {
|
||||
assert.match(packageJson.scripts['build:appimage'] ?? '', /--publish never/);
|
||||
assert.match(packageJson.scripts['build:mac'] ?? '', /--publish never/);
|
||||
assert.match(packageJson.scripts['build:win'] ?? '', /--publish never/);
|
||||
});
|
||||
|
||||
test('windows release workflow retries SignPath submission and fails only after exhausting attempts', () => {
|
||||
assert.match(releaseWorkflow, /Submit Windows signing request \(attempt 1\)/);
|
||||
assert.match(releaseWorkflow, /Submit Windows signing request \(attempt 2\)/);
|
||||
assert.match(releaseWorkflow, /Submit Windows signing request \(attempt 3\)/);
|
||||
assert.match(releaseWorkflow, /All SignPath signing attempts failed; rerun the workflow when SignPath is healthy\./);
|
||||
});
|
||||
|
||||
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