Skip to content

ci(release): keep third-party @handles in the auto release notes (#736) - #792

Merged
ryanbr merged 1 commit into
mainfrom
ci/release-keep-contributor-handles-736
Jul 25, 2026
Merged

ryanbr merged 1 commit into
mainfrom
ci/release-keep-contributor-handles-736

Conversation

@ryanbr

@ryanbr ryanbr commented Jul 25, 2026

Copy link
Copy Markdown
Owner

Follow-up to #790, and the part of #736 that fixes what was actually reported.

#790 landed the convention, the corrected v9.1.0 credit line, and a collector for the handles. All of that
governs the curated section at the top of a release body. This governs the auto-generated PR list
below it, which is where the handles were being destroyed.

The mechanism

fork-release.yml post-processes GitHub's generated notes and did two destructive things:

| sed -E 's/ by @[A-Za-z0-9_-]+//g' \                       # every handle, gone
| awk '/^#+ *New Contributors/{skip=1; next} ...'           # the whole block, deleted

Measured against v9.1.0's real generated notes, that removed 66 by @handle credits covering 7 distinct
third-party contributors
, plus the New Contributors block. The issue reads as drift in hand-written prose
because this is invisible from the release page — so implementing its four suggestions literally would still
have left every contributor's handle off the next release.

The comment justified it with "this is a solo fork". That premise has expired: 16 people have landed merged
PRs here
, 7 of them in v9.1.0 alone.

The fix

Targeted rather than a revert. Un-stripping everything would stamp by @ryanbr on nearly every line — the
self-credit noise the convention exists to avoid, and a self-mention notifies nobody. So the maintainer's own
handles keep being stripped and everyone else's is kept:

| sed -E 's/ by @([Rr]yanbr|[Ff]anboynz)([^A-Za-z0-9_-]|$)/\2/g'

Nothing deletes the New Contributors block any more, so it returns.

Verification

Run against v9.1.0's real generated notes, not a mock:

  • third-party credits kept: 35 (was 0)
  • maintainer credits surviving: 0 of 31
  • New Contributors block: restored
  • shortened lines stay well-formed — … (#613) in https://…; the trailing capture group is what preserves
    the following separator
  • YAML re-validated

One workflow file, 7 insertions / 4 deletions. No app or package code, no parity surface.

Closes #736.

The reported symptom was hand-written credit lines using display names, but the
mechanical cause is here: the release body builder stripped EVERY "by @author"
credit from GitHub's generated notes and deleted the "New Contributors" block
outright. Measured on v9.1.0's real auto-notes, that removed 66 credits covering
7 distinct third-party contributors, plus the block. Fixing the curated section
alone would have left this running on every future release.

The strip's premise — "this is a solo fork" — no longer holds: 16 people have
landed merged PRs here, 7 of them in v9.1.0 alone.

Only the maintainer's own credit is stripped now. Self-credit on nearly every
line is still noise and a self-mention notifies nobody, so that part was right;
everyone else's handle is the entire point of a contributors section. On v9.1.0's
notes the new filter keeps 35 third-party credits, removes all 31 maintainer
ones, and restores the New Contributors block.
@ryanbr
ryanbr merged commit 3a16846 into main Jul 25, 2026
1 check passed
@ryanbr
ryanbr deleted the ci/release-keep-contributor-handles-736 branch August 2, 2026 07:41
simoncad7 pushed a commit to simoncad7/noop that referenced this pull request Aug 17, 2026
…nbr#736) (ryanbr#792)

The release body builder stripped every "by @author" credit from GitHub's
generated notes and deleted the "New Contributors" block outright. Measured on
v9.1.0's real generated notes, that removed 66 credits covering 7 distinct
third-party contributors, plus the block — invisible from the release page, which
is why the issue reads as drift in hand-written prose.

The strip's premise, "this is a solo fork", has expired: 16 people have landed
merged PRs here, 7 of them in v9.1.0 alone.

Only the maintainer's own credit is stripped now. Self-credit on nearly every line
is noise and a self-mention notifies nobody, so that part was right; everyone
else's handle is the entire point of a contributors section. On v9.1.0's notes the
new filter keeps 35 third-party credits, removes all 31 maintainer ones, and
restores the New Contributors block.
ryanbr added a commit that referenced this pull request Aug 21, 2026
…ng (#1513)

Two gaps, one cause: KeyTileData had nowhere to put a subtitle.

stepsEstimateCaption (#760/#792) is computed and passed into MetricGrid and then
never read - four occurrences in the tree, one of them a parameter declaration
and none of them a use. The feature exists so "a WHOOP 4.0 user can see WHY the
number reads as it does"; on Android they never have.

And a blank Steps tile said nothing at all. The iOS half (#589, gate fixed in
#1512) explains what would unblock it; Android renders NO_DATA and stops, so an
Android 4.0 owner hits the same dead end #1491 reported, by a different route.

KeyTileData gains an optional caption, rendered only when a tile supplies one, so
every other tile keeps its exact current height. The Steps tile now sets it:
nothing for a measured count, the calibration status behind an estimate, and on a
blank tile the line that says what would unblock it.

The wording is the engine's own CalibrationStatus.headline, which already says
"connect your phone's step count" when NO day has both motion and a phone total
rather than a countdown that can never advance. So this adds no new copy and no
new localized keys - the string was already written and already translated
through the engine, it simply had no way to reach the screen.

Keyed on the persisted model NAME, not DeviceFamily.forRegistryModel: that
resolver maps registry labels ("4.0", "WHOOP 4.0") and answers WHOOP5 for
everything else, including the enum names this preference stores, so routing
through it would classify every 4.0 as a 5 and the prompt would silently never
appear. A null preference - no model ever selected - also yields no prompt, so a
user with no strap is never told to calibrate one.

Android 4182 tests 0 failures; doc lint, i18n --ci and lintVitalFullRelease all
clean.

NOT verified on a device. This adds a subtitle line to the Steps tile only, and
the tiles are height-equalised, so the row containing Steps will grow by one
line. That is the part I cannot check by reasoning and the part most worth a look
before trusting it.
ryanbr added a commit that referenced this pull request Aug 21, 2026
…ng (#1514)

Two gaps, one cause: KeyTileData had nowhere to put a subtitle.

stepsEstimateCaption (#760/#792) is computed, passed into MetricGrid, declared as
a parameter - and never read. Four occurrences in the tree, none of them a use.
The feature exists so "a WHOOP 4.0 user can see WHY the number reads as it does";
on Android they never have.

And a blank Steps tile said nothing at all. The iOS half (#589, gate fixed in
#1512) explains what would unblock it; Android rendered NO_DATA and stopped, so
an Android 4.0 owner hit the same dead end #1491 reported, by a different route.

KeyTileData gains an optional caption, rendered only when a tile supplies one, so
every other tile keeps its exact current height. Steps sets it: nothing for a
measured count, the calibration status behind an estimate, and on a blank tile
the line saying what would unblock it.

No new copy and no new localized keys. The wording is the engine's own
CalibrationStatus.headline, which already says "connect your phone's step count"
when NO day has both motion and a phone total rather than a countdown that can
never advance. The string was already written and already translated through the
engine; it had no route to the screen.

Keyed on the persisted model NAME, not DeviceFamily.forRegistryModel: that
resolver maps registry labels ("4.0", "WHOOP 4.0") and answers WHOOP5 for
everything else, including the enum names this preference stores, so routing
through it would classify every 4.0 as a 5 and the prompt would silently never
appear. A null preference - no model ever selected - yields no prompt, so a user
with no strap is never told to calibrate one.

Withheld from anyone already calibrated. The headline's countdown is
max(0, need - have), so a user past `need` would otherwise read "Need 0 more days
where your phone also counted steps" on any day the estimate came out blank -
which happens on a quiet day below the engine's motion floor. Nothing for them to
go and do, so no caption is the honest answer. The same wording stays reachable
on iOS, where a fitted coefficient satisfied that gate both before and after
#1512; it predates this and is untouched.

The preference lookup is remembered on the calibration fields it reads, matching
the identical getSharedPreferences call in SettingsScreen - the Today body
recomposes with live heart rate.

Partial parity, deliberately: the information now matches iOS, the one-tap route
does not. iOS opens the calibration sheet from a gear on the tile;
StepsCalibrationScreen on Android is a full-screen Dialog local to SettingsScreen
with no route from Today, so that half wants its own change with a device to
check it on. Settings -> Steps estimate reaches it on both platforms today.

Android 4182 tests 0 failures; doc lint, i18n --ci and lintVitalFullRelease all
clean. Diff is purely additive.

NOT verified on a device: this adds a subtitle line to the Steps tile, and the
tiles are height-equalised, so the row containing Steps grows by one line.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Release notes should mention contributor GitHub handles

1 participant