Compare commits
5 Commits
agent/gith
...
main
| Author | SHA1 | Date |
|---|---|---|
|
|
9a96883c87 | |
|
|
a80a2b55e6 | |
|
|
4dd87dc8cc | |
|
|
057b63a946 | |
|
|
39e93e0987 |
26
README.md
26
README.md
|
|
@ -55,21 +55,29 @@ 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:
|
||||
Create the signed XPI locally, without publishing it:
|
||||
|
||||
```bash
|
||||
VERSTAK_BROWSER_ENV=/path/to/.env npm run publish:firefox
|
||||
VERSTAK_BROWSER_ENV=/path/to/.env npm run release: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:
|
||||
Publish the signed XPI and `updates.json` as the current GitHub Release:
|
||||
|
||||
```bash
|
||||
VERSTAK_BROWSER_ENV=/home/mirivlad/git/verstak/.env npm run release:firefox
|
||||
VERSTAK_BROWSER_ENV=/path/to/.env npm run publish:github
|
||||
```
|
||||
|
||||
The publisher reads the version from `package.json` and requires an
|
||||
authenticated GitHub CLI plus a clean local `main` equal to `origin/main`. It
|
||||
creates and pushes the version tag if needed, then creates or updates the
|
||||
GitHub Release. Re-running it for the same tag replaces the XPI and
|
||||
`updates.json` assets. `npm run publish:firefox` remains as a compatible alias
|
||||
for the same Firefox publishing flow.
|
||||
|
||||
For an explicit version check, pass the current tag after `--`:
|
||||
|
||||
```bash
|
||||
VERSTAK_BROWSER_ENV=/path/to/.env npm run publish:github -- v2.0.3
|
||||
```
|
||||
|
||||
Release output:
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
{
|
||||
"manifest_version": 3,
|
||||
"name": "Verstak Bridge",
|
||||
"version": "2.0.2",
|
||||
"version": "2.0.3",
|
||||
"description": "Send pages, selections, links, and files to the local Verstak browser inbox.",
|
||||
"author": "Verstak",
|
||||
"homepage_url": "https://git.mirv.top/verstak/verstak-browser-extension",
|
||||
"homepage_url": "https://github.com/mirivlad/verstak-browser-extension",
|
||||
"permissions": ["alarms", "contextMenus", "idle", "storage", "tabs", "windows"],
|
||||
"host_permissions": ["http://127.0.0.1/*", "http://localhost/*"],
|
||||
"background": {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
- Publish repository: `mirivlad/verstak-browser-extension`.
|
||||
- Firefox addon ID: `verstak-bridge@verstak.app`.
|
||||
- Initial GitHub release: `v2.0.2`; package and both browser manifests are version `2.0.2`.
|
||||
- Initial GitHub release: `v2.0.3`; package and both browser manifests are version `2.0.3`.
|
||||
- Every alpha GitHub release is ordinary/latest, not a prerelease.
|
||||
- XPI remains Mozilla-signed as an unlisted/self-distributed addon before upload.
|
||||
- `npm run release:firefox` remains a local sign-and-package action.
|
||||
|
|
@ -41,19 +41,19 @@ Create `scripts/test-firefox-github-release.js` with:
|
|||
const assert = require('assert');
|
||||
const release = require('./firefox-github-release');
|
||||
|
||||
const version = '2.0.2';
|
||||
const asset = 'verstak-firefox-2.0.2.xpi';
|
||||
assert.equal(release.releaseTag(version), 'v2.0.2');
|
||||
const version = '2.0.3';
|
||||
const asset = 'verstak-firefox-2.0.3.xpi';
|
||||
assert.equal(release.releaseTag(version), 'v2.0.3');
|
||||
assert.equal(
|
||||
release.releaseAssetURL(version, asset),
|
||||
'https://github.com/mirivlad/verstak-browser-extension/releases/download/v2.0.2/verstak-firefox-2.0.2.xpi',
|
||||
'https://github.com/mirivlad/verstak-browser-extension/releases/download/v2.0.3/verstak-firefox-2.0.3.xpi',
|
||||
);
|
||||
assert.deepEqual(release.updateManifest('verstak-bridge@verstak.app', version, asset), {
|
||||
addons: {
|
||||
'verstak-bridge@verstak.app': {
|
||||
updates: [{
|
||||
version: '2.0.2',
|
||||
update_link: 'https://github.com/mirivlad/verstak-browser-extension/releases/download/v2.0.2/verstak-firefox-2.0.2.xpi',
|
||||
version: '2.0.3',
|
||||
update_link: 'https://github.com/mirivlad/verstak-browser-extension/releases/download/v2.0.3/verstak-firefox-2.0.3.xpi',
|
||||
}],
|
||||
},
|
||||
},
|
||||
|
|
@ -246,7 +246,7 @@ Rewrite the Firefox Release README section so it documents:
|
|||
- `VERSTAK_BROWSER_ENV=/path/to/.env npm run publish:firefox`;
|
||||
- that signing remains unlisted with Mozilla but distribution and automatic
|
||||
updates use GitHub Release assets;
|
||||
- that the first `v2.0.2` publish bootstraps the `latest/download/updates.json`
|
||||
- that the first `v2.0.3` publish bootstraps the `latest/download/updates.json`
|
||||
endpoint.
|
||||
|
||||
- [ ] **Step 4: Run checks without publishing**
|
||||
|
|
@ -275,12 +275,12 @@ git push origin main
|
|||
### Task 4: Bootstrap and verify the first public update release
|
||||
|
||||
**Files:**
|
||||
- Generated: `release/firefox/verstak-firefox-2.0.2.xpi` (untracked)
|
||||
- Generated: `release/firefox/verstak-firefox-2.0.3.xpi` (untracked)
|
||||
- Generated: `release/firefox/updates.json` (untracked)
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes the Task 3 `npm run publish:firefox` command and valid AMO signing credentials.
|
||||
- Produces GitHub Release tag `v2.0.2` and public XPI/update-manifest assets.
|
||||
- Produces GitHub Release tag `v2.0.3` and public XPI/update-manifest assets.
|
||||
|
||||
- [ ] **Step 1: Verify release credentials before write operations**
|
||||
|
||||
|
|
@ -302,20 +302,20 @@ Run:
|
|||
npm run publish:firefox
|
||||
```
|
||||
|
||||
Expected: Mozilla signing succeeds, GitHub Release `v2.0.2` is latest, and it
|
||||
contains `verstak-firefox-2.0.2.xpi` plus `updates.json`.
|
||||
Expected: Mozilla signing succeeds, GitHub Release `v2.0.3` is latest, and it
|
||||
contains `verstak-firefox-2.0.3.xpi` plus `updates.json`.
|
||||
|
||||
- [ ] **Step 3: Verify public delivery**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
gh release view v2.0.2 --repo mirivlad/verstak-browser-extension --json isLatest,url,assets
|
||||
gh release view v2.0.3 --repo mirivlad/verstak-browser-extension --json isLatest,url,assets
|
||||
curl -fsSL https://github.com/mirivlad/verstak-browser-extension/releases/latest/download/updates.json
|
||||
```
|
||||
|
||||
Expected: the release is latest and the JSON contains addon ID
|
||||
`verstak-bridge@verstak.app`, version `2.0.2`, and the versioned GitHub XPI
|
||||
`verstak-bridge@verstak.app`, version `2.0.3`, and the versioned GitHub XPI
|
||||
asset URL.
|
||||
|
||||
- [ ] **Step 4: Record release verification without committing assets**
|
||||
|
|
|
|||
|
|
@ -22,10 +22,10 @@ Each release uploads two assets:
|
|||
- `updates.json`, whose `update_link` points to that same release tag's XPI
|
||||
asset.
|
||||
|
||||
For version `2.0.2`, the versioned link is:
|
||||
For version `2.0.3`, the versioned link is:
|
||||
|
||||
```text
|
||||
https://github.com/mirivlad/verstak-browser-extension/releases/download/v2.0.2/verstak-firefox-2.0.2.xpi
|
||||
https://github.com/mirivlad/verstak-browser-extension/releases/download/v2.0.3/verstak-firefox-2.0.3.xpi
|
||||
```
|
||||
|
||||
The stable `latest/download` endpoint lets already installed extensions discover
|
||||
|
|
@ -46,10 +46,10 @@ endpoint.
|
|||
## Bootstrap
|
||||
|
||||
There is currently no GitHub Release in this repository. After the code change,
|
||||
the first `v2.0.2` signed release must be published before shipping a manifest
|
||||
the first `v2.0.3` signed release must be published before shipping a manifest
|
||||
that points to `latest/download/updates.json`; until then that URL is a 404.
|
||||
The current package, Chromium manifest and Firefox manifest all use version
|
||||
`2.0.2`, so the initial tag and XPI asset name are unambiguous.
|
||||
`2.0.3`, so the initial tag and XPI asset name are unambiguous.
|
||||
|
||||
## Documentation
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"manifest_version": 2,
|
||||
"name": "Verstak Bridge",
|
||||
"version": "2.0.2",
|
||||
"version": "2.0.3",
|
||||
"description": "Send pages, selections, links, and files to the local Verstak browser inbox.",
|
||||
"author": "Verstak",
|
||||
"homepage_url": "https://github.com/mirivlad/verstak-browser-extension",
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "verstak-browser-extension",
|
||||
"version": "2.0.2",
|
||||
"version": "2.0.3",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "verstak-browser-extension",
|
||||
"version": "2.0.2",
|
||||
"version": "2.0.3",
|
||||
"devDependencies": {
|
||||
"web-ext": "^8.3.0"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,16 @@
|
|||
{
|
||||
"name": "verstak-browser-extension",
|
||||
"version": "2.0.2",
|
||||
"version": "2.0.3",
|
||||
"private": true,
|
||||
"description": "Verstak browser capture extension for Chromium and Firefox",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"scripts": {
|
||||
"build": "node scripts/build-extension.js",
|
||||
"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",
|
||||
"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-select-style.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",
|
||||
"publish:github": "./scripts/publish-github-release.sh",
|
||||
"release:package": "./scripts/package-release.sh"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
|||
|
|
@ -7,13 +7,29 @@ cd "$ROOT_DIR"
|
|||
REPOSITORY="mirivlad/verstak-browser-extension"
|
||||
SOURCE_DIR="${VERSTAK_FIREFOX_SOURCE_DIR:-dist/firefox}"
|
||||
RELEASE_DIR="${VERSTAK_FIREFOX_RELEASE_DIR:-release/firefox}"
|
||||
GIT_BIN="${GIT_BIN:-git}"
|
||||
GH_BIN="${GH_BIN:-gh}"
|
||||
|
||||
if ! command -v gh >/dev/null; then
|
||||
if ! command -v "$GH_BIN" >/dev/null; then
|
||||
echo "ERROR: gh CLI is required to publish a GitHub Release" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ "$("$GIT_BIN" branch --show-current)" != "main" ]]; then
|
||||
echo "ERROR: GitHub releases must be published from main" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ -n "$("$GIT_BIN" status --porcelain)" ]]; then
|
||||
echo "ERROR: working tree must be clean before publishing a release" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
gh auth status
|
||||
"$GH_BIN" auth status
|
||||
"$GIT_BIN" fetch origin main --tags
|
||||
HEAD="$("$GIT_BIN" rev-parse HEAD)"
|
||||
if [[ "$HEAD" != "$("$GIT_BIN" rev-parse origin/main)" ]]; then
|
||||
echo "ERROR: local main must match origin/main before publishing a release" >&2
|
||||
exit 1
|
||||
fi
|
||||
./scripts/release-firefox-xpi.sh
|
||||
|
||||
VERSION="$(node -e "console.log(require('./${SOURCE_DIR}/manifest.json').version)")"
|
||||
|
|
@ -28,16 +44,26 @@ for artifact in "$XPI" "$UPDATES"; do
|
|||
fi
|
||||
done
|
||||
|
||||
if gh release view "$TAG" --repo "$REPOSITORY" >/dev/null 2>&1; then
|
||||
gh release upload "$TAG" "$XPI" "$UPDATES" --repo "$REPOSITORY" --clobber
|
||||
if "$GIT_BIN" rev-parse -q --verify "refs/tags/$TAG" >/dev/null; then
|
||||
if [[ "$("$GIT_BIN" rev-parse "${TAG}^{commit}")" != "$HEAD" ]]; then
|
||||
echo "ERROR: existing tag $TAG does not point at HEAD" >&2
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
gh release create "$TAG" "$XPI" "$UPDATES" \
|
||||
"$GIT_BIN" tag -a "$TAG" -m "Release $TAG"
|
||||
"$GIT_BIN" push origin "refs/tags/$TAG"
|
||||
fi
|
||||
|
||||
if "$GH_BIN" release view "$TAG" --repo "$REPOSITORY" >/dev/null 2>&1; then
|
||||
"$GH_BIN" release upload "$TAG" "$XPI" "$UPDATES" --repo "$REPOSITORY" --clobber
|
||||
else
|
||||
"$GH_BIN" release create "$TAG" "$XPI" "$UPDATES" \
|
||||
--repo "$REPOSITORY" \
|
||||
--title "Verstak Browser Extension $VERSION" \
|
||||
--generate-notes \
|
||||
--latest \
|
||||
--target "$(git rev-parse HEAD)"
|
||||
--verify-tag
|
||||
fi
|
||||
|
||||
echo "GitHub release:"
|
||||
gh release view "$TAG" --repo "$REPOSITORY" --json url --jq .url
|
||||
"$GH_BIN" release view "$TAG" --repo "$REPOSITORY" --json url --jq .url
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
VERSION="$(node -p "require('$ROOT/package.json').version")"
|
||||
|
||||
if [[ $# -gt 1 || ( $# -eq 1 && "$1" != "v$VERSION" && "$1" != "$VERSION" ) ]]; then
|
||||
echo "usage: $0 [v$VERSION]" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
exec "$ROOT/scripts/publish-firefox-github-release.sh"
|
||||
|
|
@ -2,27 +2,32 @@
|
|||
const assert = require('assert');
|
||||
const fs = require('fs');
|
||||
const release = require('./firefox-github-release');
|
||||
const packageManifest = require('../package.json');
|
||||
const chromiumManifest = require('../chromium/manifest.json');
|
||||
const firefoxManifest = require('../firefox/manifest.json');
|
||||
|
||||
const version = '2.0.2';
|
||||
const asset = 'verstak-firefox-2.0.2.xpi';
|
||||
const version = '2.0.3';
|
||||
const asset = 'verstak-firefox-2.0.3.xpi';
|
||||
|
||||
assert.equal(release.releaseTag(version), 'v2.0.2');
|
||||
assert.equal(packageManifest.version, version);
|
||||
assert.equal(chromiumManifest.version, version);
|
||||
assert.equal(firefoxManifest.version, version);
|
||||
assert.equal(release.releaseTag(version), 'v2.0.3');
|
||||
assert.equal(
|
||||
release.releaseAssetURL(version, asset),
|
||||
'https://github.com/mirivlad/verstak-browser-extension/releases/download/v2.0.2/verstak-firefox-2.0.2.xpi',
|
||||
'https://github.com/mirivlad/verstak-browser-extension/releases/download/v2.0.3/verstak-firefox-2.0.3.xpi',
|
||||
);
|
||||
assert.deepEqual(release.updateManifest('verstak-bridge@verstak.app', version, asset), {
|
||||
addons: {
|
||||
'verstak-bridge@verstak.app': {
|
||||
updates: [{
|
||||
version: '2.0.2',
|
||||
update_link: 'https://github.com/mirivlad/verstak-browser-extension/releases/download/v2.0.2/verstak-firefox-2.0.2.xpi',
|
||||
version: '2.0.3',
|
||||
update_link: 'https://github.com/mirivlad/verstak-browser-extension/releases/download/v2.0.3/verstak-firefox-2.0.3.xpi',
|
||||
}],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const firefoxManifest = require('../firefox/manifest.json');
|
||||
assert.equal(firefoxManifest.homepage_url, 'https://github.com/mirivlad/verstak-browser-extension');
|
||||
assert.equal(
|
||||
firefoxManifest.browser_specific_settings.gecko.update_url,
|
||||
|
|
@ -30,10 +35,16 @@ assert.equal(
|
|||
);
|
||||
|
||||
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, /auth status/);
|
||||
assert.match(publisher, /branch --show-current/);
|
||||
assert.match(publisher, /tag -a/);
|
||||
assert.match(publisher, /push origin/);
|
||||
assert.match(publisher, /release create/);
|
||||
assert.match(publisher, /release upload/);
|
||||
assert.match(publisher, /--clobber/);
|
||||
assert.match(publisher, /--latest/);
|
||||
|
||||
const genericPublisher = fs.readFileSync('scripts/publish-github-release.sh', 'utf8');
|
||||
assert.match(genericPublisher, /publish-firefox-github-release\.sh/);
|
||||
|
||||
console.log('Firefox GitHub release metadata tests passed');
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
const assert = require('assert');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const css = fs.readFileSync(path.join(__dirname, '..', 'shared', 'popup', 'popup.css'), 'utf8');
|
||||
|
||||
assert.match(css, /select\s*\{[^}]*appearance:\s*none/, 'popup select must hide the native arrow');
|
||||
assert.match(css, /select option\s*\{[^}]*background/, 'popup options must use the extension surface');
|
||||
|
||||
console.log('browser extension popup select style test passed');
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://git.mirv.top/verstak/verstak-sdk/schemas/hostname-normalization-v1.json",
|
||||
"$id": "https://raw.githubusercontent.com/mirivlad/verstak-sdk/main/schemas/hostname-normalization-v1.json",
|
||||
"title": "Verstak canonical hostname normalization v1 test vectors",
|
||||
"description": "Canonical hostnames are lowercase ASCII A-labels without a port or trailing DNS dot. Bare hostnames accept DNS names, IPv4, bracketed IPv6, localhost, and internal single-label names. URL inputs accept only HTTP(S). Invalid or excessively long input normalizes to an empty string.",
|
||||
"version": 1,
|
||||
|
|
|
|||
|
|
@ -145,7 +145,17 @@ select {
|
|||
margin-top: 5px;
|
||||
border: 1px solid #374151;
|
||||
border-radius: 4px;
|
||||
padding: 7px 8px;
|
||||
padding: 7px 30px 7px 8px;
|
||||
appearance: none;
|
||||
background-color: #0f172a;
|
||||
background-image: linear-gradient(45deg, transparent 50%, #94a3b8 50%), linear-gradient(135deg, #94a3b8 50%, transparent 50%);
|
||||
background-position: calc(100% - 16px) 50%, calc(100% - 11px) 50%;
|
||||
background-size: 5px 5px, 5px 5px;
|
||||
background-repeat: no-repeat;
|
||||
color: #e5e7eb;
|
||||
}
|
||||
|
||||
select option {
|
||||
background: #0f172a;
|
||||
color: #e5e7eb;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue