diff --git a/go.mod b/go.mod index 79b3de73e..da3cb1611 100644 --- a/go.mod +++ b/go.mod @@ -1,9 +1,9 @@ module github.com/hybrid-cloud-patterns/patterns-operator -go 1.25.5 +go 1.26 require ( - code.gitea.io/sdk/gitea v0.23.2 + code.gitea.io/sdk/gitea v0.25.1 github.com/Masterminds/semver/v3 v3.5.0 github.com/argoproj-labs/argocd-operator v0.17.0 github.com/bradleyfalzon/ghinstallation/v2 v2.19.0 diff --git a/go.sum b/go.sum index 22bb33413..2ddb162fc 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,7 @@ cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= -code.gitea.io/sdk/gitea v0.23.2 h1:iJB1FDmLegwfwjX8gotBDHdPSbk/ZR8V9VmEJaVsJYg= -code.gitea.io/sdk/gitea v0.23.2/go.mod h1:yyF5+GhljqvA30sRDreoyHILruNiy4ASufugzYg0VHM= +code.gitea.io/sdk/gitea v0.25.1 h1:yywxWwoV+SdjHtbC6unBiXojWdZOtoHuGhEazEXeWuE= +code.gitea.io/sdk/gitea v0.25.1/go.mod h1:uDFWYBU8dgZsgOHwe6C/6olxvf8FHguNB3wW1i83fgg= cyphar.com/go-pathrs v0.2.5 h1:SnX9FBvnoyn3lUs1dkMgZ52bAETpirNu3FTRh5HlRik= cyphar.com/go-pathrs v0.2.5/go.mod h1:y8f1EMG7r+hCuFf/rXsKqMJrJAUoADZGNh5/vZPKcGc= dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8= diff --git a/vendor/code.gitea.io/sdk/gitea/action_run.go b/vendor/code.gitea.io/sdk/gitea/action_run.go index eb3b6697e..91e5bc3cc 100644 --- a/vendor/code.gitea.io/sdk/gitea/action_run.go +++ b/vendor/code.gitea.io/sdk/gitea/action_run.go @@ -40,22 +40,22 @@ type ActionWorkflowRun struct { ID int64 `json:"id"` DisplayTitle string `json:"display_title"` Event string `json:"event"` - HeadBranch string `json:"head_branch"` + HeadBranch string `json:"head_branch,omitempty"` HeadSha string `json:"head_sha"` Path string `json:"path"` RunAttempt int64 `json:"run_attempt"` RunNumber int64 `json:"run_number"` Status string `json:"status"` - Conclusion string `json:"conclusion"` + Conclusion string `json:"conclusion,omitempty"` URL string `json:"url"` HTMLURL string `json:"html_url"` StartedAt time.Time `json:"started_at"` CompletedAt time.Time `json:"completed_at"` - Actor *User `json:"actor"` - TriggerActor *User `json:"trigger_actor"` - Repository *Repository `json:"repository"` - HeadRepository *Repository `json:"head_repository"` - RepositoryID int64 `json:"repository_id"` + Actor *User `json:"actor,omitempty"` + TriggerActor *User `json:"trigger_actor,omitempty"` + Repository *Repository `json:"repository,omitempty"` + HeadRepository *Repository `json:"head_repository,omitempty"` + RepositoryID int64 `json:"repository_id,omitempty"` } // ActionWorkflowRunsResponse holds the response for listing workflow runs @@ -71,17 +71,17 @@ type ActionWorkflowJob struct { RunURL string `json:"run_url"` RunAttempt int64 `json:"run_attempt"` Name string `json:"name"` - HeadBranch string `json:"head_branch"` + HeadBranch string `json:"head_branch,omitempty"` HeadSha string `json:"head_sha"` Status string `json:"status"` - Conclusion string `json:"conclusion"` + Conclusion string `json:"conclusion,omitempty"` URL string `json:"url"` HTMLURL string `json:"html_url"` CreatedAt time.Time `json:"created_at"` StartedAt time.Time `json:"started_at"` CompletedAt time.Time `json:"completed_at"` - RunnerID int64 `json:"runner_id"` - RunnerName string `json:"runner_name"` + RunnerID int64 `json:"runner_id,omitempty"` + RunnerName string `json:"runner_name,omitempty"` Labels []string `json:"labels"` Steps []*ActionWorkflowStep `json:"steps"` } @@ -97,7 +97,7 @@ type ActionWorkflowStep struct { Name string `json:"name"` Number int64 `json:"number"` Status string `json:"status"` - Conclusion string `json:"conclusion"` + Conclusion string `json:"conclusion,omitempty"` StartedAt time.Time `json:"started_at"` CompletedAt time.Time `json:"completed_at"` } @@ -149,9 +149,9 @@ func (opt *ListRepoActionJobsOptions) QueryEncode() string { } // ListRepoActionRuns lists workflow runs for a repository. -// Requires Gitea 1.25.0 or later. For older versions, use ListRepoActionTasks. +// Requires Gitea 1.26.0 or later. For older versions, use ListRepoActionTasks. func (c *Client) ListRepoActionRuns(owner, repo string, opt ListRepoActionRunsOptions) (*ActionWorkflowRunsResponse, *Response, error) { - if err := c.checkServerVersionGreaterThanOrEqual(version1_25_0); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_26_0); err != nil { return nil, nil, err } if err := escapeValidatePathSegments(&owner, &repo); err != nil { @@ -168,9 +168,9 @@ func (c *Client) ListRepoActionRuns(owner, repo string, opt ListRepoActionRunsOp } // GetRepoActionRun gets a single workflow run. -// Requires Gitea 1.25.0 or later. +// Requires Gitea 1.26.0 or later. func (c *Client) GetRepoActionRun(owner, repo string, runID int64) (*ActionWorkflowRun, *Response, error) { - if err := c.checkServerVersionGreaterThanOrEqual(version1_25_0); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_26_0); err != nil { return nil, nil, err } if err := escapeValidatePathSegments(&owner, &repo); err != nil { @@ -183,9 +183,9 @@ func (c *Client) GetRepoActionRun(owner, repo string, runID int64) (*ActionWorkf } // ListRepoActionRunJobs lists jobs for a workflow run. -// Requires Gitea 1.25.0 or later. +// Requires Gitea 1.26.0 or later. func (c *Client) ListRepoActionRunJobs(owner, repo string, runID int64, opt ListRepoActionJobsOptions) (*ActionWorkflowJobsResponse, *Response, error) { - if err := c.checkServerVersionGreaterThanOrEqual(version1_25_0); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_26_0); err != nil { return nil, nil, err } if err := escapeValidatePathSegments(&owner, &repo); err != nil { @@ -202,9 +202,9 @@ func (c *Client) ListRepoActionRunJobs(owner, repo string, runID int64, opt List } // ListRepoActionJobs lists all jobs for a repository. -// Requires Gitea 1.25.0 or later. +// Requires Gitea 1.26.0 or later. func (c *Client) ListRepoActionJobs(owner, repo string, opt ListRepoActionJobsOptions) (*ActionWorkflowJobsResponse, *Response, error) { - if err := c.checkServerVersionGreaterThanOrEqual(version1_25_0); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_26_0); err != nil { return nil, nil, err } if err := escapeValidatePathSegments(&owner, &repo); err != nil { @@ -221,9 +221,9 @@ func (c *Client) ListRepoActionJobs(owner, repo string, opt ListRepoActionJobsOp } // GetRepoActionJob gets a single job. -// Requires Gitea 1.25.0 or later. +// Requires Gitea 1.26.0 or later. func (c *Client) GetRepoActionJob(owner, repo string, jobID int64) (*ActionWorkflowJob, *Response, error) { - if err := c.checkServerVersionGreaterThanOrEqual(version1_25_0); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_26_0); err != nil { return nil, nil, err } if err := escapeValidatePathSegments(&owner, &repo); err != nil { @@ -236,9 +236,9 @@ func (c *Client) GetRepoActionJob(owner, repo string, jobID int64) (*ActionWorkf } // GetRepoActionJobLogs gets the logs for a specific job. -// Requires Gitea 1.25.0 or later. +// Requires Gitea 1.26.0 or later. func (c *Client) GetRepoActionJobLogs(owner, repo string, jobID int64) ([]byte, *Response, error) { - if err := c.checkServerVersionGreaterThanOrEqual(version1_25_0); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_26_0); err != nil { return nil, nil, err } if err := escapeValidatePathSegments(&owner, &repo); err != nil { @@ -265,15 +265,57 @@ func (c *Client) ListRepoActionTasks(owner, repo string, opt ListOptions) (*Acti } // DeleteRepoActionRun deletes a workflow run. -// Requires Gitea 1.25.0 or later. +// Requires Gitea 1.26.0 or later. func (c *Client) DeleteRepoActionRun(owner, repo string, runID int64) (*Response, error) { - if err := c.checkServerVersionGreaterThanOrEqual(version1_25_0); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_26_0); err != nil { return nil, err } if err := escapeValidatePathSegments(&owner, &repo); err != nil { return nil, err } - _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/actions/runs/%d", owner, repo, runID), jsonHeader, nil) - return resp, err + return c.doRequestWithStatusHandle("DELETE", fmt.Sprintf("/repos/%s/%s/actions/runs/%d", owner, repo, runID), jsonHeader, nil) +} + +// RerunRepoActionRun reruns an entire workflow run. +// Requires Gitea 1.26.0 or later. +func (c *Client) RerunRepoActionRun(owner, repo string, runID int64) (*ActionWorkflowRun, *Response, error) { + if err := c.checkServerVersionGreaterThanOrEqual(version1_26_0); err != nil { + return nil, nil, err + } + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } + + run := new(ActionWorkflowRun) + resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/actions/runs/%d/rerun", owner, repo, runID), jsonHeader, nil, run) + return run, resp, err +} + +// RerunRepoActionRunFailedJobs reruns all failed jobs in a workflow run. +// Requires Gitea 1.26.0 or later. +func (c *Client) RerunRepoActionRunFailedJobs(owner, repo string, runID int64) (*Response, error) { + if err := c.checkServerVersionGreaterThanOrEqual(version1_26_0); err != nil { + return nil, err + } + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, err + } + + return c.doRequestWithStatusHandle("POST", fmt.Sprintf("/repos/%s/%s/actions/runs/%d/rerun-failed-jobs", owner, repo, runID), jsonHeader, nil) +} + +// RerunRepoActionJob reruns a specific workflow job in a run. +// Requires Gitea 1.26.0 or later. +func (c *Client) RerunRepoActionJob(owner, repo string, runID, jobID int64) (*ActionWorkflowJob, *Response, error) { + if err := c.checkServerVersionGreaterThanOrEqual(version1_26_0); err != nil { + return nil, nil, err + } + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } + + job := new(ActionWorkflowJob) + resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/actions/runs/%d/jobs/%d/rerun", owner, repo, runID, jobID), jsonHeader, nil, job) + return job, resp, err } diff --git a/vendor/code.gitea.io/sdk/gitea/action_shared.go b/vendor/code.gitea.io/sdk/gitea/action_shared.go new file mode 100644 index 000000000..c96704268 --- /dev/null +++ b/vendor/code.gitea.io/sdk/gitea/action_shared.go @@ -0,0 +1,270 @@ +// Copyright 2026 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" + "errors" + "fmt" + "net/url" + "time" +) + +// RegistrationToken is returned when creating an Actions runner registration token. +type RegistrationToken struct { + Token string `json:"token"` +} + +// CreateOrUpdateSecretOption contains the data for creating or updating an Actions secret. +type CreateOrUpdateSecretOption struct { + Data string `json:"data"` + Description string `json:"description"` +} + +// Validate checks whether a secret payload can be sent to the API. +func (opt CreateOrUpdateSecretOption) Validate() error { + if len(opt.Data) == 0 { + return errors.New("empty Data field") + } + return nil +} + +// ActionVariable represents an Actions variable. +type ActionVariable struct { + OwnerID int64 `json:"owner_id"` + RepoID int64 `json:"repo_id"` + Name string `json:"name"` + Data string `json:"data"` + Description string `json:"description"` +} + +// CreateActionVariableOption is used to create an Actions variable. +type CreateActionVariableOption struct { + Value string `json:"value"` + Description string `json:"description"` +} + +// Validate checks whether the variable create payload is valid. +func (opt CreateActionVariableOption) Validate() error { + if len(opt.Value) == 0 { + return errors.New("empty Value field") + } + return nil +} + +// UpdateActionVariableOption is used to update an Actions variable. +type UpdateActionVariableOption struct { + Name string `json:"name"` + Value string `json:"value"` + Description string `json:"description"` +} + +// Validate checks whether the variable update payload is valid. +func (opt UpdateActionVariableOption) Validate() error { + if len(opt.Value) == 0 { + return errors.New("empty Value field") + } + return nil +} + +// ListActionRunnersOptions controls runner listing requests. +type ListActionRunnersOptions struct { + ListOptions + Disabled *bool +} + +// QueryEncode turns the runner list options into a query string. +func (opt *ListActionRunnersOptions) QueryEncode() string { + query := opt.getURLQuery() + if opt.Disabled != nil { + query.Add("disabled", fmt.Sprintf("%t", *opt.Disabled)) + } + return query.Encode() +} + +// ActionRunnerLabel represents a runner label. +type ActionRunnerLabel struct { + ID int64 `json:"id"` + Name string `json:"name"` + Type string `json:"type"` +} + +// ActionRunner represents an Actions runner. +type ActionRunner struct { + ID int64 `json:"id"` + Name string `json:"name"` + Status string `json:"status"` + Busy bool `json:"busy"` + Disabled bool `json:"disabled"` + Ephemeral bool `json:"ephemeral"` + Labels []*ActionRunnerLabel `json:"labels"` +} + +// EditActionRunnerOption contains editable runner fields. +type EditActionRunnerOption struct { + Disabled *bool `json:"disabled"` +} + +// Validate checks whether the runner update payload is valid. +func (opt EditActionRunnerOption) Validate() error { + if opt.Disabled == nil { + return errors.New("nil Disabled field") + } + return nil +} + +// ActionRunnersResponse contains a page of runners. +type ActionRunnersResponse struct { + Runners []*ActionRunner `json:"runners"` + TotalCount int64 `json:"total_count"` +} + +// ActionWorkflow represents a repository workflow definition. +type ActionWorkflow struct { + ID string `json:"id"` + Name string `json:"name"` + Path string `json:"path"` + State string `json:"state"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + URL string `json:"url"` + HTMLURL string `json:"html_url"` + BadgeURL string `json:"badge_url"` + DeletedAt time.Time `json:"deleted_at"` +} + +// ActionWorkflowResponse contains a workflow list response. +type ActionWorkflowResponse struct { + Workflows []*ActionWorkflow `json:"workflows"` + TotalCount int64 `json:"total_count"` +} + +// CreateActionWorkflowDispatchOption triggers a workflow_dispatch event. +type CreateActionWorkflowDispatchOption struct { + Ref string `json:"ref"` + Inputs map[string]string `json:"inputs,omitempty"` +} + +// Validate checks whether the dispatch payload is valid. +func (opt CreateActionWorkflowDispatchOption) Validate() error { + if len(opt.Ref) == 0 { + return errors.New("empty Ref field") + } + return nil +} + +// RunDetails contains the workflow run identifiers returned by workflow dispatch. +type RunDetails struct { + WorkflowRunID int64 `json:"workflow_run_id"` + RunURL string `json:"run_url"` + HTMLURL string `json:"html_url"` +} + +// ActionArtifact represents an Actions artifact. +type ActionArtifact struct { + ID int64 `json:"id"` + Name string `json:"name"` + SizeInBytes int64 `json:"size_in_bytes"` + URL string `json:"url"` + ArchiveDownloadURL string `json:"archive_download_url"` + Expired bool `json:"expired"` + WorkflowRun *ActionWorkflowRun `json:"workflow_run"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + ExpiresAt time.Time `json:"expires_at"` +} + +// ActionArtifactsResponse contains a page of artifacts. +type ActionArtifactsResponse struct { + Artifacts []*ActionArtifact `json:"artifacts"` + TotalCount int64 `json:"total_count"` +} + +// ListActionArtifactsOptions controls artifact listing requests. +type ListActionArtifactsOptions struct { + ListOptions + Name string +} + +// QueryEncode turns the artifact list options into a query string. +func (opt *ListActionArtifactsOptions) QueryEncode() string { + query := opt.getURLQuery() + if opt.Name != "" { + query.Add("name", opt.Name) + } + return query.Encode() +} + +func (c *Client) createActionRegistrationToken(path string) (*RegistrationToken, *Response, error) { + token := new(RegistrationToken) + resp, err := c.getParsedResponse("POST", path, nil, nil, token) + return token, resp, err +} + +func (c *Client) listActionRuns(path string, opt ListRepoActionRunsOptions) (*ActionWorkflowRunsResponse, *Response, error) { + if err := c.checkServerVersionGreaterThanOrEqual(version1_26_0); err != nil { + return nil, nil, err + } + opt.setDefaults() + link, _ := url.Parse(path) + link.RawQuery = opt.QueryEncode() + + resp := new(ActionWorkflowRunsResponse) + response, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, resp) + return resp, response, err +} + +func (c *Client) listActionJobs(path string, opt ListRepoActionJobsOptions) (*ActionWorkflowJobsResponse, *Response, error) { + if err := c.checkServerVersionGreaterThanOrEqual(version1_26_0); err != nil { + return nil, nil, err + } + opt.setDefaults() + link, _ := url.Parse(path) + link.RawQuery = opt.QueryEncode() + + resp := new(ActionWorkflowJobsResponse) + response, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, resp) + return resp, response, err +} + +func (c *Client) listActionRunners(path string, opt ListActionRunnersOptions) (*ActionRunnersResponse, *Response, error) { + opt.setDefaults() + link, _ := url.Parse(path) + link.RawQuery = opt.QueryEncode() + + resp := new(ActionRunnersResponse) + response, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, resp) + return resp, response, err +} + +func (c *Client) getActionRunner(path string) (*ActionRunner, *Response, error) { + runner := new(ActionRunner) + resp, err := c.getParsedResponse("GET", path, jsonHeader, nil, runner) + return runner, resp, err +} + +func (c *Client) updateActionRunner(path string, opt EditActionRunnerOption) (*ActionRunner, *Response, error) { + if err := opt.Validate(); err != nil { + return nil, nil, err + } + body, err := json.Marshal(&opt) + if err != nil { + return nil, nil, err + } + runner := new(ActionRunner) + resp, err := c.getParsedResponse("PATCH", path, jsonHeader, bytes.NewReader(body), runner) + return runner, resp, err +} + +func (c *Client) listActionArtifacts(path string, opt ListActionArtifactsOptions) (*ActionArtifactsResponse, *Response, error) { + opt.setDefaults() + link, _ := url.Parse(path) + link.RawQuery = opt.QueryEncode() + + resp := new(ActionArtifactsResponse) + response, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, resp) + return resp, response, err +} diff --git a/vendor/code.gitea.io/sdk/gitea/activitypub.go b/vendor/code.gitea.io/sdk/gitea/activitypub.go index 82c278771..b8a599110 100644 --- a/vendor/code.gitea.io/sdk/gitea/activitypub.go +++ b/vendor/code.gitea.io/sdk/gitea/activitypub.go @@ -8,7 +8,6 @@ import ( "bytes" "encoding/json" "fmt" - "io" "net/http" ) @@ -44,13 +43,7 @@ func (c *Client) SendActivityPubInbox(userID int64, activity ActivityPub) (*Resp // GetActivityPubPersonResponse returns the raw ActivityPub Person response func (c *Client) GetActivityPubPersonResponse(userID int64) ([]byte, *Response, error) { - resp, err := c.doRequest("GET", + return c.getResponse("GET", fmt.Sprintf("/activitypub/user-id/%d", userID), jsonHeader, nil) - if err != nil { - return nil, resp, err - } - defer func() { _ = resp.Body.Close() }() - data, err := io.ReadAll(resp.Body) - return data, resp, err } diff --git a/vendor/code.gitea.io/sdk/gitea/admin_action.go b/vendor/code.gitea.io/sdk/gitea/admin_action.go new file mode 100644 index 000000000..45884fa7d --- /dev/null +++ b/vendor/code.gitea.io/sdk/gitea/admin_action.go @@ -0,0 +1,57 @@ +// Copyright 2026 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" + +// ListAdminActionJobs lists all admin-scope Actions jobs. +func (c *Client) ListAdminActionJobs(opt ListRepoActionJobsOptions) (*ActionWorkflowJobsResponse, *Response, error) { + return c.listActionJobs("/admin/actions/jobs", opt) +} + +// ListAdminActionRuns lists all admin-scope Actions workflow runs. +func (c *Client) ListAdminActionRuns(opt ListRepoActionRunsOptions) (*ActionWorkflowRunsResponse, *Response, error) { + return c.listActionRuns("/admin/actions/runs", opt) +} + +// ListAdminActionRunners lists all admin-scope Actions runners. +func (c *Client) ListAdminActionRunners(opt ListActionRunnersOptions) (*ActionRunnersResponse, *Response, error) { + if err := c.checkServerVersionGreaterThanOrEqual(version1_25_0); err != nil { + return nil, nil, err + } + return c.listActionRunners("/admin/actions/runners", opt) +} + +// GetAdminActionRunner gets one admin-scope Actions runner. +func (c *Client) GetAdminActionRunner(runnerID int64) (*ActionRunner, *Response, error) { + if err := c.checkServerVersionGreaterThanOrEqual(version1_25_0); err != nil { + return nil, nil, err + } + return c.getActionRunner(fmt.Sprintf("/admin/actions/runners/%d", runnerID)) +} + +// DeleteAdminActionRunner deletes one admin-scope Actions runner. +func (c *Client) DeleteAdminActionRunner(runnerID int64) (*Response, error) { + if err := c.checkServerVersionGreaterThanOrEqual(version1_25_0); err != nil { + return nil, err + } + return c.doRequestWithStatusHandle("DELETE", fmt.Sprintf("/admin/actions/runners/%d", runnerID), nil, nil) +} + +// UpdateAdminActionRunner updates one admin-scope Actions runner. +func (c *Client) UpdateAdminActionRunner(runnerID int64, opt EditActionRunnerOption) (*ActionRunner, *Response, error) { + if err := c.checkServerVersionGreaterThanOrEqual(version1_25_0); err != nil { + return nil, nil, err + } + return c.updateActionRunner(fmt.Sprintf("/admin/actions/runners/%d", runnerID), opt) +} + +// CreateAdminActionRunnerRegistrationToken creates an admin-scope runner registration token. +func (c *Client) CreateAdminActionRunnerRegistrationToken() (*RegistrationToken, *Response, error) { + if err := c.checkServerVersionGreaterThanOrEqual(version1_22_0); err != nil { + return nil, nil, err + } + return c.createActionRegistrationToken("/admin/actions/runners/registration-token") +} diff --git a/vendor/code.gitea.io/sdk/gitea/httpsign.go b/vendor/code.gitea.io/sdk/gitea/httpsign.go index 9b76c6ce5..65d74b441 100644 --- a/vendor/code.gitea.io/sdk/gitea/httpsign.go +++ b/vendor/code.gitea.io/sdk/gitea/httpsign.go @@ -139,6 +139,15 @@ func newHTTPSign(config *HTTPSignConfig) (*HTTPSign, error) { }, nil } +// SignWithAlgorithm implements ssh.AlgorithmSigner, required by 42wim/httpsig v1.2.4+ +// when signing with RSA keys. +func (h *HTTPSign) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*ssh.Signature, error) { + if as, ok := h.Signer.(ssh.AlgorithmSigner); ok { + return as.SignWithAlgorithm(rand, data, algorithm) + } + return h.Sign(rand, data) +} + // SignRequest signs a HTTP request func (c *Client) SignRequest(r *http.Request) error { var contents []byte diff --git a/vendor/code.gitea.io/sdk/gitea/issue.go b/vendor/code.gitea.io/sdk/gitea/issue.go index 5f5924fab..19e203596 100644 --- a/vendor/code.gitea.io/sdk/gitea/issue.go +++ b/vendor/code.gitea.io/sdk/gitea/issue.go @@ -143,7 +143,7 @@ func (opt *ListIssueOption) QueryEncode() string { query.Add("owner", opt.Owner) } if len(opt.Team) > 0 { - query.Add("team", opt.MentionedBy) + query.Add("team", opt.Team) } return query.Encode() diff --git a/vendor/code.gitea.io/sdk/gitea/issue_attachment.go b/vendor/code.gitea.io/sdk/gitea/issue_attachment.go new file mode 100644 index 000000000..545510681 --- /dev/null +++ b/vendor/code.gitea.io/sdk/gitea/issue_attachment.go @@ -0,0 +1,91 @@ +// Copyright 2026 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" + "io" + "mime/multipart" + "net/http" + "net/url" +) + +// ListIssueAttachments lists all attachments for an issue. +func (c *Client) ListIssueAttachments(owner, repo string, index int64) ([]*Attachment, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } + attachments := make([]*Attachment, 0, 10) + resp, err := c.getParsedResponse("GET", + fmt.Sprintf("/repos/%s/%s/issues/%d/assets", owner, repo, index), + nil, nil, &attachments) + return attachments, resp, err +} + +// GetIssueAttachment gets an issue attachment. +func (c *Client) GetIssueAttachment(owner, repo string, index, attachmentID int64) (*Attachment, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } + attachment := new(Attachment) + resp, err := c.getParsedResponse("GET", + fmt.Sprintf("/repos/%s/%s/issues/%d/assets/%d", owner, repo, index, attachmentID), + nil, nil, attachment) + return attachment, resp, err +} + +// CreateIssueAttachment uploads an attachment for an issue. +func (c *Client) CreateIssueAttachment(owner, repo string, index int64, file io.Reader, filename string) (*Attachment, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } + + body := new(bytes.Buffer) + writer := multipart.NewWriter(body) + part, err := writer.CreateFormFile("attachment", filename) + if err != nil { + return nil, nil, err + } + if _, err = io.Copy(part, file); err != nil { + return nil, nil, err + } + if err = writer.Close(); err != nil { + return nil, nil, err + } + + link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/issues/%d/assets", owner, repo, index)) + link.RawQuery = url.Values{"name": []string{filename}}.Encode() + + attachment := new(Attachment) + resp, err := c.getParsedResponse("POST", link.String(), http.Header{"Content-Type": []string{writer.FormDataContentType()}}, body, attachment) + return attachment, resp, err +} + +// EditIssueAttachment updates an issue attachment. +func (c *Client) EditIssueAttachment(owner, repo string, index, attachmentID int64, form EditAttachmentOptions) (*Attachment, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } + body, err := json.Marshal(&form) + if err != nil { + return nil, nil, err + } + attachment := new(Attachment) + resp, err := c.getParsedResponse("PATCH", + fmt.Sprintf("/repos/%s/%s/issues/%d/assets/%d", owner, repo, index, attachmentID), + jsonHeader, bytes.NewReader(body), attachment) + return attachment, resp, err +} + +// DeleteIssueAttachment deletes an issue attachment. +func (c *Client) DeleteIssueAttachment(owner, repo string, index, attachmentID int64) (*Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, err + } + return c.doRequestWithStatusHandle("DELETE", + fmt.Sprintf("/repos/%s/%s/issues/%d/assets/%d", owner, repo, index, attachmentID), nil, nil) +} diff --git a/vendor/code.gitea.io/sdk/gitea/issue_comment.go b/vendor/code.gitea.io/sdk/gitea/issue_comment.go index 4510e89cc..acaa4b526 100644 --- a/vendor/code.gitea.io/sdk/gitea/issue_comment.go +++ b/vendor/code.gitea.io/sdk/gitea/issue_comment.go @@ -8,22 +8,26 @@ import ( "bytes" "encoding/json" "fmt" + "io" + "mime/multipart" + "net/http" "net/url" "time" ) // Comment represents a comment on a commit or issue type Comment struct { - ID int64 `json:"id"` - HTMLURL string `json:"html_url"` - PRURL string `json:"pull_request_url"` - IssueURL string `json:"issue_url"` - Poster *User `json:"user"` - OriginalAuthor string `json:"original_author"` - OriginalAuthorID int64 `json:"original_author_id"` - Body string `json:"body"` - Created time.Time `json:"created_at"` - Updated time.Time `json:"updated_at"` + ID int64 `json:"id"` + HTMLURL string `json:"html_url"` + PRURL string `json:"pull_request_url"` + IssueURL string `json:"issue_url"` + Poster *User `json:"user"` + OriginalAuthor string `json:"original_author"` + OriginalAuthorID int64 `json:"original_author_id"` + Body string `json:"body"` + Created time.Time `json:"created_at"` + Updated time.Time `json:"updated_at"` + Attachments []*Attachment `json:"assets"` } // ListIssueCommentOptions list comment options @@ -164,6 +168,33 @@ func (c *Client) ListIssueCommentAttachments(owner, repo string, commentID int64 return attachments, resp, err } +// CreateIssueCommentAttachment uploads an attachment for a comment. +func (c *Client) CreateIssueCommentAttachment(owner, repo string, commentID int64, file io.Reader, filename string) (*Attachment, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } + + body := new(bytes.Buffer) + writer := multipart.NewWriter(body) + part, err := writer.CreateFormFile("attachment", filename) + if err != nil { + return nil, nil, err + } + if _, err = io.Copy(part, file); err != nil { + return nil, nil, err + } + if err = writer.Close(); err != nil { + return nil, nil, err + } + + link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/issues/comments/%d/assets", owner, repo, commentID)) + link.RawQuery = url.Values{"name": []string{filename}}.Encode() + + attachment := new(Attachment) + resp, err := c.getParsedResponse("POST", link.String(), http.Header{"Content-Type": []string{writer.FormDataContentType()}}, body, attachment) + return attachment, resp, err +} + // GetIssueCommentAttachment gets a comment attachment func (c *Client) GetIssueCommentAttachment(owner, repo string, commentID, attachmentID int64) (*Attachment, *Response, error) { if err := escapeValidatePathSegments(&owner, &repo); err != nil { diff --git a/vendor/code.gitea.io/sdk/gitea/miscellaneous.go b/vendor/code.gitea.io/sdk/gitea/miscellaneous.go index 8cc82d54a..a04e00aa5 100644 --- a/vendor/code.gitea.io/sdk/gitea/miscellaneous.go +++ b/vendor/code.gitea.io/sdk/gitea/miscellaneous.go @@ -8,7 +8,6 @@ import ( "bytes" "encoding/json" "fmt" - "io" ) // GitignoreTemplateInfo represents a gitignore template @@ -161,27 +160,18 @@ func (c *Client) RenderMarkdown(opt MarkdownOption) (string, *Response, error) { return "", nil, err } - resp, err := c.doRequest("POST", "/markdown", jsonHeader, bytes.NewReader(body)) - if err != nil { - return "", resp, err - } - defer func() { _ = resp.Body.Close() }() - - html, err := io.ReadAll(resp.Body) + html, resp, err := c.getResponse("POST", "/markdown", jsonHeader, bytes.NewReader(body)) return string(html), resp, err } // RenderMarkdownRaw renders raw markdown as HTML func (c *Client) RenderMarkdownRaw(markdown string) (string, *Response, error) { - resp, err := c.doRequest("POST", "/markdown/raw", + html, resp, err := c.getResponse("POST", "/markdown/raw", map[string][]string{"Content-Type": {"text/plain"}}, bytes.NewReader([]byte(markdown))) if err != nil { return "", resp, err } - defer func() { _ = resp.Body.Close() }() - - html, err := io.ReadAll(resp.Body) return string(html), resp, err } @@ -192,13 +182,10 @@ func (c *Client) RenderMarkup(opt MarkupOption) (string, *Response, error) { return "", nil, err } - resp, err := c.doRequest("POST", "/markup", jsonHeader, bytes.NewReader(body)) + html, resp, err := c.getResponse("POST", "/markup", jsonHeader, bytes.NewReader(body)) if err != nil { return "", resp, err } - defer func() { _ = resp.Body.Close() }() - - html, err := io.ReadAll(resp.Body) return string(html), resp, err } @@ -211,24 +198,18 @@ func (c *Client) GetNodeInfo() (*NodeInfo, *Response, error) { // GetSigningKeyGPG gets the default GPG signing key func (c *Client) GetSigningKeyGPG() (string, *Response, error) { - resp, err := c.doRequest("GET", "/signing-key.gpg", nil, nil) + key, resp, err := c.getResponse("GET", "/signing-key.gpg", nil, nil) if err != nil { return "", resp, err } - defer func() { _ = resp.Body.Close() }() - - key, err := io.ReadAll(resp.Body) return string(key), resp, err } // GetSigningKeySSH gets the default SSH signing key func (c *Client) GetSigningKeySSH() (string, *Response, error) { - resp, err := c.doRequest("GET", "/signing-key.pub", nil, nil) + key, resp, err := c.getResponse("GET", "/signing-key.pub", nil, nil) if err != nil { return "", resp, err } - defer func() { _ = resp.Body.Close() }() - - key, err := io.ReadAll(resp.Body) return string(key), resp, err } diff --git a/vendor/code.gitea.io/sdk/gitea/org_action.go b/vendor/code.gitea.io/sdk/gitea/org_action.go index 0dafa9144..c14003d4f 100644 --- a/vendor/code.gitea.io/sdk/gitea/org_action.go +++ b/vendor/code.gitea.io/sdk/gitea/org_action.go @@ -8,7 +8,6 @@ import ( "bytes" "encoding/json" "fmt" - "net/http" "net/url" ) @@ -31,26 +30,18 @@ func (c *Client) ListOrgActionSecret(org string, opt ListOrgActionSecretOption) return secrets, resp, err } -type OrgActionVariable struct { - OwnerID int64 `json:"owner_id"` - RepoID int64 `json:"repo_id"` - Name string `json:"name"` - Data string `json:"data"` - Description string `json:"description"` -} - -// ListOrgActionVariableOption lists OrgActionVariable options +// ListOrgActionVariableOption lists ActionVariable options type ListOrgActionVariableOption struct { ListOptions } // ListOrgActionVariable lists an organization's action variables -func (c *Client) ListOrgActionVariable(org string, opt ListOrgActionVariableOption) ([]*OrgActionVariable, *Response, error) { +func (c *Client) ListOrgActionVariable(org string, opt ListOrgActionVariableOption) ([]*ActionVariable, *Response, error) { if err := escapeValidatePathSegments(&org); err != nil { return nil, nil, err } opt.setDefaults() - variables := make([]*OrgActionVariable, 0, opt.PageSize) + variables := make([]*ActionVariable, 0, opt.PageSize) link, _ := url.Parse(fmt.Sprintf("/orgs/%s/actions/variables", org)) link.RawQuery = opt.getURLQuery().Encode() @@ -59,11 +50,11 @@ func (c *Client) ListOrgActionVariable(org string, opt ListOrgActionVariableOpti } // GetOrgActionVariable gets a single organization's action variable by name -func (c *Client) GetOrgActionVariable(org, name string) (*OrgActionVariable, *Response, error) { +func (c *Client) GetOrgActionVariable(org, name string) (*ActionVariable, *Response, error) { if err := escapeValidatePathSegments(&org, &name); err != nil { return nil, nil, err } - var variable OrgActionVariable + var variable ActionVariable resp, err := c.getParsedResponse("GET", fmt.Sprintf("/orgs/%s/actions/variables/%s", org, name), jsonHeader, nil, &variable) @@ -73,157 +64,140 @@ func (c *Client) GetOrgActionVariable(org, name string) (*OrgActionVariable, *Re return &variable, resp, nil } -// CreateOrgActionVariableOption represents the options for creating an org action variable. -type CreateOrgActionVariableOption struct { - Name string `json:"name"` // Name is the name of the variable. - Value string `json:"value"` // Value is the value of the variable. - Description string `json:"description"` // Description is the description of the variable. -} - -// Validate checks if the CreateOrgActionVariableOption is valid. -func (opt *CreateOrgActionVariableOption) Validate() error { - if len(opt.Name) == 0 { - return fmt.Errorf("name required") - } - if len(opt.Name) > 30 { - return fmt.Errorf("name too long") - } - if len(opt.Value) == 0 { - return fmt.Errorf("value required") - } - return nil -} - // CreateOrgActionVariable creates a variable for the specified organization in the Gitea Actions. -func (c *Client) CreateOrgActionVariable(org string, opt CreateOrgActionVariableOption) (*Response, error) { - if err := escapeValidatePathSegments(&org); err != nil { +func (c *Client) CreateOrgActionVariable(org, name string, opt CreateActionVariableOption) (*Response, error) { + if err := escapeValidatePathSegments(&org, &name); err != nil { return nil, err } - if err := (&opt).Validate(); err != nil { + if err := opt.Validate(); err != nil { return nil, err } body, err := json.Marshal(&opt) if err != nil { return nil, err } + return c.doRequestWithStatusHandle("POST", fmt.Sprintf("/orgs/%s/actions/variables/%s", org, name), jsonHeader, bytes.NewReader(body)) +} - status, resp, err := c.getStatusCode("POST", fmt.Sprintf("/orgs/%s/actions/variables/%s", org, opt.Name), jsonHeader, bytes.NewReader(body)) - if err != nil { +// UpdateOrgActionVariable updates a variable for the specified organization in the Gitea Actions. +func (c *Client) UpdateOrgActionVariable(org, name string, opt UpdateActionVariableOption) (*Response, error) { + if err := escapeValidatePathSegments(&org, &name); 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) + if err := opt.Validate(); err != nil { + return nil, err } -} - -// UpdateOrgActionVariableOption represents the options for updating an org action variable. -type UpdateOrgActionVariableOption struct { - Value string `json:"value"` // Value is the new value of the variable. - Description string `json:"description"` // Description is the new description of the variable. -} - -// Validate checks if the UpdateOrgActionVariableOption is valid. -func (opt *UpdateOrgActionVariableOption) Validate() error { - if len(opt.Value) == 0 { - return fmt.Errorf("value required") + body, err := json.Marshal(&opt) + if err != nil { + return nil, err } - return nil + return c.doRequestWithStatusHandle("PUT", fmt.Sprintf("/orgs/%s/actions/variables/%s", org, name), jsonHeader, bytes.NewReader(body)) } -// UpdateOrgActionVariable updates a variable for the specified organization in the Gitea Actions. -func (c *Client) UpdateOrgActionVariable(org, name string, opt UpdateOrgActionVariableOption) (*Response, error) { - if err := escapeValidatePathSegments(&org, &name); err != nil { +// CreateOrgActionSecret creates a secret for the specified organization in the Gitea Actions. +func (c *Client) CreateOrgActionSecret(org, secretName string, opt CreateOrUpdateSecretOption) (*Response, error) { + if err := escapeValidatePathSegments(&org, &secretName); err != nil { return nil, err } - if err := (&opt).Validate(); err != nil { + if err := opt.Validate(); err != nil { return nil, err } body, err := json.Marshal(&opt) if err != nil { return nil, err } + return c.doRequestWithStatusHandle("PUT", fmt.Sprintf("/orgs/%s/actions/secrets/%s", org, secretName), jsonHeader, bytes.NewReader(body)) +} - status, resp, err := c.getStatusCode("PUT", fmt.Sprintf("/orgs/%s/actions/variables/%s", org, name), jsonHeader, bytes.NewReader(body)) - if err != nil { +// DeleteOrgActionSecret deletes an organization's Actions secret. +func (c *Client) DeleteOrgActionSecret(org, secretName string) (*Response, error) { + if err := escapeValidatePathSegments(&org, &secretName); err != nil { + return nil, err + } + if err := c.checkServerVersionGreaterThanOrEqual(version1_22_0); err != nil { return nil, err } + return c.doRequestWithStatusHandle("DELETE", fmt.Sprintf("/orgs/%s/actions/secrets/%s", org, secretName), nil, nil) +} - switch status { - case http.StatusOK: - 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) +// DeleteOrgActionVariable deletes an organization's Actions variable. +func (c *Client) DeleteOrgActionVariable(org, name string) (*Response, error) { + if err := escapeValidatePathSegments(&org, &name); err != nil { + return nil, err } + if err := c.checkServerVersionGreaterThanOrEqual(version1_25_0); err != nil { + return nil, err + } + return c.doRequestWithStatusHandle("DELETE", fmt.Sprintf("/orgs/%s/actions/variables/%s", org, name), nil, nil) } -// 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. - Description string `json:"description"` // Description is the description of the secret. +// CreateOrgActionRunnerRegistrationToken creates an organization runner registration token. +func (c *Client) CreateOrgActionRunnerRegistrationToken(org string) (*RegistrationToken, *Response, error) { + if err := escapeValidatePathSegments(&org); err != nil { + return nil, nil, err + } + if err := c.checkServerVersionGreaterThanOrEqual(version1_22_0); err != nil { + return nil, nil, err + } + return c.createActionRegistrationToken(fmt.Sprintf("/orgs/%s/actions/runners/registration-token", org)) } -// 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") +// ListOrgActionRunners lists organization-scoped Actions runners. +func (c *Client) ListOrgActionRunners(org string, opt ListActionRunnersOptions) (*ActionRunnersResponse, *Response, error) { + if err := escapeValidatePathSegments(&org); err != nil { + return nil, nil, err } - if len(opt.Name) > 30 { - return fmt.Errorf("name to long") + if err := c.checkServerVersionGreaterThanOrEqual(version1_25_0); err != nil { + return nil, nil, err + } + return c.listActionRunners(fmt.Sprintf("/orgs/%s/actions/runners", org), opt) +} + +// GetOrgActionRunner gets one organization-scoped Actions runner. +func (c *Client) GetOrgActionRunner(org string, runnerID int64) (*ActionRunner, *Response, error) { + if err := escapeValidatePathSegments(&org); err != nil { + return nil, nil, err } - if len(opt.Data) == 0 { - return fmt.Errorf("data required") + if err := c.checkServerVersionGreaterThanOrEqual(version1_25_0); err != nil { + return nil, nil, err } - return nil + return c.getActionRunner(fmt.Sprintf("/orgs/%s/actions/runners/%d", org, runnerID)) } -// 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) { +// DeleteOrgActionRunner deletes one organization-scoped Actions runner. +func (c *Client) DeleteOrgActionRunner(org string, runnerID int64) (*Response, error) { if err := escapeValidatePathSegments(&org); err != nil { return nil, err } - if err := (&opt).Validate(); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_25_0); err != nil { return nil, err } - body, err := json.Marshal(&opt) - if err != nil { - return nil, err + return c.doRequestWithStatusHandle("DELETE", fmt.Sprintf("/orgs/%s/actions/runners/%d", org, runnerID), nil, nil) +} + +// UpdateOrgActionRunner updates one organization-scoped Actions runner. +func (c *Client) UpdateOrgActionRunner(org string, runnerID int64, opt EditActionRunnerOption) (*ActionRunner, *Response, error) { + if err := escapeValidatePathSegments(&org); err != nil { + return nil, nil, err + } + if err := c.checkServerVersionGreaterThanOrEqual(version1_25_0); err != nil { + return nil, nil, err } + return c.updateActionRunner(fmt.Sprintf("/orgs/%s/actions/runners/%d", org, runnerID), opt) +} - 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 +// ListOrgActionJobs lists organization-scoped Actions jobs. +func (c *Client) ListOrgActionJobs(org string, opt ListRepoActionJobsOptions) (*ActionWorkflowJobsResponse, *Response, error) { + if err := escapeValidatePathSegments(&org); err != nil { + return nil, nil, err } + return c.listActionJobs(fmt.Sprintf("/orgs/%s/actions/jobs", org), opt) +} - 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) +// ListOrgActionRuns lists organization-scoped Actions workflow runs. +func (c *Client) ListOrgActionRuns(org string, opt ListRepoActionRunsOptions) (*ActionWorkflowRunsResponse, *Response, error) { + if err := escapeValidatePathSegments(&org); err != nil { + return nil, nil, err } + return c.listActionRuns(fmt.Sprintf("/orgs/%s/actions/runs", org), opt) } diff --git a/vendor/code.gitea.io/sdk/gitea/org_team.go b/vendor/code.gitea.io/sdk/gitea/org_team.go index 070b4f91b..71a6b35fe 100644 --- a/vendor/code.gitea.io/sdk/gitea/org_team.go +++ b/vendor/code.gitea.io/sdk/gitea/org_team.go @@ -13,14 +13,15 @@ import ( // Team represents a team in an organization type Team struct { - ID int64 `json:"id"` - Name string `json:"name"` - Description string `json:"description"` - Organization *Organization `json:"organization"` - Permission AccessMode `json:"permission"` - CanCreateOrgRepo bool `json:"can_create_org_repo"` - IncludesAllRepositories bool `json:"includes_all_repositories"` - Units []RepoUnitType `json:"units"` + ID int64 `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + Organization *Organization `json:"organization"` + Permission AccessMode `json:"permission"` + CanCreateOrgRepo bool `json:"can_create_org_repo"` + IncludesAllRepositories bool `json:"includes_all_repositories"` + Units []RepoUnitType `json:"units"` + UnitsMap map[string]string `json:"units_map"` } // RepoUnitType represent all unit types of a repo gitea currently offer @@ -120,12 +121,13 @@ func (c *Client) SearchOrgTeams(org string, opt *SearchTeamsOptions) ([]*Team, * // CreateTeamOption options for creating a team type CreateTeamOption struct { - Name string `json:"name"` - Description string `json:"description"` - Permission AccessMode `json:"permission"` - CanCreateOrgRepo bool `json:"can_create_org_repo"` - IncludesAllRepositories bool `json:"includes_all_repositories"` - Units []RepoUnitType `json:"units"` + Name string `json:"name"` + Description string `json:"description"` + Permission AccessMode `json:"permission"` + CanCreateOrgRepo bool `json:"can_create_org_repo"` + IncludesAllRepositories bool `json:"includes_all_repositories"` + Units []RepoUnitType `json:"units"` + UnitsMap map[string]string `json:"units_map"` } // Validate the CreateTeamOption struct @@ -166,12 +168,13 @@ func (c *Client) CreateTeam(org string, opt CreateTeamOption) (*Team, *Response, // EditTeamOption options for editing a team type EditTeamOption struct { - Name string `json:"name"` - Description *string `json:"description"` - Permission AccessMode `json:"permission"` - CanCreateOrgRepo *bool `json:"can_create_org_repo"` - IncludesAllRepositories *bool `json:"includes_all_repositories"` - Units []RepoUnitType `json:"units"` + Name string `json:"name"` + Description *string `json:"description"` + Permission AccessMode `json:"permission"` + CanCreateOrgRepo *bool `json:"can_create_org_repo"` + IncludesAllRepositories *bool `json:"includes_all_repositories"` + Units []RepoUnitType `json:"units"` + UnitsMap map[string]string `json:"units_map"` } // Validate the EditTeamOption struct @@ -262,6 +265,16 @@ func (c *Client) ListTeamRepositories(id int64, opt ListTeamRepositoriesOptions) return repos, resp, err } +// GetTeamRepository gets a repository that belongs to a team. +func (c *Client) GetTeamRepository(id int64, org, repo string) (*Repository, *Response, error) { + if err := escapeValidatePathSegments(&org, &repo); err != nil { + return nil, nil, err + } + result := new(Repository) + resp, err := c.getParsedResponse("GET", fmt.Sprintf("/teams/%d/repos/%s/%s", id, org, repo), nil, nil, result) + return result, resp, err +} + // AddTeamRepository adds a repository to a team func (c *Client) AddTeamRepository(id int64, org, repo string) (*Response, error) { if err := escapeValidatePathSegments(&org, &repo); err != nil { diff --git a/vendor/code.gitea.io/sdk/gitea/package.go b/vendor/code.gitea.io/sdk/gitea/package.go index 1a2c2cc81..9bcb156e8 100644 --- a/vendor/code.gitea.io/sdk/gitea/package.go +++ b/vendor/code.gitea.io/sdk/gitea/package.go @@ -6,6 +6,7 @@ package gitea import ( "fmt" + "net/url" "time" ) @@ -14,17 +15,19 @@ type Package struct { // the package's id ID int64 `json:"id"` // the package's owner - Owner User `json:"owner"` + Owner *User `json:"owner"` // the repo this package belongs to (if any) Repository *Repository `json:"repository"` // the package's creator - Creator User `json:"creator"` + Creator *User `json:"creator"` // the type of package: Type string `json:"type"` // the name of the package Name string `json:"name"` // the version of the package Version string `json:"version"` + // the HTML URL for viewing the package + HTMLURL string `json:"html_url"` // the date the package was uploaded CreatedAt time.Time `json:"created_at"` } @@ -50,6 +53,20 @@ type PackageFile struct { // ListPackagesOptions options for listing packages type ListPackagesOptions struct { ListOptions + // type, and q are only used for ListPackages, not ListPackageVersions + Type string + Q string +} + +func (opt ListPackagesOptions) getURLQuery() url.Values { + query := opt.ListOptions.getURLQuery() + if opt.Type != "" { + query.Set("type", opt.Type) + } + if opt.Q != "" { + query.Set("q", opt.Q) + } + return query } // ListPackages lists all the packages owned by a given owner (user, organisation) @@ -63,6 +80,17 @@ func (c *Client) ListPackages(owner string, opt ListPackagesOptions) ([]*Package return packages, resp, err } +// ListPackageVersions lists all versions of a package. +func (c *Client) ListPackageVersions(owner, packageType, name string, opt ListPackagesOptions) ([]*Package, *Response, error) { + if err := escapeValidatePathSegments(&owner, &packageType, &name); err != nil { + return nil, nil, err + } + opt.setDefaults() + packages := make([]*Package, 0, opt.PageSize) + resp, err := c.getParsedResponse("GET", fmt.Sprintf("/packages/%s/%s/%s?%s", owner, packageType, name, opt.ListOptions.getURLQuery().Encode()), nil, nil, &packages) + return packages, resp, err +} + // GetPackage gets the details of a specific package version func (c *Client) GetPackage(owner, packageType, name, version string) (*Package, *Response, error) { if err := escapeValidatePathSegments(&owner, &packageType, &name, &version); err != nil { diff --git a/vendor/code.gitea.io/sdk/gitea/pull.go b/vendor/code.gitea.io/sdk/gitea/pull.go index 7da580492..a466d3576 100644 --- a/vendor/code.gitea.io/sdk/gitea/pull.go +++ b/vendor/code.gitea.io/sdk/gitea/pull.go @@ -103,6 +103,10 @@ const ( MergeStyleRebaseMerge MergeStyle = "rebase-merge" // MergeStyleSquash squash and merge pull MergeStyleSquash MergeStyle = "squash" + // MergeStyleFastForwardOnly fast-forward merge + MergeStyleFastForwardOnly MergeStyle = "fast-forward-only" + // MergeStyleManuallyMerged manually merged + MergeStyleManuallyMerged MergeStyle = "manually-merged" ) // QueryEncode turns options into querystring argument @@ -156,6 +160,25 @@ func (c *Client) GetPullRequest(owner, repo string, index int64) (*PullRequest, return pr, resp, err } +// GetPullRequestByBaseHead gets a pull request by its base and head branches. +func (c *Client) GetPullRequestByBaseHead(owner, repo, base, head string) (*PullRequest, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo, &base); err != nil { + return nil, nil, err + } + if err := c.checkServerVersionGreaterThanOrEqual(version1_22_0); err != nil { + return nil, nil, err + } + head = pathEscapeSegments(head) + pr := new(PullRequest) + resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/pulls/%s/%s", owner, repo, base, head), nil, nil, pr) + if c.checkServerVersionGreaterThanOrEqual(version1_14_0) != nil { + if err := fixPullHeadSha(c, pr); err != nil { + return pr, resp, err + } + } + return pr, resp, err +} + // CreatePullRequestOption options when creating a pull request type CreatePullRequestOption struct { Head string `json:"head"` @@ -240,7 +263,7 @@ type MergePullRequestOption struct { MergeCommitID string `json:"MergeCommitID"` Title string `json:"MergeTitleField"` Message string `json:"MergeMessageField"` - DeleteBranchAfterMerge bool `json:"delete_branch_after_merge"` + DeleteBranchAfterMerge *bool `json:"delete_branch_after_merge,omitempty"` ForceMerge bool `json:"force_merge"` HeadCommitId string `json:"head_commit_id"` MergeWhenChecksSucceed bool `json:"merge_when_checks_succeed"` @@ -272,7 +295,7 @@ func (c *Client) MergePullRequest(owner, repo string, index int64, opt MergePull if err != nil { return false, resp, err } - return status == 200, resp, nil + return status == 200 || status == 201, resp, nil } // IsPullRequestMerged test if one PR is merged to one repository @@ -337,6 +360,17 @@ func (c *Client) GetPullRequestDiff(owner, repo string, index int64, opts PullRe return c.getPullRequestDiffOrPatch(owner, repo, pullRequestDiffTypeDiff, index, opts) } +// CancelScheduledAutoMerge cancels a scheduled automatic merge for a pull request. +func (c *Client) CancelScheduledAutoMerge(owner, repo string, index int64) (*Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, err + } + if err := c.checkServerVersionGreaterThanOrEqual(version1_18_0); err != nil { + return nil, err + } + return c.doRequestWithStatusHandle("DELETE", fmt.Sprintf("/repos/%s/%s/pulls/%d/merge", owner, repo, index), nil, nil) +} + // ListPullRequestCommitsOptions options for listing pull requests type ListPullRequestCommitsOptions struct { ListOptions diff --git a/vendor/code.gitea.io/sdk/gitea/pull_review.go b/vendor/code.gitea.io/sdk/gitea/pull_review.go index e5e39bd2e..d241712f8 100644 --- a/vendor/code.gitea.io/sdk/gitea/pull_review.go +++ b/vendor/code.gitea.io/sdk/gitea/pull_review.go @@ -92,6 +92,11 @@ type CreatePullReviewComment struct { NewLineNum int64 `json:"new_position"` } +// CreatePullReviewCommentReplyOptions are options to reply to a pull request review comment. +type CreatePullReviewCommentReplyOptions struct { + Body string `json:"body"` +} + // SubmitPullReviewOptions are options to submit a pending pull review type SubmitPullReviewOptions struct { State ReviewStateType `json:"event"` @@ -146,6 +151,14 @@ func (opt CreatePullReviewComment) Validate() error { return nil } +// Validate the CreatePullReviewCommentReplyOptions struct. +func (opt CreatePullReviewCommentReplyOptions) Validate() error { + if len(strings.TrimSpace(opt.Body)) == 0 { + return fmt.Errorf("body is empty") + } + return nil +} + // ListPullReviews lists all reviews of a pull request func (c *Client) ListPullReviews(owner, repo string, index int64, opt ListPullReviewsOptions) ([]*PullReview, *Response, error) { if err := escapeValidatePathSegments(&owner, &repo); err != nil { @@ -228,6 +241,28 @@ func (c *Client) CreatePullReview(owner, repo string, index int64, opt CreatePul return r, resp, err } +// CreatePullReviewCommentReply replies to a pull request review comment. +// Available on Gitea main/nightly; first released version not assigned yet. +// Upstream: gitea/gitea#36683 (331450b17a025ce78b5bf9405ca8d684607680ef). +func (c *Client) CreatePullReviewCommentReply(owner, repo string, index, id int64, opt CreatePullReviewCommentReplyOptions) (*PullReviewComment, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } + if err := opt.Validate(); err != nil { + return nil, nil, err + } + body, err := json.Marshal(&opt) + if err != nil { + return nil, nil, err + } + + r := new(PullReviewComment) + resp, err := c.getParsedResponse("POST", + fmt.Sprintf("/repos/%s/%s/pulls/%d/comments/%d/replies", owner, repo, index, id), + jsonHeader, bytes.NewReader(body), r) + return r, resp, err +} + // SubmitPullReview submit a pending review to an pull request func (c *Client) SubmitPullReview(owner, repo string, index, id int64, opt SubmitPullReviewOptions) (*PullReview, *Response, error) { if err := escapeValidatePathSegments(&owner, &repo); err != nil { @@ -318,3 +353,23 @@ func (c *Client) UnDismissPullReview(owner, repo string, index, id int64) (*Resp fmt.Sprintf("/repos/%s/%s/pulls/%d/reviews/%d/undismissals", owner, repo, index, id), jsonHeader, nil) } + +// ResolvePullReviewComment resolves a pull-request review comment conversation. +// Available on Gitea main/nightly; first released version not assigned yet. +// Upstream: gitea/gitea#36441 (c2dea22926f9e7a40aa47296e7b9bc3d1c5b039e). +func (c *Client) ResolvePullReviewComment(owner, repo string, commentID int64) (*Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, err + } + return c.doRequestWithStatusHandle("POST", fmt.Sprintf("/repos/%s/%s/pulls/comments/%d/resolve", owner, repo, commentID), nil, nil) +} + +// UnresolvePullReviewComment unresolves a pull-request review comment conversation. +// Available on Gitea main/nightly; first released version not assigned yet. +// Upstream: gitea/gitea#36441 (c2dea22926f9e7a40aa47296e7b9bc3d1c5b039e). +func (c *Client) UnresolvePullReviewComment(owner, repo string, commentID int64) (*Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, err + } + return c.doRequestWithStatusHandle("POST", fmt.Sprintf("/repos/%s/%s/pulls/comments/%d/unresolve", owner, repo, commentID), nil, nil) +} diff --git a/vendor/code.gitea.io/sdk/gitea/repo.go b/vendor/code.gitea.io/sdk/gitea/repo.go index f8d8a70d8..466a4b481 100644 --- a/vendor/code.gitea.io/sdk/gitea/repo.go +++ b/vendor/code.gitea.io/sdk/gitea/repo.go @@ -421,7 +421,7 @@ func (c *Client) CreateOrgRepo(org string, opt CreateRepoOption) (*Repository, * return nil, nil, err } repo := new(Repository) - resp, err := c.getParsedResponse("POST", fmt.Sprintf("/org/%s/repos", org), jsonHeader, bytes.NewReader(body), repo) + resp, err := c.getParsedResponse("POST", fmt.Sprintf("/orgs/%s/repos", org), jsonHeader, bytes.NewReader(body), repo) return repo, resp, err } @@ -582,16 +582,7 @@ func (c *Client) GetArchiveReader(owner, repo, ref string, ext ArchiveType) (io. return nil, nil, err } ref = pathEscapeSegments(ref) - resp, err := c.doRequest("GET", fmt.Sprintf("/repos/%s/%s/archive/%s%s", owner, repo, ref, ext), nil, nil) - if err != nil { - return nil, resp, err - } - - if _, err := statusCodeToErr(resp); err != nil { - return nil, resp, err - } - - return resp.Body, resp, nil + return c.getResponseReader("GET", fmt.Sprintf("/repos/%s/%s/archive/%s%s", owner, repo, ref, ext), nil, nil) } // UpdateRepoAvatarOption options for updating repository avatar diff --git a/vendor/code.gitea.io/sdk/gitea/repo_action.go b/vendor/code.gitea.io/sdk/gitea/repo_action.go index 9c421c6eb..68ff96a10 100644 --- a/vendor/code.gitea.io/sdk/gitea/repo_action.go +++ b/vendor/code.gitea.io/sdk/gitea/repo_action.go @@ -8,7 +8,6 @@ import ( "bytes" "encoding/json" "fmt" - "net/http" "net/url" ) @@ -62,37 +61,18 @@ func (c *Client) ListRepoActionVariable(user, repo string, opt ListRepoActionVar } // 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 { +func (c *Client) CreateRepoActionSecret(user, repo, secretName string, opt CreateOrUpdateSecretOption) (*Response, error) { + if err := escapeValidatePathSegments(&user, &repo, &secretName); err != nil { return nil, err } - if err := (&opt).Validate(); err != nil { + 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) - } + return c.doRequestWithStatusHandle("PUT", fmt.Sprintf("/repos/%s/%s/actions/secrets/%s", user, repo, secretName), jsonHeader, bytes.NewReader(body)) } // DeleteRepoActionSecret deletes a secret from the Gitea Actions. diff --git a/vendor/code.gitea.io/sdk/gitea/repo_action_extra.go b/vendor/code.gitea.io/sdk/gitea/repo_action_extra.go new file mode 100644 index 000000000..b20e09061 --- /dev/null +++ b/vendor/code.gitea.io/sdk/gitea/repo_action_extra.go @@ -0,0 +1,212 @@ +// Copyright 2026 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" + "io" + "net/url" +) + +// CreateRepoActionRunnerRegistrationToken creates a repository-scope runner registration token. +func (c *Client) CreateRepoActionRunnerRegistrationToken(owner, repo string) (*RegistrationToken, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } + if err := c.checkServerVersionGreaterThanOrEqual(version1_22_0); err != nil { + return nil, nil, err + } + return c.createActionRegistrationToken(fmt.Sprintf("/repos/%s/%s/actions/runners/registration-token", owner, repo)) +} + +// ListRepoActionRunners lists repository-scope Actions runners. +func (c *Client) ListRepoActionRunners(owner, repo string, opt ListActionRunnersOptions) (*ActionRunnersResponse, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } + if err := c.checkServerVersionGreaterThanOrEqual(version1_25_0); err != nil { + return nil, nil, err + } + return c.listActionRunners(fmt.Sprintf("/repos/%s/%s/actions/runners", owner, repo), opt) +} + +// GetRepoActionRunner gets one repository-scope Actions runner. +func (c *Client) GetRepoActionRunner(owner, repo string, runnerID int64) (*ActionRunner, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } + if err := c.checkServerVersionGreaterThanOrEqual(version1_25_0); err != nil { + return nil, nil, err + } + return c.getActionRunner(fmt.Sprintf("/repos/%s/%s/actions/runners/%d", owner, repo, runnerID)) +} + +// DeleteRepoActionRunner deletes one repository-scope Actions runner. +func (c *Client) DeleteRepoActionRunner(owner, repo string, runnerID int64) (*Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, err + } + if err := c.checkServerVersionGreaterThanOrEqual(version1_25_0); err != nil { + return nil, err + } + return c.doRequestWithStatusHandle("DELETE", fmt.Sprintf("/repos/%s/%s/actions/runners/%d", owner, repo, runnerID), nil, nil) +} + +// UpdateRepoActionRunner updates one repository-scope Actions runner. +func (c *Client) UpdateRepoActionRunner(owner, repo string, runnerID int64, opt EditActionRunnerOption) (*ActionRunner, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } + if err := c.checkServerVersionGreaterThanOrEqual(version1_25_0); err != nil { + return nil, nil, err + } + return c.updateActionRunner(fmt.Sprintf("/repos/%s/%s/actions/runners/%d", owner, repo, runnerID), opt) +} + +// ListRepoActionWorkflows lists repository workflows. +func (c *Client) ListRepoActionWorkflows(owner, repo string) (*ActionWorkflowResponse, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } + if err := c.checkServerVersionGreaterThanOrEqual(version1_25_0); err != nil { + return nil, nil, err + } + workflows := new(ActionWorkflowResponse) + resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/actions/workflows", owner, repo), jsonHeader, nil, workflows) + return workflows, resp, err +} + +// GetRepoActionWorkflow gets one repository workflow. +func (c *Client) GetRepoActionWorkflow(owner, repo, workflowID string) (*ActionWorkflow, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo, &workflowID); err != nil { + return nil, nil, err + } + if err := c.checkServerVersionGreaterThanOrEqual(version1_25_0); err != nil { + return nil, nil, err + } + workflow := new(ActionWorkflow) + resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/actions/workflows/%s", owner, repo, workflowID), jsonHeader, nil, workflow) + return workflow, resp, err +} + +// DisableRepoActionWorkflow disables one repository workflow. +func (c *Client) DisableRepoActionWorkflow(owner, repo, workflowID string) (*Response, error) { + if err := escapeValidatePathSegments(&owner, &repo, &workflowID); err != nil { + return nil, err + } + if err := c.checkServerVersionGreaterThanOrEqual(version1_25_0); err != nil { + return nil, err + } + return c.doRequestWithStatusHandle("PUT", fmt.Sprintf("/repos/%s/%s/actions/workflows/%s/disable", owner, repo, workflowID), nil, nil) +} + +// EnableRepoActionWorkflow enables one repository workflow. +func (c *Client) EnableRepoActionWorkflow(owner, repo, workflowID string) (*Response, error) { + if err := escapeValidatePathSegments(&owner, &repo, &workflowID); err != nil { + return nil, err + } + if err := c.checkServerVersionGreaterThanOrEqual(version1_25_0); err != nil { + return nil, err + } + return c.doRequestWithStatusHandle("PUT", fmt.Sprintf("/repos/%s/%s/actions/workflows/%s/enable", owner, repo, workflowID), nil, nil) +} + +// DispatchRepoActionWorkflow dispatches one repository workflow. +func (c *Client) DispatchRepoActionWorkflow(owner, repo, workflowID string, opt CreateActionWorkflowDispatchOption, returnRunDetails bool) (*RunDetails, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo, &workflowID); err != nil { + return nil, nil, err + } + if err := c.checkServerVersionGreaterThanOrEqual(version1_25_0); err != nil { + return nil, nil, err + } + if err := opt.Validate(); err != nil { + return nil, nil, err + } + body, err := json.Marshal(&opt) + if err != nil { + return nil, nil, err + } + + link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/actions/workflows/%s/dispatches", owner, repo, workflowID)) + if returnRunDetails { + link.RawQuery = url.Values{"return_run_details": []string{"true"}}.Encode() + details := new(RunDetails) + resp, err := c.getParsedResponse("POST", link.String(), jsonHeader, bytes.NewReader(body), details) + return details, resp, err + } + + resp, err := c.doRequestWithStatusHandle("POST", link.String(), jsonHeader, bytes.NewReader(body)) + return nil, resp, err +} + +// ListRepoActionRunArtifacts lists artifacts for one workflow run. +func (c *Client) ListRepoActionRunArtifacts(owner, repo string, runID int64, opt ListActionArtifactsOptions) (*ActionArtifactsResponse, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } + if err := c.checkServerVersionGreaterThanOrEqual(version1_25_0); err != nil { + return nil, nil, err + } + return c.listActionArtifacts(fmt.Sprintf("/repos/%s/%s/actions/runs/%d/artifacts", owner, repo, runID), opt) +} + +// ListRepoActionArtifacts lists repository artifacts. +func (c *Client) ListRepoActionArtifacts(owner, repo string, opt ListActionArtifactsOptions) (*ActionArtifactsResponse, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } + if err := c.checkServerVersionGreaterThanOrEqual(version1_25_0); err != nil { + return nil, nil, err + } + return c.listActionArtifacts(fmt.Sprintf("/repos/%s/%s/actions/artifacts", owner, repo), opt) +} + +// GetRepoActionArtifact gets one repository artifact. +func (c *Client) GetRepoActionArtifact(owner, repo string, artifactID int64) (*ActionArtifact, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } + if err := c.checkServerVersionGreaterThanOrEqual(version1_25_0); err != nil { + return nil, nil, err + } + artifact := new(ActionArtifact) + resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/actions/artifacts/%d", owner, repo, artifactID), jsonHeader, nil, artifact) + return artifact, resp, err +} + +// DeleteRepoActionArtifact deletes one repository artifact. +func (c *Client) DeleteRepoActionArtifact(owner, repo string, artifactID int64) (*Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, err + } + if err := c.checkServerVersionGreaterThanOrEqual(version1_25_0); err != nil { + return nil, err + } + return c.doRequestWithStatusHandle("DELETE", fmt.Sprintf("/repos/%s/%s/actions/artifacts/%d", owner, repo, artifactID), nil, nil) +} + +// GetRepoActionArtifactArchive downloads one repository artifact zip archive. +func (c *Client) GetRepoActionArtifactArchive(owner, repo string, artifactID int64) ([]byte, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } + if err := c.checkServerVersionGreaterThanOrEqual(version1_25_0); err != nil { + return nil, nil, err + } + return c.getResponse("GET", fmt.Sprintf("/repos/%s/%s/actions/artifacts/%d/zip", owner, repo, artifactID), nil, nil) +} + +// GetRepoActionArtifactArchiveReader returns a reader for one repository artifact zip archive. +func (c *Client) GetRepoActionArtifactArchiveReader(owner, repo string, artifactID int64) (io.ReadCloser, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } + if err := c.checkServerVersionGreaterThanOrEqual(version1_25_0); err != nil { + return nil, nil, err + } + return c.getResponseReader("GET", fmt.Sprintf("/repos/%s/%s/actions/artifacts/%d/zip", owner, repo, artifactID), nil, nil) +} diff --git a/vendor/code.gitea.io/sdk/gitea/repo_branch.go b/vendor/code.gitea.io/sdk/gitea/repo_branch.go index 637ad5f2f..9ca8fdd7a 100644 --- a/vendor/code.gitea.io/sdk/gitea/repo_branch.go +++ b/vendor/code.gitea.io/sdk/gitea/repo_branch.go @@ -75,9 +75,10 @@ func (c *Client) ListRepoBranches(user, repo string, opt ListRepoBranchesOptions // GetRepoBranch get one branch's information of one repository func (c *Client) GetRepoBranch(user, repo, branch string) (*Branch, *Response, error) { - if err := escapeValidatePathSegments(&user, &repo, &branch); err != nil { + if err := escapeValidatePathSegments(&user, &repo); err != nil { return nil, nil, err } + branch = pathEscapeSegments(branch) b := new(Branch) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/branches/%s", user, repo, branch), nil, nil, &b) if err != nil { @@ -88,9 +89,10 @@ func (c *Client) GetRepoBranch(user, repo, branch string) (*Branch, *Response, e // DeleteRepoBranch delete a branch in a repository func (c *Client) DeleteRepoBranch(user, repo, branch string) (bool, *Response, error) { - if err := escapeValidatePathSegments(&user, &repo, &branch); err != nil { + if err := escapeValidatePathSegments(&user, &repo); err != nil { return false, nil, err } + branch = pathEscapeSegments(branch) if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return false, nil, err } @@ -113,11 +115,41 @@ func (opt UpdateRepoBranchOption) Validate() error { return nil } -func (c *Client) UpdateRepoBranch(user, repo, branch string, opt UpdateRepoBranchOption) (sucessful bool, resp *Response, err error) { - if err := escapeValidatePathSegments(&user, &repo, &branch); err != nil { +// RenameRepoBranchOption renames a repository branch. +type RenameRepoBranchOption struct { + Name string `json:"name"` +} + +// Validate checks whether the rename payload is valid. +func (opt RenameRepoBranchOption) Validate() error { + if len(opt.Name) == 0 { + return errors.New("empty Name field") + } + return nil +} + +// UpdateRepoBranchRefOption updates a branch ref to point to a new commit. +type UpdateRepoBranchRefOption struct { + NewCommitID string `json:"new_commit_id"` + OldCommitID string `json:"old_commit_id"` + Force bool `json:"force"` +} + +// Validate checks whether the branch update payload is valid. +func (opt UpdateRepoBranchRefOption) Validate() error { + if len(opt.NewCommitID) == 0 { + return errors.New("empty NewCommitID field") + } + return nil +} + +// RenameRepoBranch renames a branch in a repository. +func (c *Client) RenameRepoBranch(user, repo, branch string, opt RenameRepoBranchOption) (successful bool, resp *Response, err error) { + if err := escapeValidatePathSegments(&user, &repo); err != nil { return false, nil, err } - if err := c.checkServerVersionGreaterThanOrEqual(version1_23_0); err != nil { + branch = pathEscapeSegments(branch) + if err := c.checkServerVersionGreaterThanOrEqual(version1_24_0); err != nil { return false, nil, err } if err := opt.Validate(); err != nil { @@ -131,6 +163,33 @@ func (c *Client) UpdateRepoBranch(user, repo, branch string, opt UpdateRepoBranc return status == 204, resp, err } +// UpdateRepoBranchRef updates the commit a branch points to. +// Available on Gitea main/nightly; first released version not assigned yet. +// Upstream: gitea/gitea#35951 (a440116a16c42956f21031bea8422ffbb003c732). +func (c *Client) UpdateRepoBranchRef(user, repo, branch string, opt UpdateRepoBranchRefOption) (successful bool, resp *Response, err error) { + if err := escapeValidatePathSegments(&user, &repo); err != nil { + return false, nil, err + } + branch = pathEscapeSegments(branch) + if err := opt.Validate(); err != nil { + return false, nil, err + } + body, err := json.Marshal(&opt) + if err != nil { + return false, nil, err + } + status, resp, err := c.getStatusCode("PUT", fmt.Sprintf("/repos/%s/%s/branches/%s", user, repo, branch), jsonHeader, bytes.NewReader(body)) + return status == 204, resp, err +} + +// UpdateRepoBranch renames a branch in a repository. +// +// Deprecated: Use RenameRepoBranch instead (identical behavior, clearer name). +// For updating the commit a branch points to, use UpdateRepoBranchRef (PUT). +func (c *Client) UpdateRepoBranch(user, repo, branch string, opt UpdateRepoBranchOption) (sucessful bool, resp *Response, err error) { + return c.RenameRepoBranch(user, repo, branch, RenameRepoBranchOption(opt)) +} + // CreateBranchOption options when creating a branch in a repository type CreateBranchOption struct { // Name of the branch to create diff --git a/vendor/code.gitea.io/sdk/gitea/repo_branch_protection.go b/vendor/code.gitea.io/sdk/gitea/repo_branch_protection.go index 4f40dc360..7c85b1fb3 100644 --- a/vendor/code.gitea.io/sdk/gitea/repo_branch_protection.go +++ b/vendor/code.gitea.io/sdk/gitea/repo_branch_protection.go @@ -37,6 +37,7 @@ type BranchProtection struct { RequireSignedCommits bool `json:"require_signed_commits"` ProtectedFilePatterns string `json:"protected_file_patterns"` UnprotectedFilePatterns string `json:"unprotected_file_patterns"` + BlockAdminMergeOverride bool `json:"block_admin_merge_override"` Created time.Time `json:"created_at"` Updated time.Time `json:"updated_at"` } @@ -66,6 +67,7 @@ type CreateBranchProtectionOption struct { RequireSignedCommits bool `json:"require_signed_commits"` ProtectedFilePatterns string `json:"protected_file_patterns"` UnprotectedFilePatterns string `json:"unprotected_file_patterns"` + BlockAdminMergeOverride bool `json:"block_admin_merge_override"` } // EditBranchProtectionOption options for editing a branch protection @@ -91,6 +93,7 @@ type EditBranchProtectionOption struct { RequireSignedCommits *bool `json:"require_signed_commits"` ProtectedFilePatterns *string `json:"protected_file_patterns"` UnprotectedFilePatterns *string `json:"unprotected_file_patterns"` + BlockAdminMergeOverride *bool `json:"block_admin_merge_override"` } // ListBranchProtectionsOptions list branch protection options diff --git a/vendor/code.gitea.io/sdk/gitea/repo_ext.go b/vendor/code.gitea.io/sdk/gitea/repo_ext.go new file mode 100644 index 000000000..8f65374cb --- /dev/null +++ b/vendor/code.gitea.io/sdk/gitea/repo_ext.go @@ -0,0 +1,342 @@ +// Copyright 2026 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" + "errors" + "fmt" + "net/http" + "net/url" +) + +// --- Pinned pull requests --- + +// ListRepoPinnedPullRequests lists a repo's pinned pull requests +func (c *Client) ListRepoPinnedPullRequests(owner, repo string) ([]*PullRequest, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } + prs := make([]*PullRequest, 0, 5) + resp, err := c.getParsedResponse("GET", + fmt.Sprintf("/repos/%s/%s/pulls/pinned", owner, repo), + jsonHeader, nil, &prs) + return prs, resp, err +} + +// --- Webhooks --- + +// TestWebhook tests a webhook +func (c *Client) TestWebhook(owner, repo string, hookID int64, ref string) (*Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, err + } + opt := map[string]string{"ref": ref} + body, err := json.Marshal(&opt) + if err != nil { + return nil, err + } + status, resp, err := c.getStatusCode("POST", + fmt.Sprintf("/repos/%s/%s/hooks/%d/tests", owner, repo, hookID), + jsonHeader, bytes.NewReader(body)) + if err != nil { + return resp, err + } + if status != http.StatusNoContent { + return resp, fmt.Errorf("unexpected status: %d", status) + } + return resp, nil +} + +// --- Merge upstream --- + +// MergeUpstreamRequest options for merging upstream +type MergeUpstreamRequest struct { + Branch string `json:"branch"` + FfOnly bool `json:"ff_only"` +} + +// MergeUpstreamResponse represents the response from merging upstream +type MergeUpstreamResponse struct { + MergeStyle string `json:"merge_type"` +} + +// MergeUpstream merges upstream into a forked repository +func (c *Client) MergeUpstream(owner, repo string, opt MergeUpstreamRequest) (*MergeUpstreamResponse, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } + body, err := json.Marshal(&opt) + if err != nil { + return nil, nil, err + } + result := new(MergeUpstreamResponse) + resp, err := c.getParsedResponse("POST", + fmt.Sprintf("/repos/%s/%s/merge-upstream", owner, repo), + jsonHeader, bytes.NewReader(body), result) + return result, resp, err +} + +// --- Pin allowed --- + +// NewIssuePinsAllowed represents whether new issue/PR pins are allowed +type NewIssuePinsAllowed struct { + Issues bool `json:"issues"` + PullRequests bool `json:"pull_requests"` +} + +// CheckPinAllowed checks if the current user can pin issues or PRs +func (c *Client) CheckPinAllowed(owner, repo string) (*NewIssuePinsAllowed, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } + result := new(NewIssuePinsAllowed) + resp, err := c.getParsedResponse("GET", + fmt.Sprintf("/repos/%s/%s/new_pin_allowed", owner, repo), + jsonHeader, nil, result) + return result, resp, err +} + +// --- Batch file operations --- + +// ChangeFilesOptions options for batch file operations +type ChangeFilesOptions struct { + Files []*ChangeFileOperation `json:"files"` + Message string `json:"message"` + Branch string `json:"branch,omitempty"` + NewBranch string `json:"new_branch,omitempty"` + ForcePush bool `json:"force_push,omitempty"` + Author Identity `json:"author"` + Committer Identity `json:"committer"` + Dates CommitDateOptions `json:"dates"` + Signoff bool `json:"signoff,omitempty"` +} + +// ChangeFileOperation represents a file operation in batch +type ChangeFileOperation struct { + Operation string `json:"operation"` // create, update, upload, rename, delete + Path string `json:"path"` + Content string `json:"content"` // base64 encoded for create/update + SHA string `json:"sha,omitempty"` // required for update/delete + FromPath string `json:"from_path,omitempty"` // for rename +} + +// ChangeFiles creates, updates, or deletes multiple files +func (c *Client) ChangeFiles(owner, repo string, opt ChangeFilesOptions) (*FileResponse, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } + body, err := json.Marshal(&opt) + if err != nil { + return nil, nil, err + } + result := new(FileResponse) + resp, err := c.getParsedResponse("POST", + fmt.Sprintf("/repos/%s/%s/contents", owner, repo), + jsonHeader, bytes.NewReader(body), &result) + return result, resp, err +} + +// --- Branch protection priorities --- + +// UpdateBranchProtectionPriorities updates the priorities of branch protection rules +func (c *Client) UpdateBranchProtectionPriorities(owner, repo string, ids []int64) (*Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, err + } + opt := map[string][]int64{"ids": ids} + body, err := json.Marshal(&opt) + if err != nil { + return nil, err + } + status, resp, err := c.getStatusCode("POST", + fmt.Sprintf("/repos/%s/%s/branch_protections/priority", owner, repo), + jsonHeader, bytes.NewReader(body)) + if err != nil { + return resp, err + } + if status != http.StatusNoContent { + return resp, fmt.Errorf("unexpected status: %d", status) + } + return resp, nil +} + +// --- File contents (batch lookup) --- + +// GetFilesOptions controls batch file-content lookup requests. +type GetFilesOptions struct { + Files []string `json:"files"` +} + +// Validate checks whether the batch file lookup request is valid. +func (opt GetFilesOptions) Validate() error { + if len(opt.Files) == 0 { + return errors.New("empty Files field") + } + return nil +} + +// GetRepoFileContents fetches metadata and contents for multiple files through the GET endpoint. +// The file list is JSON-encoded in the "body" query parameter; for large file lists prefer +// PostRepoFileContents to avoid URL length limitations. +func (c *Client) GetRepoFileContents(owner, repo, ref string, opt GetFilesOptions) ([]*ContentsResponse, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } + if err := opt.Validate(); err != nil { + return nil, nil, err + } + body, err := json.Marshal(&opt) + if err != nil { + return nil, nil, err + } + link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/file-contents", owner, repo)) + query := link.Query() + if ref != "" { + query.Add("ref", ref) + } + query.Add("body", string(body)) + link.RawQuery = query.Encode() + + contents := make([]*ContentsResponse, 0, len(opt.Files)) + resp, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, &contents) + return contents, resp, err +} + +// PostRepoFileContents fetches metadata and contents for multiple files through the POST endpoint. +func (c *Client) PostRepoFileContents(owner, repo, ref string, opt GetFilesOptions) ([]*ContentsResponse, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } + if err := opt.Validate(); err != nil { + return nil, nil, err + } + body, err := json.Marshal(&opt) + if err != nil { + return nil, nil, err + } + link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/file-contents", owner, repo)) + if ref != "" { + link.RawQuery = url.Values{"ref": []string{ref}}.Encode() + } + + contents := make([]*ContentsResponse, 0, len(opt.Files)) + resp, err := c.getParsedResponse("POST", link.String(), jsonHeader, bytes.NewReader(body), &contents) + return contents, resp, err +} + +// --- Issue config --- + +// IssueConfigContactLink represents an issue config contact link. +type IssueConfigContactLink struct { + Name string `json:"name"` + URL string `json:"url"` + About string `json:"about"` +} + +// IssueConfig represents the parsed issue config for a repository. +type IssueConfig struct { + BlankIssuesEnabled bool `json:"blank_issues_enabled"` + ContactLinks []IssueConfigContactLink `json:"contact_links"` +} + +// GetIssueConfig gets the issue config for a repository. +func (c *Client) GetIssueConfig(owner, repo string) (*IssueConfig, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } + config := new(IssueConfig) + resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issue_config", owner, repo), jsonHeader, nil, config) + return config, resp, err +} + +// --- Licenses --- + +// GetRepoLicenses gets detected licenses for a repository. +func (c *Client) GetRepoLicenses(owner, repo string) ([]string, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } + licenses := make([]string, 0, 2) + resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/licenses", owner, repo), jsonHeader, nil, &licenses) + return licenses, resp, err +} + +// --- Signing keys --- + +// GetRepoSigningKeyGPG gets the repository signing GPG public key. +func (c *Client) GetRepoSigningKeyGPG(owner, repo string) (string, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return "", nil, err + } + key, resp, err := c.getResponse("GET", fmt.Sprintf("/repos/%s/%s/signing-key.gpg", owner, repo), nil, nil) + return string(key), resp, err +} + +// GetRepoSigningKeySSH gets the repository signing SSH public key. +func (c *Client) GetRepoSigningKeySSH(owner, repo string) (string, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return "", nil, err + } + key, resp, err := c.getResponse("GET", fmt.Sprintf("/repos/%s/%s/signing-key.pub", owner, repo), nil, nil) + return string(key), resp, err +} + +// --- Subscribers --- + +// ListRepoSubscribers lists repository watchers. +func (c *Client) ListRepoSubscribers(owner, repo string, opt ListOptions) ([]*User, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } + opt.setDefaults() + subscribers := make([]*User, 0, opt.PageSize) + resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/subscribers?%s", owner, repo, opt.getURLQuery().Encode()), jsonHeader, nil, &subscribers) + return subscribers, resp, err +} + +// --- Diff patch --- + +// ApplyDiffPatchFileOptions applies a patch against repository contents. +type ApplyDiffPatchFileOptions struct { + FileOptions + Content string `json:"content"` +} + +// Validate checks whether the patch payload is valid. +func (opt ApplyDiffPatchFileOptions) Validate() error { + if len(opt.Content) == 0 { + return errors.New("empty Content field") + } + return nil +} + +// ApplyRepoDiffPatch applies a patch to repository contents. +func (c *Client) ApplyRepoDiffPatch(owner, repo string, opt ApplyDiffPatchFileOptions) (*FileResponse, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } + if err := opt.Validate(); err != nil { + return nil, nil, err + } + body, err := json.Marshal(&opt) + if err != nil { + return nil, nil, err + } + result := new(FileResponse) + resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/diffpatch", owner, repo), jsonHeader, bytes.NewReader(body), result) + return result, resp, err +} + +// --- Push mirrors --- + +// TriggerPushMirrorsSync triggers push-mirror syncing for a repository. +func (c *Client) TriggerPushMirrorsSync(owner, repo string) (*Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, err + } + return c.doRequestWithStatusHandle("POST", fmt.Sprintf("/repos/%s/%s/push_mirrors-sync", owner, repo), nil, nil) +} diff --git a/vendor/code.gitea.io/sdk/gitea/repo_file.go b/vendor/code.gitea.io/sdk/gitea/repo_file.go index 1c078d9d6..ae07b5273 100644 --- a/vendor/code.gitea.io/sdk/gitea/repo_file.go +++ b/vendor/code.gitea.io/sdk/gitea/repo_file.go @@ -12,6 +12,7 @@ import ( "io" "net/url" "strings" + "time" ) // FileOptions options for all file APIs @@ -22,6 +23,8 @@ type FileOptions struct { BranchName string `json:"branch"` // new_branch (optional) will make a new branch from `branch` before creating the file NewBranchName string `json:"new_branch"` + // force_push (optional) will do a force-push if the new branch already exists + ForcePush bool `json:"force_push"` // `author` and `committer` are optional (if only one is given, it will be used for the other, otherwise the authenticated user will be used) Author Identity `json:"author"` Committer Identity `json:"committer"` @@ -71,9 +74,15 @@ type FileLinksResponse struct { // ContentsResponse contains information about a repo's entry's (dir, file, symlink, submodule) metadata and content type ContentsResponse struct { - Name string `json:"name"` - Path string `json:"path"` - SHA string `json:"sha"` + Name string `json:"name"` + Path string `json:"path"` + SHA string `json:"sha"` + LastCommitSha *string `json:"last_commit_sha,omitempty"` + // swagger:strfmt date-time + LastCommitterDate *time.Time `json:"last_committer_date,omitempty"` + // swagger:strfmt date-time + LastAuthorDate *time.Time `json:"last_author_date,omitempty"` + LastCommitMessage *string `json:"last_commit_message,omitempty"` // `type` will be `file`, `dir`, `symlink`, or `submodule` Type string `json:"type"` Size int64 `json:"size"` @@ -90,7 +99,8 @@ type ContentsResponse struct { // `submodule_git_url` is populated when `type` is `submodule`, otherwise null SubmoduleGitURL *string `json:"submodule_git_url"` Links *FileLinksResponse `json:"_links"` - LastCommitSha string `json:"last_commit_sha"` + LfsOid *string `json:"lfs_oid,omitempty"` + LfsSize *int64 `json:"lfs_size,omitempty"` } // FileCommitResponse contains information generated from a Git commit for a repo's file. diff --git a/vendor/code.gitea.io/sdk/gitea/repo_file_ext.go b/vendor/code.gitea.io/sdk/gitea/repo_file_ext.go index 111269810..c5a8f4dfa 100644 --- a/vendor/code.gitea.io/sdk/gitea/repo_file_ext.go +++ b/vendor/code.gitea.io/sdk/gitea/repo_file_ext.go @@ -6,7 +6,6 @@ package gitea import ( "fmt" - "io" "net/url" ) @@ -63,18 +62,7 @@ func (c *Client) GetEditorConfig(owner, repo, filepath string, ref ...string) ([ link.RawQuery = query.Encode() } - resp, err := c.doRequest("GET", link.String(), nil, nil) - if err != nil { - return nil, resp, err - } - defer func() { - if closeErr := resp.Body.Close(); closeErr != nil && err == nil { - err = closeErr - } - }() - - data, err := io.ReadAll(resp.Body) - return data, resp, err + return c.getResponse("GET", link.String(), nil, nil) } // GetRawFileOrLFS gets a file or its LFS object from a repository @@ -92,18 +80,7 @@ func (c *Client) GetRawFileOrLFS(owner, repo, filepath string, ref ...string) ([ link.RawQuery = query.Encode() } - resp, err := c.doRequest("GET", link.String(), nil, nil) - if err != nil { - return nil, resp, err - } - defer func() { - if closeErr := resp.Body.Close(); closeErr != nil && err == nil { - err = closeErr - } - }() - - data, err := io.ReadAll(resp.Body) - return data, resp, err + return c.getResponse("GET", link.String(), nil, nil) } // GetRawFile gets a file from a repository @@ -121,16 +98,5 @@ func (c *Client) GetRawFile(owner, repo, filepath string, ref ...string) ([]byte link.RawQuery = query.Encode() } - resp, err := c.doRequest("GET", link.String(), nil, nil) - if err != nil { - return nil, resp, err - } - defer func() { - if closeErr := resp.Body.Close(); closeErr != nil && err == nil { - err = closeErr - } - }() - - data, err := io.ReadAll(resp.Body) - return data, resp, err + return c.getResponse("GET", link.String(), nil, nil) } diff --git a/vendor/code.gitea.io/sdk/gitea/repo_helpers.go b/vendor/code.gitea.io/sdk/gitea/repo_helpers.go new file mode 100644 index 000000000..39fe38b05 --- /dev/null +++ b/vendor/code.gitea.io/sdk/gitea/repo_helpers.go @@ -0,0 +1,51 @@ +// Copyright 2026 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package gitea + +import ( + "fmt" + "net/http" +) + +// GetCommitPullRequest gets the pull request associated with a commit SHA +func (c *Client) GetCommitPullRequest(owner, repo, sha string) (*PullRequest, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo, &sha); err != nil { + return nil, nil, err + } + pr := new(PullRequest) + resp, err := c.getParsedResponse("GET", + fmt.Sprintf("/repos/%s/%s/commits/%s/pull", owner, repo, sha), + jsonHeader, nil, &pr) + return pr, resp, err +} + +// UpdatePullRequest updates a pull request with new commits from the base branch +func (c *Client) UpdatePullRequest(owner, repo string, index int64) (*Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, err + } + status, resp, err := c.getStatusCode("POST", + fmt.Sprintf("/repos/%s/%s/pulls/%d/update", owner, repo, index), + jsonHeader, nil) + if err != nil { + return resp, err + } + if status != http.StatusOK { + return resp, fmt.Errorf("unexpected status: %d", status) + } + return resp, nil +} + +// GetUserTrackedTimes gets all tracked times for a user in a repository +func (c *Client) GetUserTrackedTimes(owner, repo, user string) ([]*TrackedTime, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo, &user); err != nil { + return nil, nil, err + } + times := make([]*TrackedTime, 0, 10) + resp, err := c.getParsedResponse("GET", + fmt.Sprintf("/repos/%s/%s/times/%s", owner, repo, user), + jsonHeader, nil, ×) + return times, resp, err +} diff --git a/vendor/code.gitea.io/sdk/gitea/repo_misc.go b/vendor/code.gitea.io/sdk/gitea/repo_misc.go new file mode 100644 index 000000000..00b123605 --- /dev/null +++ b/vendor/code.gitea.io/sdk/gitea/repo_misc.go @@ -0,0 +1,90 @@ +// Copyright 2026 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package gitea + +import ( + "fmt" + "net/url" + "time" +) + +// ListRepoActivityFeedsOptions options for listing repository activity feeds +type ListRepoActivityFeedsOptions struct { + ListOptions + Date string `json:"date"` // the date of the activities to be found (format: YYYY-MM-DD) +} + +// ListRepoActivityFeeds lists activity feeds for a repository +func (c *Client) ListRepoActivityFeeds(owner, repo string, opt ListRepoActivityFeedsOptions) ([]*Activity, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } + opt.setDefaults() + + link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/activities/feeds", owner, repo)) + query := opt.getURLQuery() + if opt.Date != "" { + query.Add("date", opt.Date) + } + link.RawQuery = query.Encode() + + feeds := make([]*Activity, 0, opt.PageSize) + resp, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, &feeds) + return feeds, resp, err +} + +// IssueConfigValidation represents the validation result for issue config +type IssueConfigValidation struct { + Valid bool `json:"valid"` + Message string `json:"message"` +} + +// ValidateIssueConfig validates the issue config file for a repository +func (c *Client) ValidateIssueConfig(owner, repo string) (*IssueConfigValidation, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } + result := new(IssueConfigValidation) + resp, err := c.getParsedResponse("GET", + fmt.Sprintf("/repos/%s/%s/issue_config/validate", owner, repo), + jsonHeader, nil, &result) + return result, resp, err +} + +// TopicSearchOptions options for searching topics +type TopicSearchOptions struct { + ListOptions + Query string `json:"q"` // query string +} + +// TopicSearchResult represents a topic search result +type TopicSearchResult struct { + Topics []*TopicResponse `json:"topics"` +} + +// TopicResponse represents a topic +type TopicResponse struct { + ID int64 `json:"id"` + Name string `json:"topic_name"` + RepoCount int `json:"repo_count"` + Created time.Time `json:"created"` + Updated time.Time `json:"updated"` +} + +// SearchTopics searches for topics +func (c *Client) SearchTopics(opt TopicSearchOptions) (*TopicSearchResult, *Response, error) { + opt.setDefaults() + + link, _ := url.Parse("/topics/search") + query := opt.getURLQuery() + if opt.Query != "" { + query.Add("q", opt.Query) + } + link.RawQuery = query.Encode() + + result := new(TopicSearchResult) + resp, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, &result) + return result, resp, err +} diff --git a/vendor/code.gitea.io/sdk/gitea/repo_refs.go b/vendor/code.gitea.io/sdk/gitea/repo_refs.go index bb41c36a5..0707888a4 100644 --- a/vendor/code.gitea.io/sdk/gitea/repo_refs.go +++ b/vendor/code.gitea.io/sdk/gitea/repo_refs.go @@ -25,26 +25,30 @@ type GitObject struct { URL string `json:"url"` } -// GetRepoRef get one ref's information of one repository +// GetRepoRef gets one exact ref from a repository. +// +// The underlying API returns a filtered list for /git/refs/{ref}, so this +// method resolves the exact ref from that list. It may return HTTP errors from +// the underlying API call, or an error when the server response only contains +// partial matches. func (c *Client) GetRepoRef(user, repo, ref string) (*Reference, *Response, error) { - if err := escapeValidatePathSegments(&user, &repo); err != nil { - return nil, nil, err - } - ref = strings.TrimPrefix(ref, "refs/") - ref = pathEscapeSegments(ref) - r := new(Reference) - resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/git/refs/%s", user, repo, ref), nil, nil, &r) - if _, ok := err.(*json.UnmarshalTypeError); ok { - // Multiple refs - return nil, resp, errors.New("no exact match found for this ref") - } else if err != nil { + refs, resp, err := c.GetRepoRefs(user, repo, ref) + if err != nil { return nil, resp, err } - return r, resp, nil + normalizedRef := "refs/" + strings.TrimPrefix(ref, "refs/") + for _, repoRef := range refs { + if repoRef == nil || repoRef.Ref != normalizedRef { + continue + } + return repoRef, resp, nil + } + + return nil, resp, errors.New("no exact match found for this ref") } -// GetRepoRefs get list of ref's information of one repository +// GetRepoRefs gets the refs from a repository that match a partial or full ref. func (c *Client) GetRepoRefs(user, repo, ref string) ([]*Reference, *Response, error) { if err := escapeValidatePathSegments(&user, &repo); err != nil { return nil, nil, err @@ -77,7 +81,7 @@ func (c *Client) GetRepoRefs(user, repo, ref string) ([]*Reference, *Response, e return nil, resp, fmt.Errorf("unmarshalling failed for both single and multiple refs: %s and %s", refErr, refsErr) } -// ListAllGitRefs gets all refs from a repository without filtering +// ListAllGitRefs gets all refs from a repository without filtering. func (c *Client) ListAllGitRefs(owner, repo string) ([]*Reference, *Response, error) { if err := escapeValidatePathSegments(&owner, &repo); err != nil { return nil, nil, err diff --git a/vendor/code.gitea.io/sdk/gitea/repo_tag_protection.go b/vendor/code.gitea.io/sdk/gitea/repo_tag_protection.go index ec433ae92..430466211 100644 --- a/vendor/code.gitea.io/sdk/gitea/repo_tag_protection.go +++ b/vendor/code.gitea.io/sdk/gitea/repo_tag_protection.go @@ -15,7 +15,7 @@ import ( // TagProtection represents a tag protection for a repository type TagProtection struct { - Id int64 `json:"id"` + ID int64 `json:"id"` NamePattern string `json:"name_pattern"` WhitelistUsernames []string `json:"whitelist_usernames"` WhitelistTeams []string `json:"whitelist_teams"` diff --git a/vendor/code.gitea.io/sdk/gitea/user_action.go b/vendor/code.gitea.io/sdk/gitea/user_action.go new file mode 100644 index 000000000..aea2b5ebe --- /dev/null +++ b/vendor/code.gitea.io/sdk/gitea/user_action.go @@ -0,0 +1,161 @@ +// Copyright 2026 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" +) + +// CreateUserActionSecret creates or updates a user-scope Actions secret. +func (c *Client) CreateUserActionSecret(secretName string, opt CreateOrUpdateSecretOption) (*Response, error) { + if err := escapeValidatePathSegments(&secretName); err != nil { + return nil, err + } + if err := c.checkServerVersionGreaterThanOrEqual(version1_21_0); 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 + } + return c.doRequestWithStatusHandle("PUT", fmt.Sprintf("/user/actions/secrets/%s", secretName), jsonHeader, bytes.NewReader(body)) +} + +// DeleteUserActionSecret deletes a user-scope Actions secret. +func (c *Client) DeleteUserActionSecret(secretName string) (*Response, error) { + if err := escapeValidatePathSegments(&secretName); err != nil { + return nil, err + } + if err := c.checkServerVersionGreaterThanOrEqual(version1_21_0); err != nil { + return nil, err + } + return c.doRequestWithStatusHandle("DELETE", fmt.Sprintf("/user/actions/secrets/%s", secretName), nil, nil) +} + +// ListUserActionVariable lists user-scope Actions variables. +func (c *Client) ListUserActionVariable(opt ListOptions) ([]*ActionVariable, *Response, error) { + if err := c.checkServerVersionGreaterThanOrEqual(version1_22_0); err != nil { + return nil, nil, err + } + opt.setDefaults() + variables := make([]*ActionVariable, 0, opt.PageSize) + resp, err := c.getParsedResponse("GET", fmt.Sprintf("/user/actions/variables?%s", opt.getURLQuery().Encode()), jsonHeader, nil, &variables) + return variables, resp, err +} + +// GetUserActionVariable gets one user-scope Actions variable. +func (c *Client) GetUserActionVariable(variableName string) (*ActionVariable, *Response, error) { + if err := escapeValidatePathSegments(&variableName); err != nil { + return nil, nil, err + } + if err := c.checkServerVersionGreaterThanOrEqual(version1_22_0); err != nil { + return nil, nil, err + } + variable := new(ActionVariable) + resp, err := c.getParsedResponse("GET", fmt.Sprintf("/user/actions/variables/%s", variableName), jsonHeader, nil, variable) + return variable, resp, err +} + +// CreateUserActionVariable creates one user-scope Actions variable. +func (c *Client) CreateUserActionVariable(variableName string, opt CreateActionVariableOption) (*Response, error) { + if err := escapeValidatePathSegments(&variableName); err != nil { + return nil, err + } + if err := c.checkServerVersionGreaterThanOrEqual(version1_22_0); 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 + } + return c.doRequestWithStatusHandle("POST", fmt.Sprintf("/user/actions/variables/%s", variableName), jsonHeader, bytes.NewReader(body)) +} + +// UpdateUserActionVariable updates one user-scope Actions variable. +func (c *Client) UpdateUserActionVariable(variableName string, opt UpdateActionVariableOption) (*Response, error) { + if err := escapeValidatePathSegments(&variableName); err != nil { + return nil, err + } + if err := c.checkServerVersionGreaterThanOrEqual(version1_22_0); 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 + } + return c.doRequestWithStatusHandle("PUT", fmt.Sprintf("/user/actions/variables/%s", variableName), jsonHeader, bytes.NewReader(body)) +} + +// DeleteUserActionVariable deletes one user-scope Actions variable. +func (c *Client) DeleteUserActionVariable(variableName string) (*Response, error) { + if err := escapeValidatePathSegments(&variableName); err != nil { + return nil, err + } + if err := c.checkServerVersionGreaterThanOrEqual(version1_22_0); err != nil { + return nil, err + } + return c.doRequestWithStatusHandle("DELETE", fmt.Sprintf("/user/actions/variables/%s", variableName), nil, nil) +} + +// ListUserActionRuns lists user-scope Actions workflow runs. +func (c *Client) ListUserActionRuns(opt ListRepoActionRunsOptions) (*ActionWorkflowRunsResponse, *Response, error) { + return c.listActionRuns("/user/actions/runs", opt) +} + +// ListUserActionJobs lists user-scope Actions jobs. +func (c *Client) ListUserActionJobs(opt ListRepoActionJobsOptions) (*ActionWorkflowJobsResponse, *Response, error) { + return c.listActionJobs("/user/actions/jobs", opt) +} + +// CreateUserActionRunnerRegistrationToken creates a user-scope runner registration token. +func (c *Client) CreateUserActionRunnerRegistrationToken() (*RegistrationToken, *Response, error) { + if err := c.checkServerVersionGreaterThanOrEqual(version1_22_0); err != nil { + return nil, nil, err + } + return c.createActionRegistrationToken("/user/actions/runners/registration-token") +} + +// ListUserActionRunners lists user-scope Actions runners. +func (c *Client) ListUserActionRunners(opt ListActionRunnersOptions) (*ActionRunnersResponse, *Response, error) { + if err := c.checkServerVersionGreaterThanOrEqual(version1_25_0); err != nil { + return nil, nil, err + } + return c.listActionRunners("/user/actions/runners", opt) +} + +// GetUserActionRunner gets one user-scope Actions runner. +func (c *Client) GetUserActionRunner(runnerID int64) (*ActionRunner, *Response, error) { + if err := c.checkServerVersionGreaterThanOrEqual(version1_25_0); err != nil { + return nil, nil, err + } + return c.getActionRunner(fmt.Sprintf("/user/actions/runners/%d", runnerID)) +} + +// DeleteUserActionRunner deletes one user-scope Actions runner. +func (c *Client) DeleteUserActionRunner(runnerID int64) (*Response, error) { + if err := c.checkServerVersionGreaterThanOrEqual(version1_25_0); err != nil { + return nil, err + } + return c.doRequestWithStatusHandle("DELETE", fmt.Sprintf("/user/actions/runners/%d", runnerID), nil, nil) +} + +// UpdateUserActionRunner updates one user-scope Actions runner. +func (c *Client) UpdateUserActionRunner(runnerID int64, opt EditActionRunnerOption) (*ActionRunner, *Response, error) { + if err := c.checkServerVersionGreaterThanOrEqual(version1_25_0); err != nil { + return nil, nil, err + } + return c.updateActionRunner(fmt.Sprintf("/user/actions/runners/%d", runnerID), opt) +} diff --git a/vendor/code.gitea.io/sdk/gitea/version.go b/vendor/code.gitea.io/sdk/gitea/version.go index 43c67dfca..ffac14384 100644 --- a/vendor/code.gitea.io/sdk/gitea/version.go +++ b/vendor/code.gitea.io/sdk/gitea/version.go @@ -54,7 +54,7 @@ func SetGiteaVersion(v string) ClientOption { c.getVersionOnce.Do(func() { c.serverVersion, err = version.NewVersion(v) }) - return + return err } } @@ -69,9 +69,13 @@ 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_18_0 = version.Must(version.NewVersion("1.18.0")) + version1_21_0 = version.Must(version.NewVersion("1.21.0")) version1_22_0 = version.Must(version.NewVersion("1.22.0")) version1_23_0 = version.Must(version.NewVersion("1.23.0")) + version1_24_0 = version.Must(version.NewVersion("1.24.0")) version1_25_0 = version.Must(version.NewVersion("1.25.0")) + version1_26_0 = version.Must(version.NewVersion("1.26.0")) ) // ErrUnknownVersion is an unknown version from the API @@ -124,5 +128,5 @@ func (c *Client) loadServerVersion() (err error) { return } }) - return + return err } diff --git a/vendor/modules.txt b/vendor/modules.txt index 79b0d0341..d068549f2 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,8 +1,8 @@ # cloud.google.com/go/compute/metadata v0.9.0 ## explicit; go 1.24.0 cloud.google.com/go/compute/metadata -# code.gitea.io/sdk/gitea v0.23.2 -## explicit; go 1.23.0 +# code.gitea.io/sdk/gitea v0.25.1 +## explicit; go 1.26 code.gitea.io/sdk/gitea # cyphar.com/go-pathrs v0.2.5 ## explicit; go 1.18