diff --git a/README.md b/README.md index 2546821..0912e6a 100644 --- a/README.md +++ b/README.md @@ -39,12 +39,35 @@ domains such as `youtube.com` or `x.com`. Manual “Send page”, selection, link and file actions are separate. They create Browser Inbox captures; they do not create a workspace or a journal entry. -## Firefox Release +## Firefox download and updates + +The signed XPI is published on the [GitHub Releases page](https://github.com/mirivlad/verstak-browser-extension/releases). +Download the Firefox asset named `verstak-firefox-.xpi` from the latest +release and open it in Firefox to install it. + +After the first public release, installed copies check GitHub Releases for +updates through the release's `updates.json` asset. During the alpha phase each +published release is the current update channel. + +## Firefox release publishing Firefox signing uses `web-ext` and AMO credentials from an env file. The script requires `WEB_EXT_API_PROXY`; AMO upload and approval polling run through that proxy. +Create the signed XPI and publish it, together with `updates.json`, as the +current GitHub Release: + +```bash +VERSTAK_BROWSER_ENV=/path/to/.env npm run publish:firefox +``` + +The first invocation publishes tag `v2.0.2` and bootstraps the +`releases/latest/download/updates.json` endpoint. Re-running the command +replaces those two release assets for the same tag. + +To sign and prepare release files locally without changing GitHub: + ```bash VERSTAK_BROWSER_ENV=/home/mirivlad/git/verstak/.env npm run release:firefox ``` @@ -54,8 +77,9 @@ Release output: - `release/firefox/verstak-firefox-.xpi` - `release/firefox/updates.json` -The XPI is signed as an unlisted/self-distributed Firefox extension. Build and -release artifacts are local outputs and are not committed. +The XPI is signed as an unlisted/self-distributed Firefox extension; GitHub +Releases distribute that signed file. Build and release artifacts are local +outputs and are not committed. ## Reproducible local package diff --git a/package.json b/package.json index eba744f..59399fe 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "test": "node scripts/test-hostname.js && node scripts/test-activity-tracker.js && node scripts/test-protocol.js && node scripts/test-i18n.js && node scripts/test-popup-settings.js && node scripts/test-popup-catalog-fallback.js && node scripts/test-background-i18n.js && node scripts/test-firefox-github-release.js", "sign:firefox": "./scripts/sign-firefox-xpi.sh", "release:firefox": "./scripts/release-firefox-xpi.sh", + "publish:firefox": "./scripts/publish-firefox-github-release.sh", "release:package": "./scripts/package-release.sh" }, "devDependencies": { diff --git a/scripts/publish-firefox-github-release.sh b/scripts/publish-firefox-github-release.sh new file mode 100755 index 0000000..c025060 --- /dev/null +++ b/scripts/publish-firefox-github-release.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +cd "$ROOT_DIR" + +REPOSITORY="mirivlad/verstak-browser-extension" +SOURCE_DIR="${VERSTAK_FIREFOX_SOURCE_DIR:-dist/firefox}" +RELEASE_DIR="${VERSTAK_FIREFOX_RELEASE_DIR:-release/firefox}" + +if ! command -v gh >/dev/null; then + echo "ERROR: gh CLI is required to publish a GitHub Release" >&2 + exit 1 +fi + +gh auth status +./scripts/release-firefox-xpi.sh + +VERSION="$(node -e "console.log(require('./${SOURCE_DIR}/manifest.json').version)")" +TAG="v${VERSION}" +XPI="$RELEASE_DIR/verstak-firefox-${VERSION}.xpi" +UPDATES="$RELEASE_DIR/updates.json" + +for artifact in "$XPI" "$UPDATES"; do + if [[ ! -f "$artifact" ]]; then + echo "ERROR: release artifact not found: $artifact" >&2 + exit 1 + fi +done + +if gh release view "$TAG" --repo "$REPOSITORY" >/dev/null 2>&1; then + gh release upload "$TAG" "$XPI" "$UPDATES" --repo "$REPOSITORY" --clobber +else + gh release create "$TAG" "$XPI" "$UPDATES" \ + --repo "$REPOSITORY" \ + --title "Verstak Browser Extension $VERSION" \ + --generate-notes \ + --latest \ + --target "$(git rev-parse HEAD)" +fi + +echo "GitHub release:" +gh release view "$TAG" --repo "$REPOSITORY" --json url --jq .url diff --git a/scripts/test-firefox-github-release.js b/scripts/test-firefox-github-release.js index ae592a1..412c469 100644 --- a/scripts/test-firefox-github-release.js +++ b/scripts/test-firefox-github-release.js @@ -1,5 +1,6 @@ #!/usr/bin/env node const assert = require('assert'); +const fs = require('fs'); const release = require('./firefox-github-release'); const version = '2.0.2'; @@ -28,4 +29,11 @@ assert.equal( 'https://github.com/mirivlad/verstak-browser-extension/releases/latest/download/updates.json', ); +const publisher = fs.readFileSync('scripts/publish-firefox-github-release.sh', 'utf8'); +assert.match(publisher, /gh auth status/); +assert.match(publisher, /gh release create/); +assert.match(publisher, /gh release upload/); +assert.match(publisher, /--clobber/); +assert.match(publisher, /--latest/); + console.log('Firefox GitHub release metadata tests passed');