feat(whatsnew): add command and post-upgrade banner

Summary

Adds a glab whatsnew command that renders release notes for the gitlab-org/cli project, plus a one-time post-upgrade banner that fires whenever the running version is newer than the recorded last_seen_version — pointing users at the new command.

Motivation: we ship a lot through releases and the only place users hear about it today is the GitLab releases page (which they have to visit themselves). The existing update-available notice already links to that page, but most users upgrade out-of-band via brew/apt/etc. and never see it. This adds an in-CLI way to discover what's new.

What's in here

glab whatsnew

  • Default (no args): lists every release published since last_seen_version, capped at 10. Updates the marker after.
  • glab whatsnew v1.99.0: shows notes for one specific release.
  • glab whatsnew --latest: shows just the most recent release.
  • glab whatsnew --since v1.95.0: explicit baseline override.
  • Explicit views (--latest, --since, positional) deliberately don't advance the marker — users shouldn't silently dismiss the banner for releases they haven't actually read.
  • Uses the unauthenticated client pattern (extracted from update.CheckUpdate) so it works regardless of auth state.

Post-upgrade banner (MaybeShowPostUpgradeBanner)

  • Compares BuildInfo.Version to last_seen_version; if current is newer, prints What's new in glab vX.Y.Z\n Run: glab whatsnew to stderr and advances the marker.
  • Wording is intentionally neutral about "upgrade" so it also reads correctly for fresh installs (since they hit the same code path).
  • Gated by:
    • show_whats_new config (default true)
    • GLAB_SHOW_WHATS_NEW env override
    • Suppressed for coding agents (BuildInfo.CodingAgent != "")
    • Skipped for whatsnew, completion, git-credential, credential-helper, and the existing update subcommands via update.ShouldSkipUpdate.

Config additions

  • show_whats_new (default true) — banner opt-out.
  • last_seen_version — automatically maintained marker.
  • defaultFor("last_seen_version") returns "v1.100.0" so existing users see the banner the first time they run the release shipping this feature, instead of only on the next upgrade after that.

Why the default version?

Without a seeded default, the silent-record-on-first-run behavior means existing users would have to upgrade twice after this lands before seeing the banner — once to record their version, once to trigger it. Seeding to v1.100.0 (the most recent release as of this MR) lets the feature announce itself on first run after upgrade.

Fresh installs of the release that ships this also see the banner on their very first command. The wording was chosen to be truthful in both cases.

Test plan

  • glab whatsnew --help renders.
  • glab whatsnew v1.100.0 renders the v1.100.0 release notes.
  • glab whatsnew --latest renders the most recent release.
  • glab whatsnew (default) lists releases since last_seen_version, capped at 10, and updates the marker.
  • Post-upgrade banner fires on first run after upgrading to a newer version, doesn't fire again until the next upgrade.
  • glab config set show_whats_new false suppresses the banner.
  • GLAB_SHOW_WHATS_NEW=false env var suppresses the banner.
  • Banner does not fire for coding agents (set CodingAgent in BuildInfo).
  • Flag conflict (whatsnew v1.x --latest) errors cleanly.

Merge request reports

Loading