Skip to content

Compute the Activity rows at build time, with tests #276

Description

@mmcky

Part of #271 (Phase 4).

Why. Every Activity view builds on one set of grouped rows: the /news/ rail, the home strip, the restyled /activity/ and the feed. The round-2 handoff states the display rules as JavaScript (reference/activity-data.js: buildRows, week, range, railRows, byWeek, byMonth, panelSummary) for porting to a Jekyll plugin. Its README is in the round 2 outcome.

Liquid can't do the grouping reliably: it needs a regex and keyed merges. Production (deploy.yml) and the Netlify previews both run a plain bundle exec jekyll build, so plugins run everywhere.

Amendments from the round-2 review, which the port must implement:

  • A complete sort order, with no reliance on input order. The prototype breaks ties by input order through JavaScript's stable sort, and Ruby's sort isn't stable.
    • Days run newest first.
    • Within a day: lecture updates, then translations, then releases.
    • Within a type: by the lower-cased project name, then the exact name, then version, then url.
    • A merged translation lists its PRs in edition order.
  • Same-day entries for the same series merge into one row, as translations already do. Lecture sites published twice on one day 10 times across 5 sites between June and September 2026.
  • A release group lists each project once in its title.
  • Empty data returns nothing rather than failing. panelSummary([]) throws in the prototype.

Work.

  • _plugins/activity/rows.rb: a pure module, with no Jekyll dependency.
  • _plugins/activity_generator.rb: a generator that exposes site.data.activity_view to Liquid. It holds:
    • all rows;
    • the rail: the latest 6 rows of each type, with week groups and an "in All" flag;
    • the log's months and days;
    • the panel summary;
    • the strip rows;
    • the log's first date.
  • Tests in .github/scripts/test-activity.rb (not under _plugins/, which Jekyll loads), run against a frozen fixture copy of today's 40 entries. Add the test step to build.yml beside the data check (line 20 on Split updates into News and an Activity feed #265's head, 44f5479).

Acceptance criteria

  • On the fixture, the rail shows:
    • All: 6 rows under "Sep 21–27" and "Sep 14–20";
    • Releases: back to jlgametheory v0.2.0 (Aug 16);
    • Lectures: Sep 27 back to Jul 23, under four week headings;
    • Translations: 2 rows.
  • On the fixture, the strip rows, the panel summary ("6 updates in September · latest Sep 27") and the log (30 rows: 6/8/11/5) match the handoff.
  • Shuffled input gives identical output, and Date-object input gives the same output as string dates.
  • Week datetimes use ISO weeks: 2026-12-28 is 2026-W53, and 2029-12-31 is 2030-W01.
  • Tests run in CI. No visible change to the site.

Activity

  1. added theissue type on Sep 29, 2026
  2. mmcky commented on Sep 29, 2026

    @mmcky
    CollaboratorAuthor

    Decisions for the build (2026-09-29). These were settled with the maintainer before agents start, and take precedence where the issue differs.

    • Merged same-day lecture row. When one lecture series has two entries on a day, render one ordinary lecture row: the series name linking to its site, no tag, the distinct summaries joined, and every PR listed once. Translations follow the handoff's editions row.
    • The book type. Add book to the row code's type table: listed after lectures within a day, with the type word "Book update" and the filter key book. The data format and data check change in Harden the Activity data contract before automatic merges #284.
    • A stable row ID. Give each row an ID built from its grouping key (date, type, and series or release group), and test that it doesn't change under shuffled input or when a same-day release is added. Publish an Activity RSS feed at /activity/feed.xml #280's feed uses it as each item's ID.
    • Tests. Fixed numbers are checked against a frozen copy of the 40 entries at 4c47f03, kept under .github/scripts/fixtures/activity/ and never under _data/. Checks on live data assert only what stays true as data is added. Run the tests with plain ruby as a step in the existing build job, and keep the job's name: build is the required check.
    • Escaping. Summaries and PR titles come from outside the site. The row code returns plain strings and the templates escape every field. Add a fixture entry containing <, &, quotes and a backtick pair.
    • Design files. The handoff's activity-data.js and prototypes are in the maintainer's local project record (_reviews/_processed/2026-09-29-website-news-activity/design-round2/), not on GitHub.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions