mirror of
https://github.com/BetterSEQTA/BetterSEQTA-Plus.git
synced 2026-06-07 20:24:39 +00:00
release build and other CI
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
- [Documentation home](https://docs.betterseqta.org/)
|
||||
- [Installation](https://docs.betterseqta.org/install/)
|
||||
- [Contributing](https://docs.betterseqta.org/contributing/)
|
||||
- [GitHub releases & CI](RELEASES.md) — workflows, nightly builds, update detector
|
||||
- [Architecture](https://docs.betterseqta.org/architecture/)
|
||||
- [Contribution guidelines (repository)](../CONTRIBUTING.md)
|
||||
- [Troubleshooting](https://docs.betterseqta.org/troubleshooting/)
|
||||
|
||||
@@ -0,0 +1,266 @@
|
||||
# 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](https://github.com/BetterSEQTA/BetterSEQTA-Plus)**.
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
```mermaid
|
||||
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`](../.github/actions/build-extension/action.yml).
|
||||
|
||||
It:
|
||||
|
||||
1. Installs dependencies (`npm install --legacy-peer-deps`)
|
||||
2. Runs `npm run build` (Chrome then Firefox via Vite)
|
||||
3. Zips each unpacked folder into sideload-ready archives:
|
||||
- `dist/betterseqtaplus-{version}-chrome.zip`
|
||||
- `dist/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`](../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:
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
1. Merge your changes to `main`.
|
||||
2. Bump `version` in [`package.json`](../package.json) (e.g. `3.7.0` → `3.8.0`).
|
||||
3. Commit and push that bump.
|
||||
|
||||
### What the workflow does
|
||||
|
||||
1. Aborts if the version confirmation was not checked.
|
||||
2. Reads the version from `package.json`.
|
||||
3. Builds Chrome and Firefox with the update detector enabled (stable channel).
|
||||
4. If no release exists for that tag: creates one (e.g. `3.8.0`) with a placeholder description.
|
||||
5. If a release already exists for that tag: **only replaces the zip assets** (`--clobber`). Title and body are left unchanged.
|
||||
6. Uploads `betterseqtaplus-{version}-chrome.zip` and `-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
|
||||
|
||||
1. Open [github.com/BetterSEQTA/BetterSEQTA-Plus/releases](https://github.com/BetterSEQTA/BetterSEQTA-Plus/releases).
|
||||
2. Pick the version you want.
|
||||
3. Download `betterseqtaplus-{version}-chrome.zip` or `-firefox.zip`.
|
||||
4. 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
|
||||
|
||||
1. Builds from the current `main` branch with the update detector enabled (nightly channel).
|
||||
2. Uses a fixed release tag: **`nightly`** (marked as prerelease).
|
||||
3. On first run: creates the `nightly` release with the text in [`.github/nightly-release-notes.md`](../.github/nightly-release-notes.md).
|
||||
4. 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:**
|
||||
|
||||
1. `npm install --legacy-peer-deps`
|
||||
2. `npm run lint` (ESLint on `src/**/*.{js,ts}`)
|
||||
3. 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](https://github.com/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`](../src/utils/githubReleaseUpdate.ts)
|
||||
|
||||
**Stable channel** (from `release.yml` builds):
|
||||
|
||||
1. Fetches releases from the GitHub API for `BetterSEQTA/BetterSEQTA-Plus`.
|
||||
2. Ignores the `nightly` tag and any non-semver tags.
|
||||
3. Finds the highest semver tag.
|
||||
4. Compares it to `browser.runtime.getManifest().version`.
|
||||
5. Shows the badge if the remote version is newer.
|
||||
|
||||
**Nightly channel** (from `nightly.yml` builds):
|
||||
|
||||
1. Fetches the `nightly` release.
|
||||
2. Compares its `published_at` timestamp to `lastSeenNightlyPublishedAt` in extension storage.
|
||||
3. On first install, records the current publish time without showing a badge.
|
||||
4. 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:
|
||||
|
||||
1. Open settings and unlock **dev mode** (click the logo, type `dev`).
|
||||
2. In the developer section, set **GitHub latest version override** to a version higher than your installed one (e.g. `9.9.9`).
|
||||
3. 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
|
||||
|
||||
```text
|
||||
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
|
||||
|
||||
```text
|
||||
https://github.com/BetterSEQTA/BetterSEQTA-Plus/releases/tag/nightly
|
||||
```
|
||||
|
||||
### Verify a PR locally
|
||||
|
||||
```bash
|
||||
npm run lint
|
||||
npm run build
|
||||
```
|
||||
+23
-3
@@ -119,12 +119,13 @@ git checkout -b feature/my-new-feature
|
||||
|
||||
If your changes require documentation updates, include them in the same PR.
|
||||
|
||||
4. **Run Tests**
|
||||
4. **Run CI checks locally**
|
||||
|
||||
Make sure all tests pass before submitting your PR:
|
||||
Pull requests trigger **PR CI**, which lints and builds in a clean environment:
|
||||
|
||||
```bash
|
||||
npm test
|
||||
npm run lint
|
||||
npm run build
|
||||
```
|
||||
|
||||
5. **Submit Your PR**
|
||||
@@ -139,6 +140,25 @@ git checkout -b feature/my-new-feature
|
||||
|
||||
Once approved, a maintainer will merge your PR.
|
||||
|
||||
### GitHub Actions workflows
|
||||
|
||||
See [RELEASES.md](RELEASES.md) for a full guide (workflows, sideload installs, and update detector).
|
||||
|
||||
| Workflow | Trigger | Purpose |
|
||||
|----------|---------|---------|
|
||||
| `pr-ci.yml` | Every PR to `main` | Typecheck, lint, and build (no release) |
|
||||
| `mvp.yml` | Push to `main` | Build and upload `dist.zip` artifact |
|
||||
| `release.yml` | Manual (`workflow_dispatch`) | Stable release on [BetterSEQTA/BetterSEQTA-Plus](https://github.com/BetterSEQTA/BetterSEQTA-Plus) tagged with `package.json` version |
|
||||
| `nightly.yml` | Daily cron + manual | Updates the fixed `nightly` prerelease with latest `main` builds |
|
||||
|
||||
**Releasing a stable version:** bump `version` in `package.json` on `main`, then manually run the **Release** workflow and confirm the version checkbox. Edit the release title and notes on GitHub after the first publish. Re-running for the same tag only updates the zip files. Assets are `betterseqtaplus-{version}-chrome.zip` and `-firefox.zip`.
|
||||
|
||||
**Nightly builds** replace assets on the same `nightly` release. The release body warns that builds are experimental and must not be uploaded to extension stores.
|
||||
|
||||
**GitHub release builds** include an in-extension update checker (settings header badge). **PR CI and local dev builds do not.**
|
||||
|
||||
Release workflows are dispatched only on the main **BetterSEQTA/BetterSEQTA-Plus** repository and use the default `GITHUB_TOKEN`.
|
||||
|
||||
### Coding Standards
|
||||
|
||||
We follow TypeScript best practices and have a consistent code style:
|
||||
|
||||
Reference in New Issue
Block a user