Compare commits

...

15 Commits

Author SHA1 Message Date
appleboy 8110db1e6d feat: implement Gitea Repo Action Secrets Management (#662)
- Add imports for "bytes", "encoding/json", and "net/http" in `repo_action.go`
- Implement `CreateRepoActionSecret` function to create a secret for a repository in Gitea Actions
- Add a new test file `repo_action_test.go` with tests for creating, updating, and listing repository action secrets

<img width="518" alt="image" src="/attachments/c8e457c4-395f-4ffe-8482-0b7f5d2541cb">

Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
Reviewed-on: https://gitea.com/gitea/go-sdk/pulls/662
Reviewed-by: techknowlogick <techknowlogick@noreply.gitea.com>
Co-authored-by: appleboy <appleboy.tw@gmail.com>
Co-committed-by: appleboy <appleboy.tw@gmail.com>
2024-05-08 09:29:30 +00:00
Bo-Yi Wu 83c73e79a5 ci: update Gitea testing configurations for 1.22 release (#663)
- Update Gitea image version to `1.22.0-rc1` in testing workflow
- Increase the number of milestones to be checked in the test from `2` to `3`
- Modify the theme setting from `auto` to `gitea-auto` in user settings test
- Update the Avatar URL in user test to use `http://gitea:3000/avatars/` instead of `https://secure.gravatar.com/avatar/`
- Increase the number of user emails to be checked in the test from `2` to `3`

Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>

Reviewed-on: https://gitea.com/gitea/go-sdk/pulls/663
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: Bo-Yi Wu <appleboy.tw@gmail.com>
Co-committed-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2024-05-08 01:53:26 +00:00
Bo-Yi Wu 6c0938dc15 feat: implement organization action secret creation (#661)
- Add `bytes` and `encoding/json` imports to `org_action.go`
- Implement `CreateSecretOption` struct with validation in `org_action.go`
- Add `CreateOrgActionSecret` function to create or update organization secrets in `org_action.go`
- Create new test file `org_action_test.go` with tests for creating and updating organization secrets
- Add `Data` field to `Secret` struct in `secret.go`

Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
Reviewed-on: https://gitea.com/gitea/go-sdk/pulls/661
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: Bo-Yi Wu <appleboy.tw@gmail.com>
Co-committed-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2024-05-03 13:52:34 +00:00
tobiasbp 0a99bda0cb Get fields loginName & SourceID for users (#654)
This _PR_ adds the following fields to the _User_ struct:

-  _LoginName_: Currently returned by the Gitea API.
- _SourceID_: [Scheduled to be returned by the Gitea API as of version 1.22.0](https://github.com/go-gitea/gitea/pull/29718).

The fields are used for users with non-local Authentication Sources (LDAP, oAuth etc.).

Co-authored-by: tobias.petersen <tobias.petersen@unity3d.com>
Co-authored-by: appleboy <appleboy.tw@gmail.com>
Co-authored-by: techknowlogick <techknowlogick@noreply.gitea.com>
Reviewed-on: https://gitea.com/gitea/go-sdk/pulls/654
Reviewed-by: appleboy <appleboy.tw@gmail.com>
Reviewed-by: techknowlogick <techknowlogick@noreply.gitea.com>
Co-authored-by: tobiasbp <tobiasbp@noreply.gitea.com>
Co-committed-by: tobiasbp <tobiasbp@noreply.gitea.com>
2024-05-02 17:33:09 +00:00
Bo-Yi Wu 36723e11c8 feat(repo): support list of repo secrets (#660)
- Update comment to correctly describe `ListOrgActionSecretOption` as listing organization secrets instead of members
- Add new file `repo_action.go` with functionality to list a repository's secrets including the structure and API call

Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>

Reviewed-on: https://gitea.com/gitea/go-sdk/pulls/660
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: Bo-Yi Wu <appleboy.tw@gmail.com>
Co-committed-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2024-05-02 06:04:51 +00:00
appleboy a991e370c5 feat: implement commit comparison feature in Gitea client (#659)
See the API: https://github.com/go-gitea/gitea/pull/30349

- Add a new file `repo_compare.go` with package `gitea` and `Compare` struct
- Implement `CompareCommits` method in `Client` struct in `repo_compare.go`
- Add `version1_22_0` constant in `version.go`

Signed-off-by: appleboy <appleboy.tw@gmail.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Reviewed-on: https://gitea.com/gitea/go-sdk/pulls/659
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: appleboy <appleboy.tw@gmail.com>
Co-committed-by: appleboy <appleboy.tw@gmail.com>
2024-04-17 05:47:25 +00:00
appleboy bb25c989a0 chore: update Go module dependencies to latest versions (#658)
- Update the version of `golang.org/x/crypto` from `v0.17.0` to `v0.22.0` in `go.mod`
- Update the version of `golang.org/x/sys` from `v0.15.0` to `v0.19.0` in `go.mod`

Signed-off-by: appleboy <appleboy.tw@gmail.com>

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Reviewed-on: https://gitea.com/gitea/go-sdk/pulls/658
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: appleboy <appleboy.tw@gmail.com>
Co-committed-by: appleboy <appleboy.tw@gmail.com>
2024-04-16 08:15:01 +00:00
appleboy 18e5522f90 ci: update Gitea versions in workflows and Makefile (#657)
- Update Gitea Docker image version from `1.21.8` to `1.21.10` in testing workflow
- Update Gitea version from `1.21.1` to `1.21.10` in Makefile

Signed-off-by: appleboy <appleboy.tw@gmail.com>
Reviewed-on: https://gitea.com/gitea/go-sdk/pulls/657
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: appleboy <appleboy.tw@gmail.com>
Co-committed-by: appleboy <appleboy.tw@gmail.com>
2024-04-14 13:09:31 +00:00
Lunny Xiao bad4de0196 Upgrade CI (#655)
Reviewed-on: https://gitea.com/gitea/go-sdk/pulls/655
2024-03-16 08:34:20 +00:00
rjhaverkamp 9ec1b82849 Fix typo in visibilty error (#653)
Reviewed-on: https://gitea.com/gitea/go-sdk/pulls/653
Reviewed-by: John Olheiser <jolheiser@noreply.gitea.com>
Co-authored-by: rjhaverkamp <rjhaverkamp@noreply.gitea.com>
Co-committed-by: rjhaverkamp <rjhaverkamp@noreply.gitea.com>
2024-02-28 00:12:39 +00:00
6543 bf71ec2fd9 Make only referenc of ErrUnknownVersion an error (#648)
just a refactor nit

Reviewed-on: https://gitea.com/gitea/go-sdk/pulls/648
Reviewed-by: John Olheiser <jolheiser@noreply.gitea.com>
2024-02-22 21:33:21 +00:00
Martijn van der Kleijn 001d5fad51 chore: Bump required Go version to 1.18 (#650)
Reasoning for the bump:
- Enforce (instead of assume) use of newer Go version to ensure presence of security fixes
- Enable use of more recent language features
- Go < 1.21 is EOL
- Testing workflow already uses >= 1.20

For sec fixes, see: https://go.dev/doc/devel/release#go1.21.minor

Signed-off-by: Martijn van der Kleijn <martijn.niji@gmail.com>
Reviewed-on: https://gitea.com/gitea/go-sdk/pulls/650
Reviewed-by: 6543 <6543@obermui.de>
Co-authored-by: Martijn van der Kleijn <martijn.niji@gmail.com>
Co-committed-by: Martijn van der Kleijn <martijn.niji@gmail.com>
2024-02-22 21:28:11 +00:00
diogo464 5d0143e4e7 fix: updated repository field in Package struct (#647)
The definition for `Package` in the most recent api switch the
repository field from a string to a `Repository`.
Without this fix api calls like ListPackages will fail to deserialize
the response.

Co-authored-by: diogo464 <diogo464@protonmail.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Reviewed-on: https://gitea.com/gitea/go-sdk/pulls/647
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
Reviewed-by: John Olheiser <jolheiser@noreply.gitea.com>
Co-authored-by: diogo464 <diogo464@noreply.gitea.com>
Co-committed-by: diogo464 <diogo464@noreply.gitea.com>
2024-01-29 05:38:16 +00:00
Simon Ser 53f735b911 Add support for user hooks (#644)
Reviewed-on: https://gitea.com/gitea/go-sdk/pulls/644
Reviewed-by: techknowlogick <techknowlogick@noreply.gitea.com>
Reviewed-by: John Olheiser <jolheiser@noreply.gitea.com>
Co-authored-by: Simon Ser <contact@emersion.fr>
Co-committed-by: Simon Ser <contact@emersion.fr>
2024-01-25 16:04:00 +00:00
Christian Groschupp 98b424a8af feat(release): add GetLatestRelease method (#639)
This PR adds the GetLatestRelease method to support the /repos/{owner}/{repo}/releases/latest endpoint.
ref: https://docs.gitea.com/api/1.20/#tag/repository/operation/repoGetLatestRelease

Resolves gitea/go-sdk#630

Co-authored-by: techknowlogick <techknowlogick@noreply.gitea.com>
Reviewed-on: https://gitea.com/gitea/go-sdk/pulls/639
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: Christian Groschupp <christian@groschupp.org>
Co-committed-by: Christian Groschupp <christian@groschupp.org>
2024-01-06 05:14:12 +00:00
26 changed files with 368 additions and 84 deletions

View File

@ -15,10 +15,10 @@ jobs:
GITEA_SDK_TEST_USERNAME: "test01"
GITEA_SDK_TEST_PASSWORD: "test01"
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v3
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: ">=1.20"
go-version: ">=1.21"
check-latest: true
- run: make clean
- run: make vet
@ -28,7 +28,7 @@ jobs:
- run: make test
services:
gitea:
image: gitea/gitea:1.18
image: gitea/gitea:1.22.0-rc1
cmd:
- bash
- -c

View File

@ -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
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)-
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Linux)
@ -72,7 +72,7 @@ vet:
cd gitea && $(GO) vet -vettool=gitea-vet $(PACKAGE)
.PHONY: ci-lint
ci-lint:
ci-lint:
@cd gitea/; echo -n "gofumpt ...";\
diff=$$($(GO) run $(GOFUMPT_PACKAGE) -extra -l .); \
if [ -n "$$diff" ]; then \

View File

@ -1,11 +1,18 @@
module code.gitea.io/sdk/gitea
go 1.13
go 1.18
require (
github.com/davidmz/go-pageant v1.0.2
github.com/go-fed/httpsig v1.1.0
github.com/hashicorp/go-version v1.6.0
github.com/stretchr/testify v1.7.0
golang.org/x/crypto v0.17.0
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
)

View File

@ -11,51 +11,23 @@ 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.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
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-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
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-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/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/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
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.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/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.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=

View File

@ -62,6 +62,14 @@ func (c *Client) ListOrgHooks(org string, opt ListHooksOptions) ([]*Hook, *Respo
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
func (c *Client) ListRepoHooks(user, repo string, opt ListHooksOptions) ([]*Hook, *Response, error) {
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
}
// 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
func (c *Client) GetRepoHook(user, repo string, id int64) (*Hook, *Response, error) {
if err := escapeValidatePathSegments(&user, &repo); err != nil {
@ -128,6 +143,20 @@ func (c *Client) CreateOrgHook(org string, opt CreateHookOption) (*Hook, *Respon
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
func (c *Client) CreateRepoHook(user, repo string, opt CreateHookOption) (*Hook, *Response, error) {
if err := escapeValidatePathSegments(&user, &repo); err != nil {
@ -164,6 +193,16 @@ func (c *Client) EditOrgHook(org string, id int64, opt EditHookOption) (*Respons
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
func (c *Client) EditRepoHook(user, repo string, id int64, opt EditHookOption) (*Response, error) {
if err := escapeValidatePathSegments(&user, &repo); err != nil {
@ -186,6 +225,12 @@ func (c *Client) DeleteOrgHook(org string, id int64) (*Response, error) {
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
func (c *Client) DeleteRepoHook(user, repo string, id int64) (*Response, error) {
if err := escapeValidatePathSegments(&user, &repo); err != nil {

View File

@ -68,14 +68,14 @@ func TestLabels(t *testing.T) {
assert.EqualValues(t, labelTwo, label)
label, _, err = c.EditLabel(repo.Owner.UserName, repo.Name, labelTwo.ID, EditLabelOption{
Color: OptionalString("#0E0175"),
Color: OptionalString("#0e0175"),
Description: OptionalString("blueish"),
})
assert.NoError(t, err)
assert.EqualValues(t, &Label{
ID: labelTwo.ID,
Name: labelTwo.Name,
Color: "0E0175",
Color: "0e0175",
Description: "blueish",
URL: labelTwo.URL,
}, label)

View File

@ -43,7 +43,7 @@ func TestMilestones(t *testing.T) {
// ListRepoMilestones
ml, _, err := c.ListRepoMilestones(repo.Owner.UserName, repo.Name, ListMilestoneOption{})
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})
assert.NoError(t, err)
assert.Len(t, ml, 1)

View File

@ -19,7 +19,7 @@ func TestIssue(t *testing.T) {
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
time.Sleep(100 * time.Millisecond)
time.Sleep(200 * time.Millisecond)
editIssues(t, c)
listIssues(t, c)
deleteIssue(t, c)
@ -62,7 +62,7 @@ func deleteIssue(t *testing.T, c *Client) {
func editIssues(t *testing.T, c *Client) {
log.Println("== TestEditIssues ==")
il, _, err := c.ListIssues(ListIssueOption{KeyWord: "soon"})
il, _, err := c.ListIssues(ListIssueOption{KeyWord: "soon!"})
assert.NoError(t, err)
issue, _, err := c.GetIssue(il[0].Poster.UserName, il[0].Repository.Name, il[0].Index)
assert.NoError(t, err)

View File

@ -46,7 +46,7 @@ func TestNotifications(t *testing.T) {
assert.NoError(t, err)
issue, _, err := c.CreateIssue(repoB.Owner.UserName, repoB.Name, CreateIssueOption{Title: "B Issue", Closed: false})
assert.NoError(t, err)
time.Sleep(time.Second * 1)
time.Sleep(time.Second * 5)
// CheckNotifications of user2
c.sudo = user2.UserName
@ -101,7 +101,7 @@ func TestNotifications(t *testing.T) {
c.sudo = ""
_, _, err = c.EditIssue(repoB.Owner.UserName, repoB.Name, issue.Index, EditIssueOption{State: &iState})
assert.NoError(t, err)
time.Sleep(time.Second * 1)
time.Sleep(time.Second * 5)
c.sudo = user2.UserName
nList, _, err = c.ListNotifications(ListNotificationOptions{})
@ -120,18 +120,17 @@ func TestNotifications(t *testing.T) {
notifications, _, err = c.ReadNotifications(MarkNotificationOptions{})
assert.NoError(t, err)
assert.Len(t, notifications, 2)
_, _ = c.DeleteRepo("test01", "Reviews")
nList, _, err = c.ListNotifications(ListNotificationOptions{Status: []NotifyStatus{NotifyStatusRead}})
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)
assert.EqualValues(t, notification.ID, nList[0].ID)
assert.NoError(t, err)
notification, _, err = c.ReadNotification(nList[1].ID, NotifyStatusUnread)
assert.EqualValues(t, notification.ID, nList[1].ID)
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}})
assert.NoError(t, err)
if assert.Len(t, nList, 2) {

View File

@ -93,7 +93,7 @@ func (opt CreateOrgOption) Validate() error {
return fmt.Errorf("empty org name")
}
if len(opt.Visibility) != 0 && !checkVisibilityOpt(opt.Visibility) {
return fmt.Errorf("infalid bisibility option")
return fmt.Errorf("invalid visibility option")
}
return nil
}
@ -124,7 +124,7 @@ type EditOrgOption struct {
// Validate the EditOrgOption struct
func (opt EditOrgOption) Validate() error {
if len(opt.Visibility) != 0 && !checkVisibilityOpt(opt.Visibility) {
return fmt.Errorf("infalid bisibility option")
return fmt.Errorf("invalid visibility option")
}
return nil
}

View File

@ -5,16 +5,19 @@
package gitea
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"net/url"
)
// ListOrgMembershipOption list OrgMembership options
// ListOrgActionSecretOption list OrgActionSecret options
type ListOrgActionSecretOption struct {
ListOptions
}
// ListOrgMembership list an organization's members
// ListOrgActionSecret list an organization's secrets
func (c *Client) ListOrgActionSecret(org string, opt ListOrgActionSecretOption) ([]*Secret, *Response, error) {
if err := escapeValidatePathSegments(&org); err != nil {
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)
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
View 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)
}

View File

@ -16,7 +16,7 @@ type Package struct {
// the package's owner
Owner User `json:"owner"`
// the repo this package belongs to (if any)
Repository *string `json:"repository"`
Repository *Repository `json:"repository"`
// the package's creator
Creator User `json:"creator"`
// the type of package:

View File

@ -78,6 +78,18 @@ func (c *Client) GetRelease(owner, repo string, id int64) (*Release, *Response,
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
func (c *Client) GetReleaseByTag(owner, repo, tag string) (*Release, *Response, error) {
if c.checkServerVersionGreaterThanOrEqual(version1_13_0) != nil {

View File

@ -76,6 +76,11 @@ func TestRelease(t *testing.T) {
assert.EqualValues(t, false, r2.IsPrerelease)
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
_, err = c.DeleteRelease(repo.Owner.UserName, repo.Name, r.ID)
assert.NoError(t, err)

66
gitea/repo_action.go Normal file
View 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
View 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)
}

View File

@ -6,8 +6,8 @@ package gitea
import (
"log"
"sort"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
@ -21,22 +21,23 @@ func TestRepoBranches(t *testing.T) {
if repo == nil {
return
}
time.Sleep(1 * time.Second)
bl, _, err := c.ListRepoBranches(repo.Owner.UserName, repo.Name, ListRepoBranchesOptions{})
assert.NoError(t, err)
assert.Len(t, bl, 3)
sort.Slice(bl, func(i, j int) bool {
return bl[i].Name < bl[j].Name
})
assert.EqualValues(t, "feature", bl[0].Name)
assert.EqualValues(t, "main", bl[1].Name)
assert.EqualValues(t, "update", bl[2].Name)
branchNames := make([]string, len(bl))
branches := make(map[string]Branch, len(bl))
for index, branch := range bl {
branchNames[index] = branch.Name
branches[branch.Name] = *branch
}
assert.ElementsMatch(t, []string{"feature", "main", "update"}, branchNames)
b, _, err := c.GetRepoBranch(repo.Owner.UserName, repo.Name, "update")
assert.NoError(t, err)
assert.EqualValues(t, bl[2].Commit.ID, b.Commit.ID)
assert.EqualValues(t, bl[2].Commit.Added, b.Commit.Added)
assert.EqualValues(t, branches["update"].Commit.ID, b.Commit.ID)
assert.EqualValues(t, branches["update"].Commit.Added, b.Commit.Added)
s, _, err := c.DeleteRepoBranch(repo.Owner.UserName, repo.Name, "main")
assert.NoError(t, err)

33
gitea/repo_compare.go Normal file
View 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, &current); 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
}

View File

@ -65,7 +65,7 @@ func TestRepoMigrateAndLanguages(t *testing.T) {
assert.NotEqual(t, zeroTime, repoG.MirrorUpdated)
log.Println("== TestRepoLanguages ==")
time.Sleep(time.Second)
time.Sleep(time.Second * 2)
lang, _, err := c.GetRepoLanguages(repoM.Owner.UserName, repoM.Name)
assert.NoError(t, err)
assert.Len(t, lang, 2)

View File

@ -9,6 +9,8 @@ import "time"
type Secret struct {
// the secret's name
Name string `json:"name"`
// the secret's data
Data string `json:"data"`
// Date and Time of secret creation
Created time.Time `json:"created_at"`
}

View File

@ -44,7 +44,7 @@ func TestGetGlobalSettings(t *testing.T) {
}
assert.EqualValues(t, &GlobalAttachmentSettings{
Enabled: true,
MaxSize: 4,
MaxSize: 2048,
MaxFiles: 5,
}, attachSettings)
}

View File

@ -17,6 +17,10 @@ type User struct {
ID int64 `json:"id"`
// the user's username
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
FullName string `json:"full_name"`
Email string `json:"email"`

View File

@ -19,7 +19,7 @@ func TestUserSettings(t *testing.T) {
assert.NoError(t, err)
assert.NotNil(t, userConf)
assert.EqualValues(t, UserSettings{
Theme: "auto",
Theme: "gitea-auto",
HideEmail: false,
HideActivity: false,
}, *userConf)
@ -33,7 +33,7 @@ func TestUserSettings(t *testing.T) {
assert.NotNil(t, userConf)
assert.EqualValues(t, UserSettings{
FullName: "Admin User on Test",
Theme: "auto",
Theme: "gitea-auto",
Language: "de_de",
HideEmail: true,
HideActivity: false,

View File

@ -21,7 +21,7 @@ func TestMyUser(t *testing.T) {
assert.EqualValues(t, "test01", user.UserName)
assert.EqualValues(t, "test01@gitea.io", user.Email)
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)
}
@ -144,14 +144,14 @@ func TestUserEmail(t *testing.T) {
el, _, err := c.ListEmails(ListEmailsOptions{})
assert.NoError(t, err)
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)
// AddEmail
mails := []string{"wow@mail.send", "speed@mail.me"}
el, _, err = c.AddEmail(CreateEmailOption{Emails: mails})
assert.NoError(t, err)
assert.Len(t, el, 2)
assert.Len(t, el, 3)
_, _, err = c.AddEmail(CreateEmailOption{Emails: []string{mails[1]}})
assert.Error(t, err)
el, _, err = c.ListEmails(ListEmailsOptions{})

View File

@ -69,6 +69,7 @@ var (
version1_15_0 = version.Must(version.NewVersion("1.15.0"))
version1_16_0 = version.Must(version.NewVersion("1.16.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
@ -77,14 +78,13 @@ type ErrUnknownVersion struct {
}
// Error fulfills error
func (e ErrUnknownVersion) Error() string {
func (e *ErrUnknownVersion) Error() string {
return fmt.Sprintf("unknown version: %s", e.raw)
}
func (_ ErrUnknownVersion) Is(target error) bool {
_, ok1 := target.(*ErrUnknownVersion)
_, ok2 := target.(ErrUnknownVersion)
return ok1 || ok2
func (*ErrUnknownVersion) Is(target error) bool {
_, ok := target.(*ErrUnknownVersion)
return ok
}
// checkServerVersionGreaterThanOrEqual is the canonical way in the SDK to check for versions for API compatibility reasons