diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index b5fde73b..0df53e7b 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -10,10 +10,11 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true -# contents: write -> publish the badge JSON to the `badges` branch (main only) # pull-requests: write -> post/update the per-PR coverage summary comment +# The live % badge is pushed to a GitHub Gist (see the gist step below) with a +# dedicated GIST_TOKEN secret, so this workflow no longer needs `contents: write` +# and no longer publishes a `badges` branch (which Cloudflare kept trying to deploy). permissions: - contents: write pull-requests: write jobs: @@ -68,22 +69,23 @@ jobs: core.warning(`Could not post coverage comment: ${e.message}`); } - # ---- Live % badge: publish shields.io endpoint JSON to `badges` branch ---- - - name: Generate badge JSON + # ---- Live % badge: push shields.io endpoint fields to a GitHub Gist ---- + # No Git branch is created, so Cloudflare Workers Builds has nothing extra + # to deploy. coverage-badge.mjs computes the message + color and hands them + # over as step outputs. Requires repo secret GIST_TOKEN (PAT with `gist` + # scope) and repo variable COVERAGE_GIST_ID (see README → Coverage badge). + - name: Generate badge fields + id: badge if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' run: npm run coverage:badge - - name: Stage badge for publish + - name: Push badge to coverage gist if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' - run: | - mkdir -p badge-publish - cp coverage/coverage-badge.json badge-publish/ - - - name: Publish badge to the `badges` branch - if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' - uses: peaceiris/actions-gh-pages@v3 + uses: Schneegans/dynamic-badges-action@v1.7.0 with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_branch: badges - publish_dir: ./badge-publish - force_orphan: true + auth: ${{ secrets.GIST_TOKEN }} + gistID: ${{ vars.COVERAGE_GIST_ID }} + filename: coverage-badge.json + label: coverage + message: ${{ steps.badge.outputs.message }} + color: ${{ steps.badge.outputs.color }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a0c6f9f..09c78004 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,33 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [2.0.0] - 2026-06-03 + +### Fixed +- **Spurious sign-out on page refresh (and the paid plan card vanishing with + it).** The auth bootstrap awaited a Supabase RPC (`has_role`) *inside* the + `onAuthStateChange` callback. supabase-js holds the GoTrue cross-tab Web Lock + for the duration of that callback, so the awaited call deadlocked token + refresh on reload — signing the user out and, downstream, collapsing the + subscription to the free tier (hiding the paid plan card). The admin-role + lookup is now deferred out of the callback; session/user state is set + synchronously. (Symptom only cleared on a full browser restart, since the + contended Web Lock survives reloads.) + ### Changed +- **Pricing cards now clarify that paid plans only cover cloud backups.** Every + storage line on the plan cards (home + sign-up) carries an asterisk to a new + footnote spelling out that storage on your own device is always unlimited and + free — paid tiers only back your datalogs up to the cloud (and help support + development). Removes the common confusion that you have to pay to keep using + the app or to store logs locally. +- **Coverage badge now publishes to a GitHub Gist instead of a `badges` branch.** + The orphan `badges` branch caused Cloudflare Workers Builds to repeatedly try + (and fail) to deploy a branch with no app in it. The `coverage.yml` workflow + now pushes the badge `%`/color to a gist via `Schneegans/dynamic-badges-action` + (repo secret `GIST_TOKEN` + variable `COVERAGE_GIST_ID`), drops its + `contents: write` permission, and no longer creates a Git branch. See the + README "Coverage badge" section for setup. - **Bumped the optional AI coach plugin (`@perchwerks/eye-in-the-sky`) from `0.3.0` to `0.4.1`, and pinned it to a tilde patch range (`~0.4.1`)** so coach `0.4.x` patch releases are picked up automatically on the next install, while a @@ -531,5 +557,6 @@ open-source project scaffolding and a bundle-size pass. admin, pro view, file-manager drawer, BLE download, and the Leaflet editor off the first-load path. -[Unreleased]: https://github.com/TheAngryRaven/DovesDataViewer/compare/v1.5.0...HEAD +[Unreleased]: https://github.com/TheAngryRaven/DovesDataViewer/compare/v2.0.0...HEAD +[2.0.0]: https://github.com/TheAngryRaven/DovesDataViewer/compare/v1.5.0...v2.0.0 [1.5.0]: https://github.com/TheAngryRaven/DovesDataViewer/compare/V1.0.0...v1.5.0 diff --git a/CLAUDE.md b/CLAUDE.md index 1d9466f4..cabb24e7 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -659,7 +659,10 @@ CI is split into five parallel workflows under `.github/workflows/` (`lint.yml`, `typecheck.yml`, `test.yml`, `build.yml`, `coverage.yml`). Each runs on every PR and push to `main` and shows up as its own status check + README badge. `coverage.yml` also enforces the thresholds in `vitest.config.ts`, -posts a per-PR summary comment, and publishes the % badge JSON. +posts a per-PR summary comment, and pushes the % badge fields to a **GitHub Gist** +(repo secret `GIST_TOKEN` + repo variable `COVERAGE_GIST_ID`) — not a Git branch, +so Cloudflare Workers Builds has no badge-only branch to try to deploy. See the +README "Coverage badge" section for the gist wiring. --- diff --git a/README.md b/README.md index 5b3206fb..a1756051 100644 --- a/README.md +++ b/README.md @@ -7,11 +7,12 @@ [](https://github.com/TheAngryRaven/DovesDataViewer/actions/workflows/typecheck.yml) [](https://github.com/TheAngryRaven/DovesDataViewer/actions/workflows/test.yml) [](https://github.com/TheAngryRaven/DovesDataViewer/actions/workflows/build.yml) -[](https://github.com/TheAngryRaven/DovesDataViewer/actions/workflows/coverage.yml) +[](https://github.com/TheAngryRaven/DovesDataViewer/actions/workflows/coverage.yml) 🌐 **Live Demo:** [HackTheTrack.net](https://hackthetrack.net) 🔧 **Hardware Project:** [DovesDataLogger on GitHub](https://github.com/TheAngryRaven/DovesDataLogger) +**Now officially in BETA status** ---
@@ -283,6 +284,24 @@ Open [http://localhost:8080](http://localhost:8080) in your browser.
| `npm test` | Run Vitest in watch mode |
| `npm run test:run` | Run Vitest once (CI-style) |
+### Coverage badge
+
+The live coverage badge is a [shields.io endpoint](https://shields.io/badges/endpoint-badge)
+backed by a **GitHub Gist** (not a Git branch — that kept Cloudflare Workers
+Builds trying to deploy a badge-only branch). The `coverage.yml` workflow runs
+`npm run coverage:badge` (which computes the `%` + color from the Vitest summary)
+and pushes those fields to the gist on every push to `main`. To wire it up on a
+fork:
+
+1. Create a **public** gist with a single file named `coverage-badge.json`
+ (any placeholder contents) and copy its ID from the URL
+ (`gist.github.com/
+ * Storage on your own device is always unlimited and free.
+ Paid plans only cover cloud backups of your datalogs —
+ so you can dump as many logs as you like and keep them synced across devices. Upgrading mostly just helps
+ support development ❤️
+