feat: add milestones command group and --milestone issue flag - #57
Open
martin-piliar wants to merge 8 commits into
Open
feat: add milestones command group and --milestone issue flag#57martin-piliar wants to merge 8 commits into
martin-piliar wants to merge 8 commits into
Conversation
Adds a Linear API client for project milestones (list/get/create/update/ delete via projectMilestone* GraphQL operations) and links issues to milestones: Issue.ProjectMilestone, IssueCreateInput/UpdateIssueInput/ IssueFilter gain ProjectMilestoneID, and a ResolveProjectMilestone resolver (with TTL cache) translates milestone names to UUIDs scoped to a project.
Adds RenderMilestone/RenderMilestoneList to the Renderer interface and both implementations (minimal/compact/detailed/full text views, JSON DTOs), and surfaces the assigned milestone on issue text/JSON output.
New 'linear milestones' command group (list/get/create/update/delete), plus --milestone on 'issues list/create/update' to filter or assign issues by project milestone. Milestone names resolve within a project scope (--project flag or .linear.yaml default).
Adds milestones usage to README, CLAUDE.md, the changelog, and the embedded /linear skill.
Covers buildCreateInput/buildUpdateInput field presence and the early-validation error paths on List/Get/Create/Update/Delete.
Covers text (minimal/compact/full) and JSON rendering, including a regression check for the progress-percentage double-scaling bug.
Covers List/Get/Create/Update/Delete with a mocked MilestoneClientOperations, including project/milestone identifier resolution and error propagation. Also asserts --project on update only scopes the lookup and never moves the milestone between projects.
There was a problem hiding this comment.
Pull request overview
Adds first-class support for Linear project milestones across the CLI stack (client/resolver/service/format/commands), including issue filtering/assignment and output rendering.
Changes:
- Introduces
linear milestones list|get|create|update|delete(aliasm) with project-scoped name resolution. - Adds
--milestone/-mtoissues list|create|updateand includes milestone in issue text/JSON output. - Extends core types, client plumbing, formatting/DTOs, and adds milestone-specific tests + docs/changelog updates.
Reviewed changes
Copilot reviewed 32 out of 32 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| README.md | Documents milestone commands and --milestone usage. |
| pkg/linear/resolver.go | Adds project-scoped milestone identifier resolution. |
| pkg/linear/resolver_cache.go | Adds resolver cache for milestone name→ID within a project. |
| pkg/linear/milestones/client.go | New GraphQL client for project milestone CRUD + list/get. |
| pkg/linear/milestones/client_test.go | Unit tests for milestones client input building + validation. |
| pkg/linear/issues/client.go | Adds projectMilestone fields to issue queries and supports milestone filters/inputs. |
| pkg/linear/core/types.go | Adds ProjectMilestone type and milestone fields on issue-related structs/inputs. |
| pkg/linear/client.go | Wires milestones sub-client and exposes milestone operations/resolver passthrough. |
| internal/skills/linear/SKILL.md | Updates skill docs/examples to include milestone operations and --milestone. |
| internal/service/service.go | Registers MilestoneService in service container. |
| internal/service/search_resolve_test.go | Updates mocks to support milestone resolution. |
| internal/service/milestone.go | New service layer for milestones + project/milestone resolution logic. |
| internal/service/milestone_test.go | Tests milestone service behavior and resolution rules. |
| internal/service/issue.go | Adds milestone filter/assignment resolution in issue service flows. |
| internal/service/issue_relation_test.go | Updates issue service relation test mocks for milestone resolver method. |
| internal/service/issue_delegate_test.go | Updates issue delegate test mocks for milestone resolver method. |
| internal/service/issue_create_test.go | Updates issue create test mocks for milestone resolver method. |
| internal/service/interfaces.go | Adds MilestoneServiceInterface. |
| internal/service/client_interfaces.go | Adds milestone ops interface and resolver method to client interfaces. |
| internal/format/text_renderer.go | Renders milestone info for issues and adds milestone text renderers. |
| internal/format/renderer.go | Extends renderer interface with milestone render methods. |
| internal/format/json_renderer.go | Adds milestone JSON rendering entry points. |
| internal/format/json_dtos.go | Adds milestone DTOs and includes milestone info in issue DTOs. |
| internal/format/issue.go | Adds milestone line to issue body rendering. |
| internal/format/format.go | Adds formatter methods for milestone render/list render. |
| internal/format/format_test.go | Adds tests for milestone text+JSON formatting. |
| internal/cli/root.go | Registers milestones command and updates help text for -m. |
| internal/cli/milestones.go | New cobra command group for milestones CRUD/list/get. |
| internal/cli/issues.go | Adds --milestone/-m to issues list/create/update flags and wiring. |
| internal/cli/dependencies.go | Exposes milestone service via CLI dependencies. |
| CLAUDE.md | Updates user-facing docs/examples to include milestones and --milestone. |
| CHANGELOG.md | Notes new milestone commands, flags, and output changes. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
This looks like a nice addition. Anything blocking its merge? @joa23 Might need a rebase @martin-piliar |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Linear project milestones are fully public in the GraphQL API (
projectMilestone*queries and mutations), but this CLI had no support for them at all. This adds:linear milestones list|get|create|update|delete--milestone/-monissues list|create|update, to filter or assign by milestoneissues getnow shows the assigned milestone--projectonmilestones updateonly scopes the lookup - it doesn't move the milestone. Point it at a different project and the update just won't find a match there; moving a milestone between projects is a separate Linear mutation (projectMilestoneMove), left out here on purpose.Usage
Sorry to whoever is going to review this...
Most of it isn't new logic. Adding
ProjectMilestonetoIssueand a few sibling structs gave them a longer field name, which pushed gofmt to realign every field in those structs - that's whitespace, not code, and it's most of what you'll see intypes.goandissues/client.go. The actual new logic is milestones getting the same client → resolver → format → service → CLI treatment every other resource here gets, plus tests.Test plan
go build / vet / test ./...- 17 new test casesgofmt -lclean on everything this PR touches--milestone, reassign one without--project(resolves through the issue's own project), filterissues list --milestone