nightly build

This commit is contained in:
2026-06-10 01:25:51 +09:30
parent 9166bebef7
commit ec94376e1f
5 changed files with 48 additions and 13 deletions
+13 -5
View File
@@ -11,7 +11,7 @@ inputs:
required: false required: false
default: stable default: stable
build_label: build_label:
description: Optional build label for nightly display (e.g. run number). description: Optional build label for nightly display (e.g. UTC build date).
required: false required: false
default: "" default: ""
release_repo: release_repo:
@@ -59,9 +59,17 @@ runs:
- name: Package zips - name: Package zips
id: zip id: zip
shell: bash shell: bash
env:
UPDATE_CHANNEL: ${{ inputs.update_channel }}
BUILD_LABEL: ${{ inputs.build_label }}
run: | run: |
VERSION="${{ steps.version.outputs.version }}" VERSION="${{ steps.version.outputs.version }}"
(cd dist/chrome && zip -r "../betterseqtaplus-${VERSION}-chrome.zip" .) if [ "$UPDATE_CHANNEL" = "nightly" ] && [ -n "$BUILD_LABEL" ]; then
(cd dist/firefox && zip -r "../betterseqtaplus-${VERSION}-firefox.zip" .) BASE="betterseqtaplus-nightly-${BUILD_LABEL}"
echo "chrome_zip=dist/betterseqtaplus-${VERSION}-chrome.zip" >> "$GITHUB_OUTPUT" else
echo "firefox_zip=dist/betterseqtaplus-${VERSION}-firefox.zip" >> "$GITHUB_OUTPUT" BASE="betterseqtaplus-${VERSION}"
fi
(cd dist/chrome && zip -r "../${BASE}-chrome.zip" .)
(cd dist/firefox && zip -r "../${BASE}-firefox.zip" .)
echo "chrome_zip=dist/${BASE}-chrome.zip" >> "$GITHUB_OUTPUT"
echo "firefox_zip=dist/${BASE}-firefox.zip" >> "$GITHUB_OUTPUT"
+9 -2
View File
@@ -20,22 +20,29 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Set build date
id: build_date
run: echo "date=$(date -u +'%Y-%m-%d')" >> "$GITHUB_OUTPUT"
- name: Build extension - name: Build extension
id: build id: build
uses: ./.github/actions/build-extension uses: ./.github/actions/build-extension
with: with:
gh_release_update_check: "true" gh_release_update_check: "true"
update_channel: nightly update_channel: nightly
build_label: ${{ github.run_number }} build_label: ${{ steps.build_date.outputs.date }}
release_repo: ${{ github.repository }} release_repo: ${{ github.repository }}
- name: Ensure nightly release exists - name: Ensure nightly release exists
run: | run: |
TITLE="Nightly (${{ steps.build_date.outputs.date }})"
if ! gh release view "${{ env.NIGHTLY_TAG }}" 2>/dev/null; then if ! gh release view "${{ env.NIGHTLY_TAG }}" 2>/dev/null; then
gh release create "${{ env.NIGHTLY_TAG }}" \ gh release create "${{ env.NIGHTLY_TAG }}" \
--prerelease \ --prerelease \
--title "Nightly" \ --title "$TITLE" \
--notes-file .github/nightly-release-notes.md --notes-file .github/nightly-release-notes.md
else
gh release edit "${{ env.NIGHTLY_TAG }}" --title "$TITLE"
fi fi
- name: Upload nightly assets - name: Upload nightly assets
+4 -3
View File
@@ -71,7 +71,7 @@ Release and nightly workflows pass environment variables into Vite, which bakes
| `GH_RELEASE_UPDATE_CHECK` | `true` | `true` | `false` / unset | | `GH_RELEASE_UPDATE_CHECK` | `true` | `true` | `false` / unset |
| `UPDATE_CHANNEL` | `stable` | `nightly` | `stable` (unused) | | `UPDATE_CHANNEL` | `stable` | `nightly` | `stable` (unused) |
| `GH_RELEASE_REPO` | `BetterSEQTA/BetterSEQTA-Plus` | same | same | | `GH_RELEASE_REPO` | `BetterSEQTA/BetterSEQTA-Plus` | same | same |
| `BUILD_LABEL` | empty | GitHub run number | empty | | `BUILD_LABEL` | empty | UTC build date (`YYYY-MM-DD`) | 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. 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.
@@ -139,7 +139,8 @@ On first publish, edit the **title** and **release notes** on GitHub afterward.
1. Builds from the current `main` branch with the update detector enabled (nightly channel). 1. Builds from the current `main` branch with the update detector enabled (nightly channel).
2. Uses a fixed release tag: **`nightly`** (marked as prerelease). 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). 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. 4. On every run: sets the release title to **`Nightly (YYYY-MM-DD)`** (UTC build date) and **replaces** the zip assets on the same release (`--clobber`). The release body is not rewritten.
5. Packages zips as `betterseqtaplus-nightly-{date}-chrome.zip` / `-firefox.zip`.
The nightly release body warns that builds are experimental and must not be uploaded to extension stores. The nightly release body warns that builds are experimental and must not be uploaded to extension stores.
@@ -206,7 +207,7 @@ Implementation: [`src/utils/githubReleaseUpdate.ts`](../src/utils/githubReleaseU
1. Fetches the `nightly` release. 1. Fetches the `nightly` release.
2. Compares its `published_at` timestamp to `lastSeenNightlyPublishedAt` in extension storage. 2. Compares its `published_at` timestamp to `lastSeenNightlyPublishedAt` in extension storage.
3. On first install, records the current publish time without showing a badge. 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. 4. Shows **“Update available — nightly (YYYY-MM-DD)”** 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. Checks are throttled to once every **6 hours** per browser profile (`localStorage` key `bsplus_lastGhReleaseCheck`). Recent results are cached in memory for the session.
+7 -1
View File
@@ -22,6 +22,7 @@
import { import {
checkGithubReleaseUpdate, checkGithubReleaseUpdate,
dismissNightlyUpdate, dismissNightlyUpdate,
getInstalledGhReleaseChannelLabel,
isGhReleaseUpdateCheckEnabled, isGhReleaseUpdateCheckEnabled,
type GhReleaseUpdateInfo, type GhReleaseUpdateInfo,
} from "@/utils/githubReleaseUpdate"; } from "@/utils/githubReleaseUpdate";
@@ -33,6 +34,7 @@
let disclaimerTitle = $state("Confirm"); let disclaimerTitle = $state("Confirm");
let disclaimerMessage = $state(""); let disclaimerMessage = $state("");
const ghReleaseUpdateEnabled = isGhReleaseUpdateCheckEnabled(); const ghReleaseUpdateEnabled = isGhReleaseUpdateCheckEnabled();
const ghReleaseChannelLabel = getInstalledGhReleaseChannelLabel();
let ghReleaseUpdate = $state<GhReleaseUpdateInfo | null>(null); let ghReleaseUpdate = $state<GhReleaseUpdateInfo | null>(null);
const openGhRelease = () => { const openGhRelease = () => {
@@ -172,7 +174,11 @@
</button> </button>
{/if} {/if}
<p class="text-[9px] leading-tight text-right text-zinc-500 dark:text-zinc-400"> <p class="text-[9px] leading-tight text-right text-zinc-500 dark:text-zinc-400">
GitHub release build — do not upload to extension stores. {#if ghReleaseChannelLabel}
{ghReleaseChannelLabel} — do not upload to extension stores.
{:else}
GitHub release build — do not upload to extension stores.
{/if}
</p> </p>
</div> </div>
{/if} {/if}
+15 -2
View File
@@ -35,6 +35,14 @@ function getBuildLabel(): string {
return typeof __BUILD_LABEL__ !== "undefined" ? __BUILD_LABEL__ : ""; return typeof __BUILD_LABEL__ !== "undefined" ? __BUILD_LABEL__ : "";
} }
function formatNightlyLabel(buildDate: string): string {
return buildDate ? `nightly (${buildDate})` : "nightly";
}
function nightlyDateFromPublishedAt(publishedAt: string): string {
return publishedAt.slice(0, 10);
}
function getCurrentVersion(): string { function getCurrentVersion(): string {
return browser.runtime.getManifest().version; return browser.runtime.getManifest().version;
} }
@@ -158,8 +166,7 @@ async function checkNightlyUpdate(): Promise<GhReleaseUpdateInfo> {
} }
const lastSeen = settingsState.lastSeenNightlyPublishedAt; const lastSeen = settingsState.lastSeenNightlyPublishedAt;
const buildLabel = getBuildLabel(); const label = formatNightlyLabel(nightlyDateFromPublishedAt(release.published_at));
const label = buildLabel ? `nightly #${buildLabel}` : "nightly";
if (!lastSeen) { if (!lastSeen) {
settingsState.lastSeenNightlyPublishedAt = release.published_at; settingsState.lastSeenNightlyPublishedAt = release.published_at;
@@ -177,6 +184,12 @@ export function isGhReleaseUpdateCheckEnabled(): boolean {
return isUpdateCheckEnabled(); return isUpdateCheckEnabled();
} }
/** Label for the installed GitHub release build (e.g. `nightly (2025-06-10)`). */
export function getInstalledGhReleaseChannelLabel(): string | null {
if (!isUpdateCheckEnabled() || getUpdateChannel() !== "nightly") return null;
return formatNightlyLabel(getBuildLabel());
}
export async function checkGithubReleaseUpdate(): Promise<GhReleaseUpdateInfo> { export async function checkGithubReleaseUpdate(): Promise<GhReleaseUpdateInfo> {
const fallback = { available: false, label: "", url: releasesBaseUrl() }; const fallback = { available: false, label: "", url: releasesBaseUrl() };