fix: avoid false community-bot outage alerts
Some checks are pending
Deploy to GitHub Pages / deploy (push) Waiting to run

This commit is contained in:
SkateSpots 2026-11-01 11:24:01 +07:00
parent 719a6791f9
commit ae1d7275e6
5 changed files with 32 additions and 12 deletions

View file

@ -2237,7 +2237,7 @@ session with **no other memory of this project**. So:
instead of showing the error boundary. instead of showing the error boundary.
- **Baselines** (verified 2026-10-29): `npm test` → **0 errors, 0 warnings**, - **Baselines** (verified 2026-10-29): `npm test` → **0 errors, 0 warnings**,
**156 tests**, build ok. The gate also type-checks the CVM server **156 tests**, build ok. The gate also type-checks the CVM server
(`tsc -p cvm-server/tsconfig.json`). `package.json` version **1.7.72**. (`tsc -p cvm-server/tsconfig.json`). `package.json` version **1.7.73**.
- ✅ Lint is **clean**: `no-explicit-any` = 0 · `react-hooks/exhaustive-deps` = 0 - ✅ Lint is **clean**: `no-explicit-any` = 0 · `react-hooks/exhaustive-deps` = 0
· `no-unused-vars` = 0 · `react-refresh` = 0. Non-component exports were · `no-unused-vars` = 0 · `react-refresh` = 0. Non-component exports were
**split into their own modules** (`contexts/language.ts`, `lib/sortOptions.ts`, **split into their own modules** (`contexts/language.ts`, `lib/sortOptions.ts`,
@ -2464,7 +2464,7 @@ Rules:
or `FORGEJO_PASSWORD`; `scripts/release.sh` calls it automatically when either or `FORGEJO_PASSWORD`; `scripts/release.sh` calls it automatically when either
is set). It uploads the APK and checksum, but does not push git history. is set). It uploads the APK and checksum, but does not push git history.
- **Self-hosted F-Droid repo:** `https://fdroid.skate-spots.org/repo` - **Self-hosted F-Droid repo:** `https://fdroid.skate-spots.org/repo`
(`org.skatespots.app`; currently 1.7.72). It is a **third-party repo**, not (`org.skatespots.app`; currently 1.7.73). It is a **third-party repo**, not
F-Droid main. Repo signing fingerprint: F-Droid main. Repo signing fingerprint:
`88:B1:71:1C:24:02:89:FB:B2:A7:FC:C1:B3:1F:BB:9D:60:F5:7F:19:18:E0:3D:62:2D:35:F2:3D:E1:84:46:75`. `88:B1:71:1C:24:02:89:FB:B2:A7:FC:C1:B3:1F:BB:9D:60:F5:7F:19:18:E0:3D:62:2D:35:F2:3D:E1:84:46:75`.
The developer APK signature is unchanged; the repo key only signs indexes. The developer APK signature is unchanged; the repo key only signs indexes.
@ -2522,6 +2522,10 @@ Rules:
- Flags: `--probe-push` runs a bounded 45s **real** `git push` — signing only happens when there *is* something to push, so this is the only true signer probe (it publishes any unpushed commits; a timeout ⇒ signer down ⇒ open Amber in the foreground, or `ngit account login --interactive`). `--notify` = desktop notification (deduped by an actionable-problem signature). `--quiet` = silent when healthy. Test against a fake state dir with `SKATESPOTS_STATE_DIR=…`. - Flags: `--probe-push` runs a bounded 45s **real** `git push` — signing only happens when there *is* something to push, so this is the only true signer probe (it publishes any unpushed commits; a timeout ⇒ signer down ⇒ open Amber in the foreground, or `ngit account login --interactive`). `--notify` = desktop notification (deduped by an actionable-problem signature). `--quiet` = silent when healthy. Test against a fake state dir with `SKATESPOTS_STATE_DIR=…`.
- ⚠️ `git push --dry-run` does **NOT** exercise signing (prints "Everything up-to-date", never signs) — do not use it as a signer probe. - ⚠️ `git push --dry-run` does **NOT** exercise signing (prints "Everything up-to-date", never signs) — do not use it as a signer probe.
- **Runs automatically every 15 min:** `skatespots-ops-health.timer` → `skatespots-ops-health.service` (`--quiet --notify`). Install/refresh with `scripts/install-ops-health-timer.sh`; logs `journalctl --user -u skatespots-ops-health`. - **Runs automatically every 15 min:** `skatespots-ops-health.timer` → `skatespots-ops-health.service` (`--quiet --notify`). Install/refresh with `scripts/install-ops-health-timer.sh`; logs `journalctl --user -u skatespots-ops-health`.
- **Community bot check is conservative:** a failed SSH probe now reports
“state unknown” and does **not** notify. Only an actual `inactive`/`failed`
systemd state is actionable. This stops transient SSH/DNS hiccups from
producing “community Cordn bot is unreachable” notifications.
- **Web (manual)**: `npm run build` produces the web `dist/` (with `_headers`/`_redirects`); deploy by dragging `dist/` to the Netlify site's Deploys tab. - **Web (manual)**: `npm run build` produces the web `dist/` (with `_headers`/`_redirects`); deploy by dragging `dist/` to the Netlify site's Deploys tab.
- **Zapstore (Android)**, from the repo root: `SIGN_WITH='bunker://...' zsp publish zapstore.yaml` - **Zapstore (Android)**, from the repo root: `SIGN_WITH='bunker://...' zsp publish zapstore.yaml`
- `zsp publish --wizard` is **broken for this app** (the wizard can't parse a nostrhub web `repository` — it supports only GitHub/GitLab/Gitea/F-Droid/local). Always pass `zapstore.yaml`. - `zsp publish --wizard` is **broken for this app** (the wizard can't parse a nostrhub web `repository` — it supports only GitHub/GitLab/Gitea/F-Droid/local). Always pass `zapstore.yaml`.
@ -2941,6 +2945,10 @@ Rules:
shared merge path; image/avatar requests and the site referrer policy use shared merge path; image/avatar requests and the site referrer policy use
no-referrer. APK sha256 `c2169cae…`, versionCode 10772. Web live at no-referrer. APK sha256 `c2169cae…`, versionCode 10772. Web live at
`78741f9`. `78741f9`.
- **1.7.73 (2026-11-01):** login dialog now has two adaptive methods:
Amber on Android, NIP-46 QR on desktop, with bunker paste as a secondary
path and no duplicate NIP-46 card. APK sha256 `bcd51861…`, versionCode
10773. Web live at `719a679`.
### Relay archive (dataset backup) ### Relay archive (dataset backup)
- **Transfer content between keys (`scripts/transfer-content.mjs`, 2026-10-04):** - **Transfer content between keys (`scripts/transfer-content.mjs`, 2026-10-04):**

View file

@ -7,10 +7,10 @@ account is required.
- Forge: <https://git.skate-spots.org/skatespots/SkateSpots> - Forge: <https://git.skate-spots.org/skatespots/SkateSpots>
- Latest release: <https://git.skate-spots.org/skatespots/SkateSpots/releases/latest> - Latest release: <https://git.skate-spots.org/skatespots/SkateSpots/releases/latest>
- Signed APK (1.7.72): - Signed APK (1.7.73):
<https://git.skate-spots.org/skatespots/SkateSpots/releases/download/v1.7.72/SkateSpots-1.7.72.apk> <https://git.skate-spots.org/skatespots/SkateSpots/releases/download/v1.7.73/SkateSpots-1.7.73.apk>
- SHA-256: - SHA-256:
`c2169caecab538ebff661a287d211f07c516a96ec05287f18baa2a75ef0a8169` `bcd51861f8bba7b01d632d6f20f692f6f727f7ae31e9f5c6ee059565164b5bc4`
The APK is signed with the same key as the Zapstore build. Installing an The APK is signed with the same key as the Zapstore build. Installing an
F-Droid-signed build over it would require uninstalling SkateSpots and losing F-Droid-signed build over it would require uninstalling SkateSpots and losing

View file

@ -0,0 +1 @@
The login dialog now shows two adaptive methods: Amber on Android, or NIP-46 QR pairing on desktop. Bunker paste is a secondary path, and the duplicate NIP-46 card was removed.

View file

@ -98,16 +98,16 @@
<a <a
class="download" class="download"
href="https://git.skate-spots.org/skatespots/SkateSpots/releases/download/v1.7.72/SkateSpots-1.7.72.apk" href="https://git.skate-spots.org/skatespots/SkateSpots/releases/download/v1.7.73/SkateSpots-1.7.73.apk"
rel="noopener" rel="noopener"
> >
<span>Download SkateSpots-1.7.72.apk · 56 MB</span> <span>Download SkateSpots-1.7.73.apk · 56 MB</span>
<span aria-hidden="true">↓</span> <span aria-hidden="true">↓</span>
</a> </a>
<div class="meta"> <div class="meta">
<span>Requires Android 7.0 or newer.</span> <span>Requires Android 7.0 or newer.</span>
<span>SHA-256: <code>c2169caecab538ebff661a287d211f07c516a96ec05287f18baa2a75ef0a8169</code></span> <span>SHA-256: <code>bcd51861f8bba7b01d632d6f20f692f6f727f7ae31e9f5c6ee059565164b5bc4</code></span>
<span>Only install APKs from a source you trust. Android will ask you to allow installs from your browser.</span> <span>Only install APKs from a source you trust. Android will ask you to allow installs from your browser.</span>
</div> </div>

View file

@ -218,12 +218,23 @@ p ""
p "${B}Community bot${N}" p "${B}Community bot${N}"
COMMUNITY_HOST="${SKATESPOTS_COMMUNITY_HOST:-skatespots-cvm}" COMMUNITY_HOST="${SKATESPOTS_COMMUNITY_HOST:-skatespots-cvm}"
if command -v ssh >/dev/null 2>&1 && grep -qsE "^Host[[:space:]]+${COMMUNITY_HOST}([[:space:]]|$)" "$HOME/.ssh/config"; then if command -v ssh >/dev/null 2>&1 && grep -qsE "^Host[[:space:]]+${COMMUNITY_HOST}([[:space:]]|$)" "$HOME/.ssh/config"; then
community_state="$(timeout 8 ssh -o BatchMode=yes -o ConnectTimeout=5 "$COMMUNITY_HOST" 'systemctl is-active skatespots-community' 2>/dev/null || true)" # A failed SSH connection is NOT evidence that the remote bot is down. The
if [ "$community_state" = "active" ]; then # previous version turned an empty SSH result into "unreachable" and emitted
# an ops notification on every transient network/DNS hiccup. Retry once, then
# report an honest unknown state without alerting.
community_state=""
for attempt in 1 2; do
community_state="$(timeout 8 ssh -o BatchMode=yes -o ConnectTimeout=5 "$COMMUNITY_HOST" 'systemctl is-active skatespots-community' 2>/dev/null || true)"
[ -n "$community_state" ] && break
[ "$attempt" = "1" ] && sleep 1
done
if [ -z "$community_state" ]; then
p " ${Y}⚠${N} skatespots-community: health check unreachable (SSH failed; state unknown)"
elif [ "$community_state" = "active" ]; then
p " ${G}✓${N} skatespots-community active" p " ${G}✓${N} skatespots-community active"
else else
p " ${R}✗${N} skatespots-community: ${community_state:-unreachable}" p " ${R}✗${N} skatespots-community: ${community_state}"
problems+=("community Cordn bot is ${community_state:-unreachable}") problems+=("community Cordn bot is ${community_state}")
signature+="community-bot;" signature+="community-bot;"
fi fi
community_backup="$(systemctl --user is-active skatespots-community-backup.timer 2>/dev/null || echo unknown)" community_backup="$(systemctl --user is-active skatespots-community-backup.timer 2>/dev/null || echo unknown)"