Skip to content

feat(rust): port freeze create/update/delete to native Rust#1437

Open
jd wants to merge 1 commit into
mainfrom
devs/jd/worktree-rust-port/port-freeze-create-update-delete-native-rust--653dbf47
Open

feat(rust): port freeze create/update/delete to native Rust#1437
jd wants to merge 1 commit into
mainfrom
devs/jd/worktree-rust-port/port-freeze-create-update-delete-native-rust--653dbf47

Conversation

@jd
Copy link
Copy Markdown
Member

@jd jd commented May 19, 2026

Round-trip the three remaining freeze mutations:

  • freeze createPOST /v1/repos/<r>/scheduled_freeze with
    the Python CreateScheduledFreezePayload shape: start/end
    always present (null for open-ended emergency freezes),
    matching_conditions/exclude_conditions keys omitted when
    the user passed no -c/-e flags. When --timezone is left
    off, falls back to iana-time-zone::get_timezone() — same
    role as Python's tzlocal.get_localzone_name().
  • freeze updatePATCH /v1/repos/<r>/scheduled_freeze/<id>
    with skip-if-none on every field so PATCH semantics work
    correctly: a flag the user didn't pass doesn't touch the
    stored field.
  • freeze deletePOST /v1/repos/<r>/scheduled_freeze/<id>/delete
    with delete_reason in the body only when supplied (the API
    requires it for active freezes; the CLI lets the server
    reject a missing reason rather than pre-validating).

Adds Client::patch on the core HTTP client, a shared
mergify-freeze::common module (wire-format struct, naive-DT
parser, system-timezone detection, per-freeze human printer
used by create and update), and iana-time-zone as a new
dependency. The Python implementation of each command is left
in place but no longer reachable via the binary, since clap now
dispatches the whole freeze group natively.

Co-Authored-By: Claude Opus 4.7 noreply@anthropic.com

@jd
Copy link
Copy Markdown
Member Author

jd commented May 19, 2026

This pull request is part of a Mergify stack:

# Pull Request Link
1 feat(rust): port freeze create/update/delete to native Rust #1437 👈
2 refactor(rust): dedupe emit-helper boilerplate across command crates #1438
3 refactor(rust): share test scaffolding via mergify-test-support crate #1439
4 refactor(core): introduce CommandContext for the queue+freeze prelude #1441
5 refactor(ci): consolidate the CI-env scrubber into a shared testing module #1442
6 refactor: drop stale Phase X.Y doc markers and one inline color branch #1443
7 refactor(tui): share StyledGlyph across queue show/status renderers #1444
8 refactor(queue): drop indexmap, group_by_scope returns a Vec<(K, V)> #1445
9 refactor(ci): swap uuid for getrandom in the GHA heredoc delimiter #1446
10 refactor(config): standardize the workspace on serde_yaml_ng for YAML parsing #1447

@mergify
Copy link
Copy Markdown
Contributor

mergify Bot commented May 19, 2026

Merge Protections

Your pull request matches the following merge protections and will not be merged until they are valid.

🔴 👀 Review Requirements

Waiting for

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

🔴 🔎 Reviews

Waiting for

  • #review-requested = 0
  • #review-threads-unresolved = 0
This rule is failing.
  • #review-requested = 0
  • #review-threads-unresolved = 0
  • #changes-requested-reviews-by = 0

🟢 🤖 Continuous Integration

Wonderful, this rule succeeded.
  • all of:
    • check-success=ci-gate

🟢 Enforce conventional commit

Wonderful, this rule succeeded.

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

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

🟢 📕 PR description

Wonderful, this rule succeeded.
  • body ~= (?ms:.{48,})

@mergify mergify Bot requested a review from a team May 19, 2026 08:37
@jd jd marked this pull request as ready for review May 19, 2026 08:54
@jd jd force-pushed the devs/jd/worktree-rust-port/port-freeze-create-update-delete-native-rust--653dbf47 branch from be2b24a to f0eb260 Compare May 19, 2026 08:56
@jd jd temporarily deployed to func-tests-live May 19, 2026 08:56 — with GitHub Actions Inactive
@jd jd temporarily deployed to func-tests-live May 19, 2026 08:56 — with GitHub Actions Inactive
@jd
Copy link
Copy Markdown
Member Author

jd commented May 19, 2026

Revision history

# Type Changes Reason Date
1 initial be2b24a 2026-05-19 08:56 UTC
2 rebase be2b24a → f0eb260 (rebase only) 2026-05-19 08:56 UTC
3 content f0eb260 → 56f3cf1 (raw) 2026-05-19 12:06 UTC
4 rebase 56f3cf1 → 50fcb0d (rebase only) 2026-05-19 13:04 UTC
5 rebase 50fcb0d → f322a06 (rebase only) 2026-05-19 14:15 UTC
6 rebase f322a06 → 7aefa73 (rebase only) 2026-05-20 08:42 UTC
7 rebase 7aefa73 → 622f895 (rebase only) 2026-05-20 09:05 UTC
8 rebase 622f895 → 032f043 (rebase only) 2026-05-21 07:25 UTC
9 content 032f043 → fcc43ed 2026-05-21 07:56 UTC
10 rebase fcc43ed → a2bd0dd (rebase only) 2026-05-21 12:39 UTC
11 content a2bd0dd → 659f960 2026-05-22 07:10 UTC

@mergify mergify Bot had a problem deploying to Mergify Merge Protections May 19, 2026 08:56 Failure
@jd jd force-pushed the devs/jd/worktree-rust-port/port-freeze-create-update-delete-native-rust--653dbf47 branch from f0eb260 to 56f3cf1 Compare May 19, 2026 12:06
@jd jd temporarily deployed to func-tests-live May 19, 2026 12:06 — with GitHub Actions Inactive
@mergify mergify Bot had a problem deploying to Mergify Merge Protections May 19, 2026 12:07 Failure
@jd jd force-pushed the devs/jd/worktree-rust-port/add-live-smoke-test-freeze-create-update-delete--9a7b270e branch from 414a70b to 8106d1c Compare May 19, 2026 13:04
@jd jd force-pushed the devs/jd/worktree-rust-port/port-freeze-create-update-delete-native-rust--653dbf47 branch from 56f3cf1 to 50fcb0d Compare May 19, 2026 13:04
@jd jd temporarily deployed to func-tests-live May 19, 2026 13:04 — with GitHub Actions Inactive
@jd jd temporarily deployed to func-tests-live May 19, 2026 13:04 — with GitHub Actions Inactive
@jd jd force-pushed the devs/jd/worktree-rust-port/port-freeze-create-update-delete-native-rust--653dbf47 branch from 7aefa73 to 622f895 Compare May 20, 2026 09:05
@jd jd temporarily deployed to func-tests-live May 20, 2026 09:05 — with GitHub Actions Inactive
@mergify mergify Bot had a problem deploying to Mergify Merge Protections May 20, 2026 09:06 Failure
@jd jd force-pushed the devs/jd/worktree-rust-port/add-live-smoke-test-freeze-create-update-delete--9a7b270e branch from 1ac4b0d to a8fc711 Compare May 21, 2026 07:24
@jd jd force-pushed the devs/jd/worktree-rust-port/port-freeze-create-update-delete-native-rust--653dbf47 branch from 622f895 to 032f043 Compare May 21, 2026 07:24
@jd jd temporarily deployed to func-tests-live May 21, 2026 07:25 — with GitHub Actions Inactive
@jd jd temporarily deployed to func-tests-live May 21, 2026 07:25 — with GitHub Actions Inactive
@mergify mergify Bot had a problem deploying to Mergify Merge Protections May 21, 2026 07:25 Failure
@jd jd force-pushed the devs/jd/worktree-rust-port/port-freeze-create-update-delete-native-rust--653dbf47 branch from 032f043 to fcc43ed Compare May 21, 2026 07:55
@jd jd temporarily deployed to func-tests-live May 21, 2026 07:56 — with GitHub Actions Inactive
@mergify mergify Bot had a problem deploying to Mergify Merge Protections May 21, 2026 07:56 Failure
@jd jd force-pushed the devs/jd/worktree-rust-port/port-freeze-create-update-delete-native-rust--653dbf47 branch from fcc43ed to a2bd0dd Compare May 21, 2026 12:39
@jd jd force-pushed the devs/jd/worktree-rust-port/add-live-smoke-test-freeze-create-update-delete--9a7b270e branch from d82958d to 8f0b96b Compare May 21, 2026 12:39
@jd jd temporarily deployed to func-tests-live May 21, 2026 12:39 — with GitHub Actions Inactive
@jd jd temporarily deployed to func-tests-live May 21, 2026 12:39 — with GitHub Actions Inactive
@jd jd temporarily deployed to func-tests-live May 21, 2026 12:39 — with GitHub Actions Inactive
@mergify mergify Bot had a problem deploying to Mergify Merge Protections May 21, 2026 12:40 Failure
Base automatically changed from devs/jd/worktree-rust-port/add-live-smoke-test-freeze-create-update-delete--9a7b270e to main May 21, 2026 14:50
@mergify
Copy link
Copy Markdown
Contributor

mergify Bot commented May 21, 2026

@jd this pull request is now in conflict 😩

@mergify mergify Bot added the conflict label May 21, 2026
Round-trip the three remaining freeze mutations:

- `freeze create` — `POST /v1/repos/<r>/scheduled_freeze` with
  the Python `CreateScheduledFreezePayload` shape: `start`/`end`
  always present (null for open-ended emergency freezes),
  `matching_conditions`/`exclude_conditions` keys omitted when
  the user passed no `-c`/`-e` flags. When `--timezone` is left
  off, falls back to `iana-time-zone::get_timezone()` — same
  role as Python's `tzlocal.get_localzone_name()`.
- `freeze update` — `PATCH /v1/repos/<r>/scheduled_freeze/<id>`
  with skip-if-none on every field so PATCH semantics work
  correctly: a flag the user didn't pass doesn't touch the
  stored field.
- `freeze delete` — `POST /v1/repos/<r>/scheduled_freeze/<id>/delete`
  with `delete_reason` in the body only when supplied (the API
  requires it for active freezes; the CLI lets the server
  reject a missing reason rather than pre-validating).

Adds `Client::patch` on the core HTTP client, a shared
`mergify-freeze::common` module (wire-format struct, naive-DT
parser, system-timezone detection, per-freeze human printer
used by `create` and `update`), and `iana-time-zone` as a new
dependency. The Python implementation of each command is left
in place but no longer reachable via the binary, since clap now
dispatches the whole freeze group natively.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Change-Id: I653dbf47080f439f8c3500a7a526e46d707fc639
Copilot AI review requested due to automatic review settings May 22, 2026 07:09
@jd jd force-pushed the devs/jd/worktree-rust-port/port-freeze-create-update-delete-native-rust--653dbf47 branch from a2bd0dd to 659f960 Compare May 22, 2026 07:09
@jd jd temporarily deployed to func-tests-live May 22, 2026 07:10 — with GitHub Actions Inactive
@mergify mergify Bot had a problem deploying to Mergify Merge Protections May 22, 2026 07:10 Failure
@mergify mergify Bot removed the conflict label May 22, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Ports the remaining mergify freeze mutations (create, update, delete) from the Python implementation to native Rust, aligning wire formats and human output with the existing CLI behavior while extending the core HTTP client with a PATCH verb.

Changes:

  • Add native Rust implementations for freeze create/update/delete plus a shared common module for wire structs, datetime parsing, timezone detection, and human formatting.
  • Extend mergify-core HTTP client with Client::patch and route freeze subcommands through Rust clap dispatch (no Python fallback).
  • Add iana-time-zone (timezone detection) and a direct chrono dependency to mergify-cli for typed datetime CLI args.

Reviewed changes

Copilot reviewed 10 out of 11 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
crates/mergify-freeze/src/create.rs Implements freeze create POST payload + human output and wiremock tests.
crates/mergify-freeze/src/update.rs Implements freeze update PATCH payload with optional fields + tests for omitted fields.
crates/mergify-freeze/src/delete.rs Implements freeze delete POST-to-/delete semantics + tests for optional reason body.
crates/mergify-freeze/src/common.rs Introduces shared wire struct, datetime parsing, timezone detection, and freeze pretty-printer.
crates/mergify-freeze/src/list.rs Refactors list rendering to reuse common helpers/structs.
crates/mergify-freeze/src/lib.rs Exposes new freeze subcommand modules and shared common.
crates/mergify-freeze/Cargo.toml Adds iana-time-zone dependency for system timezone detection.
crates/mergify-core/src/http.rs Adds Client::patch + unit test coverage.
crates/mergify-cli/src/main.rs Wires freeze create/update/delete into native dispatch and adds clap parsing for new args.
crates/mergify-cli/Cargo.toml Adds direct chrono dependency for clap-parsed NaiveDateTime.
Cargo.lock Locks new dependencies (chrono for cli, iana-time-zone for freeze).

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

//! Three responsibilities:
//!
//! - [`ScheduledFreeze`] — the wire format shared by every endpoint.
//! - [`print_freeze`] — the per-freeze human block that
//! open-ended emergency freeze), `matching_conditions` and
//! `exclude_conditions` only included when non-empty. On success
//! the server echoes the freeze body, which we render through the
//! shared [`print_freeze`](crate::common::print_freeze) helper.
Comment on lines +62 to +69
let payload = UpdatePayload {
reason: opts.reason,
timezone: opts.timezone,
start: opts.start.as_ref().map(|dt| NaiveDateTimeWire(dt).iso()),
end: opts.end.as_ref().map(|dt| NaiveDateTimeWire(dt).iso()),
matching_conditions: opts.matching_conditions.map(<[String]>::to_vec),
exclude_conditions: opts.exclude_conditions.map(<[String]>::to_vec),
};
Comment on lines +1155 to +1156
/// Matching condition (repeatable). Passing the flag — even
/// with no value — replaces the existing list.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

2 participants