Move hill chart dots and post a progress update

Merged
RO
10h ago
+717-17

What

Move dots on a hill chart and post a progress update, as updating the hill in Basecamp does:

basecamp hillcharts update --dot <todolist-id|name>=<0-100> [--dot ...] [--note TEXT|-] [--notify <people>] [--in PROJECT | --todoset ID]
  • --dot is repeatable. Each one moves a tracked todolist, named by ID or by name. Names resolve within the todoset, as hillcharts track does. The value splits at the last =, so a name can contain one. Todolists left out keep their position. Two --dots for the same list are refused before the request.
  • --note is Markdown converted to rich text, like other commands' bodies (--format html sends HTML as written; @mentions resolve). - reads stdin.
  • --notify takes comma-separated names, emails, IDs or me and sends them as subscriptions. Without it the API notifies nobody else. --notify alone posts the chart as it stands and tells those people.
  • Output is the new progress update, rendered with the hill_chart_version schema from #990. Breadcrumbs lead to the hill chart, the updates list and the update's comments.
  • Flag mistakes are refused before stdin is read or any request is sent: no position, a position outside 0 to 100 or not a whole number, an empty --notify, a non-numeric --todoset, or nothing to post. A 422 from Basecamp (an untracked list, say) comes back as a validation error with its message.

For Hill chart writes in the API. The endpoint is added by bc3#14214, and the SDK operation HillChartsService.CreateVersion by basecamp/basecamp-sdk#1068.

bc3#14214 has merged and basecamp-sdk v0.34.0 ships the operation. This branch is rebased onto main, which now has #990, and pinned to that release.

SDK pin

go.mod pins github.com/basecamp/basecamp-sdk/go to the released v0.34.0 (make bump-sdk REF=v0.34.0). The MCP model is synced from go/v0.34.0 (f8902736), which adds create_hill_chart_version: the catalog goes from 286 to 287 operations and the snapshot is updated. nix/package.nix vendorHash is regenerated with make update-nix-hash, and the Docker Nix build of the new hash passes. sdk-provenance.json reads v0.34.0. API-COVERAGE.md (221 of 221) and .surface are unchanged from the earlier review.

Testing

  • make check passes locally on the head commit, with golangci-lint v2.11.1 as in CI.
  • Go: 11 new tests (22 including subtests). They cover moves by ID and by name (including a name with =), Markdown, --format html and stdin notes, --notify with and without dots, todoset resolution from --in with breadcrumbs, duplicate lists, a 422 from the server, and 11 flag mistakes refused before any request.
  • BATS: e2e/hillcharts.bats 19/19, including 4 new tests.
  • Against a real bc3, on the released SDK: the CLI built from 945ef9e3 (SDK v0.34.0), against a local bc3 on master 4303f1dafd4 (which includes bc3#14214):
    • hillcharts update --dot Launch=60 --note "Over the hill: **design is settled**" --notify me exited 0. GET .../hills/versions/:id.json and GET .../hill.json both show Launch at 60, the note as <strong> HTML, and one subscriber.
    • hillcharts updates lists the new update first.
    • --todoset 999999999 got bc3's 404 as not_found, with exit 2. An untracked list by ID got bc3's 422 as validation, Not tracked on the hill chart: ..., with exit 9. Both reached the server. --dot Launch=150 was refused as a usage error before any request.
    • The Ruby SDK v0.34.0's create_version, against the same server, moved Launch to 75 (read back from the API) and raised ValidationError on the untracked list.
  • Earlier, against the bc3#14214 branch: I ran the built CLI against a local bc3 server on the bc3#14214 branch (hill-chart-updates-api f0f63e7d438) and read each result back from the API:
    • Moving "Design = layout" by name to 55 and a list by ID to 100, with a Markdown note, returned 201. GET /todosets/:id/hill.json and GET .../hills/versions/:id.json show both positions and the note as <strong>/<em> HTML.
    • A stdin note with one --dot left the other list where it was. A note-only post moved nothing.
    • Without --notify, the update has 1 subscriber (the creator). --notify <person id> gave 2: that person and the creator.
    • An untracked list got the server's 422 as {"code":"validation","error":"Not tracked on the hill chart: ..."} with exit 9.
    • updates list shows the new updates newest first. --styled renders the dots.
    • The project the run created was trashed afterwards.
  • Not run: the new smoke test (hillcharts update posts a progress update), which needs a live account. It re-posts a tracked dot at its current position, so the chart is left as it was.

Review

A cross-family review of the branch found two issues, both fixed in 7f74fa35:

  1. Fixed. --notify with no --dot or --note was refused as "No update fields specified", though the API accepts subscriptions alone (it records the chart and notifies). It now posts. There's a test.
  2. Fixed. A non-numeric --todoset with --note - read stdin before the todoset was rejected, so a live pipe would hang. The todoset ID is now checked with the other flags, before stdin. There's a test.

Codex reviewed 7f74fa35 and found no issues. The rebase onto main and the repin to v0.34.0 change no command code: 3ec106b5 and 945ef9e3 are those two commits, replayed unchanged.