Merge pull request 'Cherry pick latest commits from Gitea SDK' (#4) from chore-cherry-pick-gitea-sdk-updates into main
Reviewed-on: https://codeberg.org/mvdkleijn/forgejo-sdk/pulls/4
This commit is contained in:
commit
c7d07f49b6
10 changed files with 196 additions and 20 deletions
|
@ -7,12 +7,12 @@ require (
|
|||
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.15.0 // indirect
|
||||
golang.org/x/sys v0.19.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
|
||||
)
|
||||
|
|
|
@ -14,18 +14,17 @@ 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-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.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
|
||||
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||
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-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
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.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.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/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
|
|
|
@ -97,7 +97,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
|
||||
}
|
||||
|
@ -128,7 +128,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
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2024 The Forgjo Authors. All rights reserved.
|
||||
// Copyright 2024 The Forgejo Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
|
@ -9,16 +9,19 @@
|
|||
package forgejo
|
||||
|
||||
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
|
||||
|
@ -31,3 +34,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)
|
||||
}
|
||||
}
|
||||
|
|
43
forgejo/org_action_test.go
Normal file
43
forgejo/org_action_test.go
Normal file
|
@ -0,0 +1,43 @@
|
|||
// Copyright 2024 The Forgejo Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// 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 forgejo
|
||||
|
||||
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)
|
||||
}
|
33
forgejo/repo_action.go
Normal file
33
forgejo/repo_action.go
Normal file
|
@ -0,0 +1,33 @@
|
|||
// Copyright 2024 The Forgejo Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// 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 forgejo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"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
|
||||
}
|
37
forgejo/repo_compare.go
Normal file
37
forgejo/repo_compare.go
Normal file
|
@ -0,0 +1,37 @@
|
|||
// Copyright 2024 The Forgejo Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// 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 forgejo
|
||||
|
||||
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
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2024 The Forgjo Authors. All rights reserved.
|
||||
// Copyright 2024 The Forgejo Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
|
@ -13,6 +13,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"`
|
||||
}
|
||||
|
|
|
@ -21,6 +21,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"`
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2024 The Forgjo Authors. All rights reserved.
|
||||
// Copyright 2024 The Forgejo Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
|
@ -73,6 +73,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
|
||||
|
@ -81,14 +82,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
|
||||
|
|
Loading…
Reference in a new issue