Repository: xanzy/go-gitlab
Pull request #1566 (2022-10-21 17:14:29)

Add resoruce weight events 
Add resource weight events get 
GitLab API docs https://docs.gitlab.com/ee/api/resource_weight_events.html


Patch:
diff --git a/discussions.go b/discussions.go
index 0497c2f..c8f8668 100644
--- a/discussions.go
+++ b/discussions.go
@@ -917,12 +917,12 @@ type ListCommitDiscussionsOptions ListOptions
 //
 // GitLab API docs:
 // https://docs.gitlab.com/ce/api/discussions.html#list-project-commit-discussion-items
-func (s *DiscussionsService) ListCommitDiscussions(pid interface{}, commit string, opt *ListCommitDiscussionsOptions, options ...RequestOptionFunc) ([]*Discussion, *Response, error) {
+func (s *DiscussionsService) ListCommitDiscussions(pid interface{}, commit int, opt *ListCommitDiscussionsOptions, options ...RequestOptionFunc) ([]*Discussion, *Response, error) {
 	project, err := parseID(pid)
 	if err != nil {
 		return nil, nil, err
 	}
-	u := fmt.Sprintf("projects/%s/repository/commits/%s/discussions",
+	u := fmt.Sprintf("projects/%s/repository/commits/%d/discussions",
 		PathEscape(project),
 		commit,
 	)
@@ -946,12 +946,12 @@ func (s *DiscussionsService) ListCommitDiscussions(pid interface{}, commit strin
 //
 // GitLab API docs:
 // https://docs.gitlab.com/ce/api/discussions.html#get-single-commit-discussion-item
-func (s *DiscussionsService) GetCommitDiscussion(pid interface{}, commit string, discussion string, options ...RequestOptionFunc) (*Discussion, *Response, error) {
+func (s *DiscussionsService) GetCommitDiscussion(pid interface{}, commit int, discussion string, options ...RequestOptionFunc) (*Discussion, *Response, error) {
 	project, err := parseID(pid)
 	if err != nil {
 		return nil, nil, err
 	}
-	u := fmt.Sprintf("projects/%s/repository/commits/%s/discussions/%s",
+	u := fmt.Sprintf("projects/%s/repository/commits/%d/discussions/%s",
 		PathEscape(project),
 		commit,
 		discussion,
@@ -986,12 +986,12 @@ type CreateCommitDiscussionOptions struct {
 //
 // GitLab API docs:
 // https://docs.gitlab.com/ce/api/discussions.html#create-new-commit-thread
-func (s *DiscussionsService) CreateCommitDiscussion(pid interface{}, commit string, opt *CreateCommitDiscussionOptions, options ...RequestOptionFunc) (*Discussion, *Response, error) {
+func (s *DiscussionsService) CreateCommitDiscussion(pid interface{}, commit int, opt *CreateCommitDiscussionOptions, options ...RequestOptionFunc) (*Discussion, *Response, error) {
 	project, err := parseID(pid)
 	if err != nil {
 		return nil, nil, err
 	}
-	u := fmt.Sprintf("projects/%s/repository/commits/%s/discussions",
+	u := fmt.Sprintf("projects/%s/repository/commits/%d/discussions",
 		PathEscape(project),
 		commit,
 	)
@@ -1024,12 +1024,12 @@ type AddCommitDiscussionNoteOptions struct {
 //
 // GitLab API docs:
 // https://docs.gitlab.com/ce/api/discussions.html#add-note-to-existing-commit-thread
-func (s *DiscussionsService) AddCommitDiscussionNote(pid interface{}, commit string, discussion string, opt *AddCommitDiscussionNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) {
+func (s *DiscussionsService) AddCommitDiscussionNote(pid interface{}, commit int, discussion string, opt *AddCommitDiscussionNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) {
 	project, err := parseID(pid)
 	if err != nil {
 		return nil, nil, err
 	}
-	u := fmt.Sprintf("projects/%s/repository/commits/%s/discussions/%s/notes",
+	u := fmt.Sprintf("projects/%s/repository/commits/%d/discussions/%s/notes",
 		PathEscape(project),
 		commit,
 		discussion,
@@ -1063,12 +1063,12 @@ type UpdateCommitDiscussionNoteOptions struct {
 //
 // GitLab API docs:
 // https://docs.gitlab.com/ce/api/discussions.html#modify-an-existing-commit-thread-note
-func (s *DiscussionsService) UpdateCommitDiscussionNote(pid interface{}, commit string, discussion string, note int, opt *UpdateCommitDiscussionNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) {
+func (s *DiscussionsService) UpdateCommitDiscussionNote(pid interface{}, commit int, discussion string, note int, opt *UpdateCommitDiscussionNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) {
 	project, err := parseID(pid)
 	if err != nil {
 		return nil, nil, err
 	}
-	u := fmt.Sprintf("projects/%s/repository/commits/%s/discussions/%s/notes/%d",
+	u := fmt.Sprintf("projects/%s/repository/commits/%d/discussions/%s/notes/%d",
 		PathEscape(project),
 		commit,
 		discussion,
@@ -1093,12 +1093,12 @@ func (s *DiscussionsService) UpdateCommitDiscussionNote(pid interface{}, commit
 //
 // GitLab API docs:
 // https://docs.gitlab.com/ce/api/discussions.html#delete-a-commit-thread-note
-func (s *DiscussionsService) DeleteCommitDiscussionNote(pid interface{}, commit string, discussion string, note int, options ...RequestOptionFunc) (*Response, error) {
+func (s *DiscussionsService) DeleteCommitDiscussionNote(pid interface{}, commit int, discussion string, note int, options ...RequestOptionFunc) (*Response, error) {
 	project, err := parseID(pid)
 	if err != nil {
 		return nil, err
 	}
-	u := fmt.Sprintf("projects/%s/repository/commits/%s/discussions/%s/notes/%d",
+	u := fmt.Sprintf("projects/%s/repository/commits/%d/discussions/%s/notes/%d",
 		PathEscape(project),
 		commit,
 		discussion,
diff --git a/event_webhook_types.go b/event_webhook_types.go
index e596213..cb94322 100644
--- a/event_webhook_types.go
+++ b/event_webhook_types.go
@@ -151,7 +151,6 @@ type DeploymentEvent struct {
 		SSHURL            string  `json:"ssh_url"`
 		HTTPURL           string  `json:"http_url"`
 	} `json:"project"`
-	Ref         string     `json:"ref"`
 	ShortSHA    string     `json:"short_sha"`
 	User        *EventUser `json:"user"`
 	UserURL     string     `json:"user_url"`
@@ -306,7 +305,8 @@ type IssueEvent struct {
 // JobEvent represents a job event.
 //
 // GitLab API docs:
-// https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#job-events
+// TODO: link to docs instead of src once they are published.
+// https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/gitlab/data_builder/build.rb
 type JobEvent struct {
 	ObjectKind         string     `json:"object_kind"`
 	Ref                string     `json:"ref"`
diff --git a/gitlab.go b/gitlab.go
index c9055f8..d56ca26 100644
--- a/gitlab.go
+++ b/gitlab.go
@@ -190,6 +190,7 @@ type Client struct {
 	ResourceLabelEvents     *ResourceLabelEventsService
 	ResourceMilestoneEvents *ResourceMilestoneEventsService
 	ResourceStateEvents     *ResourceStateEventsService
+	ResourceWeightEvents    *ResourceWeightEventsService
 	Runners                 *RunnersService
 	Search                  *SearchService
 	Services                *ServicesService
@@ -393,6 +394,7 @@ func newClient(options ...ClientOptionFunc) (*Client, error) {
 	c.ResourceLabelEvents = &ResourceLabelEventsService{client: c}
 	c.ResourceMilestoneEvents = &ResourceMilestoneEventsService{client: c}
 	c.ResourceStateEvents = &ResourceStateEventsService{client: c}
+	c.ResourceWeightEvents = &ResourceWeightEventsService{client: c}
 	c.Runners = &RunnersService{client: c}
 	c.Search = &SearchService{client: c}
 	c.Services = &ServicesService{client: c}
@@ -902,23 +904,24 @@ func CheckResponse(r *http.Response) error {
 }
 
 // Format:
-// {
-//     "message": {
-//         "<property-name>": [
-//             "<error-message>",
-//             "<error-message>",
-//             ...
-//         ],
-//         "<embed-entity>": {
-//             "<property-name>": [
-//                 "<error-message>",
-//                 "<error-message>",
-//                 ...
-//             ],
-//         }
-//     },
-//     "error": "<error-message>"
-// }
+//
+//	{
+//	    "message": {
+//	        "<property-name>": [
+//	            "<error-message>",
+//	            "<error-message>",
+//	            ...
+//	        ],
+//	        "<embed-entity>": {
+//	            "<property-name>": [
+//	                "<error-message>",
+//	                "<error-message>",
+//	                ...
+//	            ],
+//	        }
+//	    },
+//	    "error": "<error-message>"
+//	}
 func parseError(raw interface{}) string {
 	switch raw := raw.(type) {
 	case string:
diff --git a/issue_links.go b/issue_links.go
index 0d4a29e..4fe81ff 100644
--- a/issue_links.go
+++ b/issue_links.go
@@ -19,7 +19,6 @@ package gitlab
 import (
 	"fmt"
 	"net/http"
-	"time"
 )
 
 // IssueLinksService handles communication with the issue relations related methods
@@ -39,36 +38,6 @@ type IssueLink struct {
 	LinkType    string `json:"link_type"`
 }
 
-// IssueRelation gets a relation between two issues.
-//
-// GitLab API docs:
-// https://docs.gitlab.com/ee/api/issue_links.html#list-issue-relations
-type IssueRelation struct {
-	ID             int              `json:"id"`
-	IID            int              `json:"iid"`
-	State          string           `json:"state"`
-	Description    string           `json:"description"`
-	Confidential   bool             `json:"confidential"`
-	Author         *IssueAuthor     `json:"author"`
-	Milestone      *Milestone       `json:"milestone"`
-	ProjectID      int              `json:"project_id"`
-	Assignees      []*IssueAssignee `json:"assignees"`
-	Assignee       *IssueAssignee   `json:"assignee"`
-	UpdatedAt      *time.Time       `json:"updated_at"`
-	Title          string           `json:"title"`
-	CreatedAt      *time.Time       `json:"created_at"`
-	Labels         Labels           `json:"labels"`
-	DueDate        *ISOTime         `json:"due_date"`
-	WebURL         string           `json:"web_url"`
-	References     *IssueReferences `json:"references"`
-	Weight         int              `json:"weight"`
-	UserNotesCount int              `json:"user_notes_count"`
-	IssueLinkID    int              `json:"issue_link_id"`
-	LinkType       string           `json:"link_type"`
-	LinkCreatedAt  *time.Time       `json:"link_created_at"`
-	LinkUpdatedAt  *time.Time       `json:"link_updated_at"`
-}
-
 // ListIssueRelations gets a list of related issues of a given issue,
 // sorted by the relationship creation datetime (ascending).
 //
@@ -76,7 +45,7 @@ type IssueRelation struct {
 //
 // GitLab API docs:
 // https://docs.gitlab.com/ee/api/issue_links.html#list-issue-relations
-func (s *IssueLinksService) ListIssueRelations(pid interface{}, issue int, options ...RequestOptionFunc) ([]*IssueRelation, *Response, error) {
+func (s *IssueLinksService) ListIssueRelations(pid interface{}, issue int, options ...RequestOptionFunc) ([]*Issue, *Response, error) {
 	project, err := parseID(pid)
 	if err != nil {
 		return nil, nil, err
@@ -88,7 +57,7 @@ func (s *IssueLinksService) ListIssueRelations(pid interface{}, issue int, optio
 		return nil, nil, err
 	}
 
-	var is []*IssueRelation
+	var is []*Issue
 	resp, err := s.client.Do(req, &is)
 	if err != nil {
 		return nil, resp, err
diff --git a/issues.go b/issues.go
index 31bb935..7280efb 100644
--- a/issues.go
+++ b/issues.go
@@ -207,38 +207,33 @@ type LabelDetails struct {
 // GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#list-issues
 type ListIssuesOptions struct {
 	ListOptions
-	State               *string          `url:"state,omitempty" json:"state,omitempty"`
-	Labels              *Labels          `url:"labels,comma,omitempty" json:"labels,omitempty"`
-	NotLabels           *Labels          `url:"not[labels],comma,omitempty" json:"not[labels],omitempty"`
-	WithLabelDetails    *bool            `url:"with_labels_details,omitempty" json:"with_labels_details,omitempty"`
-	Milestone           *string          `url:"milestone,omitempty" json:"milestone,omitempty"`
-	NotMilestone        *string          `url:"not[milestone],omitempty" json:"not[milestone],omitempty"`
-	Scope               *string          `url:"scope,omitempty" json:"scope,omitempty"`
-	AuthorID            *int             `url:"author_id,omitempty" json:"author_id,omitempty"`
-	AuthorUsername      *string          `url:"author_username,omitempty" json:"author_username,omitempty"`
-	NotAuthorUsername   *string          `url:"not[author_username],omitempty" json:"not[author_username],omitempty"`
-	NotAuthorID         *[]int           `url:"not[author_id],omitempty" json:"not[author_id],omitempty"`
-	AssigneeID          *AssigneeIDValue `url:"assignee_id,omitempty" json:"assignee_id,omitempty"`
-	NotAssigneeID       *[]int           `url:"not[assignee_id],omitempty" json:"not[assignee_id],omitempty"`
-	AssigneeUsername    *string          `url:"assignee_username,omitempty" json:"assignee_username,omitempty"`
-	NotAssigneeUsername *string          `url:"not[assignee_username],omitempty" json:"not[assignee_username],omitempty"`
-	MyReactionEmoji     *string          `url:"my_reaction_emoji,omitempty" json:"my_reaction_emoji,omitempty"`
-	NotMyReactionEmoji  *[]string        `url:"not[my_reaction_emoji],omitempty" json:"not[my_reaction_emoji],omitempty"`
-	IIDs                *[]int           `url:"iids[],omitempty" json:"iids,omitempty"`
-	In                  *string          `url:"in,omitempty" json:"in,omitempty"`
-	NotIn               *string          `url:"not[in],omitempty" json:"not[in],omitempty"`
-	OrderBy             *string          `url:"order_by,omitempty" json:"order_by,omitempty"`
-	Sort                *string          `url:"sort,omitempty" json:"sort,omitempty"`
-	Search              *string          `url:"search,omitempty" json:"search,omitempty"`
-	NotSearch           *string          `url:"not[search],omitempty" json:"not[search],omitempty"`
-	CreatedAfter        *time.Time       `url:"created_after,omitempty" json:"created_after,omitempty"`
-	CreatedBefore       *time.Time       `url:"created_before,omitempty" json:"created_before,omitempty"`
-	DueDate             *string          `url:"due_date,omitempty" json:"due_date,omitempty"`
-	UpdatedAfter        *time.Time       `url:"updated_after,omitempty" json:"updated_after,omitempty"`
-	UpdatedBefore       *time.Time       `url:"updated_before,omitempty" json:"updated_before,omitempty"`
-	Confidential        *bool            `url:"confidential,omitempty" json:"confidential,omitempty"`
-	IssueType           *string          `url:"issue_type,omitempty" json:"issue_type,omitempty"`
-	IterationID         *int             `url:"iteration_id,omitempty" json:"iteration_id,omitempty"`
+	State              *string          `url:"state,omitempty" json:"state,omitempty"`
+	Labels             *Labels          `url:"labels,comma,omitempty" json:"labels,omitempty"`
+	NotLabels          *Labels          `url:"not[labels],comma,omitempty" json:"not[labels],omitempty"`
+	WithLabelDetails   *bool            `url:"with_labels_details,omitempty" json:"with_labels_details,omitempty"`
+	Milestone          *string          `url:"milestone,omitempty" json:"milestone,omitempty"`
+	NotMilestone       *string          `url:"not[milestone],omitempty" json:"not[milestone],omitempty"`
+	Scope              *string          `url:"scope,omitempty" json:"scope,omitempty"`
+	AuthorID           *int             `url:"author_id,omitempty" json:"author_id,omitempty"`
+	AuthorUsername     *string          `url:"author_username,omitempty" json:"author_username,omitempty"`
+	NotAuthorID        *[]int           `url:"not[author_id],omitempty" json:"not[author_id],omitempty"`
+	AssigneeID         *AssigneeIDValue `url:"assignee_id,omitempty" json:"assignee_id,omitempty"`
+	NotAssigneeID      *[]int           `url:"not[assignee_id],omitempty" json:"not[assignee_id],omitempty"`
+	AssigneeUsername   *string          `url:"assignee_username,omitempty" json:"assignee_username,omitempty"`
+	MyReactionEmoji    *string          `url:"my_reaction_emoji,omitempty" json:"my_reaction_emoji,omitempty"`
+	NotMyReactionEmoji *[]string        `url:"not[my_reaction_emoji],omitempty" json:"not[my_reaction_emoji],omitempty"`
+	IIDs               *[]int           `url:"iids[],omitempty" json:"iids,omitempty"`
+	In                 *string          `url:"in,omitempty" json:"in,omitempty"`
+	OrderBy            *string          `url:"order_by,omitempty" json:"order_by,omitempty"`
+	Sort               *string          `url:"sort,omitempty" json:"sort,omitempty"`
+	Search             *string          `url:"search,omitempty" json:"search,omitempty"`
+	CreatedAfter       *time.Time       `url:"created_after,omitempty" json:"created_after,omitempty"`
+	CreatedBefore      *time.Time       `url:"created_before,omitempty" json:"created_before,omitempty"`
+	UpdatedAfter       *time.Time       `url:"updated_after,omitempty" json:"updated_after,omitempty"`
+	UpdatedBefore      *time.Time       `url:"updated_before,omitempty" json:"updated_before,omitempty"`
+	Confidential       *bool            `url:"confidential,omitempty" json:"confidential,omitempty"`
+	IssueType          *string          `url:"issue_type,omitempty" json:"issue_type,omitempty"`
+	IterationID        *int             `url:"iteration_id,omitempty" json:"iteration_id,omitempty"`
 }
 
 // ListIssues gets all issues created by authenticated user. This function
@@ -265,38 +260,33 @@ func (s *IssuesService) ListIssues(opt *ListIssuesOptions, options ...RequestOpt
 // GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#list-group-issues
 type ListGroupIssuesOptions struct {
 	ListOptions
-	State             *string `url:"state,omitempty" json:"state,omitempty"`
-	Labels            *Labels `url:"labels,comma,omitempty" json:"labels,omitempty"`
-	NotLabels         *Labels `url:"not[labels],comma,omitempty" json:"not[labels],omitempty"`
-	WithLabelDetails  *bool   `url:"with_labels_details,omitempty" json:"with_labels_details,omitempty"`
-	IIDs              *[]int  `url:"iids[],omitempty" json:"iids,omitempty"`
-	Milestone         *string `url:"milestone,omitempty" json:"milestone,omitempty"`
-	NotMilestone      *string `url:"not[milestone],omitempty" json:"not[milestone],omitempty"`
-	Scope             *string `url:"scope,omitempty" json:"scope,omitempty"`
-	AuthorID          *int    `url:"author_id,omitempty" json:"author_id,omitempty"`
-	NotAuthorID       *[]int  `url:"not[author_id],omitempty" json:"not[author_id],omitempty"`
-	AuthorUsername    *string `url:"author_username,omitempty" json:"author_username,omitempty"`
-	NotAuthorUsername *string `url:"not[author_username],omitempty" json:"not[author_username],omitempty"`
-
-	AssigneeID          *AssigneeIDValue `url:"assignee_id,omitempty" json:"assignee_id,omitempty"`
-	NotAssigneeID       *[]int           `url:"not[assignee_id],omitempty" json:"not[assignee_id],omitempty"`
-	AssigneeUsername    *string          `url:"assignee_username,omitempty" json:"assignee_username,omitempty"`
-	NotAssigneeUsername *string          `url:"not[assignee_username],omitempty" json:"not[assignee_username],omitempty"`
-	MyReactionEmoji     *string          `url:"my_reaction_emoji,omitempty" json:"my_reaction_emoji,omitempty"`
-	NotMyReactionEmoji  *[]string        `url:"not[my_reaction_emoji],omitempty" json:"not[my_reaction_emoji],omitempty"`
-	OrderBy             *string          `url:"order_by,omitempty" json:"order_by,omitempty"`
-	Sort                *string          `url:"sort,omitempty" json:"sort,omitempty"`
-	Search              *string          `url:"search,omitempty" json:"search,omitempty"`
-	NotSearch           *string          `url:"not[search],omitempty" json:"not[search],omitempty"`
-	In                  *string          `url:"in,omitempty" json:"in,omitempty"`
-	NotIn               *string          `url:"not[in],omitempty" json:"not[in],omitempty"`
-	CreatedAfter        *time.Time       `url:"created_after,omitempty" json:"created_after,omitempty"`
-	CreatedBefore       *time.Time       `url:"created_before,omitempty" json:"created_before,omitempty"`
-	DueDate             *string          `url:"due_date,omitempty" json:"due_date,omitempty"`
-	UpdatedAfter        *time.Time       `url:"updated_after,omitempty" json:"updated_after,omitempty"`
-	UpdatedBefore       *time.Time       `url:"updated_before,omitempty" json:"updated_before,omitempty"`
-	IssueType           *string          `url:"issue_type,omitempty" json:"issue_type,omitempty"`
-	IterationID         *int             `url:"iteration_id,omitempty" json:"iteration_id,omitempty"`
+	State            *string `url:"state,omitempty" json:"state,omitempty"`
+	Labels           *Labels `url:"labels,comma,omitempty" json:"labels,omitempty"`
+	NotLabels        *Labels `url:"not[labels],comma,omitempty" json:"not[labels],omitempty"`
+	WithLabelDetails *bool   `url:"with_labels_details,omitempty" json:"with_labels_details,omitempty"`
+	IIDs             *[]int  `url:"iids[],omitempty" json:"iids,omitempty"`
+	Milestone        *string `url:"milestone,omitempty" json:"milestone,omitempty"`
+	NotMilestone     *string `url:"not[milestone],omitempty" json:"not[milestone],omitempty"`
+	Scope            *string `url:"scope,omitempty" json:"scope,omitempty"`
+	AuthorID         *int    `url:"author_id,omitempty" json:"author_id,omitempty"`
+	NotAuthorID      *[]int  `url:"not[author_id],omitempty" json:"not[author_id],omitempty"`
+	AuthorUsername   *string `url:"author_username,omitempty" json:"author_username,omitempty"`
+
+	AssigneeID         *AssigneeIDValue `url:"assignee_id,omitempty" json:"assignee_id,omitempty"`
+	NotAssigneeID      *[]int           `url:"not[assignee_id],omitempty" json:"not[assignee_id],omitempty"`
+	AssigneeUsername   *string          `url:"assignee_username,omitempty" json:"assignee_username,omitempty"`
+	MyReactionEmoji    *string          `url:"my_reaction_emoji,omitempty" json:"my_reaction_emoji,omitempty"`
+	NotMyReactionEmoji *[]string        `url:"not[my_reaction_emoji],omitempty" json:"not[my_reaction_emoji],omitempty"`
+	OrderBy            *string          `url:"order_by,omitempty" json:"order_by,omitempty"`
+	Sort               *string          `url:"sort,omitempty" json:"sort,omitempty"`
+	Search             *string          `url:"search,omitempty" json:"search,omitempty"`
+	In                 *string          `url:"in,omitempty" json:"in,omitempty"`
+	CreatedAfter       *time.Time       `url:"created_after,omitempty" json:"created_after,omitempty"`
+	CreatedBefore      *time.Time       `url:"created_before,omitempty" json:"created_before,omitempty"`
+	UpdatedAfter       *time.Time       `url:"updated_after,omitempty" json:"updated_after,omitempty"`
+	UpdatedBefore      *time.Time       `url:"updated_before,omitempty" json:"updated_before,omitempty"`
+	IssueType          *string          `url:"issue_type,omitempty" json:"issue_type,omitempty"`
+	IterationID        *int             `url:"iteration_id,omitempty" json:"iteration_id,omitempty"`
 }
 
 // ListGroupIssues gets a list of group issues. This function accepts
@@ -329,37 +319,34 @@ func (s *IssuesService) ListGroupIssues(pid interface{}, opt *ListGroupIssuesOpt
 // GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#list-project-issues
 type ListProjectIssuesOptions struct {
 	ListOptions
-	IIDs                *[]int           `url:"iids[],omitempty" json:"iids,omitempty"`
-	State               *string          `url:"state,omitempty" json:"state,omitempty"`
-	Labels              *Labels          `url:"labels,comma,omitempty" json:"labels,omitempty"`
-	NotLabels           *Labels          `url:"not[labels],comma,omitempty" json:"not[labels],omitempty"`
-	WithLabelDetails    *bool            `url:"with_labels_details,omitempty" json:"with_labels_details,omitempty"`
-	Milestone           *string          `url:"milestone,omitempty" json:"milestone,omitempty"`
-	NotMilestone        *string          `url:"not[milestone],omitempty" json:"not[milestone],omitempty"`
-	Scope               *string          `url:"scope,omitempty" json:"scope,omitempty"`
-	AuthorID            *int             `url:"author_id,omitempty" json:"author_id,omitempty"`
-	AuthorUsername      *string          `url:"author_username,omitempty" json:"author_username,omitempty"`
-	NotAuthorUsername   *string          `url:"not[author_username],omitempty" json:"not[author_username],omitempty"`
-	NotAuthorID         *[]int           `url:"not[author_id],omitempty" json:"not[author_id],omitempty"`
-	AssigneeID          *AssigneeIDValue `url:"assignee_id,omitempty" json:"assignee_id,omitempty"`
-	NotAssigneeID       *[]int           `url:"not[assignee_id],omitempty" json:"not[assignee_id],omitempty"`
-	AssigneeUsername    *string          `url:"assignee_username,omitempty" json:"assignee_username,omitempty"`
-	NotAssigneeUsername *string          `url:"not[assignee_username],omitempty" json:"not[assignee_username],omitempty"`
-	MyReactionEmoji     *string          `url:"my_reaction_emoji,omitempty" json:"my_reaction_emoji,omitempty"`
-	NotMyReactionEmoji  *[]string        `url:"not[my_reaction_emoji],omitempty" json:"not[my_reaction_emoji],omitempty"`
-	OrderBy             *string          `url:"order_by,omitempty" json:"order_by,omitempty"`
-	Sort                *string          `url:"sort,omitempty" json:"sort,omitempty"`
-	Search              *string          `url:"search,omitempty" json:"search,omitempty"`
-	In                  *string          `url:"in,omitempty" json:"in,omitempty"`
-	NotIn               *string          `url:"not[in],omitempty" json:"not[in],omitempty"`
-	CreatedAfter        *time.Time       `url:"created_after,omitempty" json:"created_after,omitempty"`
-	CreatedBefore       *time.Time       `url:"created_before,omitempty" json:"created_before,omitempty"`
-	DueDate             *string          `url:"due_date,omitempty" json:"due_date,omitempty"`
-	UpdatedAfter        *time.Time       `url:"updated_after,omitempty" json:"updated_after,omitempty"`
-	UpdatedBefore       *time.Time       `url:"updated_before,omitempty" json:"updated_before,omitempty"`
-	Confidential        *bool            `url:"confidential,omitempty" json:"confidential,omitempty"`
-	IssueType           *string          `url:"issue_type,omitempty" json:"issue_type,omitempty"`
-	IterationID         *int             `url:"iteration_id,omitempty" json:"iteration_id,omitempty"`
+	IIDs               *[]int           `url:"iids[],omitempty" json:"iids,omitempty"`
+	State              *string          `url:"state,omitempty" json:"state,omitempty"`
+	Labels             *Labels          `url:"labels,comma,omitempty" json:"labels,omitempty"`
+	NotLabels          *Labels          `url:"not[labels],comma,omitempty" json:"not[labels],omitempty"`
+	WithLabelDetails   *bool            `url:"with_labels_details,omitempty" json:"with_labels_details,omitempty"`
+	Milestone          *string          `url:"milestone,omitempty" json:"milestone,omitempty"`
+	NotMilestone       *string          `url:"not[milestone],omitempty" json:"not[milestone],omitempty"`
+	Scope              *string          `url:"scope,omitempty" json:"scope,omitempty"`
+	AuthorID           *int             `url:"author_id,omitempty" json:"author_id,omitempty"`
+	AuthorUsername     *string          `url:"author_username,omitempty" json:"author_username,omitempty"`
+	NotAuthorID        *[]int           `url:"not[author_id],omitempty" json:"not[author_id],omitempty"`
+	AssigneeID         *AssigneeIDValue `url:"assignee_id,omitempty" json:"assignee_id,omitempty"`
+	NotAssigneeID      *[]int           `url:"not[assignee_id],omitempty" json:"not[assignee_id],omitempty"`
+	AssigneeUsername   *string          `url:"assignee_username,omitempty" json:"assignee_username,omitempty"`
+	MyReactionEmoji    *string          `url:"my_reaction_emoji,omitempty" json:"my_reaction_emoji,omitempty"`
+	NotMyReactionEmoji *[]string        `url:"not[my_reaction_emoji],omitempty" json:"not[my_reaction_emoji],omitempty"`
+	OrderBy            *string          `url:"order_by,omitempty" json:"order_by,omitempty"`
+	Sort               *string          `url:"sort,omitempty" json:"sort,omitempty"`
+	Search             *string          `url:"search,omitempty" json:"search,omitempty"`
+	In                 *string          `url:"in,omitempty" json:"in,omitempty"`
+	CreatedAfter       *time.Time       `url:"created_after,omitempty" json:"created_after,omitempty"`
+	CreatedBefore      *time.Time       `url:"created_before,omitempty" json:"created_before,omitempty"`
+	DueDate            *string          `url:"due_date,omitempty" json:"due_date,omitempty"`
+	UpdatedAfter       *time.Time       `url:"updated_after,omitempty" json:"updated_after,omitempty"`
+	UpdatedBefore      *time.Time       `url:"updated_before,omitempty" json:"updated_before,omitempty"`
+	Confidential       *bool            `url:"confidential,omitempty" json:"confidential,omitempty"`
+	IssueType          *string          `url:"issue_type,omitempty" json:"issue_type,omitempty"`
+	IterationID        *int             `url:"iteration_id,omitempty" json:"iteration_id,omitempty"`
 }
 
 // ListProjectIssues gets a list of project issues. This function accepts
diff --git a/jobs.go b/jobs.go
index ec06009..3136e55 100644
--- a/jobs.go
+++ b/jobs.go
@@ -499,36 +499,18 @@ func (s *JobsService) KeepArtifacts(pid interface{}, jobID int, options ...Reque
 	return job, resp, err
 }
 
-// PlayJobOptions represents the available PlayJob() options.
-//
-// GitLab API docs:
-// https://docs.gitlab.com/ce/api/jobs.html#run-a-job
-type PlayJobOptions struct {
-	JobVariablesAttributes *[]*JobVariableOptions `url:"job_variables_attributes,omitempty" json:"job_variables_attributes,omitempty"`
-}
-
-// JobVariableOptions represents a single job variable.
-//
-// GitLab API docs:
-// https://docs.gitlab.com/ce/api/jobs.html#run-a-job
-type JobVariableOptions struct {
-	Key          *string `url:"key,omitempty" json:"key,omitempty"`
-	Value        *string `url:"value,omitempty" json:"value,omitempty"`
-	VariableType *string `url:"variable_type,omitempty" json:"variable_type,omitempty"`
-}
-
 // PlayJob triggers a manual action to start a job.
 //
 // GitLab API docs:
-// https://docs.gitlab.com/ce/api/jobs.html#run-a-job
-func (s *JobsService) PlayJob(pid interface{}, jobID int, opt *PlayJobOptions, options ...RequestOptionFunc) (*Job, *Response, error) {
+// https://docs.gitlab.com/ce/api/jobs.html#play-a-job
+func (s *JobsService) PlayJob(pid interface{}, jobID int, options ...RequestOptionFunc) (*Job, *Response, error) {
 	project, err := parseID(pid)
 	if err != nil {
 		return nil, nil, err
 	}
 	u := fmt.Sprintf("projects/%s/jobs/%d/play", PathEscape(project), jobID)
 
-	req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
+	req, err := s.client.NewRequest(http.MethodPost, u, nil, options)
 	if err != nil {
 		return nil, nil, err
 	}
diff --git a/pipeline_schedules.go b/pipeline_schedules.go
index 1a8cb8c..12640e2 100644
--- a/pipeline_schedules.go
+++ b/pipeline_schedules.go
@@ -110,39 +110,6 @@ func (s *PipelineSchedulesService) GetPipelineSchedule(pid interface{}, schedule
 	return p, resp, err
 }
 
-// ListPipelinesTriggeredByScheduleOptions represents the available
-// ListPipelinesTriggeredBySchedule() options.
-//
-// GitLab API docs:
-// https://docs.gitlab.com/ee/api/pipeline_schedules.html#get-all-pipelines-triggered-by-a-pipeline-schedule
-type ListPipelinesTriggeredByScheduleOptions ListOptions
-
-// ListPipelinesTriggeredBySchedule gets all pipelines triggered by a pipeline
-// schedule.
-//
-// GitLab API docs:
-// https://docs.gitlab.com/ee/api/pipeline_schedules.html#get-all-pipelines-triggered-by-a-pipeline-schedule
-func (s *PipelineSchedulesService) ListPipelinesTriggeredBySchedule(pid interface{}, schedule int, opt *ListPipelinesTriggeredByScheduleOptions, options ...RequestOptionFunc) ([]*Pipeline, *Response, error) {
-	project, err := parseID(pid)
-	if err != nil {
-		return nil, nil, err
-	}
-	u := fmt.Sprintf("projects/%s/pipeline_schedules/%d/pipelines", PathEscape(project), schedule)
-
-	req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
-	if err != nil {
-		return nil, nil, err
-	}
-
-	var p []*Pipeline
-	resp, err := s.client.Do(req, &p)
-	if err != nil {
-		return nil, resp, err
-	}
-
-	return p, resp, err
-}
-
 // CreatePipelineScheduleOptions represents the available
 // CreatePipelineSchedule() options.
 //
diff --git a/resource_weight_events.go b/resource_weight_events.go
new file mode 100644
index 0000000..e1a4bf5
--- /dev/null
+++ b/resource_weight_events.go
@@ -0,0 +1,80 @@
+//
+// Copyright 2021, Matthias Simon
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package gitlab
+
+import (
+	"fmt"
+	"net/http"
+	"time"
+)
+
+// ResourceWeightEventsService handles communication with the event related
+// methods of the GitLab API.
+//
+// GitLab API docs: https://docs.gitlab.com/ee/api/resource_weight_events.html
+type ResourceWeightEventsService struct {
+	client *Client
+}
+
+// WeightEvent represents a resource weight event.
+//
+// GitLab API docs: https://docs.gitlab.com/ee/api/resource_weight_events.html
+type WeightEvent struct {
+	ID           int            `json:"id"`
+	User         *BasicUser     `json:"user"`
+	CreatedAt    *time.Time     `json:"created_at"`
+	ResourceType string         `json:"resource_type"`
+	ResourceID   int            `json:"resource_id"`
+	State        EventTypeValue `json:"state"`
+	IssueID      int            `json:"issue_id"`
+	Weight       int            `json:"weight"`
+}
+
+// ListWeightEventsOptions represents the options for all resource weight events
+// list methods.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/resource_weight_events.html#list-project-issue-weight-events
+type ListWeightEventsOptions struct {
+	ListOptions
+}
+
+// ListIssueWeightEvents retrieves resource weight events for the specified
+// project and issue.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/resource_weight_events.html#list-project-issue-weight-events
+func (s *ResourceWeightEventsService) ListIssueWeightEvents(pid interface{}, issue int, opt *ListWeightEventsOptions, options ...RequestOptionFunc) ([]*WeightEvent, *Response, error) {
+	project, err := parseID(pid)
+	if err != nil {
+		return nil, nil, err
+	}
+	u := fmt.Sprintf("projects/%s/issues/%d/resource_weight_events", PathEscape(project), issue)
+
+	req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var wes []*WeightEvent
+	resp, err := s.client.Do(req, &wes)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return wes, resp, err
+}
diff --git a/users.go b/users.go
index f04acfb..d03e7e1 100644
--- a/users.go
+++ b/users.go
@@ -26,16 +26,14 @@ import (
 
 // List a couple of standard errors.
 var (
-	ErrUserActivatePrevented         = errors.New("Cannot activate a user that is blocked by admin or by LDAP synchronization")
-	ErrUserApprovePrevented          = errors.New("Cannot approve a user that is blocked by admin or by LDAP synchronization")
-	ErrUserBlockPrevented            = errors.New("Cannot block a user that is already blocked by LDAP synchronization")
-	ErrUserConflict                  = errors.New("User does not have a pending request")
-	ErrUserDeactivatePrevented       = errors.New("Cannot deactivate a user that is blocked by admin or by LDAP synchronization")
-	ErrUserDisableTwoFactorPrevented = errors.New("Cannot disable two factor authentication if not authenticated as administrator")
-	ErrUserNotFound                  = errors.New("User does not exist")
-	ErrUserRejectPrevented           = errors.New("Cannot reject a user if not authenticated as administrator")
-	ErrUserTwoFactorNotEnabled       = errors.New("Cannot disable two factor authentication if not enabled")
-	ErrUserUnblockPrevented          = errors.New("Cannot unblock a user that is blocked by LDAP synchronization")
+	ErrUserActivatePrevented   = errors.New("Cannot activate a user that is blocked by admin or by LDAP synchronization")
+	ErrUserApprovePrevented    = errors.New("Cannot approve a user that is blocked by admin or by LDAP synchronization")
+	ErrUserBlockPrevented      = errors.New("Cannot block a user that is already blocked by LDAP synchronization")
+	ErrUserConflict            = errors.New("User does not have a pending request")
+	ErrUserDeactivatePrevented = errors.New("Cannot deactivate a user that is blocked by admin or by LDAP synchronization")
+	ErrUserNotFound            = errors.New("User does not exist")
+	ErrUserRejectPrevented     = errors.New("Cannot reject a user if not authenticated as administrator")
+	ErrUserUnblockPrevented    = errors.New("Cannot unblock a user that is blocked by LDAP synchronization")
 )
 
 // UsersService handles communication with the user related methods of
@@ -1340,34 +1338,3 @@ func (s *UsersService) GetUserMemberships(user int, opt *GetUserMembershipOption
 
 	return m, resp, err
 }
-
-// DisableTwoFactor disables two factor authentication for the specified user.
-//
-// GitLab API docs:
-// https://docs.gitlab.com/ee/api/users.html#disable-two-factor-authentication
-func (s *UsersService) DisableTwoFactor(user int, options ...RequestOptionFunc) error {
-	u := fmt.Sprintf("users/%d/disable_two_factor", user)
-
-	req, err := s.client.NewRequest(http.MethodPatch, u, nil, options)
-	if err != nil {
-		return err
-	}
-
-	resp, err := s.client.Do(req, nil)
-	if err != nil && resp == nil {
-		return err
-	}
-
-	switch resp.StatusCode {
-	case 204:
-		return nil
-	case 400:
-		return ErrUserTwoFactorNotEnabled
-	case 403:
-		return ErrUserDisableTwoFactorPrevented
-	case 404:
-		return ErrUserNotFound
-	default:
-		return fmt.Errorf("Received unexpected result code: %d", resp.StatusCode)
-	}
-}


Test patch:
diff --git a/discussions_test.go b/discussions_test.go
index 81c4e4c..bb4214d 100644
--- a/discussions_test.go
+++ b/discussions_test.go
@@ -2245,7 +2245,7 @@ func TestDiscussionsService_ListCommitDiscussions(t *testing.T) {
 	mux, server, client := setup(t)
 	defer teardown(server)
 
-	mux.HandleFunc("/api/v4/projects/5/repository/commits/abc123/discussions", func(w http.ResponseWriter, r *http.Request) {
+	mux.HandleFunc("/api/v4/projects/5/repository/commits/11/discussions", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, http.MethodGet)
 		fmt.Fprintf(w, `
 			[
@@ -2327,22 +2327,22 @@ func TestDiscussionsService_ListCommitDiscussions(t *testing.T) {
 		}},
 	}}
 
-	ds, resp, err := client.Discussions.ListCommitDiscussions(5, "abc123", nil, nil)
+	ds, resp, err := client.Discussions.ListCommitDiscussions(5, 11, nil, nil)
 	require.NoError(t, err)
 	require.NotNil(t, resp)
 	require.Equal(t, want, ds)
 
-	ds, resp, err = client.Discussions.ListCommitDiscussions(5.01, "abc123", nil, nil)
+	ds, resp, err = client.Discussions.ListCommitDiscussions(5.01, 11, nil, nil)
 	require.EqualError(t, err, "invalid ID type 5.01, the ID must be an int or a string")
 	require.Nil(t, resp)
 	require.Nil(t, ds)
 
-	ds, resp, err = client.Discussions.ListCommitDiscussions(5, "abc123", nil, nil, errorOption)
+	ds, resp, err = client.Discussions.ListCommitDiscussions(5, 11, nil, nil, errorOption)
 	require.EqualError(t, err, "RequestOptionFunc returns an error")
 	require.Nil(t, resp)
 	require.Nil(t, ds)
 
-	ds, resp, err = client.Discussions.ListCommitDiscussions(3, "abc123", nil, nil)
+	ds, resp, err = client.Discussions.ListCommitDiscussions(3, 11, nil, nil)
 	require.Error(t, err)
 	require.Nil(t, ds)
 	require.Equal(t, http.StatusNotFound, resp.StatusCode)
@@ -2352,7 +2352,7 @@ func TestDiscussionsService_GetCommitDiscussion(t *testing.T) {
 	mux, server, client := setup(t)
 	defer teardown(server)
 
-	mux.HandleFunc("/api/v4/projects/5/repository/commits/abc123/discussions/6a9c1750b37d513a43987b574953fceb50b03ce7", func(w http.ResponseWriter, r *http.Request) {
+	mux.HandleFunc("/api/v4/projects/5/repository/commits/11/discussions/6a9c1750b37d513a43987b574953fceb50b03ce7", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, http.MethodGet)
 		fmt.Fprintf(w, `
 		  {
@@ -2432,22 +2432,22 @@ func TestDiscussionsService_GetCommitDiscussion(t *testing.T) {
 		}},
 	}
 
-	d, resp, err := client.Discussions.GetCommitDiscussion(5, "abc123", "6a9c1750b37d513a43987b574953fceb50b03ce7", nil, nil)
+	d, resp, err := client.Discussions.GetCommitDiscussion(5, 11, "6a9c1750b37d513a43987b574953fceb50b03ce7", nil, nil)
 	require.NoError(t, err)
 	require.NotNil(t, resp)
 	require.Equal(t, want, d)
 
-	d, resp, err = client.Discussions.GetCommitDiscussion(5.01, "abc123", "6a9c1750b37d513a43987b574953fceb50b03ce7", nil, nil)
+	d, resp, err = client.Discussions.GetCommitDiscussion(5.01, 11, "6a9c1750b37d513a43987b574953fceb50b03ce7", nil, nil)
 	require.EqualError(t, err, "invalid ID type 5.01, the ID must be an int or a string")
 	require.Nil(t, resp)
 	require.Nil(t, d)
 
-	d, resp, err = client.Discussions.GetCommitDiscussion(5, "abc123", "6a9c1750b37d513a43987b574953fceb50b03ce7", nil, nil, errorOption)
+	d, resp, err = client.Discussions.GetCommitDiscussion(5, 11, "6a9c1750b37d513a43987b574953fceb50b03ce7", nil, nil, errorOption)
 	require.EqualError(t, err, "RequestOptionFunc returns an error")
 	require.Nil(t, resp)
 	require.Nil(t, d)
 
-	d, resp, err = client.Discussions.GetCommitDiscussion(3, "abc123", "6a9c1750b37d513a43987b574953fceb50b03ce7", nil, nil)
+	d, resp, err = client.Discussions.GetCommitDiscussion(3, 11, "6a9c1750b37d513a43987b574953fceb50b03ce7", nil, nil)
 	require.Error(t, err)
 	require.Nil(t, d)
 	require.Equal(t, http.StatusNotFound, resp.StatusCode)
@@ -2457,7 +2457,7 @@ func TestDiscussionsService_CreateCommitDiscussion(t *testing.T) {
 	mux, server, client := setup(t)
 	defer teardown(server)
 
-	mux.HandleFunc("/api/v4/projects/5/repository/commits/abc123/discussions", func(w http.ResponseWriter, r *http.Request) {
+	mux.HandleFunc("/api/v4/projects/5/repository/commits/11/discussions", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, http.MethodPost)
 		fmt.Fprintf(w, `
 		  {
@@ -2537,22 +2537,22 @@ func TestDiscussionsService_CreateCommitDiscussion(t *testing.T) {
 		}},
 	}
 
-	d, resp, err := client.Discussions.CreateCommitDiscussion(5, "abc123", nil, nil)
+	d, resp, err := client.Discussions.CreateCommitDiscussion(5, 11, nil, nil)
 	require.NoError(t, err)
 	require.NotNil(t, resp)
 	require.Equal(t, want, d)
 
-	d, resp, err = client.Discussions.CreateCommitDiscussion(5.01, "abc123", nil, nil)
+	d, resp, err = client.Discussions.CreateCommitDiscussion(5.01, 11, nil, nil)
 	require.EqualError(t, err, "invalid ID type 5.01, the ID must be an int or a string")
 	require.Nil(t, resp)
 	require.Nil(t, d)
 
-	d, resp, err = client.Discussions.CreateCommitDiscussion(5, "abc123", nil, nil, errorOption)
+	d, resp, err = client.Discussions.CreateCommitDiscussion(5, 11, nil, nil, errorOption)
 	require.EqualError(t, err, "RequestOptionFunc returns an error")
 	require.Nil(t, resp)
 	require.Nil(t, d)
 
-	d, resp, err = client.Discussions.CreateCommitDiscussion(3, "abc123", nil, nil)
+	d, resp, err = client.Discussions.CreateCommitDiscussion(3, 11, nil, nil)
 	require.Error(t, err)
 	require.Nil(t, d)
 	require.Equal(t, http.StatusNotFound, resp.StatusCode)
@@ -2562,7 +2562,7 @@ func TestDiscussionsService_AddCommitDiscussionNote(t *testing.T) {
 	mux, server, client := setup(t)
 	defer teardown(server)
 
-	mux.HandleFunc("/api/v4/projects/5/repository/commits/abc123/discussions/6a9c1750b37d513a43987b574953fceb50b03ce7/notes", func(w http.ResponseWriter, r *http.Request) {
+	mux.HandleFunc("/api/v4/projects/5/repository/commits/11/discussions/6a9c1750b37d513a43987b574953fceb50b03ce7/notes", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, http.MethodPost)
 		fmt.Fprintf(w, `
 		  {
@@ -2632,22 +2632,22 @@ func TestDiscussionsService_AddCommitDiscussionNote(t *testing.T) {
 		NoteableIID: 377,
 	}
 
-	n, resp, err := client.Discussions.AddCommitDiscussionNote(5, "abc123", "6a9c1750b37d513a43987b574953fceb50b03ce7", nil, nil)
+	n, resp, err := client.Discussions.AddCommitDiscussionNote(5, 11, "6a9c1750b37d513a43987b574953fceb50b03ce7", nil, nil)
 	require.NoError(t, err)
 	require.NotNil(t, resp)
 	require.Equal(t, want, n)
 
-	n, resp, err = client.Discussions.AddCommitDiscussionNote(5.01, "abc123", "6a9c1750b37d513a43987b574953fceb50b03ce7", nil, nil)
+	n, resp, err = client.Discussions.AddCommitDiscussionNote(5.01, 11, "6a9c1750b37d513a43987b574953fceb50b03ce7", nil, nil)
 	require.EqualError(t, err, "invalid ID type 5.01, the ID must be an int or a string")
 	require.Nil(t, resp)
 	require.Nil(t, n)
 
-	n, resp, err = client.Discussions.AddCommitDiscussionNote(5, "abc123", "6a9c1750b37d513a43987b574953fceb50b03ce7", nil, nil, errorOption)
+	n, resp, err = client.Discussions.AddCommitDiscussionNote(5, 11, "6a9c1750b37d513a43987b574953fceb50b03ce7", nil, nil, errorOption)
 	require.EqualError(t, err, "RequestOptionFunc returns an error")
 	require.Nil(t, resp)
 	require.Nil(t, n)
 
-	n, resp, err = client.Discussions.AddCommitDiscussionNote(3, "abc123", "6a9c1750b37d513a43987b574953fceb50b03ce7", nil, nil)
+	n, resp, err = client.Discussions.AddCommitDiscussionNote(3, 11, "6a9c1750b37d513a43987b574953fceb50b03ce7", nil, nil)
 	require.Error(t, err)
 	require.Nil(t, n)
 	require.Equal(t, http.StatusNotFound, resp.StatusCode)
@@ -2657,7 +2657,7 @@ func TestDiscussionsService_UpdateCommitDiscussionNote(t *testing.T) {
 	mux, server, client := setup(t)
 	defer teardown(server)
 
-	mux.HandleFunc("/api/v4/projects/5/repository/commits/abc123/discussions/6a9c1750b37d513a43987b574953fceb50b03ce7/notes/302", func(w http.ResponseWriter, r *http.Request) {
+	mux.HandleFunc("/api/v4/projects/5/repository/commits/11/discussions/6a9c1750b37d513a43987b574953fceb50b03ce7/notes/302", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, http.MethodPut)
 		fmt.Fprintf(w, `
 		  {
@@ -2727,22 +2727,22 @@ func TestDiscussionsService_UpdateCommitDiscussionNote(t *testing.T) {
 		NoteableIID: 377,
 	}
 
-	n, resp, err := client.Discussions.UpdateCommitDiscussionNote(5, "abc123", "6a9c1750b37d513a43987b574953fceb50b03ce7", 302, nil, nil)
+	n, resp, err := client.Discussions.UpdateCommitDiscussionNote(5, 11, "6a9c1750b37d513a43987b574953fceb50b03ce7", 302, nil, nil)
 	require.NoError(t, err)
 	require.NotNil(t, resp)
 	require.Equal(t, want, n)
 
-	n, resp, err = client.Discussions.UpdateCommitDiscussionNote(5.01, "abc123", "6a9c1750b37d513a43987b574953fceb50b03ce7", 302, nil, nil)
+	n, resp, err = client.Discussions.UpdateCommitDiscussionNote(5.01, 11, "6a9c1750b37d513a43987b574953fceb50b03ce7", 302, nil, nil)
 	require.EqualError(t, err, "invalid ID type 5.01, the ID must be an int or a string")
 	require.Nil(t, resp)
 	require.Nil(t, n)
 
-	n, resp, err = client.Discussions.UpdateCommitDiscussionNote(5, "abc123", "6a9c1750b37d513a43987b574953fceb50b03ce7", 302, nil, nil, errorOption)
+	n, resp, err = client.Discussions.UpdateCommitDiscussionNote(5, 11, "6a9c1750b37d513a43987b574953fceb50b03ce7", 302, nil, nil, errorOption)
 	require.EqualError(t, err, "RequestOptionFunc returns an error")
 	require.Nil(t, resp)
 	require.Nil(t, n)
 
-	n, resp, err = client.Discussions.UpdateCommitDiscussionNote(3, "abc123", "6a9c1750b37d513a43987b574953fceb50b03ce7", 302, nil, nil)
+	n, resp, err = client.Discussions.UpdateCommitDiscussionNote(3, 11, "6a9c1750b37d513a43987b574953fceb50b03ce7", 302, nil, nil)
 	require.Error(t, err)
 	require.Nil(t, n)
 	require.Equal(t, http.StatusNotFound, resp.StatusCode)
@@ -2752,23 +2752,23 @@ func TestDiscussionsService_DeleteCommitDiscussionNote(t *testing.T) {
 	mux, server, client := setup(t)
 	defer teardown(server)
 
-	mux.HandleFunc("/api/v4/projects/5/repository/commits/abc123/discussions/6a9c1750b37d513a43987b574953fceb50b03ce7/notes/302", func(w http.ResponseWriter, r *http.Request) {
+	mux.HandleFunc("/api/v4/projects/5/repository/commits/11/discussions/6a9c1750b37d513a43987b574953fceb50b03ce7/notes/302", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, http.MethodDelete)
 	})
 
-	resp, err := client.Discussions.DeleteCommitDiscussionNote(5, "abc123", "6a9c1750b37d513a43987b574953fceb50b03ce7", 302, nil, nil)
+	resp, err := client.Discussions.DeleteCommitDiscussionNote(5, 11, "6a9c1750b37d513a43987b574953fceb50b03ce7", 302, nil, nil)
 	require.NoError(t, err)
 	require.NotNil(t, resp)
 
-	resp, err = client.Discussions.DeleteCommitDiscussionNote(5.01, "abc123", "6a9c1750b37d513a43987b574953fceb50b03ce7", 302, nil, nil)
+	resp, err = client.Discussions.DeleteCommitDiscussionNote(5.01, 11, "6a9c1750b37d513a43987b574953fceb50b03ce7", 302, nil, nil)
 	require.EqualError(t, err, "invalid ID type 5.01, the ID must be an int or a string")
 	require.Nil(t, resp)
 
-	resp, err = client.Discussions.DeleteCommitDiscussionNote(5, "abc123", "6a9c1750b37d513a43987b574953fceb50b03ce7", 302, nil, nil, errorOption)
+	resp, err = client.Discussions.DeleteCommitDiscussionNote(5, 11, "6a9c1750b37d513a43987b574953fceb50b03ce7", 302, nil, nil, errorOption)
 	require.EqualError(t, err, "RequestOptionFunc returns an error")
 	require.Nil(t, resp)
 
-	resp, err = client.Discussions.DeleteCommitDiscussionNote(3, "abc123", "6a9c1750b37d513a43987b574953fceb50b03ce7", 302, nil, nil)
+	resp, err = client.Discussions.DeleteCommitDiscussionNote(3, 11, "6a9c1750b37d513a43987b574953fceb50b03ce7", 302, nil, nil)
 	require.Error(t, err)
 	require.Equal(t, http.StatusNotFound, resp.StatusCode)
 }
diff --git a/event_webhook_types_test.go b/event_webhook_types_test.go
index e01ff40..7c2d67b 100644
--- a/event_webhook_types_test.go
+++ b/event_webhook_types_test.go
@@ -92,10 +92,6 @@ func TestDeploymentEventUnmarshal(t *testing.T) {
 	if event.CommitTitle != "Add new file" {
 		t.Errorf("CommitTitle is %s, want %s", event.CommitTitle, "Add new file")
 	}
-
-	if event.Ref != "1.0.0" {
-		t.Errorf("Ref is %s, want %s", event.Ref, "1.0.0")
-	}
 }
 
 func TestIssueCommentEventUnmarshal(t *testing.T) {
diff --git a/issue_links_test.go b/issue_links_test.go
index 6823312..dcad1be 100644
--- a/issue_links_test.go
+++ b/issue_links_test.go
@@ -19,7 +19,6 @@ func TestIssueLinksService_ListIssueRelations(t *testing.T) {
 			  {
 				"id" : 84,
 				"iid" : 14,
-				"confidential": false,
 				"issue_link_id": 1,
 				"project_id" : 4,
 				"title" : "Issues with auth",
@@ -50,30 +49,35 @@ func TestIssueLinksService_ListIssueRelations(t *testing.T) {
 		`)
 	})
 
-	want := []*IssueRelation{{
-		ID:           84,
-		IID:          14,
-		State:        "opened",
-		Description:  "",
-		Confidential: false,
+	want := []*Issue{{
+		ID:          84,
+		IID:         14,
+		ExternalID:  "",
+		State:       "opened",
+		Description: "",
 		Author: &IssueAuthor{
 			ID:        18,
 			State:     "active",
 			WebURL:    "https://gitlab.example.com/eileen.lowe",
 			Name:      "Venkatesh Thalluri",
 			AvatarURL: "",
-			Username:  "venkatesh.thalluri",
-		},
-		Milestone:   nil,
-		ProjectID:   4,
-		Assignees:   []*IssueAssignee{},
-		Assignee:    nil,
-		Title:       "Issues with auth",
-		Labels:      []string{"bug"},
-		WebURL:      "http://example.com/example/example/issues/14",
-		Weight:      0,
-		IssueLinkID: 1,
-		LinkType:    "relates_to",
+			Username:  "venkatesh.thalluri"},
+		ProjectID:         4,
+		Assignees:         []*IssueAssignee{},
+		Title:             "Issues with auth",
+		MovedToID:         0,
+		Labels:            []string{"bug"},
+		Upvotes:           0,
+		Downvotes:         0,
+		WebURL:            "http://example.com/example/example/issues/14",
+		Confidential:      false,
+		Weight:            0,
+		DiscussionLocked:  false,
+		Subscribed:        false,
+		UserNotesCount:    0,
+		IssueLinkID:       1,
+		MergeRequestCount: 0,
+		EpicIssueID:       0,
 	}}
 
 	is, resp, err := client.IssueLinks.ListIssueRelations(4, 14, nil)
diff --git a/resource_weight_events_test.go b/resource_weight_events_test.go
new file mode 100644
index 0000000..41ac3ca
--- /dev/null
+++ b/resource_weight_events_test.go
@@ -0,0 +1,56 @@
+package gitlab
+
+import (
+	"fmt"
+	"net/http"
+	"testing"
+	"time"
+
+	"github.com/stretchr/testify/require"
+)
+
+func TestResourceWeightEventsService_ListIssueWightEvents(t *testing.T) {
+	mux, server, client := setup(t)
+	defer teardown(server)
+
+	mux.HandleFunc("/api/v4/projects/5/issues/11/resource_weight_events", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, http.MethodGet)
+		fmt.Fprintf(w, `[
+			{
+			  "id": 142,
+			  "user": {
+				"id": 1,
+				"name": "Administrator",
+				"username": "root",
+				"state": "active",
+				"avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
+				"web_url": "http://gitlab.example.com/root"
+			  },
+			  "created_at": "2018-08-20T13:38:20.077Z",
+			  "issue_id": 253,
+			  "weight": 3
+			}
+		]`)
+	})
+
+	opt := &ListWeightEventsOptions{ListOptions{Page: 1, PerPage: 10}}
+
+	wes, _, err := client.ResourceWeightEvents.ListIssueWeightEvents(5, 11, opt)
+	require.NoError(t, err)
+
+	want := []*WeightEvent{{
+		ID: 142,
+		User: &BasicUser{
+			ID:        1,
+			Username:  "root",
+			Name:      "Administrator",
+			State:     "active",
+			AvatarURL: "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
+			WebURL:    "http://gitlab.example.com/root",
+		},
+		CreatedAt: Time(time.Date(2018, time.August, 20, 13, 38, 20, 77000000, time.UTC)),
+		IssueID:   253,
+		Weight:    3,
+	}}
+	require.Equal(t, want, wes)
+}
diff --git a/testdata/webhooks/deployment.json b/testdata/webhooks/deployment.json
index ce3c131..3ab09fd 100644
--- a/testdata/webhooks/deployment.json
+++ b/testdata/webhooks/deployment.json
@@ -32,6 +32,5 @@
   },
   "user_url": "http://10.126.0.2:3000/root",
   "commit_url": "http://10.126.0.2:3000/root/test-deployment-webhooks/-/commit/279484c09fbe69ededfced8c1bb6e6d24616b468",
-  "commit_title": "Add new file",
-  "ref": "1.0.0"
+  "commit_title": "Add new file"
 }
diff --git a/users_test.go b/users_test.go
index 380255b..3a388e0 100644
--- a/users_test.go
+++ b/users_test.go
@@ -649,19 +649,3 @@ func TestGetSingleSSHKeyForUser(t *testing.T) {
 		t.Errorf("Users.GetSSHKeyForUser returned %+v, want %+v", sshKey, want)
 	}
 }
-
-func TestDisableUser2FA(t *testing.T) {
-	mux, server, client := setup(t)
-	defer teardown(server)
-
-	path := fmt.Sprintf("/%susers/1/disable_two_factor", apiVersionPath)
-	mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
-		testMethod(t, r, http.MethodPatch)
-		w.WriteHeader(http.StatusNoContent)
-	})
-
-	err := client.Users.DisableTwoFactor(1)
-	if err != nil {
-		t.Errorf("Users.DisableTwoFactor returned error: %v", err)
-	}
-}