9.6 KiB
GitHub releases, CI, and the update detector
BetterSEQTA+ is distributed on the Chrome Web Store and Firefox Add-ons, but some users sideload builds from GitHub. This document explains how automated builds, releases, and the in-extension update badge work.
All published releases target the upstream repository: BetterSEQTA/BetterSEQTA-Plus.
Overview
flowchart TB
subgraph ci [Continuous integration]
PrCi[pr-ci.yml — every PR]
Mvp[mvp.yml — push to main]
end
subgraph releases [GitHub releases]
Manual[release.yml — manual stable]
Nightly[nightly.yml — daily cron]
end
subgraph output [Outputs]
Zips["betterseqtaplus-VERSION-chrome.zip\nbetterseqtaplus-VERSION-firefox.zip"]
GhStable["Release tag: 3.7.0"]
GhNightly["Release tag: nightly"]
Badge[Update badge in settings]
end
PrCi -->|build only| NoRelease[No release]
Mvp -->|artifact| DistZip[dist.zip artifact]
Manual --> Zips
Manual --> GhStable
Manual --> Badge
Nightly --> Zips
Nightly --> GhNightly
Nightly --> Badge
| Workflow | Trigger | Creates a release? | Update detector in build? |
|---|---|---|---|
pr-ci.yml |
Every pull request to main |
No | No |
mvp.yml |
Every push to main |
No | No |
release.yml |
Manual (workflow_dispatch) |
Yes — stable version tag | Yes — stable channel |
nightly.yml |
Daily at 03:00 UTC + manual | Yes — reuses nightly tag |
Yes — nightly channel |
Shared build action
All release and CI builds that need packaged extensions use the composite action at .github/actions/build-extension/action.yml.
It:
- Installs dependencies (
npm install --legacy-peer-deps) - Runs
npm run build(Chrome then Firefox via Vite) - Zips each unpacked folder into sideload-ready archives:
dist/betterseqtaplus-{version}-chrome.zipdist/betterseqtaplus-{version}-firefox.zip
The {version} comes from package.json.
Build-time flags (release builds only)
Release and nightly workflows pass environment variables into Vite, which bakes them into the extension at compile time via define in vite.config.ts:
| Variable | Stable release | Nightly | PR / local dev |
|---|---|---|---|
GH_RELEASE_UPDATE_CHECK |
true |
true |
false / unset |
UPDATE_CHANNEL |
stable |
nightly |
stable (unused) |
GH_RELEASE_REPO |
BetterSEQTA/BetterSEQTA-Plus |
same | same |
BUILD_LABEL |
empty | GitHub run number | empty |
When GH_RELEASE_UPDATE_CHECK is not true, the update-checker code is tree-shaken out of the bundle. PR CI builds and local npm run build do not include the update badge.
To test a release-style build locally:
# PowerShell
$env:GH_RELEASE_UPDATE_CHECK="true"
$env:UPDATE_CHANNEL="stable"
npm run build
# bash
GH_RELEASE_UPDATE_CHECK=true UPDATE_CHANNEL=stable npm run build
Stable release (release.yml)
Purpose: A safe, manual way to publish versioned builds that users can download from GitHub.
Trigger: Manual only — Actions → Release → Run workflow. There is no schedule or automatic trigger.
When dispatching, check “I have already updated the version in package.json”. The workflow will not run without that confirmation.
Before you run it
- Merge your changes to
main. - Bump
versioninpackage.json(e.g.3.7.0→3.8.0). - Commit and push that bump.
What the workflow does
- Aborts if the version confirmation was not checked.
- Reads the version from
package.json. - Builds Chrome and Firefox with the update detector enabled (stable channel).
- If no release exists for that tag: creates one (e.g.
3.8.0) with a placeholder description. - If a release already exists for that tag: only replaces the zip assets (
--clobber). Title and body are left unchanged. - Uploads
betterseqtaplus-{version}-chrome.zipand-firefox.zip.
On first publish, edit the title and release notes on GitHub afterward. Re-running for the same version refreshes the files only.
Downloading and installing
- Open github.com/BetterSEQTA/BetterSEQTA-Plus/releases.
- Pick the version you want.
- Download
betterseqtaplus-{version}-chrome.zipor-firefox.zip. - Unzip and load the unpacked folder as a temporary extension (Chrome: Extensions → Load unpacked; Firefox:
about:debugging→ Load Temporary Add-on).
These GitHub builds are for sideloading only. Do not upload them to the Chrome Web Store or Firefox Add-ons.
Nightly release (nightly.yml)
Purpose: Continuous experimental builds from main so testers always have a single place to get the latest code.
Trigger:
- Automatically every day at 03:00 UTC
- Manually via Actions → Nightly Release → Run workflow
What the workflow does
- Builds from the current
mainbranch with the update detector enabled (nightly channel). - Uses a fixed release tag:
nightly(marked as prerelease). - On first run: creates the
nightlyrelease with the text in.github/nightly-release-notes.md. - On every subsequent run: replaces the zip assets on the same release (
--clobber). The release title and body are not rewritten.
The nightly release body warns that builds are experimental and must not be uploaded to extension stores.
PR CI (pr-ci.yml)
Purpose: Verify that every pull request builds cleanly in a fresh environment.
Trigger: Every pull request targeting main.
Steps:
npm install --legacy-peer-depsnpm run lint(ESLint onsrc/**/*.{js,ts})- Build via the shared action with no update detector
No release is created and no artifacts are published for end users.
Push CI (mvp.yml)
Purpose: Build verification when code lands on main.
Trigger: Push to main only (not pull requests — those use pr-ci.yml).
Uploads a dist.zip artifact containing the full dist/ folder for debugging. No release, no update detector.
Authentication
Release workflows run only on BetterSEQTA/BetterSEQTA-Plus. They use the default GITHUB_TOKEN with contents: write — no extra secrets or PATs required.
Update detector (in-extension)
GitHub release builds include a small feature that tells sideload users when a newer build is available, so they do not have to check GitHub manually.
Where it appears
In the settings popup header (top-right): an amber “Update available — X.X.X” pill when an update exists, plus a muted line:
GitHub release build — do not upload to extension stores.
Clicking the badge opens the relevant GitHub releases page.
How it checks for updates
Implementation: src/utils/githubReleaseUpdate.ts
Stable channel (from release.yml builds):
- Fetches releases from the GitHub API for
BetterSEQTA/BetterSEQTA-Plus. - Ignores the
nightlytag and any non-semver tags. - Finds the highest semver tag.
- Compares it to
browser.runtime.getManifest().version. - Shows the badge if the remote version is newer.
Nightly channel (from nightly.yml builds):
- Fetches the
nightlyrelease. - Compares its
published_attimestamp tolastSeenNightlyPublishedAtin extension storage. - On first install, records the current publish time without showing a badge.
- Shows “Update available — nightly #123” (run number) when a newer nightly has been published.
Checks are throttled to once every 6 hours per browser profile (localStorage key bsplus_lastGhReleaseCheck). Recent results are cached in memory for the session.
Dev override (testing)
To test the badge without publishing a real release:
- Open settings and unlock dev mode (click the logo, type
dev). - In the developer section, set GitHub latest version override to a version higher than your installed one (e.g.
9.9.9). - Reopen settings — the badge should appear.
This only applies when dev mode is on. Clear the field to return to normal API checks.
File reference
| Path | Role |
|---|---|
.github/actions/build-extension/action.yml |
Shared install, build, zip |
.github/workflows/release.yml |
Manual stable releases |
.github/workflows/nightly.yml |
Nightly releases |
.github/workflows/pr-ci.yml |
PR lint + build |
.github/workflows/mvp.yml |
Push-to-main build artifact |
.github/nightly-release-notes.md |
Static body for the nightly release |
vite.config.ts |
Injects build-time define flags |
src/env.d.ts |
TypeScript declarations for those flags |
src/utils/githubReleaseUpdate.ts |
Update check logic |
src/interface/pages/settings.svelte |
Badge and disclaimer UI |
src/interface/pages/settings/general.svelte |
Dev override input |
src/types/storage.ts |
devGhReleaseVersionOverride, lastSeenNightlyPublishedAt |
Quick reference
Publish a stable release
1. Bump version in package.json on main
2. Actions → Release → Run workflow → confirm version checkbox
3. Edit release title/notes on GitHub (first time only)
4. Re-run with same version to refresh zips without changing release text
Get the latest nightly
https://github.com/BetterSEQTA/BetterSEQTA-Plus/releases/tag/nightly
Verify a PR locally
npm run lint
npm run build