Skip to content

feat(events): add a shared activity-log client crate - #1758

Open
jd wants to merge 1 commit into
mainfrom
devs/jd/jd/mrgfy-8363-make-the-activity-log-answerable-from-the-cli-a-shared-logs/add-shared-activity-log-client-crate--1f15266a
Open

feat(events): add a shared activity-log client crate#1758
jd wants to merge 1 commit into
mainfrom
devs/jd/jd/mrgfy-8363-make-the-activity-log-answerable-from-the-cli-a-shared-logs/add-shared-activity-log-client-crate--1f15266a

Conversation

@jd

@jd jd commented Aug 5, 2026

Copy link
Copy Markdown
Member

The activity log (GET /v1/repos/.../logs) carries every event type the
engine records — the action.queue.* family, the workflow actions,
ci_insights., command. — behind a contract with sharp edges that cost
#1747 ~700 lines to pin for a single lookup: a silent
received_from = received_to - 1 day default that makes a pull
request dequeued last week read exactly like one never queued, a raw
422 on ranges over 93 days while retention is 90, opaque-cursor
pagination, and unstated ordering.

Own that contract once, in a new mergify-events crate, so nothing
above it thinks about the traps:

  • The window is always explicit. Window carries both bounds and
    every request sends them; the silent 1-day default is unreachable.
  • The 93-day cap is a typed error. Window refuses to construct a
    range the API would 422 on, and "everything retained" is spelled
    Window::retained — the widest useful window has a name.
  • Pagination is followed to completion via the RFC 5988 Link
    cursors (new Client::get_page in mergify-core, which extracts only
    the cursor from the rel="next" target so a server cannot rewrite the
    caller's query), with a same-cursor loop guard.
  • Ordering is guaranteed newest-first by the client after
    collecting — a promise of the crate, not an observation about
    today's server.
  • Unknown fields pass through verbatim. An Event keeps the raw
    API object untouched next to a decoded envelope of the fields every
    event shares, so a newer engine cannot break an older CLI and
    --json republishes Mergify's contract, not this crate's.

Nothing consumes the crate yet: the next two changes port queue show's last-leave fallback onto it (so the contract has one home) and
add mergify events.

Part of MRGFY-8363.

Co-Authored-By: Claude Fable 5 noreply@anthropic.com

Copilot AI lite review requested due to automatic review settings August 5, 2026 07:42
@mergify
mergify Bot had a problem deploying to Mergify Merge Protections August 5, 2026 07:42 Failure
@jd

jd commented Aug 5, 2026

Copy link
Copy Markdown
Member Author

This pull request is part of a Mergify stack:

# Pull Request Link
1 feat(events): add a shared activity-log client crate #1758 👈
2 refactor(queue): port queue show's dequeue diagnosis onto mergify-events #1759
3 feat(events): add mergify events, a timeline over the activity log #1760

@mergify

mergify Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Merge Protections

🟢 All 6 merge protections satisfied — ready to merge.

Show 6 satisfied protections

🟢 🤖 Continuous Integration

  • all of:
    • check-success=ci-gate

🟢 👀 Review Requirements

  • any of:
    • #approved-reviews-by>=2
    • author = dependabot[bot]
    • author = mergify-ci-bot
    • author = renovate[bot]

🟢 Enforce conventional commit

Make sure that we follow https://www.conventionalcommits.org/en/v1.0.0/

  • title ~= ^(fix|feat|internal|docs|style|refactor|perf|test|build|ci|chore|revert|ui)(?:\(.+\))?!?:

🟢 🔎 Reviews

  • #changes-requested-reviews-by = 0
  • #review-requested = 0
  • #review-threads-unresolved = 0

🟢 📕 PR description

  • body ~= (?ms:.{48,})

🟢 🚦 Auto-queue

When all merge protections are satisfied, this pull request will be queued automatically.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new mergify-events crate to centralize the Mergify activity-log (/logs) contract (explicit time windows, typed span validation, cursor pagination, stable newest-first ordering, and raw-field passthrough), plus a small mergify-core HTTP helper to fetch cursor-paginated pages safely.

Changes:

  • Introduces crates/mergify-events with Window, Event, and fetch(Query) APIs, backed by wiremock-based tests.
  • Adds Client::get_page + Page<T> and RFC5988 Link cursor extraction to mergify-core::http.
  • Wires the new crate into the workspace (new crate manifest + lockfile entry).

Reviewed changes

Copilot reviewed 7 out of 8 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
crates/mergify-events/src/window.rs Adds explicit time window type with retention/span constraints + unit tests.
crates/mergify-events/src/lib.rs New crate root docs + exports for the activity-log client surface.
crates/mergify-events/src/event.rs Adds Event wrapper that preserves raw payload while exposing a decoded envelope.
crates/mergify-events/src/client.rs Implements /logs fetching with explicit bounds, cursor pagination, ordering guarantee + wiremock tests.
crates/mergify-events/Cargo.toml Declares the new crate and its workspace dependencies.
crates/mergify-core/src/lib.rs Re-exports new http::Page type from mergify-core.
crates/mergify-core/src/http.rs Adds Page<T>, Client::get_page, and cursor parsing from Link header + tests.
Cargo.lock Adds lock entry for the new mergify-events crate.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread crates/mergify-events/src/event.rs
Comment thread crates/mergify-events/src/window.rs
@mergify
mergify Bot requested a review from a team August 5, 2026 07:49
@jd
jd marked this pull request as ready for review August 5, 2026 09:34
The activity log (GET /v1/repos/.../logs) carries every event type the
engine records — the action.queue.* family, the workflow actions,
ci_insights.*, command.* — behind a contract with sharp edges that cost
#1747 ~700 lines to pin for a single lookup: a silent
`received_from = received_to - 1 day` default that makes a pull
request dequeued last week read exactly like one never queued, a raw
422 on ranges over 93 days while retention is 90, opaque-cursor
pagination, and unstated ordering.

Own that contract once, in a new `mergify-events` crate, so nothing
above it thinks about the traps:

- **The window is always explicit.** `Window` carries both bounds and
  every request sends them; the silent 1-day default is unreachable.
- **The 93-day cap is a typed error.** `Window` refuses to construct a
  range the API would 422 on, and "everything retained" is spelled
  `Window::retained` — the widest useful window has a name.
- **Pagination is followed to completion** via the RFC 5988 `Link`
  cursors (new `Client::get_page` in mergify-core, which extracts only
  the cursor from the rel="next" target so a server cannot rewrite the
  caller's query), with a same-cursor loop guard.
- **Ordering is guaranteed newest-first** by the client after
  collecting — a promise of the crate, not an observation about
  today's server.
- **Unknown fields pass through verbatim.** An `Event` keeps the raw
  API object untouched next to a decoded envelope of the fields every
  event shares, so a newer engine cannot break an older CLI and
  `--json` republishes Mergify's contract, not this crate's.

Nothing consumes the crate yet: the next two changes port `queue
show`'s last-leave fallback onto it (so the contract has one home) and
add `mergify events`.

Part of MRGFY-8363.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Change-Id: I1f15266ac6680c63d95dddeec34978ad4edf0a50
@jd
jd force-pushed the devs/jd/jd/mrgfy-8363-make-the-activity-log-answerable-from-the-cli-a-shared-logs/add-shared-activity-log-client-crate--1f15266a branch from 6220917 to f6b6132 Compare August 5, 2026 12:18
@jd

jd commented Aug 5, 2026

Copy link
Copy Markdown
Member Author

Revision history

# Type Changes Reason Date
1 initial 6220917 2026-08-05 12:18 UTC
2 content 6220917 → f6b6132 2026-08-05 12:18 UTC

@jd
jd temporarily deployed to func-tests-live August 5, 2026 12:18 — with GitHub Actions Inactive
@mergify
mergify Bot deployed to Mergify Merge Protections August 5, 2026 12:18 Active
@mergify
mergify Bot requested a review from a team August 6, 2026 08:22
@mergify

mergify Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Merge Queue Status

Waiting for
  • check-success=ci-gate
All merge conditions
Required conditions to stay in the queue
  • -closed [📌 queue requirement]
  • -conflict [📌 queue requirement]
  • -draft [📌 queue requirement]
  • deployment-success = Mergify Merge Protections [📌 queue requirement]
  • any of [📌 queue -> configuration change requirements]:
    • -mergify-configuration-changed
    • check-success = Configuration changed
  • any of [🔀 queue conditions]:
    • all of [📌 queue conditions of queue rule default]:
      • base=main
      • github-review-approved [🛡 GitHub branch protection]
      • github-review-approved [🛡 GitHub repository ruleset rule Require pull request for default branch]
      • label!=manual merge
      • all of [🛡 Merge Protections rule Enforce conventional commit]:
        • title ~= ^(fix|feat|internal|docs|style|refactor|perf|test|build|ci|chore|revert|ui)(?:\(.+\))?!?:
      • all of [🛡 Merge Protections rule 👀 Review Requirements]:
        • any of:
          • #approved-reviews-by>=2
          • author = dependabot[bot]
          • author = mergify-ci-bot
          • author = renovate[bot]
      • all of [🛡 Merge Protections rule 📕 PR description]:
        • body ~= (?ms:.{48,})
      • all of [🛡 Merge Protections rule 🔎 Reviews]:
        • #changes-requested-reviews-by = 0
        • #review-requested = 0
        • #review-threads-unresolved = 0
      • all of [🛡 Merge Protections rule 🤖 Continuous Integration]:
        • all of:
          • check-success=ci-gate
    • all of [📌 queue conditions of queue rule dependencies]:
      • any of:
        • author = dependabot[bot]
        • author = renovate[bot]
      • base=main
      • github-review-approved [🛡 GitHub branch protection]
      • github-review-approved [🛡 GitHub repository ruleset rule Require pull request for default branch]
      • label!=manual merge
      • all of [🛡 Merge Protections rule Enforce conventional commit]:
        • title ~= ^(fix|feat|internal|docs|style|refactor|perf|test|build|ci|chore|revert|ui)(?:\(.+\))?!?:
      • all of [🛡 Merge Protections rule 👀 Review Requirements]:
        • any of:
          • #approved-reviews-by>=2
          • author = dependabot[bot]
          • author = mergify-ci-bot
          • author = renovate[bot]
      • all of [🛡 Merge Protections rule 📕 PR description]:
        • body ~= (?ms:.{48,})
      • all of [🛡 Merge Protections rule 🔎 Reviews]:
        • #changes-requested-reviews-by = 0
        • #review-requested = 0
        • #review-threads-unresolved = 0
      • all of [🛡 Merge Protections rule 🤖 Continuous Integration]:
        • all of:
          • check-success=ci-gate

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Development

Successfully merging this pull request may close these issues.

4 participants