4 Commits

Author SHA1 Message Date
7b5ab3294d chore: cut v0.5.2 release 2026-03-08 20:46:16 -07:00
2bbf38f987 fix: pin signpath artifact configuration 2026-03-08 20:44:00 -07:00
f09c91494d chore: cut v0.5.1 release 2026-03-08 20:28:16 -07:00
58ec9b76e0 fix: harden windows release signing workflow 2026-03-08 20:24:47 -07:00
14 changed files with 374 additions and 39 deletions

View File

@@ -104,8 +104,6 @@ jobs:
- name: Build AppImage - name: Build AppImage
run: bun run build:appimage run: bun run build:appimage
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build unversioned AppImage - name: Build unversioned AppImage
run: | run: |
@@ -182,7 +180,6 @@ jobs:
- name: Build signed + notarized macOS artifacts - name: Build signed + notarized macOS artifacts
run: bun run build:mac run: bun run build:mac
env: env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CSC_LINK: ${{ secrets.CSC_LINK }} CSC_LINK: ${{ secrets.CSC_LINK }}
CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }} CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }}
APPLE_ID: ${{ secrets.APPLE_ID }} APPLE_ID: ${{ secrets.APPLE_ID }}
@@ -227,7 +224,7 @@ jobs:
shell: bash shell: bash
run: | run: |
missing=0 missing=0
for name in SIGNPATH_API_TOKEN SIGNPATH_ORGANIZATION_ID SIGNPATH_PROJECT_SLUG SIGNPATH_SIGNING_POLICY_SLUG; do for name in SIGNPATH_API_TOKEN SIGNPATH_ORGANIZATION_ID SIGNPATH_PROJECT_SLUG SIGNPATH_SIGNING_POLICY_SLUG SIGNPATH_ARTIFACT_CONFIGURATION_SLUG; do
if [ -z "${!name}" ]; then if [ -z "${!name}" ]; then
echo "Missing required secret: $name" echo "Missing required secret: $name"
missing=1 missing=1
@@ -242,6 +239,7 @@ jobs:
SIGNPATH_ORGANIZATION_ID: ${{ secrets.SIGNPATH_ORGANIZATION_ID }} SIGNPATH_ORGANIZATION_ID: ${{ secrets.SIGNPATH_ORGANIZATION_ID }}
SIGNPATH_PROJECT_SLUG: ${{ secrets.SIGNPATH_PROJECT_SLUG }} SIGNPATH_PROJECT_SLUG: ${{ secrets.SIGNPATH_PROJECT_SLUG }}
SIGNPATH_SIGNING_POLICY_SLUG: ${{ secrets.SIGNPATH_SIGNING_POLICY_SLUG }} SIGNPATH_SIGNING_POLICY_SLUG: ${{ secrets.SIGNPATH_SIGNING_POLICY_SLUG }}
SIGNPATH_ARTIFACT_CONFIGURATION_SLUG: ${{ secrets.SIGNPATH_ARTIFACT_CONFIGURATION_SLUG }}
- name: Install dependencies - name: Install dependencies
run: bun install --frozen-lockfile run: bun install --frozen-lockfile
@@ -255,8 +253,6 @@ jobs:
- name: Build unsigned Windows artifacts - name: Build unsigned Windows artifacts
run: bun run build:win run: bun run build:win
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload unsigned Windows artifact for SignPath - name: Upload unsigned Windows artifact for SignPath
id: upload-unsigned-windows-artifact id: upload-unsigned-windows-artifact
@@ -268,26 +264,86 @@ jobs:
release/*.zip release/*.zip
if-no-files-found: error if-no-files-found: error
- name: Submit Windows signing request - name: Submit Windows signing request (attempt 1)
id: signpath-sign id: signpath-sign-attempt-1
continue-on-error: true
uses: signpath/github-action-submit-signing-request@v2 uses: signpath/github-action-submit-signing-request@v2
with: with:
api-token: ${{ secrets.SIGNPATH_API_TOKEN }} api-token: ${{ secrets.SIGNPATH_API_TOKEN }}
organization-id: ${{ secrets.SIGNPATH_ORGANIZATION_ID }} organization-id: ${{ secrets.SIGNPATH_ORGANIZATION_ID }}
project-slug: ${{ secrets.SIGNPATH_PROJECT_SLUG }} project-slug: ${{ secrets.SIGNPATH_PROJECT_SLUG }}
signing-policy-slug: ${{ secrets.SIGNPATH_SIGNING_POLICY_SLUG }} signing-policy-slug: ${{ secrets.SIGNPATH_SIGNING_POLICY_SLUG }}
artifact-configuration-slug: ${{ secrets.SIGNPATH_ARTIFACT_CONFIGURATION_SLUG }}
github-artifact-id: ${{ steps.upload-unsigned-windows-artifact.outputs.artifact-id }} github-artifact-id: ${{ steps.upload-unsigned-windows-artifact.outputs.artifact-id }}
wait-for-completion: true wait-for-completion: true
output-artifact-directory: signed-windows output-artifact-directory: signed-windows-attempt-1
github-token: ${{ secrets.GITHUB_TOKEN }} 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 }}
artifact-configuration-slug: ${{ secrets.SIGNPATH_ARTIFACT_CONFIGURATION_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 }}
artifact-configuration-slug: ${{ secrets.SIGNPATH_ARTIFACT_CONFIGURATION_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 uses: actions/upload-artifact@v4
with: with:
name: windows name: windows
path: | path: |
signed-windows/*.exe signed-windows-attempt-1/*.exe
signed-windows/*.zip 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: release:
needs: [build-linux, build-macos, build-windows] needs: [build-linux, build-macos, build-windows]
@@ -380,6 +436,7 @@ jobs:
if gh release view "${{ steps.version.outputs.VERSION }}" >/dev/null 2>&1; then 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. # Do not pass the prerelease flag here; gh defaults to a normal release.
gh release edit "${{ steps.version.outputs.VERSION }}" \ gh release edit "${{ steps.version.outputs.VERSION }}" \
--draft=false \
--title "${{ steps.version.outputs.VERSION }}" \ --title "${{ steps.version.outputs.VERSION }}" \
--notes-file release/release-notes.md --notes-file release/release-notes.md
else else

View File

@@ -1,5 +1,22 @@
# Changelog # Changelog
## v0.5.2 (2026-03-09)
### Internal
- Release: Pinned the Windows SignPath submission workflow to an explicit artifact-configuration slug instead of relying on the SignPath project's default configuration.
## 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) ## v0.3.0 (2026-03-05)
- Added keyboard-driven Yomitan navigation and popup controls, including optional auto-pause. - Added keyboard-driven Yomitan navigation and popup controls, including optional auto-pause.
- Added subtitle/jump keyboard handling fixes for smoother subtitle playback control. - Added subtitle/jump keyboard handling fixes for smoother subtitle playback control.

View File

@@ -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 -->

View File

@@ -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 -->

View File

@@ -0,0 +1,61 @@
---
id: TASK-136
title: Pin SignPath artifact configuration in release workflow
status: Done
assignee:
- codex
created_date: '2026-03-08 20:41'
updated_date: '2026-03-08 20:58'
labels:
- ci
- release
- windows
- signing
dependencies:
- TASK-134
references:
- .github/workflows/release.yml
- build/signpath-windows-artifact-config.xml
- src/release-workflow.test.ts
priority: high
---
## Description
<!-- SECTION:DESCRIPTION:BEGIN -->
The Windows release workflow currently relies on the default SignPath artifact configuration configured in the SignPath UI. Pin the workflow to an explicit artifact-configuration slug so the checked-in signing configuration and CI behavior stay deterministic across future SignPath project changes.
<!-- SECTION:DESCRIPTION:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [ ] #1 The Windows release workflow validates a dedicated SignPath artifact-configuration secret/input.
- [ ] #2 Every SignPath submission attempt passes `artifact-configuration-slug`.
- [ ] #3 Regression coverage fails if the explicit SignPath artifact-configuration binding is removed.
<!-- AC:END -->
## Implementation Plan
<!-- SECTION:PLAN:BEGIN -->
1. Add a failing workflow regression test for the explicit SignPath artifact-configuration slug.
2. Patch the Windows signing secret validation and SignPath action inputs to require the slug.
3. Run targeted release-workflow verification plus the standard fast lane.
4. Cut a new patch release so the tag-triggered release workflow runs with the pinned SignPath configuration.
<!-- SECTION:PLAN:END -->
## Implementation Notes
<!-- SECTION:NOTES:BEGIN -->
Added regression coverage in `src/release-workflow.test.ts` for an explicit SignPath artifact-configuration slug so the release workflow test now fails if the slug validation or action input is removed.
Patched `.github/workflows/release.yml` so Windows signing now requires `SIGNPATH_ARTIFACT_CONFIGURATION_SLUG` during secret validation and passes `artifact-configuration-slug: ${{ secrets.SIGNPATH_ARTIFACT_CONFIGURATION_SLUG }}` on every SignPath submission attempt.
Verification: `bun test src/release-workflow.test.ts`, `bun run typecheck`, `bun run test:fast`.
<!-- SECTION:NOTES:END -->
## Final Summary
<!-- SECTION:FINAL_SUMMARY:BEGIN -->
The release workflow is now pinned to an explicit SignPath artifact configuration instead of relying on whichever SignPath artifact config is marked default in the UI. Windows signing secret validation fails fast if `SIGNPATH_ARTIFACT_CONFIGURATION_SLUG` is missing, and every SignPath submission attempt now includes the pinned slug.
Validation: `bun test src/release-workflow.test.ts`, `bun run typecheck`, `bun run test:fast`.
<!-- SECTION:FINAL_SUMMARY:END -->

View File

@@ -0,0 +1,57 @@
---
id: TASK-137
title: Cut patch release v0.5.2 for SignPath artifact config pinning
status: Done
assignee:
- codex
created_date: '2026-03-08 20:44'
updated_date: '2026-03-08 20:58'
labels:
- release
- patch
dependencies:
- TASK-136
references:
- package.json
- CHANGELOG.md
- release/release-notes.md
priority: high
---
## Description
<!-- SECTION:DESCRIPTION:BEGIN -->
Publish a patch release from the SignPath artifact-configuration pinning change by bumping the app version, generating the committed changelog artifacts for the new version, and pushing a new `v0.5.2` tag.
<!-- SECTION:DESCRIPTION:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [ ] #1 Repository version metadata is updated to `0.5.2`.
- [ ] #2 `CHANGELOG.md` and `release/release-notes.md` contain the committed `v0.5.2` section and consumed fragments are removed.
- [ ] #3 New `v0.5.2` commit and tag are pushed to `origin`.
<!-- AC:END -->
## Implementation Plan
<!-- SECTION:PLAN:BEGIN -->
1. Add the release fragment for the SignPath configuration pinning change.
2. Bump `package.json` to `0.5.2` and run the changelog builder.
3. Run changelog/typecheck/test verification.
4. Commit the release-prep change set, create `v0.5.2`, and push commit plus tag.
<!-- SECTION:PLAN:END -->
## Implementation Notes
<!-- SECTION:NOTES:BEGIN -->
Bumped `package.json` from `0.5.1` to `0.5.2`, ran `bun run changelog:build`, and committed the generated release artifacts. That prepended the `v0.5.2` section to `CHANGELOG.md`, regenerated `release/release-notes.md`, and removed the consumed `changes/signpath-artifact-config-pin.md` fragment.
Verification before tagging: `bun run changelog:lint`, `bun run changelog:check --version 0.5.2`, `bun run typecheck`, and `bun run test:fast`.
<!-- SECTION:NOTES:END -->
## Final Summary
<!-- SECTION:FINAL_SUMMARY:BEGIN -->
Prepared patch release `v0.5.2` so the explicit SignPath artifact-configuration pin ships on a fresh release tag. Version metadata, committed changelog artifacts, and release notes are aligned with the new patch version.
Validation: `bun run changelog:lint`, `bun run changelog:check --version 0.5.2`, `bun run typecheck`, `bun run test:fast`.
<!-- SECTION:FINAL_SUMMARY:END -->

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -1,4 +0,0 @@
type: changed
area: launcher
- Removed the YouTube subtitle generation mode switch so YouTube playback always preloads subtitles before mpv starts.

View File

@@ -1,6 +1,6 @@
{ {
"name": "subminer", "name": "subminer",
"version": "0.5.0", "version": "0.5.2",
"description": "All-in-one sentence mining overlay with AnkiConnect and dictionary integration", "description": "All-in-one sentence mining overlay with AnkiConnect and dictionary integration",
"packageManager": "bun@1.3.5", "packageManager": "bun@1.3.5",
"main": "dist/main-entry.js", "main": "dist/main-entry.js",
@@ -56,11 +56,11 @@
"dev": "bun run build && electron . --start --dev", "dev": "bun run build && electron . --start --dev",
"stop": "electron . --stop", "stop": "electron . --stop",
"toggle": "electron . --toggle", "toggle": "electron . --toggle",
"build:appimage": "bun run build && electron-builder --linux AppImage", "build:appimage": "bun run build && electron-builder --linux AppImage --publish never",
"build:mac": "bun run build && electron-builder --mac dmg zip", "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", "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", "build:mac:zip": "bun run build && electron-builder --mac zip --publish never",
"build:win": "bun run build && electron-builder --win nsis zip" "build:win": "bun run build && electron-builder --win nsis zip --publish never"
}, },
"keywords": [ "keywords": [
"anki", "anki",

15
release/release-notes.md Normal file
View File

@@ -0,0 +1,15 @@
## Highlights
### Internal
- Release: Pinned the Windows SignPath submission workflow to an explicit artifact-configuration slug instead of relying on the SignPath project's default configuration.
## 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`.

View File

@@ -7,11 +7,19 @@ const releaseWorkflowPath = resolve(__dirname, '../.github/workflows/release.yml
const releaseWorkflow = readFileSync(releaseWorkflowPath, 'utf8'); const releaseWorkflow = readFileSync(releaseWorkflowPath, 'utf8');
const makefilePath = resolve(__dirname, '../Makefile'); const makefilePath = resolve(__dirname, '../Makefile');
const makefile = readFileSync(makefilePath, 'utf8'); 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', () => { test('publish release leaves prerelease unset so gh creates a normal release', () => {
assert.ok(!releaseWorkflow.includes('--prerelease')); 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', () => { test('release workflow verifies a committed changelog section before publish', () => {
assert.match(releaseWorkflow, /bun run changelog:check/); assert.match(releaseWorkflow, /bun run changelog:check/);
}); });
@@ -26,6 +34,24 @@ 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]*\)/); 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('windows release workflow pins the SignPath artifact configuration slug explicitly', () => {
assert.match(releaseWorkflow, /SIGNPATH_ARTIFACT_CONFIGURATION_SLUG/);
assert.match(releaseWorkflow, /artifact-configuration-slug: \$\{\{ secrets\.SIGNPATH_ARTIFACT_CONFIGURATION_SLUG \}\}/);
});
test('Makefile routes Windows install-plugin setup through bun and documents Windows builds', () => { 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, /windows\) printf '%s\\n' "\[INFO\] Windows builds run via: bun run build:win" ;;/);
assert.match(makefile, /bun \.\/scripts\/configure-plugin-binary-path\.mjs/); assert.match(makefile, /bun \.\/scripts\/configure-plugin-binary-path\.mjs/);