Skip to content

ci: fix the Windows build so it produces & attaches the release zip - #22

Closed
arousi wants to merge 10 commits into
billysams21:devfrom
arousi:fix/ci-build
Closed

ci: fix the Windows build so it produces & attaches the release zip#22
arousi wants to merge 10 commits into
billysams21:devfrom
arousi:fix/ci-build

Conversation

@arousi

@arousi arousi commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Summary

The release build workflow failed on both v1.5.0 and v1.5.1, so the release zips had to be uploaded manually. Two fixes:

  1. Add permissions: contents: write — the release-attach step was failing with Resource not accessible by integration (403) because the default GITHUB_TOKEN is read-only.
  2. Resolve bundled Chromium via Playwright itself (p.chromium.executable_path) instead of a hand-rolled ms-playwright glob that returned nothing on the Chrome-for-Testing layout — the 'Playwright Chromium was not found' failure.

Stacked

On top of #21#20#19#18; merge in order (afterwards this PR's diff is just the workflow change).

Verifying

Best verified by running the workflow (it's workflow_dispatch-enabled) or on the next tag push.

arousi added 10 commits August 22, 2026 06:16
The old modal UpdateDownloaderDialog streamed the whole release zip while
flooding the GUI thread with per-chunk cross-thread progress calls; on a
large (205MB) release, concurrent with the live-graph update_ui, it could
crash the app mid-download.

Route updates through the existing, proven download engine instead:
- an available update is added to the normal queue as a DownloadTask
  (is_update); the user starts it and can pause/resume (Range-resume) it
  like any other download
- update tasks bypass the Cloudflare/CAPTCHA direct-link step and are never
  auto-extracted
- on completion the app offers Install now (restart) or Install on next
  open; a deferred update is applied via _check_pending_update on launch
- execute_update -> _apply_downloaded_update(zip_path): the robust
  extract -> robocopy swap -> marker-verify -> rollback flow is unchanged,
  it just consumes the already-downloaded zip

Removes the crash-prone modal download path entirely.
Root cause of the 'added but never progresses / connection timed out':
the queued update task ran through download_worker on a manager-spawned
thread and reused the shared curl_cffi self.dl_session. That session
(built on the main thread) hangs with curl (28) for a plain request that
never went through the nodriver/get_direct_link path first — normal
downloads work only because get_direct_link runs before the transfer.

Route update tasks through a dedicated _download_update_file() using urllib
(stdlib): supports Range-resume, pause/cancel, progress, and a 416
already-complete short-circuit. Confirmed progressing via the real manager
path where curl deterministically hung. Also stop a previously failed
update task from blocking a fresh re-offer.
Update downloads were written to a hidden ~/.silverspoon_updates folder, so
users couldn't find the completed file. Download to the same Save-To
directory as every other download (…/SilverSpoon Update <version>/), so it's
visible, consistent, and persists for an install-on-next-open.
Guard the completion prompt and the re-offer dedup on os.path.exists(filepath)
so a stale Completed update task (file deleted/moved) neither fires a phantom
install prompt nor blocks re-downloading.
…aNodes

Normalize the download path: any link whose host isn't a Turnstile/CAPTCHA
host now downloads straight over HTTP via urllib (the same robust path used
for app updates), with resume/pause/progress. FuckingFast and DataNodes
links still go through get_direct_link (the nodriver Turnstile solver) + the
curl transport exactly as before.

- add needs_resolution(link) + RESOLVER_HOSTS = (fuckingfast.co, datanodes.to)
- download_worker routes non-resolver hosts (and updates) to the renamed,
  now host-agnostic _download_direct_file()
- broaden the paste-box hint to mention direct URLs

Verified: general URL downloads without invoking the solver; a fuckingfast
link still invokes get_direct_link exactly once.
When the solver couldn't load the download page (Cloudflare/flagged IP, or a
host the dev-branch solver doesn't support), _resolve_direct_link_async did
close->respawn->navigate and, if that also failed, raised WITHOUT closing —
leaving a broken browser that the next call reused and re-spawned, so Chrome
kept spawning and never reached the page.

- wrap resolution in _resolve_with_cleanup: any failure tears the browser
  down (under the lock) so a broken instance is never reused
- don't auto-retry a CAPTCHA timeout (re-solving immediately just respawns
  the browser and rarely helps)

Manual test only (nodriver browser can't be exercised headlessly).
The STATUS pill width was purely text-based with no column clamp, so long
statuses (e.g. 'Solving CAPTCHA...') overflowed into the PROGRESS column.
Clamp the pill to the cell width and elide the label.
The build failed on v1.5.0/v1.5.1 (so release zips were uploaded manually):
- add 'permissions: contents: write' so the release-attach step can upload
  (was failing with 'Resource not accessible by integration')
- resolve bundled Chromium via Playwright's own executable_path instead of a
  fragile ms-playwright glob that found nothing on Chrome-for-Testing layouts
Add a post-build check that fails the workflow if SilverSpoon.exe, the
curl_cffi .dist-info metadata, or bundled chromium is missing — so a build
that would crash on launch (PackageNotFoundError: curl_cffi) can never be
zipped and shipped.
arousi pushed a commit to arousi/SilverSpoon that referenced this pull request Sep 8, 2026
…, status-pill, ci-build

Supersedes the earlier drafts on dev with the rebased PR branches (billysams21#18-billysams21#22 on
upstream), merged on top of v1.5.1. Tree is identical to main + the stack.
@arousi

arousi commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

Superseded by #27, which carries this change together with the other four fixes on top of v1.5.1 as a single PR from my fork's main.

@arousi arousi closed this Sep 8, 2026
@arousi
arousi deleted the fix/ci-build branch September 8, 2026 17:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant