From ecad738da9069300088640f39dec2487985e1bd6 Mon Sep 17 00:00:00 2001 From: Snider Date: Mon, 23 Mar 2026 12:53:10 +0000 Subject: [PATCH] feat(forge): add MilestoneService, fix comment creation - Add MilestoneService with ListAll, Get, Create - Fix CreateIssueCommentOption Updated field to *time.Time (was serialising zero value) - Register Milestones in Forge client Co-Authored-By: Virgil --- forge.go | 2 ++ milestones.go | 43 +++++++++++++++++++++++++++++++++++++++++++ types/issue.go | 2 +- 3 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 milestones.go diff --git a/forge.go b/forge.go index c65689a..ecb5c17 100644 --- a/forge.go +++ b/forge.go @@ -22,6 +22,7 @@ type Forge struct { Wiki *WikiService Misc *MiscService Commits *CommitService + Milestones *MilestoneService } // NewForge creates a new Forge client. @@ -46,6 +47,7 @@ func NewForge(url, token string, opts ...Option) *Forge { f.Wiki = newWikiService(c) f.Misc = newMiscService(c) f.Commits = newCommitService(c) + f.Milestones = newMilestoneService(c) return f } diff --git a/milestones.go b/milestones.go new file mode 100644 index 0000000..fa2dfd8 --- /dev/null +++ b/milestones.go @@ -0,0 +1,43 @@ +package forge + +import ( + "context" + "fmt" + + "dappco.re/go/core/forge/types" +) + +// MilestoneService handles repository milestones. +type MilestoneService struct { + client *Client +} + +func newMilestoneService(c *Client) *MilestoneService { + return &MilestoneService{client: c} +} + +// ListAll returns all milestones for a repository. +func (s *MilestoneService) ListAll(ctx context.Context, params Params) ([]types.Milestone, error) { + path := fmt.Sprintf("/api/v1/repos/%s/%s/milestones", params["owner"], params["repo"]) + return ListAll[types.Milestone](ctx, s.client, path, nil) +} + +// Get returns a single milestone by ID. +func (s *MilestoneService) Get(ctx context.Context, owner, repo string, id int64) (*types.Milestone, error) { + path := fmt.Sprintf("/api/v1/repos/%s/%s/milestones/%d", owner, repo, id) + var out types.Milestone + if err := s.client.Get(ctx, path, &out); err != nil { + return nil, err + } + return &out, nil +} + +// Create creates a new milestone. +func (s *MilestoneService) Create(ctx context.Context, owner, repo string, opts *types.CreateMilestoneOption) (*types.Milestone, error) { + path := fmt.Sprintf("/api/v1/repos/%s/%s/milestones", owner, repo) + var out types.Milestone + if err := s.client.Post(ctx, path, opts, &out); err != nil { + return nil, err + } + return &out, nil +} diff --git a/types/issue.go b/types/issue.go index f411c8e..c7157e5 100644 --- a/types/issue.go +++ b/types/issue.go @@ -8,7 +8,7 @@ import "time" // CreateIssueCommentOption — CreateIssueCommentOption options for creating a comment on an issue type CreateIssueCommentOption struct { Body string `json:"body"` - Updated time.Time `json:"updated_at,omitempty"` + Updated *time.Time `json:"updated_at,omitempty"` } // CreateIssueOption — CreateIssueOption options to create one issue