mirror of
https://gitea.com/gitea/go-sdk.git
synced 2024-06-02 10:11:26 +05:30
Compare commits
23 commits
gitea/v0.1
...
main
Author | SHA1 | Date | |
---|---|---|---|
8110db1e6d | |||
83c73e79a5 | |||
6c0938dc15 | |||
0a99bda0cb | |||
36723e11c8 | |||
a991e370c5 | |||
bb25c989a0 | |||
18e5522f90 | |||
bad4de0196 | |||
9ec1b82849 | |||
bf71ec2fd9 | |||
001d5fad51 | |||
5d0143e4e7 | |||
53f735b911 | |||
98b424a8af | |||
2abfdd7ba6 | |||
8f4d3d8916 | |||
bde56fb9bb | |||
228d6931f4 | |||
c8745e1599 | |||
0e0a4691b6 | |||
e23e8aa300 | |||
d5e174e5b5 |
|
@ -15,10 +15,10 @@ jobs:
|
||||||
GITEA_SDK_TEST_USERNAME: "test01"
|
GITEA_SDK_TEST_USERNAME: "test01"
|
||||||
GITEA_SDK_TEST_PASSWORD: "test01"
|
GITEA_SDK_TEST_PASSWORD: "test01"
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-go@v3
|
- uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: '>=1.20'
|
go-version: ">=1.21"
|
||||||
check-latest: true
|
check-latest: true
|
||||||
- run: make clean
|
- run: make clean
|
||||||
- run: make vet
|
- run: make vet
|
||||||
|
@ -28,7 +28,7 @@ jobs:
|
||||||
- run: make test
|
- run: make test
|
||||||
services:
|
services:
|
||||||
gitea:
|
gitea:
|
||||||
image: gitea/gitea:1.18
|
image: gitea/gitea:1.22.0-rc1
|
||||||
cmd:
|
cmd:
|
||||||
- bash
|
- bash
|
||||||
- -c
|
- -c
|
||||||
|
|
4
Makefile
4
Makefile
|
@ -12,7 +12,7 @@ GOFUMPT_PACKAGE ?= mvdan.cc/gofumpt@v0.4.0
|
||||||
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@v1.51.0
|
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@v1.51.0
|
||||||
GITEA_VET_PACKAGE ?= code.gitea.io/gitea-vet@v0.2.1
|
GITEA_VET_PACKAGE ?= code.gitea.io/gitea-vet@v0.2.1
|
||||||
|
|
||||||
GITEA_VERSION := 1.18
|
GITEA_VERSION := 1.21.10
|
||||||
GITEA_DL := https://dl.gitea.com/gitea/$(GITEA_VERSION)/gitea-$(GITEA_VERSION)-
|
GITEA_DL := https://dl.gitea.com/gitea/$(GITEA_VERSION)/gitea-$(GITEA_VERSION)-
|
||||||
UNAME_S := $(shell uname -s)
|
UNAME_S := $(shell uname -s)
|
||||||
ifeq ($(UNAME_S),Linux)
|
ifeq ($(UNAME_S),Linux)
|
||||||
|
@ -72,7 +72,7 @@ vet:
|
||||||
cd gitea && $(GO) vet -vettool=gitea-vet $(PACKAGE)
|
cd gitea && $(GO) vet -vettool=gitea-vet $(PACKAGE)
|
||||||
|
|
||||||
.PHONY: ci-lint
|
.PHONY: ci-lint
|
||||||
ci-lint:
|
ci-lint:
|
||||||
@cd gitea/; echo -n "gofumpt ...";\
|
@cd gitea/; echo -n "gofumpt ...";\
|
||||||
diff=$$($(GO) run $(GOFUMPT_PACKAGE) -extra -l .); \
|
diff=$$($(GO) run $(GOFUMPT_PACKAGE) -extra -l .); \
|
||||||
if [ -n "$$diff" ]; then \
|
if [ -n "$$diff" ]; then \
|
||||||
|
|
|
@ -12,9 +12,9 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@ type Client struct {
|
||||||
password string
|
password string
|
||||||
otp string
|
otp string
|
||||||
sudo string
|
sudo string
|
||||||
|
userAgent string
|
||||||
debug bool
|
debug bool
|
||||||
httpsigner *HTTPSign
|
httpsigner *HTTPSign
|
||||||
client *http.Client
|
client *http.Client
|
||||||
|
@ -49,6 +50,11 @@ type Client struct {
|
||||||
// Response represents the gitea response
|
// Response represents the gitea response
|
||||||
type Response struct {
|
type Response struct {
|
||||||
*http.Response
|
*http.Response
|
||||||
|
|
||||||
|
FirstPage int
|
||||||
|
PrevPage int
|
||||||
|
NextPage int
|
||||||
|
LastPage int
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClientOption are functions used to init a new client
|
// ClientOption are functions used to init a new client
|
||||||
|
@ -215,6 +221,21 @@ func (c *Client) SetSudo(sudo string) {
|
||||||
c.mutex.Unlock()
|
c.mutex.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetUserAgent is an option for NewClient to set user-agent header
|
||||||
|
func SetUserAgent(userAgent string) ClientOption {
|
||||||
|
return func(client *Client) error {
|
||||||
|
client.SetUserAgent(userAgent)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetUserAgent sets the user-agent to send with every request.
|
||||||
|
func (c *Client) SetUserAgent(userAgent string) {
|
||||||
|
c.mutex.Lock()
|
||||||
|
c.userAgent = userAgent
|
||||||
|
c.mutex.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
// SetDebugMode is an option for NewClient to enable debug mode
|
// SetDebugMode is an option for NewClient to enable debug mode
|
||||||
func SetDebugMode() ClientOption {
|
func SetDebugMode() ClientOption {
|
||||||
return func(client *Client) error {
|
return func(client *Client) error {
|
||||||
|
@ -225,6 +246,57 @@ func SetDebugMode() ClientOption {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newResponse(r *http.Response) *Response {
|
||||||
|
response := &Response{Response: r}
|
||||||
|
response.parseLinkHeader()
|
||||||
|
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Response) parseLinkHeader() {
|
||||||
|
link := r.Header.Get("Link")
|
||||||
|
if link == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
links := strings.Split(link, ",")
|
||||||
|
for _, l := range links {
|
||||||
|
u, param, ok := strings.Cut(l, ";")
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
u = strings.Trim(u, " <>")
|
||||||
|
|
||||||
|
key, value, ok := strings.Cut(strings.TrimSpace(param), "=")
|
||||||
|
if !ok || key != "rel" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
value = strings.Trim(value, "\"")
|
||||||
|
|
||||||
|
parsed, err := url.Parse(u)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
page := parsed.Query().Get("page")
|
||||||
|
if page == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
switch value {
|
||||||
|
case "first":
|
||||||
|
r.FirstPage, _ = strconv.Atoi(page)
|
||||||
|
case "prev":
|
||||||
|
r.PrevPage, _ = strconv.Atoi(page)
|
||||||
|
case "next":
|
||||||
|
r.NextPage, _ = strconv.Atoi(page)
|
||||||
|
case "last":
|
||||||
|
r.LastPage, _ = strconv.Atoi(page)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Client) getWebResponse(method, path string, body io.Reader) ([]byte, *Response, error) {
|
func (c *Client) getWebResponse(method, path string, body io.Reader) ([]byte, *Response, error) {
|
||||||
c.mutex.RLock()
|
c.mutex.RLock()
|
||||||
debug := c.debug
|
debug := c.debug
|
||||||
|
@ -246,11 +318,12 @@ func (c *Client) getWebResponse(method, path string, body io.Reader) ([]byte, *R
|
||||||
}
|
}
|
||||||
|
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
data, err := ioutil.ReadAll(resp.Body)
|
data, err := io.ReadAll(resp.Body)
|
||||||
if debug {
|
if debug {
|
||||||
fmt.Printf("Response: %v\n\n", resp)
|
fmt.Printf("Response: %v\n\n", resp)
|
||||||
}
|
}
|
||||||
return data, &Response{resp}, err
|
|
||||||
|
return data, newResponse(resp), err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) doRequest(method, path string, header http.Header, body io.Reader) (*Response, error) {
|
func (c *Client) doRequest(method, path string, header http.Header, body io.Reader) (*Response, error) {
|
||||||
|
@ -259,7 +332,7 @@ func (c *Client) doRequest(method, path string, header http.Header, body io.Read
|
||||||
if debug {
|
if debug {
|
||||||
var bodyStr string
|
var bodyStr string
|
||||||
if body != nil {
|
if body != nil {
|
||||||
bs, _ := ioutil.ReadAll(body)
|
bs, _ := io.ReadAll(body)
|
||||||
body = bytes.NewReader(bs)
|
body = bytes.NewReader(bs)
|
||||||
bodyStr = string(bs)
|
bodyStr = string(bs)
|
||||||
}
|
}
|
||||||
|
@ -282,6 +355,9 @@ func (c *Client) doRequest(method, path string, header http.Header, body io.Read
|
||||||
if len(c.sudo) != 0 {
|
if len(c.sudo) != 0 {
|
||||||
req.Header.Set("Sudo", c.sudo)
|
req.Header.Set("Sudo", c.sudo)
|
||||||
}
|
}
|
||||||
|
if len(c.userAgent) != 0 {
|
||||||
|
req.Header.Set("User-Agent", c.userAgent)
|
||||||
|
}
|
||||||
|
|
||||||
client := c.client // client ref can change from this point on so safe it
|
client := c.client // client ref can change from this point on so safe it
|
||||||
c.mutex.RUnlock()
|
c.mutex.RUnlock()
|
||||||
|
@ -304,7 +380,8 @@ func (c *Client) doRequest(method, path string, header http.Header, body io.Read
|
||||||
if debug {
|
if debug {
|
||||||
fmt.Printf("Response: %v\n\n", resp)
|
fmt.Printf("Response: %v\n\n", resp)
|
||||||
}
|
}
|
||||||
return &Response{resp}, nil
|
|
||||||
|
return newResponse(resp), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Converts a response for a HTTP status code indicating an error condition
|
// Converts a response for a HTTP status code indicating an error condition
|
||||||
|
@ -321,7 +398,7 @@ func statusCodeToErr(resp *Response) (body []byte, err error) {
|
||||||
// error: body will be read for details
|
// error: body will be read for details
|
||||||
//
|
//
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
data, err := ioutil.ReadAll(resp.Body)
|
data, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("body read on HTTP error %d: %v", resp.StatusCode, err)
|
return nil, fmt.Errorf("body read on HTTP error %d: %v", resp.StatusCode, err)
|
||||||
}
|
}
|
||||||
|
@ -374,7 +451,7 @@ func (c *Client) getResponse(method, path string, header http.Header, body io.Re
|
||||||
}
|
}
|
||||||
|
|
||||||
// success (2XX), read body
|
// success (2XX), read body
|
||||||
data, err = ioutil.ReadAll(resp.Body)
|
data, err = io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, resp, err
|
return nil, resp, err
|
||||||
}
|
}
|
||||||
|
|
35
gitea/client_test.go
Normal file
35
gitea/client_test.go
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
// Copyright 2023 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 (
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestParsedPaging(t *testing.T) {
|
||||||
|
resp := newResponse(&http.Response{
|
||||||
|
Header: http.Header{
|
||||||
|
"Link": []string{
|
||||||
|
strings.Join(
|
||||||
|
[]string{
|
||||||
|
`<https://try.gitea.io/api/v1/repos/gitea/go-sdk/issues/1/comments?page=3>; rel="next"`,
|
||||||
|
`<https://try.gitea.io/api/v1/repos/gitea/go-sdk/issues/1/comments?page=4>; rel="last"`,
|
||||||
|
`<https://try.gitea.io/api/v1/repos/gitea/go-sdk/issues/1/comments?page=1>; rel="first"`,
|
||||||
|
`<https://try.gitea.io/api/v1/repos/gitea/go-sdk/issues/1/comments?page=1>; rel="prev"`,
|
||||||
|
}, ",",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.Equal(t, 1, resp.FirstPage)
|
||||||
|
assert.Equal(t, 1, resp.PrevPage)
|
||||||
|
assert.Equal(t, 3, resp.NextPage)
|
||||||
|
assert.Equal(t, 4, resp.LastPage)
|
||||||
|
}
|
13
gitea/go.mod
13
gitea/go.mod
|
@ -1,11 +1,18 @@
|
||||||
module code.gitea.io/sdk/gitea
|
module code.gitea.io/sdk/gitea
|
||||||
|
|
||||||
go 1.13
|
go 1.18
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/davidmz/go-pageant v1.0.2
|
github.com/davidmz/go-pageant v1.0.2
|
||||||
github.com/go-fed/httpsig v1.1.0
|
github.com/go-fed/httpsig v1.1.0
|
||||||
github.com/hashicorp/go-version v1.5.0
|
github.com/hashicorp/go-version v1.6.0
|
||||||
github.com/stretchr/testify v1.7.0
|
github.com/stretchr/testify v1.7.0
|
||||||
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e
|
golang.org/x/crypto v0.22.0
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/davecgh/go-spew v1.1.0 // indirect
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
|
golang.org/x/sys v0.19.0 // indirect
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
|
||||||
)
|
)
|
||||||
|
|
17
gitea/go.sum
17
gitea/go.sum
|
@ -4,8 +4,8 @@ github.com/davidmz/go-pageant v1.0.2 h1:bPblRCh5jGU+Uptpz6LgMZGD5hJoOt7otgT454Wv
|
||||||
github.com/davidmz/go-pageant v1.0.2/go.mod h1:P2EDDnMqIwG5Rrp05dTRITj9z2zpGcD9efWSkTNKLIE=
|
github.com/davidmz/go-pageant v1.0.2/go.mod h1:P2EDDnMqIwG5Rrp05dTRITj9z2zpGcD9efWSkTNKLIE=
|
||||||
github.com/go-fed/httpsig v1.1.0 h1:9M+hb0jkEICD8/cAiNqEB66R87tTINszBRTjwjQzWcI=
|
github.com/go-fed/httpsig v1.1.0 h1:9M+hb0jkEICD8/cAiNqEB66R87tTINszBRTjwjQzWcI=
|
||||||
github.com/go-fed/httpsig v1.1.0/go.mod h1:RCMrTZvN1bJYtofsG4rd5NaO5obxQ5xBkdiS7xsT7bM=
|
github.com/go-fed/httpsig v1.1.0/go.mod h1:RCMrTZvN1bJYtofsG4rd5NaO5obxQ5xBkdiS7xsT7bM=
|
||||||
github.com/hashicorp/go-version v1.5.0 h1:O293SZ2Eg+AAYijkVK3jR786Am1bhDEh2GHT0tIVE5E=
|
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
|
||||||
github.com/hashicorp/go-version v1.5.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
@ -14,22 +14,19 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
||||||
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM=
|
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
|
||||||
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
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/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4=
|
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
|
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
|
golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
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/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
|
|
@ -62,6 +62,14 @@ func (c *Client) ListOrgHooks(org string, opt ListHooksOptions) ([]*Hook, *Respo
|
||||||
return hooks, resp, err
|
return hooks, resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListMyHooks list all the hooks of the authenticated user
|
||||||
|
func (c *Client) ListMyHooks(opt ListHooksOptions) ([]*Hook, *Response, error) {
|
||||||
|
opt.setDefaults()
|
||||||
|
hooks := make([]*Hook, 0, opt.PageSize)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/user/hooks?%s", opt.getURLQuery().Encode()), nil, nil, &hooks)
|
||||||
|
return hooks, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
// ListRepoHooks list all the hooks of one repository
|
// ListRepoHooks list all the hooks of one repository
|
||||||
func (c *Client) ListRepoHooks(user, repo string, opt ListHooksOptions) ([]*Hook, *Response, error) {
|
func (c *Client) ListRepoHooks(user, repo string, opt ListHooksOptions) ([]*Hook, *Response, error) {
|
||||||
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
@ -83,6 +91,13 @@ func (c *Client) GetOrgHook(org string, id int64) (*Hook, *Response, error) {
|
||||||
return h, resp, err
|
return h, resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetMyHook get a hook of the authenticated user
|
||||||
|
func (c *Client) GetMyHook(id int64) (*Hook, *Response, error) {
|
||||||
|
h := new(Hook)
|
||||||
|
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/user/hooks/%d", id), nil, nil, h)
|
||||||
|
return h, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
// GetRepoHook get a hook of a repository
|
// GetRepoHook get a hook of a repository
|
||||||
func (c *Client) GetRepoHook(user, repo string, id int64) (*Hook, *Response, error) {
|
func (c *Client) GetRepoHook(user, repo string, id int64) (*Hook, *Response, error) {
|
||||||
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
@ -95,11 +110,12 @@ func (c *Client) GetRepoHook(user, repo string, id int64) (*Hook, *Response, err
|
||||||
|
|
||||||
// CreateHookOption options when create a hook
|
// CreateHookOption options when create a hook
|
||||||
type CreateHookOption struct {
|
type CreateHookOption struct {
|
||||||
Type HookType `json:"type"`
|
Type HookType `json:"type"`
|
||||||
Config map[string]string `json:"config"`
|
Config map[string]string `json:"config"`
|
||||||
Events []string `json:"events"`
|
Events []string `json:"events"`
|
||||||
BranchFilter string `json:"branch_filter"`
|
BranchFilter string `json:"branch_filter"`
|
||||||
Active bool `json:"active"`
|
Active bool `json:"active"`
|
||||||
|
AuthorizationHeader string `json:"authorization_header"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate the CreateHookOption struct
|
// Validate the CreateHookOption struct
|
||||||
|
@ -127,6 +143,20 @@ func (c *Client) CreateOrgHook(org string, opt CreateHookOption) (*Hook, *Respon
|
||||||
return h, resp, err
|
return h, resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateMyHook create one hook for the authenticated user, with options
|
||||||
|
func (c *Client) CreateMyHook(opt CreateHookOption) (*Hook, *Response, error) {
|
||||||
|
if err := opt.Validate(); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
h := new(Hook)
|
||||||
|
resp, err := c.getParsedResponse("POST", "/user/hooks", jsonHeader, bytes.NewReader(body), h)
|
||||||
|
return h, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
// CreateRepoHook create one hook for a repository, with options
|
// CreateRepoHook create one hook for a repository, with options
|
||||||
func (c *Client) CreateRepoHook(user, repo string, opt CreateHookOption) (*Hook, *Response, error) {
|
func (c *Client) CreateRepoHook(user, repo string, opt CreateHookOption) (*Hook, *Response, error) {
|
||||||
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
@ -143,10 +173,11 @@ func (c *Client) CreateRepoHook(user, repo string, opt CreateHookOption) (*Hook,
|
||||||
|
|
||||||
// EditHookOption options when modify one hook
|
// EditHookOption options when modify one hook
|
||||||
type EditHookOption struct {
|
type EditHookOption struct {
|
||||||
Config map[string]string `json:"config"`
|
Config map[string]string `json:"config"`
|
||||||
Events []string `json:"events"`
|
Events []string `json:"events"`
|
||||||
BranchFilter string `json:"branch_filter"`
|
BranchFilter string `json:"branch_filter"`
|
||||||
Active *bool `json:"active"`
|
Active *bool `json:"active"`
|
||||||
|
AuthorizationHeader string `json:"authorization_header"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// EditOrgHook modify one hook of an organization, with hook id and options
|
// EditOrgHook modify one hook of an organization, with hook id and options
|
||||||
|
@ -162,6 +193,16 @@ func (c *Client) EditOrgHook(org string, id int64, opt EditHookOption) (*Respons
|
||||||
return resp, err
|
return resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EditMyHook modify one hook of the authenticated user, with hook id and options
|
||||||
|
func (c *Client) EditMyHook(id int64, opt EditHookOption) (*Response, error) {
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, resp, err := c.getResponse("PATCH", fmt.Sprintf("/user/hooks/%d", id), jsonHeader, bytes.NewReader(body))
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
// EditRepoHook modify one hook of a repository, with hook id and options
|
// EditRepoHook modify one hook of a repository, with hook id and options
|
||||||
func (c *Client) EditRepoHook(user, repo string, id int64, opt EditHookOption) (*Response, error) {
|
func (c *Client) EditRepoHook(user, repo string, id int64, opt EditHookOption) (*Response, error) {
|
||||||
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
@ -184,6 +225,12 @@ func (c *Client) DeleteOrgHook(org string, id int64) (*Response, error) {
|
||||||
return resp, err
|
return resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeleteMyHook delete one hook from the authenticated user, with hook id
|
||||||
|
func (c *Client) DeleteMyHook(id int64) (*Response, error) {
|
||||||
|
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/user/hooks/%d", id), nil, nil)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
// DeleteRepoHook delete one hook from a repository, with hook id
|
// DeleteRepoHook delete one hook from a repository, with hook id
|
||||||
func (c *Client) DeleteRepoHook(user, repo string, id int64) (*Response, error) {
|
func (c *Client) DeleteRepoHook(user, repo string, id int64) (*Response, error) {
|
||||||
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
|
|
@ -68,14 +68,14 @@ func TestLabels(t *testing.T) {
|
||||||
assert.EqualValues(t, labelTwo, label)
|
assert.EqualValues(t, labelTwo, label)
|
||||||
|
|
||||||
label, _, err = c.EditLabel(repo.Owner.UserName, repo.Name, labelTwo.ID, EditLabelOption{
|
label, _, err = c.EditLabel(repo.Owner.UserName, repo.Name, labelTwo.ID, EditLabelOption{
|
||||||
Color: OptionalString("#0E0175"),
|
Color: OptionalString("#0e0175"),
|
||||||
Description: OptionalString("blueish"),
|
Description: OptionalString("blueish"),
|
||||||
})
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.EqualValues(t, &Label{
|
assert.EqualValues(t, &Label{
|
||||||
ID: labelTwo.ID,
|
ID: labelTwo.ID,
|
||||||
Name: labelTwo.Name,
|
Name: labelTwo.Name,
|
||||||
Color: "0E0175",
|
Color: "0e0175",
|
||||||
Description: "blueish",
|
Description: "blueish",
|
||||||
URL: labelTwo.URL,
|
URL: labelTwo.URL,
|
||||||
}, label)
|
}, label)
|
||||||
|
|
|
@ -43,7 +43,7 @@ func TestMilestones(t *testing.T) {
|
||||||
// ListRepoMilestones
|
// ListRepoMilestones
|
||||||
ml, _, err := c.ListRepoMilestones(repo.Owner.UserName, repo.Name, ListMilestoneOption{})
|
ml, _, err := c.ListRepoMilestones(repo.Owner.UserName, repo.Name, ListMilestoneOption{})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Len(t, ml, 2)
|
assert.Len(t, ml, 3)
|
||||||
ml, _, err = c.ListRepoMilestones(repo.Owner.UserName, repo.Name, ListMilestoneOption{State: StateClosed})
|
ml, _, err = c.ListRepoMilestones(repo.Owner.UserName, repo.Name, ListMilestoneOption{State: StateClosed})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Len(t, ml, 1)
|
assert.Len(t, ml, 1)
|
||||||
|
|
|
@ -19,7 +19,7 @@ func TestIssue(t *testing.T) {
|
||||||
|
|
||||||
createIssue(t, c)
|
createIssue(t, c)
|
||||||
// Little sleep in order to give some time for gitea to properly store all information on database. Without this sleep, CI is a bit unstable
|
// Little sleep in order to give some time for gitea to properly store all information on database. Without this sleep, CI is a bit unstable
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(200 * time.Millisecond)
|
||||||
editIssues(t, c)
|
editIssues(t, c)
|
||||||
listIssues(t, c)
|
listIssues(t, c)
|
||||||
deleteIssue(t, c)
|
deleteIssue(t, c)
|
||||||
|
@ -62,7 +62,7 @@ func deleteIssue(t *testing.T, c *Client) {
|
||||||
|
|
||||||
func editIssues(t *testing.T, c *Client) {
|
func editIssues(t *testing.T, c *Client) {
|
||||||
log.Println("== TestEditIssues ==")
|
log.Println("== TestEditIssues ==")
|
||||||
il, _, err := c.ListIssues(ListIssueOption{KeyWord: "soon"})
|
il, _, err := c.ListIssues(ListIssueOption{KeyWord: "soon!"})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
issue, _, err := c.GetIssue(il[0].Poster.UserName, il[0].Repository.Name, il[0].Index)
|
issue, _, err := c.GetIssue(il[0].Poster.UserName, il[0].Repository.Name, il[0].Index)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
|
@ -46,7 +46,7 @@ func TestNotifications(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
issue, _, err := c.CreateIssue(repoB.Owner.UserName, repoB.Name, CreateIssueOption{Title: "B Issue", Closed: false})
|
issue, _, err := c.CreateIssue(repoB.Owner.UserName, repoB.Name, CreateIssueOption{Title: "B Issue", Closed: false})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
time.Sleep(time.Second * 1)
|
time.Sleep(time.Second * 5)
|
||||||
|
|
||||||
// CheckNotifications of user2
|
// CheckNotifications of user2
|
||||||
c.sudo = user2.UserName
|
c.sudo = user2.UserName
|
||||||
|
@ -101,7 +101,7 @@ func TestNotifications(t *testing.T) {
|
||||||
c.sudo = ""
|
c.sudo = ""
|
||||||
_, _, err = c.EditIssue(repoB.Owner.UserName, repoB.Name, issue.Index, EditIssueOption{State: &iState})
|
_, _, err = c.EditIssue(repoB.Owner.UserName, repoB.Name, issue.Index, EditIssueOption{State: &iState})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
time.Sleep(time.Second * 1)
|
time.Sleep(time.Second * 5)
|
||||||
|
|
||||||
c.sudo = user2.UserName
|
c.sudo = user2.UserName
|
||||||
nList, _, err = c.ListNotifications(ListNotificationOptions{})
|
nList, _, err = c.ListNotifications(ListNotificationOptions{})
|
||||||
|
@ -120,18 +120,17 @@ func TestNotifications(t *testing.T) {
|
||||||
notifications, _, err = c.ReadNotifications(MarkNotificationOptions{})
|
notifications, _, err = c.ReadNotifications(MarkNotificationOptions{})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Len(t, notifications, 2)
|
assert.Len(t, notifications, 2)
|
||||||
_, _ = c.DeleteRepo("test01", "Reviews")
|
|
||||||
nList, _, err = c.ListNotifications(ListNotificationOptions{Status: []NotifyStatus{NotifyStatusRead}})
|
nList, _, err = c.ListNotifications(ListNotificationOptions{Status: []NotifyStatus{NotifyStatusRead}})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Len(t, nList, 2)
|
if assert.Len(t, nList, 2) {
|
||||||
|
notification, _, err := c.ReadNotification(nList[0].ID, NotifyStatusPinned)
|
||||||
|
assert.EqualValues(t, notification.ID, nList[0].ID)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
notification, _, err := c.ReadNotification(nList[0].ID, NotifyStatusPinned)
|
notification, _, err = c.ReadNotification(nList[1].ID, NotifyStatusUnread)
|
||||||
assert.EqualValues(t, notification.ID, nList[0].ID)
|
assert.EqualValues(t, notification.ID, nList[1].ID)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
notification, _, err = c.ReadNotification(nList[1].ID, NotifyStatusUnread)
|
|
||||||
assert.EqualValues(t, notification.ID, nList[1].ID)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
nList, _, err = c.ListNotifications(ListNotificationOptions{Status: []NotifyStatus{NotifyStatusPinned, NotifyStatusUnread}})
|
nList, _, err = c.ListNotifications(ListNotificationOptions{Status: []NotifyStatus{NotifyStatusPinned, NotifyStatusUnread}})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
if assert.Len(t, nList, 2) {
|
if assert.Len(t, nList, 2) {
|
||||||
|
|
|
@ -93,7 +93,7 @@ func (opt CreateOrgOption) Validate() error {
|
||||||
return fmt.Errorf("empty org name")
|
return fmt.Errorf("empty org name")
|
||||||
}
|
}
|
||||||
if len(opt.Visibility) != 0 && !checkVisibilityOpt(opt.Visibility) {
|
if len(opt.Visibility) != 0 && !checkVisibilityOpt(opt.Visibility) {
|
||||||
return fmt.Errorf("infalid bisibility option")
|
return fmt.Errorf("invalid visibility option")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -124,7 +124,7 @@ type EditOrgOption struct {
|
||||||
// Validate the EditOrgOption struct
|
// Validate the EditOrgOption struct
|
||||||
func (opt EditOrgOption) Validate() error {
|
func (opt EditOrgOption) Validate() error {
|
||||||
if len(opt.Visibility) != 0 && !checkVisibilityOpt(opt.Visibility) {
|
if len(opt.Visibility) != 0 && !checkVisibilityOpt(opt.Visibility) {
|
||||||
return fmt.Errorf("infalid bisibility option")
|
return fmt.Errorf("invalid visibility option")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,16 +5,19 @@
|
||||||
package gitea
|
package gitea
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ListOrgMembershipOption list OrgMembership options
|
// ListOrgActionSecretOption list OrgActionSecret options
|
||||||
type ListOrgActionSecretOption struct {
|
type ListOrgActionSecretOption struct {
|
||||||
ListOptions
|
ListOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListOrgMembership list an organization's members
|
// ListOrgActionSecret list an organization's secrets
|
||||||
func (c *Client) ListOrgActionSecret(org string, opt ListOrgActionSecretOption) ([]*Secret, *Response, error) {
|
func (c *Client) ListOrgActionSecret(org string, opt ListOrgActionSecretOption) ([]*Secret, *Response, error) {
|
||||||
if err := escapeValidatePathSegments(&org); err != nil {
|
if err := escapeValidatePathSegments(&org); err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
|
@ -27,3 +30,58 @@ func (c *Client) ListOrgActionSecret(org string, opt ListOrgActionSecretOption)
|
||||||
resp, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, &secrets)
|
resp, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, &secrets)
|
||||||
return secrets, resp, err
|
return secrets, resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateSecretOption represents the options for creating a secret.
|
||||||
|
type CreateSecretOption struct {
|
||||||
|
Name string `json:"name"` // Name is the name of the secret.
|
||||||
|
Data string `json:"data"` // Data is the data of the secret.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate checks if the CreateSecretOption is valid.
|
||||||
|
// It returns an error if any of the validation checks fail.
|
||||||
|
func (opt *CreateSecretOption) Validate() error {
|
||||||
|
if len(opt.Name) == 0 {
|
||||||
|
return fmt.Errorf("name required")
|
||||||
|
}
|
||||||
|
if len(opt.Name) > 30 {
|
||||||
|
return fmt.Errorf("name to long")
|
||||||
|
}
|
||||||
|
if len(opt.Data) == 0 {
|
||||||
|
return fmt.Errorf("data required")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateOrgActionSecret creates a secret for the specified organization in the Gitea Actions.
|
||||||
|
// It takes the organization name and the secret options as parameters.
|
||||||
|
// The function returns the HTTP response and an error, if any.
|
||||||
|
func (c *Client) CreateOrgActionSecret(org string, opt CreateSecretOption) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&org); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := (&opt).Validate(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
status, resp, err := c.getStatusCode("PUT", fmt.Sprintf("/orgs/%s/actions/secrets/%s", org, opt.Name), jsonHeader, bytes.NewReader(body))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch status {
|
||||||
|
case http.StatusCreated:
|
||||||
|
return resp, nil
|
||||||
|
case http.StatusNoContent:
|
||||||
|
return resp, nil
|
||||||
|
case http.StatusNotFound:
|
||||||
|
return resp, fmt.Errorf("forbidden")
|
||||||
|
case http.StatusBadRequest:
|
||||||
|
return resp, fmt.Errorf("bad request")
|
||||||
|
default:
|
||||||
|
return resp, fmt.Errorf("unexpected Status: %d", status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
39
gitea/org_action_test.go
Normal file
39
gitea/org_action_test.go
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
// Copyright 2024 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 (
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCreateOrgActionSecret(t *testing.T) {
|
||||||
|
log.Println("== TestCreateOrgActionSecret ==")
|
||||||
|
c := newTestClient()
|
||||||
|
|
||||||
|
user := createTestUser(t, "org_action_user", c)
|
||||||
|
c.SetSudo(user.UserName)
|
||||||
|
newOrg, _, err := c.CreateOrg(CreateOrgOption{Name: "ActionOrg"})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, newOrg)
|
||||||
|
|
||||||
|
// create secret
|
||||||
|
resp, err := c.CreateOrgActionSecret(newOrg.UserName, CreateSecretOption{Name: "test", Data: "test"})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, http.StatusCreated, resp.StatusCode)
|
||||||
|
|
||||||
|
// update secret
|
||||||
|
resp, err = c.CreateOrgActionSecret(newOrg.UserName, CreateSecretOption{Name: "test", Data: "test2"})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, http.StatusNoContent, resp.StatusCode)
|
||||||
|
|
||||||
|
// list secrets
|
||||||
|
secrets, _, err := c.ListOrgActionSecret(newOrg.UserName, ListOrgActionSecretOption{})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Len(t, secrets, 1)
|
||||||
|
}
|
|
@ -45,6 +45,8 @@ const (
|
||||||
RepoUnitProjects RepoUnitType = "repo.projects"
|
RepoUnitProjects RepoUnitType = "repo.projects"
|
||||||
// RepoUnitPackages represents packages of a repository
|
// RepoUnitPackages represents packages of a repository
|
||||||
RepoUnitPackages RepoUnitType = "repo.packages"
|
RepoUnitPackages RepoUnitType = "repo.packages"
|
||||||
|
// RepoUnitActions represents actions of a repository
|
||||||
|
RepoUnitActions RepoUnitType = "repo.actions"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ListTeamsOptions options for listing teams
|
// ListTeamsOptions options for listing teams
|
||||||
|
|
|
@ -16,7 +16,7 @@ type Package struct {
|
||||||
// the package's owner
|
// the package's owner
|
||||||
Owner User `json:"owner"`
|
Owner User `json:"owner"`
|
||||||
// the repo this package belongs to (if any)
|
// the repo this package belongs to (if any)
|
||||||
Repository *string `json:"repository"`
|
Repository *Repository `json:"repository"`
|
||||||
// the package's creator
|
// the package's creator
|
||||||
Creator User `json:"creator"`
|
Creator User `json:"creator"`
|
||||||
// the type of package:
|
// the type of package:
|
||||||
|
|
|
@ -78,6 +78,18 @@ func (c *Client) GetRelease(owner, repo string, id int64) (*Release, *Response,
|
||||||
return r, resp, err
|
return r, resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetLatestRelease get the latest release of a repository
|
||||||
|
func (c *Client) GetLatestRelease(owner, repo string) (*Release, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&owner, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
r := new(Release)
|
||||||
|
resp, err := c.getParsedResponse("GET",
|
||||||
|
fmt.Sprintf("/repos/%s/%s/releases/latest", owner, repo),
|
||||||
|
jsonHeader, nil, &r)
|
||||||
|
return r, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
// GetReleaseByTag get a release of a repository by tag
|
// GetReleaseByTag get a release of a repository by tag
|
||||||
func (c *Client) GetReleaseByTag(owner, repo, tag string) (*Release, *Response, error) {
|
func (c *Client) GetReleaseByTag(owner, repo, tag string) (*Release, *Response, error) {
|
||||||
if c.checkServerVersionGreaterThanOrEqual(version1_13_0) != nil {
|
if c.checkServerVersionGreaterThanOrEqual(version1_13_0) != nil {
|
||||||
|
@ -190,7 +202,7 @@ func (c *Client) fallbackGetReleaseByTag(owner, repo, tag string) (*Release, *Re
|
||||||
}
|
}
|
||||||
if len(rl) == 0 {
|
if len(rl) == 0 {
|
||||||
return nil,
|
return nil,
|
||||||
&Response{&http.Response{StatusCode: 404}},
|
newResponse(&http.Response{StatusCode: 404}),
|
||||||
fmt.Errorf("release with tag '%s' not found", tag)
|
fmt.Errorf("release with tag '%s' not found", tag)
|
||||||
}
|
}
|
||||||
for _, r := range rl {
|
for _, r := range rl {
|
||||||
|
|
|
@ -76,6 +76,11 @@ func TestRelease(t *testing.T) {
|
||||||
assert.EqualValues(t, false, r2.IsPrerelease)
|
assert.EqualValues(t, false, r2.IsPrerelease)
|
||||||
assert.EqualValues(t, r.Note, r2.Note)
|
assert.EqualValues(t, r.Note, r2.Note)
|
||||||
|
|
||||||
|
// GetLatestRelease
|
||||||
|
r3, _, err := c.GetLatestRelease(repo.Owner.UserName, repo.Name)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.EqualValues(t, r2, r3)
|
||||||
|
|
||||||
// DeleteRelease
|
// DeleteRelease
|
||||||
_, err = c.DeleteRelease(repo.Owner.UserName, repo.Name, r.ID)
|
_, err = c.DeleteRelease(repo.Owner.UserName, repo.Name, r.ID)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
|
@ -85,6 +85,9 @@ type Repository struct {
|
||||||
ExternalWiki *ExternalWiki `json:"external_wiki,omitempty"`
|
ExternalWiki *ExternalWiki `json:"external_wiki,omitempty"`
|
||||||
HasPullRequests bool `json:"has_pull_requests"`
|
HasPullRequests bool `json:"has_pull_requests"`
|
||||||
HasProjects bool `json:"has_projects"`
|
HasProjects bool `json:"has_projects"`
|
||||||
|
HasReleases bool `json:"has_releases,omitempty"`
|
||||||
|
HasPackages bool `json:"has_packages,omitempty"`
|
||||||
|
HasActions bool `json:"has_actions,omitempty"`
|
||||||
IgnoreWhitespaceConflicts bool `json:"ignore_whitespace_conflicts"`
|
IgnoreWhitespaceConflicts bool `json:"ignore_whitespace_conflicts"`
|
||||||
AllowMerge bool `json:"allow_merge_commits"`
|
AllowMerge bool `json:"allow_merge_commits"`
|
||||||
AllowRebase bool `json:"allow_rebase"`
|
AllowRebase bool `json:"allow_rebase"`
|
||||||
|
@ -331,8 +334,8 @@ func (opt CreateRepoOption) Validate(c *Client) error {
|
||||||
if len(opt.Name) > 100 {
|
if len(opt.Name) > 100 {
|
||||||
return fmt.Errorf("name has more than 100 chars")
|
return fmt.Errorf("name has more than 100 chars")
|
||||||
}
|
}
|
||||||
if len(opt.Description) > 255 {
|
if len(opt.Description) > 2048 {
|
||||||
return fmt.Errorf("description has more than 255 chars")
|
return fmt.Errorf("description has more than 2048 chars")
|
||||||
}
|
}
|
||||||
if len(opt.DefaultBranch) > 100 {
|
if len(opt.DefaultBranch) > 100 {
|
||||||
return fmt.Errorf("default branch name has more than 100 chars")
|
return fmt.Errorf("default branch name has more than 100 chars")
|
||||||
|
@ -423,6 +426,12 @@ type EditRepoOption struct {
|
||||||
HasPullRequests *bool `json:"has_pull_requests,omitempty"`
|
HasPullRequests *bool `json:"has_pull_requests,omitempty"`
|
||||||
// either `true` to enable project unit, or `false` to disable them.
|
// either `true` to enable project unit, or `false` to disable them.
|
||||||
HasProjects *bool `json:"has_projects,omitempty"`
|
HasProjects *bool `json:"has_projects,omitempty"`
|
||||||
|
// either `true` to enable release, or `false` to disable them.
|
||||||
|
HasReleases *bool `json:"has_releases,omitempty"`
|
||||||
|
// either `true` to enable packages, or `false` to disable them.
|
||||||
|
HasPackages *bool `json:"has_packages,omitempty"`
|
||||||
|
// either `true` to enable actions, or `false` to disable them.
|
||||||
|
HasActions *bool `json:"has_actions,omitempty"`
|
||||||
// either `true` to ignore whitespace for conflicts, or `false` to not ignore whitespace. `has_pull_requests` must be `true`.
|
// either `true` to ignore whitespace for conflicts, or `false` to not ignore whitespace. `has_pull_requests` must be `true`.
|
||||||
IgnoreWhitespaceConflicts *bool `json:"ignore_whitespace_conflicts,omitempty"`
|
IgnoreWhitespaceConflicts *bool `json:"ignore_whitespace_conflicts,omitempty"`
|
||||||
// either `true` to allow merging pull requests with a merge commit, or `false` to prevent merging pull requests with merge commits. `has_pull_requests` must be `true`.
|
// either `true` to allow merging pull requests with a merge commit, or `false` to prevent merging pull requests with merge commits. `has_pull_requests` must be `true`.
|
||||||
|
|
66
gitea/repo_action.go
Normal file
66
gitea/repo_action.go
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
// Copyright 2024 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"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ListRepoActionSecretOption list RepoActionSecret options
|
||||||
|
type ListRepoActionSecretOption struct {
|
||||||
|
ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListRepoActionSecret list a repository's secrets
|
||||||
|
func (c *Client) ListRepoActionSecret(user, repo string, opt ListRepoActionSecretOption) ([]*Secret, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
opt.setDefaults()
|
||||||
|
secrets := make([]*Secret, 0, opt.PageSize)
|
||||||
|
|
||||||
|
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/actions/secrets", user, repo))
|
||||||
|
link.RawQuery = opt.getURLQuery().Encode()
|
||||||
|
resp, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, &secrets)
|
||||||
|
return secrets, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateRepoActionSecret creates a secret for the specified repository in the Gitea Actions.
|
||||||
|
// It takes the organization name and the secret options as parameters.
|
||||||
|
// The function returns the HTTP response and an error, if any.
|
||||||
|
func (c *Client) CreateRepoActionSecret(user, repo string, opt CreateSecretOption) (*Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := (&opt).Validate(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
status, resp, err := c.getStatusCode("PUT", fmt.Sprintf("/repos/%s/%s/actions/secrets/%s", user, repo, opt.Name), jsonHeader, bytes.NewReader(body))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch status {
|
||||||
|
case http.StatusCreated:
|
||||||
|
return resp, nil
|
||||||
|
case http.StatusNoContent:
|
||||||
|
return resp, nil
|
||||||
|
case http.StatusNotFound:
|
||||||
|
return resp, fmt.Errorf("forbidden")
|
||||||
|
case http.StatusBadRequest:
|
||||||
|
return resp, fmt.Errorf("bad request")
|
||||||
|
default:
|
||||||
|
return resp, fmt.Errorf("unexpected Status: %d", status)
|
||||||
|
}
|
||||||
|
}
|
41
gitea/repo_action_test.go
Normal file
41
gitea/repo_action_test.go
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
// Copyright 2024 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 (
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCreateRepoActionSecret(t *testing.T) {
|
||||||
|
log.Println("== TestCreateRepoActionSecret ==")
|
||||||
|
c := newTestClient()
|
||||||
|
|
||||||
|
user := createTestUser(t, "repo_action_user", c)
|
||||||
|
c.SetSudo(user.UserName)
|
||||||
|
newRepo, _, err := c.CreateRepo(CreateRepoOption{
|
||||||
|
Name: "test",
|
||||||
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, newRepo)
|
||||||
|
|
||||||
|
// create secret
|
||||||
|
resp, err := c.CreateRepoActionSecret(newRepo.Owner.UserName, newRepo.Name, CreateSecretOption{Name: "test", Data: "test"})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, http.StatusCreated, resp.StatusCode)
|
||||||
|
|
||||||
|
// update secret
|
||||||
|
resp, err = c.CreateRepoActionSecret(newRepo.Owner.UserName, newRepo.Name, CreateSecretOption{Name: "test", Data: "test2"})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, http.StatusNoContent, resp.StatusCode)
|
||||||
|
|
||||||
|
// list secrets
|
||||||
|
secrets, _, err := c.ListRepoActionSecret(newRepo.Owner.UserName, newRepo.Name, ListRepoActionSecretOption{})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Len(t, secrets, 1)
|
||||||
|
}
|
|
@ -6,8 +6,8 @@ package gitea
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"sort"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
@ -21,22 +21,23 @@ func TestRepoBranches(t *testing.T) {
|
||||||
if repo == nil {
|
if repo == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
time.Sleep(1 * time.Second)
|
||||||
bl, _, err := c.ListRepoBranches(repo.Owner.UserName, repo.Name, ListRepoBranchesOptions{})
|
bl, _, err := c.ListRepoBranches(repo.Owner.UserName, repo.Name, ListRepoBranchesOptions{})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Len(t, bl, 3)
|
assert.Len(t, bl, 3)
|
||||||
|
|
||||||
sort.Slice(bl, func(i, j int) bool {
|
branchNames := make([]string, len(bl))
|
||||||
return bl[i].Name < bl[j].Name
|
branches := make(map[string]Branch, len(bl))
|
||||||
})
|
for index, branch := range bl {
|
||||||
assert.EqualValues(t, "feature", bl[0].Name)
|
branchNames[index] = branch.Name
|
||||||
assert.EqualValues(t, "main", bl[1].Name)
|
branches[branch.Name] = *branch
|
||||||
assert.EqualValues(t, "update", bl[2].Name)
|
}
|
||||||
|
assert.ElementsMatch(t, []string{"feature", "main", "update"}, branchNames)
|
||||||
|
|
||||||
b, _, err := c.GetRepoBranch(repo.Owner.UserName, repo.Name, "update")
|
b, _, err := c.GetRepoBranch(repo.Owner.UserName, repo.Name, "update")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.EqualValues(t, bl[2].Commit.ID, b.Commit.ID)
|
assert.EqualValues(t, branches["update"].Commit.ID, b.Commit.ID)
|
||||||
assert.EqualValues(t, bl[2].Commit.Added, b.Commit.Added)
|
assert.EqualValues(t, branches["update"].Commit.Added, b.Commit.Added)
|
||||||
|
|
||||||
s, _, err := c.DeleteRepoBranch(repo.Owner.UserName, repo.Name, "main")
|
s, _, err := c.DeleteRepoBranch(repo.Owner.UserName, repo.Name, "main")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
33
gitea/repo_compare.go
Normal file
33
gitea/repo_compare.go
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
// Copyright 2024 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"
|
||||||
|
|
||||||
|
// Compare represents a comparison between two commits.
|
||||||
|
type Compare struct {
|
||||||
|
TotalCommits int `json:"total_commits"` // Total number of commits in the comparison.
|
||||||
|
Commits []*Commit `json:"commits"` // List of commits in the comparison.
|
||||||
|
}
|
||||||
|
|
||||||
|
// CompareCommits compares two commits in a repository.
|
||||||
|
func (c *Client) CompareCommits(user, repo, prev, current string) (*Compare, *Response, error) {
|
||||||
|
if err := c.checkServerVersionGreaterThanOrEqual(version1_22_0); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo, &prev, ¤t); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
basehead := fmt.Sprintf("%s...%s", prev, current)
|
||||||
|
|
||||||
|
apiResp := new(Compare)
|
||||||
|
resp, err := c.getParsedResponse(
|
||||||
|
"GET",
|
||||||
|
fmt.Sprintf("/repos/%s/%s/compare/%s", user, repo, basehead),
|
||||||
|
nil, nil, apiResp,
|
||||||
|
)
|
||||||
|
return apiResp, resp, err
|
||||||
|
}
|
|
@ -10,7 +10,6 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
@ -128,7 +127,7 @@ func (c *Client) GetFile(owner, repo, ref, filepath string, resolveLFS ...bool)
|
||||||
}
|
}
|
||||||
defer reader.Close()
|
defer reader.Close()
|
||||||
|
|
||||||
data, err2 := ioutil.ReadAll(reader)
|
data, err2 := io.ReadAll(reader)
|
||||||
if err2 != nil {
|
if err2 != nil {
|
||||||
return nil, resp, err2
|
return nil, resp, err2
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,7 @@ func (opt *MigrateRepoOption) Validate(c *Client) error {
|
||||||
} else if len(opt.RepoName) > 100 {
|
} else if len(opt.RepoName) > 100 {
|
||||||
return fmt.Errorf("RepoName to long")
|
return fmt.Errorf("RepoName to long")
|
||||||
}
|
}
|
||||||
if len(opt.Description) > 255 {
|
if len(opt.Description) > 2048 {
|
||||||
return fmt.Errorf("Description to long")
|
return fmt.Errorf("Description to long")
|
||||||
}
|
}
|
||||||
switch opt.Service {
|
switch opt.Service {
|
||||||
|
|
45
gitea/repo_mirror.go
Normal file
45
gitea/repo_mirror.go
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
// Copyright 2023 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"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CreatePushMirrorOption struct {
|
||||||
|
Interval string `json:"interval"`
|
||||||
|
RemoteAddress string `json:"remote_address"`
|
||||||
|
RemotePassword string `json:"remote_password"`
|
||||||
|
RemoteUsername string `json:"remote_username"`
|
||||||
|
SyncONCommit bool `json:"sync_on_commit"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// PushMirrorResponse returns a git push mirror
|
||||||
|
type PushMirrorResponse struct {
|
||||||
|
Created string `json:"created"`
|
||||||
|
Interval string `json:"interval"`
|
||||||
|
LastError string `json:"last_error"`
|
||||||
|
LastUpdate string `json:"last_update"`
|
||||||
|
RemoteAddress string `json:"remote_address"`
|
||||||
|
RemoteName string `json:"remote_name"`
|
||||||
|
RepoName string `json:"repo_name"`
|
||||||
|
SyncONCommit bool `json:"sync_on_commit"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// PushMirrors add a push mirror to the repository
|
||||||
|
func (c *Client) PushMirrors(user, repo string, opt CreatePushMirrorOption) (*PushMirrorResponse, *Response, error) {
|
||||||
|
if err := escapeValidatePathSegments(&user, &repo); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
body, err := json.Marshal(opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
pm := new(PushMirrorResponse)
|
||||||
|
resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/push_mirrors", user, repo), jsonHeader, bytes.NewReader(body), &pm)
|
||||||
|
return pm, resp, err
|
||||||
|
}
|
|
@ -65,7 +65,7 @@ func TestRepoMigrateAndLanguages(t *testing.T) {
|
||||||
assert.NotEqual(t, zeroTime, repoG.MirrorUpdated)
|
assert.NotEqual(t, zeroTime, repoG.MirrorUpdated)
|
||||||
|
|
||||||
log.Println("== TestRepoLanguages ==")
|
log.Println("== TestRepoLanguages ==")
|
||||||
time.Sleep(time.Second)
|
time.Sleep(time.Second * 2)
|
||||||
lang, _, err := c.GetRepoLanguages(repoM.Owner.UserName, repoM.Name)
|
lang, _, err := c.GetRepoLanguages(repoM.Owner.UserName, repoM.Name)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Len(t, lang, 2)
|
assert.Len(t, lang, 2)
|
||||||
|
|
|
@ -9,6 +9,8 @@ import "time"
|
||||||
type Secret struct {
|
type Secret struct {
|
||||||
// the secret's name
|
// the secret's name
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
// the secret's data
|
||||||
|
Data string `json:"data"`
|
||||||
// Date and Time of secret creation
|
// Date and Time of secret creation
|
||||||
Created time.Time `json:"created_at"`
|
Created time.Time `json:"created_at"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ func TestGetGlobalSettings(t *testing.T) {
|
||||||
}
|
}
|
||||||
assert.EqualValues(t, &GlobalAttachmentSettings{
|
assert.EqualValues(t, &GlobalAttachmentSettings{
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
MaxSize: 4,
|
MaxSize: 2048,
|
||||||
MaxFiles: 5,
|
MaxFiles: 5,
|
||||||
}, attachSettings)
|
}, attachSettings)
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,10 @@ type User struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
// the user's username
|
// the user's username
|
||||||
UserName string `json:"login"`
|
UserName string `json:"login"`
|
||||||
|
// The login_name of non local users (e.g. LDAP / OAuth / SMTP)
|
||||||
|
LoginName string `json:"login_name"`
|
||||||
|
// The ID of the Authentication Source for non local users.
|
||||||
|
SourceID int64 `json:"source_id"`
|
||||||
// the user's full name
|
// the user's full name
|
||||||
FullName string `json:"full_name"`
|
FullName string `json:"full_name"`
|
||||||
Email string `json:"email"`
|
Email string `json:"email"`
|
||||||
|
|
|
@ -19,7 +19,7 @@ func TestUserSettings(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotNil(t, userConf)
|
assert.NotNil(t, userConf)
|
||||||
assert.EqualValues(t, UserSettings{
|
assert.EqualValues(t, UserSettings{
|
||||||
Theme: "auto",
|
Theme: "gitea-auto",
|
||||||
HideEmail: false,
|
HideEmail: false,
|
||||||
HideActivity: false,
|
HideActivity: false,
|
||||||
}, *userConf)
|
}, *userConf)
|
||||||
|
@ -33,7 +33,7 @@ func TestUserSettings(t *testing.T) {
|
||||||
assert.NotNil(t, userConf)
|
assert.NotNil(t, userConf)
|
||||||
assert.EqualValues(t, UserSettings{
|
assert.EqualValues(t, UserSettings{
|
||||||
FullName: "Admin User on Test",
|
FullName: "Admin User on Test",
|
||||||
Theme: "auto",
|
Theme: "gitea-auto",
|
||||||
Language: "de_de",
|
Language: "de_de",
|
||||||
HideEmail: true,
|
HideEmail: true,
|
||||||
HideActivity: false,
|
HideActivity: false,
|
||||||
|
|
|
@ -21,7 +21,7 @@ func TestMyUser(t *testing.T) {
|
||||||
assert.EqualValues(t, "test01", user.UserName)
|
assert.EqualValues(t, "test01", user.UserName)
|
||||||
assert.EqualValues(t, "test01@gitea.io", user.Email)
|
assert.EqualValues(t, "test01@gitea.io", user.Email)
|
||||||
assert.EqualValues(t, "", user.FullName)
|
assert.EqualValues(t, "", user.FullName)
|
||||||
assert.EqualValues(t, "https://secure.gravatar.com/avatar/d794373e882a68fb173cef817fb6180a?d=identicon", user.AvatarURL)
|
assert.EqualValues(t, "http://gitea:3000/avatars/d794373e882a68fb173cef817fb6180a", user.AvatarURL)
|
||||||
assert.True(t, user.IsAdmin)
|
assert.True(t, user.IsAdmin)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,14 +144,14 @@ func TestUserEmail(t *testing.T) {
|
||||||
el, _, err := c.ListEmails(ListEmailsOptions{})
|
el, _, err := c.ListEmails(ListEmailsOptions{})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Len(t, el, 1)
|
assert.Len(t, el, 1)
|
||||||
assert.EqualValues(t, "testuseremail@gitea.io", el[0].Email)
|
assert.EqualValues(t, "TestUserEmail@gitea.io", el[0].Email)
|
||||||
assert.True(t, el[0].Primary)
|
assert.True(t, el[0].Primary)
|
||||||
|
|
||||||
// AddEmail
|
// AddEmail
|
||||||
mails := []string{"wow@mail.send", "speed@mail.me"}
|
mails := []string{"wow@mail.send", "speed@mail.me"}
|
||||||
el, _, err = c.AddEmail(CreateEmailOption{Emails: mails})
|
el, _, err = c.AddEmail(CreateEmailOption{Emails: mails})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Len(t, el, 2)
|
assert.Len(t, el, 3)
|
||||||
_, _, err = c.AddEmail(CreateEmailOption{Emails: []string{mails[1]}})
|
_, _, err = c.AddEmail(CreateEmailOption{Emails: []string{mails[1]}})
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
el, _, err = c.ListEmails(ListEmailsOptions{})
|
el, _, err = c.ListEmails(ListEmailsOptions{})
|
||||||
|
|
|
@ -69,6 +69,7 @@ var (
|
||||||
version1_15_0 = version.Must(version.NewVersion("1.15.0"))
|
version1_15_0 = version.Must(version.NewVersion("1.15.0"))
|
||||||
version1_16_0 = version.Must(version.NewVersion("1.16.0"))
|
version1_16_0 = version.Must(version.NewVersion("1.16.0"))
|
||||||
version1_17_0 = version.Must(version.NewVersion("1.17.0"))
|
version1_17_0 = version.Must(version.NewVersion("1.17.0"))
|
||||||
|
version1_22_0 = version.Must(version.NewVersion("1.22.0"))
|
||||||
)
|
)
|
||||||
|
|
||||||
// ErrUnknownVersion is an unknown version from the API
|
// ErrUnknownVersion is an unknown version from the API
|
||||||
|
@ -77,14 +78,13 @@ type ErrUnknownVersion struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Error fulfills error
|
// Error fulfills error
|
||||||
func (e ErrUnknownVersion) Error() string {
|
func (e *ErrUnknownVersion) Error() string {
|
||||||
return fmt.Sprintf("unknown version: %s", e.raw)
|
return fmt.Sprintf("unknown version: %s", e.raw)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_ ErrUnknownVersion) Is(target error) bool {
|
func (*ErrUnknownVersion) Is(target error) bool {
|
||||||
_, ok1 := target.(*ErrUnknownVersion)
|
_, ok := target.(*ErrUnknownVersion)
|
||||||
_, ok2 := target.(ErrUnknownVersion)
|
return ok
|
||||||
return ok1 || ok2
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkServerVersionGreaterThanOrEqual is the canonical way in the SDK to check for versions for API compatibility reasons
|
// checkServerVersionGreaterThanOrEqual is the canonical way in the SDK to check for versions for API compatibility reasons
|
||||||
|
|
Loading…
Reference in a new issue