diff --git a/event_webhook_types.go b/event_webhook_types.go index 8d6827997..03f8a7c11 100644 --- a/event_webhook_types.go +++ b/event_webhook_types.go @@ -20,9 +20,35 @@ import ( "encoding/json" "fmt" "strconv" + "strings" "time" ) +type customTime struct { + time.Time +} + +func (t *customTime) UnmarshalJSON(b []byte) (err error) { + layout := []string{ + "2006-01-02 15:04:05 MST", + "2006-01-02 15:04:05 Z07:00", + "2006-01-02 15:04:05 Z0700", + time.RFC3339, + } + s := strings.Trim(string(b), "\"") + if s == "null" { + t.Time = time.Time{} + return + } + for _, l := range layout { + t.Time, err = time.Parse(l, s) + if err == nil { + break + } + } + return +} + // StateID identifies the state of an issue or merge request. // // There are no GitLab API docs on the subject, but the mappings can be found in @@ -61,15 +87,15 @@ type BuildEvent struct { ProjectName string `json:"project_name"` User *EventUser `json:"user"` Commit struct { - ID int `json:"id"` - SHA string `json:"sha"` - Message string `json:"message"` - AuthorName string `json:"author_name"` - AuthorEmail string `json:"author_email"` - Status string `json:"status"` - Duration int `json:"duration"` - StartedAt string `json:"started_at"` - FinishedAt string `json:"finished_at"` + ID int `json:"id"` + SHA string `json:"sha"` + Message string `json:"message"` + AuthorName string `json:"author_name"` + AuthorEmail string `json:"author_email"` + Status string `json:"status"` + Duration float64 `json:"duration"` + StartedAt string `json:"started_at"` + FinishedAt string `json:"finished_at"` } `json:"commit"` Repository *Repository `json:"repository"` } @@ -79,10 +105,12 @@ type BuildEvent struct { // GitLab API docs: // https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#comment-on-a-commit type CommitCommentEvent struct { - ObjectKind string `json:"object_kind"` - User *User `json:"user"` - ProjectID int `json:"project_id"` - Project struct { + ObjectKind string `json:"object_kind"` + EventType string `json:"event_type"` + User *User `json:"user"` + ProjectID int `json:"project_id"` + Project struct { // TODO: create EventProject struct + ID int `json:"id"` Name string `json:"name"` Description string `json:"description"` AvatarURL string `json:"avatar_url"` @@ -96,7 +124,7 @@ type CommitCommentEvent struct { SSHURL string `json:"ssh_url"` HTTPURL string `json:"http_url"` WebURL string `json:"web_url"` - Visibility VisibilityValue `json:"visibility"` + Visibility VisibilityValue `json:"visibility"` // TODO GitLab now returns visibility_level of int type } `json:"project"` Repository *Repository `json:"repository"` ObjectAttributes struct { @@ -104,28 +132,19 @@ type CommitCommentEvent struct { Note string `json:"note"` NoteableType string `json:"noteable_type"` AuthorID int `json:"author_id"` - CreatedAt string `json:"created_at"` - UpdatedAt string `json:"updated_at"` + CreatedAt string `json:"created_at"` // TODO: should be *time.Time + UpdatedAt string `json:"updated_at"` // TODO: should be *time.Time ProjectID int `json:"project_id"` Attachment string `json:"attachment"` LineCode string `json:"line_code"` CommitID string `json:"commit_id"` NoteableID int `json:"noteable_id"` System bool `json:"system"` - StDiff struct { - Diff string `json:"diff"` - NewPath string `json:"new_path"` - OldPath string `json:"old_path"` - AMode string `json:"a_mode"` - BMode string `json:"b_mode"` - NewFile bool `json:"new_file"` - RenamedFile bool `json:"renamed_file"` - DeletedFile bool `json:"deleted_file"` - } `json:"st_diff"` - Description string `json:"description"` - URL string `json:"url"` + StDiff *Diff `json:"st_diff"` + Description string `json:"description"` + URL string `json:"url"` } `json:"object_attributes"` - Commit *struct { + Commit *struct { // TODO create Commit struct ID string `json:"id"` Title string `json:"title"` Message string `json:"message"` @@ -143,12 +162,16 @@ type CommitCommentEvent struct { // GitLab API docs: // https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#deployment-events type DeploymentEvent struct { - ObjectKind string `json:"object_kind"` - Status string `json:"status"` - DeployableID int `json:"deployable_id"` - DeployableURL string `json:"deployable_url"` - Environment string `json:"environment"` - Project struct { + ObjectKind string `json:"object_kind"` + Status string `json:"status"` + StatusChangedAt customTime `json:"status_changed_at"` + DeploymentID int `json:"deployment_id"` + DeployableID int `json:"deployable_id"` + DeployableURL string `json:"deployable_url"` + Environment string `json:"environment"` + EnvironmentSlug string `json:"environment_slug"` + EnvironmentExternalURL string `json:"environment_external_url"` + Project struct { ID int `json:"id"` Name string `json:"name"` Description string `json:"description"` @@ -174,15 +197,33 @@ type DeploymentEvent struct { CommitTitle string `json:"commit_title"` } +// FeatureFlagEvent represents a feature flag event +// +// GitLab API docs: +// https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#feature-flag-events +type FeatureFlagEvent struct { + ObjectKind string `json:"object_kind"` + Project *Project `json:"project"` // TODO check which Project struct to use Project or ProjectEvent + User *EventUser `json:"user"` + UserURL string `json:"user_url"` + ObjectAttributes struct { + ID int `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + Active bool `json:"active"` + } `json:"object_attributes"` +} + // IssueCommentEvent represents a comment on an issue event. // // GitLab API docs: // https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#comment-on-an-issue type IssueCommentEvent struct { - ObjectKind string `json:"object_kind"` - User *User `json:"user"` - ProjectID int `json:"project_id"` - Project struct { + ObjectKind string `json:"object_kind"` + EventType string `json:"event_type"` + User *User `json:"user"` + ProjectID int `json:"project_id"` + Project struct { // TODO: create EventProject struct Name string `json:"name"` Description string `json:"description"` AvatarURL string `json:"avatar_url"` @@ -217,7 +258,7 @@ type IssueCommentEvent struct { Description string `json:"description"` URL string `json:"url"` } `json:"object_attributes"` - Issue struct { + Issue struct { // TODO Check if this can be replaced by IssueEvent struct ID int `json:"id"` IID int `json:"iid"` ProjectID int `json:"project_id"` @@ -227,12 +268,12 @@ type IssueCommentEvent struct { State string `json:"state"` Title string `json:"title"` Labels []*EventLabel `json:"labels"` - LastEditedAt string `json:"last_edit_at"` + LastEditedAt string `json:"last_edit_at"` // TODO should be *time.Time LastEditedByID int `json:"last_edited_by_id"` - UpdatedAt string `json:"updated_at"` + UpdatedAt string `json:"updated_at"` // TODO should be *time.Time UpdatedByID int `json:"updated_by_id"` - CreatedAt string `json:"created_at"` - ClosedAt string `json:"closed_at"` + CreatedAt string `json:"created_at"` // TODO should be *time.Time + ClosedAt string `json:"closed_at"` // TODO should be *time.Time DueDate *ISOTime `json:"due_date"` URL string `json:"url"` TimeEstimate int `json:"time_estimate"` @@ -242,6 +283,8 @@ type IssueCommentEvent struct { HumanTimeEstimate string `json:"human_time_estimate"` AssigneeIDs []int `json:"assignee_ids"` AssigneeID int `json:"assignee_id"` + Position int `json:"position"` + BranchName string `json:"branch_name"` } `json:"issue"` } @@ -251,8 +294,9 @@ type IssueCommentEvent struct { // https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#issue-events type IssueEvent struct { ObjectKind string `json:"object_kind"` + EventType string `json:"event_type"` User *EventUser `json:"user"` - Project struct { + Project struct { // TODO replace with EventProject struct ID int `json:"id"` Name string `json:"name"` Description string `json:"description"` @@ -271,21 +315,45 @@ type IssueEvent struct { } `json:"project"` Repository *Repository `json:"repository"` ObjectAttributes struct { - ID int `json:"id"` - Title string `json:"title"` - AssigneeID int `json:"assignee_id"` - AuthorID int `json:"author_id"` - ProjectID int `json:"project_id"` - CreatedAt string `json:"created_at"` // Should be *time.Time (see Gitlab issue #21468) - UpdatedAt string `json:"updated_at"` // Should be *time.Time (see Gitlab issue #21468) - Position int `json:"position"` - BranchName string `json:"branch_name"` - Description string `json:"description"` - MilestoneID int `json:"milestone_id"` - State string `json:"state"` - IID int `json:"iid"` - URL string `json:"url"` - Action string `json:"action"` + ID int `json:"id"` + Title string `json:"title"` + AssigneeIDs []int `json:"assignee_ids"` + AssigneeID int `json:"assignee_id"` + AuthorID int `json:"author_id"` + ProjectID int `json:"project_id"` + CreatedAt string `json:"created_at"` // Should be *time.Time (see Gitlab issue #21468) + UpdatedAt string `json:"updated_at"` // Should be *time.Time (see Gitlab issue #21468) + UpdatedByID int `json:"updated_by_id"` + LastEditedAt string `json:"last_edited_at"` // Should be *time.Time + LastEditedByID int `json:"last_edited_by_id"` + RelativePosition int `json:"relative_position"` + BranchName string `json:"branch_name"` + Description string `json:"description"` + MilestoneID int `json:"milestone_id"` + StateID int `json:"state_id"` + Confidential bool `json:"confidential"` + DiscussionLocked bool `json:"discussion_locked"` + DueDate *ISOTime `json:"due_date"` + MovedToID int `json:"moved_to_id"` + DuplicatedToID int `json:"duplicated_to_id"` + TimeEstimate int `json:"time_estimate"` + TotalTimeSpent int `json:"total_time_spent"` + TimeChange int `json:"time_change"` + HumanTotalTimeSpent string `json:"human_total_time_spent"` + HumanTimeEstimate string `json:"human_time_estimate"` + HumanTimeChange string `json:"human_time_change"` + Weight string `json:"weight"` + IID int `json:"iid"` + URL string `json:"url"` + State string `json:"state"` + Action string `json:"action"` + Severity string `json:"severity"` + EscalationStatus string `json:"escalation_status"` + EscalationPolicy struct { + ID int `json:"id"` + Name string `json:"name"` + } `json:"escalation_policy"` + Labels []*EventLabel `json:"labels"` } `json:"object_attributes"` Assignee *EventUser `json:"assignee"` Assignees *[]EventUser `json:"assignees"` @@ -335,46 +403,50 @@ type IssueEvent struct { // GitLab API docs: // https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#job-events type JobEvent struct { - ObjectKind string `json:"object_kind"` - Ref string `json:"ref"` - Tag bool `json:"tag"` - BeforeSHA string `json:"before_sha"` - SHA string `json:"sha"` - BuildID int `json:"build_id"` - BuildName string `json:"build_name"` - BuildStage string `json:"build_stage"` - BuildStatus string `json:"build_status"` - BuildCreatedAt string `json:"build_created_at"` - BuildStartedAt string `json:"build_started_at"` - BuildFinishedAt string `json:"build_finished_at"` - BuildDuration float64 `json:"build_duration"` - BuildAllowFailure bool `json:"build_allow_failure"` - BuildFailureReason string `json:"build_failure_reason"` - RetriesCount int `json:"retries_count"` - PipelineID int `json:"pipeline_id"` - ProjectID int `json:"project_id"` - ProjectName string `json:"project_name"` - User *EventUser `json:"user"` - Commit struct { - ID int `json:"id"` - Name string `json:"name"` - SHA string `json:"sha"` - Message string `json:"message"` - AuthorName string `json:"author_name"` - AuthorEmail string `json:"author_email"` - AuthorURL string `json:"author_url"` - Status string `json:"status"` - Duration int `json:"duration"` - StartedAt string `json:"started_at"` - FinishedAt string `json:"finished_at"` + ObjectKind string `json:"object_kind"` + Ref string `json:"ref"` + Tag bool `json:"tag"` + BeforeSHA string `json:"before_sha"` + SHA string `json:"sha"` + BuildID int `json:"build_id"` + BuildName string `json:"build_name"` + BuildStage string `json:"build_stage"` + BuildStatus string `json:"build_status"` + BuildCreatedAt string `json:"build_created_at"` + BuildStartedAt string `json:"build_started_at"` // TODO Should be *time.Time + BuildFinishedAt string `json:"build_finished_at"` // TODO Should be *time.Time + BuildDuration float64 `json:"build_duration"` + BuildQueuedDuration float64 `json:"build_queued_duration"` + BuildAllowFailure bool `json:"build_allow_failure"` + BuildFailureReason string `json:"build_failure_reason"` + RetriesCount int `json:"retries_count"` + PipelineID int `json:"pipeline_id"` + ProjectID int `json:"project_id"` + ProjectName string `json:"project_name"` + User *EventUser `json:"user"` + Commit struct { + ID int `json:"id"` + Name string `json:"name"` + SHA string `json:"sha"` + Message string `json:"message"` + AuthorName string `json:"author_name"` + AuthorEmail string `json:"author_email"` + AuthorURL string `json:"author_url"` + Status string `json:"status"` + Duration float64 `json:"duration"` + StartedAt string `json:"started_at"` + FinishedAt string `json:"finished_at"` } `json:"commit"` Repository *Repository `json:"repository"` Runner struct { - ID int `json:"id"` - Active bool `json:"active"` - Shared bool `json:"is_shared"` - Description string `json:"description"` + ID int `json:"id"` + Active bool `json:"active"` + RunnerType string `json:"runner_type"` + IsShared bool `json:"is_shared"` + Description string `json:"description"` + Tags []string `json:"tags"` } `json:"runner"` + Environment string `json:"environment"` } // MemberEvent represents a member event. @@ -403,9 +475,11 @@ type MemberEvent struct { // https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#comment-on-a-merge-request type MergeCommentEvent struct { ObjectKind string `json:"object_kind"` + EventType string `json:"event_type"` User *EventUser `json:"user"` ProjectID int `json:"project_id"` - Project struct { + Project struct { // TODO use Project struct + ID int `json:"id"` Name string `json:"name"` Description string `json:"description"` AvatarURL string `json:"avatar_url"` @@ -426,7 +500,7 @@ type MergeCommentEvent struct { AuthorID int `json:"author_id"` ChangePosition *NotePosition `json:"change_position"` CommitID string `json:"commit_id"` - CreatedAt string `json:"created_at"` + CreatedAt string `json:"created_at"` // TODO Should be *time.Time DiscussionID string `json:"discussion_id"` ID int `json:"id"` LineCode string `json:"line_code"` @@ -448,42 +522,43 @@ type MergeCommentEvent struct { URL string `json:"url"` } `json:"object_attributes"` Repository *Repository `json:"repository"` - MergeRequest struct { - ID int `json:"id"` - TargetBranch string `json:"target_branch"` - SourceBranch string `json:"source_branch"` - SourceProjectID int `json:"source_project_id"` - AuthorID int `json:"author_id"` - AssigneeID int `json:"assignee_id"` - AssigneeIDs []int `json:"assignee_ids"` - Title string `json:"title"` - CreatedAt string `json:"created_at"` - UpdatedAt string `json:"updated_at"` - MilestoneID int `json:"milestone_id"` - State string `json:"state"` - MergeStatus string `json:"merge_status"` - TargetProjectID int `json:"target_project_id"` - IID int `json:"iid"` - Description string `json:"description"` - Position int `json:"position"` - LockedAt string `json:"locked_at"` - UpdatedByID int `json:"updated_by_id"` - MergeError string `json:"merge_error"` - MergeParams *MergeParams `json:"merge_params"` - MergeWhenPipelineSucceeds bool `json:"merge_when_pipeline_succeeds"` - MergeUserID int `json:"merge_user_id"` - MergeCommitSHA string `json:"merge_commit_sha"` - DeletedAt string `json:"deleted_at"` - InProgressMergeCommitSHA string `json:"in_progress_merge_commit_sha"` - LockVersion int `json:"lock_version"` - ApprovalsBeforeMerge string `json:"approvals_before_merge"` - RebaseCommitSHA string `json:"rebase_commit_sha"` - TimeEstimate int `json:"time_estimate"` - Squash bool `json:"squash"` - LastEditedAt string `json:"last_edited_at"` - LastEditedByID int `json:"last_edited_by_id"` - Source *Repository `json:"source"` - Target *Repository `json:"target"` + MergeRequest struct { // TODO Check if MergeEvent struct can be used + ID int `json:"id"` + TargetBranch string `json:"target_branch"` + SourceBranch string `json:"source_branch"` + SourceProjectID int `json:"source_project_id"` + AuthorID int `json:"author_id"` + AssigneeID int `json:"assignee_id"` + AssigneeIDs []int `json:"assignee_ids"` + Title string `json:"title"` + CreatedAt string `json:"created_at"` // TODO Should be *time.Time + UpdatedAt string `json:"updated_at"` // TODO Should be *time.Time + MilestoneID int `json:"milestone_id"` + State string `json:"state"` + MergeStatus string `json:"merge_status"` + TargetProjectID int `json:"target_project_id"` + IID int `json:"iid"` + Description string `json:"description"` + Position int `json:"position"` + Labels []*EventLabel `json:"labels"` + LockedAt string `json:"locked_at"` + UpdatedByID int `json:"updated_by_id"` + MergeError string `json:"merge_error"` + MergeParams *MergeParams `json:"merge_params"` + MergeWhenPipelineSucceeds bool `json:"merge_when_pipeline_succeeds"` + MergeUserID int `json:"merge_user_id"` + MergeCommitSHA string `json:"merge_commit_sha"` + DeletedAt string `json:"deleted_at"` + InProgressMergeCommitSHA string `json:"in_progress_merge_commit_sha"` + LockVersion int `json:"lock_version"` + ApprovalsBeforeMerge string `json:"approvals_before_merge"` + RebaseCommitSHA string `json:"rebase_commit_sha"` + TimeEstimate int `json:"time_estimate"` + Squash bool `json:"squash"` + LastEditedAt string `json:"last_edited_at"` + LastEditedByID int `json:"last_edited_by_id"` + Source *Repository `json:"source"` + Target *Repository `json:"target"` LastCommit struct { ID string `json:"id"` Title string `json:"title"` @@ -495,9 +570,11 @@ type MergeCommentEvent struct { Email string `json:"email"` } `json:"author"` } `json:"last_commit"` - WorkInProgress bool `json:"work_in_progress"` - TotalTimeSpent int `json:"total_time_spent"` - HeadPipelineID int `json:"head_pipeline_id"` + WorkInProgress bool `json:"work_in_progress"` + TotalTimeSpent int `json:"total_time_spent"` + HeadPipelineID int `json:"head_pipeline_id"` + Assignee *EventUser `json:"assignee"` + DetailedMergeStatus string `json:"detailed_merge_status"` } `json:"merge_request"` } @@ -507,6 +584,7 @@ type MergeCommentEvent struct { // https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#merge-request-events type MergeEvent struct { ObjectKind string `json:"object_kind"` + EventType string `json:"event_type"` User *EventUser `json:"user"` Project struct { ID int `json:"id"` @@ -518,12 +596,13 @@ type MergeEvent struct { Namespace string `json:"namespace"` PathWithNamespace string `json:"path_with_namespace"` DefaultBranch string `json:"default_branch"` + CIConfigPath string `json:"ci_config_path"` Homepage string `json:"homepage"` URL string `json:"url"` SSHURL string `json:"ssh_url"` HTTPURL string `json:"http_url"` WebURL string `json:"web_url"` - Visibility VisibilityValue `json:"visibility"` + Visibility VisibilityValue `json:"visibility"` // TODO GitLab now returns visibility_level of int type } `json:"project"` ObjectAttributes struct { ID int `json:"id"` @@ -545,8 +624,8 @@ type MergeEvent struct { TargetProjectID int `json:"target_project_id"` IID int `json:"iid"` Description string `json:"description"` - Position int `json:"position"` - LockedAt string `json:"locked_at"` + Position int `json:"position"` // TODO this is not returned by GitLab + LockedAt string `json:"locked_at"` // TODO this is not returned by GitLab UpdatedByID int `json:"updated_by_id"` MergeError string `json:"merge_error"` MergeParams *MergeParams `json:"merge_params"` @@ -562,9 +641,13 @@ type MergeEvent struct { Source *Repository `json:"source"` Target *Repository `json:"target"` HeadPipelineID *int `json:"head_pipeline_id"` + LastEditedAt customTime `json:"last_edited_at"` + LastEditedByID int `json:"last_edited_by_id"` + StateID int `json:"state_id"` // TODO Create GitLab state id type LastCommit struct { ID string `json:"id"` Message string `json:"message"` + Title string `json:"title"` Timestamp *time.Time `json:"timestamp"` URL string `json:"url"` Author struct { @@ -572,17 +655,20 @@ type MergeEvent struct { Email string `json:"email"` } `json:"author"` } `json:"last_commit"` - BlockingDiscussionsResolved bool `json:"blocking_discussions_resolved"` - WorkInProgress bool `json:"work_in_progress"` - URL string `json:"url"` - Action string `json:"action"` - OldRev string `json:"oldrev"` - Assignee *EventUser `json:"assignee"` + BlockingDiscussionsResolved bool `json:"blocking_discussions_resolved"` + WorkInProgress bool `json:"work_in_progress"` + TotalTimeSpent int `json:"total_time_spent"` + TimeChange int `json:"time_change"` + HumanTotalTimeSpent int `json:"human_total_time_spent"` + HumanTimeChange int `json:"human_time_change"` + HumanTimeEstimate int `json:"human_time_estimate"` + Labels []*EventLabel `json:"labels"` + FirstContribution bool `json:"first_contribution"` + DetailedMergeStatus string `json:"detailed_merge_status"` + URL string `json:"url"` + Action string `json:"action"` } `json:"object_attributes"` Repository *Repository `json:"repository"` - Assignee *EventUser `json:"assignee"` - Assignees []*EventUser `json:"assignees"` - Reviewers []*EventUser `json:"reviewers"` Labels []*EventLabel `json:"labels"` Changes struct { Assignees struct { @@ -601,6 +687,18 @@ type MergeEvent struct { Previous []*EventLabel `json:"previous"` Current []*EventLabel `json:"current"` } `json:"labels"` + LastEditedAt struct { + Previous string `json:"previous"` + Current string `json:"current"` + } `json:"last_edited_at"` + LastEditedByID struct { + Previous int `json:"previous"` + Current int `json:"current"` + } `json:"last_edited_by_id"` + MilestoneID struct { + Previous int `json:"previous"` + Current int `json:"current"` + } `json:"milestone_id"` SourceBranch struct { Previous string `json:"previous"` Current string `json:"current"` @@ -633,11 +731,9 @@ type MergeEvent struct { Previous int `json:"previous"` Current int `json:"current"` } `json:"updated_by_id"` - MilestoneID struct { - Previous int `json:"previous"` - Current int `json:"current"` - } `json:"milestone_id"` } `json:"changes"` + Assignees []*EventUser `json:"assignees"` + Reviewers []*EventUser `json:"reviewers"` } // EventUser represents a user record in an event and is used as an even initiator or a merge assignee. @@ -696,6 +792,7 @@ type PipelineEvent struct { ObjectKind string `json:"object_kind"` ObjectAttributes struct { ID int `json:"id"` + IID int `json:"iid"` Ref string `json:"ref"` Tag bool `json:"tag"` SHA string `json:"sha"` @@ -704,29 +801,30 @@ type PipelineEvent struct { Status string `json:"status"` DetailedStatus string `json:"detailed_status"` Stages []string `json:"stages"` - CreatedAt string `json:"created_at"` - FinishedAt string `json:"finished_at"` - Duration int `json:"duration"` - QueuedDuration int `json:"queued_duration"` + CreatedAt string `json:"created_at"` // TODO should be *time.Time + FinishedAt string `json:"finished_at"` // TODO should be *time.Time + Duration float64 `json:"duration"` + QueuedDuration float64 `json:"queued_duration"` Variables []struct { Key string `json:"key"` Value string `json:"value"` } `json:"variables"` } `json:"object_attributes"` MergeRequest struct { - ID int `json:"id"` - IID int `json:"iid"` - Title string `json:"title"` - SourceBranch string `json:"source_branch"` - SourceProjectID int `json:"source_project_id"` - TargetBranch string `json:"target_branch"` - TargetProjectID int `json:"target_project_id"` - State string `json:"state"` - MergeRequestStatus string `json:"merge_status"` - URL string `json:"url"` + ID int `json:"id"` + IID int `json:"iid"` + Title string `json:"title"` + SourceBranch string `json:"source_branch"` + SourceProjectID int `json:"source_project_id"` + TargetBranch string `json:"target_branch"` + TargetProjectID int `json:"target_project_id"` + State string `json:"state"` + MergeRequestStatus string `json:"merge_status"` + DetailedMergeStatus string `json:"detailed_merge_status"` + URL string `json:"url"` } `json:"merge_request"` User *EventUser `json:"user"` - Project struct { + Project struct { // TODO create EventProject struct ID int `json:"id"` Name string `json:"name"` Description string `json:"description"` @@ -741,7 +839,7 @@ type PipelineEvent struct { SSHURL string `json:"ssh_url"` HTTPURL string `json:"http_url"` WebURL string `json:"web_url"` - Visibility VisibilityValue `json:"visibility"` + Visibility VisibilityValue `json:"visibility"` // TODO GitLab now returns visibility_level of int type } `json:"project"` Commit struct { ID string `json:"id"` @@ -754,14 +852,23 @@ type PipelineEvent struct { Email string `json:"email"` } `json:"author"` } `json:"commit"` + SourcePipeline struct { + Project struct { + ID int `json:"id"` + WebURL string `json:"web_url"` + PathWithNamespace string `json:"path_with_namespace"` + } `json:"project"` + PipelineID int `json:"pipeline_id"` + JobID int `json:"job_id"` + } `json:"source_pipeline"` Builds []struct { ID int `json:"id"` Stage string `json:"stage"` Name string `json:"name"` Status string `json:"status"` - CreatedAt string `json:"created_at"` - StartedAt string `json:"started_at"` - FinishedAt string `json:"finished_at"` + CreatedAt string `json:"created_at"` // TODO should be *time.Time + StartedAt string `json:"started_at"` // TODO should be *time.Time + FinishedAt string `json:"finished_at"` // TODO should be *time.Time Duration float64 `json:"duration"` QueuedDuration float64 `json:"queued_duration"` FailureReason string `json:"failure_reason"` @@ -769,7 +876,7 @@ type PipelineEvent struct { Manual bool `json:"manual"` AllowFailure bool `json:"allow_failure"` User *EventUser `json:"user"` - Runner struct { + Runner struct { // TODO Create EventRunner struct ID int `json:"id"` Description string `json:"description"` Active bool `json:"active"` @@ -794,18 +901,20 @@ type PipelineEvent struct { // GitLab API docs: // https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#push-events type PushEvent struct { - ObjectKind string `json:"object_kind"` - Before string `json:"before"` - After string `json:"after"` - Ref string `json:"ref"` - CheckoutSHA string `json:"checkout_sha"` - UserID int `json:"user_id"` - UserName string `json:"user_name"` - UserUsername string `json:"user_username"` - UserEmail string `json:"user_email"` - UserAvatar string `json:"user_avatar"` - ProjectID int `json:"project_id"` - Project struct { + ObjectKind string `json:"object_kind"` + EventName string `json:"event_name"` + Before string `json:"before"` + After string `json:"after"` + Ref string `json:"ref"` + CheckoutSHA string `json:"checkout_sha"` + UserID int `json:"user_id"` + UserName string `json:"user_name"` + UserUsername string `json:"user_username"` + UserEmail string `json:"user_email"` + UserAvatar string `json:"user_avatar"` + ProjectID int `json:"project_id"` + Project struct { // TODO create EventProject struct + ID int `json:"id"` Name string `json:"name"` Description string `json:"description"` AvatarURL string `json:"avatar_url"` @@ -819,7 +928,7 @@ type PushEvent struct { SSHURL string `json:"ssh_url"` HTTPURL string `json:"http_url"` WebURL string `json:"web_url"` - Visibility VisibilityValue `json:"visibility"` + Visibility VisibilityValue `json:"visibility"` // GitLab now returns visibility_level of int type } `json:"project"` Repository *Repository `json:"repository"` Commits []*struct { @@ -885,7 +994,7 @@ type ReleaseEvent struct { URL string `json:"url"` } `json:"sources"` } `json:"assets"` - Commit struct { + Commit struct { // TODO replace with Commit struct ID string `json:"id"` Message string `json:"message"` Title string `json:"title"` @@ -904,9 +1013,10 @@ type ReleaseEvent struct { // https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#comment-on-a-code-snippet type SnippetCommentEvent struct { ObjectKind string `json:"object_kind"` + EventType string `json:"event_type"` User *EventUser `json:"user"` ProjectID int `json:"project_id"` - Project struct { + Project struct { // TODO replace with Project struct Name string `json:"name"` Description string `json:"description"` AvatarURL string `json:"avatar_url"` @@ -928,8 +1038,8 @@ type SnippetCommentEvent struct { Note string `json:"note"` NoteableType string `json:"noteable_type"` AuthorID int `json:"author_id"` - CreatedAt string `json:"created_at"` - UpdatedAt string `json:"updated_at"` + CreatedAt string `json:"created_at"` // TODO should be *time.Time + UpdatedAt string `json:"updated_at"` // TODO should be *time.Time ProjectID int `json:"project_id"` Attachment string `json:"attachment"` LineCode string `json:"line_code"` @@ -946,10 +1056,10 @@ type SnippetCommentEvent struct { Content string `json:"content"` AuthorID int `json:"author_id"` ProjectID int `json:"project_id"` - CreatedAt string `json:"created_at"` - UpdatedAt string `json:"updated_at"` + CreatedAt string `json:"created_at"` // TODO should be *time.Time + UpdatedAt string `json:"updated_at"` // TODO should be *time.Time Filename string `json:"file_name"` - ExpiresAt string `json:"expires_at"` + ExpiresAt string `json:"expires_at"` // TODO should be *time.Time Type string `json:"type"` VisibilityLevel int `json:"visibility_level"` Description string `json:"description"` @@ -981,19 +1091,21 @@ type SubGroupEvent struct { // GitLab API docs: // https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#tag-events type TagEvent struct { - ObjectKind string `json:"object_kind"` - Before string `json:"before"` - After string `json:"after"` - Ref string `json:"ref"` - CheckoutSHA string `json:"checkout_sha"` - UserID int `json:"user_id"` - UserName string `json:"user_name"` - UserUsername string `json:"user_username"` - UserAvatar string `json:"user_avatar"` - UserEmail string `json:"user_email"` - ProjectID int `json:"project_id"` - Message string `json:"message"` - Project struct { + ObjectKind string `json:"object_kind"` + EventName string `json:"event_name"` + Before string `json:"before"` + After string `json:"after"` + Ref string `json:"ref"` + CheckoutSHA string `json:"checkout_sha"` + UserID int `json:"user_id"` + UserName string `json:"user_name"` + UserUsername string `json:"user_username"` + UserAvatar string `json:"user_avatar"` + UserEmail string `json:"user_email"` + ProjectID int `json:"project_id"` + Message string `json:"message"` + Project struct { // TODO replace with Project struct + ID int `json:"id"` Name string `json:"name"` Description string `json:"description"` AvatarURL string `json:"avatar_url"` @@ -1010,7 +1122,7 @@ type TagEvent struct { Visibility VisibilityValue `json:"visibility"` } `json:"project"` Repository *Repository `json:"repository"` - Commits []*struct { + Commits []*struct { // TODO Check if can be replaced with Commit struct ID string `json:"id"` Message string `json:"message"` Title string `json:"title"` @@ -1034,7 +1146,8 @@ type TagEvent struct { type WikiPageEvent struct { ObjectKind string `json:"object_kind"` User *EventUser `json:"user"` - Project struct { + Project struct { // TODO replace with Project struct + ID int `json:"id"` Name string `json:"name"` Description string `json:"description"` AvatarURL string `json:"avatar_url"` @@ -1065,6 +1178,7 @@ type WikiPageEvent struct { Slug string `json:"slug"` URL string `json:"url"` Action string `json:"action"` + DiffURL string `json:"diff_url"` } `json:"object_attributes"` } diff --git a/go.mod b/go.mod index 61cefcccd..7ab64cdca 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/xanzy/go-gitlab +module github.com/smit-modi/go-gitlab go 1.18 @@ -7,6 +7,7 @@ require ( github.com/hashicorp/go-cleanhttp v0.5.2 github.com/hashicorp/go-retryablehttp v0.7.2 github.com/stretchr/testify v1.8.1 + github.com/xanzy/go-gitlab v0.81.0 golang.org/x/oauth2 v0.6.0 golang.org/x/time v0.3.0 ) diff --git a/go.sum b/go.sum index db408ebf5..a0fbf3490 100644 --- a/go.sum +++ b/go.sum @@ -26,6 +26,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/xanzy/go-gitlab v0.81.0 h1:ofbhZ5ZY9AjHATWQie4qd2JfncdUmvcSA/zfQB767Dk= +github.com/xanzy/go-gitlab v0.81.0/go.mod h1:VMbY3JIWdZ/ckvHbQqkyd3iYk2aViKrNIQ23IbFMQDo= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= diff --git a/projects.go b/projects.go index e85b19224..2b6c18d91 100644 --- a/projects.go +++ b/projects.go @@ -258,6 +258,7 @@ type ProjectNamespace struct { // Repository represents a repository. type Repository struct { + ID int `json:"id"` Name string `json:"name"` Description string `json:"description"` WebURL string `json:"web_url"` @@ -265,7 +266,7 @@ type Repository struct { GitSSHURL string `json:"git_ssh_url"` GitHTTPURL string `json:"git_http_url"` Namespace string `json:"namespace"` - Visibility VisibilityValue `json:"visibility"` + Visibility VisibilityValue `json:"visibility"` // TODO GitLab now returns visibility_level of int type PathWithNamespace string `json:"path_with_namespace"` DefaultBranch string `json:"default_branch"` Homepage string `json:"homepage"` diff --git a/testdata/webhooks/deployment.json b/testdata/webhooks/deployment.json index ce3c13137..ecd1ad5c4 100644 --- a/testdata/webhooks/deployment.json +++ b/testdata/webhooks/deployment.json @@ -1,9 +1,13 @@ { "object_kind": "deployment", "status": "success", + "status_changed_at": "2023-03-15 00:00:17 +0000", + "deployment_id": 123, "deployable_id": 796, "deployable_url": "http://10.126.0.2:3000/root/test-deployment-webhooks/-/jobs/796", "environment": "staging", + "environment_slug": "staging", + "environment_external_url": null, "project": { "id": 30, "name": "test-deployment-webhooks",