Step 3 of milestone 481 (Scribe note 5071: a full rename).
- crates thoughtsync-{core,desktop,ffi,uniffi-bindgen} → inkwell-*, the
Cargo.lock entries moved to match (checked with `cargo metadata --locked`)
- Tauri: productName "Inkwell", identifier com.fabledsword.inkwell, binary
`inkwell`, updater feed on bvandeusen/inkwell, store file inkwell.db
- client agent inkwell-desktop, headers X-Inkwell-Client/-Protocol (the server
reads neither), capture event inkwell://captured, display-version env
- .deb: conflicts + replaces thought-sync, so the updater's install retires the
old package instead of colliding on it. kebab-case("Inkwell") is `inkwell`, so
the package name finally matches the command and verify.sh now asserts it
- pacman: inkwell, conflicting with and replacing thoughtsync and
thoughtsync-desktop
- AppImage ~/Applications/Inkwell.AppImage, menu entry inkwell.desktop,
installer, release titles, desktop asset names in fetch-clients.sh
The one shim, chosen by the operator because it is the only copy of a
local-first user's notes: crossover.rs moves the old
com.fabledsword.thoughtsync app-data dir's contents into the new one on startup,
before the store opens, renaming thoughtsync.db and its -wal/-shm with it. It
skips when the new dir already has a store, and anything already in the new dir
wins (the installer writes its channel marker there first). Tested.
Android's Kotlin side (package, applicationId, uniffi class) is step 4. Its
release asset names stay thoughtsync.* until then.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
80 lines
3.3 KiB
Bash
Executable File
80 lines
3.3 KiB
Bash
Executable File
#!/usr/bin/env sh
|
|
#
|
|
# The markdown body for a release: what went live since the previous one.
|
|
#
|
|
# release-notes.sh <tag>
|
|
#
|
|
# A release BUILDS NOTHING now (M314 step 7). The merge to `main` already published
|
|
# `:latest`, `:<sha>` and both channel feeds, so a tag rebuilding that same source
|
|
# would produce identical artifacts and re-push `:<sha>` with different bytes —
|
|
# which rule 145 forbids even when the bytes match.
|
|
#
|
|
# So what is a release FOR? Note 3127 §5 answers it: the changelog. There are two
|
|
# halves to "what am I running" and the version answers only the first —
|
|
#
|
|
# which build is this the footer, /api/config, the APK's versionName
|
|
# what is in it that was not ← this
|
|
# in the one I ran last month
|
|
#
|
|
# DERIVED FROM GIT, not hand-maintained. A CHANGELOG.md drifts into being
|
|
# aspirational — it records what someone meant to ship. `git log` records what
|
|
# shipped, and cannot say otherwise.
|
|
set -eu
|
|
|
|
cd "$(git rev-parse --show-toplevel)"
|
|
|
|
tag="${1:?usage: release-notes.sh <tag>}"
|
|
|
|
# The previous release tag, by DATE rather than by name.
|
|
#
|
|
# `v*` only: this repo also carries `dev` and `stable` tags, which are the fixed-tag
|
|
# pointer releases the updater reads. They move constantly and are not releases in
|
|
# this sense; sorting them in would make "the previous release" mean whichever
|
|
# channel published most recently.
|
|
#
|
|
# Excludes the tag being described, so re-running on an existing tag still produces
|
|
# the range that tag covers rather than an empty one.
|
|
prev="$(git tag -l 'v*' --sort=-creatordate | grep -vxF "$tag" | head -1 || true)"
|
|
|
|
if [ -n "$prev" ]; then
|
|
range="$prev..$tag"
|
|
header="Changes since \`$prev\`."
|
|
else
|
|
# The first release. Everything is new, and listing the entire history would be
|
|
# noise — say so instead.
|
|
range="$tag"
|
|
header="First release."
|
|
fi
|
|
|
|
printf 'Inkwell %s\n\n%s\n\n' "$tag" "$header"
|
|
|
|
# `--no-merges`: a merge commit's subject is "Merge branch ..." and says nothing
|
|
# about what shipped. The commits it brought in are listed individually, which is
|
|
# what somebody reading this wants.
|
|
#
|
|
# `%s` alone, not `%s (%h)`: the sha is in the forge's own view of the release and
|
|
# a reader chasing a specific change clicks through rather than copying a hash out
|
|
# of prose.
|
|
# CAPPED, because an unbounded list is not a changelog — it is a wall.
|
|
#
|
|
# The first dated release spans everything since `v0.1.0` — 181 commits at the
|
|
# time of writing: nobody reads that, and burying twelve interesting changes in it is worse
|
|
# than not writing one. Later releases will be short and the cap will never bite.
|
|
#
|
|
# The most RECENT are kept, not the oldest, and the count of what was dropped is
|
|
# stated — a truncated list that does not say it is truncated is a lie.
|
|
CAP=60
|
|
total="$(git log --no-merges --format='%s' "$range" | wc -l | tr -d ' ')"
|
|
|
|
git log --no-merges --reverse --format='- %s' "$range" | tail -"$CAP"
|
|
|
|
if [ "$total" -gt "$CAP" ]; then
|
|
printf '\n_...and %s earlier commits in this range, omitted for length._\n' \
|
|
"$((total - CAP))"
|
|
fi
|
|
|
|
printf '\n'
|
|
printf '%s\n' "_No artifacts here. Builds reach users from \`main\`: the desktop and Android"
|
|
printf '%s\n' "channels and the server image all publish on merge, with no tag required. This"
|
|
printf '%s\n' "release is a bookmark — it names a moment and says what was in it._"
|