diff --git a/.gitea/workflows/publish.yml b/.gitea/workflows/publish.yml index be7ab56..ec0eaa9 100644 --- a/.gitea/workflows/publish.yml +++ b/.gitea/workflows/publish.yml @@ -88,9 +88,9 @@ jobs: tag="${{ github.ref_name }}" api="${{ github.server_url }}/api/v1/repos/${{ github.repository }}" auth="Authorization: token ${{ secrets.GITHUB_TOKEN }}" - subject=$(git log -1 --format=%s) - body=$(printf '{"tag_name":"%s","name":"%s"}' \ - "$tag" "$tag: $(echo "$subject" | sed 's/"/\\"/g')") + # The release notes are this version's section of CHANGELOG.md. + notes=$(awk -v v="${tag#v}" '/^## /{p = ($2 == v)} p' CHANGELOG.md | tail -n +2) + body=$(jq -n --arg tag "$tag" --arg notes "$notes" '{tag_name: $tag, name: $tag, body: $notes}') id=$(curl -sf -X POST -H "$auth" -H 'Content-Type: application/json' \ -d "$body" "$api/releases" | jq .id) \ || id=$(curl -sf -H "$auth" "$api/releases/tags/$tag" | jq .id) diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..3d7e116 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,282 @@ +# Changelog + +One line per change, grouped by the release that shipped it. Newest +first. A release is a Cargo.toml bump plus a `v` tag; the +content repos pin the tag they run (see the end of this file). + +## Unreleased + +- One bounded HTTP client for every server-side fetch: 20 s budget, size caps per kind of fetch (`src/http.rs`) +- Uploads are refused past 20 MB while streaming, and the route body limit that had capped them at axum's 2 MB default is raised to match +- `tests/jetstream.rs`: the store, the event log and the projection tested against a real JetStream (CI starts a throwaway one) +- `content` split into `gitea`, `validate`, `markdown`, `handlers`; every path still `content::x` +- This changelog, and the table of what each site runs +- Business needs as a checkable spec: needs.yaml + question_lint pass +- needs: `success` states and a resolved simulation model +- needs: `stages` - every stage the business named must be a state +- needs_replay: make simulated cases real aggregates, report buckets by state +- needs: also_moved_by - a need carried by more than one group's desk + +## 0.3.35 (2026-09-12) + +- Item cards: no paragraph margin under the description + +## 0.3.34 (2026-09-11) + +- Question nav: offer followups by reach, not by carrying any chain + +## 0.3.33 (2026-09-02) + +- Head preloads: latin font, wordmark, content-host preconnect + +## 0.3.32 (2026-09-01) + +- Per-site favicon via site.yaml + +## 0.3.31 (2026-09-01) + +- Markdown links allow tel: + +## 0.3.30 (2026-09-01) + +- Single alt-image shows natural height + +## 0.3.29 (2026-09-01) + +- Markdown image layout hints + AVIF assets + +## 0.3.28 (2026-09-01) + +- Hero description renders inline markdown + +## 0.3.27 (2026-09-01) + +- wordmark_invert: explicit, not inferred from .svg + +## 0.3.26 (2026-09-01) + +- Select fields: inline static options + +## 0.3.25 (2026-09-01) + +- Content-shipped stylesheet override (site.yaml stylesheet) + +## 0.3.24 (2026-09-01) + +- Gateway submit-as-link loses the underline + +## 0.3.23 (2026-09-01) + +- Chrome speaks the site's language: site.yaml lang + i18n table + +## 0.3.22 (2026-09-01) + +- site.yaml wordmark_height; raster logos keep their colors + +## 0.3.21 (2026-09-01) + +- Hero paragraph centers its measure box + +## 0.3.20 (2026-09-01) + +- Sign-in becomes optional: KANIDM_URL unset disables auth cleanly + +## 0.3.19 (2026-09-01) + +- Markdown images in descriptions, gated and framed + +## 0.3.18 (2026-09-01) + +- Item cards render inline markdown descriptions +- Convergence: ink converges onto the decoded key (WebGL glow) +- Gesture results overlay the canvas - the page never jumps + +## 0.3.16 (2026-08-30) + +- Announce sweeper: refresh open records from content + +## 0.3.15 (2026-08-30) + +- Hidden fields: carrier value without a label row + +## 0.3.14 (2026-08-30) + +- Feature cards: icon column, one text edge + +## 0.3.13 (2026-08-30) + +- Voice field: nothing leaves the browser until Keep it here + +## 0.3.12 (2026-08-30) + +- Voice preview stays hidden until there is something to play + +## 0.3.11 (2026-08-30) + +- README: gesture and voice fields +- Validate templated actions against the page pattern + +## 0.3.10 (2026-08-30) + +- type: voice, Requirement.value, playable resource cards + +## 0.3.9 (2026-08-30) + +- Templated actions; places are pickable in the gesture input + +## 0.3.8 (2026-08-30) + +- Descriptions are inline markdown; Feature.link withdrawn + +## 0.3.7 (2026-08-30) + +- Feature.link: a card's name may point elsewhere + +## 0.3.6 (2026-08-30) + +- Announced pages: event windows, header announcements, summary tasks + +## 0.3.5 (2026-08-30) + +- Gesture widget: stop drawing the decoded ghost path +- Gesture widget: ghost path back, for v2 keys only + +## 0.3.4 (2026-08-25) + +- Alternative.disabled: announced but not yet takeable + +## 0.3.3 (2026-08-25) + +- Empty list says so before it can parse as zero answers + +## 0.3.2 (2026-08-25) + +- README: hashed pkg assets in the release flow +- Resource empty text: content-declared, and null counts as empty + +## 0.3.1 (2026-08-25) + +- Content-hashed pkg assets (hash-files) so stale bundles can't pair with new wasm + +## 0.3.0 (2026-08-25) + +- Hero becomes a content-owned module; site asset proxy; gesture growth fix + +## 0.2.4 (2026-08-25) + +- Gates keep the question nav + +## 0.2.3 (2026-08-25) + +- Attended-bucket lint rule; app-lifetime resources fix first-nav corruption + +## 0.2.2 (2026-08-24) + +- One app-level Title fed by a shared site resource + +## 0.2.1 (2026-08-24) + +- Docs: routing bullet + design doc marked implemented +- Revalidating cache on app assets; site title survives SPA navigation + +## 0.2.0 (2026-08-24) + +- Initial commit: content-driven onboarding portal +- Load content from Gitea directly, drop the local clone; add deploy workflow +- Share sccache between manual dev builds and CI +- Give CI its own SCCACHE_SERVER_PORT +- Erase view types at every list/component boundary, not just leaves +- Redirect cargo-leptos's tool cache out of act-runner-bare's StateDirectory +- Fix Ship release: site-root is project-relative, not CARGO_TARGET_DIR +- Drop sudo from the deploy workflow - NoNewPrivileges blocks it outright +- Caddy snippet: use multi-line log block +- Fix static asset 404s and build-time SITE_NAME +- Hot-reload content on a NATS trigger instead of requiring a restart +- Add prosekit rich-text field, Gitea repo embeds, automation KV read endpoint; fix apex/www session-cookie mismatch on /auth/callback +- Fix prosekit-editor.js: remove bare CSS imports that aborted the whole module +- Redirect back to the originating page after sign-in, not always / +- Fix hero-canvas navigation race; style the prosekit editor and add a toolbar +- yes.js: guard against the canvas not being in the DOM yet +- Fix get_resource/transition_answer: scope feature lookup to its own alternative +- Add self-service transitions, authorized by item possession not group membership +- Event-sourced applicant/subscriber/project aggregates, generalized resources +- deploy.yml: write GITEA_API_TOKEN for the new GiteaStarred/OrgRepos resource sources +- Cargo.toml: disambiguate bin-target for cargo-leptos +- Add manually-triggered backfill workflow, no terminal/sudo needed +- Trigger redeploy to pick up PORTAL_GITEA_API_TOKEN secret +- Render generic resource lists as cards, not raw JSON dump +- Fix recursion-limit build failure in the new item-card renderer +- Resource-backed multi/single-select requirement +- Add Organization aggregate (client-as-status), wired but inert +- Fix favicon (real icon, not an unrelated orange circle) + stack encouragements with the submit button +- Fix bucket-404 on empty resources, redesign review actions as select-then-confirm, CSS polish +- Inline encouragements with the submit button, vertically centered +- Use the real institutional logo for the header wordmark, not plain text +- Use the actual UHHM-letters wordmark, not the institutional mark +- Responsive base font size via svmin, not fixed 17px +- Add plain-unit fallbacks for svmin/svh in case of unsupported engines +- Size the YES canvas from its container, not window.innerHeight +- Debounce the YES canvas resize handler and skip no-op resizes +- Revert canvas sizing to window.innerWidth/innerHeight, gate resize on width change +- Stop blocking native scroll on the YES canvas's touch handlers +- Quicksand: font-display optional, not swap, to stop the text-jump on scroll +- Use lvh/lvmin, not svh/svmin - svh was the wrong end of the viewport +- Update style/main.css +- Update style/main.css +- YES canvas: size off its own container rect, not window.innerHeight +- yes.js: freeze .hero-yes's height via inline style, don't trust svh alone +- add responsive container width +- deploy.yml: build and publish question_lint alongside the app binary +- Make aggregate state graphs content-driven, not compiled Rust +- One shared, content-labeled Confirm button per alternative instead of one per row +- get_resource/get_requirement_options: #[server(default)] on params +- Add optional Alternative.image and Feature.color/icon for richer layouts +- Drop the feature list's left-padding +- Drop question-report entirely, obfuscate the mailto link instead +- Transition.from: state graphs deeper than one decision +- Alternative.images: array of urls, rendered as a Swiper card deck +- Reseed lost event history from the KV projection on transition +- Lighten the comment load +- Validate action targets; format timestamps client-side; clippy cleanup +- Question nav + gateway alternatives +- Responsible note under the title; followup pages out of the nav until a chain exists +- README: what the engine provides +- Feature icons: masked span painted by currentColor, not +- Responsible note: one line, same hue and size as the hero description +- Responsible note as : meta information, dimmer than the description +- Responsible note back to the footer, above the question nav +- Bound inputs: a field that loads its value from a sibling-parameterized resource +- add some more width to our alternatives +- Accent to a dusty press-cyan, a muted echo of the canvas's cyan ink +- Editor type in rem: prosekit's px typography ignored the responsive root +- Ban px from stylesheets: every length rem/em off the responsive root +- No translucent input chrome: solid ink-dim placeholders and embed meta +- Editor type scales for real: drop prosekit typography.css, fix selectors +- Stable server fn endpoints: open tabs survive deploys +- Drop stray local tool temp file, ignore .claude/ +- Noise-driven YES, sticky hero with frosted cards, full light theme +- increase translucency of laternative cards +- Showcase jq test tracks Gitea repo shape and website-first links +- Gesture input type, redoal-relay client, gitea_releases, content-driven branding +- Echo thumbnails fade in via timeout, not rAF +- Trigger deploy: redoal OAuth2 credentials now configured +- Deploy becomes publish: portal ships as a versioned release artifact +- Semver releases cut with cargo-release; publish on v* tags only +- Docs: release/rollout flow after the instance-ownership refactor +- README: frame portal as a generic multi-site question engine +- Design doc: filesystem routes, sections, dynamic segments +- Filesystem routes, sections, dynamic segments; instant YES hero + + +## What each site runs + +Read from the hosts on 2026-09-22; a rollout is a pin bump in the +site's content repo (`PORTAL_RELEASE` in its `deploy.yml`), or a manual +tarball deploy on kasse. + +| Site | Host | Instance | Version | +|---|---|---|---| +| uhhm.no | ergo | `app@uhhm-portal` | v0.3.35 | +| redoal.com | ergo | `app@redoal-portal` | v0.3.35 | +| westra.klingenbergbygg.no | kasse | `app@westra-portal` | v0.3.35 | +| portal.klingenbergbygg.no | kasse | `app@klingenberg-portal` | v0.3.35 | diff --git a/README.md b/README.md index e9b017c..ee0bebf 100644 --- a/README.md +++ b/README.md @@ -142,6 +142,11 @@ content-hashed (`hash-files = true`; instances run with stale cached bundle with new wasm. Plain pushes to `main` only run the tests (`test.yml`) — nothing reaches production from this repo. +Before cutting, move the `Unreleased` lines in `CHANGELOG.md` under a +heading for the new version. That section becomes the Gitea release +notes, and the table at the end of the file records which version each +site runs; update it when a pin moves. + **Roll it out** (in a content repo): edit one line in that repo's `.gitea/workflows/deploy.yml` —