diff --git a/go.mod b/go.mod
index 070ab65325..27e89fae3c 100644
--- a/go.mod
+++ b/go.mod
@@ -5,7 +5,7 @@ go 1.16
 require (
 	cloud.google.com/go v0.78.0 // indirect
 	code.gitea.io/gitea-vet v0.2.1
-	code.gitea.io/sdk/gitea v0.14.0
+	code.gitea.io/sdk/gitea v0.15.1
 	gitea.com/go-chi/binding v0.0.0-20211013065440-d16dc407c2be
 	gitea.com/go-chi/cache v0.0.0-20211013020926-78790b11abf1
 	gitea.com/go-chi/captcha v0.0.0-20211013065431-70641c1a35d5
diff --git a/go.sum b/go.sum
index c9c37e70c0..fd1105627e 100644
--- a/go.sum
+++ b/go.sum
@@ -38,8 +38,8 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX
 cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
 code.gitea.io/gitea-vet v0.2.1 h1:b30by7+3SkmiftK0RjuXqFvZg2q4p68uoPGuxhzBN0s=
 code.gitea.io/gitea-vet v0.2.1/go.mod h1:zcNbT/aJEmivCAhfmkHOlT645KNOf9W2KnkLgFjGGfE=
-code.gitea.io/sdk/gitea v0.14.0 h1:m4J352I3p9+bmJUfS+g0odeQzBY/5OXP91Gv6D4fnJ0=
-code.gitea.io/sdk/gitea v0.14.0/go.mod h1:89WiyOX1KEcvjP66sRHdu0RafojGo60bT9UqW17VbWs=
+code.gitea.io/sdk/gitea v0.15.1 h1:WJreC7YYuxbn0UDaPuWIe/mtiNKTvLN8MLkaw71yx/M=
+code.gitea.io/sdk/gitea v0.15.1/go.mod h1:klY2LVI3s3NChzIk/MzMn7G1FHrfU7qd63iSMVoHRBA=
 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
 gitea.com/go-chi/binding v0.0.0-20211013065440-d16dc407c2be h1:IzSwPVzd2hE6e67ujY8ReBCrQ5IFNd0uiBmC7Ux5IaY=
 gitea.com/go-chi/binding v0.0.0-20211013065440-d16dc407c2be/go.mod h1:/vR0YjlusOYvosKYW7QKcSnrY0nPLe4RQ/DGi3+i/Do=
diff --git a/vendor/code.gitea.io/sdk/gitea/admin_user.go b/vendor/code.gitea.io/sdk/gitea/admin_user.go
index 161dc6058d..172f0645c9 100644
--- a/vendor/code.gitea.io/sdk/gitea/admin_user.go
+++ b/vendor/code.gitea.io/sdk/gitea/admin_user.go
@@ -26,14 +26,15 @@ func (c *Client) AdminListUsers(opt AdminListUsersOptions) ([]*User, *Response,
 
 // CreateUserOption create user options
 type CreateUserOption struct {
-	SourceID           int64  `json:"source_id"`
-	LoginName          string `json:"login_name"`
-	Username           string `json:"username"`
-	FullName           string `json:"full_name"`
-	Email              string `json:"email"`
-	Password           string `json:"password"`
-	MustChangePassword *bool  `json:"must_change_password"`
-	SendNotify         bool   `json:"send_notify"`
+	SourceID           int64        `json:"source_id"`
+	LoginName          string       `json:"login_name"`
+	Username           string       `json:"username"`
+	FullName           string       `json:"full_name"`
+	Email              string       `json:"email"`
+	Password           string       `json:"password"`
+	MustChangePassword *bool        `json:"must_change_password"`
+	SendNotify         bool         `json:"send_notify"`
+	Visibility         *VisibleType `json:"visibility"`
 }
 
 // Validate the CreateUserOption struct
@@ -63,21 +64,24 @@ func (c *Client) AdminCreateUser(opt CreateUserOption) (*User, *Response, error)
 
 // EditUserOption edit user options
 type EditUserOption struct {
-	SourceID                int64   `json:"source_id"`
-	LoginName               string  `json:"login_name"`
-	Email                   *string `json:"email"`
-	FullName                *string `json:"full_name"`
-	Password                string  `json:"password"`
-	MustChangePassword      *bool   `json:"must_change_password"`
-	Website                 *string `json:"website"`
-	Location                *string `json:"location"`
-	Active                  *bool   `json:"active"`
-	Admin                   *bool   `json:"admin"`
-	AllowGitHook            *bool   `json:"allow_git_hook"`
-	AllowImportLocal        *bool   `json:"allow_import_local"`
-	MaxRepoCreation         *int    `json:"max_repo_creation"`
-	ProhibitLogin           *bool   `json:"prohibit_login"`
-	AllowCreateOrganization *bool   `json:"allow_create_organization"`
+	SourceID                int64        `json:"source_id"`
+	LoginName               string       `json:"login_name"`
+	Email                   *string      `json:"email"`
+	FullName                *string      `json:"full_name"`
+	Password                string       `json:"password"`
+	Description             *string      `json:"description"`
+	MustChangePassword      *bool        `json:"must_change_password"`
+	Website                 *string      `json:"website"`
+	Location                *string      `json:"location"`
+	Active                  *bool        `json:"active"`
+	Admin                   *bool        `json:"admin"`
+	AllowGitHook            *bool        `json:"allow_git_hook"`
+	AllowImportLocal        *bool        `json:"allow_import_local"`
+	MaxRepoCreation         *int         `json:"max_repo_creation"`
+	ProhibitLogin           *bool        `json:"prohibit_login"`
+	AllowCreateOrganization *bool        `json:"allow_create_organization"`
+	Restricted              *bool        `json:"restricted"`
+	Visibility              *VisibleType `json:"visibility"`
 }
 
 // AdminEditUser modify user informations
diff --git a/vendor/code.gitea.io/sdk/gitea/client.go b/vendor/code.gitea.io/sdk/gitea/client.go
index 9f857f85ae..3fe3e8bd77 100644
--- a/vendor/code.gitea.io/sdk/gitea/client.go
+++ b/vendor/code.gitea.io/sdk/gitea/client.go
@@ -24,23 +24,25 @@ var jsonHeader = http.Header{"content-type": []string{"application/json"}}
 
 // Version return the library version
 func Version() string {
-	return "0.14.0"
+	return "0.15.1"
 }
 
 // Client represents a thread-safe Gitea API client.
 type Client struct {
-	url            string
-	accessToken    string
-	username       string
-	password       string
-	otp            string
-	sudo           string
-	debug          bool
-	client         *http.Client
-	ctx            context.Context
-	mutex          sync.RWMutex
+	url         string
+	accessToken string
+	username    string
+	password    string
+	otp         string
+	sudo        string
+	debug       bool
+	client      *http.Client
+	ctx         context.Context
+	mutex       sync.RWMutex
+
 	serverVersion  *version.Version
 	getVersionOnce sync.Once
+	ignoreVersion  bool // only set by SetGiteaVersion so don't need a mutex lock
 }
 
 // Response represents the gitea response
@@ -48,16 +50,21 @@ type Response struct {
 	*http.Response
 }
 
+// ClientOption are functions used to init a new client
+type ClientOption func(*Client) error
+
 // NewClient initializes and returns a API client.
 // Usage of all gitea.Client methods is concurrency-safe.
-func NewClient(url string, options ...func(*Client)) (*Client, error) {
+func NewClient(url string, options ...ClientOption) (*Client, error) {
 	client := &Client{
 		url:    strings.TrimSuffix(url, "/"),
 		client: &http.Client{},
 		ctx:    context.Background(),
 	}
 	for _, opt := range options {
-		opt(client)
+		if err := opt(client); err != nil {
+			return nil, err
+		}
 	}
 	if err := client.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil {
 		return nil, err
@@ -73,9 +80,10 @@ func NewClientWithHTTP(url string, httpClient *http.Client) *Client {
 }
 
 // SetHTTPClient is an option for NewClient to set custom http client
-func SetHTTPClient(httpClient *http.Client) func(client *Client) {
-	return func(client *Client) {
+func SetHTTPClient(httpClient *http.Client) ClientOption {
+	return func(client *Client) error {
 		client.SetHTTPClient(httpClient)
+		return nil
 	}
 }
 
@@ -87,18 +95,20 @@ func (c *Client) SetHTTPClient(client *http.Client) {
 }
 
 // SetToken is an option for NewClient to set token
-func SetToken(token string) func(client *Client) {
-	return func(client *Client) {
+func SetToken(token string) ClientOption {
+	return func(client *Client) error {
 		client.mutex.Lock()
 		client.accessToken = token
 		client.mutex.Unlock()
+		return nil
 	}
 }
 
 // SetBasicAuth is an option for NewClient to set username and password
-func SetBasicAuth(username, password string) func(client *Client) {
-	return func(client *Client) {
+func SetBasicAuth(username, password string) ClientOption {
+	return func(client *Client) error {
 		client.SetBasicAuth(username, password)
+		return nil
 	}
 }
 
@@ -110,9 +120,10 @@ func (c *Client) SetBasicAuth(username, password string) {
 }
 
 // SetOTP is an option for NewClient to set OTP for 2FA
-func SetOTP(otp string) func(client *Client) {
-	return func(client *Client) {
+func SetOTP(otp string) ClientOption {
+	return func(client *Client) error {
 		client.SetOTP(otp)
+		return nil
 	}
 }
 
@@ -123,14 +134,15 @@ func (c *Client) SetOTP(otp string) {
 	c.mutex.Unlock()
 }
 
-// SetContext is an option for NewClient to set context
-func SetContext(ctx context.Context) func(client *Client) {
-	return func(client *Client) {
+// SetContext is an option for NewClient to set the default context
+func SetContext(ctx context.Context) ClientOption {
+	return func(client *Client) error {
 		client.SetContext(ctx)
+		return nil
 	}
 }
 
-// SetContext set context witch is used for http requests
+// SetContext set default context witch is used for http requests
 func (c *Client) SetContext(ctx context.Context) {
 	c.mutex.Lock()
 	c.ctx = ctx
@@ -138,9 +150,10 @@ func (c *Client) SetContext(ctx context.Context) {
 }
 
 // SetSudo is an option for NewClient to set sudo header
-func SetSudo(sudo string) func(client *Client) {
-	return func(client *Client) {
+func SetSudo(sudo string) ClientOption {
+	return func(client *Client) error {
 		client.SetSudo(sudo)
+		return nil
 	}
 }
 
@@ -152,11 +165,12 @@ func (c *Client) SetSudo(sudo string) {
 }
 
 // SetDebugMode is an option for NewClient to enable debug mode
-func SetDebugMode() func(client *Client) {
-	return func(client *Client) {
+func SetDebugMode() ClientOption {
+	return func(client *Client) error {
 		client.mutex.Lock()
 		client.debug = true
 		client.mutex.Unlock()
+		return nil
 	}
 }
 
diff --git a/vendor/code.gitea.io/sdk/gitea/go.mod b/vendor/code.gitea.io/sdk/gitea/go.mod
index ac2a262ab3..7141bfa474 100644
--- a/vendor/code.gitea.io/sdk/gitea/go.mod
+++ b/vendor/code.gitea.io/sdk/gitea/go.mod
@@ -3,6 +3,7 @@ module code.gitea.io/sdk/gitea
 go 1.13
 
 require (
+	code.gitea.io/gitea-vet v0.2.1 // indirect
 	github.com/hashicorp/go-version v1.2.1
 	github.com/stretchr/testify v1.4.0
 )
diff --git a/vendor/code.gitea.io/sdk/gitea/go.sum b/vendor/code.gitea.io/sdk/gitea/go.sum
index 82997d0cce..833e39100e 100644
--- a/vendor/code.gitea.io/sdk/gitea/go.sum
+++ b/vendor/code.gitea.io/sdk/gitea/go.sum
@@ -1,7 +1,7 @@
+code.gitea.io/gitea-vet v0.2.1 h1:b30by7+3SkmiftK0RjuXqFvZg2q4p68uoPGuxhzBN0s=
+code.gitea.io/gitea-vet v0.2.1/go.mod h1:zcNbT/aJEmivCAhfmkHOlT645KNOf9W2KnkLgFjGGfE=
 github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/hashicorp/go-version v1.2.0 h1:3vNe/fWF5CBgRIguda1meWhsZHy3m8gCJ5wx+dIzX/E=
-github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
 github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI=
 github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@@ -9,6 +9,24 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20200325010219-a49f79bcc224 h1:azwY/v0y0K4mFHVsg5+UrTgchqALYWpqVo6vL5OmkmI=
+golang.org/x/tools v0.0.0-20200325010219-a49f79bcc224/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
diff --git a/vendor/code.gitea.io/sdk/gitea/hook.go b/vendor/code.gitea.io/sdk/gitea/hook.go
index af4154e2ab..67a7518b68 100644
--- a/vendor/code.gitea.io/sdk/gitea/hook.go
+++ b/vendor/code.gitea.io/sdk/gitea/hook.go
@@ -24,6 +24,28 @@ type Hook struct {
 	Created time.Time         `json:"created_at"`
 }
 
+// HookType represent all webhook types gitea currently offer
+type HookType string
+
+const (
+	// HookTypeDingtalk webhook that dingtalk understand
+	HookTypeDingtalk HookType = "dingtalk"
+	// HookTypeDiscord webhook that discord understand
+	HookTypeDiscord HookType = "discord"
+	// HookTypeGitea webhook that gitea understand
+	HookTypeGitea HookType = "gitea"
+	// HookTypeGogs webhook that gogs understand
+	HookTypeGogs HookType = "gogs"
+	// HookTypeMsteams webhook that msteams understand
+	HookTypeMsteams HookType = "msteams"
+	// HookTypeSlack webhook that slack understand
+	HookTypeSlack HookType = "slack"
+	// HookTypeTelegram webhook that telegram understand
+	HookTypeTelegram HookType = "telegram"
+	// HookTypeFeishu webhook that feishu understand
+	HookTypeFeishu HookType = "feishu"
+)
+
 // ListHooksOptions options for listing hooks
 type ListHooksOptions struct {
 	ListOptions
@@ -73,7 +95,7 @@ func (c *Client) GetRepoHook(user, repo string, id int64) (*Hook, *Response, err
 
 // CreateHookOption options when create a hook
 type CreateHookOption struct {
-	Type         string            `json:"type"`
+	Type         HookType          `json:"type"`
 	Config       map[string]string `json:"config"`
 	Events       []string          `json:"events"`
 	BranchFilter string            `json:"branch_filter"`
diff --git a/vendor/code.gitea.io/sdk/gitea/issue.go b/vendor/code.gitea.io/sdk/gitea/issue.go
index 688924634b..c33856a4da 100644
--- a/vendor/code.gitea.io/sdk/gitea/issue.go
+++ b/vendor/code.gitea.io/sdk/gitea/issue.go
@@ -42,10 +42,7 @@ type Issue struct {
 	Ref              string     `json:"ref"`
 	Labels           []*Label   `json:"labels"`
 	Milestone        *Milestone `json:"milestone"`
-	// deprecated
-	// TODO: rm on sdk 0.15.0
-	Assignee  *User   `json:"assignee"`
-	Assignees []*User `json:"assignees"`
+	Assignees        []*User    `json:"assignees"`
 	// Whether the issue is open or closed
 	State       StateType        `json:"state"`
 	IsLocked    bool             `json:"is_locked"`
@@ -66,6 +63,14 @@ type ListIssueOption struct {
 	Labels     []string
 	Milestones []string
 	KeyWord    string
+	Since      time.Time
+	Before     time.Time
+	// filter by created by username
+	CreatedBy string
+	// filter by assigned to username
+	AssignedBy string
+	// filter by username mentioned
+	MentionedBy string
 }
 
 // StateType issue state type
@@ -114,6 +119,23 @@ func (opt *ListIssueOption) QueryEncode() string {
 		query.Add("milestones", strings.Join(opt.Milestones, ","))
 	}
 
+	if !opt.Since.IsZero() {
+		query.Add("since", opt.Since.Format(time.RFC3339))
+	}
+	if !opt.Before.IsZero() {
+		query.Add("before", opt.Before.Format(time.RFC3339))
+	}
+
+	if len(opt.CreatedBy) > 0 {
+		query.Add("created_by", opt.CreatedBy)
+	}
+	if len(opt.AssignedBy) > 0 {
+		query.Add("assigned_by", opt.AssignedBy)
+	}
+	if len(opt.MentionedBy) > 0 {
+		query.Add("mentioned_by", opt.MentionedBy)
+	}
+
 	return query.Encode()
 }
 
@@ -178,12 +200,9 @@ func (c *Client) GetIssue(owner, repo string, index int64) (*Issue, *Response, e
 
 // CreateIssueOption options to create one issue
 type CreateIssueOption struct {
-	Title string `json:"title"`
-	Body  string `json:"body"`
-	Ref   string `json:"ref"`
-	// deprecated
-	// TODO: rm on sdk 0.15.0
-	Assignee  string     `json:"assignee"`
+	Title     string     `json:"title"`
+	Body      string     `json:"body"`
+	Ref       string     `json:"ref"`
 	Assignees []string   `json:"assignees"`
 	Deadline  *time.Time `json:"due_date"`
 	// milestone id
@@ -222,12 +241,9 @@ func (c *Client) CreateIssue(owner, repo string, opt CreateIssueOption) (*Issue,
 
 // EditIssueOption options for editing an issue
 type EditIssueOption struct {
-	Title string  `json:"title"`
-	Body  *string `json:"body"`
-	Ref   *string `json:"ref"`
-	// deprecated
-	// TODO: rm on sdk 0.15.0
-	Assignee       *string    `json:"assignee"`
+	Title          string     `json:"title"`
+	Body           *string    `json:"body"`
+	Ref            *string    `json:"ref"`
 	Assignees      []string   `json:"assignees"`
 	Milestone      *int64     `json:"milestone"`
 	State          *StateType `json:"state"`
diff --git a/vendor/code.gitea.io/sdk/gitea/issue_milestone.go b/vendor/code.gitea.io/sdk/gitea/issue_milestone.go
index a865a45839..dfb5720a0c 100644
--- a/vendor/code.gitea.io/sdk/gitea/issue_milestone.go
+++ b/vendor/code.gitea.io/sdk/gitea/issue_milestone.go
@@ -73,7 +73,7 @@ func (c *Client) GetMilestone(owner, repo string, id int64) (*Milestone, *Respon
 
 // GetMilestoneByName get one milestone by repo and milestone name
 func (c *Client) GetMilestoneByName(owner, repo string, name string) (*Milestone, *Response, error) {
-	if c.CheckServerVersionConstraint(">=1.13") != nil {
+	if c.checkServerVersionGreaterThanOrEqual(version1_13_0) != nil {
 		// backwards compatibility mode
 		m, resp, err := c.resolveMilestoneByName(owner, repo, name)
 		return m, resp, err
@@ -164,7 +164,7 @@ func (c *Client) EditMilestone(owner, repo string, id int64, opt EditMilestoneOp
 
 // EditMilestoneByName modify milestone with options
 func (c *Client) EditMilestoneByName(owner, repo string, name string, opt EditMilestoneOption) (*Milestone, *Response, error) {
-	if c.CheckServerVersionConstraint(">=1.13") != nil {
+	if c.checkServerVersionGreaterThanOrEqual(version1_13_0) != nil {
 		// backwards compatibility mode
 		m, _, err := c.resolveMilestoneByName(owner, repo, name)
 		if err != nil {
@@ -198,7 +198,7 @@ func (c *Client) DeleteMilestone(owner, repo string, id int64) (*Response, error
 
 // DeleteMilestoneByName delete one milestone by name
 func (c *Client) DeleteMilestoneByName(owner, repo string, name string) (*Response, error) {
-	if c.CheckServerVersionConstraint(">=1.13") != nil {
+	if c.checkServerVersionGreaterThanOrEqual(version1_13_0) != nil {
 		// backwards compatibility mode
 		m, _, err := c.resolveMilestoneByName(owner, repo, name)
 		if err != nil {
diff --git a/vendor/code.gitea.io/sdk/gitea/list_options.go b/vendor/code.gitea.io/sdk/gitea/list_options.go
index d56c651b34..6f3ffb2313 100644
--- a/vendor/code.gitea.io/sdk/gitea/list_options.go
+++ b/vendor/code.gitea.io/sdk/gitea/list_options.go
@@ -26,8 +26,13 @@ func (o ListOptions) getURLQuery() url.Values {
 	return query
 }
 
-func (o ListOptions) setDefaults() {
-	if o.Page < 1 {
+// setDefaults set default pagination options if none or wrong are set
+// if you set -1 as page it will set all to 0
+func (o *ListOptions) setDefaults() {
+	if o.Page < 0 {
+		o.Page, o.PageSize = 0, 0
+		return
+	} else if o.Page == 0 {
 		o.Page = 1
 	}
 
diff --git a/vendor/code.gitea.io/sdk/gitea/notifications.go b/vendor/code.gitea.io/sdk/gitea/notifications.go
index de53e2ce99..8b1ffa7ba2 100644
--- a/vendor/code.gitea.io/sdk/gitea/notifications.go
+++ b/vendor/code.gitea.io/sdk/gitea/notifications.go
@@ -29,11 +29,11 @@ type NotificationThread struct {
 
 // NotificationSubject contains the notification subject (Issue/Pull/Commit)
 type NotificationSubject struct {
-	Title            string    `json:"title"`
-	URL              string    `json:"url"`
-	LatestCommentURL string    `json:"latest_comment_url"`
-	Type             string    `json:"type"`
-	State            StateType `json:"state"`
+	Title            string             `json:"title"`
+	URL              string             `json:"url"`
+	LatestCommentURL string             `json:"latest_comment_url"`
+	Type             NotifySubjectType  `json:"type"`
+	State            NotifySubjectState `json:"state"`
 }
 
 // NotifyStatus notification status type
@@ -48,12 +48,39 @@ const (
 	NotifyStatusPinned NotifyStatus = "pinned"
 )
 
+// NotifySubjectType represent type of notification subject
+type NotifySubjectType string
+
+const (
+	// NotifySubjectIssue an issue is subject of an notification
+	NotifySubjectIssue NotifySubjectType = "Issue"
+	// NotifySubjectPull an pull is subject of an notification
+	NotifySubjectPull NotifySubjectType = "Pull"
+	// NotifySubjectCommit an commit is subject of an notification
+	NotifySubjectCommit NotifySubjectType = "Commit"
+	// NotifySubjectRepository an repository is subject of an notification
+	NotifySubjectRepository NotifySubjectType = "Repository"
+)
+
+// NotifySubjectState reflect state of notification subject
+type NotifySubjectState string
+
+const (
+	// NotifySubjectOpen if subject is a pull/issue and is open at the moment
+	NotifySubjectOpen NotifySubjectState = "open"
+	// NotifySubjectClosed if subject is a pull/issue and is closed at the moment
+	NotifySubjectClosed NotifySubjectState = "closed"
+	// NotifySubjectMerged if subject is a pull and got merged
+	NotifySubjectMerged NotifySubjectState = "merged"
+)
+
 // ListNotificationOptions represents the filter options
 type ListNotificationOptions struct {
 	ListOptions
-	Since  time.Time
-	Before time.Time
-	Status []NotifyStatus
+	Since        time.Time
+	Before       time.Time
+	Status       []NotifyStatus
+	SubjectTypes []NotifySubjectType
 }
 
 // MarkNotificationOptions represents the filter & modify options
@@ -75,6 +102,9 @@ func (opt *ListNotificationOptions) QueryEncode() string {
 	for _, s := range opt.Status {
 		query.Add("status-types", string(s))
 	}
+	for _, s := range opt.SubjectTypes {
+		query.Add("subject-type", string(s))
+	}
 	return query.Encode()
 }
 
diff --git a/vendor/code.gitea.io/sdk/gitea/org.go b/vendor/code.gitea.io/sdk/gitea/org.go
index b7c439bc4f..82e1bf540d 100644
--- a/vendor/code.gitea.io/sdk/gitea/org.go
+++ b/vendor/code.gitea.io/sdk/gitea/org.go
@@ -73,12 +73,13 @@ func (c *Client) GetOrg(orgname string) (*Organization, *Response, error) {
 
 // CreateOrgOption options for creating an organization
 type CreateOrgOption struct {
-	Name        string      `json:"username"`
-	FullName    string      `json:"full_name"`
-	Description string      `json:"description"`
-	Website     string      `json:"website"`
-	Location    string      `json:"location"`
-	Visibility  VisibleType `json:"visibility"`
+	Name                      string      `json:"username"`
+	FullName                  string      `json:"full_name"`
+	Description               string      `json:"description"`
+	Website                   string      `json:"website"`
+	Location                  string      `json:"location"`
+	Visibility                VisibleType `json:"visibility"`
+	RepoAdminChangeTeamAccess bool        `json:"repo_admin_change_team_access"`
 }
 
 // checkVisibilityOpt check if mode exist
diff --git a/vendor/code.gitea.io/sdk/gitea/org_team.go b/vendor/code.gitea.io/sdk/gitea/org_team.go
index 0373c6ed2d..4b1b27b4b7 100644
--- a/vendor/code.gitea.io/sdk/gitea/org_team.go
+++ b/vendor/code.gitea.io/sdk/gitea/org_team.go
@@ -12,17 +12,38 @@ import (
 
 // Team represents a team in an organization
 type Team struct {
-	ID                      int64         `json:"id"`
-	Name                    string        `json:"name"`
-	Description             string        `json:"description"`
-	Organization            *Organization `json:"organization"`
-	Permission              AccessMode    `json:"permission"`
-	CanCreateOrgRepo        bool          `json:"can_create_org_repo"`
-	IncludesAllRepositories bool          `json:"includes_all_repositories"`
-	// example: ["repo.code","repo.issues","repo.ext_issues","repo.wiki","repo.pulls","repo.releases","repo.ext_wiki"]
-	Units []string `json:"units"`
+	ID                      int64          `json:"id"`
+	Name                    string         `json:"name"`
+	Description             string         `json:"description"`
+	Organization            *Organization  `json:"organization"`
+	Permission              AccessMode     `json:"permission"`
+	CanCreateOrgRepo        bool           `json:"can_create_org_repo"`
+	IncludesAllRepositories bool           `json:"includes_all_repositories"`
+	Units                   []RepoUnitType `json:"units"`
 }
 
+// RepoUnitType represent all unit types of a repo gitea currently offer
+type RepoUnitType string
+
+const (
+	// RepoUnitCode represent file view of a repository
+	RepoUnitCode RepoUnitType = "repo.code"
+	// RepoUnitIssues represent issues of a repository
+	RepoUnitIssues RepoUnitType = "repo.issues"
+	// RepoUnitPulls represent pulls of a repository
+	RepoUnitPulls RepoUnitType = "repo.pulls"
+	// RepoUnitExtIssues represent external issues of a repository
+	RepoUnitExtIssues RepoUnitType = "repo.ext_issues"
+	// RepoUnitWiki represent wiki of a repository
+	RepoUnitWiki RepoUnitType = "repo.wiki"
+	// RepoUnitExtWiki represent external wiki of a repository
+	RepoUnitExtWiki RepoUnitType = "repo.ext_wiki"
+	// RepoUnitReleases represent releases of a repository
+	RepoUnitReleases RepoUnitType = "repo.releases"
+	// RepoUnitProjects represent projects of a repository
+	RepoUnitProjects RepoUnitType = "repo.projects"
+)
+
 // ListTeamsOptions options for listing teams
 type ListTeamsOptions struct {
 	ListOptions
@@ -56,13 +77,12 @@ func (c *Client) GetTeam(id int64) (*Team, *Response, error) {
 
 // CreateTeamOption options for creating a team
 type CreateTeamOption struct {
-	Name                    string     `json:"name"`
-	Description             string     `json:"description"`
-	Permission              AccessMode `json:"permission"`
-	CanCreateOrgRepo        bool       `json:"can_create_org_repo"`
-	IncludesAllRepositories bool       `json:"includes_all_repositories"`
-	// example: ["repo.code","repo.issues","repo.ext_issues","repo.wiki","repo.pulls","repo.releases","repo.ext_wiki"]
-	Units []string `json:"units"`
+	Name                    string         `json:"name"`
+	Description             string         `json:"description"`
+	Permission              AccessMode     `json:"permission"`
+	CanCreateOrgRepo        bool           `json:"can_create_org_repo"`
+	IncludesAllRepositories bool           `json:"includes_all_repositories"`
+	Units                   []RepoUnitType `json:"units"`
 }
 
 // Validate the CreateTeamOption struct
@@ -103,13 +123,12 @@ func (c *Client) CreateTeam(org string, opt CreateTeamOption) (*Team, *Response,
 
 // EditTeamOption options for editing a team
 type EditTeamOption struct {
-	Name                    string     `json:"name"`
-	Description             *string    `json:"description"`
-	Permission              AccessMode `json:"permission"`
-	CanCreateOrgRepo        *bool      `json:"can_create_org_repo"`
-	IncludesAllRepositories *bool      `json:"includes_all_repositories"`
-	// example: ["repo.code","repo.issues","repo.ext_issues","repo.wiki","repo.pulls","repo.releases","repo.ext_wiki"]
-	Units []string `json:"units"`
+	Name                    string         `json:"name"`
+	Description             *string        `json:"description"`
+	Permission              AccessMode     `json:"permission"`
+	CanCreateOrgRepo        *bool          `json:"can_create_org_repo"`
+	IncludesAllRepositories *bool          `json:"includes_all_repositories"`
+	Units                   []RepoUnitType `json:"units"`
 }
 
 // Validate the EditTeamOption struct
diff --git a/vendor/code.gitea.io/sdk/gitea/pull.go b/vendor/code.gitea.io/sdk/gitea/pull.go
index 7c946e8918..e0198c2890 100644
--- a/vendor/code.gitea.io/sdk/gitea/pull.go
+++ b/vendor/code.gitea.io/sdk/gitea/pull.go
@@ -12,6 +12,8 @@ import (
 	"net/url"
 	"strings"
 	"time"
+
+	"github.com/hashicorp/go-version"
 )
 
 // PRBranchInfo information about a branch
@@ -214,10 +216,12 @@ type MergePullRequestOption struct {
 	Message string     `json:"MergeMessageField"`
 }
 
+var version1_11_5, _ = version.NewVersion("1.11.5")
+
 // Validate the MergePullRequestOption struct
 func (opt MergePullRequestOption) Validate(c *Client) error {
 	if opt.Style == MergeStyleSquash {
-		if err := c.CheckServerVersionConstraint(">=1.11.5"); err != nil {
+		if err := c.checkServerVersionGreaterThanOrEqual(version1_11_5); err != nil {
 			return err
 		}
 	}
@@ -285,6 +289,24 @@ func (c *Client) GetPullRequestDiff(owner, repo string, index int64) ([]byte, *R
 	return c.getPullRequestDiffOrPatch(owner, repo, "diff", index)
 }
 
+// ListPullRequestCommitsOptions options for listing pull requests
+type ListPullRequestCommitsOptions struct {
+	ListOptions
+}
+
+// ListPullRequestCommits list commits for a pull request
+func (c *Client) ListPullRequestCommits(owner, repo string, index int64, opt ListPullRequestCommitsOptions) ([]*Commit, *Response, error) {
+	if err := escapeValidatePathSegments(&owner, &repo); err != nil {
+		return nil, nil, err
+	}
+	link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/pulls/%d/commits", owner, repo, index))
+	opt.setDefaults()
+	commits := make([]*Commit, 0, opt.PageSize)
+	link.RawQuery = opt.getURLQuery().Encode()
+	resp, err := c.getParsedResponse("GET", link.String(), nil, nil, &commits)
+	return commits, resp, err
+}
+
 // fixPullHeadSha is a workaround for https://github.com/go-gitea/gitea/issues/12675
 // When no head sha is available, this is because the branch got deleted in the base repo.
 // pr.Head.Ref points in this case not to the head repo branch name, but the base repo ref,
diff --git a/vendor/code.gitea.io/sdk/gitea/pull_review.go b/vendor/code.gitea.io/sdk/gitea/pull_review.go
index fa7921b023..a484dfdd9c 100644
--- a/vendor/code.gitea.io/sdk/gitea/pull_review.go
+++ b/vendor/code.gitea.io/sdk/gitea/pull_review.go
@@ -57,6 +57,7 @@ type PullReviewComment struct {
 	Body     string `json:"body"`
 	Reviewer *User  `json:"user"`
 	ReviewID int64  `json:"pull_request_review_id"`
+	Resolver *User  `json:"resolver"`
 
 	Created time.Time `json:"created_at"`
 	Updated time.Time `json:"updated_at"`
diff --git a/vendor/code.gitea.io/sdk/gitea/release.go b/vendor/code.gitea.io/sdk/gitea/release.go
index 7d36e7106e..c8e7681d02 100644
--- a/vendor/code.gitea.io/sdk/gitea/release.go
+++ b/vendor/code.gitea.io/sdk/gitea/release.go
@@ -35,6 +35,22 @@ type Release struct {
 // ListReleasesOptions options for listing repository's releases
 type ListReleasesOptions struct {
 	ListOptions
+	IsDraft      *bool
+	IsPreRelease *bool
+}
+
+// QueryEncode turns options into querystring argument
+func (opt *ListReleasesOptions) QueryEncode() string {
+	query := opt.getURLQuery()
+
+	if opt.IsDraft != nil {
+		query.Add("draft", fmt.Sprintf("%t", *opt.IsDraft))
+	}
+	if opt.IsPreRelease != nil {
+		query.Add("draft", fmt.Sprintf("%t", *opt.IsPreRelease))
+	}
+
+	return query.Encode()
 }
 
 // ListReleases list releases of a repository
@@ -45,7 +61,7 @@ func (c *Client) ListReleases(owner, repo string, opt ListReleasesOptions) ([]*R
 	opt.setDefaults()
 	releases := make([]*Release, 0, opt.PageSize)
 	resp, err := c.getParsedResponse("GET",
-		fmt.Sprintf("/repos/%s/%s/releases?%s", owner, repo, opt.getURLQuery().Encode()),
+		fmt.Sprintf("/repos/%s/%s/releases?%s", owner, repo, opt.QueryEncode()),
 		nil, nil, &releases)
 	return releases, resp, err
 }
@@ -168,7 +184,7 @@ func (c *Client) DeleteReleaseByTag(user, repo string, tag string) (*Response, e
 // fallbackGetReleaseByTag is fallback for old gitea installations ( < 1.13.0 )
 func (c *Client) fallbackGetReleaseByTag(owner, repo string, tag string) (*Release, *Response, error) {
 	for i := 1; ; i++ {
-		rl, resp, err := c.ListReleases(owner, repo, ListReleasesOptions{ListOptions{Page: i}})
+		rl, resp, err := c.ListReleases(owner, repo, ListReleasesOptions{ListOptions: ListOptions{Page: i}})
 		if err != nil {
 			return nil, resp, err
 		}
diff --git a/vendor/code.gitea.io/sdk/gitea/repo.go b/vendor/code.gitea.io/sdk/gitea/repo.go
index 67bd956308..62d13a3ab5 100644
--- a/vendor/code.gitea.io/sdk/gitea/repo.go
+++ b/vendor/code.gitea.io/sdk/gitea/repo.go
@@ -93,6 +93,7 @@ type Repository struct {
 	AvatarURL                 string           `json:"avatar_url"`
 	Internal                  bool             `json:"internal"`
 	MirrorInterval            string           `json:"mirror_interval"`
+	DefaultMergeStyle         MergeStyle       `json:"default_merge_style"`
 }
 
 // RepoType represent repo type
@@ -334,7 +335,7 @@ func (opt CreateRepoOption) Validate(c *Client) error {
 		return fmt.Errorf("name has more than 100 chars")
 	}
 	if len(opt.TrustModel) != 0 {
-		if err := c.CheckServerVersionConstraint(">=1.13.0"); err != nil {
+		if err := c.checkServerVersionGreaterThanOrEqual(version1_13_0); err != nil {
 			return err
 		}
 	}
@@ -382,6 +383,13 @@ func (c *Client) GetRepo(owner, reponame string) (*Repository, *Response, error)
 	return repo, resp, err
 }
 
+// GetRepoByID returns information of a repository by a giver repository ID.
+func (c *Client) GetRepoByID(id int64) (*Repository, *Response, error) {
+	repo := new(Repository)
+	resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repositories/%d", id), nil, nil, repo)
+	return repo, resp, err
+}
+
 // EditRepoOption options when editing a repository's properties
 type EditRepoOption struct {
 	// name of the repository
@@ -426,6 +434,13 @@ type EditRepoOption struct {
 	Archived *bool `json:"archived,omitempty"`
 	// set to a string like `8h30m0s` to set the mirror interval time
 	MirrorInterval *string `json:"mirror_interval,omitempty"`
+	// either `true` to allow mark pr as merged manually, or `false` to prevent it. `has_pull_requests` must be `true`.
+	AllowManualMerge *bool `json:"allow_manual_merge,omitempty"`
+	// either `true` to enable AutodetectManualMerge, or `false` to prevent it. `has_pull_requests` must be `true`, Note: In some special cases, misjudgments can occur.
+	AutodetectManualMerge *bool `json:"autodetect_manual_merge,omitempty"`
+	// set to a merge style to be used by this repository: "merge", "rebase", "rebase-merge", or "squash". `has_pull_requests` must be `true`.
+	DefaultMergeStyle *MergeStyle `json:"default_merge_style,omitempty"`
+	// set to `true` to archive this repository.
 }
 
 // EditRepo edit the properties of a repository
diff --git a/vendor/code.gitea.io/sdk/gitea/repo_collaborator.go b/vendor/code.gitea.io/sdk/gitea/repo_collaborator.go
index 2019e22db5..c766250f42 100644
--- a/vendor/code.gitea.io/sdk/gitea/repo_collaborator.go
+++ b/vendor/code.gitea.io/sdk/gitea/repo_collaborator.go
@@ -1,3 +1,4 @@
+// Copyright 2021 The Gitea Authors. All rights reserved.
 // Copyright 2016 The Gogs Authors. All rights reserved.
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
@@ -107,3 +108,29 @@ func (c *Client) DeleteCollaborator(user, repo, collaborator string) (*Response,
 		fmt.Sprintf("/repos/%s/%s/collaborators/%s", user, repo, collaborator), nil, nil)
 	return resp, err
 }
+
+// GetReviewers return all users that can be requested to review in this repo
+func (c *Client) GetReviewers(user, repo string) ([]*User, *Response, error) {
+	if err := c.checkServerVersionGreaterThanOrEqual(version1_15_0); err != nil {
+		return nil, nil, err
+	}
+	if err := escapeValidatePathSegments(&user, &repo); err != nil {
+		return nil, nil, err
+	}
+	reviewers := make([]*User, 0, 5)
+	resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/reviewers", user, repo), nil, nil, &reviewers)
+	return reviewers, resp, err
+}
+
+// GetAssignees return all users that have write access and can be assigned to issues
+func (c *Client) GetAssignees(user, repo string) ([]*User, *Response, error) {
+	if err := c.checkServerVersionGreaterThanOrEqual(version1_15_0); err != nil {
+		return nil, nil, err
+	}
+	if err := escapeValidatePathSegments(&user, &repo); err != nil {
+		return nil, nil, err
+	}
+	assignees := make([]*User, 0, 5)
+	resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/assignees", user, repo), nil, nil, &assignees)
+	return assignees, resp, err
+}
diff --git a/vendor/code.gitea.io/sdk/gitea/repo_migrate.go b/vendor/code.gitea.io/sdk/gitea/repo_migrate.go
index 91f19d6aea..cd0fe44c80 100644
--- a/vendor/code.gitea.io/sdk/gitea/repo_migrate.go
+++ b/vendor/code.gitea.io/sdk/gitea/repo_migrate.go
@@ -47,6 +47,8 @@ type MigrateRepoOption struct {
 	PullRequests   bool           `json:"pull_requests"`
 	Releases       bool           `json:"releases"`
 	MirrorInterval string         `json:"mirror_interval"`
+	LFS            bool           `json:"lfs"`
+	LFSEndpoint    string         `json:"lfs_endpoint"`
 }
 
 // Validate the MigrateRepoOption struct
diff --git a/vendor/code.gitea.io/sdk/gitea/repo_tag.go b/vendor/code.gitea.io/sdk/gitea/repo_tag.go
index 0a3c806a41..7317d3f393 100644
--- a/vendor/code.gitea.io/sdk/gitea/repo_tag.go
+++ b/vendor/code.gitea.io/sdk/gitea/repo_tag.go
@@ -5,18 +5,39 @@
 package gitea
 
 import (
+	"bytes"
+	"encoding/json"
 	"fmt"
 )
 
 // Tag represents a repository tag
 type Tag struct {
 	Name       string      `json:"name"`
+	Message    string      `json:"message"`
 	ID         string      `json:"id"`
 	Commit     *CommitMeta `json:"commit"`
 	ZipballURL string      `json:"zipball_url"`
 	TarballURL string      `json:"tarball_url"`
 }
 
+// AnnotatedTag represents an annotated tag
+type AnnotatedTag struct {
+	Tag          string                     `json:"tag"`
+	SHA          string                     `json:"sha"`
+	URL          string                     `json:"url"`
+	Message      string                     `json:"message"`
+	Tagger       *CommitUser                `json:"tagger"`
+	Object       *AnnotatedTagObject        `json:"object"`
+	Verification *PayloadCommitVerification `json:"verification"`
+}
+
+// AnnotatedTagObject contains meta information of the tag object
+type AnnotatedTagObject struct {
+	Type string `json:"type"`
+	URL  string `json:"url"`
+	SHA  string `json:"sha"`
+}
+
 // ListRepoTagsOptions options for listing a repository's tags
 type ListRepoTagsOptions struct {
 	ListOptions
@@ -33,8 +54,69 @@ func (c *Client) ListRepoTags(user, repo string, opt ListRepoTagsOptions) ([]*Ta
 	return tags, resp, err
 }
 
+// GetTag get the tag of a repository
+func (c *Client) GetTag(user, repo, tag string) (*Tag, *Response, error) {
+	if err := c.checkServerVersionGreaterThanOrEqual(version1_15_0); err != nil {
+		return nil, nil, err
+	}
+	if err := escapeValidatePathSegments(&user, &repo, &tag); err != nil {
+		return nil, nil, err
+	}
+	t := new(Tag)
+	resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/tags/%s", user, repo, tag), nil, nil, &t)
+	return t, resp, err
+}
+
+// GetAnnotatedTag get the tag object of an annotated tag (not lightweight tags) of a repository
+func (c *Client) GetAnnotatedTag(user, repo, sha string) (*AnnotatedTag, *Response, error) {
+	if err := c.checkServerVersionGreaterThanOrEqual(version1_15_0); err != nil {
+		return nil, nil, err
+	}
+	if err := escapeValidatePathSegments(&user, &repo, &sha); err != nil {
+		return nil, nil, err
+	}
+	t := new(AnnotatedTag)
+	resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/git/tags/%s", user, repo, sha), nil, nil, &t)
+	return t, resp, err
+}
+
+// CreateTagOption options when creating a tag
+type CreateTagOption struct {
+	TagName string `json:"tag_name"`
+	Message string `json:"message"`
+	Target  string `json:"target"`
+}
+
+// Validate validates CreateTagOption
+func (opt CreateTagOption) Validate() error {
+	if len(opt.TagName) == 0 {
+		return fmt.Errorf("TagName is required")
+	}
+	return nil
+}
+
+// CreateTag create a new git tag in a repository
+func (c *Client) CreateTag(user, repo string, opt CreateTagOption) (*Tag, *Response, error) {
+	if err := c.checkServerVersionGreaterThanOrEqual(version1_15_0); err != nil {
+		return nil, nil, err
+	}
+	if err := escapeValidatePathSegments(&user, &repo); err != nil {
+		return nil, nil, err
+	}
+	if err := opt.Validate(); err != nil {
+		return nil, nil, err
+	}
+	body, err := json.Marshal(opt)
+	if err != nil {
+		return nil, nil, err
+	}
+	t := new(Tag)
+	resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/tags", user, repo), jsonHeader, bytes.NewReader(body), &t)
+	return t, resp, err
+}
+
 // DeleteTag deletes a tag from a repository, if no release refers to it
-func (c *Client) DeleteTag(user, repo string, tag string) (*Response, error) {
+func (c *Client) DeleteTag(user, repo, tag string) (*Response, error) {
 	if err := escapeValidatePathSegments(&user, &repo, &tag); err != nil {
 		return nil, err
 	}
diff --git a/vendor/code.gitea.io/sdk/gitea/repo_team.go b/vendor/code.gitea.io/sdk/gitea/repo_team.go
new file mode 100644
index 0000000000..b983d8748a
--- /dev/null
+++ b/vendor/code.gitea.io/sdk/gitea/repo_team.go
@@ -0,0 +1,65 @@
+// Copyright 2021 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package gitea
+
+import (
+	"fmt"
+	"net/http"
+)
+
+// GetRepoTeams return teams from a repository
+func (c *Client) GetRepoTeams(user, repo string) ([]*Team, *Response, error) {
+	if err := c.checkServerVersionGreaterThanOrEqual(version1_15_0); err != nil {
+		return nil, nil, err
+	}
+	if err := escapeValidatePathSegments(&user, &repo); err != nil {
+		return nil, nil, err
+	}
+	teams := make([]*Team, 0, 5)
+	resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/teams", user, repo), nil, nil, &teams)
+	return teams, resp, err
+}
+
+// AddRepoTeam add a team to a repository
+func (c *Client) AddRepoTeam(user, repo, team string) (*Response, error) {
+	if err := c.checkServerVersionGreaterThanOrEqual(version1_15_0); err != nil {
+		return nil, err
+	}
+	if err := escapeValidatePathSegments(&user, &repo, &team); err != nil {
+		return nil, err
+	}
+	_, resp, err := c.getResponse("PUT", fmt.Sprintf("/repos/%s/%s/teams/%s", user, repo, team), nil, nil)
+	return resp, err
+}
+
+// RemoveRepoTeam delete a team from a repository
+func (c *Client) RemoveRepoTeam(user, repo, team string) (*Response, error) {
+	if err := c.checkServerVersionGreaterThanOrEqual(version1_15_0); err != nil {
+		return nil, err
+	}
+	if err := escapeValidatePathSegments(&user, &repo, &team); err != nil {
+		return nil, err
+	}
+	_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/teams/%s", user, repo, team), nil, nil)
+	return resp, err
+}
+
+// CheckRepoTeam check if team is assigned to repo by name and return it.
+// If not assigned, it will return nil.
+func (c *Client) CheckRepoTeam(user, repo, team string) (*Team, *Response, error) {
+	if err := c.checkServerVersionGreaterThanOrEqual(version1_15_0); err != nil {
+		return nil, nil, err
+	}
+	if err := escapeValidatePathSegments(&user, &repo, &team); err != nil {
+		return nil, nil, err
+	}
+	t := new(Team)
+	resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/teams/%s", user, repo, team), nil, nil, &t)
+	if resp != nil && resp.StatusCode == http.StatusNotFound {
+		// if not found it's not an error, it indicates it's not assigned
+		return nil, resp, nil
+	}
+	return t, resp, err
+}
diff --git a/vendor/code.gitea.io/sdk/gitea/repo_template.go b/vendor/code.gitea.io/sdk/gitea/repo_template.go
new file mode 100644
index 0000000000..8b689bea49
--- /dev/null
+++ b/vendor/code.gitea.io/sdk/gitea/repo_template.go
@@ -0,0 +1,65 @@
+// Copyright 2021 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package gitea
+
+import (
+	"bytes"
+	"encoding/json"
+	"fmt"
+)
+
+// CreateRepoFromTemplateOption options when creating repository using a template
+type CreateRepoFromTemplateOption struct {
+	// Owner is the organization or person who will own the new repository
+	Owner string `json:"owner"`
+	// Name of the repository to create
+	Name string `json:"name"`
+	// Description of the repository to create
+	Description string `json:"description"`
+	// Private is whether the repository is private
+	Private bool `json:"private"`
+	// GitContent include git content of default branch in template repo
+	GitContent bool `json:"git_content"`
+	// Topics include topics of template repo
+	Topics bool `json:"topics"`
+	// GitHooks include git hooks of template repo
+	GitHooks bool `json:"git_hooks"`
+	// Webhooks include webhooks of template repo
+	Webhooks bool `json:"webhooks"`
+	// Avatar include avatar of the template repo
+	Avatar bool `json:"avatar"`
+	// Labels include labels of template repo
+	Labels bool `json:"labels"`
+}
+
+// Validate validates CreateRepoFromTemplateOption
+func (opt CreateRepoFromTemplateOption) Validate() error {
+	if len(opt.Owner) == 0 {
+		return fmt.Errorf("field Owner is required")
+	}
+	if len(opt.Name) == 0 {
+		return fmt.Errorf("field Name is required")
+	}
+	return nil
+}
+
+// CreateRepoFromTemplate create a repository using a template
+func (c *Client) CreateRepoFromTemplate(templateOwner, templateRepo string, opt CreateRepoFromTemplateOption) (*Repository, *Response, error) {
+	if err := escapeValidatePathSegments(&templateOwner, &templateRepo); err != nil {
+		return nil, nil, err
+	}
+
+	if err := opt.Validate(); err != nil {
+		return nil, nil, err
+	}
+	body, err := json.Marshal(&opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	repo := new(Repository)
+	resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/generate", templateOwner, templateRepo), jsonHeader, bytes.NewReader(body), &repo)
+	return repo, resp, err
+}
diff --git a/vendor/code.gitea.io/sdk/gitea/settings.go b/vendor/code.gitea.io/sdk/gitea/settings.go
index 134d2ad993..fb94248f63 100644
--- a/vendor/code.gitea.io/sdk/gitea/settings.go
+++ b/vendor/code.gitea.io/sdk/gitea/settings.go
@@ -8,13 +8,17 @@ package gitea
 type GlobalUISettings struct {
 	DefaultTheme     string   `json:"default_theme"`
 	AllowedReactions []string `json:"allowed_reactions"`
+	CustomEmojis     []string `json:"custom_emojis"`
 }
 
 // GlobalRepoSettings represent the global repository settings of a gitea instance witch is exposed by API
 type GlobalRepoSettings struct {
-	MirrorsDisabled    bool `json:"mirrors_disabled"`
-	HTTPGitDisabled    bool `json:"http_git_disabled"`
-	MigrationsDisabled bool `json:"migrations_disabled"`
+	MirrorsDisabled      bool `json:"mirrors_disabled"`
+	HTTPGitDisabled      bool `json:"http_git_disabled"`
+	MigrationsDisabled   bool `json:"migrations_disabled"`
+	StarsDisabled        bool `json:"stars_disabled"`
+	TimeTrackingDisabled bool `json:"time_tracking_disabled"`
+	LFSDisabled          bool `json:"lfs_disabled"`
 }
 
 // GlobalAPISettings contains global api settings exposed by it
diff --git a/vendor/code.gitea.io/sdk/gitea/user.go b/vendor/code.gitea.io/sdk/gitea/user.go
index 209523632d..c37627bfaa 100644
--- a/vendor/code.gitea.io/sdk/gitea/user.go
+++ b/vendor/code.gitea.io/sdk/gitea/user.go
@@ -6,6 +6,8 @@ package gitea
 
 import (
 	"fmt"
+	"net/url"
+	"strconv"
 	"time"
 )
 
@@ -23,9 +25,30 @@ type User struct {
 	// User locale
 	Language string `json:"language"`
 	// Is the user an administrator
-	IsAdmin   bool      `json:"is_admin"`
-	LastLogin time.Time `json:"last_login,omitempty"`
-	Created   time.Time `json:"created,omitempty"`
+	IsAdmin bool `json:"is_admin"`
+	// Date and Time of last login
+	LastLogin time.Time `json:"last_login"`
+	// Date and Time of user creation
+	Created time.Time `json:"created"`
+	// Is user restricted
+	Restricted bool `json:"restricted"`
+	// Is user active
+	IsActive bool `json:"active"`
+	// Is user login prohibited
+	ProhibitLogin bool `json:"prohibit_login"`
+	// the user's location
+	Location string `json:"location"`
+	// the user's website
+	Website string `json:"website"`
+	// the user's description
+	Description string `json:"description"`
+	// User visibility level option
+	Visibility VisibleType `json:"visibility"`
+
+	// user counts
+	FollowerCount    int `json:"followers_count"`
+	FollowingCount   int `json:"following_count"`
+	StarredRepoCount int `json:"starred_repos_count"`
 }
 
 // GetUserInfo get user info by user's name
@@ -44,3 +67,24 @@ func (c *Client) GetMyUserInfo() (*User, *Response, error) {
 	resp, err := c.getParsedResponse("GET", "/user", nil, nil, u)
 	return u, resp, err
 }
+
+// GetUserByID returns user by a given user ID
+func (c *Client) GetUserByID(id int64) (*User, *Response, error) {
+	if id < 0 {
+		return nil, nil, fmt.Errorf("invalid user id %d", id)
+	}
+
+	query := make(url.Values)
+	query.Add("uid", strconv.FormatInt(id, 10))
+	users, resp, err := c.searchUsers(query.Encode())
+
+	if err != nil {
+		return nil, resp, err
+	}
+
+	if len(users) == 1 {
+		return users[0], resp, err
+	}
+
+	return nil, resp, fmt.Errorf("user not found with id %d", id)
+}
diff --git a/vendor/code.gitea.io/sdk/gitea/user_app.go b/vendor/code.gitea.io/sdk/gitea/user_app.go
index 2921eea7df..88b01ed083 100644
--- a/vendor/code.gitea.io/sdk/gitea/user_app.go
+++ b/vendor/code.gitea.io/sdk/gitea/user_app.go
@@ -77,7 +77,7 @@ func (c *Client) DeleteAccessToken(value interface{}) (*Response, error) {
 	case reflect.Int64:
 		token = fmt.Sprintf("%d", value.(int64))
 	case reflect.String:
-		if err := c.CheckServerVersionConstraint(">= 1.13.0"); err != nil {
+		if err := c.checkServerVersionGreaterThanOrEqual(version1_13_0); err != nil {
 			return nil, err
 		}
 		token = value.(string)
diff --git a/vendor/code.gitea.io/sdk/gitea/user_search.go b/vendor/code.gitea.io/sdk/gitea/user_search.go
index 7e4064d18e..5ea0c45f81 100644
--- a/vendor/code.gitea.io/sdk/gitea/user_search.go
+++ b/vendor/code.gitea.io/sdk/gitea/user_search.go
@@ -34,11 +34,15 @@ func (opt *SearchUsersOption) QueryEncode() string {
 	return query.Encode()
 }
 
-// SearchUsers finds users by query
-func (c *Client) SearchUsers(opt SearchUsersOption) ([]*User, *Response, error) {
+func (c *Client) searchUsers(rawQuery string) ([]*User, *Response, error) {
 	link, _ := url.Parse("/users/search")
-	link.RawQuery = opt.QueryEncode()
+	link.RawQuery = rawQuery
 	userResp := new(searchUsersResponse)
 	resp, err := c.getParsedResponse("GET", link.String(), nil, nil, &userResp)
 	return userResp.Users, resp, err
 }
+
+// SearchUsers finds users by query
+func (c *Client) SearchUsers(opt SearchUsersOption) ([]*User, *Response, error) {
+	return c.searchUsers(opt.QueryEncode())
+}
diff --git a/vendor/code.gitea.io/sdk/gitea/user_settings.go b/vendor/code.gitea.io/sdk/gitea/user_settings.go
new file mode 100644
index 0000000000..494cab3629
--- /dev/null
+++ b/vendor/code.gitea.io/sdk/gitea/user_settings.go
@@ -0,0 +1,62 @@
+// Copyright 2021 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package gitea
+
+import (
+	"bytes"
+	"encoding/json"
+)
+
+// UserSettings represents user settings
+type UserSettings struct {
+	FullName      string `json:"full_name"`
+	Website       string `json:"website"`
+	Description   string `json:"description"`
+	Location      string `json:"location"`
+	Language      string `json:"language"`
+	Theme         string `json:"theme"`
+	DiffViewStyle string `json:"diff_view_style"`
+	// Privacy
+	HideEmail    bool `json:"hide_email"`
+	HideActivity bool `json:"hide_activity"`
+}
+
+// UserSettingsOptions represents options to change user settings
+type UserSettingsOptions struct {
+	FullName      *string `json:"full_name,omitempty"`
+	Website       *string `json:"website,omitempty"`
+	Description   *string `json:"description,omitempty"`
+	Location      *string `json:"location,omitempty"`
+	Language      *string `json:"language,omitempty"`
+	Theme         *string `json:"theme,omitempty"`
+	DiffViewStyle *string `json:"diff_view_style,omitempty"`
+	// Privacy
+	HideEmail    *bool `json:"hide_email,omitempty"`
+	HideActivity *bool `json:"hide_activity,omitempty"`
+}
+
+// GetUserSettings returns user settings
+func (c *Client) GetUserSettings() (*UserSettings, *Response, error) {
+	if err := c.checkServerVersionGreaterThanOrEqual(version1_15_0); err != nil {
+		return nil, nil, err
+	}
+	userConfig := new(UserSettings)
+	resp, err := c.getParsedResponse("GET", "/user/settings", nil, nil, userConfig)
+	return userConfig, resp, err
+}
+
+// UpdateUserSettings returns user settings
+func (c *Client) UpdateUserSettings(opt UserSettingsOptions) (*UserSettings, *Response, error) {
+	if err := c.checkServerVersionGreaterThanOrEqual(version1_15_0); err != nil {
+		return nil, nil, err
+	}
+	body, err := json.Marshal(&opt)
+	if err != nil {
+		return nil, nil, err
+	}
+	userConfig := new(UserSettings)
+	resp, err := c.getParsedResponse("PATCH", "/user/settings", jsonHeader, bytes.NewReader(body), userConfig)
+	return userConfig, resp, err
+}
diff --git a/vendor/code.gitea.io/sdk/gitea/version.go b/vendor/code.gitea.io/sdk/gitea/version.go
index ed8a2ae5dd..1f41c77183 100644
--- a/vendor/code.gitea.io/sdk/gitea/version.go
+++ b/vendor/code.gitea.io/sdk/gitea/version.go
@@ -39,16 +39,39 @@ func (c *Client) CheckServerVersionConstraint(constraint string) error {
 	return nil
 }
 
+// SetGiteaVersion configures the Client to assume the given version of the
+// Gitea server, instead of querying the server for it when initializing.
+// Use "" to skip all canonical ways in the SDK to check for versions
+func SetGiteaVersion(v string) ClientOption {
+	if v == "" {
+		return func(c *Client) error {
+			c.ignoreVersion = true
+			return nil
+		}
+	}
+	return func(c *Client) (err error) {
+		c.getVersionOnce.Do(func() {
+			c.serverVersion, err = version.NewVersion(v)
+			return
+		})
+		return
+	}
+}
+
 // predefined versions only have to be parsed by library once
 var (
 	version1_11_0, _ = version.NewVersion("1.11.0")
 	version1_12_0, _ = version.NewVersion("1.12.0")
 	version1_13_0, _ = version.NewVersion("1.13.0")
 	version1_14_0, _ = version.NewVersion("1.14.0")
+	version1_15_0, _ = version.NewVersion("1.15.0")
 )
 
-// checkServerVersionGreaterThanOrEqual is internally used to speed up things and ignore issues with prerelease
+// checkServerVersionGreaterThanOrEqual is the canonical way in the SDK to check for versions for API compatibility reasons
 func (c *Client) checkServerVersionGreaterThanOrEqual(v *version.Version) error {
+	if c.ignoreVersion {
+		return nil
+	}
 	if err := c.loadServerVersion(); err != nil {
 		return err
 	}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 23a59c18ac..1609ad964c 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -5,7 +5,7 @@ cloud.google.com/go/compute/metadata
 ## explicit
 code.gitea.io/gitea-vet
 code.gitea.io/gitea-vet/checks
-# code.gitea.io/sdk/gitea v0.14.0
+# code.gitea.io/sdk/gitea v0.15.1
 ## explicit
 code.gitea.io/sdk/gitea
 # gitea.com/go-chi/binding v0.0.0-20211013065440-d16dc407c2be