From ad98ea63ee62c3b9f994bfa6b1ecc8dde617f71f Mon Sep 17 00:00:00 2001 From: FuXiaoHei Date: Wed, 17 Jan 2024 11:21:16 +0800 Subject: [PATCH 1/6] Fix uploaded artifacts should be overwritten (#28726) Fix `Uploaded artifacts should be overwritten` https://github.com/go-gitea/gitea/issues/28549 When upload different content to uploaded artifact, it checks that content size is not match in db record with previous artifact size, then the new artifact is refused. Now if it finds uploading content size is not matching db record when receiving chunks, it updates db records to follow the latest size value. --- routers/api/actions/artifacts.go | 9 +- routers/api/actions/artifacts_chunks.go | 9 +- .../integration/api_actions_artifact_test.go | 89 +++++++++++++++++++ 3 files changed, 104 insertions(+), 3 deletions(-) diff --git a/routers/api/actions/artifacts.go b/routers/api/actions/artifacts.go index 5bfcc9dfcd76..0d2062ad0515 100644 --- a/routers/api/actions/artifacts.go +++ b/routers/api/actions/artifacts.go @@ -257,8 +257,11 @@ func (ar artifactRoutes) uploadArtifact(ctx *ArtifactContext) { return } - // update artifact size if zero - if artifact.FileSize == 0 || artifact.FileCompressedSize == 0 { + // update artifact size if zero or not match, over write artifact size + if artifact.FileSize == 0 || + artifact.FileCompressedSize == 0 || + artifact.FileSize != fileRealTotalSize || + artifact.FileCompressedSize != chunksTotalSize { artifact.FileSize = fileRealTotalSize artifact.FileCompressedSize = chunksTotalSize artifact.ContentEncoding = ctx.Req.Header.Get("Content-Encoding") @@ -267,6 +270,8 @@ func (ar artifactRoutes) uploadArtifact(ctx *ArtifactContext) { ctx.Error(http.StatusInternalServerError, "Error update artifact") return } + log.Debug("[artifact] update artifact size, artifact_id: %d, size: %d, compressed size: %d", + artifact.ID, artifact.FileSize, artifact.FileCompressedSize) } ctx.JSON(http.StatusOK, map[string]string{ diff --git a/routers/api/actions/artifacts_chunks.go b/routers/api/actions/artifacts_chunks.go index 36432a0ca084..0713c8bba8ce 100644 --- a/routers/api/actions/artifacts_chunks.go +++ b/routers/api/actions/artifacts_chunks.go @@ -186,7 +186,14 @@ func mergeChunksForArtifact(ctx *ArtifactContext, chunks []*chunkFileItem, st st }() // save storage path to artifact - log.Debug("[artifact] merge chunks to artifact: %d, %s", artifact.ID, storagePath) + log.Debug("[artifact] merge chunks to artifact: %d, %s, old:%s", artifact.ID, storagePath, artifact.StoragePath) + // if artifact is already uploaded, delete the old file + if artifact.StoragePath != "" { + if err := st.Delete(artifact.StoragePath); err != nil { + log.Warn("Error deleting old artifact: %s, %v", artifact.StoragePath, err) + } + } + artifact.StoragePath = storagePath artifact.Status = int64(actions.ArtifactStatusUploadConfirmed) if err := actions.UpdateArtifactByID(ctx, artifact.ID, artifact); err != nil { diff --git a/tests/integration/api_actions_artifact_test.go b/tests/integration/api_actions_artifact_test.go index 2597d103746e..ce2d14cc0c9c 100644 --- a/tests/integration/api_actions_artifact_test.go +++ b/tests/integration/api_actions_artifact_test.go @@ -287,3 +287,92 @@ func TestActionsArtifactUploadWithRetentionDays(t *testing.T) { AddTokenAuth("8061e833a55f6fc0157c98b883e91fcfeeb1a71a") MakeRequest(t, req, http.StatusOK) } + +func TestActionsArtifactOverwrite(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + { + // download old artifact uploaded by tests above, it should 1024 A + req := NewRequest(t, "GET", "/api/actions_pipeline/_apis/pipelines/workflows/791/artifacts"). + AddTokenAuth("8061e833a55f6fc0157c98b883e91fcfeeb1a71a") + resp := MakeRequest(t, req, http.StatusOK) + var listResp listArtifactsResponse + DecodeJSON(t, resp, &listResp) + + idx := strings.Index(listResp.Value[0].FileContainerResourceURL, "/api/actions_pipeline/_apis/pipelines/") + url := listResp.Value[0].FileContainerResourceURL[idx+1:] + "?itemPath=artifact" + req = NewRequest(t, "GET", url). + AddTokenAuth("8061e833a55f6fc0157c98b883e91fcfeeb1a71a") + resp = MakeRequest(t, req, http.StatusOK) + var downloadResp downloadArtifactResponse + DecodeJSON(t, resp, &downloadResp) + + idx = strings.Index(downloadResp.Value[0].ContentLocation, "/api/actions_pipeline/_apis/pipelines/") + url = downloadResp.Value[0].ContentLocation[idx:] + req = NewRequest(t, "GET", url). + AddTokenAuth("8061e833a55f6fc0157c98b883e91fcfeeb1a71a") + resp = MakeRequest(t, req, http.StatusOK) + body := strings.Repeat("A", 1024) + assert.Equal(t, resp.Body.String(), body) + } + + { + // upload same artifact, it uses 4096 B + req := NewRequestWithJSON(t, "POST", "/api/actions_pipeline/_apis/pipelines/workflows/791/artifacts", getUploadArtifactRequest{ + Type: "actions_storage", + Name: "artifact", + }).AddTokenAuth("8061e833a55f6fc0157c98b883e91fcfeeb1a71a") + resp := MakeRequest(t, req, http.StatusOK) + var uploadResp uploadArtifactResponse + DecodeJSON(t, resp, &uploadResp) + + idx := strings.Index(uploadResp.FileContainerResourceURL, "/api/actions_pipeline/_apis/pipelines/") + url := uploadResp.FileContainerResourceURL[idx:] + "?itemPath=artifact/abc.txt" + body := strings.Repeat("B", 4096) + req = NewRequestWithBody(t, "PUT", url, strings.NewReader(body)). + AddTokenAuth("8061e833a55f6fc0157c98b883e91fcfeeb1a71a"). + SetHeader("Content-Range", "bytes 0-4095/4096"). + SetHeader("x-tfs-filelength", "4096"). + SetHeader("x-actions-results-md5", "wUypcJFeZCK5T6r4lfqzqg==") // base64(md5(body)) + MakeRequest(t, req, http.StatusOK) + + // confirm artifact upload + req = NewRequest(t, "PATCH", "/api/actions_pipeline/_apis/pipelines/workflows/791/artifacts?artifactName=artifact"). + AddTokenAuth("8061e833a55f6fc0157c98b883e91fcfeeb1a71a") + MakeRequest(t, req, http.StatusOK) + } + + { + // download artifact again, it should 4096 B + req := NewRequest(t, "GET", "/api/actions_pipeline/_apis/pipelines/workflows/791/artifacts"). + AddTokenAuth("8061e833a55f6fc0157c98b883e91fcfeeb1a71a") + resp := MakeRequest(t, req, http.StatusOK) + var listResp listArtifactsResponse + DecodeJSON(t, resp, &listResp) + + var uploadedItem listArtifactsResponseItem + for _, item := range listResp.Value { + if item.Name == "artifact" { + uploadedItem = item + break + } + } + assert.Equal(t, uploadedItem.Name, "artifact") + + idx := strings.Index(uploadedItem.FileContainerResourceURL, "/api/actions_pipeline/_apis/pipelines/") + url := uploadedItem.FileContainerResourceURL[idx+1:] + "?itemPath=artifact" + req = NewRequest(t, "GET", url). + AddTokenAuth("8061e833a55f6fc0157c98b883e91fcfeeb1a71a") + resp = MakeRequest(t, req, http.StatusOK) + var downloadResp downloadArtifactResponse + DecodeJSON(t, resp, &downloadResp) + + idx = strings.Index(downloadResp.Value[0].ContentLocation, "/api/actions_pipeline/_apis/pipelines/") + url = downloadResp.Value[0].ContentLocation[idx:] + req = NewRequest(t, "GET", url). + AddTokenAuth("8061e833a55f6fc0157c98b883e91fcfeeb1a71a") + resp = MakeRequest(t, req, http.StatusOK) + body := strings.Repeat("B", 4096) + assert.Equal(t, resp.Body.String(), body) + } +} From 2bdab948cbbd7b348621f853bb8aecd8a74aa3ee Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Wed, 17 Jan 2024 17:26:45 +0800 Subject: [PATCH 2/6] Add missing migration (#28827) Missed from #28498 --- models/migrations/migrations.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index 578cbca035d8..3b4ac24a2c38 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -552,6 +552,8 @@ var migrations = []Migration{ NewMigration("Add Index to pull_auto_merge.doer_id", v1_22.AddIndexToPullAutoMergeDoerID), // v283 -> v284 NewMigration("Add combined Index to issue_user.uid and issue_id", v1_22.AddCombinedIndexToIssueUser), + // v284 -> v285 + NewMigration("Add ignore stale approval column on branch table", v1_22.AddIgnoreStaleApprovalsColumnToProtectedBranchTable), } // GetCurrentDBVersion returns the current db version From c8ba17c73ff455ea381c8ab5a81f77d545a672fd Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Wed, 17 Jan 2024 17:56:00 +0800 Subject: [PATCH 3/6] Remove duplicated checkinit on git module (#28824) `checkInit` has been invoked in `InitSimple`. So it's unnecessary to invoke it twice in `InitFull`. --- modules/git/git.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/modules/git/git.go b/modules/git/git.go index 166655eb738f..24eff05afcd6 100644 --- a/modules/git/git.go +++ b/modules/git/git.go @@ -166,10 +166,6 @@ func InitSimple(ctx context.Context) error { // InitFull initializes git module with version check and change global variables, sync gitconfig. // It should only be called once at the beginning of the program initialization (TestMain/GlobalInitInstalled) as this code makes unsynchronized changes to variables. func InitFull(ctx context.Context) (err error) { - if err = checkInit(); err != nil { - return err - } - if err = InitSimple(ctx); err != nil { return err } From eba9c0ce48c7d43910eb77db74c6648157663ceb Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Wed, 17 Jan 2024 21:27:59 +0800 Subject: [PATCH 4/6] Add testing for CalcCommitStatus (#28823) --- models/git/commit_status_test.go | 115 +++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) diff --git a/models/git/commit_status_test.go b/models/git/commit_status_test.go index f7dd8597ed84..74ba4a10069d 100644 --- a/models/git/commit_status_test.go +++ b/models/git/commit_status_test.go @@ -60,3 +60,118 @@ func TestGetCommitStatuses(t *testing.T) { assert.Equal(t, int(maxResults), 5) assert.Empty(t, statuses) } + +func Test_CalcCommitStatus(t *testing.T) { + kases := []struct { + statuses []*git_model.CommitStatus + expected *git_model.CommitStatus + }{ + { + statuses: []*git_model.CommitStatus{ + { + State: structs.CommitStatusPending, + }, + }, + expected: &git_model.CommitStatus{ + State: structs.CommitStatusPending, + }, + }, + { + statuses: []*git_model.CommitStatus{ + { + State: structs.CommitStatusSuccess, + }, + { + State: structs.CommitStatusPending, + }, + }, + expected: &git_model.CommitStatus{ + State: structs.CommitStatusPending, + }, + }, + { + statuses: []*git_model.CommitStatus{ + { + State: structs.CommitStatusSuccess, + }, + { + State: structs.CommitStatusPending, + }, + { + State: structs.CommitStatusSuccess, + }, + }, + expected: &git_model.CommitStatus{ + State: structs.CommitStatusPending, + }, + }, + { + statuses: []*git_model.CommitStatus{ + { + State: structs.CommitStatusError, + }, + { + State: structs.CommitStatusPending, + }, + { + State: structs.CommitStatusSuccess, + }, + }, + expected: &git_model.CommitStatus{ + State: structs.CommitStatusError, + }, + }, + { + statuses: []*git_model.CommitStatus{ + { + State: structs.CommitStatusWarning, + }, + { + State: structs.CommitStatusPending, + }, + { + State: structs.CommitStatusSuccess, + }, + }, + expected: &git_model.CommitStatus{ + State: structs.CommitStatusWarning, + }, + }, + { + statuses: []*git_model.CommitStatus{ + { + State: structs.CommitStatusSuccess, + }, + { + State: structs.CommitStatusSuccess, + }, + { + State: structs.CommitStatusSuccess, + }, + }, + expected: &git_model.CommitStatus{ + State: structs.CommitStatusSuccess, + }, + }, + { + statuses: []*git_model.CommitStatus{ + { + State: structs.CommitStatusFailure, + }, + { + State: structs.CommitStatusError, + }, + { + State: structs.CommitStatusWarning, + }, + }, + expected: &git_model.CommitStatus{ + State: structs.CommitStatusError, + }, + }, + } + + for _, kase := range kases { + assert.Equal(t, kase.expected, git_model.CalcCommitStatus(kase.statuses)) + } +} From 4674aea25b54baf08594c54f061dee9e44190f02 Mon Sep 17 00:00:00 2001 From: yp05327 <576951401@qq.com> Date: Thu, 18 Jan 2024 19:27:07 +0900 Subject: [PATCH 5/6] Fix display latest sync time for pull mirrors on the repo page (#28841) Follow #28712 1. Missing Locale word `mirror_sync` 2. Maybe forgot checking the conflict from #27760 Before: ![image](https://github.com/go-gitea/gitea/assets/18380374/6100d35b-7fe3-4095-9c24-7875568f7380) After: ![image](https://github.com/go-gitea/gitea/assets/18380374/69647169-b812-45bc-a267-ab28f2df6ef6) --- options/locale/locale_en-US.ini | 1 + templates/repo/header.tmpl | 15 +++++++-------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 90e3ac503a77..6f9ba8c88470 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -987,6 +987,7 @@ mirror_prune = Prune mirror_prune_desc = Remove obsolete remote-tracking references mirror_interval = Mirror Interval (valid time units are 'h', 'm', 's'). 0 to disable periodic sync. (Minimum interval: %s) mirror_interval_invalid = The mirror interval is not valid. +mirror_sync = synced mirror_sync_on_commit = Sync when commits are pushed mirror_address = Clone From URL mirror_address_desc = Put any required credentials in the Authorization section. diff --git a/templates/repo/header.tmpl b/templates/repo/header.tmpl index c362059ef3be..a5ef8daa9a1e 100644 --- a/templates/repo/header.tmpl +++ b/templates/repo/header.tmpl @@ -28,13 +28,6 @@
{{svg "octicon-repo-template" 18}}
{{end}} - {{if $.PullMirror}} -
- {{ctx.Locale.Tr "repo.mirror_from"}} - {{$.PullMirror.RemoteAddress}} - {{if $.PullMirror.UpdatedUnix}}{{ctx.Locale.Tr "repo.mirror_sync"}} {{TimeSinceUnix $.PullMirror.UpdatedUnix ctx.Locale}}{{end}} -
- {{end}} {{if not (or .IsBeingCreated .IsBroken)}}
@@ -147,7 +140,13 @@
{{end}} - {{if $.PullMirror}}
{{ctx.Locale.Tr "repo.mirror_from"}} {{$.PullMirror.RemoteAddress}}
{{end}} + {{if $.PullMirror}} +
+ {{ctx.Locale.Tr "repo.mirror_from"}} + {{$.PullMirror.RemoteAddress}} + {{if $.PullMirror.UpdatedUnix}}{{ctx.Locale.Tr "repo.mirror_sync"}} {{TimeSinceUnix $.PullMirror.UpdatedUnix ctx.Locale}}{{end}} +
+ {{end}} {{if .IsFork}}
{{ctx.Locale.Tr "repo.forked_from"}} {{.BaseRepo.FullName}}
{{end}} {{if .IsGenerated}}
{{ctx.Locale.Tr "repo.generated_from"}} {{(.TemplateRepo ctx).FullName}}
{{end}} From b60a7c3358cdeec3e0a731b68be33b6ba63a6563 Mon Sep 17 00:00:00 2001 From: yp05327 <576951401@qq.com> Date: Fri, 19 Jan 2024 11:45:23 +0900 Subject: [PATCH 6/6] Return `responseText` instead of string in some functions (#28836) Follow https://github.com/go-gitea/gitea/pull/28796#issuecomment-1891727591 --- cmd/actions.go | 2 +- cmd/keys.go | 2 +- cmd/mailer.go | 2 +- modules/private/actions.go | 8 ++------ modules/private/hook.go | 6 +++--- modules/private/key.go | 10 +++------- modules/private/mail.go | 8 ++------ modules/private/request.go | 10 +++++----- 8 files changed, 18 insertions(+), 30 deletions(-) diff --git a/cmd/actions.go b/cmd/actions.go index 275fd7904eae..f582c16c81c4 100644 --- a/cmd/actions.go +++ b/cmd/actions.go @@ -50,6 +50,6 @@ func runGenerateActionsRunnerToken(c *cli.Context) error { if extra.HasError() { return handleCliResponseExtra(extra) } - _, _ = fmt.Printf("%s\n", respText) + _, _ = fmt.Printf("%s\n", respText.Text) return nil } diff --git a/cmd/keys.go b/cmd/keys.go index 9d5278f1099e..ceeec4848615 100644 --- a/cmd/keys.go +++ b/cmd/keys.go @@ -78,6 +78,6 @@ func runKeys(c *cli.Context) error { if extra.Error != nil { return extra.Error } - _, _ = fmt.Fprintln(c.App.Writer, strings.TrimSpace(authorizedString)) + _, _ = fmt.Fprintln(c.App.Writer, strings.TrimSpace(authorizedString.Text)) return nil } diff --git a/cmd/mailer.go b/cmd/mailer.go index 646330e85aae..0c5f2c8c8d47 100644 --- a/cmd/mailer.go +++ b/cmd/mailer.go @@ -45,6 +45,6 @@ func runSendMail(c *cli.Context) error { if extra.HasError() { return handleCliResponseExtra(extra) } - _, _ = fmt.Printf("Sent %s email(s) to all users\n", respText) + _, _ = fmt.Printf("Sent %s email(s) to all users\n", respText.Text) return nil } diff --git a/modules/private/actions.go b/modules/private/actions.go index a22833632e0c..311a28365004 100644 --- a/modules/private/actions.go +++ b/modules/private/actions.go @@ -14,16 +14,12 @@ type GenerateTokenRequest struct { } // GenerateActionsRunnerToken calls the internal GenerateActionsRunnerToken function -func GenerateActionsRunnerToken(ctx context.Context, scope string) (string, ResponseExtra) { +func GenerateActionsRunnerToken(ctx context.Context, scope string) (*ResponseText, ResponseExtra) { reqURL := setting.LocalURL + "api/internal/actions/generate_actions_runner_token" req := newInternalRequest(ctx, reqURL, "POST", GenerateTokenRequest{ Scope: scope, }) - resp, extra := requestJSONResp(req, &responseText{}) - if extra.HasError() { - return "", extra - } - return resp.Text, extra + return requestJSONResp(req, &ResponseText{}) } diff --git a/modules/private/hook.go b/modules/private/hook.go index 23e03896e4d8..cab8c812248f 100644 --- a/modules/private/hook.go +++ b/modules/private/hook.go @@ -101,7 +101,7 @@ func HookPreReceive(ctx context.Context, ownerName, repoName string, opts HookOp reqURL := setting.LocalURL + fmt.Sprintf("api/internal/hook/pre-receive/%s/%s", url.PathEscape(ownerName), url.PathEscape(repoName)) req := newInternalRequest(ctx, reqURL, "POST", opts) req.SetReadWriteTimeout(time.Duration(60+len(opts.OldCommitIDs)) * time.Second) - _, extra := requestJSONResp(req, &responseText{}) + _, extra := requestJSONResp(req, &ResponseText{}) return extra } @@ -130,7 +130,7 @@ func SetDefaultBranch(ctx context.Context, ownerName, repoName, branch string) R url.PathEscape(branch), ) req := newInternalRequest(ctx, reqURL, "POST") - _, extra := requestJSONResp(req, &responseText{}) + _, extra := requestJSONResp(req, &ResponseText{}) return extra } @@ -138,6 +138,6 @@ func SetDefaultBranch(ctx context.Context, ownerName, repoName, branch string) R func SSHLog(ctx context.Context, isErr bool, msg string) error { reqURL := setting.LocalURL + "api/internal/ssh/log" req := newInternalRequest(ctx, reqURL, "POST", &SSHLogOption{IsError: isErr, Message: msg}) - _, extra := requestJSONResp(req, &responseText{}) + _, extra := requestJSONResp(req, &ResponseText{}) return extra.Error } diff --git a/modules/private/key.go b/modules/private/key.go index 08762bd4013d..dcd17148564c 100644 --- a/modules/private/key.go +++ b/modules/private/key.go @@ -15,20 +15,16 @@ func UpdatePublicKeyInRepo(ctx context.Context, keyID, repoID int64) error { // Ask for running deliver hook and test pull request tasks. reqURL := setting.LocalURL + fmt.Sprintf("api/internal/ssh/%d/update/%d", keyID, repoID) req := newInternalRequest(ctx, reqURL, "POST") - _, extra := requestJSONResp(req, &responseText{}) + _, extra := requestJSONResp(req, &ResponseText{}) return extra.Error } // AuthorizedPublicKeyByContent searches content as prefix (leak e-mail part) // and returns public key found. -func AuthorizedPublicKeyByContent(ctx context.Context, content string) (string, ResponseExtra) { +func AuthorizedPublicKeyByContent(ctx context.Context, content string) (*ResponseText, ResponseExtra) { // Ask for running deliver hook and test pull request tasks. reqURL := setting.LocalURL + "api/internal/ssh/authorized_keys" req := newInternalRequest(ctx, reqURL, "POST") req.Param("content", content) - resp, extra := requestJSONResp(req, &responseText{}) - if extra.HasError() { - return "", extra - } - return resp.Text, extra + return requestJSONResp(req, &ResponseText{}) } diff --git a/modules/private/mail.go b/modules/private/mail.go index ac55d6fe4d73..08de5b7e2872 100644 --- a/modules/private/mail.go +++ b/modules/private/mail.go @@ -20,7 +20,7 @@ type Email struct { // It accepts a list of usernames. // If DB contains these users it will send the email to them. // If to list == nil, it's supposed to send emails to every user present in DB -func SendEmail(ctx context.Context, subject, message string, to []string) (string, ResponseExtra) { +func SendEmail(ctx context.Context, subject, message string, to []string) (*ResponseText, ResponseExtra) { reqURL := setting.LocalURL + "api/internal/mail/send" req := newInternalRequest(ctx, reqURL, "POST", Email{ @@ -29,9 +29,5 @@ func SendEmail(ctx context.Context, subject, message string, to []string) (strin To: to, }) - resp, extra := requestJSONResp(req, &responseText{}) - if extra.HasError() { - return "", extra - } - return resp.Text, extra + return requestJSONResp(req, &ResponseText{}) } diff --git a/modules/private/request.go b/modules/private/request.go index 2bc43b972d4f..58cd2612393f 100644 --- a/modules/private/request.go +++ b/modules/private/request.go @@ -12,8 +12,8 @@ import ( "code.gitea.io/gitea/modules/json" ) -// responseText is used to get the response as text, instead of parsing it as JSON. -type responseText struct { +// ResponseText is used to get the response as text, instead of parsing it as JSON. +type ResponseText struct { Text string } @@ -50,7 +50,7 @@ func (re responseError) Error() string { // Caller should check the ResponseExtra.HasError() first to see whether the request fails. // // * If the "res" is a struct pointer, the response will be parsed as JSON -// * If the "res" is responseText pointer, the response will be stored as text in it +// * If the "res" is ResponseText pointer, the response will be stored as text in it // * If the "res" is responseCallback pointer, the callback function should set the ResponseExtra fields accordingly func requestJSONResp[T any](req *httplib.Request, res *T) (ret *T, extra ResponseExtra) { resp, err := req.Response() @@ -81,7 +81,7 @@ func requestJSONResp[T any](req *httplib.Request, res *T) (ret *T, extra Respons // now, the StatusCode must be 2xx var v any = res - if respText, ok := v.(*responseText); ok { + if respText, ok := v.(*ResponseText); ok { // get the whole response as a text string bs, err := io.ReadAll(resp.Body) if err != nil { @@ -119,7 +119,7 @@ func requestJSONResp[T any](req *httplib.Request, res *T) (ret *T, extra Respons // requestJSONClientMsg sends a request to the gitea server, server only responds text message status=200 with "success" body // If the request succeeds (200), the argument clientSuccessMsg will be used as ResponseExtra.UserMsg. func requestJSONClientMsg(req *httplib.Request, clientSuccessMsg string) ResponseExtra { - _, extra := requestJSONResp(req, &responseText{}) + _, extra := requestJSONResp(req, &ResponseText{}) if extra.HasError() { return extra }