From a091c7ad88f1853b99f8d2e43bba145e7ff5ad38 Mon Sep 17 00:00:00 2001 From: MartinBraquet Date: Mon, 27 Jul 2026 01:26:14 +0200 Subject: [PATCH] Add CHANGELOG.md and integrate user-facing release notes with technical details into `release.sh` and `/news` page. Enhance `/news` with collapsible technical sections and improve localization. --- CHANGELOG.md | 107 ++++++++++++++++++++++++++++++++++++++++ common/messages/de.json | 2 + common/messages/fr.json | 2 + package.json | 2 +- scripts/release.sh | 36 ++++++++++++-- web/pages/news.tsx | 101 +++++++++++++++++++++++++++---------- 6 files changed, 218 insertions(+), 32 deletions(-) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..3f6faf94 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,107 @@ +# Changelog + +Release notes for Compass. `scripts/release.sh` reads the entry for the version being tagged straight out +of this file and uses it as the GitHub release body (falls back to `gh release --generate-notes` if no +entry matches). That release body is what the [/news](/news) page reads, via the GitHub Releases API — so +an entry here only reaches users once its version is actually tagged and released. + +Each entry: + +- Starts with `## ` (must match `package.json`'s `version` exactly) and ends at the next `## ` + heading or a `---` separator line — `scripts/release.sh` parses on that boundary. +- Has two parts, in order: + 1. A **user-facing summary** — plain language, no internals. Shown by default on `/news`. + 2. A **technical details** section — implementation-level notes. Collapsed behind a "Show technical + details" toggle on `/news`. +- Separates those two parts with an HTML comment, ``, alone on its own line. That exact marker + is what `web/pages/news.tsx` splits on. An entry without the marker (e.g. old releases before this + convention) just renders as-is on `/news`, with no expandable section — keep that in mind while + backfilling. + +To edit an already-published release's notes to match this convention, use +`gh release edit --notes-file <(sed ...)` or paste manually in the GitHub UI — `scripts/release.sh` +only runs at tag-creation time, so it won't touch releases that already exist. + +--- + +## 1.13.0 — 2026-07-27 + +### New features + +- Voice messages: record, transcribe, and play back audio directly in profiles and chats +- Added a media creator tool for building profile photos/videos in-app +- Added a searchable FAQ page with categories and deep links to individual answers +- Signal is now a supported way to share contact info (phone number or signal.me link) +- Finnish added to the list of profile languages +- Sexual orientation is now its own profile field, with expanded gender options +- Added neurotype and other accessibility fields to profiles +- "Get Notified" button on saved searches — get alerted as soon as a new match appears +- Redesigned notifications: clearer settings and empty states explaining what triggers an alert + +### Improvements + +- Redesigned the About page with growth stats and clearer help cards +- Redesigned the sidebar for better accessibility and visual hierarchy +- Saved profiles are now called "bookmarks" instead of "stars" throughout the app +- Added a lightbox for viewing a profile's pinned photos/videos +- Nudge to keep your account (instead of deleting it) when matches are scarce +- Customizable share icon and a targeted share sheet for sending profiles to friends +- Hint to help you center your face when uploading a profile picture +- Tidied up filter labels; moved "relationship style", "raised in", and "causes" into clearer sections +- Refined numeric-range and diet filters to handle edge cases better +- Added a world map and demographic breakdowns to the `/stats` page + +### Trust & safety + +- Added a spam guard that limits new conversations per day and auto-bans abusers +- Banned and disabled profiles no longer appear in search results +- Added limitations for accounts flagged as suspicious +- Added the ability to report a message channel + + + +### Backend & API + +- `compute-scores`: delete invalid compatibility-score rows instead of nulling them; exclude null scores + when ordering profiles, with test coverage +- `searchUsers`: exclude banned users and disabled profiles at the query level when `excludeUnavailable` is + set, with unit tests +- Hardened SQL across notification settings, private messages, and GeoDB API requests (input sanitization, + stricter limit validation) +- `content_owner_id` made nullable on `reports`; removed the outdated "self update" policy on `profiles` +- Added `getChannelsCount` API endpoint +- Refactored profile column retrieval for better caching +- API version bumped 1.40.0 → 1.50.0 across the range + +### Android + +- Declared microphone permissions and runtime permission handling for voice recording +- Added a custom icon/color for FCM push notifications +- Added `MEDIA_SOURCE_BASE_URL` to the CD build environment +- Bumped `compileSdkVersion`/`targetSdkVersion` to 36; app version bumped through 1.31.1 (versionCode 133) + +### Testing + +- Restructured the Playwright E2E suite around a POM/Fixture app-class pattern +- Added a multi-account context manager for tests that need several accounts interacting at once +- Added coverage for messaging, profile hiding/bookmarking, filters, onboarding, compatibility questions, + and Google-account sign-in +- Added DB seeding and account-cleanup helpers for test isolation + +### Performance + +- Reduced excessive re-renders in the rich-text editor; editor max-height is now computed dynamically +- Added loading skeletons and avoided redundant refetches on the profiles grid + +### Tooling & docs + +- Added scripts for OG/social-preview card rendering, AI-generated showcase portraits, vote-tally capture, + and demo/tour video generation (Remotion) +- Vote-tally images switched to PNG; dropped the narrow and WebP variants +- Added `.env.local` override support to `run_local.sh`; added dev DB/Firebase reset commands +- Added F-Droid publishing documentation and a React/TypeScript fundamentals guide; added `CLAUDE.md` to + several sub-packages + +--- + + diff --git a/common/messages/de.json b/common/messages/de.json index 024a713d..2cb9500d 100644 --- a/common/messages/de.json +++ b/common/messages/de.json @@ -642,10 +642,12 @@ "nav.social": "Sozial", "nav.vote": "Abstimmung", "news.failed": "Abrufen der Versionen fehlgeschlagen.", + "news.hide_technical_details": "Technische Details ausblenden", "news.no_release_notes": "_Keine Versionshinweise vorhanden._", "news.note": "Hinweis: Leider ist diese Seite nur auf Englisch verfügbar.", "news.seo.description": "Die neuesten Updates und Funktionen ansehen", "news.seo.description_general": "Alle Neuigkeiten und Code-Updates für Compass", + "news.show_technical_details": "Technische Details anzeigen", "news.title": "Neuigkeiten", "news.view_on_github": "Auf GitHub ansehen", "notifications.comment.commented": "kommentierte ", diff --git a/common/messages/fr.json b/common/messages/fr.json index 7eb41ca8..7cf59762 100644 --- a/common/messages/fr.json +++ b/common/messages/fr.json @@ -642,10 +642,12 @@ "nav.social": "Social", "nav.vote": "Vote", "news.failed": "Échec de la récupération des versions.", + "news.hide_technical_details": "Masquer les détails techniques", "news.no_release_notes": "_Aucune note de version fournie._", "news.note": "Note : Malheureusement, cette page n'est disponible qu'en anglais.", "news.seo.description": "Voir les dernières mises à jour et fonctionnalités", "news.seo.description_general": "Toutes les actualités et mises à jour du code pour Compass", + "news.show_technical_details": "Afficher les détails techniques", "news.title": "Quoi de neuf", "news.view_on_github": "Voir sur GitHub", "notifications.comment.commented": "a commenté ", diff --git a/package.json b/package.json index 0c97a983..09267d11 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "compass", - "version": "1.12.0", + "version": "1.13.0", "private": true, "workspaces": [ "common", diff --git a/scripts/release.sh b/scripts/release.sh index 82aee118..e234825c 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -15,11 +15,37 @@ if [ -z "$tagged" ]; then git push origin "$tag" echo "Tagged release $tag" - gh release create "$tag" \ - --repo="$GITHUB_REPOSITORY" \ - --title="$tag" \ - --generate-notes - echo "Created release" + # Pull this version's entry out of CHANGELOG.md (see the file header for the format: a user-facing + # summary, a `` marker, then technical details). An entry ends at the next `## ` heading or a + # `---` separator line. Falls back to --generate-notes when the version has no hand-written entry yet, so + # releases without a changelog entry still get created. + notes_file=$(mktemp) + awk -v tag="$tag" ' + /^## / { + if (found) exit + if ($0 ~ ("^## " tag "([^0-9.]|$)")) { found=1; next } + next + } + found { + if ($0 == "---") exit + print + } + ' CHANGELOG.md | sed -e '/./,$!d' > "$notes_file" + + if [ -s "$notes_file" ]; then + gh release create "$tag" \ + --repo="$GITHUB_REPOSITORY" \ + --title="$tag" \ + --notes-file "$notes_file" + echo "Created release from CHANGELOG.md entry" + else + gh release create "$tag" \ + --repo="$GITHUB_REPOSITORY" \ + --title="$tag" \ + --generate-notes + echo "Created release (no CHANGELOG.md entry found for $tag, used --generate-notes)" + fi + rm -f "$notes_file" # Release to ... diff --git a/web/pages/news.tsx b/web/pages/news.tsx index 3a2e37d7..dea23955 100644 --- a/web/pages/news.tsx +++ b/web/pages/news.tsx @@ -1,6 +1,8 @@ +import {ChevronDownIcon, ChevronUpIcon} from '@heroicons/react/24/solid' import {githubRepoSlug} from 'common/constants' import {useEffect, useState} from 'react' import {Col} from 'web/components/layout/col' +import {Row} from 'web/components/layout/row' import {CustomLink} from 'web/components/links' import {CustomMarkdown} from 'web/components/markdown' import {EnglishOnlyWarning} from 'web/components/news/english-only-warning' @@ -11,6 +13,22 @@ import {useT} from 'web/lib/locale' import {getPageData} from 'web/lib/util/page-data' import {isNativeMobile} from 'web/lib/util/webview' +// Release notes are written with a user-facing summary followed by a technical section, separated by this +// marker on its own line (see CHANGELOG.md). Only the summary renders by default; the technical section is +// tucked behind a toggle. Releases predating this convention have no marker, so they render as-is. +const TECHNICAL_SECTION_MARKER = '' + +function splitReleaseNotes(body: string): {summary: string; technical: string | null} { + const markerIndex = body.indexOf(TECHNICAL_SECTION_MARKER) + if (markerIndex === -1) { + return {summary: body, technical: null} + } + return { + summary: body.slice(0, markerIndex).trim(), + technical: body.slice(markerIndex + TECHNICAL_SECTION_MARKER.length).trim(), + } +} + async function fetchReleases() { const releases = await fetch(`https://api.github.com/repos/${githubRepoSlug}/releases`) .then((r) => r.json()) @@ -109,32 +127,7 @@ export default function WhatsNew(props: {releases?: Release[]}) { {releases.map((release: Release) => ( -
-
-

- {release.name || release.tag_name} -

- - {new Date(release.published_at).toISOString().split('T')[0]} - -
-
- - {formatPullLinks( - release.body || t('news.no_release_notes', '_No release notes provided._'), - )} - -
- - {t('news.view_on_github', 'View on GitHub')} - -
+ ))} )} @@ -142,6 +135,62 @@ export default function WhatsNew(props: {releases?: Release[]}) { ) } +function ReleaseCard(props: {release: Release}) { + const {release} = props + const t = useT() + const [showTechnical, setShowTechnical] = useState(false) + + const {summary, technical} = splitReleaseNotes( + formatPullLinks(release.body || t('news.no_release_notes', '_No release notes provided._')), + ) + + return ( +
+
+

+ {release.name || release.tag_name} +

+ + {new Date(release.published_at).toISOString().split('T')[0]} + +
+
+ {summary} +
+ {technical && ( +
+ + {showTechnical && ( +
+ {technical} +
+ )} +
+ )} + + {t('news.view_on_github', 'View on GitHub')} + +
+ ) +} + function formatPullLinks(text = '') { return text .replace('CompassMeet', 'CompassConnections')