with class="link-action" and a data-url), will cause
-// the browser to redirect to the target page.
-type redirectObject struct {
- Redirect string `json:"redirect"`
+ ctx.JSON(http.StatusOK, resp)
}
// Rerun will rerun jobs in the given run
@@ -493,7 +383,7 @@ func Rerun(ctx *context_module.Context) {
run.PreviousDuration = run.Duration()
run.Started = 0
run.Stopped = 0
- if err := actions_service.UpdateRun(ctx, run, "started", "stopped", "previous_duration"); err != nil {
+ if err := actions_model.UpdateRun(ctx, run, "started", "stopped", "previous_duration"); err != nil {
ctx.Error(http.StatusInternalServerError, err.Error())
return
}
@@ -505,7 +395,6 @@ func Rerun(ctx *context_module.Context) {
}
if jobIndexStr == "" { // rerun all jobs
- var redirectURL string
for _, j := range jobs {
// if the job has needs, it should be set to "blocked" status to wait for other jobs
shouldBlock := len(j.Needs) > 0
@@ -513,31 +402,13 @@ func Rerun(ctx *context_module.Context) {
ctx.Error(http.StatusInternalServerError, err.Error())
return
}
- if redirectURL == "" {
- // ActionRunJob's `Attempt` field won't be updated to reflect the rerun until the job is picked by a
- // runner. But we need to redirect the user somewhere; if they stay on the current attempt then the
- // rerun's logs won't appear. So, we redirect to the upcoming new attempt and then we'll handle the
- // weirdness in the UI if the attempt doesn't exist yet.
- j.Attempt++ // note: this is intentionally not persisted
- redirectURL, err = j.HTMLURL(ctx)
- if err != nil {
- ctx.Error(http.StatusInternalServerError, err.Error())
- return
- }
- }
- }
-
- if redirectURL != "" {
- ctx.JSON(http.StatusOK, &redirectObject{Redirect: redirectURL})
- } else {
- ctx.Error(http.StatusInternalServerError, "unable to determine redirectURL for job rerun")
}
+ ctx.JSON(http.StatusOK, struct{}{})
return
}
rerunJobs := actions_service.GetAllRerunJobs(job, jobs)
- var redirectURL string
for _, j := range rerunJobs {
// jobs other than the specified one should be set to "blocked" status
shouldBlock := j.JobID != job.JobID
@@ -545,22 +416,9 @@ func Rerun(ctx *context_module.Context) {
ctx.Error(http.StatusInternalServerError, err.Error())
return
}
- if j.JobID == job.JobID {
- // see earlier comment about redirectURL, applicable here as well
- j.Attempt++ // note: this is intentionally not persisted
- redirectURL, err = j.HTMLURL(ctx)
- if err != nil {
- ctx.Error(http.StatusInternalServerError, err.Error())
- return
- }
- }
}
- if redirectURL != "" {
- ctx.JSON(http.StatusOK, &redirectObject{Redirect: redirectURL})
- } else {
- ctx.Error(http.StatusInternalServerError, "unable to determine redirectURL for job rerun")
- }
+ ctx.JSON(http.StatusOK, struct{}{})
}
func rerunJob(ctx *context_module.Context, job *actions_model.ActionRunJob, shouldBlock bool) error {
@@ -578,7 +436,7 @@ func rerunJob(ctx *context_module.Context, job *actions_model.ActionRunJob, shou
job.Stopped = 0
if err := db.WithTx(ctx, func(ctx context.Context) error {
- _, err := actions_service.UpdateRunJob(ctx, job, builder.Eq{"status": status}, "task_id", "status", "started", "stopped")
+ _, err := actions_model.UpdateRunJob(ctx, job, builder.Eq{"status": status}, "task_id", "status", "started", "stopped")
return err
}); err != nil {
return err
@@ -654,16 +512,16 @@ func Cancel(ctx *context_module.Context) {
if job.TaskID == 0 {
job.Status = actions_model.StatusCancelled
job.Stopped = timeutil.TimeStampNow()
- n, err := actions_service.UpdateRunJob(ctx, job, builder.Eq{"task_id": 0}, "status", "stopped")
+ n, err := actions_model.UpdateRunJob(ctx, job, builder.Eq{"task_id": 0}, "status", "stopped")
if err != nil {
return err
}
if n == 0 {
- return errors.New("job has changed, try again")
+ return fmt.Errorf("job has changed, try again")
}
continue
}
- if err := actions_service.StopTask(ctx, job.TaskID, actions_model.StatusCancelled); err != nil {
+ if err := actions_model.StopTask(ctx, job.TaskID, actions_model.StatusCancelled); err != nil {
return err
}
}
@@ -691,13 +549,13 @@ func Approve(ctx *context_module.Context) {
if err := db.WithTx(ctx, func(ctx context.Context) error {
run.NeedApproval = false
run.ApprovedBy = doer.ID
- if err := actions_service.UpdateRun(ctx, run, "need_approval", "approved_by"); err != nil {
+ if err := actions_model.UpdateRun(ctx, run, "need_approval", "approved_by"); err != nil {
return err
}
for _, job := range jobs {
if len(job.Needs) == 0 && job.Status.IsBlocked() {
job.Status = actions_model.StatusWaiting
- _, err := actions_service.UpdateRunJob(ctx, job, nil, "status")
+ _, err := actions_model.UpdateRunJob(ctx, job, nil, "status")
if err != nil {
return err
}
@@ -761,27 +619,19 @@ type ArtifactsViewItem struct {
func ArtifactsView(ctx *context_module.Context) {
runIndex := ctx.ParamsInt64("run")
- artifactsResponse := getArtifactsViewResponse(ctx, runIndex)
- if ctx.Written() {
- return
- }
- ctx.JSON(http.StatusOK, artifactsResponse)
-}
-
-func getArtifactsViewResponse(ctx *context_module.Context, runIndex int64) *ArtifactsViewResponse {
run, err := actions_model.GetRunByIndex(ctx, ctx.Repo.Repository.ID, runIndex)
if err != nil {
if errors.Is(err, util.ErrNotExist) {
ctx.Error(http.StatusNotFound, err.Error())
- return nil
+ return
}
ctx.Error(http.StatusInternalServerError, err.Error())
- return nil
+ return
}
artifacts, err := actions_model.ListUploadedArtifactsMeta(ctx, run.ID)
if err != nil {
ctx.Error(http.StatusInternalServerError, err.Error())
- return nil
+ return
}
artifactsResponse := ArtifactsViewResponse{
Artifacts: make([]*ArtifactsViewItem, 0, len(artifacts)),
@@ -797,7 +647,7 @@ func getArtifactsViewResponse(ctx *context_module.Context, runIndex int64) *Arti
Status: status,
})
}
- return &artifactsResponse
+ ctx.JSON(http.StatusOK, artifactsResponse)
}
func ArtifactsDeleteView(ctx *context_module.Context) {
@@ -818,82 +668,30 @@ func ArtifactsDeleteView(ctx *context_module.Context) {
ctx.JSON(http.StatusOK, struct{}{})
}
-func getRunByID(ctx *context_module.Context, runID int64) *actions_model.ActionRun {
- if runID == 0 {
- log.Debug("Requested runID is zero.")
- ctx.Error(http.StatusNotFound, "zero is not a valid run ID")
- return nil
- }
-
- run, has, err := actions_model.GetRunByIDWithHas(ctx, runID)
- if err != nil {
- ctx.Error(http.StatusInternalServerError, err.Error())
- return nil
- }
- if !has {
- log.Debug("Requested runID[%d] not found.", runID)
- ctx.Error(http.StatusNotFound, fmt.Sprintf("no such run %d", runID))
- return nil
- }
- if run.RepoID != ctx.Repo.Repository.ID {
- log.Debug("Requested runID[%d] does not belong to repo[%-v].", runID, ctx.Repo.Repository)
- ctx.Error(http.StatusNotFound, "no such run")
- return nil
- }
- return run
-}
-
-func artifactsFind(ctx *context_module.Context, opts actions_model.FindArtifactsOptions) []*actions_model.ActionArtifact {
- artifacts, err := db.Find[actions_model.ActionArtifact](ctx, opts)
- if err != nil {
- ctx.Error(http.StatusInternalServerError, err.Error())
- return nil
- }
- if len(artifacts) == 0 {
- return nil
- }
- return artifacts
-}
-
-func artifactsFindByNameOrID(ctx *context_module.Context, runID int64, nameOrID string) []*actions_model.ActionArtifact {
- artifacts := artifactsFind(ctx, actions_model.FindArtifactsOptions{
- RunID: runID,
- ArtifactName: nameOrID,
- })
- if ctx.Written() {
- return nil
- }
- // if lookup by name found nothing, maybe it is an ID
- if len(artifacts) == 0 {
- id, err := strconv.ParseInt(nameOrID, 10, 64)
- if err != nil || id == 0 {
- ctx.Error(http.StatusNotFound, fmt.Sprintf("runID %d: artifact name not found: %v", runID, nameOrID))
- return nil
- }
- artifacts = artifactsFind(ctx, actions_model.FindArtifactsOptions{
- RunID: runID,
- ID: id,
- })
- if ctx.Written() {
- return nil
- }
- if len(artifacts) == 0 {
- ctx.Error(http.StatusNotFound, fmt.Sprintf("runID %d: artifact ID not found: %v", runID, nameOrID))
- return nil
- }
- }
- return artifacts
-}
-
func ArtifactsDownloadView(ctx *context_module.Context) {
- run := getRunByID(ctx, ctx.ParamsInt64("run"))
- if ctx.Written() {
+ runIndex := ctx.ParamsInt64("run")
+ artifactName := ctx.Params("artifact_name")
+
+ run, err := actions_model.GetRunByIndex(ctx, ctx.Repo.Repository.ID, runIndex)
+ if err != nil {
+ if errors.Is(err, util.ErrNotExist) {
+ ctx.Error(http.StatusNotFound, err.Error())
+ return
+ }
+ ctx.Error(http.StatusInternalServerError, err.Error())
return
}
- artifactNameOrID := ctx.Params("artifact_name_or_id")
- artifacts := artifactsFindByNameOrID(ctx, run.ID, artifactNameOrID)
- if ctx.Written() {
+ artifacts, err := db.Find[actions_model.ActionArtifact](ctx, actions_model.FindArtifactsOptions{
+ RunID: run.ID,
+ ArtifactName: artifactName,
+ })
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, err.Error())
+ return
+ }
+ if len(artifacts) == 0 {
+ ctx.Error(http.StatusNotFound, "artifact not found")
return
}
@@ -922,14 +720,12 @@ func ArtifactsDownloadView(ctx *context_module.Context) {
ctx.Error(http.StatusInternalServerError, err.Error())
return
}
- common.ServeContentByReadSeeker(ctx.Base, artifacts[0].ArtifactName+".zip", util.ToPointer(art.UpdatedUnix.AsTime()), f)
+ common.ServeContentByReadSeeker(ctx.Base, artifactName, util.ToPointer(art.UpdatedUnix.AsTime()), f)
return
}
// Artifacts using the v1-v3 backend are stored as multiple individual files per artifact on the backend
// Those need to be zipped for download
- artifactName := artifacts[0].ArtifactName
-
ctx.Resp.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%s.zip; filename*=UTF-8''%s.zip", url.PathEscape(artifactName), artifactName))
writer := zip.NewWriter(ctx.Resp)
defer writer.Close()
diff --git a/routers/web/repo/actions/view_test.go b/routers/web/repo/actions/view_test.go
deleted file mode 100644
index e3f72e9e37..0000000000
--- a/routers/web/repo/actions/view_test.go
+++ /dev/null
@@ -1,512 +0,0 @@
-// Copyright 2025 The Forgejo Authors. All rights reserved.
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-package actions
-
-import (
- "fmt"
- "html/template"
- "net/http"
- "testing"
-
- actions_model "forgejo.org/models/actions"
- repo_model "forgejo.org/models/repo"
- unittest "forgejo.org/models/unittest"
- "forgejo.org/modules/json"
- "forgejo.org/modules/web"
- "forgejo.org/services/contexttest"
-
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
-)
-
-func Test_getRunByID(t *testing.T) {
- unittest.PrepareTestEnv(t)
-
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: 5, ID: 4})
-
- for _, testCase := range []struct {
- name string
- runID int64
- err string
- }{
- {
- name: "Found",
- runID: 792,
- },
- {
- name: "NotFound",
- runID: 24344,
- err: "no such run",
- },
- {
- name: "ZeroNotFound",
- runID: 0,
- err: "zero is not a valid run ID",
- },
- } {
- t.Run(testCase.name, func(t *testing.T) {
- ctx, resp := contexttest.MockContext(t, fmt.Sprintf("user5/repo4/actions/runs/%v/artifacts/some-name", testCase.runID))
- ctx.Repo.Repository = repo
- run := getRunByID(ctx, testCase.runID)
- if testCase.err == "" {
- assert.NotNil(t, run)
- assert.False(t, ctx.Written(), resp.Body.String())
- } else {
- assert.Nil(t, run)
- assert.True(t, ctx.Written())
- assert.Contains(t, resp.Body.String(), testCase.err)
- }
- })
- }
-}
-
-func Test_artifactsFind(t *testing.T) {
- unittest.PrepareTestEnv(t)
-
- for _, testCase := range []struct {
- name string
- artifactName string
- count int
- }{
- {
- name: "Found",
- artifactName: "artifact-v4-download",
- count: 1,
- },
- {
- name: "NotFound",
- artifactName: "notexist",
- count: 0,
- },
- } {
- t.Run(testCase.name, func(t *testing.T) {
- runID := int64(792)
- ctx, _ := contexttest.MockContext(t, fmt.Sprintf("user5/repo4/actions/runs/%v/artifacts/%v", runID, testCase.artifactName))
- artifacts := artifactsFind(ctx, actions_model.FindArtifactsOptions{
- RunID: runID,
- ArtifactName: testCase.artifactName,
- })
- assert.False(t, ctx.Written())
- assert.Len(t, artifacts, testCase.count)
- })
- }
-}
-
-func Test_artifactsFindByNameOrID(t *testing.T) {
- unittest.PrepareTestEnv(t)
-
- for _, testCase := range []struct {
- name string
- nameOrID string
- err string
- }{
- {
- name: "NameFound",
- nameOrID: "artifact-v4-download",
- },
- {
- name: "NameNotFound",
- nameOrID: "notexist",
- err: "artifact name not found",
- },
- {
- name: "IDFound",
- nameOrID: "22",
- },
- {
- name: "IDNotFound",
- nameOrID: "666",
- err: "artifact ID not found",
- },
- {
- name: "IDZeroNotFound",
- nameOrID: "0",
- err: "artifact name not found",
- },
- } {
- t.Run(testCase.name, func(t *testing.T) {
- runID := int64(792)
- ctx, resp := contexttest.MockContext(t, fmt.Sprintf("user5/repo4/actions/runs/%v/artifacts/%v", runID, testCase.nameOrID))
- artifacts := artifactsFindByNameOrID(ctx, runID, testCase.nameOrID)
- if testCase.err == "" {
- assert.NotEmpty(t, artifacts)
- assert.False(t, ctx.Written(), resp.Body.String())
- } else {
- assert.Empty(t, artifacts)
- assert.True(t, ctx.Written())
- assert.Contains(t, resp.Body.String(), testCase.err)
- }
- })
- }
-}
-
-func baseExpectedViewResponse() *ViewResponse {
- return &ViewResponse{
- State: ViewState{
- Run: ViewRunInfo{
- Link: "/user5/repo4/actions/runs/187",
- Title: "update actions",
- TitleHTML: template.HTML("update actions"),
- Status: "success",
- CanCancel: false,
- CanApprove: false,
- CanRerun: false,
- CanDeleteArtifact: false,
- Done: true,
- Jobs: []*ViewJob{
- {
- ID: 192,
- Name: "job_2",
- Status: "success",
- CanRerun: false,
- Duration: "1m38s",
- },
- },
- Commit: ViewCommit{
- LocaleCommit: "actions.runs.commit",
- LocalePushedBy: "actions.runs.pushed_by",
- LocaleWorkflow: "actions.runs.workflow",
- ShortSha: "c2d72f5484",
- Link: "/user5/repo4/commit/c2d72f548424103f01ee1dc02889c1e2bff816b0",
- Pusher: ViewUser{
- DisplayName: "user1",
- Link: "/user1",
- },
- Branch: ViewBranch{
- Name: "master",
- Link: "/user5/repo4/src/branch/master",
- IsDeleted: false,
- },
- },
- },
- CurrentJob: ViewCurrentJob{
- Title: "job_2",
- Detail: "actions.status.success",
- Steps: []*ViewJobStep{
- {
- Summary: "Set up job",
- Status: "running",
- },
- {
- Summary: "Complete job",
- Status: "waiting",
- },
- },
- AllAttempts: []*TaskAttempt{
- {
- Number: 3,
- Started: template.HTML("2023-05-09 12:48:48 +00:00 "),
- Status: "running",
- },
- {
- Number: 2,
- Started: template.HTML("2023-05-09 12:48:48 +00:00 "),
- Status: "success",
- },
- {
- Number: 1,
- Started: template.HTML("2023-05-09 12:48:48 +00:00 "),
- Status: "success",
- },
- },
- },
- },
- Logs: ViewLogs{
- StepsLog: []*ViewStepLog{},
- },
- }
-}
-
-func TestActionsViewViewPost(t *testing.T) {
- unittest.PrepareTestEnv(t)
-
- tests := []struct {
- name string
- runIndex int64
- jobIndex int64
- attemptNumber int64
- expected *ViewResponse
- expectedTweaks func(*ViewResponse)
- }{
- {
- name: "base case",
- runIndex: 187,
- jobIndex: 0,
- attemptNumber: 1,
- expected: baseExpectedViewResponse(),
- expectedTweaks: func(resp *ViewResponse) {
- resp.State.CurrentJob.Steps[0].Status = "success"
- resp.State.CurrentJob.Steps[1].Status = "success"
- },
- },
- {
- name: "run with waiting jobs",
- runIndex: 189,
- jobIndex: 0,
- attemptNumber: 1,
- expected: baseExpectedViewResponse(),
- expectedTweaks: func(resp *ViewResponse) {
- // Variations from runIndex 187 -> runIndex 189 that are not the subject of this test...
- resp.State.Run.Link = "/user5/repo4/actions/runs/189"
- resp.State.Run.Title = "job output"
- resp.State.Run.TitleHTML = "job output"
- resp.State.Run.Jobs = []*ViewJob{
- {
- ID: 194,
- Name: "job1 (1)",
- Status: "success",
- },
- {
- ID: 195,
- Name: "job1 (2)",
- Status: "success",
- },
- {
- ID: 196,
- Name: "job2",
- Status: "waiting",
- },
- }
- resp.State.CurrentJob.Title = "job1 (1)"
- resp.State.CurrentJob.Steps = []*ViewJobStep{
- {
- Summary: "Set up job",
- Status: "success",
- },
- {
- Summary: "Complete job",
- Status: "success",
- },
- }
- resp.State.CurrentJob.AllAttempts = []*TaskAttempt{
- {
- Number: 1,
- Started: template.HTML("2023-05-09 12:48:48 +00:00 "),
- Status: "success",
- },
- }
-
- // Under test in this case: verify that Done is set to false; in the fixture data, job.ID=195 is status
- // Success, but job.ID=196 is status Waiting, and so we expect to signal Done=false to indicate to the
- // UI to continue refreshing the page.
- resp.State.Run.Done = false
- },
- },
- {
- name: "attempt 3",
- runIndex: 187,
- jobIndex: 0,
- attemptNumber: 3,
- expected: baseExpectedViewResponse(),
- expectedTweaks: func(resp *ViewResponse) {
- resp.State.CurrentJob.Steps[0].Status = "running"
- resp.State.CurrentJob.Steps[1].Status = "waiting"
- },
- },
- {
- // This ActionRunJob has TaskID: null, which allows us to access out-of-range attempts without errors and
- // with just some stub data for the UI to start waiting around on.
- name: "attempt out-of-bounds on non-picked task",
- runIndex: 190,
- jobIndex: 0,
- attemptNumber: 100,
- expected: baseExpectedViewResponse(),
- expectedTweaks: func(resp *ViewResponse) {
- // Variations from runIndex 187 -> runIndex 190 that are not the subject of this test...
- resp.State.Run.Link = "/user5/repo4/actions/runs/190"
- resp.State.Run.Title = "job output"
- resp.State.Run.TitleHTML = "job output"
- resp.State.Run.Done = false
- resp.State.Run.Jobs = []*ViewJob{
- {
- ID: 396,
- Name: "job_2",
- Status: "waiting",
- },
- }
- resp.State.Run.Commit.Branch = ViewBranch{
- Name: "test",
- Link: "/user5/repo4/src/branch/test",
- IsDeleted: true,
- }
-
- // Expected blank data in the response because this job isn't picked by a runner yet. Keep details here
- // in-sync with the RepoActionView 'view non-picked action run job' test.
- resp.State.CurrentJob.Detail = "actions.status.waiting"
- resp.State.CurrentJob.Steps = []*ViewJobStep{}
- resp.State.CurrentJob.AllAttempts = nil
- },
- },
- }
-
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- ctx, resp := contexttest.MockContext(t, "user2/repo1/actions/runs/0")
- contexttest.LoadUser(t, ctx, 2)
- contexttest.LoadRepo(t, ctx, 4)
- ctx.SetParams(":run", fmt.Sprintf("%d", tt.runIndex))
- ctx.SetParams(":job", fmt.Sprintf("%d", tt.jobIndex))
- ctx.SetParams(":attempt", fmt.Sprintf("%d", tt.attemptNumber))
- web.SetForm(ctx, &ViewRequest{})
-
- ViewPost(ctx)
- require.Equal(t, http.StatusOK, resp.Result().StatusCode, "failure in ViewPost(): %q", resp.Body.String())
-
- var actual ViewResponse
- err := json.Unmarshal(resp.Body.Bytes(), &actual)
- require.NoError(t, err)
-
- // `Duration` field is dynamic based upon current time, so eliminate it from comparison -- but check that it
- // has the right format at least.
- zeroDurations := func(vr *ViewResponse) {
- for _, job := range vr.State.Run.Jobs {
- assert.Regexp(t, `^(\d+[hms]){1,3}$`, job.Duration)
- job.Duration = ""
- }
- for _, step := range vr.State.CurrentJob.Steps {
- step.Duration = ""
- }
- }
- zeroDurations(&actual)
- zeroDurations(tt.expected)
- tt.expectedTweaks(tt.expected)
-
- assert.Equal(t, *tt.expected, actual)
- })
- }
-}
-
-func TestActionsViewRedirectToLatestAttempt(t *testing.T) {
- unittest.PrepareTestEnv(t)
-
- tests := []struct {
- name string
- runIndex int64
- jobIndex int64
- expectedCode int
- expectedURL string
- userID int64
- repoID int64
- }{
- {
- name: "no job index",
- runIndex: 187,
- jobIndex: -1,
- expectedURL: "https://try.gitea.io/user2/repo1/actions/runs/187/jobs/0/attempt/1",
- },
- {
- name: "job w/ 1 attempt",
- runIndex: 187,
- jobIndex: 0,
- expectedURL: "https://try.gitea.io/user2/repo1/actions/runs/187/jobs/0/attempt/1",
- },
- {
- name: "job w/ multiple attempts",
- runIndex: 187,
- jobIndex: 2,
- expectedURL: "https://try.gitea.io/user2/repo1/actions/runs/187/jobs/2/attempt/2",
- },
- {
- name: "run out-of-range",
- runIndex: 5000,
- jobIndex: -1,
- expectedCode: http.StatusNotFound,
- },
- // Odd behavior with an out-of-bound jobIndex -- defaults to the first job. This is existing behavior
- // documented in the getRunJobs internal helper which... seems not perfect for the redirect... but it's high
- // risk to change and it's an OK user outcome to be redirected to something valid in the requested run.
- {
- name: "job out-of-range",
- runIndex: 187,
- jobIndex: 500,
- expectedURL: "https://try.gitea.io/user2/repo1/actions/runs/187/jobs/0/attempt/1",
- },
- // This ActionRunJob has Attempt: 0 and TaskID: null, which indicates its first run is pending pickup by a
- // runner. Should redirect to the attempt/1 since that's what it will be when it is running.
- {
- name: "redirect to non-picked task",
- userID: 2,
- repoID: 4,
- runIndex: 190,
- jobIndex: 0,
- expectedURL: "https://try.gitea.io/user5/repo4/actions/runs/190/jobs/0/attempt/1",
- },
- }
-
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- ctx, resp := contexttest.MockContext(t, "user2/repo1/actions/runs/0")
- if tt.userID == 0 {
- contexttest.LoadUser(t, ctx, 2)
- } else {
- contexttest.LoadUser(t, ctx, tt.userID)
- }
- if tt.repoID == 0 {
- contexttest.LoadRepo(t, ctx, 1)
- } else {
- contexttest.LoadRepo(t, ctx, tt.repoID)
- }
- ctx.SetParams(":run", fmt.Sprintf("%d", tt.runIndex))
- if tt.jobIndex != -1 {
- ctx.SetParams(":job", fmt.Sprintf("%d", tt.jobIndex))
- }
-
- RedirectToLatestAttempt(ctx)
- if tt.expectedCode == 0 {
- assert.Equal(t, http.StatusTemporaryRedirect, resp.Code)
- url, err := resp.Result().Location()
- require.NoError(t, err)
- assert.Equal(t, tt.expectedURL, url.String())
- } else {
- assert.Equal(t, tt.expectedCode, resp.Code)
- }
- })
- }
-}
-
-func TestActionsRerun(t *testing.T) {
- tests := []struct {
- name string
- runIndex int64
- jobIndex int64
- expectedCode int
- expectedURL string
- }{
- {
- name: "rerun all",
- runIndex: 187,
- jobIndex: -1,
- expectedURL: "https://try.gitea.io/user2/repo1/actions/runs/187/jobs/0/attempt/2",
- },
- {
- name: "rerun job",
- runIndex: 187,
- jobIndex: 2,
- expectedURL: "https://try.gitea.io/user2/repo1/actions/runs/187/jobs/2/attempt/3",
- },
- }
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- ctx, resp := contexttest.MockContext(t, "user2/repo1/actions/runs/187/rerun")
- contexttest.LoadUser(t, ctx, 2)
- contexttest.LoadRepo(t, ctx, 1)
- ctx.SetParams(":run", fmt.Sprintf("%d", tt.runIndex))
- if tt.jobIndex != -1 {
- ctx.SetParams(":job", fmt.Sprintf("%d", tt.jobIndex))
- }
-
- Rerun(ctx)
- require.Equal(t, http.StatusOK, resp.Result().StatusCode, "failure in Rerun(): %q", resp.Body.String())
-
- var actual redirectObject
- err := json.Unmarshal(resp.Body.Bytes(), &actual)
- require.NoError(t, err)
-
- // Note: this test isn't doing any functional testing of the Rerun handler's actual ability to set up a job
- // rerun. This test was added when the redirect to the correct `attempt` was added and only covers that
- // addition at this time.
- assert.Equal(t, redirectObject{Redirect: tt.expectedURL}, actual)
- })
- }
-}
diff --git a/routers/web/repo/activity.go b/routers/web/repo/activity.go
index c9cd2c13bb..af9cea0f33 100644
--- a/routers/web/repo/activity.go
+++ b/routers/web/repo/activity.go
@@ -7,10 +7,10 @@ import (
"net/http"
"time"
- activities_model "forgejo.org/models/activities"
- "forgejo.org/models/unit"
- "forgejo.org/modules/base"
- "forgejo.org/services/context"
+ activities_model "code.gitea.io/gitea/models/activities"
+ "code.gitea.io/gitea/models/unit"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/services/context"
)
const (
diff --git a/routers/web/repo/attachment.go b/routers/web/repo/attachment.go
index 5b2eaef889..b5078e1f63 100644
--- a/routers/web/repo/attachment.go
+++ b/routers/web/repo/attachment.go
@@ -7,18 +7,18 @@ import (
"fmt"
"net/http"
- access_model "forgejo.org/models/perm/access"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/modules/httpcache"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/storage"
- "forgejo.org/modules/util"
- "forgejo.org/routers/common"
- "forgejo.org/services/attachment"
- "forgejo.org/services/context"
- "forgejo.org/services/context/upload"
- repo_service "forgejo.org/services/repository"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/modules/httpcache"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/storage"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/routers/common"
+ "code.gitea.io/gitea/services/attachment"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/context/upload"
+ repo_service "code.gitea.io/gitea/services/repository"
)
// UploadIssueAttachment response for Issue/PR attachments
@@ -106,7 +106,7 @@ func ServeAttachment(ctx *context.Context, uuid string) {
}
if repository == nil { // If not linked
- if !ctx.IsSigned || attach.UploaderID != ctx.Doer.ID { // We block if not the uploader
+ if !(ctx.IsSigned && attach.UploaderID == ctx.Doer.ID) { // We block if not the uploader
ctx.Error(http.StatusNotFound)
return
}
diff --git a/routers/web/repo/badges/badges.go b/routers/web/repo/badges/badges.go
index e623a21fc0..a2306d5836 100644
--- a/routers/web/repo/badges/badges.go
+++ b/routers/web/repo/badges/badges.go
@@ -8,11 +8,11 @@ import (
"net/url"
"strings"
- actions_model "forgejo.org/models/actions"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unit"
- "forgejo.org/modules/setting"
- context_module "forgejo.org/services/context"
+ actions_model "code.gitea.io/gitea/models/actions"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unit"
+ "code.gitea.io/gitea/modules/setting"
+ context_module "code.gitea.io/gitea/services/context"
)
func getBadgeURL(ctx *context_module.Context, label, text, color string) string {
diff --git a/routers/web/repo/blame.go b/routers/web/repo/blame.go
index f4cc2a2cea..c7fbaaefcb 100644
--- a/routers/web/repo/blame.go
+++ b/routers/web/repo/blame.go
@@ -10,16 +10,16 @@ import (
"net/url"
"strings"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/charset"
- "forgejo.org/modules/git"
- "forgejo.org/modules/highlight"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/templates"
- "forgejo.org/modules/util"
- "forgejo.org/services/context"
- files_service "forgejo.org/services/repository/files"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/charset"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/highlight"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/templates"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/services/context"
+ files_service "code.gitea.io/gitea/services/repository/files"
)
type blameRow struct {
@@ -82,19 +82,19 @@ func RefBlame(ctx *context.Context) {
return
}
+ ctx.Data["NumLinesSet"] = true
+ ctx.Data["NumLines"], err = blob.GetBlobLineCount()
+ if err != nil {
+ ctx.ServerError("GetBlobLineCount", err)
+ return
+ }
+
result, err := performBlame(ctx, ctx.Repo.Commit, ctx.Repo.TreePath, ctx.FormBool("bypass-blame-ignore"))
if err != nil {
ctx.ServerError("performBlame", err)
return
}
- ctx.Data["NumLinesSet"] = true
- numLines := 0
- for _, p := range result.Parts {
- numLines += len(p.Lines)
- }
- ctx.Data["NumLines"] = numLines
-
ctx.Data["UsesIgnoreRevs"] = result.UsesIgnoreRevs
ctx.Data["FaultyIgnoreRevsFile"] = result.FaultyIgnoreRevsFile
diff --git a/routers/web/repo/branch.go b/routers/web/repo/branch.go
index 0fe52bfb48..4897a5f4fc 100644
--- a/routers/web/repo/branch.go
+++ b/routers/web/repo/branch.go
@@ -11,23 +11,23 @@ import (
"net/url"
"strings"
- "forgejo.org/models"
- git_model "forgejo.org/models/git"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unit"
- "forgejo.org/modules/base"
- "forgejo.org/modules/git"
- "forgejo.org/modules/log"
- "forgejo.org/modules/optional"
- repo_module "forgejo.org/modules/repository"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/util"
- "forgejo.org/modules/web"
- "forgejo.org/routers/utils"
- "forgejo.org/services/context"
- "forgejo.org/services/forms"
- release_service "forgejo.org/services/release"
- repo_service "forgejo.org/services/repository"
+ "code.gitea.io/gitea/models"
+ git_model "code.gitea.io/gitea/models/git"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unit"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/optional"
+ repo_module "code.gitea.io/gitea/modules/repository"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/modules/web"
+ "code.gitea.io/gitea/routers/utils"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/forms"
+ release_service "code.gitea.io/gitea/services/release"
+ repo_service "code.gitea.io/gitea/services/repository"
)
const (
@@ -70,6 +70,11 @@ func Branches(ctx *context.Context) {
ctx.ServerError("LoadBranches", err)
return
}
+ if !ctx.Repo.CanRead(unit.TypeActions) {
+ for key := range commitStatuses {
+ git_model.CommitStatusesHideActionsURL(ctx, commitStatuses[key])
+ }
+ }
commitStatus := make(map[string]*git_model.CommitStatus)
for commitID, cs := range commitStatuses {
diff --git a/routers/web/repo/card.go b/routers/web/repo/card.go
index 449e5c4890..e73971cd94 100644
--- a/routers/web/repo/card.go
+++ b/routers/web/repo/card.go
@@ -15,17 +15,17 @@ import (
"strings"
"time"
- "forgejo.org/models/db"
- issue_model "forgejo.org/models/issues"
- repo_model "forgejo.org/models/repo"
- unit_model "forgejo.org/models/unit"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/cache"
- "forgejo.org/modules/card"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/storage"
- "forgejo.org/services/context"
+ "code.gitea.io/gitea/models/db"
+ issue_model "code.gitea.io/gitea/models/issues"
+ repo_model "code.gitea.io/gitea/models/repo"
+ unit_model "code.gitea.io/gitea/models/unit"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/cache"
+ "code.gitea.io/gitea/modules/card"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/storage"
+ "code.gitea.io/gitea/services/context"
)
// drawUser draws a user avatar in a summary card
diff --git a/routers/web/repo/cherry_pick.go b/routers/web/repo/cherry_pick.go
index 0f57eb66f0..90dae704f4 100644
--- a/routers/web/repo/cherry_pick.go
+++ b/routers/web/repo/cherry_pick.go
@@ -8,17 +8,17 @@ import (
"errors"
"strings"
- "forgejo.org/models"
- git_model "forgejo.org/models/git"
- "forgejo.org/models/unit"
- "forgejo.org/modules/base"
- "forgejo.org/modules/git"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/util"
- "forgejo.org/modules/web"
- "forgejo.org/services/context"
- "forgejo.org/services/forms"
- "forgejo.org/services/repository/files"
+ "code.gitea.io/gitea/models"
+ git_model "code.gitea.io/gitea/models/git"
+ "code.gitea.io/gitea/models/unit"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/modules/web"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/forms"
+ "code.gitea.io/gitea/services/repository/files"
)
var tplCherryPick base.TplName = "repo/editor/cherry_pick"
diff --git a/routers/web/repo/code_frequency.go b/routers/web/repo/code_frequency.go
index 44c07e617e..c76f492da0 100644
--- a/routers/web/repo/code_frequency.go
+++ b/routers/web/repo/code_frequency.go
@@ -7,9 +7,9 @@ import (
"errors"
"net/http"
- "forgejo.org/modules/base"
- "forgejo.org/services/context"
- contributors_service "forgejo.org/services/repository"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/services/context"
+ contributors_service "code.gitea.io/gitea/services/repository"
)
const (
@@ -34,7 +34,7 @@ func CodeFrequencyData(ctx *context.Context) {
ctx.Status(http.StatusAccepted)
return
}
- ctx.ServerError("GetContributorStats", err)
+ ctx.ServerError("GetCodeFrequencyData", err)
} else {
ctx.JSON(http.StatusOK, contributorStats["total"].Weeks)
}
diff --git a/routers/web/repo/commit.go b/routers/web/repo/commit.go
index 408a2844de..857e34381e 100644
--- a/routers/web/repo/commit.go
+++ b/routers/web/repo/commit.go
@@ -12,25 +12,26 @@ import (
"path"
"strings"
- asymkey_model "forgejo.org/models/asymkey"
- "forgejo.org/models/db"
- git_model "forgejo.org/models/git"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/base"
- "forgejo.org/modules/charset"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/log"
- "forgejo.org/modules/markup"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/util"
- "forgejo.org/modules/web"
- "forgejo.org/services/context"
- "forgejo.org/services/forms"
- "forgejo.org/services/gitdiff"
- git_service "forgejo.org/services/repository"
- "forgejo.org/services/repository/gitgraph"
+ asymkey_model "code.gitea.io/gitea/models/asymkey"
+ "code.gitea.io/gitea/models/db"
+ git_model "code.gitea.io/gitea/models/git"
+ repo_model "code.gitea.io/gitea/models/repo"
+ unit_model "code.gitea.io/gitea/models/unit"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/charset"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/markup"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/modules/web"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/forms"
+ "code.gitea.io/gitea/services/gitdiff"
+ git_service "code.gitea.io/gitea/services/repository"
+ "code.gitea.io/gitea/services/repository/gitgraph"
)
const (
@@ -83,19 +84,8 @@ func Commits(ctx *context.Context) {
ctx.ServerError("CommitsByRange", err)
return
}
- ctx.Data["Commits"] = git_model.ParseCommitsWithStatus(ctx, commits, ctx.Repo.Repository)
+ ctx.Data["Commits"] = processGitCommits(ctx, commits)
- commitIDs := make([]string, 0, len(commits))
- for _, c := range commits {
- commitIDs = append(commitIDs, c.ID.String())
- }
- commitTagsMap, err := repo_model.FindTagsByCommitIDs(ctx, ctx.Repo.Repository.ID, commitIDs...)
- if err != nil {
- log.Error("FindTagsByCommitIDs: %v", err)
- ctx.Flash.Error(ctx.Tr("repo.commit.load_tags_failed"))
- } else {
- ctx.Data["CommitTagsMap"] = commitTagsMap
- }
ctx.Data["Username"] = ctx.Repo.Owner.Name
ctx.Data["Reponame"] = ctx.Repo.Repository.Name
ctx.Data["CommitCount"] = commitsCount
@@ -212,7 +202,7 @@ func SearchCommits(ctx *context.Context) {
return
}
ctx.Data["CommitCount"] = len(commits)
- ctx.Data["Commits"] = git_model.ParseCommitsWithStatus(ctx, commits, ctx.Repo.Repository)
+ ctx.Data["Commits"] = processGitCommits(ctx, commits)
ctx.Data["Keyword"] = query
if all {
@@ -277,7 +267,7 @@ func FileHistory(ctx *context.Context) {
}
}
- ctx.Data["Commits"] = git_model.ParseCommitsWithStatus(ctx, commits, ctx.Repo.Repository)
+ ctx.Data["Commits"] = processGitCommits(ctx, commits)
ctx.Data["Username"] = ctx.Repo.Owner.Name
ctx.Data["Reponame"] = ctx.Repo.Repository.Name
@@ -339,7 +329,7 @@ func Diff(ctx *context.Context) {
maxLines, maxFiles = -1, -1
}
- diff, err := gitdiff.GetDiffFull(ctx, gitRepo, &gitdiff.DiffOptions{
+ diff, err := gitdiff.GetDiff(ctx, gitRepo, &gitdiff.DiffOptions{
AfterCommitID: commitID,
SkipTo: ctx.FormString("skip-to"),
MaxLines: maxLines,
@@ -385,6 +375,9 @@ func Diff(ctx *context.Context) {
if err != nil {
log.Error("GetLatestCommitStatus: %v", err)
}
+ if !ctx.Repo.CanRead(unit_model.TypeActions) {
+ git_model.CommitStatusesHideActionsURL(ctx, statuses)
+ }
ctx.Data["CommitStatus"] = git_model.CalcCommitStatus(statuses)
ctx.Data["CommitStatuses"] = statuses
@@ -463,6 +456,20 @@ func RawDiff(ctx *context.Context) {
}
}
+func processGitCommits(ctx *context.Context, gitCommits []*git.Commit) []*git_model.SignCommitWithStatuses {
+ commits := git_model.ConvertFromGitCommit(ctx, gitCommits, ctx.Repo.Repository)
+ if !ctx.Repo.CanRead(unit_model.TypeActions) {
+ for _, commit := range commits {
+ if commit.Status == nil {
+ continue
+ }
+ commit.Status.HideActionsURL(ctx)
+ git_model.CommitStatusesHideActionsURL(ctx, commit.Statuses)
+ }
+ }
+ return commits
+}
+
func SetCommitNotes(ctx *context.Context) {
form := web.GetForm(ctx).(*forms.CommitNotesForm)
diff --git a/routers/web/repo/compare.go b/routers/web/repo/compare.go
index feedeef945..24785d867e 100644
--- a/routers/web/repo/compare.go
+++ b/routers/web/repo/compare.go
@@ -16,29 +16,29 @@ import (
"path/filepath"
"strings"
- "forgejo.org/models/db"
- git_model "forgejo.org/models/git"
- issues_model "forgejo.org/models/issues"
- access_model "forgejo.org/models/perm/access"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unit"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/base"
- "forgejo.org/modules/charset"
- csv_module "forgejo.org/modules/csv"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/log"
- "forgejo.org/modules/markup"
- "forgejo.org/modules/optional"
- "forgejo.org/modules/setting"
- api "forgejo.org/modules/structs"
- "forgejo.org/modules/typesniffer"
- "forgejo.org/modules/util"
- "forgejo.org/routers/common"
- "forgejo.org/services/context"
- "forgejo.org/services/context/upload"
- "forgejo.org/services/gitdiff"
+ "code.gitea.io/gitea/models/db"
+ git_model "code.gitea.io/gitea/models/git"
+ issues_model "code.gitea.io/gitea/models/issues"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unit"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/charset"
+ csv_module "code.gitea.io/gitea/modules/csv"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/markup"
+ "code.gitea.io/gitea/modules/optional"
+ "code.gitea.io/gitea/modules/setting"
+ api "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/typesniffer"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/routers/common"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/context/upload"
+ "code.gitea.io/gitea/services/gitdiff"
)
const (
@@ -312,16 +312,22 @@ func ParseCompareInfo(ctx *context.Context) *common.CompareInfo {
baseIsTag := ctx.Repo.GitRepo.IsTagExist(ci.BaseBranch)
if !baseIsCommit && !baseIsBranch && !baseIsTag {
- if ci.BaseBranch == ctx.Repo.GetObjectFormat().EmptyObjectID().String() {
+ // Check if baseBranch is short sha commit hash
+ if baseCommit, _ := ctx.Repo.GitRepo.GetCommit(ci.BaseBranch); baseCommit != nil {
+ ci.BaseBranch = baseCommit.ID.String()
+ ctx.Data["BaseBranch"] = ci.BaseBranch
+ baseIsCommit = true
+ } else if ci.BaseBranch == ctx.Repo.GetObjectFormat().EmptyObjectID().String() {
if isSameRepo {
ctx.Redirect(ctx.Repo.RepoLink + "/compare/" + util.PathEscapeSegments(ci.HeadBranch))
} else {
ctx.Redirect(ctx.Repo.RepoLink + "/compare/" + util.PathEscapeSegments(ci.HeadRepo.FullName()) + ":" + util.PathEscapeSegments(ci.HeadBranch))
}
+ return nil
} else {
ctx.NotFound("IsRefExist", nil)
+ return nil
}
- return nil
}
ctx.Data["BaseIsCommit"] = baseIsCommit
ctx.Data["BaseIsBranch"] = baseIsBranch
@@ -508,8 +514,15 @@ func ParseCompareInfo(ctx *context.Context) *common.CompareInfo {
headIsBranch := ci.HeadGitRepo.IsBranchExist(ci.HeadBranch)
headIsTag := ci.HeadGitRepo.IsTagExist(ci.HeadBranch)
if !headIsCommit && !headIsBranch && !headIsTag {
- ctx.NotFound("IsRefExist", nil)
- return nil
+ // Check if headBranch is short sha commit hash
+ if headCommit, _ := ci.HeadGitRepo.GetCommit(ci.HeadBranch); headCommit != nil {
+ ci.HeadBranch = headCommit.ID.String()
+ ctx.Data["HeadBranch"] = ci.HeadBranch
+ headIsCommit = true
+ } else {
+ ctx.NotFound("IsRefExist", nil)
+ return nil
+ }
}
ctx.Data["HeadIsCommit"] = headIsCommit
ctx.Data["HeadIsBranch"] = headIsBranch
@@ -520,6 +533,17 @@ func ParseCompareInfo(ctx *context.Context) *common.CompareInfo {
ctx.Data["PageIsComparePull"] = headIsBranch && baseIsBranch
}
+ if ctx.Data["PageIsComparePull"] == true && !permBase.CanReadIssuesOrPulls(true) {
+ if log.IsTrace() {
+ log.Trace("Permission Denied: User: %-v cannot create/read pull requests in Repo: %-v\nUser in baseRepo has Permissions: %-+v",
+ ctx.Doer,
+ baseRepo,
+ permBase)
+ }
+ ctx.NotFound("ParseCompareInfo", nil)
+ return nil
+ }
+
baseBranchRef := ci.BaseBranch
if baseIsBranch {
baseBranchRef = git.BranchPrefix + ci.BaseBranch
@@ -573,7 +597,7 @@ func PrepareCompareDiff(
config := unit.PullRequestsConfig()
if !config.AutodetectManualMerge {
- allowEmptyPr := ci.BaseBranch != ci.HeadBranch || ctx.Repo.Repository.Name != ci.HeadRepo.Name
+ allowEmptyPr := !(ci.BaseBranch == ci.HeadBranch && ctx.Repo.Repository.Name == ci.HeadRepo.Name)
ctx.Data["AllowEmptyPr"] = allowEmptyPr
return !allowEmptyPr
@@ -597,7 +621,7 @@ func PrepareCompareDiff(
fileOnly := ctx.FormBool("file-only")
- diff, err := gitdiff.GetDiffFull(ctx, ci.HeadGitRepo,
+ diff, err := gitdiff.GetDiff(ctx, ci.HeadGitRepo,
&gitdiff.DiffOptions{
BeforeCommitID: beforeCommitID,
AfterCommitID: headCommitID,
@@ -630,15 +654,15 @@ func PrepareCompareDiff(
return false
}
- commits := git_model.ParseCommitsWithStatus(ctx, ci.CompareInfo.Commits, ctx.Repo.Repository)
+ commits := processGitCommits(ctx, ci.CompareInfo.Commits)
ctx.Data["Commits"] = commits
ctx.Data["CommitCount"] = len(commits)
if len(commits) == 1 {
c := commits[0]
- title = strings.TrimSpace(c.Summary())
+ title = strings.TrimSpace(c.UserCommit.Summary())
- body := strings.Split(strings.TrimSpace(c.Message()), "\n")
+ body := strings.Split(strings.TrimSpace(c.UserCommit.Message()), "\n")
if len(body) > 1 {
ctx.Data["content"] = strings.Join(body[1:], "\n")
}
@@ -909,33 +933,28 @@ func ExcerptBlob(ctx *context.Context) {
ctx.Error(http.StatusInternalServerError, "getExcerptLines")
return
}
-
- // After the "up" or "down" expansion, check if there's any remaining content in the diff and add a line that will
- // be rendered into a new expander at either the top, or bottom.
- lineSection := &gitdiff.DiffLine{
- Type: gitdiff.DiffLineSection,
- SectionInfo: &gitdiff.DiffLineSectionInfo{
- Path: filePath,
- LastLeftIdx: lastLeft,
- LastRightIdx: lastRight,
- LeftIdx: idxLeft,
- RightIdx: idxRight,
- LeftHunkSize: leftHunkSize,
- RightHunkSize: rightHunkSize,
- },
- }
- if lineSection.GetExpandDirection() != gitdiff.DiffLineExpandNone {
+ if idxRight > lastRight {
lineText := " "
if rightHunkSize > 0 || leftHunkSize > 0 {
lineText = fmt.Sprintf("@@ -%d,%d +%d,%d @@\n", idxLeft, leftHunkSize, idxRight, rightHunkSize)
}
lineText = html.EscapeString(lineText)
- lineSection.Content = lineText
-
- switch direction {
- case "up":
+ lineSection := &gitdiff.DiffLine{
+ Type: gitdiff.DiffLineSection,
+ Content: lineText,
+ SectionInfo: &gitdiff.DiffLineSectionInfo{
+ Path: filePath,
+ LastLeftIdx: lastLeft,
+ LastRightIdx: lastRight,
+ LeftIdx: idxLeft,
+ RightIdx: idxRight,
+ LeftHunkSize: leftHunkSize,
+ RightHunkSize: rightHunkSize,
+ },
+ }
+ if direction == "up" {
section.Lines = append([]*gitdiff.DiffLine{lineSection}, section.Lines...)
- case "down":
+ } else if direction == "down" {
section.Lines = append(section.Lines, lineSection)
}
}
@@ -947,7 +966,7 @@ func ExcerptBlob(ctx *context.Context) {
}
func getExcerptLines(commit *git.Commit, filePath string, idxLeft, idxRight, chunkSize int) ([]*gitdiff.DiffLine, error) {
- blob, err := commit.GetBlobByPath(filePath)
+ blob, err := commit.Tree.GetBlobByPath(filePath)
if err != nil {
return nil, err
}
diff --git a/routers/web/repo/contributors.go b/routers/web/repo/contributors.go
index 094d13b54b..762fbf9379 100644
--- a/routers/web/repo/contributors.go
+++ b/routers/web/repo/contributors.go
@@ -7,9 +7,9 @@ import (
"errors"
"net/http"
- "forgejo.org/modules/base"
- "forgejo.org/services/context"
- contributors_service "forgejo.org/services/repository"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/services/context"
+ contributors_service "code.gitea.io/gitea/services/repository"
)
const (
diff --git a/routers/web/repo/download.go b/routers/web/repo/download.go
index 9fb4d78fe3..d7fe368474 100644
--- a/routers/web/repo/download.go
+++ b/routers/web/repo/download.go
@@ -7,15 +7,15 @@ package repo
import (
"time"
- git_model "forgejo.org/models/git"
- "forgejo.org/modules/git"
- "forgejo.org/modules/httpcache"
- "forgejo.org/modules/lfs"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/storage"
- "forgejo.org/routers/common"
- "forgejo.org/services/context"
+ git_model "code.gitea.io/gitea/models/git"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/httpcache"
+ "code.gitea.io/gitea/modules/lfs"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/storage"
+ "code.gitea.io/gitea/routers/common"
+ "code.gitea.io/gitea/services/context"
)
// ServeBlobOrLFS download a git.Blob redirecting to LFS if necessary
@@ -92,7 +92,7 @@ func getBlobForEntry(ctx *context.Context) (*git.Blob, *time.Time) {
return nil, nil
}
- if entry.IsDir() || entry.IsSubmodule() {
+ if entry.IsDir() || entry.IsSubModule() {
ctx.NotFound("getBlobForEntry", nil)
return nil, nil
}
diff --git a/routers/web/repo/editor.go b/routers/web/repo/editor.go
index 3e3cb0016d..f27ad62982 100644
--- a/routers/web/repo/editor.go
+++ b/routers/web/repo/editor.go
@@ -10,26 +10,26 @@ import (
"path"
"strings"
- "forgejo.org/models"
- git_model "forgejo.org/models/git"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unit"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/base"
- "forgejo.org/modules/charset"
- "forgejo.org/modules/git"
- "forgejo.org/modules/json"
- "forgejo.org/modules/log"
- "forgejo.org/modules/markup"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/typesniffer"
- "forgejo.org/modules/util"
- "forgejo.org/modules/web"
- "forgejo.org/routers/utils"
- "forgejo.org/services/context"
- "forgejo.org/services/context/upload"
- "forgejo.org/services/forms"
- files_service "forgejo.org/services/repository/files"
+ "code.gitea.io/gitea/models"
+ git_model "code.gitea.io/gitea/models/git"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unit"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/charset"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/markup"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/typesniffer"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/modules/web"
+ "code.gitea.io/gitea/routers/utils"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/context/upload"
+ "code.gitea.io/gitea/services/forms"
+ files_service "code.gitea.io/gitea/services/repository/files"
)
const (
@@ -189,7 +189,7 @@ func editFile(ctx *context.Context, isNewFile bool) {
buf = buf[:n]
// Only some file types are editable online as text.
- if !typesniffer.DetectContentType(buf, blob.Name()).IsRepresentableAsText() {
+ if !typesniffer.DetectContentType(buf).IsRepresentableAsText() {
ctx.NotFound("typesniffer.IsRepresentableAsText", nil)
return
}
@@ -585,7 +585,7 @@ func DeleteFilePost(ctx *context.Context) {
ctx.Error(http.StatusInternalServerError, err.Error())
}
} else if models.IsErrCommitIDDoesNotMatch(err) || git.IsErrPushOutOfDate(err) {
- ctx.RenderWithErr(ctx.Tr("repo.editor.file_changed_while_editing", ctx.Repo.RepoLink+"/compare/"+util.PathEscapeSegments(form.LastCommit)+"..."+util.PathEscapeSegments(ctx.Repo.CommitID)), tplDeleteFile, &form)
+ ctx.RenderWithErr(ctx.Tr("repo.editor.file_changed_while_deleting", ctx.Repo.RepoLink+"/compare/"+util.PathEscapeSegments(form.LastCommit)+"..."+util.PathEscapeSegments(ctx.Repo.CommitID)), tplDeleteFile, &form)
} else if git.IsErrPushRejected(err) {
errPushRej := err.(*git.ErrPushRejected)
if len(errPushRej.Message) == 0 {
diff --git a/routers/web/repo/editor_test.go b/routers/web/repo/editor_test.go
index b5d40abdab..4d565b5fd6 100644
--- a/routers/web/repo/editor_test.go
+++ b/routers/web/repo/editor_test.go
@@ -6,11 +6,11 @@ package repo
import (
"testing"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unittest"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/services/contexttest"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unittest"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/services/contexttest"
"github.com/stretchr/testify/assert"
)
@@ -37,7 +37,7 @@ func TestCleanUploadName(t *testing.T) {
"..a.dotty../.folder../.name...": "..a.dotty../.folder../.name...",
}
for k, v := range kases {
- assert.Equal(t, cleanUploadFileName(k), v)
+ assert.EqualValues(t, cleanUploadFileName(k), v)
}
}
diff --git a/routers/web/repo/find.go b/routers/web/repo/find.go
index 808323631c..9da4237c1e 100644
--- a/routers/web/repo/find.go
+++ b/routers/web/repo/find.go
@@ -6,9 +6,9 @@ package repo
import (
"net/http"
- "forgejo.org/modules/base"
- "forgejo.org/modules/util"
- "forgejo.org/services/context"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/services/context"
)
const (
diff --git a/routers/web/repo/flags/manage.go b/routers/web/repo/flags/manage.go
index c97ef54818..377a5c20f8 100644
--- a/routers/web/repo/flags/manage.go
+++ b/routers/web/repo/flags/manage.go
@@ -6,10 +6,10 @@ package flags
import (
"net/http"
- "forgejo.org/modules/base"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- "forgejo.org/services/context"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/services/context"
)
const (
diff --git a/routers/web/repo/githttp.go b/routers/web/repo/githttp.go
index 403245596d..bced8e61b1 100644
--- a/routers/web/repo/githttp.go
+++ b/routers/web/repo/githttp.go
@@ -18,21 +18,20 @@ import (
"sync"
"time"
- actions_model "forgejo.org/models/actions"
- auth_model "forgejo.org/models/auth"
- "forgejo.org/models/perm"
- access_model "forgejo.org/models/perm/access"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unit"
- "forgejo.org/modules/git"
- "forgejo.org/modules/log"
- repo_module "forgejo.org/modules/repository"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/structs"
- "forgejo.org/modules/util"
- "forgejo.org/services/context"
- redirect_service "forgejo.org/services/redirect"
- repo_service "forgejo.org/services/repository"
+ actions_model "code.gitea.io/gitea/models/actions"
+ auth_model "code.gitea.io/gitea/models/auth"
+ "code.gitea.io/gitea/models/perm"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unit"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/log"
+ repo_module "code.gitea.io/gitea/modules/repository"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/services/context"
+ repo_service "code.gitea.io/gitea/services/repository"
"github.com/go-chi/cors"
)
@@ -112,7 +111,7 @@ func httpBase(ctx *context.Context) *serviceHandler {
return nil
}
- if redirectRepoID, err := redirect_service.LookupRepoRedirect(ctx, ctx.Doer, owner.ID, reponame); err == nil {
+ if redirectRepoID, err := repo_model.LookupRedirect(ctx, owner.ID, reponame); err == nil {
context.RedirectToRepo(ctx.Base, redirectRepoID)
return nil
}
@@ -184,7 +183,9 @@ func httpBase(ctx *context.Context) *serviceHandler {
if repoExist {
// Because of special ref "refs/for" .. , need delay write permission check
- accessMode = perm.AccessModeRead
+ if git.SupportProcReceive {
+ accessMode = perm.AccessModeRead
+ }
if ctx.Data["IsActionsToken"] == true {
taskID := ctx.Data["ActionsTaskID"].(int64)
@@ -193,19 +194,24 @@ func httpBase(ctx *context.Context) *serviceHandler {
ctx.ServerError("GetTaskByID", err)
return nil
}
-
- p, err := access_model.GetActionRepoPermission(ctx, repo, task)
- if err != nil {
- ctx.ServerError("GetActionRepoPermission", err)
- return nil
- }
-
- if !p.CanAccess(accessMode, unitType) {
+ if task.RepoID != repo.ID {
ctx.PlainText(http.StatusForbidden, "User permission denied")
return nil
}
- environ = append(environ, fmt.Sprintf("%s=%d", repo_module.EnvActionPerm, p.AccessMode))
+ if task.IsForkPullRequest {
+ if accessMode > perm.AccessModeRead {
+ ctx.PlainText(http.StatusForbidden, "User permission denied")
+ return nil
+ }
+ environ = append(environ, fmt.Sprintf("%s=%d", repo_module.EnvActionPerm, perm.AccessModeRead))
+ } else {
+ if accessMode > perm.AccessModeWrite {
+ ctx.PlainText(http.StatusForbidden, "User permission denied")
+ return nil
+ }
+ environ = append(environ, fmt.Sprintf("%s=%d", repo_module.EnvActionPerm, perm.AccessModeWrite))
+ }
} else {
p, err := access_model.GetUserRepoPermission(ctx, repo, ctx.Doer)
if err != nil {
diff --git a/routers/web/repo/githttp_test.go b/routers/web/repo/githttp_test.go
index 0164b11f66..5ba8de3d63 100644
--- a/routers/web/repo/githttp_test.go
+++ b/routers/web/repo/githttp_test.go
@@ -37,6 +37,6 @@ func TestContainsParentDirectorySeparator(t *testing.T) {
}
for i := range tests {
- assert.Equal(t, tests[i].b, containsParentDirectorySeparator(tests[i].v))
+ assert.EqualValues(t, tests[i].b, containsParentDirectorySeparator(tests[i].v))
}
}
diff --git a/routers/web/repo/helper.go b/routers/web/repo/helper.go
index 3401f2f666..6fa7579231 100644
--- a/routers/web/repo/helper.go
+++ b/routers/web/repo/helper.go
@@ -7,9 +7,9 @@ import (
"net/url"
"slices"
- "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/services/context"
+ "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/services/context"
)
func MakeSelfOnTop(doer *user.User, users []*user.User) []*user.User {
@@ -35,7 +35,7 @@ func HandleGitError(ctx *context.Context, msg string, err error) {
case ctx.Repo.IsViewCommit:
refType = "commit"
}
- ctx.Data["NotFoundPrompt"] = ctx.Locale.Tr("repo.tree_path_not_found."+refType, ctx.Repo.TreePath, url.PathEscape(ctx.Repo.RefName))
+ ctx.Data["NotFoundPrompt"] = ctx.Locale.Tr("repo.tree_path_not_found_"+refType, ctx.Repo.TreePath, url.PathEscape(ctx.Repo.RefName))
ctx.Data["NotFoundGoBackURL"] = ctx.Repo.RepoLink + "/src/" + refType + "/" + url.PathEscape(ctx.Repo.RefName)
ctx.NotFound(msg, err)
} else {
diff --git a/routers/web/repo/helper_test.go b/routers/web/repo/helper_test.go
index 2607fd32f8..844ad5bf79 100644
--- a/routers/web/repo/helper_test.go
+++ b/routers/web/repo/helper_test.go
@@ -6,7 +6,7 @@ package repo
import (
"testing"
- "forgejo.org/models/user"
+ "code.gitea.io/gitea/models/user"
"github.com/stretchr/testify/assert"
)
diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go
index f445ce4a1a..e45abd3952 100644
--- a/routers/web/repo/issue.go
+++ b/routers/web/repo/issue.go
@@ -20,44 +20,44 @@ import (
"strings"
"time"
- activities_model "forgejo.org/models/activities"
- "forgejo.org/models/db"
- git_model "forgejo.org/models/git"
- issues_model "forgejo.org/models/issues"
- "forgejo.org/models/organization"
- access_model "forgejo.org/models/perm/access"
- project_model "forgejo.org/models/project"
- pull_model "forgejo.org/models/pull"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unit"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/base"
- "forgejo.org/modules/container"
- "forgejo.org/modules/emoji"
- "forgejo.org/modules/git"
- issue_indexer "forgejo.org/modules/indexer/issues"
- issue_template "forgejo.org/modules/issue/template"
- "forgejo.org/modules/log"
- "forgejo.org/modules/markup"
- "forgejo.org/modules/markup/markdown"
- "forgejo.org/modules/optional"
- repo_module "forgejo.org/modules/repository"
- "forgejo.org/modules/setting"
- api "forgejo.org/modules/structs"
- "forgejo.org/modules/templates"
- "forgejo.org/modules/templates/vars"
- "forgejo.org/modules/timeutil"
- "forgejo.org/modules/util"
- "forgejo.org/modules/web"
- "forgejo.org/routers/utils"
- asymkey_service "forgejo.org/services/asymkey"
- "forgejo.org/services/context"
- "forgejo.org/services/context/upload"
- "forgejo.org/services/convert"
- "forgejo.org/services/forms"
- issue_service "forgejo.org/services/issue"
- pull_service "forgejo.org/services/pull"
- repo_service "forgejo.org/services/repository"
+ activities_model "code.gitea.io/gitea/models/activities"
+ "code.gitea.io/gitea/models/db"
+ git_model "code.gitea.io/gitea/models/git"
+ issues_model "code.gitea.io/gitea/models/issues"
+ "code.gitea.io/gitea/models/organization"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ project_model "code.gitea.io/gitea/models/project"
+ pull_model "code.gitea.io/gitea/models/pull"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unit"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/container"
+ "code.gitea.io/gitea/modules/emoji"
+ "code.gitea.io/gitea/modules/git"
+ issue_indexer "code.gitea.io/gitea/modules/indexer/issues"
+ issue_template "code.gitea.io/gitea/modules/issue/template"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/markup"
+ "code.gitea.io/gitea/modules/markup/markdown"
+ "code.gitea.io/gitea/modules/optional"
+ repo_module "code.gitea.io/gitea/modules/repository"
+ "code.gitea.io/gitea/modules/setting"
+ api "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/templates"
+ "code.gitea.io/gitea/modules/templates/vars"
+ "code.gitea.io/gitea/modules/timeutil"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/modules/web"
+ "code.gitea.io/gitea/routers/utils"
+ asymkey_service "code.gitea.io/gitea/services/asymkey"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/context/upload"
+ "code.gitea.io/gitea/services/convert"
+ "code.gitea.io/gitea/services/forms"
+ issue_service "code.gitea.io/gitea/services/issue"
+ pull_service "code.gitea.io/gitea/services/pull"
+ repo_service "code.gitea.io/gitea/services/repository"
"code.forgejo.org/go-chi/binding"
)
@@ -76,27 +76,34 @@ const (
issueTemplateTitleKey = "IssueTemplateTitle"
)
-// generateIssueTemplateLocations generates all the file paths where we
-// look for an issue template, e.g. ".forgejo/ISSUE_TEMPLATE.md".
-func generateIssueTemplateLocations() []string {
- var result []string
- prefixes := []string{"", ".forgejo/", ".gitea/", ".github/", "docs/"}
- filenames := []string{"ISSUE_TEMPLATE", "issue_template"}
- extensions := []string{".md", ".yaml", ".yml"}
-
- for _, prefix := range prefixes {
- for _, filename := range filenames {
- for _, extension := range extensions {
- result = append(result, prefix+filename+extension)
- }
- }
- }
-
- return result
+// IssueTemplateCandidates issue templates
+var IssueTemplateCandidates = []string{
+ "ISSUE_TEMPLATE.md",
+ "ISSUE_TEMPLATE.yaml",
+ "ISSUE_TEMPLATE.yml",
+ "issue_template.md",
+ "issue_template.yaml",
+ "issue_template.yml",
+ ".forgejo/ISSUE_TEMPLATE.md",
+ ".forgejo/ISSUE_TEMPLATE.yaml",
+ ".forgejo/ISSUE_TEMPLATE.yml",
+ ".forgejo/issue_template.md",
+ ".forgejo/issue_template.yaml",
+ ".forgejo/issue_template.yml",
+ ".gitea/ISSUE_TEMPLATE.md",
+ ".gitea/ISSUE_TEMPLATE.yaml",
+ ".gitea/ISSUE_TEMPLATE.yml",
+ ".gitea/issue_template.md",
+ ".gitea/issue_template.yaml",
+ ".gitea/issue_template.yml",
+ ".github/ISSUE_TEMPLATE.md",
+ ".github/ISSUE_TEMPLATE.yaml",
+ ".github/ISSUE_TEMPLATE.yml",
+ ".github/issue_template.md",
+ ".github/issue_template.yaml",
+ ".github/issue_template.yml",
}
-var issueTemplateCandidates = generateIssueTemplateLocations()
-
// MustAllowUserComment checks to make sure if an issue is locked.
// If locked and user has permissions to write to the repository,
// then the comment is allowed, else it is blocked
@@ -180,10 +187,9 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption opt
// 0 means issues with no label
// blank means labels will not be filtered for issues
selectLabels := ctx.FormString("labels")
- switch selectLabels {
- case "":
+ if selectLabels == "" {
ctx.Data["AllLabels"] = true
- case "0":
+ } else if selectLabels == "0" {
ctx.Data["NoLabel"] = true
}
if len(selectLabels) > 0 {
@@ -341,6 +347,11 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption opt
ctx.ServerError("GetIssuesAllCommitStatus", err)
return
}
+ if !ctx.Repo.CanRead(unit.TypeActions) {
+ for key := range commitStatuses {
+ git_model.CommitStatusesHideActionsURL(ctx, commitStatuses[key])
+ }
+ }
if err := issues.LoadAttributes(ctx); err != nil {
ctx.ServerError("issues.LoadAttributes", err)
@@ -415,10 +426,9 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption opt
return 0
}
reviewTyp := issues_model.ReviewTypeApprove
- switch typ {
- case "reject":
+ if typ == "reject" {
reviewTyp = issues_model.ReviewTypeReject
- case "waiting":
+ } else if typ == "waiting" {
reviewTyp = issues_model.ReviewTypeRequest
}
for _, count := range counts {
@@ -998,7 +1008,7 @@ func NewIssue(ctx *context.Context) {
ctx.Data["Tags"] = tags
_, templateErrs := issue_service.GetTemplatesFromDefaultBranch(ctx.Repo.Repository, ctx.Repo.GitRepo)
- templateLoaded, errs := setTemplateIfExists(ctx, issueTemplateKey, issueTemplateCandidates)
+ templateLoaded, errs := setTemplateIfExists(ctx, issueTemplateKey, IssueTemplateCandidates)
for k, v := range errs {
templateErrs[k] = v
}
@@ -1301,7 +1311,7 @@ func roleDescriptor(ctx stdCtx.Context, repo *repo_model.Repository, poster *use
}
// Special user that can't have associated contributions and permissions in the repo.
- if poster.IsSystem() || poster.IsAPServerActor() {
+ if poster.IsGhost() || poster.IsActions() || poster.IsAPActor() {
return roleDescriptor, nil
}
@@ -1465,7 +1475,6 @@ func ViewIssue(ctx *context.Context) {
ctx.Data["IssueType"] = "all"
}
- ctx.Data["IsModerationEnabled"] = setting.Moderation.Enabled
ctx.Data["IsProjectsEnabled"] = ctx.Repo.CanRead(unit.TypeProjects)
ctx.Data["IsAttachmentEnabled"] = setting.Attachment.Enabled
upload.AddUploadContext(ctx, "comment")
@@ -1590,7 +1599,6 @@ func ViewIssue(ctx *context.Context) {
ok bool
marked = make(map[int64]issues_model.RoleDescriptor)
comment *issues_model.Comment
- commentIdx int
participants = make([]*user_model.User, 1, 10)
latestCloseCommentID int64
)
@@ -1646,17 +1654,15 @@ func ViewIssue(ctx *context.Context) {
return
}
- for commentIdx, comment = range issue.Comments {
+ for _, comment = range issue.Comments {
comment.Issue = issue
- metas := ctx.Repo.Repository.ComposeMetas(ctx)
- metas["scope"] = fmt.Sprintf("comment-%d", commentIdx)
if comment.Type == issues_model.CommentTypeComment || comment.Type == issues_model.CommentTypeReview {
comment.RenderedContent, err = markdown.RenderString(&markup.RenderContext{
Links: markup.Links{
Base: ctx.Repo.RepoLink,
},
- Metas: metas,
+ Metas: ctx.Repo.Repository.ComposeMetas(ctx),
GitRepo: ctx.Repo.GitRepo,
Ctx: ctx,
}, comment.Content)
@@ -1689,7 +1695,7 @@ func ViewIssue(ctx *context.Context) {
return
}
ghostMilestone := &issues_model.Milestone{
- ID: issues_model.GhostMilestoneID,
+ ID: -1,
Name: ctx.Locale.TrString("repo.issues.deleted_milestone"),
}
if comment.OldMilestoneID > 0 && comment.OldMilestone == nil {
@@ -1733,7 +1739,7 @@ func ViewIssue(ctx *context.Context) {
Links: markup.Links{
Base: ctx.Repo.RepoLink,
},
- Metas: metas,
+ Metas: ctx.Repo.Repository.ComposeMetas(ctx),
GitRepo: ctx.Repo.GitRepo,
Ctx: ctx,
}, comment.Content)
@@ -1790,6 +1796,15 @@ func ViewIssue(ctx *context.Context) {
ctx.ServerError("LoadPushCommits", err)
return
}
+ if !ctx.Repo.CanRead(unit.TypeActions) {
+ for _, commit := range comment.Commits {
+ if commit.Status == nil {
+ continue
+ }
+ commit.Status.HideActionsURL(ctx)
+ git_model.CommitStatusesHideActionsURL(ctx, commit.Statuses)
+ }
+ }
} else if comment.Type == issues_model.CommentTypeAddTimeManual ||
comment.Type == issues_model.CommentTypeStopTracking ||
comment.Type == issues_model.CommentTypeDeleteTimeManual {
@@ -2113,7 +2128,7 @@ func checkBlockedByIssues(ctx *context.Context, blockers []*issues_model.Depende
}
repoPerms[blocker.RepoID] = perm
}
- if perm.CanReadIssuesOrPulls(blocker.IsPull) {
+ if perm.CanReadIssuesOrPulls(blocker.Issue.IsPull) {
canRead = append(canRead, blocker)
} else {
notPermitted = append(notPermitted, blocker)
@@ -2397,6 +2412,10 @@ func UpdateIssueMilestone(ctx *context.Context) {
}
if ctx.FormBool("htmx") {
+ renderMilestones(ctx)
+ if ctx.Written() {
+ return
+ }
prepareHiddenCommentType(ctx)
if ctx.Written() {
return
@@ -2410,7 +2429,6 @@ func UpdateIssueMilestone(ctx *context.Context) {
ctx.ServerError("GetMilestoneByRepoID", err)
return
}
- ctx.Data["OpenMilestones"] = true
} else {
issue.Milestone = nil
}
@@ -2768,7 +2786,7 @@ func SearchIssues(ctx *context.Context) {
IncludedAnyLabelIDs: includedAnyLabels,
MilestoneIDs: includedMilestones,
ProjectID: projectID,
- SortBy: issue_indexer.ParseSortBy(ctx.FormString("sort"), issue_indexer.SortByCreatedDesc),
+ SortBy: issue_indexer.SortByCreatedDesc,
}
if since != 0 {
@@ -2797,10 +2815,9 @@ func SearchIssues(ctx *context.Context) {
}
}
- priorityRepoID := ctx.FormInt64("priority_repo_id")
- if priorityRepoID > 0 {
- searchOpt.PriorityRepoID = optional.Some(priorityRepoID)
- }
+ // FIXME: It's unsupported to sort by priority repo when searching by indexer,
+ // it's indeed an regression, but I think it is worth to support filtering by indexer first.
+ _ = ctx.FormInt64("priority_repo_id")
ids, total, err := issue_indexer.SearchIssues(ctx, searchOpt)
if err != nil {
@@ -2938,7 +2955,7 @@ func ListIssues(ctx *context.Context) {
IsPull: isPull,
IsClosed: isClosed,
ProjectID: projectID,
- SortBy: issue_indexer.ParseSortBy(ctx.FormString("sort"), issue_indexer.SortByCreatedDesc),
+ SortBy: issue_indexer.SortByCreatedDesc,
}
if since != 0 {
searchOpt.UpdatedAfterUnix = optional.Some(since)
@@ -3100,7 +3117,7 @@ func NewComment(ctx *context.Context) {
// Check if issue admin/poster changes the status of issue.
if (ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) || (ctx.IsSigned && issue.IsPoster(ctx.Doer.ID))) &&
(form.Status == "reopen" || form.Status == "close") &&
- (!issue.IsPull || !issue.PullRequest.HasMerged) {
+ !(issue.IsPull && issue.PullRequest.HasMerged) {
// Duplication and conflict check should apply to reopen pull request.
var pr *issues_model.PullRequest
@@ -3236,7 +3253,11 @@ func NewComment(ctx *context.Context) {
comment, err := issue_service.CreateIssueComment(ctx, ctx.Doer, ctx.Repo.Repository, issue, form.Content, attachments)
if err != nil {
if errors.Is(err, user_model.ErrBlockedByUser) {
- ctx.JSONError(ctx.Tr("repo.comment.blocked_by_user"))
+ if issue.IsPull {
+ ctx.JSONError(ctx.Tr("repo.pulls.comment.blocked_by_user"))
+ } else {
+ ctx.JSONError(ctx.Tr("repo.issues.comment.blocked_by_user"))
+ }
} else {
ctx.ServerError("CreateIssueComment", err)
}
@@ -3586,9 +3607,9 @@ func GetIssueAttachments(ctx *context.Context) {
if ctx.Written() {
return
}
- attachments := make([]*api.WebAttachment, len(issue.Attachments))
+ attachments := make([]*api.Attachment, len(issue.Attachments))
for i := 0; i < len(issue.Attachments); i++ {
- attachments[i] = convert.ToWebAttachment(ctx.Repo.Repository, issue.Attachments[i])
+ attachments[i] = convert.ToAttachment(ctx.Repo.Repository, issue.Attachments[i])
}
ctx.JSON(http.StatusOK, attachments)
}
@@ -3611,7 +3632,7 @@ func GetCommentAttachments(ctx *context.Context) {
return
}
- if !ctx.Repo.CanReadIssuesOrPulls(comment.Issue.IsPull) {
+ if !ctx.Repo.Permission.CanReadIssuesOrPulls(comment.Issue.IsPull) {
ctx.NotFound("CanReadIssuesOrPulls", issues_model.ErrCommentNotExist{})
return
}
@@ -3621,13 +3642,13 @@ func GetCommentAttachments(ctx *context.Context) {
return
}
+ attachments := make([]*api.Attachment, 0)
if err := comment.LoadAttachments(ctx); err != nil {
ctx.ServerError("LoadAttachments", err)
return
}
- attachments := make([]*api.WebAttachment, len(comment.Attachments))
for i := 0; i < len(comment.Attachments); i++ {
- attachments[i] = convert.ToWebAttachment(ctx.Repo.Repository, comment.Attachments[i])
+ attachments = append(attachments, convert.ToAttachment(ctx.Repo.Repository, comment.Attachments[i]))
}
ctx.JSON(http.StatusOK, attachments)
}
@@ -3777,49 +3798,3 @@ func issuePosters(ctx *context.Context, isPullList bool) {
}
ctx.JSON(http.StatusOK, resp)
}
-
-func getIssueParticipants(ctx *context.Context, issue *issues_model.Issue) []*user_model.User {
- var (
- participants = make([]*user_model.User, 1, 10)
- comment *issues_model.Comment
- )
-
- participants[0] = issue.Poster
-
- if err := issue.LoadComments(ctx); err != nil {
- ctx.ServerError("loadComments", err)
- return nil
- }
-
- if err := issue.Comments.LoadPosters(ctx); err != nil {
- ctx.ServerError("LoadPosters", err)
- return nil
- }
-
- for _, comment = range issue.Comments {
- if comment.Type == issues_model.CommentTypeComment ||
- comment.Type == issues_model.CommentTypeReview ||
- comment.Type == issues_model.CommentTypePullRequestPush {
- participants = addParticipant(comment.Poster, participants)
- } else if comment.Type.HasContentSupport() {
- participants = addParticipant(comment.Poster, participants)
-
- if comment.Review == nil {
- continue
- }
- if err := comment.Review.LoadCodeComments(ctx); err != nil {
- ctx.ServerError("Review.LoadCodeComments", err)
- return nil
- }
- for _, codeComments := range comment.Review.CodeComments {
- for _, lineComments := range codeComments {
- for _, c := range lineComments {
- participants = addParticipant(c.Poster, participants)
- }
- }
- }
- }
- }
-
- return participants
-}
diff --git a/routers/web/repo/issue_content_history.go b/routers/web/repo/issue_content_history.go
index 11d0de90de..4ce76b2bb9 100644
--- a/routers/web/repo/issue_content_history.go
+++ b/routers/web/repo/issue_content_history.go
@@ -9,12 +9,12 @@ import (
"net/http"
"strings"
- "forgejo.org/models/avatars"
- issues_model "forgejo.org/models/issues"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/templates"
- "forgejo.org/services/context"
+ "code.gitea.io/gitea/models/avatars"
+ issues_model "code.gitea.io/gitea/models/issues"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/templates"
+ "code.gitea.io/gitea/services/context"
"github.com/sergi/go-diff/diffmatchpatch"
)
@@ -160,16 +160,15 @@ func GetContentHistoryDetail(ctx *context.Context) {
diffHTMLBuf := bytes.Buffer{}
diffHTMLBuf.WriteString("")
for _, it := range diff {
- switch it.Type {
- case diffmatchpatch.DiffInsert:
+ if it.Type == diffmatchpatch.DiffInsert {
diffHTMLBuf.WriteString("")
diffHTMLBuf.WriteString(html.EscapeString(it.Text))
diffHTMLBuf.WriteString(" ")
- case diffmatchpatch.DiffDelete:
+ } else if it.Type == diffmatchpatch.DiffDelete {
diffHTMLBuf.WriteString("")
diffHTMLBuf.WriteString(html.EscapeString(it.Text))
diffHTMLBuf.WriteString(" ")
- default:
+ } else {
diffHTMLBuf.WriteString(html.EscapeString(it.Text))
}
}
diff --git a/routers/web/repo/issue_dependency.go b/routers/web/repo/issue_dependency.go
index 3764a6bd7e..66b38688ec 100644
--- a/routers/web/repo/issue_dependency.go
+++ b/routers/web/repo/issue_dependency.go
@@ -6,10 +6,10 @@ package repo
import (
"net/http"
- issues_model "forgejo.org/models/issues"
- access_model "forgejo.org/models/perm/access"
- "forgejo.org/modules/setting"
- "forgejo.org/services/context"
+ issues_model "code.gitea.io/gitea/models/issues"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/services/context"
)
// AddDependency adds new dependencies
diff --git a/routers/web/repo/issue_label.go b/routers/web/repo/issue_label.go
index 74674e9550..81bee4dbb5 100644
--- a/routers/web/repo/issue_label.go
+++ b/routers/web/repo/issue_label.go
@@ -6,17 +6,17 @@ package repo
import (
"net/http"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- "forgejo.org/models/organization"
- "forgejo.org/modules/base"
- "forgejo.org/modules/label"
- "forgejo.org/modules/log"
- repo_module "forgejo.org/modules/repository"
- "forgejo.org/modules/web"
- "forgejo.org/services/context"
- "forgejo.org/services/forms"
- issue_service "forgejo.org/services/issue"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ "code.gitea.io/gitea/models/organization"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/label"
+ "code.gitea.io/gitea/modules/log"
+ repo_module "code.gitea.io/gitea/modules/repository"
+ "code.gitea.io/gitea/modules/web"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/forms"
+ issue_service "code.gitea.io/gitea/services/issue"
)
const (
diff --git a/routers/web/repo/issue_label_test.go b/routers/web/repo/issue_label_test.go
index 0adcc39499..2b4915e855 100644
--- a/routers/web/repo/issue_label_test.go
+++ b/routers/web/repo/issue_label_test.go
@@ -8,13 +8,13 @@ import (
"strconv"
"testing"
- issues_model "forgejo.org/models/issues"
- "forgejo.org/models/unittest"
- "forgejo.org/modules/repository"
- "forgejo.org/modules/test"
- "forgejo.org/modules/web"
- "forgejo.org/services/contexttest"
- "forgejo.org/services/forms"
+ issues_model "code.gitea.io/gitea/models/issues"
+ "code.gitea.io/gitea/models/unittest"
+ "code.gitea.io/gitea/modules/repository"
+ "code.gitea.io/gitea/modules/test"
+ "code.gitea.io/gitea/modules/web"
+ "code.gitea.io/gitea/services/contexttest"
+ "code.gitea.io/gitea/services/forms"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -39,7 +39,7 @@ func TestInitializeLabels(t *testing.T) {
contexttest.LoadRepo(t, ctx, 2)
web.SetForm(ctx, &forms.InitializeLabelsForm{TemplateName: "Default"})
InitializeLabels(ctx)
- assert.Equal(t, http.StatusSeeOther, ctx.Resp.Status())
+ assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status())
unittest.AssertExistsAndLoadBean(t, &issues_model.Label{
RepoID: 2,
Name: "enhancement",
@@ -69,7 +69,7 @@ func TestRetrieveLabels(t *testing.T) {
assert.True(t, ok)
if assert.Len(t, labels, len(testCase.ExpectedLabelIDs)) {
for i, label := range labels {
- assert.Equal(t, testCase.ExpectedLabelIDs[i], label.ID)
+ assert.EqualValues(t, testCase.ExpectedLabelIDs[i], label.ID)
}
}
}
@@ -85,7 +85,7 @@ func TestNewLabel(t *testing.T) {
Color: "#abcdef",
})
NewLabel(ctx)
- assert.Equal(t, http.StatusSeeOther, ctx.Resp.Status())
+ assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status())
unittest.AssertExistsAndLoadBean(t, &issues_model.Label{
Name: "newlabel",
Color: "#abcdef",
@@ -105,7 +105,7 @@ func TestUpdateLabel(t *testing.T) {
IsArchived: true,
})
UpdateLabel(ctx)
- assert.Equal(t, http.StatusSeeOther, ctx.Resp.Status())
+ assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status())
unittest.AssertExistsAndLoadBean(t, &issues_model.Label{
ID: 2,
Name: "newnameforlabel",
@@ -121,7 +121,7 @@ func TestDeleteLabel(t *testing.T) {
contexttest.LoadRepo(t, ctx, 1)
ctx.Req.Form.Set("id", "2")
DeleteLabel(ctx)
- assert.Equal(t, http.StatusOK, ctx.Resp.Status())
+ assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
unittest.AssertNotExistsBean(t, &issues_model.Label{ID: 2})
unittest.AssertNotExistsBean(t, &issues_model.IssueLabel{LabelID: 2})
assert.EqualValues(t, ctx.Tr("repo.issues.label_deletion_success"), ctx.Flash.SuccessMsg)
@@ -135,7 +135,7 @@ func TestUpdateIssueLabel_Clear(t *testing.T) {
ctx.Req.Form.Set("issue_ids", "1,3")
ctx.Req.Form.Set("action", "clear")
UpdateIssueLabel(ctx)
- assert.Equal(t, http.StatusOK, ctx.Resp.Status())
+ assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
unittest.AssertNotExistsBean(t, &issues_model.IssueLabel{IssueID: 1})
unittest.AssertNotExistsBean(t, &issues_model.IssueLabel{IssueID: 3})
unittest.CheckConsistencyFor(t, &issues_model.Label{})
@@ -161,7 +161,7 @@ func TestUpdateIssueLabel_Toggle(t *testing.T) {
ctx.Req.Form.Set("action", testCase.Action)
ctx.Req.Form.Set("id", strconv.Itoa(int(testCase.LabelID)))
UpdateIssueLabel(ctx)
- assert.Equal(t, http.StatusOK, ctx.Resp.Status())
+ assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
for _, issueID := range testCase.IssueIDs {
unittest.AssertExistsIf(t, testCase.ExpectedAdd, &issues_model.IssueLabel{
IssueID: issueID,
diff --git a/routers/web/repo/issue_lock.go b/routers/web/repo/issue_lock.go
index dea67ab996..1d5fc8a5f3 100644
--- a/routers/web/repo/issue_lock.go
+++ b/routers/web/repo/issue_lock.go
@@ -4,10 +4,10 @@
package repo
import (
- issues_model "forgejo.org/models/issues"
- "forgejo.org/modules/web"
- "forgejo.org/services/context"
- "forgejo.org/services/forms"
+ issues_model "code.gitea.io/gitea/models/issues"
+ "code.gitea.io/gitea/modules/web"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/forms"
)
// LockIssue locks an issue. This would limit commenting abilities to
diff --git a/routers/web/repo/issue_pin.go b/routers/web/repo/issue_pin.go
index 5e2075a17f..365c812681 100644
--- a/routers/web/repo/issue_pin.go
+++ b/routers/web/repo/issue_pin.go
@@ -6,10 +6,10 @@ package repo
import (
"net/http"
- issues_model "forgejo.org/models/issues"
- "forgejo.org/modules/json"
- "forgejo.org/modules/log"
- "forgejo.org/services/context"
+ issues_model "code.gitea.io/gitea/models/issues"
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/services/context"
)
// IssuePinOrUnpin pin or unpin a Issue
diff --git a/routers/web/repo/issue_stopwatch.go b/routers/web/repo/issue_stopwatch.go
index 5bc49464dd..70d42b27c0 100644
--- a/routers/web/repo/issue_stopwatch.go
+++ b/routers/web/repo/issue_stopwatch.go
@@ -7,10 +7,10 @@ import (
"net/http"
"strings"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- "forgejo.org/modules/eventsource"
- "forgejo.org/services/context"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ "code.gitea.io/gitea/modules/eventsource"
+ "code.gitea.io/gitea/services/context"
)
// IssueStopwatch creates or stops a stopwatch for the given issue.
diff --git a/routers/web/repo/issue_timetrack.go b/routers/web/repo/issue_timetrack.go
index e63f7e2dc2..241e434049 100644
--- a/routers/web/repo/issue_timetrack.go
+++ b/routers/web/repo/issue_timetrack.go
@@ -7,12 +7,12 @@ import (
"net/http"
"time"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- "forgejo.org/modules/util"
- "forgejo.org/modules/web"
- "forgejo.org/services/context"
- "forgejo.org/services/forms"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/modules/web"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/forms"
)
// AddTimeManually tracks time manually
diff --git a/routers/web/repo/issue_watch.go b/routers/web/repo/issue_watch.go
index 5af223f865..5cff9f4ddd 100644
--- a/routers/web/repo/issue_watch.go
+++ b/routers/web/repo/issue_watch.go
@@ -7,10 +7,10 @@ import (
"net/http"
"strconv"
- issues_model "forgejo.org/models/issues"
- "forgejo.org/modules/base"
- "forgejo.org/modules/log"
- "forgejo.org/services/context"
+ issues_model "code.gitea.io/gitea/models/issues"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/services/context"
)
const (
diff --git a/routers/web/repo/main_test.go b/routers/web/repo/main_test.go
index 8b30ad41ed..6e469cf2ed 100644
--- a/routers/web/repo/main_test.go
+++ b/routers/web/repo/main_test.go
@@ -6,7 +6,7 @@ package repo
import (
"testing"
- "forgejo.org/models/unittest"
+ "code.gitea.io/gitea/models/unittest"
)
func TestMain(m *testing.M) {
diff --git a/routers/web/repo/middlewares.go b/routers/web/repo/middlewares.go
index 9aba447433..ddda9f3ff2 100644
--- a/routers/web/repo/middlewares.go
+++ b/routers/web/repo/middlewares.go
@@ -7,12 +7,12 @@ import (
"fmt"
"strconv"
- system_model "forgejo.org/models/system"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/optional"
- "forgejo.org/services/context"
- user_service "forgejo.org/services/user"
+ system_model "code.gitea.io/gitea/models/system"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/optional"
+ "code.gitea.io/gitea/services/context"
+ user_service "code.gitea.io/gitea/services/user"
)
// SetEditorconfigIfExists set editor config as render variable
diff --git a/routers/web/repo/migrate.go b/routers/web/repo/migrate.go
index 3a5cf30dbe..0acf966bca 100644
--- a/routers/web/repo/migrate.go
+++ b/routers/web/repo/migrate.go
@@ -9,23 +9,23 @@ import (
"net/url"
"strings"
- "forgejo.org/models"
- admin_model "forgejo.org/models/admin"
- "forgejo.org/models/db"
- quota_model "forgejo.org/models/quota"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/base"
- "forgejo.org/modules/lfs"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/structs"
- "forgejo.org/modules/util"
- "forgejo.org/modules/web"
- "forgejo.org/services/context"
- "forgejo.org/services/forms"
- "forgejo.org/services/migrations"
- "forgejo.org/services/task"
+ "code.gitea.io/gitea/models"
+ admin_model "code.gitea.io/gitea/models/admin"
+ "code.gitea.io/gitea/models/db"
+ quota_model "code.gitea.io/gitea/models/quota"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/lfs"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/modules/web"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/forms"
+ "code.gitea.io/gitea/services/migrations"
+ "code.gitea.io/gitea/services/task"
)
const (
@@ -138,8 +138,6 @@ func handleMigrateRemoteAddrError(ctx *context.Context, err error, tpl base.TplN
}
case addrErr.IsInvalidPath:
ctx.RenderWithErr(ctx.Tr("repo.migrate.invalid_local_path"), tpl, form)
- case addrErr.HasCredentials:
- ctx.RenderWithErr(ctx.Tr("migrate.form.error.url_credentials"), tpl, form)
default:
log.Error("Error whilst updating url: %v", err)
ctx.RenderWithErr(ctx.Tr("form.url_error", "unknown"), tpl, form)
diff --git a/routers/web/repo/milestone.go b/routers/web/repo/milestone.go
index 920a9ee12a..1c53f73fdb 100644
--- a/routers/web/repo/milestone.go
+++ b/routers/web/repo/milestone.go
@@ -9,18 +9,18 @@ import (
"net/url"
"time"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- "forgejo.org/modules/base"
- "forgejo.org/modules/markup"
- "forgejo.org/modules/markup/markdown"
- "forgejo.org/modules/optional"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/timeutil"
- "forgejo.org/modules/web"
- "forgejo.org/services/context"
- "forgejo.org/services/forms"
- "forgejo.org/services/issue"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/markup"
+ "code.gitea.io/gitea/modules/markup/markdown"
+ "code.gitea.io/gitea/modules/optional"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/timeutil"
+ "code.gitea.io/gitea/modules/web"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/forms"
+ "code.gitea.io/gitea/services/issue"
"xorm.io/builder"
)
diff --git a/routers/web/repo/packages.go b/routers/web/repo/packages.go
index c947fb99bf..11874ab0d0 100644
--- a/routers/web/repo/packages.go
+++ b/routers/web/repo/packages.go
@@ -6,13 +6,13 @@ package repo
import (
"net/http"
- "forgejo.org/models/db"
- "forgejo.org/models/packages"
- "forgejo.org/models/unit"
- "forgejo.org/modules/base"
- "forgejo.org/modules/optional"
- "forgejo.org/modules/setting"
- "forgejo.org/services/context"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/packages"
+ "code.gitea.io/gitea/models/unit"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/optional"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/services/context"
)
const (
diff --git a/routers/web/repo/patch.go b/routers/web/repo/patch.go
index 688ef19375..d234f6c964 100644
--- a/routers/web/repo/patch.go
+++ b/routers/web/repo/patch.go
@@ -6,16 +6,16 @@ package repo
import (
"strings"
- "forgejo.org/models"
- git_model "forgejo.org/models/git"
- "forgejo.org/models/unit"
- "forgejo.org/modules/base"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/util"
- "forgejo.org/modules/web"
- "forgejo.org/services/context"
- "forgejo.org/services/forms"
- "forgejo.org/services/repository/files"
+ "code.gitea.io/gitea/models"
+ git_model "code.gitea.io/gitea/models/git"
+ "code.gitea.io/gitea/models/unit"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/modules/web"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/forms"
+ "code.gitea.io/gitea/services/repository/files"
)
const (
diff --git a/routers/web/repo/projects.go b/routers/web/repo/projects.go
index e5bd06e987..0689b0a721 100644
--- a/routers/web/repo/projects.go
+++ b/routers/web/repo/projects.go
@@ -9,22 +9,22 @@ import (
"net/http"
"strings"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- "forgejo.org/models/perm"
- project_model "forgejo.org/models/project"
- attachment_model "forgejo.org/models/repo"
- "forgejo.org/models/unit"
- "forgejo.org/modules/base"
- "forgejo.org/modules/json"
- "forgejo.org/modules/markup"
- "forgejo.org/modules/markup/markdown"
- "forgejo.org/modules/optional"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/util"
- "forgejo.org/modules/web"
- "forgejo.org/services/context"
- "forgejo.org/services/forms"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ "code.gitea.io/gitea/models/perm"
+ project_model "code.gitea.io/gitea/models/project"
+ attachment_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unit"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/markup"
+ "code.gitea.io/gitea/modules/markup/markdown"
+ "code.gitea.io/gitea/modules/optional"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/modules/web"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/forms"
)
const (
@@ -120,7 +120,7 @@ func Projects(ctx *context.Context) {
pager.AddParam(ctx, "state", "State")
ctx.Data["Page"] = pager
- ctx.Data["CanWriteProjects"] = ctx.Repo.CanWrite(unit.TypeProjects)
+ ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(unit.TypeProjects)
ctx.Data["IsShowClosed"] = isShowClosed
ctx.Data["IsProjectsPage"] = true
ctx.Data["SortType"] = sortType
@@ -146,7 +146,7 @@ func RenderNewProject(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("repo.projects.new")
ctx.Data["TemplateConfigs"] = project_model.GetTemplateConfigs()
ctx.Data["CardTypes"] = project_model.GetCardConfig()
- ctx.Data["CanWriteProjects"] = ctx.Repo.CanWrite(unit.TypeProjects)
+ ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(unit.TypeProjects)
ctx.Data["CancelLink"] = ctx.Repo.Repository.Link() + "/projects"
ctx.HTML(http.StatusOK, tplProjectsNew)
}
@@ -228,7 +228,7 @@ func DeleteProject(ctx *context.Context) {
func RenderEditProject(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("repo.projects.edit")
ctx.Data["PageIsEditProjects"] = true
- ctx.Data["CanWriteProjects"] = ctx.Repo.CanWrite(unit.TypeProjects)
+ ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(unit.TypeProjects)
ctx.Data["CardTypes"] = project_model.GetCardConfig()
p, err := project_model.GetProjectByID(ctx, ctx.ParamsInt64(":id"))
@@ -262,7 +262,7 @@ func EditProjectPost(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("repo.projects.edit")
ctx.Data["PageIsEditProjects"] = true
- ctx.Data["CanWriteProjects"] = ctx.Repo.CanWrite(unit.TypeProjects)
+ ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(unit.TypeProjects)
ctx.Data["CardTypes"] = project_model.GetCardConfig()
ctx.Data["CancelLink"] = project_model.ProjectLinkForRepo(ctx.Repo.Repository, projectID)
@@ -378,7 +378,7 @@ func ViewProject(ctx *context.Context) {
ctx.Data["Title"] = project.Title
ctx.Data["IsProjectsPage"] = true
- ctx.Data["CanWriteProjects"] = ctx.Repo.CanWrite(unit.TypeProjects)
+ ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(unit.TypeProjects)
ctx.Data["Project"] = project
ctx.Data["IssuesMap"] = issuesMap
ctx.Data["Columns"] = columns
diff --git a/routers/web/repo/projects_test.go b/routers/web/repo/projects_test.go
index bc8b747980..d61230a57e 100644
--- a/routers/web/repo/projects_test.go
+++ b/routers/web/repo/projects_test.go
@@ -6,8 +6,8 @@ package repo
import (
"testing"
- "forgejo.org/models/unittest"
- "forgejo.org/services/contexttest"
+ "code.gitea.io/gitea/models/unittest"
+ "code.gitea.io/gitea/services/contexttest"
"github.com/stretchr/testify/assert"
)
diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go
index e484187b54..98dacc1a0d 100644
--- a/routers/web/repo/pull.go
+++ b/routers/web/repo/pull.go
@@ -10,49 +10,45 @@ import (
"errors"
"fmt"
"html"
- "html/template"
"net/http"
"net/url"
- "path"
"strconv"
"strings"
+ "time"
- "forgejo.org/models"
- activities_model "forgejo.org/models/activities"
- asymkey_model "forgejo.org/models/asymkey"
- "forgejo.org/models/db"
- git_model "forgejo.org/models/git"
- issues_model "forgejo.org/models/issues"
- "forgejo.org/models/organization"
- access_model "forgejo.org/models/perm/access"
- pull_model "forgejo.org/models/pull"
- quota_model "forgejo.org/models/quota"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unit"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/base"
- "forgejo.org/modules/charset"
- "forgejo.org/modules/emoji"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- issue_template "forgejo.org/modules/issue/template"
- "forgejo.org/modules/log"
- "forgejo.org/modules/markup"
- "forgejo.org/modules/optional"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/structs"
- "forgejo.org/modules/util"
- "forgejo.org/modules/web"
- "forgejo.org/routers/utils"
- asymkey_service "forgejo.org/services/asymkey"
- "forgejo.org/services/automerge"
- "forgejo.org/services/context"
- "forgejo.org/services/context/upload"
- "forgejo.org/services/forms"
- "forgejo.org/services/gitdiff"
- notify_service "forgejo.org/services/notify"
- pull_service "forgejo.org/services/pull"
- repo_service "forgejo.org/services/repository"
+ "code.gitea.io/gitea/models"
+ activities_model "code.gitea.io/gitea/models/activities"
+ "code.gitea.io/gitea/models/db"
+ git_model "code.gitea.io/gitea/models/git"
+ issues_model "code.gitea.io/gitea/models/issues"
+ "code.gitea.io/gitea/models/organization"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ pull_model "code.gitea.io/gitea/models/pull"
+ quota_model "code.gitea.io/gitea/models/quota"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unit"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/emoji"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ issue_template "code.gitea.io/gitea/modules/issue/template"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/optional"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/modules/web"
+ "code.gitea.io/gitea/routers/utils"
+ asymkey_service "code.gitea.io/gitea/services/asymkey"
+ "code.gitea.io/gitea/services/automerge"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/context/upload"
+ "code.gitea.io/gitea/services/forms"
+ "code.gitea.io/gitea/services/gitdiff"
+ notify_service "code.gitea.io/gitea/services/notify"
+ pull_service "code.gitea.io/gitea/services/pull"
+ repo_service "code.gitea.io/gitea/services/repository"
"github.com/gobwas/glob"
)
@@ -66,27 +62,33 @@ const (
pullRequestTemplateKey = "PullRequestTemplate"
)
-// generatePullRequestTemplateLocations generates all the file paths where we
-// look for a pull request template, e.g. ".forgejo/PULL_REQUEST_TEMPLATE.md".
-func generatePullRequestTemplateLocations() []string {
- var result []string
- prefixes := []string{"", ".forgejo/", ".gitea/", ".github/", "docs/"}
- filenames := []string{"PULL_REQUEST_TEMPLATE", "pull_request_template"}
- extensions := []string{".md", ".yaml", ".yml"}
-
- for _, prefix := range prefixes {
- for _, filename := range filenames {
- for _, extension := range extensions {
- result = append(result, prefix+filename+extension)
- }
- }
- }
-
- return result
+var pullRequestTemplateCandidates = []string{
+ "PULL_REQUEST_TEMPLATE.md",
+ "PULL_REQUEST_TEMPLATE.yaml",
+ "PULL_REQUEST_TEMPLATE.yml",
+ "pull_request_template.md",
+ "pull_request_template.yaml",
+ "pull_request_template.yml",
+ ".forgejo/PULL_REQUEST_TEMPLATE.md",
+ ".forgejo/PULL_REQUEST_TEMPLATE.yaml",
+ ".forgejo/PULL_REQUEST_TEMPLATE.yml",
+ ".forgejo/pull_request_template.md",
+ ".forgejo/pull_request_template.yaml",
+ ".forgejo/pull_request_template.yml",
+ ".gitea/PULL_REQUEST_TEMPLATE.md",
+ ".gitea/PULL_REQUEST_TEMPLATE.yaml",
+ ".gitea/PULL_REQUEST_TEMPLATE.yml",
+ ".gitea/pull_request_template.md",
+ ".gitea/pull_request_template.yaml",
+ ".gitea/pull_request_template.yml",
+ ".github/PULL_REQUEST_TEMPLATE.md",
+ ".github/PULL_REQUEST_TEMPLATE.yaml",
+ ".github/PULL_REQUEST_TEMPLATE.yml",
+ ".github/pull_request_template.md",
+ ".github/pull_request_template.yaml",
+ ".github/pull_request_template.yml",
}
-var pullRequestTemplateCandidates = generatePullRequestTemplateLocations()
-
func getRepository(ctx *context.Context, repoID int64) *repo_model.Repository {
repo, err := repo_model.GetRepositoryByID(ctx, repoID)
if err != nil {
@@ -354,7 +356,7 @@ func getPullInfo(ctx *context.Context) (issue *issues_model.Issue, ok bool) {
ctx.Data["Issue"] = issue
if !issue.IsPull {
- ctx.Redirect(issue.Link())
+ ctx.NotFound("ViewPullCommits", nil)
return nil, false
}
@@ -399,7 +401,6 @@ func setMergeTarget(ctx *context.Context, pull *issues_model.PullRequest) {
// GetPullDiffStats get Pull Requests diff stats
func GetPullDiffStats(ctx *context.Context) {
- // FIXME: this getPullInfo seems to be a duplicate call with other route handlers
issue, ok := getPullInfo(ctx)
if !ok {
return
@@ -407,15 +408,15 @@ func GetPullDiffStats(ctx *context.Context) {
pull := issue.PullRequest
mergeBaseCommitID := GetMergedBaseCommitID(ctx, issue)
+
if mergeBaseCommitID == "" {
ctx.NotFound("PullFiles", nil)
return
}
- // do not report 500 server error to end users if error occurs, otherwise a PR missing ref won't be able to view.
headCommitID, err := ctx.Repo.GitRepo.GetRefCommitID(pull.GetGitRefName())
if err != nil {
- log.Error("Failed to GetRefCommitID: %v, repo: %v", err, ctx.Repo.Repository.FullName())
+ ctx.ServerError("GetRefCommitID", err)
return
}
@@ -497,7 +498,6 @@ func PrepareMergedViewPullInfo(ctx *context.Context, issue *issues_model.Issue)
ctx.Data["IsPullRequestBroken"] = true
ctx.Data["BaseTarget"] = pull.BaseBranch
ctx.Data["NumCommits"] = 0
- ctx.Data["CommitIDs"] = map[string]bool{}
ctx.Data["NumFiles"] = 0
return nil
}
@@ -508,12 +508,6 @@ func PrepareMergedViewPullInfo(ctx *context.Context, issue *issues_model.Issue)
ctx.Data["NumCommits"] = len(compareInfo.Commits)
ctx.Data["NumFiles"] = compareInfo.NumFiles
- commitIDs := map[string]bool{}
- for _, commit := range compareInfo.Commits {
- commitIDs[commit.ID.String()] = true
- }
- ctx.Data["CommitIDs"] = commitIDs
-
if len(compareInfo.Commits) != 0 {
sha := compareInfo.Commits[0].ID.String()
commitStatuses, _, err := git_model.GetLatestCommitStatus(ctx, ctx.Repo.Repository.ID, sha, db.ListOptionsAll)
@@ -521,6 +515,9 @@ func PrepareMergedViewPullInfo(ctx *context.Context, issue *issues_model.Issue)
ctx.ServerError("GetLatestCommitStatus", err)
return nil
}
+ if !ctx.Repo.CanRead(unit.TypeActions) {
+ git_model.CommitStatusesHideActionsURL(ctx, commitStatuses)
+ }
if len(commitStatuses) != 0 {
ctx.Data["LatestCommitStatuses"] = commitStatuses
@@ -584,6 +581,9 @@ func PrepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C
ctx.ServerError("GetLatestCommitStatus", err)
return nil
}
+ if !ctx.Repo.CanRead(unit.TypeActions) {
+ git_model.CommitStatusesHideActionsURL(ctx, commitStatuses)
+ }
if len(commitStatuses) > 0 {
ctx.Data["LatestCommitStatuses"] = commitStatuses
@@ -597,7 +597,6 @@ func PrepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C
ctx.Data["IsPullRequestBroken"] = true
ctx.Data["BaseTarget"] = pull.BaseBranch
ctx.Data["NumCommits"] = 0
- ctx.Data["CommitIDs"] = map[string]bool{}
ctx.Data["NumFiles"] = 0
return nil
}
@@ -608,13 +607,6 @@ func PrepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C
ctx.Data["NumCommits"] = len(compareInfo.Commits)
ctx.Data["NumFiles"] = compareInfo.NumFiles
-
- commitIDs := map[string]bool{}
- for _, commit := range compareInfo.Commits {
- commitIDs[commit.ID.String()] = true
- }
- ctx.Data["CommitIDs"] = commitIDs
-
return compareInfo
}
@@ -632,7 +624,7 @@ func PrepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C
if pull.Flow == issues_model.PullRequestFlowGithub {
headBranchExist = headGitRepo.IsBranchExist(pull.HeadBranch)
} else {
- headBranchExist = baseGitRepo.IsReferenceExist(pull.GetGitRefName())
+ headBranchExist = git.IsReferenceExist(ctx, baseGitRepo.Path, pull.GetGitRefName())
}
if headBranchExist {
@@ -673,7 +665,6 @@ func PrepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C
}
ctx.Data["BaseTarget"] = pull.BaseBranch
ctx.Data["NumCommits"] = 0
- ctx.Data["CommitIDs"] = map[string]bool{}
ctx.Data["NumFiles"] = 0
return nil
}
@@ -686,6 +677,9 @@ func PrepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C
ctx.ServerError("GetLatestCommitStatus", err)
return nil
}
+ if !ctx.Repo.CanRead(unit.TypeActions) {
+ git_model.CommitStatusesHideActionsURL(ctx, commitStatuses)
+ }
if len(commitStatuses) > 0 {
ctx.Data["LatestCommitStatuses"] = commitStatuses
@@ -733,7 +727,7 @@ func PrepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C
ctx.Data["HeadBranchCommitID"] = headBranchSha
ctx.Data["PullHeadCommitID"] = sha
- if pull.HeadRepo == nil || !headBranchExist || (!pull.Issue.IsClosed && !pull.IsChecking() && (headBranchSha != sha)) {
+ if pull.HeadRepo == nil || !headBranchExist || (!pull.Issue.IsClosed && (headBranchSha != sha)) {
ctx.Data["IsPullRequestBroken"] = true
if pull.IsSameRepo() {
ctx.Data["HeadTarget"] = pull.HeadBranch
@@ -751,7 +745,6 @@ func PrepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C
ctx.Data["IsPullRequestBroken"] = true
ctx.Data["BaseTarget"] = pull.BaseBranch
ctx.Data["NumCommits"] = 0
- ctx.Data["CommitIDs"] = map[string]bool{}
ctx.Data["NumFiles"] = 0
return nil
}
@@ -776,13 +769,6 @@ func PrepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C
ctx.Data["NumCommits"] = len(compareInfo.Commits)
ctx.Data["NumFiles"] = compareInfo.NumFiles
-
- commitIDs := map[string]bool{}
- for _, commit := range compareInfo.Commits {
- commitIDs[commit.ID.String()] = true
- }
- ctx.Data["CommitIDs"] = commitIDs
-
return compareInfo
}
@@ -861,7 +847,7 @@ func ViewPullCommits(ctx *context.Context) {
ctx.Data["Username"] = ctx.Repo.Owner.Name
ctx.Data["Reponame"] = ctx.Repo.Repository.Name
- commits := git_model.ParseCommitsWithStatus(ctx, prInfo.Commits, ctx.Repo.Repository)
+ commits := processGitCommits(ctx, prInfo.Commits)
ctx.Data["Commits"] = commits
ctx.Data["CommitCount"] = len(commits)
@@ -906,7 +892,7 @@ func viewPullFiles(ctx *context.Context, specifiedStartCommit, specifiedEndCommi
foundStartCommit := len(specifiedStartCommit) == 0
foundEndCommit := len(specifiedEndCommit) == 0
- if !foundStartCommit || !foundEndCommit {
+ if !(foundStartCommit && foundEndCommit) {
for _, commit := range prInfo.Commits {
if commit.ID.String() == specifiedStartCommit {
foundStartCommit = true
@@ -921,7 +907,7 @@ func viewPullFiles(ctx *context.Context, specifiedStartCommit, specifiedEndCommi
}
}
- if !foundStartCommit || !foundEndCommit {
+ if !(foundStartCommit && foundEndCommit) {
ctx.NotFound("Given SHA1 not found for this PR", nil)
return
}
@@ -942,85 +928,7 @@ func viewPullFiles(ctx *context.Context, specifiedStartCommit, specifiedEndCommi
ctx.Data["IsShowingOnlySingleCommit"] = willShowSpecifiedCommit
- if willShowSpecifiedCommit {
- commitID := specifiedEndCommit
-
- ctx.Data["CommitID"] = commitID
-
- var prevCommit, curCommit, nextCommit *git.Commit
-
- // Iterate in reverse to properly map "previous" and "next" buttons
- for i := len(prInfo.Commits) - 1; i >= 0; i-- {
- commit := prInfo.Commits[i]
-
- if curCommit != nil {
- nextCommit = commit
- break
- }
-
- if commit.ID.String() == commitID {
- curCommit = commit
- } else {
- prevCommit = commit
- }
- }
-
- if curCommit == nil {
- ctx.ServerError("Repo.GitRepo.viewPullFiles", git.ErrNotExist{ID: commitID})
- return
- }
-
- ctx.Data["Commit"] = curCommit
- if prevCommit != nil {
- ctx.Data["PrevCommitLink"] = path.Join(ctx.Repo.RepoLink, "pulls", strconv.FormatInt(issue.Index, 10), "commits", prevCommit.ID.String())
- }
- if nextCommit != nil {
- ctx.Data["NextCommitLink"] = path.Join(ctx.Repo.RepoLink, "pulls", strconv.FormatInt(issue.Index, 10), "commits", nextCommit.ID.String())
- }
-
- statuses, _, err := git_model.GetLatestCommitStatus(ctx, ctx.Repo.Repository.ID, commitID, db.ListOptionsAll)
- if err != nil {
- log.Error("GetLatestCommitStatus: %v", err)
- }
-
- ctx.Data["CommitStatus"] = git_model.CalcCommitStatus(statuses)
- ctx.Data["CommitStatuses"] = statuses
-
- verification := asymkey_model.ParseCommitWithSignature(ctx, curCommit)
- ctx.Data["Verification"] = verification
- ctx.Data["Author"] = user_model.ValidateCommitWithEmail(ctx, curCommit)
-
- if err := asymkey_model.CalculateTrustStatus(verification, ctx.Repo.Repository.GetTrustModel(), func(user *user_model.User) (bool, error) {
- return repo_model.IsOwnerMemberCollaborator(ctx, ctx.Repo.Repository, user.ID)
- }, nil); err != nil {
- ctx.ServerError("CalculateTrustStatus", err)
- return
- }
-
- note := &git.Note{}
- err = git.GetNote(ctx, ctx.Repo.GitRepo, specifiedEndCommit, note)
- if err == nil {
- ctx.Data["NoteCommit"] = note.Commit
- ctx.Data["NoteAuthor"] = user_model.ValidateCommitWithEmail(ctx, note.Commit)
- ctx.Data["NoteRendered"], err = markup.RenderCommitMessage(&markup.RenderContext{
- Links: markup.Links{
- Base: ctx.Repo.RepoLink,
- BranchPath: path.Join("commit", util.PathEscapeSegments(commitID)),
- },
- Metas: ctx.Repo.Repository.ComposeMetas(ctx),
- GitRepo: ctx.Repo.GitRepo,
- Ctx: ctx,
- }, template.HTMLEscapeString(string(charset.ToUTF8WithFallback(note.Message, charset.ConvertOpts{}))))
- if err != nil {
- ctx.ServerError("RenderCommitMessage", err)
- return
- }
- }
-
- endCommitID = commitID
- startCommitID = prInfo.MergeBase
- ctx.Data["IsShowingAllCommits"] = false
- } else if willShowSpecifiedCommitRange {
+ if willShowSpecifiedCommit || willShowSpecifiedCommitRange {
if len(specifiedEndCommit) > 0 {
endCommitID = specifiedEndCommit
} else {
@@ -1031,7 +939,6 @@ func viewPullFiles(ctx *context.Context, specifiedStartCommit, specifiedEndCommi
} else {
startCommitID = prInfo.MergeBase
}
-
ctx.Data["IsShowingAllCommits"] = false
} else {
endCommitID = headCommitID
@@ -1039,10 +946,10 @@ func viewPullFiles(ctx *context.Context, specifiedStartCommit, specifiedEndCommi
ctx.Data["IsShowingAllCommits"] = true
}
- ctx.Data["AfterCommitID"] = endCommitID
- ctx.Data["BeforeCommitID"] = startCommitID
ctx.Data["Username"] = ctx.Repo.Owner.Name
ctx.Data["Reponame"] = ctx.Repo.Repository.Name
+ ctx.Data["AfterCommitID"] = endCommitID
+ ctx.Data["BeforeCommitID"] = startCommitID
fileOnly := ctx.FormBool("file-only")
@@ -1074,7 +981,7 @@ func viewPullFiles(ctx *context.Context, specifiedStartCommit, specifiedEndCommi
// as the viewed information is designed to be loaded only on latest PR
// diff and if you're signed in.
if !ctx.IsSigned || willShowSpecifiedCommit || willShowSpecifiedCommitRange {
- diff, err = gitdiff.GetDiffFull(ctx, gitRepo, diffOptions, files...)
+ diff, err = gitdiff.GetDiff(ctx, gitRepo, diffOptions, files...)
methodWithError = "GetDiff"
} else {
diff, err = gitdiff.SyncAndGetUserSpecificDiff(ctx, ctx.Doer.ID, pull, gitRepo, diffOptions, files...)
@@ -1146,7 +1053,7 @@ func viewPullFiles(ctx *context.Context, specifiedStartCommit, specifiedEndCommi
ctx.ServerError("GetUserRepoPermission", err)
return
}
- ctx.Data["HeadBranchIsEditable"] = pull.HeadRepo.CanEnableEditor() && issues_model.CanMaintainerWriteToBranch(ctx, headRepoPerm, pull.HeadBranch, ctx.Doer) && pull.Flow != issues_model.PullRequestFlowAGit
+ ctx.Data["HeadBranchIsEditable"] = pull.HeadRepo.CanEnableEditor() && issues_model.CanMaintainerWriteToBranch(ctx, headRepoPerm, pull.HeadBranch, ctx.Doer)
ctx.Data["SourceRepoLink"] = pull.HeadRepo.Link()
ctx.Data["HeadBranch"] = pull.HeadBranch
}
@@ -1167,13 +1074,6 @@ func viewPullFiles(ctx *context.Context, specifiedStartCommit, specifiedEndCommi
}
ctx.Data["Assignees"] = MakeSelfOnTop(ctx.Doer, assigneeUsers)
- participants := getIssueParticipants(ctx, issue)
- if ctx.Written() {
- return
- }
- ctx.Data["Participants"] = participants
- ctx.Data["NumParticipants"] = len(participants)
-
handleTeamMentions(ctx)
if ctx.Written() {
return
@@ -1307,6 +1207,8 @@ func UpdatePullRequest(ctx *context.Context) {
return
}
+ time.Sleep(1 * time.Second)
+
ctx.Flash.Success(ctx.Tr("repo.pulls.update_branch_success"))
ctx.Redirect(issue.Link())
}
@@ -1419,8 +1321,8 @@ func MergePullRequest(ctx *context.Context) {
} else if models.IsErrMergeConflicts(err) {
conflictError := err.(models.ErrMergeConflicts)
flashError, err := ctx.RenderToHTML(tplAlertDetails, map[string]any{
- "Message": ctx.Tr("repo.pulls.merge_conflict"),
- "Summary": ctx.Tr("repo.pulls.merge_conflict_summary"),
+ "Message": ctx.Tr("repo.editor.merge_conflict"),
+ "Summary": ctx.Tr("repo.editor.merge_conflict_summary"),
"Details": utils.SanitizeFlashErrorString(conflictError.StdErr) + " " + utils.SanitizeFlashErrorString(conflictError.StdOut),
})
if err != nil {
@@ -1446,10 +1348,6 @@ func MergePullRequest(ctx *context.Context) {
log.Debug("MergeUnrelatedHistories error: %v", err)
ctx.Flash.Error(ctx.Tr("repo.pulls.unrelated_histories"))
ctx.JSONRedirect(issue.Link())
- } else if models.IsErrPullRequestHasMerged(err) {
- log.Debug("MergePullRequestHasMerged error: %v", err)
- ctx.Flash.Error(ctx.Tr("repo.pulls.already_merged"))
- ctx.JSONRedirect(issue.Link())
} else if git.IsErrPushOutOfDate(err) {
log.Debug("MergePushOutOfDate error: %v", err)
ctx.Flash.Error(ctx.Tr("repo.pulls.merge_out_of_date"))
diff --git a/routers/web/repo/pull_review.go b/routers/web/repo/pull_review.go
index 941e428039..eb8dd83d9c 100644
--- a/routers/web/repo/pull_review.go
+++ b/routers/web/repo/pull_review.go
@@ -8,17 +8,17 @@ import (
"fmt"
"net/http"
- issues_model "forgejo.org/models/issues"
- pull_model "forgejo.org/models/pull"
- "forgejo.org/modules/base"
- "forgejo.org/modules/json"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/web"
- "forgejo.org/services/context"
- "forgejo.org/services/context/upload"
- "forgejo.org/services/forms"
- pull_service "forgejo.org/services/pull"
+ issues_model "code.gitea.io/gitea/models/issues"
+ pull_model "code.gitea.io/gitea/models/pull"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/web"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/context/upload"
+ "code.gitea.io/gitea/services/forms"
+ pull_service "code.gitea.io/gitea/services/pull"
)
const (
@@ -211,10 +211,9 @@ func renderConversation(ctx *context.Context, comment *issues_model.Comment, ori
return
}
ctx.Data["AfterCommitID"] = pullHeadCommitID
- switch origin {
- case "diff":
+ if origin == "diff" {
ctx.HTML(http.StatusOK, tplDiffConversation)
- case "timeline":
+ } else if origin == "timeline" {
ctx.HTML(http.StatusOK, tplTimelineConversation)
}
}
diff --git a/routers/web/repo/pull_review_test.go b/routers/web/repo/pull_review_test.go
index 14e6714a63..329e83fe4b 100644
--- a/routers/web/repo/pull_review_test.go
+++ b/routers/web/repo/pull_review_test.go
@@ -8,13 +8,13 @@ import (
"net/http/httptest"
"testing"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- "forgejo.org/models/unittest"
- "forgejo.org/modules/templates"
- "forgejo.org/services/context"
- "forgejo.org/services/contexttest"
- "forgejo.org/services/pull"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ "code.gitea.io/gitea/models/unittest"
+ "code.gitea.io/gitea/modules/templates"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/contexttest"
+ "code.gitea.io/gitea/services/pull"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
diff --git a/routers/web/repo/recent_commits.go b/routers/web/repo/recent_commits.go
index 211b1b2b12..c158fb30b6 100644
--- a/routers/web/repo/recent_commits.go
+++ b/routers/web/repo/recent_commits.go
@@ -4,10 +4,12 @@
package repo
import (
+ "errors"
"net/http"
- "forgejo.org/modules/base"
- "forgejo.org/services/context"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/services/context"
+ contributors_service "code.gitea.io/gitea/services/repository"
)
const (
@@ -24,3 +26,16 @@ func RecentCommits(ctx *context.Context) {
ctx.HTML(http.StatusOK, tplRecentCommits)
}
+
+// RecentCommitsData returns JSON of recent commits data
+func RecentCommitsData(ctx *context.Context) {
+ if contributorStats, err := contributors_service.GetContributorStats(ctx, ctx.Cache, ctx.Repo.Repository, ctx.Repo.CommitID); err != nil {
+ if errors.Is(err, contributors_service.ErrAwaitGeneration) {
+ ctx.Status(http.StatusAccepted)
+ return
+ }
+ ctx.ServerError("RecentCommitsData", err)
+ } else {
+ ctx.JSON(http.StatusOK, contributorStats["total"].Weeks)
+ }
+}
diff --git a/routers/web/repo/release.go b/routers/web/repo/release.go
index a6de337192..1791788743 100644
--- a/routers/web/repo/release.go
+++ b/routers/web/repo/release.go
@@ -1,6 +1,5 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// Copyright 2018 The Gitea Authors. All rights reserved.
-// Copyright 2025 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package repo
@@ -11,29 +10,29 @@ import (
"net/http"
"strings"
- "forgejo.org/models"
- "forgejo.org/models/asymkey"
- "forgejo.org/models/db"
- git_model "forgejo.org/models/git"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unit"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/base"
- "forgejo.org/modules/container"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/log"
- "forgejo.org/modules/markup"
- "forgejo.org/modules/markup/markdown"
- "forgejo.org/modules/optional"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/util"
- "forgejo.org/modules/web"
- "forgejo.org/routers/web/feed"
- "forgejo.org/services/context"
- "forgejo.org/services/context/upload"
- "forgejo.org/services/forms"
- releaseservice "forgejo.org/services/release"
+ "code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/models/asymkey"
+ "code.gitea.io/gitea/models/db"
+ git_model "code.gitea.io/gitea/models/git"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unit"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/container"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/markup"
+ "code.gitea.io/gitea/modules/markup/markdown"
+ "code.gitea.io/gitea/modules/optional"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/modules/web"
+ "code.gitea.io/gitea/routers/web/feed"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/context/upload"
+ "code.gitea.io/gitea/services/forms"
+ releaseservice "code.gitea.io/gitea/services/release"
)
const (
@@ -250,7 +249,7 @@ func addVerifyTagToContext(ctx *context.Context) {
if verification == nil {
return false
}
- return verification.Reason != asymkey.NotSigned
+ return verification.Reason != "gpg.error.not_signed_commit"
}
}
diff --git a/routers/web/repo/release_test.go b/routers/web/repo/release_test.go
index 785b1fdf69..5c7b6e2e8f 100644
--- a/routers/web/repo/release_test.go
+++ b/routers/web/repo/release_test.go
@@ -6,13 +6,13 @@ package repo
import (
"testing"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unit"
- "forgejo.org/models/unittest"
- "forgejo.org/modules/web"
- "forgejo.org/services/contexttest"
- "forgejo.org/services/forms"
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unit"
+ "code.gitea.io/gitea/models/unittest"
+ "code.gitea.io/gitea/modules/web"
+ "code.gitea.io/gitea/services/contexttest"
+ "code.gitea.io/gitea/services/forms"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
diff --git a/routers/web/repo/render.go b/routers/web/repo/render.go
index 05eeadc519..e64db03e20 100644
--- a/routers/web/repo/render.go
+++ b/routers/web/repo/render.go
@@ -9,13 +9,13 @@ import (
"net/http"
"path"
- "forgejo.org/modules/charset"
- "forgejo.org/modules/git"
- "forgejo.org/modules/log"
- "forgejo.org/modules/markup"
- "forgejo.org/modules/typesniffer"
- "forgejo.org/modules/util"
- "forgejo.org/services/context"
+ "code.gitea.io/gitea/modules/charset"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/markup"
+ "code.gitea.io/gitea/modules/typesniffer"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/services/context"
)
// RenderFile renders a file by repos path
@@ -41,7 +41,7 @@ func RenderFile(ctx *context.Context) {
n, _ := util.ReadAtMost(dataRc, buf)
buf = buf[:n]
- st := typesniffer.DetectContentType(buf, blob.Name())
+ st := typesniffer.DetectContentType(buf)
isTextFile := st.IsText()
rd := charset.ToUTF8WithFallbackReader(io.MultiReader(bytes.NewReader(buf), dataRc), charset.ConvertOpts{})
diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go
index 493787ad8b..2e8ca61bf5 100644
--- a/routers/web/repo/repo.go
+++ b/routers/web/repo/repo.go
@@ -12,32 +12,32 @@ import (
"slices"
"strings"
- "forgejo.org/models"
- "forgejo.org/models/db"
- git_model "forgejo.org/models/git"
- "forgejo.org/models/organization"
- access_model "forgejo.org/models/perm/access"
- quota_model "forgejo.org/models/quota"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unit"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/base"
- "forgejo.org/modules/cache"
- "forgejo.org/modules/git"
- "forgejo.org/modules/log"
- "forgejo.org/modules/optional"
- repo_module "forgejo.org/modules/repository"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/storage"
- api "forgejo.org/modules/structs"
- "forgejo.org/modules/util"
- "forgejo.org/modules/web"
- "forgejo.org/services/context"
- "forgejo.org/services/convert"
- "forgejo.org/services/forms"
- repo_service "forgejo.org/services/repository"
- archiver_service "forgejo.org/services/repository/archiver"
- commitstatus_service "forgejo.org/services/repository/commitstatus"
+ "code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/models/db"
+ git_model "code.gitea.io/gitea/models/git"
+ "code.gitea.io/gitea/models/organization"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ quota_model "code.gitea.io/gitea/models/quota"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unit"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/cache"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/optional"
+ repo_module "code.gitea.io/gitea/modules/repository"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/storage"
+ api "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/modules/web"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/convert"
+ "code.gitea.io/gitea/services/forms"
+ repo_service "code.gitea.io/gitea/services/repository"
+ archiver_service "code.gitea.io/gitea/services/repository/archiver"
+ commitstatus_service "code.gitea.io/gitea/services/repository/commitstatus"
)
const (
@@ -693,6 +693,9 @@ func SearchRepo(ctx *context.Context) {
ctx.JSON(http.StatusInternalServerError, nil)
return
}
+ if !ctx.Repo.CanRead(unit.TypeActions) {
+ git_model.CommitStatusesHideActionsURL(ctx, latestCommitStatuses)
+ }
results := make([]*repo_service.WebSearchRepository, len(repos))
for i, repo := range repos {
@@ -779,27 +782,3 @@ func PrepareBranchList(ctx *context.Context) {
}
ctx.Data["Branches"] = brs
}
-
-func SyncFork(ctx *context.Context) {
- redirectURL := fmt.Sprintf("%s/src/branch/%s", ctx.Repo.RepoLink, util.PathEscapeSegments(ctx.Repo.BranchName))
- branch := ctx.FormString("branch")
-
- syncForkInfo, err := repo_service.GetSyncForkInfo(ctx, ctx.Repo.Repository, branch)
- if err != nil {
- ctx.ServerError("GetSyncForkInfo", err)
- return
- }
-
- if !syncForkInfo.Allowed {
- ctx.Redirect(redirectURL)
- return
- }
-
- err = repo_service.SyncFork(ctx, ctx.Doer, ctx.Repo.Repository, branch)
- if err != nil {
- ctx.ServerError("SyncFork", err)
- return
- }
-
- ctx.Redirect(redirectURL)
-}
diff --git a/routers/web/repo/search.go b/routers/web/repo/search.go
index ad10542c01..d10eb67528 100644
--- a/routers/web/repo/search.go
+++ b/routers/web/repo/search.go
@@ -7,12 +7,12 @@ import (
"net/http"
"strings"
- "forgejo.org/models/db"
- "forgejo.org/modules/base"
- "forgejo.org/modules/git"
- code_indexer "forgejo.org/modules/indexer/code"
- "forgejo.org/modules/setting"
- "forgejo.org/services/context"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/git"
+ code_indexer "code.gitea.io/gitea/modules/indexer/code"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/services/context"
)
const tplSearch base.TplName = "repo/search"
@@ -165,8 +165,6 @@ func Search(ctx *context.Context) {
pager := context.NewPagination(total, setting.UI.RepoSearchPagingNum, page, 5)
pager.SetDefaultParams(ctx)
pager.AddParam(ctx, "l", "Language")
- pager.AddParam(ctx, "mode", "CodeSearchMode")
- pager.AddParam(ctx, "path", "CodeSearchPath")
ctx.Data["Page"] = pager
ctx.HTML(http.StatusOK, tplSearch)
diff --git a/routers/web/repo/setting/avatar.go b/routers/web/repo/setting/avatar.go
index 20e211316d..504f57cfc2 100644
--- a/routers/web/repo/setting/avatar.go
+++ b/routers/web/repo/setting/avatar.go
@@ -8,13 +8,13 @@ import (
"fmt"
"io"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/typesniffer"
- "forgejo.org/modules/web"
- "forgejo.org/services/context"
- "forgejo.org/services/forms"
- repo_service "forgejo.org/services/repository"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/typesniffer"
+ "code.gitea.io/gitea/modules/web"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/forms"
+ repo_service "code.gitea.io/gitea/services/repository"
)
// UpdateAvatarSetting update repo's avatar
@@ -45,8 +45,8 @@ func UpdateAvatarSetting(ctx *context.Context, form forms.AvatarForm) error {
if err != nil {
return fmt.Errorf("io.ReadAll: %w", err)
}
- st := typesniffer.DetectContentType(data, "")
- if !st.IsImage() || st.IsSvgImage() {
+ st := typesniffer.DetectContentType(data)
+ if !(st.IsImage() && !st.IsSvgImage()) {
return errors.New(ctx.Locale.TrString("settings.uploaded_avatar_not_a_image"))
}
if err = repo_service.UploadAvatar(ctx, ctxRepo, data); err != nil {
diff --git a/routers/web/repo/setting/collaboration.go b/routers/web/repo/setting/collaboration.go
index a816a16bc8..75b55151e7 100644
--- a/routers/web/repo/setting/collaboration.go
+++ b/routers/web/repo/setting/collaboration.go
@@ -8,19 +8,19 @@ import (
"net/http"
"strings"
- "forgejo.org/models/db"
- "forgejo.org/models/organization"
- "forgejo.org/models/perm"
- repo_model "forgejo.org/models/repo"
- unit_model "forgejo.org/models/unit"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/log"
- repo_module "forgejo.org/modules/repository"
- "forgejo.org/modules/setting"
- "forgejo.org/services/context"
- "forgejo.org/services/mailer"
- org_service "forgejo.org/services/org"
- repo_service "forgejo.org/services/repository"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/organization"
+ "code.gitea.io/gitea/models/perm"
+ repo_model "code.gitea.io/gitea/models/repo"
+ unit_model "code.gitea.io/gitea/models/unit"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/log"
+ repo_module "code.gitea.io/gitea/modules/repository"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/mailer"
+ org_service "code.gitea.io/gitea/services/org"
+ repo_service "code.gitea.io/gitea/services/repository"
)
// Collaboration render a repository's collaboration page
diff --git a/routers/web/repo/setting/default_branch.go b/routers/web/repo/setting/default_branch.go
index 1c6033f1e4..881d148afc 100644
--- a/routers/web/repo/setting/default_branch.go
+++ b/routers/web/repo/setting/default_branch.go
@@ -6,12 +6,12 @@ package setting
import (
"net/http"
- git_model "forgejo.org/models/git"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- "forgejo.org/routers/web/repo"
- "forgejo.org/services/context"
- repo_service "forgejo.org/services/repository"
+ git_model "code.gitea.io/gitea/models/git"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/routers/web/repo"
+ "code.gitea.io/gitea/services/context"
+ repo_service "code.gitea.io/gitea/services/repository"
)
// SetDefaultBranchPost set default branch
diff --git a/routers/web/repo/setting/deploy_key.go b/routers/web/repo/setting/deploy_key.go
index c59f0e90c2..abc3eb4af1 100644
--- a/routers/web/repo/setting/deploy_key.go
+++ b/routers/web/repo/setting/deploy_key.go
@@ -6,14 +6,14 @@ package setting
import (
"net/http"
- asymkey_model "forgejo.org/models/asymkey"
- "forgejo.org/models/db"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/web"
- asymkey_service "forgejo.org/services/asymkey"
- "forgejo.org/services/context"
- "forgejo.org/services/forms"
+ asymkey_model "code.gitea.io/gitea/models/asymkey"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/web"
+ asymkey_service "code.gitea.io/gitea/services/asymkey"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/forms"
)
// DeployKeys render the deploy keys list of a repository page
diff --git a/routers/web/repo/setting/git_hooks.go b/routers/web/repo/setting/git_hooks.go
index a50bce2a27..217a01c90c 100644
--- a/routers/web/repo/setting/git_hooks.go
+++ b/routers/web/repo/setting/git_hooks.go
@@ -6,8 +6,8 @@ package setting
import (
"net/http"
- "forgejo.org/modules/git"
- "forgejo.org/services/context"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/services/context"
)
// GitHooks hooks of a repository
diff --git a/routers/web/repo/setting/lfs.go b/routers/web/repo/setting/lfs.go
index 9930d03e8e..7e3634375a 100644
--- a/routers/web/repo/setting/lfs.go
+++ b/routers/web/repo/setting/lfs.go
@@ -14,20 +14,20 @@ import (
"strconv"
"strings"
- git_model "forgejo.org/models/git"
- "forgejo.org/modules/base"
- "forgejo.org/modules/charset"
- "forgejo.org/modules/container"
- "forgejo.org/modules/git"
- "forgejo.org/modules/git/pipeline"
- "forgejo.org/modules/lfs"
- "forgejo.org/modules/log"
- repo_module "forgejo.org/modules/repository"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/storage"
- "forgejo.org/modules/typesniffer"
- "forgejo.org/modules/util"
- "forgejo.org/services/context"
+ git_model "code.gitea.io/gitea/models/git"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/charset"
+ "code.gitea.io/gitea/modules/container"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/git/pipeline"
+ "code.gitea.io/gitea/modules/lfs"
+ "code.gitea.io/gitea/modules/log"
+ repo_module "code.gitea.io/gitea/modules/repository"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/storage"
+ "code.gitea.io/gitea/modules/typesniffer"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/services/context"
)
const (
@@ -291,7 +291,7 @@ func LFSFileGet(ctx *context.Context) {
}
buf = buf[:n]
- st := typesniffer.DetectContentType(buf, "")
+ st := typesniffer.DetectContentType(buf)
ctx.Data["IsTextFile"] = st.IsText()
isRepresentableAsText := st.IsRepresentableAsText()
@@ -342,20 +342,6 @@ func LFSFileGet(ctx *context.Context) {
ctx.Data["IsVideoFile"] = true
case st.IsAudio():
ctx.Data["IsAudioFile"] = true
- case st.Is3DModel():
- ctx.Data["Is3DModelFile"] = true
- switch {
- case st.IsGLB():
- ctx.Data["IsGLBFile"] = true
- case st.IsSTL():
- ctx.Data["IsSTLFile"] = true
- case st.IsGLTF():
- ctx.Data["IsGLTFFile"] = true
- case st.IsOBJ():
- ctx.Data["IsOBJFile"] = true
- case st.Is3MF():
- ctx.Data["Is3MFFile"] = true
- }
case st.IsImage() && (setting.UI.SVG.Enabled || !st.IsSvgImage()):
ctx.Data["IsImageFile"] = true
}
diff --git a/routers/web/repo/setting/main_test.go b/routers/web/repo/setting/main_test.go
index 6b5a70ba08..c414b853e5 100644
--- a/routers/web/repo/setting/main_test.go
+++ b/routers/web/repo/setting/main_test.go
@@ -6,7 +6,7 @@ package setting
import (
"testing"
- "forgejo.org/models/unittest"
+ "code.gitea.io/gitea/models/unittest"
)
func TestMain(m *testing.M) {
diff --git a/routers/web/repo/setting/protected_branch.go b/routers/web/repo/setting/protected_branch.go
index 18efbc37c4..b2f5798a26 100644
--- a/routers/web/repo/setting/protected_branch.go
+++ b/routers/web/repo/setting/protected_branch.go
@@ -11,17 +11,17 @@ import (
"strings"
"time"
- git_model "forgejo.org/models/git"
- "forgejo.org/models/organization"
- "forgejo.org/models/perm"
- access_model "forgejo.org/models/perm/access"
- "forgejo.org/modules/base"
- "forgejo.org/modules/web"
- "forgejo.org/routers/web/repo"
- "forgejo.org/services/context"
- "forgejo.org/services/forms"
- pull_service "forgejo.org/services/pull"
- "forgejo.org/services/repository"
+ git_model "code.gitea.io/gitea/models/git"
+ "code.gitea.io/gitea/models/organization"
+ "code.gitea.io/gitea/models/perm"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/web"
+ "code.gitea.io/gitea/routers/web/repo"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/forms"
+ pull_service "code.gitea.io/gitea/services/pull"
+ "code.gitea.io/gitea/services/repository"
"github.com/gobwas/glob"
)
diff --git a/routers/web/repo/setting/protected_tag.go b/routers/web/repo/setting/protected_tag.go
index 5735149dfd..2c25b650b9 100644
--- a/routers/web/repo/setting/protected_tag.go
+++ b/routers/web/repo/setting/protected_tag.go
@@ -8,15 +8,15 @@ import (
"net/http"
"strings"
- git_model "forgejo.org/models/git"
- "forgejo.org/models/organization"
- "forgejo.org/models/perm"
- access_model "forgejo.org/models/perm/access"
- "forgejo.org/modules/base"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/web"
- "forgejo.org/services/context"
- "forgejo.org/services/forms"
+ git_model "code.gitea.io/gitea/models/git"
+ "code.gitea.io/gitea/models/organization"
+ "code.gitea.io/gitea/models/perm"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/web"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/forms"
)
const (
diff --git a/routers/web/repo/setting/runners.go b/routers/web/repo/setting/runners.go
index 32c8667825..9dce5d13b7 100644
--- a/routers/web/repo/setting/runners.go
+++ b/routers/web/repo/setting/runners.go
@@ -8,13 +8,13 @@ import (
"net/http"
"net/url"
- actions_model "forgejo.org/models/actions"
- "forgejo.org/models/db"
- "forgejo.org/modules/base"
- "forgejo.org/modules/setting"
- actions_shared "forgejo.org/routers/web/shared/actions"
- shared_user "forgejo.org/routers/web/shared/user"
- "forgejo.org/services/context"
+ actions_model "code.gitea.io/gitea/models/actions"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/setting"
+ actions_shared "code.gitea.io/gitea/routers/web/shared/actions"
+ shared_user "code.gitea.io/gitea/routers/web/shared/user"
+ "code.gitea.io/gitea/services/context"
)
const (
diff --git a/routers/web/repo/setting/secrets.go b/routers/web/repo/setting/secrets.go
index 11c83e8bd6..d4d56bfc57 100644
--- a/routers/web/repo/setting/secrets.go
+++ b/routers/web/repo/setting/secrets.go
@@ -7,11 +7,11 @@ import (
"errors"
"net/http"
- "forgejo.org/modules/base"
- "forgejo.org/modules/setting"
- shared "forgejo.org/routers/web/shared/secrets"
- shared_user "forgejo.org/routers/web/shared/user"
- "forgejo.org/services/context"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/setting"
+ shared "code.gitea.io/gitea/routers/web/shared/secrets"
+ shared_user "code.gitea.io/gitea/routers/web/shared/user"
+ "code.gitea.io/gitea/services/context"
)
const (
diff --git a/routers/web/repo/setting/setting.go b/routers/web/repo/setting/setting.go
index 1f54ba353d..df7e388680 100644
--- a/routers/web/repo/setting/setting.go
+++ b/routers/web/repo/setting/setting.go
@@ -6,7 +6,6 @@
package setting
import (
- go_context "context"
"errors"
"fmt"
"net/http"
@@ -14,34 +13,34 @@ import (
"strings"
"time"
- "forgejo.org/models"
- "forgejo.org/models/db"
- "forgejo.org/models/organization"
- quota_model "forgejo.org/models/quota"
- repo_model "forgejo.org/models/repo"
- unit_model "forgejo.org/models/unit"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/base"
- "forgejo.org/modules/git"
- "forgejo.org/modules/indexer/code"
- "forgejo.org/modules/indexer/issues"
- "forgejo.org/modules/indexer/stats"
- "forgejo.org/modules/lfs"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/structs"
- "forgejo.org/modules/util"
- "forgejo.org/modules/validation"
- "forgejo.org/modules/web"
- actions_service "forgejo.org/services/actions"
- asymkey_service "forgejo.org/services/asymkey"
- "forgejo.org/services/context"
- "forgejo.org/services/federation"
- "forgejo.org/services/forms"
- "forgejo.org/services/migrations"
- mirror_service "forgejo.org/services/mirror"
- repo_service "forgejo.org/services/repository"
- wiki_service "forgejo.org/services/wiki"
+ "code.gitea.io/gitea/models"
+ actions_model "code.gitea.io/gitea/models/actions"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/organization"
+ quota_model "code.gitea.io/gitea/models/quota"
+ repo_model "code.gitea.io/gitea/models/repo"
+ unit_model "code.gitea.io/gitea/models/unit"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/indexer/code"
+ "code.gitea.io/gitea/modules/indexer/stats"
+ "code.gitea.io/gitea/modules/lfs"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/modules/validation"
+ "code.gitea.io/gitea/modules/web"
+ actions_service "code.gitea.io/gitea/services/actions"
+ asymkey_service "code.gitea.io/gitea/services/asymkey"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/federation"
+ "code.gitea.io/gitea/services/forms"
+ "code.gitea.io/gitea/services/migrations"
+ mirror_service "code.gitea.io/gitea/services/mirror"
+ repo_service "code.gitea.io/gitea/services/repository"
+ wiki_service "code.gitea.io/gitea/services/wiki"
)
const (
@@ -65,9 +64,6 @@ func SettingsCtxData(ctx *context.Context) {
ctx.Data["DisableNewPushMirrors"] = setting.Mirror.DisableNewPush
ctx.Data["DefaultMirrorInterval"] = setting.Mirror.DefaultInterval
ctx.Data["MinimumMirrorInterval"] = setting.Mirror.MinInterval
- ctx.Data["MaxAvatarFileSize"] = setting.Avatar.MaxFileSize
- ctx.Data["MaxAvatarWidth"] = setting.Avatar.MaxWidth
- ctx.Data["MaxAvatarHeight"] = setting.Avatar.MaxHeight
signing, _ := asymkey_service.SigningKey(ctx, ctx.Repo.Repository.RepoPath())
ctx.Data["SigningKeyAvailable"] = len(signing) > 0
@@ -109,10 +105,6 @@ func Units(ctx *context.Context) {
func UnitsPost(ctx *context.Context) {
form := web.GetForm(ctx).(*forms.RepoUnitSettingForm)
- if ctx.HasError() {
- ctx.Redirect(ctx.Repo.Repository.Link() + "/settings/units")
- return
- }
repo := ctx.Repo.Repository
@@ -154,9 +146,11 @@ func UnitsPost(ctx *context.Context) {
})
deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeWiki)
} else if form.EnableWiki && !form.EnableExternalWiki && !unit_model.TypeWiki.UnitGlobalDisabled() {
- wikiPermissions := repo_model.UnitAccessModeUnset
+ var wikiPermissions repo_model.UnitAccessMode
if form.GloballyWriteableWiki {
wikiPermissions = repo_model.UnitAccessModeWrite
+ } else {
+ wikiPermissions = repo_model.UnitAccessModeRead
}
units = append(units, repo_model.RepoUnit{
RepoID: repo.ID,
@@ -543,13 +537,7 @@ func SettingsPost(ctx *context.Context) {
mirror_service.AddPullMirrorToQueue(repo.ID)
- sanitizedOriginalURL, err := util.SanitizeURL(repo.OriginalURL)
- if err != nil {
- ctx.ServerError("SanitizeURL", err)
- return
- }
-
- ctx.Flash.Info(ctx.Tr("repo.settings.pull_mirror_sync_in_progress", sanitizedOriginalURL))
+ ctx.Flash.Info(ctx.Tr("repo.settings.pull_mirror_sync_in_progress", repo.OriginalURL))
ctx.Redirect(repo.Link() + "/settings")
case "push-mirror-sync":
@@ -596,23 +584,6 @@ func SettingsPost(ctx *context.Context) {
ctx.ServerError("UpdatePushMirrorInterval", err)
return
}
-
- if m.BranchFilter != form.PushMirrorBranchFilter {
- // replace `remote..push` in config and db
- m.BranchFilter = form.PushMirrorBranchFilter
- if err := db.WithTx(ctx, func(ctx go_context.Context) error {
- // Update the DB
- if err = repo_model.UpdatePushMirrorBranchFilter(ctx, m); err != nil {
- return err
- }
- // Update the repo config
- return mirror_service.UpdatePushMirrorBranchFilter(ctx, m)
- }); err != nil {
- ctx.ServerError("UpdatePushMirrorBranchFilter", err)
- return
- }
- }
-
// Background why we are adding it to Queue
// If we observed its implementation in the context of `push-mirror-sync` where it
// is evident that pushing to the queue is necessary for updates.
@@ -708,7 +679,6 @@ func SettingsPost(ctx *context.Context) {
SyncOnCommit: form.PushMirrorSyncOnCommit,
Interval: interval,
RemoteAddress: remoteAddress,
- BranchFilter: form.PushMirrorBranchFilter,
}
var plainPrivateKey []byte
@@ -802,8 +772,6 @@ func SettingsPost(ctx *context.Context) {
return
}
code.UpdateRepoIndexer(ctx.Repo.Repository)
- case "issues":
- issues.UpdateRepoIndexer(ctx, ctx.Repo.Repository.ID)
default:
ctx.NotFound("", nil)
return
@@ -828,9 +796,13 @@ func SettingsPost(ctx *context.Context) {
ctx.Error(http.StatusNotFound)
return
}
+ repo.IsMirror = false
- if err := repo_service.ConvertMirrorToNormalRepo(ctx, ctx.Repo.Repository); err != nil {
- ctx.ServerError("ConvertMirror", err)
+ if _, err := repo_service.CleanUpMigrateInfo(ctx, repo); err != nil {
+ ctx.ServerError("CleanUpMigrateInfo", err)
+ return
+ } else if err = repo_model.DeleteMirrorByRepoID(ctx, ctx.Repo.Repository.ID); err != nil {
+ ctx.ServerError("DeleteMirrorByRepoID", err)
return
}
log.Trace("Repository converted from mirror to regular: %s", repo.FullName())
@@ -1058,7 +1030,7 @@ func SettingsPost(ctx *context.Context) {
return
}
- if err := actions_service.CleanRepoScheduleTasks(ctx, repo, true); err != nil {
+ if err := actions_model.CleanRepoScheduleTasks(ctx, repo, true); err != nil {
log.Error("CleanRepoScheduleTasks for archived repo %s/%s: %v", ctx.Repo.Owner.Name, repo.Name, err)
}
@@ -1112,8 +1084,6 @@ func handleSettingRemoteAddrError(ctx *context.Context, err error, form *forms.R
}
case addrErr.IsInvalidPath:
ctx.RenderWithErr(ctx.Tr("repo.migrate.invalid_local_path"), tplSettingsOptions, form)
- case addrErr.HasCredentials:
- ctx.RenderWithErr(ctx.Tr("migrate.form.error.url_credentials"), tplSettingsOptions, form)
default:
ctx.ServerError("Unknown error", err)
}
diff --git a/routers/web/repo/setting/settings_test.go b/routers/web/repo/setting/settings_test.go
index 3a81b85e4c..0c8553faea 100644
--- a/routers/web/repo/setting/settings_test.go
+++ b/routers/web/repo/setting/settings_test.go
@@ -7,27 +7,41 @@ import (
"net/http"
"testing"
- asymkey_model "forgejo.org/models/asymkey"
- "forgejo.org/models/db"
- "forgejo.org/models/organization"
- "forgejo.org/models/perm"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unittest"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/test"
- "forgejo.org/modules/web"
- "forgejo.org/services/context"
- "forgejo.org/services/contexttest"
- "forgejo.org/services/forms"
- repo_service "forgejo.org/services/repository"
+ asymkey_model "code.gitea.io/gitea/models/asymkey"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/organization"
+ "code.gitea.io/gitea/models/perm"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unittest"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/web"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/contexttest"
+ "code.gitea.io/gitea/services/forms"
+ repo_service "code.gitea.io/gitea/services/repository"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
+func createSSHAuthorizedKeysTmpPath(t *testing.T) func() {
+ tmpDir := t.TempDir()
+
+ oldPath := setting.SSH.RootPath
+ setting.SSH.RootPath = tmpDir
+
+ return func() {
+ setting.SSH.RootPath = oldPath
+ }
+}
+
func TestAddReadOnlyDeployKey(t *testing.T) {
- defer test.MockVariableValue(&setting.SSH.RootPath, t.TempDir())()
+ if deferable := createSSHAuthorizedKeysTmpPath(t); deferable != nil {
+ defer deferable()
+ } else {
+ return
+ }
unittest.PrepareTestEnv(t)
ctx, _ := contexttest.MockContext(t, "user2/repo1/settings/keys")
@@ -41,7 +55,7 @@ func TestAddReadOnlyDeployKey(t *testing.T) {
}
web.SetForm(ctx, &addKeyForm)
DeployKeysPost(ctx)
- assert.Equal(t, http.StatusSeeOther, ctx.Resp.Status())
+ assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status())
unittest.AssertExistsAndLoadBean(t, &asymkey_model.DeployKey{
Name: addKeyForm.Title,
@@ -51,7 +65,11 @@ func TestAddReadOnlyDeployKey(t *testing.T) {
}
func TestAddReadWriteOnlyDeployKey(t *testing.T) {
- defer test.MockVariableValue(&setting.SSH.RootPath, t.TempDir())()
+ if deferable := createSSHAuthorizedKeysTmpPath(t); deferable != nil {
+ defer deferable()
+ } else {
+ return
+ }
unittest.PrepareTestEnv(t)
@@ -67,7 +85,7 @@ func TestAddReadWriteOnlyDeployKey(t *testing.T) {
}
web.SetForm(ctx, &addKeyForm)
DeployKeysPost(ctx)
- assert.Equal(t, http.StatusSeeOther, ctx.Resp.Status())
+ assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status())
unittest.AssertExistsAndLoadBean(t, &asymkey_model.DeployKey{
Name: addKeyForm.Title,
@@ -106,7 +124,7 @@ func TestCollaborationPost(t *testing.T) {
CollaborationPost(ctx)
- assert.Equal(t, http.StatusSeeOther, ctx.Resp.Status())
+ assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status())
exists, err := repo_model.IsCollaborator(ctx, re.ID, 4)
require.NoError(t, err)
@@ -132,7 +150,7 @@ func TestCollaborationPost_InactiveUser(t *testing.T) {
CollaborationPost(ctx)
- assert.Equal(t, http.StatusSeeOther, ctx.Resp.Status())
+ assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status())
assert.NotEmpty(t, ctx.Flash.ErrorMsg)
}
@@ -166,7 +184,7 @@ func TestCollaborationPost_AddCollaboratorTwice(t *testing.T) {
CollaborationPost(ctx)
- assert.Equal(t, http.StatusSeeOther, ctx.Resp.Status())
+ assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status())
exists, err := repo_model.IsCollaborator(ctx, re.ID, 4)
require.NoError(t, err)
@@ -175,7 +193,7 @@ func TestCollaborationPost_AddCollaboratorTwice(t *testing.T) {
// Try adding the same collaborator again
CollaborationPost(ctx)
- assert.Equal(t, http.StatusSeeOther, ctx.Resp.Status())
+ assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status())
assert.NotEmpty(t, ctx.Flash.ErrorMsg)
}
@@ -197,7 +215,7 @@ func TestCollaborationPost_NonExistentUser(t *testing.T) {
CollaborationPost(ctx)
- assert.Equal(t, http.StatusSeeOther, ctx.Resp.Status())
+ assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status())
assert.NotEmpty(t, ctx.Flash.ErrorMsg)
}
@@ -237,7 +255,7 @@ func TestAddTeamPost(t *testing.T) {
AddTeamPost(ctx)
assert.True(t, repo_service.HasRepository(db.DefaultContext, team, re.ID))
- assert.Equal(t, http.StatusSeeOther, ctx.Resp.Status())
+ assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status())
assert.Empty(t, ctx.Flash.ErrorMsg)
}
@@ -277,7 +295,7 @@ func TestAddTeamPost_NotAllowed(t *testing.T) {
AddTeamPost(ctx)
assert.False(t, repo_service.HasRepository(db.DefaultContext, team, re.ID))
- assert.Equal(t, http.StatusSeeOther, ctx.Resp.Status())
+ assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status())
assert.NotEmpty(t, ctx.Flash.ErrorMsg)
}
@@ -318,7 +336,7 @@ func TestAddTeamPost_AddTeamTwice(t *testing.T) {
AddTeamPost(ctx)
assert.True(t, repo_service.HasRepository(db.DefaultContext, team, re.ID))
- assert.Equal(t, http.StatusSeeOther, ctx.Resp.Status())
+ assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status())
assert.NotEmpty(t, ctx.Flash.ErrorMsg)
}
@@ -351,7 +369,7 @@ func TestAddTeamPost_NonExistentTeam(t *testing.T) {
ctx.Repo = repo
AddTeamPost(ctx)
- assert.Equal(t, http.StatusSeeOther, ctx.Resp.Status())
+ assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status())
assert.NotEmpty(t, ctx.Flash.ErrorMsg)
}
diff --git a/routers/web/repo/setting/variables.go b/routers/web/repo/setting/variables.go
index a83d2dea6f..4fb8c06e84 100644
--- a/routers/web/repo/setting/variables.go
+++ b/routers/web/repo/setting/variables.go
@@ -7,11 +7,11 @@ import (
"errors"
"net/http"
- "forgejo.org/modules/base"
- "forgejo.org/modules/setting"
- shared "forgejo.org/routers/web/shared/actions"
- shared_user "forgejo.org/routers/web/shared/user"
- "forgejo.org/services/context"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/setting"
+ shared "code.gitea.io/gitea/routers/web/shared/actions"
+ shared_user "code.gitea.io/gitea/routers/web/shared/user"
+ "code.gitea.io/gitea/services/context"
)
const (
diff --git a/routers/web/repo/setting/webhook.go b/routers/web/repo/setting/webhook.go
index 0caa196e25..af54997794 100644
--- a/routers/web/repo/setting/webhook.go
+++ b/routers/web/repo/setting/webhook.go
@@ -11,22 +11,22 @@ import (
"net/url"
"path"
- "forgejo.org/models/db"
- "forgejo.org/models/perm"
- access_model "forgejo.org/models/perm/access"
- user_model "forgejo.org/models/user"
- "forgejo.org/models/webhook"
- "forgejo.org/modules/base"
- "forgejo.org/modules/git"
- "forgejo.org/modules/json"
- "forgejo.org/modules/setting"
- api "forgejo.org/modules/structs"
- "forgejo.org/modules/web/middleware"
- webhook_module "forgejo.org/modules/webhook"
- "forgejo.org/services/context"
- "forgejo.org/services/convert"
- "forgejo.org/services/forms"
- webhook_service "forgejo.org/services/webhook"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/perm"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/setting"
+ api "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/web/middleware"
+ webhook_module "code.gitea.io/gitea/modules/webhook"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/convert"
+ "code.gitea.io/gitea/services/forms"
+ webhook_service "code.gitea.io/gitea/services/webhook"
"code.forgejo.org/go-chi/binding"
)
@@ -175,9 +175,6 @@ func ParseHookEvent(form forms.WebhookCoreForm) *webhook_module.HookEvent {
Wiki: form.Wiki,
Repository: form.Repository,
Package: form.Package,
- ActionRunFailure: form.ActionFailure,
- ActionRunRecover: form.ActionRecover,
- ActionRunSuccess: form.ActionSuccess,
},
BranchFilter: form.BranchFilter,
}
diff --git a/routers/web/repo/topic.go b/routers/web/repo/topic.go
index a028afb042..d81a695df9 100644
--- a/routers/web/repo/topic.go
+++ b/routers/web/repo/topic.go
@@ -7,9 +7,9 @@ import (
"net/http"
"strings"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/modules/log"
- "forgejo.org/services/context"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/services/context"
)
// TopicsPost response for creating repository
diff --git a/routers/web/repo/treelist.go b/routers/web/repo/treelist.go
index 20ea9babbe..d11af4669f 100644
--- a/routers/web/repo/treelist.go
+++ b/routers/web/repo/treelist.go
@@ -6,9 +6,9 @@ package repo
import (
"net/http"
- "forgejo.org/modules/base"
- "forgejo.org/modules/git"
- "forgejo.org/services/context"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/services/context"
"github.com/go-enry/go-enry/v2"
)
@@ -42,7 +42,7 @@ func isExcludedEntry(entry *git.TreeEntry) bool {
return true
}
- if entry.IsSubmodule() {
+ if entry.IsSubModule() {
return true
}
diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go
index 3b11d73390..9030b03a90 100644
--- a/routers/web/repo/view.go
+++ b/routers/web/repo/view.go
@@ -1,6 +1,5 @@
-// Copyright 2014 The Gogs Authors. All rights reserved.
// Copyright 2017 The Gitea Authors. All rights reserved.
-// Copyright 2023 The Forgejo Authors. All rights reserved.
+// Copyright 2014 The Gogs Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package repo
@@ -25,38 +24,37 @@ import (
_ "image/jpeg" // for processing jpeg images
_ "image/png" // for processing png images
- activities_model "forgejo.org/models/activities"
- admin_model "forgejo.org/models/admin"
- asymkey_model "forgejo.org/models/asymkey"
- "forgejo.org/models/db"
- git_model "forgejo.org/models/git"
- issue_model "forgejo.org/models/issues"
- repo_model "forgejo.org/models/repo"
- unit_model "forgejo.org/models/unit"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/actions"
- "forgejo.org/modules/base"
- "forgejo.org/modules/charset"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/highlight"
- code_indexer "forgejo.org/modules/indexer/code"
- "forgejo.org/modules/lfs"
- "forgejo.org/modules/log"
- "forgejo.org/modules/markup"
- repo_module "forgejo.org/modules/repository"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/structs"
- "forgejo.org/modules/svg"
- "forgejo.org/modules/typesniffer"
- "forgejo.org/modules/util"
- "forgejo.org/routers/web/feed"
- "forgejo.org/services/context"
- issue_service "forgejo.org/services/issue"
- repo_service "forgejo.org/services/repository"
- files_service "forgejo.org/services/repository/files"
+ activities_model "code.gitea.io/gitea/models/activities"
+ admin_model "code.gitea.io/gitea/models/admin"
+ asymkey_model "code.gitea.io/gitea/models/asymkey"
+ "code.gitea.io/gitea/models/db"
+ git_model "code.gitea.io/gitea/models/git"
+ issue_model "code.gitea.io/gitea/models/issues"
+ repo_model "code.gitea.io/gitea/models/repo"
+ unit_model "code.gitea.io/gitea/models/unit"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/actions"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/charset"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/highlight"
+ code_indexer "code.gitea.io/gitea/modules/indexer/code"
+ "code.gitea.io/gitea/modules/lfs"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/markup"
+ repo_module "code.gitea.io/gitea/modules/repository"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/svg"
+ "code.gitea.io/gitea/modules/typesniffer"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/routers/web/feed"
+ "code.gitea.io/gitea/services/context"
+ issue_service "code.gitea.io/gitea/services/issue"
+ files_service "code.gitea.io/gitea/services/repository/files"
- "code.forgejo.org/forgejo/runner/v11/act/model"
+ "github.com/nektos/act/pkg/model"
_ "golang.org/x/image/bmp" // for processing bmp images
_ "golang.org/x/image/webp" // for processing webp images
@@ -228,7 +226,7 @@ func getFileReader(ctx gocontext.Context, repoID int64, blob *git.Blob) ([]byte,
n, _ := util.ReadAtMost(dataRc, buf)
buf = buf[:n]
- st := typesniffer.DetectContentType(buf, blob.Name())
+ st := typesniffer.DetectContentType(buf)
isTextFile := st.IsText()
// FIXME: what happens when README file is an image?
@@ -262,7 +260,7 @@ func getFileReader(ctx gocontext.Context, repoID int64, blob *git.Blob) ([]byte,
}
buf = buf[:n]
- st = typesniffer.DetectContentType(buf, blob.Name())
+ st = typesniffer.DetectContentType(buf)
return buf, dataRc, &fileInfo{st.IsText(), true, meta.Size, &meta.Pointer, st}, nil
}
@@ -369,6 +367,9 @@ func loadLatestCommitData(ctx *context.Context, latestCommit *git.Commit) bool {
if err != nil {
log.Error("GetLatestCommitStatus: %v", err)
}
+ if !ctx.Repo.CanRead(unit_model.TypeActions) {
+ git_model.CommitStatusesHideActionsURL(ctx, statuses)
+ }
ctx.Data["LatestCommitStatus"] = git_model.CalcCommitStatus(statuses)
ctx.Data["LatestCommitStatuses"] = statuses
@@ -434,13 +435,13 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry) {
if err != nil {
log.Error("actions.GetContentFromEntry: %v", err)
}
- _, workFlowErr := model.ReadWorkflow(bytes.NewReader(content), true)
+ _, workFlowErr := model.ReadWorkflow(bytes.NewReader(content))
if workFlowErr != nil {
ctx.Data["FileError"] = ctx.Locale.Tr("actions.runs.invalid_workflow_helper", workFlowErr.Error())
}
- } else if slices.Contains([]string{"CODEOWNERS", "docs/CODEOWNERS", ".gitea/CODEOWNERS", ".forgejo/CODEOWNERS"}, ctx.Repo.TreePath) {
- if rc, size, err := blob.NewTruncatedReader(setting.UI.MaxDisplayFileSize); err == nil {
- _, warnings := issue_model.GetCodeOwnersFromReader(ctx, rc, size > setting.UI.MaxDisplayFileSize)
+ } else if slices.Contains([]string{"CODEOWNERS", "docs/CODEOWNERS", ".gitea/CODEOWNERS"}, ctx.Repo.TreePath) {
+ if data, err := blob.GetBlobContent(setting.UI.MaxDisplayFileSize); err == nil {
+ _, warnings := issue_model.GetCodeOwnersFromContent(ctx, data)
if len(warnings) > 0 {
ctx.Data["FileWarning"] = strings.Join(warnings, "\n")
}
@@ -624,20 +625,6 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry) {
ctx.Data["IsVideoFile"] = true
case fInfo.st.IsAudio():
ctx.Data["IsAudioFile"] = true
- case fInfo.st.Is3DModel():
- ctx.Data["Is3DModelFile"] = true
- switch {
- case fInfo.st.IsGLB():
- ctx.Data["IsGLBFile"] = true
- case fInfo.st.IsSTL():
- ctx.Data["IsSTLFile"] = true
- case fInfo.st.IsGLTF():
- ctx.Data["IsGLTFFile"] = true
- case fInfo.st.IsOBJ():
- ctx.Data["IsOBJFile"] = true
- case fInfo.st.Is3MF():
- ctx.Data["Is3MFFile"] = true
- }
case fInfo.st.IsImage() && (setting.UI.SVG.Enabled || !fInfo.st.IsSvgImage()):
ctx.Data["IsImageFile"] = true
ctx.Data["CanCopyContent"] = true
@@ -1057,14 +1044,7 @@ func renderHomeCode(ctx *context.Context) {
return
}
- if entry.IsSubmodule() {
- submodule, err := ctx.Repo.Commit.GetSubmodule(ctx.Repo.TreePath, entry)
- if err != nil {
- HandleGitError(ctx, "Repo.Commit.GetSubmodule", err)
- return
- }
- ctx.Redirect(submodule.ResolveUpstreamURL(ctx.Repo.Repository.HTMLURL()))
- } else if entry.IsDir() {
+ if entry.IsDir() {
renderDirectory(ctx)
} else {
renderFile(ctx, entry)
@@ -1166,20 +1146,6 @@ PostRecentBranchCheck:
}
}
- if ctx.Repo.Repository.IsFork && ctx.Repo.IsViewBranch && len(ctx.Repo.TreePath) == 0 && ctx.Repo.CanWriteToBranch(ctx, ctx.Doer, ctx.Repo.BranchName) {
- syncForkInfo, err := repo_service.GetSyncForkInfo(ctx, ctx.Repo.Repository, ctx.Repo.BranchName)
- if err != nil {
- ctx.ServerError("CanSync", err)
- return
- }
-
- if syncForkInfo.Allowed {
- ctx.Data["CanSyncFork"] = true
- ctx.Data["ForkCommitsBehind"] = syncForkInfo.CommitsBehind
- ctx.Data["BaseBranchLink"] = fmt.Sprintf("%s/src/branch/%s", ctx.Repo.Repository.BaseRepo.HTMLURL(), util.PathEscapeSegments(ctx.Repo.BranchName))
- }
- }
-
ctx.Data["Paths"] = paths
branchLink := ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL()
@@ -1221,7 +1187,7 @@ func checkOutdatedBranch(ctx *context.Context) {
}
if dbBranch.CommitID != commit.ID.String() {
- ctx.Flash.Warning(ctx.Tr("warning.repository.out_of_sync"), true)
+ ctx.Flash.Warning(ctx.Tr("repo.error.broken_git_hook", "https://docs.gitea.com/help/faq#push-hook--webhook--actions-arent-running"), true)
}
}
@@ -1251,7 +1217,6 @@ func RenderUserCards(ctx *context.Context, total int, getter func(opts db.ListOp
func Watchers(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("repo.watchers")
ctx.Data["CardsTitle"] = ctx.Tr("repo.watchers")
- ctx.Data["CardsNoneMsg"] = ctx.Tr("watch.list.none")
ctx.Data["PageIsWatchers"] = true
RenderUserCards(ctx, ctx.Repo.Repository.NumWatches, func(opts db.ListOptions) ([]*user_model.User, error) {
@@ -1263,7 +1228,6 @@ func Watchers(ctx *context.Context) {
func Stars(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("repo.stargazers")
ctx.Data["CardsTitle"] = ctx.Tr("repo.stargazers")
- ctx.Data["CardsNoneMsg"] = ctx.Tr("stars.list.none")
ctx.Data["PageIsStargazers"] = true
RenderUserCards(ctx, ctx.Repo.Repository.NumStars, func(opts db.ListOptions) ([]*user_model.User, error) {
return repo_model.GetStargazers(ctx, ctx.Repo.Repository, opts)
diff --git a/routers/web/repo/wiki.go b/routers/web/repo/wiki.go
index 1b5265978a..070d07cdf3 100644
--- a/routers/web/repo/wiki.go
+++ b/routers/web/repo/wiki.go
@@ -14,25 +14,25 @@ import (
"path/filepath"
"strings"
- git_model "forgejo.org/models/git"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unit"
- "forgejo.org/modules/base"
- "forgejo.org/modules/charset"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/log"
- "forgejo.org/modules/markup"
- "forgejo.org/modules/markup/markdown"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/timeutil"
- "forgejo.org/modules/util"
- "forgejo.org/modules/web"
- "forgejo.org/routers/common"
- "forgejo.org/services/context"
- "forgejo.org/services/forms"
- notify_service "forgejo.org/services/notify"
- wiki_service "forgejo.org/services/wiki"
+ git_model "code.gitea.io/gitea/models/git"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unit"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/charset"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/markup"
+ "code.gitea.io/gitea/modules/markup/markdown"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/timeutil"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/modules/web"
+ "code.gitea.io/gitea/routers/common"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/forms"
+ notify_service "code.gitea.io/gitea/services/notify"
+ wiki_service "code.gitea.io/gitea/services/wiki"
)
const (
@@ -393,7 +393,7 @@ func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry)
ctx.ServerError("CommitsByFileAndRange", err)
return nil, nil
}
- ctx.Data["Commits"] = git_model.ParseCommitsWithStatus(ctx, commitsHistory, ctx.Repo.Repository)
+ ctx.Data["Commits"] = git_model.ConvertFromGitCommit(ctx, commitsHistory, ctx.Repo.Repository)
pager := context.NewPagination(int(commitsCount), setting.Git.CommitsRangeSize, page, 5)
pager.SetDefaultParams(ctx)
diff --git a/routers/web/repo/wiki_test.go b/routers/web/repo/wiki_test.go
index 5709b32257..0c49e7d902 100644
--- a/routers/web/repo/wiki_test.go
+++ b/routers/web/repo/wiki_test.go
@@ -9,14 +9,14 @@ import (
"net/url"
"testing"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unittest"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/web"
- "forgejo.org/services/contexttest"
- "forgejo.org/services/forms"
- wiki_service "forgejo.org/services/wiki"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unittest"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/web"
+ "code.gitea.io/gitea/services/contexttest"
+ "code.gitea.io/gitea/services/forms"
+ wiki_service "code.gitea.io/gitea/services/wiki"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -73,7 +73,7 @@ func assertPagesMetas(t *testing.T, expectedNames []string, metas any) {
return
}
for i, pageMeta := range pageMetas {
- assert.Equal(t, expectedNames[i], pageMeta.Name)
+ assert.EqualValues(t, expectedNames[i], pageMeta.Name)
}
}
@@ -84,7 +84,7 @@ func TestWiki(t *testing.T) {
ctx.SetParams("*", "Home")
contexttest.LoadRepo(t, ctx, 1)
Wiki(ctx)
- assert.Equal(t, http.StatusOK, ctx.Resp.Status())
+ assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
assert.EqualValues(t, "Home", ctx.Data["Title"])
assertPagesMetas(t, []string{"Home", "Long Page", "Page With Image", "Page With Spaced Name", "Unescaped File", "XSS"}, ctx.Data["Pages"])
}
@@ -95,7 +95,7 @@ func TestWikiPages(t *testing.T) {
ctx, _ := contexttest.MockContext(t, "user2/repo1/wiki/?action=_pages")
contexttest.LoadRepo(t, ctx, 1)
WikiPages(ctx)
- assert.Equal(t, http.StatusOK, ctx.Resp.Status())
+ assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
assertPagesMetas(t, []string{"Home", "Long Page", "Page With Image", "Page With Spaced Name", "Unescaped File", "XSS"}, ctx.Data["Pages"])
}
@@ -106,7 +106,7 @@ func TestNewWiki(t *testing.T) {
contexttest.LoadUser(t, ctx, 2)
contexttest.LoadRepo(t, ctx, 1)
NewWiki(ctx)
- assert.Equal(t, http.StatusOK, ctx.Resp.Status())
+ assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
assert.EqualValues(t, ctx.Tr("repo.wiki.new_page"), ctx.Data["Title"])
}
@@ -126,7 +126,7 @@ func TestNewWikiPost(t *testing.T) {
Message: message,
})
NewWikiPost(ctx)
- assert.Equal(t, http.StatusSeeOther, ctx.Resp.Status())
+ assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status())
assertWikiExists(t, ctx.Repo.Repository, wiki_service.UserTitleToWebPath("", title))
assert.Equal(t, content, wikiContent(t, ctx.Repo.Repository, wiki_service.UserTitleToWebPath("", title)))
}
@@ -144,7 +144,7 @@ func TestNewWikiPost_ReservedName(t *testing.T) {
Message: message,
})
NewWikiPost(ctx)
- assert.Equal(t, http.StatusOK, ctx.Resp.Status())
+ assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
assert.EqualValues(t, ctx.Tr("repo.wiki.reserved_page"), ctx.Flash.ErrorMsg)
assertWikiNotExists(t, ctx.Repo.Repository, "_edit")
}
@@ -157,7 +157,7 @@ func TestEditWiki(t *testing.T) {
contexttest.LoadUser(t, ctx, 2)
contexttest.LoadRepo(t, ctx, 1)
EditWiki(ctx)
- assert.Equal(t, http.StatusOK, ctx.Resp.Status())
+ assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
assert.EqualValues(t, "Home", ctx.Data["Title"])
assert.Equal(t, wikiContent(t, ctx.Repo.Repository, "Home"), ctx.Data["content"])
}
@@ -178,7 +178,7 @@ func TestEditWikiPost(t *testing.T) {
Message: message,
})
EditWikiPost(ctx)
- assert.Equal(t, http.StatusSeeOther, ctx.Resp.Status())
+ assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status())
assertWikiExists(t, ctx.Repo.Repository, wiki_service.UserTitleToWebPath("", title))
assert.Equal(t, content, wikiContent(t, ctx.Repo.Repository, wiki_service.UserTitleToWebPath("", title)))
if title != "Home" {
@@ -194,7 +194,7 @@ func TestDeleteWikiPagePost(t *testing.T) {
contexttest.LoadUser(t, ctx, 2)
contexttest.LoadRepo(t, ctx, 1)
DeleteWikiPagePost(ctx)
- assert.Equal(t, http.StatusOK, ctx.Resp.Status())
+ assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
assertWikiNotExists(t, ctx.Repo.Repository, "Home")
}
@@ -215,10 +215,10 @@ func TestWikiRaw(t *testing.T) {
contexttest.LoadRepo(t, ctx, 1)
WikiRaw(ctx)
if filetype == "" {
- assert.Equal(t, http.StatusNotFound, ctx.Resp.Status(), "filepath: %s", filepath)
+ assert.EqualValues(t, http.StatusNotFound, ctx.Resp.Status(), "filepath: %s", filepath)
} else {
- assert.Equal(t, http.StatusOK, ctx.Resp.Status(), "filepath: %s", filepath)
- assert.Equal(t, filetype, ctx.Resp.Header().Get("Content-Type"), "filepath: %s", filepath)
+ assert.EqualValues(t, http.StatusOK, ctx.Resp.Status(), "filepath: %s", filepath)
+ assert.EqualValues(t, filetype, ctx.Resp.Header().Get("Content-Type"), "filepath: %s", filepath)
}
}
}
diff --git a/routers/web/shared/actions/fixtures/TestRunnerDetails/action_runner.yml b/routers/web/shared/actions/fixtures/TestRunnerDetails/action_runner.yml
deleted file mode 100644
index d783f83110..0000000000
--- a/routers/web/shared/actions/fixtures/TestRunnerDetails/action_runner.yml
+++ /dev/null
@@ -1,7 +0,0 @@
--
- id: 1004
- uuid: "fb857e63-c0ce-4571-a6c9-fde26c128073"
- name: "Global runner"
- owner_id: 0
- repo_id: 0
- deleted: 0
diff --git a/routers/web/shared/actions/fixtures/TestRunnerDetails/action_task.yml b/routers/web/shared/actions/fixtures/TestRunnerDetails/action_task.yml
deleted file mode 100644
index 63a2d30deb..0000000000
--- a/routers/web/shared/actions/fixtures/TestRunnerDetails/action_task.yml
+++ /dev/null
@@ -1,160 +0,0 @@
--
- id: 1
- runner_id: 1004
- token_hash: a1
--
- id: 2
- runner_id: 1004
- token_hash: a2
--
- id: 3
- runner_id: 1004
- token_hash: a3
--
- id: 4
- runner_id: 1004
- token_hash: a4
--
- id: 5
- runner_id: 1004
- token_hash: a5
--
- id: 6
- runner_id: 1004
- token_hash: a6
--
- id: 7
- runner_id: 1004
- token_hash: a7
--
- id: 8
- runner_id: 1004
- token_hash: a8
--
- id: 9
- runner_id: 1004
- token_hash: a9
--
- id: 10
- runner_id: 1004
- token_hash: a10
--
- id: 11
- runner_id: 1004
- token_hash: a11
--
- id: 12
- runner_id: 1004
- token_hash: a12
--
- id: 13
- runner_id: 1004
- token_hash: a13
--
- id: 14
- runner_id: 1004
- token_hash: a14
--
- id: 15
- runner_id: 1004
- token_hash: a15
--
- id: 16
- runner_id: 1004
- token_hash: a16
--
- id: 17
- runner_id: 1004
- token_hash: a17
--
- id: 18
- runner_id: 1004
- token_hash: a18
--
- id: 19
- runner_id: 1004
- token_hash: a19
--
- id: 20
- runner_id: 1004
- token_hash: a20
--
- id: 21
- runner_id: 1004
- token_hash: a21
--
- id: 22
- runner_id: 1004
- token_hash: a22
--
- id: 23
- runner_id: 1004
- token_hash: a23
--
- id: 24
- runner_id: 1004
- token_hash: a24
--
- id: 25
- runner_id: 1004
- token_hash: a25
--
- id: 26
- runner_id: 1004
- token_hash: a26
--
- id: 27
- runner_id: 1004
- token_hash: a27
--
- id: 28
- runner_id: 1004
- token_hash: a28
--
- id: 29
- runner_id: 1004
- token_hash: a29
--
- id: 30
- runner_id: 1004
- token_hash: a30
--
- id: 31
- runner_id: 1004
- token_hash: a31
--
- id: 32
- runner_id: 1004
- token_hash: a32
--
- id: 33
- runner_id: 1004
- token_hash: a33
--
- id: 34
- runner_id: 1004
- token_hash: a34
--
- id: 35
- runner_id: 1004
- token_hash: a35
--
- id: 36
- runner_id: 1004
- token_hash: a36
--
- id: 37
- runner_id: 1004
- token_hash: a37
--
- id: 38
- runner_id: 1004
- token_hash: a38
--
- id: 39
- runner_id: 1004
- token_hash: a39
--
- id: 40
- runner_id: 1004
- token_hash: a40
diff --git a/routers/web/shared/actions/main_test.go b/routers/web/shared/actions/main_test.go
deleted file mode 100644
index 056f48b98d..0000000000
--- a/routers/web/shared/actions/main_test.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2025 The Forgejo Authors.
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-package actions
-
-import (
- "testing"
-
- "forgejo.org/models/unittest"
-
- _ "forgejo.org/models"
- _ "forgejo.org/models/forgefed"
-)
-
-func TestMain(m *testing.M) {
- unittest.MainTest(m)
-}
diff --git a/routers/web/shared/actions/runners.go b/routers/web/shared/actions/runners.go
index 2ab6b2dadd..66dce1412b 100644
--- a/routers/web/shared/actions/runners.go
+++ b/routers/web/shared/actions/runners.go
@@ -6,13 +6,13 @@ package actions
import (
"errors"
- actions_model "forgejo.org/models/actions"
- "forgejo.org/models/db"
- "forgejo.org/modules/log"
- "forgejo.org/modules/util"
- "forgejo.org/modules/web"
- "forgejo.org/services/context"
- "forgejo.org/services/forms"
+ actions_model "code.gitea.io/gitea/models/actions"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/modules/web"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/forms"
)
// RunnersList prepares data for runners list
@@ -79,6 +79,7 @@ func RunnerDetails(ctx *context.Context, page int, runnerID, ownerID, repoID int
Page: page,
PageSize: 30,
},
+ Status: []actions_model.Status{actions_model.StatusUnknown}, // Unknown means all
RunnerID: runner.ID,
}
diff --git a/routers/web/shared/actions/runners_test.go b/routers/web/shared/actions/runners_test.go
deleted file mode 100644
index ad75d34ee6..0000000000
--- a/routers/web/shared/actions/runners_test.go
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2025 The Forgejo Authors.
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-package actions
-
-import (
- "net/http"
- "testing"
-
- actions_model "forgejo.org/models/actions"
- "forgejo.org/models/unittest"
- user_model "forgejo.org/models/user"
- "forgejo.org/services/contexttest"
-
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
-)
-
-func TestRunnerDetails(t *testing.T) {
- defer unittest.OverrideFixtures("routers/web/shared/actions/fixtures/TestRunnerDetails")()
- require.NoError(t, unittest.PrepareTestDatabase())
-
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
- runner := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunner{ID: 1004})
-
- t.Run("permission denied", func(t *testing.T) {
- ctx, resp := contexttest.MockContext(t, "/admin/actions/runners")
- RunnerDetails(ctx, 1, runner.ID, user.ID, 0)
- assert.Equal(t, http.StatusNotFound, resp.Code)
- })
-
- t.Run("first page", func(t *testing.T) {
- ctx, resp := contexttest.MockContext(t, "/admin/actions/runners")
- page := 1
- RunnerDetails(ctx, page, runner.ID, 0, 0)
- require.Equal(t, http.StatusOK, resp.Code)
- assert.Len(t, ctx.GetData()["Tasks"], 30)
- })
-
- t.Run("second and last page", func(t *testing.T) {
- ctx, resp := contexttest.MockContext(t, "/admin/actions/runners")
- page := 2
- RunnerDetails(ctx, page, runner.ID, 0, 0)
- require.Equal(t, http.StatusOK, resp.Code)
- assert.Len(t, ctx.GetData()["Tasks"], 10)
- })
-}
diff --git a/routers/web/shared/actions/variables.go b/routers/web/shared/actions/variables.go
index 13dff2f11a..47f1176f46 100644
--- a/routers/web/shared/actions/variables.go
+++ b/routers/web/shared/actions/variables.go
@@ -4,13 +4,13 @@
package actions
import (
- actions_model "forgejo.org/models/actions"
- "forgejo.org/models/db"
- "forgejo.org/modules/log"
- "forgejo.org/modules/web"
- actions_service "forgejo.org/services/actions"
- "forgejo.org/services/context"
- "forgejo.org/services/forms"
+ actions_model "code.gitea.io/gitea/models/actions"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/web"
+ actions_service "code.gitea.io/gitea/services/actions"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/forms"
)
func SetVariablesContext(ctx *context.Context, ownerID, repoID int64) {
diff --git a/routers/web/shared/packages/packages.go b/routers/web/shared/packages/packages.go
index 538c1e4b71..af960f1c0c 100644
--- a/routers/web/shared/packages/packages.go
+++ b/routers/web/shared/packages/packages.go
@@ -9,18 +9,19 @@ import (
"net/http"
"time"
- packages_model "forgejo.org/models/packages"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/base"
- "forgejo.org/modules/log"
- "forgejo.org/modules/optional"
- "forgejo.org/modules/util"
- "forgejo.org/modules/web"
- "forgejo.org/services/context"
- "forgejo.org/services/forms"
- cargo_service "forgejo.org/services/packages/cargo"
- container_service "forgejo.org/services/packages/container"
+ "code.gitea.io/gitea/models/db"
+ packages_model "code.gitea.io/gitea/models/packages"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/optional"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/modules/web"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/forms"
+ cargo_service "code.gitea.io/gitea/services/packages/cargo"
+ container_service "code.gitea.io/gitea/services/packages/container"
)
func SetPackagesContext(ctx *context.Context, owner *user_model.User) {
@@ -167,12 +168,13 @@ func SetRulePreviewContext(ctx *context.Context, owner *user_model.User) {
PackageID: p.ID,
IsInternal: optional.Some(false),
Sort: packages_model.SortCreatedDesc,
+ Paginator: db.NewAbsoluteListOptions(pcr.KeepCount, 200),
})
if err != nil {
ctx.ServerError("SearchVersions", err)
return
}
- for _, pv := range pvs[pcr.KeepCount:] {
+ for _, pv := range pvs {
if skip, err := container_service.ShouldBeSkipped(ctx, pcr, p, pv); err != nil {
ctx.ServerError("ShouldBeSkipped", err)
return
diff --git a/routers/web/shared/project/column.go b/routers/web/shared/project/column.go
index 40bb439452..599842ea9e 100644
--- a/routers/web/shared/project/column.go
+++ b/routers/web/shared/project/column.go
@@ -4,9 +4,9 @@
package project
import (
- project_model "forgejo.org/models/project"
- "forgejo.org/modules/json"
- "forgejo.org/services/context"
+ project_model "code.gitea.io/gitea/models/project"
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/services/context"
)
// MoveColumns moves or keeps columns in a project and sorts them inside that project
diff --git a/routers/web/shared/secrets/secrets.go b/routers/web/shared/secrets/secrets.go
index a853598939..3bd421f86a 100644
--- a/routers/web/shared/secrets/secrets.go
+++ b/routers/web/shared/secrets/secrets.go
@@ -4,14 +4,14 @@
package secrets
import (
- "forgejo.org/models/db"
- secret_model "forgejo.org/models/secret"
- "forgejo.org/modules/log"
- "forgejo.org/modules/util"
- "forgejo.org/modules/web"
- "forgejo.org/services/context"
- "forgejo.org/services/forms"
- secret_service "forgejo.org/services/secrets"
+ "code.gitea.io/gitea/models/db"
+ secret_model "code.gitea.io/gitea/models/secret"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/modules/web"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/forms"
+ secret_service "code.gitea.io/gitea/services/secrets"
)
func SetSecretsContext(ctx *context.Context, ownerID, repoID int64) {
diff --git a/routers/web/shared/storage_overview.go b/routers/web/shared/storage_overview.go
index fac4aa99e5..3bebdfb688 100644
--- a/routers/web/shared/storage_overview.go
+++ b/routers/web/shared/storage_overview.go
@@ -7,10 +7,10 @@ import (
"html/template"
"net/http"
- quota_model "forgejo.org/models/quota"
- "forgejo.org/modules/base"
- "forgejo.org/modules/setting"
- "forgejo.org/services/context"
+ quota_model "code.gitea.io/gitea/models/quota"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/services/context"
)
// StorageOverview render a size overview of the user, as well as relevant
diff --git a/routers/web/shared/user/header.go b/routers/web/shared/user/header.go
index 87feb966cb..fd7605c33b 100644
--- a/routers/web/shared/user/header.go
+++ b/routers/web/shared/user/header.go
@@ -7,23 +7,22 @@ package user
import (
"net/url"
- "forgejo.org/models/db"
- "forgejo.org/models/organization"
- packages_model "forgejo.org/models/packages"
- access_model "forgejo.org/models/perm/access"
- project_model "forgejo.org/models/project"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unit"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/log"
- "forgejo.org/modules/markup"
- "forgejo.org/modules/markup/markdown"
- "forgejo.org/modules/optional"
- "forgejo.org/modules/setting"
- "forgejo.org/routers/web/repo"
- "forgejo.org/services/context"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/organization"
+ packages_model "code.gitea.io/gitea/models/packages"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ project_model "code.gitea.io/gitea/models/project"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unit"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/markup"
+ "code.gitea.io/gitea/modules/markup/markdown"
+ "code.gitea.io/gitea/modules/optional"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/services/context"
)
// prepareContextForCommonProfile store some common data into context data for user's profile related pages (including the nav menu)
@@ -39,7 +38,6 @@ func prepareContextForCommonProfile(ctx *context.Context) {
func PrepareContextForProfileBigAvatar(ctx *context.Context) {
prepareContextForCommonProfile(ctx)
- ctx.Data["IsModerationEnabled"] = setting.Moderation.Enabled
ctx.Data["IsBlocked"] = ctx.Doer != nil && user_model.IsBlocked(ctx, ctx.Doer.ID, ctx.ContextUser.ID)
ctx.Data["IsFollowing"] = ctx.Doer != nil && user_model.IsFollowing(ctx, ctx.Doer.ID, ctx.ContextUser.ID)
ctx.Data["ShowUserEmail"] = setting.UI.ShowUserEmail && ctx.ContextUser.Email != "" && ctx.IsSigned && !ctx.ContextUser.KeepEmailPrivate
@@ -68,7 +66,6 @@ func PrepareContextForProfileBigAvatar(ctx *context.Context) {
showPrivate := ctx.IsSigned && (ctx.Doer.IsAdmin || ctx.Doer.ID == ctx.ContextUser.ID)
orgs, err := db.Find[organization.Organization](ctx, organization.FindOrgOptions{
UserID: ctx.ContextUser.ID,
- IncludeLimited: ctx.IsSigned,
IncludePrivate: showPrivate,
})
if err != nil {
@@ -105,22 +102,7 @@ func FindUserProfileReadme(ctx *context.Context, doer *user_model.User) (profile
if commit, err := profileGitRepo.GetBranchCommit(profileDbRepo.DefaultBranch); err != nil {
log.Error("FindUserProfileReadme failed to GetBranchCommit: %v", err)
} else {
- tree, err := commit.SubTree("")
- if err != nil {
- log.Error("FindUserProfileReadme failed to get SubTree: %v", err)
- } else {
- entries, err := tree.ListEntries()
- if err != nil {
- log.Error("FindUserProfileReadme failed to list entries: %v", err)
- } else {
- _, readmeEntry, err := repo.FindReadmeFileInEntries(ctx, entries, true)
- if err != nil {
- log.Error("FindUserProfileReadme failed to find readme in entries: %v", err)
- } else if readmeEntry != nil {
- profileReadmeBlob = readmeEntry.Blob()
- }
- }
- }
+ profileReadmeBlob, _ = commit.GetBlobByFoldedPath("README.md")
}
}
}
diff --git a/routers/web/swagger_json.go b/routers/web/swagger_json.go
index 1569600734..fc39b504a9 100644
--- a/routers/web/swagger_json.go
+++ b/routers/web/swagger_json.go
@@ -4,7 +4,7 @@
package web
import (
- "forgejo.org/services/context"
+ "code.gitea.io/gitea/services/context"
)
// SwaggerV1Json render swagger v1 json
diff --git a/routers/web/user/avatar.go b/routers/web/user/avatar.go
index 76cc342770..04f510161d 100644
--- a/routers/web/user/avatar.go
+++ b/routers/web/user/avatar.go
@@ -7,10 +7,10 @@ import (
"strings"
"time"
- "forgejo.org/models/avatars"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/httpcache"
- "forgejo.org/services/context"
+ "code.gitea.io/gitea/models/avatars"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/httpcache"
+ "code.gitea.io/gitea/services/context"
)
func cacheableRedirect(ctx *context.Context, location string) {
diff --git a/routers/web/user/code.go b/routers/web/user/code.go
index b5c5e54953..019249e3e0 100644
--- a/routers/web/user/code.go
+++ b/routers/web/user/code.go
@@ -6,13 +6,13 @@ package user
import (
"net/http"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/modules/base"
- code_indexer "forgejo.org/modules/indexer/code"
- "forgejo.org/modules/setting"
- shared_user "forgejo.org/routers/web/shared/user"
- "forgejo.org/services/context"
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/modules/base"
+ code_indexer "code.gitea.io/gitea/modules/indexer/code"
+ "code.gitea.io/gitea/modules/setting"
+ shared_user "code.gitea.io/gitea/routers/web/shared/user"
+ "code.gitea.io/gitea/services/context"
)
const (
@@ -131,7 +131,6 @@ func CodeSearch(ctx *context.Context) {
pager := context.NewPagination(total, setting.UI.RepoSearchPagingNum, page, 5)
pager.SetDefaultParams(ctx)
pager.AddParam(ctx, "l", "Language")
- pager.AddParam(ctx, "mode", "CodeSearchMode")
ctx.Data["Page"] = pager
ctx.HTML(http.StatusOK, tplUserCode)
diff --git a/routers/web/user/home.go b/routers/web/user/home.go
index d980fa393a..a0841c0227 100644
--- a/routers/web/user/home.go
+++ b/routers/web/user/home.go
@@ -13,26 +13,27 @@ import (
"strconv"
"strings"
- activities_model "forgejo.org/models/activities"
- asymkey_model "forgejo.org/models/asymkey"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- "forgejo.org/models/organization"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unit"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/base"
- "forgejo.org/modules/container"
- issue_indexer "forgejo.org/modules/indexer/issues"
- "forgejo.org/modules/log"
- "forgejo.org/modules/markup"
- "forgejo.org/modules/markup/markdown"
- "forgejo.org/modules/optional"
- "forgejo.org/modules/setting"
- "forgejo.org/routers/web/feed"
- "forgejo.org/services/context"
- issue_service "forgejo.org/services/issue"
- pull_service "forgejo.org/services/pull"
+ activities_model "code.gitea.io/gitea/models/activities"
+ asymkey_model "code.gitea.io/gitea/models/asymkey"
+ "code.gitea.io/gitea/models/db"
+ git_model "code.gitea.io/gitea/models/git"
+ issues_model "code.gitea.io/gitea/models/issues"
+ "code.gitea.io/gitea/models/organization"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unit"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/container"
+ issue_indexer "code.gitea.io/gitea/modules/indexer/issues"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/markup"
+ "code.gitea.io/gitea/modules/markup/markdown"
+ "code.gitea.io/gitea/modules/optional"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/routers/web/feed"
+ "code.gitea.io/gitea/services/context"
+ issue_service "code.gitea.io/gitea/services/issue"
+ pull_service "code.gitea.io/gitea/services/pull"
"github.com/ProtonMail/go-crypto/openpgp"
"github.com/ProtonMail/go-crypto/openpgp/armor"
@@ -610,6 +611,11 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
ctx.ServerError("GetIssuesLastCommitStatus", err)
return
}
+ if !ctx.Repo.CanRead(unit.TypeActions) {
+ for key := range commitStatuses {
+ git_model.CommitStatusesHideActionsURL(ctx, commitStatuses[key])
+ }
+ }
// -------------------------------
// Fill stats to post to ctx.Data.
@@ -649,10 +655,9 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
return 0
}
reviewTyp := issues_model.ReviewTypeApprove
- switch typ {
- case "reject":
+ if typ == "reject" {
reviewTyp = issues_model.ReviewTypeReject
- case "waiting":
+ } else if typ == "waiting" {
reviewTyp = issues_model.ReviewTypeRequest
}
for _, count := range counts {
diff --git a/routers/web/user/home_test.go b/routers/web/user/home_test.go
index f3a2f12ae6..c09f609161 100644
--- a/routers/web/user/home_test.go
+++ b/routers/web/user/home_test.go
@@ -7,14 +7,14 @@ import (
"net/http"
"testing"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unittest"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/templates"
- "forgejo.org/services/context"
- "forgejo.org/services/contexttest"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unittest"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/templates"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/contexttest"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -40,15 +40,15 @@ func TestArchivedIssues(t *testing.T) {
NumIssues[repo.ID] = repo.NumIssues
}
assert.False(t, IsArchived[50])
- assert.Equal(t, 1, NumIssues[50])
+ assert.EqualValues(t, 1, NumIssues[50])
assert.True(t, IsArchived[51])
- assert.Equal(t, 1, NumIssues[51])
+ assert.EqualValues(t, 1, NumIssues[51])
// Act
Issues(ctx)
// Assert: One Issue (ID 30) from one Repo (ID 50) is retrieved, while nothing from archived Repo 51 is retrieved
- assert.Equal(t, http.StatusOK, ctx.Resp.Status())
+ assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
assert.Len(t, ctx.Data["Issues"], 1)
}
@@ -61,7 +61,7 @@ func TestIssues(t *testing.T) {
contexttest.LoadUser(t, ctx, 2)
ctx.Req.Form.Set("state", "closed")
Issues(ctx)
- assert.Equal(t, http.StatusOK, ctx.Resp.Status())
+ assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
assert.EqualValues(t, true, ctx.Data["IsShowClosed"])
assert.Len(t, ctx.Data["Issues"], 1)
@@ -76,7 +76,7 @@ func TestPulls(t *testing.T) {
ctx.Req.Form.Set("state", "open")
ctx.Req.Form.Set("type", "your_repositories")
Pulls(ctx)
- assert.Equal(t, http.StatusOK, ctx.Resp.Status())
+ assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
assert.Len(t, ctx.Data["Issues"], 5)
}
@@ -91,15 +91,15 @@ func TestMilestones(t *testing.T) {
ctx.Req.Form.Set("state", "closed")
ctx.Req.Form.Set("sort", "furthestduedate")
Milestones(ctx)
- assert.Equal(t, http.StatusOK, ctx.Resp.Status())
+ assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
assert.EqualValues(t, map[int64]int64{1: 1}, ctx.Data["Counts"])
assert.EqualValues(t, true, ctx.Data["IsShowClosed"])
assert.EqualValues(t, "furthestduedate", ctx.Data["SortType"])
assert.EqualValues(t, 1, ctx.Data["Total"])
assert.Len(t, ctx.Data["Milestones"], 1)
assert.Len(t, ctx.Data["Repos"], 2) // both repo 42 and 1 have milestones and both are owned by user 2
- assert.Equal(t, "user2/glob", ctx.Data["Repos"].(repo_model.RepositoryList)[0].FullName())
- assert.Equal(t, "user2/repo1", ctx.Data["Repos"].(repo_model.RepositoryList)[1].FullName())
+ assert.EqualValues(t, "user2/glob", ctx.Data["Repos"].(repo_model.RepositoryList)[0].FullName())
+ assert.EqualValues(t, "user2/repo1", ctx.Data["Repos"].(repo_model.RepositoryList)[1].FullName())
}
func TestMilestonesForSpecificRepo(t *testing.T) {
@@ -113,7 +113,7 @@ func TestMilestonesForSpecificRepo(t *testing.T) {
ctx.Req.Form.Set("state", "closed")
ctx.Req.Form.Set("sort", "furthestduedate")
Milestones(ctx)
- assert.Equal(t, http.StatusOK, ctx.Resp.Status())
+ assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
assert.EqualValues(t, map[int64]int64{1: 1}, ctx.Data["Counts"])
assert.EqualValues(t, true, ctx.Data["IsShowClosed"])
assert.EqualValues(t, "furthestduedate", ctx.Data["SortType"])
@@ -144,7 +144,7 @@ func TestOrgLabels(t *testing.T) {
contexttest.LoadUser(t, ctx, 2)
contexttest.LoadOrganization(t, ctx, 3)
Issues(ctx)
- assert.Equal(t, http.StatusOK, ctx.Resp.Status())
+ assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
assert.True(t, ctx.Data["PageIsOrgIssues"].(bool))
@@ -163,9 +163,9 @@ func TestOrgLabels(t *testing.T) {
if assert.Len(t, labels, len(orgLabels)) {
for i, label := range labels {
- assert.Equal(t, orgLabels[i].OrgID, label.OrgID)
- assert.Equal(t, orgLabels[i].ID, label.ID)
- assert.Equal(t, orgLabels[i].Name, label.Name)
+ assert.EqualValues(t, orgLabels[i].OrgID, label.OrgID)
+ assert.EqualValues(t, orgLabels[i].ID, label.ID)
+ assert.EqualValues(t, orgLabels[i].Name, label.Name)
}
}
}
diff --git a/routers/web/user/main_test.go b/routers/web/user/main_test.go
index 080e3fdcfe..8b6ae69296 100644
--- a/routers/web/user/main_test.go
+++ b/routers/web/user/main_test.go
@@ -6,7 +6,7 @@ package user
import (
"testing"
- "forgejo.org/models/unittest"
+ "code.gitea.io/gitea/models/unittest"
)
func TestMain(m *testing.M) {
diff --git a/routers/web/user/notification.go b/routers/web/user/notification.go
index fdca1a2fdd..c3358dbf62 100644
--- a/routers/web/user/notification.go
+++ b/routers/web/user/notification.go
@@ -11,19 +11,21 @@ import (
"net/url"
"strings"
- activities_model "forgejo.org/models/activities"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/modules/base"
- "forgejo.org/modules/log"
- "forgejo.org/modules/optional"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/structs"
- "forgejo.org/modules/util"
- "forgejo.org/services/context"
- issue_service "forgejo.org/services/issue"
- pull_service "forgejo.org/services/pull"
+ activities_model "code.gitea.io/gitea/models/activities"
+ "code.gitea.io/gitea/models/db"
+ git_model "code.gitea.io/gitea/models/git"
+ issues_model "code.gitea.io/gitea/models/issues"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unit"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/optional"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/services/context"
+ issue_service "code.gitea.io/gitea/services/issue"
+ pull_service "code.gitea.io/gitea/services/pull"
)
const (
@@ -309,6 +311,11 @@ func NotificationSubscriptions(ctx *context.Context) {
ctx.ServerError("GetIssuesAllCommitStatus", err)
return
}
+ if !ctx.Repo.CanRead(unit.TypeActions) {
+ for key := range commitStatuses {
+ git_model.CommitStatusesHideActionsURL(ctx, commitStatuses[key])
+ }
+ }
ctx.Data["CommitLastStatus"] = lastStatus
ctx.Data["CommitStatuses"] = commitStatuses
ctx.Data["Issues"] = issues
@@ -333,10 +340,9 @@ func NotificationSubscriptions(ctx *context.Context) {
return 0
}
reviewTyp := issues_model.ReviewTypeApprove
- switch typ {
- case "reject":
+ if typ == "reject" {
reviewTyp = issues_model.ReviewTypeReject
- case "waiting":
+ } else if typ == "waiting" {
reviewTyp = issues_model.ReviewTypeRequest
}
for _, count := range counts {
diff --git a/routers/web/user/package.go b/routers/web/user/package.go
index 2862c6684b..70ea20d388 100644
--- a/routers/web/user/package.go
+++ b/routers/web/user/package.go
@@ -8,28 +8,28 @@ import (
"net/http"
"slices"
- "forgejo.org/models/db"
- org_model "forgejo.org/models/organization"
- packages_model "forgejo.org/models/packages"
- container_model "forgejo.org/models/packages/container"
- "forgejo.org/models/perm"
- access_model "forgejo.org/models/perm/access"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/modules/base"
- "forgejo.org/modules/container"
- "forgejo.org/modules/log"
- "forgejo.org/modules/optional"
- alpine_module "forgejo.org/modules/packages/alpine"
- arch_model "forgejo.org/modules/packages/arch"
- debian_module "forgejo.org/modules/packages/debian"
- rpm_module "forgejo.org/modules/packages/rpm"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/web"
- packages_helper "forgejo.org/routers/api/packages/helper"
- shared_user "forgejo.org/routers/web/shared/user"
- "forgejo.org/services/context"
- "forgejo.org/services/forms"
- packages_service "forgejo.org/services/packages"
+ "code.gitea.io/gitea/models/db"
+ org_model "code.gitea.io/gitea/models/organization"
+ packages_model "code.gitea.io/gitea/models/packages"
+ container_model "code.gitea.io/gitea/models/packages/container"
+ "code.gitea.io/gitea/models/perm"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/container"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/optional"
+ alpine_module "code.gitea.io/gitea/modules/packages/alpine"
+ arch_model "code.gitea.io/gitea/modules/packages/arch"
+ debian_module "code.gitea.io/gitea/modules/packages/debian"
+ rpm_module "code.gitea.io/gitea/modules/packages/rpm"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/web"
+ packages_helper "code.gitea.io/gitea/routers/api/packages/helper"
+ shared_user "code.gitea.io/gitea/routers/web/shared/user"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/forms"
+ packages_service "code.gitea.io/gitea/services/packages"
)
const (
diff --git a/routers/web/user/profile.go b/routers/web/user/profile.go
index 02cea05a47..de1c6850aa 100644
--- a/routers/web/user/profile.go
+++ b/routers/web/user/profile.go
@@ -1,6 +1,5 @@
// Copyright 2015 The Gogs Authors. All rights reserved.
// Copyright 2019 The Gitea Authors. All rights reserved.
-// Copyright 2023 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package user
@@ -8,29 +7,27 @@ package user
import (
"errors"
"fmt"
- gotemplate "html/template"
- "io"
"net/http"
"path"
"strings"
- activities_model "forgejo.org/models/activities"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/base"
- "forgejo.org/modules/git"
- "forgejo.org/modules/log"
- "forgejo.org/modules/markup"
- "forgejo.org/modules/markup/markdown"
- "forgejo.org/modules/optional"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/util"
- "forgejo.org/routers/web/feed"
- "forgejo.org/routers/web/org"
- shared_user "forgejo.org/routers/web/shared/user"
- "forgejo.org/services/context"
- user_service "forgejo.org/services/user"
+ activities_model "code.gitea.io/gitea/models/activities"
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/markup"
+ "code.gitea.io/gitea/modules/markup/markdown"
+ "code.gitea.io/gitea/modules/optional"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/routers/web/feed"
+ "code.gitea.io/gitea/routers/web/org"
+ shared_user "code.gitea.io/gitea/routers/web/shared/user"
+ "code.gitea.io/gitea/services/context"
+ user_service "code.gitea.io/gitea/services/user"
)
const (
@@ -72,6 +69,17 @@ func userProfile(ctx *context.Context) {
ctx.Data["OpenGraphURL"] = ctx.ContextUser.HTMLURL()
ctx.Data["OpenGraphDescription"] = ctx.ContextUser.Description
+ // prepare heatmap data
+ if setting.Service.EnableUserHeatmap {
+ data, err := activities_model.GetUserHeatmapDataByUser(ctx, ctx.ContextUser, ctx.Doer)
+ if err != nil {
+ ctx.ServerError("GetUserHeatmapDataByUser", err)
+ return
+ }
+ ctx.Data["HeatmapData"] = data
+ ctx.Data["HeatmapTotalContributions"] = activities_model.GetTotalContributionsInHeatmap(data)
+ }
+
profileDbRepo, profileGitRepo, profileReadmeBlob, profileClose := shared_user.FindUserProfileReadme(ctx, ctx.Doer)
defer profileClose()
@@ -162,32 +170,11 @@ func prepareUserProfileTabData(ctx *context.Context, showPrivate bool, profileDb
ctx.Data["Cards"] = followers
total = int(numFollowers)
ctx.Data["CardsTitle"] = ctx.TrN(total, "user.followers.title.one", "user.followers.title.few")
- if ctx.IsSigned && ctx.ContextUser.ID == ctx.Doer.ID {
- ctx.Data["CardsNoneMsg"] = ctx.Tr("followers.incoming.list.self.none")
- } else {
- ctx.Data["CardsNoneMsg"] = ctx.Tr("followers.incoming.list.none")
- }
case "following":
ctx.Data["Cards"] = following
total = int(numFollowing)
ctx.Data["CardsTitle"] = ctx.TrN(total, "user.following.title.one", "user.following.title.few")
- if ctx.IsSigned && ctx.ContextUser.ID == ctx.Doer.ID {
- ctx.Data["CardsNoneMsg"] = ctx.Tr("followers.outgoing.list.self.none")
- } else {
- ctx.Data["CardsNoneMsg"] = ctx.Tr("followers.outgoing.list.none", ctx.ContextUser.Name)
- }
case "activity":
- // prepare heatmap data
- if setting.Service.EnableUserHeatmap {
- data, err := activities_model.GetUserHeatmapDataByUser(ctx, ctx.ContextUser, ctx.Doer)
- if err != nil {
- ctx.ServerError("GetUserHeatmapDataByUser", err)
- return
- }
- ctx.Data["HeatmapData"] = data
- ctx.Data["HeatmapTotalContributions"] = activities_model.GetTotalContributionsInHeatmap(data)
- }
-
date := ctx.FormString("date")
pagingNum = setting.UI.FeedPagingNum
items, count, err := activities_model.GetFeeds(ctx, activities_model.GetFeedsOptions{
@@ -266,38 +253,26 @@ func prepareUserProfileTabData(ctx *context.Context, showPrivate bool, profileDb
total = int(count)
case "overview":
- if rc, _, err := profileReadme.NewTruncatedReader(setting.UI.MaxDisplayFileSize); err != nil {
- log.Error("failed to NewTruncatedReader: %v", err)
+ if bytes, err := profileReadme.GetBlobContent(setting.UI.MaxDisplayFileSize); err != nil {
+ log.Error("failed to GetBlobContent: %v", err)
} else {
- defer rc.Close()
-
- if markupType := markup.Type(profileReadme.Name()); markupType != "" {
- if profileContent, err := markdown.RenderReader(&markup.RenderContext{
- Ctx: ctx,
- Type: markupType,
- GitRepo: profileGitRepo,
- Links: markup.Links{
- // Give the repo link to the markdown render for the full link of media element.
- // the media link usually be like /[user]/[repoName]/media/branch/[branchName],
- // Eg. /Tom/.profile/media/branch/main
- // The branch shown on the profile page is the default branch, this need to be in sync with doc, see:
- // https://docs.gitea.com/usage/profile-readme
- Base: profileDbRepo.Link(),
- BranchPath: path.Join("branch", util.PathEscapeSegments(profileDbRepo.DefaultBranch)),
- },
- Metas: map[string]string{"mode": "document"},
- }, rc); err != nil {
- log.Error("failed to RenderString: %v", err)
- } else {
- ctx.Data["ProfileReadme"] = profileContent
- }
+ if profileContent, err := markdown.RenderString(&markup.RenderContext{
+ Ctx: ctx,
+ GitRepo: profileGitRepo,
+ Links: markup.Links{
+ // Give the repo link to the markdown render for the full link of media element.
+ // the media link usually be like /[user]/[repoName]/media/branch/[branchName],
+ // Eg. /Tom/.profile/media/branch/main
+ // The branch shown on the profile page is the default branch, this need to be in sync with doc, see:
+ // https://docs.gitea.com/usage/profile-readme
+ Base: profileDbRepo.Link(),
+ BranchPath: path.Join("branch", util.PathEscapeSegments(profileDbRepo.DefaultBranch)),
+ },
+ Metas: map[string]string{"mode": "document"},
+ }, bytes); err != nil {
+ log.Error("failed to RenderString: %v", err)
} else {
- content, err := io.ReadAll(rc)
- if err != nil {
- log.Error("Read readme content failed: %v", err)
- }
- ctx.Data["ProfileReadme"] = gotemplate.HTMLEscapeString(util.UnsafeBytesToString(content))
- ctx.Data["IsProfileReadmePlain"] = true
+ ctx.Data["ProfileReadme"] = profileContent
}
}
default: // default to "repositories"
diff --git a/routers/web/user/search.go b/routers/web/user/search.go
index 411a356d9b..be5eee90a9 100644
--- a/routers/web/user/search.go
+++ b/routers/web/user/search.go
@@ -6,12 +6,12 @@ package user
import (
"net/http"
- "forgejo.org/models/db"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/optional"
- "forgejo.org/modules/setting"
- "forgejo.org/services/context"
- "forgejo.org/services/convert"
+ "code.gitea.io/gitea/models/db"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/optional"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/convert"
)
// SearchCandidates searches candidate users for dropdown list
diff --git a/routers/web/user/setting/account.go b/routers/web/user/setting/account.go
index 1dfcc90e35..6f40e39c8d 100644
--- a/routers/web/user/setting/account.go
+++ b/routers/web/user/setting/account.go
@@ -9,23 +9,23 @@ import (
"net/http"
"time"
- "forgejo.org/models"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/auth/password"
- "forgejo.org/modules/base"
- "forgejo.org/modules/log"
- "forgejo.org/modules/optional"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/timeutil"
- "forgejo.org/modules/validation"
- "forgejo.org/modules/web"
- "forgejo.org/services/auth"
- "forgejo.org/services/auth/source/db"
- "forgejo.org/services/auth/source/smtp"
- "forgejo.org/services/context"
- "forgejo.org/services/forms"
- "forgejo.org/services/mailer"
- "forgejo.org/services/user"
+ "code.gitea.io/gitea/models"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/auth/password"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/optional"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/timeutil"
+ "code.gitea.io/gitea/modules/validation"
+ "code.gitea.io/gitea/modules/web"
+ "code.gitea.io/gitea/services/auth"
+ "code.gitea.io/gitea/services/auth/source/db"
+ "code.gitea.io/gitea/services/auth/source/smtp"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/forms"
+ "code.gitea.io/gitea/services/mailer"
+ "code.gitea.io/gitea/services/user"
)
const (
@@ -57,7 +57,7 @@ func AccountPost(ctx *context.Context) {
return
}
- if ctx.Doer.IsPasswordSet() && !ctx.Doer.ValidatePassword(ctx, form.OldPassword) {
+ if ctx.Doer.IsPasswordSet() && !ctx.Doer.ValidatePassword(form.OldPassword) {
ctx.Flash.Error(ctx.Tr("settings.password_incorrect"))
} else if form.Password != form.Retype {
ctx.Flash.Error(ctx.Tr("form.password_not_match"))
@@ -178,10 +178,10 @@ func EmailPost(ctx *context.Context) {
// Set Email Notification Preference
if ctx.FormString("_method") == "NOTIFICATION" {
preference := ctx.FormString("preference")
- if preference != user_model.EmailNotificationsEnabled &&
- preference != user_model.EmailNotificationsOnMention &&
- preference != user_model.EmailNotificationsDisabled &&
- preference != user_model.EmailNotificationsAndYourOwn {
+ if !(preference == user_model.EmailNotificationsEnabled ||
+ preference == user_model.EmailNotificationsOnMention ||
+ preference == user_model.EmailNotificationsDisabled ||
+ preference == user_model.EmailNotificationsAndYourOwn) {
log.Error("Email notifications preference change returned unrecognized option %s: %s", preference, ctx.Doer.Name)
ctx.ServerError("SetEmailPreference", errors.New("option unrecognized"))
return
@@ -212,7 +212,7 @@ func EmailPost(ctx *context.Context) {
loadAccountData(ctx)
ctx.RenderWithErr(ctx.Tr("form.email_been_used"), tplSettingsAccount, &form)
- } else if validation.IsErrEmailInvalid(err) {
+ } else if validation.IsErrEmailCharIsNotSupported(err) || validation.IsErrEmailInvalid(err) {
loadAccountData(ctx)
ctx.RenderWithErr(ctx.Tr("form.email_invalid"), tplSettingsAccount, &form)
diff --git a/routers/web/user/setting/account_test.go b/routers/web/user/setting/account_test.go
index 3f7e1c13bc..9fdc5e4d53 100644
--- a/routers/web/user/setting/account_test.go
+++ b/routers/web/user/setting/account_test.go
@@ -7,11 +7,11 @@ import (
"net/http"
"testing"
- "forgejo.org/models/unittest"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/web"
- "forgejo.org/services/contexttest"
- "forgejo.org/services/forms"
+ "code.gitea.io/gitea/models/unittest"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/web"
+ "code.gitea.io/gitea/services/contexttest"
+ "code.gitea.io/gitea/services/forms"
"github.com/stretchr/testify/assert"
)
@@ -95,7 +95,7 @@ func TestChangePassword(t *testing.T) {
AccountPost(ctx)
assert.Contains(t, ctx.Flash.ErrorMsg, req.Message)
- assert.Equal(t, http.StatusSeeOther, ctx.Resp.Status())
+ assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status())
})
}
}
diff --git a/routers/web/user/setting/adopt.go b/routers/web/user/setting/adopt.go
index 59ff31162b..171c1933d4 100644
--- a/routers/web/user/setting/adopt.go
+++ b/routers/web/user/setting/adopt.go
@@ -6,18 +6,22 @@ package setting
import (
"path/filepath"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/util"
- "forgejo.org/services/context"
- repo_service "forgejo.org/services/repository"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/services/context"
+ repo_service "code.gitea.io/gitea/services/repository"
)
// AdoptOrDeleteRepository adopts or deletes a repository
func AdoptOrDeleteRepository(ctx *context.Context) {
+ ctx.Data["Title"] = ctx.Tr("settings.adopt")
+ ctx.Data["PageIsSettingsRepos"] = true
allowAdopt := ctx.IsUserSiteAdmin() || setting.Repository.AllowAdoptionOfUnadoptedRepositories
+ ctx.Data["allowAdopt"] = allowAdopt
allowDelete := ctx.IsUserSiteAdmin() || setting.Repository.AllowDeleteOfUnadoptedRepositories
+ ctx.Data["allowDelete"] = allowDelete
dir := ctx.FormString("id")
action := ctx.FormString("action")
diff --git a/routers/web/user/setting/applications.go b/routers/web/user/setting/applications.go
index e73239b79b..4dfd859a44 100644
--- a/routers/web/user/setting/applications.go
+++ b/routers/web/user/setting/applications.go
@@ -7,14 +7,14 @@ package setting
import (
"net/http"
- auth_model "forgejo.org/models/auth"
- "forgejo.org/models/db"
- "forgejo.org/modules/base"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/web"
- "forgejo.org/services/context"
- "forgejo.org/services/forms"
+ auth_model "code.gitea.io/gitea/models/auth"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/web"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/forms"
)
const (
@@ -49,9 +49,6 @@ func ApplicationsPost(ctx *context.Context) {
ctx.ServerError("GetScope", err)
return
}
- if !scope.HasPermissionScope() {
- ctx.Flash.Error(ctx.Tr("settings.at_least_one_permission"), true)
- }
t := &auth_model.AccessToken{
UID: ctx.Doer.ID,
Name: form.Name,
diff --git a/routers/web/user/setting/blocked_users.go b/routers/web/user/setting/blocked_users.go
index 1448dc9a3c..3f35b2eadf 100644
--- a/routers/web/user/setting/blocked_users.go
+++ b/routers/web/user/setting/blocked_users.go
@@ -6,11 +6,11 @@ package setting
import (
"net/http"
- "forgejo.org/models/db"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/base"
- "forgejo.org/modules/setting"
- "forgejo.org/services/context"
+ "code.gitea.io/gitea/models/db"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/services/context"
)
const (
diff --git a/routers/web/user/setting/keys.go b/routers/web/user/setting/keys.go
index 935efd7ba7..9462be71c2 100644
--- a/routers/web/user/setting/keys.go
+++ b/routers/web/user/setting/keys.go
@@ -5,18 +5,18 @@
package setting
import (
- "errors"
+ "fmt"
"net/http"
- asymkey_model "forgejo.org/models/asymkey"
- "forgejo.org/models/db"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/base"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/web"
- asymkey_service "forgejo.org/services/asymkey"
- "forgejo.org/services/context"
- "forgejo.org/services/forms"
+ asymkey_model "code.gitea.io/gitea/models/asymkey"
+ "code.gitea.io/gitea/models/db"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/web"
+ asymkey_service "code.gitea.io/gitea/services/asymkey"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/forms"
)
const (
@@ -80,7 +80,7 @@ func KeysPost(ctx *context.Context) {
ctx.Redirect(setting.AppSubURL + "/user/settings/keys")
case "gpg":
if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageGPGKeys) {
- ctx.NotFound("Not Found", errors.New("gpg keys setting is not allowed to be visited"))
+ ctx.NotFound("Not Found", fmt.Errorf("gpg keys setting is not allowed to be visited"))
return
}
@@ -161,7 +161,7 @@ func KeysPost(ctx *context.Context) {
ctx.Redirect(setting.AppSubURL + "/user/settings/keys")
case "ssh":
if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageSSHKeys) {
- ctx.NotFound("Not Found", errors.New("ssh keys setting is not allowed to be visited"))
+ ctx.NotFound("Not Found", fmt.Errorf("ssh keys setting is not allowed to be visited"))
return
}
@@ -205,7 +205,7 @@ func KeysPost(ctx *context.Context) {
ctx.Redirect(setting.AppSubURL + "/user/settings/keys")
case "verify_ssh":
if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageSSHKeys) {
- ctx.NotFound("Not Found", errors.New("ssh keys setting is not allowed to be visited"))
+ ctx.NotFound("Not Found", fmt.Errorf("ssh keys setting is not allowed to be visited"))
return
}
@@ -242,7 +242,7 @@ func DeleteKey(ctx *context.Context) {
switch ctx.FormString("type") {
case "gpg":
if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageGPGKeys) {
- ctx.NotFound("Not Found", errors.New("gpg keys setting is not allowed to be visited"))
+ ctx.NotFound("Not Found", fmt.Errorf("gpg keys setting is not allowed to be visited"))
return
}
if err := asymkey_model.DeleteGPGKey(ctx, ctx.Doer, ctx.FormInt64("id")); err != nil {
@@ -252,7 +252,7 @@ func DeleteKey(ctx *context.Context) {
}
case "ssh":
if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageSSHKeys) {
- ctx.NotFound("Not Found", errors.New("ssh keys setting is not allowed to be visited"))
+ ctx.NotFound("Not Found", fmt.Errorf("ssh keys setting is not allowed to be visited"))
return
}
diff --git a/routers/web/user/setting/main_test.go b/routers/web/user/setting/main_test.go
index 38ac2842dd..e398208d0d 100644
--- a/routers/web/user/setting/main_test.go
+++ b/routers/web/user/setting/main_test.go
@@ -6,7 +6,7 @@ package setting
import (
"testing"
- "forgejo.org/models/unittest"
+ "code.gitea.io/gitea/models/unittest"
)
func TestMain(m *testing.M) {
diff --git a/routers/web/user/setting/oauth2.go b/routers/web/user/setting/oauth2.go
index 64b252e97f..1f485e06c8 100644
--- a/routers/web/user/setting/oauth2.go
+++ b/routers/web/user/setting/oauth2.go
@@ -4,9 +4,9 @@
package setting
import (
- "forgejo.org/modules/base"
- "forgejo.org/modules/setting"
- "forgejo.org/services/context"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/services/context"
)
const (
diff --git a/routers/web/user/setting/oauth2_common.go b/routers/web/user/setting/oauth2_common.go
index 7449e45216..2132d127b8 100644
--- a/routers/web/user/setting/oauth2_common.go
+++ b/routers/web/user/setting/oauth2_common.go
@@ -7,13 +7,13 @@ import (
"fmt"
"net/http"
- "forgejo.org/models/auth"
- "forgejo.org/modules/base"
- "forgejo.org/modules/util"
- "forgejo.org/modules/web"
- shared_user "forgejo.org/routers/web/shared/user"
- "forgejo.org/services/context"
- "forgejo.org/services/forms"
+ "code.gitea.io/gitea/models/auth"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/modules/web"
+ shared_user "code.gitea.io/gitea/routers/web/shared/user"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/forms"
)
type OAuth2CommonHandlers struct {
diff --git a/routers/web/user/setting/packages.go b/routers/web/user/setting/packages.go
index ba739a03fc..4132659495 100644
--- a/routers/web/user/setting/packages.go
+++ b/routers/web/user/setting/packages.go
@@ -7,13 +7,13 @@ import (
"net/http"
"strings"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/base"
- chef_module "forgejo.org/modules/packages/chef"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/util"
- shared "forgejo.org/routers/web/shared/packages"
- "forgejo.org/services/context"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/base"
+ chef_module "code.gitea.io/gitea/modules/packages/chef"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/util"
+ shared "code.gitea.io/gitea/routers/web/shared/packages"
+ "code.gitea.io/gitea/services/context"
)
const (
diff --git a/routers/web/user/setting/profile.go b/routers/web/user/setting/profile.go
index e0ce88b582..271621872f 100644
--- a/routers/web/user/setting/profile.go
+++ b/routers/web/user/setting/profile.go
@@ -15,23 +15,23 @@ import (
"strings"
"time"
- "forgejo.org/models/avatars"
- "forgejo.org/models/db"
- "forgejo.org/models/organization"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/base"
- "forgejo.org/modules/log"
- "forgejo.org/modules/optional"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/translation"
- "forgejo.org/modules/typesniffer"
- "forgejo.org/modules/util"
- "forgejo.org/modules/web"
- "forgejo.org/modules/web/middleware"
- "forgejo.org/services/context"
- "forgejo.org/services/forms"
- user_service "forgejo.org/services/user"
+ "code.gitea.io/gitea/models/avatars"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/organization"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/optional"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/translation"
+ "code.gitea.io/gitea/modules/typesniffer"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/modules/web"
+ "code.gitea.io/gitea/modules/web/middleware"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/forms"
+ user_service "code.gitea.io/gitea/services/user"
)
const (
@@ -51,9 +51,6 @@ func Profile(ctx *context.Context) {
ctx.Data["DisableGravatar"] = setting.Config().Picture.DisableGravatar.Value(ctx)
ctx.Data["CooldownPeriod"] = setting.Service.UsernameCooldownPeriod
ctx.Data["CommonPronouns"] = commonPronouns
- ctx.Data["MaxAvatarFileSize"] = setting.Avatar.MaxFileSize
- ctx.Data["MaxAvatarWidth"] = setting.Avatar.MaxWidth
- ctx.Data["MaxAvatarHeight"] = setting.Avatar.MaxHeight
ctx.HTML(http.StatusOK, tplSettingsProfile)
}
@@ -66,9 +63,6 @@ func ProfilePost(ctx *context.Context) {
ctx.Data["DisableGravatar"] = setting.Config().Picture.DisableGravatar.Value(ctx)
ctx.Data["CooldownPeriod"] = setting.Service.UsernameCooldownPeriod
ctx.Data["CommonPronouns"] = commonPronouns
- ctx.Data["MaxAvatarFileSize"] = setting.Avatar.MaxFileSize
- ctx.Data["MaxAvatarWidth"] = setting.Avatar.MaxWidth
- ctx.Data["MaxAvatarHeight"] = setting.Avatar.MaxHeight
if ctx.HasError() {
ctx.HTML(http.StatusOK, tplSettingsProfile)
@@ -151,8 +145,8 @@ func UpdateAvatarSetting(ctx *context.Context, form *forms.AvatarForm, ctxUser *
return fmt.Errorf("io.ReadAll: %w", err)
}
- st := typesniffer.DetectContentType(data, "")
- if !st.IsImage() || st.IsSvgImage() {
+ st := typesniffer.DetectContentType(data)
+ if !(st.IsImage() && !st.IsSvgImage()) {
return errors.New(ctx.Locale.TrString("settings.uploaded_avatar_not_a_image"))
}
if err = user_service.UploadAvatar(ctx, ctxUser, data); err != nil {
diff --git a/routers/web/user/setting/runner.go b/routers/web/user/setting/runner.go
index 5c8bba82a1..2bb10cceb9 100644
--- a/routers/web/user/setting/runner.go
+++ b/routers/web/user/setting/runner.go
@@ -4,8 +4,8 @@
package setting
import (
- "forgejo.org/modules/setting"
- "forgejo.org/services/context"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/services/context"
)
func RedirectToDefaultSetting(ctx *context.Context) {
diff --git a/routers/web/user/setting/security/2fa.go b/routers/web/user/setting/security/2fa.go
index d23917f8b2..37ccb5e5c4 100644
--- a/routers/web/user/setting/security/2fa.go
+++ b/routers/web/user/setting/security/2fa.go
@@ -12,13 +12,13 @@ import (
"net/http"
"strings"
- "forgejo.org/models/auth"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/web"
- "forgejo.org/services/context"
- "forgejo.org/services/forms"
- "forgejo.org/services/mailer"
+ "code.gitea.io/gitea/models/auth"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/web"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/forms"
+ "code.gitea.io/gitea/services/mailer"
"github.com/pquerna/otp"
"github.com/pquerna/otp/totp"
@@ -40,7 +40,11 @@ func RegenerateScratchTwoFactor(ctx *context.Context) {
return
}
- token := t.GenerateScratchToken()
+ token, err := t.GenerateScratchToken()
+ if err != nil {
+ ctx.ServerError("SettingsTwoFactor: Failed to GenerateScratchToken", err)
+ return
+ }
if err = auth.UpdateTwoFactor(ctx, t); err != nil {
ctx.ServerError("SettingsTwoFactor: Failed to UpdateTwoFactor", err)
@@ -56,21 +60,6 @@ func DisableTwoFactor(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("settings")
ctx.Data["PageIsSettingsSecurity"] = true
- if ctx.Doer.MustHaveTwoFactor() {
- ctx.NotFound("DisableTwoFactor", nil)
- return
- }
-
- disableTwoFactor(ctx)
- if ctx.Written() {
- return
- }
-
- ctx.Flash.Success(ctx.Tr("settings.twofa_disabled"))
- ctx.Redirect(setting.AppSubURL + "/user/settings/security")
-}
-
-func disableTwoFactor(ctx *context.Context) {
t, err := auth.GetTwoFactorByUID(ctx, ctx.Doer.ID)
if err != nil {
if auth.IsErrTwoFactorNotEnrolled(err) {
@@ -97,6 +86,9 @@ func disableTwoFactor(ctx *context.Context) {
ctx.ServerError("SendDisabledTOTP", err)
return
}
+
+ ctx.Flash.Success(ctx.Tr("settings.twofa_disabled"))
+ ctx.Redirect(setting.AppSubURL + "/user/settings/security")
}
func twofaGenerateSecretAndQr(ctx *context.Context) bool {
@@ -184,6 +176,7 @@ func EnrollTwoFactor(ctx *context.Context) {
// EnrollTwoFactorPost handles enrolling the user into 2FA.
func EnrollTwoFactorPost(ctx *context.Context) {
+ form := web.GetForm(ctx).(*forms.TwoFactorAuthForm)
ctx.Data["Title"] = ctx.Tr("settings")
ctx.Data["PageIsSettingsSecurity"] = true
@@ -199,12 +192,6 @@ func EnrollTwoFactorPost(ctx *context.Context) {
return
}
- enrollTwoFactor(ctx)
-}
-
-func enrollTwoFactor(ctx *context.Context) {
- form := web.GetForm(ctx).(*forms.TwoFactorAuthForm)
-
if ctx.HasError() {
if !twofaGenerateSecretAndQr(ctx) {
return
@@ -230,10 +217,14 @@ func enrollTwoFactor(ctx *context.Context) {
return
}
- twoFactor := &auth.TwoFactor{
+ t = &auth.TwoFactor{
UID: ctx.Doer.ID,
}
- token := twoFactor.GenerateScratchToken()
+ token, err := t.GenerateScratchToken()
+ if err != nil {
+ ctx.ServerError("SettingsTwoFactor: Failed to generate scratch token", err)
+ return
+ }
// Now we have to delete the secrets - because if we fail to insert then it's highly likely that they have already been used
// If we can detect the unique constraint failure below we can move this to after the NewTwoFactor
@@ -255,7 +246,7 @@ func enrollTwoFactor(ctx *context.Context) {
return
}
- if err := auth.NewTwoFactor(ctx, twoFactor, secret); err != nil {
+ if err = auth.NewTwoFactor(ctx, t, secret); err != nil {
// FIXME: We need to handle a unique constraint fail here it's entirely possible that another request has beaten us.
// If there is a unique constraint fail we should just tolerate the error
ctx.ServerError("SettingsTwoFactor: Failed to save two factor", err)
@@ -265,41 +256,3 @@ func enrollTwoFactor(ctx *context.Context) {
ctx.Flash.Success(ctx.Tr("settings.twofa_enrolled", token))
ctx.Redirect(setting.AppSubURL + "/user/settings/security")
}
-
-// ReenrollTwoFactor shows the page where the user can reenroll 2FA.
-func ReenrollTwoFactor(ctx *context.Context) {
- ctx.Data["Title"] = ctx.Tr("settings")
- ctx.Data["PageIsSettingsSecurity"] = true
- ctx.Data["ReenrollTwofa"] = true
-
- _, err := auth.GetTwoFactorByUID(ctx, ctx.Doer.ID)
- if auth.IsErrTwoFactorNotEnrolled(err) {
- ctx.Flash.Error(ctx.Tr("settings.twofa_not_enrolled"))
- ctx.Redirect(setting.AppSubURL + "/user/settings/security")
- return
- }
- if err != nil {
- ctx.ServerError("SettingsTwoFactor: GetTwoFactorByUID", err)
- return
- }
-
- if !twofaGenerateSecretAndQr(ctx) {
- return
- }
-
- ctx.HTML(http.StatusOK, tplSettingsTwofaEnroll)
-}
-
-// ReenrollTwoFactorPost handles reenrolling the user 2FA.
-func ReenrollTwoFactorPost(ctx *context.Context) {
- ctx.Data["Title"] = ctx.Tr("settings")
- ctx.Data["PageIsSettingsSecurity"] = true
- ctx.Data["ReenrollTwofa"] = true
-
- disableTwoFactor(ctx)
- if ctx.Written() {
- return
- }
-
- enrollTwoFactor(ctx)
-}
diff --git a/routers/web/user/setting/security/openid.go b/routers/web/user/setting/security/openid.go
index 14660e1646..8f788e1735 100644
--- a/routers/web/user/setting/security/openid.go
+++ b/routers/web/user/setting/security/openid.go
@@ -6,13 +6,13 @@ package security
import (
"net/http"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/auth/openid"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/web"
- "forgejo.org/services/context"
- "forgejo.org/services/forms"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/auth/openid"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/web"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/forms"
)
// OpenIDPost response for change user's openid
diff --git a/routers/web/user/setting/security/security.go b/routers/web/user/setting/security/security.go
index 8b801cfebd..8d6859ab87 100644
--- a/routers/web/user/setting/security/security.go
+++ b/routers/web/user/setting/security/security.go
@@ -8,14 +8,14 @@ import (
"net/http"
"sort"
- auth_model "forgejo.org/models/auth"
- "forgejo.org/models/db"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/base"
- "forgejo.org/modules/optional"
- "forgejo.org/modules/setting"
- "forgejo.org/services/auth/source/oauth2"
- "forgejo.org/services/context"
+ auth_model "code.gitea.io/gitea/models/auth"
+ "code.gitea.io/gitea/models/db"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/optional"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/services/auth/source/oauth2"
+ "code.gitea.io/gitea/services/context"
)
const (
@@ -55,7 +55,7 @@ func DeleteAccountLink(ctx *context.Context) {
}
func loadSecurityData(ctx *context.Context) {
- enrolled, err := auth_model.HasTOTPByUID(ctx, ctx.Doer.ID)
+ enrolled, err := auth_model.HasTwoFactorByUID(ctx, ctx.Doer.ID)
if err != nil {
ctx.ServerError("SettingsTwoFactor", err)
return
diff --git a/routers/web/user/setting/security/webauthn.go b/routers/web/user/setting/security/webauthn.go
index a909d479c9..bfbc06c701 100644
--- a/routers/web/user/setting/security/webauthn.go
+++ b/routers/web/user/setting/security/webauthn.go
@@ -9,14 +9,14 @@ import (
"strconv"
"time"
- "forgejo.org/models/auth"
- wa "forgejo.org/modules/auth/webauthn"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/web"
- "forgejo.org/services/context"
- "forgejo.org/services/forms"
- "forgejo.org/services/mailer"
+ "code.gitea.io/gitea/models/auth"
+ wa "code.gitea.io/gitea/modules/auth/webauthn"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/web"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/forms"
+ "code.gitea.io/gitea/services/mailer"
"github.com/go-webauthn/webauthn/protocol"
"github.com/go-webauthn/webauthn/webauthn"
diff --git a/routers/web/user/setting/storage_overview.go b/routers/web/user/setting/storage_overview.go
index 4586600572..8a0c773077 100644
--- a/routers/web/user/setting/storage_overview.go
+++ b/routers/web/user/setting/storage_overview.go
@@ -4,9 +4,9 @@
package setting
import (
- "forgejo.org/modules/base"
- "forgejo.org/routers/web/shared"
- "forgejo.org/services/context"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/routers/web/shared"
+ "code.gitea.io/gitea/services/context"
)
const (
diff --git a/routers/web/user/setting/webhooks.go b/routers/web/user/setting/webhooks.go
index bc07accad4..3cc67d9def 100644
--- a/routers/web/user/setting/webhooks.go
+++ b/routers/web/user/setting/webhooks.go
@@ -6,12 +6,12 @@ package setting
import (
"net/http"
- "forgejo.org/models/db"
- "forgejo.org/models/webhook"
- "forgejo.org/modules/base"
- "forgejo.org/modules/setting"
- "forgejo.org/services/context"
- webhook_service "forgejo.org/services/webhook"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/services/context"
+ webhook_service "code.gitea.io/gitea/services/webhook"
)
const (
diff --git a/routers/web/user/stop_watch.go b/routers/web/user/stop_watch.go
index 210b32d205..38f74ea455 100644
--- a/routers/web/user/stop_watch.go
+++ b/routers/web/user/stop_watch.go
@@ -6,10 +6,10 @@ package user
import (
"net/http"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- "forgejo.org/services/context"
- "forgejo.org/services/convert"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/convert"
)
// GetStopwatches get all stopwatches
diff --git a/routers/web/user/task.go b/routers/web/user/task.go
index 4059139552..8476767e9e 100644
--- a/routers/web/user/task.go
+++ b/routers/web/user/task.go
@@ -7,9 +7,9 @@ import (
"net/http"
"strconv"
- admin_model "forgejo.org/models/admin"
- "forgejo.org/modules/json"
- "forgejo.org/services/context"
+ admin_model "code.gitea.io/gitea/models/admin"
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/services/context"
)
// TaskStatus returns task's status
@@ -35,7 +35,7 @@ func TaskStatus(ctx *context.Context) {
var translatableMessage admin_model.TranslatableMessage
if err := json.Unmarshal([]byte(message), &translatableMessage); err != nil {
translatableMessage = admin_model.TranslatableMessage{
- Format: "repo.migrate.migrating_failed.error",
+ Format: "migrate.migrating_failed.error",
Args: []any{task.Message},
}
}
diff --git a/routers/web/web.go b/routers/web/web.go
index 20d5376cfe..15264ccc89 100644
--- a/routers/web/web.go
+++ b/routers/web/web.go
@@ -1,57 +1,53 @@
// Copyright 2017 The Gitea Authors. All rights reserved.
-// Copyright 2023 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package web
import (
gocontext "context"
- "fmt"
"net/http"
"strings"
- auth_model "forgejo.org/models/auth"
- "forgejo.org/models/perm"
- quota_model "forgejo.org/models/quota"
- "forgejo.org/models/unit"
- "forgejo.org/modules/log"
- "forgejo.org/modules/metrics"
- "forgejo.org/modules/public"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/storage"
- "forgejo.org/modules/structs"
- "forgejo.org/modules/templates"
- "forgejo.org/modules/validation"
- "forgejo.org/modules/web"
- "forgejo.org/modules/web/middleware"
- "forgejo.org/modules/web/routing"
- "forgejo.org/routers/common"
- "forgejo.org/routers/web/admin"
- "forgejo.org/routers/web/auth"
- "forgejo.org/routers/web/devtest"
- "forgejo.org/routers/web/events"
- "forgejo.org/routers/web/explore"
- "forgejo.org/routers/web/feed"
- "forgejo.org/routers/web/healthcheck"
- "forgejo.org/routers/web/misc"
- "forgejo.org/routers/web/moderation"
- "forgejo.org/routers/web/org"
- org_setting "forgejo.org/routers/web/org/setting"
- "forgejo.org/routers/web/repo"
- "forgejo.org/routers/web/repo/actions"
- "forgejo.org/routers/web/repo/badges"
- repo_flags "forgejo.org/routers/web/repo/flags"
- repo_setting "forgejo.org/routers/web/repo/setting"
- "forgejo.org/routers/web/shared/project"
- "forgejo.org/routers/web/user"
- user_setting "forgejo.org/routers/web/user/setting"
- "forgejo.org/routers/web/user/setting/security"
- auth_service "forgejo.org/services/auth"
- "forgejo.org/services/context"
- "forgejo.org/services/forms"
- "forgejo.org/services/lfs"
+ "code.gitea.io/gitea/models/perm"
+ quota_model "code.gitea.io/gitea/models/quota"
+ "code.gitea.io/gitea/models/unit"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/metrics"
+ "code.gitea.io/gitea/modules/public"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/storage"
+ "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/templates"
+ "code.gitea.io/gitea/modules/validation"
+ "code.gitea.io/gitea/modules/web"
+ "code.gitea.io/gitea/modules/web/middleware"
+ "code.gitea.io/gitea/modules/web/routing"
+ "code.gitea.io/gitea/routers/common"
+ "code.gitea.io/gitea/routers/web/admin"
+ "code.gitea.io/gitea/routers/web/auth"
+ "code.gitea.io/gitea/routers/web/devtest"
+ "code.gitea.io/gitea/routers/web/events"
+ "code.gitea.io/gitea/routers/web/explore"
+ "code.gitea.io/gitea/routers/web/feed"
+ "code.gitea.io/gitea/routers/web/healthcheck"
+ "code.gitea.io/gitea/routers/web/misc"
+ "code.gitea.io/gitea/routers/web/org"
+ org_setting "code.gitea.io/gitea/routers/web/org/setting"
+ "code.gitea.io/gitea/routers/web/repo"
+ "code.gitea.io/gitea/routers/web/repo/actions"
+ "code.gitea.io/gitea/routers/web/repo/badges"
+ repo_flags "code.gitea.io/gitea/routers/web/repo/flags"
+ repo_setting "code.gitea.io/gitea/routers/web/repo/setting"
+ "code.gitea.io/gitea/routers/web/shared/project"
+ "code.gitea.io/gitea/routers/web/user"
+ user_setting "code.gitea.io/gitea/routers/web/user/setting"
+ "code.gitea.io/gitea/routers/web/user/setting/security"
+ auth_service "code.gitea.io/gitea/services/auth"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/forms"
+ "code.gitea.io/gitea/services/lfs"
- _ "forgejo.org/modules/session" // to registers all internal adapters
+ _ "code.gitea.io/gitea/modules/session" // to registers all internal adapters
"code.forgejo.org/go-chi/captcha"
chi_middleware "github.com/go-chi/chi/v5/middleware"
@@ -119,7 +115,7 @@ func webAuth(authMethod auth_service.Method) func(*context.Context) {
return func(ctx *context.Context) {
ar, err := common.AuthShared(ctx.Base, ctx.Session, authMethod)
if err != nil {
- log.Info("Failed to verify user: %v", err)
+ log.Error("Failed to verify user: %v", err)
ctx.Error(http.StatusUnauthorized, ctx.Locale.TrString("auth.unauthorized_credentials", "https://codeberg.org/forgejo/forgejo/issues/2809"))
return
}
@@ -171,19 +167,6 @@ func verifyAuthWithOptions(options *common.VerifyOptions) func(ctx *context.Cont
ctx.Redirect(setting.AppSubURL + "/")
return
}
-
- if ctx.Doer.MustHaveTwoFactor() && !strings.HasPrefix(ctx.Req.URL.Path, "/user/settings/security") {
- hasTwoFactor, err := auth_model.HasTwoFactorByUID(ctx, ctx.Doer.ID)
- if err != nil {
- log.Error("Error getting 2fa: %s", err)
- ctx.Error(http.StatusInternalServerError, "HasTwoFactorByUID", err.Error())
- return
- }
- if !hasTwoFactor {
- ctx.Redirect(setting.AppSubURL + "/user/settings/security")
- return
- }
- }
}
// Redirect to dashboard (or alternate location) if user tries to visit any non-login page.
@@ -192,8 +175,7 @@ func verifyAuthWithOptions(options *common.VerifyOptions) func(ctx *context.Cont
return
}
- safeMethod := ctx.Req.Method == "GET" || ctx.Req.Method == "HEAD" || ctx.Req.Method == "OPTIONS"
- if !options.SignOutRequired && !options.DisableCSRF && !safeMethod {
+ if !options.SignOutRequired && !options.DisableCSRF && ctx.Req.Method == "POST" {
ctx.Csrf.Validate(ctx)
if ctx.Written() {
return
@@ -325,20 +307,6 @@ func registerRoutes(m *web.Route) {
}
}
- requiredTwoFactor := func(ctx *context.Context) {
- if !ctx.Doer.MustHaveTwoFactor() {
- return
- }
-
- hasTwoFactor, err := auth_model.HasTwoFactorByUID(ctx, ctx.Doer.ID)
- if err != nil {
- ctx.Error(http.StatusInternalServerError, fmt.Sprintf("Error getting 2fa: %s", err))
- return
- }
- ctx.Data["MustEnableTwoFactor"] = !hasTwoFactor
- ctx.Data["HideNavbarLinks"] = !hasTwoFactor
- }
-
openIDSignInEnabled := func(ctx *context.Context) {
if !setting.Service.EnableOpenIDSignIn {
ctx.Error(http.StatusForbidden)
@@ -505,11 +473,6 @@ func registerRoutes(m *web.Route) {
m.Get("/search", repo.SearchIssues)
}, reqSignIn)
- if setting.Moderation.Enabled {
- m.Get("/report_abuse", reqSignIn, moderation.NewReport)
- m.Post("/report_abuse", reqSignIn, web.Bind(forms.ReportAbuseForm{}), moderation.CreatePost)
- }
-
m.Get("/pulls", reqSignIn, user.Pulls)
m.Get("/milestones", reqSignIn, reqMilestonesDashboardPageEnabled, user.Milestones)
@@ -594,8 +557,6 @@ func registerRoutes(m *web.Route) {
m.Post("/disable", security.DisableTwoFactor)
m.Get("/enroll", security.EnrollTwoFactor)
m.Post("/enroll", web.Bind(forms.TwoFactorAuthForm{}), security.EnrollTwoFactorPost)
- m.Get("/reenroll", security.ReenrollTwoFactor)
- m.Post("/reenroll", web.Bind(forms.TwoFactorAuthForm{}), security.ReenrollTwoFactorPost)
})
m.Group("/webauthn", func() {
m.Post("/request_register", web.Bind(forms.WebauthnRegistrationForm{}), security.WebAuthnRegister)
@@ -608,7 +569,7 @@ func registerRoutes(m *web.Route) {
m.Post("/toggle_visibility", security.ToggleOpenIDVisibility)
}, openIDSignInEnabled)
m.Post("/account_link", linkAccountEnabled, security.DeleteAccountLink)
- }, requiredTwoFactor)
+ })
m.Group("/applications", func() {
// oauth2 applications
@@ -813,14 +774,7 @@ func registerRoutes(m *web.Route) {
addSettingsRunnersRoutes()
addSettingsVariablesRoutes()
})
-
- if setting.Moderation.Enabled {
- m.Group("/moderation/reports", func() {
- m.Get("", admin.AbuseReports)
- m.Get("/type/{type:1|2|3|4}/id/{id}", admin.AbuseReportDetails)
- })
- }
- }, adminReq, ctxDataSet("EnableOAuth2", setting.OAuth2.Enabled, "EnablePackages", setting.Packages.Enabled, "EnableModeration", setting.Moderation.Enabled))
+ }, adminReq, ctxDataSet("EnableOAuth2", setting.OAuth2.Enabled, "EnablePackages", setting.Packages.Enabled))
// ***** END: Admin *****
m.Group("", func() {
@@ -857,13 +811,13 @@ func registerRoutes(m *web.Route) {
individualPermsChecker := func(ctx *context.Context) {
// org permissions have been checked in context.OrgAssignment(), but individual permissions haven't been checked.
if ctx.ContextUser.IsIndividual() {
- switch ctx.ContextUser.Visibility {
- case structs.VisibleTypePrivate:
+ switch {
+ case ctx.ContextUser.Visibility == structs.VisibleTypePrivate:
if ctx.Doer == nil || (ctx.ContextUser.ID != ctx.Doer.ID && !ctx.Doer.IsAdmin) {
ctx.NotFound("Visit Project", nil)
return
}
- case structs.VisibleTypeLimited:
+ case ctx.ContextUser.Visibility == structs.VisibleTypeLimited:
if ctx.Doer == nil {
ctx.NotFound("Visit Project", nil)
return
@@ -1438,28 +1392,25 @@ func registerRoutes(m *web.Route) {
m.Get("", actions.List)
m.Post("/disable", reqRepoAdmin, actions.DisableWorkflowFile)
m.Post("/enable", reqRepoAdmin, actions.EnableWorkflowFile)
- m.Post("/manual", reqRepoActionsWriter, actions.ManualRunWorkflow)
+ m.Post("/manual", reqRepoAdmin, actions.ManualRunWorkflow)
m.Group("/runs", func() {
m.Get("/latest", actions.ViewLatest)
m.Group("/{run}", func() {
m.Combo("").
- Get(actions.RedirectToLatestAttempt).
+ Get(actions.View).
Post(web.Bind(actions.ViewRequest{}), actions.ViewPost)
m.Group("/jobs/{job}", func() {
m.Combo("").
- Get(actions.RedirectToLatestAttempt).
+ Get(actions.View).
Post(web.Bind(actions.ViewRequest{}), actions.ViewPost)
m.Post("/rerun", reqRepoActionsWriter, actions.Rerun)
m.Get("/logs", actions.Logs)
- m.Combo("/attempt/{attempt}").
- Get(actions.View).
- Post(web.Bind(actions.ViewRequest{}), actions.ViewPost)
})
m.Post("/cancel", reqRepoActionsWriter, actions.Cancel)
m.Post("/approve", reqRepoActionsWriter, actions.Approve)
m.Get("/artifacts", actions.ArtifactsView)
- m.Get("/artifacts/{artifact_name_or_id}", actions.ArtifactsDownloadView)
+ m.Get("/artifacts/{artifact_name}", actions.ArtifactsDownloadView)
m.Delete("/artifacts/{artifact_name}", reqRepoActionsWriter, actions.ArtifactsDeleteView)
m.Post("/rerun", reqRepoActionsWriter, actions.Rerun)
})
@@ -1503,7 +1454,7 @@ func registerRoutes(m *web.Route) {
}, repo.MustBeNotEmpty, context.RequireRepoReaderOr(unit.TypeCode))
m.Group("/recent-commits", func() {
m.Get("", repo.RecentCommits)
- m.Get("/data", repo.CodeFrequencyData)
+ m.Get("/data", repo.RecentCommitsData)
}, repo.MustBeNotEmpty, context.RequireRepoReaderOr(unit.TypeCode))
}, context.RepoRef(), context.RequireRepoReaderOr(unit.TypeCode, unit.TypePullRequests, unit.TypeIssues, unit.TypeReleases))
@@ -1552,10 +1503,7 @@ func registerRoutes(m *web.Route) {
m.Group("/commits", func() {
m.Get("", context.RepoRef(), repo.SetWhitespaceBehavior, repo.GetPullDiffStats, repo.ViewPullCommits)
m.Get("/list", context.RepoRef(), repo.GetPullCommits)
- m.Group("/{sha:[a-f0-9]{4,40}}", func() {
- m.Get("", context.RepoRef(), repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.SetShowOutdatedComments, repo.ViewPullFilesForSingleCommit)
- m.Post("/reviews/submit", context.RepoMustNotBeArchived(), web.Bind(forms.SubmitReviewForm{}), repo.SubmitReview)
- })
+ m.Get("/{sha:[a-f0-9]{4,40}}", context.RepoRef(), repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.SetShowOutdatedComments, repo.ViewPullFilesForSingleCommit)
})
m.Post("/merge", context.RepoMustNotBeArchived(), web.Bind(forms.MergePullRequestForm{}), context.EnforceQuotaWeb(quota_model.LimitSubjectSizeGitAll, context.QuotaTargetRepo), repo.MergePullRequest)
m.Post("/cancel_auto_merge", context.RepoMustNotBeArchived(), repo.CancelAutoMergePullRequest)
@@ -1643,8 +1591,6 @@ func registerRoutes(m *web.Route) {
}, context.RepoRef(), reqRepoCodeReader)
}
m.Get("/commit/{sha:([a-f0-9]{4,64})}.{ext:patch|diff}", repo.MustBeNotEmpty, reqRepoCodeReader, repo.RawDiff)
-
- m.Post("/sync_fork", context.RepoMustNotBeArchived(), repo.MustBeNotEmpty, reqRepoCodeWriter, repo.SyncFork)
}, ignSignIn, context.RepoAssignment, context.UnitTypes())
m.Post("/{username}/{reponame}/lastcommit/*", ignSignInAndCsrf, context.RepoAssignment, context.UnitTypes(), context.RepoRefByType(context.RepoRefCommit), reqRepoCodeReader, repo.LastCommit)
@@ -1715,7 +1661,6 @@ func registerRoutes(m *web.Route) {
m.Any("/devtest", devtest.List)
m.Any("/devtest/fetch-action-test", devtest.FetchActionTest)
m.Any("/devtest/{sub}", devtest.Tmpl)
- m.Get("/devtest/error/{errcode}", devtest.ErrorPage)
}
m.NotFound(func(w http.ResponseWriter, req *http.Request) {
diff --git a/routers/web/webfinger.go b/routers/web/webfinger.go
index 5f67e436bf..1f3de70db0 100644
--- a/routers/web/webfinger.go
+++ b/routers/web/webfinger.go
@@ -9,10 +9,10 @@ import (
"net/url"
"strings"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- "forgejo.org/services/context"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/services/context"
)
// https://datatracker.ietf.org/doc/html/draft-ietf-appsawg-webfinger-14#section-4.4
@@ -58,33 +58,7 @@ func WebfingerQuery(ctx *context.Context) {
return
}
- // Instance actor
- if parts[0] == "ghost" {
- aliases := []string{
- appURL.String() + "api/v1/activitypub/actor",
- }
-
- links := []*webfingerLink{
- {
- Rel: "self",
- Type: "application/activity+json",
- Href: appURL.String() + "api/v1/activitypub/actor",
- },
- }
-
- ctx.Resp.Header().Add("Access-Control-Allow-Origin", "*")
- ctx.JSON(http.StatusOK, &webfingerJRD{
- Subject: fmt.Sprintf("acct:%s@%s", "ghost", appURL.Host),
- Aliases: aliases,
- Links: links,
- })
- ctx.Resp.Header().Set("Content-Type", "application/jrd+json")
-
- return
- }
-
u, err = user_model.GetUserByName(ctx, parts[0])
-
case "mailto":
u, err = user_model.GetUserByEmail(ctx, resource.Opaque)
if u != nil && u.KeepEmailPrivate {
@@ -179,7 +153,7 @@ func WebfingerQuery(ctx *context.Context) {
},
{
Rel: "http://openid.net/specs/connect/1.0/issuer",
- Href: strings.TrimSuffix(appURL.String(), "/"),
+ Href: appURL.String(),
},
}
diff --git a/services/actions/TestServiceActions_startTask/action_schedule.yml b/services/actions/TestServiceActions_startTask/action_schedule.yml
deleted file mode 100644
index d0e7234475..0000000000
--- a/services/actions/TestServiceActions_startTask/action_schedule.yml
+++ /dev/null
@@ -1,41 +0,0 @@
-# A corrupted cron spec with a valid schedule workflow
--
- id: 1
- title: schedule_title1
- specs:
- - '* * * * *'
- repo_id: 4
- owner_id: 2
- workflow_id: 'workflow1.yml'
- trigger_user_id: 2
- ref: main
- commit_sha: shashasha
- event: "schedule"
- event_payload: "fakepayload"
- content: |
- jobs:
- job2:
- runs-on: ubuntu-latest
- steps:
- - run: true
-
-# A valid cron spec with a corrupted schedule workflow
--
- id: 2
- title: schedule_title2
- specs:
- - '* * * * *'
- repo_id: 4
- owner_id: 2
- workflow_id: 'workflow2.yml'
- trigger_user_id: 2
- ref: main
- commit_sha: shashasha
- event: "schedule"
- event_payload: "fakepayload"
- content: |
- jobs:
- job2: { invalid yaml
- runs-on: ubuntu-latest
- steps:
- - run: true
diff --git a/services/actions/TestServiceActions_startTask/action_schedule_spec.yml b/services/actions/TestServiceActions_startTask/action_schedule_spec.yml
deleted file mode 100644
index 7bcc78f010..0000000000
--- a/services/actions/TestServiceActions_startTask/action_schedule_spec.yml
+++ /dev/null
@@ -1,15 +0,0 @@
-# A corrupted cron spec with a valid schedule workflow
--
- id: 1
- repo_id: 4
- schedule_id: 1
- next: 1
- spec: 'corrupted * *'
-
-# A valid cron spec with a corrupted schedule workflow
--
- id: 2
- repo_id: 4
- schedule_id: 2
- next: 1
- spec: '* * * * *'
diff --git a/services/actions/auth.go b/services/actions/auth.go
index 98b618aeba..1ef21f6e0e 100644
--- a/services/actions/auth.go
+++ b/services/actions/auth.go
@@ -4,15 +4,14 @@
package actions
import (
- "errors"
"fmt"
"net/http"
"strings"
"time"
- "forgejo.org/modules/json"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
"github.com/golang-jwt/jwt/v5"
)
@@ -81,7 +80,7 @@ func ParseAuthorizationToken(req *http.Request) (int64, error) {
parts := strings.SplitN(h, " ", 2)
if len(parts) != 2 {
log.Error("split token failed: %s", h)
- return 0, errors.New("split token failed")
+ return 0, fmt.Errorf("split token failed")
}
return TokenToTaskID(parts[1])
@@ -101,7 +100,7 @@ func TokenToTaskID(token string) (int64, error) {
c, ok := parsedToken.Claims.(*actionsClaims)
if !parsedToken.Valid || !ok {
- return 0, errors.New("invalid token claim")
+ return 0, fmt.Errorf("invalid token claim")
}
return c.TaskID, nil
diff --git a/services/actions/auth_test.go b/services/actions/auth_test.go
index d9f0437e1b..1400e61f47 100644
--- a/services/actions/auth_test.go
+++ b/services/actions/auth_test.go
@@ -7,8 +7,8 @@ import (
"net/http"
"testing"
- "forgejo.org/modules/json"
- "forgejo.org/modules/setting"
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/setting"
"github.com/golang-jwt/jwt/v5"
"github.com/stretchr/testify/assert"
@@ -19,7 +19,7 @@ func TestCreateAuthorizationToken(t *testing.T) {
var taskID int64 = 23
token, err := CreateAuthorizationToken(taskID, 1, 2)
require.NoError(t, err)
- assert.NotEmpty(t, token)
+ assert.NotEqual(t, "", token)
claims := jwt.MapClaims{}
_, err = jwt.ParseWithClaims(token, claims, func(t *jwt.Token) (any, error) {
return setting.GetGeneralTokenSigningSecret(), nil
@@ -45,7 +45,7 @@ func TestParseAuthorizationToken(t *testing.T) {
var taskID int64 = 23
token, err := CreateAuthorizationToken(taskID, 1, 2)
require.NoError(t, err)
- assert.NotEmpty(t, token)
+ assert.NotEqual(t, "", token)
headers := http.Header{}
headers.Set("Authorization", "Bearer "+token)
rTaskID, err := ParseAuthorizationToken(&http.Request{
diff --git a/services/actions/cleanup.go b/services/actions/cleanup.go
index 918be0f185..34fa2688e7 100644
--- a/services/actions/cleanup.go
+++ b/services/actions/cleanup.go
@@ -10,12 +10,12 @@ import (
"os"
"time"
- actions_model "forgejo.org/models/actions"
- actions_module "forgejo.org/modules/actions"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/storage"
- "forgejo.org/modules/timeutil"
+ actions_model "code.gitea.io/gitea/models/actions"
+ actions_module "code.gitea.io/gitea/modules/actions"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/storage"
+ "code.gitea.io/gitea/modules/timeutil"
)
// Cleanup removes expired actions logs, data and artifacts
@@ -126,9 +126,3 @@ func CleanupLogs(ctx context.Context) error {
log.Info("Removed %d logs", count)
return nil
}
-
-// CleanupOfflineRunners removes offline runners
-func CleanupOfflineRunners(ctx context.Context, duration time.Duration, globalOnly bool) error {
- olderThan := timeutil.TimeStampNow().AddDuration(-duration)
- return actions_model.DeleteOfflineRunners(ctx, olderThan, globalOnly)
-}
diff --git a/services/actions/cleanup_test.go b/services/actions/cleanup_test.go
index 4a847ced23..65fae840c1 100644
--- a/services/actions/cleanup_test.go
+++ b/services/actions/cleanup_test.go
@@ -6,10 +6,10 @@ package actions
import (
"testing"
- actions_model "forgejo.org/models/actions"
- "forgejo.org/models/db"
- "forgejo.org/models/unittest"
- "forgejo.org/modules/timeutil"
+ actions_model "code.gitea.io/gitea/models/actions"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/unittest"
+ "code.gitea.io/gitea/modules/timeutil"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -24,7 +24,7 @@ func TestCleanup(t *testing.T) {
require.NoError(t, CleanupLogs(db.DefaultContext))
task := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionTask{ID: 1001})
- assert.Equal(t, "does-not-exist", task.LogFilename)
+ assert.EqualValues(t, "does-not-exist", task.LogFilename)
assert.True(t, task.LogExpired)
assert.Nil(t, task.LogIndexes)
})
diff --git a/services/actions/clear_tasks.go b/services/actions/clear_tasks.go
index c36dda55b2..f146c22372 100644
--- a/services/actions/clear_tasks.go
+++ b/services/actions/clear_tasks.go
@@ -8,12 +8,12 @@ import (
"fmt"
"time"
- actions_model "forgejo.org/models/actions"
- "forgejo.org/models/db"
- "forgejo.org/modules/actions"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/timeutil"
+ actions_model "code.gitea.io/gitea/models/actions"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/modules/actions"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/timeutil"
)
// StopZombieTasks stops the task which have running status, but haven't been updated for a long time
@@ -41,7 +41,7 @@ func stopTasks(ctx context.Context, opts actions_model.FindTaskOptions) error {
jobs := make([]*actions_model.ActionRunJob, 0, len(tasks))
for _, task := range tasks {
if err := db.WithTx(ctx, func(ctx context.Context) error {
- if err := StopTask(ctx, task.ID, actions_model.StatusFailure); err != nil {
+ if err := actions_model.StopTask(ctx, task.ID, actions_model.StatusFailure); err != nil {
return err
}
if err := task.LoadJob(ctx); err != nil {
@@ -88,7 +88,7 @@ func CancelAbandonedJobs(ctx context.Context) error {
job.Status = actions_model.StatusCancelled
job.Stopped = now
if err := db.WithTx(ctx, func(ctx context.Context) error {
- _, err := UpdateRunJob(ctx, job, nil, "status", "stopped")
+ _, err := actions_model.UpdateRunJob(ctx, job, nil, "status", "stopped")
return err
}); err != nil {
log.Warn("cancel abandoned job %v: %v", job.ID, err)
diff --git a/services/actions/commit_status.go b/services/actions/commit_status.go
index d45b75ac0b..04dffbac88 100644
--- a/services/actions/commit_status.go
+++ b/services/actions/commit_status.go
@@ -5,21 +5,20 @@ package actions
import (
"context"
- "errors"
"fmt"
"path"
- actions_model "forgejo.org/models/actions"
- "forgejo.org/models/db"
- git_model "forgejo.org/models/git"
- user_model "forgejo.org/models/user"
- actions_module "forgejo.org/modules/actions"
- "forgejo.org/modules/log"
- api "forgejo.org/modules/structs"
- webhook_module "forgejo.org/modules/webhook"
- commitstatus_service "forgejo.org/services/repository/commitstatus"
+ actions_model "code.gitea.io/gitea/models/actions"
+ "code.gitea.io/gitea/models/db"
+ git_model "code.gitea.io/gitea/models/git"
+ user_model "code.gitea.io/gitea/models/user"
+ actions_module "code.gitea.io/gitea/modules/actions"
+ "code.gitea.io/gitea/modules/log"
+ api "code.gitea.io/gitea/modules/structs"
+ webhook_module "code.gitea.io/gitea/modules/webhook"
+ commitstatus_service "code.gitea.io/gitea/services/repository/commitstatus"
- "code.forgejo.org/forgejo/runner/v11/act/jobparser"
+ "github.com/nektos/act/pkg/jobparser"
)
// CreateCommitStatus creates a commit status for the given job.
@@ -51,7 +50,7 @@ func createCommitStatus(ctx context.Context, job *actions_model.ActionRunJob) er
return fmt.Errorf("GetPushEventPayload: %w", err)
}
if payload.HeadCommit == nil {
- return errors.New("head commit is missing in event payload")
+ return fmt.Errorf("head commit is missing in event payload")
}
sha = payload.HeadCommit.ID
case webhook_module.HookEventPullRequest, webhook_module.HookEventPullRequestSync, webhook_module.HookEventPullRequestLabel, webhook_module.HookEventPullRequestAssign, webhook_module.HookEventPullRequestMilestone:
@@ -65,9 +64,9 @@ func createCommitStatus(ctx context.Context, job *actions_model.ActionRunJob) er
return fmt.Errorf("GetPullRequestEventPayload: %w", err)
}
if payload.PullRequest == nil {
- return errors.New("pull request is missing in event payload")
+ return fmt.Errorf("pull request is missing in event payload")
} else if payload.PullRequest.Head == nil {
- return errors.New("head of pull request is missing in event payload")
+ return fmt.Errorf("head of pull request is missing in event payload")
}
sha = payload.PullRequest.Head.Sha
case webhook_module.HookEventRelease:
@@ -80,7 +79,7 @@ func createCommitStatus(ctx context.Context, job *actions_model.ActionRunJob) er
repo := run.Repo
// TODO: store workflow name as a field in ActionRun to avoid parsing
runName := path.Base(run.WorkflowID)
- if wfs, err := jobparser.Parse(job.WorkflowPayload, false); err == nil && len(wfs) > 0 {
+ if wfs, err := jobparser.Parse(job.WorkflowPayload); err == nil && len(wfs) > 0 {
runName = wfs[0].Name
}
ctxname := fmt.Sprintf("%s / %s (%s)", runName, job.Name, event)
diff --git a/services/actions/context.go b/services/actions/context.go
index bf187c56bf..be1c85522b 100644
--- a/services/actions/context.go
+++ b/services/actions/context.go
@@ -7,13 +7,13 @@ import (
"context"
"fmt"
- actions_model "forgejo.org/models/actions"
- "forgejo.org/models/db"
- actions_module "forgejo.org/modules/actions"
- "forgejo.org/modules/container"
- "forgejo.org/modules/git"
- "forgejo.org/modules/json"
- "forgejo.org/modules/setting"
+ actions_model "code.gitea.io/gitea/models/actions"
+ "code.gitea.io/gitea/models/db"
+ actions_module "code.gitea.io/gitea/modules/actions"
+ "code.gitea.io/gitea/modules/container"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/setting"
)
// GenerateGiteaContext generate the gitea context without token and gitea_runtime_token
diff --git a/services/actions/context_test.go b/services/actions/context_test.go
index c96094ade8..4cd8825870 100644
--- a/services/actions/context_test.go
+++ b/services/actions/context_test.go
@@ -6,8 +6,8 @@ package actions
import (
"testing"
- actions_model "forgejo.org/models/actions"
- "forgejo.org/models/unittest"
+ actions_model "code.gitea.io/gitea/models/actions"
+ "code.gitea.io/gitea/models/unittest"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
diff --git a/services/actions/init.go b/services/actions/init.go
index 8f1db64e27..0f49cb6297 100644
--- a/services/actions/init.go
+++ b/services/actions/init.go
@@ -4,11 +4,11 @@
package actions
import (
- "forgejo.org/modules/graceful"
- "forgejo.org/modules/log"
- "forgejo.org/modules/queue"
- "forgejo.org/modules/setting"
- notify_service "forgejo.org/services/notify"
+ "code.gitea.io/gitea/modules/graceful"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/queue"
+ "code.gitea.io/gitea/modules/setting"
+ notify_service "code.gitea.io/gitea/services/notify"
)
func Init() {
diff --git a/services/actions/interface.go b/services/actions/interface.go
index 54a30061bc..76bee6f153 100644
--- a/services/actions/interface.go
+++ b/services/actions/interface.go
@@ -3,7 +3,7 @@
package actions
-import "forgejo.org/services/context"
+import "code.gitea.io/gitea/services/context"
// API for actions of a repository or organization
type API interface {
diff --git a/services/actions/job_emitter.go b/services/actions/job_emitter.go
index 8e58105e47..1f859fcf70 100644
--- a/services/actions/job_emitter.go
+++ b/services/actions/job_emitter.go
@@ -8,12 +8,12 @@ import (
"errors"
"fmt"
- actions_model "forgejo.org/models/actions"
- "forgejo.org/models/db"
- "forgejo.org/modules/graceful"
- "forgejo.org/modules/queue"
+ actions_model "code.gitea.io/gitea/models/actions"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/modules/graceful"
+ "code.gitea.io/gitea/modules/queue"
- "code.forgejo.org/forgejo/runner/v11/act/jobparser"
+ "github.com/nektos/act/pkg/jobparser"
"xorm.io/builder"
)
@@ -59,7 +59,7 @@ func checkJobsOfRun(ctx context.Context, runID int64) error {
for _, job := range jobs {
if status, ok := updates[job.ID]; ok {
job.Status = status
- if n, err := UpdateRunJob(ctx, job, builder.Eq{"status": actions_model.StatusBlocked}, "status"); err != nil {
+ if n, err := actions_model.UpdateRunJob(ctx, job, builder.Eq{"status": actions_model.StatusBlocked}, "status"); err != nil {
return err
} else if n != 1 {
return fmt.Errorf("no affected for updating blocked job %v", job.ID)
@@ -142,7 +142,7 @@ func (r *jobStatusResolver) resolve() map[int64]actions_model.Status {
} else {
// Check if the job has an "if" condition
hasIf := false
- if wfJobs, _ := jobparser.Parse(r.jobMap[id].WorkflowPayload, false); len(wfJobs) == 1 {
+ if wfJobs, _ := jobparser.Parse(r.jobMap[id].WorkflowPayload); len(wfJobs) == 1 {
_, wfJob := wfJobs[0].Job()
hasIf = len(wfJob.If.Value) > 0
}
diff --git a/services/actions/job_emitter_test.go b/services/actions/job_emitter_test.go
index a3e0e95d04..58c2dc3b24 100644
--- a/services/actions/job_emitter_test.go
+++ b/services/actions/job_emitter_test.go
@@ -6,7 +6,7 @@ package actions
import (
"testing"
- actions_model "forgejo.org/models/actions"
+ actions_model "code.gitea.io/gitea/models/actions"
"github.com/stretchr/testify/assert"
)
diff --git a/services/actions/job_parser.go b/services/actions/job_parser.go
deleted file mode 100644
index 8c880977d1..0000000000
--- a/services/actions/job_parser.go
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2025 The Forgejo Authors. All rights reserved.
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-package actions
-
-import (
- "fmt"
-
- "code.forgejo.org/forgejo/runner/v11/act/jobparser"
-)
-
-func jobParser(workflow []byte, options ...jobparser.ParseOption) ([]*jobparser.SingleWorkflow, error) {
- singleWorkflows, err := jobparser.Parse(workflow, false, options...)
- if err != nil {
- return nil, err
- }
- nameToSingleWorkflows := make(map[string][]*jobparser.SingleWorkflow, len(singleWorkflows))
- duplicates := make(map[string]int, len(singleWorkflows))
- for _, singleWorkflow := range singleWorkflows {
- id, job := singleWorkflow.Job()
- nameToSingleWorkflows[job.Name] = append(nameToSingleWorkflows[job.Name], singleWorkflow)
- if len(nameToSingleWorkflows[job.Name]) > 1 {
- duplicates[job.Name]++
- job.Name = fmt.Sprintf("%s-%d", job.Name, duplicates[job.Name])
- if err := singleWorkflow.SetJob(id, job); err != nil {
- return nil, err
- }
- }
- }
- return singleWorkflows, nil
-}
diff --git a/services/actions/job_parser_test.go b/services/actions/job_parser_test.go
deleted file mode 100644
index 9c1361d74e..0000000000
--- a/services/actions/job_parser_test.go
+++ /dev/null
@@ -1,212 +0,0 @@
-// Copyright 2025 The Forgejo Authors. All rights reserved.
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-package actions
-
-import (
- "testing"
-
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
-)
-
-func TestServiceActions_jobParser(t *testing.T) {
- for _, testCase := range []struct {
- name string
- workflow string
- singleWorkflows []string
- }{
- {
- name: "OneJobNoDuplicate",
- workflow: `
-jobs:
- job1:
- runs-on: docker
- steps:
- - run: echo OK
-`,
- singleWorkflows: []string{
- `jobs:
- job1:
- name: job1
- runs-on: docker
- steps:
- - run: echo OK
-`,
- },
- },
- {
- name: "MatrixTwoJobsWithSameJobName",
- workflow: `
-name: test
-jobs:
- job1:
- name: shadowdefaultmatrixgeneratednames
- strategy:
- matrix:
- version: [1.17, 1.19]
- runs-on: docker
- steps:
- - run: echo OK
-`,
- singleWorkflows: []string{
- `name: test
-jobs:
- job1:
- name: shadowdefaultmatrixgeneratednames
- runs-on: docker
- steps:
- - run: echo OK
- strategy:
- matrix:
- version:
- - 1.17
-`,
- `name: test
-jobs:
- job1:
- name: shadowdefaultmatrixgeneratednames-1
- runs-on: docker
- steps:
- - run: echo OK
- strategy:
- matrix:
- version:
- - 1.19
-`,
- },
- },
- {
- name: "MatrixTwoJobsWithMatrixGeneratedNames",
- workflow: `
-name: test
-jobs:
- job1:
- strategy:
- matrix:
- version: [1.17, 1.19]
- runs-on: docker
- steps:
- - run: echo OK
-`,
- singleWorkflows: []string{
- `name: test
-jobs:
- job1:
- name: job1 (1.17)
- runs-on: docker
- steps:
- - run: echo OK
- strategy:
- matrix:
- version:
- - 1.17
-`,
- `name: test
-jobs:
- job1:
- name: job1 (1.19)
- runs-on: docker
- steps:
- - run: echo OK
- strategy:
- matrix:
- version:
- - 1.19
-`,
- },
- },
- {
- name: "MatrixTwoJobsWithDistinctInterpolatedNames",
- workflow: `
-name: test
-jobs:
- job1:
- name: myname-${{ matrix.version }}
- strategy:
- matrix:
- version: [1.17, 1.19]
- runs-on: docker
- steps:
- - run: echo OK
-`,
- singleWorkflows: []string{
- `name: test
-jobs:
- job1:
- name: myname-1.17
- runs-on: docker
- steps:
- - run: echo OK
- strategy:
- matrix:
- version:
- - 1.17
-`,
- `name: test
-jobs:
- job1:
- name: myname-1.19
- runs-on: docker
- steps:
- - run: echo OK
- strategy:
- matrix:
- version:
- - 1.19
-`,
- },
- },
- {
- name: "MatrixTwoJobsWithIdenticalInterpolatedNames",
- workflow: `
-name: test
-jobs:
- job1:
- name: myname-${{ matrix.typo }}
- strategy:
- matrix:
- version: [1.17, 1.19]
- runs-on: docker
- steps:
- - run: echo OK
-`,
- singleWorkflows: []string{
- `name: test
-jobs:
- job1:
- name: myname-
- runs-on: docker
- steps:
- - run: echo OK
- strategy:
- matrix:
- version:
- - 1.17
-`,
- `name: test
-jobs:
- job1:
- name: myname--1
- runs-on: docker
- steps:
- - run: echo OK
- strategy:
- matrix:
- version:
- - 1.19
-`,
- },
- },
- } {
- t.Run(testCase.name, func(t *testing.T) {
- sw, err := jobParser([]byte(testCase.workflow))
- require.NoError(t, err)
- for i, sw := range sw {
- actual, err := sw.Marshal()
- require.NoError(t, err)
- assert.Equal(t, testCase.singleWorkflows[i], string(actual))
- }
- })
- }
-}
diff --git a/services/actions/main_test.go b/services/actions/main_test.go
index 71ec1d3426..49629ecb03 100644
--- a/services/actions/main_test.go
+++ b/services/actions/main_test.go
@@ -6,11 +6,11 @@ package actions
import (
"testing"
- "forgejo.org/models/unittest"
+ "code.gitea.io/gitea/models/unittest"
- _ "forgejo.org/models/actions"
- _ "forgejo.org/models/activities"
- _ "forgejo.org/models/forgefed"
+ _ "code.gitea.io/gitea/models/actions"
+ _ "code.gitea.io/gitea/models/activities"
+ _ "code.gitea.io/gitea/models/forgefed"
)
func TestMain(m *testing.M) {
diff --git a/services/actions/notifier.go b/services/actions/notifier.go
index 7b291d491b..2dd81158a7 100644
--- a/services/actions/notifier.go
+++ b/services/actions/notifier.go
@@ -5,26 +5,21 @@ package actions
import (
"context"
- "errors"
- actions_model "forgejo.org/models/actions"
- issues_model "forgejo.org/models/issues"
- packages_model "forgejo.org/models/packages"
- perm_model "forgejo.org/models/perm"
- access_model "forgejo.org/models/perm/access"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/log"
- "forgejo.org/modules/repository"
- "forgejo.org/modules/setting"
- api "forgejo.org/modules/structs"
- "forgejo.org/modules/util"
- webhook_module "forgejo.org/modules/webhook"
- "forgejo.org/services/convert"
- notify_service "forgejo.org/services/notify"
-
- "xorm.io/builder"
+ issues_model "code.gitea.io/gitea/models/issues"
+ packages_model "code.gitea.io/gitea/models/packages"
+ perm_model "code.gitea.io/gitea/models/perm"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/repository"
+ "code.gitea.io/gitea/modules/setting"
+ api "code.gitea.io/gitea/modules/structs"
+ webhook_module "code.gitea.io/gitea/modules/webhook"
+ "code.gitea.io/gitea/services/convert"
+ notify_service "code.gitea.io/gitea/services/notify"
)
type actionsNotifier struct {
@@ -227,7 +222,7 @@ func notifyIssueChange(ctx context.Context, doer *user_model.User, issue *issues
var apiLabel *api.Label
if action == api.HookIssueLabelUpdated || action == api.HookIssueLabelCleared {
- apiLabel = convert.ToLabel(label, issue.Repo, issue.Repo.Owner)
+ apiLabel = convert.ToLabel(label, issue.Repo, nil)
}
if issue.IsPull {
@@ -343,7 +338,7 @@ func notifyIssueCommentChange(ctx context.Context, doer *user_model.User, commen
newNotifyInputFromIssue(comment.Issue, event).
WithDoer(doer).
WithPayload(payload).
- WithPullRequestData(comment.Issue.PullRequest).
+ WithPullRequest(comment.Issue.PullRequest).
Notify(ctx)
return
}
@@ -780,76 +775,3 @@ func (n *actionsNotifier) MigrateRepository(ctx context.Context, doer, u *user_m
Sender: convert.ToUser(ctx, doer, nil),
}).Notify(ctx)
}
-
-// Call this sendActionRunNowDoneNotificationIfNeeded when there has been an update for an ActionRun.
-// priorRun and updatedRun represent the very same ActionRun, just at different times:
-// priorRun before the update and updatedRun after.
-// The parameter lastRun in the ActionRunNowDone notification represents an entirely different ActionRun:
-// the ActionRun of the same workflow that finished before priorRun/updatedRun.
-func sendActionRunNowDoneNotificationIfNeeded(ctx context.Context, priorRun, updatedRun *actions_model.ActionRun) error {
- if !priorRun.Status.IsDone() && updatedRun.Status.IsDone() {
- lastRun, err := actions_model.GetRunBefore(ctx, updatedRun)
- if err != nil && !errors.Is(err, util.ErrNotExist) {
- return err
- }
- // when no last run was found lastRun is nil
- if lastRun != nil {
- if err = lastRun.LoadAttributes(ctx); err != nil {
- return err
- }
- }
- if err = updatedRun.LoadAttributes(ctx); err != nil {
- return err
- }
- notify_service.ActionRunNowDone(ctx, updatedRun, priorRun.Status, lastRun)
- }
- return nil
-}
-
-// wrapper of UpdateRunWithoutNotification with a call to the ActionRunNowDone notification channel
-func UpdateRun(ctx context.Context, run *actions_model.ActionRun, cols ...string) error {
- // run.ID is the only thing that must be given
- priorRun, err := actions_model.GetRunByID(ctx, run.ID)
- if err != nil {
- return err
- }
-
- if err = actions_model.UpdateRunWithoutNotification(ctx, run, cols...); err != nil {
- return err
- }
-
- updatedRun, err := actions_model.GetRunByID(ctx, run.ID)
- if err != nil {
- return err
- }
- return sendActionRunNowDoneNotificationIfNeeded(ctx, priorRun, updatedRun)
-}
-
-// wrapper of UpdateRunJobWithoutNotification with a call to the ActionRunNowDone notification channel
-func UpdateRunJob(ctx context.Context, job *actions_model.ActionRunJob, cond builder.Cond, cols ...string) (int64, error) {
- runID := job.RunID
- if runID == 0 {
- // job.ID is the only thing that must be given
- // Don't overwrite job here, we'd loose the change we need to make.
- oldJob, err := actions_model.GetRunJobByID(ctx, job.ID)
- if err != nil {
- return 0, err
- }
- runID = oldJob.RunID
- }
- priorRun, err := actions_model.GetRunByID(ctx, runID)
- if err != nil {
- return 0, err
- }
-
- affected, err := actions_model.UpdateRunJobWithoutNotification(ctx, job, cond, cols...)
- if err != nil {
- return affected, err
- }
-
- updatedRun, err := actions_model.GetRunByID(ctx, runID)
- if err != nil {
- return affected, err
- }
- return affected, sendActionRunNowDoneNotificationIfNeeded(ctx, priorRun, updatedRun)
-}
diff --git a/services/actions/notifier_helper.go b/services/actions/notifier_helper.go
index a9978c32cb..0a1dbb162d 100644
--- a/services/actions/notifier_helper.go
+++ b/services/actions/notifier_helper.go
@@ -11,27 +11,27 @@ import (
"slices"
"strings"
- actions_model "forgejo.org/models/actions"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- packages_model "forgejo.org/models/packages"
- access_model "forgejo.org/models/perm/access"
- repo_model "forgejo.org/models/repo"
- unit_model "forgejo.org/models/unit"
- user_model "forgejo.org/models/user"
- actions_module "forgejo.org/modules/actions"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/json"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- api "forgejo.org/modules/structs"
- "forgejo.org/modules/util"
- webhook_module "forgejo.org/modules/webhook"
- "forgejo.org/services/convert"
+ actions_model "code.gitea.io/gitea/models/actions"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ packages_model "code.gitea.io/gitea/models/packages"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ repo_model "code.gitea.io/gitea/models/repo"
+ unit_model "code.gitea.io/gitea/models/unit"
+ user_model "code.gitea.io/gitea/models/user"
+ actions_module "code.gitea.io/gitea/modules/actions"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ api "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/util"
+ webhook_module "code.gitea.io/gitea/modules/webhook"
+ "code.gitea.io/gitea/services/convert"
- "code.forgejo.org/forgejo/runner/v11/act/jobparser"
- "code.forgejo.org/forgejo/runner/v11/act/model"
+ "github.com/nektos/act/pkg/jobparser"
+ "github.com/nektos/act/pkg/model"
)
type methodCtx struct{}
@@ -102,12 +102,6 @@ func (input *notifyInput) WithPayload(payload api.Payloader) *notifyInput {
return input
}
-// for cases like issue comments on PRs, which have the PR data, but don't run on its ref
-func (input *notifyInput) WithPullRequestData(pr *issues_model.PullRequest) *notifyInput {
- input.PullRequest = pr
- return input
-}
-
func (input *notifyInput) WithPullRequest(pr *issues_model.PullRequest) *notifyInput {
input.PullRequest = pr
if input.Ref == "" {
@@ -145,7 +139,7 @@ func notify(ctx context.Context, input *notifyInput) error {
return nil
}
if unit_model.TypeActions.UnitGlobalDisabled() {
- if err := CleanRepoScheduleTasks(ctx, input.Repo, true); err != nil {
+ if err := actions_model.CleanRepoScheduleTasks(ctx, input.Repo, true); err != nil {
log.Error("CleanRepoScheduleTasks: %v", err)
}
return nil
@@ -225,7 +219,7 @@ func notify(ctx context.Context, input *notifyInput) error {
}
}
- if input.PullRequest != nil && !actions_module.IsDefaultBranchWorkflow(input.Event) {
+ if input.PullRequest != nil {
// detect pull_request_target workflows
baseRef := git.BranchPrefix + input.PullRequest.BaseBranch
baseCommit, err := gitRepo.GetCommit(baseRef)
@@ -321,7 +315,7 @@ func handleWorkflows(
}
isForkPullRequest := false
- if pr := input.PullRequest; pr != nil && !actions_module.IsDefaultBranchWorkflow(input.Event) {
+ if pr := input.PullRequest; pr != nil {
switch pr.Flow {
case issues_model.PullRequestFlowGithub:
isForkPullRequest = pr.IsFromFork()
@@ -351,14 +345,6 @@ func handleWorkflows(
Status: actions_model.StatusWaiting,
}
- if workflow, err := model.ReadWorkflow(bytes.NewReader(dwf.Content), false); err == nil {
- notifications, err := workflow.Notifications()
- if err != nil {
- log.Error("Notifications: %w", err)
- }
- run.NotifyEmail = notifications
- }
-
need, err := ifNeedApproval(ctx, run, input.Repo, input.Doer)
if err != nil {
log.Error("check if need approval for repo %d with user %d: %v", input.Repo.ID, input.Doer.ID, err)
@@ -378,19 +364,16 @@ func handleWorkflows(
continue
}
- jobs, err := jobParser(dwf.Content, jobparser.WithVars(vars))
+ jobs, err := jobparser.Parse(dwf.Content, jobparser.WithVars(vars))
if err != nil {
- run.Status = actions_model.StatusFailure
- log.Info("jobparser.Parse: invalid workflow, setting job status to failed: %v", err)
- jobs = []*jobparser.SingleWorkflow{{
- Name: dwf.EntryName,
- }}
+ log.Error("jobparser.Parse: %v", err)
+ continue
}
// cancel running jobs if the event is push or pull_request_sync
if run.Event == webhook_module.HookEventPush ||
run.Event == webhook_module.HookEventPullRequestSync {
- if err := CancelPreviousJobs(
+ if err := actions_model.CancelPreviousJobs(
ctx,
run.RepoID,
run.Ref,
@@ -521,7 +504,7 @@ func handleSchedules(
log.Error("CountSchedules: %v", err)
return err
} else if count > 0 {
- if err := CleanRepoScheduleTasks(ctx, input.Repo, false); err != nil {
+ if err := actions_model.CleanRepoScheduleTasks(ctx, input.Repo, false); err != nil {
log.Error("CleanRepoScheduleTasks: %v", err)
}
}
@@ -543,7 +526,7 @@ func handleSchedules(
crons := make([]*actions_model.ActionSchedule, 0, len(detectedWorkflows))
for _, dwf := range detectedWorkflows {
// Check cron job condition. Only working in default branch
- workflow, err := model.ReadWorkflow(bytes.NewReader(dwf.Content), false)
+ workflow, err := model.ReadWorkflow(bytes.NewReader(dwf.Content))
if err != nil {
log.Error("ReadWorkflow: %v", err)
continue
diff --git a/services/actions/notifier_helper_test.go b/services/actions/notifier_helper_test.go
index 525103927b..0fa40c0168 100644
--- a/services/actions/notifier_helper_test.go
+++ b/services/actions/notifier_helper_test.go
@@ -6,18 +6,11 @@ package actions
import (
"testing"
- actions_model "forgejo.org/models/actions"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unittest"
- user_model "forgejo.org/models/user"
- actions_module "forgejo.org/modules/actions"
- "forgejo.org/modules/git"
- api "forgejo.org/modules/structs"
- webhook_module "forgejo.org/modules/webhook"
+ actions_model "code.gitea.io/gitea/models/actions"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/unittest"
+ webhook_module "code.gitea.io/gitea/modules/webhook"
- "code.forgejo.org/forgejo/runner/v11/act/jobparser"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@@ -56,91 +49,3 @@ func Test_SkipPullRequestEvent(t *testing.T) {
unittest.AssertSuccessfulInsert(t, run)
assert.True(t, SkipPullRequestEvent(db.DefaultContext, webhook_module.HookEventPullRequestSync, repoID, commitSHA))
}
-
-func Test_IssueCommentOnForkPullRequestEvent(t *testing.T) {
- require.NoError(t, unittest.PrepareTestDatabase())
-
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10})
- doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
- pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 3})
- require.NoError(t, pr.LoadIssue(db.DefaultContext))
-
- require.True(t, pr.IsFromFork())
-
- commit := &git.Commit{
- ID: git.MustIDFromString("0000000000000000000000000000000000000000"),
- CommitMessage: "test",
- }
- detectedWorkflows := []*actions_module.DetectedWorkflow{
- {
- TriggerEvent: &jobparser.Event{
- Name: "issue_comment",
- },
- },
- }
- input := ¬ifyInput{
- Repo: repo,
- Doer: doer,
- Event: webhook_module.HookEventIssueComment,
- PullRequest: pr,
- Payload: &api.IssueCommentPayload{},
- }
-
- unittest.AssertSuccessfulDelete(t, &actions_model.ActionRun{RepoID: repo.ID})
-
- err := handleWorkflows(db.DefaultContext, detectedWorkflows, commit, input, "")
- require.NoError(t, err)
-
- runs, err := db.Find[actions_model.ActionRun](db.DefaultContext, actions_model.FindRunOptions{
- RepoID: repo.ID,
- })
- require.NoError(t, err)
- require.Len(t, runs, 1)
-
- assert.Equal(t, webhook_module.HookEventIssueComment, runs[0].Event)
- assert.False(t, runs[0].IsForkPullRequest)
-}
-
-func Test_OpenForkPullRequestEvent(t *testing.T) {
- require.NoError(t, unittest.PrepareTestDatabase())
-
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10})
- doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
- pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 3})
- require.NoError(t, pr.LoadIssue(db.DefaultContext))
-
- require.True(t, pr.IsFromFork())
-
- commit := &git.Commit{
- ID: git.MustIDFromString("0000000000000000000000000000000000000000"),
- CommitMessage: "test",
- }
- detectedWorkflows := []*actions_module.DetectedWorkflow{
- {
- TriggerEvent: &jobparser.Event{
- Name: "pull_request",
- },
- },
- }
- input := ¬ifyInput{
- Repo: repo,
- Doer: doer,
- Event: webhook_module.HookEventPullRequest,
- PullRequest: pr,
- Payload: &api.PullRequestPayload{},
- }
-
- unittest.AssertSuccessfulDelete(t, &actions_model.ActionRun{RepoID: repo.ID})
-
- err := handleWorkflows(db.DefaultContext, detectedWorkflows, commit, input, "")
- require.NoError(t, err)
-
- runs, err := db.Find[actions_model.ActionRun](db.DefaultContext, actions_model.FindRunOptions{
- RepoID: repo.ID,
- })
- require.NoError(t, err)
- require.Len(t, runs, 1)
-
- assert.Equal(t, webhook_module.HookEventPullRequest, runs[0].Event)
- assert.True(t, runs[0].IsForkPullRequest)
-}
diff --git a/services/actions/rerun.go b/services/actions/rerun.go
index f6dd4af5c7..60f6650905 100644
--- a/services/actions/rerun.go
+++ b/services/actions/rerun.go
@@ -4,8 +4,8 @@
package actions
import (
- actions_model "forgejo.org/models/actions"
- "forgejo.org/modules/container"
+ actions_model "code.gitea.io/gitea/models/actions"
+ "code.gitea.io/gitea/modules/container"
)
// GetAllRerunJobs get all jobs that need to be rerun when job should be rerun
diff --git a/services/actions/rerun_test.go b/services/actions/rerun_test.go
index 4b822e8da1..a98de7b788 100644
--- a/services/actions/rerun_test.go
+++ b/services/actions/rerun_test.go
@@ -6,7 +6,7 @@ package actions
import (
"testing"
- actions_model "forgejo.org/models/actions"
+ actions_model "code.gitea.io/gitea/models/actions"
"github.com/stretchr/testify/assert"
)
diff --git a/services/actions/schedule_tasks.go b/services/actions/schedule_tasks.go
index 07ff7b3187..18f3324fd2 100644
--- a/services/actions/schedule_tasks.go
+++ b/services/actions/schedule_tasks.go
@@ -4,24 +4,19 @@
package actions
import (
- "bytes"
"context"
- "errors"
"fmt"
"time"
- actions_model "forgejo.org/models/actions"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unit"
- "forgejo.org/modules/log"
- "forgejo.org/modules/timeutil"
- webhook_module "forgejo.org/modules/webhook"
+ actions_model "code.gitea.io/gitea/models/actions"
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unit"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/timeutil"
+ webhook_module "code.gitea.io/gitea/modules/webhook"
- "code.forgejo.org/forgejo/runner/v11/act/jobparser"
- act_model "code.forgejo.org/forgejo/runner/v11/act/model"
- "github.com/robfig/cron/v3"
- "xorm.io/builder"
+ "github.com/nektos/act/pkg/jobparser"
)
// StartScheduleTasks start the task
@@ -60,7 +55,7 @@ func startTasks(ctx context.Context) error {
// cancel running jobs if the event is push
if row.Schedule.Event == webhook_module.HookEventPush {
// cancel running jobs of the same workflow
- if err := CancelPreviousJobs(
+ if err := actions_model.CancelPreviousJobs(
ctx,
row.RepoID,
row.Schedule.Ref,
@@ -84,33 +79,20 @@ func startTasks(ctx context.Context) error {
}
return fmt.Errorf("GetUnit: %w", err)
}
- actionConfig := cfg.ActionsConfig()
- if actionConfig.IsWorkflowDisabled(row.Schedule.WorkflowID) {
+ if cfg.ActionsConfig().IsWorkflowDisabled(row.Schedule.WorkflowID) {
continue
}
- createAndSchedule := func(row *actions_model.ActionScheduleSpec) (cron.Schedule, error) {
- if err := CreateScheduleTask(ctx, row.Schedule); err != nil {
- return nil, fmt.Errorf("CreateScheduleTask: %v", err)
- }
-
- // Parse the spec
- schedule, err := row.Parse()
- if err != nil {
- return nil, fmt.Errorf("Parse(Spec=%v): %v", row.Spec, err)
- }
- return schedule, nil
+ if err := CreateScheduleTask(ctx, row.Schedule); err != nil {
+ log.Error("CreateScheduleTask: %v", err)
+ return err
}
- schedule, err := createAndSchedule(row)
+ // Parse the spec
+ schedule, err := row.Parse()
if err != nil {
- log.Error("RepoID=%v WorkflowID=%v: %v", row.Schedule.RepoID, row.Schedule.WorkflowID, err)
- actionConfig.DisableWorkflow(row.Schedule.WorkflowID)
- if err := repo_model.UpdateRepoUnit(ctx, cfg); err != nil {
- log.Error("RepoID=%v WorkflowID=%v: CreateScheduleTask: %v", row.Schedule.RepoID, row.Schedule.WorkflowID, err)
- return err
- }
- continue
+ log.Error("Parse: %v", err)
+ return err
}
// Update the spec's next run time and previous run time
@@ -156,18 +138,8 @@ func CreateScheduleTask(ctx context.Context, cron *actions_model.ActionSchedule)
return err
}
- workflow, err := act_model.ReadWorkflow(bytes.NewReader(cron.Content), false)
- if err != nil {
- return err
- }
- notifications, err := workflow.Notifications()
- if err != nil {
- return err
- }
- run.NotifyEmail = notifications
-
// Parse the workflow specification from the cron schedule
- workflows, err := jobParser(cron.Content, jobparser.WithVars(vars))
+ workflows, err := jobparser.Parse(cron.Content, jobparser.WithVars(vars))
if err != nil {
return err
}
@@ -180,93 +152,3 @@ func CreateScheduleTask(ctx context.Context, cron *actions_model.ActionSchedule)
// Return nil if no errors occurred
return nil
}
-
-// CancelPreviousJobs cancels all previous jobs of the same repository, reference, workflow, and event.
-// It's useful when a new run is triggered, and all previous runs needn't be continued anymore.
-func CancelPreviousJobs(ctx context.Context, repoID int64, ref, workflowID string, event webhook_module.HookEventType) error {
- // Find all runs in the specified repository, reference, and workflow with non-final status
- runs, total, err := db.FindAndCount[actions_model.ActionRun](ctx, actions_model.FindRunOptions{
- RepoID: repoID,
- Ref: ref,
- WorkflowID: workflowID,
- TriggerEvent: event,
- Status: []actions_model.Status{actions_model.StatusRunning, actions_model.StatusWaiting, actions_model.StatusBlocked},
- })
- if err != nil {
- return err
- }
-
- // If there are no runs found, there's no need to proceed with cancellation, so return nil.
- if total == 0 {
- return nil
- }
-
- // Iterate over each found run and cancel its associated jobs.
- for _, run := range runs {
- // Find all jobs associated with the current run.
- jobs, err := db.Find[actions_model.ActionRunJob](ctx, actions_model.FindRunJobOptions{
- RunID: run.ID,
- })
- if err != nil {
- return err
- }
-
- // Iterate over each job and attempt to cancel it.
- for _, job := range jobs {
- // Skip jobs that are already in a terminal state (completed, cancelled, etc.).
- status := job.Status
- if status.IsDone() {
- continue
- }
-
- // If the job has no associated task (probably an error), set its status to 'Cancelled' and stop it.
- if job.TaskID == 0 {
- job.Status = actions_model.StatusCancelled
- job.Stopped = timeutil.TimeStampNow()
-
- // Update the job's status and stopped time in the database.
- n, err := UpdateRunJob(ctx, job, builder.Eq{"task_id": 0}, "status", "stopped")
- if err != nil {
- return err
- }
-
- // If the update affected 0 rows, it means the job has changed in the meantime, so we need to try again.
- if n == 0 {
- return errors.New("job has changed, try again")
- }
-
- // Continue with the next job.
- continue
- }
-
- // If the job has an associated task, try to stop the task, effectively cancelling the job.
- if err := StopTask(ctx, job.TaskID, actions_model.StatusCancelled); err != nil {
- return err
- }
- }
- }
-
- // Return nil to indicate successful cancellation of all running and waiting jobs.
- return nil
-}
-
-func CleanRepoScheduleTasks(ctx context.Context, repo *repo_model.Repository, cancelPreviousJobs bool) error {
- // If actions disabled when there is schedule task, this will remove the outdated schedule tasks
- // There is no other place we can do this because the app.ini will be changed manually
- if err := actions_model.DeleteScheduleTaskByRepo(ctx, repo.ID); err != nil {
- return fmt.Errorf("DeleteCronTaskByRepo: %v", err)
- }
- if cancelPreviousJobs {
- // cancel running cron jobs of this repository and delete old schedules
- if err := CancelPreviousJobs(
- ctx,
- repo.ID,
- repo.DefaultBranch,
- "",
- webhook_module.HookEventSchedule,
- ); err != nil {
- return fmt.Errorf("CancelPreviousJobs: %v", err)
- }
- }
- return nil
-}
diff --git a/services/actions/schedule_tasks_test.go b/services/actions/schedule_tasks_test.go
deleted file mode 100644
index 31ed5ec813..0000000000
--- a/services/actions/schedule_tasks_test.go
+++ /dev/null
@@ -1,175 +0,0 @@
-// Copyright 2025 The Forgejo Authors. All rights reserved.
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-package actions
-
-import (
- "testing"
-
- actions_model "forgejo.org/models/actions"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unit"
- "forgejo.org/models/unittest"
- webhook_module "forgejo.org/modules/webhook"
-
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
-)
-
-func TestServiceActions_startTask(t *testing.T) {
- defer unittest.OverrideFixtures("services/actions/TestServiceActions_startTask")()
- require.NoError(t, unittest.PrepareTestDatabase())
-
- // Load fixtures that are corrupted and create one valid scheduled workflow
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4})
-
- workflowID := "some.yml"
- schedules := []*actions_model.ActionSchedule{
- {
- Title: "scheduletitle1",
- RepoID: repo.ID,
- OwnerID: repo.OwnerID,
- WorkflowID: workflowID,
- TriggerUserID: repo.OwnerID,
- Ref: "branch",
- CommitSHA: "fakeSHA",
- Event: webhook_module.HookEventSchedule,
- EventPayload: "fakepayload",
- Specs: []string{"* * * * *"},
- Content: []byte(
- `
-jobs:
- job2:
- runs-on: ubuntu-latest
- steps:
- - run: true
-`),
- },
- }
-
- require.Equal(t, 2, unittest.GetCount(t, actions_model.ActionScheduleSpec{}))
- require.NoError(t, actions_model.CreateScheduleTask(t.Context(), schedules))
- require.Equal(t, 3, unittest.GetCount(t, actions_model.ActionScheduleSpec{}))
- _, err := db.GetEngine(db.DefaultContext).Exec("UPDATE `action_schedule_spec` SET next = 1")
- require.NoError(t, err)
-
- // After running startTasks an ActionRun row is created for the valid scheduled workflow
- require.Empty(t, unittest.GetCount(t, actions_model.ActionRun{WorkflowID: workflowID}))
- require.NoError(t, startTasks(t.Context()))
- require.NotEmpty(t, unittest.GetCount(t, actions_model.ActionRun{WorkflowID: workflowID}))
-
- // The invalid workflows loaded from the fixtures are disabled
- repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4})
- actionUnit, err := repo.GetUnit(t.Context(), unit.TypeActions)
- require.NoError(t, err)
- actionConfig := actionUnit.ActionsConfig()
- assert.True(t, actionConfig.IsWorkflowDisabled("workflow2.yml"))
- assert.True(t, actionConfig.IsWorkflowDisabled("workflow1.yml"))
- assert.False(t, actionConfig.IsWorkflowDisabled("some.yml"))
-}
-
-func TestCreateScheduleTask(t *testing.T) {
- require.NoError(t, unittest.PrepareTestDatabase())
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2, OwnerID: 2})
-
- assertConstant := func(t *testing.T, cron *actions_model.ActionSchedule, run *actions_model.ActionRun) {
- t.Helper()
- assert.Equal(t, cron.Title, run.Title)
- assert.Equal(t, cron.RepoID, run.RepoID)
- assert.Equal(t, cron.OwnerID, run.OwnerID)
- assert.Equal(t, cron.WorkflowID, run.WorkflowID)
- assert.Equal(t, cron.TriggerUserID, run.TriggerUserID)
- assert.Equal(t, cron.Ref, run.Ref)
- assert.Equal(t, cron.CommitSHA, run.CommitSHA)
- assert.Equal(t, cron.Event, run.Event)
- assert.Equal(t, cron.EventPayload, run.EventPayload)
- assert.Equal(t, cron.ID, run.ScheduleID)
- assert.Equal(t, actions_model.StatusWaiting, run.Status)
- }
-
- assertMutable := func(t *testing.T, expected, run *actions_model.ActionRun) {
- t.Helper()
- assert.Equal(t, expected.NotifyEmail, run.NotifyEmail)
- }
-
- testCases := []struct {
- name string
- cron actions_model.ActionSchedule
- want []actions_model.ActionRun
- }{
- {
- name: "simple",
- cron: actions_model.ActionSchedule{
- Title: "scheduletitle1",
- RepoID: repo.ID,
- OwnerID: repo.OwnerID,
- WorkflowID: "some.yml",
- TriggerUserID: repo.OwnerID,
- Ref: "branch",
- CommitSHA: "fakeSHA",
- Event: webhook_module.HookEventSchedule,
- EventPayload: "fakepayload",
- Content: []byte(
- `
-name: test
-on: push
-jobs:
- job2:
- runs-on: ubuntu-latest
- steps:
- - run: true
-`),
- },
- want: []actions_model.ActionRun{
- {
- Title: "scheduletitle1",
- NotifyEmail: false,
- },
- },
- },
- {
- name: "enable-email-notifications is true",
- cron: actions_model.ActionSchedule{
- Title: "scheduletitle2",
- RepoID: repo.ID,
- OwnerID: repo.OwnerID,
- WorkflowID: "some.yml",
- TriggerUserID: repo.OwnerID,
- Ref: "branch",
- CommitSHA: "fakeSHA",
- Event: webhook_module.HookEventSchedule,
- EventPayload: "fakepayload",
- Content: []byte(
- `
-name: test
-enable-email-notifications: true
-on: push
-jobs:
- job2:
- runs-on: ubuntu-latest
- steps:
- - run: true
-`),
- },
- want: []actions_model.ActionRun{
- {
- Title: "scheduletitle2",
- NotifyEmail: true,
- },
- },
- },
- }
- for _, testCase := range testCases {
- t.Run(testCase.name, func(t *testing.T) {
- require.NoError(t, CreateScheduleTask(t.Context(), &testCase.cron))
- require.Equal(t, len(testCase.want), unittest.GetCount(t, actions_model.ActionRun{RepoID: repo.ID}))
- for _, expected := range testCase.want {
- run := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{Title: expected.Title})
- assertConstant(t, &testCase.cron, run)
- assertMutable(t, &expected, run)
- }
- unittest.AssertSuccessfulDelete(t, actions_model.ActionRun{RepoID: repo.ID})
- })
- }
-}
diff --git a/services/actions/task.go b/services/actions/task.go
index bb319c7d05..bc54ade347 100644
--- a/services/actions/task.go
+++ b/services/actions/task.go
@@ -5,18 +5,14 @@ package actions
import (
"context"
- "errors"
"fmt"
- actions_model "forgejo.org/models/actions"
- "forgejo.org/models/db"
- secret_model "forgejo.org/models/secret"
- "forgejo.org/modules/timeutil"
- "forgejo.org/modules/util"
+ actions_model "code.gitea.io/gitea/models/actions"
+ "code.gitea.io/gitea/models/db"
+ secret_model "code.gitea.io/gitea/models/secret"
runnerv1 "code.gitea.io/actions-proto-go/runner/v1"
"google.golang.org/protobuf/types/known/structpb"
- "google.golang.org/protobuf/types/known/timestamppb"
)
func PickTask(ctx context.Context, runner *actions_model.ActionRunner) (*runnerv1.Task, bool, error) {
@@ -109,144 +105,3 @@ func findTaskNeeds(ctx context.Context, taskJob *actions_model.ActionRunJob) (ma
}
return ret, nil
}
-
-func StopTask(ctx context.Context, taskID int64, status actions_model.Status) error {
- if !status.IsDone() {
- return fmt.Errorf("cannot stop task with status %v", status)
- }
- e := db.GetEngine(ctx)
-
- task := &actions_model.ActionTask{}
- if has, err := e.ID(taskID).Get(task); err != nil {
- return err
- } else if !has {
- return util.ErrNotExist
- }
- if task.Status.IsDone() {
- return nil
- }
-
- now := timeutil.TimeStampNow()
- task.Status = status
- task.Stopped = now
- if _, err := UpdateRunJob(ctx, &actions_model.ActionRunJob{
- ID: task.JobID,
- Status: task.Status,
- Stopped: task.Stopped,
- }, nil); err != nil {
- return err
- }
-
- if err := actions_model.UpdateTask(ctx, task, "status", "stopped"); err != nil {
- return err
- }
-
- if err := task.LoadAttributes(ctx); err != nil {
- return err
- }
-
- for _, step := range task.Steps {
- if !step.Status.IsDone() {
- step.Status = status
- if step.Started == 0 {
- step.Started = now
- }
- step.Stopped = now
- }
- if _, err := e.ID(step.ID).Update(step); err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// UpdateTaskByState updates the task by the state.
-// It will always update the task if the state is not final, even there is no change.
-// So it will update ActionTask.Updated to avoid the task being judged as a zombie task.
-func UpdateTaskByState(ctx context.Context, runnerID int64, state *runnerv1.TaskState) (*actions_model.ActionTask, error) {
- stepStates := map[int64]*runnerv1.StepState{}
- for _, v := range state.Steps {
- stepStates[v.Id] = v
- }
-
- ctx, commiter, err := db.TxContext(ctx)
- if err != nil {
- return nil, err
- }
- defer commiter.Close()
-
- e := db.GetEngine(ctx)
-
- task := &actions_model.ActionTask{}
- if has, err := e.ID(state.Id).Get(task); err != nil {
- return nil, err
- } else if !has {
- return nil, util.ErrNotExist
- } else if runnerID != task.RunnerID {
- return nil, errors.New("invalid runner for task")
- }
-
- if task.Status.IsDone() {
- // the state is final, do nothing
- return task, nil
- }
-
- // state.Result is not unspecified means the task is finished
- if state.Result != runnerv1.Result_RESULT_UNSPECIFIED {
- task.Status = actions_model.Status(state.Result)
- task.Stopped = timeutil.TimeStamp(state.StoppedAt.AsTime().Unix())
- if err := actions_model.UpdateTask(ctx, task, "status", "stopped"); err != nil {
- return nil, err
- }
- if _, err := UpdateRunJob(ctx, &actions_model.ActionRunJob{
- ID: task.JobID,
- Status: task.Status,
- Stopped: task.Stopped,
- }, nil); err != nil {
- return nil, err
- }
- } else {
- // Force update ActionTask.Updated to avoid the task being judged as a zombie task
- task.Updated = timeutil.TimeStampNow()
- if err := actions_model.UpdateTask(ctx, task, "updated"); err != nil {
- return nil, err
- }
- }
-
- if err := task.LoadAttributes(ctx); err != nil {
- return nil, err
- }
-
- for _, step := range task.Steps {
- var result runnerv1.Result
- if v, ok := stepStates[step.Index]; ok {
- result = v.Result
- step.LogIndex = v.LogIndex
- step.LogLength = v.LogLength
- step.Started = convertTimestamp(v.StartedAt)
- step.Stopped = convertTimestamp(v.StoppedAt)
- }
- if result != runnerv1.Result_RESULT_UNSPECIFIED {
- step.Status = actions_model.Status(result)
- } else if step.Started != 0 {
- step.Status = actions_model.StatusRunning
- }
- if _, err := e.ID(step.ID).Update(step); err != nil {
- return nil, err
- }
- }
-
- if err := commiter.Commit(); err != nil {
- return nil, err
- }
-
- return task, nil
-}
-
-func convertTimestamp(timestamp *timestamppb.Timestamp) timeutil.TimeStamp {
- if timestamp.GetSeconds() == 0 && timestamp.GetNanos() == 0 {
- return timeutil.TimeStamp(0)
- }
- return timeutil.TimeStamp(timestamp.AsTime().Unix())
-}
diff --git a/services/actions/variables.go b/services/actions/variables.go
index a9f42105a3..a5703898ab 100644
--- a/services/actions/variables.go
+++ b/services/actions/variables.go
@@ -8,10 +8,10 @@ import (
"regexp"
"strings"
- actions_model "forgejo.org/models/actions"
- "forgejo.org/modules/log"
- "forgejo.org/modules/util"
- secret_service "forgejo.org/services/secrets"
+ actions_model "code.gitea.io/gitea/models/actions"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/util"
+ secret_service "code.gitea.io/gitea/services/secrets"
)
func CreateVariable(ctx context.Context, ownerID, repoID int64, name, data string) (*actions_model.ActionVariable, error) {
@@ -87,7 +87,7 @@ func GetVariable(ctx context.Context, opts actions_model.FindVariablesOpts) (*ac
// https://docs.github.com/en/actions/learn-github-actions/variables#naming-conventions-for-configuration-variables
// https://docs.github.com/en/actions/security-guides/encrypted-secrets#naming-your-secrets
var (
- forbiddenEnvNameCIRx = regexp.MustCompile("(?i)^CI$")
+ forbiddenEnvNameCIRx = regexp.MustCompile("(?i)^CI")
)
func envNameCIRegexMatch(name string) error {
diff --git a/services/actions/variables_test.go b/services/actions/variables_test.go
deleted file mode 100644
index f69bc674e1..0000000000
--- a/services/actions/variables_test.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2025 The Forgejo Authors. All rights reserved.
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-package actions
-
-import (
- "testing"
-
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
-)
-
-func TestServicesAction_envNameCIRegexMatch(t *testing.T) {
- require.ErrorContains(t, envNameCIRegexMatch("ci"), "cannot be ci")
- require.ErrorContains(t, envNameCIRegexMatch("CI"), "cannot be ci")
- assert.NoError(t, envNameCIRegexMatch("CI_SOMETHING"))
-}
diff --git a/services/actions/workflows.go b/services/actions/workflows.go
index 27d05c9043..e3e342264d 100644
--- a/services/actions/workflows.go
+++ b/services/actions/workflows.go
@@ -10,22 +10,22 @@ import (
"fmt"
"strconv"
- actions_model "forgejo.org/models/actions"
- "forgejo.org/models/perm"
- "forgejo.org/models/perm/access"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/user"
- "forgejo.org/modules/actions"
- "forgejo.org/modules/git"
- "forgejo.org/modules/json"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/structs"
- "forgejo.org/modules/util"
- "forgejo.org/modules/webhook"
- "forgejo.org/services/convert"
+ actions_model "code.gitea.io/gitea/models/actions"
+ "code.gitea.io/gitea/models/perm"
+ "code.gitea.io/gitea/models/perm/access"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/actions"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/modules/webhook"
+ "code.gitea.io/gitea/services/convert"
- "code.forgejo.org/forgejo/runner/v11/act/jobparser"
- act_model "code.forgejo.org/forgejo/runner/v11/act/model"
+ "github.com/nektos/act/pkg/jobparser"
+ act_model "github.com/nektos/act/pkg/model"
)
type InputRequiredErr struct {
@@ -56,7 +56,7 @@ func (entry *Workflow) Dispatch(ctx context.Context, inputGetter InputValueGette
return nil, nil, err
}
- wf, err := act_model.ReadWorkflow(bytes.NewReader(content), false)
+ wf, err := act_model.ReadWorkflow(bytes.NewReader(content))
if err != nil {
return nil, nil, err
}
@@ -111,11 +111,6 @@ func (entry *Workflow) Dispatch(ctx context.Context, inputGetter InputValueGette
return nil, nil, err
}
- notifications, err := wf.Notifications()
- if err != nil {
- return nil, nil, err
- }
-
run := &actions_model.ActionRun{
Title: title,
RepoID: repo.ID,
@@ -130,7 +125,6 @@ func (entry *Workflow) Dispatch(ctx context.Context, inputGetter InputValueGette
EventPayload: string(p),
TriggerEvent: string(webhook.HookEventWorkflowDispatch),
Status: actions_model.StatusWaiting,
- NotifyEmail: notifications,
}
vars, err := actions_model.GetVariablesOfRun(ctx, run)
@@ -138,7 +132,7 @@ func (entry *Workflow) Dispatch(ctx context.Context, inputGetter InputValueGette
return nil, nil, err
}
- jobs, err := jobParser(content, jobparser.WithVars(vars))
+ jobs, err := jobparser.Parse(content, jobparser.WithVars(vars))
if err != nil {
return nil, nil, err
}
diff --git a/services/agit/agit.go b/services/agit/agit.go
index 8ef641629a..a18f9ef728 100644
--- a/services/agit/agit.go
+++ b/services/agit/agit.go
@@ -9,15 +9,15 @@ import (
"os"
"strings"
- issues_model "forgejo.org/models/issues"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/git/pushoptions"
- "forgejo.org/modules/log"
- "forgejo.org/modules/private"
- notify_service "forgejo.org/services/notify"
- pull_service "forgejo.org/services/pull"
+ issues_model "code.gitea.io/gitea/models/issues"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/git/pushoptions"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/private"
+ notify_service "code.gitea.io/gitea/services/notify"
+ pull_service "code.gitea.io/gitea/services/pull"
)
// ProcReceive handle proc receive work
@@ -221,7 +221,7 @@ func ProcReceive(ctx context.Context, repo *repo_model.Repository, gitRepo *git.
}
// Validate pull request.
- pull_service.ValidatePullRequest(ctx, pr, opts.NewCommitIDs[i], oldCommitID, pusher)
+ pull_service.ValidatePullRequest(ctx, pr, oldCommitID, opts.NewCommitIDs[i], pusher)
// TODO: call `InvalidateCodeComments`
diff --git a/services/asymkey/deploy_key.go b/services/asymkey/deploy_key.go
index 4a2cb53eec..e127cbfc6e 100644
--- a/services/asymkey/deploy_key.go
+++ b/services/asymkey/deploy_key.go
@@ -6,10 +6,10 @@ package asymkey
import (
"context"
- "forgejo.org/models"
- asymkey_model "forgejo.org/models/asymkey"
- "forgejo.org/models/db"
- user_model "forgejo.org/models/user"
+ "code.gitea.io/gitea/models"
+ asymkey_model "code.gitea.io/gitea/models/asymkey"
+ "code.gitea.io/gitea/models/db"
+ user_model "code.gitea.io/gitea/models/user"
)
// DeleteDeployKey deletes deploy key from its repository authorized_keys file if needed.
diff --git a/services/asymkey/main_test.go b/services/asymkey/main_test.go
index 8ba76668b1..060cc78cec 100644
--- a/services/asymkey/main_test.go
+++ b/services/asymkey/main_test.go
@@ -6,11 +6,11 @@ package asymkey
import (
"testing"
- "forgejo.org/models/unittest"
+ "code.gitea.io/gitea/models/unittest"
- _ "forgejo.org/models/actions"
- _ "forgejo.org/models/activities"
- _ "forgejo.org/models/forgefed"
+ _ "code.gitea.io/gitea/models/actions"
+ _ "code.gitea.io/gitea/models/activities"
+ _ "code.gitea.io/gitea/models/forgefed"
)
func TestMain(m *testing.M) {
diff --git a/services/asymkey/sign.go b/services/asymkey/sign.go
index 527f6edd92..8fb569939c 100644
--- a/services/asymkey/sign.go
+++ b/services/asymkey/sign.go
@@ -8,17 +8,18 @@ import (
"fmt"
"strings"
- asymkey_model "forgejo.org/models/asymkey"
- "forgejo.org/models/auth"
- git_model "forgejo.org/models/git"
- issues_model "forgejo.org/models/issues"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/log"
- "forgejo.org/modules/process"
- "forgejo.org/modules/setting"
+ asymkey_model "code.gitea.io/gitea/models/asymkey"
+ "code.gitea.io/gitea/models/auth"
+ "code.gitea.io/gitea/models/db"
+ git_model "code.gitea.io/gitea/models/git"
+ issues_model "code.gitea.io/gitea/models/issues"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/process"
+ "code.gitea.io/gitea/modules/setting"
)
type signingMode string
@@ -89,13 +90,6 @@ func SigningKey(ctx context.Context, repoPath string) (string, *git.Signature) {
return "", nil
}
- if setting.Repository.Signing.Format == "ssh" {
- return setting.Repository.Signing.SigningKey, &git.Signature{
- Name: setting.Repository.Signing.SigningName,
- Email: setting.Repository.Signing.SigningEmail,
- }
- }
-
if setting.Repository.Signing.SigningKey == "default" || setting.Repository.Signing.SigningKey == "" {
// Can ignore the error here as it means that commit.gpgsign is not set
value, _, _ := git.NewCommand(ctx, "config", "--get", "commit.gpgsign").RunStdString(&git.RunOpts{Dir: repoPath})
@@ -151,19 +145,22 @@ Loop:
case always:
break Loop
case pubkey:
- hasPubKey, err := asymkey_model.HasAsymKeyByUID(ctx, u.ID)
+ keys, err := db.Find[asymkey_model.GPGKey](ctx, asymkey_model.FindGPGKeyOptions{
+ OwnerID: u.ID,
+ IncludeSubKeys: true,
+ })
if err != nil {
return false, "", nil, err
}
- if !hasPubKey {
+ if len(keys) == 0 {
return false, "", nil, &ErrWontSign{pubkey}
}
case twofa:
- hasTwoFactor, err := auth.HasTwoFactorByUID(ctx, u.ID)
- if err != nil {
+ twofaModel, err := auth.GetTwoFactorByUID(ctx, u.ID)
+ if err != nil && !auth.IsErrTwoFactorNotEnrolled(err) {
return false, "", nil, err
}
- if !hasTwoFactor {
+ if twofaModel == nil {
return false, "", nil, &ErrWontSign{twofa}
}
}
@@ -188,19 +185,22 @@ Loop:
case always:
break Loop
case pubkey:
- hasPubKey, err := asymkey_model.HasAsymKeyByUID(ctx, u.ID)
+ keys, err := db.Find[asymkey_model.GPGKey](ctx, asymkey_model.FindGPGKeyOptions{
+ OwnerID: u.ID,
+ IncludeSubKeys: true,
+ })
if err != nil {
return false, "", nil, err
}
- if !hasPubKey {
+ if len(keys) == 0 {
return false, "", nil, &ErrWontSign{pubkey}
}
case twofa:
- hasTwoFactor, err := auth.HasTwoFactorByUID(ctx, u.ID)
- if err != nil {
+ twofaModel, err := auth.GetTwoFactorByUID(ctx, u.ID)
+ if err != nil && !auth.IsErrTwoFactorNotEnrolled(err) {
return false, "", nil, err
}
- if !hasTwoFactor {
+ if twofaModel == nil {
return false, "", nil, &ErrWontSign{twofa}
}
case parentSigned:
@@ -241,19 +241,22 @@ Loop:
case always:
break Loop
case pubkey:
- hasPubKey, err := asymkey_model.HasAsymKeyByUID(ctx, u.ID)
+ keys, err := db.Find[asymkey_model.GPGKey](ctx, asymkey_model.FindGPGKeyOptions{
+ OwnerID: u.ID,
+ IncludeSubKeys: true,
+ })
if err != nil {
return false, "", nil, err
}
- if !hasPubKey {
+ if len(keys) == 0 {
return false, "", nil, &ErrWontSign{pubkey}
}
case twofa:
- hasTwoFactor, err := auth.HasTwoFactorByUID(ctx, u.ID)
- if err != nil {
+ twofaModel, err := auth.GetTwoFactorByUID(ctx, u.ID)
+ if err != nil && !auth.IsErrTwoFactorNotEnrolled(err) {
return false, "", nil, err
}
- if !hasTwoFactor {
+ if twofaModel == nil {
return false, "", nil, &ErrWontSign{twofa}
}
case parentSigned:
@@ -303,19 +306,22 @@ Loop:
case always:
break Loop
case pubkey:
- hasPubKey, err := asymkey_model.HasAsymKeyByUID(ctx, u.ID)
+ keys, err := db.Find[asymkey_model.GPGKey](ctx, asymkey_model.FindGPGKeyOptions{
+ OwnerID: u.ID,
+ IncludeSubKeys: true,
+ })
if err != nil {
return false, "", nil, err
}
- if !hasPubKey {
+ if len(keys) == 0 {
return false, "", nil, &ErrWontSign{pubkey}
}
case twofa:
- hasTwoFactor, err := auth.HasTwoFactorByUID(ctx, u.ID)
- if err != nil {
+ twofaModel, err := auth.GetTwoFactorByUID(ctx, u.ID)
+ if err != nil && !auth.IsErrTwoFactorNotEnrolled(err) {
return false, "", nil, err
}
- if !hasTwoFactor {
+ if twofaModel == nil {
return false, "", nil, &ErrWontSign{twofa}
}
case approved:
diff --git a/services/asymkey/ssh_key.go b/services/asymkey/ssh_key.go
index f20445891d..83d7edafa3 100644
--- a/services/asymkey/ssh_key.go
+++ b/services/asymkey/ssh_key.go
@@ -6,9 +6,9 @@ package asymkey
import (
"context"
- asymkey_model "forgejo.org/models/asymkey"
- "forgejo.org/models/db"
- user_model "forgejo.org/models/user"
+ asymkey_model "code.gitea.io/gitea/models/asymkey"
+ "code.gitea.io/gitea/models/db"
+ user_model "code.gitea.io/gitea/models/user"
)
// DeletePublicKey deletes SSH key information both in database and authorized_keys file.
diff --git a/services/asymkey/ssh_key_test.go b/services/asymkey/ssh_key_test.go
index 24b28d295e..d667a02557 100644
--- a/services/asymkey/ssh_key_test.go
+++ b/services/asymkey/ssh_key_test.go
@@ -6,11 +6,11 @@ package asymkey
import (
"testing"
- asymkey_model "forgejo.org/models/asymkey"
- "forgejo.org/models/auth"
- "forgejo.org/models/db"
- "forgejo.org/models/unittest"
- user_model "forgejo.org/models/user"
+ asymkey_model "code.gitea.io/gitea/models/asymkey"
+ "code.gitea.io/gitea/models/auth"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/unittest"
+ user_model "code.gitea.io/gitea/models/user"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
diff --git a/services/attachment/attachment.go b/services/attachment/attachment.go
index b6f763842b..c911945e5d 100644
--- a/services/attachment/attachment.go
+++ b/services/attachment/attachment.go
@@ -9,12 +9,12 @@ import (
"fmt"
"io"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/modules/storage"
- "forgejo.org/modules/util"
- "forgejo.org/modules/validation"
- "forgejo.org/services/context/upload"
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/modules/storage"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/modules/validation"
+ "code.gitea.io/gitea/services/context/upload"
"github.com/google/uuid"
)
@@ -51,7 +51,7 @@ func NewExternalAttachment(ctx context.Context, attach *repo_model.Attachment) (
if attach.ExternalURL == "" {
return nil, fmt.Errorf("attachment %s should have a external url", attach.Name)
}
- if !validation.IsValidReleaseAssetURL(attach.ExternalURL) {
+ if !validation.IsValidExternalURL(attach.ExternalURL) {
return nil, repo_model.ErrInvalidExternalURL{ExternalURL: attach.ExternalURL}
}
diff --git a/services/attachment/attachment_test.go b/services/attachment/attachment_test.go
index ef002bf16c..c24b3f8006 100644
--- a/services/attachment/attachment_test.go
+++ b/services/attachment/attachment_test.go
@@ -8,13 +8,13 @@ import (
"path/filepath"
"testing"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unittest"
- user_model "forgejo.org/models/user"
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unittest"
+ user_model "code.gitea.io/gitea/models/user"
- _ "forgejo.org/models/actions"
- _ "forgejo.org/models/forgefed"
+ _ "code.gitea.io/gitea/models/actions"
+ _ "code.gitea.io/gitea/models/forgefed"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -43,6 +43,6 @@ func TestUploadAttachment(t *testing.T) {
attachment, err := repo_model.GetAttachmentByUUID(db.DefaultContext, attach.UUID)
require.NoError(t, err)
- assert.Equal(t, user.ID, attachment.UploaderID)
+ assert.EqualValues(t, user.ID, attachment.UploaderID)
assert.Equal(t, int64(0), attachment.DownloadCount)
}
diff --git a/services/auth/auth.go b/services/auth/auth.go
index 85121b2d7f..c10872313f 100644
--- a/services/auth/auth.go
+++ b/services/auth/auth.go
@@ -10,15 +10,15 @@ import (
"regexp"
"strings"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/auth/webauthn"
- "forgejo.org/modules/log"
- "forgejo.org/modules/optional"
- "forgejo.org/modules/session"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/web/middleware"
- gitea_context "forgejo.org/services/context"
- user_service "forgejo.org/services/user"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/auth/webauthn"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/optional"
+ "code.gitea.io/gitea/modules/session"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/web/middleware"
+ gitea_context "code.gitea.io/gitea/services/context"
+ user_service "code.gitea.io/gitea/services/user"
)
// Init should be called exactly once when the application starts to allow plugins
@@ -77,7 +77,6 @@ func handleSignIn(resp http.ResponseWriter, req *http.Request, sess SessionStore
_ = sess.Delete("openid_determined_username")
_ = sess.Delete("twofaUid")
_ = sess.Delete("twofaRemember")
- _ = sess.Delete("twofaOpenID")
_ = sess.Delete("webauthnAssertion")
_ = sess.Delete("linkAccount")
err = sess.Set("uid", user.ID)
diff --git a/services/auth/auth_test.go b/services/auth/auth_test.go
index a6c6c74022..3adaa28664 100644
--- a/services/auth/auth_test.go
+++ b/services/auth/auth_test.go
@@ -8,7 +8,7 @@ import (
"net/http"
"testing"
- "forgejo.org/modules/setting"
+ "code.gitea.io/gitea/modules/setting"
)
func Test_isGitRawOrLFSPath(t *testing.T) {
diff --git a/services/auth/basic.go b/services/auth/basic.go
index 4ffe712744..d489164954 100644
--- a/services/auth/basic.go
+++ b/services/auth/basic.go
@@ -9,15 +9,15 @@ import (
"net/http"
"strings"
- actions_model "forgejo.org/models/actions"
- auth_model "forgejo.org/models/auth"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/base"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/timeutil"
- "forgejo.org/modules/util"
- "forgejo.org/modules/web/middleware"
+ actions_model "code.gitea.io/gitea/models/actions"
+ auth_model "code.gitea.io/gitea/models/auth"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/timeutil"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/modules/web/middleware"
)
// Ensure the struct implements the interface.
@@ -151,7 +151,6 @@ func (b *Basic) Verify(req *http.Request, w http.ResponseWriter, store DataStore
log.Trace("Basic Authorization: Logged in user %-v", u)
- store.GetData()["IsPasswordLogin"] = true
return u, nil
}
diff --git a/services/auth/group.go b/services/auth/group.go
index b713301b50..aecf43cb24 100644
--- a/services/auth/group.go
+++ b/services/auth/group.go
@@ -7,7 +7,7 @@ import (
"net/http"
"strings"
- user_model "forgejo.org/models/user"
+ user_model "code.gitea.io/gitea/models/user"
)
// Ensure the struct implements the interface.
diff --git a/services/auth/httpsign.go b/services/auth/httpsign.go
index e776ccbbed..83a36bef23 100644
--- a/services/auth/httpsign.go
+++ b/services/auth/httpsign.go
@@ -11,11 +11,11 @@ import (
"net/http"
"strings"
- asymkey_model "forgejo.org/models/asymkey"
- "forgejo.org/models/db"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
+ asymkey_model "code.gitea.io/gitea/models/asymkey"
+ "code.gitea.io/gitea/models/db"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
"github.com/42wim/httpsig"
"golang.org/x/crypto/ssh"
@@ -134,7 +134,7 @@ func VerifyCert(r *http.Request) (*asymkey_model.PublicKey, error) {
// Check if it's really a ssh certificate
cert, ok := pk.(*ssh.Certificate)
if !ok {
- return nil, errors.New("no certificate found")
+ return nil, fmt.Errorf("no certificate found")
}
c := &ssh.CertChecker{
@@ -153,7 +153,7 @@ func VerifyCert(r *http.Request) (*asymkey_model.PublicKey, error) {
// check the CA of the cert
if !c.IsUserAuthority(cert.SignatureKey) {
- return nil, errors.New("CA check failed")
+ return nil, fmt.Errorf("CA check failed")
}
// Create a verifier
@@ -191,7 +191,7 @@ func VerifyCert(r *http.Request) (*asymkey_model.PublicKey, error) {
}
// No public key matching a principal in the certificate is registered in gitea
- return nil, errors.New("no valid principal found")
+ return nil, fmt.Errorf("no valid principal found")
}
// doVerify iterates across the provided public keys attempting the verify the current request against each key in turn
diff --git a/services/auth/interface.go b/services/auth/interface.go
index 12b04a7abf..ece28af12d 100644
--- a/services/auth/interface.go
+++ b/services/auth/interface.go
@@ -7,9 +7,9 @@ import (
"context"
"net/http"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/session"
- "forgejo.org/modules/web/middleware"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/session"
+ "code.gitea.io/gitea/modules/web/middleware"
)
// DataStore represents a data store
diff --git a/services/auth/main_test.go b/services/auth/main_test.go
index 0e6315b06e..b81c39a1f2 100644
--- a/services/auth/main_test.go
+++ b/services/auth/main_test.go
@@ -6,7 +6,7 @@ package auth
import (
"testing"
- "forgejo.org/models/unittest"
+ "code.gitea.io/gitea/models/unittest"
)
func TestMain(m *testing.M) {
diff --git a/services/auth/oauth2.go b/services/auth/oauth2.go
index fa13c20a7f..b983e57ecd 100644
--- a/services/auth/oauth2.go
+++ b/services/auth/oauth2.go
@@ -11,16 +11,15 @@ import (
"strings"
"time"
- actions_model "forgejo.org/models/actions"
- auth_model "forgejo.org/models/auth"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/timeutil"
- "forgejo.org/modules/util"
- "forgejo.org/modules/web/middleware"
- "forgejo.org/services/actions"
- "forgejo.org/services/auth/source/oauth2"
+ actions_model "code.gitea.io/gitea/models/actions"
+ auth_model "code.gitea.io/gitea/models/auth"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/timeutil"
+ "code.gitea.io/gitea/modules/web/middleware"
+ "code.gitea.io/gitea/services/actions"
+ "code.gitea.io/gitea/services/auth/source/oauth2"
)
// Ensure the struct implements the interface.
@@ -138,7 +137,7 @@ func parseToken(req *http.Request) (string, bool) {
// check header token
if auHead := req.Header.Get("Authorization"); auHead != "" {
auths := strings.Fields(auHead)
- if len(auths) == 2 && (util.ASCIIEqualFold(auths[0], "token") || util.ASCIIEqualFold(auths[0], "bearer")) {
+ if len(auths) == 2 && (auths[0] == "token" || strings.ToLower(auths[0]) == "bearer") {
return auths[1], true
}
}
diff --git a/services/auth/oauth2_test.go b/services/auth/oauth2_test.go
index 3fce7df50b..90e2fe4517 100644
--- a/services/auth/oauth2_test.go
+++ b/services/auth/oauth2_test.go
@@ -4,13 +4,12 @@
package auth
import (
- "net/http"
"testing"
- "forgejo.org/models/unittest"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/web/middleware"
- "forgejo.org/services/actions"
+ "code.gitea.io/gitea/models/unittest"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/web/middleware"
+ "code.gitea.io/gitea/services/actions"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -53,30 +52,3 @@ func TestCheckTaskIsRunning(t *testing.T) {
})
}
}
-
-func TestParseToken(t *testing.T) {
- cases := map[string]struct {
- Header string
- ExpectedToken string
- Expected bool
- }{
- "Token Uppercase": {Header: "Token 1234567890123456789012345687901325467890", ExpectedToken: "1234567890123456789012345687901325467890", Expected: true},
- "Token Lowercase": {Header: "token 1234567890123456789012345687901325467890", ExpectedToken: "1234567890123456789012345687901325467890", Expected: true},
- "Token Unicode": {Header: "to\u212Aen 1234567890123456789012345687901325467890", ExpectedToken: "", Expected: false},
- "Bearer Uppercase": {Header: "Bearer 1234567890123456789012345687901325467890", ExpectedToken: "1234567890123456789012345687901325467890", Expected: true},
- "Bearer Lowercase": {Header: "bearer 1234567890123456789012345687901325467890", ExpectedToken: "1234567890123456789012345687901325467890", Expected: true},
- "Missing type": {Header: "1234567890123456789012345687901325467890", ExpectedToken: "", Expected: false},
- "Three Parts": {Header: "abc 1234567890 test", ExpectedToken: "", Expected: false},
- }
-
- for name := range cases {
- c := cases[name]
- t.Run(name, func(t *testing.T) {
- req, _ := http.NewRequest("GET", "/", nil)
- req.Header.Add("Authorization", c.Header)
- ActualToken, ActualSuccess := parseToken(req)
- assert.Equal(t, c.ExpectedToken, ActualToken)
- assert.Equal(t, c.Expected, ActualSuccess)
- })
- }
-}
diff --git a/services/auth/reverseproxy.go b/services/auth/reverseproxy.go
index eb9ceb8cf2..8a5a5dc992 100644
--- a/services/auth/reverseproxy.go
+++ b/services/auth/reverseproxy.go
@@ -8,11 +8,11 @@ import (
"net/http"
"strings"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/log"
- "forgejo.org/modules/optional"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/web/middleware"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/optional"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/web/middleware"
gouuid "github.com/google/uuid"
)
diff --git a/services/auth/reverseproxy_test.go b/services/auth/reverseproxy_test.go
index cdcd845148..7f1b2a7782 100644
--- a/services/auth/reverseproxy_test.go
+++ b/services/auth/reverseproxy_test.go
@@ -7,11 +7,11 @@ import (
"net/http"
"testing"
- "forgejo.org/models/db"
- "forgejo.org/models/unittest"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/test"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/unittest"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/test"
"github.com/stretchr/testify/require"
)
@@ -38,10 +38,10 @@ func TestReverseProxyAuth(t *testing.T) {
require.EqualValues(t, 1, user_model.CountUsers(db.DefaultContext, nil))
unittest.AssertExistsAndLoadBean(t, &user_model.User{Email: "edgar@example.org", Name: "Edgar", LowerName: "edgar", FullName: "Edgar Allan Poe", IsAdmin: true})
- require.Equal(t, "edgar@example.org", user.Email)
- require.Equal(t, "Edgar", user.Name)
- require.Equal(t, "edgar", user.LowerName)
- require.Equal(t, "Edgar Allan Poe", user.FullName)
+ require.EqualValues(t, "edgar@example.org", user.Email)
+ require.EqualValues(t, "Edgar", user.Name)
+ require.EqualValues(t, "edgar", user.LowerName)
+ require.EqualValues(t, "Edgar Allan Poe", user.FullName)
require.True(t, user.IsAdmin)
})
@@ -58,10 +58,10 @@ func TestReverseProxyAuth(t *testing.T) {
require.EqualValues(t, 2, user_model.CountUsers(db.DefaultContext, nil))
unittest.AssertExistsAndLoadBean(t, &user_model.User{Email: "gusted@example.org", Name: "Gusted", LowerName: "gusted", FullName: "â¤â€¿â¤"}, "is_admin = false")
- require.Equal(t, "gusted@example.org", user.Email)
- require.Equal(t, "Gusted", user.Name)
- require.Equal(t, "gusted", user.LowerName)
- require.Equal(t, "â¤â€¿â¤", user.FullName)
+ require.EqualValues(t, "gusted@example.org", user.Email)
+ require.EqualValues(t, "Gusted", user.Name)
+ require.EqualValues(t, "gusted", user.LowerName)
+ require.EqualValues(t, "â¤â€¿â¤", user.FullName)
require.False(t, user.IsAdmin)
})
}
diff --git a/services/auth/session.go b/services/auth/session.go
index a15c24c940..35d97e42da 100644
--- a/services/auth/session.go
+++ b/services/auth/session.go
@@ -6,8 +6,8 @@ package auth
import (
"net/http"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/log"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/log"
)
// Ensure the struct implements the interface.
diff --git a/services/auth/signin.go b/services/auth/signin.go
index 495b3d387e..7c69da8f94 100644
--- a/services/auth/signin.go
+++ b/services/auth/signin.go
@@ -7,17 +7,17 @@ import (
"context"
"strings"
- "forgejo.org/models/auth"
- "forgejo.org/models/db"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/log"
- "forgejo.org/modules/optional"
- "forgejo.org/services/auth/source/oauth2"
- "forgejo.org/services/auth/source/smtp"
+ "code.gitea.io/gitea/models/auth"
+ "code.gitea.io/gitea/models/db"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/optional"
+ "code.gitea.io/gitea/services/auth/source/oauth2"
+ "code.gitea.io/gitea/services/auth/source/smtp"
- _ "forgejo.org/services/auth/source/db" // register the sources (and below)
- _ "forgejo.org/services/auth/source/ldap" // register the ldap source
- _ "forgejo.org/services/auth/source/pam" // register the pam source
+ _ "code.gitea.io/gitea/services/auth/source/db" // register the sources (and below)
+ _ "code.gitea.io/gitea/services/auth/source/ldap" // register the ldap source
+ _ "code.gitea.io/gitea/services/auth/source/pam" // register the pam source
)
// UserSignIn validates user name and password.
diff --git a/services/auth/source.go b/services/auth/source.go
index b13554efde..69b71a6dea 100644
--- a/services/auth/source.go
+++ b/services/auth/source.go
@@ -6,9 +6,9 @@ package auth
import (
"context"
- "forgejo.org/models/auth"
- "forgejo.org/models/db"
- user_model "forgejo.org/models/user"
+ "code.gitea.io/gitea/models/auth"
+ "code.gitea.io/gitea/models/db"
+ user_model "code.gitea.io/gitea/models/user"
)
// DeleteSource deletes a AuthSource record in DB.
diff --git a/services/auth/source/db/assert_interface_test.go b/services/auth/source/db/assert_interface_test.go
index 1422e9693c..62387c78f0 100644
--- a/services/auth/source/db/assert_interface_test.go
+++ b/services/auth/source/db/assert_interface_test.go
@@ -4,9 +4,9 @@
package db_test
import (
- auth_model "forgejo.org/models/auth"
- "forgejo.org/services/auth"
- "forgejo.org/services/auth/source/db"
+ auth_model "code.gitea.io/gitea/models/auth"
+ "code.gitea.io/gitea/services/auth"
+ "code.gitea.io/gitea/services/auth/source/db"
)
// This test file exists to assert that our Source exposes the interfaces that we expect
diff --git a/services/auth/source/db/authenticate.go b/services/auth/source/db/authenticate.go
index b1d8eae6ae..8160141863 100644
--- a/services/auth/source/db/authenticate.go
+++ b/services/auth/source/db/authenticate.go
@@ -7,9 +7,9 @@ import (
"context"
"fmt"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/util"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/util"
)
// ErrUserPasswordNotSet represents a "ErrUserPasswordNotSet" kind of error.
@@ -50,7 +50,7 @@ func Authenticate(ctx context.Context, user *user_model.User, login, password st
if !user.IsPasswordSet() {
return nil, ErrUserPasswordNotSet{UID: user.ID, Name: user.Name}
- } else if !user.ValidatePassword(ctx, password) {
+ } else if !user.ValidatePassword(password) {
return nil, ErrUserPasswordInvalid{UID: user.ID, Name: user.Name}
}
diff --git a/services/auth/source/db/source.go b/services/auth/source/db/source.go
index d158718bb2..bb2270cbd6 100644
--- a/services/auth/source/db/source.go
+++ b/services/auth/source/db/source.go
@@ -6,8 +6,8 @@ package db
import (
"context"
- "forgejo.org/models/auth"
- user_model "forgejo.org/models/user"
+ "code.gitea.io/gitea/models/auth"
+ user_model "code.gitea.io/gitea/models/user"
)
// Source is a password authentication service
diff --git a/services/auth/source/ldap/assert_interface_test.go b/services/auth/source/ldap/assert_interface_test.go
index 859143a3f8..33347687dc 100644
--- a/services/auth/source/ldap/assert_interface_test.go
+++ b/services/auth/source/ldap/assert_interface_test.go
@@ -4,9 +4,9 @@
package ldap_test
import (
- auth_model "forgejo.org/models/auth"
- "forgejo.org/services/auth"
- "forgejo.org/services/auth/source/ldap"
+ auth_model "code.gitea.io/gitea/models/auth"
+ "code.gitea.io/gitea/services/auth"
+ "code.gitea.io/gitea/services/auth/source/ldap"
)
// This test file exists to assert that our Source exposes the interfaces that we expect
diff --git a/services/auth/source/ldap/source.go b/services/auth/source/ldap/source.go
index a094c1410c..ba407b351a 100644
--- a/services/auth/source/ldap/source.go
+++ b/services/auth/source/ldap/source.go
@@ -6,10 +6,10 @@ package ldap
import (
"strings"
- "forgejo.org/models/auth"
- "forgejo.org/modules/json"
- "forgejo.org/modules/secret"
- "forgejo.org/modules/setting"
+ "code.gitea.io/gitea/models/auth"
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/secret"
+ "code.gitea.io/gitea/modules/setting"
)
// .____ ________ _____ __________
diff --git a/services/auth/source/ldap/source_authenticate.go b/services/auth/source/ldap/source_authenticate.go
index a2ff10cd07..68ecd16342 100644
--- a/services/auth/source/ldap/source_authenticate.go
+++ b/services/auth/source/ldap/source_authenticate.go
@@ -8,13 +8,13 @@ import (
"fmt"
"strings"
- asymkey_model "forgejo.org/models/asymkey"
- "forgejo.org/models/auth"
- user_model "forgejo.org/models/user"
- auth_module "forgejo.org/modules/auth"
- "forgejo.org/modules/optional"
- source_service "forgejo.org/services/auth/source"
- user_service "forgejo.org/services/user"
+ asymkey_model "code.gitea.io/gitea/models/asymkey"
+ "code.gitea.io/gitea/models/auth"
+ user_model "code.gitea.io/gitea/models/user"
+ auth_module "code.gitea.io/gitea/modules/auth"
+ "code.gitea.io/gitea/modules/optional"
+ source_service "code.gitea.io/gitea/services/auth/source"
+ user_service "code.gitea.io/gitea/services/user"
)
// Authenticate queries if login/password is valid against the LDAP directory pool,
diff --git a/services/auth/source/ldap/source_search.go b/services/auth/source/ldap/source_search.go
index da7e225428..2a61386ae1 100644
--- a/services/auth/source/ldap/source_search.go
+++ b/services/auth/source/ldap/source_search.go
@@ -11,8 +11,8 @@ import (
"strconv"
"strings"
- "forgejo.org/modules/container"
- "forgejo.org/modules/log"
+ "code.gitea.io/gitea/modules/container"
+ "code.gitea.io/gitea/modules/log"
"github.com/go-ldap/ldap/v3"
)
diff --git a/services/auth/source/ldap/source_sync.go b/services/auth/source/ldap/source_sync.go
index cb6172ed1d..1f70edaa82 100644
--- a/services/auth/source/ldap/source_sync.go
+++ b/services/auth/source/ldap/source_sync.go
@@ -8,16 +8,16 @@ import (
"fmt"
"strings"
- asymkey_model "forgejo.org/models/asymkey"
- "forgejo.org/models/db"
- "forgejo.org/models/organization"
- user_model "forgejo.org/models/user"
- auth_module "forgejo.org/modules/auth"
- "forgejo.org/modules/container"
- "forgejo.org/modules/log"
- "forgejo.org/modules/optional"
- source_service "forgejo.org/services/auth/source"
- user_service "forgejo.org/services/user"
+ asymkey_model "code.gitea.io/gitea/models/asymkey"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/organization"
+ user_model "code.gitea.io/gitea/models/user"
+ auth_module "code.gitea.io/gitea/modules/auth"
+ "code.gitea.io/gitea/modules/container"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/optional"
+ source_service "code.gitea.io/gitea/services/auth/source"
+ user_service "code.gitea.io/gitea/services/user"
)
// Sync causes this ldap source to synchronize its users with the db
diff --git a/services/auth/source/oauth2/assert_interface_test.go b/services/auth/source/oauth2/assert_interface_test.go
index 12fce257cf..56fe0e4aa8 100644
--- a/services/auth/source/oauth2/assert_interface_test.go
+++ b/services/auth/source/oauth2/assert_interface_test.go
@@ -4,9 +4,9 @@
package oauth2_test
import (
- auth_model "forgejo.org/models/auth"
- "forgejo.org/services/auth"
- "forgejo.org/services/auth/source/oauth2"
+ auth_model "code.gitea.io/gitea/models/auth"
+ "code.gitea.io/gitea/services/auth"
+ "code.gitea.io/gitea/services/auth/source/oauth2"
)
// This test file exists to assert that our Source exposes the interfaces that we expect
diff --git a/services/auth/source/oauth2/init.go b/services/auth/source/oauth2/init.go
index 6c78a14da4..5c25681548 100644
--- a/services/auth/source/oauth2/init.go
+++ b/services/auth/source/oauth2/init.go
@@ -9,11 +9,11 @@ import (
"net/http"
"sync"
- "forgejo.org/models/auth"
- "forgejo.org/models/db"
- "forgejo.org/modules/log"
- "forgejo.org/modules/optional"
- "forgejo.org/modules/setting"
+ "code.gitea.io/gitea/models/auth"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/optional"
+ "code.gitea.io/gitea/modules/setting"
"github.com/google/uuid"
"github.com/gorilla/sessions"
diff --git a/services/auth/source/oauth2/jwtsigningkey.go b/services/auth/source/oauth2/jwtsigningkey.go
index 550945a812..92adfc4d84 100644
--- a/services/auth/source/oauth2/jwtsigningkey.go
+++ b/services/auth/source/oauth2/jwtsigningkey.go
@@ -18,9 +18,9 @@ import (
"path/filepath"
"strings"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/util"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/util"
"github.com/golang-jwt/jwt/v5"
)
diff --git a/services/auth/source/oauth2/jwtsigningkey_test.go b/services/auth/source/oauth2/jwtsigningkey_test.go
index 9b07b022df..4db538b0e8 100644
--- a/services/auth/source/oauth2/jwtsigningkey_test.go
+++ b/services/auth/source/oauth2/jwtsigningkey_test.go
@@ -13,8 +13,8 @@ import (
"path/filepath"
"testing"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/test"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/test"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -30,7 +30,7 @@ func TestLoadOrCreateAsymmetricKey(t *testing.T) {
block, _ := pem.Decode(fileContent)
assert.NotNil(t, block)
- assert.Equal(t, "PRIVATE KEY", block.Type)
+ assert.EqualValues(t, "PRIVATE KEY", block.Type)
parsedKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
require.NoError(t, err)
@@ -44,14 +44,14 @@ func TestLoadOrCreateAsymmetricKey(t *testing.T) {
parsedKey := loadKey(t)
rsaPrivateKey := parsedKey.(*rsa.PrivateKey)
- assert.Equal(t, 2048, rsaPrivateKey.N.BitLen())
+ assert.EqualValues(t, 2048, rsaPrivateKey.N.BitLen())
t.Run("Load key with differ specified algorithm", func(t *testing.T) {
defer test.MockVariableValue(&setting.OAuth2.JWTSigningAlgorithm, "EdDSA")()
parsedKey := loadKey(t)
rsaPrivateKey := parsedKey.(*rsa.PrivateKey)
- assert.Equal(t, 2048, rsaPrivateKey.N.BitLen())
+ assert.EqualValues(t, 2048, rsaPrivateKey.N.BitLen())
})
})
@@ -62,7 +62,7 @@ func TestLoadOrCreateAsymmetricKey(t *testing.T) {
parsedKey := loadKey(t)
rsaPrivateKey := parsedKey.(*rsa.PrivateKey)
- assert.Equal(t, 3072, rsaPrivateKey.N.BitLen())
+ assert.EqualValues(t, 3072, rsaPrivateKey.N.BitLen())
})
t.Run("RSA-4096", func(t *testing.T) {
@@ -72,7 +72,7 @@ func TestLoadOrCreateAsymmetricKey(t *testing.T) {
parsedKey := loadKey(t)
rsaPrivateKey := parsedKey.(*rsa.PrivateKey)
- assert.Equal(t, 4096, rsaPrivateKey.N.BitLen())
+ assert.EqualValues(t, 4096, rsaPrivateKey.N.BitLen())
})
t.Run("ECDSA-256", func(t *testing.T) {
@@ -82,7 +82,7 @@ func TestLoadOrCreateAsymmetricKey(t *testing.T) {
parsedKey := loadKey(t)
ecdsaPrivateKey := parsedKey.(*ecdsa.PrivateKey)
- assert.Equal(t, 256, ecdsaPrivateKey.Params().BitSize)
+ assert.EqualValues(t, 256, ecdsaPrivateKey.Params().BitSize)
})
t.Run("ECDSA-384", func(t *testing.T) {
@@ -92,7 +92,7 @@ func TestLoadOrCreateAsymmetricKey(t *testing.T) {
parsedKey := loadKey(t)
ecdsaPrivateKey := parsedKey.(*ecdsa.PrivateKey)
- assert.Equal(t, 384, ecdsaPrivateKey.Params().BitSize)
+ assert.EqualValues(t, 384, ecdsaPrivateKey.Params().BitSize)
})
t.Run("ECDSA-512", func(t *testing.T) {
@@ -102,7 +102,7 @@ func TestLoadOrCreateAsymmetricKey(t *testing.T) {
parsedKey := loadKey(t)
ecdsaPrivateKey := parsedKey.(*ecdsa.PrivateKey)
- assert.Equal(t, 521, ecdsaPrivateKey.Params().BitSize)
+ assert.EqualValues(t, 521, ecdsaPrivateKey.Params().BitSize)
})
t.Run("EdDSA", func(t *testing.T) {
diff --git a/services/auth/source/oauth2/providers.go b/services/auth/source/oauth2/providers.go
index 773ce19c12..f2c1bb4894 100644
--- a/services/auth/source/oauth2/providers.go
+++ b/services/auth/source/oauth2/providers.go
@@ -12,11 +12,11 @@ import (
"net/url"
"sort"
- "forgejo.org/models/auth"
- "forgejo.org/models/db"
- "forgejo.org/modules/log"
- "forgejo.org/modules/optional"
- "forgejo.org/modules/setting"
+ "code.gitea.io/gitea/models/auth"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/optional"
+ "code.gitea.io/gitea/modules/setting"
"github.com/markbates/goth"
)
diff --git a/services/auth/source/oauth2/providers_base.go b/services/auth/source/oauth2/providers_base.go
index 1ef8d0af72..63318b84ef 100644
--- a/services/auth/source/oauth2/providers_base.go
+++ b/services/auth/source/oauth2/providers_base.go
@@ -6,8 +6,8 @@ package oauth2
import (
"html/template"
- "forgejo.org/modules/log"
- "forgejo.org/modules/svg"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/svg"
)
// BaseProvider represents a common base for Provider
diff --git a/services/auth/source/oauth2/providers_custom.go b/services/auth/source/oauth2/providers_custom.go
index 51a412e0be..65cf538ad7 100644
--- a/services/auth/source/oauth2/providers_custom.go
+++ b/services/auth/source/oauth2/providers_custom.go
@@ -4,7 +4,7 @@
package oauth2
import (
- "forgejo.org/modules/setting"
+ "code.gitea.io/gitea/modules/setting"
"github.com/markbates/goth"
"github.com/markbates/goth/providers/azureadv2"
diff --git a/services/auth/source/oauth2/providers_openid.go b/services/auth/source/oauth2/providers_openid.go
index 7950506ab7..f606581271 100644
--- a/services/auth/source/oauth2/providers_openid.go
+++ b/services/auth/source/oauth2/providers_openid.go
@@ -6,9 +6,9 @@ package oauth2
import (
"html/template"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/svg"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/svg"
"github.com/markbates/goth"
"github.com/markbates/goth/providers/openidConnect"
diff --git a/services/auth/source/oauth2/providers_simple.go b/services/auth/source/oauth2/providers_simple.go
index 8e2c0a7700..e95323a62a 100644
--- a/services/auth/source/oauth2/providers_simple.go
+++ b/services/auth/source/oauth2/providers_simple.go
@@ -4,7 +4,7 @@
package oauth2
import (
- "forgejo.org/modules/setting"
+ "code.gitea.io/gitea/modules/setting"
"github.com/markbates/goth"
"github.com/markbates/goth/providers/azuread"
diff --git a/services/auth/source/oauth2/source.go b/services/auth/source/oauth2/source.go
index a3126cf353..3f8616c6ff 100644
--- a/services/auth/source/oauth2/source.go
+++ b/services/auth/source/oauth2/source.go
@@ -6,8 +6,8 @@ package oauth2
import (
"strings"
- "forgejo.org/models/auth"
- "forgejo.org/modules/json"
+ "code.gitea.io/gitea/models/auth"
+ "code.gitea.io/gitea/modules/json"
)
// Source holds configuration for the OAuth2 login source.
@@ -29,7 +29,6 @@ type Source struct {
GroupTeamMapRemoval bool
RestrictedGroup string
SkipLocalTwoFA bool `json:",omitempty"`
- AllowUsernameChange bool
// reference to the authSource
authSource *auth.Source
diff --git a/services/auth/source/oauth2/source_authenticate.go b/services/auth/source/oauth2/source_authenticate.go
index 1efd7be02a..bbda35dee0 100644
--- a/services/auth/source/oauth2/source_authenticate.go
+++ b/services/auth/source/oauth2/source_authenticate.go
@@ -6,8 +6,8 @@ package oauth2
import (
"context"
- user_model "forgejo.org/models/user"
- "forgejo.org/services/auth/source/db"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/services/auth/source/db"
)
// Authenticate falls back to the db authenticator
diff --git a/services/auth/source/oauth2/store.go b/services/auth/source/oauth2/store.go
index d52581ea2d..e031653119 100644
--- a/services/auth/source/oauth2/store.go
+++ b/services/auth/source/oauth2/store.go
@@ -8,8 +8,8 @@ import (
"fmt"
"net/http"
- "forgejo.org/modules/log"
- session_module "forgejo.org/modules/session"
+ "code.gitea.io/gitea/modules/log"
+ session_module "code.gitea.io/gitea/modules/session"
chiSession "code.forgejo.org/go-chi/session"
"github.com/gorilla/sessions"
diff --git a/services/auth/source/oauth2/token.go b/services/auth/source/oauth2/token.go
index b060b6b746..3405619d3f 100644
--- a/services/auth/source/oauth2/token.go
+++ b/services/auth/source/oauth2/token.go
@@ -4,11 +4,10 @@
package oauth2
import (
- "errors"
"fmt"
"time"
- "forgejo.org/modules/timeutil"
+ "code.gitea.io/gitea/modules/timeutil"
"github.com/golang-jwt/jwt/v5"
)
@@ -52,12 +51,12 @@ func ParseToken(jwtToken string, signingKey JWTSigningKey) (*Token, error) {
return nil, err
}
if !parsedToken.Valid {
- return nil, errors.New("invalid token")
+ return nil, fmt.Errorf("invalid token")
}
var token *Token
var ok bool
if token, ok = parsedToken.Claims.(*Token); !ok || !parsedToken.Valid {
- return nil, errors.New("invalid token")
+ return nil, fmt.Errorf("invalid token")
}
return token, nil
}
diff --git a/services/auth/source/pam/assert_interface_test.go b/services/auth/source/pam/assert_interface_test.go
index 8c54b7e9e2..8e7648b8d3 100644
--- a/services/auth/source/pam/assert_interface_test.go
+++ b/services/auth/source/pam/assert_interface_test.go
@@ -4,9 +4,9 @@
package pam_test
import (
- auth_model "forgejo.org/models/auth"
- "forgejo.org/services/auth"
- "forgejo.org/services/auth/source/pam"
+ auth_model "code.gitea.io/gitea/models/auth"
+ "code.gitea.io/gitea/services/auth"
+ "code.gitea.io/gitea/services/auth/source/pam"
)
// This test file exists to assert that our Source exposes the interfaces that we expect
diff --git a/services/auth/source/pam/source.go b/services/auth/source/pam/source.go
index e1dc83ba43..96b182e185 100644
--- a/services/auth/source/pam/source.go
+++ b/services/auth/source/pam/source.go
@@ -4,8 +4,8 @@
package pam
import (
- "forgejo.org/models/auth"
- "forgejo.org/modules/json"
+ "code.gitea.io/gitea/models/auth"
+ "code.gitea.io/gitea/modules/json"
)
// __________ _____ _____
diff --git a/services/auth/source/pam/source_authenticate.go b/services/auth/source/pam/source_authenticate.go
index 6f3ffc2d9d..0df0b2bca1 100644
--- a/services/auth/source/pam/source_authenticate.go
+++ b/services/auth/source/pam/source_authenticate.go
@@ -8,12 +8,12 @@ import (
"fmt"
"strings"
- "forgejo.org/models/auth"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/auth/pam"
- "forgejo.org/modules/optional"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/validation"
+ "code.gitea.io/gitea/models/auth"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/auth/pam"
+ "code.gitea.io/gitea/modules/optional"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/validation"
"github.com/google/uuid"
)
diff --git a/services/auth/source/remote/source.go b/services/auth/source/remote/source.go
index effbabc7d0..4165858a56 100644
--- a/services/auth/source/remote/source.go
+++ b/services/auth/source/remote/source.go
@@ -4,8 +4,8 @@
package remote
import (
- "forgejo.org/models/auth"
- "forgejo.org/modules/json"
+ "code.gitea.io/gitea/models/auth"
+ "code.gitea.io/gitea/modules/json"
)
type Source struct {
diff --git a/services/auth/source/smtp/assert_interface_test.go b/services/auth/source/smtp/assert_interface_test.go
index 6826dae873..6c9cde66e1 100644
--- a/services/auth/source/smtp/assert_interface_test.go
+++ b/services/auth/source/smtp/assert_interface_test.go
@@ -4,9 +4,9 @@
package smtp_test
import (
- auth_model "forgejo.org/models/auth"
- "forgejo.org/services/auth"
- "forgejo.org/services/auth/source/smtp"
+ auth_model "code.gitea.io/gitea/models/auth"
+ "code.gitea.io/gitea/services/auth"
+ "code.gitea.io/gitea/services/auth/source/smtp"
)
// This test file exists to assert that our Source exposes the interfaces that we expect
diff --git a/services/auth/source/smtp/source.go b/services/auth/source/smtp/source.go
index d44971bab0..2a648e421e 100644
--- a/services/auth/source/smtp/source.go
+++ b/services/auth/source/smtp/source.go
@@ -4,8 +4,8 @@
package smtp
import (
- "forgejo.org/models/auth"
- "forgejo.org/modules/json"
+ "code.gitea.io/gitea/models/auth"
+ "code.gitea.io/gitea/modules/json"
)
// _________ __________________________
diff --git a/services/auth/source/smtp/source_authenticate.go b/services/auth/source/smtp/source_authenticate.go
index 3d7ccd0669..1f0a61c789 100644
--- a/services/auth/source/smtp/source_authenticate.go
+++ b/services/auth/source/smtp/source_authenticate.go
@@ -10,10 +10,10 @@ import (
"net/textproto"
"strings"
- auth_model "forgejo.org/models/auth"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/optional"
- "forgejo.org/modules/util"
+ auth_model "code.gitea.io/gitea/models/auth"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/optional"
+ "code.gitea.io/gitea/modules/util"
)
// Authenticate queries if the provided login/password is authenticates against the SMTP server
diff --git a/services/auth/source/source_group_sync.go b/services/auth/source/source_group_sync.go
index 46be6937fb..3a2411ec55 100644
--- a/services/auth/source/source_group_sync.go
+++ b/services/auth/source/source_group_sync.go
@@ -7,11 +7,11 @@ import (
"context"
"fmt"
- "forgejo.org/models"
- "forgejo.org/models/organization"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/container"
- "forgejo.org/modules/log"
+ "code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/models/organization"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/container"
+ "code.gitea.io/gitea/modules/log"
)
type syncType int
diff --git a/services/auth/sync.go b/services/auth/sync.go
index c594be7a24..7562ac812b 100644
--- a/services/auth/sync.go
+++ b/services/auth/sync.go
@@ -6,9 +6,9 @@ package auth
import (
"context"
- "forgejo.org/models/auth"
- "forgejo.org/models/db"
- "forgejo.org/modules/log"
+ "code.gitea.io/gitea/models/auth"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/modules/log"
)
// SyncExternalUsers is used to synchronize users with external authorization source
diff --git a/services/automerge/automerge.go b/services/automerge/automerge.go
index 0cdc113379..d3cc4c6fb1 100644
--- a/services/automerge/automerge.go
+++ b/services/automerge/automerge.go
@@ -8,22 +8,22 @@ import (
"errors"
"fmt"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- access_model "forgejo.org/models/perm/access"
- pull_model "forgejo.org/models/pull"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/graceful"
- "forgejo.org/modules/log"
- "forgejo.org/modules/process"
- "forgejo.org/modules/queue"
- notify_service "forgejo.org/services/notify"
- pull_service "forgejo.org/services/pull"
- repo_service "forgejo.org/services/repository"
- shared_automerge "forgejo.org/services/shared/automerge"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ pull_model "code.gitea.io/gitea/models/pull"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/graceful"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/process"
+ "code.gitea.io/gitea/modules/queue"
+ notify_service "code.gitea.io/gitea/services/notify"
+ pull_service "code.gitea.io/gitea/services/pull"
+ repo_service "code.gitea.io/gitea/services/repository"
+ shared_automerge "code.gitea.io/gitea/services/shared/automerge"
)
// Init runs the task queue to that handles auto merges
@@ -32,7 +32,7 @@ func Init() error {
shared_automerge.PRAutoMergeQueue = queue.CreateUniqueQueue(graceful.GetManager().ShutdownContext(), "pr_auto_merge", handler)
if shared_automerge.PRAutoMergeQueue == nil {
- return errors.New("unable to create pr_auto_merge queue")
+ return fmt.Errorf("unable to create pr_auto_merge queue")
}
go graceful.GetManager().RunWithCancel(shared_automerge.PRAutoMergeQueue)
return nil
@@ -107,7 +107,6 @@ func handlePullRequestAutoMerge(pullID int64, sha string) {
return
}
if !exists {
- log.Trace("GetScheduledMergeByPullID found nothing for PR %d", pullID)
return
}
@@ -162,7 +161,7 @@ func handlePullRequestAutoMerge(pullID int64, sha string) {
return
}
case issues_model.PullRequestFlowAGit:
- headBranchExist := baseGitRepo.IsReferenceExist(pr.GetGitRefName())
+ headBranchExist := git.IsReferenceExist(ctx, baseGitRepo.Path, pr.GetGitRefName())
if !headBranchExist {
log.Warn("Head branch of auto merge %-v does not exist [HeadRepoID: %d, Branch(Agit): %s]", pr, pr.HeadRepoID, pr.HeadBranch)
return
@@ -205,10 +204,6 @@ func handlePullRequestAutoMerge(pullID int64, sha string) {
return
}
- if err := pull_model.DeleteScheduledAutoMerge(ctx, pr.ID); err != nil && !db.IsErrNotExist(err) {
- log.Error("DeleteScheduledAutoMerge[%d]: %v", pr.ID, err)
- }
-
if err := pull_service.Merge(ctx, pr, doer, baseGitRepo, scheduledPRM.MergeStyle, "", scheduledPRM.Message, true); err != nil {
log.Error("pull_service.Merge: %v", err)
// FIXME: if merge failed, we should display some error message to the pull request page.
diff --git a/services/automerge/notify.go b/services/automerge/notify.go
index 3b5eae9d48..cb078214f6 100644
--- a/services/automerge/notify.go
+++ b/services/automerge/notify.go
@@ -6,10 +6,10 @@ package automerge
import (
"context"
- issues_model "forgejo.org/models/issues"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/log"
- notify_service "forgejo.org/services/notify"
+ issues_model "code.gitea.io/gitea/models/issues"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/log"
+ notify_service "code.gitea.io/gitea/services/notify"
)
type automergeNotifier struct {
diff --git a/services/context/access_log.go b/services/context/access_log.go
index 7a54b746f6..0926748ac5 100644
--- a/services/context/access_log.go
+++ b/services/context/access_log.go
@@ -12,10 +12,10 @@ import (
"text/template"
"time"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/web/middleware"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/web/middleware"
)
type routerLoggerOptions struct {
diff --git a/services/context/api.go b/services/context/api.go
index e9f67c720d..871a2f012d 100644
--- a/services/context/api.go
+++ b/services/context/api.go
@@ -6,24 +6,23 @@ package context
import (
"context"
- "errors"
"fmt"
"net/http"
"net/url"
"strings"
- issues_model "forgejo.org/models/issues"
- quota_model "forgejo.org/models/quota"
- "forgejo.org/models/unit"
- user_model "forgejo.org/models/user"
- mc "forgejo.org/modules/cache"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/httpcache"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/web"
- web_types "forgejo.org/modules/web/types"
+ issues_model "code.gitea.io/gitea/models/issues"
+ quota_model "code.gitea.io/gitea/models/quota"
+ "code.gitea.io/gitea/models/unit"
+ user_model "code.gitea.io/gitea/models/user"
+ mc "code.gitea.io/gitea/modules/cache"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/httpcache"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/web"
+ web_types "code.gitea.io/gitea/modules/web/types"
"code.forgejo.org/go-chi/cache"
)
@@ -187,7 +186,7 @@ func (ctx *APIContext) Error(status int, title string, obj any) {
if status == http.StatusInternalServerError {
log.ErrorWithSkip(1, "%s: %s", title, message)
- if setting.IsProd && (ctx.Doer == nil || !ctx.Doer.IsAdmin) {
+ if setting.IsProd && !(ctx.Doer != nil && ctx.Doer.IsAdmin) {
message = ""
}
}
@@ -286,8 +285,8 @@ func APIContexter() func(http.Handler) http.Handler {
}
defer baseCleanUp()
- ctx.AppendContextValue(apiContextKey, ctx)
- ctx.AppendContextValueFunc(gitrepo.RepositoryContextKey, func() any { return ctx.Repo.GitRepo })
+ ctx.Base.AppendContextValue(apiContextKey, ctx)
+ ctx.Base.AppendContextValueFunc(gitrepo.RepositoryContextKey, func() any { return ctx.Repo.GitRepo })
// If request sends files, parse them here otherwise the Query() can't be parsed and the CsrfToken will be invalid.
if ctx.Req.Method == "POST" && strings.Contains(ctx.Req.Header.Get("Content-Type"), "multipart/form-data") {
@@ -335,7 +334,7 @@ func (ctx *APIContext) NotFound(objs ...any) {
func ReferencesGitRepo(allowEmpty ...bool) func(ctx *APIContext) (cancel context.CancelFunc) {
return func(ctx *APIContext) (cancel context.CancelFunc) {
// Empty repository does not have reference information.
- if ctx.Repo.Repository.IsEmpty && (len(allowEmpty) == 0 || !allowEmpty[0]) {
+ if ctx.Repo.Repository.IsEmpty && !(len(allowEmpty) != 0 && allowEmpty[0]) {
return nil
}
@@ -366,12 +365,12 @@ func RepoRefForAPI(next http.Handler) http.Handler {
ctx := GetAPIContext(req)
if ctx.Repo.Repository.IsEmpty {
- ctx.NotFound(errors.New("repository is empty"))
+ ctx.NotFound(fmt.Errorf("repository is empty"))
return
}
if ctx.Repo.GitRepo == nil {
- ctx.InternalServerError(errors.New("no open git repo"))
+ ctx.InternalServerError(fmt.Errorf("no open git repo"))
return
}
diff --git a/services/context/api_org.go b/services/context/api_org.go
index acc9594e48..dad02b1719 100644
--- a/services/context/api_org.go
+++ b/services/context/api_org.go
@@ -3,7 +3,7 @@
package context
-import "forgejo.org/models/organization"
+import "code.gitea.io/gitea/models/organization"
// APIOrganization contains organization and team
type APIOrganization struct {
diff --git a/services/context/api_test.go b/services/context/api_test.go
index 4bc89939ca..6064fee1c3 100644
--- a/services/context/api_test.go
+++ b/services/context/api_test.go
@@ -8,15 +8,14 @@ import (
"strconv"
"testing"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/test"
+ "code.gitea.io/gitea/modules/setting"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestGenAPILinks(t *testing.T) {
- defer test.MockVariableValue(&setting.AppURL, "http://localhost:3000/")()
+ setting.AppURL = "http://localhost:3000/"
kases := map[string][]string{
"api/v1/repos/jerrykan/example-repo/issues?state=all": {
`; rel="next"`,
@@ -47,6 +46,6 @@ func TestGenAPILinks(t *testing.T) {
links := genAPILinks(u, 100, 20, curPage)
- assert.Equal(t, links, response)
+ assert.EqualValues(t, links, response)
}
}
diff --git a/services/context/base.go b/services/context/base.go
index dc3d226bb0..0259e0d806 100644
--- a/services/context/base.go
+++ b/services/context/base.go
@@ -14,12 +14,12 @@ import (
"strings"
"time"
- "forgejo.org/modules/httplib"
- "forgejo.org/modules/json"
- "forgejo.org/modules/log"
- "forgejo.org/modules/optional"
- "forgejo.org/modules/translation"
- "forgejo.org/modules/web/middleware"
+ "code.gitea.io/gitea/modules/httplib"
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/optional"
+ "code.gitea.io/gitea/modules/translation"
+ "code.gitea.io/gitea/modules/web/middleware"
"github.com/go-chi/chi/v5"
)
@@ -250,7 +250,7 @@ func (b *Base) PlainText(status int, text string) {
// Redirect redirects the request
func (b *Base) Redirect(location string, status ...int) {
code := http.StatusSeeOther
- if len(status) == 1 && status[0] > 0 {
+ if len(status) == 1 {
code = status[0]
}
diff --git a/services/context/base_test.go b/services/context/base_test.go
index 9e058d8f24..823f20e00b 100644
--- a/services/context/base_test.go
+++ b/services/context/base_test.go
@@ -8,14 +8,12 @@ import (
"net/http/httptest"
"testing"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/test"
+ "code.gitea.io/gitea/modules/setting"
"github.com/stretchr/testify/assert"
)
func TestRedirect(t *testing.T) {
- defer test.MockVariableValue(&setting.AppURL, "http://localhost:3000/")()
req, _ := http.NewRequest("GET", "/", nil)
cases := []struct {
@@ -36,7 +34,6 @@ func TestRedirect(t *testing.T) {
cleanup()
has := resp.Header().Get("Set-Cookie") == "i_like_gitea=dummy"
assert.Equal(t, c.keep, has, "url = %q", c.url)
- assert.Equal(t, http.StatusSeeOther, resp.Code)
}
req, _ = http.NewRequest("GET", "/", nil)
@@ -48,24 +45,3 @@ func TestRedirect(t *testing.T) {
assert.Equal(t, "/other", resp.Header().Get("HX-Redirect"))
assert.Equal(t, http.StatusNoContent, resp.Code)
}
-
-func TestRedirectOptionalStatus(t *testing.T) {
- defer test.MockVariableValue(&setting.AppURL, "http://localhost:3000/")()
- req, _ := http.NewRequest("GET", "/", nil)
-
- cases := []struct {
- expected int
- actual int
- }{
- {expected: 303},
- {http.StatusTemporaryRedirect, 307},
- {http.StatusPermanentRedirect, 308},
- }
- for _, c := range cases {
- resp := httptest.NewRecorder()
- b, cleanup := NewBaseContext(resp, req)
- b.Redirect("/", c.actual)
- cleanup()
- assert.Equal(t, c.expected, resp.Code)
- }
-}
diff --git a/services/context/captcha.go b/services/context/captcha.go
index 8ae8bdcae3..da837acb00 100644
--- a/services/context/captcha.go
+++ b/services/context/captcha.go
@@ -7,14 +7,14 @@ import (
"fmt"
"sync"
- "forgejo.org/modules/base"
- "forgejo.org/modules/cache"
- "forgejo.org/modules/hcaptcha"
- "forgejo.org/modules/log"
- "forgejo.org/modules/mcaptcha"
- "forgejo.org/modules/recaptcha"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/turnstile"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/cache"
+ "code.gitea.io/gitea/modules/hcaptcha"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/mcaptcha"
+ "code.gitea.io/gitea/modules/recaptcha"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/turnstile"
mc "code.forgejo.org/go-chi/cache"
"code.forgejo.org/go-chi/captcha"
diff --git a/services/context/context.go b/services/context/context.go
index 68074964c8..91e7b1849d 100644
--- a/services/context/context.go
+++ b/services/context/context.go
@@ -15,17 +15,17 @@ import (
"strings"
"time"
- "forgejo.org/models/unit"
- user_model "forgejo.org/models/user"
- mc "forgejo.org/modules/cache"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/httpcache"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/templates"
- "forgejo.org/modules/translation"
- "forgejo.org/modules/web"
- "forgejo.org/modules/web/middleware"
- web_types "forgejo.org/modules/web/types"
+ "code.gitea.io/gitea/models/unit"
+ user_model "code.gitea.io/gitea/models/user"
+ mc "code.gitea.io/gitea/modules/cache"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/httpcache"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/templates"
+ "code.gitea.io/gitea/modules/translation"
+ "code.gitea.io/gitea/modules/web"
+ "code.gitea.io/gitea/modules/web/middleware"
+ web_types "code.gitea.io/gitea/modules/web/types"
"code.forgejo.org/go-chi/cache"
"code.forgejo.org/go-chi/session"
@@ -41,7 +41,7 @@ type Render interface {
type Context struct {
*Base
- TemplateContext *templates.Context
+ TemplateContext TemplateContext
Render Render
PageData map[string]any // data used by JavaScript modules in one page, it's `window.config.pageData`
@@ -64,6 +64,8 @@ type Context struct {
Package *Package
}
+type TemplateContext map[string]any
+
func init() {
web.RegisterResponseStatusProvider[*Context](func(req *http.Request) web_types.ResponseStatusProvider {
return req.Context().Value(WebContextKey).(*Context)
@@ -96,11 +98,10 @@ func GetValidateContext(req *http.Request) (ctx *ValidateContext) {
return ctx
}
-func NewTemplateContextForWeb(ctx *Context) *templates.Context {
- tmplCtx := templates.NewContext(ctx)
- tmplCtx.Locale = ctx.Locale
- tmplCtx.AvatarUtils = templates.NewAvatarUtils(ctx)
- tmplCtx.Data = ctx.Data
+func NewTemplateContextForWeb(ctx *Context) TemplateContext {
+ tmplCtx := NewTemplateContext(ctx)
+ tmplCtx["Locale"] = ctx.Base.Locale
+ tmplCtx["AvatarUtils"] = templates.NewAvatarUtils(ctx)
return tmplCtx
}
@@ -120,18 +121,6 @@ func NewWebContext(base *Base, render Render, session session.Store) *Context {
return ctx
}
-func (ctx *Context) AddPluralStringsToPageData(keys []string) {
- for _, key := range keys {
- array, fallback := ctx.Locale.TrPluralStringAllForms(key)
-
- ctx.PageData["PLURALSTRINGS_LANG"].(map[string][]string)[key] = array
-
- if fallback != nil {
- ctx.PageData["PLURALSTRINGS_FALLBACK"].(map[string][]string)[key] = fallback
- }
- }
-}
-
// Contexter initializes a classic context for a request.
func Contexter() func(next http.Handler) http.Handler {
rnd := templates.HTMLRenderer()
@@ -162,8 +151,8 @@ func Contexter() func(next http.Handler) http.Handler {
ctx.PageData = map[string]any{}
ctx.Data["PageData"] = ctx.PageData
- ctx.AppendContextValue(WebContextKey, ctx)
- ctx.AppendContextValueFunc(gitrepo.RepositoryContextKey, func() any { return ctx.Repo.GitRepo })
+ ctx.Base.AppendContextValue(WebContextKey, ctx)
+ ctx.Base.AppendContextValueFunc(gitrepo.RepositoryContextKey, func() any { return ctx.Repo.GitRepo })
ctx.Csrf = NewCSRFProtector(csrfOpts)
@@ -219,25 +208,6 @@ func Contexter() func(next http.Handler) http.Handler {
ctx.Data["AllLangs"] = translation.AllLangs()
- ctx.PageData["PLURAL_RULE_LANG"] = translation.GetPluralRule(ctx.Locale)
- ctx.PageData["PLURAL_RULE_FALLBACK"] = translation.GetDefaultPluralRule()
- ctx.PageData["PLURALSTRINGS_LANG"] = map[string][]string{}
- ctx.PageData["PLURALSTRINGS_FALLBACK"] = map[string][]string{}
-
- ctx.AddPluralStringsToPageData([]string{"relativetime.mins", "relativetime.hours", "relativetime.days", "relativetime.weeks", "relativetime.months", "relativetime.years"})
-
- ctx.PageData["DATETIMESTRINGS"] = map[string]string{
- "FUTURE": ctx.Locale.TrString("relativetime.future"),
- "NOW": ctx.Locale.TrString("relativetime.now"),
- }
- for _, key := range []string{"relativetime.1day", "relativetime.1week", "relativetime.1month", "relativetime.1year", "relativetime.2days", "relativetime.2weeks", "relativetime.2months", "relativetime.2years"} {
- // These keys are used for special-casing some time words. We only add keys that are actually translated, so that we
- // can fall back to the generic pluralized time word in the correct language if the special case is untranslated.
- if ctx.Locale.HasKey(key) {
- ctx.PageData["DATETIMESTRINGS"].(map[string]string)[key] = ctx.Locale.TrString(key)
- }
- }
-
next.ServeHTTP(ctx.Resp, ctx.Req)
})
}
diff --git a/services/context/context_cookie.go b/services/context/context_cookie.go
index 08ef84b5eb..3699f81071 100644
--- a/services/context/context_cookie.go
+++ b/services/context/context_cookie.go
@@ -7,11 +7,11 @@ import (
"net/http"
"strings"
- auth_model "forgejo.org/models/auth"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/timeutil"
- "forgejo.org/modules/web/middleware"
+ auth_model "code.gitea.io/gitea/models/auth"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/timeutil"
+ "code.gitea.io/gitea/modules/web/middleware"
)
const CookieNameFlash = "gitea_flash"
diff --git a/services/context/context_model.go b/services/context/context_model.go
index 1a8751ee63..4f70aac516 100644
--- a/services/context/context_model.go
+++ b/services/context/context_model.go
@@ -4,7 +4,7 @@
package context
import (
- "forgejo.org/models/unit"
+ "code.gitea.io/gitea/models/unit"
)
// IsUserSiteAdmin returns true if current user is a site admin
diff --git a/services/context/context_response.go b/services/context/context_response.go
index 386bdd2652..f36b834a44 100644
--- a/services/context/context_response.go
+++ b/services/context/context_response.go
@@ -1,5 +1,4 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
-// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package context
@@ -17,14 +16,13 @@ import (
"syscall"
"time"
- "forgejo.org/models/auth"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/base"
- "forgejo.org/modules/httplib"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/templates"
- "forgejo.org/modules/web/middleware"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/httplib"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/templates"
+ "code.gitea.io/gitea/modules/web/middleware"
)
// RedirectToUser redirect to a differently-named user
@@ -68,10 +66,7 @@ func (ctx *Context) RedirectToFirst(location ...string) string {
return setting.AppSubURL + "/"
}
-const (
- tplStatus404 base.TplName = "status/404"
- tplStatus500 base.TplName = "status/500"
-)
+const tplStatus500 base.TplName = "status/500"
// HTML calls Context.HTML and renders the template to HTTP response
func (ctx *Context) HTML(status int, name base.TplName) {
@@ -130,21 +125,6 @@ func (ctx *Context) RenderWithErr(msg any, tpl base.TplName, form any) {
ctx.HTML(http.StatusOK, tpl)
}
-// validateTwoFactorRequirement sets ctx-data to hide/show ui-elements depending on the GlobalTwoFactorRequirement
-func (ctx *Context) validateTwoFactorRequirement() {
- if ctx.Doer == nil || !ctx.Doer.MustHaveTwoFactor() {
- return
- }
-
- hasTwoFactor, err := auth.HasTwoFactorByUID(ctx, ctx.Doer.ID)
- if err != nil {
- log.ErrorWithSkip(2, "Error getting 2fa: %s", err)
- // fallthrough to set the variables
- }
- ctx.Data["MustEnableTwoFactor"] = !hasTwoFactor
- ctx.Data["HideNavbarLinks"] = !hasTwoFactor
-}
-
// NotFound displays a 404 (Not Found) page and prints the given error, if any.
func (ctx *Context) NotFound(logMsg string, logErr error) {
ctx.notFoundInternal(logMsg, logErr)
@@ -172,10 +152,9 @@ func (ctx *Context) notFoundInternal(logMsg string, logErr error) {
return
}
- ctx.validateTwoFactorRequirement()
ctx.Data["IsRepo"] = ctx.Repo.Repository != nil
- ctx.Data["Title"] = ctx.Locale.TrString("error.not_found.title")
- ctx.HTML(http.StatusNotFound, tplStatus404)
+ ctx.Data["Title"] = "Page Not Found"
+ ctx.HTML(http.StatusNotFound, base.TplName("status/404"))
}
// ServerError displays a 500 (Internal Server Error) page and prints the given error, if any.
@@ -198,7 +177,7 @@ func (ctx *Context) serverErrorInternal(logMsg string, logErr error) {
}
}
- ctx.validateTwoFactorRequirement()
+ ctx.Data["Title"] = "Internal Server Error"
ctx.HTML(http.StatusInternalServerError, tplStatus500)
}
diff --git a/services/context/context_template.go b/services/context/context_template.go
new file mode 100644
index 0000000000..7878d409ca
--- /dev/null
+++ b/services/context/context_template.go
@@ -0,0 +1,35 @@
+// Copyright 2023 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package context
+
+import (
+ "context"
+ "time"
+)
+
+var _ context.Context = TemplateContext(nil)
+
+func NewTemplateContext(ctx context.Context) TemplateContext {
+ return TemplateContext{"_ctx": ctx}
+}
+
+func (c TemplateContext) parentContext() context.Context {
+ return c["_ctx"].(context.Context)
+}
+
+func (c TemplateContext) Deadline() (deadline time.Time, ok bool) {
+ return c.parentContext().Deadline()
+}
+
+func (c TemplateContext) Done() <-chan struct{} {
+ return c.parentContext().Done()
+}
+
+func (c TemplateContext) Err() error {
+ return c.parentContext().Err()
+}
+
+func (c TemplateContext) Value(key any) any {
+ return c.parentContext().Value(key)
+}
diff --git a/services/context/context_test.go b/services/context/context_test.go
index c2a271d2b7..033ce2ef0a 100644
--- a/services/context/context_test.go
+++ b/services/context/context_test.go
@@ -8,7 +8,7 @@ import (
"net/http/httptest"
"testing"
- "forgejo.org/modules/setting"
+ "code.gitea.io/gitea/modules/setting"
"github.com/stretchr/testify/assert"
)
diff --git a/services/context/csrf.go b/services/context/csrf.go
index 82dd9283ff..51127c6eb0 100644
--- a/services/context/csrf.go
+++ b/services/context/csrf.go
@@ -25,8 +25,8 @@ import (
"strconv"
"time"
- "forgejo.org/modules/log"
- "forgejo.org/modules/util"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/util"
)
const (
diff --git a/services/context/org.go b/services/context/org.go
index c7d06b9bcc..9673f2f5a9 100644
--- a/services/context/org.go
+++ b/services/context/org.go
@@ -1,6 +1,5 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
-// Copyright 2020 The Gitea Authors. All rights reserved.
-// Copyright 2025 The Forgejo Authors. All rights reserved.
+// Copyright 2020 The Gitea Authors.
// SPDX-License-Identifier: MIT
package context
@@ -8,15 +7,14 @@ package context
import (
"strings"
- "forgejo.org/models/organization"
- "forgejo.org/models/perm"
- "forgejo.org/models/unit"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/markup"
- "forgejo.org/modules/markup/markdown"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/structs"
- redirect_service "forgejo.org/services/redirect"
+ "code.gitea.io/gitea/models/organization"
+ "code.gitea.io/gitea/models/perm"
+ "code.gitea.io/gitea/models/unit"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/markup"
+ "code.gitea.io/gitea/modules/markup/markdown"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/structs"
)
// Organization contains organization context
@@ -49,13 +47,13 @@ func GetOrganizationByParams(ctx *Context) {
ctx.Org.Organization, err = organization.GetOrgByName(ctx, orgName)
if err != nil {
if organization.IsErrOrgNotExist(err) {
- redirectUserID, err := redirect_service.LookupUserRedirect(ctx, ctx.Doer, orgName)
+ redirectUserID, err := user_model.LookupUserRedirect(ctx, orgName)
if err == nil {
RedirectToUser(ctx.Base, orgName, redirectUserID)
} else if user_model.IsErrUserRedirectNotExist(err) {
ctx.NotFound("GetUserByName", err)
} else {
- ctx.ServerError("LookupRedirect", err)
+ ctx.ServerError("LookupUserRedirect", err)
}
} else {
ctx.ServerError("GetUserByName", err)
@@ -167,7 +165,6 @@ func HandleOrgAssignment(ctx *Context, args ...bool) {
ctx.Data["IsOrganizationMember"] = ctx.Org.IsMember
ctx.Data["IsPackageEnabled"] = setting.Packages.Enabled
ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
- ctx.Data["IsModerationEnabled"] = setting.Moderation.Enabled
ctx.Data["IsPublicMember"] = func(uid int64) bool {
is, _ := organization.IsPublicMembership(ctx, ctx.Org.Organization.ID, uid)
return is
diff --git a/services/context/package.go b/services/context/package.go
index 50ffa8eb7c..c452c657e7 100644
--- a/services/context/package.go
+++ b/services/context/package.go
@@ -7,14 +7,14 @@ import (
"fmt"
"net/http"
- "forgejo.org/models/organization"
- packages_model "forgejo.org/models/packages"
- "forgejo.org/models/perm"
- "forgejo.org/models/unit"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/structs"
- "forgejo.org/modules/templates"
+ "code.gitea.io/gitea/models/organization"
+ packages_model "code.gitea.io/gitea/models/packages"
+ "code.gitea.io/gitea/models/perm"
+ "code.gitea.io/gitea/models/unit"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/templates"
)
// Package contains owner, access mode and optional the package descriptor
@@ -97,7 +97,7 @@ func determineAccessMode(ctx *Base, pkg *Package, doer *user_model.User) (perm.A
return perm.AccessModeNone, nil
}
- if doer != nil && !doer.IsGhost() && !doer.IsAccessAllowed(ctx) {
+ if doer != nil && !doer.IsGhost() && (!doer.IsActive || doer.ProhibitLogin) {
return perm.AccessModeNone, nil
}
@@ -158,7 +158,7 @@ func PackageContexter() func(next http.Handler) http.Handler {
// it is still needed when rendering 500 page in a package handler
ctx := NewWebContext(base, renderer, nil)
- ctx.AppendContextValue(WebContextKey, ctx)
+ ctx.Base.AppendContextValue(WebContextKey, ctx)
next.ServeHTTP(ctx.Resp, ctx.Req)
})
}
diff --git a/services/context/pagination.go b/services/context/pagination.go
index b826e59dea..655a278f9f 100644
--- a/services/context/pagination.go
+++ b/services/context/pagination.go
@@ -9,7 +9,7 @@ import (
"net/url"
"strings"
- "forgejo.org/modules/paginator"
+ "code.gitea.io/gitea/modules/paginator"
)
// Pagination provides a pagination via paginator.Paginator and additional configurations for the link params used in rendering
diff --git a/services/context/permission.go b/services/context/permission.go
index b6af87f912..14a9801dcc 100644
--- a/services/context/permission.go
+++ b/services/context/permission.go
@@ -6,10 +6,10 @@ package context
import (
"net/http"
- auth_model "forgejo.org/models/auth"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unit"
- "forgejo.org/modules/log"
+ auth_model "code.gitea.io/gitea/models/auth"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unit"
+ "code.gitea.io/gitea/modules/log"
)
// RequireRepoAdmin returns a middleware for requiring repository admin permission
diff --git a/services/context/private.go b/services/context/private.go
index 94ee31876a..8b41949f60 100644
--- a/services/context/private.go
+++ b/services/context/private.go
@@ -9,10 +9,10 @@ import (
"net/http"
"time"
- "forgejo.org/modules/graceful"
- "forgejo.org/modules/process"
- "forgejo.org/modules/web"
- web_types "forgejo.org/modules/web/types"
+ "code.gitea.io/gitea/modules/graceful"
+ "code.gitea.io/gitea/modules/process"
+ "code.gitea.io/gitea/modules/web"
+ web_types "code.gitea.io/gitea/modules/web/types"
)
// PrivateContext represents a context for private routes
@@ -67,7 +67,7 @@ func PrivateContexter() func(http.Handler) http.Handler {
base, baseCleanUp := NewBaseContext(w, req)
ctx := &PrivateContext{Base: base}
defer baseCleanUp()
- ctx.AppendContextValue(privateContextKey, ctx)
+ ctx.Base.AppendContextValue(privateContextKey, ctx)
next.ServeHTTP(ctx.Resp, ctx.Req)
})
diff --git a/services/context/quota.go b/services/context/quota.go
index 502a316107..94e8847696 100644
--- a/services/context/quota.go
+++ b/services/context/quota.go
@@ -8,8 +8,8 @@ import (
"net/http"
"strings"
- quota_model "forgejo.org/models/quota"
- "forgejo.org/modules/base"
+ quota_model "code.gitea.io/gitea/models/quota"
+ "code.gitea.io/gitea/modules/base"
)
type QuotaTargetType int
@@ -64,7 +64,7 @@ func QuotaRuleAssignmentAPI() func(ctx *APIContext) {
// ctx.CheckQuota checks whether the user in question is within quota limits (web context)
func (ctx *Context) CheckQuota(subject quota_model.LimitSubject, userID int64, username string) bool {
- ok, err := checkQuota(ctx.originCtx, subject, userID, username, func(userID int64, username string) {
+ ok, err := checkQuota(ctx.Base.originCtx, subject, userID, username, func(userID int64, username string) {
showHTML := false
for _, part := range ctx.Req.Header["Accept"] {
if strings.Contains(part, "text/html") {
@@ -91,7 +91,7 @@ func (ctx *Context) CheckQuota(subject quota_model.LimitSubject, userID int64, u
// ctx.CheckQuota checks whether the user in question is within quota limits (API context)
func (ctx *APIContext) CheckQuota(subject quota_model.LimitSubject, userID int64, username string) bool {
- ok, err := checkQuota(ctx.originCtx, subject, userID, username, func(userID int64, username string) {
+ ok, err := checkQuota(ctx.Base.originCtx, subject, userID, username, func(userID int64, username string) {
ctx.JSON(http.StatusRequestEntityTooLarge, APIQuotaExceeded{
Message: "quota exceeded",
UserID: userID,
diff --git a/services/context/repo.go b/services/context/repo.go
index e01e1ddafc..ff03844c03 100644
--- a/services/context/repo.go
+++ b/services/context/repo.go
@@ -15,27 +15,26 @@ import (
"path"
"strings"
- "forgejo.org/models"
- "forgejo.org/models/db"
- git_model "forgejo.org/models/git"
- issues_model "forgejo.org/models/issues"
- packages_model "forgejo.org/models/packages"
- access_model "forgejo.org/models/perm/access"
- repo_model "forgejo.org/models/repo"
- unit_model "forgejo.org/models/unit"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/cache"
- "forgejo.org/modules/card"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- code_indexer "forgejo.org/modules/indexer/code"
- "forgejo.org/modules/log"
- "forgejo.org/modules/optional"
- repo_module "forgejo.org/modules/repository"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/util"
- asymkey_service "forgejo.org/services/asymkey"
- redirect_service "forgejo.org/services/redirect"
+ "code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/models/db"
+ git_model "code.gitea.io/gitea/models/git"
+ issues_model "code.gitea.io/gitea/models/issues"
+ packages_model "code.gitea.io/gitea/models/packages"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ repo_model "code.gitea.io/gitea/models/repo"
+ unit_model "code.gitea.io/gitea/models/unit"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/cache"
+ "code.gitea.io/gitea/modules/card"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ code_indexer "code.gitea.io/gitea/modules/indexer/code"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/optional"
+ repo_module "code.gitea.io/gitea/modules/repository"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/util"
+ asymkey_service "code.gitea.io/gitea/services/asymkey"
"github.com/editorconfig/editorconfig-core-go/v2"
)
@@ -84,7 +83,7 @@ func (r *Repository) CanEnableEditor(ctx context.Context, user *user_model.User)
// CanCreateBranch returns true if repository is editable and user has proper access level.
func (r *Repository) CanCreateBranch() bool {
- return r.CanWrite(unit_model.TypeCode) && r.Repository.CanCreateBranch()
+ return r.Permission.CanWrite(unit_model.TypeCode) && r.Repository.CanCreateBranch()
}
func (r *Repository) GetObjectFormat() git.ObjectFormat {
@@ -161,12 +160,12 @@ func (r *Repository) CanUseTimetracker(ctx context.Context, issue *issues_model.
// 2. Is the user a contributor, admin, poster or assignee and do the repository policies require this?
isAssigned, _ := issues_model.IsUserAssignedToIssue(ctx, issue, user)
return r.Repository.IsTimetrackerEnabled(ctx) && (!r.Repository.AllowOnlyContributorsToTrackTime(ctx) ||
- r.CanWriteIssuesOrPulls(issue.IsPull) || issue.IsPoster(user.ID) || isAssigned)
+ r.Permission.CanWriteIssuesOrPulls(issue.IsPull) || issue.IsPoster(user.ID) || isAssigned)
}
// CanCreateIssueDependencies returns whether or not a user can create dependencies.
func (r *Repository) CanCreateIssueDependencies(ctx context.Context, user *user_model.User, isPull bool) bool {
- return r.Repository.IsDependenciesEnabled(ctx) && r.CanWriteIssuesOrPulls(isPull)
+ return r.Repository.IsDependenciesEnabled(ctx) && r.Permission.CanWriteIssuesOrPulls(isPull)
}
// GetCommitsCount returns cached commit count for current view
@@ -362,9 +361,7 @@ func RedirectToRepo(ctx *Base, redirectRepoID int64) {
if ctx.Req.URL.RawQuery != "" {
redirectPath += "?" + ctx.Req.URL.RawQuery
}
- // Git client needs a 301 redirect by default to follow the new location
- // It's not documentated in git documentation, but it's the behavior of git client
- ctx.Redirect(path.Join(setting.AppSubURL, redirectPath), http.StatusMovedPermanently)
+ ctx.Redirect(path.Join(setting.AppSubURL, redirectPath), http.StatusTemporaryRedirect)
}
func repoAssignment(ctx *Context, repo *repo_model.Repository) {
@@ -381,7 +378,7 @@ func repoAssignment(ctx *Context, repo *repo_model.Repository) {
}
// Check access.
- if !ctx.Repo.HasAccess() {
+ if !ctx.Repo.Permission.HasAccess() {
if ctx.FormString("go-get") == "1" {
EarlyResponseForGoGetMeta(ctx)
return
@@ -478,12 +475,12 @@ func RepoAssignment(ctx *Context) context.CancelFunc {
return nil
}
- if redirectUserID, err := redirect_service.LookupUserRedirect(ctx, ctx.Doer, userName); err == nil {
+ if redirectUserID, err := user_model.LookupUserRedirect(ctx, userName); err == nil {
RedirectToUser(ctx.Base, userName, redirectUserID)
} else if user_model.IsErrUserRedirectNotExist(err) {
ctx.NotFound("GetUserByName", nil)
} else {
- ctx.ServerError("LookupRedirect", err)
+ ctx.ServerError("LookupUserRedirect", err)
}
} else {
ctx.ServerError("GetUserByName", err)
@@ -520,7 +517,7 @@ func RepoAssignment(ctx *Context) context.CancelFunc {
repo, err := repo_model.GetRepositoryByName(ctx, owner.ID, repoName)
if err != nil {
if repo_model.IsErrRepoNotExist(err) {
- redirectRepoID, err := redirect_service.LookupRepoRedirect(ctx, ctx.Doer, owner.ID, repoName)
+ redirectRepoID, err := repo_model.LookupRedirect(ctx, owner.ID, repoName)
if err == nil {
RedirectToRepo(ctx.Base, redirectRepoID)
} else if repo_model.IsErrRedirectNotExist(err) {
@@ -594,7 +591,6 @@ func RepoAssignment(ctx *Context) context.CancelFunc {
ctx.Data["CanWriteIssues"] = ctx.Repo.CanWrite(unit_model.TypeIssues)
ctx.Data["CanWritePulls"] = ctx.Repo.CanWrite(unit_model.TypePullRequests)
ctx.Data["CanWriteActions"] = ctx.Repo.CanWrite(unit_model.TypeActions)
- ctx.Data["IsModerationEnabled"] = setting.Moderation.Enabled
canSignedUserFork, err := repo_module.CanUserForkRepo(ctx, ctx.Doer, ctx.Repo.Repository)
if err != nil {
@@ -645,11 +641,7 @@ func RepoAssignment(ctx *Context) context.CancelFunc {
ctx.Data["OpenGraphImageURL"] = repo.SummaryCardURL()
ctx.Data["OpenGraphImageWidth"] = cardWidth
ctx.Data["OpenGraphImageHeight"] = cardHeight
- if util.IsEmptyString(repo.Description) {
- ctx.Data["OpenGraphImageAltText"] = ctx.Tr("repo.summary_card_alt", repo.FullName())
- } else {
- ctx.Data["OpenGraphImageAltText"] = ctx.Tr("og.repo.summary_card.alt_description", repo.FullName(), repo.Description)
- }
+ ctx.Data["OpenGraphImageAltText"] = ctx.Tr("repo.summary_card_alt", repo.FullName())
if repo.IsFork {
RetrieveBaseRepo(ctx, repo)
diff --git a/services/context/repository.go b/services/context/repository.go
index 7eef2c5068..422ac3f58d 100644
--- a/services/context/repository.go
+++ b/services/context/repository.go
@@ -6,7 +6,7 @@ package context
import (
"net/http"
- repo_model "forgejo.org/models/repo"
+ repo_model "code.gitea.io/gitea/models/repo"
)
// RepositoryIDAssignmentAPI returns a middleware to handle context-repo assignment for api routes
diff --git a/services/context/response.go b/services/context/response.go
index 8fc631e671..2f271f211b 100644
--- a/services/context/response.go
+++ b/services/context/response.go
@@ -6,7 +6,7 @@ package context
import (
"net/http"
- web_types "forgejo.org/modules/web/types"
+ web_types "code.gitea.io/gitea/modules/web/types"
)
// ResponseWriter represents a response writer for HTTP
diff --git a/services/context/upload/upload.go b/services/context/upload/upload.go
index e71fc50c1f..77a7eb9377 100644
--- a/services/context/upload/upload.go
+++ b/services/context/upload/upload.go
@@ -11,9 +11,9 @@ import (
"regexp"
"strings"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- "forgejo.org/services/context"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/services/context"
)
// ErrFileTypeForbidden not allowed file type error
@@ -76,15 +76,14 @@ func Verify(buf []byte, fileName, allowedTypesStr string) error {
// AddUploadContext renders template values for dropzone
func AddUploadContext(ctx *context.Context, uploadType string) {
- switch uploadType {
- case "release":
+ if uploadType == "release" {
ctx.Data["UploadUrl"] = ctx.Repo.RepoLink + "/releases/attachments"
ctx.Data["UploadRemoveUrl"] = ctx.Repo.RepoLink + "/releases/attachments/remove"
ctx.Data["UploadLinkUrl"] = ctx.Repo.RepoLink + "/releases/attachments"
ctx.Data["UploadAccepts"] = strings.ReplaceAll(setting.Repository.Release.AllowedTypes, "|", ",")
ctx.Data["UploadMaxFiles"] = setting.Attachment.MaxFiles
ctx.Data["UploadMaxSize"] = setting.Attachment.MaxSize
- case "comment":
+ } else if uploadType == "comment" {
ctx.Data["UploadUrl"] = ctx.Repo.RepoLink + "/issues/attachments"
ctx.Data["UploadRemoveUrl"] = ctx.Repo.RepoLink + "/issues/attachments/remove"
if len(ctx.Params(":index")) > 0 {
@@ -95,7 +94,7 @@ func AddUploadContext(ctx *context.Context, uploadType string) {
ctx.Data["UploadAccepts"] = strings.ReplaceAll(setting.Attachment.AllowedTypes, "|", ",")
ctx.Data["UploadMaxFiles"] = setting.Attachment.MaxFiles
ctx.Data["UploadMaxSize"] = setting.Attachment.MaxSize
- case "repo":
+ } else if uploadType == "repo" {
ctx.Data["UploadUrl"] = ctx.Repo.RepoLink + "/upload-file"
ctx.Data["UploadRemoveUrl"] = ctx.Repo.RepoLink + "/upload-remove"
ctx.Data["UploadLinkUrl"] = ctx.Repo.RepoLink + "/upload-file"
diff --git a/services/context/user.go b/services/context/user.go
index 63260a49aa..4c9cd2928b 100644
--- a/services/context/user.go
+++ b/services/context/user.go
@@ -8,8 +8,7 @@ import (
"net/http"
"strings"
- user_model "forgejo.org/models/user"
- redirect_service "forgejo.org/services/redirect"
+ user_model "code.gitea.io/gitea/models/user"
)
// UserAssignmentWeb returns a middleware to handle context-user assignment for web routes
@@ -69,12 +68,12 @@ func userAssignment(ctx *Base, doer *user_model.User, errCb func(int, string, an
contextUser, err = user_model.GetUserByName(ctx, username)
if err != nil {
if user_model.IsErrUserNotExist(err) {
- if redirectUserID, err := redirect_service.LookupUserRedirect(ctx, doer, username); err == nil {
+ if redirectUserID, err := user_model.LookupUserRedirect(ctx, username); err == nil {
RedirectToUser(ctx, username, redirectUserID)
} else if user_model.IsErrUserRedirectNotExist(err) {
errCb(http.StatusNotFound, "GetUserByName", err)
} else {
- errCb(http.StatusInternalServerError, "LookupRedirect", err)
+ errCb(http.StatusInternalServerError, "LookupUserRedirect", err)
}
} else {
errCb(http.StatusInternalServerError, "GetUserByName", err)
diff --git a/services/contexttest/context_tests.go b/services/contexttest/context_tests.go
index a4e674a896..7c829f3598 100644
--- a/services/contexttest/context_tests.go
+++ b/services/contexttest/context_tests.go
@@ -15,16 +15,16 @@ import (
"testing"
"time"
- org_model "forgejo.org/models/organization"
- access_model "forgejo.org/models/perm/access"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unittest"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/templates"
- "forgejo.org/modules/translation"
- "forgejo.org/modules/web/middleware"
- "forgejo.org/services/context"
+ org_model "code.gitea.io/gitea/models/organization"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unittest"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/templates"
+ "code.gitea.io/gitea/modules/translation"
+ "code.gitea.io/gitea/modules/web/middleware"
+ "code.gitea.io/gitea/services/context"
"github.com/go-chi/chi/v5"
"github.com/stretchr/testify/assert"
@@ -68,7 +68,7 @@ func MockContext(t *testing.T, reqPath string, opts ...MockContextOption) (*cont
ctx.PageData = map[string]any{}
ctx.Data["PageStartTime"] = time.Now()
chiCtx := chi.NewRouteContext()
- ctx.AppendContextValue(chi.RouteCtxKey, chiCtx)
+ ctx.Base.AppendContextValue(chi.RouteCtxKey, chiCtx)
return ctx, resp
}
@@ -83,7 +83,7 @@ func MockAPIContext(t *testing.T, reqPath string) (*context.APIContext, *httptes
_ = baseCleanUp // during test, it doesn't need to do clean up. TODO: this can be improved later
chiCtx := chi.NewRouteContext()
- ctx.AppendContextValue(chi.RouteCtxKey, chiCtx)
+ ctx.Base.AppendContextValue(chi.RouteCtxKey, chiCtx)
return ctx, resp
}
@@ -96,7 +96,7 @@ func MockPrivateContext(t *testing.T, reqPath string) (*context.PrivateContext,
ctx := &context.PrivateContext{Base: base}
_ = baseCleanUp // during test, it doesn't need to do clean up. TODO: this can be improved later
chiCtx := chi.NewRouteContext()
- ctx.AppendContextValue(chi.RouteCtxKey, chiCtx)
+ ctx.Base.AppendContextValue(chi.RouteCtxKey, chiCtx)
return ctx, resp
}
diff --git a/services/contexttest/pagedata_test.go b/services/contexttest/pagedata_test.go
deleted file mode 100644
index 0c9319b6db..0000000000
--- a/services/contexttest/pagedata_test.go
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2024 The Forgejo Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package contexttest
-
-import (
- "testing"
-
- "forgejo.org/modules/translation"
- "forgejo.org/modules/translation/i18n"
-
- "github.com/stretchr/testify/assert"
-)
-
-func TestPluralStringsForClient(t *testing.T) {
- mockLocale := translation.MockLocale{}
- mockLocale.MockTranslations = map[string]string{
- "relativetime.mins" + i18n.PluralFormSeparator + "one": "%d minute ago",
- "relativetime.hours" + i18n.PluralFormSeparator + "one": "%d hour ago",
- "relativetime.days" + i18n.PluralFormSeparator + "one": "%d day ago",
- "relativetime.weeks" + i18n.PluralFormSeparator + "one": "%d week ago",
- "relativetime.months" + i18n.PluralFormSeparator + "one": "%d month ago",
- "relativetime.years" + i18n.PluralFormSeparator + "one": "%d year ago",
- "relativetime.mins" + i18n.PluralFormSeparator + "other": "%d minutes ago",
- "relativetime.hours" + i18n.PluralFormSeparator + "other": "%d hours ago",
- "relativetime.days" + i18n.PluralFormSeparator + "other": "%d days ago",
- "relativetime.weeks" + i18n.PluralFormSeparator + "other": "%d weeks ago",
- "relativetime.months" + i18n.PluralFormSeparator + "other": "%d months ago",
- "relativetime.years" + i18n.PluralFormSeparator + "other": "%d years ago",
- }
-
- ctx, _ := MockContext(t, "/")
- ctx.Locale = mockLocale
- assert.True(t, ctx.Locale.HasKey("relativetime.mins"))
- assert.True(t, ctx.Locale.HasKey("relativetime.weeks"))
- assert.Equal(t, "%d minutes ago", ctx.Locale.TrString("relativetime.mins"+i18n.PluralFormSeparator+"other"))
- assert.Equal(t, "%d week ago", ctx.Locale.TrString("relativetime.weeks"+i18n.PluralFormSeparator+"one"))
-
- assert.Empty(t, ctx.PageData)
- ctx.PageData["PLURALSTRINGS_LANG"] = map[string][]string{}
- assert.Empty(t, ctx.PageData["PLURALSTRINGS_LANG"])
-
- ctx.AddPluralStringsToPageData([]string{"relativetime.mins", "relativetime.hours"})
- assert.Len(t, ctx.PageData["PLURALSTRINGS_LANG"], 2)
- assert.Len(t, ctx.PageData["PLURALSTRINGS_LANG"].(map[string][]string)["relativetime.mins"], 2)
- assert.Len(t, ctx.PageData["PLURALSTRINGS_LANG"].(map[string][]string)["relativetime.hours"], 2)
- assert.Equal(t, "%d minute ago", ctx.PageData["PLURALSTRINGS_LANG"].(map[string][]string)["relativetime.mins"][0])
- assert.Equal(t, "%d minutes ago", ctx.PageData["PLURALSTRINGS_LANG"].(map[string][]string)["relativetime.mins"][1])
- assert.Equal(t, "%d hour ago", ctx.PageData["PLURALSTRINGS_LANG"].(map[string][]string)["relativetime.hours"][0])
- assert.Equal(t, "%d hours ago", ctx.PageData["PLURALSTRINGS_LANG"].(map[string][]string)["relativetime.hours"][1])
-
- ctx.AddPluralStringsToPageData([]string{"relativetime.years", "relativetime.days"})
- assert.Len(t, ctx.PageData["PLURALSTRINGS_LANG"], 4)
- assert.Len(t, ctx.PageData["PLURALSTRINGS_LANG"].(map[string][]string)["relativetime.mins"], 2)
- assert.Len(t, ctx.PageData["PLURALSTRINGS_LANG"].(map[string][]string)["relativetime.days"], 2)
- assert.Len(t, ctx.PageData["PLURALSTRINGS_LANG"].(map[string][]string)["relativetime.years"], 2)
- assert.Equal(t, "%d minute ago", ctx.PageData["PLURALSTRINGS_LANG"].(map[string][]string)["relativetime.mins"][0])
- assert.Equal(t, "%d minutes ago", ctx.PageData["PLURALSTRINGS_LANG"].(map[string][]string)["relativetime.mins"][1])
- assert.Equal(t, "%d day ago", ctx.PageData["PLURALSTRINGS_LANG"].(map[string][]string)["relativetime.days"][0])
- assert.Equal(t, "%d days ago", ctx.PageData["PLURALSTRINGS_LANG"].(map[string][]string)["relativetime.days"][1])
- assert.Equal(t, "%d year ago", ctx.PageData["PLURALSTRINGS_LANG"].(map[string][]string)["relativetime.years"][0])
- assert.Equal(t, "%d years ago", ctx.PageData["PLURALSTRINGS_LANG"].(map[string][]string)["relativetime.years"][1])
-}
diff --git a/services/convert/action.go b/services/convert/action.go
deleted file mode 100644
index 703c1f1261..0000000000
--- a/services/convert/action.go
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2025 The Forgejo Authors. All rights reserved.
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-package convert
-
-import (
- "context"
-
- actions_model "forgejo.org/models/actions"
- access_model "forgejo.org/models/perm/access"
- user_model "forgejo.org/models/user"
- api "forgejo.org/modules/structs"
-)
-
-// ToActionRun convert actions_model.User to api.ActionRun
-// the run needs all attributes loaded
-func ToActionRun(ctx context.Context, run *actions_model.ActionRun, doer *user_model.User) *api.ActionRun {
- if run == nil {
- return nil
- }
-
- permissionInRepo, _ := access_model.GetUserRepoPermission(ctx, run.Repo, doer)
-
- return &api.ActionRun{
- ID: run.ID,
- Title: run.Title,
- Repo: ToRepo(ctx, run.Repo, permissionInRepo),
- WorkflowID: run.WorkflowID,
- Index: run.Index,
- TriggerUser: ToUser(ctx, run.TriggerUser, doer),
- ScheduleID: run.ScheduleID,
- PrettyRef: run.PrettyRef(),
- IsRefDeleted: run.IsRefDeleted,
- CommitSHA: run.CommitSHA,
- IsForkPullRequest: run.IsForkPullRequest,
- NeedApproval: run.NeedApproval,
- ApprovedBy: run.ApprovedBy,
- Event: run.Event.Event(),
- EventPayload: run.EventPayload,
- TriggerEvent: run.TriggerEvent,
- Status: run.Status.String(),
- Started: run.Started.AsTime(),
- Stopped: run.Stopped.AsTime(),
- Created: run.Created.AsTime(),
- Updated: run.Updated.AsTime(),
- Duration: run.Duration(),
- HTMLURL: run.HTMLURL(),
- }
-}
diff --git a/services/convert/activity.go b/services/convert/activity.go
index 213db13772..01fef73e58 100644
--- a/services/convert/activity.go
+++ b/services/convert/activity.go
@@ -6,12 +6,12 @@ package convert
import (
"context"
- activities_model "forgejo.org/models/activities"
- perm_model "forgejo.org/models/perm"
- access_model "forgejo.org/models/perm/access"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/log"
- api "forgejo.org/modules/structs"
+ activities_model "code.gitea.io/gitea/models/activities"
+ perm_model "code.gitea.io/gitea/models/perm"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/log"
+ api "code.gitea.io/gitea/modules/structs"
)
func ToActivity(ctx context.Context, ac *activities_model.Action, doer *user_model.User) *api.Activity {
diff --git a/services/convert/activitypub_person.go b/services/convert/activitypub_person.go
deleted file mode 100644
index 2c05f8c1c0..0000000000
--- a/services/convert/activitypub_person.go
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2024 The Forgejo Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package convert
-
-import (
- "context"
-
- "forgejo.org/models/activities"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/activitypub"
-
- ap "github.com/go-ap/activitypub"
-)
-
-func ToActivityPubPersonFeedItem(item *activities.FederatedUserActivity) ap.Note {
- return ap.Note{
- AttributedTo: ap.IRI(item.ActorURI),
- Content: ap.NaturalLanguageValues{{Value: ap.Content(item.NoteContent), Ref: ap.NilLangRef}},
- ID: ap.IRI(item.NoteURL),
- URL: ap.IRI(item.OriginalNote),
- }
-}
-
-func ToActivityPubPerson(ctx context.Context, user *user_model.User) (*ap.Person, error) {
- link := user.APActorID()
- person := ap.PersonNew(ap.IRI(link))
-
- person.Name = ap.NaturalLanguageValuesNew()
- err := person.Name.Set("en", ap.Content(user.FullName))
- if err != nil {
- return nil, err
- }
-
- person.PreferredUsername = ap.NaturalLanguageValuesNew()
- err = person.PreferredUsername.Set("en", ap.Content(user.Name))
- if err != nil {
- return nil, err
- }
-
- person.URL = ap.IRI(user.HTMLURL())
-
- person.Icon = ap.Image{
- Type: ap.ImageType,
- MediaType: "image/png",
- URL: ap.IRI(user.AvatarLink(ctx)),
- }
-
- person.Inbox = ap.IRI(link + "/inbox")
- person.Outbox = ap.IRI(link + "/outbox")
-
- person.PublicKey.ID = ap.IRI(link + "#main-key")
- person.PublicKey.Owner = ap.IRI(link)
-
- publicKeyPem, err := activitypub.GetPublicKey(ctx, user)
- if err != nil {
- return nil, err
- }
- person.PublicKey.PublicKeyPem = publicKeyPem
-
- return person, nil
-}
diff --git a/services/convert/activitypub_user_action.go b/services/convert/activitypub_user_action.go
deleted file mode 100644
index 9c62e6f25c..0000000000
--- a/services/convert/activitypub_user_action.go
+++ /dev/null
@@ -1,177 +0,0 @@
-// Copyright 2024 The Forgejo Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package convert
-
-import (
- "context"
- "fmt"
- "html"
- "net/url"
- "time"
-
- activities_model "forgejo.org/models/activities"
- issues_model "forgejo.org/models/issues"
- fm "forgejo.org/modules/forgefed"
- "forgejo.org/modules/json"
- "forgejo.org/modules/markup"
- "forgejo.org/modules/markup/markdown"
-)
-
-func ActionToForgeUserActivity(ctx context.Context, action *activities_model.Action) (fm.ForgeUserActivity, error) {
- render := func(format string, args ...any) string {
- return fmt.Sprintf(`%s %s`, action.ActUser.HTMLURL(), action.GetActDisplayName(ctx), fmt.Sprintf(format, args...))
- }
- renderIssue := func(issue *issues_model.Issue) string {
- return fmt.Sprintf(`%s#%d `,
- issue.HTMLURL(),
- action.GetRepoPath(ctx),
- issue.Index,
- )
- }
- renderRepo := func() string {
- return fmt.Sprintf(`%s `, action.Repo.HTMLURL(), action.GetRepoPath(ctx))
- }
- renderBranch := func() string {
- return fmt.Sprintf(`%s `, action.GetRefLink(ctx), action.GetBranch())
- }
- renderTag := func() string {
- return fmt.Sprintf(`%s `, action.GetRefLink(ctx), action.GetTag())
- }
-
- makeUserActivity := func(format string, args ...any) (fm.ForgeUserActivity, error) {
- return fm.NewForgeUserActivity(action.ActUser, action.ID, render(format, args...))
- }
-
- switch action.OpType {
- case activities_model.ActionCreateRepo:
- return makeUserActivity("created a new repository: %s", renderRepo())
- case activities_model.ActionRenameRepo:
- return makeUserActivity("renamed a repository: %s", renderRepo())
- case activities_model.ActionStarRepo:
- return makeUserActivity("starred a repository: %s", renderRepo())
- case activities_model.ActionWatchRepo:
- return makeUserActivity("started watching a repository: %s", renderRepo())
- case activities_model.ActionCommitRepo:
- type PushCommit struct {
- Sha1 string
- Message string
- AuthorEmail string
- AuthorName string
- CommitterEmail string
- CommitterName string
- Timestamp time.Time
- }
- type PushCommits struct {
- Commits []*PushCommit
- HeadCommit *PushCommit
- CompareURL string
- Len int
- }
-
- commits := &PushCommits{}
- if err := json.Unmarshal([]byte(action.GetContent()), commits); err != nil {
- return fm.ForgeUserActivity{}, err
- }
- commitsHTML := ""
- renderCommit := func(commit *PushCommit) string {
- return fmt.Sprintf(`%s %s `,
- fmt.Sprintf("%s/commit/%s", action.GetRepoAbsoluteLink(ctx), url.PathEscape(commit.Sha1)),
- commit.Sha1,
- html.EscapeString(commit.Message),
- )
- }
- for _, commit := range commits.Commits {
- commitsHTML += renderCommit(commit)
- }
- return makeUserActivity("pushed to %s at %s: ", renderBranch(), renderRepo(), commitsHTML)
- case activities_model.ActionCreateIssue:
- if err := action.LoadIssue(ctx); err != nil {
- return fm.ForgeUserActivity{}, err
- }
- return makeUserActivity("opened issue %s", renderIssue(action.Issue))
- case activities_model.ActionCreatePullRequest:
- if err := action.LoadIssue(ctx); err != nil {
- return fm.ForgeUserActivity{}, err
- }
- return makeUserActivity("opened pull request %s", renderIssue(action.Issue))
- case activities_model.ActionTransferRepo:
- return makeUserActivity("transferred %s", renderRepo())
- case activities_model.ActionPushTag:
- return makeUserActivity("pushed %s at %s", renderTag(), renderRepo())
- case activities_model.ActionCommentIssue:
- renderedComment, err := markdown.RenderString(&markup.RenderContext{
- Ctx: ctx,
- }, action.Comment.Content)
- if err != nil {
- return fm.ForgeUserActivity{}, err
- }
-
- return makeUserActivity(`commented on %s: %s `,
- action.GetCommentHTMLURL(ctx),
- renderIssue(action.Comment.Issue),
- renderedComment,
- )
- case activities_model.ActionMergePullRequest:
- if err := action.LoadIssue(ctx); err != nil {
- return fm.ForgeUserActivity{}, err
- }
- return makeUserActivity("merged pull request %s", renderIssue(action.Issue))
- case activities_model.ActionCloseIssue:
- if err := action.LoadIssue(ctx); err != nil {
- return fm.ForgeUserActivity{}, err
- }
- return makeUserActivity("closed issue %s", renderIssue(action.Issue))
- case activities_model.ActionReopenIssue:
- if err := action.LoadIssue(ctx); err != nil {
- return fm.ForgeUserActivity{}, err
- }
- return makeUserActivity("reopened issue %s", renderIssue(action.Issue))
- case activities_model.ActionClosePullRequest:
- if err := action.LoadIssue(ctx); err != nil {
- return fm.ForgeUserActivity{}, err
- }
- return makeUserActivity("closed pull request %s", renderIssue(action.Issue))
- case activities_model.ActionReopenPullRequest:
- if err := action.LoadIssue(ctx); err != nil {
- return fm.ForgeUserActivity{}, err
- }
- return makeUserActivity("reopened pull request %s", renderIssue(action.Issue))
- case activities_model.ActionDeleteTag:
- return makeUserActivity("deleted tag %s at %s", action.GetTag(), renderRepo())
- case activities_model.ActionDeleteBranch:
- return makeUserActivity("deleted branch %s at %s", action.GetBranch(), renderRepo())
- case activities_model.ActionApprovePullRequest:
- if err := action.LoadIssue(ctx); err != nil {
- return fm.ForgeUserActivity{}, err
- }
- return makeUserActivity("approved pull request %s", renderIssue(action.Issue))
- case activities_model.ActionRejectPullRequest:
- if err := action.LoadIssue(ctx); err != nil {
- return fm.ForgeUserActivity{}, err
- }
- return makeUserActivity("rejected pull request %s", renderIssue(action.Issue))
- case activities_model.ActionCommentPull:
- renderedComment, err := markdown.RenderString(&markup.RenderContext{
- Ctx: ctx,
- }, action.Comment.Content)
- if err != nil {
- return fm.ForgeUserActivity{}, err
- }
-
- return makeUserActivity(`commented on %s: %s `,
- action.GetCommentHTMLURL(ctx),
- renderIssue(action.Comment.Issue),
- renderedComment,
- )
- case activities_model.ActionMirrorSyncPush:
- case activities_model.ActionMirrorSyncCreate:
- case activities_model.ActionMirrorSyncDelete:
- case activities_model.ActionPublishRelease:
- case activities_model.ActionPullReviewDismissed:
- case activities_model.ActionPullRequestReadyForReview:
- case activities_model.ActionAutoMergePullRequest:
- }
-
- return makeUserActivity("performed an unrecognised action: %s", action.OpType.String())
-}
diff --git a/services/convert/attachment.go b/services/convert/attachment.go
index 74ae7c509c..d632c94c18 100644
--- a/services/convert/attachment.go
+++ b/services/convert/attachment.go
@@ -4,11 +4,8 @@
package convert
import (
- "mime"
- "path/filepath"
-
- repo_model "forgejo.org/models/repo"
- api "forgejo.org/modules/structs"
+ repo_model "code.gitea.io/gitea/models/repo"
+ api "code.gitea.io/gitea/modules/structs"
)
func WebAssetDownloadURL(repo *repo_model.Repository, attach *repo_model.Attachment) string {
@@ -23,13 +20,9 @@ func APIAssetDownloadURL(repo *repo_model.Repository, attach *repo_model.Attachm
return attach.DownloadURL()
}
-// ToWebAttachment converts models.Attachment to api.WebAttachment for API usage
-func ToWebAttachment(repo *repo_model.Repository, a *repo_model.Attachment) *api.WebAttachment {
- attachment := toAttachment(repo, a, WebAssetDownloadURL)
- return &api.WebAttachment{
- Attachment: attachment,
- MimeType: mime.TypeByExtension(filepath.Ext(attachment.Name)),
- }
+// ToAttachment converts models.Attachment to api.Attachment for API usage
+func ToAttachment(repo *repo_model.Repository, a *repo_model.Attachment) *api.Attachment {
+ return toAttachment(repo, a, WebAssetDownloadURL)
}
// ToAPIAttachment converts models.Attachment to api.Attachment for API usage
diff --git a/services/convert/attachment_test.go b/services/convert/attachment_test.go
deleted file mode 100644
index d7bf0c1ee7..0000000000
--- a/services/convert/attachment_test.go
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2025 The Forgejo Authors. All rights reserved.
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-package convert
-
-import (
- "fmt"
- "testing"
- "time"
-
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unittest"
- "forgejo.org/modules/setting"
- api "forgejo.org/modules/structs"
-
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
-)
-
-func TestToWebAttachment(t *testing.T) {
- require.NoError(t, unittest.PrepareTestDatabase())
- headRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
- attachment := &repo_model.Attachment{
- ID: 10,
- UUID: "uuidxxx",
- RepoID: 1,
- IssueID: 1,
- ReleaseID: 0,
- UploaderID: 0,
- CommentID: 0,
- Name: "test.png",
- DownloadCount: 90,
- Size: 30,
- NoAutoTime: false,
- CreatedUnix: 9342,
- CustomDownloadURL: "",
- ExternalURL: "",
- }
-
- webAttachment := ToWebAttachment(headRepo, attachment)
-
- assert.NotNil(t, webAttachment)
- assert.Equal(t, &api.WebAttachment{
- Attachment: &api.Attachment{
- ID: 10,
- Name: "test.png",
- Created: time.Unix(9342, 0),
- DownloadCount: 90,
- Size: 30,
- UUID: "uuidxxx",
- DownloadURL: fmt.Sprintf("%sattachments/uuidxxx", setting.AppURL),
- Type: "attachment",
- },
- MimeType: "image/png",
- }, webAttachment)
-}
diff --git a/services/convert/convert.go b/services/convert/convert.go
index 2ea24a1b51..7a094494e4 100644
--- a/services/convert/convert.go
+++ b/services/convert/convert.go
@@ -11,24 +11,24 @@ import (
"strings"
"time"
- actions_model "forgejo.org/models/actions"
- asymkey_model "forgejo.org/models/asymkey"
- "forgejo.org/models/auth"
- git_model "forgejo.org/models/git"
- issues_model "forgejo.org/models/issues"
- "forgejo.org/models/organization"
- "forgejo.org/models/perm"
- access_model "forgejo.org/models/perm/access"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unit"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/container"
- "forgejo.org/modules/git"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- api "forgejo.org/modules/structs"
- "forgejo.org/modules/util"
- "forgejo.org/services/gitdiff"
+ actions_model "code.gitea.io/gitea/models/actions"
+ asymkey_model "code.gitea.io/gitea/models/asymkey"
+ "code.gitea.io/gitea/models/auth"
+ git_model "code.gitea.io/gitea/models/git"
+ issues_model "code.gitea.io/gitea/models/issues"
+ "code.gitea.io/gitea/models/organization"
+ "code.gitea.io/gitea/models/perm"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unit"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/container"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ api "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/services/gitdiff"
)
// ToEmail convert models.EmailAddress to api.Email
diff --git a/services/convert/git_commit.go b/services/convert/git_commit.go
index 6a691966b8..e0efcddbcb 100644
--- a/services/convert/git_commit.go
+++ b/services/convert/git_commit.go
@@ -8,13 +8,14 @@ import (
"net/url"
"time"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/log"
- api "forgejo.org/modules/structs"
- "forgejo.org/modules/util"
- ctx "forgejo.org/services/context"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/log"
+ api "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/util"
+ ctx "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/gitdiff"
)
// ToCommitUser convert a git.Signature to an api.CommitUser
@@ -209,15 +210,17 @@ func ToCommit(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Rep
// Get diff stats for commit
if opts.Stat {
- _, totalAdditions, totalDeletions, err := gitRepo.GetCommitShortStat(commit.ID.String())
+ diff, err := gitdiff.GetDiff(ctx, gitRepo, &gitdiff.DiffOptions{
+ AfterCommitID: commit.ID.String(),
+ })
if err != nil {
return nil, err
}
res.Stats = &api.CommitStats{
- Total: totalAdditions + totalDeletions,
- Additions: totalAdditions,
- Deletions: totalDeletions,
+ Total: diff.TotalAddition + diff.TotalDeletion,
+ Additions: diff.TotalAddition,
+ Deletions: diff.TotalDeletion,
}
}
diff --git a/services/convert/git_commit_test.go b/services/convert/git_commit_test.go
index 97dff365e6..68d1b05168 100644
--- a/services/convert/git_commit_test.go
+++ b/services/convert/git_commit_test.go
@@ -7,11 +7,11 @@ import (
"testing"
"time"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unittest"
- "forgejo.org/modules/git"
- api "forgejo.org/modules/structs"
- "forgejo.org/modules/util"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unittest"
+ "code.gitea.io/gitea/modules/git"
+ api "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/util"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -34,7 +34,7 @@ func TestToCommitMeta(t *testing.T) {
commitMeta := ToCommitMeta(headRepo, tag)
assert.NotNil(t, commitMeta)
- assert.Equal(t, &api.CommitMeta{
+ assert.EqualValues(t, &api.CommitMeta{
SHA: sha1.EmptyObjectID().String(),
URL: util.URLJoin(headRepo.APIURL(), "git/commits", sha1.EmptyObjectID().String()),
Created: time.Unix(0, 0),
diff --git a/services/convert/issue.go b/services/convert/issue.go
index c7803794d0..f514dc4313 100644
--- a/services/convert/issue.go
+++ b/services/convert/issue.go
@@ -9,13 +9,13 @@ import (
"net/url"
"strings"
- issues_model "forgejo.org/models/issues"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/label"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- api "forgejo.org/modules/structs"
+ issues_model "code.gitea.io/gitea/models/issues"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/label"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ api "code.gitea.io/gitea/modules/structs"
)
func ToIssue(ctx context.Context, doer *user_model.User, issue *issues_model.Issue) *api.Issue {
diff --git a/services/convert/issue_comment.go b/services/convert/issue_comment.go
index 9ea315aee6..9ec9ac7684 100644
--- a/services/convert/issue_comment.go
+++ b/services/convert/issue_comment.go
@@ -6,12 +6,12 @@ package convert
import (
"context"
- issues_model "forgejo.org/models/issues"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/log"
- api "forgejo.org/modules/structs"
- "forgejo.org/modules/util"
+ issues_model "code.gitea.io/gitea/models/issues"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/log"
+ api "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/util"
)
// ToAPIComment converts a issues_model.Comment to the api.Comment format for API usage
diff --git a/services/convert/issue_test.go b/services/convert/issue_test.go
index ea8ad9b7ef..0aeb3e5612 100644
--- a/services/convert/issue_test.go
+++ b/services/convert/issue_test.go
@@ -8,12 +8,12 @@ import (
"testing"
"time"
- issues_model "forgejo.org/models/issues"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unittest"
- "forgejo.org/modules/setting"
- api "forgejo.org/modules/structs"
- "forgejo.org/modules/timeutil"
+ issues_model "code.gitea.io/gitea/models/issues"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unittest"
+ "code.gitea.io/gitea/modules/setting"
+ api "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/timeutil"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -24,11 +24,10 @@ func TestLabel_ToLabel(t *testing.T) {
label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1})
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: label.RepoID})
assert.Equal(t, &api.Label{
- ID: label.ID,
- Name: label.Name,
- Color: "abcdef",
- Description: label.Description,
- URL: fmt.Sprintf("%sapi/v1/repos/user2/repo1/labels/%d", setting.AppURL, label.ID),
+ ID: label.ID,
+ Name: label.Name,
+ Color: "abcdef",
+ URL: fmt.Sprintf("%sapi/v1/repos/user2/repo1/labels/%d", setting.AppURL, label.ID),
}, ToLabel(label, repo, nil))
}
diff --git a/services/convert/main_test.go b/services/convert/main_test.go
index 5915d16be4..b28b8f9446 100644
--- a/services/convert/main_test.go
+++ b/services/convert/main_test.go
@@ -6,10 +6,10 @@ package convert
import (
"testing"
- "forgejo.org/models/unittest"
+ "code.gitea.io/gitea/models/unittest"
- _ "forgejo.org/models/actions"
- _ "forgejo.org/models/forgefed"
+ _ "code.gitea.io/gitea/models/actions"
+ _ "code.gitea.io/gitea/models/forgefed"
)
func TestMain(m *testing.M) {
diff --git a/services/convert/mirror.go b/services/convert/mirror.go
index 5a815f3a5c..85e0d1c856 100644
--- a/services/convert/mirror.go
+++ b/services/convert/mirror.go
@@ -6,8 +6,8 @@ package convert
import (
"context"
- repo_model "forgejo.org/models/repo"
- api "forgejo.org/modules/structs"
+ repo_model "code.gitea.io/gitea/models/repo"
+ api "code.gitea.io/gitea/modules/structs"
)
// ToPushMirror convert from repo_model.PushMirror and remoteAddress to api.TopicResponse
@@ -23,6 +23,5 @@ func ToPushMirror(ctx context.Context, pm *repo_model.PushMirror) (*api.PushMirr
Interval: pm.Interval.String(),
SyncOnCommit: pm.SyncOnCommit,
PublicKey: pm.GetPublicKey(),
- BranchFilter: pm.BranchFilter,
}, nil
}
diff --git a/services/convert/notification.go b/services/convert/notification.go
index 2a69b62e4b..41063cf399 100644
--- a/services/convert/notification.go
+++ b/services/convert/notification.go
@@ -7,17 +7,17 @@ import (
"context"
"net/url"
- activities_model "forgejo.org/models/activities"
- "forgejo.org/models/perm"
- access_model "forgejo.org/models/perm/access"
- api "forgejo.org/modules/structs"
+ activities_model "code.gitea.io/gitea/models/activities"
+ "code.gitea.io/gitea/models/perm"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ api "code.gitea.io/gitea/modules/structs"
)
// ToNotificationThread convert a Notification to api.NotificationThread
func ToNotificationThread(ctx context.Context, n *activities_model.Notification) *api.NotificationThread {
result := &api.NotificationThread{
ID: n.ID,
- Unread: n.Status != activities_model.NotificationStatusRead && n.Status != activities_model.NotificationStatusPinned,
+ Unread: !(n.Status == activities_model.NotificationStatusRead || n.Status == activities_model.NotificationStatusPinned),
Pinned: n.Status == activities_model.NotificationStatusPinned,
UpdatedAt: n.UpdatedUnix.AsTime(),
URL: n.APIURL(),
diff --git a/services/convert/package.go b/services/convert/package.go
index a28e60e1b1..b5fca21a3c 100644
--- a/services/convert/package.go
+++ b/services/convert/package.go
@@ -6,10 +6,10 @@ package convert
import (
"context"
- "forgejo.org/models/packages"
- access_model "forgejo.org/models/perm/access"
- user_model "forgejo.org/models/user"
- api "forgejo.org/modules/structs"
+ "code.gitea.io/gitea/models/packages"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ user_model "code.gitea.io/gitea/models/user"
+ api "code.gitea.io/gitea/modules/structs"
)
// ToPackage convert a packages.PackageDescriptor to api.Package
diff --git a/services/convert/pull.go b/services/convert/pull.go
index ca965a0d18..70dc22445a 100644
--- a/services/convert/pull.go
+++ b/services/convert/pull.go
@@ -7,15 +7,15 @@ import (
"context"
"fmt"
- issues_model "forgejo.org/models/issues"
- "forgejo.org/models/perm"
- access_model "forgejo.org/models/perm/access"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/cache"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/log"
- api "forgejo.org/modules/structs"
+ issues_model "code.gitea.io/gitea/models/issues"
+ "code.gitea.io/gitea/models/perm"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/cache"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/log"
+ api "code.gitea.io/gitea/modules/structs"
)
// ToAPIPullRequest assumes following fields have been assigned with valid values:
@@ -66,36 +66,33 @@ func ToAPIPullRequest(ctx context.Context, pr *issues_model.PullRequest, doer *u
}
apiPullRequest := &api.PullRequest{
- ID: pr.ID,
- URL: pr.Issue.HTMLURL(),
- Index: pr.Index,
- Poster: apiIssue.Poster,
- Title: apiIssue.Title,
- Body: apiIssue.Body,
- Labels: apiIssue.Labels,
- Milestone: apiIssue.Milestone,
- Assignee: apiIssue.Assignee,
- Assignees: apiIssue.Assignees,
- State: apiIssue.State,
- Draft: pr.IsWorkInProgress(ctx),
- IsLocked: apiIssue.IsLocked,
- Comments: apiIssue.Comments,
- ReviewComments: pr.GetReviewCommentsCount(ctx),
- HTMLURL: pr.Issue.HTMLURL(),
- DiffURL: pr.Issue.DiffURL(),
- PatchURL: pr.Issue.PatchURL(),
- HasMerged: pr.HasMerged,
- MergeBase: pr.MergeBase,
- Mergeable: pr.Mergeable(ctx),
- Deadline: apiIssue.Deadline,
- Created: pr.Issue.CreatedUnix.AsTimePtr(),
- Updated: pr.Issue.UpdatedUnix.AsTimePtr(),
- PinOrder: apiIssue.PinOrder,
- RequestedReviewers: []*api.User{},
- RequestedReviewersTeams: []*api.Team{},
+ ID: pr.ID,
+ URL: pr.Issue.HTMLURL(),
+ Index: pr.Index,
+ Poster: apiIssue.Poster,
+ Title: apiIssue.Title,
+ Body: apiIssue.Body,
+ Labels: apiIssue.Labels,
+ Milestone: apiIssue.Milestone,
+ Assignee: apiIssue.Assignee,
+ Assignees: apiIssue.Assignees,
+ State: apiIssue.State,
+ Draft: pr.IsWorkInProgress(ctx),
+ IsLocked: apiIssue.IsLocked,
+ Comments: apiIssue.Comments,
+ ReviewComments: pr.GetReviewCommentsCount(ctx),
+ HTMLURL: pr.Issue.HTMLURL(),
+ DiffURL: pr.Issue.DiffURL(),
+ PatchURL: pr.Issue.PatchURL(),
+ HasMerged: pr.HasMerged,
+ MergeBase: pr.MergeBase,
+ Mergeable: pr.Mergeable(ctx),
+ Deadline: apiIssue.Deadline,
+ Created: pr.Issue.CreatedUnix.AsTimePtr(),
+ Updated: pr.Issue.UpdatedUnix.AsTimePtr(),
+ PinOrder: apiIssue.PinOrder,
AllowMaintainerEdit: pr.AllowMaintainerEdit,
- Flow: int64(pr.Flow),
Base: &api.PRBranchInfo{
Name: pr.BaseBranch,
diff --git a/services/convert/pull_review.go b/services/convert/pull_review.go
index 97be118a83..f7990e7a5c 100644
--- a/services/convert/pull_review.go
+++ b/services/convert/pull_review.go
@@ -7,9 +7,9 @@ import (
"context"
"strings"
- issues_model "forgejo.org/models/issues"
- user_model "forgejo.org/models/user"
- api "forgejo.org/modules/structs"
+ issues_model "code.gitea.io/gitea/models/issues"
+ user_model "code.gitea.io/gitea/models/user"
+ api "code.gitea.io/gitea/modules/structs"
)
// ToPullReview convert a review to api format
@@ -66,7 +66,7 @@ func ToPullReviewList(ctx context.Context, rl []*issues_model.Review, doer *user
result := make([]*api.PullReview, 0, len(rl))
for i := range rl {
// show pending reviews only for the user who created them
- if rl[i].Type == issues_model.ReviewTypePending && (doer == nil || (!doer.IsAdmin && doer.ID != rl[i].ReviewerID)) {
+ if rl[i].Type == issues_model.ReviewTypePending && (doer == nil || !(doer.IsAdmin || doer.ID == rl[i].ReviewerID)) {
continue
}
r, err := ToPullReview(ctx, rl[i], doer)
diff --git a/services/convert/pull_test.go b/services/convert/pull_test.go
index c0c69fd9ad..1339ed5cc0 100644
--- a/services/convert/pull_test.go
+++ b/services/convert/pull_test.go
@@ -6,15 +6,15 @@ package convert
import (
"testing"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- "forgejo.org/models/perm"
- access_model "forgejo.org/models/perm/access"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unittest"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/structs"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ "code.gitea.io/gitea/models/perm"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unittest"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/structs"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -29,7 +29,7 @@ func TestPullRequest_APIFormat(t *testing.T) {
require.NoError(t, pr.LoadIssue(db.DefaultContext))
apiPullRequest := ToAPIPullRequest(git.DefaultContext, pr, nil)
assert.NotNil(t, apiPullRequest)
- assert.Equal(t, &structs.PRBranchInfo{
+ assert.EqualValues(t, &structs.PRBranchInfo{
Name: "branch1",
Ref: "refs/pull/2/head",
Sha: "4a357436d925b5c974181ff12a994538ddc5a269",
diff --git a/services/convert/quota.go b/services/convert/quota.go
index ba729feaac..791cd8e038 100644
--- a/services/convert/quota.go
+++ b/services/convert/quota.go
@@ -7,12 +7,12 @@ import (
"context"
"strconv"
- action_model "forgejo.org/models/actions"
- issue_model "forgejo.org/models/issues"
- package_model "forgejo.org/models/packages"
- quota_model "forgejo.org/models/quota"
- repo_model "forgejo.org/models/repo"
- api "forgejo.org/modules/structs"
+ action_model "code.gitea.io/gitea/models/actions"
+ issue_model "code.gitea.io/gitea/models/issues"
+ package_model "code.gitea.io/gitea/models/packages"
+ quota_model "code.gitea.io/gitea/models/quota"
+ repo_model "code.gitea.io/gitea/models/repo"
+ api "code.gitea.io/gitea/modules/structs"
)
func ToQuotaRuleInfo(rule quota_model.Rule, withName bool) api.QuotaRuleInfo {
diff --git a/services/convert/release.go b/services/convert/release.go
index 7773cf3b19..8c0f61b56c 100644
--- a/services/convert/release.go
+++ b/services/convert/release.go
@@ -6,8 +6,8 @@ package convert
import (
"context"
- repo_model "forgejo.org/models/repo"
- api "forgejo.org/modules/structs"
+ repo_model "code.gitea.io/gitea/models/repo"
+ api "code.gitea.io/gitea/modules/structs"
)
// ToAPIRelease convert a repo_model.Release to api.Release
diff --git a/services/convert/release_test.go b/services/convert/release_test.go
index 1d214f0222..2e40bb9cdd 100644
--- a/services/convert/release_test.go
+++ b/services/convert/release_test.go
@@ -6,9 +6,9 @@ package convert
import (
"testing"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unittest"
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unittest"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -24,6 +24,6 @@ func TestRelease_ToRelease(t *testing.T) {
apiRelease := ToAPIRelease(db.DefaultContext, repo1, release1)
assert.NotNil(t, apiRelease)
assert.EqualValues(t, 1, apiRelease.ID)
- assert.Equal(t, "https://try.gitea.io/api/v1/repos/user2/repo1/releases/1", apiRelease.URL)
- assert.Equal(t, "https://try.gitea.io/api/v1/repos/user2/repo1/releases/1/assets", apiRelease.UploadURL)
+ assert.EqualValues(t, "https://try.gitea.io/api/v1/repos/user2/repo1/releases/1", apiRelease.URL)
+ assert.EqualValues(t, "https://try.gitea.io/api/v1/repos/user2/repo1/releases/1/assets", apiRelease.UploadURL)
}
diff --git a/services/convert/repository.go b/services/convert/repository.go
index 1b0f46b3da..e4b2c7b8bc 100644
--- a/services/convert/repository.go
+++ b/services/convert/repository.go
@@ -7,14 +7,14 @@ import (
"context"
"time"
- "forgejo.org/models"
- "forgejo.org/models/db"
- "forgejo.org/models/perm"
- access_model "forgejo.org/models/perm/access"
- repo_model "forgejo.org/models/repo"
- unit_model "forgejo.org/models/unit"
- "forgejo.org/modules/log"
- api "forgejo.org/modules/structs"
+ "code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/perm"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ repo_model "code.gitea.io/gitea/models/repo"
+ unit_model "code.gitea.io/gitea/models/unit"
+ "code.gitea.io/gitea/modules/log"
+ api "code.gitea.io/gitea/modules/structs"
)
// ToRepo converts a Repository to api.Repository
diff --git a/services/convert/status.go b/services/convert/status.go
index 1a71e70a52..6cef63c1cd 100644
--- a/services/convert/status.go
+++ b/services/convert/status.go
@@ -6,9 +6,9 @@ package convert
import (
"context"
- git_model "forgejo.org/models/git"
- user_model "forgejo.org/models/user"
- api "forgejo.org/modules/structs"
+ git_model "code.gitea.io/gitea/models/git"
+ user_model "code.gitea.io/gitea/models/user"
+ api "code.gitea.io/gitea/modules/structs"
)
// ToCommitStatus converts git_model.CommitStatus to api.CommitStatus
diff --git a/services/convert/user.go b/services/convert/user.go
index 444089fd83..7b6775dfb4 100644
--- a/services/convert/user.go
+++ b/services/convert/user.go
@@ -6,9 +6,9 @@ package convert
import (
"context"
- "forgejo.org/models/perm"
- user_model "forgejo.org/models/user"
- api "forgejo.org/modules/structs"
+ "code.gitea.io/gitea/models/perm"
+ user_model "code.gitea.io/gitea/models/user"
+ api "code.gitea.io/gitea/modules/structs"
)
// ToUser convert user_model.User to api.User
diff --git a/services/convert/user_test.go b/services/convert/user_test.go
index 8a42a9d97d..0f0b520c9b 100644
--- a/services/convert/user_test.go
+++ b/services/convert/user_test.go
@@ -6,10 +6,10 @@ package convert
import (
"testing"
- "forgejo.org/models/db"
- "forgejo.org/models/unittest"
- user_model "forgejo.org/models/user"
- api "forgejo.org/modules/structs"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/unittest"
+ user_model "code.gitea.io/gitea/models/user"
+ api "code.gitea.io/gitea/modules/structs"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -31,11 +31,11 @@ func TestUser_ToUser(t *testing.T) {
apiUser = toUser(db.DefaultContext, user1, false, false)
assert.False(t, apiUser.IsAdmin)
- assert.Equal(t, api.VisibleTypePublic.String(), apiUser.Visibility)
+ assert.EqualValues(t, api.VisibleTypePublic.String(), apiUser.Visibility)
user31 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 31, IsAdmin: false, Visibility: api.VisibleTypePrivate})
apiUser = toUser(db.DefaultContext, user31, true, true)
assert.False(t, apiUser.IsAdmin)
- assert.Equal(t, api.VisibleTypePrivate.String(), apiUser.Visibility)
+ assert.EqualValues(t, api.VisibleTypePrivate.String(), apiUser.Visibility)
}
diff --git a/services/convert/utils.go b/services/convert/utils.go
index 70c5f5cc18..fe35fd2dac 100644
--- a/services/convert/utils.go
+++ b/services/convert/utils.go
@@ -7,8 +7,8 @@ package convert
import (
"strings"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/structs"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/structs"
)
// ToCorrectPageSize makes sure page size is in allowed range.
@@ -38,8 +38,6 @@ func ToGitServiceType(value string) structs.GitServiceType {
return structs.GitBucketService
case "forgejo":
return structs.ForgejoService
- case "pagure":
- return structs.PagureService
default:
return structs.PlainGitService
}
diff --git a/services/convert/utils_test.go b/services/convert/utils_test.go
index 6c3bf7d938..b464d8bb68 100644
--- a/services/convert/utils_test.go
+++ b/services/convert/utils_test.go
@@ -10,10 +10,10 @@ import (
)
func TestToCorrectPageSize(t *testing.T) {
- assert.Equal(t, 30, ToCorrectPageSize(0))
- assert.Equal(t, 30, ToCorrectPageSize(-10))
- assert.Equal(t, 20, ToCorrectPageSize(20))
- assert.Equal(t, 50, ToCorrectPageSize(100))
+ assert.EqualValues(t, 30, ToCorrectPageSize(0))
+ assert.EqualValues(t, 30, ToCorrectPageSize(-10))
+ assert.EqualValues(t, 20, ToCorrectPageSize(20))
+ assert.EqualValues(t, 50, ToCorrectPageSize(100))
}
func TestToGitServiceType(t *testing.T) {
diff --git a/services/convert/wiki.go b/services/convert/wiki.go
index adcbd52949..767bfdb88d 100644
--- a/services/convert/wiki.go
+++ b/services/convert/wiki.go
@@ -6,8 +6,8 @@ package convert
import (
"time"
- "forgejo.org/modules/git"
- api "forgejo.org/modules/structs"
+ "code.gitea.io/gitea/modules/git"
+ api "code.gitea.io/gitea/modules/structs"
)
// ToWikiCommit convert a git commit into a WikiCommit
diff --git a/services/cron/cron.go b/services/cron/cron.go
index d020f3fd6c..3c5737e371 100644
--- a/services/cron/cron.go
+++ b/services/cron/cron.go
@@ -9,10 +9,10 @@ import (
"runtime/pprof"
"time"
- "forgejo.org/modules/graceful"
- "forgejo.org/modules/process"
- "forgejo.org/modules/sync"
- "forgejo.org/modules/translation"
+ "code.gitea.io/gitea/modules/graceful"
+ "code.gitea.io/gitea/modules/process"
+ "code.gitea.io/gitea/modules/sync"
+ "code.gitea.io/gitea/modules/translation"
"github.com/go-co-op/gocron"
)
diff --git a/services/cron/setting.go b/services/cron/setting.go
index 2db6c15370..6dad88830a 100644
--- a/services/cron/setting.go
+++ b/services/cron/setting.go
@@ -6,7 +6,7 @@ package cron
import (
"time"
- "forgejo.org/modules/translation"
+ "code.gitea.io/gitea/modules/translation"
)
// Config represents a basic configuration interface that cron task
@@ -46,13 +46,6 @@ type CleanupHookTaskConfig struct {
NumberToKeep int
}
-// CleanupOfflineRunnersConfig represents a cron task with settings to clean up offline-runner
-type CleanupOfflineRunnersConfig struct {
- BaseConfig
- OlderThan time.Duration
- GlobalScopeOnly bool
-}
-
// GetSchedule returns the schedule for the base config
func (b *BaseConfig) GetSchedule() string {
return b.Schedule
diff --git a/services/cron/tasks.go b/services/cron/tasks.go
index b547acdf05..f8a7444c49 100644
--- a/services/cron/tasks.go
+++ b/services/cron/tasks.go
@@ -11,14 +11,14 @@ import (
"sync"
"time"
- "forgejo.org/models/db"
- system_model "forgejo.org/models/system"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/graceful"
- "forgejo.org/modules/log"
- "forgejo.org/modules/process"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/translation"
+ "code.gitea.io/gitea/models/db"
+ system_model "code.gitea.io/gitea/models/system"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/graceful"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/process"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/translation"
)
var (
diff --git a/services/cron/tasks_actions.go b/services/cron/tasks_actions.go
index 2cd484fa69..59cfe36d14 100644
--- a/services/cron/tasks_actions.go
+++ b/services/cron/tasks_actions.go
@@ -5,11 +5,10 @@ package cron
import (
"context"
- "time"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/setting"
- actions_service "forgejo.org/services/actions"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/setting"
+ actions_service "code.gitea.io/gitea/services/actions"
)
func initActionsTasks() {
@@ -21,7 +20,6 @@ func initActionsTasks() {
registerCancelAbandonedJobs()
registerScheduleTasks()
registerActionsCleanup()
- registerOfflineRunnersCleanup()
}
func registerStopZombieTasks() {
@@ -76,22 +74,3 @@ func registerActionsCleanup() {
return actions_service.Cleanup(ctx)
})
}
-
-func registerOfflineRunnersCleanup() {
- RegisterTaskFatal("cleanup_offline_runners", &CleanupOfflineRunnersConfig{
- BaseConfig: BaseConfig{
- Enabled: false,
- RunAtStart: false,
- Schedule: "@midnight",
- },
- GlobalScopeOnly: true,
- OlderThan: time.Hour * 24,
- }, func(ctx context.Context, _ *user_model.User, cfg Config) error {
- c := cfg.(*CleanupOfflineRunnersConfig)
- return actions_service.CleanupOfflineRunners(
- ctx,
- c.OlderThan,
- c.GlobalScopeOnly,
- )
- })
-}
diff --git a/services/cron/tasks_basic.go b/services/cron/tasks_basic.go
index 5ada7a8f5c..23eb0dd291 100644
--- a/services/cron/tasks_basic.go
+++ b/services/cron/tasks_basic.go
@@ -7,18 +7,18 @@ import (
"context"
"time"
- "forgejo.org/models"
- git_model "forgejo.org/models/git"
- user_model "forgejo.org/models/user"
- "forgejo.org/models/webhook"
- "forgejo.org/modules/git"
- "forgejo.org/modules/setting"
- "forgejo.org/services/auth"
- "forgejo.org/services/migrations"
- mirror_service "forgejo.org/services/mirror"
- packages_cleanup_service "forgejo.org/services/packages/cleanup"
- repo_service "forgejo.org/services/repository"
- archiver_service "forgejo.org/services/repository/archiver"
+ "code.gitea.io/gitea/models"
+ git_model "code.gitea.io/gitea/models/git"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/services/auth"
+ "code.gitea.io/gitea/services/migrations"
+ mirror_service "code.gitea.io/gitea/services/mirror"
+ packages_cleanup_service "code.gitea.io/gitea/services/packages/cleanup"
+ repo_service "code.gitea.io/gitea/services/repository"
+ archiver_service "code.gitea.io/gitea/services/repository/archiver"
)
func registerUpdateMirrorTask() {
diff --git a/services/cron/tasks_extended.go b/services/cron/tasks_extended.go
index 5cc5d4eb14..e1ba5274e6 100644
--- a/services/cron/tasks_extended.go
+++ b/services/cron/tasks_extended.go
@@ -7,18 +7,17 @@ import (
"context"
"time"
- activities_model "forgejo.org/models/activities"
- asymkey_model "forgejo.org/models/asymkey"
- "forgejo.org/models/system"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- issue_indexer "forgejo.org/modules/indexer/issues"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/updatechecker"
- moderation_service "forgejo.org/services/moderation"
- repo_service "forgejo.org/services/repository"
- archiver_service "forgejo.org/services/repository/archiver"
- user_service "forgejo.org/services/user"
+ activities_model "code.gitea.io/gitea/models/activities"
+ asymkey_model "code.gitea.io/gitea/models/asymkey"
+ "code.gitea.io/gitea/models/system"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ issue_indexer "code.gitea.io/gitea/modules/indexer/issues"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/updatechecker"
+ repo_service "code.gitea.io/gitea/services/repository"
+ archiver_service "code.gitea.io/gitea/services/repository/archiver"
+ user_service "code.gitea.io/gitea/services/user"
)
func registerDeleteInactiveUsers() {
@@ -174,35 +173,34 @@ func registerDeleteOldSystemNotices() {
})
}
-type GCLFSConfig struct {
- BaseConfig
- OlderThan time.Duration
- LastUpdatedMoreThanAgo time.Duration
- NumberToCheckPerRepo int64
- ProportionToCheckPerRepo float64
-}
-
func registerGCLFS() {
if !setting.LFS.StartServer {
return
}
+ type GCLFSConfig struct {
+ OlderThanConfig
+ LastUpdatedMoreThanAgo time.Duration
+ NumberToCheckPerRepo int64
+ ProportionToCheckPerRepo float64
+ }
RegisterTaskFatal("gc_lfs", &GCLFSConfig{
- BaseConfig: BaseConfig{
- Enabled: false,
- RunAtStart: false,
- Schedule: "@every 24h",
+ OlderThanConfig: OlderThanConfig{
+ BaseConfig: BaseConfig{
+ Enabled: false,
+ RunAtStart: false,
+ Schedule: "@every 24h",
+ },
+ // Only attempt to garbage collect lfs meta objects older than a week as the order of git lfs upload
+ // and git object upload is not necessarily guaranteed. It's possible to imagine a situation whereby
+ // an LFS object is uploaded but the git branch is not uploaded immediately, or there are some rapid
+ // changes in new branches that might lead to lfs objects becoming temporarily unassociated with git
+ // objects.
+ //
+ // It is likely that a week is potentially excessive but it should definitely be enough that any
+ // unassociated LFS object is genuinely unassociated.
+ OlderThan: 24 * time.Hour * 7,
},
- // Only attempt to garbage collect lfs meta objects older than a week as the order of git lfs upload
- // and git object upload is not necessarily guaranteed. It's possible to imagine a situation whereby
- // an LFS object is uploaded but the git branch is not uploaded immediately, or there are some rapid
- // changes in new branches that might lead to lfs objects becoming temporarily unassociated with git
- // objects.
- //
- // It is likely that a week is potentially excessive but it should definitely be enough that any
- // unassociated LFS object is genuinely unassociated.
- OlderThan: 24 * time.Hour * 7,
-
// Only GC things that haven't been looked at in the past 3 days
LastUpdatedMoreThanAgo: 24 * time.Hour * 3,
NumberToCheckPerRepo: 100,
@@ -227,24 +225,6 @@ func registerRebuildIssueIndexer() {
})
}
-func registerRemoveResolvedReports() {
- type ReportConfig struct {
- BaseConfig
- ConfigKeepResolvedReportsFor time.Duration
- }
- RegisterTaskFatal("remove_resolved_reports", &ReportConfig{
- BaseConfig: BaseConfig{
- Enabled: false,
- RunAtStart: false,
- Schedule: "@every 24h",
- },
- ConfigKeepResolvedReportsFor: setting.Moderation.KeepResolvedReportsFor,
- }, func(ctx context.Context, _ *user_model.User, config Config) error {
- reportConfig := config.(*ReportConfig)
- return moderation_service.RemoveResolvedReports(ctx, reportConfig.ConfigKeepResolvedReportsFor)
- })
-}
-
func initExtendedTasks() {
registerDeleteInactiveUsers()
registerDeleteRepositoryArchives()
@@ -260,7 +240,4 @@ func initExtendedTasks() {
registerDeleteOldSystemNotices()
registerGCLFS()
registerRebuildIssueIndexer()
- if setting.Moderation.Enabled {
- registerRemoveResolvedReports()
- }
}
diff --git a/services/cron/tasks_extended_test.go b/services/cron/tasks_extended_test.go
deleted file mode 100644
index 0b05ff9918..0000000000
--- a/services/cron/tasks_extended_test.go
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2025 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package cron
-
-import (
- "testing"
- "time"
-
- "forgejo.org/modules/setting"
- "forgejo.org/modules/test"
-
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
-)
-
-func Test_GCLFSConfig(t *testing.T) {
- cfg, err := setting.NewConfigProviderFromData(`
-[cron.gc_lfs]
-ENABLED = true
-RUN_AT_START = true
-SCHEDULE = "@every 2h"
-OLDER_THAN = "1h"
-LAST_UPDATED_MORE_THAN_AGO = "7h"
-NUMBER_TO_CHECK_PER_REPO = 10
-PROPORTION_TO_CHECK_PER_REPO = 0.1
-`)
- require.NoError(t, err)
- defer test.MockVariableValue(&setting.CfgProvider, cfg)()
-
- config := &GCLFSConfig{
- BaseConfig: BaseConfig{
- Enabled: false,
- RunAtStart: false,
- Schedule: "@every 24h",
- },
- OlderThan: 24 * time.Hour * 7,
- LastUpdatedMoreThanAgo: 24 * time.Hour * 3,
- NumberToCheckPerRepo: 100,
- ProportionToCheckPerRepo: 0.6,
- }
-
- _, err = setting.GetCronSettings("gc_lfs", config)
- require.NoError(t, err)
- assert.True(t, config.Enabled)
- assert.True(t, config.RunAtStart)
- assert.Equal(t, "@every 2h", config.Schedule)
- assert.Equal(t, 1*time.Hour, config.OlderThan)
- assert.Equal(t, 7*time.Hour, config.LastUpdatedMoreThanAgo)
- assert.Equal(t, int64(10), config.NumberToCheckPerRepo)
- assert.InDelta(t, 0.1, config.ProportionToCheckPerRepo, 0.001)
-}
diff --git a/services/doctor/actions.go b/services/doctor/actions.go
index c382132265..7c44fb8392 100644
--- a/services/doctor/actions.go
+++ b/services/doctor/actions.go
@@ -7,12 +7,12 @@ import (
"context"
"fmt"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
- unit_model "forgejo.org/models/unit"
- "forgejo.org/modules/log"
- "forgejo.org/modules/optional"
- repo_service "forgejo.org/services/repository"
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
+ unit_model "code.gitea.io/gitea/models/unit"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/optional"
+ repo_service "code.gitea.io/gitea/services/repository"
)
func disableMirrorActionsUnit(ctx context.Context, logger log.Logger, autofix bool) error {
diff --git a/services/doctor/authorizedkeys.go b/services/doctor/authorizedkeys.go
index 465a3fc7c0..2920cf51d7 100644
--- a/services/doctor/authorizedkeys.go
+++ b/services/doctor/authorizedkeys.go
@@ -7,16 +7,15 @@ import (
"bufio"
"bytes"
"context"
- "errors"
"fmt"
"os"
"path/filepath"
"strings"
- asymkey_model "forgejo.org/models/asymkey"
- "forgejo.org/modules/container"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
+ asymkey_model "code.gitea.io/gitea/models/asymkey"
+ "code.gitea.io/gitea/modules/container"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
)
const tplCommentPrefix = `# gitea public key`
@@ -78,7 +77,7 @@ func checkAuthorizedKeys(ctx context.Context, logger log.Logger, autofix bool) e
fPath,
"forgejo admin regenerate keys",
"forgejo doctor check --run authorized-keys --fix")
- return errors.New(`authorized_keys is out of date and should be regenerated with "forgejo admin regenerate keys" or "forgejo doctor check --run authorized-keys --fix"`)
+ return fmt.Errorf(`authorized_keys is out of date and should be regenerated with "forgejo admin regenerate keys" or "forgejo doctor check --run authorized-keys --fix"`)
}
logger.Warn("authorized_keys is out of date. Attempting rewrite...")
err = asymkey_model.RewriteAllPublicKeys(ctx)
diff --git a/services/doctor/breaking.go b/services/doctor/breaking.go
index 339f8e847c..ec8433b8de 100644
--- a/services/doctor/breaking.go
+++ b/services/doctor/breaking.go
@@ -7,11 +7,11 @@ import (
"context"
"fmt"
- "forgejo.org/models/db"
- "forgejo.org/models/user"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/validation"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/validation"
"xorm.io/builder"
)
diff --git a/services/doctor/checkOldArchives.go b/services/doctor/checkOldArchives.go
index 301e99391b..390dfb43aa 100644
--- a/services/doctor/checkOldArchives.go
+++ b/services/doctor/checkOldArchives.go
@@ -8,9 +8,9 @@ import (
"os"
"path/filepath"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/modules/log"
- "forgejo.org/modules/util"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/util"
)
func checkOldArchives(ctx context.Context, logger log.Logger, autofix bool) error {
diff --git a/services/doctor/dbconsistency.go b/services/doctor/dbconsistency.go
index 6fe4c9c5e6..9e2fcb645f 100644
--- a/services/doctor/dbconsistency.go
+++ b/services/doctor/dbconsistency.go
@@ -6,16 +6,16 @@ package doctor
import (
"context"
- actions_model "forgejo.org/models/actions"
- activities_model "forgejo.org/models/activities"
- auth_model "forgejo.org/models/auth"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- "forgejo.org/models/migrations"
- org_model "forgejo.org/models/organization"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
+ actions_model "code.gitea.io/gitea/models/actions"
+ activities_model "code.gitea.io/gitea/models/activities"
+ auth_model "code.gitea.io/gitea/models/auth"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ "code.gitea.io/gitea/models/migrations"
+ org_model "code.gitea.io/gitea/models/organization"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
)
type consistencyCheck struct {
@@ -78,14 +78,7 @@ func genericOrphanCheck(name, subject, refobject, joincond string) consistencyCh
func checkDBConsistency(ctx context.Context, logger log.Logger, autofix bool) error {
// make sure DB version is up-to-date
- ensureUpToDateWrapper := func(e db.Engine) error {
- engine, err := db.GetMasterEngine(e)
- if err != nil {
- return err
- }
- return migrations.EnsureUpToDate(engine)
- }
- if err := db.InitEngineWithMigration(ctx, ensureUpToDateWrapper); err != nil {
+ if err := db.InitEngineWithMigration(ctx, migrations.EnsureUpToDate); err != nil {
logger.Critical("Model version on the database does not match the current Gitea version. Model consistency will not be checked until the database is upgraded")
return err
}
diff --git a/services/doctor/dbversion.go b/services/doctor/dbversion.go
index c0ff22915d..2a102b2194 100644
--- a/services/doctor/dbversion.go
+++ b/services/doctor/dbversion.go
@@ -6,18 +6,14 @@ package doctor
import (
"context"
- "forgejo.org/models/db"
- "forgejo.org/models/migrations"
- "forgejo.org/modules/log"
-
- "xorm.io/xorm"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/migrations"
+ "code.gitea.io/gitea/modules/log"
)
func checkDBVersion(ctx context.Context, logger log.Logger, autofix bool) error {
logger.Info("Expected database version: %d", migrations.ExpectedDBVersion())
- if err := db.InitEngineWithMigration(ctx, func(eng db.Engine) error {
- return migrations.EnsureUpToDate(eng.(*xorm.Engine))
- }); err != nil {
+ if err := db.InitEngineWithMigration(ctx, migrations.EnsureUpToDate); err != nil {
if !autofix {
logger.Critical("Error: %v during ensure up to date", err)
return err
@@ -25,9 +21,7 @@ func checkDBVersion(ctx context.Context, logger log.Logger, autofix bool) error
logger.Warn("Got Error: %v during ensure up to date", err)
logger.Warn("Attempting to migrate to the latest DB version to fix this.")
- err = db.InitEngineWithMigration(ctx, func(eng db.Engine) error {
- return migrations.Migrate(eng.(*xorm.Engine))
- })
+ err = db.InitEngineWithMigration(ctx, migrations.Migrate)
if err != nil {
logger.Critical("Error: %v during migration", err)
}
diff --git a/services/doctor/doctor.go b/services/doctor/doctor.go
index 6d8e168bf2..a4eb5e16b9 100644
--- a/services/doctor/doctor.go
+++ b/services/doctor/doctor.go
@@ -10,11 +10,11 @@ import (
"sort"
"strings"
- "forgejo.org/models/db"
- "forgejo.org/modules/git"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/storage"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/storage"
)
// Check represents a Doctor check
diff --git a/services/doctor/fix16961.go b/services/doctor/fix16961.go
index 2212d9e903..50d9ac6621 100644
--- a/services/doctor/fix16961.go
+++ b/services/doctor/fix16961.go
@@ -9,12 +9,12 @@ import (
"errors"
"fmt"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unit"
- "forgejo.org/modules/json"
- "forgejo.org/modules/log"
- "forgejo.org/modules/timeutil"
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unit"
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/timeutil"
"xorm.io/builder"
)
diff --git a/services/doctor/fix16961_test.go b/services/doctor/fix16961_test.go
index 75f9f206ab..498ed9c8d5 100644
--- a/services/doctor/fix16961_test.go
+++ b/services/doctor/fix16961_test.go
@@ -6,7 +6,7 @@ package doctor
import (
"testing"
- repo_model "forgejo.org/models/repo"
+ repo_model "code.gitea.io/gitea/models/repo"
"github.com/stretchr/testify/assert"
)
@@ -221,7 +221,7 @@ func Test_fixPullRequestsConfig_16961(t *testing.T) {
if gotFixed != tt.wantFixed {
t.Errorf("fixPullRequestsConfig_16961() = %v, want %v", gotFixed, tt.wantFixed)
}
- assert.Equal(t, &tt.expected, cfg)
+ assert.EqualValues(t, &tt.expected, cfg)
})
}
}
@@ -265,7 +265,7 @@ func Test_fixIssuesConfig_16961(t *testing.T) {
if gotFixed != tt.wantFixed {
t.Errorf("fixIssuesConfig_16961() = %v, want %v", gotFixed, tt.wantFixed)
}
- assert.Equal(t, &tt.expected, cfg)
+ assert.EqualValues(t, &tt.expected, cfg)
})
}
}
diff --git a/services/doctor/fix8312.go b/services/doctor/fix8312.go
index 31cd6686d7..4fc049873a 100644
--- a/services/doctor/fix8312.go
+++ b/services/doctor/fix8312.go
@@ -6,11 +6,11 @@ package doctor
import (
"context"
- "forgejo.org/models"
- "forgejo.org/models/db"
- org_model "forgejo.org/models/organization"
- "forgejo.org/models/perm"
- "forgejo.org/modules/log"
+ "code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/models/db"
+ org_model "code.gitea.io/gitea/models/organization"
+ "code.gitea.io/gitea/models/perm"
+ "code.gitea.io/gitea/modules/log"
"xorm.io/builder"
)
diff --git a/services/doctor/heads.go b/services/doctor/heads.go
index 7f9d1c73e8..41fca01d57 100644
--- a/services/doctor/heads.go
+++ b/services/doctor/heads.go
@@ -6,9 +6,9 @@ package doctor
import (
"context"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/modules/git"
- "forgejo.org/modules/log"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/log"
)
func synchronizeRepoHeads(ctx context.Context, logger log.Logger, autofix bool) error {
diff --git a/services/doctor/lfs.go b/services/doctor/lfs.go
index fe858605f4..8531b7bbe8 100644
--- a/services/doctor/lfs.go
+++ b/services/doctor/lfs.go
@@ -5,12 +5,12 @@ package doctor
import (
"context"
- "errors"
+ "fmt"
"time"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- "forgejo.org/services/repository"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/services/repository"
)
func init() {
@@ -27,7 +27,7 @@ func init() {
func garbageCollectLFSCheck(ctx context.Context, logger log.Logger, autofix bool) error {
if !setting.LFS.StartServer {
- return errors.New("LFS support is disabled")
+ return fmt.Errorf("LFS support is disabled")
}
if err := repository.GarbageCollectLFSMetaObjects(ctx, repository.GarbageCollectLFSMetaObjectsOptions{
diff --git a/services/doctor/mergebase.go b/services/doctor/mergebase.go
index bebde30bee..de460c4190 100644
--- a/services/doctor/mergebase.go
+++ b/services/doctor/mergebase.go
@@ -8,11 +8,11 @@ import (
"fmt"
"strings"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/modules/git"
- "forgejo.org/modules/log"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/log"
"xorm.io/builder"
)
diff --git a/services/doctor/misc.go b/services/doctor/misc.go
index 9b9c96b52b..9300c3a25c 100644
--- a/services/doctor/misc.go
+++ b/services/doctor/misc.go
@@ -11,17 +11,17 @@ import (
"path"
"strings"
- "forgejo.org/models"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/log"
- "forgejo.org/modules/repository"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/structs"
- "forgejo.org/modules/util"
+ "code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/repository"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/util"
lru "github.com/hashicorp/golang-lru/v2"
"xorm.io/builder"
diff --git a/services/doctor/packages_nuget.go b/services/doctor/packages_nuget.go
index f6a33db779..47fdb3ac12 100644
--- a/services/doctor/packages_nuget.go
+++ b/services/doctor/packages_nuget.go
@@ -9,12 +9,12 @@ import (
"slices"
"strings"
- "forgejo.org/models/db"
- "forgejo.org/models/packages"
- "forgejo.org/modules/log"
- packages_module "forgejo.org/modules/packages"
- nuget_module "forgejo.org/modules/packages/nuget"
- packages_service "forgejo.org/services/packages"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/packages"
+ "code.gitea.io/gitea/modules/log"
+ packages_module "code.gitea.io/gitea/modules/packages"
+ nuget_module "code.gitea.io/gitea/modules/packages/nuget"
+ packages_service "code.gitea.io/gitea/services/packages"
"xorm.io/builder"
)
diff --git a/services/doctor/paths.go b/services/doctor/paths.go
index 4fbe19ea04..8e37f01ef5 100644
--- a/services/doctor/paths.go
+++ b/services/doctor/paths.go
@@ -8,8 +8,8 @@ import (
"fmt"
"os"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
)
type configurationFile struct {
diff --git a/services/doctor/push_mirror_consistency.go b/services/doctor/push_mirror_consistency.go
index 07986770b2..68b96d6415 100644
--- a/services/doctor/push_mirror_consistency.go
+++ b/services/doctor/push_mirror_consistency.go
@@ -7,9 +7,9 @@ import (
"context"
"strings"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/modules/log"
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/modules/log"
"xorm.io/builder"
)
diff --git a/services/doctor/repository.go b/services/doctor/repository.go
index cd51483d88..6c33426636 100644
--- a/services/doctor/repository.go
+++ b/services/doctor/repository.go
@@ -6,11 +6,11 @@ package doctor
import (
"context"
- "forgejo.org/models/db"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/log"
- "forgejo.org/modules/storage"
- repo_service "forgejo.org/services/repository"
+ "code.gitea.io/gitea/models/db"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/storage"
+ repo_service "code.gitea.io/gitea/services/repository"
"xorm.io/builder"
)
diff --git a/services/doctor/storage.go b/services/doctor/storage.go
index 7dbe475d6c..3f3b562c37 100644
--- a/services/doctor/storage.go
+++ b/services/doctor/storage.go
@@ -9,16 +9,16 @@ import (
"io/fs"
"strings"
- "forgejo.org/models/git"
- "forgejo.org/models/packages"
- "forgejo.org/models/repo"
- "forgejo.org/models/user"
- "forgejo.org/modules/base"
- "forgejo.org/modules/log"
- packages_module "forgejo.org/modules/packages"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/storage"
- "forgejo.org/modules/util"
+ "code.gitea.io/gitea/models/git"
+ "code.gitea.io/gitea/models/packages"
+ "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/log"
+ packages_module "code.gitea.io/gitea/modules/packages"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/storage"
+ "code.gitea.io/gitea/modules/util"
)
type commonStorageCheckOptions struct {
diff --git a/services/doctor/usertype.go b/services/doctor/usertype.go
index 0a034d8f9d..ab32b78e62 100644
--- a/services/doctor/usertype.go
+++ b/services/doctor/usertype.go
@@ -6,8 +6,8 @@ package doctor
import (
"context"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/log"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/log"
)
func checkUserType(ctx context.Context, logger log.Logger, autofix bool) error {
diff --git a/services/externalaccount/link.go b/services/externalaccount/link.go
index 5672313181..d6e2ea7e94 100644
--- a/services/externalaccount/link.go
+++ b/services/externalaccount/link.go
@@ -5,9 +5,9 @@ package externalaccount
import (
"context"
- "errors"
+ "fmt"
- user_model "forgejo.org/models/user"
+ user_model "code.gitea.io/gitea/models/user"
"github.com/markbates/goth"
)
@@ -23,7 +23,7 @@ type Store interface {
func LinkAccountFromStore(ctx context.Context, store Store, user *user_model.User) error {
gothUser := store.Get("linkAccountGothUser")
if gothUser == nil {
- return errors.New("not in LinkAccount session")
+ return fmt.Errorf("not in LinkAccount session")
}
return LinkAccountToUser(ctx, user, gothUser.(goth.User))
diff --git a/services/externalaccount/user.go b/services/externalaccount/user.go
index 68d085f6d0..3cfd8c81f9 100644
--- a/services/externalaccount/user.go
+++ b/services/externalaccount/user.go
@@ -8,11 +8,11 @@ import (
"strconv"
"strings"
- "forgejo.org/models/auth"
- issues_model "forgejo.org/models/issues"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/structs"
+ "code.gitea.io/gitea/models/auth"
+ issues_model "code.gitea.io/gitea/models/issues"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/structs"
"github.com/markbates/goth"
)
diff --git a/services/f3/driver/asset.go b/services/f3/driver/asset.go
new file mode 100644
index 0000000000..61e571d1b6
--- /dev/null
+++ b/services/f3/driver/asset.go
@@ -0,0 +1,172 @@
+// Copyright Earl Warren
+// Copyright Loïc Dachary
+// SPDX-License-Identifier: MIT
+
+package driver
+
+import (
+ "context"
+ "crypto/sha256"
+ "encoding/hex"
+ "fmt"
+ "io"
+ "os"
+
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/storage"
+ "code.gitea.io/gitea/modules/timeutil"
+ "code.gitea.io/gitea/services/attachment"
+
+ "code.forgejo.org/f3/gof3/v3/f3"
+ f3_id "code.forgejo.org/f3/gof3/v3/id"
+ f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
+ "code.forgejo.org/f3/gof3/v3/tree/generic"
+ f3_util "code.forgejo.org/f3/gof3/v3/util"
+ "github.com/google/uuid"
+)
+
+var _ f3_tree.ForgeDriverInterface = &issue{}
+
+type asset struct {
+ common
+
+ forgejoAsset *repo_model.Attachment
+ sha string
+ contentType string
+ downloadFunc f3.DownloadFuncType
+}
+
+func (o *asset) SetNative(asset any) {
+ o.forgejoAsset = asset.(*repo_model.Attachment)
+}
+
+func (o *asset) GetNativeID() string {
+ return fmt.Sprintf("%d", o.forgejoAsset.ID)
+}
+
+func (o *asset) NewFormat() f3.Interface {
+ node := o.GetNode()
+ return node.GetTree().(f3_tree.TreeInterface).NewFormat(node.GetKind())
+}
+
+func (o *asset) ToFormat() f3.Interface {
+ if o.forgejoAsset == nil {
+ return o.NewFormat()
+ }
+
+ return &f3.ReleaseAsset{
+ Common: f3.NewCommon(o.GetNativeID()),
+ Name: o.forgejoAsset.Name,
+ ContentType: o.contentType,
+ Size: o.forgejoAsset.Size,
+ DownloadCount: o.forgejoAsset.DownloadCount,
+ Created: o.forgejoAsset.CreatedUnix.AsTime(),
+ SHA256: o.sha,
+ DownloadURL: o.forgejoAsset.DownloadURL(),
+ DownloadFunc: o.downloadFunc,
+ }
+}
+
+func (o *asset) FromFormat(content f3.Interface) {
+ asset := content.(*f3.ReleaseAsset)
+ o.forgejoAsset = &repo_model.Attachment{
+ ID: f3_util.ParseInt(asset.GetID()),
+ Name: asset.Name,
+ Size: asset.Size,
+ DownloadCount: asset.DownloadCount,
+ CreatedUnix: timeutil.TimeStamp(asset.Created.Unix()),
+ CustomDownloadURL: asset.DownloadURL,
+ }
+ o.contentType = asset.ContentType
+ o.sha = asset.SHA256
+ o.downloadFunc = asset.DownloadFunc
+}
+
+func (o *asset) Get(ctx context.Context) bool {
+ node := o.GetNode()
+ o.Trace("%s", node.GetID())
+
+ id := node.GetID().Int64()
+
+ asset, err := repo_model.GetAttachmentByID(ctx, id)
+ if repo_model.IsErrAttachmentNotExist(err) {
+ return false
+ }
+ if err != nil {
+ panic(fmt.Errorf("asset %v %w", id, err))
+ }
+
+ o.forgejoAsset = asset
+
+ path := o.forgejoAsset.RelativePath()
+
+ {
+ f, err := storage.Attachments.Open(path)
+ if err != nil {
+ panic(err)
+ }
+ hasher := sha256.New()
+ if _, err := io.Copy(hasher, f); err != nil {
+ panic(fmt.Errorf("io.Copy to hasher: %v", err))
+ }
+ o.sha = hex.EncodeToString(hasher.Sum(nil))
+ }
+
+ o.downloadFunc = func() io.ReadCloser {
+ o.Trace("download %s from copy stored in temporary file %s", o.forgejoAsset.DownloadURL, path)
+ f, err := os.Open(path)
+ if err != nil {
+ panic(err)
+ }
+ return f
+ }
+ return true
+}
+
+func (o *asset) Patch(ctx context.Context) {
+ o.Trace("%d", o.forgejoAsset.ID)
+ if _, err := db.GetEngine(ctx).ID(o.forgejoAsset.ID).Cols("name").Update(o.forgejoAsset); err != nil {
+ panic(fmt.Errorf("UpdateAssetCols: %v %v", o.forgejoAsset, err))
+ }
+}
+
+func (o *asset) Put(ctx context.Context) f3_id.NodeID {
+ node := o.GetNode()
+ o.Trace("%s", node.GetID())
+
+ uploader, err := user_model.GetAdminUser(ctx)
+ if err != nil {
+ panic(fmt.Errorf("GetAdminUser %w", err))
+ }
+
+ o.forgejoAsset.UploaderID = uploader.ID
+ o.forgejoAsset.RepoID = f3_tree.GetProjectID(o.GetNode())
+ o.forgejoAsset.ReleaseID = f3_tree.GetReleaseID(o.GetNode())
+ o.forgejoAsset.UUID = uuid.New().String()
+
+ download := o.downloadFunc()
+ defer download.Close()
+
+ _, err = attachment.NewAttachment(ctx, o.forgejoAsset, download, o.forgejoAsset.Size)
+ if err != nil {
+ panic(err)
+ }
+
+ o.Trace("asset created %d", o.forgejoAsset.ID)
+ return f3_id.NewNodeID(o.forgejoAsset.ID)
+}
+
+func (o *asset) Delete(ctx context.Context) {
+ node := o.GetNode()
+ o.Trace("%s", node.GetID())
+
+ if err := repo_model.DeleteAttachment(ctx, o.forgejoAsset, true); err != nil {
+ panic(err)
+ }
+}
+
+func newAsset() generic.NodeDriverInterface {
+ return &asset{}
+}
diff --git a/services/f3/driver/assets.go b/services/f3/driver/assets.go
new file mode 100644
index 0000000000..88a3979713
--- /dev/null
+++ b/services/f3/driver/assets.go
@@ -0,0 +1,42 @@
+// Copyright Earl Warren
+// Copyright Loïc Dachary
+// SPDX-License-Identifier: MIT
+
+package driver
+
+import (
+ "context"
+ "fmt"
+
+ repo_model "code.gitea.io/gitea/models/repo"
+
+ f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
+ "code.forgejo.org/f3/gof3/v3/tree/generic"
+)
+
+type assets struct {
+ container
+}
+
+func (o *assets) ListPage(ctx context.Context, page int) generic.ChildrenSlice {
+ if page > 1 {
+ return generic.NewChildrenSlice(0)
+ }
+
+ releaseID := f3_tree.GetReleaseID(o.GetNode())
+
+ release, err := repo_model.GetReleaseByID(ctx, releaseID)
+ if err != nil {
+ panic(fmt.Errorf("GetReleaseByID %v %w", releaseID, err))
+ }
+
+ if err := release.LoadAttributes(ctx); err != nil {
+ panic(fmt.Errorf("error while listing assets: %v", err))
+ }
+
+ return f3_tree.ConvertListed(ctx, o.GetNode(), f3_tree.ConvertToAny(release.Attachments...)...)
+}
+
+func newAssets() generic.NodeDriverInterface {
+ return &assets{}
+}
diff --git a/services/f3/driver/attachment.go b/services/f3/driver/attachment.go
deleted file mode 100644
index 64c188d6e0..0000000000
--- a/services/f3/driver/attachment.go
+++ /dev/null
@@ -1,185 +0,0 @@
-// Copyright Earl Warren
-// Copyright Loïc Dachary
-// SPDX-License-Identifier: MIT
-
-package driver
-
-import (
- "context"
- "crypto/sha256"
- "encoding/hex"
- "fmt"
- "io"
- "os"
-
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/storage"
- "forgejo.org/modules/timeutil"
- forgejo_attachment "forgejo.org/services/attachment"
-
- "code.forgejo.org/f3/gof3/v3/f3"
- f3_id "code.forgejo.org/f3/gof3/v3/id"
- f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
- "code.forgejo.org/f3/gof3/v3/tree/generic"
- f3_util "code.forgejo.org/f3/gof3/v3/util"
- "github.com/google/uuid"
-)
-
-var _ f3_tree.ForgeDriverInterface = &issue{}
-
-type attachment struct {
- common
-
- forgejoAttachment *repo_model.Attachment
- sha string
- contentType string
- downloadFunc f3.DownloadFuncType
-}
-
-func (o *attachment) SetNative(attachment any) {
- o.forgejoAttachment = attachment.(*repo_model.Attachment)
-}
-
-func (o *attachment) GetNativeID() string {
- return fmt.Sprintf("%d", o.forgejoAttachment.ID)
-}
-
-func (o *attachment) NewFormat() f3.Interface {
- node := o.GetNode()
- return node.GetTree().(f3_tree.TreeInterface).NewFormat(node.GetKind())
-}
-
-func (o *attachment) ToFormat() f3.Interface {
- if o.forgejoAttachment == nil {
- return o.NewFormat()
- }
-
- return &f3.Attachment{
- Common: f3.NewCommon(o.GetNativeID()),
- Name: o.forgejoAttachment.Name,
- ContentType: o.contentType,
- Size: o.forgejoAttachment.Size,
- DownloadCount: o.forgejoAttachment.DownloadCount,
- Created: o.forgejoAttachment.CreatedUnix.AsTime(),
- SHA256: o.sha,
- DownloadURL: o.forgejoAttachment.DownloadURL(),
- DownloadFunc: o.downloadFunc,
- }
-}
-
-func (o *attachment) FromFormat(content f3.Interface) {
- attachment := content.(*f3.Attachment)
- o.forgejoAttachment = &repo_model.Attachment{
- ID: f3_util.ParseInt(attachment.GetID()),
- Name: attachment.Name,
- Size: attachment.Size,
- DownloadCount: attachment.DownloadCount,
- CreatedUnix: timeutil.TimeStamp(attachment.Created.Unix()),
- CustomDownloadURL: attachment.DownloadURL,
- }
- o.contentType = attachment.ContentType
- o.sha = attachment.SHA256
- o.downloadFunc = attachment.DownloadFunc
-}
-
-func (o *attachment) Get(ctx context.Context) bool {
- node := o.GetNode()
- o.Trace("%s", node.GetID())
-
- id := node.GetID().Int64()
-
- attachment, err := repo_model.GetAttachmentByID(ctx, id)
- if repo_model.IsErrAttachmentNotExist(err) {
- return false
- }
- if err != nil {
- panic(fmt.Errorf("attachment %v %w", id, err))
- }
-
- o.forgejoAttachment = attachment
-
- path := o.forgejoAttachment.RelativePath()
-
- {
- f, err := storage.Attachments.Open(path)
- if err != nil {
- panic(err)
- }
- hasher := sha256.New()
- if _, err := io.Copy(hasher, f); err != nil {
- panic(fmt.Errorf("io.Copy to hasher: %v", err))
- }
- o.sha = hex.EncodeToString(hasher.Sum(nil))
- }
-
- o.downloadFunc = func() io.ReadCloser {
- o.Trace("download %s from copy stored in temporary file %s", o.forgejoAttachment.DownloadURL, path)
- f, err := os.Open(path)
- if err != nil {
- panic(err)
- }
- return f
- }
- return true
-}
-
-func (o *attachment) Patch(ctx context.Context) {
- o.Trace("%d", o.forgejoAttachment.ID)
- if _, err := db.GetEngine(ctx).ID(o.forgejoAttachment.ID).Cols("name").Update(o.forgejoAttachment); err != nil {
- panic(fmt.Errorf("UpdateAttachmentCols: %v %v", o.forgejoAttachment, err))
- }
-}
-
-func (o *attachment) Put(ctx context.Context) f3_id.NodeID {
- node := o.GetNode()
- o.Trace("%s", node.GetID())
-
- uploader, err := user_model.GetAdminUser(ctx)
- if err != nil {
- panic(fmt.Errorf("GetAdminUser %w", err))
- }
-
- attachable := f3_tree.GetAttachable(o.GetNode())
- attachableID := f3_tree.GetAttachableID(o.GetNode())
-
- switch attachable.GetKind() {
- case f3_tree.KindRelease:
- o.forgejoAttachment.ReleaseID = attachableID
- case f3_tree.KindComment:
- o.forgejoAttachment.CommentID = attachableID
- case f3_tree.KindIssue, f3_tree.KindPullRequest:
- o.forgejoAttachment.IssueID = attachableID
- default:
- panic(fmt.Errorf("unexpected type %s", attachable.GetKind()))
- }
-
- o.forgejoAttachment.UploaderID = uploader.ID
- o.forgejoAttachment.RepoID = f3_tree.GetProjectID(o.GetNode())
- o.forgejoAttachment.UUID = uuid.New().String()
-
- download := o.downloadFunc()
- defer download.Close()
-
- _, err = forgejo_attachment.NewAttachment(ctx, o.forgejoAttachment, download, o.forgejoAttachment.Size)
- if err != nil {
- panic(err)
- }
-
- o.Trace("attachment created %d", o.forgejoAttachment.ID)
- return f3_id.NewNodeID(o.forgejoAttachment.ID)
-}
-
-func (o *attachment) Delete(ctx context.Context) {
- node := o.GetNode()
- o.Trace("%s", node.GetID())
-
- if err := repo_model.DeleteAttachment(ctx, o.forgejoAttachment, true); err != nil {
- panic(err)
- }
-}
-
-func newAttachment() generic.NodeDriverInterface {
- return &attachment{}
-}
diff --git a/services/f3/driver/attachments.go b/services/f3/driver/attachments.go
deleted file mode 100644
index 392afda52c..0000000000
--- a/services/f3/driver/attachments.go
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright Earl Warren
-// Copyright Loïc Dachary
-// SPDX-License-Identifier: MIT
-
-package driver
-
-import (
- "context"
- "fmt"
-
- issues_model "forgejo.org/models/issues"
- repo_model "forgejo.org/models/repo"
-
- f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
- "code.forgejo.org/f3/gof3/v3/tree/generic"
-)
-
-type attachments struct {
- container
-}
-
-func (o *attachments) ListPage(ctx context.Context, page int) generic.ChildrenSlice {
- if page > 1 {
- return generic.NewChildrenSlice(0)
- }
-
- attachable := f3_tree.GetAttachable(o.GetNode())
- attachableID := f3_tree.GetAttachableID(o.GetNode())
-
- var attachments []*repo_model.Attachment
-
- switch attachable.GetKind() {
- case f3_tree.KindRelease:
- release, err := repo_model.GetReleaseByID(ctx, attachableID)
- if err != nil {
- panic(fmt.Errorf("GetReleaseByID %v %w", attachableID, err))
- }
-
- if err := release.LoadAttributes(ctx); err != nil {
- panic(fmt.Errorf("error while listing attachments: %v", err))
- }
-
- attachments = release.Attachments
-
- case f3_tree.KindComment:
- comment, err := issues_model.GetCommentByID(ctx, attachableID)
- if err != nil {
- panic(fmt.Errorf("GetCommentByID %v %w", attachableID, err))
- }
-
- if err := comment.LoadAttachments(ctx); err != nil {
- panic(fmt.Errorf("error while listing attachments: %v", err))
- }
-
- attachments = comment.Attachments
-
- case f3_tree.KindIssue, f3_tree.KindPullRequest:
- repoID := f3_tree.GetProjectID(o.GetNode())
- issue, err := issues_model.GetIssueByIndex(ctx, repoID, attachableID)
- if err != nil {
- panic(fmt.Errorf("GetIssueByID %v %w", attachableID, err))
- }
-
- if err := issue.LoadAttachments(ctx); err != nil {
- panic(fmt.Errorf("error while listing attachments: %v", err))
- }
-
- attachments = issue.Attachments
-
- default:
- panic(fmt.Errorf("unexpected type %s", attachable.GetKind()))
- }
-
- return f3_tree.ConvertListed(ctx, o.GetNode(), f3_tree.ConvertToAny(attachments...)...)
-}
-
-func newAttachments() generic.NodeDriverInterface {
- return &attachments{}
-}
diff --git a/services/f3/driver/comment.go b/services/f3/driver/comment.go
index bd924930b5..166bfcd328 100644
--- a/services/f3/driver/comment.go
+++ b/services/f3/driver/comment.go
@@ -8,10 +8,10 @@ import (
"context"
"fmt"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/timeutil"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/timeutil"
"code.forgejo.org/f3/gof3/v3/f3"
f3_id "code.forgejo.org/f3/gof3/v3/id"
diff --git a/services/f3/driver/comments.go b/services/f3/driver/comments.go
index d8c84e290c..eb79b74066 100644
--- a/services/f3/driver/comments.go
+++ b/services/f3/driver/comments.go
@@ -8,8 +8,8 @@ import (
"context"
"fmt"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic"
diff --git a/services/f3/driver/forge.go b/services/f3/driver/forge.go
index 03acb41450..c232882753 100644
--- a/services/f3/driver/forge.go
+++ b/services/f3/driver/forge.go
@@ -8,7 +8,7 @@ import (
"context"
"fmt"
- user_model "forgejo.org/models/user"
+ user_model "code.gitea.io/gitea/models/user"
"code.forgejo.org/f3/gof3/v3/f3"
f3_id "code.forgejo.org/f3/gof3/v3/id"
diff --git a/services/f3/driver/issue.go b/services/f3/driver/issue.go
index 6308c4cc2d..7e10f3a9db 100644
--- a/services/f3/driver/issue.go
+++ b/services/f3/driver/issue.go
@@ -8,13 +8,13 @@ import (
"context"
"fmt"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/timeutil"
- issue_service "forgejo.org/services/issue"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/timeutil"
+ issue_service "code.gitea.io/gitea/services/issue"
"code.forgejo.org/f3/gof3/v3/f3"
f3_id "code.forgejo.org/f3/gof3/v3/id"
diff --git a/services/f3/driver/issues.go b/services/f3/driver/issues.go
index dd6828dc86..3a5a64e2b1 100644
--- a/services/f3/driver/issues.go
+++ b/services/f3/driver/issues.go
@@ -8,8 +8,8 @@ import (
"context"
"fmt"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic"
diff --git a/services/f3/driver/label.go b/services/f3/driver/label.go
index 707ac2bab3..509a69cf71 100644
--- a/services/f3/driver/label.go
+++ b/services/f3/driver/label.go
@@ -9,8 +9,8 @@ import (
"fmt"
"strings"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
"code.forgejo.org/f3/gof3/v3/f3"
f3_id "code.forgejo.org/f3/gof3/v3/id"
diff --git a/services/f3/driver/labels.go b/services/f3/driver/labels.go
index 4f705ed206..03f986b57a 100644
--- a/services/f3/driver/labels.go
+++ b/services/f3/driver/labels.go
@@ -8,8 +8,8 @@ import (
"context"
"fmt"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic"
diff --git a/services/f3/driver/main.go b/services/f3/driver/main.go
index eb6e4a6fb6..825d456692 100644
--- a/services/f3/driver/main.go
+++ b/services/f3/driver/main.go
@@ -5,7 +5,7 @@
package driver
import (
- driver_options "forgejo.org/services/f3/driver/options"
+ driver_options "code.gitea.io/gitea/services/f3/driver/options"
"code.forgejo.org/f3/gof3/v3/options"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
diff --git a/services/f3/driver/main_test.go b/services/f3/driver/main_test.go
index b136fd5b23..8505b69b7e 100644
--- a/services/f3/driver/main_test.go
+++ b/services/f3/driver/main_test.go
@@ -7,14 +7,14 @@ package driver
import (
"testing"
- "forgejo.org/models/unittest"
- driver_options "forgejo.org/services/f3/driver/options"
+ "code.gitea.io/gitea/models/unittest"
+ driver_options "code.gitea.io/gitea/services/f3/driver/options"
- _ "forgejo.org/models"
- _ "forgejo.org/models/actions"
- _ "forgejo.org/models/activities"
- _ "forgejo.org/models/perm/access"
- _ "forgejo.org/services/f3/driver/tests"
+ _ "code.gitea.io/gitea/models"
+ _ "code.gitea.io/gitea/models/actions"
+ _ "code.gitea.io/gitea/models/activities"
+ _ "code.gitea.io/gitea/models/perm/access"
+ _ "code.gitea.io/gitea/services/f3/driver/tests"
tests_f3 "code.forgejo.org/f3/gof3/v3/tree/tests/f3"
"github.com/stretchr/testify/require"
diff --git a/services/f3/driver/milestone.go b/services/f3/driver/milestone.go
index d10e6918ac..e57fee95a7 100644
--- a/services/f3/driver/milestone.go
+++ b/services/f3/driver/milestone.go
@@ -9,10 +9,10 @@ import (
"fmt"
"time"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/timeutil"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/timeutil"
"code.forgejo.org/f3/gof3/v3/f3"
f3_id "code.forgejo.org/f3/gof3/v3/id"
diff --git a/services/f3/driver/milestones.go b/services/f3/driver/milestones.go
index cf0b70c158..c816903bb1 100644
--- a/services/f3/driver/milestones.go
+++ b/services/f3/driver/milestones.go
@@ -8,8 +8,8 @@ import (
"context"
"fmt"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic"
diff --git a/services/f3/driver/options.go b/services/f3/driver/options.go
index 516f9baf7a..abc5015dd0 100644
--- a/services/f3/driver/options.go
+++ b/services/f3/driver/options.go
@@ -7,7 +7,7 @@ package driver
import (
"net/http"
- driver_options "forgejo.org/services/f3/driver/options"
+ driver_options "code.gitea.io/gitea/services/f3/driver/options"
"code.forgejo.org/f3/gof3/v3/options"
)
diff --git a/services/f3/driver/organization.go b/services/f3/driver/organization.go
index af1eea4dda..8e818a231a 100644
--- a/services/f3/driver/organization.go
+++ b/services/f3/driver/organization.go
@@ -8,9 +8,9 @@ import (
"context"
"fmt"
- "forgejo.org/models/db"
- org_model "forgejo.org/models/organization"
- user_model "forgejo.org/models/user"
+ "code.gitea.io/gitea/models/db"
+ org_model "code.gitea.io/gitea/models/organization"
+ user_model "code.gitea.io/gitea/models/user"
"code.forgejo.org/f3/gof3/v3/f3"
f3_id "code.forgejo.org/f3/gof3/v3/id"
diff --git a/services/f3/driver/organizations.go b/services/f3/driver/organizations.go
index eca6bfb9d4..adebdbbe95 100644
--- a/services/f3/driver/organizations.go
+++ b/services/f3/driver/organizations.go
@@ -8,9 +8,9 @@ import (
"context"
"fmt"
- "forgejo.org/models/db"
- org_model "forgejo.org/models/organization"
- user_model "forgejo.org/models/user"
+ "code.gitea.io/gitea/models/db"
+ org_model "code.gitea.io/gitea/models/organization"
+ user_model "code.gitea.io/gitea/models/user"
f3_id "code.forgejo.org/f3/gof3/v3/id"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
diff --git a/services/f3/driver/project.go b/services/f3/driver/project.go
index 5a3ec81e40..2400663426 100644
--- a/services/f3/driver/project.go
+++ b/services/f3/driver/project.go
@@ -9,9 +9,9 @@ import (
"fmt"
"strings"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- repo_service "forgejo.org/services/repository"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ repo_service "code.gitea.io/gitea/services/repository"
"code.forgejo.org/f3/gof3/v3/f3"
f3_id "code.forgejo.org/f3/gof3/v3/id"
diff --git a/services/f3/driver/projects.go b/services/f3/driver/projects.go
index 0c76854f43..fb447f3f01 100644
--- a/services/f3/driver/projects.go
+++ b/services/f3/driver/projects.go
@@ -8,8 +8,8 @@ import (
"context"
"fmt"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
f3_id "code.forgejo.org/f3/gof3/v3/id"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
diff --git a/services/f3/driver/pullrequest.go b/services/f3/driver/pullrequest.go
index 664ee6b13b..b8cb06c4d5 100644
--- a/services/f3/driver/pullrequest.go
+++ b/services/f3/driver/pullrequest.go
@@ -9,13 +9,13 @@ import (
"fmt"
"time"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/timeutil"
- issue_service "forgejo.org/services/issue"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/timeutil"
+ issue_service "code.gitea.io/gitea/services/issue"
"code.forgejo.org/f3/gof3/v3/f3"
f3_id "code.forgejo.org/f3/gof3/v3/id"
diff --git a/services/f3/driver/pullrequests.go b/services/f3/driver/pullrequests.go
index 227171994c..e7f2910314 100644
--- a/services/f3/driver/pullrequests.go
+++ b/services/f3/driver/pullrequests.go
@@ -8,9 +8,9 @@ import (
"context"
"fmt"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- "forgejo.org/modules/optional"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ "code.gitea.io/gitea/modules/optional"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic"
diff --git a/services/f3/driver/reaction.go b/services/f3/driver/reaction.go
index b959206074..4f12fa41db 100644
--- a/services/f3/driver/reaction.go
+++ b/services/f3/driver/reaction.go
@@ -8,9 +8,9 @@ import (
"context"
"fmt"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- user_model "forgejo.org/models/user"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ user_model "code.gitea.io/gitea/models/user"
"code.forgejo.org/f3/gof3/v3/f3"
f3_id "code.forgejo.org/f3/gof3/v3/id"
@@ -89,7 +89,7 @@ func (o *reaction) Patch(ctx context.Context) {
}
func (o *reaction) Put(ctx context.Context) f3_id.NodeID {
- o.Trace("%v", o.forgejoReaction.User)
+ o.Error("%v", o.forgejoReaction.User)
sess := db.GetEngine(ctx)
@@ -110,7 +110,7 @@ func (o *reaction) Put(ctx context.Context) f3_id.NodeID {
panic(fmt.Errorf("unexpected type %v", reactionable.GetKind()))
}
- o.Trace("%v", o.forgejoReaction)
+ o.Error("%v", o.forgejoReaction)
if _, err := sess.Insert(o.forgejoReaction); err != nil {
panic(err)
diff --git a/services/f3/driver/reactions.go b/services/f3/driver/reactions.go
index a546927b92..b7fd5e8f0a 100644
--- a/services/f3/driver/reactions.go
+++ b/services/f3/driver/reactions.go
@@ -8,8 +8,8 @@ import (
"context"
"fmt"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic"
diff --git a/services/f3/driver/release.go b/services/f3/driver/release.go
index df38bd8bc0..86490e8b02 100644
--- a/services/f3/driver/release.go
+++ b/services/f3/driver/release.go
@@ -9,12 +9,12 @@ import (
"fmt"
"strings"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/timeutil"
- release_service "forgejo.org/services/release"
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/timeutil"
+ release_service "code.gitea.io/gitea/services/release"
"code.forgejo.org/f3/gof3/v3/f3"
f3_id "code.forgejo.org/f3/gof3/v3/id"
diff --git a/services/f3/driver/releases.go b/services/f3/driver/releases.go
index a631c0b60e..3b46bc7c54 100644
--- a/services/f3/driver/releases.go
+++ b/services/f3/driver/releases.go
@@ -8,8 +8,8 @@ import (
"context"
"fmt"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic"
diff --git a/services/f3/driver/repository.go b/services/f3/driver/repository.go
index 3cd9aa7f2e..118d5f2f2a 100644
--- a/services/f3/driver/repository.go
+++ b/services/f3/driver/repository.go
@@ -7,7 +7,7 @@ package driver
import (
"context"
- repo_model "forgejo.org/models/repo"
+ repo_model "code.gitea.io/gitea/models/repo"
"code.forgejo.org/f3/gof3/v3/f3"
helpers_repository "code.forgejo.org/f3/gof3/v3/forges/helpers/repository"
@@ -72,7 +72,7 @@ func (o *repository) upsert(ctx context.Context) f3_id.NodeID {
return f3_id.NewNodeID(o.f.Name)
}
-func (o *repository) SetFetchFunc(fetchFunc func(ctx context.Context, destination, internalRef string)) {
+func (o *repository) SetFetchFunc(fetchFunc func(ctx context.Context, destination string, internalRefs []string)) {
o.f.FetchFunc = fetchFunc
}
@@ -93,16 +93,10 @@ func (o *repository) GetRepositoryPushURL() string {
return o.getURL()
}
-func (o *repository) GetRepositoryInternalRef() string {
- return ""
+func (o *repository) GetRepositoryInternalRefs() []string {
+ return []string{}
}
-func (o *repository) GetPullRequestBranch(pr *f3.PullRequestBranch) *f3.PullRequestBranch {
- panic("")
-}
-func (o *repository) CreatePullRequestBranch(pr *f3.PullRequestBranch) {}
-func (o *repository) DeletePullRequestBranch(pr *f3.PullRequestBranch) {}
-
func newRepository(_ context.Context) generic.NodeDriverInterface {
r := &repository{
f: &f3.Repository{},
diff --git a/services/f3/driver/review.go b/services/f3/driver/review.go
index f4f5ff44b8..d180ea96be 100644
--- a/services/f3/driver/review.go
+++ b/services/f3/driver/review.go
@@ -8,10 +8,10 @@ import (
"context"
"fmt"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/timeutil"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/timeutil"
"code.forgejo.org/f3/gof3/v3/f3"
f3_id "code.forgejo.org/f3/gof3/v3/id"
diff --git a/services/f3/driver/reviewcomment.go b/services/f3/driver/reviewcomment.go
index 22759b6df3..7ba0e15802 100644
--- a/services/f3/driver/reviewcomment.go
+++ b/services/f3/driver/reviewcomment.go
@@ -9,10 +9,10 @@ import (
"fmt"
"strings"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/timeutil"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/timeutil"
"code.forgejo.org/f3/gof3/v3/f3"
f3_id "code.forgejo.org/f3/gof3/v3/id"
diff --git a/services/f3/driver/reviewcomments.go b/services/f3/driver/reviewcomments.go
index 2aa4dea22c..e11aaa489b 100644
--- a/services/f3/driver/reviewcomments.go
+++ b/services/f3/driver/reviewcomments.go
@@ -8,8 +8,8 @@ import (
"context"
"fmt"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic"
diff --git a/services/f3/driver/reviews.go b/services/f3/driver/reviews.go
index 7c3dcb37de..a20d5741d1 100644
--- a/services/f3/driver/reviews.go
+++ b/services/f3/driver/reviews.go
@@ -8,8 +8,8 @@ import (
"context"
"fmt"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic"
diff --git a/services/f3/driver/tests/init.go b/services/f3/driver/tests/init.go
index 9035296dc0..d7bf23ac88 100644
--- a/services/f3/driver/tests/init.go
+++ b/services/f3/driver/tests/init.go
@@ -5,7 +5,7 @@
package tests
import (
- driver_options "forgejo.org/services/f3/driver/options"
+ driver_options "code.gitea.io/gitea/services/f3/driver/options"
tests_forge "code.forgejo.org/f3/gof3/v3/tree/tests/f3/forge"
)
diff --git a/services/f3/driver/tests/new.go b/services/f3/driver/tests/new.go
index 2f5c6c64db..dc6ac437e6 100644
--- a/services/f3/driver/tests/new.go
+++ b/services/f3/driver/tests/new.go
@@ -7,7 +7,7 @@ package tests
import (
"testing"
- driver_options "forgejo.org/services/f3/driver/options"
+ driver_options "code.gitea.io/gitea/services/f3/driver/options"
f3_kind "code.forgejo.org/f3/gof3/v3/kind"
"code.forgejo.org/f3/gof3/v3/options"
diff --git a/services/f3/driver/tests/options.go b/services/f3/driver/tests/options.go
index f61b10c9ef..adaa1da588 100644
--- a/services/f3/driver/tests/options.go
+++ b/services/f3/driver/tests/options.go
@@ -7,9 +7,9 @@ package tests
import (
"testing"
- forgejo_log "forgejo.org/modules/log"
- driver_options "forgejo.org/services/f3/driver/options"
- "forgejo.org/services/f3/util"
+ forgejo_log "code.gitea.io/gitea/modules/log"
+ driver_options "code.gitea.io/gitea/services/f3/driver/options"
+ "code.gitea.io/gitea/services/f3/util"
"code.forgejo.org/f3/gof3/v3/options"
)
diff --git a/services/f3/driver/topic.go b/services/f3/driver/topic.go
index cc94aa35fa..eeb387cf93 100644
--- a/services/f3/driver/topic.go
+++ b/services/f3/driver/topic.go
@@ -8,8 +8,8 @@ import (
"context"
"fmt"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
"code.forgejo.org/f3/gof3/v3/f3"
f3_id "code.forgejo.org/f3/gof3/v3/id"
diff --git a/services/f3/driver/topics.go b/services/f3/driver/topics.go
index 38f03dbd2d..2685a47928 100644
--- a/services/f3/driver/topics.go
+++ b/services/f3/driver/topics.go
@@ -8,8 +8,8 @@ import (
"context"
"fmt"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic"
diff --git a/services/f3/driver/tree.go b/services/f3/driver/tree.go
index fe11b15f6e..2377d3794d 100644
--- a/services/f3/driver/tree.go
+++ b/services/f3/driver/tree.go
@@ -8,7 +8,7 @@ import (
"context"
"fmt"
- forgejo_options "forgejo.org/services/f3/driver/options"
+ forgejo_options "code.gitea.io/gitea/services/f3/driver/options"
f3_kind "code.forgejo.org/f3/gof3/v3/kind"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
@@ -49,10 +49,10 @@ func (o *treeDriver) Factory(ctx context.Context, kind f3_kind.Kind) generic.Nod
return newComments()
case f3_tree.KindComment:
return newComment()
- case f3_tree.KindAttachments:
- return newAttachments()
- case f3_tree.KindAttachment:
- return newAttachment()
+ case f3_tree.KindAssets:
+ return newAssets()
+ case f3_tree.KindAsset:
+ return newAsset()
case f3_tree.KindLabels:
return newLabels()
case f3_tree.KindLabel:
diff --git a/services/f3/driver/user.go b/services/f3/driver/user.go
index bf8bfaf9c9..0ba6cbb7c6 100644
--- a/services/f3/driver/user.go
+++ b/services/f3/driver/user.go
@@ -9,9 +9,9 @@ import (
"fmt"
"strings"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/optional"
- user_service "forgejo.org/services/user"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/optional"
+ user_service "code.gitea.io/gitea/services/user"
"code.forgejo.org/f3/gof3/v3/f3"
f3_id "code.forgejo.org/f3/gof3/v3/id"
diff --git a/services/f3/driver/users.go b/services/f3/driver/users.go
index cb413ae05d..59b10fc51d 100644
--- a/services/f3/driver/users.go
+++ b/services/f3/driver/users.go
@@ -8,8 +8,8 @@ import (
"context"
"fmt"
- "forgejo.org/models/db"
- user_model "forgejo.org/models/user"
+ "code.gitea.io/gitea/models/db"
+ user_model "code.gitea.io/gitea/models/user"
f3_id "code.forgejo.org/f3/gof3/v3/id"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
diff --git a/services/f3/util/logger.go b/services/f3/util/logger.go
index 9a1409ae84..21d8d6bbfa 100644
--- a/services/f3/util/logger.go
+++ b/services/f3/util/logger.go
@@ -6,8 +6,8 @@ package util
import (
"fmt"
- forgejo_log "forgejo.org/modules/log"
- "forgejo.org/modules/migration"
+ forgejo_log "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/migration"
"code.forgejo.org/f3/gof3/v3/logger"
)
diff --git a/services/f3/util/logger_test.go b/services/f3/util/logger_test.go
index f62d9e2e82..db880aa439 100644
--- a/services/f3/util/logger_test.go
+++ b/services/f3/util/logger_test.go
@@ -8,8 +8,8 @@ import (
"testing"
"time"
- forgejo_log "forgejo.org/modules/log"
- "forgejo.org/modules/test"
+ forgejo_log "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/test"
"code.forgejo.org/f3/gof3/v3/logger"
"github.com/stretchr/testify/assert"
@@ -23,7 +23,7 @@ func TestF3UtilMessage(t *testing.T) {
actual = fmt.Sprintf(message, args...)
}, nil)
logger.Message("EXPECTED %s", "MESSAGE")
- assert.Equal(t, expected, actual)
+ assert.EqualValues(t, expected, actual)
}
func TestF3UtilLogger(t *testing.T) {
diff --git a/services/federation/delivery_queue.go b/services/federation/delivery_queue.go
deleted file mode 100644
index f71467e9f0..0000000000
--- a/services/federation/delivery_queue.go
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2024 The Forgejo Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package federation
-
-import (
- "fmt"
- "io"
-
- "forgejo.org/models/user"
- "forgejo.org/modules/activitypub"
- "forgejo.org/modules/graceful"
- "forgejo.org/modules/log"
- "forgejo.org/modules/process"
- "forgejo.org/modules/queue"
-)
-
-type deliveryQueueItem struct {
- Doer *user.User
- InboxURL string
- Payload []byte
- DeliveryCount int
-}
-
-var deliveryQueue *queue.WorkerPoolQueue[deliveryQueueItem]
-
-func initDeliveryQueue() error {
- deliveryQueue = queue.CreateUniqueQueue(graceful.GetManager().ShutdownContext(), "activitypub_inbox_delivery", deliveryQueueHandler)
- if deliveryQueue == nil {
- return fmt.Errorf("unable to create activitypub_inbox_delivery queue")
- }
- go graceful.GetManager().RunWithCancel(deliveryQueue)
-
- return nil
-}
-
-func deliveryQueueHandler(items ...deliveryQueueItem) (unhandled []deliveryQueueItem) {
- for _, item := range items {
- item.DeliveryCount++
- err := deliverToInbox(item)
- if err != nil && item.DeliveryCount < 10 {
- unhandled = append(unhandled, item)
- }
- }
- return unhandled
-}
-
-func deliverToInbox(item deliveryQueueItem) error {
- ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(),
- fmt.Sprintf("Delivering an Activity via user[%d] (%s), to %s", item.Doer.ID, item.Doer.Name, item.InboxURL))
- defer finished()
-
- clientFactory, err := activitypub.GetClientFactory(ctx)
- if err != nil {
- return err
- }
- apclient, err := clientFactory.WithKeys(ctx, item.Doer, item.Doer.APActorID()+"#main-key")
- if err != nil {
- return err
- }
-
- log.Debug("Delivering %s to %s", item.Payload, item.InboxURL)
- res, err := apclient.Post(item.Payload, item.InboxURL)
- if err != nil {
- return err
- }
- if res.StatusCode >= 400 {
- defer res.Body.Close()
- body, _ := io.ReadAll(io.LimitReader(res.Body, 16*1024))
-
- log.Warn("Delivering to %s failed: %d %s, %v times", item.InboxURL, res.StatusCode, string(body), item.DeliveryCount)
- return fmt.Errorf("delivery failed")
- }
-
- return nil
-}
diff --git a/services/federation/error.go b/services/federation/error.go
deleted file mode 100644
index 425035d0d5..0000000000
--- a/services/federation/error.go
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2025 The Forgejo Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package federation
-
-import (
- "fmt"
- "net/http"
-)
-
-type ErrNotAcceptable struct {
- Message string
-}
-
-func NewErrNotAcceptablef(format string, a ...any) ErrNotAcceptable {
- message := fmt.Sprintf(format, a...)
- return ErrNotAcceptable{Message: message}
-}
-
-func (err ErrNotAcceptable) Error() string {
- return fmt.Sprintf("NotAcceptable: %v", err.Message)
-}
-
-type ErrInternal struct {
- Message string
-}
-
-func NewErrInternalf(format string, a ...any) ErrInternal {
- message := fmt.Sprintf(format, a...)
- return ErrInternal{Message: message}
-}
-
-func (err ErrInternal) Error() string {
- return fmt.Sprintf("InternalServerError: %v", err.Message)
-}
-
-func HTTPStatus(err error) int {
- switch err.(type) {
- case ErrNotAcceptable:
- return http.StatusNotAcceptable
- default:
- return http.StatusInternalServerError
- }
-}
diff --git a/services/federation/federation_service.go b/services/federation/federation_service.go
index ccdb9bbab0..4c6f5ca0ca 100644
--- a/services/federation/federation_service.go
+++ b/services/federation/federation_service.go
@@ -1,45 +1,151 @@
-// Copyright 2024, 2025 The Forgejo Authors. All rights reserved.
+// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package federation
import (
"context"
- "database/sql"
"fmt"
+ "net/http"
"net/url"
"strings"
+ "time"
- "forgejo.org/models/forgefed"
- "forgejo.org/models/user"
- "forgejo.org/modules/activitypub"
- "forgejo.org/modules/auth/password"
- fm "forgejo.org/modules/forgefed"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/validation"
+ "code.gitea.io/gitea/models/forgefed"
+ "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/activitypub"
+ "code.gitea.io/gitea/modules/auth/password"
+ fm "code.gitea.io/gitea/modules/forgefed"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/validation"
"github.com/google/uuid"
)
-func Init() error {
- if !setting.Federation.Enabled {
- return nil
+// ProcessLikeActivity receives a ForgeLike activity and does the following:
+// Validation of the activity
+// Creation of a (remote) federationHost if not existing
+// Creation of a forgefed Person if not existing
+// Validation of incoming RepositoryID against Local RepositoryID
+// Star the repo if it wasn't already stared
+// Do some mitigation against out of order attacks
+func ProcessLikeActivity(ctx context.Context, form any, repositoryID int64) (int, string, error) {
+ activity := form.(*fm.ForgeLike)
+ if res, err := validation.IsValid(activity); !res {
+ return http.StatusNotAcceptable, "Invalid activity", err
}
- return initDeliveryQueue()
+ log.Info("Activity validated:%v", activity)
+
+ // parse actorID (person)
+ actorURI := activity.Actor.GetID().String()
+ log.Info("actorURI was: %v", actorURI)
+ federationHost, err := GetFederationHostForURI(ctx, actorURI)
+ if err != nil {
+ return http.StatusInternalServerError, "Wrong FederationHost", err
+ }
+ if !activity.IsNewer(federationHost.LatestActivity) {
+ return http.StatusNotAcceptable, "Activity out of order.", fmt.Errorf("Activity already processed")
+ }
+ actorID, err := fm.NewPersonID(actorURI, string(federationHost.NodeInfo.SoftwareName))
+ if err != nil {
+ return http.StatusNotAcceptable, "Invalid PersonID", err
+ }
+ log.Info("Actor accepted:%v", actorID)
+
+ // parse objectID (repository)
+ objectID, err := fm.NewRepositoryID(activity.Object.GetID().String(), string(forgefed.ForgejoSourceType))
+ if err != nil {
+ return http.StatusNotAcceptable, "Invalid objectId", err
+ }
+ if objectID.ID != fmt.Sprint(repositoryID) {
+ return http.StatusNotAcceptable, "Invalid objectId", err
+ }
+ log.Info("Object accepted:%v", objectID)
+
+ // Check if user already exists
+ user, _, err := user.FindFederatedUser(ctx, actorID.ID, federationHost.ID)
+ if err != nil {
+ return http.StatusInternalServerError, "Searching for user failed", err
+ }
+ if user != nil {
+ log.Info("Found local federatedUser: %v", user)
+ } else {
+ user, _, err = CreateUserFromAP(ctx, actorID, federationHost.ID)
+ if err != nil {
+ return http.StatusInternalServerError, "Error creating federatedUser", err
+ }
+ log.Info("Created federatedUser from ap: %v", user)
+ }
+ log.Info("Got user:%v", user.Name)
+
+ // execute the activity if the repo was not stared already
+ alreadyStared := repo.IsStaring(ctx, user.ID, repositoryID)
+ if !alreadyStared {
+ err = repo.StarRepo(ctx, user.ID, repositoryID, true)
+ if err != nil {
+ return http.StatusNotAcceptable, "Error staring", err
+ }
+ }
+ federationHost.LatestActivity = activity.StartTime
+ err = forgefed.UpdateFederationHost(ctx, federationHost)
+ if err != nil {
+ return http.StatusNotAcceptable, "Error updating federatedHost", err
+ }
+
+ return 0, "", nil
}
-func FindOrCreateFederationHost(ctx context.Context, actorURI string) (*forgefed.FederationHost, error) {
+func CreateFederationHostFromAP(ctx context.Context, actorID fm.ActorID) (*forgefed.FederationHost, error) {
+ actionsUser := user.NewActionsUser()
+ clientFactory, err := activitypub.GetClientFactory(ctx)
+ if err != nil {
+ return nil, err
+ }
+ client, err := clientFactory.WithKeys(ctx, actionsUser, "no idea where to get key material.")
+ if err != nil {
+ return nil, err
+ }
+ body, err := client.GetBody(actorID.AsWellKnownNodeInfoURI())
+ if err != nil {
+ return nil, err
+ }
+ nodeInfoWellKnown, err := forgefed.NewNodeInfoWellKnown(body)
+ if err != nil {
+ return nil, err
+ }
+ body, err = client.GetBody(nodeInfoWellKnown.Href)
+ if err != nil {
+ return nil, err
+ }
+ nodeInfo, err := forgefed.NewNodeInfo(body)
+ if err != nil {
+ return nil, err
+ }
+ result, err := forgefed.NewFederationHost(nodeInfo, actorID.Host)
+ if err != nil {
+ return nil, err
+ }
+ err = forgefed.CreateFederationHost(ctx, &result)
+ if err != nil {
+ return nil, err
+ }
+ return &result, nil
+}
+
+func GetFederationHostForURI(ctx context.Context, actorURI string) (*forgefed.FederationHost, error) {
+ log.Info("Input was: %v", actorURI)
rawActorID, err := fm.NewActorID(actorURI)
if err != nil {
return nil, err
}
- federationHost, err := forgefed.FindFederationHostByFqdnAndPort(ctx, rawActorID.Host, rawActorID.HostPort)
+ federationHost, err := forgefed.FindFederationHostByFqdn(ctx, rawActorID.Host)
if err != nil {
return nil, err
}
if federationHost == nil {
- result, err := createFederationHostFromAP(ctx, rawActorID)
+ result, err := CreateFederationHostFromAP(ctx, rawActorID)
if err != nil {
return nil, err
}
@@ -48,109 +154,19 @@ func FindOrCreateFederationHost(ctx context.Context, actorURI string) (*forgefed
return federationHost, nil
}
-func FindOrCreateFederatedUser(ctx context.Context, actorURI string) (*user.User, *user.FederatedUser, *forgefed.FederationHost, error) {
- user, federatedUser, federationHost, err := findFederatedUser(ctx, actorURI)
- if err != nil {
- return nil, nil, nil, err
- }
- personID, err := fm.NewPersonID(actorURI, string(federationHost.NodeInfo.SoftwareName))
- if err != nil {
- return nil, nil, nil, err
- }
-
- if user != nil {
- log.Trace("Local ActivityPub user found (actorURI: %#v, user: %#v)", actorURI, user)
- } else {
- log.Trace("Attempting to create new user and federatedUser for actorURI: %#v", actorURI)
- user, federatedUser, err = createUserFromAP(ctx, personID, federationHost.ID)
- if err != nil {
- return nil, nil, nil, err
- }
- log.Trace("Created user %#v with federatedUser %#v from distant server", user, federatedUser)
- }
- log.Trace("Got user: %v", user.Name)
-
- return user, federatedUser, federationHost, nil
-}
-
-func findFederatedUser(ctx context.Context, actorURI string) (*user.User, *user.FederatedUser, *forgefed.FederationHost, error) {
- federationHost, err := FindOrCreateFederationHost(ctx, actorURI)
- if err != nil {
- return nil, nil, nil, err
- }
- actorID, err := fm.NewPersonID(actorURI, string(federationHost.NodeInfo.SoftwareName))
- if err != nil {
- return nil, nil, nil, err
- }
-
- user, federatedUser, err := user.FindFederatedUser(ctx, actorID.ID, federationHost.ID)
- if err != nil {
- return nil, nil, nil, err
- }
-
- return user, federatedUser, federationHost, nil
-}
-
-func createFederationHostFromAP(ctx context.Context, actorID fm.ActorID) (*forgefed.FederationHost, error) {
- actionsUser := user.NewAPServerActor()
-
- clientFactory, err := activitypub.GetClientFactory(ctx)
- if err != nil {
- return nil, err
- }
-
- client, err := clientFactory.WithKeys(ctx, actionsUser, actionsUser.KeyID())
- if err != nil {
- return nil, err
- }
-
- body, err := client.GetBody(actorID.AsWellKnownNodeInfoURI())
- if err != nil {
- return nil, err
- }
-
- nodeInfoWellKnown, err := forgefed.NewNodeInfoWellKnown(body)
- if err != nil {
- return nil, err
- }
-
- body, err = client.GetBody(nodeInfoWellKnown.Href)
- if err != nil {
- return nil, err
- }
-
- nodeInfo, err := forgefed.NewNodeInfo(body)
- if err != nil {
- return nil, err
- }
-
- // TODO: we should get key material here also to have it immediately
- result, err := forgefed.NewFederationHost(actorID.Host, nodeInfo, actorID.HostPort, actorID.HostSchema)
- if err != nil {
- return nil, err
- }
-
- err = forgefed.CreateFederationHost(ctx, &result)
- if err != nil {
- return nil, err
- }
-
- return &result, nil
-}
-
-func fetchUserFromAP(ctx context.Context, personID fm.PersonID, federationHostID int64) (*user.User, *user.FederatedUser, error) {
- actionsUser := user.NewAPServerActor()
+func CreateUserFromAP(ctx context.Context, personID fm.PersonID, federationHostID int64) (*user.User, *user.FederatedUser, error) {
+ // ToDo: Do we get a publicKeyId from server, repo or owner or repo?
+ actionsUser := user.NewActionsUser()
clientFactory, err := activitypub.GetClientFactory(ctx)
if err != nil {
return nil, nil, err
}
-
- apClient, err := clientFactory.WithKeys(ctx, actionsUser, actionsUser.KeyID())
+ client, err := clientFactory.WithKeys(ctx, actionsUser, "no idea where to get key material.")
if err != nil {
return nil, nil, err
}
- body, err := apClient.GetBody(personID.AsURI())
+ body, err := client.GetBody(personID.AsURI())
if err != nil {
return nil, nil, err
}
@@ -160,42 +176,26 @@ func fetchUserFromAP(ctx context.Context, personID fm.PersonID, federationHostID
if err != nil {
return nil, nil, err
}
-
if res, err := validation.IsValid(person); !res {
return nil, nil, err
}
-
- log.Info("Fetched valid person from distant server: %q", person)
+ log.Info("Fetched valid person:%q", person)
localFqdn, err := url.ParseRequestURI(setting.AppURL)
if err != nil {
return nil, nil, err
}
-
email := fmt.Sprintf("f%v@%v", uuid.New().String(), localFqdn.Hostname())
loginName := personID.AsLoginName()
name := fmt.Sprintf("%v%v", person.PreferredUsername.String(), personID.HostSuffix())
fullName := person.Name.String()
-
if len(person.Name) == 0 {
fullName = name
}
-
password, err := password.Generate(32)
if err != nil {
return nil, nil, err
}
-
- inbox, err := url.ParseRequestURI(person.Inbox.GetLink().String())
- if err != nil {
- return nil, nil, err
- }
-
- pubKeyBytes, err := decodePublicKeyPem(person.PublicKey.PublicKeyPem)
- if err != nil {
- return nil, nil, err
- }
-
newUser := user.User{
LowerName: strings.ToLower(name),
Name: name,
@@ -207,37 +207,89 @@ func fetchUserFromAP(ctx context.Context, personID fm.PersonID, federationHostID
LoginName: loginName,
Type: user.UserTypeRemoteUser,
IsAdmin: false,
+ NormalizedFederatedURI: personID.AsURI(),
}
-
federatedUser := user.FederatedUser{
- ExternalID: personID.ID,
- FederationHostID: federationHostID,
- InboxPath: inbox.Path,
- NormalizedOriginalURL: personID.AsURI(),
- KeyID: sql.NullString{
- String: person.PublicKey.ID.String(),
- Valid: true,
- },
- PublicKey: sql.Null[sql.RawBytes]{
- V: pubKeyBytes,
- Valid: true,
- },
+ ExternalID: personID.ID,
+ FederationHostID: federationHostID,
}
+ err = user.CreateFederatedUser(ctx, &newUser, &federatedUser)
+ if err != nil {
+ return nil, nil, err
+ }
+ log.Info("Created federatedUser:%q", federatedUser)
- log.Info("Fetched person's %q federatedUser from distant server: %q", person, federatedUser)
return &newUser, &federatedUser, nil
}
-func createUserFromAP(ctx context.Context, personID fm.PersonID, federationHostID int64) (*user.User, *user.FederatedUser, error) {
- newUser, federatedUser, err := fetchUserFromAP(ctx, personID, federationHostID)
- if err != nil {
- return nil, nil, err
- }
- err = user.CreateFederatedUser(ctx, newUser, federatedUser)
- if err != nil {
- return nil, nil, err
+// Create or update a list of FollowingRepo structs
+func StoreFollowingRepoList(ctx context.Context, localRepoID int64, followingRepoList []string) (int, string, error) {
+ followingRepos := make([]*repo.FollowingRepo, 0, len(followingRepoList))
+ for _, uri := range followingRepoList {
+ federationHost, err := GetFederationHostForURI(ctx, uri)
+ if err != nil {
+ return http.StatusInternalServerError, "Wrong FederationHost", err
+ }
+ followingRepoID, err := fm.NewRepositoryID(uri, string(federationHost.NodeInfo.SoftwareName))
+ if err != nil {
+ return http.StatusNotAcceptable, "Invalid federated repo", err
+ }
+ followingRepo, err := repo.NewFollowingRepo(localRepoID, followingRepoID.ID, federationHost.ID, uri)
+ if err != nil {
+ return http.StatusNotAcceptable, "Invalid federated repo", err
+ }
+ followingRepos = append(followingRepos, &followingRepo)
}
- log.Info("Created federatedUser: %q", federatedUser)
- return newUser, federatedUser, nil
+ if err := repo.StoreFollowingRepos(ctx, localRepoID, followingRepos); err != nil {
+ return 0, "", err
+ }
+
+ return 0, "", nil
+}
+
+func DeleteFollowingRepos(ctx context.Context, localRepoID int64) error {
+ return repo.StoreFollowingRepos(ctx, localRepoID, []*repo.FollowingRepo{})
+}
+
+func SendLikeActivities(ctx context.Context, doer user.User, repoID int64) error {
+ followingRepos, err := repo.FindFollowingReposByRepoID(ctx, repoID)
+ log.Info("Federated Repos is: %v", followingRepos)
+ if err != nil {
+ return err
+ }
+
+ likeActivityList := make([]fm.ForgeLike, 0)
+ for _, followingRepo := range followingRepos {
+ log.Info("Found following repo: %v", followingRepo)
+ target := followingRepo.URI
+ likeActivity, err := fm.NewForgeLike(doer.APActorID(), target, time.Now())
+ if err != nil {
+ return err
+ }
+ likeActivityList = append(likeActivityList, likeActivity)
+ }
+
+ apclientFactory, err := activitypub.GetClientFactory(ctx)
+ if err != nil {
+ return err
+ }
+ apclient, err := apclientFactory.WithKeys(ctx, &doer, doer.APActorID())
+ if err != nil {
+ return err
+ }
+ for i, activity := range likeActivityList {
+ activity.StartTime = activity.StartTime.Add(time.Duration(i) * time.Second)
+ json, err := activity.MarshalJSON()
+ if err != nil {
+ return err
+ }
+
+ _, err = apclient.Post(json, fmt.Sprintf("%v/inbox/", activity.Object))
+ if err != nil {
+ log.Error("error %v while sending activity: %q", err, activity)
+ }
+ }
+
+ return nil
}
diff --git a/services/federation/person_inbox_accept.go b/services/federation/person_inbox_accept.go
deleted file mode 100644
index d0a840bd2d..0000000000
--- a/services/federation/person_inbox_accept.go
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2024 The Forgejo Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package federation
-
-import (
- "net/http"
-
- "forgejo.org/modules/log"
-
- ap "github.com/go-ap/activitypub"
-)
-
-func processPersonInboxAccept(activity *ap.Activity) (ServiceResult, error) {
- if activity.Object.GetType() != ap.FollowType {
- log.Error("Invalid object type for Accept activity: %v", activity.Object.GetType())
- return ServiceResult{}, NewErrNotAcceptablef("invalid object type for Accept activity: %v", activity.Object.GetType())
- }
-
- // We currently do not do anything here, we just drop it.
- return NewServiceResultStatusOnly(http.StatusNoContent), nil
-}
diff --git a/services/federation/person_inbox_create.go b/services/federation/person_inbox_create.go
deleted file mode 100644
index 2132c7ede1..0000000000
--- a/services/federation/person_inbox_create.go
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2024 The Forgejo Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package federation
-
-import (
- "context"
- "net/http"
-
- "forgejo.org/models/activities"
- "forgejo.org/models/user"
- fm "forgejo.org/modules/forgefed"
- "forgejo.org/modules/log"
-
- ap "github.com/go-ap/activitypub"
-)
-
-func processPersonInboxCreate(ctx context.Context, user *user.User, activity *ap.Activity) (ServiceResult, error) {
- createAct, err := fm.NewForgeUserActivityFromAp(*activity)
- if err != nil {
- log.Error("Invalid user activity: %v, %v", activity, err)
- return ServiceResult{}, NewErrNotAcceptablef("Invalid user activity: %v", err)
- }
-
- actorURI := createAct.Actor.GetLink().String()
- federatedBaseUser, _, _, err := findFederatedUser(ctx, actorURI)
- if err != nil {
- log.Error("Federated user not found (%s): %v", actorURI, err)
- return ServiceResult{}, NewErrNotAcceptablef("federated user not found (%s): %v", actorURI, err)
- }
- if federatedBaseUser == nil {
- log.Error("Federated user not found (%s): %v", actorURI, err)
- return ServiceResult{}, NewErrNotAcceptablef("federated user not found (%s): %v", actorURI, err)
- }
-
- federatedUserActivity, err := activities.NewFederatedUserActivity(
- user.ID,
- federatedBaseUser.ID,
- createAct.Actor.GetLink().String(),
- createAct.Note.Content.String(),
- createAct.Note.URL.GetID().String(),
- *activity,
- )
- if err != nil {
- log.Error("Error creating federatedUserActivity (%s): %v", actorURI, err)
- return ServiceResult{}, NewErrNotAcceptablef("Error creating federatedUserActivity: %v", err)
- }
-
- if err := activities.CreateUserActivity(ctx, &federatedUserActivity); err != nil {
- log.Error("Unable to record activity: %v", err)
- return ServiceResult{}, NewErrNotAcceptablef("Unable to record activity: %v", err)
- }
-
- return NewServiceResultStatusOnly(http.StatusNoContent), nil
-}
diff --git a/services/federation/person_inbox_follow.go b/services/federation/person_inbox_follow.go
deleted file mode 100644
index baa7934ad5..0000000000
--- a/services/federation/person_inbox_follow.go
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2024 The Forgejo Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package federation
-
-import (
- "context"
- "fmt"
- "net/http"
-
- "forgejo.org/models/user"
- "forgejo.org/modules/forgefed"
- "forgejo.org/modules/log"
-
- ap "github.com/go-ap/activitypub"
- "github.com/go-ap/jsonld"
-)
-
-func processPersonFollow(ctx context.Context, ctxUser *user.User, activity *ap.Activity) (ServiceResult, error) {
- follow, err := forgefed.NewForgeFollowFromAp(*activity)
- if err != nil {
- log.Error("Invalid follow activity: %s", err)
- return ServiceResult{}, NewErrNotAcceptablef("Invalid follow activity: %v", err)
- }
-
- actorURI := follow.Actor.GetLink().String()
- _, federatedUser, federationHost, err := FindOrCreateFederatedUser(ctx, actorURI)
- if err != nil {
- log.Error("Error finding or creating federated user (%s): %v", actorURI, err)
- return ServiceResult{}, NewErrNotAcceptablef("Federated user not found: %v", err)
- }
-
- following, err := user.IsFollowingAp(ctx, ctxUser, federatedUser)
- if err != nil {
- log.Error("forgefed.IsFollowing: %v", err)
- return ServiceResult{}, NewErrNotAcceptablef("forgefed.IsFollowing: %v", err)
- }
- if following {
- // If the user is already following, we're good, nothing to do.
- log.Trace("Local user[%d] is already following federated user[%d]", ctxUser.ID, federatedUser.ID)
- return NewServiceResultStatusOnly(http.StatusNoContent), nil
- }
-
- follower, err := user.AddFollower(ctx, ctxUser, federatedUser)
- if err != nil {
- log.Error("Unable to add follower: %v", err)
- return ServiceResult{}, NewErrNotAcceptablef("Unable to add follower: %v", err)
- }
-
- accept := ap.AcceptNew(ap.IRI(fmt.Sprintf(
- "%s#accepts/follow/%d", ctxUser.APActorID(), follower.ID,
- )), follow)
- accept.Actor = ap.IRI(ctxUser.APActorID())
- payload, err := jsonld.WithContext(jsonld.IRI(ap.ActivityBaseURI)).Marshal(accept)
- if err != nil {
- log.Error("Unable to Marshal JSON: %v", err)
- return ServiceResult{}, NewErrInternalf("MarshalJSON: %v", err)
- }
-
- hostURL := federationHost.AsURL()
- if err := deliveryQueue.Push(deliveryQueueItem{
- InboxURL: hostURL.JoinPath(federatedUser.InboxPath).String(),
- Doer: ctxUser,
- Payload: payload,
- }); err != nil {
- log.Error("Unable to push to pending queue: %v", err)
- return ServiceResult{}, NewErrInternalf("Unable to push to pending queue: %v", err)
- }
-
- // Respond back with an accept
- result := NewServiceResultWithBytes(http.StatusAccepted, []byte(`{"status":"Accepted"}`))
- return result, nil
-}
diff --git a/services/federation/person_inbox_undo.go b/services/federation/person_inbox_undo.go
deleted file mode 100644
index 4379cf242a..0000000000
--- a/services/federation/person_inbox_undo.go
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2024 The Forgejo Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package federation
-
-import (
- "context"
- "net/http"
-
- "forgejo.org/models/user"
- "forgejo.org/modules/log"
-
- ap "github.com/go-ap/activitypub"
-)
-
-func processPersonInboxUndo(ctx context.Context, ctxUser *user.User, activity *ap.Activity) (ServiceResult, error) {
- if activity.Object.GetType() != ap.FollowType {
- log.Error("Invalid object type for Undo activity: %v", activity.Object.GetType())
- return ServiceResult{}, NewErrNotAcceptablef("Invalid object type for Undo activity: %v", activity.Object.GetType())
- }
-
- actorURI := activity.Actor.GetLink().String()
- _, federatedUser, _, err := findFederatedUser(ctx, actorURI)
- if err != nil {
- log.Error("User not found: %v", err)
- return ServiceResult{}, NewErrInternalf("User not found: %v", err)
- }
-
- if federatedUser != nil {
- following, err := user.IsFollowingAp(ctx, ctxUser, federatedUser)
- if err != nil {
- log.Error("forgefed.IsFollowing: %v", err)
- return ServiceResult{}, NewErrInternalf("forgefed.IsFollowing: %v", err)
- }
- if !following {
- // The local user is not following the federated one, nothing to do.
- log.Trace("Local user[%d] is not following federated user[%d]", ctxUser.ID, federatedUser.ID)
- return NewServiceResultStatusOnly(http.StatusNoContent), nil
- }
- if err := user.RemoveFollower(ctx, ctxUser, federatedUser); err != nil {
- log.Error("Unable to remove follower", err)
- return ServiceResult{}, NewErrInternalf("Unable to remove follower: %v", err)
- }
- }
-
- return NewServiceResultStatusOnly(http.StatusNoContent), nil
-}
diff --git a/services/federation/person_service.go b/services/federation/person_service.go
deleted file mode 100644
index d6482d013c..0000000000
--- a/services/federation/person_service.go
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2024 The Forgejo Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package federation
-
-import (
- "context"
- "net/http"
-
- "forgejo.org/models/user"
- "forgejo.org/modules/forgefed"
- "forgejo.org/modules/log"
- context_service "forgejo.org/services/context"
-
- ap "github.com/go-ap/activitypub"
- "github.com/go-ap/jsonld"
-)
-
-func ProcessPersonInbox(ctx context.Context, user *user.User, activity *ap.Activity) (ServiceResult, error) {
- switch activity.Type {
- case ap.CreateType:
- return processPersonInboxCreate(ctx, user, activity)
- case ap.FollowType:
- return processPersonFollow(ctx, user, activity)
- case ap.UndoType:
- return processPersonInboxUndo(ctx, user, activity)
- case ap.AcceptType:
- return processPersonInboxAccept(activity)
- }
-
- log.Error("Unsupported PersonInbox activity: %v", activity.Type)
- return ServiceResult{}, NewErrNotAcceptablef("unsupported activity: %v", activity.Type)
-}
-
-func FollowRemoteActor(ctx *context_service.APIContext, localUser *user.User, actorURI string) error {
- _, federatedUser, federationHost, err := FindOrCreateFederatedUser(ctx.Base, actorURI)
- if err != nil {
- log.Error("Federated user not found (%s): %v", actorURI, err)
- ctx.Error(http.StatusNotAcceptable, "Federated user not found", err)
- return err
- }
-
- followReq, err := forgefed.NewForgeFollow(localUser.APActorID(), actorURI)
- if err != nil {
- return err
- }
-
- payload, err := jsonld.WithContext(jsonld.IRI(ap.ActivityBaseURI)).
- Marshal(followReq)
- if err != nil {
- return err
- }
-
- hostURL := federationHost.AsURL()
- return deliveryQueue.Push(deliveryQueueItem{
- InboxURL: hostURL.JoinPath(federatedUser.InboxPath).String(),
- Doer: localUser,
- Payload: payload,
- })
-}
diff --git a/services/federation/repository_inbox_like.go b/services/federation/repository_inbox_like.go
deleted file mode 100644
index 478a12d92c..0000000000
--- a/services/federation/repository_inbox_like.go
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright 2024 The Forgejo Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package federation
-
-import (
- "context"
- "fmt"
- "net/http"
- "time"
-
- "forgejo.org/models/forgefed"
- "forgejo.org/models/repo"
- "forgejo.org/models/user"
- "forgejo.org/modules/activitypub"
- fm "forgejo.org/modules/forgefed"
- "forgejo.org/modules/log"
- "forgejo.org/modules/validation"
- context_service "forgejo.org/services/context"
-
- ap "github.com/go-ap/activitypub"
-)
-
-// ProcessLikeActivity receives a ForgeLike activity and does the following:
-// Validation of the activity
-// Creation of a (remote) federationHost if not existing
-// Creation of a forgefed Person if not existing
-// Validation of incoming RepositoryID against Local RepositoryID
-// Star the repo if it wasn't already stared
-// Do some mitigation against out of order attacks
-func ProcessLikeActivity(ctx context.Context, activity *ap.Activity, repositoryID int64) (ServiceResult, error) {
- constructorLikeActivity, _ := fm.NewForgeLike(activity.Actor.GetLink().String(), activity.Object.GetLink().String(), activity.StartTime)
- if res, err := validation.IsValid(constructorLikeActivity); !res {
- return ServiceResult{}, NewErrNotAcceptablef("Invalid activity: %v", err)
- }
- log.Trace("Activity validated: %#v", activity)
-
- // parse actorID (person)
- actorURI := activity.Actor.GetID().String()
- user, _, federationHost, err := FindOrCreateFederatedUser(ctx, actorURI)
- if err != nil {
- log.Error("Federated user not found (%s): %v", actorURI, err)
- return ServiceResult{}, NewErrNotAcceptablef("FindOrCreateFederatedUser failed: %v", err)
- }
-
- if !constructorLikeActivity.IsNewer(federationHost.LatestActivity) {
- return ServiceResult{}, NewErrNotAcceptablef("LatestActivity: activity already processed: %v", err)
- }
-
- // parse objectID (repository)
- objectID, err := fm.NewRepositoryID(constructorLikeActivity.Object.GetID().String(), string(forgefed.ForgejoSourceType))
- if err != nil {
- return ServiceResult{}, NewErrNotAcceptablef("Parsing repo objectID failed: %v", err)
- }
- if objectID.ID != fmt.Sprint(repositoryID) {
- return ServiceResult{}, NewErrNotAcceptablef("Invalid repoId: %v", err)
- }
- log.Trace("Object accepted: %#v", objectID)
-
- // execute the activity if the repo was not stared already
- alreadyStared := repo.IsStaring(ctx, user.ID, repositoryID)
- if !alreadyStared {
- err = repo.StarRepo(ctx, user.ID, repositoryID, true)
- if err != nil {
- return ServiceResult{}, NewErrNotAcceptablef("Staring failed: %v", err)
- }
- }
- federationHost.LatestActivity = activity.StartTime
- err = forgefed.UpdateFederationHost(ctx, federationHost)
- if err != nil {
- return ServiceResult{}, NewErrNotAcceptablef("Updating federatedHost failed: %v", err)
- }
-
- return NewServiceResultStatusOnly(http.StatusNoContent), nil
-}
-
-// Create or update a list of FollowingRepo structs
-func StoreFollowingRepoList(ctx *context_service.Context, localRepoID int64, followingRepoList []string) (int, string, error) {
- followingRepos := make([]*repo.FollowingRepo, 0, len(followingRepoList))
- for _, uri := range followingRepoList {
- federationHost, err := FindOrCreateFederationHost(ctx.Base, uri)
- if err != nil {
- return http.StatusInternalServerError, "Wrong FederationHost", err
- }
- followingRepoID, err := fm.NewRepositoryID(uri, string(federationHost.NodeInfo.SoftwareName))
- if err != nil {
- return http.StatusNotAcceptable, "Invalid federated repo", err
- }
- followingRepo, err := repo.NewFollowingRepo(localRepoID, followingRepoID.ID, federationHost.ID, uri)
- if err != nil {
- return http.StatusNotAcceptable, "Invalid federated repo", err
- }
- followingRepos = append(followingRepos, &followingRepo)
- }
-
- if err := repo.StoreFollowingRepos(ctx, localRepoID, followingRepos); err != nil {
- return 0, "", err
- }
-
- return 0, "", nil
-}
-
-func DeleteFollowingRepos(ctx context.Context, localRepoID int64) error {
- return repo.StoreFollowingRepos(ctx, localRepoID, []*repo.FollowingRepo{})
-}
-
-func SendLikeActivities(ctx context.Context, doer user.User, repoID int64) error {
- followingRepos, err := repo.FindFollowingReposByRepoID(ctx, repoID)
- log.Trace("Federated Repos is: %#v", followingRepos)
- if err != nil {
- return err
- }
-
- likeActivityList := make([]fm.ForgeLike, 0)
- for _, followingRepo := range followingRepos {
- log.Trace("Found following repo: %#v", followingRepo)
- target := followingRepo.URI
- likeActivity, err := fm.NewForgeLike(doer.APActorID(), target, time.Now())
- if err != nil {
- return err
- }
- likeActivityList = append(likeActivityList, likeActivity)
- }
-
- apclientFactory, err := activitypub.GetClientFactory(ctx)
- if err != nil {
- return err
- }
- apclient, err := apclientFactory.WithKeys(ctx, &doer, doer.APActorID()+"#main-key")
- if err != nil {
- return err
- }
- for i, activity := range likeActivityList {
- activity.StartTime = activity.StartTime.Add(time.Duration(i) * time.Second)
- json, err := activity.MarshalJSON()
- if err != nil {
- return err
- }
-
- _, err = apclient.Post(json, fmt.Sprintf("%v/inbox", activity.Object))
- if err != nil {
- log.Error("error %v while sending activity: %#v", err, activity)
- }
- }
-
- return nil
-}
diff --git a/services/federation/repository_service.go b/services/federation/repository_service.go
deleted file mode 100644
index 7891d786e2..0000000000
--- a/services/federation/repository_service.go
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2025 The Forgejo Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package federation
-
-import (
- "context"
-
- ap "github.com/go-ap/activitypub"
-)
-
-func ProcessRepositoryInbox(ctx context.Context, activity *ap.Activity, repositoryID int64) (ServiceResult, error) {
- switch activity.Type {
- case ap.LikeType:
- return ProcessLikeActivity(ctx, activity, repositoryID)
- default:
- return ServiceResult{}, NewErrNotAcceptablef("Not a like activity: %v", activity.Type)
- }
-}
diff --git a/services/federation/result.go b/services/federation/result.go
deleted file mode 100644
index 47afb2bdf6..0000000000
--- a/services/federation/result.go
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2025 The Forgejo Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package federation
-
-import "github.com/go-ap/activitypub"
-
-type ServiceResult struct {
- HTTPStatus int
- Bytes []byte
- Activity activitypub.Activity
- withBytes bool
- withActivity bool
- statusOnly bool
-}
-
-func NewServiceResultStatusOnly(status int) ServiceResult {
- return ServiceResult{HTTPStatus: status, statusOnly: true}
-}
-
-func NewServiceResultWithBytes(status int, bytes []byte) ServiceResult {
- return ServiceResult{HTTPStatus: status, Bytes: bytes, withBytes: true}
-}
-
-func (serviceResult ServiceResult) WithBytes() bool {
- return serviceResult.withBytes
-}
-
-func (serviceResult ServiceResult) WithActivity() bool {
- return serviceResult.withActivity
-}
-
-func (serviceResult ServiceResult) StatusOnly() bool {
- return serviceResult.statusOnly
-}
diff --git a/services/federation/signature_service.go b/services/federation/signature_service.go
deleted file mode 100644
index fd8cbb39cd..0000000000
--- a/services/federation/signature_service.go
+++ /dev/null
@@ -1,235 +0,0 @@
-// Copyright 2024, 2025 The Forgejo Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package federation
-
-import (
- "context"
- "crypto/x509"
- "database/sql"
- "encoding/pem"
- "errors"
- "fmt"
- "net/url"
-
- "forgejo.org/models/forgefed"
- "forgejo.org/models/user"
- "forgejo.org/modules/activitypub"
- fm "forgejo.org/modules/forgefed"
-
- ap "github.com/go-ap/activitypub"
-)
-
-// Factory function for ActorID. Created struct is asserted to be valid
-func NewActorIDFromKeyID(ctx context.Context, uri string) (fm.ActorID, error) {
- parsedURI, err := url.Parse(uri)
- parsedURI.Fragment = ""
- if err != nil {
- return fm.ActorID{}, err
- }
-
- actionsUser := user.NewAPServerActor()
- clientFactory, err := activitypub.GetClientFactory(ctx)
- if err != nil {
- return fm.ActorID{}, err
- }
-
- apClient, err := clientFactory.WithKeys(ctx, actionsUser, actionsUser.KeyID())
- if err != nil {
- return fm.ActorID{}, err
- }
-
- userResponse, err := apClient.GetBody(parsedURI.String())
- if err != nil {
- return fm.ActorID{}, err
- }
-
- var actor ap.Actor
- err = actor.UnmarshalJSON(userResponse)
- if err != nil {
- return fm.ActorID{}, err
- }
-
- result, err := fm.NewActorID(actor.PublicKey.Owner.String())
- return result, err
-}
-
-func FindOrCreateFederatedUserKey(ctx context.Context, keyID string) (pubKey any, err error) {
- var federatedUser *user.FederatedUser
- var keyURL *url.URL
-
- keyURL, err = url.Parse(keyID)
- if err != nil {
- return nil, err
- }
-
- // Try if the signing actor is an already known federated user
- _, federatedUser, err = user.FindFederatedUserByKeyID(ctx, keyURL.String())
- if err != nil {
- return nil, err
- }
-
- if federatedUser == nil {
- rawActorID, err := NewActorIDFromKeyID(ctx, keyID)
- if err != nil {
- return nil, err
- }
-
- _, federatedUser, _, err = FindOrCreateFederatedUser(ctx, rawActorID.AsURI())
- if err != nil {
- return nil, err
- }
- } else {
- _, err = forgefed.GetFederationHost(ctx, federatedUser.FederationHostID)
- if err != nil {
- return nil, err
- }
- }
-
- if federatedUser.PublicKey.Valid {
- pubKey, err := x509.ParsePKIXPublicKey(federatedUser.PublicKey.V)
- if err != nil {
- return nil, err
- }
- return pubKey, nil
- }
-
- // Fetch missing public key
- pubKey, pubKeyBytes, apPerson, err := fetchKeyFromAp(ctx, *keyURL)
- if err != nil {
- return nil, err
- }
- if apPerson.Type == ap.ActivityVocabularyType("Person") {
- // Check federatedUser.id = person.id
- if federatedUser.ExternalID != apPerson.ID.String() {
- return nil, fmt.Errorf("federated user fetched (%v) does not match the stored one %v", apPerson, federatedUser)
- }
- // update federated user
- federatedUser.KeyID = sql.NullString{
- String: apPerson.PublicKey.ID.String(),
- Valid: true,
- }
- federatedUser.PublicKey = sql.Null[sql.RawBytes]{
- V: pubKeyBytes,
- Valid: true,
- }
- err = user.UpdateFederatedUser(ctx, federatedUser)
- if err != nil {
- return nil, err
- }
- return pubKey, nil
- }
- return nil, nil
-}
-
-func FindOrCreateFederationHostKey(ctx context.Context, keyID string) (pubKey any, err error) {
- keyURL, err := url.Parse(keyID)
- if err != nil {
- return nil, err
- }
- rawActorID, err := NewActorIDFromKeyID(ctx, keyID)
- if err != nil {
- return nil, err
- }
-
- // Is there an already known federation host?
- federationHost, err := forgefed.FindFederationHostByKeyID(ctx, keyURL.String())
- if err != nil {
- return nil, err
- }
-
- if federationHost == nil {
- federationHost, err = FindOrCreateFederationHost(ctx, rawActorID.AsURI())
- if err != nil {
- return nil, err
- }
- }
-
- // Is there an already an key?
- if federationHost.PublicKey.Valid {
- pubKey, err := x509.ParsePKIXPublicKey(federationHost.PublicKey.V)
- if err != nil {
- return nil, err
- }
- return pubKey, nil
- }
-
- // If not, fetch missing public key
- pubKey, pubKeyBytes, apPerson, err := fetchKeyFromAp(ctx, *keyURL)
- if err != nil {
- return nil, err
- }
- if apPerson.Type == ap.ActivityVocabularyType("Application") {
- // Check federationhost.id = person.id
- if federationHost.HostPort != rawActorID.HostPort || federationHost.HostFqdn != rawActorID.Host ||
- federationHost.HostSchema != rawActorID.HostSchema {
- return nil, fmt.Errorf("federation host fetched (%v) does not match the stored one %v", apPerson, federationHost)
- }
- // update federation host
- federationHost.KeyID = sql.NullString{
- String: apPerson.PublicKey.ID.String(),
- Valid: true,
- }
- federationHost.PublicKey = sql.Null[sql.RawBytes]{
- V: pubKeyBytes,
- Valid: true,
- }
- err = forgefed.UpdateFederationHost(ctx, federationHost)
- if err != nil {
- return nil, err
- }
- return pubKey, nil
- }
- return nil, nil
-}
-
-func fetchKeyFromAp(ctx context.Context, keyURL url.URL) (pubKey any, pubKeyBytes []byte, apPerson *ap.Person, err error) {
- actionsUser := user.NewAPServerActor()
-
- clientFactory, err := activitypub.GetClientFactory(ctx)
- if err != nil {
- return nil, nil, nil, err
- }
-
- apClient, err := clientFactory.WithKeys(ctx, actionsUser, actionsUser.KeyID())
- if err != nil {
- return nil, nil, nil, err
- }
-
- b, err := apClient.GetBody(keyURL.String())
- if err != nil {
- return nil, nil, nil, err
- }
-
- person := ap.PersonNew(ap.IRI(keyURL.String()))
- err = person.UnmarshalJSON(b)
- if err != nil {
- return nil, nil, nil, fmt.Errorf("ActivityStreams type cannot be converted to one known to have publicKey property: %w", err)
- }
-
- pubKeyFromAp := person.PublicKey
- if pubKeyFromAp.ID.String() != keyURL.String() {
- return nil, nil, nil, fmt.Errorf("cannot find publicKey with id: %v in %v", keyURL, string(b))
- }
-
- pubKeyBytes, err = decodePublicKeyPem(pubKeyFromAp.PublicKeyPem)
- if err != nil {
- return nil, nil, nil, err
- }
-
- pubKey, err = x509.ParsePKIXPublicKey(pubKeyBytes)
- if err != nil {
- return nil, nil, nil, err
- }
-
- return pubKey, pubKeyBytes, person, err
-}
-
-func decodePublicKeyPem(pubKeyPem string) ([]byte, error) {
- block, _ := pem.Decode([]byte(pubKeyPem))
- if block == nil || block.Type != "PUBLIC KEY" {
- return nil, errors.New("could not decode publicKeyPem to PUBLIC KEY pem block type")
- }
-
- return block.Bytes, nil
-}
diff --git a/services/federation/user_activity.go b/services/federation/user_activity.go
deleted file mode 100644
index 0db2aee4ec..0000000000
--- a/services/federation/user_activity.go
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2024 The Forgejo Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package federation
-
-import (
- "context"
-
- activities_model "forgejo.org/models/activities"
- "forgejo.org/models/forgefed"
- "forgejo.org/models/user"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/structs"
- "forgejo.org/services/convert"
-
- ap "github.com/go-ap/activitypub"
- "github.com/go-ap/jsonld"
-)
-
-func SendUserActivity(ctx context.Context, doer *user.User, activity *activities_model.Action) error {
- followers, err := user.GetFollowersForUser(ctx, doer)
- if err != nil {
- return err
- }
-
- userActivity, err := convert.ActionToForgeUserActivity(ctx, activity)
- if err != nil {
- return err
- }
-
- payload, err := jsonld.WithContext(
- jsonld.IRI(ap.ActivityBaseURI),
- ).Marshal(userActivity)
- if err != nil {
- return err
- }
-
- for _, follower := range followers {
- _, federatedUserFollower, err := user.GetFederatedUserByUserID(ctx, follower.FollowingUserID)
- if err != nil {
- return err
- }
-
- federationHost, err := forgefed.GetFederationHost(ctx, federatedUserFollower.FederationHostID)
- if err != nil {
- return err
- }
-
- hostURL := federationHost.AsURL()
- if err := deliveryQueue.Push(deliveryQueueItem{
- InboxURL: hostURL.JoinPath(federatedUserFollower.InboxPath).String(),
- Doer: doer,
- Payload: payload,
- }); err != nil {
- return err
- }
- }
-
- return nil
-}
-
-func NotifyActivityPubFollowers(ctx context.Context, actions []activities_model.Action) error {
- if !setting.Federation.Enabled {
- return nil
- }
- for _, act := range actions {
- if act.Repo != nil {
- if act.Repo.IsPrivate {
- continue
- }
- if act.Repo.Owner.KeepActivityPrivate || act.Repo.Owner.Visibility != structs.VisibleTypePublic {
- continue
- }
- }
- if act.ActUser.KeepActivityPrivate || act.ActUser.Visibility != structs.VisibleTypePublic {
- continue
- }
- if err := SendUserActivity(ctx, act.ActUser, &act); err != nil {
- return err
- }
- }
- return nil
-}
diff --git a/services/feed/action.go b/services/feed/action.go
index 96de080691..2d6a6cb09a 100644
--- a/services/feed/action.go
+++ b/services/feed/action.go
@@ -9,18 +9,17 @@ import (
"path"
"strings"
- activities_model "forgejo.org/models/activities"
- issues_model "forgejo.org/models/issues"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/json"
- "forgejo.org/modules/log"
- "forgejo.org/modules/repository"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/util"
- federation_service "forgejo.org/services/federation"
- notify_service "forgejo.org/services/notify"
+ activities_model "code.gitea.io/gitea/models/activities"
+ issues_model "code.gitea.io/gitea/models/issues"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/repository"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/util"
+ notify_service "code.gitea.io/gitea/services/notify"
)
type actionNotifier struct {
@@ -40,22 +39,6 @@ func NewNotifier() notify_service.Notifier {
return &actionNotifier{}
}
-func notifyAll(ctx context.Context, action *activities_model.Action) error {
- out, err := activities_model.NotifyWatchers(ctx, action)
- if err != nil {
- return err
- }
- return federation_service.NotifyActivityPubFollowers(ctx, out)
-}
-
-func notifyAllActions(ctx context.Context, acts []*activities_model.Action) error {
- out, err := activities_model.NotifyWatchersActions(ctx, acts)
- if err != nil {
- return err
- }
- return federation_service.NotifyActivityPubFollowers(ctx, out)
-}
-
func (a *actionNotifier) NewIssue(ctx context.Context, issue *issues_model.Issue, mentions []*user_model.User) {
if err := issue.LoadPoster(ctx); err != nil {
log.Error("issue.LoadPoster: %v", err)
@@ -67,11 +50,11 @@ func (a *actionNotifier) NewIssue(ctx context.Context, issue *issues_model.Issue
}
repo := issue.Repo
- if err := notifyAll(ctx, &activities_model.Action{
+ if err := activities_model.NotifyWatchers(ctx, &activities_model.Action{
ActUserID: issue.Poster.ID,
ActUser: issue.Poster,
OpType: activities_model.ActionCreateIssue,
- Content: encodeContent(fmt.Sprintf("%d", issue.Index), issue.Title),
+ Content: fmt.Sprintf("%d|%s", issue.Index, issue.Title),
RepoID: repo.ID,
Repo: repo,
IsPrivate: repo.IsPrivate,
@@ -87,7 +70,7 @@ func (a *actionNotifier) IssueChangeStatus(ctx context.Context, doer *user_model
act := &activities_model.Action{
ActUserID: doer.ID,
ActUser: doer,
- Content: encodeContent(fmt.Sprintf("%d", issue.Index), ""),
+ Content: fmt.Sprintf("%d|%s", issue.Index, ""),
RepoID: issue.Repo.ID,
Repo: issue.Repo,
Comment: actionComment,
@@ -108,7 +91,7 @@ func (a *actionNotifier) IssueChangeStatus(ctx context.Context, doer *user_model
}
// Notify watchers for whatever action comes in, ignore if no action type.
- if err := notifyAll(ctx, act); err != nil {
+ if err := activities_model.NotifyWatchers(ctx, act); err != nil {
log.Error("NotifyWatchers: %v", err)
}
}
@@ -125,9 +108,18 @@ func (a *actionNotifier) CreateIssueComment(ctx context.Context, doer *user_mode
Comment: comment,
CommentID: comment.ID,
IsPrivate: issue.Repo.IsPrivate,
- Content: encodeContent(fmt.Sprintf("%d", issue.Index), abbreviatedComment(comment.Content)),
}
+ truncatedContent, truncatedRight := util.SplitStringAtByteN(comment.Content, 200)
+ if truncatedRight != "" {
+ // in case the content is in a Latin family language, we remove the last broken word.
+ lastSpaceIdx := strings.LastIndex(truncatedContent, " ")
+ if lastSpaceIdx != -1 && (len(truncatedContent)-lastSpaceIdx < 15) {
+ truncatedContent = truncatedContent[:lastSpaceIdx] + "…"
+ }
+ }
+ act.Content = fmt.Sprintf("%d|%s", issue.Index, truncatedContent)
+
if issue.IsPull {
act.OpType = activities_model.ActionCommentPull
} else {
@@ -135,7 +127,7 @@ func (a *actionNotifier) CreateIssueComment(ctx context.Context, doer *user_mode
}
// Notify watchers for whatever action comes in, ignore if no action type.
- if err := notifyAll(ctx, act); err != nil {
+ if err := activities_model.NotifyWatchers(ctx, act); err != nil {
log.Error("NotifyWatchers: %v", err)
}
}
@@ -154,11 +146,11 @@ func (a *actionNotifier) NewPullRequest(ctx context.Context, pull *issues_model.
return
}
- if err := notifyAll(ctx, &activities_model.Action{
+ if err := activities_model.NotifyWatchers(ctx, &activities_model.Action{
ActUserID: pull.Issue.Poster.ID,
ActUser: pull.Issue.Poster,
OpType: activities_model.ActionCreatePullRequest,
- Content: encodeContent(fmt.Sprintf("%d", pull.Issue.Index), pull.Issue.Title),
+ Content: fmt.Sprintf("%d|%s", pull.Issue.Index, pull.Issue.Title),
RepoID: pull.Issue.Repo.ID,
Repo: pull.Issue.Repo,
IsPrivate: pull.Issue.Repo.IsPrivate,
@@ -168,7 +160,7 @@ func (a *actionNotifier) NewPullRequest(ctx context.Context, pull *issues_model.
}
func (a *actionNotifier) RenameRepository(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, oldRepoName string) {
- if err := notifyAll(ctx, &activities_model.Action{
+ if err := activities_model.NotifyWatchers(ctx, &activities_model.Action{
ActUserID: doer.ID,
ActUser: doer,
OpType: activities_model.ActionRenameRepo,
@@ -182,7 +174,7 @@ func (a *actionNotifier) RenameRepository(ctx context.Context, doer *user_model.
}
func (a *actionNotifier) TransferRepository(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, oldOwnerName string) {
- if err := notifyAll(ctx, &activities_model.Action{
+ if err := activities_model.NotifyWatchers(ctx, &activities_model.Action{
ActUserID: doer.ID,
ActUser: doer,
OpType: activities_model.ActionTransferRepo,
@@ -196,7 +188,7 @@ func (a *actionNotifier) TransferRepository(ctx context.Context, doer *user_mode
}
func (a *actionNotifier) CreateRepository(ctx context.Context, doer, u *user_model.User, repo *repo_model.Repository) {
- if err := notifyAll(ctx, &activities_model.Action{
+ if err := activities_model.NotifyWatchers(ctx, &activities_model.Action{
ActUserID: doer.ID,
ActUser: doer,
OpType: activities_model.ActionCreateRepo,
@@ -209,7 +201,7 @@ func (a *actionNotifier) CreateRepository(ctx context.Context, doer, u *user_mod
}
func (a *actionNotifier) ForkRepository(ctx context.Context, doer *user_model.User, oldRepo, repo *repo_model.Repository) {
- if err := notifyAll(ctx, &activities_model.Action{
+ if err := activities_model.NotifyWatchers(ctx, &activities_model.Action{
ActUserID: doer.ID,
ActUser: doer,
OpType: activities_model.ActionCreateRepo,
@@ -238,7 +230,7 @@ func (a *actionNotifier) PullRequestReview(ctx context.Context, pr *issues_model
actions = append(actions, &activities_model.Action{
ActUserID: review.Reviewer.ID,
ActUser: review.Reviewer,
- Content: encodeContent(fmt.Sprintf("%d", review.Issue.Index), abbreviatedComment(comm.Content)),
+ Content: fmt.Sprintf("%d|%s", review.Issue.Index, strings.Split(comm.Content, "\n")[0]),
OpType: activities_model.ActionCommentPull,
RepoID: review.Issue.RepoID,
Repo: review.Issue.Repo,
@@ -254,7 +246,7 @@ func (a *actionNotifier) PullRequestReview(ctx context.Context, pr *issues_model
action := &activities_model.Action{
ActUserID: review.Reviewer.ID,
ActUser: review.Reviewer,
- Content: encodeContent(fmt.Sprintf("%d", review.Issue.Index), abbreviatedComment(comment.Content)),
+ Content: fmt.Sprintf("%d|%s", review.Issue.Index, strings.Split(comment.Content, "\n")[0]),
RepoID: review.Issue.RepoID,
Repo: review.Issue.Repo,
IsPrivate: review.Issue.Repo.IsPrivate,
@@ -274,17 +266,17 @@ func (a *actionNotifier) PullRequestReview(ctx context.Context, pr *issues_model
actions = append(actions, action)
}
- if err := notifyAllActions(ctx, actions); err != nil {
+ if err := activities_model.NotifyWatchersActions(ctx, actions); err != nil {
log.Error("notify watchers '%d/%d': %v", review.Reviewer.ID, review.Issue.RepoID, err)
}
}
func (*actionNotifier) MergePullRequest(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest) {
- if err := notifyAll(ctx, &activities_model.Action{
+ if err := activities_model.NotifyWatchers(ctx, &activities_model.Action{
ActUserID: doer.ID,
ActUser: doer,
OpType: activities_model.ActionMergePullRequest,
- Content: encodeContent(fmt.Sprintf("%d", pr.Issue.Index), pr.Issue.Title),
+ Content: fmt.Sprintf("%d|%s", pr.Issue.Index, pr.Issue.Title),
RepoID: pr.Issue.Repo.ID,
Repo: pr.Issue.Repo,
IsPrivate: pr.Issue.Repo.IsPrivate,
@@ -294,11 +286,11 @@ func (*actionNotifier) MergePullRequest(ctx context.Context, doer *user_model.Us
}
func (*actionNotifier) AutoMergePullRequest(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest) {
- if err := notifyAll(ctx, &activities_model.Action{
+ if err := activities_model.NotifyWatchers(ctx, &activities_model.Action{
ActUserID: doer.ID,
ActUser: doer,
OpType: activities_model.ActionAutoMergePullRequest,
- Content: encodeContent(fmt.Sprintf("%d", pr.Issue.Index), pr.Issue.Title),
+ Content: fmt.Sprintf("%d|%s", pr.Issue.Index, pr.Issue.Title),
RepoID: pr.Issue.Repo.ID,
Repo: pr.Issue.Repo,
IsPrivate: pr.Issue.Repo.IsPrivate,
@@ -307,16 +299,16 @@ func (*actionNotifier) AutoMergePullRequest(ctx context.Context, doer *user_mode
}
}
-func (*actionNotifier) PullReviewDismiss(ctx context.Context, doer *user_model.User, review *issues_model.Review, comment *issues_model.Comment) {
+func (*actionNotifier) NotifyPullRevieweDismiss(ctx context.Context, doer *user_model.User, review *issues_model.Review, comment *issues_model.Comment) {
reviewerName := review.Reviewer.Name
if len(review.OriginalAuthor) > 0 {
reviewerName = review.OriginalAuthor
}
- if err := notifyAll(ctx, &activities_model.Action{
+ if err := activities_model.NotifyWatchers(ctx, &activities_model.Action{
ActUserID: doer.ID,
ActUser: doer,
OpType: activities_model.ActionPullReviewDismissed,
- Content: encodeContent(fmt.Sprintf("%d", review.Issue.Index), reviewerName, abbreviatedComment(comment.Content)),
+ Content: fmt.Sprintf("%d|%s|%s", review.Issue.Index, reviewerName, comment.Content),
RepoID: review.Issue.Repo.ID,
Repo: review.Issue.Repo,
IsPrivate: review.Issue.Repo.IsPrivate,
@@ -328,7 +320,9 @@ func (*actionNotifier) PullReviewDismiss(ctx context.Context, doer *user_model.U
}
func (a *actionNotifier) PushCommits(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) {
- commits = prepareCommitsForFeed(commits)
+ if len(commits.Commits) > setting.UI.FeedMaxCommitNum {
+ commits.Commits = commits.Commits[:setting.UI.FeedMaxCommitNum]
+ }
data, err := json.Marshal(commits)
if err != nil {
@@ -348,7 +342,7 @@ func (a *actionNotifier) PushCommits(ctx context.Context, pusher *user_model.Use
opType = activities_model.ActionDeleteBranch
}
- if err = notifyAll(ctx, &activities_model.Action{
+ if err = activities_model.NotifyWatchers(ctx, &activities_model.Action{
ActUserID: pusher.ID,
ActUser: pusher,
OpType: opType,
@@ -368,7 +362,7 @@ func (a *actionNotifier) CreateRef(ctx context.Context, doer *user_model.User, r
// has sent same action in `PushCommits`, so skip it.
return
}
- if err := notifyAll(ctx, &activities_model.Action{
+ if err := activities_model.NotifyWatchers(ctx, &activities_model.Action{
ActUserID: doer.ID,
ActUser: doer,
OpType: opType,
@@ -387,7 +381,7 @@ func (a *actionNotifier) DeleteRef(ctx context.Context, doer *user_model.User, r
// has sent same action in `PushCommits`, so skip it.
return
}
- if err := notifyAll(ctx, &activities_model.Action{
+ if err := activities_model.NotifyWatchers(ctx, &activities_model.Action{
ActUserID: doer.ID,
ActUser: doer,
OpType: opType,
@@ -401,7 +395,9 @@ func (a *actionNotifier) DeleteRef(ctx context.Context, doer *user_model.User, r
}
func (a *actionNotifier) SyncPushCommits(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) {
- commits = prepareCommitsForFeed(commits)
+ if len(commits.Commits) > setting.UI.FeedMaxCommitNum {
+ commits.Commits = commits.Commits[:setting.UI.FeedMaxCommitNum]
+ }
data, err := json.Marshal(commits)
if err != nil {
@@ -409,7 +405,7 @@ func (a *actionNotifier) SyncPushCommits(ctx context.Context, pusher *user_model
return
}
- if err := notifyAll(ctx, &activities_model.Action{
+ if err := activities_model.NotifyWatchers(ctx, &activities_model.Action{
ActUserID: repo.OwnerID,
ActUser: repo.MustOwner(ctx),
OpType: activities_model.ActionMirrorSyncPush,
@@ -424,7 +420,7 @@ func (a *actionNotifier) SyncPushCommits(ctx context.Context, pusher *user_model
}
func (a *actionNotifier) SyncCreateRef(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, refFullName git.RefName, refID string) {
- if err := notifyAll(ctx, &activities_model.Action{
+ if err := activities_model.NotifyWatchers(ctx, &activities_model.Action{
ActUserID: repo.OwnerID,
ActUser: repo.MustOwner(ctx),
OpType: activities_model.ActionMirrorSyncCreate,
@@ -438,7 +434,7 @@ func (a *actionNotifier) SyncCreateRef(ctx context.Context, doer *user_model.Use
}
func (a *actionNotifier) SyncDeleteRef(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, refFullName git.RefName) {
- if err := notifyAll(ctx, &activities_model.Action{
+ if err := activities_model.NotifyWatchers(ctx, &activities_model.Action{
ActUserID: repo.OwnerID,
ActUser: repo.MustOwner(ctx),
OpType: activities_model.ActionMirrorSyncDelete,
@@ -456,7 +452,7 @@ func (a *actionNotifier) NewRelease(ctx context.Context, rel *repo_model.Release
log.Error("LoadAttributes: %v", err)
return
}
- if err := notifyAll(ctx, &activities_model.Action{
+ if err := activities_model.NotifyWatchers(ctx, &activities_model.Action{
ActUserID: rel.PublisherID,
ActUser: rel.Publisher,
OpType: activities_model.ActionPublishRelease,
@@ -469,73 +465,3 @@ func (a *actionNotifier) NewRelease(ctx context.Context, rel *repo_model.Release
log.Error("NotifyWatchers: %v", err)
}
}
-
-// ... later decoded in models/activities/action.go:GetIssueInfos
-func encodeContent(params ...string) string {
- contentEncoded, err := json.Marshal(params)
- if err != nil {
- log.Error("encodeContent: Unexpected json encoding error: %v", err)
- }
- return string(contentEncoded)
-}
-
-// Given a comment of arbitrary-length Markdown text, create an abbreviated Markdown text appropriate for the
-// activity feed.
-func abbreviatedComment(comment string) string {
- firstLine := strings.Split(comment, "\n")[0]
-
- if strings.HasPrefix(firstLine, "```") {
- // First line is is a fenced code block... with no special abbreviate we would display a blank block, or in the
- // worst-case a ```mermaid would display an error. Better to omit the comment.
- return ""
- }
-
- truncatedContent, truncatedRight := util.SplitStringAtByteN(firstLine, 200)
- if truncatedRight != "" {
- // in case the content is in a Latin family language, we remove the last broken word.
- lastSpaceIdx := strings.LastIndex(truncatedContent, " ")
- if lastSpaceIdx != -1 && (len(truncatedContent)-lastSpaceIdx < 15) {
- truncatedContent = truncatedContent[:lastSpaceIdx] + "…"
- }
- }
-
- return truncatedContent
-}
-
-// Return a clone of the incoming repository.PushCommits that is appropriately tweaked for the activity feed. The struct
-// is cloned rather than modified in-place because the same data will be sent to multiple notifiers. Transformations
-// applied are: # of commits are limited to FeedMaxCommitNum, commit messages are trimmed to just the content displayed
-// in the activity feed.
-func prepareCommitsForFeed(commits *repository.PushCommits) *repository.PushCommits {
- numCommits := min(len(commits.Commits), setting.UI.FeedMaxCommitNum)
- retval := repository.PushCommits{
- Commits: make([]*repository.PushCommit, 0, numCommits),
- HeadCommit: nil,
- CompareURL: commits.CompareURL,
- Len: commits.Len,
- }
- if commits.HeadCommit != nil {
- retval.HeadCommit = prepareCommitForFeed(commits.HeadCommit)
- }
- for i, commit := range commits.Commits {
- if i == numCommits {
- break
- }
- retval.Commits = append(retval.Commits, prepareCommitForFeed(commit))
- }
- return &retval
-}
-
-func prepareCommitForFeed(commit *repository.PushCommit) *repository.PushCommit {
- return &repository.PushCommit{
- Sha1: commit.Sha1,
- Message: abbreviatedComment(commit.Message),
- AuthorEmail: commit.AuthorEmail,
- AuthorName: commit.AuthorName,
- CommitterEmail: commit.CommitterEmail,
- CommitterName: commit.CommitterName,
- Signature: commit.Signature,
- Verification: commit.Verification,
- Timestamp: commit.Timestamp,
- }
-}
diff --git a/services/feed/action_test.go b/services/feed/action_test.go
index fd27bf32a9..037cf08dfe 100644
--- a/services/feed/action_test.go
+++ b/services/feed/action_test.go
@@ -1,5 +1,4 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
-// Copyright 2025 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package feed
@@ -8,18 +7,18 @@ import (
"strings"
"testing"
- activities_model "forgejo.org/models/activities"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unittest"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/repository"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/test"
+ activities_model "code.gitea.io/gitea/models/activities"
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unittest"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/repository"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/test"
- _ "forgejo.org/models/actions"
- _ "forgejo.org/models/forgefed"
+ _ "code.gitea.io/gitea/models/actions"
+ _ "code.gitea.io/gitea/models/forgefed"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -67,7 +66,7 @@ func pushCommits() *repository.PushCommits {
CommitterName: "User2",
AuthorEmail: "user2@example.com",
AuthorName: "User2",
- Message: "not signed commit\nline two",
+ Message: "not signed commit",
},
{
Sha1: "27566bd",
@@ -83,10 +82,10 @@ func pushCommits() *repository.PushCommits {
CommitterName: "User2",
AuthorEmail: "user2@example.com",
AuthorName: "User2",
- Message: "good signed commit\nlong commit message\nwith lots of details\nabout how cool the implementation is",
+ Message: "good signed commit",
},
}
- pushCommits.HeadCommit = &repository.PushCommit{Sha1: "69554a6", Message: "not signed commit\nline two"}
+ pushCommits.HeadCommit = &repository.PushCommit{Sha1: "69554a6"}
return pushCommits
}
@@ -103,7 +102,7 @@ func TestSyncPushCommits(t *testing.T) {
NewNotifier().SyncPushCommits(db.DefaultContext, user, repo, &repository.PushUpdateOptions{RefFullName: git.RefNameFromBranch("master")}, pushCommits())
newNotification := unittest.AssertExistsAndLoadBean(t, &activities_model.Action{ActUserID: user.ID, RefName: "refs/heads/master"}, unittest.Cond("id > ?", maxID))
- assert.JSONEq(t, `{"Commits":[{"Sha1":"69554a6","Message":"not signed commit","AuthorEmail":"user2@example.com","AuthorName":"User2","CommitterEmail":"user2@example.com","CommitterName":"User2","Signature":null,"Verification":null,"Timestamp":"0001-01-01T00:00:00Z"},{"Sha1":"27566bd","Message":"good signed commit (with not yet validated email)","AuthorEmail":"user2@example.com","AuthorName":"User2","CommitterEmail":"user2@example.com","CommitterName":"User2","Signature":null,"Verification":null,"Timestamp":"0001-01-01T00:00:00Z"},{"Sha1":"5099b81","Message":"good signed commit","AuthorEmail":"user2@example.com","AuthorName":"User2","CommitterEmail":"user2@example.com","CommitterName":"User2","Signature":null,"Verification":null,"Timestamp":"0001-01-01T00:00:00Z"}],"HeadCommit":{"Sha1":"69554a6","Message":"not signed commit","AuthorEmail":"","AuthorName":"","CommitterEmail":"","CommitterName":"","Signature":null,"Verification":null,"Timestamp":"0001-01-01T00:00:00Z"},"CompareURL":"","Len":0}`, newNotification.Content)
+ assert.JSONEq(t, `{"Commits":[{"Sha1":"69554a6","Message":"not signed commit","AuthorEmail":"user2@example.com","AuthorName":"User2","CommitterEmail":"user2@example.com","CommitterName":"User2","Timestamp":"0001-01-01T00:00:00Z"},{"Sha1":"27566bd","Message":"good signed commit (with not yet validated email)","AuthorEmail":"user2@example.com","AuthorName":"User2","CommitterEmail":"user2@example.com","CommitterName":"User2","Timestamp":"0001-01-01T00:00:00Z"},{"Sha1":"5099b81","Message":"good signed commit","AuthorEmail":"user2@example.com","AuthorName":"User2","CommitterEmail":"user2@example.com","CommitterName":"User2","Timestamp":"0001-01-01T00:00:00Z"}],"HeadCommit":{"Sha1":"69554a6","Message":"","AuthorEmail":"","AuthorName":"","CommitterEmail":"","CommitterName":"","Timestamp":"0001-01-01T00:00:00Z"},"CompareURL":"","Len":0}`, newNotification.Content)
})
t.Run("Only one commit", func(t *testing.T) {
@@ -113,23 +112,7 @@ func TestSyncPushCommits(t *testing.T) {
NewNotifier().SyncPushCommits(db.DefaultContext, user, repo, &repository.PushUpdateOptions{RefFullName: git.RefNameFromBranch("main")}, pushCommits())
newNotification := unittest.AssertExistsAndLoadBean(t, &activities_model.Action{ActUserID: user.ID, RefName: "refs/heads/main"}, unittest.Cond("id > ?", maxID))
- assert.JSONEq(t, `{"Commits":[{"Sha1":"69554a6","Message":"not signed commit","AuthorEmail":"user2@example.com","AuthorName":"User2","CommitterEmail":"user2@example.com","CommitterName":"User2","Signature":null,"Verification":null,"Timestamp":"0001-01-01T00:00:00Z"}],"HeadCommit":{"Sha1":"69554a6","Message":"not signed commit","AuthorEmail":"","AuthorName":"","CommitterEmail":"","CommitterName":"","Signature":null,"Verification":null,"Timestamp":"0001-01-01T00:00:00Z"},"CompareURL":"","Len":0}`, newNotification.Content)
- })
-
- t.Run("Does not mutate commits param", func(t *testing.T) {
- defer test.MockVariableValue(&setting.UI.FeedMaxCommitNum, 1)()
-
- commits := pushCommits()
-
- assert.Equal(t, "not signed commit\nline two", commits.HeadCommit.Message)
- assert.Equal(t, "good signed commit\nlong commit message\nwith lots of details\nabout how cool the implementation is", commits.Commits[2].Message)
-
- NewNotifier().SyncPushCommits(db.DefaultContext, user, repo, &repository.PushUpdateOptions{RefFullName: git.RefNameFromBranch("master")}, commits)
-
- // commits passed into SyncPushCommits may be passed into other notifiers, so checking that the struct wasn't
- // mutated by truncate of messages, or truncation to match FeedMaxCommitNum (Commits[2])...
- assert.Equal(t, "not signed commit\nline two", commits.HeadCommit.Message)
- assert.Equal(t, "good signed commit\nlong commit message\nwith lots of details\nabout how cool the implementation is", commits.Commits[2].Message)
+ assert.JSONEq(t, `{"Commits":[{"Sha1":"69554a6","Message":"not signed commit","AuthorEmail":"user2@example.com","AuthorName":"User2","CommitterEmail":"user2@example.com","CommitterName":"User2","Timestamp":"0001-01-01T00:00:00Z"}],"HeadCommit":{"Sha1":"69554a6","Message":"","AuthorEmail":"","AuthorName":"","CommitterEmail":"","CommitterName":"","Timestamp":"0001-01-01T00:00:00Z"},"CompareURL":"","Len":0}`, newNotification.Content)
})
}
@@ -146,7 +129,7 @@ func TestPushCommits(t *testing.T) {
NewNotifier().PushCommits(db.DefaultContext, user, repo, &repository.PushUpdateOptions{RefFullName: git.RefNameFromBranch("master")}, pushCommits())
newNotification := unittest.AssertExistsAndLoadBean(t, &activities_model.Action{ActUserID: user.ID, RefName: "refs/heads/master"}, unittest.Cond("id > ?", maxID))
- assert.JSONEq(t, `{"Commits":[{"Sha1":"69554a6","Message":"not signed commit","AuthorEmail":"user2@example.com","AuthorName":"User2","CommitterEmail":"user2@example.com","CommitterName":"User2","Signature":null,"Verification":null,"Timestamp":"0001-01-01T00:00:00Z"},{"Sha1":"27566bd","Message":"good signed commit (with not yet validated email)","AuthorEmail":"user2@example.com","AuthorName":"User2","CommitterEmail":"user2@example.com","CommitterName":"User2","Signature":null,"Verification":null,"Timestamp":"0001-01-01T00:00:00Z"},{"Sha1":"5099b81","Message":"good signed commit","AuthorEmail":"user2@example.com","AuthorName":"User2","CommitterEmail":"user2@example.com","CommitterName":"User2","Signature":null,"Verification":null,"Timestamp":"0001-01-01T00:00:00Z"}],"HeadCommit":{"Sha1":"69554a6","Message":"not signed commit","AuthorEmail":"","AuthorName":"","CommitterEmail":"","CommitterName":"","Signature":null,"Verification":null,"Timestamp":"0001-01-01T00:00:00Z"},"CompareURL":"","Len":0}`, newNotification.Content)
+ assert.JSONEq(t, `{"Commits":[{"Sha1":"69554a6","Message":"not signed commit","AuthorEmail":"user2@example.com","AuthorName":"User2","CommitterEmail":"user2@example.com","CommitterName":"User2","Timestamp":"0001-01-01T00:00:00Z"},{"Sha1":"27566bd","Message":"good signed commit (with not yet validated email)","AuthorEmail":"user2@example.com","AuthorName":"User2","CommitterEmail":"user2@example.com","CommitterName":"User2","Timestamp":"0001-01-01T00:00:00Z"},{"Sha1":"5099b81","Message":"good signed commit","AuthorEmail":"user2@example.com","AuthorName":"User2","CommitterEmail":"user2@example.com","CommitterName":"User2","Timestamp":"0001-01-01T00:00:00Z"}],"HeadCommit":{"Sha1":"69554a6","Message":"","AuthorEmail":"","AuthorName":"","CommitterEmail":"","CommitterName":"","Timestamp":"0001-01-01T00:00:00Z"},"CompareURL":"","Len":0}`, newNotification.Content)
})
t.Run("Only one commit", func(t *testing.T) {
@@ -156,83 +139,6 @@ func TestPushCommits(t *testing.T) {
NewNotifier().PushCommits(db.DefaultContext, user, repo, &repository.PushUpdateOptions{RefFullName: git.RefNameFromBranch("main")}, pushCommits())
newNotification := unittest.AssertExistsAndLoadBean(t, &activities_model.Action{ActUserID: user.ID, RefName: "refs/heads/main"}, unittest.Cond("id > ?", maxID))
- assert.JSONEq(t, `{"Commits":[{"Sha1":"69554a6","Message":"not signed commit","AuthorEmail":"user2@example.com","AuthorName":"User2","CommitterEmail":"user2@example.com","CommitterName":"User2","Signature":null,"Verification":null,"Timestamp":"0001-01-01T00:00:00Z"}],"HeadCommit":{"Sha1":"69554a6","Message":"not signed commit","AuthorEmail":"","AuthorName":"","CommitterEmail":"","CommitterName":"","Signature":null,"Verification":null,"Timestamp":"0001-01-01T00:00:00Z"},"CompareURL":"","Len":0}`, newNotification.Content)
- })
-
- t.Run("Does not mutate commits param", func(t *testing.T) {
- defer test.MockVariableValue(&setting.UI.FeedMaxCommitNum, 1)()
-
- commits := pushCommits()
-
- assert.Equal(t, "not signed commit\nline two", commits.HeadCommit.Message)
- assert.Equal(t, "good signed commit\nlong commit message\nwith lots of details\nabout how cool the implementation is", commits.Commits[2].Message)
-
- NewNotifier().PushCommits(db.DefaultContext, user, repo, &repository.PushUpdateOptions{RefFullName: git.RefNameFromBranch("main")}, commits)
-
- // commits passed into SyncPushCommits may be passed into other notifiers, so checking that the struct wasn't
- // mutated by truncate of messages, or truncation to match FeedMaxCommitNum (Commits[2])...
- assert.Equal(t, "not signed commit\nline two", commits.HeadCommit.Message)
- assert.Equal(t, "good signed commit\nlong commit message\nwith lots of details\nabout how cool the implementation is", commits.Commits[2].Message)
+ assert.JSONEq(t, `{"Commits":[{"Sha1":"69554a6","Message":"not signed commit","AuthorEmail":"user2@example.com","AuthorName":"User2","CommitterEmail":"user2@example.com","CommitterName":"User2","Timestamp":"0001-01-01T00:00:00Z"}],"HeadCommit":{"Sha1":"69554a6","Message":"","AuthorEmail":"","AuthorName":"","CommitterEmail":"","CommitterName":"","Timestamp":"0001-01-01T00:00:00Z"},"CompareURL":"","Len":0}`, newNotification.Content)
})
}
-
-func TestAbbreviatedComment(t *testing.T) {
- tests := []struct {
- name string
- input string
- expected string
- }{
- {
- name: "short single line comment",
- input: "This is a short comment",
- expected: "This is a short comment",
- },
- {
- name: "empty comment",
- input: "",
- expected: "",
- },
- {
- name: "multiline comment - only first line",
- input: "First line of comment\nSecond line\nThird line",
- expected: "First line of comment",
- },
- {
- name: "before clip boundry",
- input: strings.Repeat("abc ", 50),
- expected: strings.Repeat("abc ", 50),
- },
- {
- name: "after clip boundry",
- input: strings.Repeat("abc ", 51),
- expected: "abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc…",
- },
- {
- name: "byte-split would land in middle of a rune",
- input: strings.Repeat("🎉", 200),
- expected: "🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉…",
- },
- {
- name: "mermaid block",
- input: "Interesting point, here's a digram with my thoughts:\n```mermaid\ngraph LR\n a -->|some text| b\n```",
- expected: "Interesting point, here's a digram with my thoughts:",
- },
- {
- name: "block start",
- input: "```\n# This file describes the expected reviewers for a PR based on the changed\n# files.\n```\n\nI think this comment is wrong...",
- expected: "",
- },
- {
- name: "labeled block start",
- input: "```mermaid\ngraph LR\n a -->|some text| b\n```",
- expected: "",
- },
- }
-
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- result := abbreviatedComment(tt.input)
- assert.Equal(t, tt.expected, result, "abbreviatedComment(%q)", tt.input)
- })
- }
-}
diff --git a/services/forgejo/main_test.go b/services/forgejo/main_test.go
index 5523ed1aab..40ce1715b1 100644
--- a/services/forgejo/main_test.go
+++ b/services/forgejo/main_test.go
@@ -5,12 +5,12 @@ package forgejo
import (
"testing"
- "forgejo.org/models/unittest"
+ "code.gitea.io/gitea/models/unittest"
- _ "forgejo.org/models"
- _ "forgejo.org/models/actions"
- _ "forgejo.org/models/activities"
- _ "forgejo.org/models/forgefed"
+ _ "code.gitea.io/gitea/models"
+ _ "code.gitea.io/gitea/models/actions"
+ _ "code.gitea.io/gitea/models/activities"
+ _ "code.gitea.io/gitea/models/forgefed"
)
func TestMain(m *testing.M) {
diff --git a/services/forgejo/sanity.go b/services/forgejo/sanity.go
index 70f15889d4..5e817d67f5 100644
--- a/services/forgejo/sanity.go
+++ b/services/forgejo/sanity.go
@@ -3,9 +3,9 @@
package forgejo
import (
- "forgejo.org/models/db"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
)
var (
diff --git a/services/forgejo/sanity_test.go b/services/forgejo/sanity_test.go
index 065a9fda4d..657f7e2720 100644
--- a/services/forgejo/sanity_test.go
+++ b/services/forgejo/sanity_test.go
@@ -7,9 +7,9 @@ import (
"path/filepath"
"testing"
- "forgejo.org/models/db"
- "forgejo.org/models/unittest"
- "forgejo.org/modules/setting"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/unittest"
+ "code.gitea.io/gitea/modules/setting"
"github.com/stretchr/testify/require"
)
diff --git a/services/forgejo/sanity_v1TOv5_0_1Included.go b/services/forgejo/sanity_v1TOv5_0_1Included.go
index 1d3f07d8e1..49de636f33 100644
--- a/services/forgejo/sanity_v1TOv5_0_1Included.go
+++ b/services/forgejo/sanity_v1TOv5_0_1Included.go
@@ -6,9 +6,9 @@ import (
"fmt"
"strings"
- "forgejo.org/models/db"
- "forgejo.org/models/forgejo/semver"
- "forgejo.org/modules/setting"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/forgejo/semver"
+ "code.gitea.io/gitea/modules/setting"
"github.com/hashicorp/go-version"
)
diff --git a/services/forgejo/sanity_v1TOv5_0_1Included_test.go b/services/forgejo/sanity_v1TOv5_0_1Included_test.go
index 2521afb496..56618ebd5f 100644
--- a/services/forgejo/sanity_v1TOv5_0_1Included_test.go
+++ b/services/forgejo/sanity_v1TOv5_0_1Included_test.go
@@ -6,10 +6,10 @@ import (
"fmt"
"testing"
- "forgejo.org/models/db"
- "forgejo.org/models/forgejo/semver"
- "forgejo.org/models/unittest"
- "forgejo.org/modules/log"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/forgejo/semver"
+ "code.gitea.io/gitea/models/unittest"
+ "code.gitea.io/gitea/modules/log"
"github.com/stretchr/testify/require"
)
diff --git a/services/forms/admin.go b/services/forms/admin.go
index 5a5d46634b..1f055cff55 100644
--- a/services/forms/admin.go
+++ b/services/forms/admin.go
@@ -6,9 +6,9 @@ package forms
import (
"net/http"
- "forgejo.org/modules/structs"
- "forgejo.org/modules/web/middleware"
- "forgejo.org/services/context"
+ "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/web/middleware"
+ "code.gitea.io/gitea/services/context"
"code.forgejo.org/go-chi/binding"
)
diff --git a/services/forms/auth_form.go b/services/forms/auth_form.go
index b89e87f749..21443ff6a5 100644
--- a/services/forms/auth_form.go
+++ b/services/forms/auth_form.go
@@ -6,8 +6,8 @@ package forms
import (
"net/http"
- "forgejo.org/modules/web/middleware"
- "forgejo.org/services/context"
+ "code.gitea.io/gitea/modules/web/middleware"
+ "code.gitea.io/gitea/services/context"
"code.forgejo.org/go-chi/binding"
)
@@ -79,7 +79,6 @@ type AuthenticationForm struct {
SkipLocalTwoFA bool
GroupTeamMap string `binding:"ValidGroupTeamMap"`
GroupTeamMapRemoval bool
- AllowUsernameChange bool
}
// Validate validates fields
diff --git a/services/forms/org.go b/services/forms/org.go
index a6e4e72c4a..dea2e159e9 100644
--- a/services/forms/org.go
+++ b/services/forms/org.go
@@ -7,9 +7,9 @@ package forms
import (
"net/http"
- "forgejo.org/modules/structs"
- "forgejo.org/modules/web/middleware"
- "forgejo.org/services/context"
+ "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/web/middleware"
+ "code.gitea.io/gitea/services/context"
"code.forgejo.org/go-chi/binding"
)
diff --git a/services/forms/package_form.go b/services/forms/package_form.go
index 82e5a09f86..7a7d8752cf 100644
--- a/services/forms/package_form.go
+++ b/services/forms/package_form.go
@@ -6,8 +6,8 @@ package forms
import (
"net/http"
- "forgejo.org/modules/web/middleware"
- "forgejo.org/services/context"
+ "code.gitea.io/gitea/modules/web/middleware"
+ "code.gitea.io/gitea/services/context"
"code.forgejo.org/go-chi/binding"
)
diff --git a/services/forms/repo_branch_form.go b/services/forms/repo_branch_form.go
index c34e7c6d17..186a4ad367 100644
--- a/services/forms/repo_branch_form.go
+++ b/services/forms/repo_branch_form.go
@@ -6,8 +6,8 @@ package forms
import (
"net/http"
- "forgejo.org/modules/web/middleware"
- "forgejo.org/services/context"
+ "code.gitea.io/gitea/modules/web/middleware"
+ "code.gitea.io/gitea/services/context"
"code.forgejo.org/go-chi/binding"
)
diff --git a/services/forms/repo_form.go b/services/forms/repo_form.go
index 11aac1fd52..8253a8957b 100644
--- a/services/forms/repo_form.go
+++ b/services/forms/repo_form.go
@@ -12,14 +12,14 @@ import (
"regexp"
"strings"
- "forgejo.org/models"
- issues_model "forgejo.org/models/issues"
- project_model "forgejo.org/models/project"
- webhook_model "forgejo.org/models/webhook"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/structs"
- "forgejo.org/modules/web/middleware"
- "forgejo.org/services/context"
+ "code.gitea.io/gitea/models"
+ issues_model "code.gitea.io/gitea/models/issues"
+ project_model "code.gitea.io/gitea/models/project"
+ webhook_model "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/web/middleware"
+ "code.gitea.io/gitea/services/context"
"code.forgejo.org/go-chi/binding"
)
@@ -105,9 +105,6 @@ func ParseRemoteAddr(remoteAddr, authUsername, authPassword string) (string, err
if err != nil {
return "", &models.ErrInvalidCloneAddr{IsURLError: true, Host: remoteAddr}
}
- if u.User != nil {
- return "", &models.ErrInvalidCloneAddr{Host: remoteAddr, HasCredentials: true}
- }
if len(authUsername)+len(authPassword) > 0 {
u.User = url.UserPassword(authUsername, authPassword)
}
@@ -144,7 +141,6 @@ type RepoSettingForm struct {
PushMirrorSyncOnCommit bool
PushMirrorInterval string
PushMirrorUseSSH bool
- PushMirrorBranchFilter string `binding:"MaxSize(2048)" preprocess:"TrimSpace"`
Private bool
Template bool
EnablePrune bool
@@ -192,8 +188,8 @@ type RepoUnitSettingForm struct {
PullsAllowSquash bool
PullsAllowFastForwardOnly bool
PullsAllowManualMerge bool
- PullsDefaultMergeStyle string `binding:"In(merge,rebase,rebase-merge,squash,fast-forward-only,manually-merged,rebase-update-only)"`
- PullsDefaultUpdateStyle string `binding:"In(merge,rebase)"`
+ PullsDefaultMergeStyle string
+ PullsDefaultUpdateStyle string
EnableAutodetectManualMerge bool
PullsAllowRebaseUpdate bool
DefaultDeleteBranchAfterMerge bool
@@ -281,9 +277,6 @@ type WebhookCoreForm struct {
Wiki bool
Repository bool
Package bool
- ActionFailure bool
- ActionRecover bool
- ActionSuccess bool
Active bool
BranchFilter string `binding:"GlobPattern"`
AuthorizationHeader string
@@ -732,8 +725,8 @@ func (f *DeleteRepoFileForm) Validate(req *http.Request, errs binding.Errors) bi
// AddTimeManuallyForm form that adds spent time manually.
type AddTimeManuallyForm struct {
- Hours int `binding:"Range(0,1000)" locale:"repo.issues.add_time_hours"`
- Minutes int `binding:"Range(0,1000)" locale:"repo.issues.add_time_minutes"`
+ Hours int `binding:"Range(0,1000)"`
+ Minutes int `binding:"Range(0,1000)"`
}
// Validate validates the fields
diff --git a/services/forms/repo_form_test.go b/services/forms/repo_form_test.go
index 4047762096..2c5a8e2c0f 100644
--- a/services/forms/repo_form_test.go
+++ b/services/forms/repo_form_test.go
@@ -6,7 +6,7 @@ package forms
import (
"testing"
- "forgejo.org/modules/setting"
+ "code.gitea.io/gitea/modules/setting"
"github.com/stretchr/testify/assert"
)
diff --git a/services/forms/repo_tag_form.go b/services/forms/repo_tag_form.go
index 1254c84d07..38f5996db3 100644
--- a/services/forms/repo_tag_form.go
+++ b/services/forms/repo_tag_form.go
@@ -6,8 +6,8 @@ package forms
import (
"net/http"
- "forgejo.org/modules/web/middleware"
- "forgejo.org/services/context"
+ "code.gitea.io/gitea/modules/web/middleware"
+ "code.gitea.io/gitea/services/context"
"code.forgejo.org/go-chi/binding"
)
diff --git a/services/forms/report_abuse.go b/services/forms/report_abuse.go
deleted file mode 100644
index 5e9d7dc45f..0000000000
--- a/services/forms/report_abuse.go
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2025 The Forgejo Authors. All rights reserved.
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-package forms
-
-import (
- "net/http"
-
- "forgejo.org/models/moderation"
- "forgejo.org/modules/web/middleware"
- "forgejo.org/services/context"
-
- "code.forgejo.org/go-chi/binding"
-)
-
-// ReportAbuseForm is used to interact with the UI of the form that submits new abuse reports.
-type ReportAbuseForm struct {
- ContentID int64
- ContentType moderation.ReportedContentType
- AbuseCategory moderation.AbuseCategoryType `binding:"Required" locale:"moderation.abuse_category"`
- Remarks string `binding:"Required;MinSize(20);MaxSize(500)" preprocess:"TrimSpace" locale:"moderation.report_remarks"`
-}
-
-// Validate validates the fields of ReportAbuseForm.
-func (f *ReportAbuseForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
- ctx := context.GetValidateContext(req)
- return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
-}
diff --git a/services/forms/runner.go b/services/forms/runner.go
index fcf6c5a694..f933750858 100644
--- a/services/forms/runner.go
+++ b/services/forms/runner.go
@@ -6,8 +6,8 @@ package forms
import (
"net/http"
- "forgejo.org/modules/web/middleware"
- "forgejo.org/services/context"
+ "code.gitea.io/gitea/modules/web/middleware"
+ "code.gitea.io/gitea/services/context"
"code.forgejo.org/go-chi/binding"
)
diff --git a/services/forms/user_form.go b/services/forms/user_form.go
index 8c95139e2c..d76e97ceb1 100644
--- a/services/forms/user_form.go
+++ b/services/forms/user_form.go
@@ -9,12 +9,12 @@ import (
"net/http"
"strings"
- auth_model "forgejo.org/models/auth"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/structs"
- "forgejo.org/modules/validation"
- "forgejo.org/modules/web/middleware"
- "forgejo.org/services/context"
+ auth_model "code.gitea.io/gitea/models/auth"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/validation"
+ "code.gitea.io/gitea/modules/web/middleware"
+ "code.gitea.io/gitea/services/context"
"code.forgejo.org/go-chi/binding"
)
@@ -109,7 +109,7 @@ func (f *RegisterForm) Validate(req *http.Request, errs binding.Errors) binding.
// The email is marked as allowed if it matches any of the
// domains in the whitelist or if it doesn't match any of
// domains in the blocklist, if any such list is not empty.
-func (f *RegisterForm) IsEmailDomainAllowed() (validEmail, ok bool) {
+func (f *RegisterForm) IsEmailDomainAllowed() bool {
return validation.IsEmailDomainAllowed(f.Email)
}
diff --git a/services/forms/user_form_auth_openid.go b/services/forms/user_form_auth_openid.go
index 02d4f873bc..c5ab703fa1 100644
--- a/services/forms/user_form_auth_openid.go
+++ b/services/forms/user_form_auth_openid.go
@@ -6,8 +6,8 @@ package forms
import (
"net/http"
- "forgejo.org/modules/web/middleware"
- "forgejo.org/services/context"
+ "code.gitea.io/gitea/modules/web/middleware"
+ "code.gitea.io/gitea/services/context"
"code.forgejo.org/go-chi/binding"
)
diff --git a/services/forms/user_form_hidden_comments.go b/services/forms/user_form_hidden_comments.go
index 74a1aaccb0..b9677c1800 100644
--- a/services/forms/user_form_hidden_comments.go
+++ b/services/forms/user_form_hidden_comments.go
@@ -6,9 +6,9 @@ package forms
import (
"math/big"
- issues_model "forgejo.org/models/issues"
- "forgejo.org/modules/log"
- "forgejo.org/services/context"
+ issues_model "code.gitea.io/gitea/models/issues"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/services/context"
)
type hiddenCommentTypeGroupsType map[string][]issues_model.CommentType
diff --git a/services/forms/user_form_test.go b/services/forms/user_form_test.go
index 4ce63ab552..66050187c9 100644
--- a/services/forms/user_form_test.go
+++ b/services/forms/user_form_test.go
@@ -7,26 +7,33 @@ import (
"strconv"
"testing"
- auth_model "forgejo.org/models/auth"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/test"
+ auth_model "code.gitea.io/gitea/models/auth"
+ "code.gitea.io/gitea/modules/setting"
"github.com/gobwas/glob"
"github.com/stretchr/testify/assert"
)
func TestRegisterForm_IsDomainAllowed_Empty(t *testing.T) {
- defer test.MockVariableValue(&setting.Service.EmailDomainAllowList, nil)()
+ oldService := setting.Service
+ defer func() {
+ setting.Service = oldService
+ }()
+
+ setting.Service.EmailDomainAllowList = nil
form := RegisterForm{}
- emailValid, ok := form.IsEmailDomainAllowed()
- assert.False(t, emailValid)
- assert.False(t, ok)
+ assert.True(t, form.IsEmailDomainAllowed())
}
func TestRegisterForm_IsDomainAllowed_InvalidEmail(t *testing.T) {
- defer test.MockVariableValue(&setting.Service.EmailDomainAllowList, []glob.Glob{glob.MustCompile("gitea.io")})()
+ oldService := setting.Service
+ defer func() {
+ setting.Service = oldService
+ }()
+
+ setting.Service.EmailDomainAllowList = []glob.Glob{glob.MustCompile("gitea.io")}
tt := []struct {
email string
@@ -38,13 +45,17 @@ func TestRegisterForm_IsDomainAllowed_InvalidEmail(t *testing.T) {
for _, v := range tt {
form := RegisterForm{Email: v.email}
- _, ok := form.IsEmailDomainAllowed()
- assert.False(t, ok)
+ assert.False(t, form.IsEmailDomainAllowed())
}
}
func TestRegisterForm_IsDomainAllowed_AllowedEmail(t *testing.T) {
- defer test.MockVariableValue(&setting.Service.EmailDomainAllowList, []glob.Glob{glob.MustCompile("gitea.io"), glob.MustCompile("*.allow")})()
+ oldService := setting.Service
+ defer func() {
+ setting.Service = oldService
+ }()
+
+ setting.Service.EmailDomainAllowList = []glob.Glob{glob.MustCompile("gitea.io"), glob.MustCompile("*.allow")}
tt := []struct {
email string
@@ -62,13 +73,18 @@ func TestRegisterForm_IsDomainAllowed_AllowedEmail(t *testing.T) {
for _, v := range tt {
form := RegisterForm{Email: v.email}
- _, ok := form.IsEmailDomainAllowed()
- assert.Equal(t, v.valid, ok)
+ assert.Equal(t, v.valid, form.IsEmailDomainAllowed())
}
}
func TestRegisterForm_IsDomainAllowed_BlockedEmail(t *testing.T) {
- defer test.MockVariableValue(&setting.Service.EmailDomainBlockList, []glob.Glob{glob.MustCompile("gitea.io"), glob.MustCompile("*.block")})()
+ oldService := setting.Service
+ defer func() {
+ setting.Service = oldService
+ }()
+
+ setting.Service.EmailDomainAllowList = nil
+ setting.Service.EmailDomainBlockList = []glob.Glob{glob.MustCompile("gitea.io"), glob.MustCompile("*.block")}
tt := []struct {
email string
@@ -76,6 +92,7 @@ func TestRegisterForm_IsDomainAllowed_BlockedEmail(t *testing.T) {
}{
{"security@gitea.io", false},
{"security@gitea.example", true},
+ {"invalid", true},
{"user@my.block", false},
{"user@my.block1", true},
@@ -84,8 +101,7 @@ func TestRegisterForm_IsDomainAllowed_BlockedEmail(t *testing.T) {
for _, v := range tt {
form := RegisterForm{Email: v.email}
- _, ok := form.IsEmailDomainAllowed()
- assert.Equal(t, v.valid, ok)
+ assert.Equal(t, v.valid, form.IsEmailDomainAllowed())
}
}
diff --git a/services/gitdiff/csv_test.go b/services/gitdiff/csv_test.go
index 9bffba33fd..1dbe616374 100644
--- a/services/gitdiff/csv_test.go
+++ b/services/gitdiff/csv_test.go
@@ -8,9 +8,9 @@ import (
"strings"
"testing"
- "forgejo.org/models/db"
- csv_module "forgejo.org/modules/csv"
- "forgejo.org/modules/setting"
+ "code.gitea.io/gitea/models/db"
+ csv_module "code.gitea.io/gitea/modules/csv"
+ "code.gitea.io/gitea/modules/setting"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
diff --git a/services/gitdiff/gitdiff.go b/services/gitdiff/gitdiff.go
index 2f3d289c80..f2070983e6 100644
--- a/services/gitdiff/gitdiff.go
+++ b/services/gitdiff/gitdiff.go
@@ -17,19 +17,19 @@ import (
"strings"
"time"
- "forgejo.org/models/db"
- git_model "forgejo.org/models/git"
- issues_model "forgejo.org/models/issues"
- pull_model "forgejo.org/models/pull"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/analyze"
- "forgejo.org/modules/charset"
- "forgejo.org/modules/git"
- "forgejo.org/modules/highlight"
- "forgejo.org/modules/lfs"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/translation"
+ "code.gitea.io/gitea/models/db"
+ git_model "code.gitea.io/gitea/models/git"
+ issues_model "code.gitea.io/gitea/models/issues"
+ pull_model "code.gitea.io/gitea/models/pull"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/analyze"
+ "code.gitea.io/gitea/modules/charset"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/highlight"
+ "code.gitea.io/gitea/modules/lfs"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/translation"
"github.com/sergi/go-diff/diffmatchpatch"
stdcharset "golang.org/x/net/html/charset"
@@ -85,20 +85,11 @@ type DiffLine struct {
// DiffLineSectionInfo represents diff line section meta data
type DiffLineSectionInfo struct {
- Path string
-
- // Last(Left/Right)Idx do not directly relate to this diff section, but indicate the last line number in the
- // previous diff section. Set to 0 for the first diff section of a file, and 1 for the first line of code in the
- // file.
- LastLeftIdx int
- LastRightIdx int
-
- // (Left/Right)Idx are the first line number in this diff section
- LeftIdx int
- RightIdx int
-
- // Number of lines contained within each diff section. In the UI, these fields are set to 0 in cases where a
- // section is being used as a placeholder at the end of a diff to allow expansion into the remainder of the file.
+ Path string
+ LastLeftIdx int
+ LastRightIdx int
+ LeftIdx int
+ RightIdx int
LeftHunkSize int
RightHunkSize int
}
@@ -166,7 +157,7 @@ func (d *DiffLine) GetExpandDirection() DiffLineExpandDirection {
}
if d.SectionInfo.LastLeftIdx <= 0 && d.SectionInfo.LastRightIdx <= 0 {
return DiffLineExpandUp
- } else if d.SectionInfo.RightIdx-d.SectionInfo.LastRightIdx-1 > BlobExcerptChunkSize && d.SectionInfo.RightHunkSize > 0 {
+ } else if d.SectionInfo.RightIdx-d.SectionInfo.LastRightIdx > BlobExcerptChunkSize && d.SectionInfo.RightHunkSize > 0 {
return DiffLineExpandUpDown
} else if d.SectionInfo.LeftHunkSize <= 0 && d.SectionInfo.RightHunkSize <= 0 {
return DiffLineExpandDown
@@ -427,7 +418,6 @@ func (diffFile *DiffFile) ShouldBeHidden() bool {
return diffFile.IsGenerated || diffFile.IsViewed
}
-//llu:returnsTrKey
func (diffFile *DiffFile) ModeTranslationKey(mode string) string {
switch mode {
case "040000":
@@ -450,29 +440,11 @@ func getCommitFileLineCount(commit *git.Commit, filePath string) int {
if err != nil {
return 0
}
- reader, err := blob.DataAsync()
+ lineCount, err := blob.GetBlobLineCount()
if err != nil {
return 0
}
- defer reader.Close()
- buf := make([]byte, 32*1024)
- count := 1
- lineSep := []byte{'\n'}
-
- c, err := reader.Read(buf)
- if c == 0 && err == io.EOF {
- return 0
- }
- for {
- count += bytes.Count(buf[:c], lineSep)
- switch {
- case err == io.EOF:
- return count
- case err != nil:
- return count
- }
- c, err = reader.Read(buf)
- }
+ return lineCount
}
// Diff represents a difference between two git trees.
@@ -1088,7 +1060,7 @@ func readFileName(rd *strings.Reader) (string, bool) {
_, _ = fmt.Fscanf(rd, "%s ", &name)
char, _ := rd.ReadByte()
_ = rd.UnreadByte()
- for char != 0 && char != '"' && char != 'b' {
+ for !(char == 0 || char == '"' || char == 'b') {
var suffix string
_, _ = fmt.Fscanf(rd, "%s ", &suffix)
name += " " + suffix
@@ -1116,63 +1088,62 @@ type DiffOptions struct {
FileOnly bool
}
-// GetDiffSimple builds a Diff between two commits of a repository.
+// GetDiff builds a Diff between two commits of a repository.
// Passing the empty string as beforeCommitID returns a diff from the parent commit.
-// The whitespaceBehavior is either an empty string or a git flag.
-func GetDiffSimple(ctx context.Context, gitRepo *git.Repository, opts *DiffOptions, files ...string) (diff *Diff, afterCommit *git.Commit, err error) {
- afterCommit, err = gitRepo.GetCommit(opts.AfterCommitID)
+// The whitespaceBehavior is either an empty string or a git flag
+func GetDiff(ctx context.Context, gitRepo *git.Repository, opts *DiffOptions, files ...string) (*Diff, error) {
+ repoPath := gitRepo.Path
+
+ var beforeCommit *git.Commit
+ commit, err := gitRepo.GetCommit(opts.AfterCommitID)
if err != nil {
- return nil, nil, fmt.Errorf("unable to get the after commit %q: %w", opts.AfterCommitID, err)
+ return nil, err
}
cmdCtx, cmdCancel := context.WithCancel(ctx)
defer cmdCancel()
- cmdDiff := git.NewCommand(cmdCtx).
- AddArguments("diff", "--src-prefix=\\a/", "--dst-prefix=\\b/", "-M").
- AddArguments(opts.WhitespaceBehavior...)
-
+ cmdDiff := git.NewCommand(cmdCtx)
objectFormat, err := gitRepo.GetObjectFormat()
if err != nil {
- return nil, nil, fmt.Errorf("not able to determine the object format: %w", err)
+ return nil, err
}
- // If before commit is empty or the empty object and the after commit has no
- // parents, then use the empty tree as before commit.
- //
- // This is the case for a 'initial commit' of a Git tree, which obviously has
- // no parents.
- if (len(opts.BeforeCommitID) == 0 || opts.BeforeCommitID == objectFormat.EmptyObjectID().String()) && afterCommit.ParentCount() == 0 {
- // Reset before commit ID to indicate empty tree was used.
- opts.BeforeCommitID = ""
- // Add enpty tree as before commit.
- cmdDiff.AddDynamicArguments(objectFormat.EmptyTree().String())
+ if (len(opts.BeforeCommitID) == 0 || opts.BeforeCommitID == objectFormat.EmptyObjectID().String()) && commit.ParentCount() == 0 {
+ cmdDiff.AddArguments("diff", "--src-prefix=\\a/", "--dst-prefix=\\b/", "-M").
+ AddArguments(opts.WhitespaceBehavior...).
+ AddDynamicArguments(objectFormat.EmptyTree().String()).
+ AddDynamicArguments(opts.AfterCommitID)
} else {
- // If before commit ID is empty, use the first parent of the after commit.
- if len(opts.BeforeCommitID) == 0 {
- parentCommit, err := afterCommit.Parent(0)
+ actualBeforeCommitID := opts.BeforeCommitID
+ if len(actualBeforeCommitID) == 0 {
+ parentCommit, err := commit.Parent(0)
if err != nil {
- return nil, nil, fmt.Errorf("not able to get first parent of %q: %w", afterCommit.ID.String(), err)
+ return nil, err
}
- opts.BeforeCommitID = parentCommit.ID.String()
+ actualBeforeCommitID = parentCommit.ID.String()
}
- cmdDiff.AddDynamicArguments(opts.BeforeCommitID)
- }
+ cmdDiff.AddArguments("diff", "--src-prefix=\\a/", "--dst-prefix=\\b/", "-M").
+ AddArguments(opts.WhitespaceBehavior...).
+ AddDynamicArguments(actualBeforeCommitID, opts.AfterCommitID)
+ opts.BeforeCommitID = actualBeforeCommitID
- // Add the after commit to the diff command.
- cmdDiff.AddDynamicArguments(opts.AfterCommitID)
+ beforeCommit, err = gitRepo.GetCommit(opts.BeforeCommitID)
+ if err != nil {
+ return nil, err
+ }
+ }
// In git 2.31, git diff learned --skip-to which we can use to shortcut skip to file
// so if we are using at least this version of git we don't have to tell ParsePatch to do
// the skipping for us
parsePatchSkipToFile := opts.SkipTo
- if opts.SkipTo != "" {
+ if opts.SkipTo != "" && git.CheckGitVersionAtLeast("2.31") == nil {
cmdDiff.AddOptionFormat("--skip-to=%s", opts.SkipTo)
parsePatchSkipToFile = ""
}
- // If we only want to diff for some files, add that as well.
cmdDiff.AddDashesAndList(files...)
reader, writer := io.Pipe()
@@ -1182,7 +1153,6 @@ func GetDiffSimple(ctx context.Context, gitRepo *git.Repository, opts *DiffOptio
}()
go func() {
- repoPath := gitRepo.Path
stderr := &bytes.Buffer{}
cmdDiff.SetDescription(fmt.Sprintf("GetDiffRange [repo_path: %s]", repoPath))
if err := cmdDiff.Run(&git.RunOpts{
@@ -1197,33 +1167,14 @@ func GetDiffSimple(ctx context.Context, gitRepo *git.Repository, opts *DiffOptio
_ = writer.Close()
}()
- diff, err = ParsePatch(cmdCtx, opts.MaxLines, opts.MaxLineCharacters, opts.MaxFiles, reader, parsePatchSkipToFile)
+ diff, err := ParsePatch(cmdCtx, opts.MaxLines, opts.MaxLineCharacters, opts.MaxFiles, reader, parsePatchSkipToFile)
// Ensure the git process is killed if it didn't exit already
cmdCancel()
if err != nil {
- return nil, nil, fmt.Errorf("unable to parse a git diff: %w", err)
+ return nil, fmt.Errorf("unable to ParsePatch: %w", err)
}
diff.Start = opts.SkipTo
- return diff, afterCommit, nil
-}
-
-func GetDiffFull(ctx context.Context, gitRepo *git.Repository, opts *DiffOptions, files ...string) (*Diff, error) {
- diff, afterCommit, err := GetDiffSimple(ctx, gitRepo, opts, files...)
- if err != nil {
- return nil, err
- }
-
- // If there's a before commit, then GetDiffSimple will set it, otherwise it
- // is empty.
- var beforeCommit *git.Commit
- if len(opts.BeforeCommitID) != 0 {
- beforeCommit, err = gitRepo.GetCommit(opts.BeforeCommitID)
- if err != nil {
- return nil, fmt.Errorf("unable to get before commit %q: %w", opts.BeforeCommitID, err)
- }
- }
-
checker, err := gitRepo.GitAttributeChecker(opts.AfterCommitID, git.LinguistAttributes...)
if err != nil {
return nil, fmt.Errorf("unable to GitAttributeChecker: %w", err)
@@ -1259,7 +1210,7 @@ func GetDiffFull(ctx context.Context, gitRepo *git.Repository, opts *DiffOptions
diffFile.IsGenerated = analyze.IsGenerated(diffFile.Name)
}
- tailSection := diffFile.GetTailSection(gitRepo, beforeCommit, afterCommit)
+ tailSection := diffFile.GetTailSection(gitRepo, beforeCommit, commit)
if tailSection != nil {
diffFile.Sections = append(diffFile.Sections, tailSection)
}
@@ -1321,7 +1272,7 @@ func GetPullDiffStats(gitRepo *git.Repository, opts *DiffOptions) (*PullDiffStat
// SyncAndGetUserSpecificDiff is like GetDiff, except that user specific data such as which files the given user has already viewed on the given PR will also be set
// Additionally, the database asynchronously is updated if files have changed since the last review
func SyncAndGetUserSpecificDiff(ctx context.Context, userID int64, pull *issues_model.PullRequest, gitRepo *git.Repository, opts *DiffOptions, files ...string) (*Diff, error) {
- diff, err := GetDiffFull(ctx, gitRepo, opts, files...)
+ diff, err := GetDiff(ctx, gitRepo, opts, files...)
if err != nil {
return nil, err
}
diff --git a/services/gitdiff/gitdiff_test.go b/services/gitdiff/gitdiff_test.go
index d4d1cd4460..f2c099d554 100644
--- a/services/gitdiff/gitdiff_test.go
+++ b/services/gitdiff/gitdiff_test.go
@@ -9,13 +9,13 @@ import (
"strings"
"testing"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- "forgejo.org/models/unittest"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/json"
- "forgejo.org/modules/setting"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ "code.gitea.io/gitea/models/unittest"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/setting"
dmp "github.com/sergi/go-diff/diffmatchpatch"
"github.com/stretchr/testify/assert"
@@ -635,7 +635,7 @@ func TestGetDiffRangeWithWhitespaceBehavior(t *testing.T) {
defer gitRepo.Close()
for _, behavior := range []git.TrustedCmdArgs{{"-w"}, {"--ignore-space-at-eol"}, {"-b"}, nil} {
- diffs, _, err := GetDiffSimple(db.DefaultContext, gitRepo,
+ diffs, err := GetDiff(db.DefaultContext, gitRepo,
&DiffOptions{
AfterCommitID: "bd7063cc7c04689c4d082183d32a604ed27a24f9",
BeforeCommitID: "559c156f8e0178b71cb44355428f24001b08fc68",
@@ -651,229 +651,6 @@ func TestGetDiffRangeWithWhitespaceBehavior(t *testing.T) {
}
}
-func TestGetDiffFull(t *testing.T) {
- gitRepo, err := git.OpenRepository(git.DefaultContext, "./../../modules/git/tests/repos/language_stats_repo")
- require.NoError(t, err)
-
- defer gitRepo.Close()
-
- t.Run("Initial commit", func(t *testing.T) {
- diff, err := GetDiffFull(db.DefaultContext, gitRepo,
- &DiffOptions{
- AfterCommitID: "8fee858da5796dfb37704761701bb8e800ad9ef3",
- MaxLines: setting.Git.MaxGitDiffLines,
- MaxLineCharacters: setting.Git.MaxGitDiffLineCharacters,
- MaxFiles: setting.Git.MaxGitDiffFiles,
- })
- require.NoError(t, err)
-
- assert.Empty(t, diff.Start)
- assert.Empty(t, diff.End)
- assert.False(t, diff.IsIncomplete)
- assert.Equal(t, 5, diff.NumFiles)
- assert.Equal(t, 23, diff.TotalAddition)
- assert.Len(t, diff.Files, 5)
-
- assert.True(t, diff.Files[0].IsVendored)
- assert.Equal(t, ".gitattributes", diff.Files[0].Name)
- assert.Equal(t, "24139dae656713ba861751fb2c2ac38839349a7a", diff.Files[0].NameHash)
-
- assert.Equal(t, "Python", diff.Files[1].Language)
- assert.Equal(t, "i-am-a-python.p", diff.Files[1].Name)
- assert.Equal(t, "32154957b043de62cbcdbe254a53ec4c3e00c5a0", diff.Files[1].NameHash)
-
- assert.Equal(t, "java-hello/main.java", diff.Files[2].Name)
- assert.Equal(t, "ef9f6a406a4cde7bb5480ba7b027bdc8cd6fa11d", diff.Files[2].NameHash)
-
- assert.Equal(t, "main.vendor.java", diff.Files[3].Name)
- assert.Equal(t, "c94fd7272f109d4d21d6df2b637c864a5ab63f46", diff.Files[3].NameHash)
-
- assert.Equal(t, "python-hello/hello.py", diff.Files[4].Name)
- assert.Equal(t, "021705ba8b98778dc4e277d3a6ea1b8c6122a7f9", diff.Files[4].NameHash)
- })
-
- t.Run("Normal diff", func(t *testing.T) {
- diff, err := GetDiffFull(db.DefaultContext, gitRepo,
- &DiffOptions{
- AfterCommitID: "341fca5b5ea3de596dc483e54c2db28633cd2f97",
- BeforeCommitID: "8fee858da5796dfb37704761701bb8e800ad9ef3",
- MaxLines: setting.Git.MaxGitDiffLines,
- MaxLineCharacters: setting.Git.MaxGitDiffLineCharacters,
- MaxFiles: setting.Git.MaxGitDiffFiles,
- })
- require.NoError(t, err)
-
- assert.Empty(t, diff.Start)
- assert.Empty(t, diff.End)
- assert.False(t, diff.IsIncomplete)
- assert.Equal(t, 1, diff.NumFiles)
- assert.Equal(t, 1, diff.TotalAddition)
- assert.Len(t, diff.Files, 1)
-
- assert.Equal(t, ".gitattributes", diff.Files[0].Name)
- assert.Equal(t, "24139dae656713ba861751fb2c2ac38839349a7a", diff.Files[0].NameHash)
- assert.Len(t, diff.Files[0].Sections, 2)
- assert.Equal(t, 4, diff.Files[0].Sections[1].Lines[0].SectionInfo.LeftIdx)
- })
-}
-
-func TestDiffLine_GetExpandDirection(t *testing.T) {
- tests := []struct {
- name string
- diffLine *DiffLine
- expectedResult DiffLineExpandDirection
- }{
- {
- name: "non-section line - no expansion",
- diffLine: &DiffLine{
- Type: DiffLineAdd,
- SectionInfo: &DiffLineSectionInfo{},
- },
- expectedResult: DiffLineExpandNone,
- },
- {
- name: "nil section info - no expansion",
- diffLine: &DiffLine{
- Type: DiffLineSection,
- SectionInfo: nil,
- },
- expectedResult: DiffLineExpandNone,
- },
- {
- name: "no lines between",
- diffLine: &DiffLine{
- Type: DiffLineSection,
- SectionInfo: &DiffLineSectionInfo{
- // Previous section of the diff displayed up to line 530...
- LastRightIdx: 530,
- LastLeftIdx: 530,
- // This section of the diff starts at line 531...
- RightIdx: 531,
- LeftIdx: 531,
- },
- },
- // There are zero lines between 530 and 531, so we should have nothing to expand.
- expectedResult: DiffLineExpandNone,
- },
- {
- name: "first diff section is the start of the file",
- diffLine: &DiffLine{
- Type: DiffLineSection,
- SectionInfo: &DiffLineSectionInfo{
- // Last[...]Idx is set to zero when it's the first section in the file (and not 1, which would be
- // the first section -is- the first line of the file).
- LastRightIdx: 0,
- LastLeftIdx: 0,
- // The diff section is showing line 1, the top of th efile.
- RightIdx: 1,
- LeftIdx: 1,
- },
- },
- // We're at the top of the file; no expansion.
- expectedResult: DiffLineExpandNone,
- },
- {
- name: "first diff section doesn't start at the top of the file",
- diffLine: &DiffLine{
- Type: DiffLineSection,
- SectionInfo: &DiffLineSectionInfo{
- // Last[...]Idx is set to zero when it's the first section in the file (and not 1, which would be
- // the first section -is- the first line of the file).
- LastRightIdx: 0,
- LastLeftIdx: 0,
- RightIdx: 531,
- LeftIdx: 531,
- },
- },
- // We're at the top of the diff but there's content above, so can only expand up.
- expectedResult: DiffLineExpandUp,
- },
- {
- name: "middle of the file with single expansion",
- diffLine: &DiffLine{
- Type: DiffLineSection,
- SectionInfo: &DiffLineSectionInfo{
- // Previous section ended at ~500...
- LastRightIdx: 500,
- LastLeftIdx: 500,
- // Next section starts one line away...
- RightIdx: 502,
- LeftIdx: 502,
- // The next block has content (> 0)
- RightHunkSize: 50,
- LeftHunkSize: 50,
- },
- },
- // Can be expanded in a single direction, displaying the missing line (501).
- expectedResult: DiffLineExpandSingle,
- },
- {
- name: "middle of the file with multi line expansion",
- diffLine: &DiffLine{
- Type: DiffLineSection,
- SectionInfo: &DiffLineSectionInfo{
- // Previous section ended at ~500...
- LastRightIdx: 500,
- LastLeftIdx: 500,
- // Lines 501-520 are hidden, exactly 20 lines, matching BlobExcerptChunkSize (20)...
- RightIdx: 521,
- LeftIdx: 521,
- // The next block has content (> 0)
- RightHunkSize: 50,
- LeftHunkSize: 50,
- },
- },
- // Can be expanded in a single direction, displaying all the hidden 20 lines.
- expectedResult: DiffLineExpandSingle,
- },
- {
- name: "middle of the file with multi direction expansion",
- diffLine: &DiffLine{
- Type: DiffLineSection,
- SectionInfo: &DiffLineSectionInfo{
- // Previous section ended at ~500...
- LastRightIdx: 500,
- LastLeftIdx: 500,
- // Lines 501-521 are hidden, exactly 21 lines, exceeding BlobExcerptChunkSize (20)...
- RightIdx: 522,
- LeftIdx: 522,
- // The next block has content (> 0)
- RightHunkSize: 50,
- LeftHunkSize: 50,
- },
- },
- // Now can be expanded down to display from 501-520 (521 remains hidden), or up to display 502-521 (501
- // remains hidden).
- expectedResult: DiffLineExpandUpDown,
- },
- {
- name: "end of the diff but still file content to display",
- diffLine: &DiffLine{
- Type: DiffLineSection,
- SectionInfo: &DiffLineSectionInfo{
- // We had a previous diff section, of any size/location...
- LastRightIdx: 200,
- LastLeftIdx: 200,
- RightIdx: 531,
- LeftIdx: 531,
- // Hunk size size 0 is a placeholder value for the end or beginning of a file...
- RightHunkSize: 0,
- LeftHunkSize: 0,
- },
- },
- // Combination of conditions says we're at the end of the last diff section, can only expand down.
- expectedResult: DiffLineExpandDown,
- },
- }
-
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- result := tt.diffLine.GetExpandDirection()
- assert.Equal(t, tt.expectedResult, result)
- })
- }
-}
-
func TestNoCrashes(t *testing.T) {
type testcase struct {
gitdiff string
diff --git a/services/gitdiff/highlightdiff.go b/services/gitdiff/highlightdiff.go
index 61d52d91e6..c72959ea16 100644
--- a/services/gitdiff/highlightdiff.go
+++ b/services/gitdiff/highlightdiff.go
@@ -6,7 +6,7 @@ package gitdiff
import (
"strings"
- "forgejo.org/modules/highlight"
+ "code.gitea.io/gitea/modules/highlight"
"github.com/sergi/go-diff/diffmatchpatch"
)
@@ -14,14 +14,13 @@ import (
// token is a html tag or entity, eg: "", " ", "<"
func extractHTMLToken(s string) (before, token, after string, valid bool) {
for pos1 := 0; pos1 < len(s); pos1++ {
- switch s[pos1] {
- case '<':
+ if s[pos1] == '<' {
pos2 := strings.IndexByte(s[pos1:], '>')
if pos2 == -1 {
return "", "", s, false
}
return s[:pos1], s[pos1 : pos1+pos2+1], s[pos1+pos2+1:], true
- case '&':
+ } else if s[pos1] == '&' {
pos2 := strings.IndexByte(s[pos1:], ';')
if pos2 == -1 {
return "", "", s, false
diff --git a/services/gitdiff/highlightdiff_test.go b/services/gitdiff/highlightdiff_test.go
index 0070173b9f..2ff4472bcc 100644
--- a/services/gitdiff/highlightdiff_test.go
+++ b/services/gitdiff/highlightdiff_test.go
@@ -43,7 +43,7 @@ func TestDiffWithHighlight(t *testing.T) {
diff.Text = "C"
hcd.recoverOneDiff(&diff)
- assert.Empty(t, diff.Text)
+ assert.Equal(t, "", diff.Text)
}
func TestDiffWithHighlightPlaceholder(t *testing.T) {
@@ -53,8 +53,8 @@ func TestDiffWithHighlightPlaceholder(t *testing.T) {
"a='\U00100000'",
"a='\U0010FFFD''",
)
- assert.Empty(t, hcd.PlaceholderTokenMap[0x00100000])
- assert.Empty(t, hcd.PlaceholderTokenMap[0x0010FFFD])
+ assert.Equal(t, "", hcd.PlaceholderTokenMap[0x00100000])
+ assert.Equal(t, "", hcd.PlaceholderTokenMap[0x0010FFFD])
expected := fmt.Sprintf(`a = ' %s '`, "\U00100000")
output := diffToHTML(hcd.lineWrapperTags, diffs, DiffLineDel)
diff --git a/services/gitdiff/main_test.go b/services/gitdiff/main_test.go
index cd7a6a4a6b..3d4d480530 100644
--- a/services/gitdiff/main_test.go
+++ b/services/gitdiff/main_test.go
@@ -6,12 +6,12 @@ package gitdiff
import (
"testing"
- "forgejo.org/models/unittest"
+ "code.gitea.io/gitea/models/unittest"
- _ "forgejo.org/models"
- _ "forgejo.org/models/actions"
- _ "forgejo.org/models/activities"
- _ "forgejo.org/models/forgefed"
+ _ "code.gitea.io/gitea/models"
+ _ "code.gitea.io/gitea/models/actions"
+ _ "code.gitea.io/gitea/models/activities"
+ _ "code.gitea.io/gitea/models/forgefed"
)
func TestMain(m *testing.M) {
diff --git a/services/indexer/indexer.go b/services/indexer/indexer.go
index 92036f95c3..38dd012a51 100644
--- a/services/indexer/indexer.go
+++ b/services/indexer/indexer.go
@@ -4,10 +4,10 @@
package indexer
import (
- code_indexer "forgejo.org/modules/indexer/code"
- issue_indexer "forgejo.org/modules/indexer/issues"
- stats_indexer "forgejo.org/modules/indexer/stats"
- notify_service "forgejo.org/services/notify"
+ code_indexer "code.gitea.io/gitea/modules/indexer/code"
+ issue_indexer "code.gitea.io/gitea/modules/indexer/issues"
+ stats_indexer "code.gitea.io/gitea/modules/indexer/stats"
+ notify_service "code.gitea.io/gitea/services/notify"
)
// Init initialize the repo indexer
diff --git a/services/indexer/notify.go b/services/indexer/notify.go
index ddd89f733c..e2cfe477d3 100644
--- a/services/indexer/notify.go
+++ b/services/indexer/notify.go
@@ -6,16 +6,16 @@ package indexer
import (
"context"
- issues_model "forgejo.org/models/issues"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- code_indexer "forgejo.org/modules/indexer/code"
- issue_indexer "forgejo.org/modules/indexer/issues"
- stats_indexer "forgejo.org/modules/indexer/stats"
- "forgejo.org/modules/log"
- "forgejo.org/modules/repository"
- "forgejo.org/modules/setting"
- notify_service "forgejo.org/services/notify"
+ issues_model "code.gitea.io/gitea/models/issues"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ code_indexer "code.gitea.io/gitea/modules/indexer/code"
+ issue_indexer "code.gitea.io/gitea/modules/indexer/issues"
+ stats_indexer "code.gitea.io/gitea/modules/indexer/stats"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/repository"
+ "code.gitea.io/gitea/modules/setting"
+ notify_service "code.gitea.io/gitea/services/notify"
)
type indexerNotifier struct {
diff --git a/services/issue/assignee.go b/services/issue/assignee.go
index a5f9c2731f..3d6d0b881a 100644
--- a/services/issue/assignee.go
+++ b/services/issue/assignee.go
@@ -6,15 +6,15 @@ package issue
import (
"context"
- issues_model "forgejo.org/models/issues"
- "forgejo.org/models/organization"
- "forgejo.org/models/perm"
- access_model "forgejo.org/models/perm/access"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unit"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/log"
- notify_service "forgejo.org/services/notify"
+ issues_model "code.gitea.io/gitea/models/issues"
+ "code.gitea.io/gitea/models/organization"
+ "code.gitea.io/gitea/models/perm"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unit"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/log"
+ notify_service "code.gitea.io/gitea/services/notify"
)
// DeleteNotPassedAssignee deletes all assignees who aren't passed via the "assignees" array
diff --git a/services/issue/assignee_test.go b/services/issue/assignee_test.go
index 66a66459cb..2b70b8c8ce 100644
--- a/services/issue/assignee_test.go
+++ b/services/issue/assignee_test.go
@@ -6,10 +6,10 @@ package issue
import (
"testing"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- "forgejo.org/models/unittest"
- user_model "forgejo.org/models/user"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ "code.gitea.io/gitea/models/unittest"
+ user_model "code.gitea.io/gitea/models/user"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
diff --git a/services/issue/comments.go b/services/issue/comments.go
index 2cac900d41..3ab577b83f 100644
--- a/services/issue/comments.go
+++ b/services/issue/comments.go
@@ -5,21 +5,20 @@ package issue
import (
"context"
- "errors"
"fmt"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/timeutil"
- notify_service "forgejo.org/services/notify"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/timeutil"
+ notify_service "code.gitea.io/gitea/services/notify"
)
// CreateRefComment creates a commit reference comment to issue.
func CreateRefComment(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, issue *issues_model.Issue, content, commitSHA string) error {
if len(commitSHA) == 0 {
- return errors.New("cannot create reference with empty commit SHA")
+ return fmt.Errorf("cannot create reference with empty commit SHA")
}
// Check if same reference from same commit has already existed.
@@ -120,28 +119,7 @@ func UpdateComment(ctx context.Context, c *issues_model.Comment, contentVersion
// DeleteComment deletes the comment
func DeleteComment(ctx context.Context, doer *user_model.User, comment *issues_model.Comment) error {
err := db.WithTx(ctx, func(ctx context.Context) error {
- reviewID := comment.ReviewID
-
- err := issues_model.DeleteComment(ctx, comment)
- if err != nil {
- return err
- }
-
- if comment.Review != nil {
- reviewType := comment.Review.Type
- if reviewType == issues_model.ReviewTypePending {
- found, err := db.GetEngine(ctx).Table("comment").Where("review_id = ?", reviewID).Exist()
- if err != nil {
- return err
- } else if !found {
- _, err := db.GetEngine(ctx).Table("review").Where("id = ?", reviewID).Delete()
- if err != nil {
- return err
- }
- }
- }
- }
- return nil
+ return issues_model.DeleteComment(ctx, comment)
})
if err != nil {
return err
diff --git a/services/issue/comments_test.go b/services/issue/comments_test.go
index fcf06d9ec8..62547a584a 100644
--- a/services/issue/comments_test.go
+++ b/services/issue/comments_test.go
@@ -6,19 +6,17 @@ package issue_test
import (
"testing"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- "forgejo.org/models/moderation"
- "forgejo.org/models/unittest"
- user_model "forgejo.org/models/user"
- webhook_model "forgejo.org/models/webhook"
- "forgejo.org/modules/json"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/test"
- issue_service "forgejo.org/services/issue"
- "forgejo.org/tests"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ "code.gitea.io/gitea/models/unittest"
+ user_model "code.gitea.io/gitea/models/user"
+ webhook_model "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/test"
+ issue_service "code.gitea.io/gitea/services/issue"
+ "code.gitea.io/gitea/tests"
- _ "forgejo.org/services/webhook"
+ _ "code.gitea.io/gitea/services/webhook"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -50,9 +48,9 @@ func TestDeleteComment(t *testing.T) {
// Reactions don't exist anymore for this comment.
unittest.AssertNotExistsBean(t, &issues_model.Reaction{CommentID: comment.ID})
// Number of comments was decreased.
- assert.Equal(t, issue.NumComments-1, unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID}).NumComments)
+ assert.EqualValues(t, issue.NumComments-1, unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID}).NumComments)
// A notification was fired for the deletion of this comment.
- assert.Equal(t, hookTaskCount+1, unittest.GetCount(t, &webhook_model.HookTask{}))
+ assert.EqualValues(t, hookTaskCount+1, unittest.GetCount(t, &webhook_model.HookTask{}))
})
t.Run("Comment of pending review", func(t *testing.T) {
@@ -61,7 +59,7 @@ func TestDeleteComment(t *testing.T) {
// We have to ensure that this comment's linked review is pending.
comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 4}, "review_id != 0")
review := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: comment.ReviewID})
- assert.Equal(t, issues_model.ReviewTypePending, review.Type)
+ assert.EqualValues(t, issues_model.ReviewTypePending, review.Type)
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID})
require.NoError(t, webhook_model.CreateWebhook(db.DefaultContext, &webhook_model.Webhook{
@@ -71,17 +69,14 @@ func TestDeleteComment(t *testing.T) {
}))
hookTaskCount := unittest.GetCount(t, &webhook_model.HookTask{})
- require.NoError(t, comment.LoadReview(t.Context()))
require.NoError(t, issue_service.DeleteComment(db.DefaultContext, nil, comment))
// The comment doesn't exist anymore.
unittest.AssertNotExistsBean(t, &issues_model.Comment{ID: comment.ID})
// Ensure that the number of comments wasn't decreased.
- assert.Equal(t, issue.NumComments, unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID}).NumComments)
+ assert.EqualValues(t, issue.NumComments, unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID}).NumComments)
// No notification was fired for the deletion of this comment.
- assert.Equal(t, hookTaskCount, unittest.GetCount(t, &webhook_model.HookTask{}))
- // The review doesn't exist anymore.
- unittest.AssertNotExistsBean(t, &issues_model.Review{ID: comment.ReviewID})
+ assert.EqualValues(t, hookTaskCount, unittest.GetCount(t, &webhook_model.HookTask{}))
})
}
@@ -110,11 +105,11 @@ func TestUpdateComment(t *testing.T) {
newComment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 2})
// Content was updated.
- assert.Equal(t, comment.Content, newComment.Content)
+ assert.EqualValues(t, comment.Content, newComment.Content)
// Content version was updated.
- assert.Equal(t, 2, newComment.ContentVersion)
+ assert.EqualValues(t, 2, newComment.ContentVersion)
// A notification was fired for the update of this comment.
- assert.Equal(t, hookTaskCount+1, unittest.GetCount(t, &webhook_model.HookTask{}))
+ assert.EqualValues(t, hookTaskCount+1, unittest.GetCount(t, &webhook_model.HookTask{}))
// Issue history was saved for this comment.
unittest.AssertExistsAndLoadBean(t, &issues_model.ContentHistory{CommentID: comment.ID, IsFirstCreated: true, ContentText: oldContent})
unittest.AssertExistsAndLoadBean(t, &issues_model.ContentHistory{CommentID: comment.ID, ContentText: comment.Content}, "is_first_created = false")
@@ -125,7 +120,7 @@ func TestUpdateComment(t *testing.T) {
comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 4}, "review_id != 0")
review := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: comment.ReviewID})
- assert.Equal(t, issues_model.ReviewTypePending, review.Type)
+ assert.EqualValues(t, issues_model.ReviewTypePending, review.Type)
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID})
unittest.AssertNotExistsBean(t, &issues_model.ContentHistory{CommentID: comment.ID})
require.NoError(t, webhook_model.CreateWebhook(db.DefaultContext, &webhook_model.Webhook{
@@ -141,49 +136,12 @@ func TestUpdateComment(t *testing.T) {
newComment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 2})
// Content was updated.
- assert.Equal(t, comment.Content, newComment.Content)
+ assert.EqualValues(t, comment.Content, newComment.Content)
// Content version was updated.
- assert.Equal(t, 2, newComment.ContentVersion)
+ assert.EqualValues(t, 2, newComment.ContentVersion)
// No notification was fired for the update of this comment.
- assert.Equal(t, hookTaskCount, unittest.GetCount(t, &webhook_model.HookTask{}))
+ assert.EqualValues(t, hookTaskCount, unittest.GetCount(t, &webhook_model.HookTask{}))
// Issue history was not saved for this comment.
unittest.AssertNotExistsBean(t, &issues_model.ContentHistory{CommentID: comment.ID})
})
}
-
-func TestCreateShadowCopyOnCommentUpdate(t *testing.T) {
- defer unittest.OverrideFixtures("models/fixtures/ModerationFeatures")()
- require.NoError(t, unittest.PrepareTestDatabase())
-
- userAlexSmithID := int64(1002)
- spamCommentID := int64(18) // posted by @alexsmith
- abuseReportID := int64(1) // submitted for above comment
- newCommentContent := "If anyone needs help, just contact me."
-
- // Retrieve the abusive user (@alexsmith), their SPAM comment and the abuse report already created for this comment.
- poster := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: userAlexSmithID})
- comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: spamCommentID, PosterID: poster.ID})
- report := unittest.AssertExistsAndLoadBean(t, &moderation.AbuseReport{
- ID: abuseReportID,
- ContentType: moderation.ReportedContentTypeComment,
- ContentID: comment.ID,
- })
- // The report should not already have a shadow copy linked.
- assert.False(t, report.ShadowCopyID.Valid)
-
- // The abusive user is updating their comment.
- oldContent := comment.Content
- comment.Content = newCommentContent
- require.NoError(t, issue_service.UpdateComment(t.Context(), comment, 0, poster, oldContent))
-
- // Reload the report.
- report = unittest.AssertExistsAndLoadBean(t, &moderation.AbuseReport{ID: report.ID})
- // A shadow copy should have been created and linked to our report.
- assert.True(t, report.ShadowCopyID.Valid)
- // Retrieve the newly created shadow copy and unmarshal the stored JSON so that we can check the values.
- shadowCopy := unittest.AssertExistsAndLoadBean(t, &moderation.AbuseReportShadowCopy{ID: report.ShadowCopyID.Int64})
- shadowCopyCommentData := new(issues_model.CommentData)
- require.NoError(t, json.Unmarshal([]byte(shadowCopy.RawValue), &shadowCopyCommentData))
- // Check to see if the initial content of the comment was stored within the shadow copy.
- assert.Equal(t, oldContent, shadowCopyCommentData.Content)
-}
diff --git a/services/issue/commit.go b/services/issue/commit.go
index 1e51fb32b7..8b927d52b6 100644
--- a/services/issue/commit.go
+++ b/services/issue/commit.go
@@ -13,15 +13,15 @@ import (
"strings"
"time"
- issues_model "forgejo.org/models/issues"
- access_model "forgejo.org/models/perm/access"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/container"
- "forgejo.org/modules/git"
- "forgejo.org/modules/log"
- "forgejo.org/modules/references"
- "forgejo.org/modules/repository"
+ issues_model "code.gitea.io/gitea/models/issues"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/container"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/references"
+ "code.gitea.io/gitea/modules/repository"
)
const (
diff --git a/services/issue/commit_test.go b/services/issue/commit_test.go
index e3a41d2305..c3c3e4c042 100644
--- a/services/issue/commit_test.go
+++ b/services/issue/commit_test.go
@@ -6,14 +6,14 @@ package issue
import (
"testing"
- activities_model "forgejo.org/models/activities"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unittest"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/repository"
- "forgejo.org/modules/setting"
+ activities_model "code.gitea.io/gitea/models/activities"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unittest"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/repository"
+ "code.gitea.io/gitea/modules/setting"
"github.com/stretchr/testify/require"
)
diff --git a/services/issue/content.go b/services/issue/content.go
index d5c79e5fde..612a9a6b4c 100644
--- a/services/issue/content.go
+++ b/services/issue/content.go
@@ -6,9 +6,9 @@ package issue
import (
"context"
- issues_model "forgejo.org/models/issues"
- user_model "forgejo.org/models/user"
- notify_service "forgejo.org/services/notify"
+ issues_model "code.gitea.io/gitea/models/issues"
+ user_model "code.gitea.io/gitea/models/user"
+ notify_service "code.gitea.io/gitea/services/notify"
)
// ChangeContent changes issue content, as the given user.
diff --git a/services/issue/issue.go b/services/issue/issue.go
index 7071a912b0..5e726176d0 100644
--- a/services/issue/issue.go
+++ b/services/issue/issue.go
@@ -1,28 +1,26 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
-// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package issue
import (
"context"
- "errors"
"fmt"
"time"
- activities_model "forgejo.org/models/activities"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- access_model "forgejo.org/models/perm/access"
- project_model "forgejo.org/models/project"
- repo_model "forgejo.org/models/repo"
- system_model "forgejo.org/models/system"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/log"
- "forgejo.org/modules/storage"
- "forgejo.org/modules/timeutil"
- notify_service "forgejo.org/services/notify"
+ activities_model "code.gitea.io/gitea/models/activities"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ project_model "code.gitea.io/gitea/models/project"
+ repo_model "code.gitea.io/gitea/models/repo"
+ system_model "code.gitea.io/gitea/models/system"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/storage"
+ "code.gitea.io/gitea/modules/timeutil"
+ notify_service "code.gitea.io/gitea/services/notify"
)
// NewIssue creates new issue with labels for repository.
@@ -61,6 +59,7 @@ func NewIssue(ctx context.Context, repo *repo_model.Repository, issue *issues_mo
// ChangeTitle changes the title of this issue, as the given user.
func ChangeTitle(ctx context.Context, issue *issues_model.Issue, doer *user_model.User, title string) error {
oldTitle := issue.Title
+ issue.Title = title
if oldTitle == title {
return nil
@@ -74,12 +73,6 @@ func ChangeTitle(ctx context.Context, issue *issues_model.Issue, doer *user_mode
return user_model.ErrBlockedByUser
}
- // If the issue was reported as abusive, a shadow copy should be created before first update.
- if err := issues_model.IfNeededCreateShadowCopyForIssue(ctx, issue); err != nil {
- return err
- }
-
- issue.Title = title
if err := issues_model.ChangeIssueTitle(ctx, issue, doer, oldTitle); err != nil {
return err
}
@@ -259,12 +252,6 @@ func deleteIssue(ctx context.Context, issue *issues_model.Issue) error {
defer committer.Close()
e := db.GetEngine(ctx)
-
- // If the issue was reported as abusive, a shadow copy should be created before deletion.
- if err := issues_model.IfNeededCreateShadowCopyForIssue(ctx, issue); err != nil {
- return err
- }
-
if _, err := e.ID(issue.ID).NoAutoCondition().Delete(issue); err != nil {
return err
}
@@ -346,13 +333,13 @@ func SetIssueUpdateDate(ctx context.Context, issue *issues_model.Issue, updated
return err
}
if !perm.IsAdmin() && !perm.IsOwner() {
- return errors.New("user needs to have admin or owner right")
+ return fmt.Errorf("user needs to have admin or owner right")
}
// A simple guard against potential inconsistent calls
updatedUnix := timeutil.TimeStamp(updated.Unix())
if updatedUnix < issue.CreatedUnix || updatedUnix > timeutil.TimeStampNow() {
- return errors.New("unallowed update date")
+ return fmt.Errorf("unallowed update date")
}
issue.UpdatedUnix = updatedUnix
diff --git a/services/issue/issue_test.go b/services/issue/issue_test.go
index fb2b2870bd..a0bb88e387 100644
--- a/services/issue/issue_test.go
+++ b/services/issue/issue_test.go
@@ -6,11 +6,11 @@ package issue
import (
"testing"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unittest"
- user_model "forgejo.org/models/user"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unittest"
+ user_model "code.gitea.io/gitea/models/user"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -25,8 +25,8 @@ func TestGetRefEndNamesAndURLs(t *testing.T) {
repoLink := "/foo/bar"
endNames, urls := GetRefEndNamesAndURLs(issues, repoLink)
- assert.Equal(t, map[int64]string{1: "branch1", 2: "tag1", 3: "c0ffee"}, endNames)
- assert.Equal(t, map[int64]string{
+ assert.EqualValues(t, map[int64]string{1: "branch1", 2: "tag1", 3: "c0ffee"}, endNames)
+ assert.EqualValues(t, map[int64]string{
1: repoLink + "/src/branch/branch1",
2: repoLink + "/src/tag/tag1",
3: repoLink + "/src/commit/c0ffee",
diff --git a/services/issue/label.go b/services/issue/label.go
index f18dd67a19..6b8070d8aa 100644
--- a/services/issue/label.go
+++ b/services/issue/label.go
@@ -6,10 +6,11 @@ package issue
import (
"context"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- user_model "forgejo.org/models/user"
- notify_service "forgejo.org/services/notify"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ user_model "code.gitea.io/gitea/models/user"
+ notify_service "code.gitea.io/gitea/services/notify"
)
// ClearLabels clears all of an issue's labels
@@ -55,6 +56,17 @@ func RemoveLabel(ctx context.Context, issue *issues_model.Issue, doer *user_mode
return err
}
+ perm, err := access_model.GetUserRepoPermission(dbCtx, issue.Repo, doer)
+ if err != nil {
+ return err
+ }
+ if !perm.CanWriteIssuesOrPulls(issue.IsPull) {
+ if label.OrgID > 0 {
+ return issues_model.ErrOrgLabelNotExist{}
+ }
+ return issues_model.ErrRepoLabelNotExist{}
+ }
+
if err := issues_model.DeleteIssueLabel(dbCtx, issue, label, doer); err != nil {
return err
}
diff --git a/services/issue/label_test.go b/services/issue/label_test.go
index 73a028684b..b9d26345c1 100644
--- a/services/issue/label_test.go
+++ b/services/issue/label_test.go
@@ -6,10 +6,10 @@ package issue
import (
"testing"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- "forgejo.org/models/unittest"
- user_model "forgejo.org/models/user"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ "code.gitea.io/gitea/models/unittest"
+ user_model "code.gitea.io/gitea/models/user"
"github.com/stretchr/testify/require"
)
diff --git a/services/issue/main_test.go b/services/issue/main_test.go
index 673ec5e4cc..c3da441537 100644
--- a/services/issue/main_test.go
+++ b/services/issue/main_test.go
@@ -6,11 +6,11 @@ package issue
import (
"testing"
- "forgejo.org/models/unittest"
- "forgejo.org/modules/setting"
- "forgejo.org/services/webhook"
+ "code.gitea.io/gitea/models/unittest"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/services/webhook"
- _ "forgejo.org/models/actions"
+ _ "code.gitea.io/gitea/models/actions"
)
func TestMain(m *testing.M) {
diff --git a/services/issue/milestone.go b/services/issue/milestone.go
index a561bf8eee..407ad0a59b 100644
--- a/services/issue/milestone.go
+++ b/services/issue/milestone.go
@@ -5,13 +5,12 @@ package issue
import (
"context"
- "errors"
"fmt"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- user_model "forgejo.org/models/user"
- notify_service "forgejo.org/services/notify"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ user_model "code.gitea.io/gitea/models/user"
+ notify_service "code.gitea.io/gitea/services/notify"
)
func updateMilestoneCounters(ctx context.Context, issue *issues_model.Issue, id int64) error {
@@ -48,7 +47,7 @@ func changeMilestoneAssign(ctx context.Context, doer *user_model.User, issue *is
return fmt.Errorf("HasMilestoneByRepoID: %w", err)
}
if !has {
- return errors.New("HasMilestoneByRepoID: issue doesn't exist")
+ return fmt.Errorf("HasMilestoneByRepoID: issue doesn't exist")
}
}
diff --git a/services/issue/milestone_test.go b/services/issue/milestone_test.go
index 4123433c2a..e75f64550c 100644
--- a/services/issue/milestone_test.go
+++ b/services/issue/milestone_test.go
@@ -6,10 +6,10 @@ package issue
import (
"testing"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- "forgejo.org/models/unittest"
- user_model "forgejo.org/models/user"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ "code.gitea.io/gitea/models/unittest"
+ user_model "code.gitea.io/gitea/models/user"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
diff --git a/services/issue/pull.go b/services/issue/pull.go
index 6245344ccb..3b61c00afa 100644
--- a/services/issue/pull.go
+++ b/services/issue/pull.go
@@ -8,15 +8,15 @@ import (
"fmt"
"time"
- issues_model "forgejo.org/models/issues"
- org_model "forgejo.org/models/organization"
- access_model "forgejo.org/models/perm/access"
- "forgejo.org/models/unit"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
+ issues_model "code.gitea.io/gitea/models/issues"
+ org_model "code.gitea.io/gitea/models/organization"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ "code.gitea.io/gitea/models/unit"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
)
func getMergeBase(repo *git.Repository, pr *issues_model.PullRequest, baseBranch, headBranch string) (string, error) {
@@ -43,6 +43,8 @@ type ReviewRequestNotifier struct {
}
func PullRequestCodeOwnersReview(ctx context.Context, issue *issues_model.Issue, pr *issues_model.PullRequest) ([]*ReviewRequestNotifier, error) {
+ files := []string{"CODEOWNERS", "docs/CODEOWNERS", ".gitea/CODEOWNERS"}
+
if pr.IsWorkInProgress(ctx) {
return nil, nil
}
@@ -70,17 +72,18 @@ func PullRequestCodeOwnersReview(ctx context.Context, issue *issues_model.Issue,
return nil, err
}
- var rules []*issues_model.CodeOwnerRule
- for _, file := range []string{"CODEOWNERS", "docs/CODEOWNERS", ".gitea/CODEOWNERS", ".forgejo/CODEOWNERS"} {
+ var data string
+ for _, file := range files {
if blob, err := commit.GetBlobByPath(file); err == nil {
- rc, size, err := blob.NewTruncatedReader(setting.UI.MaxDisplayFileSize)
+ data, err = blob.GetBlobContent(setting.UI.MaxDisplayFileSize)
if err == nil {
- rules, _ = issues_model.GetCodeOwnersFromReader(ctx, rc, size > setting.UI.MaxDisplayFileSize)
break
}
}
}
+ rules, _ := issues_model.GetCodeOwnersFromContent(ctx, data)
+
// get the mergebase
mergeBase, err := getMergeBase(repo, pr, git.BranchPrefix+pr.BaseBranch, pr.GetGitRefName())
if err != nil {
diff --git a/services/issue/reaction.go b/services/issue/reaction.go
index c6a11aa0f0..dbb4735de2 100644
--- a/services/issue/reaction.go
+++ b/services/issue/reaction.go
@@ -5,8 +5,8 @@ package issue
import (
"context"
- issues_model "forgejo.org/models/issues"
- user_model "forgejo.org/models/user"
+ issues_model "code.gitea.io/gitea/models/issues"
+ user_model "code.gitea.io/gitea/models/user"
)
// CreateIssueReaction creates a reaction on issue.
diff --git a/services/issue/status.go b/services/issue/status.go
index 6664da7daa..9b6c683f4f 100644
--- a/services/issue/status.go
+++ b/services/issue/status.go
@@ -6,10 +6,10 @@ package issue
import (
"context"
- issues_model "forgejo.org/models/issues"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/log"
- notify_service "forgejo.org/services/notify"
+ issues_model "code.gitea.io/gitea/models/issues"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/log"
+ notify_service "code.gitea.io/gitea/services/notify"
)
// ChangeStatus changes issue status to open or closed.
diff --git a/services/issue/template.go b/services/issue/template.go
index 07f59af630..9a2b048401 100644
--- a/services/issue/template.go
+++ b/services/issue/template.go
@@ -10,13 +10,13 @@ import (
"path"
"strings"
- "forgejo.org/models/repo"
- "forgejo.org/modules/git"
- "forgejo.org/modules/issue/template"
- "forgejo.org/modules/log"
- api "forgejo.org/modules/structs"
+ "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/issue/template"
+ "code.gitea.io/gitea/modules/log"
+ api "code.gitea.io/gitea/modules/structs"
- "go.yaml.in/yaml/v3"
+ "gopkg.in/yaml.v3"
)
// templateDirCandidates issue templates directory
@@ -31,8 +31,6 @@ var templateDirCandidates = []string{
".github/issue_template",
".gitlab/ISSUE_TEMPLATE",
".gitlab/issue_template",
- "docs/ISSUE_TEMPLATE",
- "docs/issue_template",
}
var templateConfigCandidates = []string{
@@ -42,8 +40,6 @@ var templateConfigCandidates = []string{
".gitea/issue_template/config",
".github/ISSUE_TEMPLATE/config",
".github/issue_template/config",
- "docs/ISSUE_TEMPLATE/config",
- "docs/issue_template/config",
}
func GetDefaultTemplateConfig() api.IssueConfig {
diff --git a/services/lfs/locks.go b/services/lfs/locks.go
index a45b2cc93b..2a362b1c0d 100644
--- a/services/lfs/locks.go
+++ b/services/lfs/locks.go
@@ -8,16 +8,16 @@ import (
"strconv"
"strings"
- auth_model "forgejo.org/models/auth"
- git_model "forgejo.org/models/git"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/modules/json"
- lfs_module "forgejo.org/modules/lfs"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- api "forgejo.org/modules/structs"
- "forgejo.org/services/context"
- "forgejo.org/services/convert"
+ auth_model "code.gitea.io/gitea/models/auth"
+ git_model "code.gitea.io/gitea/models/git"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/modules/json"
+ lfs_module "code.gitea.io/gitea/modules/lfs"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ api "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/convert"
)
func handleLockListOut(ctx *context.Context, repo *repo_model.Repository, lock *git_model.LFSLock, err error) {
diff --git a/services/lfs/server.go b/services/lfs/server.go
index 17e6d0eec7..51d6f42776 100644
--- a/services/lfs/server.go
+++ b/services/lfs/server.go
@@ -18,21 +18,21 @@ import (
"strconv"
"strings"
- actions_model "forgejo.org/models/actions"
- auth_model "forgejo.org/models/auth"
- git_model "forgejo.org/models/git"
- "forgejo.org/models/perm"
- access_model "forgejo.org/models/perm/access"
- quota_model "forgejo.org/models/quota"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unit"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/json"
- lfs_module "forgejo.org/modules/lfs"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/storage"
- "forgejo.org/services/context"
+ actions_model "code.gitea.io/gitea/models/actions"
+ auth_model "code.gitea.io/gitea/models/auth"
+ git_model "code.gitea.io/gitea/models/git"
+ "code.gitea.io/gitea/models/perm"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ quota_model "code.gitea.io/gitea/models/quota"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unit"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/json"
+ lfs_module "code.gitea.io/gitea/modules/lfs"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/storage"
+ "code.gitea.io/gitea/services/context"
"github.com/golang-jwt/jwt/v5"
)
@@ -163,12 +163,11 @@ func BatchHandler(ctx *context.Context) {
}
var isUpload bool
- switch br.Operation {
- case "upload":
+ if br.Operation == "upload" {
isUpload = true
- case "download":
+ } else if br.Operation == "download" {
isUpload = false
- default:
+ } else {
log.Trace("Attempt to BATCH with invalid operation: %s", br.Operation)
writeStatus(ctx, http.StatusBadRequest)
return
@@ -595,15 +594,15 @@ func handleLFSToken(ctx stdCtx.Context, tokenSHA string, target *repo_model.Repo
claims, claimsOk := token.Claims.(*Claims)
if !token.Valid || !claimsOk {
- return nil, errors.New("invalid token claim")
+ return nil, fmt.Errorf("invalid token claim")
}
if claims.RepoID != target.ID {
- return nil, errors.New("invalid token claim")
+ return nil, fmt.Errorf("invalid token claim")
}
if mode == perm.AccessModeWrite && claims.Op != "upload" {
- return nil, errors.New("invalid token claim")
+ return nil, fmt.Errorf("invalid token claim")
}
u, err := user_model.GetUserByID(ctx, claims.UserID)
@@ -616,12 +615,12 @@ func handleLFSToken(ctx stdCtx.Context, tokenSHA string, target *repo_model.Repo
func parseToken(ctx stdCtx.Context, authorization string, target *repo_model.Repository, mode perm.AccessMode) (*user_model.User, error) {
if authorization == "" {
- return nil, errors.New("no token")
+ return nil, fmt.Errorf("no token")
}
parts := strings.SplitN(authorization, " ", 2)
if len(parts) != 2 {
- return nil, errors.New("no token")
+ return nil, fmt.Errorf("no token")
}
tokenSHA := parts[1]
switch strings.ToLower(parts[0]) {
@@ -630,7 +629,7 @@ func parseToken(ctx stdCtx.Context, authorization string, target *repo_model.Rep
case "token":
return handleLFSToken(ctx, tokenSHA, target, mode)
}
- return nil, errors.New("token not found")
+ return nil, fmt.Errorf("token not found")
}
func requireAuth(ctx *context.Context) {
diff --git a/services/mailer/incoming/incoming.go b/services/mailer/incoming/incoming.go
index b1b9191df3..1b1be4c656 100644
--- a/services/mailer/incoming/incoming.go
+++ b/services/mailer/incoming/incoming.go
@@ -14,10 +14,10 @@ import (
"strings"
"time"
- "forgejo.org/modules/log"
- "forgejo.org/modules/process"
- "forgejo.org/modules/setting"
- "forgejo.org/services/mailer/token"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/process"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/services/mailer/token"
"code.forgejo.org/forgejo/reply"
"github.com/emersion/go-imap"
diff --git a/services/mailer/incoming/incoming_handler.go b/services/mailer/incoming/incoming_handler.go
index 7505148978..dc3c4ec69b 100644
--- a/services/mailer/incoming/incoming_handler.go
+++ b/services/mailer/incoming/incoming_handler.go
@@ -8,19 +8,19 @@ import (
"context"
"fmt"
- issues_model "forgejo.org/models/issues"
- access_model "forgejo.org/models/perm/access"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/util"
- attachment_service "forgejo.org/services/attachment"
- "forgejo.org/services/context/upload"
- issue_service "forgejo.org/services/issue"
- incoming_payload "forgejo.org/services/mailer/incoming/payload"
- "forgejo.org/services/mailer/token"
- pull_service "forgejo.org/services/pull"
+ issues_model "code.gitea.io/gitea/models/issues"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/util"
+ attachment_service "code.gitea.io/gitea/services/attachment"
+ "code.gitea.io/gitea/services/context/upload"
+ issue_service "code.gitea.io/gitea/services/issue"
+ incoming_payload "code.gitea.io/gitea/services/mailer/incoming/payload"
+ "code.gitea.io/gitea/services/mailer/token"
+ pull_service "code.gitea.io/gitea/services/pull"
)
type MailHandler interface {
diff --git a/services/mailer/incoming/payload/payload.go b/services/mailer/incoming/payload/payload.go
index bb7a65e3d5..00ada7826b 100644
--- a/services/mailer/incoming/payload/payload.go
+++ b/services/mailer/incoming/payload/payload.go
@@ -6,8 +6,8 @@ package payload
import (
"context"
- issues_model "forgejo.org/models/issues"
- "forgejo.org/modules/util"
+ issues_model "code.gitea.io/gitea/models/issues"
+ "code.gitea.io/gitea/modules/util"
)
const replyPayloadVersion1 byte = 1
diff --git a/services/mailer/mail.go b/services/mailer/mail.go
index 410fdf6894..bfede28bbe 100644
--- a/services/mailer/mail.go
+++ b/services/mailer/mail.go
@@ -16,21 +16,21 @@ import (
texttmpl "text/template"
"time"
- activities_model "forgejo.org/models/activities"
- auth_model "forgejo.org/models/auth"
- issues_model "forgejo.org/models/issues"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/base"
- "forgejo.org/modules/emoji"
- "forgejo.org/modules/log"
- "forgejo.org/modules/markup"
- "forgejo.org/modules/markup/markdown"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/timeutil"
- "forgejo.org/modules/translation"
- incoming_payload "forgejo.org/services/mailer/incoming/payload"
- "forgejo.org/services/mailer/token"
+ activities_model "code.gitea.io/gitea/models/activities"
+ auth_model "code.gitea.io/gitea/models/auth"
+ issues_model "code.gitea.io/gitea/models/issues"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/emoji"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/markup"
+ "code.gitea.io/gitea/modules/markup/markdown"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/timeutil"
+ "code.gitea.io/gitea/modules/translation"
+ incoming_payload "code.gitea.io/gitea/services/mailer/incoming/payload"
+ "code.gitea.io/gitea/services/mailer/token"
"gopkg.in/gomail.v2"
)
@@ -685,14 +685,19 @@ func SendRemovedSecurityKey(ctx context.Context, u *user_model.User, securityKey
}
locale := translation.NewLocale(u.Language)
- hasTwoFactor, err := auth_model.HasTwoFactorByUID(ctx, u.ID)
+ hasWebAuthn, err := auth_model.HasWebAuthnRegistrationsByUID(ctx, u.ID)
+ if err != nil {
+ return err
+ }
+ hasTOTP, err := auth_model.HasTwoFactorByUID(ctx, u.ID)
if err != nil {
return err
}
data := map[string]any{
"locale": locale,
- "HasTwoFactor": hasTwoFactor,
+ "HasWebAuthn": hasWebAuthn,
+ "HasTOTP": hasTOTP,
"SecurityKeyName": securityKeyName,
"DisplayName": u.DisplayName(),
"Username": u.Name,
diff --git a/services/mailer/mail_actions.go b/services/mailer/mail_actions.go
deleted file mode 100644
index 1119781613..0000000000
--- a/services/mailer/mail_actions.go
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2025 The Forgejo Authors. All rights reserved.
-// SPDX-License-Identifier: GPL-3.0-or-later
-package mailer
-
-import (
- "bytes"
-
- actions_model "forgejo.org/models/actions"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/base"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/translation"
-)
-
-const (
- tplActionNowDone base.TplName = "actions/now_done"
-)
-
-var MailActionRun = mailActionRun // make it mockable
-func mailActionRun(run *actions_model.ActionRun, priorStatus actions_model.Status, lastRun *actions_model.ActionRun) error {
- if setting.MailService == nil {
- // No mail service configured
- return nil
- }
-
- if !run.NotifyEmail {
- return nil
- }
-
- user := run.TriggerUser
- // this happens e.g. when this is a scheduled run
- if user.IsSystem() {
- user = run.Repo.Owner
- }
- if user.IsSystem() || user.Email == "" {
- return nil
- }
-
- if user.EmailNotificationsPreference == user_model.EmailNotificationsDisabled {
- return nil
- }
-
- return sendMailActionRun(user, run, priorStatus, lastRun)
-}
-
-func sendMailActionRun(to *user_model.User, run *actions_model.ActionRun, priorStatus actions_model.Status, lastRun *actions_model.ActionRun) error {
- var (
- locale = translation.NewLocale(to.Language)
- content bytes.Buffer
- )
-
- var subject string
- if run.Status.IsSuccess() {
- subject = locale.TrString("mail.actions.successful_run_after_failure_subject", run.Title, run.Repo.FullName())
- } else {
- subject = locale.TrString("mail.actions.not_successful_run_subject", run.Title, run.Repo.FullName())
- }
-
- commitSHA := run.CommitSHA
- if len(commitSHA) > 7 {
- commitSHA = commitSHA[:7]
- }
-
- data := map[string]any{
- "locale": locale,
- "Link": run.HTMLURL(),
- "Subject": subject,
- "Language": locale.Language(),
- "RepoFullName": run.Repo.FullName(),
- "Run": run,
- "TriggerUserLink": run.TriggerUser.HTMLURL(),
- "LastRun": lastRun,
- "PriorStatus": priorStatus,
- "CommitSHA": commitSHA,
- "IsSuccess": run.Status.IsSuccess(),
- }
-
- if err := bodyTemplates.ExecuteTemplate(&content, string(tplActionNowDone), data); err != nil {
- return err
- }
-
- msg := NewMessage(to.EmailTo(), subject, content.String())
- msg.Info = subject
- SendAsync(msg)
-
- return nil
-}
diff --git a/services/mailer/mail_actions_now_done_test.go b/services/mailer/mail_actions_now_done_test.go
deleted file mode 100644
index e84441f460..0000000000
--- a/services/mailer/mail_actions_now_done_test.go
+++ /dev/null
@@ -1,325 +0,0 @@
-// Copyright 2025 The Forgejo Authors. All rights reserved.
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-package mailer
-
-import (
- "slices"
- "testing"
-
- actions_model "forgejo.org/models/actions"
- "forgejo.org/models/db"
- organization_model "forgejo.org/models/organization"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/optional"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/test"
- notify_service "forgejo.org/services/notify"
-
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
-)
-
-func getActionsNowDoneTestUser(t *testing.T, name, email, notifications string) *user_model.User {
- t.Helper()
- user := new(user_model.User)
- user.Name = name
- user.Language = "en_US"
- user.IsAdmin = false
- user.Email = email
- user.LastLoginUnix = 1693648327
- user.CreatedUnix = 1693648027
- opts := user_model.CreateUserOverwriteOptions{
- AllowCreateOrganization: optional.Some(true),
- EmailNotificationsPreference: ¬ifications,
- }
- require.NoError(t, user_model.AdminCreateUser(db.DefaultContext, user, &opts))
- return user
-}
-
-func getActionsNowDoneTestOrg(t *testing.T, name, email string, owner *user_model.User) *user_model.User {
- t.Helper()
- org := new(organization_model.Organization)
- org.Name = name
- org.Language = "en_US"
- org.IsAdmin = false
- // contact email for the organization, for display purposes but otherwise not used as of v12
- org.Email = email
- org.LastLoginUnix = 1693648327
- org.CreatedUnix = 1693648027
- org.Email = email
- require.NoError(t, organization_model.CreateOrganization(db.DefaultContext, org, owner))
- return (*user_model.User)(org)
-}
-
-func assertTranslatedLocaleMailActionsNowDone(t *testing.T, msgBody string) {
- AssertTranslatedLocale(t, msgBody, "mail.actions.successful_run_after_failure", "mail.actions.not_successful_run", "mail.actions.run_info_cur_status", "mail.actions.run_info_sha", "mail.actions.run_info_previous_status", "mail.actions.run_info_trigger", "mail.view_it_on")
-}
-
-func TestActionRunNowDoneStatusMatrix(t *testing.T) {
- successStatuses := []actions_model.Status{
- actions_model.StatusSuccess,
- actions_model.StatusSkipped,
- actions_model.StatusCancelled,
- }
- failureStatuses := []actions_model.Status{
- actions_model.StatusFailure,
- }
-
- for _, testCase := range []struct {
- name string
- statuses []actions_model.Status
- hasLastRun bool
- lastStatuses []actions_model.Status
- run bool
- }{
- {
- name: "FailureNoLastRun",
- statuses: failureStatuses,
- run: true,
- },
- {
- name: "SuccessNoLastRun",
- statuses: successStatuses,
- run: false,
- },
- {
- name: "FailureLastRunSuccess",
- statuses: failureStatuses,
- hasLastRun: true,
- lastStatuses: successStatuses,
- run: true,
- },
- {
- name: "FailureLastRunFailure",
- statuses: failureStatuses,
- hasLastRun: true,
- lastStatuses: failureStatuses,
- run: true,
- },
- {
- name: "SuccessLastRunFailure",
- statuses: successStatuses,
- hasLastRun: true,
- lastStatuses: failureStatuses,
- run: true,
- },
- {
- name: "SuccessLastRunSuccess",
- statuses: successStatuses,
- hasLastRun: true,
- lastStatuses: successStatuses,
- run: false,
- },
- } {
- t.Run(testCase.name, func(t *testing.T) {
- var called bool
- defer test.MockVariableValue(&MailActionRun, func(run *actions_model.ActionRun, priorStatus actions_model.Status, lastRun *actions_model.ActionRun) error {
- called = true
- return nil
- })()
- for _, status := range testCase.statuses {
- for _, lastStatus := range testCase.lastStatuses {
- called = false
- n := NewNotifier()
- var lastRun *actions_model.ActionRun
- if testCase.hasLastRun {
- lastRun = &actions_model.ActionRun{
- Status: lastStatus,
- }
- }
- n.ActionRunNowDone(t.Context(),
- &actions_model.ActionRun{
- Status: status,
- },
- actions_model.StatusUnknown,
- lastRun)
- assert.Equal(t, testCase.run, called, "status = %s, lastStatus = %s", status, lastStatus)
- }
- }
- })
- }
-}
-
-func TestActionRunNowDoneNotificationMail(t *testing.T) {
- ctx := t.Context()
-
- defer test.MockVariableValue(&setting.Admin.DisableRegularOrgCreation, false)()
-
- actionsUser := user_model.NewActionsUser()
- require.NotEmpty(t, actionsUser.Email)
-
- repo := repo_model.Repository{
- Name: "some repo",
- Description: "rockets are cool",
- }
-
- // Do some funky stuff with the action run's ids:
- // The run with the larger ID finished first.
- // This is odd but something that must work.
- run1 := &actions_model.ActionRun{ID: 2, Repo: &repo, RepoID: repo.ID, Title: "some workflow", Status: actions_model.StatusFailure, Stopped: 1745821796, TriggerEvent: "workflow_dispatch"}
- run2 := &actions_model.ActionRun{ID: 1, Repo: &repo, RepoID: repo.ID, Title: "some workflow", Status: actions_model.StatusSuccess, Stopped: 1745822796, TriggerEvent: "push"}
-
- assignUsers := func(triggerUser, owner *user_model.User) {
- for _, run := range []*actions_model.ActionRun{run1, run2} {
- run.TriggerUser = triggerUser
- run.TriggerUserID = triggerUser.ID
- run.NotifyEmail = true
- }
- repo.Owner = owner
- repo.OwnerID = owner.ID
- }
-
- notify_service.RegisterNotifier(NewNotifier())
-
- orgOwner := getActionsNowDoneTestUser(t, "org_owner", "org_owner@example.com", "disabled")
- defer CleanUpUsers(ctx, []*user_model.User{orgOwner})
-
- t.Run("DontSendNotificationEmailOnFirstActionSuccess", func(t *testing.T) {
- user := getActionsNowDoneTestUser(t, "new_user", "new_user@example.com", "enabled")
- defer CleanUpUsers(ctx, []*user_model.User{user})
- assignUsers(user, user)
- defer MockMailSettings(func(msgs ...*Message) {
- assert.Fail(t, "no mail should be sent")
- })()
- notify_service.ActionRunNowDone(ctx, run2, actions_model.StatusRunning, nil)
- })
-
- t.Run("WorkflowEnableEmailNotificationIsFalse", func(t *testing.T) {
- user := getActionsNowDoneTestUser(t, "new_user1", "new_user1@example.com", "enabled")
- defer CleanUpUsers(ctx, []*user_model.User{user})
- assignUsers(user, user)
- defer MockMailSettings(func(msgs ...*Message) {
- assert.Fail(t, "no mail should be sent")
- })()
- run2.NotifyEmail = false
- notify_service.ActionRunNowDone(ctx, run2, actions_model.StatusRunning, nil)
- })
-
- for _, testCase := range []struct {
- name string
- triggerUser *user_model.User
- owner *user_model.User
- expected string
- expectMail bool
- }{
- {
- // if the action is assigned a trigger user in a repository
- // owned by a regular user, the mail is sent to the trigger user
- name: "RegularTriggerUser",
- triggerUser: getActionsNowDoneTestUser(t, "new_trigger_user0", "new_trigger_user0@example.com", user_model.EmailNotificationsEnabled),
- owner: getActionsNowDoneTestUser(t, "new_owner0", "new_owner0@example.com", user_model.EmailNotificationsEnabled),
- expected: "trigger",
- expectMail: true,
- },
- {
- // if the action is assigned to a system user (e.g. ActionsUser)
- // in a repository owned by a regular user, the mail is sent to
- // the user that owns the repository
- name: "SystemTriggerUserAndRegularOwner",
- triggerUser: actionsUser,
- owner: getActionsNowDoneTestUser(t, "new_owner1", "new_owner1@example.com", user_model.EmailNotificationsEnabled),
- expected: "owner",
- expectMail: true,
- },
- {
- // if the action is assigned a trigger user with disabled notifications in a repository
- // owned by a regular user, no mail is sent
- name: "RegularTriggerUserNotificationsDisabled",
- triggerUser: getActionsNowDoneTestUser(t, "new_trigger_user2", "new_trigger_user2@example.com", user_model.EmailNotificationsDisabled),
- owner: getActionsNowDoneTestUser(t, "new_owner2", "new_owner2@example.com", user_model.EmailNotificationsEnabled),
- expectMail: false,
- },
- {
- // if the action is assigned to a system user (e.g. ActionsUser)
- // owned by a regular user with disabled notifications, no mail is sent
- name: "SystemTriggerUserAndRegularOwnerNotificationsDisabled",
- triggerUser: actionsUser,
- owner: getActionsNowDoneTestUser(t, "new_owner3", "new_owner3@example.com", user_model.EmailNotificationsDisabled),
- expectMail: false,
- },
- {
- // if the action is assigned to a system user (e.g. ActionsUser)
- // in a repository owned by an organization with an email contact, the mail is sent to
- // this email contact
- name: "SystemTriggerUserAndOrgOwner",
- triggerUser: actionsUser,
- owner: getActionsNowDoneTestOrg(t, "new_org1", "new_org_owner0@example.com", orgOwner),
- expected: "owner",
- expectMail: true,
- },
- {
- // if the action is assigned to a system user (e.g. ActionsUser)
- // in a repository owned by an organization without an email contact, no mail is sent
- name: "SystemTriggerUserAndNoMailOrgOwner",
- triggerUser: actionsUser,
- owner: getActionsNowDoneTestOrg(t, "new_org2", "", orgOwner),
- expectMail: false,
- },
- } {
- t.Run(testCase.name, func(t *testing.T) {
- assignUsers(testCase.triggerUser, testCase.owner)
- defer CleanUpUsers(ctx, slices.DeleteFunc([]*user_model.User{testCase.triggerUser, testCase.owner}, func(user *user_model.User) bool {
- return user.IsSystem()
- }))
-
- t.Run("SendNotificationEmailOnActionRunFailed", func(t *testing.T) {
- mailSent := false
- defer MockMailSettings(func(msgs ...*Message) {
- assert.Len(t, msgs, 1)
- msg := msgs[0]
- assert.False(t, mailSent, "sent mail twice")
- expectedEmail := testCase.triggerUser.Email
- if testCase.expected == "owner" { // otherwise "trigger"
- expectedEmail = testCase.owner.Email
- }
- require.Contains(t, msg.To, expectedEmail, "sent mail to unknown sender")
- mailSent = true
- assert.Contains(t, msg.Body, testCase.triggerUser.HTMLURL())
- assert.Contains(t, msg.Body, testCase.triggerUser.Name)
- // what happened
- assert.Contains(t, msg.Body, "failed")
- // new status of run
- assert.Contains(t, msg.Body, "failure")
- // prior status of this run
- assert.Contains(t, msg.Body, "waiting")
- assertTranslatedLocaleMailActionsNowDone(t, msg.Body)
- })()
- require.NotNil(t, setting.MailService)
-
- notify_service.ActionRunNowDone(ctx, run1, actions_model.StatusWaiting, nil)
- assert.Equal(t, testCase.expectMail, mailSent)
- })
-
- t.Run("SendNotificationEmailOnActionRunRecovered", func(t *testing.T) {
- mailSent := false
- defer MockMailSettings(func(msgs ...*Message) {
- assert.Len(t, msgs, 1)
- msg := msgs[0]
- assert.False(t, mailSent, "sent mail twice")
- expectedEmail := testCase.triggerUser.Email
- if testCase.expected == "owner" { // otherwise "trigger"
- expectedEmail = testCase.owner.Email
- }
- require.Contains(t, msg.To, expectedEmail, "sent mail to unknown sender")
- mailSent = true
- assert.Contains(t, msg.Body, testCase.triggerUser.HTMLURL())
- assert.Contains(t, msg.Body, testCase.triggerUser.Name)
- // what happened
- assert.Contains(t, msg.Body, "recovered")
- // old status of run
- assert.Contains(t, msg.Body, "failure")
- // new status of run
- assert.Contains(t, msg.Body, "success")
- // prior status of this run
- assert.Contains(t, msg.Body, "running")
- })()
- require.NotNil(t, setting.MailService)
-
- notify_service.ActionRunNowDone(ctx, run2, actions_model.StatusRunning, run1)
- assert.Equal(t, testCase.expectMail, mailSent)
- })
- })
- }
-}
diff --git a/services/mailer/mail_admin_new_user.go b/services/mailer/mail_admin_new_user.go
index ffb03197b7..0713de8a95 100644
--- a/services/mailer/mail_admin_new_user.go
+++ b/services/mailer/mail_admin_new_user.go
@@ -7,12 +7,12 @@ import (
"context"
"strconv"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/base"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/templates"
- "forgejo.org/modules/translation"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/templates"
+ "code.gitea.io/gitea/modules/translation"
)
const (
diff --git a/services/mailer/mail_admin_new_user_test.go b/services/mailer/mail_admin_new_user_test.go
index 58afcfcda6..765c8cb6c9 100644
--- a/services/mailer/mail_admin_new_user_test.go
+++ b/services/mailer/mail_admin_new_user_test.go
@@ -4,19 +4,20 @@
package mailer
import (
+ "context"
"strconv"
"testing"
- "forgejo.org/models/db"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/test"
+ "code.gitea.io/gitea/models/db"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/test"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
-func getAdminNewUserTestUsers(t *testing.T) []*user_model.User {
+func getTestUsers(t *testing.T) []*user_model.User {
t.Helper()
admin := new(user_model.User)
admin.Name = "testadmin"
@@ -37,10 +38,16 @@ func getAdminNewUserTestUsers(t *testing.T) []*user_model.User {
return []*user_model.User{admin, newUser}
}
+func cleanUpUsers(ctx context.Context, users []*user_model.User) {
+ for _, u := range users {
+ db.DeleteByID[user_model.User](ctx, u.ID)
+ }
+}
+
func TestAdminNotificationMail_test(t *testing.T) {
ctx := t.Context()
- users := getAdminNewUserTestUsers(t)
+ users := getTestUsers(t)
t.Run("SendNotificationEmailOnNewUser_true", func(t *testing.T) {
defer test.MockVariableValue(&setting.Admin.SendNotificationEmailOnNewUser, true)()
@@ -68,5 +75,5 @@ func TestAdminNotificationMail_test(t *testing.T) {
MailNewUser(ctx, users[1])
})
- CleanUpUsers(ctx, users)
+ cleanUpUsers(ctx, users)
}
diff --git a/services/mailer/mail_auth_test.go b/services/mailer/mail_auth_test.go
index e40a0d6fa0..38e3721a22 100644
--- a/services/mailer/mail_auth_test.go
+++ b/services/mailer/mail_auth_test.go
@@ -6,14 +6,14 @@ package mailer_test
import (
"testing"
- "forgejo.org/models/db"
- "forgejo.org/models/unittest"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/optional"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/translation"
- "forgejo.org/services/mailer"
- user_service "forgejo.org/services/user"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/unittest"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/optional"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/translation"
+ "code.gitea.io/gitea/services/mailer"
+ user_service "code.gitea.io/gitea/services/user"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
diff --git a/services/mailer/mail_comment.go b/services/mailer/mail_comment.go
index b4ed3145ed..1812441d5a 100644
--- a/services/mailer/mail_comment.go
+++ b/services/mailer/mail_comment.go
@@ -6,12 +6,12 @@ package mailer
import (
"context"
- activities_model "forgejo.org/models/activities"
- issues_model "forgejo.org/models/issues"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/container"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
+ activities_model "code.gitea.io/gitea/models/activities"
+ issues_model "code.gitea.io/gitea/models/issues"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/container"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
)
// MailParticipantsComment sends new comment emails to repository watchers and mentioned people.
diff --git a/services/mailer/mail_issue.go b/services/mailer/mail_issue.go
index 0d8e054041..1bb6fdc7a3 100644
--- a/services/mailer/mail_issue.go
+++ b/services/mailer/mail_issue.go
@@ -7,15 +7,15 @@ import (
"context"
"fmt"
- activities_model "forgejo.org/models/activities"
- issues_model "forgejo.org/models/issues"
- access_model "forgejo.org/models/perm/access"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unit"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/container"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
+ activities_model "code.gitea.io/gitea/models/activities"
+ issues_model "code.gitea.io/gitea/models/issues"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unit"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/container"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
)
func fallbackMailSubject(issue *issues_model.Issue) string {
@@ -85,7 +85,7 @@ func mailIssueCommentToParticipants(ctx *mailCommentContext, mentions []*user_mo
// =========== Repo watchers ===========
// Make repo watchers last, since it's likely the list with the most users
- if !ctx.Issue.IsPull || !ctx.Issue.PullRequest.IsWorkInProgress(ctx) || ctx.ActionType == activities_model.ActionCreatePullRequest {
+ if !(ctx.Issue.IsPull && ctx.Issue.PullRequest.IsWorkInProgress(ctx) && ctx.ActionType != activities_model.ActionCreatePullRequest) {
ids, err = repo_model.GetRepoWatchersIDs(ctx, ctx.Issue.RepoID)
if err != nil {
return fmt.Errorf("GetRepoWatchersIDs(%d): %w", ctx.Issue.RepoID, err)
@@ -137,8 +137,9 @@ func mailIssueCommentBatch(ctx *mailCommentContext, users []*user_model.User, vi
}
// At this point we exclude:
// user that don't have all mails enabled or users only get mail on mention and this is one ...
- if user.EmailNotificationsPreference != user_model.EmailNotificationsEnabled &&
- user.EmailNotificationsPreference != user_model.EmailNotificationsAndYourOwn && (!fromMention || user.EmailNotificationsPreference != user_model.EmailNotificationsOnMention) {
+ if !(user.EmailNotificationsPreference == user_model.EmailNotificationsEnabled ||
+ user.EmailNotificationsPreference == user_model.EmailNotificationsAndYourOwn ||
+ fromMention && user.EmailNotificationsPreference == user_model.EmailNotificationsOnMention) {
continue
}
diff --git a/services/mailer/mail_release.go b/services/mailer/mail_release.go
index 0f2ef33fe1..0b8b97e9cd 100644
--- a/services/mailer/mail_release.go
+++ b/services/mailer/mail_release.go
@@ -7,14 +7,14 @@ import (
"bytes"
"context"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/base"
- "forgejo.org/modules/log"
- "forgejo.org/modules/markup"
- "forgejo.org/modules/markup/markdown"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/translation"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/markup"
+ "code.gitea.io/gitea/modules/markup/markdown"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/translation"
)
const (
diff --git a/services/mailer/mail_repo.go b/services/mailer/mail_repo.go
index eed650f3ac..7003584786 100644
--- a/services/mailer/mail_repo.go
+++ b/services/mailer/mail_repo.go
@@ -8,11 +8,11 @@ import (
"context"
"fmt"
- "forgejo.org/models/organization"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/translation"
+ "code.gitea.io/gitea/models/organization"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/translation"
)
// SendRepoTransferNotifyMail triggers a notification e-mail when a pending repository transfer was created
diff --git a/services/mailer/mail_team_invite.go b/services/mailer/mail_team_invite.go
index 5375133415..ceecefa50f 100644
--- a/services/mailer/mail_team_invite.go
+++ b/services/mailer/mail_team_invite.go
@@ -6,16 +6,15 @@ package mailer
import (
"bytes"
"context"
- "errors"
"fmt"
"net/url"
- org_model "forgejo.org/models/organization"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/base"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/translation"
+ org_model "code.gitea.io/gitea/models/organization"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/translation"
)
const (
@@ -40,7 +39,7 @@ func MailTeamInvite(ctx context.Context, inviter *user_model.User, team *org_mod
if err != nil && !user_model.IsErrUserNotExist(err) {
return err
} else if user != nil && user.ProhibitLogin {
- return errors.New("login is prohibited for the invited user")
+ return fmt.Errorf("login is prohibited for the invited user")
}
inviteRedirect := url.QueryEscape(fmt.Sprintf("/org/invite/%s", invite.Token))
diff --git a/services/mailer/mail_test.go b/services/mailer/mail_test.go
index afbcb8064e..43e5d83890 100644
--- a/services/mailer/mail_test.go
+++ b/services/mailer/mail_test.go
@@ -15,15 +15,15 @@ import (
"testing"
texttmpl "text/template"
- activities_model "forgejo.org/models/activities"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unittest"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/markup"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/test"
+ activities_model "code.gitea.io/gitea/models/activities"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unittest"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/markup"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/test"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -494,7 +494,8 @@ func Test_createReference(t *testing.T) {
func TestFromDisplayName(t *testing.T) {
template, err := texttmpl.New("mailFrom").Parse("{{ .DisplayName }}")
require.NoError(t, err)
- defer test.MockVariableValue(&setting.MailService, &setting.Mailer{FromDisplayNameFormatTemplate: template})()
+ setting.MailService = &setting.Mailer{FromDisplayNameFormatTemplate: template}
+ defer func() { setting.MailService = nil }()
tests := []struct {
userDisplayName string
@@ -517,18 +518,24 @@ func TestFromDisplayName(t *testing.T) {
t.Run(tc.userDisplayName, func(t *testing.T) {
user := &user_model.User{FullName: tc.userDisplayName, Name: "tmp"}
got := fromDisplayName(user)
- assert.Equal(t, tc.fromDisplayName, got)
+ assert.EqualValues(t, tc.fromDisplayName, got)
})
}
t.Run("template with all available vars", func(t *testing.T) {
template, err = texttmpl.New("mailFrom").Parse("{{ .DisplayName }} (by {{ .AppName }} on [{{ .Domain }}])")
require.NoError(t, err)
- defer test.MockVariableValue(&setting.MailService, &setting.Mailer{FromDisplayNameFormatTemplate: template})()
- defer test.MockVariableValue(&setting.AppName, "Code IT")()
- defer test.MockVariableValue(&setting.Domain, "code.it")()
+ setting.MailService = &setting.Mailer{FromDisplayNameFormatTemplate: template}
+ oldAppName := setting.AppName
+ setting.AppName = "Code IT"
+ oldDomain := setting.Domain
+ setting.Domain = "code.it"
+ defer func() {
+ setting.AppName = oldAppName
+ setting.Domain = oldDomain
+ }()
- assert.Equal(t, "Mister X (by Code IT on [code.it])", fromDisplayName(&user_model.User{FullName: "Mister X", Name: "tmp"}))
+ assert.EqualValues(t, "Mister X (by Code IT on [code.it])", fromDisplayName(&user_model.User{FullName: "Mister X", Name: "tmp"}))
})
}
diff --git a/services/mailer/mailer.go b/services/mailer/mailer.go
index d8646d9ddd..0a723f974a 100644
--- a/services/mailer/mailer.go
+++ b/services/mailer/mailer.go
@@ -8,7 +8,6 @@ import (
"bytes"
"context"
"crypto/tls"
- "errors"
"fmt"
"hash/fnv"
"io"
@@ -19,17 +18,17 @@ import (
"strings"
"time"
- "forgejo.org/modules/base"
- "forgejo.org/modules/graceful"
- "forgejo.org/modules/log"
- "forgejo.org/modules/process"
- "forgejo.org/modules/queue"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/templates"
- notify_service "forgejo.org/services/notify"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/graceful"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/process"
+ "code.gitea.io/gitea/modules/queue"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/templates"
+ notify_service "code.gitea.io/gitea/services/notify"
ntlmssp "github.com/Azure/go-ntlmssp"
- "github.com/inbucket/html2text"
+ "github.com/jaytaylor/html2text"
"gopkg.in/gomail.v2"
)
@@ -177,7 +176,7 @@ func (a *ntlmAuth) Start(server *smtp.ServerInfo) (string, []byte, error) {
func (a *ntlmAuth) Next(fromServer []byte, more bool) ([]byte, error) {
if more {
if len(fromServer) == 0 {
- return nil, errors.New("ntlm ChallengeMessage is empty")
+ return nil, fmt.Errorf("ntlm ChallengeMessage is empty")
}
authenticateMessage, err := ntlmssp.ProcessChallenge(fromServer, a.username, a.password, a.domainNeeded)
return authenticateMessage, err
@@ -265,7 +264,7 @@ func (s *smtpSender) Send(from string, to []string, msg io.WriterTo) error {
canAuth, options := client.Extension("AUTH")
if len(opts.User) > 0 {
if !canAuth {
- return errors.New("SMTP server does not support AUTH, but credentials provided")
+ return fmt.Errorf("SMTP server does not support AUTH, but credentials provided")
}
var auth smtp.Auth
diff --git a/services/mailer/mailer_test.go b/services/mailer/mailer_test.go
index 34fd847c05..045701f3a5 100644
--- a/services/mailer/mailer_test.go
+++ b/services/mailer/mailer_test.go
@@ -8,9 +8,9 @@ import (
"testing"
"time"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/test"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/test"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -72,7 +72,7 @@ func TestToMessage(t *testing.T) {
_, err := m1.ToMessage().WriteTo(buf)
require.NoError(t, err)
header, _ := extractMailHeaderAndContent(t, buf.String())
- assert.Equal(t, map[string]string{
+ assert.EqualValues(t, map[string]string{
"Content-Type": "multipart/alternative;",
"Date": "Mon, 01 Jan 0001 00:00:00 +0000",
"From": "\"Test Gitea\" ",
@@ -92,7 +92,7 @@ func TestToMessage(t *testing.T) {
_, err = m1.ToMessage().WriteTo(buf)
require.NoError(t, err)
header, _ = extractMailHeaderAndContent(t, buf.String())
- assert.Equal(t, map[string]string{
+ assert.EqualValues(t, map[string]string{
"Content-Type": "multipart/alternative;",
"Date": "Mon, 01 Jan 0001 00:00:00 +0000",
"From": "\"Test Gitea\" ",
diff --git a/services/mailer/main_test.go b/services/mailer/main_test.go
index 5e9cbe3e99..908976e7ef 100644
--- a/services/mailer/main_test.go
+++ b/services/mailer/main_test.go
@@ -7,16 +7,13 @@ import (
"context"
"testing"
- "forgejo.org/models/db"
- organization_model "forgejo.org/models/organization"
- "forgejo.org/models/unittest"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/templates"
- "forgejo.org/modules/test"
- "forgejo.org/modules/translation"
+ "code.gitea.io/gitea/models/unittest"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/templates"
+ "code.gitea.io/gitea/modules/test"
+ "code.gitea.io/gitea/modules/translation"
- _ "forgejo.org/models/actions"
+ _ "code.gitea.io/gitea/models/actions"
"github.com/stretchr/testify/assert"
)
@@ -49,14 +46,3 @@ func MockMailSettings(send func(msgs ...*Message)) func() {
}
}
}
-
-func CleanUpUsers(ctx context.Context, users []*user_model.User) {
- for _, u := range users {
- if u.IsOrganization() {
- organization_model.DeleteOrganization(ctx, (*organization_model.Organization)(u))
- } else {
- db.DeleteByID[user_model.User](ctx, u.ID)
- db.DeleteByBean(ctx, &user_model.EmailAddress{UID: u.ID})
- }
- }
-}
diff --git a/services/mailer/notify.go b/services/mailer/notify.go
index 640de31fcc..54ab80aab9 100644
--- a/services/mailer/notify.go
+++ b/services/mailer/notify.go
@@ -7,13 +7,12 @@ import (
"context"
"fmt"
- actions_model "forgejo.org/models/actions"
- activities_model "forgejo.org/models/activities"
- issues_model "forgejo.org/models/issues"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/log"
- notify_service "forgejo.org/services/notify"
+ activities_model "code.gitea.io/gitea/models/activities"
+ issues_model "code.gitea.io/gitea/models/issues"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/log"
+ notify_service "code.gitea.io/gitea/services/notify"
)
type mailNotifier struct {
@@ -31,16 +30,15 @@ func (m *mailNotifier) CreateIssueComment(ctx context.Context, doer *user_model.
issue *issues_model.Issue, comment *issues_model.Comment, mentions []*user_model.User,
) {
var act activities_model.ActionType
- switch comment.Type {
- case issues_model.CommentTypeClose:
+ if comment.Type == issues_model.CommentTypeClose {
act = activities_model.ActionCloseIssue
- case issues_model.CommentTypeReopen:
+ } else if comment.Type == issues_model.CommentTypeReopen {
act = activities_model.ActionReopenIssue
- case issues_model.CommentTypeComment:
+ } else if comment.Type == issues_model.CommentTypeComment {
act = activities_model.ActionCommentIssue
- case issues_model.CommentTypeCode:
+ } else if comment.Type == issues_model.CommentTypeCode {
act = activities_model.ActionCommentIssue
- case issues_model.CommentTypePullRequestPush:
+ } else if comment.Type == issues_model.CommentTypePullRequestPush {
act = 0
}
@@ -96,12 +94,11 @@ func (m *mailNotifier) NewPullRequest(ctx context.Context, pr *issues_model.Pull
func (m *mailNotifier) PullRequestReview(ctx context.Context, pr *issues_model.PullRequest, r *issues_model.Review, comment *issues_model.Comment, mentions []*user_model.User) {
var act activities_model.ActionType
- switch comment.Type {
- case issues_model.CommentTypeClose:
+ if comment.Type == issues_model.CommentTypeClose {
act = activities_model.ActionCloseIssue
- case issues_model.CommentTypeReopen:
+ } else if comment.Type == issues_model.CommentTypeReopen {
act = activities_model.ActionReopenIssue
- case issues_model.CommentTypeComment:
+ } else if comment.Type == issues_model.CommentTypeComment {
act = activities_model.ActionCommentPull
}
if err := MailParticipantsComment(ctx, comment, act, pr.Issue, mentions); err != nil {
@@ -209,13 +206,3 @@ func (m *mailNotifier) RepoPendingTransfer(ctx context.Context, doer, newOwner *
func (m *mailNotifier) NewUserSignUp(ctx context.Context, newUser *user_model.User) {
MailNewUser(ctx, newUser)
}
-
-func (m *mailNotifier) ActionRunNowDone(ctx context.Context, run *actions_model.ActionRun, priorStatus actions_model.Status, lastRun *actions_model.ActionRun) {
- // Only send a mail on a successful run when the workflow recovered (i.e., the run before failed).
- if !run.Status.IsFailure() && (lastRun == nil || !lastRun.Status.IsFailure()) {
- return
- }
- if err := MailActionRun(run, priorStatus, lastRun); err != nil {
- log.Error("MailActionRunNowDone: %v", err)
- }
-}
diff --git a/services/mailer/token/token.go b/services/mailer/token/token.go
index f3d7286cb0..1a52bce803 100644
--- a/services/mailer/token/token.go
+++ b/services/mailer/token/token.go
@@ -11,8 +11,8 @@ import (
"fmt"
"time"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/util"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/util"
)
// A token is a verifiable container describing an action.
diff --git a/services/markup/main_test.go b/services/markup/main_test.go
index 1b085b4929..89fe3e7e34 100644
--- a/services/markup/main_test.go
+++ b/services/markup/main_test.go
@@ -6,7 +6,7 @@ package markup
import (
"testing"
- "forgejo.org/models/unittest"
+ "code.gitea.io/gitea/models/unittest"
)
func TestMain(m *testing.M) {
diff --git a/services/markup/processorhelper.go b/services/markup/processorhelper.go
index 2f1b1e738c..40bf1d65da 100644
--- a/services/markup/processorhelper.go
+++ b/services/markup/processorhelper.go
@@ -5,18 +5,18 @@ package markup
import (
"context"
- "errors"
+ "fmt"
- "forgejo.org/models/perm/access"
- "forgejo.org/models/repo"
- "forgejo.org/models/unit"
- "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/log"
- "forgejo.org/modules/markup"
- gitea_context "forgejo.org/services/context"
- file_service "forgejo.org/services/repository/files"
+ "code.gitea.io/gitea/models/perm/access"
+ "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unit"
+ "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/markup"
+ gitea_context "code.gitea.io/gitea/services/context"
+ file_service "code.gitea.io/gitea/services/repository/files"
)
func ProcessorHelper() *markup.ProcessorHelper {
@@ -55,7 +55,7 @@ func ProcessorHelper() *markup.ProcessorHelper {
return nil, err
}
if !perms.CanRead(unit.TypeCode) {
- return nil, errors.New("cannot access repository code")
+ return nil, fmt.Errorf("cannot access repository code")
}
gitRepo, err := gitrepo.OpenRepository(ctx, repo)
diff --git a/services/markup/processorhelper_test.go b/services/markup/processorhelper_test.go
index 8195451746..4d103048b5 100644
--- a/services/markup/processorhelper_test.go
+++ b/services/markup/processorhelper_test.go
@@ -8,11 +8,11 @@ import (
"net/http/httptest"
"testing"
- "forgejo.org/models/db"
- "forgejo.org/models/unittest"
- "forgejo.org/models/user"
- gitea_context "forgejo.org/services/context"
- "forgejo.org/services/contexttest"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/unittest"
+ "code.gitea.io/gitea/models/user"
+ gitea_context "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/contexttest"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
diff --git a/services/migrations/codebase.go b/services/migrations/codebase.go
index 843df0f973..492fc908e9 100644
--- a/services/migrations/codebase.go
+++ b/services/migrations/codebase.go
@@ -13,10 +13,10 @@ import (
"strings"
"time"
- "forgejo.org/modules/log"
- base "forgejo.org/modules/migration"
- "forgejo.org/modules/proxy"
- "forgejo.org/modules/structs"
+ "code.gitea.io/gitea/modules/log"
+ base "code.gitea.io/gitea/modules/migration"
+ "code.gitea.io/gitea/modules/proxy"
+ "code.gitea.io/gitea/modules/structs"
)
var (
diff --git a/services/migrations/codebase_test.go b/services/migrations/codebase_test.go
index 315c7be709..fbd4e70143 100644
--- a/services/migrations/codebase_test.go
+++ b/services/migrations/codebase_test.go
@@ -9,7 +9,7 @@ import (
"testing"
"time"
- base "forgejo.org/modules/migration"
+ base "code.gitea.io/gitea/modules/migration"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
diff --git a/services/migrations/common.go b/services/migrations/common.go
index ee74461447..d88518899d 100644
--- a/services/migrations/common.go
+++ b/services/migrations/common.go
@@ -7,10 +7,10 @@ import (
"fmt"
"strings"
- system_model "forgejo.org/models/system"
- "forgejo.org/modules/git"
- "forgejo.org/modules/log"
- base "forgejo.org/modules/migration"
+ system_model "code.gitea.io/gitea/models/system"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/log"
+ base "code.gitea.io/gitea/modules/migration"
)
// WarnAndNotice will log the provided message and send a repository notice
diff --git a/services/migrations/dump.go b/services/migrations/dump.go
index af161bc73d..cb13cd3e5c 100644
--- a/services/migrations/dump.go
+++ b/services/migrations/dump.go
@@ -16,16 +16,16 @@ import (
"strings"
"time"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/log"
- base "forgejo.org/modules/migration"
- "forgejo.org/modules/repository"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/structs"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/log"
+ base "code.gitea.io/gitea/modules/migration"
+ "code.gitea.io/gitea/modules/repository"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/structs"
"github.com/google/uuid"
- "go.yaml.in/yaml/v3"
+ "gopkg.in/yaml.v3"
)
var _ base.Uploader = &RepositoryDumper{}
diff --git a/services/migrations/forgejo_downloader.go b/services/migrations/forgejo_downloader.go
index 5f809b82be..25dbb6ec51 100644
--- a/services/migrations/forgejo_downloader.go
+++ b/services/migrations/forgejo_downloader.go
@@ -4,7 +4,7 @@
package migrations
import (
- "forgejo.org/modules/structs"
+ "code.gitea.io/gitea/modules/structs"
)
func init() {
diff --git a/services/migrations/forgejo_downloader_test.go b/services/migrations/forgejo_downloader_test.go
index db1930ebba..5bd37551cc 100644
--- a/services/migrations/forgejo_downloader_test.go
+++ b/services/migrations/forgejo_downloader_test.go
@@ -6,7 +6,7 @@ package migrations
import (
"testing"
- "forgejo.org/modules/structs"
+ "code.gitea.io/gitea/modules/structs"
"github.com/stretchr/testify/require"
)
diff --git a/services/migrations/git.go b/services/migrations/git.go
index 46710b0abe..22ffd5e765 100644
--- a/services/migrations/git.go
+++ b/services/migrations/git.go
@@ -6,7 +6,7 @@ package migrations
import (
"context"
- base "forgejo.org/modules/migration"
+ base "code.gitea.io/gitea/modules/migration"
)
var _ base.Downloader = &PlainGitDownloader{}
diff --git a/services/migrations/gitbucket.go b/services/migrations/gitbucket.go
index a9bd2dafb0..4fe9e30a39 100644
--- a/services/migrations/gitbucket.go
+++ b/services/migrations/gitbucket.go
@@ -9,9 +9,9 @@ import (
"net/url"
"strings"
- "forgejo.org/modules/log"
- base "forgejo.org/modules/migration"
- "forgejo.org/modules/structs"
+ "code.gitea.io/gitea/modules/log"
+ base "code.gitea.io/gitea/modules/migration"
+ "code.gitea.io/gitea/modules/structs"
)
var (
@@ -71,7 +71,7 @@ func (g *GitBucketDownloader) LogString() string {
// NewGitBucketDownloader creates a GitBucket downloader
func NewGitBucketDownloader(ctx context.Context, baseURL, userName, password, token, repoOwner, repoName string) *GitBucketDownloader {
- githubDownloader := NewGithubDownloaderV3(ctx, baseURL, true, true, userName, password, token, repoOwner, repoName)
+ githubDownloader := NewGithubDownloaderV3(ctx, baseURL, userName, password, token, repoOwner, repoName)
// Gitbucket 4.40 uses different internal hard-coded perPage values.
// Issues, PRs, and other major parts use 25. Release page uses 10.
// Some API doesn't support paging yet. Sounds difficult, but using
diff --git a/services/migrations/gitbucket_test.go b/services/migrations/gitbucket_test.go
deleted file mode 100644
index 3cb69d65c9..0000000000
--- a/services/migrations/gitbucket_test.go
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2025 The Forgejo Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package migrations
-
-import (
- "os"
- "testing"
-
- "forgejo.org/models/unittest"
-
- "github.com/stretchr/testify/require"
-)
-
-func TestGitbucketDownloaderCreation(t *testing.T) {
- token := os.Getenv("GITHUB_READ_TOKEN")
- fixturePath := "./testdata/github/full_download"
- server := unittest.NewMockWebServer(t, "https://api.github.com", fixturePath, false)
- defer server.Close()
-
- downloader := NewGitBucketDownloader(t.Context(), server.URL, "", "", token, "forgejo", "test_repo")
- err := downloader.RefreshRate()
- require.NoError(t, err)
-}
diff --git a/services/migrations/gitea_downloader.go b/services/migrations/gitea_downloader.go
index 133cc5c928..b42c7aa4da 100644
--- a/services/migrations/gitea_downloader.go
+++ b/services/migrations/gitea_downloader.go
@@ -13,9 +13,9 @@ import (
"strings"
"time"
- "forgejo.org/modules/log"
- base "forgejo.org/modules/migration"
- "forgejo.org/modules/structs"
+ "code.gitea.io/gitea/modules/log"
+ base "code.gitea.io/gitea/modules/migration"
+ "code.gitea.io/gitea/modules/structs"
gitea_sdk "code.gitea.io/sdk/gitea"
)
@@ -504,28 +504,6 @@ func (g *GiteaDownloader) GetComments(commentable base.Commentable) ([]*base.Com
return allComments, true, nil
}
-type ForgejoPullRequest struct {
- gitea_sdk.PullRequest
- Flow int64 `json:"flow"`
-}
-
-// Extracted from https://gitea.com/gitea/go-sdk/src/commit/164e3358bc02213954fb4380b821bed80a14824d/gitea/pull.go#L347-L364
-func (g *GiteaDownloader) fixPullHeadSha(pr *ForgejoPullRequest) error {
- if pr.Base != nil && pr.Base.Repository != nil && pr.Base.Repository.Owner != nil && pr.Head != nil && pr.Head.Ref != "" && pr.Head.Sha == "" {
- owner := pr.Base.Repository.Owner.UserName
- repo := pr.Base.Repository.Name
- refs, _, err := g.client.GetRepoRefs(owner, repo, pr.Head.Ref)
- if err != nil {
- return err
- }
- if len(refs) == 0 {
- return fmt.Errorf("unable to resolve PR ref %q", pr.Head.Ref)
- }
- pr.Head.Sha = refs[0].Object.SHA
- }
- return nil
-}
-
// GetPullRequests returns pull requests according page and perPage
func (g *GiteaDownloader) GetPullRequests(page, perPage int) ([]*base.PullRequest, bool, error) {
if perPage > g.maxPerPage {
@@ -533,30 +511,16 @@ func (g *GiteaDownloader) GetPullRequests(page, perPage int) ([]*base.PullReques
}
allPRs := make([]*base.PullRequest, 0, perPage)
- prs := make([]*ForgejoPullRequest, 0, perPage)
- opt := gitea_sdk.ListPullRequestsOptions{
+ prs, _, err := g.client.ListRepoPullRequests(g.repoOwner, g.repoName, gitea_sdk.ListPullRequestsOptions{
ListOptions: gitea_sdk.ListOptions{
Page: page,
PageSize: perPage,
},
State: gitea_sdk.StateAll,
- }
-
- link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/pulls", url.PathEscape(g.repoOwner), url.PathEscape(g.repoName)))
- link.RawQuery = opt.QueryEncode()
- _, err := getParsedResponse(g.client, "GET", link.String(), http.Header{"content-type": []string{"application/json"}}, nil, &prs)
+ })
if err != nil {
return nil, false, fmt.Errorf("error while listing pull requests (page: %d, pagesize: %d). Error: %w", page, perPage, err)
}
-
- if g.client.CheckServerVersionConstraint(">= 1.14.0") != nil {
- for i := range prs {
- if err := g.fixPullHeadSha(prs[i]); err != nil {
- return nil, false, fmt.Errorf("error while listing pull requests (page: %d, pagesize: %d). Error: %w", page, perPage, err)
- }
- }
- }
-
for _, pr := range prs {
var milestone string
if pr.Milestone != nil {
@@ -634,7 +598,6 @@ func (g *GiteaDownloader) GetPullRequests(page, perPage int) ([]*base.PullReques
MergeCommitSHA: mergeCommitSHA,
IsLocked: pr.IsLocked,
PatchURL: pr.PatchURL,
- Flow: pr.Flow,
Head: base.PullRequestBranch{
Ref: headRef,
SHA: headSHA,
diff --git a/services/migrations/gitea_downloader_test.go b/services/migrations/gitea_downloader_test.go
index 5acc3b86a9..b9ddb9b431 100644
--- a/services/migrations/gitea_downloader_test.go
+++ b/services/migrations/gitea_downloader_test.go
@@ -9,8 +9,8 @@ import (
"testing"
"time"
- "forgejo.org/models/unittest"
- base "forgejo.org/modules/migration"
+ "code.gitea.io/gitea/models/unittest"
+ base "code.gitea.io/gitea/modules/migration"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -45,7 +45,7 @@ func TestGiteaDownloadRepo(t *testing.T) {
topics, err := downloader.GetTopics()
require.NoError(t, err)
sort.Strings(topics)
- assert.Equal(t, []string{"ci", "gitea", "migration", "test"}, topics)
+ assert.EqualValues(t, []string{"ci", "gitea", "migration", "test"}, topics)
labels, err := downloader.GetLabels()
require.NoError(t, err)
@@ -132,7 +132,7 @@ func TestGiteaDownloadRepo(t *testing.T) {
require.NoError(t, err)
assert.True(t, isEnd)
assert.Len(t, issues, 7)
- assert.Equal(t, "open", issues[0].State)
+ assert.EqualValues(t, "open", issues[0].State)
issues, isEnd, err = downloader.GetIssues(3, 2)
require.NoError(t, err)
@@ -307,46 +307,3 @@ func TestGiteaDownloadRepo(t *testing.T) {
},
}, reviews)
}
-
-func TestForgejoDownloadRepo(t *testing.T) {
- token := os.Getenv("CODE_FORGEJO_TOKEN")
-
- fixturePath := "./testdata/code-forgejo-org/full_download"
- server := unittest.NewMockWebServer(t, "https://code.forgejo.org", fixturePath, token != "")
- defer server.Close()
-
- downloader, err := NewGiteaDownloader(t.Context(), server.URL, "Gusted/agit-test", "", "", token)
- require.NoError(t, err)
- require.NotNil(t, downloader)
-
- prs, _, err := downloader.GetPullRequests(1, 50)
- require.NoError(t, err)
- assert.Len(t, prs, 1)
-
- assertPullRequestEqual(t, &base.PullRequest{
- Number: 1,
- PosterID: 63,
- PosterName: "Gusted",
- PosterEmail: "postmaster@gusted.xyz",
- Title: "Add extra information",
- State: "open",
- Created: time.Date(2025, time.April, 1, 20, 28, 45, 0, time.UTC),
- Updated: time.Date(2025, time.April, 1, 20, 28, 45, 0, time.UTC),
- Base: base.PullRequestBranch{
- CloneURL: "",
- Ref: "main",
- SHA: "79ebb873a6497c8847141ba9706b3f757196a1e6",
- RepoName: "agit-test",
- OwnerName: "Gusted",
- },
- Head: base.PullRequestBranch{
- CloneURL: server.URL + "/Gusted/agit-test.git",
- Ref: "refs/pull/1/head",
- SHA: "667e9317ec37b977e6d3d7d43e3440636970563c",
- RepoName: "agit-test",
- OwnerName: "Gusted",
- },
- PatchURL: server.URL + "/Gusted/agit-test/pulls/1.patch",
- Flow: 1,
- }, prs[0])
-}
diff --git a/services/migrations/gitea_sdk_hack.go b/services/migrations/gitea_sdk_hack.go
deleted file mode 100644
index f3959717a8..0000000000
--- a/services/migrations/gitea_sdk_hack.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2025 The Forgejo Authors. All rights reserved.
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-package migrations
-
-import (
- "io"
- "net/http"
-
- _ "unsafe" // Needed for go:linkname support
-
- gitea_sdk "code.gitea.io/sdk/gitea"
-)
-
-//go:linkname getParsedResponse code.gitea.io/sdk/gitea.(*Client).getParsedResponse
-func getParsedResponse(client *gitea_sdk.Client, method, path string, header http.Header, body io.Reader, obj any) (*gitea_sdk.Response, error)
diff --git a/services/migrations/gitea_uploader.go b/services/migrations/gitea_uploader.go
index 7887dacdb1..7bd6538ff2 100644
--- a/services/migrations/gitea_uploader.go
+++ b/services/migrations/gitea_uploader.go
@@ -14,26 +14,26 @@ import (
"strings"
"time"
- "forgejo.org/models"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- base_module "forgejo.org/modules/base"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/label"
- "forgejo.org/modules/log"
- base "forgejo.org/modules/migration"
- repo_module "forgejo.org/modules/repository"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/storage"
- "forgejo.org/modules/structs"
- "forgejo.org/modules/timeutil"
- "forgejo.org/modules/uri"
- "forgejo.org/modules/util"
- "forgejo.org/services/pull"
- repo_service "forgejo.org/services/repository"
+ "code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ base_module "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/label"
+ "code.gitea.io/gitea/modules/log"
+ base "code.gitea.io/gitea/modules/migration"
+ repo_module "code.gitea.io/gitea/modules/repository"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/storage"
+ "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/timeutil"
+ "code.gitea.io/gitea/modules/uri"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/services/pull"
+ repo_service "code.gitea.io/gitea/services/repository"
"github.com/google/uuid"
)
@@ -766,7 +766,7 @@ func (g *GiteaLocalUploader) newPullRequest(pr *base.PullRequest) (*issues_model
issue := issues_model.Issue{
RepoID: g.repo.ID,
Repo: g.repo,
- Title: util.TruncateRunes(prTitle, 255),
+ Title: prTitle,
Index: pr.Number,
Content: pr.Content,
MilestoneID: milestoneID,
@@ -802,7 +802,6 @@ func (g *GiteaLocalUploader) newPullRequest(pr *base.PullRequest) (*issues_model
MergeBase: pr.Base.SHA,
Index: pr.Number,
HasMerged: pr.Merged,
- Flow: issues_model.PullRequestFlow(pr.Flow),
Issue: &issue,
}
diff --git a/services/migrations/gitea_uploader_test.go b/services/migrations/gitea_uploader_test.go
index e33d597cdc..e01f4664ba 100644
--- a/services/migrations/gitea_uploader_test.go
+++ b/services/migrations/gitea_uploader_test.go
@@ -12,147 +12,24 @@ import (
"testing"
"time"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unittest"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/log"
- base "forgejo.org/modules/migration"
- "forgejo.org/modules/optional"
- "forgejo.org/modules/structs"
- "forgejo.org/modules/test"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unittest"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/graceful"
+ "code.gitea.io/gitea/modules/log"
+ base "code.gitea.io/gitea/modules/migration"
+ "code.gitea.io/gitea/modules/optional"
+ "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/test"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
-func TestCommentUpload(t *testing.T) {
- unittest.PrepareTestEnv(t)
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
- var (
- opts = base.MigrateOptions{
- Issues: true,
- }
- repoName = "test_repo"
- uploader = NewGiteaLocalUploader(t.Context(), user, user.Name, repoName)
- )
- defer uploader.Close()
-
- fixturePath := "./testdata/github/full_download"
- server := unittest.NewMockWebServer(t, "https://api.github.com", fixturePath, false)
- defer server.Close()
-
- // Mock Data
- repoMock := &base.Repository{
- Name: repoName,
- Owner: "forgejo",
- Description: "Some mock repo",
- CloneURL: server.URL + "/forgejo/test_repo.git",
- OriginalURL: server.URL + "/forgejo/test_repo",
- DefaultBranch: "master",
- Website: "https://codeberg.org/forgejo/forgejo/",
- }
-
- // Create Repo
- require.NoError(t, uploader.CreateRepo(repoMock, opts))
-
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: user.ID, Name: repoName})
-
- // Create and Test Issues Uploading
- issueA := &base.Issue{
- Title: "First issue",
- Number: 0,
- PosterID: 37243484,
- PosterName: "PatDyn",
- PosterEmail: "",
- Content: "Mock Content",
- Milestone: "Mock Milestone",
- State: "open",
- Created: time.Date(2025, 8, 7, 12, 44, 7, 0, time.UTC),
- Updated: time.Date(2025, 8, 7, 12, 44, 47, 0, time.UTC),
- Labels: nil,
- Reactions: nil,
- Closed: nil,
- IsLocked: false,
- Assignees: nil,
- ForeignIndex: 0,
- }
-
- issueB := &base.Issue{
- Title: "Second Issue",
- Number: 1,
- PosterID: 37243484,
- PosterName: "PatDyn",
- PosterEmail: "",
- Content: "Mock Content",
- Milestone: "Mock Milestone",
- State: "open",
- Created: time.Date(2025, 8, 7, 12, 45, 44, 0, time.UTC),
- Updated: time.Date(2025, 8, 7, 13, 7, 25, 0, time.UTC),
- Labels: nil,
- Reactions: nil,
- Closed: nil,
- IsLocked: false,
- Assignees: nil,
- ForeignIndex: 1,
- }
-
- err := uploader.CreateIssues(issueA, issueB)
- require.NoError(t, err)
-
- issues, err := issues_model.Issues(db.DefaultContext, &issues_model.IssuesOptions{
- RepoIDs: []int64{repo.ID},
- IsPull: optional.Some(false),
- SortType: "newest",
- })
- require.NoError(t, err)
- assert.Len(t, issues, 2)
-
- // Create and Test Comment Uploading
- issueAComment := &base.Comment{
- IssueIndex: 0,
- Index: 0,
- CommentType: "comment",
- PosterID: 37243484,
- PosterName: "PatDyn",
- PosterEmail: "",
- Created: time.Date(2025, 8, 7, 12, 44, 24, 0, time.UTC),
- Updated: time.Date(2025, 8, 7, 12, 44, 24, 0, time.UTC),
- Content: "First Mock Comment",
- Reactions: nil,
- Meta: nil,
- }
- issueBComment := &base.Comment{
- IssueIndex: 1,
- Index: 1,
- CommentType: "comment",
- PosterID: 37243484,
- PosterName: "PatDyn",
- PosterEmail: "",
- Created: time.Date(2025, 8, 7, 13, 7, 25, 0, time.UTC),
- Updated: time.Date(2025, 8, 7, 13, 7, 25, 0, time.UTC),
- Content: "Second Mock Comment",
- Reactions: nil,
- Meta: nil,
- }
- require.NoError(t, uploader.CreateComments(issueBComment, issueAComment))
-
- issues, err = issues_model.Issues(db.DefaultContext, &issues_model.IssuesOptions{
- RepoIDs: []int64{repo.ID},
- IsPull: optional.Some(false),
- SortType: "newest",
- })
- require.NoError(t, err)
- assert.Len(t, issues, 2)
- require.NoError(t, issues[0].LoadDiscussComments(db.DefaultContext))
- require.NoError(t, issues[1].LoadDiscussComments(db.DefaultContext))
- assert.Len(t, issues[0].Comments, 1)
- assert.Len(t, issues[1].Comments, 1)
-}
-
func TestGiteaUploadRepo(t *testing.T) {
// FIXME: Since no accesskey or user/password will trigger rate limit of github, just skip
t.Skip()
@@ -163,9 +40,9 @@ func TestGiteaUploadRepo(t *testing.T) {
var (
ctx = t.Context()
- downloader = NewGithubDownloaderV3(ctx, "https://github.com", true, true, "", "", "", "go-xorm", "builder")
+ downloader = NewGithubDownloaderV3(ctx, "https://github.com", "", "", "", "go-xorm", "builder")
repoName = "builder-" + time.Now().Format("2006-01-02-15-04-05")
- uploader = NewGiteaLocalUploader(t.Context(), user, user.Name, repoName)
+ uploader = NewGiteaLocalUploader(graceful.GetManager().HammerContext(), user, user.Name, repoName)
)
err := migrateRepository(db.DefaultContext, user, downloader, uploader, base.MigrateOptions{
@@ -187,7 +64,7 @@ func TestGiteaUploadRepo(t *testing.T) {
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: user.ID, Name: repoName})
assert.True(t, repo.HasWiki())
- assert.Equal(t, repo_model.RepositoryReady, repo.Status)
+ assert.EqualValues(t, repo_model.RepositoryReady, repo.Status)
milestones, err := db.Find[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{
RepoID: repo.ID,
@@ -296,7 +173,7 @@ func TestGiteaUploadRemapLocalUser(t *testing.T) {
uploader.userMap = make(map[int64]int64)
err = uploader.remapUser(&source, &target)
require.NoError(t, err)
- assert.Equal(t, user.ID, target.GetUserID())
+ assert.EqualValues(t, user.ID, target.GetUserID())
}
func TestGiteaUploadRemapExternalUser(t *testing.T) {
@@ -347,7 +224,7 @@ func TestGiteaUploadRemapExternalUser(t *testing.T) {
target = repo_model.Release{}
err = uploader.remapUser(&source, &target)
require.NoError(t, err)
- assert.Equal(t, linkedUser.ID, target.GetUserID())
+ assert.EqualValues(t, linkedUser.ID, target.GetUserID())
}
func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) {
@@ -627,14 +504,14 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) {
head, err := uploader.updateGitForPullRequest(&testCase.pr)
require.NoError(t, err)
- assert.Equal(t, testCase.head, head)
+ assert.EqualValues(t, testCase.head, head)
log.Info(stopMark)
logFiltered, logStopped := logChecker.Check(5 * time.Second)
assert.True(t, logStopped)
if len(testCase.logFilter) > 0 {
- assert.Equal(t, testCase.logFiltered, logFiltered, "for log message filters: %v", testCase.logFilter)
+ assert.EqualValues(t, testCase.logFiltered, logFiltered, "for log message filters: %v", testCase.logFilter)
}
})
}
diff --git a/services/migrations/github.go b/services/migrations/github.go
index 1fe5d2cc8e..7025354f77 100644
--- a/services/migrations/github.go
+++ b/services/migrations/github.go
@@ -14,11 +14,11 @@ import (
"strings"
"time"
- "forgejo.org/modules/git"
- "forgejo.org/modules/log"
- base "forgejo.org/modules/migration"
- "forgejo.org/modules/proxy"
- "forgejo.org/modules/structs"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/log"
+ base "code.gitea.io/gitea/modules/migration"
+ "code.gitea.io/gitea/modules/proxy"
+ "code.gitea.io/gitea/modules/structs"
"github.com/google/go-github/v64/github"
"golang.org/x/oauth2"
@@ -57,7 +57,7 @@ func (f *GithubDownloaderV3Factory) New(ctx context.Context, opts base.MigrateOp
log.Trace("Create github downloader BaseURL: %s %s/%s", baseURL, oldOwner, oldName)
- return NewGithubDownloaderV3(ctx, baseURL, opts.PullRequests, opts.Issues, opts.AuthUsername, opts.AuthPassword, opts.AuthToken, oldOwner, oldName), nil
+ return NewGithubDownloaderV3(ctx, baseURL, opts.AuthUsername, opts.AuthPassword, opts.AuthToken, oldOwner, oldName), nil
}
// GitServiceType returns the type of git service
@@ -69,34 +69,30 @@ func (f *GithubDownloaderV3Factory) GitServiceType() structs.GitServiceType {
// from github via APIv3
type GithubDownloaderV3 struct {
base.NullDownloader
- ctx context.Context
- clients []*github.Client
- baseURL string
- repoOwner string
- repoName string
- userName string
- password string
- getPullRequests bool
- getIssues bool
- rates []*github.Rate
- curClientIdx int
- maxPerPage int
- SkipReactions bool
- SkipReviews bool
+ ctx context.Context
+ clients []*github.Client
+ baseURL string
+ repoOwner string
+ repoName string
+ userName string
+ password string
+ rates []*github.Rate
+ curClientIdx int
+ maxPerPage int
+ SkipReactions bool
+ SkipReviews bool
}
// NewGithubDownloaderV3 creates a github Downloader via github v3 API
-func NewGithubDownloaderV3(ctx context.Context, baseURL string, getPullRequests, getIssues bool, userName, password, token, repoOwner, repoName string) *GithubDownloaderV3 {
+func NewGithubDownloaderV3(ctx context.Context, baseURL, userName, password, token, repoOwner, repoName string) *GithubDownloaderV3 {
downloader := GithubDownloaderV3{
- userName: userName,
- baseURL: baseURL,
- password: password,
- ctx: ctx,
- repoOwner: repoOwner,
- repoName: repoName,
- maxPerPage: 100,
- getPullRequests: getPullRequests,
- getIssues: getIssues,
+ userName: userName,
+ baseURL: baseURL,
+ password: password,
+ ctx: ctx,
+ repoOwner: repoOwner,
+ repoName: repoName,
+ maxPerPage: 100,
}
if token != "" {
@@ -144,7 +140,7 @@ func (g *GithubDownloaderV3) LogString() string {
func (g *GithubDownloaderV3) addClient(client *http.Client, baseURL string) {
githubClient := github.NewClient(client)
if baseURL != "https://github.com" {
- githubClient, _ = githubClient.WithEnterpriseURLs(baseURL, baseURL)
+ githubClient, _ = github.NewClient(client).WithEnterpriseURLs(baseURL, baseURL)
}
g.clients = append(g.clients, githubClient)
g.rates = append(g.rates, nil)
@@ -368,8 +364,7 @@ func (g *GithubDownloaderV3) convertGithubRelease(rel *github.RepositoryRelease)
// Prevent open redirect
if !hasBaseURL(redirectURL, g.baseURL) &&
- !hasBaseURL(redirectURL, "https://objects.githubusercontent.com/") &&
- !hasBaseURL(redirectURL, "https://release-assets.githubusercontent.com/") {
+ !hasBaseURL(redirectURL, "https://objects.githubusercontent.com/") {
WarnAndNotice("Unexpected AssetURL for assetID[%d] in %s: %s", asset.GetID(), g, redirectURL)
return io.NopCloser(strings.NewReader(redirectURL)), nil
@@ -586,24 +581,6 @@ func (g *GithubDownloaderV3) getComments(commentable base.Commentable) ([]*base.
return allComments, nil
}
-func (g *GithubDownloaderV3) filterByHTMLURL(comments []*github.IssueComment, filterBy string) []*github.IssueComment {
- var result []*github.IssueComment
- for _, val := range comments {
- if !strings.Contains(*val.HTMLURL, filterBy) {
- result = append(result, val)
- }
- }
- return result
-}
-
-func (g *GithubDownloaderV3) filterPRComments(comments []*github.IssueComment) []*github.IssueComment {
- return g.filterByHTMLURL(comments, "/pull/")
-}
-
-func (g *GithubDownloaderV3) filterIssueComments(comments []*github.IssueComment) []*github.IssueComment {
- return g.filterByHTMLURL(comments, "/issues/")
-}
-
// GetAllComments returns repository comments according page and perPageSize
func (g *GithubDownloaderV3) GetAllComments(page, perPage int) ([]*base.Comment, bool, error) {
var (
@@ -630,12 +607,6 @@ func (g *GithubDownloaderV3) GetAllComments(page, perPage int) ([]*base.Comment,
}
isEnd := resp.NextPage == 0
- if g.getIssues && !g.getPullRequests {
- comments = g.filterPRComments(comments)
- } else if !g.getIssues && g.getPullRequests {
- comments = g.filterIssueComments(comments)
- }
-
log.Trace("Request get comments %d/%d, but in fact get %d, next page is %d", perPage, page, len(comments), resp.NextPage)
g.setRate(&resp.Rate)
for _, comment := range comments {
@@ -914,18 +885,3 @@ func (g *GithubDownloaderV3) GetReviews(reviewable base.Reviewable) ([]*base.Rev
}
return allReviews, nil
}
-
-// FormatCloneURL add authentication into remote URLs
-func (g *GithubDownloaderV3) FormatCloneURL(opts MigrateOptions, remoteAddr string) (string, error) {
- u, err := url.Parse(remoteAddr)
- if err != nil {
- return "", err
- }
- if len(opts.AuthToken) > 0 {
- // "multiple tokens" are used to benefit more "API rate limit quota"
- // git clone doesn't count for rate limits, so only use the first token.
- // source: https://github.com/orgs/community/discussions/44515
- u.User = url.UserPassword("oauth2", strings.Split(opts.AuthToken, ",")[0])
- }
- return u.String(), nil
-}
diff --git a/services/migrations/github_test.go b/services/migrations/github_test.go
index ef2850d2d2..080fd497ca 100644
--- a/services/migrations/github_test.go
+++ b/services/migrations/github_test.go
@@ -9,103 +9,22 @@ import (
"testing"
"time"
- "forgejo.org/models/unittest"
- base "forgejo.org/modules/migration"
+ "code.gitea.io/gitea/models/unittest"
+ base "code.gitea.io/gitea/modules/migration"
- "github.com/google/go-github/v64/github"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
-func TestGithubDownloaderFilterComments(t *testing.T) {
- GithubLimitRateRemaining = 3 // Wait at 3 remaining since we could have 3 CI in //
-
- token := os.Getenv("GITHUB_READ_TOKEN")
- fixturePath := "./testdata/github/full_download"
- server := unittest.NewMockWebServer(t, "https://api.github.com", fixturePath, false)
- defer server.Close()
-
- downloader := NewGithubDownloaderV3(t.Context(), server.URL, true, true, "", "", token, "forgejo", "test_repo")
- err := downloader.RefreshRate()
- require.NoError(t, err)
-
- var githubComments []*github.IssueComment
- issueID := int64(7)
- iNodeID := "MDEyOklzc3VlQ29tbWVudDE=" // "IssueComment1"
- iBody := "Hello"
- iCreated := new(github.Timestamp)
- iUpdated := new(github.Timestamp)
- iCreated.Time = time.Date(2025, 1, 1, 12, 0, 0, 0, time.UTC)
- iUpdated.Time = time.Date(2025, 1, 1, 12, 1, 0, 0, time.UTC)
- iAssociation := "COLLABORATOR"
- iURL := "https://api.github.com/repos/forgejo/test_repo/issues/comments/3164032267"
- iHTMLURL := "https://github.com/forgejo/test_repo/issues/1#issuecomment-3164032267"
- iIssueURL := "https://api.github.com/repos/forgejo/test_repo/issues/1"
-
- githubComments = append(githubComments,
- &github.IssueComment{
- ID: &issueID,
- NodeID: &iNodeID,
- Body: &iBody,
- Reactions: nil,
- CreatedAt: iCreated,
- UpdatedAt: iUpdated,
- AuthorAssociation: &iAssociation,
- URL: &iURL,
- HTMLURL: &iHTMLURL,
- IssueURL: &iIssueURL,
- },
- )
-
- prID := int64(4)
- pNodeID := "IC_kwDOPQx9Mc65LHhx"
- pBody := "Hello"
- pCreated := new(github.Timestamp)
- pUpdated := new(github.Timestamp)
- pCreated.Time = time.Date(2025, 1, 1, 11, 0, 0, 0, time.UTC)
- pUpdated.Time = time.Date(2025, 1, 1, 11, 1, 0, 0, time.UTC)
- pAssociation := "COLLABORATOR"
- pURL := "https://api.github.com/repos/forgejo/test_repo/issues/comments/3164118916"
- pHTMLURL := "https://github.com/forgejo/test_repo/pull/3#issuecomment-3164118916"
- pIssueURL := "https://api.github.com/repos/forgejo/test_repo/issues/3"
-
- githubComments = append(githubComments, &github.IssueComment{
- ID: &prID,
- NodeID: &pNodeID,
- Body: &pBody,
- Reactions: nil,
- CreatedAt: pCreated,
- UpdatedAt: pUpdated,
- AuthorAssociation: &pAssociation,
- URL: &pURL,
- HTMLURL: &pHTMLURL,
- IssueURL: &pIssueURL,
- })
-
- filteredComments := downloader.filterPRComments(githubComments)
-
- // Check each issue index not being from the PR
- for _, comment := range filteredComments {
- assert.NotEqual(t, *comment.ID, prID)
- }
-
- filteredComments = downloader.filterIssueComments(githubComments)
-
- // Check each issue index not being from the issue
- for _, comment := range filteredComments {
- assert.NotEqual(t, *comment.ID, issueID)
- }
-}
-
func TestGitHubDownloadRepo(t *testing.T) {
GithubLimitRateRemaining = 3 // Wait at 3 remaining since we could have 3 CI in //
token := os.Getenv("GITHUB_READ_TOKEN")
fixturePath := "./testdata/github/full_download"
- server := unittest.NewMockWebServer(t, "https://api.github.com", fixturePath, false)
+ server := unittest.NewMockWebServer(t, "https://api.github.com", fixturePath, token != "")
defer server.Close()
- downloader := NewGithubDownloaderV3(t.Context(), server.URL, true, true, "", "", token, "forgejo", "test_repo")
+ downloader := NewGithubDownloaderV3(t.Context(), server.URL, "", "", token, "go-gitea", "test_repo")
err := downloader.RefreshRate()
require.NoError(t, err)
@@ -113,44 +32,38 @@ func TestGitHubDownloadRepo(t *testing.T) {
require.NoError(t, err)
assertRepositoryEqual(t, &base.Repository{
Name: "test_repo",
- Owner: "forgejo",
- Description: "Exclusively used for testing Github->Forgejo migration",
- CloneURL: server.URL + "/forgejo/test_repo.git",
- OriginalURL: server.URL + "/forgejo/test_repo",
- DefaultBranch: "main",
+ Owner: "go-gitea",
+ Description: "Test repository for testing migration from github to gitea",
+ CloneURL: server.URL + "/go-gitea/test_repo.git",
+ OriginalURL: server.URL + "/go-gitea/test_repo",
+ DefaultBranch: "master",
Website: "https://codeberg.org/forgejo/forgejo/",
}, repo)
topics, err := downloader.GetTopics()
require.NoError(t, err)
- assert.Contains(t, topics, "forgejo")
+ assert.Contains(t, topics, "gitea")
milestones, err := downloader.GetMilestones()
require.NoError(t, err)
assertMilestonesEqual(t, []*base.Milestone{
{
Title: "1.0.0",
- Description: "Version 1",
- Created: time.Date(2025, 8, 7, 12, 48, 56, 0, time.UTC),
- Updated: timePtr(time.Date(2025, time.August, 12, 12, 34, 20, 0, time.UTC)),
- State: "open",
- },
- {
- Title: "0.9.0",
- Description: "A milestone",
- Deadline: timePtr(time.Date(2025, 8, 1, 7, 0, 0, 0, time.UTC)),
- Created: time.Date(2025, 8, 7, 12, 54, 20, 0, time.UTC),
- Updated: timePtr(time.Date(2025, 8, 12, 11, 29, 52, 0, time.UTC)),
- Closed: timePtr(time.Date(2025, 8, 7, 12, 54, 38, 0, time.UTC)),
+ Description: "Milestone 1.0.0",
+ Deadline: timePtr(time.Date(2019, 11, 11, 8, 0, 0, 0, time.UTC)),
+ Created: time.Date(2019, 11, 12, 19, 37, 8, 0, time.UTC),
+ Updated: timePtr(time.Date(2019, 11, 12, 21, 56, 17, 0, time.UTC)),
+ Closed: timePtr(time.Date(2019, 11, 12, 19, 45, 49, 0, time.UTC)),
State: "closed",
},
{
Title: "1.1.0",
- Description: "We can do that",
- Deadline: timePtr(time.Date(2025, 8, 31, 7, 0, 0, 0, time.UTC)),
- Created: time.Date(2025, 8, 7, 12, 50, 58, 0, time.UTC),
- Updated: timePtr(time.Date(2025, 8, 7, 12, 53, 15, 0, time.UTC)),
- State: "open",
+ Description: "Milestone 1.1.0",
+ Deadline: timePtr(time.Date(2019, 11, 12, 8, 0, 0, 0, time.UTC)),
+ Created: time.Date(2019, 11, 12, 19, 37, 25, 0, time.UTC),
+ Updated: timePtr(time.Date(2019, 11, 12, 21, 39, 27, 0, time.UTC)),
+ Closed: timePtr(time.Date(2019, 11, 12, 19, 45, 46, 0, time.UTC)),
+ State: "closed",
},
}, milestones)
@@ -204,34 +117,18 @@ func TestGitHubDownloadRepo(t *testing.T) {
},
}, labels)
- id := int64(280443629)
- ct := "application/pdf"
- size := 550175
- dc := 0
-
releases, err := downloader.GetReleases()
require.NoError(t, err)
assertReleasesEqual(t, []*base.Release{
{
- TagName: "v1.0",
- TargetCommitish: "main",
+ TagName: "v0.9.99",
+ TargetCommitish: "master",
Name: "First Release",
- Body: "Hi, this is the first release! The asset contains the wireguard whitepaper, amazing read for such a simple protocol.",
- Created: time.Date(2025, time.August, 7, 13, 2, 19, 0, time.UTC),
- Published: time.Date(2025, time.August, 7, 13, 7, 49, 0, time.UTC),
- PublisherID: 25481501,
- PublisherName: "Gusted",
- Assets: []*base.ReleaseAsset{
- {
- ID: id,
- Name: "wireguard.pdf",
- ContentType: &ct,
- Size: &size,
- DownloadCount: &dc,
- Created: time.Date(2025, time.August, 7, 23, 39, 27, 0, time.UTC),
- Updated: time.Date(2025, time.August, 7, 23, 39, 29, 0, time.UTC),
- },
- },
+ Body: "A test release",
+ Created: time.Date(2019, 11, 9, 16, 49, 21, 0, time.UTC),
+ Published: time.Date(2019, 11, 12, 20, 12, 10, 0, time.UTC),
+ PublisherID: 1669571,
+ PublisherName: "mrsdizzie",
},
}, releases)
@@ -242,41 +139,85 @@ func TestGitHubDownloadRepo(t *testing.T) {
assertIssuesEqual(t, []*base.Issue{
{
Number: 1,
- Title: "First issue",
- Content: "This is an issue.",
- PosterID: 37243484,
- PosterName: "PatDyn",
- State: "open",
- Created: time.Date(2025, time.August, 7, 12, 44, 7, 0, time.UTC),
- Updated: time.Date(2025, time.August, 7, 12, 44, 47, 0, time.UTC),
- },
- {
- Number: 2,
- Title: "Second Issue",
- Content: "Mentioning #1 ",
- Milestone: "1.1.0",
- PosterID: 37243484,
- PosterName: "PatDyn",
- State: "open",
- Created: time.Date(2025, 8, 7, 12, 45, 44, 0, time.UTC),
- Updated: time.Date(2025, 8, 7, 13, 7, 25, 0, time.UTC),
+ Title: "Please add an animated gif icon to the merge button",
+ Content: "I just want the merge button to hurt my eyes a little. \xF0\x9F\x98\x9D ",
+ Milestone: "1.0.0",
+ PosterID: 18600385,
+ PosterName: "guillep2k",
+ State: "closed",
+ Created: time.Date(2019, 11, 9, 17, 0, 29, 0, time.UTC),
+ Updated: time.Date(2019, 11, 12, 20, 29, 53, 0, time.UTC),
Labels: []*base.Label{
{
- Name: "duplicate",
- Color: "cfd3d7",
- Description: "This issue or pull request already exists",
+ Name: "bug",
+ Color: "d73a4a",
+ Description: "Something isn't working",
},
{
Name: "good first issue",
Color: "7057ff",
Description: "Good for newcomers",
},
+ },
+ Reactions: []*base.Reaction{
{
- Name: "help wanted",
- Color: "008672",
- Description: "Extra attention is needed",
+ UserID: 1669571,
+ UserName: "mrsdizzie",
+ Content: "+1",
},
},
+ Closed: timePtr(time.Date(2019, 11, 12, 20, 22, 22, 0, time.UTC)),
+ },
+ {
+ Number: 2,
+ Title: "Test issue",
+ Content: "This is test issue 2, do not touch!",
+ Milestone: "1.1.0",
+ PosterID: 1669571,
+ PosterName: "mrsdizzie",
+ State: "closed",
+ Created: time.Date(2019, 11, 12, 21, 0, 6, 0, time.UTC),
+ Updated: time.Date(2019, 11, 12, 22, 7, 14, 0, time.UTC),
+ Labels: []*base.Label{
+ {
+ Name: "duplicate",
+ Color: "cfd3d7",
+ Description: "This issue or pull request already exists",
+ },
+ },
+ Reactions: []*base.Reaction{
+ {
+ UserID: 1669571,
+ UserName: "mrsdizzie",
+ Content: "heart",
+ },
+ {
+ UserID: 1669571,
+ UserName: "mrsdizzie",
+ Content: "laugh",
+ },
+ {
+ UserID: 1669571,
+ UserName: "mrsdizzie",
+ Content: "-1",
+ },
+ {
+ UserID: 1669571,
+ UserName: "mrsdizzie",
+ Content: "confused",
+ },
+ {
+ UserID: 1669571,
+ UserName: "mrsdizzie",
+ Content: "hooray",
+ },
+ {
+ UserID: 1669571,
+ UserName: "mrsdizzie",
+ Content: "+1",
+ },
+ },
+ Closed: timePtr(time.Date(2019, 11, 12, 21, 1, 31, 0, time.UTC)),
},
}, issues)
@@ -286,11 +227,26 @@ func TestGitHubDownloadRepo(t *testing.T) {
assertCommentsEqual(t, []*base.Comment{
{
IssueIndex: 2,
- PosterID: 37243484,
- PosterName: "PatDyn",
- Created: time.Date(2025, time.August, 7, 13, 7, 25, 0, time.UTC),
- Updated: time.Date(2025, time.August, 7, 13, 7, 25, 0, time.UTC),
- Content: "Mentioning #3 \nWith some **bold** *statement*",
+ PosterID: 1669571,
+ PosterName: "mrsdizzie",
+ Created: time.Date(2019, 11, 12, 21, 0, 13, 0, time.UTC),
+ Updated: time.Date(2019, 11, 12, 21, 0, 13, 0, time.UTC),
+ Content: "This is a comment",
+ Reactions: []*base.Reaction{
+ {
+ UserID: 1669571,
+ UserName: "mrsdizzie",
+ Content: "+1",
+ },
+ },
+ },
+ {
+ IssueIndex: 2,
+ PosterID: 1669571,
+ PosterName: "mrsdizzie",
+ Created: time.Date(2019, 11, 12, 22, 7, 14, 0, time.UTC),
+ Updated: time.Date(2019, 11, 12, 22, 7, 14, 0, time.UTC),
+ Content: "A second comment",
Reactions: nil,
},
}, comments)
@@ -301,50 +257,52 @@ func TestGitHubDownloadRepo(t *testing.T) {
assertPullRequestsEqual(t, []*base.PullRequest{
{
Number: 3,
- Title: "Update readme.md",
- Content: "Added a feature description",
- Milestone: "1.0.0",
- PosterID: 37243484,
- PosterName: "PatDyn",
- State: "open",
- Created: time.Date(2025, time.August, 7, 12, 47, 6, 0, time.UTC),
- Updated: time.Date(2025, time.August, 12, 13, 16, 49, 0, time.UTC),
+ Title: "Update README.md",
+ Content: "add warning to readme",
+ Milestone: "1.1.0",
+ PosterID: 1669571,
+ PosterName: "mrsdizzie",
+ State: "closed",
+ Created: time.Date(2019, 11, 12, 21, 21, 43, 0, time.UTC),
+ Updated: time.Date(2019, 11, 12, 21, 39, 28, 0, time.UTC),
Labels: []*base.Label{
{
- Name: "enhancement",
- Color: "a2eeef",
- Description: "New feature or request",
+ Name: "documentation",
+ Color: "0075ca",
+ Description: "Improvements or additions to documentation",
},
},
- PatchURL: server.URL + "/forgejo/test_repo/pull/3.patch",
+ PatchURL: server.URL + "/go-gitea/test_repo/pull/3.patch",
Head: base.PullRequestBranch{
- Ref: "some-feature",
- CloneURL: server.URL + "/forgejo/test_repo.git",
- SHA: "c608ab3997349219e1510cdb5ddd1e5e82897dfa",
+ Ref: "master",
+ CloneURL: server.URL + "/mrsdizzie/test_repo.git",
+ SHA: "076160cf0b039f13e5eff19619932d181269414b",
RepoName: "test_repo",
- OwnerName: "forgejo",
+ OwnerName: "mrsdizzie",
},
Base: base.PullRequestBranch{
- Ref: "main",
- SHA: "442d28a55b842472c95bead51a4c61f209ac1636",
- OwnerName: "forgejo",
+ Ref: "master",
+ SHA: "72866af952e98d02a73003501836074b286a78f6",
+ OwnerName: "go-gitea",
RepoName: "test_repo",
},
- ForeignIndex: 3,
+ Closed: timePtr(time.Date(2019, 11, 12, 21, 39, 27, 0, time.UTC)),
+ Merged: true,
+ MergedTime: timePtr(time.Date(2019, 11, 12, 21, 39, 27, 0, time.UTC)),
+ MergeCommitSHA: "f32b0a9dfd09a60f616f29158f772cedd89942d2",
+ ForeignIndex: 3,
},
{
- Number: 7,
- Title: "Update readme.md",
- Content: "Adding some text to the readme",
+ Number: 4,
+ Title: "Test branch",
+ Content: "do not merge this PR",
Milestone: "1.0.0",
- PosterID: 37243484,
- PosterName: "PatDyn",
- State: "closed",
- Created: time.Date(2025, time.August, 7, 13, 1, 36, 0, time.UTC),
- Updated: time.Date(2025, time.August, 12, 12, 47, 35, 0, time.UTC),
- Closed: timePtr(time.Date(2025, time.August, 7, 13, 2, 19, 0, time.UTC)),
- MergedTime: timePtr(time.Date(2025, time.August, 7, 13, 2, 19, 0, time.UTC)),
+ PosterID: 1669571,
+ PosterName: "mrsdizzie",
+ State: "open",
+ Created: time.Date(2019, 11, 12, 21, 54, 18, 0, time.UTC),
+ Updated: time.Date(2020, 1, 4, 11, 30, 1, 0, time.UTC),
Labels: []*base.Label{
{
Name: "bug",
@@ -352,23 +310,35 @@ func TestGitHubDownloadRepo(t *testing.T) {
Description: "Something isn't working",
},
},
- PatchURL: server.URL + "/forgejo/test_repo/pull/7.patch",
+ PatchURL: server.URL + "/go-gitea/test_repo/pull/4.patch",
Head: base.PullRequestBranch{
- Ref: "another-feature",
- SHA: "5638cb8f3278e467fc1eefcac14d3c0d5d91601f",
+ Ref: "test-branch",
+ SHA: "2be9101c543658591222acbee3eb799edfc3853d",
RepoName: "test_repo",
- OwnerName: "forgejo",
- CloneURL: server.URL + "/forgejo/test_repo.git",
+ OwnerName: "mrsdizzie",
+ CloneURL: server.URL + "/mrsdizzie/test_repo.git",
},
Base: base.PullRequestBranch{
- Ref: "main",
- SHA: "6dd0c6801ddbb7333787e73e99581279492ff449",
- OwnerName: "forgejo",
+ Ref: "master",
+ SHA: "f32b0a9dfd09a60f616f29158f772cedd89942d2",
+ OwnerName: "go-gitea",
RepoName: "test_repo",
},
- Merged: true,
- MergeCommitSHA: "ca43b48ca2c461f9a5cb66500a154b23d07c9f90",
- ForeignIndex: 7,
+ Merged: false,
+ MergeCommitSHA: "565d1208f5fffdc1c5ae1a2436491eb9a5e4ebae",
+ Reactions: []*base.Reaction{
+ {
+ UserID: 81045,
+ UserName: "lunny",
+ Content: "heart",
+ },
+ {
+ UserID: 81045,
+ UserName: "lunny",
+ Content: "+1",
+ },
+ },
+ ForeignIndex: 4,
},
}, prs)
@@ -376,85 +346,90 @@ func TestGitHubDownloadRepo(t *testing.T) {
require.NoError(t, err)
assertReviewsEqual(t, []*base.Review{
{
- ID: 3096999684,
+ ID: 315859956,
IssueIndex: 3,
- ReviewerID: 37243484,
- ReviewerName: "PatDyn",
- CommitID: "c608ab3997349219e1510cdb5ddd1e5e82897dfa",
- CreatedAt: time.Date(2025, 8, 7, 12, 47, 55, 0, time.UTC),
- State: base.ReviewStateCommented,
+ ReviewerID: 42128690,
+ ReviewerName: "jolheiser",
+ CommitID: "076160cf0b039f13e5eff19619932d181269414b",
+ CreatedAt: time.Date(2019, 11, 12, 21, 35, 24, 0, time.UTC),
+ State: base.ReviewStateApproved,
+ },
+ {
+ ID: 315860062,
+ IssueIndex: 3,
+ ReviewerID: 1824502,
+ ReviewerName: "zeripath",
+ CommitID: "076160cf0b039f13e5eff19619932d181269414b",
+ CreatedAt: time.Date(2019, 11, 12, 21, 35, 36, 0, time.UTC),
+ State: base.ReviewStateApproved,
+ },
+ {
+ ID: 315861440,
+ IssueIndex: 3,
+ ReviewerID: 165205,
+ ReviewerName: "lafriks",
+ CommitID: "076160cf0b039f13e5eff19619932d181269414b",
+ CreatedAt: time.Date(2019, 11, 12, 21, 38, 0, 0, time.UTC),
+ State: base.ReviewStateApproved,
+ },
+ }, reviews)
+
+ reviews, err = downloader.GetReviews(&base.PullRequest{Number: 4, ForeignIndex: 4})
+ require.NoError(t, err)
+ assertReviewsEqual(t, []*base.Review{
+ {
+ ID: 338338740,
+ IssueIndex: 4,
+ ReviewerID: 81045,
+ ReviewerName: "lunny",
+ CommitID: "2be9101c543658591222acbee3eb799edfc3853d",
+ CreatedAt: time.Date(2020, 1, 4, 5, 33, 18, 0, time.UTC),
+ State: base.ReviewStateApproved,
Comments: []*base.ReviewComment{
{
- ID: 2260216729,
- InReplyTo: 0,
- Content: "May want to write more",
- TreePath: "readme.md",
- DiffHunk: "@@ -1,3 +1,5 @@\n # Forgejo Test Repo\n \n This repo is used to test migrations\n+\n+Add some feature description.",
- Position: 5,
- Line: 0,
- CommitID: "c608ab3997349219e1510cdb5ddd1e5e82897dfa",
- PosterID: 37243484,
- CreatedAt: time.Date(2025, 8, 7, 12, 47, 50, 0, time.UTC),
- UpdatedAt: time.Date(2025, 8, 7, 12, 47, 55, 0, time.UTC),
+ ID: 363017488,
+ Content: "This is a good pull request.",
+ TreePath: "README.md",
+ DiffHunk: "@@ -1,2 +1,4 @@\n # test_repo\n Test repository for testing migration from github to gitea\n+",
+ Position: 3,
+ CommitID: "2be9101c543658591222acbee3eb799edfc3853d",
+ PosterID: 81045,
+ CreatedAt: time.Date(2020, 1, 4, 5, 33, 6, 0, time.UTC),
+ UpdatedAt: time.Date(2020, 1, 4, 5, 33, 18, 0, time.UTC),
},
},
},
{
- ID: 3097007243,
- IssueIndex: 3,
- ReviewerID: 37243484,
- ReviewerName: "PatDyn",
- CommitID: "c608ab3997349219e1510cdb5ddd1e5e82897dfa",
- CreatedAt: time.Date(2025, 8, 7, 12, 49, 36, 0, time.UTC),
+ ID: 338339651,
+ IssueIndex: 4,
+ ReviewerID: 81045,
+ ReviewerName: "lunny",
+ CommitID: "2be9101c543658591222acbee3eb799edfc3853d",
+ CreatedAt: time.Date(2020, 1, 4, 6, 7, 6, 0, time.UTC),
+ State: base.ReviewStateChangesRequested,
+ Content: "Don't add more reviews",
+ },
+ {
+ ID: 338349019,
+ IssueIndex: 4,
+ ReviewerID: 81045,
+ ReviewerName: "lunny",
+ CommitID: "2be9101c543658591222acbee3eb799edfc3853d",
+ CreatedAt: time.Date(2020, 1, 4, 11, 21, 41, 0, time.UTC),
State: base.ReviewStateCommented,
Comments: []*base.ReviewComment{
{
- ID: 2260221159,
- InReplyTo: 0,
- Content: "Comment",
- TreePath: "readme.md",
- DiffHunk: "@@ -1,3 +1,5 @@\n # Forgejo Test Repo\n \n This repo is used to test migrations",
- Position: 3,
- Line: 0,
- CommitID: "c608ab3997349219e1510cdb5ddd1e5e82897dfa",
- PosterID: 37243484,
- CreatedAt: time.Date(2025, 8, 7, 12, 49, 36, 0, time.UTC),
- UpdatedAt: time.Date(2025, 8, 7, 12, 49, 36, 0, time.UTC),
+ ID: 363029944,
+ Content: "test a single comment.",
+ TreePath: "LICENSE",
+ DiffHunk: "@@ -19,3 +19,5 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n SOFTWARE.\n+",
+ Position: 4,
+ CommitID: "2be9101c543658591222acbee3eb799edfc3853d",
+ PosterID: 81045,
+ CreatedAt: time.Date(2020, 1, 4, 11, 21, 41, 0, time.UTC),
+ UpdatedAt: time.Date(2020, 1, 4, 11, 21, 41, 0, time.UTC),
},
},
},
}, reviews)
}
-
-func TestGithubMultiToken(t *testing.T) {
- testCases := []struct {
- desc string
- token string
- expectedCloneURL string
- }{
- {
- desc: "Single Token",
- token: "single_token",
- expectedCloneURL: "https://oauth2:single_token@github.com",
- },
- {
- desc: "Multi Token",
- token: "token1,token2",
- expectedCloneURL: "https://oauth2:token1@github.com",
- },
- }
- factory := GithubDownloaderV3Factory{}
-
- for _, tC := range testCases {
- t.Run(tC.desc, func(t *testing.T) {
- opts := base.MigrateOptions{CloneAddr: "https://github.com/go-gitea/gitea", AuthToken: tC.token}
- client, err := factory.New(t.Context(), opts)
- require.NoError(t, err)
-
- cloneURL, err := client.FormatCloneURL(opts, "https://github.com")
- require.NoError(t, err)
-
- assert.Equal(t, tC.expectedCloneURL, cloneURL)
- })
- }
-}
diff --git a/services/migrations/gitlab.go b/services/migrations/gitlab.go
index f54f682c47..2eb3e6629d 100644
--- a/services/migrations/gitlab.go
+++ b/services/migrations/gitlab.go
@@ -15,12 +15,12 @@ import (
"strings"
"time"
- issues_model "forgejo.org/models/issues"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/container"
- "forgejo.org/modules/log"
- base "forgejo.org/modules/migration"
- "forgejo.org/modules/structs"
+ issues_model "code.gitea.io/gitea/models/issues"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/container"
+ "code.gitea.io/gitea/modules/log"
+ base "code.gitea.io/gitea/modules/migration"
+ "code.gitea.io/gitea/modules/structs"
gitlab "gitlab.com/gitlab-org/api/client-go"
)
@@ -99,7 +99,6 @@ func NewGitlabDownloader(ctx context.Context, baseURL, repoPath, username, passw
// Only use basic auth if token is blank and password is NOT
// Basic auth will fail with empty strings, but empty token will allow anonymous public API usage
if token == "" && password != "" {
- //nolint // SA1019 gitlab.NewBasicAuthClient is deprecated: GitLab recommends against using this authentication method
gitlabClient, err = gitlab.NewBasicAuthClient(username, password, gitlab.WithBaseURL(baseURL), gitlab.WithHTTPClient(NewMigrationHTTPClient()))
}
@@ -214,7 +213,7 @@ func (g *GitlabDownloader) GetTopics() ([]string, error) {
if err != nil {
return nil, err
}
- return gr.Topics, err
+ return gr.TagList, err
}
// GetMilestones returns milestones
diff --git a/services/migrations/gitlab_test.go b/services/migrations/gitlab_test.go
index 30b24f09e8..f1404d946d 100644
--- a/services/migrations/gitlab_test.go
+++ b/services/migrations/gitlab_test.go
@@ -12,9 +12,9 @@ import (
"testing"
"time"
- "forgejo.org/models/unittest"
- "forgejo.org/modules/json"
- base "forgejo.org/modules/migration"
+ "code.gitea.io/gitea/models/unittest"
+ "code.gitea.io/gitea/modules/json"
+ base "code.gitea.io/gitea/modules/migration"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -49,7 +49,7 @@ func TestGitlabDownloadRepo(t *testing.T) {
topics, err := downloader.GetTopics()
require.NoError(t, err)
assert.Len(t, topics, 2)
- assert.Equal(t, []string{"migration", "test"}, topics)
+ assert.EqualValues(t, []string{"migration", "test"}, topics)
milestones, err := downloader.GetMilestones()
require.NoError(t, err)
@@ -352,7 +352,7 @@ func TestGitlabSkippedIssueNumber(t *testing.T) {
// the only issue in this repository has number 2
assert.Len(t, issues, 1)
assert.EqualValues(t, 2, issues[0].Number)
- assert.Equal(t, "vpn unlimited errors", issues[0].Title)
+ assert.EqualValues(t, "vpn unlimited errors", issues[0].Title)
prs, _, err := downloader.GetPullRequests(1, 10)
require.NoError(t, err)
@@ -361,7 +361,7 @@ func TestGitlabSkippedIssueNumber(t *testing.T) {
// pull request 3 in Forgejo
assert.Len(t, prs, 1)
assert.EqualValues(t, 3, prs[0].Number)
- assert.Equal(t, "Review", prs[0].Title)
+ assert.EqualValues(t, "Review", prs[0].Title)
}
func gitlabClientMockSetup(t *testing.T) (*http.ServeMux, *httptest.Server, *gitlab.Client) {
@@ -531,7 +531,7 @@ func TestAwardsToReactions(t *testing.T) {
require.NoError(t, json.Unmarshal([]byte(testResponse), &awards))
reactions := downloader.awardsToReactions(awards)
- assert.Equal(t, []*base.Reaction{
+ assert.EqualValues(t, []*base.Reaction{
{
UserName: "lafriks",
UserID: 1241334,
@@ -623,7 +623,7 @@ func TestNoteToComment(t *testing.T) {
for i, note := range notes {
actualComment := *downloader.convertNoteToComment(17, ¬e)
- assert.Equal(t, actualComment, comments[i])
+ assert.EqualValues(t, actualComment, comments[i])
}
}
diff --git a/services/migrations/gogs.go b/services/migrations/gogs.go
index b6fb8cef0a..1fef4808b0 100644
--- a/services/migrations/gogs.go
+++ b/services/migrations/gogs.go
@@ -11,10 +11,10 @@ import (
"strings"
"time"
- "forgejo.org/modules/log"
- base "forgejo.org/modules/migration"
- "forgejo.org/modules/proxy"
- "forgejo.org/modules/structs"
+ "code.gitea.io/gitea/modules/log"
+ base "code.gitea.io/gitea/modules/migration"
+ "code.gitea.io/gitea/modules/proxy"
+ "code.gitea.io/gitea/modules/structs"
"github.com/gogs/go-gogs-client"
)
diff --git a/services/migrations/gogs_test.go b/services/migrations/gogs_test.go
index bf0d063ca4..450aeab5ef 100644
--- a/services/migrations/gogs_test.go
+++ b/services/migrations/gogs_test.go
@@ -9,7 +9,7 @@ import (
"testing"
"time"
- base "forgejo.org/modules/migration"
+ base "code.gitea.io/gitea/modules/migration"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -25,7 +25,7 @@ func TestGogsDownloadRepo(t *testing.T) {
resp, err := http.Get("https://try.gogs.io/lunnytest/TESTREPO")
if err != nil || resp.StatusCode/100 != 2 {
// skip and don't run test
- t.Skip("visit test repo failed, ignored")
+ t.Skipf("visit test repo failed, ignored")
return
}
@@ -215,9 +215,9 @@ func TestGogsDownloaderFactory_New(t *testing.T) {
}
assert.IsType(t, &GogsDownloader{}, got)
- assert.Equal(t, tt.baseURL, got.(*GogsDownloader).baseURL)
- assert.Equal(t, tt.repoOwner, got.(*GogsDownloader).repoOwner)
- assert.Equal(t, tt.repoName, got.(*GogsDownloader).repoName)
+ assert.EqualValues(t, tt.baseURL, got.(*GogsDownloader).baseURL)
+ assert.EqualValues(t, tt.repoOwner, got.(*GogsDownloader).repoOwner)
+ assert.EqualValues(t, tt.repoName, got.(*GogsDownloader).repoName)
})
}
}
diff --git a/services/migrations/http_client.go b/services/migrations/http_client.go
index 26962f2976..0b997e08f4 100644
--- a/services/migrations/http_client.go
+++ b/services/migrations/http_client.go
@@ -7,9 +7,9 @@ import (
"crypto/tls"
"net/http"
- "forgejo.org/modules/hostmatcher"
- "forgejo.org/modules/proxy"
- "forgejo.org/modules/setting"
+ "code.gitea.io/gitea/modules/hostmatcher"
+ "code.gitea.io/gitea/modules/proxy"
+ "code.gitea.io/gitea/modules/setting"
)
// NewMigrationHTTPClient returns a HTTP client for migration
diff --git a/services/migrations/main_test.go b/services/migrations/main_test.go
index d543bd6d9c..f78d75e4db 100644
--- a/services/migrations/main_test.go
+++ b/services/migrations/main_test.go
@@ -8,8 +8,8 @@ import (
"testing"
"time"
- "forgejo.org/models/unittest"
- base "forgejo.org/modules/migration"
+ "code.gitea.io/gitea/models/unittest"
+ base "code.gitea.io/gitea/modules/migration"
"github.com/stretchr/testify/assert"
)
@@ -136,7 +136,6 @@ func assertPullRequestEqual(t *testing.T, expected, actual *base.PullRequest) {
assert.ElementsMatch(t, expected.Assignees, actual.Assignees)
assert.Equal(t, expected.IsLocked, actual.IsLocked)
assertReactionsEqual(t, expected.Reactions, actual.Reactions)
- assert.Equal(t, expected.Flow, actual.Flow)
}
func assertPullRequestsEqual(t *testing.T, expected, actual []*base.PullRequest) {
diff --git a/services/migrations/migrate.go b/services/migrations/migrate.go
index 61630d9c6d..ccb9cb7e98 100644
--- a/services/migrations/migrate.go
+++ b/services/migrations/migrate.go
@@ -6,23 +6,22 @@ package migrations
import (
"context"
- "errors"
"fmt"
"net"
"net/url"
"path/filepath"
"strings"
- "forgejo.org/models"
- repo_model "forgejo.org/models/repo"
- system_model "forgejo.org/models/system"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/hostmatcher"
- "forgejo.org/modules/log"
- base "forgejo.org/modules/migration"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/structs"
- "forgejo.org/modules/util"
+ "code.gitea.io/gitea/models"
+ repo_model "code.gitea.io/gitea/models/repo"
+ system_model "code.gitea.io/gitea/models/system"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/hostmatcher"
+ "code.gitea.io/gitea/modules/log"
+ base "code.gitea.io/gitea/modules/migration"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/util"
)
// MigrateOptions is equal to base.MigrateOptions
@@ -228,7 +227,7 @@ func migrateRepository(_ context.Context, doer *user_model.User, downloader base
if cloneURL.Scheme == "file" || cloneURL.Scheme == "" {
if cloneAddrURL.Scheme != "file" && cloneAddrURL.Scheme != "" {
- return errors.New("repo info has changed from external to local filesystem")
+ return fmt.Errorf("repo info has changed from external to local filesystem")
}
}
diff --git a/services/migrations/migrate_test.go b/services/migrations/migrate_test.go
index 804d01df7a..6e45cbd906 100644
--- a/services/migrations/migrate_test.go
+++ b/services/migrations/migrate_test.go
@@ -8,9 +8,9 @@ import (
"path/filepath"
"testing"
- "forgejo.org/models/unittest"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/setting"
+ "code.gitea.io/gitea/models/unittest"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/setting"
"github.com/stretchr/testify/require"
)
diff --git a/services/migrations/onedev.go b/services/migrations/onedev.go
index a553a4d8f5..e2f7b771f3 100644
--- a/services/migrations/onedev.go
+++ b/services/migrations/onedev.go
@@ -12,10 +12,10 @@ import (
"strings"
"time"
- "forgejo.org/modules/json"
- "forgejo.org/modules/log"
- base "forgejo.org/modules/migration"
- "forgejo.org/modules/structs"
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/log"
+ base "code.gitea.io/gitea/modules/migration"
+ "code.gitea.io/gitea/modules/structs"
)
var (
diff --git a/services/migrations/onedev_test.go b/services/migrations/onedev_test.go
index 5bb2e2bb5c..46e3eb8d18 100644
--- a/services/migrations/onedev_test.go
+++ b/services/migrations/onedev_test.go
@@ -9,7 +9,7 @@ import (
"testing"
"time"
- base "forgejo.org/modules/migration"
+ base "code.gitea.io/gitea/modules/migration"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
diff --git a/services/migrations/pagure.go b/services/migrations/pagure.go
deleted file mode 100644
index f9433671c0..0000000000
--- a/services/migrations/pagure.go
+++ /dev/null
@@ -1,600 +0,0 @@
-// Copyright 2025 The Forgejo Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package migrations
-
-import (
- "context"
- "fmt"
- "net/http"
- "net/url"
- "strconv"
- "strings"
- "time"
-
- "forgejo.org/modules/json"
- "forgejo.org/modules/log"
- base "forgejo.org/modules/migration"
- "forgejo.org/modules/proxy"
- "forgejo.org/modules/structs"
- "forgejo.org/modules/util"
-)
-
-var (
- _ base.Downloader = &PagureDownloader{}
- _ base.DownloaderFactory = &PagureDownloaderFactory{}
-)
-
-func init() {
- RegisterDownloaderFactory(&PagureDownloaderFactory{})
-}
-
-// PagureDownloaderFactory defines a downloader factory
-type PagureDownloaderFactory struct{}
-
-// PagureUser defines a user on Pagure to be migrated over to Forgejo
-type PagureUser struct {
- FullURL string `json:"full_url"`
- Fullname string `json:"fullname"`
- Name string `json:"name"`
- URLPath string `json:"url_path"`
-}
-
-// PagureRepoInfo describes the repository with preliminary information
-type PagureRepoInfo struct {
- ID int64 `json:"id"`
- Name string `json:"name"`
- FullName string `json:"fullname"`
- Description string `json:"description"`
- Topics []string `json:"tags"`
- CloseStatuses []string `json:"close_status"`
- Priorities map[string]string `json:"priorities"`
- Milestones map[string]struct {
- Active bool `json:"active"`
- Date *string `json:"date"`
- } `json:"milestones"`
-}
-
-// PagureDownloader implements a Downloader interface to get repository information from Pagure
-type PagureDownloader struct {
- base.NullDownloader
- ctx context.Context
- client *http.Client
- baseURL *url.URL
- meta PagureRepoInfo
- repoName string
- token string
- privateIssuesOnlyRepo bool
- repoID int64
- maxIssueIndex int64
- userMap map[string]*PagureUser
- milestoneMap map[int64]string
- priorities map[string]string
-}
-
-// PagureLabelsList defines a list of labels under an issue tracker
-type PagureLabelsList struct {
- Labels []string `json:"tags"`
-}
-
-// PagureLabel defines a label under the issue tracker labels list
-type PagureLabel struct {
- Label string `json:"tag"`
- LabelColor string `json:"tag_color"`
- LabelDescription string `json:"tag_description"`
-}
-
-// PagureIssueContext confirms if a said unit is an issue ticket or a pull request
-type PagureIssueContext struct {
- IsPullRequest bool
-}
-
-// PagureIssuesResponse describes a list of issue tickets under an issue tracker
-type PagureIssuesResponse struct {
- Issues []struct {
- Assignee any `json:"assignee"`
- Blocks []string `json:"blocks"`
- CloseStatus string `json:"close_status"`
- ClosedAt string `json:"closed_at"`
- ClosedBy any `json:"closed_by"`
- Comments []any `json:"comments"`
- Content string `json:"content"`
- CustomFields []any `json:"custom_fields"`
- DateCreated string `json:"date_created"`
- Depends []any `json:"depends"`
- ID int64 `json:"id"`
- LastUpdated string `json:"last_updated"`
- Milestone string `json:"milestone"`
- Priority int64 `json:"priority"`
- Private bool `json:"private"`
- Status string `json:"status"`
- Tags []string `json:"tags"`
- Title string `json:"title"`
- User PagureUser `json:"user"`
- } `json:"issues"`
- Pagination struct {
- First string `json:"first"`
- Last string `json:"last"`
- Next *string `json:"next"`
- Page int `json:"page"`
- Pages int `json:"pages"`
- PerPage int `json:"per_page"`
- Prev string `json:"prev"`
- }
-}
-
-// PagureIssueDetail describes a list of issue comments under an issue ticket
-type PagureIssueDetail struct {
- Comment string `json:"comment"`
- DateCreated string `json:"date_created"`
- ID int64 `json:"id"`
- Notification bool `json:"notification"`
- User PagureUser `json:"user"`
-}
-
-// PagureCommitInfo describes a commit
-type PagureCommitInfo struct {
- Author string `json:"author"`
- CommitTime int64 `json:"commit_time"`
- CommitTimeOffset int `json:"commit_time_offset"`
- Committer string `json:"committer"`
- Hash string `json:"hash"`
- Message string `json:"message"`
- ParentIDs []string `json:"parent_ids"`
- TreeID string `json:"tree_id"`
-}
-
-// PagurePRRresponse describes a list of pull requests under an issue tracker
-type PagurePRResponse struct {
- Pagination struct {
- Next *string `json:"next"`
- } `json:"pagination"`
- Requests []struct {
- Branch string `json:"branch"`
- BranchFrom string `json:"branch_from"`
- CommitStop string `json:"commit_stop"`
- DateCreated string `json:"date_created"`
- FullURL string `json:"full_url"`
- ID int `json:"id"`
- InitialComment string `json:"initial_comment"`
- LastUpdated string `json:"last_updated"`
- Status string `json:"status"`
- Tags []string `json:"tags"`
- Title string `json:"title"`
- User PagureUser `json:"user"`
- ClosedAt string `json:"closed_at"`
- ClosedBy PagureUser `json:"closed_by"`
- RepoFrom struct {
- FullURL string `json:"full_url"`
- } `json:"repo_from"`
- } `json:"requests"`
-}
-
-// processDate converts epoch time string to Go formatted time
-func processDate(dateStr *string) time.Time {
- date := time.Time{}
- if dateStr == nil || *dateStr == "" {
- return date
- }
-
- unix, err := strconv.Atoi(*dateStr)
- if err != nil {
- log.Error("Error:", err)
- return date
- }
-
- date = time.Unix(int64(unix), 0)
- return date
-}
-
-// New returns a downloader related to this factory according MigrateOptions
-func (f *PagureDownloaderFactory) New(ctx context.Context, opts base.MigrateOptions) (base.Downloader, error) {
- u, err := url.Parse(opts.CloneAddr)
- if err != nil {
- return nil, err
- }
-
- var repoName string
-
- fields := strings.Split(strings.Trim(u.Path, "/"), "/")
- if len(fields) == 2 {
- repoName = fields[0] + "/" + strings.TrimSuffix(fields[1], ".git")
- } else if len(fields) == 1 {
- repoName = strings.TrimSuffix(fields[0], ".git")
- } else {
- return nil, fmt.Errorf("invalid path: %s", u.Path)
- }
-
- u.Path, u.Fragment = "", ""
- log.Info("Create Pagure downloader. BaseURL: %v RepoName: %s", u, repoName)
-
- return NewPagureDownloader(ctx, u, opts.AuthToken, repoName), nil
-}
-
-// GitServiceType returns the type of Git service
-func (f *PagureDownloaderFactory) GitServiceType() structs.GitServiceType {
- return structs.PagureService
-}
-
-// SetContext sets context
-func (d *PagureDownloader) SetContext(ctx context.Context) {
- d.ctx = ctx
-}
-
-// NewPagureDownloader creates a new downloader object
-func NewPagureDownloader(ctx context.Context, baseURL *url.URL, token, repoName string) *PagureDownloader {
- var privateIssuesOnlyRepo bool
- if token != "" {
- privateIssuesOnlyRepo = true
- }
-
- downloader := &PagureDownloader{
- ctx: ctx,
- baseURL: baseURL,
- repoName: repoName,
- client: &http.Client{
- Transport: &http.Transport{
- Proxy: proxy.Proxy(),
- },
- },
- token: token,
- privateIssuesOnlyRepo: privateIssuesOnlyRepo,
- userMap: make(map[string]*PagureUser),
- milestoneMap: make(map[int64]string),
- priorities: make(map[string]string),
- }
-
- return downloader
-}
-
-// String sets the default text for information purposes
-func (d *PagureDownloader) String() string {
- return fmt.Sprintf("migration from Pagure server %s [%d]/%s", d.baseURL, d.repoID, d.repoName)
-}
-
-// LogString sets the default text for logging purposes
-func (d *PagureDownloader) LogString() string {
- if d == nil {
- return ""
- }
- return fmt.Sprintf("", d.baseURL, d.repoID, d.repoName)
-}
-
-// callAPI handles all the requests made against Pagure
-func (d *PagureDownloader) callAPI(endpoint string, parameter map[string]string, result any) error {
- u, err := d.baseURL.Parse(endpoint)
- if err != nil {
- return err
- }
-
- if parameter != nil {
- query := u.Query()
- for k, v := range parameter {
- query.Set(k, v)
- }
- u.RawQuery = query.Encode()
- }
-
- req, err := http.NewRequestWithContext(d.ctx, "GET", u.String(), nil)
- if err != nil {
- return err
- }
- if d.privateIssuesOnlyRepo {
- req.Header.Set("Authorization", "token "+d.token)
- }
-
- resp, err := d.client.Do(req)
- if err != nil {
- return err
- }
- defer resp.Body.Close()
-
- decoder := json.NewDecoder(resp.Body)
- return decoder.Decode(&result)
-}
-
-// GetRepoInfo returns repository information from Pagure
-func (d *PagureDownloader) GetRepoInfo() (*base.Repository, error) {
- err := d.callAPI("/api/0/"+d.repoName, nil, &d.meta)
- if err != nil {
- return nil, err
- }
-
- d.repoID, d.priorities = d.meta.ID, d.meta.Priorities
-
- cloneURL, err := d.baseURL.Parse(d.meta.FullName)
- if err != nil {
- return nil, err
- }
- originalURL, err := d.baseURL.Parse(d.meta.FullName)
- if err != nil {
- return nil, err
- }
-
- return &base.Repository{
- Name: d.meta.Name,
- Description: d.meta.Description,
- CloneURL: cloneURL.String() + ".git",
- OriginalURL: originalURL.String(),
- }, nil
-}
-
-// GetMilestones returns milestones information from Pagure
-func (d *PagureDownloader) GetMilestones() ([]*base.Milestone, error) {
- milestones := make([]*base.Milestone, 0, len(d.meta.Milestones))
- for name, details := range d.meta.Milestones {
- state := "closed"
- if details.Active {
- state = "open"
- }
-
- deadline := processDate(details.Date)
- milestones = append(milestones, &base.Milestone{
- Title: name,
- Description: "",
- Deadline: &deadline,
- State: state,
- })
- }
-
- return milestones, nil
-}
-
-// GetLabels returns labels information from Pagure
-func (d *PagureDownloader) GetLabels() ([]*base.Label, error) {
- rawLabels := PagureLabelsList{}
-
- err := d.callAPI("/api/0/"+d.repoName+"/tags", nil, &rawLabels)
- if err != nil {
- return nil, err
- }
-
- labels := make([]*base.Label, 0, len(rawLabels.Labels)+len(d.meta.CloseStatuses))
-
- for _, label := range rawLabels.Labels {
- rawLabel := PagureLabel{}
- err = d.callAPI("/api/0/"+d.repoName+"/tag/"+label, nil, &rawLabel)
- if err != nil {
- return nil, err
- }
- labels = append(labels, &base.Label{
- Name: label,
- Description: rawLabel.LabelDescription,
- Color: strings.TrimPrefix(rawLabel.LabelColor, "#"),
- })
- }
-
- for _, closeStatus := range d.meta.CloseStatuses {
- labels = append(labels, &base.Label{
- Name: "Closed As/" + closeStatus,
- Description: "Closed with the reason of " + closeStatus,
- Color: "FF0000",
- Exclusive: true,
- })
- }
-
- for _, value := range d.priorities {
- if value != "" {
- labels = append(labels, &base.Label{
- Name: "Priority/" + value,
- Description: "Priority of " + value,
- Color: "FF00FF",
- Exclusive: true,
- })
- }
- }
-
- return labels, nil
-}
-
-// GetIssues returns issue tickets from Pagure
-func (d *PagureDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, error) {
- rawIssues := PagureIssuesResponse{}
-
- err := d.callAPI(
- "/api/0/"+d.repoName+"/issues",
- map[string]string{
- "page": strconv.Itoa(page),
- "per_page": strconv.Itoa(perPage),
- "status": "all",
- },
- &rawIssues,
- )
- if err != nil {
- return nil, false, err
- }
-
- issues := make([]*base.Issue, 0, len(rawIssues.Issues))
- for _, issue := range rawIssues.Issues {
- log.Debug("Processing issue %d", issue.ID)
- if d.privateIssuesOnlyRepo && !issue.Private {
- log.Info("Skipping issue %d because it is not private and we are only downloading private issues", issue.ID)
- continue
- }
- labels := []*base.Label{}
- for _, tag := range issue.Tags {
- labels = append(labels, &base.Label{Name: tag})
- }
-
- if issue.CloseStatus != "" {
- labels = append(labels, &base.Label{Name: "Closed As/" + issue.CloseStatus})
- }
-
- priorityStr := ""
- if issue.Priority != 0 {
- priorityStr = strconv.FormatInt(issue.Priority, 10)
- }
-
- if priorityStr != "" {
- priorityValue, ok := d.priorities[priorityStr]
- if ok {
- labels = append(labels, &base.Label{Name: "Priority/" + priorityValue})
- }
- }
- log.Trace("Adding issue: %d", issue.ID)
-
- closedat := processDate(&issue.ClosedAt)
-
- issues = append(issues, &base.Issue{
- Title: issue.Title,
- Number: issue.ID,
- PosterName: issue.User.Name,
- PosterID: -1,
- Content: issue.Content,
- Milestone: issue.Milestone,
- State: strings.ToLower(issue.Status),
- Created: processDate(&issue.DateCreated),
- Updated: processDate(&issue.LastUpdated),
- Closed: &closedat,
- Labels: labels,
- ForeignIndex: issue.ID,
- Context: PagureIssueContext{IsPullRequest: false},
- })
-
- if d.maxIssueIndex < issue.ID {
- d.maxIssueIndex = issue.ID
- }
- }
- hasNext := rawIssues.Pagination.Next == nil
-
- return issues, hasNext, nil
-}
-
-// GetComments returns issue comments from Pagure
-func (d *PagureDownloader) GetComments(commentable base.Commentable) ([]*base.Comment, bool, error) {
- context, ok := commentable.GetContext().(PagureIssueContext)
- if !ok {
- return nil, false, fmt.Errorf("unexpected context: %+v", commentable.GetContext())
- }
-
- list := struct {
- Comments []PagureIssueDetail `json:"comments"`
- }{}
- var endpoint string
-
- if context.IsPullRequest {
- endpoint = fmt.Sprintf("/api/0/%s/pull-request/%d", d.repoName, commentable.GetForeignIndex())
- } else {
- endpoint = fmt.Sprintf("/api/0/%s/issue/%d", d.repoName, commentable.GetForeignIndex())
- }
-
- err := d.callAPI(endpoint, nil, &list)
- if err != nil {
- log.Error("Error calling API: %v", err)
- return nil, false, err
- }
-
- comments := make([]*base.Comment, 0, len(list.Comments))
- for _, unit := range list.Comments {
- if len(unit.Comment) == 0 {
- log.Error("Empty comment")
- continue
- }
-
- log.Trace("Adding comment: %d", unit.ID)
- c := &base.Comment{
- IssueIndex: commentable.GetLocalIndex(),
- Index: unit.ID,
- PosterName: unit.User.Name,
- PosterID: -1,
- Content: unit.Comment,
- Created: processDate(&unit.DateCreated),
- }
- comments = append(comments, c)
- }
-
- return comments, true, nil
-}
-
-// GetPullRequests returns pull requests from Pagure
-func (d *PagureDownloader) GetPullRequests(page, perPage int) ([]*base.PullRequest, bool, error) {
- // Could not figure out how to disable this in opts, so if a private issues only repo,
- // We just return an empty list
- if d.privateIssuesOnlyRepo {
- pullRequests := make([]*base.PullRequest, 0)
- return pullRequests, true, nil
- }
-
- rawPullRequests := PagurePRResponse{}
- commit := PagureCommitInfo{}
-
- err := d.callAPI(
- "/api/0/"+d.repoName+"/pull-requests",
- map[string]string{
- "page": strconv.Itoa(page),
- "per_page": strconv.Itoa(perPage),
- "status": "all",
- },
- &rawPullRequests,
- )
- if err != nil {
- return nil, false, err
- }
-
- pullRequests := make([]*base.PullRequest, 0, len(rawPullRequests.Requests))
-
- for _, pr := range rawPullRequests.Requests {
- var state, baseSHA string
- var merged bool
- labels := []*base.Label{}
-
- for _, tag := range pr.Tags {
- labels = append(labels, &base.Label{Name: tag})
- }
- mergedtime := processDate(&pr.ClosedAt)
-
- err = d.callAPI("/api/0/"+d.repoName+"/c/"+pr.CommitStop+"/info", nil, &commit)
- if err != nil {
- return nil, false, err
- }
-
- if util.ASCIIEqualFold(pr.Status, "merged") {
- state, merged, baseSHA = "closed", true, commit.ParentIDs[0]
- } else if util.ASCIIEqualFold(pr.Status, "open") {
- state, merged, baseSHA = "open", false, commit.ParentIDs[0]
- } else {
- state, merged, baseSHA = "closed", false, commit.ParentIDs[0]
- }
-
- pullRequests = append(pullRequests, &base.PullRequest{
- Title: pr.Title,
- Number: int64(pr.ID),
- PosterName: pr.User.Name,
- PosterID: -1,
- Content: pr.InitialComment,
- State: state,
- Created: processDate(&pr.DateCreated),
- Updated: processDate(&pr.LastUpdated),
- MergedTime: &mergedtime,
- Closed: &mergedtime,
- Merged: merged,
- Labels: labels,
- Head: base.PullRequestBranch{
- Ref: pr.BranchFrom,
- SHA: pr.CommitStop,
- RepoName: d.repoName,
- CloneURL: pr.RepoFrom.FullURL + ".git",
- },
- Base: base.PullRequestBranch{
- Ref: pr.Branch,
- SHA: baseSHA,
- RepoName: d.repoName,
- },
- ForeignIndex: int64(pr.ID),
- PatchURL: pr.FullURL + ".patch",
- Context: PagureIssueContext{IsPullRequest: true},
- })
-
- // SECURITY: Ensure that the PR is safe
- _ = CheckAndEnsureSafePR(pullRequests[len(pullRequests)-1], d.baseURL.String(), d)
- }
-
- hasNext := rawPullRequests.Pagination.Next == nil
-
- return pullRequests, hasNext, nil
-}
-
-// GetTopics return repository topics from Pagure
-func (d *PagureDownloader) GetTopics() ([]string, error) {
- return d.meta.Topics, nil
-}
diff --git a/services/migrations/pagure_test.go b/services/migrations/pagure_test.go
deleted file mode 100644
index 22b2eed85e..0000000000
--- a/services/migrations/pagure_test.go
+++ /dev/null
@@ -1,637 +0,0 @@
-// Copyright 2025 The Forgejo Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package migrations
-
-import (
- "net/url"
- "os"
- "strings"
- "testing"
- "time"
-
- "forgejo.org/models/unittest"
- base "forgejo.org/modules/migration"
-
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
-)
-
-func TestPagureDownloadRepoWithPublicIssues(t *testing.T) {
- // Skip tests if Pagure token is not found
- cloneUser := os.Getenv("PAGURE_CLONE_USER")
- clonePassword := os.Getenv("PAGURE_CLONE_PASSWORD")
- apiUser := os.Getenv("PAGURE_API_USER")
- apiPassword := os.Getenv("PAGURE_API_TOKEN")
-
- fixtPath := "./testdata/pagure/full_download/unauthorized"
- server := unittest.NewMockWebServer(t, "https://pagure.io", fixtPath, false)
- defer server.Close()
-
- serverURL, err := url.Parse(server.URL)
- require.NoError(t, err)
-
- if clonePassword != "" || cloneUser != "" {
- serverURL.User = url.UserPassword(cloneUser, clonePassword)
- }
- serverURL.Path = "protop2g-test-srce.git"
- cloneAddr := serverURL.String()
-
- factory := &PagureDownloaderFactory{}
- downloader, err := factory.New(t.Context(), base.MigrateOptions{
- CloneAddr: cloneAddr,
- AuthUsername: apiUser,
- AuthPassword: apiPassword,
- })
- require.NoError(t, err)
-
- repo, err := downloader.GetRepoInfo()
- require.NoError(t, err)
-
- // Testing repository contents migration
- assertRepositoryEqual(t, &base.Repository{
- Name: "protop2g-test-srce",
- Owner: "",
- Description: "The source namespace for the Pagure Exporter project to run tests against",
- CloneURL: cloneAddr,
- OriginalURL: strings.ReplaceAll(cloneAddr, ".git", ""),
- }, repo)
-
- topics, err := downloader.GetTopics()
- require.NoError(t, err)
-
- // Testing repository topics migration
- assert.Equal(t, []string{"srce", "test", "gridhead", "protop2g"}, topics)
-
- // Testing labels migration
- labels, err := downloader.GetLabels()
- require.NoError(t, err)
- assert.Len(t, labels, 15)
-
- // Testing issue tickets probing
- issues, isEnd, err := downloader.GetIssues(1, 20)
- require.NoError(t, err)
- assert.True(t, isEnd)
-
- // Testing issue tickets migration
- assertIssuesEqual(t, []*base.Issue{
- {
- Number: 2,
- Title: "This is the title of the second test issue",
- Content: "This is the body of the second test issue",
- PosterName: "t0xic0der",
- PosterID: -1,
- State: "closed",
- Milestone: "Milestone BBBB",
- Created: time.Date(2023, time.October, 13, 4, 1, 16, 0, time.UTC),
- Updated: time.Date(2025, time.June, 25, 6, 25, 57, 0, time.UTC),
- Closed: timePtr(time.Date(2025, time.June, 25, 6, 22, 59, 0, time.UTC)),
- Labels: []*base.Label{
- {
- Name: "cccc",
- },
- {
- Name: "dddd",
- },
- {
- Name: "Closed As/Complete",
- },
- {
- Name: "Priority/Rare",
- },
- },
- },
- {
- Number: 1,
- Title: "This is the title of the first test issue",
- Content: "This is the body of the first test issue",
- PosterName: "t0xic0der",
- PosterID: -1,
- State: "open",
- Milestone: "Milestone AAAA",
- Created: time.Date(2023, time.October, 13, 3, 57, 42, 0, time.UTC),
- Updated: time.Date(2025, time.June, 25, 6, 25, 45, 0, time.UTC),
- Closed: timePtr(time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC)),
- Labels: []*base.Label{
- {
- Name: "aaaa",
- },
- {
- Name: "bbbb",
- },
- {
- Name: "Priority/Epic",
- },
- },
- },
- }, issues)
-
- // Testing comments under issue tickets
- comments, _, err := downloader.GetComments(issues[0])
- require.NoError(t, err)
- assertCommentsEqual(t, []*base.Comment{
- {
- IssueIndex: 2,
- PosterName: "t0xic0der",
- PosterID: -1,
- Created: time.Date(2023, time.October, 13, 4, 3, 30, 0, time.UTC),
- Updated: time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC),
- Content: "**Metadata Update from @t0xic0der**:\n- Issue tagged with: cccc, dddd",
- },
- {
- IssueIndex: 2,
- PosterName: "t0xic0der",
- PosterID: -1,
- Created: time.Date(2023, time.October, 13, 4, 6, 4, 0, time.UTC),
- Updated: time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC),
- Content: "The is the first comment under the second test issue",
- },
- {
- IssueIndex: 2,
- PosterName: "t0xic0der",
- PosterID: -1,
- Created: time.Date(2023, time.October, 13, 4, 6, 16, 0, time.UTC),
- Updated: time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC),
- Content: "The is the second comment under the second test issue",
- },
- {
- IssueIndex: 2,
- PosterName: "t0xic0der",
- PosterID: -1,
- Created: time.Date(2023, time.October, 13, 4, 7, 12, 0, time.UTC),
- Updated: time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC),
- Content: "**Metadata Update from @t0xic0der**:\n- Issue status updated to: Closed (was: Open)",
- },
- {
- IssueIndex: 2,
- PosterName: "t0xic0der",
- PosterID: -1,
- Created: time.Date(2025, time.May, 8, 4, 50, 21, 0, time.UTC),
- Updated: time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC),
- Content: "**Metadata Update from @t0xic0der**:\n- Issue set to the milestone: Milestone BBBB",
- },
- {
- IssueIndex: 2,
- PosterName: "t0xic0der",
- PosterID: -1,
- Created: time.Date(2025, time.June, 25, 6, 22, 52, 0, time.UTC),
- Updated: time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC),
- Content: "**Metadata Update from @t0xic0der**:\n- Issue set to the milestone: None (was: Milestone BBBB)\n- Issue status updated to: Open (was: Closed)",
- },
- {
- IssueIndex: 2,
- PosterName: "t0xic0der",
- PosterID: -1,
- Created: time.Date(2025, time.June, 25, 6, 23, 0o2, 0, time.UTC),
- Updated: time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC),
- Content: "**Metadata Update from @t0xic0der**:\n- Issue close_status updated to: Complete\n- Issue status updated to: Closed (was: Open)",
- },
- {
- IssueIndex: 2,
- PosterName: "t0xic0der",
- PosterID: -1,
- Created: time.Date(2025, time.June, 25, 6, 24, 34, 0, time.UTC),
- Updated: time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC),
- Content: "**Metadata Update from @t0xic0der**:\n- Issue set to the milestone: Milestone BBBB",
- },
- {
- IssueIndex: 2,
- PosterName: "t0xic0der",
- PosterID: -1,
- Created: time.Date(2025, time.June, 25, 6, 25, 57, 0, time.UTC),
- Updated: time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC),
- Content: "**Metadata Update from @t0xic0der**:\n- Issue priority set to: Rare",
- },
- }, comments)
-
- prs, isEnd, err := downloader.GetPullRequests(1, 20)
- require.NoError(t, err)
- assert.True(t, isEnd)
-
- // Testing pull requests migrated
- assertPullRequestsEqual(t, []*base.PullRequest{
- {
- Number: 10,
- Title: "Change the branch identity to `test-ffff` in the README.md file",
- Content: "Signed-off-by: Akashdeep Dhar ",
- PosterName: "t0xic0der",
- PosterID: -1,
- State: "closed",
- Created: time.Date(2025, time.May, 19, 6, 12, 45, 0, time.UTC),
- Updated: time.Date(2025, time.May, 19, 6, 17, 11, 0, time.UTC),
- Closed: timePtr(time.Date(2025, time.May, 19, 6, 17, 11, 0, time.UTC)),
- MergedTime: timePtr(time.Date(2025, time.May, 19, 6, 17, 11, 0, time.UTC)),
- Merged: true,
- PatchURL: server.URL + "/protop2g-test-srce/pull-request/10.patch",
- Labels: []*base.Label{
- {
- Name: "ffff",
- },
- },
- Head: base.PullRequestBranch{
- Ref: "test-ffff",
- SHA: "1a6ccc212aa958a0fe76155c2907c889969a7224",
- RepoName: "protop2g-test-srce",
- CloneURL: server.URL + "/protop2g-test-srce.git",
- },
- Base: base.PullRequestBranch{
- Ref: "main",
- SHA: "01b420e2964928a15f790f9b7c1a0053e7b5f0a5",
- RepoName: "protop2g-test-srce",
- },
- },
- {
- Number: 9,
- Title: "Change the branch identity to `test-eeee` in the README.md file",
- Content: "Signed-off-by: Akashdeep Dhar ",
- PosterName: "t0xic0der",
- PosterID: -1,
- State: "closed",
- Created: time.Date(2025, time.May, 19, 6, 12, 41, 0, time.UTC),
- Updated: time.Date(2025, time.May, 19, 6, 14, 3, 0, time.UTC),
- Closed: timePtr(time.Date(2025, time.May, 19, 6, 14, 3, 0, time.UTC)),
- MergedTime: timePtr(time.Date(2025, time.May, 19, 6, 14, 3, 0, time.UTC)),
- Merged: true,
- PatchURL: server.URL + "/protop2g-test-srce/pull-request/9.patch",
- Labels: []*base.Label{
- {
- Name: "eeee",
- },
- },
- Head: base.PullRequestBranch{
- Ref: "test-eeee",
- SHA: "01b420e2964928a15f790f9b7c1a0053e7b5f0a5",
- RepoName: "protop2g-test-srce",
- CloneURL: server.URL + "/protop2g-test-srce.git",
- },
- Base: base.PullRequestBranch{
- Ref: "main",
- SHA: "3f12d300f62f1c5b8a1d3265bd85d61cf6d924d7",
- RepoName: "protop2g-test-srce",
- },
- },
- {
- Number: 8,
- Title: "Change the branch identity to `test-dddd` in the README.md file",
- Content: "Signed-off-by: Akashdeep Dhar ",
- PosterName: "t0xic0der",
- PosterID: -1,
- State: "closed",
- Created: time.Date(2025, time.May, 5, 6, 45, 32, 0, time.UTC),
- Updated: time.Date(2025, time.May, 5, 6, 54, 13, 0, time.UTC),
- Closed: timePtr(time.Date(2025, time.May, 5, 6, 54, 13, 0, time.UTC)),
- MergedTime: timePtr(time.Date(2025, time.May, 5, 6, 54, 13, 0, time.UTC)), // THIS IS WRONG
- Merged: false,
- PatchURL: server.URL + "/protop2g-test-srce/pull-request/8.patch",
- Labels: []*base.Label{
- {
- Name: "dddd",
- },
- },
- Head: base.PullRequestBranch{
- Ref: "test-dddd",
- SHA: "0bc8b0c38e0790e9ef5c8d512a00b9c4dd048160",
- RepoName: "protop2g-test-srce",
- CloneURL: server.URL + "/protop2g-test-srce.git",
- },
- Base: base.PullRequestBranch{
- Ref: "main",
- SHA: "3f12d300f62f1c5b8a1d3265bd85d61cf6d924d7",
- RepoName: "protop2g-test-srce",
- },
- },
- {
- Number: 7,
- Title: "Change the branch identity to `test-cccc` in the README.md file",
- Content: "Signed-off-by: Akashdeep Dhar ",
- PosterName: "t0xic0der",
- PosterID: -1,
- State: "closed",
- Created: time.Date(2025, time.May, 5, 6, 45, 6, 0, time.UTC),
- Updated: time.Date(2025, time.May, 5, 6, 54, 3, 0, time.UTC), // IT SHOULD BE NIL
- Closed: timePtr(time.Date(2025, time.May, 5, 6, 54, 3, 0, time.UTC)), // IT is CLOSED, Not MERGED so SHOULD NOT BE NIL
- MergedTime: timePtr(time.Date(2025, time.May, 5, 6, 54, 3, 0, time.UTC)), // THIS IS WRONG
- Merged: false,
- PatchURL: server.URL + "/protop2g-test-srce/pull-request/7.patch",
- Labels: []*base.Label{
- {
- Name: "cccc",
- },
- },
- Head: base.PullRequestBranch{
- Ref: "test-cccc",
- SHA: "f1246e331cade9341b9e4f311b7a134f99893d21",
- RepoName: "protop2g-test-srce",
- CloneURL: server.URL + "/protop2g-test-srce.git",
- },
- Base: base.PullRequestBranch{
- Ref: "main",
- SHA: "3f12d300f62f1c5b8a1d3265bd85d61cf6d924d7",
- RepoName: "protop2g-test-srce",
- },
- },
- {
- Number: 6,
- Title: "Change the branch identity to `test-bbbb` in the README.md file",
- Content: "Signed-off-by: Akashdeep Dhar ",
- PosterName: "t0xic0der",
- PosterID: -1,
- State: "open",
- Created: time.Date(2025, time.May, 5, 6, 44, 30, 0, time.UTC),
- Updated: time.Date(2025, time.May, 19, 8, 30, 50, 0, time.UTC),
- Closed: timePtr(time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC)),
- MergedTime: timePtr(time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC)),
- Merged: false,
- PatchURL: server.URL + "/protop2g-test-srce/pull-request/6.patch",
- Labels: []*base.Label{
- {
- Name: "bbbb",
- },
- },
- Head: base.PullRequestBranch{
- Ref: "test-bbbb",
- SHA: "2d40761dc53e6fa060ac49d88e1452c6751d4b1c",
- RepoName: "protop2g-test-srce",
- CloneURL: server.URL + "/protop2g-test-srce.git",
- },
- Base: base.PullRequestBranch{
- Ref: "main",
- SHA: "3f12d300f62f1c5b8a1d3265bd85d61cf6d924d7",
- RepoName: "protop2g-test-srce",
- },
- },
- {
- Number: 5,
- Title: "Change the branch identity to `test-aaaa` in the README.md file",
- Content: "Signed-off-by: Akashdeep Dhar ",
- PosterName: "t0xic0der",
- PosterID: -1,
- State: "open",
- Created: time.Date(2025, time.May, 5, 6, 43, 57, 0, time.UTC),
- Updated: time.Date(2025, time.May, 19, 6, 29, 45, 0, time.UTC),
- Closed: timePtr(time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC)),
- MergedTime: timePtr(time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC)),
- Merged: false,
- PatchURL: server.URL + "/protop2g-test-srce/pull-request/5.patch",
- Labels: []*base.Label{
- {
- Name: "aaaa",
- },
- },
- Head: base.PullRequestBranch{
- Ref: "test-aaaa",
- SHA: "b55e5c91d2572d60a8d7e71b3d3003e523127bd4",
- RepoName: "protop2g-test-srce",
- CloneURL: server.URL + "/protop2g-test-srce.git",
- },
- Base: base.PullRequestBranch{
- Ref: "main",
- SHA: "3f12d300f62f1c5b8a1d3265bd85d61cf6d924d7",
- RepoName: "protop2g-test-srce",
- },
- },
- }, prs)
-
- // Testing comments under pull requests
- comments, _, err = downloader.GetComments(prs[5])
- require.NoError(t, err)
- assertCommentsEqual(t, []*base.Comment{
- {
- IssueIndex: 5,
- PosterName: "t0xic0der",
- PosterID: -1,
- Created: time.Date(2025, time.May, 5, 6, 44, 13, 0, time.UTC),
- Updated: time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC),
- Content: "**Metadata Update from @t0xic0der**:\n- Pull-request tagged with: aaaa",
- },
- {
- IssueIndex: 5,
- PosterName: "t0xic0der",
- PosterID: -1,
- Created: time.Date(2025, time.May, 7, 5, 25, 21, 0, time.UTC),
- Updated: time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC),
- Content: "This is the first comment under this pull request.",
- },
- {
- IssueIndex: 5,
- PosterName: "t0xic0der",
- PosterID: -1,
- Created: time.Date(2025, time.May, 7, 5, 25, 29, 0, time.UTC),
- Updated: time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC),
- Content: "This is the second comment under this pull request.",
- },
- }, comments)
-
- // Testing milestones migration
- milestones, err := downloader.GetMilestones()
- require.NoError(t, err)
- dict := map[string]*base.Milestone{
- "Milestone AAAA": {
- Title: "Milestone AAAA",
- Deadline: timePtr(time.Date(2025, time.December, 12, 0, 0, 0, 0, time.UTC)),
- State: "open",
- },
- "Milestone BBBB": {
- Title: "Milestone BBBB",
- Deadline: timePtr(time.Date(2025, time.December, 12, 0, 0, 0, 0, time.UTC)),
- State: "closed",
- },
- "Milestone CCCC": {
- Title: "Milestone CCCC",
- Deadline: timePtr(time.Date(2025, time.December, 12, 0, 0, 0, 0, time.UTC)),
- State: "open",
- },
- "Milestone DDDD": {
- Title: "Milestone DDDD",
- Deadline: timePtr(time.Date(2025, time.December, 12, 0, 0, 0, 0, time.UTC)),
- State: "closed",
- },
- }
-
- // We do not like when tests fail just because of dissimilar ordering
- for _, item := range milestones {
- assertMilestoneEqual(t, item, dict[item.Title])
- }
-}
-
-func TestPagureDownloadRepoWithPrivateIssues(t *testing.T) {
- t.Skip("Does not work")
- // Skip tests if Pagure token is not found
- cloneUser := os.Getenv("PAGURE_CLONE_USER")
- clonePassword := os.Getenv("PAGURE_CLONE_PASSWORD")
- apiUser := os.Getenv("PAGURE_API_USER")
- apiPassword := os.Getenv("PAGURE_API_TOKEN")
-
- fixtPath := "./testdata/pagure/full_download/authorized"
- server := unittest.NewMockWebServer(t, "https://pagure.io", fixtPath, false)
- defer server.Close()
-
- serverURL, err := url.Parse(server.URL)
- require.NoError(t, err)
-
- if clonePassword != "" || cloneUser != "" {
- serverURL.User = url.UserPassword(cloneUser, clonePassword)
- }
- serverURL.Path = "protop2g-test-srce.git"
- cloneAddr := serverURL.String()
-
- factory := &PagureDownloaderFactory{}
- downloader, err := factory.New(t.Context(), base.MigrateOptions{
- CloneAddr: cloneAddr,
- AuthUsername: apiUser,
- AuthPassword: apiPassword,
- AuthToken: apiPassword,
- })
- require.NoError(t, err)
-
- repo, err := downloader.GetRepoInfo()
- require.NoError(t, err)
-
- // Testing repository contents migration
- assertRepositoryEqual(t, &base.Repository{
- Name: "protop2g-test-srce",
- Owner: "",
- Description: "The source namespace for the Pagure Exporter project to run tests against",
- CloneURL: cloneAddr,
- OriginalURL: strings.ReplaceAll(cloneAddr, ".git", ""),
- }, repo)
-
- topics, err := downloader.GetTopics()
- require.NoError(t, err)
-
- // Testing repository topics migration
- assert.Equal(t, []string{"srce", "test", "gridhead", "protop2g"}, topics)
-
- // Testing labels migration
- labels, err := downloader.GetLabels()
- require.NoError(t, err)
- assert.Len(t, labels, 15)
-
- // Testing issue tickets probing
- issues, isEnd, err := downloader.GetIssues(1, 20)
- require.NoError(t, err)
- assert.True(t, isEnd)
-
- // Testing issue tickets migration
- assertIssuesEqual(t, []*base.Issue{
- {
- Number: 4,
- Title: "This is the title of the fourth test issue",
- Content: "This is the body of the fourth test issue",
- PosterName: "t0xic0der",
- PosterID: -1,
- State: "closed",
- Milestone: "Milestone DDDD",
- Created: time.Date(2023, time.November, 21, 8, 6, 56, 0, time.UTC),
- Updated: time.Date(2025, time.June, 25, 6, 26, 26, 0, time.UTC),
- Closed: timePtr(time.Date(2025, time.June, 25, 6, 23, 51, 0, time.UTC)),
- Labels: []*base.Label{
- {
- Name: "gggg",
- },
- {
- Name: "hhhh",
- },
- {
- Name: "Closed As/Baseless",
- },
- {
- Name: "Priority/Common",
- },
- },
- },
- {
- Number: 3,
- Title: "This is the title of the third test issue",
- Content: "This is the body of the third test issue",
- PosterName: "t0xic0der",
- PosterID: -1,
- State: "open",
- Milestone: "Milestone CCCC",
- Created: time.Date(2023, time.November, 21, 8, 3, 57, 0, time.UTC),
- Updated: time.Date(2025, time.June, 25, 6, 26, 7, 0, time.UTC),
- Closed: timePtr(time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC)),
- Labels: []*base.Label{
- {
- Name: "eeee",
- },
- {
- Name: "ffff",
- },
- {
- Name: "Priority/Uncommon",
- },
- },
- },
- }, issues)
-
- // Testing comments under issue tickets
- comments, _, err := downloader.GetComments(issues[0])
- require.NoError(t, err)
- assertCommentsEqual(t, []*base.Comment{
- {
- IssueIndex: 4,
- PosterName: "t0xic0der",
- PosterID: -1,
- Created: time.Date(2023, time.November, 21, 8, 7, 25, 0, time.UTC),
- Updated: time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC),
- Content: "This is the first comment under the fourth test issue",
- },
- {
- IssueIndex: 4,
- PosterName: "t0xic0der",
- PosterID: -1,
- Created: time.Date(2023, time.November, 21, 8, 7, 34, 0, time.UTC),
- Updated: time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC),
- Content: "This is the second comment under the fourth test issue",
- },
- {
- IssueIndex: 4,
- PosterName: "t0xic0der",
- PosterID: -1,
- Created: time.Date(2023, time.November, 21, 8, 8, 1, 0, time.UTC),
- Updated: time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC),
- Content: "**Metadata Update from @t0xic0der**:\n- Issue status updated to: Closed (was: Open)",
- },
- {
- IssueIndex: 4,
- PosterName: "t0xic0der",
- PosterID: -1,
- Created: time.Date(2025, time.May, 8, 4, 50, 46, 0, time.UTC),
- Updated: time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC),
- Content: "**Metadata Update from @t0xic0der**:\n- Issue set to the milestone: Milestone DDDD",
- },
- {
- IssueIndex: 4,
- PosterName: "t0xic0der",
- PosterID: -1,
- Created: time.Date(2025, time.June, 25, 6, 23, 46, 0, time.UTC),
- Updated: time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC),
- Content: "**Metadata Update from @t0xic0der**:\n- Issue set to the milestone: None (was: Milestone DDDD)\n- Issue status updated to: Open (was: Closed)",
- },
- {
- IssueIndex: 4,
- PosterName: "t0xic0der",
- PosterID: -1,
- Created: time.Date(2025, time.June, 25, 6, 23, 52, 0, time.UTC),
- Updated: time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC),
- Content: "**Metadata Update from @t0xic0der**:\n- Issue close_status updated to: Baseless\n- Issue status updated to: Closed (was: Open)",
- },
- {
- IssueIndex: 4,
- PosterName: "t0xic0der",
- PosterID: -1,
- Created: time.Date(2025, time.June, 25, 6, 24, 55, 0, time.UTC),
- Updated: time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC),
- Content: "**Metadata Update from @t0xic0der**:\n- Issue set to the milestone: Milestone DDDD",
- },
- {
- IssueIndex: 4,
- PosterName: "t0xic0der",
- PosterID: -1,
- Created: time.Date(2025, time.June, 25, 6, 26, 26, 0, time.UTC),
- Updated: time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC),
- Content: "**Metadata Update from @t0xic0der**:\n- Issue priority set to: Common",
- },
- }, comments)
-}
diff --git a/services/migrations/restore.go b/services/migrations/restore.go
index e8a1e0fdcf..e8725bc647 100644
--- a/services/migrations/restore.go
+++ b/services/migrations/restore.go
@@ -10,9 +10,9 @@ import (
"path/filepath"
"strconv"
- base "forgejo.org/modules/migration"
+ base "code.gitea.io/gitea/modules/migration"
- "go.yaml.in/yaml/v3"
+ "gopkg.in/yaml.v3"
)
// RepositoryRestorer implements an Downloader from the local directory
diff --git a/services/migrations/testdata/code-forgejo-org/full_download/GET_%2Fapi%2Fv1%2Frepos%2FGusted%2Fagit-test%2Fpulls%3Flimit=50&page=1&state=all b/services/migrations/testdata/code-forgejo-org/full_download/GET_%2Fapi%2Fv1%2Frepos%2FGusted%2Fagit-test%2Fpulls%3Flimit=50&page=1&state=all
deleted file mode 100644
index 87095d9e24..0000000000
--- a/services/migrations/testdata/code-forgejo-org/full_download/GET_%2Fapi%2Fv1%2Frepos%2FGusted%2Fagit-test%2Fpulls%3Flimit=50&page=1&state=all
+++ /dev/null
@@ -1,8 +0,0 @@
-Access-Control-Expose-Headers: X-Total-Count
-Cache-Control: max-age=0, private, must-revalidate, no-transform
-Content-Type: application/json;charset=utf-8
-X-Content-Type-Options: nosniff
-X-Frame-Options: SAMEORIGIN
-X-Total-Count: 1
-
-[{"id":4980,"url":"https://code.forgejo.org/Gusted/agit-test/pulls/1","number":1,"user":{"id":63,"login":"Gusted","login_name":"26734","source_id":1,"full_name":"","email":"postmaster@gusted.xyz","avatar_url":"https://code.forgejo.org/avatars/4ca5ad8bc488630869fdbd2051da61cbed7241c9c066d4e5e1dd36300f887340","html_url":"https://code.forgejo.org/Gusted","language":"en-US","is_admin":false,"last_login":"2025-04-01T16:35:18Z","created":"2023-07-08T13:33:38Z","restricted":false,"active":true,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":2,"following_count":0,"starred_repos_count":0,"username":"Gusted"},"title":"Add extra information","body":"","labels":[],"milestone":null,"assignee":null,"assignees":null,"requested_reviewers":[],"requested_reviewers_teams":[],"state":"open","draft":false,"is_locked":false,"comments":0,"review_comments":0,"additions":0,"deletions":0,"changed_files":0,"html_url":"https://code.forgejo.org/Gusted/agit-test/pulls/1","diff_url":"https://code.forgejo.org/Gusted/agit-test/pulls/1.diff","patch_url":"https://code.forgejo.org/Gusted/agit-test/pulls/1.patch","mergeable":true,"merged":false,"merged_at":null,"merge_commit_sha":null,"merged_by":null,"allow_maintainer_edit":false,"base":{"label":"main","ref":"main","sha":"79ebb873a6497c8847141ba9706b3f757196a1e6","repo_id":1414,"repo":{"id":1414,"owner":{"id":63,"login":"Gusted","login_name":"","source_id":0,"full_name":"","email":"gusted@noreply.code.forgejo.org","avatar_url":"https://code.forgejo.org/avatars/4ca5ad8bc488630869fdbd2051da61cbed7241c9c066d4e5e1dd36300f887340","html_url":"https://code.forgejo.org/Gusted","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2023-07-08T13:33:38Z","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":2,"following_count":0,"starred_repos_count":0,"username":"Gusted"},"name":"agit-test","full_name":"Gusted/agit-test","description":"USED FOR FORGEJO UNIT TESTING","empty":false,"private":false,"fork":false,"template":false,"parent":null,"mirror":false,"size":36,"language":"","languages_url":"https://code.forgejo.org/api/v1/repos/Gusted/agit-test/languages","html_url":"https://code.forgejo.org/Gusted/agit-test","url":"https://code.forgejo.org/api/v1/repos/Gusted/agit-test","link":"","ssh_url":"ssh://git@code.forgejo.org/Gusted/agit-test.git","clone_url":"https://code.forgejo.org/Gusted/agit-test.git","original_url":"","website":"","stars_count":0,"forks_count":0,"watchers_count":1,"open_issues_count":0,"open_pr_counter":1,"release_counter":0,"default_branch":"main","archived":false,"created_at":"2025-04-01T20:25:03Z","updated_at":"2025-04-01T20:25:03Z","archived_at":"1970-01-01T00:00:00Z","permissions":{"admin":true,"push":true,"pull":true},"has_issues":true,"internal_tracker":{"enable_time_tracker":true,"allow_only_contributors_to_track_time":true,"enable_issue_dependencies":true},"has_wiki":true,"wiki_branch":"main","globally_editable_wiki":false,"has_pull_requests":true,"has_projects":true,"has_releases":true,"has_packages":true,"has_actions":true,"ignore_whitespace_conflicts":false,"allow_merge_commits":true,"allow_rebase":true,"allow_rebase_explicit":true,"allow_squash_merge":true,"allow_fast_forward_only_merge":true,"allow_rebase_update":true,"default_delete_branch_after_merge":false,"default_merge_style":"merge","default_allow_maintainer_edit":false,"default_update_style":"merge","avatar_url":"","internal":false,"mirror_interval":"","object_format_name":"sha1","mirror_updated":"0001-01-01T00:00:00Z","repo_transfer":null,"topics":null}},"head":{"label":"","ref":"refs/pull/1/head","sha":"667e9317ec37b977e6d3d7d43e3440636970563c","repo_id":1414,"repo":{"id":1414,"owner":{"id":63,"login":"Gusted","login_name":"","source_id":0,"full_name":"","email":"gusted@noreply.code.forgejo.org","avatar_url":"https://code.forgejo.org/avatars/4ca5ad8bc488630869fdbd2051da61cbed7241c9c066d4e5e1dd36300f887340","html_url":"https://code.forgejo.org/Gusted","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2023-07-08T13:33:38Z","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":2,"following_count":0,"starred_repos_count":0,"username":"Gusted"},"name":"agit-test","full_name":"Gusted/agit-test","description":"USED FOR FORGEJO UNIT TESTING","empty":false,"private":false,"fork":false,"template":false,"parent":null,"mirror":false,"size":36,"language":"","languages_url":"https://code.forgejo.org/api/v1/repos/Gusted/agit-test/languages","html_url":"https://code.forgejo.org/Gusted/agit-test","url":"https://code.forgejo.org/api/v1/repos/Gusted/agit-test","link":"","ssh_url":"ssh://git@code.forgejo.org/Gusted/agit-test.git","clone_url":"https://code.forgejo.org/Gusted/agit-test.git","original_url":"","website":"","stars_count":0,"forks_count":0,"watchers_count":1,"open_issues_count":0,"open_pr_counter":1,"release_counter":0,"default_branch":"main","archived":false,"created_at":"2025-04-01T20:25:03Z","updated_at":"2025-04-01T20:25:03Z","archived_at":"1970-01-01T00:00:00Z","permissions":{"admin":true,"push":true,"pull":true},"has_issues":true,"internal_tracker":{"enable_time_tracker":true,"allow_only_contributors_to_track_time":true,"enable_issue_dependencies":true},"has_wiki":true,"wiki_branch":"main","globally_editable_wiki":false,"has_pull_requests":true,"has_projects":true,"has_releases":true,"has_packages":true,"has_actions":true,"ignore_whitespace_conflicts":false,"allow_merge_commits":true,"allow_rebase":true,"allow_rebase_explicit":true,"allow_squash_merge":true,"allow_fast_forward_only_merge":true,"allow_rebase_update":true,"default_delete_branch_after_merge":false,"default_merge_style":"merge","default_allow_maintainer_edit":false,"default_update_style":"merge","avatar_url":"","internal":false,"mirror_interval":"","object_format_name":"sha1","mirror_updated":"0001-01-01T00:00:00Z","repo_transfer":null,"topics":null}},"merge_base":"79ebb873a6497c8847141ba9706b3f757196a1e6","due_date":null,"created_at":"2025-04-01T20:28:45Z","updated_at":"2025-04-01T20:28:45Z","closed_at":null,"pin_order":0,"flow":1}]
diff --git a/services/migrations/testdata/code-forgejo-org/full_download/GET_%2Fapi%2Fv1%2Fsettings%2Fapi b/services/migrations/testdata/code-forgejo-org/full_download/GET_%2Fapi%2Fv1%2Fsettings%2Fapi
deleted file mode 100644
index 11c4e7b8ba..0000000000
--- a/services/migrations/testdata/code-forgejo-org/full_download/GET_%2Fapi%2Fv1%2Fsettings%2Fapi
+++ /dev/null
@@ -1,7 +0,0 @@
-Content-Length: 117
-Cache-Control: max-age=0, private, must-revalidate, no-transform
-Content-Type: application/json;charset=utf-8
-X-Content-Type-Options: nosniff
-X-Frame-Options: SAMEORIGIN
-
-{"max_response_items":50,"default_paging_num":30,"default_git_trees_per_page":1000,"default_max_blob_size":10485760}
diff --git a/services/migrations/testdata/code-forgejo-org/full_download/GET_%2Fapi%2Fv1%2Fversion b/services/migrations/testdata/code-forgejo-org/full_download/GET_%2Fapi%2Fv1%2Fversion
deleted file mode 100644
index 411ed84e24..0000000000
--- a/services/migrations/testdata/code-forgejo-org/full_download/GET_%2Fapi%2Fv1%2Fversion
+++ /dev/null
@@ -1,7 +0,0 @@
-Cache-Control: max-age=0, private, must-revalidate, no-transform
-Content-Type: application/json;charset=utf-8
-X-Content-Type-Options: nosniff
-X-Frame-Options: SAMEORIGIN
-Content-Length: 53
-
-{"version":"11.0.0-dev-617-1d1e0ced3e+gitea-1.22.0"}
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frate_limit b/services/migrations/testdata/github/full_download/GET_%2Frate_limit
index f3a1c10f1d..74e43a0765 100644
--- a/services/migrations/testdata/github/full_download/GET_%2Frate_limit
+++ b/services/migrations/testdata/github/full_download/GET_%2Frate_limit
@@ -1,24 +1,23 @@
Cache-Control: no-cache
-X-Ratelimit-Used: 136
-X-Ratelimit-Resource: core
Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
-X-Frame-Options: deny
Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
-X-Github-Request-Id: E80A:118F3A:208966:1EA2B8:689B4023
-X-Github-Api-Version-Selected: 2022-11-28
-X-Ratelimit-Limit: 5000
-Vary: Accept-Encoding, Accept, X-Requested-With
-Content-Type: application/json; charset=utf-8
-X-Oauth-Scopes: public_repo, repo:status
-X-Accepted-Oauth-Scopes:
-Github-Authentication-Token-Expiration: 2025-09-11 10:37:11 UTC
-X-Ratelimit-Remaining: 4864
-X-Ratelimit-Reset: 1755007969
+X-Ratelimit-Reset: 1730800941
Access-Control-Allow-Origin: *
-X-Content-Type-Options: nosniff
+Content-Type: application/json; charset=utf-8
+X-Oauth-Scopes:
X-Github-Media-Type: github.v3; format=json
-Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+X-Ratelimit-Remaining: 4899
X-Xss-Protection: 0
Content-Security-Policy: default-src 'none'
+X-Accepted-Oauth-Scopes:
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+X-Frame-Options: deny
+X-Content-Type-Options: nosniff
+Vary: Accept-Encoding, Accept, X-Requested-With
+X-Github-Request-Id: C7CC:3118FC:3F6234D:4038C5B:6729E6C0
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Limit: 5000
+X-Ratelimit-Used: 101
+X-Ratelimit-Resource: core
-{"resources":{"core":{"limit":5000,"used":136,"remaining":4864,"reset":1755007969},"search":{"limit":30,"used":0,"remaining":30,"reset":1755005023},"graphql":{"limit":5000,"used":0,"remaining":5000,"reset":1755008563},"integration_manifest":{"limit":5000,"used":0,"remaining":5000,"reset":1755008563},"source_import":{"limit":100,"used":0,"remaining":100,"reset":1755005023},"code_scanning_upload":{"limit":5000,"used":136,"remaining":4864,"reset":1755007969},"code_scanning_autofix":{"limit":10,"used":0,"remaining":10,"reset":1755005023},"actions_runner_registration":{"limit":10000,"used":0,"remaining":10000,"reset":1755008563},"scim":{"limit":15000,"used":0,"remaining":15000,"reset":1755008563},"dependency_snapshots":{"limit":100,"used":0,"remaining":100,"reset":1755005023},"dependency_sbom":{"limit":100,"used":0,"remaining":100,"reset":1755005023},"audit_log":{"limit":1750,"used":0,"remaining":1750,"reset":1755008563},"audit_log_streaming":{"limit":15,"used":0,"remaining":15,"reset":1755008563},"code_search":{"limit":10,"used":0,"remaining":10,"reset":1755005023}},"rate":{"limit":5000,"used":136,"remaining":4864,"reset":1755007969}}
\ No newline at end of file
+{"resources":{"core":{"limit":5000,"used":101,"remaining":4899,"reset":1730800941},"search":{"limit":30,"used":0,"remaining":30,"reset":1730799356},"graphql":{"limit":5000,"used":162,"remaining":4838,"reset":1730801064},"integration_manifest":{"limit":5000,"used":0,"remaining":5000,"reset":1730802896},"source_import":{"limit":100,"used":0,"remaining":100,"reset":1730799356},"code_scanning_upload":{"limit":1000,"used":0,"remaining":1000,"reset":1730802896},"actions_runner_registration":{"limit":10000,"used":0,"remaining":10000,"reset":1730802896},"scim":{"limit":15000,"used":0,"remaining":15000,"reset":1730802896},"dependency_snapshots":{"limit":100,"used":0,"remaining":100,"reset":1730799356},"audit_log":{"limit":1750,"used":0,"remaining":1750,"reset":1730802896},"audit_log_streaming":{"limit":15,"used":0,"remaining":15,"reset":1730802896},"code_search":{"limit":10,"used":0,"remaining":10,"reset":1730799356}},"rate":{"limit":5000,"used":101,"remaining":4899,"reset":1730800941}}
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo
deleted file mode 100644
index 57e87a4775..0000000000
--- a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo
+++ /dev/null
@@ -1,26 +0,0 @@
-X-Ratelimit-Remaining: 4880
-Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
-Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
-Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
-Content-Type: application/json; charset=utf-8
-Etag: W/"86b7478cb9d7f78696810f3292315b35ab47125e71dd2315dfd41626383fc081"
-X-Github-Api-Version-Selected: 2022-11-28
-X-Ratelimit-Resource: core
-Access-Control-Allow-Origin: *
-X-Content-Type-Options: nosniff
-Content-Security-Policy: default-src 'none'
-Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
-X-Accepted-Oauth-Scopes: repo
-Github-Authentication-Token-Expiration: 2025-09-11 10:37:11 UTC
-X-Ratelimit-Reset: 1755007969
-X-Ratelimit-Used: 120
-X-Frame-Options: deny
-Last-Modified: Tue, 12 Aug 2025 11:21:45 GMT
-X-Oauth-Scopes: public_repo, repo:status
-X-Xss-Protection: 0
-X-Github-Request-Id: E80A:118F3A:20561B:1E7279:689B401B
-Cache-Control: private, max-age=60, s-maxage=60
-X-Github-Media-Type: github.v3; param=scarlet-witch-preview; format=json, github.mercy-preview; param=baptiste-preview.nebula-preview; format=json
-X-Ratelimit-Limit: 5000
-
-{"id":1033841924,"node_id":"R_kgDOPZ8tBA","name":"test_repo","full_name":"forgejo/test_repo","private":false,"owner":{"login":"forgejo","id":118922216,"node_id":"O_kgDOBxab6A","avatar_url":"https://avatars.githubusercontent.com/u/118922216?v=4","gravatar_id":"","url":"https://api.github.com/users/forgejo","html_url":"https://github.com/forgejo","followers_url":"https://api.github.com/users/forgejo/followers","following_url":"https://api.github.com/users/forgejo/following{/other_user}","gists_url":"https://api.github.com/users/forgejo/gists{/gist_id}","starred_url":"https://api.github.com/users/forgejo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/forgejo/subscriptions","organizations_url":"https://api.github.com/users/forgejo/orgs","repos_url":"https://api.github.com/users/forgejo/repos","events_url":"https://api.github.com/users/forgejo/events{/privacy}","received_events_url":"https://api.github.com/users/forgejo/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/forgejo/test_repo","description":"Exclusively used for testing Github->Forgejo migration","fork":false,"url":"https://api.github.com/repos/forgejo/test_repo","forks_url":"https://api.github.com/repos/forgejo/test_repo/forks","keys_url":"https://api.github.com/repos/forgejo/test_repo/keys{/key_id}","collaborators_url":"https://api.github.com/repos/forgejo/test_repo/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/forgejo/test_repo/teams","hooks_url":"https://api.github.com/repos/forgejo/test_repo/hooks","issue_events_url":"https://api.github.com/repos/forgejo/test_repo/issues/events{/number}","events_url":"https://api.github.com/repos/forgejo/test_repo/events","assignees_url":"https://api.github.com/repos/forgejo/test_repo/assignees{/user}","branches_url":"https://api.github.com/repos/forgejo/test_repo/branches{/branch}","tags_url":"https://api.github.com/repos/forgejo/test_repo/tags","blobs_url":"https://api.github.com/repos/forgejo/test_repo/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/forgejo/test_repo/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/forgejo/test_repo/git/refs{/sha}","trees_url":"https://api.github.com/repos/forgejo/test_repo/git/trees{/sha}","statuses_url":"https://api.github.com/repos/forgejo/test_repo/statuses/{sha}","languages_url":"https://api.github.com/repos/forgejo/test_repo/languages","stargazers_url":"https://api.github.com/repos/forgejo/test_repo/stargazers","contributors_url":"https://api.github.com/repos/forgejo/test_repo/contributors","subscribers_url":"https://api.github.com/repos/forgejo/test_repo/subscribers","subscription_url":"https://api.github.com/repos/forgejo/test_repo/subscription","commits_url":"https://api.github.com/repos/forgejo/test_repo/commits{/sha}","git_commits_url":"https://api.github.com/repos/forgejo/test_repo/git/commits{/sha}","comments_url":"https://api.github.com/repos/forgejo/test_repo/comments{/number}","issue_comment_url":"https://api.github.com/repos/forgejo/test_repo/issues/comments{/number}","contents_url":"https://api.github.com/repos/forgejo/test_repo/contents/{+path}","compare_url":"https://api.github.com/repos/forgejo/test_repo/compare/{base}...{head}","merges_url":"https://api.github.com/repos/forgejo/test_repo/merges","archive_url":"https://api.github.com/repos/forgejo/test_repo/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/forgejo/test_repo/downloads","issues_url":"https://api.github.com/repos/forgejo/test_repo/issues{/number}","pulls_url":"https://api.github.com/repos/forgejo/test_repo/pulls{/number}","milestones_url":"https://api.github.com/repos/forgejo/test_repo/milestones{/number}","notifications_url":"https://api.github.com/repos/forgejo/test_repo/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/forgejo/test_repo/labels{/name}","releases_url":"https://api.github.com/repos/forgejo/test_repo/releases{/id}","deployments_url":"https://api.github.com/repos/forgejo/test_repo/deployments","created_at":"2025-08-07T12:34:21Z","updated_at":"2025-08-12T11:21:45Z","pushed_at":"2025-08-07T13:07:49Z","git_url":"git://github.com/forgejo/test_repo.git","ssh_url":"git@github.com:forgejo/test_repo.git","clone_url":"https://github.com/forgejo/test_repo.git","svn_url":"https://github.com/forgejo/test_repo","homepage":"https://codeberg.org/forgejo/forgejo/","size":6,"stargazers_count":1,"watchers_count":1,"language":null,"has_issues":true,"has_projects":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"has_discussions":false,"forks_count":1,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":5,"license":{"key":"0bsd","name":"BSD Zero Clause License","spdx_id":"0BSD","url":"https://api.github.com/licenses/0bsd","node_id":"MDc6TGljZW5zZTM1"},"allow_forking":true,"is_template":false,"web_commit_signoff_required":false,"topics":["forgejo"],"visibility":"public","forks":1,"open_issues":5,"watchers":1,"default_branch":"main","permissions":{"admin":true,"maintain":true,"push":true,"triage":true,"pull":true},"temp_clone_token":"","allow_squash_merge":true,"allow_merge_commit":true,"allow_rebase_merge":true,"allow_auto_merge":false,"delete_branch_on_merge":false,"allow_update_branch":false,"use_squash_pr_title_as_default":false,"squash_merge_commit_message":"COMMIT_MESSAGES","squash_merge_commit_title":"COMMIT_OR_PR_TITLE","merge_commit_message":"PR_TITLE","merge_commit_title":"MERGE_MESSAGE","custom_properties":{},"organization":{"login":"forgejo","id":118922216,"node_id":"O_kgDOBxab6A","avatar_url":"https://avatars.githubusercontent.com/u/118922216?v=4","gravatar_id":"","url":"https://api.github.com/users/forgejo","html_url":"https://github.com/forgejo","followers_url":"https://api.github.com/users/forgejo/followers","following_url":"https://api.github.com/users/forgejo/following{/other_user}","gists_url":"https://api.github.com/users/forgejo/gists{/gist_id}","starred_url":"https://api.github.com/users/forgejo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/forgejo/subscriptions","organizations_url":"https://api.github.com/users/forgejo/orgs","repos_url":"https://api.github.com/users/forgejo/repos","events_url":"https://api.github.com/users/forgejo/events{/privacy}","received_events_url":"https://api.github.com/users/forgejo/received_events","type":"Organization","user_view_type":"public","site_admin":false},"security_and_analysis":{"secret_scanning":{"status":"disabled"},"secret_scanning_push_protection":{"status":"disabled"},"dependabot_security_updates":{"status":"disabled"},"secret_scanning_non_provider_patterns":{"status":"disabled"},"secret_scanning_validity_checks":{"status":"disabled"}},"network_count":1,"subscribers_count":0}
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fissues%2F2%2Fcomments%3Fdirection=asc&per_page=100&sort=created b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fissues%2F2%2Fcomments%3Fdirection=asc&per_page=100&sort=created
deleted file mode 100644
index 5a45f886a9..0000000000
--- a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fissues%2F2%2Fcomments%3Fdirection=asc&per_page=100&sort=created
+++ /dev/null
@@ -1,25 +0,0 @@
-X-Content-Type-Options: nosniff
-X-Xss-Protection: 0
-Cache-Control: private, max-age=60, s-maxage=60
-X-Oauth-Scopes: public_repo, repo:status
-X-Github-Media-Type: github.v3; param=squirrel-girl-preview
-X-Ratelimit-Reset: 1755007969
-Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
-Content-Security-Policy: default-src 'none'
-X-Github-Request-Id: E80A:118F3A:206AFD:1E8691:689B401E
-Content-Type: application/json; charset=utf-8
-X-Github-Api-Version-Selected: 2022-11-28
-X-Ratelimit-Remaining: 4873
-X-Ratelimit-Used: 127
-Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
-Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
-Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
-X-Accepted-Oauth-Scopes:
-Github-Authentication-Token-Expiration: 2025-09-11 10:37:11 UTC
-Etag: W/"efada731cc49c5e9612cad9e891f65f645857f94ff3ea109dc80927064a5978c"
-X-Ratelimit-Limit: 5000
-X-Ratelimit-Resource: core
-Access-Control-Allow-Origin: *
-X-Frame-Options: deny
-
-[{"url":"https://api.github.com/repos/forgejo/test_repo/issues/comments/3164123494","html_url":"https://github.com/forgejo/test_repo/issues/2#issuecomment-3164123494","issue_url":"https://api.github.com/repos/forgejo/test_repo/issues/2","id":3164123494,"node_id":"IC_kwDOPZ8tBM68mLFm","user":{"login":"PatDyn","id":37243484,"node_id":"MDQ6VXNlcjM3MjQzNDg0","avatar_url":"https://avatars.githubusercontent.com/u/37243484?v=4","gravatar_id":"","url":"https://api.github.com/users/PatDyn","html_url":"https://github.com/PatDyn","followers_url":"https://api.github.com/users/PatDyn/followers","following_url":"https://api.github.com/users/PatDyn/following{/other_user}","gists_url":"https://api.github.com/users/PatDyn/gists{/gist_id}","starred_url":"https://api.github.com/users/PatDyn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/PatDyn/subscriptions","organizations_url":"https://api.github.com/users/PatDyn/orgs","repos_url":"https://api.github.com/users/PatDyn/repos","events_url":"https://api.github.com/users/PatDyn/events{/privacy}","received_events_url":"https://api.github.com/users/PatDyn/received_events","type":"User","user_view_type":"public","site_admin":false},"created_at":"2025-08-07T13:07:25Z","updated_at":"2025-08-07T13:07:25Z","author_association":"COLLABORATOR","body":"Mentioning #3 \nWith some **bold** *statement*","reactions":{"url":"https://api.github.com/repos/forgejo/test_repo/issues/comments/3164123494/reactions","total_count":0,"+1":0,"-1":0,"laugh":0,"hooray":0,"confused":0,"heart":0,"rocket":0,"eyes":0},"performed_via_github_app":null}]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fissues%2F3%2Freactions%3Fpage=2&per_page=2 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fissues%2F3%2Freactions%3Fpage=2&per_page=2
deleted file mode 100644
index 7d978a2584..0000000000
--- a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fissues%2F3%2Freactions%3Fpage=2&per_page=2
+++ /dev/null
@@ -1,27 +0,0 @@
-X-Ratelimit-Limit: 5000
-Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
-X-Xss-Protection: 0
-X-Github-Request-Id: F458:8333F:84A571:7C4748:689B3396
-Content-Type: application/json; charset=utf-8
-Content-Length: 2
-X-Oauth-Scopes: public_repo, repo:status
-X-Accepted-Oauth-Scopes: repo
-X-Ratelimit-Reset: 1755004338
-X-Content-Type-Options: nosniff
-Cache-Control: private, max-age=60, s-maxage=60
-X-Ratelimit-Used: 56
-X-Ratelimit-Resource: core
-Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
-Access-Control-Allow-Origin: *
-X-Frame-Options: deny
-Github-Authentication-Token-Expiration: 2025-09-11 10:37:11 UTC
-X-Github-Media-Type: github.v3; param=squirrel-girl-preview
-X-Ratelimit-Remaining: 4944
-Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
-Content-Security-Policy: default-src 'none'
-Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
-Etag: "578cfdf865ccd59faa414c655476c87af814e220755c938b9545967521b6f14b"
-Link: ; rel="prev", ; rel="last", ; rel="first"
-X-Github-Api-Version-Selected: 2022-11-28
-
-[]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fissues%3Fdirection=asc&page=1&per_page=2&sort=created&state=all b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fissues%3Fdirection=asc&page=1&per_page=2&sort=created&state=all
deleted file mode 100644
index 6e74d44a20..0000000000
--- a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fissues%3Fdirection=asc&page=1&per_page=2&sort=created&state=all
+++ /dev/null
@@ -1,26 +0,0 @@
-Link: ; rel="next"
-X-Github-Api-Version-Selected: 2022-11-28
-X-Ratelimit-Reset: 1755007969
-Access-Control-Allow-Origin: *
-Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
-Github-Authentication-Token-Expiration: 2025-09-11 10:37:11 UTC
-X-Ratelimit-Used: 124
-X-Frame-Options: deny
-X-Xss-Protection: 0
-Content-Security-Policy: default-src 'none'
-X-Github-Request-Id: E80A:118F3A:206102:1E7D47:689B401C
-Etag: W/"cc2f0f6e0b3c82ac10b12bf3ad5d74d62a575371f88fc689a7af78408e34eeb5"
-X-Ratelimit-Limit: 5000
-X-Ratelimit-Remaining: 4876
-Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
-Content-Type: application/json; charset=utf-8
-Cache-Control: private, max-age=60, s-maxage=60
-X-Oauth-Scopes: public_repo, repo:status
-X-Accepted-Oauth-Scopes: repo
-X-Ratelimit-Resource: core
-X-Content-Type-Options: nosniff
-Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
-Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
-X-Github-Media-Type: github.v3; param=squirrel-girl-preview
-
-[{"url":"https://api.github.com/repos/forgejo/test_repo/issues/1","repository_url":"https://api.github.com/repos/forgejo/test_repo","labels_url":"https://api.github.com/repos/forgejo/test_repo/issues/1/labels{/name}","comments_url":"https://api.github.com/repos/forgejo/test_repo/issues/1/comments","events_url":"https://api.github.com/repos/forgejo/test_repo/issues/1/events","html_url":"https://github.com/forgejo/test_repo/issues/1","id":3300365512,"node_id":"I_kwDOPZ8tBM7Et5TI","number":1,"title":"First issue","user":{"login":"PatDyn","id":37243484,"node_id":"MDQ6VXNlcjM3MjQzNDg0","avatar_url":"https://avatars.githubusercontent.com/u/37243484?v=4","gravatar_id":"","url":"https://api.github.com/users/PatDyn","html_url":"https://github.com/PatDyn","followers_url":"https://api.github.com/users/PatDyn/followers","following_url":"https://api.github.com/users/PatDyn/following{/other_user}","gists_url":"https://api.github.com/users/PatDyn/gists{/gist_id}","starred_url":"https://api.github.com/users/PatDyn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/PatDyn/subscriptions","organizations_url":"https://api.github.com/users/PatDyn/orgs","repos_url":"https://api.github.com/users/PatDyn/repos","events_url":"https://api.github.com/users/PatDyn/events{/privacy}","received_events_url":"https://api.github.com/users/PatDyn/received_events","type":"User","user_view_type":"public","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":1,"created_at":"2025-08-07T12:44:07Z","updated_at":"2025-08-07T12:44:47Z","closed_at":null,"author_association":"COLLABORATOR","type":null,"active_lock_reason":null,"sub_issues_summary":{"total":0,"completed":0,"percent_completed":0},"body":"This is an issue.","closed_by":null,"reactions":{"url":"https://api.github.com/repos/forgejo/test_repo/issues/1/reactions","total_count":0,"+1":0,"-1":0,"laugh":0,"hooray":0,"confused":0,"heart":0,"rocket":0,"eyes":0},"timeline_url":"https://api.github.com/repos/forgejo/test_repo/issues/1/timeline","performed_via_github_app":null,"state_reason":null},{"url":"https://api.github.com/repos/forgejo/test_repo/issues/2","repository_url":"https://api.github.com/repos/forgejo/test_repo","labels_url":"https://api.github.com/repos/forgejo/test_repo/issues/2/labels{/name}","comments_url":"https://api.github.com/repos/forgejo/test_repo/issues/2/comments","events_url":"https://api.github.com/repos/forgejo/test_repo/issues/2/events","html_url":"https://github.com/forgejo/test_repo/issues/2","id":3300370333,"node_id":"I_kwDOPZ8tBM7Et6ed","number":2,"title":"Second Issue","user":{"login":"PatDyn","id":37243484,"node_id":"MDQ6VXNlcjM3MjQzNDg0","avatar_url":"https://avatars.githubusercontent.com/u/37243484?v=4","gravatar_id":"","url":"https://api.github.com/users/PatDyn","html_url":"https://github.com/PatDyn","followers_url":"https://api.github.com/users/PatDyn/followers","following_url":"https://api.github.com/users/PatDyn/following{/other_user}","gists_url":"https://api.github.com/users/PatDyn/gists{/gist_id}","starred_url":"https://api.github.com/users/PatDyn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/PatDyn/subscriptions","organizations_url":"https://api.github.com/users/PatDyn/orgs","repos_url":"https://api.github.com/users/PatDyn/repos","events_url":"https://api.github.com/users/PatDyn/events{/privacy}","received_events_url":"https://api.github.com/users/PatDyn/received_events","type":"User","user_view_type":"public","site_admin":false},"labels":[{"id":9072229377,"node_id":"LA_kwDOPZ8tBM8AAAACHL88AQ","url":"https://api.github.com/repos/forgejo/test_repo/labels/duplicate","name":"duplicate","color":"cfd3d7","default":true,"description":"This issue or pull request already exists"},{"id":9072229408,"node_id":"LA_kwDOPZ8tBM8AAAACHL88IA","url":"https://api.github.com/repos/forgejo/test_repo/labels/good%20first%20issue","name":"good first issue","color":"7057ff","default":true,"description":"Good for newcomers"},{"id":9072229417,"node_id":"LA_kwDOPZ8tBM8AAAACHL88KQ","url":"https://api.github.com/repos/forgejo/test_repo/labels/help%20wanted","name":"help wanted","color":"008672","default":true,"description":"Extra attention is needed"}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":{"url":"https://api.github.com/repos/forgejo/test_repo/milestones/2","html_url":"https://github.com/forgejo/test_repo/milestone/2","labels_url":"https://api.github.com/repos/forgejo/test_repo/milestones/2/labels","id":13445587,"node_id":"MI_kwDOPZ8tBM4AzSnT","number":2,"title":"1.1.0","description":"We can do that","creator":{"login":"PatDyn","id":37243484,"node_id":"MDQ6VXNlcjM3MjQzNDg0","avatar_url":"https://avatars.githubusercontent.com/u/37243484?v=4","gravatar_id":"","url":"https://api.github.com/users/PatDyn","html_url":"https://github.com/PatDyn","followers_url":"https://api.github.com/users/PatDyn/followers","following_url":"https://api.github.com/users/PatDyn/following{/other_user}","gists_url":"https://api.github.com/users/PatDyn/gists{/gist_id}","starred_url":"https://api.github.com/users/PatDyn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/PatDyn/subscriptions","organizations_url":"https://api.github.com/users/PatDyn/orgs","repos_url":"https://api.github.com/users/PatDyn/repos","events_url":"https://api.github.com/users/PatDyn/events{/privacy}","received_events_url":"https://api.github.com/users/PatDyn/received_events","type":"User","user_view_type":"public","site_admin":false},"open_issues":1,"closed_issues":0,"state":"open","created_at":"2025-08-07T12:50:58Z","updated_at":"2025-08-07T12:53:15Z","due_on":"2025-08-31T07:00:00Z","closed_at":null},"comments":1,"created_at":"2025-08-07T12:45:44Z","updated_at":"2025-08-07T13:07:25Z","closed_at":null,"author_association":"COLLABORATOR","type":null,"active_lock_reason":null,"sub_issues_summary":{"total":0,"completed":0,"percent_completed":0},"body":"Mentioning #1 ","closed_by":null,"reactions":{"url":"https://api.github.com/repos/forgejo/test_repo/issues/2/reactions","total_count":0,"+1":0,"-1":0,"laugh":0,"hooray":0,"confused":0,"heart":0,"rocket":0,"eyes":0},"timeline_url":"https://api.github.com/repos/forgejo/test_repo/issues/2/timeline","performed_via_github_app":null,"state_reason":null}]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Flabels%3Fpage=1&per_page=100 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Flabels%3Fpage=1&per_page=100
deleted file mode 100644
index ef1aebf7a8..0000000000
--- a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Flabels%3Fpage=1&per_page=100
+++ /dev/null
@@ -1,25 +0,0 @@
-Cache-Control: private, max-age=60, s-maxage=60
-Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
-X-Accepted-Oauth-Scopes: repo
-Github-Authentication-Token-Expiration: 2025-09-11 10:37:11 UTC
-X-Github-Api-Version-Selected: 2022-11-28
-X-Ratelimit-Reset: 1755007969
-X-Xss-Protection: 0
-X-Github-Request-Id: E80A:118F3A:205BDE:1E77C9:689B401C
-Content-Type: application/json; charset=utf-8
-Etag: W/"fc30186df2be93c9dbcbb326f3d0249e5d618f924528d71af1d11941dc37f8b0"
-X-Oauth-Scopes: public_repo, repo:status
-Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
-Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
-Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
-X-Github-Media-Type: github.v3; format=json
-X-Ratelimit-Limit: 5000
-Access-Control-Allow-Origin: *
-X-Frame-Options: deny
-X-Content-Type-Options: nosniff
-X-Ratelimit-Remaining: 4878
-X-Ratelimit-Used: 122
-X-Ratelimit-Resource: core
-Content-Security-Policy: default-src 'none'
-
-[{"id":9072229344,"node_id":"LA_kwDOPZ8tBM8AAAACHL874A","url":"https://api.github.com/repos/forgejo/test_repo/labels/bug","name":"bug","color":"d73a4a","default":true,"description":"Something isn't working"},{"id":9072229361,"node_id":"LA_kwDOPZ8tBM8AAAACHL878Q","url":"https://api.github.com/repos/forgejo/test_repo/labels/documentation","name":"documentation","color":"0075ca","default":true,"description":"Improvements or additions to documentation"},{"id":9072229377,"node_id":"LA_kwDOPZ8tBM8AAAACHL88AQ","url":"https://api.github.com/repos/forgejo/test_repo/labels/duplicate","name":"duplicate","color":"cfd3d7","default":true,"description":"This issue or pull request already exists"},{"id":9072229390,"node_id":"LA_kwDOPZ8tBM8AAAACHL88Dg","url":"https://api.github.com/repos/forgejo/test_repo/labels/enhancement","name":"enhancement","color":"a2eeef","default":true,"description":"New feature or request"},{"id":9072229408,"node_id":"LA_kwDOPZ8tBM8AAAACHL88IA","url":"https://api.github.com/repos/forgejo/test_repo/labels/good%20first%20issue","name":"good first issue","color":"7057ff","default":true,"description":"Good for newcomers"},{"id":9072229417,"node_id":"LA_kwDOPZ8tBM8AAAACHL88KQ","url":"https://api.github.com/repos/forgejo/test_repo/labels/help%20wanted","name":"help wanted","color":"008672","default":true,"description":"Extra attention is needed"},{"id":9072229426,"node_id":"LA_kwDOPZ8tBM8AAAACHL88Mg","url":"https://api.github.com/repos/forgejo/test_repo/labels/invalid","name":"invalid","color":"e4e669","default":true,"description":"This doesn't seem right"},{"id":9072229435,"node_id":"LA_kwDOPZ8tBM8AAAACHL88Ow","url":"https://api.github.com/repos/forgejo/test_repo/labels/question","name":"question","color":"d876e3","default":true,"description":"Further information is requested"},{"id":9072229442,"node_id":"LA_kwDOPZ8tBM8AAAACHL88Qg","url":"https://api.github.com/repos/forgejo/test_repo/labels/wontfix","name":"wontfix","color":"ffffff","default":true,"description":"This will not be worked on"}]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fmilestones%3Fpage=1&per_page=100&state=all b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fmilestones%3Fpage=1&per_page=100&state=all
deleted file mode 100644
index 7dba1e4aac..0000000000
--- a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fmilestones%3Fpage=1&per_page=100&state=all
+++ /dev/null
@@ -1,25 +0,0 @@
-Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
-X-Github-Request-Id: E80A:118F3A:205928:1E754F:689B401B
-Etag: W/"39c17013c8c7b0f5abf91f15e52496c38730029baf6f37b5c3f3e40eb9886aab"
-X-Ratelimit-Remaining: 4879
-Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
-X-Xss-Protection: 0
-Content-Type: application/json; charset=utf-8
-Cache-Control: private, max-age=60, s-maxage=60
-X-Ratelimit-Reset: 1755007969
-X-Ratelimit-Used: 121
-X-Ratelimit-Resource: core
-Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
-Github-Authentication-Token-Expiration: 2025-09-11 10:37:11 UTC
-X-Github-Media-Type: github.v3; format=json
-X-Github-Api-Version-Selected: 2022-11-28
-X-Frame-Options: deny
-X-Content-Type-Options: nosniff
-Content-Security-Policy: default-src 'none'
-Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
-X-Oauth-Scopes: public_repo, repo:status
-X-Accepted-Oauth-Scopes: repo
-X-Ratelimit-Limit: 5000
-Access-Control-Allow-Origin: *
-
-[{"url":"https://api.github.com/repos/forgejo/test_repo/milestones/1","html_url":"https://github.com/forgejo/test_repo/milestone/1","labels_url":"https://api.github.com/repos/forgejo/test_repo/milestones/1/labels","id":13445581,"node_id":"MI_kwDOPZ8tBM4AzSnN","number":1,"title":"1.0.0","description":"Version 1","creator":{"login":"PatDyn","id":37243484,"node_id":"MDQ6VXNlcjM3MjQzNDg0","avatar_url":"https://avatars.githubusercontent.com/u/37243484?v=4","gravatar_id":"","url":"https://api.github.com/users/PatDyn","html_url":"https://github.com/PatDyn","followers_url":"https://api.github.com/users/PatDyn/followers","following_url":"https://api.github.com/users/PatDyn/following{/other_user}","gists_url":"https://api.github.com/users/PatDyn/gists{/gist_id}","starred_url":"https://api.github.com/users/PatDyn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/PatDyn/subscriptions","organizations_url":"https://api.github.com/users/PatDyn/orgs","repos_url":"https://api.github.com/users/PatDyn/repos","events_url":"https://api.github.com/users/PatDyn/events{/privacy}","received_events_url":"https://api.github.com/users/PatDyn/received_events","type":"User","user_view_type":"public","site_admin":false},"open_issues":1,"closed_issues":2,"state":"open","created_at":"2025-08-07T12:48:56Z","updated_at":"2025-08-12T12:34:20Z","due_on":null,"closed_at":null},{"url":"https://api.github.com/repos/forgejo/test_repo/milestones/3","html_url":"https://github.com/forgejo/test_repo/milestone/3","labels_url":"https://api.github.com/repos/forgejo/test_repo/milestones/3/labels","id":13445604,"node_id":"MI_kwDOPZ8tBM4AzSnk","number":3,"title":"0.9.0","description":"A milestone","creator":{"login":"PatDyn","id":37243484,"node_id":"MDQ6VXNlcjM3MjQzNDg0","avatar_url":"https://avatars.githubusercontent.com/u/37243484?v=4","gravatar_id":"","url":"https://api.github.com/users/PatDyn","html_url":"https://github.com/PatDyn","followers_url":"https://api.github.com/users/PatDyn/followers","following_url":"https://api.github.com/users/PatDyn/following{/other_user}","gists_url":"https://api.github.com/users/PatDyn/gists{/gist_id}","starred_url":"https://api.github.com/users/PatDyn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/PatDyn/subscriptions","organizations_url":"https://api.github.com/users/PatDyn/orgs","repos_url":"https://api.github.com/users/PatDyn/repos","events_url":"https://api.github.com/users/PatDyn/events{/privacy}","received_events_url":"https://api.github.com/users/PatDyn/received_events","type":"User","user_view_type":"public","site_admin":false},"open_issues":1,"closed_issues":0,"state":"closed","created_at":"2025-08-07T12:54:20Z","updated_at":"2025-08-12T11:29:52Z","due_on":"2025-08-01T07:00:00Z","closed_at":"2025-08-07T12:54:38Z"},{"url":"https://api.github.com/repos/forgejo/test_repo/milestones/2","html_url":"https://github.com/forgejo/test_repo/milestone/2","labels_url":"https://api.github.com/repos/forgejo/test_repo/milestones/2/labels","id":13445587,"node_id":"MI_kwDOPZ8tBM4AzSnT","number":2,"title":"1.1.0","description":"We can do that","creator":{"login":"PatDyn","id":37243484,"node_id":"MDQ6VXNlcjM3MjQzNDg0","avatar_url":"https://avatars.githubusercontent.com/u/37243484?v=4","gravatar_id":"","url":"https://api.github.com/users/PatDyn","html_url":"https://github.com/PatDyn","followers_url":"https://api.github.com/users/PatDyn/followers","following_url":"https://api.github.com/users/PatDyn/following{/other_user}","gists_url":"https://api.github.com/users/PatDyn/gists{/gist_id}","starred_url":"https://api.github.com/users/PatDyn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/PatDyn/subscriptions","organizations_url":"https://api.github.com/users/PatDyn/orgs","repos_url":"https://api.github.com/users/PatDyn/repos","events_url":"https://api.github.com/users/PatDyn/events{/privacy}","received_events_url":"https://api.github.com/users/PatDyn/received_events","type":"User","user_view_type":"public","site_admin":false},"open_issues":1,"closed_issues":0,"state":"open","created_at":"2025-08-07T12:50:58Z","updated_at":"2025-08-07T12:53:15Z","due_on":"2025-08-31T07:00:00Z","closed_at":null}]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fpulls%2F3%2Freviews%2F3096999684%2Fcomments%3Fper_page=100 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fpulls%2F3%2Freviews%2F3096999684%2Fcomments%3Fper_page=100
deleted file mode 100644
index 51f70d2a81..0000000000
--- a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fpulls%2F3%2Freviews%2F3096999684%2Fcomments%3Fper_page=100
+++ /dev/null
@@ -1,25 +0,0 @@
-Content-Type: application/json; charset=utf-8
-Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
-Etag: W/"9f6ff2d639a65dc556bded7ae25926c53ac6673582b68d1ebbbe3ecb1c375e3b"
-X-Ratelimit-Limit: 5000
-Access-Control-Allow-Origin: *
-X-Content-Type-Options: nosniff
-X-Xss-Protection: 0
-Content-Security-Policy: default-src 'none'
-X-Oauth-Scopes: public_repo, repo:status
-X-Accepted-Oauth-Scopes:
-Github-Authentication-Token-Expiration: 2025-09-11 10:37:11 UTC
-X-Ratelimit-Remaining: 4867
-X-Ratelimit-Resource: core
-Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
-X-Github-Request-Id: E80A:118F3A:207FBB:1E9958:689B4021
-Cache-Control: private, max-age=60, s-maxage=60
-X-Github-Media-Type: github.v3; format=json
-X-Github-Api-Version-Selected: 2022-11-28
-X-Ratelimit-Reset: 1755007969
-X-Ratelimit-Used: 133
-Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
-Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
-X-Frame-Options: deny
-
-[{"id":2260216729,"node_id":"PRRC_kwDOPZ8tBM6GuCuZ","url":"https://api.github.com/repos/forgejo/test_repo/pulls/comments/2260216729","pull_request_review_id":3096999684,"diff_hunk":"@@ -1,3 +1,5 @@\n # Forgejo Test Repo\n \n This repo is used to test migrations\n+\n+Add some feature description.","path":"readme.md","position":5,"original_position":5,"commit_id":"c608ab3997349219e1510cdb5ddd1e5e82897dfa","user":{"login":"PatDyn","id":37243484,"node_id":"MDQ6VXNlcjM3MjQzNDg0","avatar_url":"https://avatars.githubusercontent.com/u/37243484?v=4","gravatar_id":"","url":"https://api.github.com/users/PatDyn","html_url":"https://github.com/PatDyn","followers_url":"https://api.github.com/users/PatDyn/followers","following_url":"https://api.github.com/users/PatDyn/following{/other_user}","gists_url":"https://api.github.com/users/PatDyn/gists{/gist_id}","starred_url":"https://api.github.com/users/PatDyn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/PatDyn/subscriptions","organizations_url":"https://api.github.com/users/PatDyn/orgs","repos_url":"https://api.github.com/users/PatDyn/repos","events_url":"https://api.github.com/users/PatDyn/events{/privacy}","received_events_url":"https://api.github.com/users/PatDyn/received_events","type":"User","user_view_type":"public","site_admin":false},"body":"May want to write more","created_at":"2025-08-07T12:47:50Z","updated_at":"2025-08-07T12:47:55Z","html_url":"https://github.com/forgejo/test_repo/pull/3#discussion_r2260216729","pull_request_url":"https://api.github.com/repos/forgejo/test_repo/pulls/3","author_association":"COLLABORATOR","_links":{"self":{"href":"https://api.github.com/repos/forgejo/test_repo/pulls/comments/2260216729"},"html":{"href":"https://github.com/forgejo/test_repo/pull/3#discussion_r2260216729"},"pull_request":{"href":"https://api.github.com/repos/forgejo/test_repo/pulls/3"}},"original_commit_id":"c608ab3997349219e1510cdb5ddd1e5e82897dfa","reactions":{"url":"https://api.github.com/repos/forgejo/test_repo/pulls/comments/2260216729/reactions","total_count":0,"+1":0,"-1":0,"laugh":0,"hooray":0,"confused":0,"heart":0,"rocket":0,"eyes":0}}]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fpulls%2F3%2Freviews%2F3097007243%2Fcomments%3Fper_page=100 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fpulls%2F3%2Freviews%2F3097007243%2Fcomments%3Fper_page=100
deleted file mode 100644
index cd5fbdaf9d..0000000000
--- a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fpulls%2F3%2Freviews%2F3097007243%2Fcomments%3Fper_page=100
+++ /dev/null
@@ -1,25 +0,0 @@
-Etag: W/"17a2560299e1dbb8e8b83de09a8a409cd7b735baeebea469a041311a71a948d0"
-X-Accepted-Oauth-Scopes:
-X-Ratelimit-Remaining: 4865
-X-Ratelimit-Resource: core
-Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
-Content-Security-Policy: default-src 'none'
-X-Github-Api-Version-Selected: 2022-11-28
-X-Ratelimit-Used: 135
-Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
-X-Github-Request-Id: E80A:118F3A:20854A:1E9EB1:689B4022
-Content-Type: application/json; charset=utf-8
-Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
-X-Github-Media-Type: github.v3; format=json
-X-Ratelimit-Limit: 5000
-X-Frame-Options: deny
-X-Content-Type-Options: nosniff
-X-Xss-Protection: 0
-X-Oauth-Scopes: public_repo, repo:status
-Github-Authentication-Token-Expiration: 2025-09-11 10:37:11 UTC
-X-Ratelimit-Reset: 1755007969
-Access-Control-Allow-Origin: *
-Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
-Cache-Control: private, max-age=60, s-maxage=60
-
-[{"id":2260221159,"node_id":"PRRC_kwDOPZ8tBM6GuDzn","url":"https://api.github.com/repos/forgejo/test_repo/pulls/comments/2260221159","pull_request_review_id":3097007243,"diff_hunk":"@@ -1,3 +1,5 @@\n # Forgejo Test Repo\n \n This repo is used to test migrations","path":"readme.md","position":3,"original_position":3,"commit_id":"c608ab3997349219e1510cdb5ddd1e5e82897dfa","user":{"login":"PatDyn","id":37243484,"node_id":"MDQ6VXNlcjM3MjQzNDg0","avatar_url":"https://avatars.githubusercontent.com/u/37243484?v=4","gravatar_id":"","url":"https://api.github.com/users/PatDyn","html_url":"https://github.com/PatDyn","followers_url":"https://api.github.com/users/PatDyn/followers","following_url":"https://api.github.com/users/PatDyn/following{/other_user}","gists_url":"https://api.github.com/users/PatDyn/gists{/gist_id}","starred_url":"https://api.github.com/users/PatDyn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/PatDyn/subscriptions","organizations_url":"https://api.github.com/users/PatDyn/orgs","repos_url":"https://api.github.com/users/PatDyn/repos","events_url":"https://api.github.com/users/PatDyn/events{/privacy}","received_events_url":"https://api.github.com/users/PatDyn/received_events","type":"User","user_view_type":"public","site_admin":false},"body":"Comment","created_at":"2025-08-07T12:49:36Z","updated_at":"2025-08-07T12:49:36Z","html_url":"https://github.com/forgejo/test_repo/pull/3#discussion_r2260221159","pull_request_url":"https://api.github.com/repos/forgejo/test_repo/pulls/3","author_association":"COLLABORATOR","_links":{"self":{"href":"https://api.github.com/repos/forgejo/test_repo/pulls/comments/2260221159"},"html":{"href":"https://github.com/forgejo/test_repo/pull/3#discussion_r2260221159"},"pull_request":{"href":"https://api.github.com/repos/forgejo/test_repo/pulls/3"}},"original_commit_id":"c608ab3997349219e1510cdb5ddd1e5e82897dfa","reactions":{"url":"https://api.github.com/repos/forgejo/test_repo/pulls/comments/2260221159/reactions","total_count":0,"+1":0,"-1":0,"laugh":0,"hooray":0,"confused":0,"heart":0,"rocket":0,"eyes":0}}]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fpulls%2F3%2Freviews%3Fper_page=100 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fpulls%2F3%2Freviews%3Fper_page=100
deleted file mode 100644
index 82970c7a67..0000000000
--- a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fpulls%2F3%2Freviews%3Fper_page=100
+++ /dev/null
@@ -1,25 +0,0 @@
-Content-Type: application/json; charset=utf-8
-X-Accepted-Oauth-Scopes:
-X-Github-Media-Type: github.v3; format=json
-Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
-X-Content-Type-Options: nosniff
-Content-Security-Policy: default-src 'none'
-Cache-Control: private, max-age=60, s-maxage=60
-Etag: W/"d3281ac301ca94c8125009c335025cae84e5af242cb315bb975afad875b825e2"
-X-Oauth-Scopes: public_repo, repo:status
-Github-Authentication-Token-Expiration: 2025-09-11 10:37:11 UTC
-X-Ratelimit-Remaining: 4868
-Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
-X-Github-Request-Id: E80A:118F3A:207BE7:1E9600:689B4020
-Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
-X-Github-Api-Version-Selected: 2022-11-28
-X-Ratelimit-Limit: 5000
-X-Ratelimit-Reset: 1755007969
-X-Ratelimit-Resource: core
-Access-Control-Allow-Origin: *
-X-Frame-Options: deny
-X-Xss-Protection: 0
-X-Ratelimit-Used: 132
-Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
-
-[{"id":3096999684,"node_id":"PRR_kwDOPZ8tBM64mHcE","user":{"login":"PatDyn","id":37243484,"node_id":"MDQ6VXNlcjM3MjQzNDg0","avatar_url":"https://avatars.githubusercontent.com/u/37243484?u=c4857996d3079f843b3eb2a7dcb347698d817034&v=4","gravatar_id":"","url":"https://api.github.com/users/PatDyn","html_url":"https://github.com/PatDyn","followers_url":"https://api.github.com/users/PatDyn/followers","following_url":"https://api.github.com/users/PatDyn/following{/other_user}","gists_url":"https://api.github.com/users/PatDyn/gists{/gist_id}","starred_url":"https://api.github.com/users/PatDyn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/PatDyn/subscriptions","organizations_url":"https://api.github.com/users/PatDyn/orgs","repos_url":"https://api.github.com/users/PatDyn/repos","events_url":"https://api.github.com/users/PatDyn/events{/privacy}","received_events_url":"https://api.github.com/users/PatDyn/received_events","type":"User","user_view_type":"public","site_admin":false},"body":"","state":"COMMENTED","html_url":"https://github.com/forgejo/test_repo/pull/3#pullrequestreview-3096999684","pull_request_url":"https://api.github.com/repos/forgejo/test_repo/pulls/3","author_association":"COLLABORATOR","_links":{"html":{"href":"https://github.com/forgejo/test_repo/pull/3#pullrequestreview-3096999684"},"pull_request":{"href":"https://api.github.com/repos/forgejo/test_repo/pulls/3"}},"submitted_at":"2025-08-07T12:47:55Z","commit_id":"c608ab3997349219e1510cdb5ddd1e5e82897dfa"},{"id":3097007243,"node_id":"PRR_kwDOPZ8tBM64mJSL","user":{"login":"PatDyn","id":37243484,"node_id":"MDQ6VXNlcjM3MjQzNDg0","avatar_url":"https://avatars.githubusercontent.com/u/37243484?u=c4857996d3079f843b3eb2a7dcb347698d817034&v=4","gravatar_id":"","url":"https://api.github.com/users/PatDyn","html_url":"https://github.com/PatDyn","followers_url":"https://api.github.com/users/PatDyn/followers","following_url":"https://api.github.com/users/PatDyn/following{/other_user}","gists_url":"https://api.github.com/users/PatDyn/gists{/gist_id}","starred_url":"https://api.github.com/users/PatDyn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/PatDyn/subscriptions","organizations_url":"https://api.github.com/users/PatDyn/orgs","repos_url":"https://api.github.com/users/PatDyn/repos","events_url":"https://api.github.com/users/PatDyn/events{/privacy}","received_events_url":"https://api.github.com/users/PatDyn/received_events","type":"User","user_view_type":"public","site_admin":false},"body":"","state":"COMMENTED","html_url":"https://github.com/forgejo/test_repo/pull/3#pullrequestreview-3097007243","pull_request_url":"https://api.github.com/repos/forgejo/test_repo/pulls/3","author_association":"COLLABORATOR","_links":{"html":{"href":"https://github.com/forgejo/test_repo/pull/3#pullrequestreview-3097007243"},"pull_request":{"href":"https://api.github.com/repos/forgejo/test_repo/pulls/3"}},"submitted_at":"2025-08-07T12:49:36Z","commit_id":"c608ab3997349219e1510cdb5ddd1e5e82897dfa"}]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fpulls%2F4%2Freviews%3Fper_page=100 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fpulls%2F4%2Freviews%3Fper_page=100
deleted file mode 100644
index eea4344781..0000000000
--- a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fpulls%2F4%2Freviews%3Fper_page=100
+++ /dev/null
@@ -1,23 +0,0 @@
-X-Ratelimit-Limit: 5000
-X-Ratelimit-Remaining: 4856
-X-Ratelimit-Used: 144
-X-Accepted-Oauth-Scopes: repo
-X-Github-Media-Type: github.v3; format=json
-X-Github-Api-Version-Selected: 2022-11-28
-Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
-X-Xss-Protection: 0
-Content-Security-Policy: default-src 'none'
-Vary: Accept-Encoding, Accept, X-Requested-With
-X-Github-Request-Id: EDE1:32C4F6:A76DB4:9D7693:689B37A6
-X-Ratelimit-Reset: 1755004338
-X-Ratelimit-Resource: core
-Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
-X-Frame-Options: deny
-Content-Type: application/json; charset=utf-8
-X-Oauth-Scopes: public_repo, repo:status
-Github-Authentication-Token-Expiration: 2025-09-11 10:37:11 UTC
-Access-Control-Allow-Origin: *
-X-Content-Type-Options: nosniff
-Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
-
-{"message":"Not Found","documentation_url":"https://docs.github.com/rest/pulls/reviews#list-reviews-for-a-pull-request","status":"404"}
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fpulls%3Fdirection=asc&page=1&per_page=2&sort=created&state=all b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fpulls%3Fdirection=asc&page=1&per_page=2&sort=created&state=all
deleted file mode 100644
index 2835f22e9b..0000000000
--- a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fpulls%3Fdirection=asc&page=1&per_page=2&sort=created&state=all
+++ /dev/null
@@ -1,25 +0,0 @@
-Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
-X-Frame-Options: deny
-Cache-Control: private, max-age=60, s-maxage=60
-X-Accepted-Oauth-Scopes:
-X-Ratelimit-Remaining: 4871
-X-Content-Type-Options: nosniff
-Content-Security-Policy: default-src 'none'
-Github-Authentication-Token-Expiration: 2025-09-11 10:37:11 UTC
-X-Github-Media-Type: github.v3; format=json
-X-Github-Api-Version-Selected: 2022-11-28
-X-Ratelimit-Reset: 1755007969
-Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
-Access-Control-Allow-Origin: *
-X-Xss-Protection: 0
-X-Github-Request-Id: E80A:118F3A:207219:1E8D78:689B401F
-Content-Type: application/json; charset=utf-8
-X-Oauth-Scopes: public_repo, repo:status
-X-Ratelimit-Limit: 5000
-X-Ratelimit-Used: 129
-Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
-Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
-Etag: W/"9669b72db2e9016fd408b8c554dc01719c614d29bb965b082a81ee0489fd0914"
-X-Ratelimit-Resource: core
-
-[{"url":"https://api.github.com/repos/forgejo/test_repo/pulls/3","id":2727677736,"node_id":"PR_kwDOPZ8tBM6ilQ8o","html_url":"https://github.com/forgejo/test_repo/pull/3","diff_url":"https://github.com/forgejo/test_repo/pull/3.diff","patch_url":"https://github.com/forgejo/test_repo/pull/3.patch","issue_url":"https://api.github.com/repos/forgejo/test_repo/issues/3","number":3,"state":"open","locked":false,"title":"Update readme.md","user":{"login":"PatDyn","id":37243484,"node_id":"MDQ6VXNlcjM3MjQzNDg0","avatar_url":"https://avatars.githubusercontent.com/u/37243484?v=4","gravatar_id":"","url":"https://api.github.com/users/PatDyn","html_url":"https://github.com/PatDyn","followers_url":"https://api.github.com/users/PatDyn/followers","following_url":"https://api.github.com/users/PatDyn/following{/other_user}","gists_url":"https://api.github.com/users/PatDyn/gists{/gist_id}","starred_url":"https://api.github.com/users/PatDyn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/PatDyn/subscriptions","organizations_url":"https://api.github.com/users/PatDyn/orgs","repos_url":"https://api.github.com/users/PatDyn/repos","events_url":"https://api.github.com/users/PatDyn/events{/privacy}","received_events_url":"https://api.github.com/users/PatDyn/received_events","type":"User","user_view_type":"public","site_admin":false},"body":"Added a feature description","created_at":"2025-08-07T12:47:06Z","updated_at":"2025-08-12T13:16:49Z","closed_at":null,"merged_at":null,"merge_commit_sha":null,"assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":9072229390,"node_id":"LA_kwDOPZ8tBM8AAAACHL88Dg","url":"https://api.github.com/repos/forgejo/test_repo/labels/enhancement","name":"enhancement","color":"a2eeef","default":true,"description":"New feature or request"}],"milestone":{"url":"https://api.github.com/repos/forgejo/test_repo/milestones/1","html_url":"https://github.com/forgejo/test_repo/milestone/1","labels_url":"https://api.github.com/repos/forgejo/test_repo/milestones/1/labels","id":13445581,"node_id":"MI_kwDOPZ8tBM4AzSnN","number":1,"title":"1.0.0","description":"Version 1","creator":{"login":"PatDyn","id":37243484,"node_id":"MDQ6VXNlcjM3MjQzNDg0","avatar_url":"https://avatars.githubusercontent.com/u/37243484?v=4","gravatar_id":"","url":"https://api.github.com/users/PatDyn","html_url":"https://github.com/PatDyn","followers_url":"https://api.github.com/users/PatDyn/followers","following_url":"https://api.github.com/users/PatDyn/following{/other_user}","gists_url":"https://api.github.com/users/PatDyn/gists{/gist_id}","starred_url":"https://api.github.com/users/PatDyn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/PatDyn/subscriptions","organizations_url":"https://api.github.com/users/PatDyn/orgs","repos_url":"https://api.github.com/users/PatDyn/repos","events_url":"https://api.github.com/users/PatDyn/events{/privacy}","received_events_url":"https://api.github.com/users/PatDyn/received_events","type":"User","user_view_type":"public","site_admin":false},"open_issues":1,"closed_issues":2,"state":"open","created_at":"2025-08-07T12:48:56Z","updated_at":"2025-08-12T12:34:20Z","due_on":null,"closed_at":null},"draft":false,"commits_url":"https://api.github.com/repos/forgejo/test_repo/pulls/3/commits","review_comments_url":"https://api.github.com/repos/forgejo/test_repo/pulls/3/comments","review_comment_url":"https://api.github.com/repos/forgejo/test_repo/pulls/comments{/number}","comments_url":"https://api.github.com/repos/forgejo/test_repo/issues/3/comments","statuses_url":"https://api.github.com/repos/forgejo/test_repo/statuses/c608ab3997349219e1510cdb5ddd1e5e82897dfa","head":{"label":"forgejo:some-feature","ref":"some-feature","sha":"c608ab3997349219e1510cdb5ddd1e5e82897dfa","user":{"login":"forgejo","id":118922216,"node_id":"O_kgDOBxab6A","avatar_url":"https://avatars.githubusercontent.com/u/118922216?v=4","gravatar_id":"","url":"https://api.github.com/users/forgejo","html_url":"https://github.com/forgejo","followers_url":"https://api.github.com/users/forgejo/followers","following_url":"https://api.github.com/users/forgejo/following{/other_user}","gists_url":"https://api.github.com/users/forgejo/gists{/gist_id}","starred_url":"https://api.github.com/users/forgejo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/forgejo/subscriptions","organizations_url":"https://api.github.com/users/forgejo/orgs","repos_url":"https://api.github.com/users/forgejo/repos","events_url":"https://api.github.com/users/forgejo/events{/privacy}","received_events_url":"https://api.github.com/users/forgejo/received_events","type":"Organization","user_view_type":"public","site_admin":false},"repo":{"id":1033841924,"node_id":"R_kgDOPZ8tBA","name":"test_repo","full_name":"forgejo/test_repo","private":false,"owner":{"login":"forgejo","id":118922216,"node_id":"O_kgDOBxab6A","avatar_url":"https://avatars.githubusercontent.com/u/118922216?v=4","gravatar_id":"","url":"https://api.github.com/users/forgejo","html_url":"https://github.com/forgejo","followers_url":"https://api.github.com/users/forgejo/followers","following_url":"https://api.github.com/users/forgejo/following{/other_user}","gists_url":"https://api.github.com/users/forgejo/gists{/gist_id}","starred_url":"https://api.github.com/users/forgejo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/forgejo/subscriptions","organizations_url":"https://api.github.com/users/forgejo/orgs","repos_url":"https://api.github.com/users/forgejo/repos","events_url":"https://api.github.com/users/forgejo/events{/privacy}","received_events_url":"https://api.github.com/users/forgejo/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/forgejo/test_repo","description":"Exclusively used for testing Github->Forgejo migration","fork":false,"url":"https://api.github.com/repos/forgejo/test_repo","forks_url":"https://api.github.com/repos/forgejo/test_repo/forks","keys_url":"https://api.github.com/repos/forgejo/test_repo/keys{/key_id}","collaborators_url":"https://api.github.com/repos/forgejo/test_repo/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/forgejo/test_repo/teams","hooks_url":"https://api.github.com/repos/forgejo/test_repo/hooks","issue_events_url":"https://api.github.com/repos/forgejo/test_repo/issues/events{/number}","events_url":"https://api.github.com/repos/forgejo/test_repo/events","assignees_url":"https://api.github.com/repos/forgejo/test_repo/assignees{/user}","branches_url":"https://api.github.com/repos/forgejo/test_repo/branches{/branch}","tags_url":"https://api.github.com/repos/forgejo/test_repo/tags","blobs_url":"https://api.github.com/repos/forgejo/test_repo/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/forgejo/test_repo/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/forgejo/test_repo/git/refs{/sha}","trees_url":"https://api.github.com/repos/forgejo/test_repo/git/trees{/sha}","statuses_url":"https://api.github.com/repos/forgejo/test_repo/statuses/{sha}","languages_url":"https://api.github.com/repos/forgejo/test_repo/languages","stargazers_url":"https://api.github.com/repos/forgejo/test_repo/stargazers","contributors_url":"https://api.github.com/repos/forgejo/test_repo/contributors","subscribers_url":"https://api.github.com/repos/forgejo/test_repo/subscribers","subscription_url":"https://api.github.com/repos/forgejo/test_repo/subscription","commits_url":"https://api.github.com/repos/forgejo/test_repo/commits{/sha}","git_commits_url":"https://api.github.com/repos/forgejo/test_repo/git/commits{/sha}","comments_url":"https://api.github.com/repos/forgejo/test_repo/comments{/number}","issue_comment_url":"https://api.github.com/repos/forgejo/test_repo/issues/comments{/number}","contents_url":"https://api.github.com/repos/forgejo/test_repo/contents/{+path}","compare_url":"https://api.github.com/repos/forgejo/test_repo/compare/{base}...{head}","merges_url":"https://api.github.com/repos/forgejo/test_repo/merges","archive_url":"https://api.github.com/repos/forgejo/test_repo/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/forgejo/test_repo/downloads","issues_url":"https://api.github.com/repos/forgejo/test_repo/issues{/number}","pulls_url":"https://api.github.com/repos/forgejo/test_repo/pulls{/number}","milestones_url":"https://api.github.com/repos/forgejo/test_repo/milestones{/number}","notifications_url":"https://api.github.com/repos/forgejo/test_repo/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/forgejo/test_repo/labels{/name}","releases_url":"https://api.github.com/repos/forgejo/test_repo/releases{/id}","deployments_url":"https://api.github.com/repos/forgejo/test_repo/deployments","created_at":"2025-08-07T12:34:21Z","updated_at":"2025-08-12T11:21:45Z","pushed_at":"2025-08-07T13:07:49Z","git_url":"git://github.com/forgejo/test_repo.git","ssh_url":"git@github.com:forgejo/test_repo.git","clone_url":"https://github.com/forgejo/test_repo.git","svn_url":"https://github.com/forgejo/test_repo","homepage":"https://codeberg.org/forgejo/forgejo/","size":6,"stargazers_count":1,"watchers_count":1,"language":null,"has_issues":true,"has_projects":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"has_discussions":false,"forks_count":1,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":5,"license":{"key":"0bsd","name":"BSD Zero Clause License","spdx_id":"0BSD","url":"https://api.github.com/licenses/0bsd","node_id":"MDc6TGljZW5zZTM1"},"allow_forking":true,"is_template":false,"web_commit_signoff_required":false,"topics":["forgejo"],"visibility":"public","forks":1,"open_issues":5,"watchers":1,"default_branch":"main"}},"base":{"label":"forgejo:main","ref":"main","sha":"442d28a55b842472c95bead51a4c61f209ac1636","user":{"login":"forgejo","id":118922216,"node_id":"O_kgDOBxab6A","avatar_url":"https://avatars.githubusercontent.com/u/118922216?v=4","gravatar_id":"","url":"https://api.github.com/users/forgejo","html_url":"https://github.com/forgejo","followers_url":"https://api.github.com/users/forgejo/followers","following_url":"https://api.github.com/users/forgejo/following{/other_user}","gists_url":"https://api.github.com/users/forgejo/gists{/gist_id}","starred_url":"https://api.github.com/users/forgejo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/forgejo/subscriptions","organizations_url":"https://api.github.com/users/forgejo/orgs","repos_url":"https://api.github.com/users/forgejo/repos","events_url":"https://api.github.com/users/forgejo/events{/privacy}","received_events_url":"https://api.github.com/users/forgejo/received_events","type":"Organization","user_view_type":"public","site_admin":false},"repo":{"id":1033841924,"node_id":"R_kgDOPZ8tBA","name":"test_repo","full_name":"forgejo/test_repo","private":false,"owner":{"login":"forgejo","id":118922216,"node_id":"O_kgDOBxab6A","avatar_url":"https://avatars.githubusercontent.com/u/118922216?v=4","gravatar_id":"","url":"https://api.github.com/users/forgejo","html_url":"https://github.com/forgejo","followers_url":"https://api.github.com/users/forgejo/followers","following_url":"https://api.github.com/users/forgejo/following{/other_user}","gists_url":"https://api.github.com/users/forgejo/gists{/gist_id}","starred_url":"https://api.github.com/users/forgejo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/forgejo/subscriptions","organizations_url":"https://api.github.com/users/forgejo/orgs","repos_url":"https://api.github.com/users/forgejo/repos","events_url":"https://api.github.com/users/forgejo/events{/privacy}","received_events_url":"https://api.github.com/users/forgejo/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/forgejo/test_repo","description":"Exclusively used for testing Github->Forgejo migration","fork":false,"url":"https://api.github.com/repos/forgejo/test_repo","forks_url":"https://api.github.com/repos/forgejo/test_repo/forks","keys_url":"https://api.github.com/repos/forgejo/test_repo/keys{/key_id}","collaborators_url":"https://api.github.com/repos/forgejo/test_repo/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/forgejo/test_repo/teams","hooks_url":"https://api.github.com/repos/forgejo/test_repo/hooks","issue_events_url":"https://api.github.com/repos/forgejo/test_repo/issues/events{/number}","events_url":"https://api.github.com/repos/forgejo/test_repo/events","assignees_url":"https://api.github.com/repos/forgejo/test_repo/assignees{/user}","branches_url":"https://api.github.com/repos/forgejo/test_repo/branches{/branch}","tags_url":"https://api.github.com/repos/forgejo/test_repo/tags","blobs_url":"https://api.github.com/repos/forgejo/test_repo/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/forgejo/test_repo/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/forgejo/test_repo/git/refs{/sha}","trees_url":"https://api.github.com/repos/forgejo/test_repo/git/trees{/sha}","statuses_url":"https://api.github.com/repos/forgejo/test_repo/statuses/{sha}","languages_url":"https://api.github.com/repos/forgejo/test_repo/languages","stargazers_url":"https://api.github.com/repos/forgejo/test_repo/stargazers","contributors_url":"https://api.github.com/repos/forgejo/test_repo/contributors","subscribers_url":"https://api.github.com/repos/forgejo/test_repo/subscribers","subscription_url":"https://api.github.com/repos/forgejo/test_repo/subscription","commits_url":"https://api.github.com/repos/forgejo/test_repo/commits{/sha}","git_commits_url":"https://api.github.com/repos/forgejo/test_repo/git/commits{/sha}","comments_url":"https://api.github.com/repos/forgejo/test_repo/comments{/number}","issue_comment_url":"https://api.github.com/repos/forgejo/test_repo/issues/comments{/number}","contents_url":"https://api.github.com/repos/forgejo/test_repo/contents/{+path}","compare_url":"https://api.github.com/repos/forgejo/test_repo/compare/{base}...{head}","merges_url":"https://api.github.com/repos/forgejo/test_repo/merges","archive_url":"https://api.github.com/repos/forgejo/test_repo/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/forgejo/test_repo/downloads","issues_url":"https://api.github.com/repos/forgejo/test_repo/issues{/number}","pulls_url":"https://api.github.com/repos/forgejo/test_repo/pulls{/number}","milestones_url":"https://api.github.com/repos/forgejo/test_repo/milestones{/number}","notifications_url":"https://api.github.com/repos/forgejo/test_repo/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/forgejo/test_repo/labels{/name}","releases_url":"https://api.github.com/repos/forgejo/test_repo/releases{/id}","deployments_url":"https://api.github.com/repos/forgejo/test_repo/deployments","created_at":"2025-08-07T12:34:21Z","updated_at":"2025-08-12T11:21:45Z","pushed_at":"2025-08-07T13:07:49Z","git_url":"git://github.com/forgejo/test_repo.git","ssh_url":"git@github.com:forgejo/test_repo.git","clone_url":"https://github.com/forgejo/test_repo.git","svn_url":"https://github.com/forgejo/test_repo","homepage":"https://codeberg.org/forgejo/forgejo/","size":6,"stargazers_count":1,"watchers_count":1,"language":null,"has_issues":true,"has_projects":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"has_discussions":false,"forks_count":1,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":5,"license":{"key":"0bsd","name":"BSD Zero Clause License","spdx_id":"0BSD","url":"https://api.github.com/licenses/0bsd","node_id":"MDc6TGljZW5zZTM1"},"allow_forking":true,"is_template":false,"web_commit_signoff_required":false,"topics":["forgejo"],"visibility":"public","forks":1,"open_issues":5,"watchers":1,"default_branch":"main"}},"_links":{"self":{"href":"https://api.github.com/repos/forgejo/test_repo/pulls/3"},"html":{"href":"https://github.com/forgejo/test_repo/pull/3"},"issue":{"href":"https://api.github.com/repos/forgejo/test_repo/issues/3"},"comments":{"href":"https://api.github.com/repos/forgejo/test_repo/issues/3/comments"},"review_comments":{"href":"https://api.github.com/repos/forgejo/test_repo/pulls/3/comments"},"review_comment":{"href":"https://api.github.com/repos/forgejo/test_repo/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/forgejo/test_repo/pulls/3/commits"},"statuses":{"href":"https://api.github.com/repos/forgejo/test_repo/statuses/c608ab3997349219e1510cdb5ddd1e5e82897dfa"}},"author_association":"COLLABORATOR","auto_merge":null,"active_lock_reason":null},{"url":"https://api.github.com/repos/forgejo/test_repo/pulls/7","id":2727724283,"node_id":"PR_kwDOPZ8tBM6ilcT7","html_url":"https://github.com/forgejo/test_repo/pull/7","diff_url":"https://github.com/forgejo/test_repo/pull/7.diff","patch_url":"https://github.com/forgejo/test_repo/pull/7.patch","issue_url":"https://api.github.com/repos/forgejo/test_repo/issues/7","number":7,"state":"closed","locked":false,"title":"Update readme.md","user":{"login":"PatDyn","id":37243484,"node_id":"MDQ6VXNlcjM3MjQzNDg0","avatar_url":"https://avatars.githubusercontent.com/u/37243484?v=4","gravatar_id":"","url":"https://api.github.com/users/PatDyn","html_url":"https://github.com/PatDyn","followers_url":"https://api.github.com/users/PatDyn/followers","following_url":"https://api.github.com/users/PatDyn/following{/other_user}","gists_url":"https://api.github.com/users/PatDyn/gists{/gist_id}","starred_url":"https://api.github.com/users/PatDyn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/PatDyn/subscriptions","organizations_url":"https://api.github.com/users/PatDyn/orgs","repos_url":"https://api.github.com/users/PatDyn/repos","events_url":"https://api.github.com/users/PatDyn/events{/privacy}","received_events_url":"https://api.github.com/users/PatDyn/received_events","type":"User","user_view_type":"public","site_admin":false},"body":"Adding some text to the readme","created_at":"2025-08-07T13:01:36Z","updated_at":"2025-08-12T12:47:35Z","closed_at":"2025-08-07T13:02:19Z","merged_at":"2025-08-07T13:02:19Z","merge_commit_sha":"ca43b48ca2c461f9a5cb66500a154b23d07c9f90","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":9072229344,"node_id":"LA_kwDOPZ8tBM8AAAACHL874A","url":"https://api.github.com/repos/forgejo/test_repo/labels/bug","name":"bug","color":"d73a4a","default":true,"description":"Something isn't working"}],"milestone":{"url":"https://api.github.com/repos/forgejo/test_repo/milestones/1","html_url":"https://github.com/forgejo/test_repo/milestone/1","labels_url":"https://api.github.com/repos/forgejo/test_repo/milestones/1/labels","id":13445581,"node_id":"MI_kwDOPZ8tBM4AzSnN","number":1,"title":"1.0.0","description":"Version 1","creator":{"login":"PatDyn","id":37243484,"node_id":"MDQ6VXNlcjM3MjQzNDg0","avatar_url":"https://avatars.githubusercontent.com/u/37243484?v=4","gravatar_id":"","url":"https://api.github.com/users/PatDyn","html_url":"https://github.com/PatDyn","followers_url":"https://api.github.com/users/PatDyn/followers","following_url":"https://api.github.com/users/PatDyn/following{/other_user}","gists_url":"https://api.github.com/users/PatDyn/gists{/gist_id}","starred_url":"https://api.github.com/users/PatDyn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/PatDyn/subscriptions","organizations_url":"https://api.github.com/users/PatDyn/orgs","repos_url":"https://api.github.com/users/PatDyn/repos","events_url":"https://api.github.com/users/PatDyn/events{/privacy}","received_events_url":"https://api.github.com/users/PatDyn/received_events","type":"User","user_view_type":"public","site_admin":false},"open_issues":1,"closed_issues":2,"state":"open","created_at":"2025-08-07T12:48:56Z","updated_at":"2025-08-12T12:34:20Z","due_on":null,"closed_at":null},"draft":false,"commits_url":"https://api.github.com/repos/forgejo/test_repo/pulls/7/commits","review_comments_url":"https://api.github.com/repos/forgejo/test_repo/pulls/7/comments","review_comment_url":"https://api.github.com/repos/forgejo/test_repo/pulls/comments{/number}","comments_url":"https://api.github.com/repos/forgejo/test_repo/issues/7/comments","statuses_url":"https://api.github.com/repos/forgejo/test_repo/statuses/5638cb8f3278e467fc1eefcac14d3c0d5d91601f","head":{"label":"forgejo:another-feature","ref":"another-feature","sha":"5638cb8f3278e467fc1eefcac14d3c0d5d91601f","user":{"login":"forgejo","id":118922216,"node_id":"O_kgDOBxab6A","avatar_url":"https://avatars.githubusercontent.com/u/118922216?v=4","gravatar_id":"","url":"https://api.github.com/users/forgejo","html_url":"https://github.com/forgejo","followers_url":"https://api.github.com/users/forgejo/followers","following_url":"https://api.github.com/users/forgejo/following{/other_user}","gists_url":"https://api.github.com/users/forgejo/gists{/gist_id}","starred_url":"https://api.github.com/users/forgejo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/forgejo/subscriptions","organizations_url":"https://api.github.com/users/forgejo/orgs","repos_url":"https://api.github.com/users/forgejo/repos","events_url":"https://api.github.com/users/forgejo/events{/privacy}","received_events_url":"https://api.github.com/users/forgejo/received_events","type":"Organization","user_view_type":"public","site_admin":false},"repo":{"id":1033841924,"node_id":"R_kgDOPZ8tBA","name":"test_repo","full_name":"forgejo/test_repo","private":false,"owner":{"login":"forgejo","id":118922216,"node_id":"O_kgDOBxab6A","avatar_url":"https://avatars.githubusercontent.com/u/118922216?v=4","gravatar_id":"","url":"https://api.github.com/users/forgejo","html_url":"https://github.com/forgejo","followers_url":"https://api.github.com/users/forgejo/followers","following_url":"https://api.github.com/users/forgejo/following{/other_user}","gists_url":"https://api.github.com/users/forgejo/gists{/gist_id}","starred_url":"https://api.github.com/users/forgejo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/forgejo/subscriptions","organizations_url":"https://api.github.com/users/forgejo/orgs","repos_url":"https://api.github.com/users/forgejo/repos","events_url":"https://api.github.com/users/forgejo/events{/privacy}","received_events_url":"https://api.github.com/users/forgejo/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/forgejo/test_repo","description":"Exclusively used for testing Github->Forgejo migration","fork":false,"url":"https://api.github.com/repos/forgejo/test_repo","forks_url":"https://api.github.com/repos/forgejo/test_repo/forks","keys_url":"https://api.github.com/repos/forgejo/test_repo/keys{/key_id}","collaborators_url":"https://api.github.com/repos/forgejo/test_repo/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/forgejo/test_repo/teams","hooks_url":"https://api.github.com/repos/forgejo/test_repo/hooks","issue_events_url":"https://api.github.com/repos/forgejo/test_repo/issues/events{/number}","events_url":"https://api.github.com/repos/forgejo/test_repo/events","assignees_url":"https://api.github.com/repos/forgejo/test_repo/assignees{/user}","branches_url":"https://api.github.com/repos/forgejo/test_repo/branches{/branch}","tags_url":"https://api.github.com/repos/forgejo/test_repo/tags","blobs_url":"https://api.github.com/repos/forgejo/test_repo/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/forgejo/test_repo/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/forgejo/test_repo/git/refs{/sha}","trees_url":"https://api.github.com/repos/forgejo/test_repo/git/trees{/sha}","statuses_url":"https://api.github.com/repos/forgejo/test_repo/statuses/{sha}","languages_url":"https://api.github.com/repos/forgejo/test_repo/languages","stargazers_url":"https://api.github.com/repos/forgejo/test_repo/stargazers","contributors_url":"https://api.github.com/repos/forgejo/test_repo/contributors","subscribers_url":"https://api.github.com/repos/forgejo/test_repo/subscribers","subscription_url":"https://api.github.com/repos/forgejo/test_repo/subscription","commits_url":"https://api.github.com/repos/forgejo/test_repo/commits{/sha}","git_commits_url":"https://api.github.com/repos/forgejo/test_repo/git/commits{/sha}","comments_url":"https://api.github.com/repos/forgejo/test_repo/comments{/number}","issue_comment_url":"https://api.github.com/repos/forgejo/test_repo/issues/comments{/number}","contents_url":"https://api.github.com/repos/forgejo/test_repo/contents/{+path}","compare_url":"https://api.github.com/repos/forgejo/test_repo/compare/{base}...{head}","merges_url":"https://api.github.com/repos/forgejo/test_repo/merges","archive_url":"https://api.github.com/repos/forgejo/test_repo/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/forgejo/test_repo/downloads","issues_url":"https://api.github.com/repos/forgejo/test_repo/issues{/number}","pulls_url":"https://api.github.com/repos/forgejo/test_repo/pulls{/number}","milestones_url":"https://api.github.com/repos/forgejo/test_repo/milestones{/number}","notifications_url":"https://api.github.com/repos/forgejo/test_repo/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/forgejo/test_repo/labels{/name}","releases_url":"https://api.github.com/repos/forgejo/test_repo/releases{/id}","deployments_url":"https://api.github.com/repos/forgejo/test_repo/deployments","created_at":"2025-08-07T12:34:21Z","updated_at":"2025-08-12T11:21:45Z","pushed_at":"2025-08-07T13:07:49Z","git_url":"git://github.com/forgejo/test_repo.git","ssh_url":"git@github.com:forgejo/test_repo.git","clone_url":"https://github.com/forgejo/test_repo.git","svn_url":"https://github.com/forgejo/test_repo","homepage":"https://codeberg.org/forgejo/forgejo/","size":6,"stargazers_count":1,"watchers_count":1,"language":null,"has_issues":true,"has_projects":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"has_discussions":false,"forks_count":1,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":5,"license":{"key":"0bsd","name":"BSD Zero Clause License","spdx_id":"0BSD","url":"https://api.github.com/licenses/0bsd","node_id":"MDc6TGljZW5zZTM1"},"allow_forking":true,"is_template":false,"web_commit_signoff_required":false,"topics":["forgejo"],"visibility":"public","forks":1,"open_issues":5,"watchers":1,"default_branch":"main"}},"base":{"label":"forgejo:main","ref":"main","sha":"6dd0c6801ddbb7333787e73e99581279492ff449","user":{"login":"forgejo","id":118922216,"node_id":"O_kgDOBxab6A","avatar_url":"https://avatars.githubusercontent.com/u/118922216?v=4","gravatar_id":"","url":"https://api.github.com/users/forgejo","html_url":"https://github.com/forgejo","followers_url":"https://api.github.com/users/forgejo/followers","following_url":"https://api.github.com/users/forgejo/following{/other_user}","gists_url":"https://api.github.com/users/forgejo/gists{/gist_id}","starred_url":"https://api.github.com/users/forgejo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/forgejo/subscriptions","organizations_url":"https://api.github.com/users/forgejo/orgs","repos_url":"https://api.github.com/users/forgejo/repos","events_url":"https://api.github.com/users/forgejo/events{/privacy}","received_events_url":"https://api.github.com/users/forgejo/received_events","type":"Organization","user_view_type":"public","site_admin":false},"repo":{"id":1033841924,"node_id":"R_kgDOPZ8tBA","name":"test_repo","full_name":"forgejo/test_repo","private":false,"owner":{"login":"forgejo","id":118922216,"node_id":"O_kgDOBxab6A","avatar_url":"https://avatars.githubusercontent.com/u/118922216?v=4","gravatar_id":"","url":"https://api.github.com/users/forgejo","html_url":"https://github.com/forgejo","followers_url":"https://api.github.com/users/forgejo/followers","following_url":"https://api.github.com/users/forgejo/following{/other_user}","gists_url":"https://api.github.com/users/forgejo/gists{/gist_id}","starred_url":"https://api.github.com/users/forgejo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/forgejo/subscriptions","organizations_url":"https://api.github.com/users/forgejo/orgs","repos_url":"https://api.github.com/users/forgejo/repos","events_url":"https://api.github.com/users/forgejo/events{/privacy}","received_events_url":"https://api.github.com/users/forgejo/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/forgejo/test_repo","description":"Exclusively used for testing Github->Forgejo migration","fork":false,"url":"https://api.github.com/repos/forgejo/test_repo","forks_url":"https://api.github.com/repos/forgejo/test_repo/forks","keys_url":"https://api.github.com/repos/forgejo/test_repo/keys{/key_id}","collaborators_url":"https://api.github.com/repos/forgejo/test_repo/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/forgejo/test_repo/teams","hooks_url":"https://api.github.com/repos/forgejo/test_repo/hooks","issue_events_url":"https://api.github.com/repos/forgejo/test_repo/issues/events{/number}","events_url":"https://api.github.com/repos/forgejo/test_repo/events","assignees_url":"https://api.github.com/repos/forgejo/test_repo/assignees{/user}","branches_url":"https://api.github.com/repos/forgejo/test_repo/branches{/branch}","tags_url":"https://api.github.com/repos/forgejo/test_repo/tags","blobs_url":"https://api.github.com/repos/forgejo/test_repo/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/forgejo/test_repo/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/forgejo/test_repo/git/refs{/sha}","trees_url":"https://api.github.com/repos/forgejo/test_repo/git/trees{/sha}","statuses_url":"https://api.github.com/repos/forgejo/test_repo/statuses/{sha}","languages_url":"https://api.github.com/repos/forgejo/test_repo/languages","stargazers_url":"https://api.github.com/repos/forgejo/test_repo/stargazers","contributors_url":"https://api.github.com/repos/forgejo/test_repo/contributors","subscribers_url":"https://api.github.com/repos/forgejo/test_repo/subscribers","subscription_url":"https://api.github.com/repos/forgejo/test_repo/subscription","commits_url":"https://api.github.com/repos/forgejo/test_repo/commits{/sha}","git_commits_url":"https://api.github.com/repos/forgejo/test_repo/git/commits{/sha}","comments_url":"https://api.github.com/repos/forgejo/test_repo/comments{/number}","issue_comment_url":"https://api.github.com/repos/forgejo/test_repo/issues/comments{/number}","contents_url":"https://api.github.com/repos/forgejo/test_repo/contents/{+path}","compare_url":"https://api.github.com/repos/forgejo/test_repo/compare/{base}...{head}","merges_url":"https://api.github.com/repos/forgejo/test_repo/merges","archive_url":"https://api.github.com/repos/forgejo/test_repo/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/forgejo/test_repo/downloads","issues_url":"https://api.github.com/repos/forgejo/test_repo/issues{/number}","pulls_url":"https://api.github.com/repos/forgejo/test_repo/pulls{/number}","milestones_url":"https://api.github.com/repos/forgejo/test_repo/milestones{/number}","notifications_url":"https://api.github.com/repos/forgejo/test_repo/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/forgejo/test_repo/labels{/name}","releases_url":"https://api.github.com/repos/forgejo/test_repo/releases{/id}","deployments_url":"https://api.github.com/repos/forgejo/test_repo/deployments","created_at":"2025-08-07T12:34:21Z","updated_at":"2025-08-12T11:21:45Z","pushed_at":"2025-08-07T13:07:49Z","git_url":"git://github.com/forgejo/test_repo.git","ssh_url":"git@github.com:forgejo/test_repo.git","clone_url":"https://github.com/forgejo/test_repo.git","svn_url":"https://github.com/forgejo/test_repo","homepage":"https://codeberg.org/forgejo/forgejo/","size":6,"stargazers_count":1,"watchers_count":1,"language":null,"has_issues":true,"has_projects":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"has_discussions":false,"forks_count":1,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":5,"license":{"key":"0bsd","name":"BSD Zero Clause License","spdx_id":"0BSD","url":"https://api.github.com/licenses/0bsd","node_id":"MDc6TGljZW5zZTM1"},"allow_forking":true,"is_template":false,"web_commit_signoff_required":false,"topics":["forgejo"],"visibility":"public","forks":1,"open_issues":5,"watchers":1,"default_branch":"main"}},"_links":{"self":{"href":"https://api.github.com/repos/forgejo/test_repo/pulls/7"},"html":{"href":"https://github.com/forgejo/test_repo/pull/7"},"issue":{"href":"https://api.github.com/repos/forgejo/test_repo/issues/7"},"comments":{"href":"https://api.github.com/repos/forgejo/test_repo/issues/7/comments"},"review_comments":{"href":"https://api.github.com/repos/forgejo/test_repo/pulls/7/comments"},"review_comment":{"href":"https://api.github.com/repos/forgejo/test_repo/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/forgejo/test_repo/pulls/7/commits"},"statuses":{"href":"https://api.github.com/repos/forgejo/test_repo/statuses/5638cb8f3278e467fc1eefcac14d3c0d5d91601f"}},"author_association":"COLLABORATOR","auto_merge":null,"active_lock_reason":null}]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Freleases%3Fpage=1&per_page=100 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Freleases%3Fpage=1&per_page=100
deleted file mode 100644
index 5fc5f2dc94..0000000000
--- a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Freleases%3Fpage=1&per_page=100
+++ /dev/null
@@ -1,25 +0,0 @@
-X-Ratelimit-Remaining: 4877
-X-Ratelimit-Used: 123
-Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
-Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
-Content-Security-Policy: default-src 'none'
-Content-Type: application/json; charset=utf-8
-Cache-Control: private, max-age=60, s-maxage=60
-Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
-Github-Authentication-Token-Expiration: 2025-09-11 10:37:11 UTC
-X-Ratelimit-Resource: core
-Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
-X-Xss-Protection: 0
-Etag: W/"da1b952735d448e2474ba8dc4ba5b9c2a1989fb8bf0002dff577ae452601af43"
-X-Github-Media-Type: github.v3; format=json
-X-Github-Api-Version-Selected: 2022-11-28
-X-Ratelimit-Reset: 1755007969
-Access-Control-Allow-Origin: *
-X-Frame-Options: deny
-X-Content-Type-Options: nosniff
-X-Github-Request-Id: E80A:118F3A:205E1D:1E7A62:689B401C
-X-Oauth-Scopes: public_repo, repo:status
-X-Accepted-Oauth-Scopes: repo
-X-Ratelimit-Limit: 5000
-
-[{"url":"https://api.github.com/repos/forgejo/test_repo/releases/238309022","assets_url":"https://api.github.com/repos/forgejo/test_repo/releases/238309022/assets","upload_url":"https://uploads.github.com/repos/forgejo/test_repo/releases/238309022/assets{?name,label}","html_url":"https://github.com/forgejo/test_repo/releases/tag/v1.0","id":238309022,"author":{"login":"Gusted","id":25481501,"node_id":"MDQ6VXNlcjI1NDgxNTAx","avatar_url":"https://avatars.githubusercontent.com/u/25481501?v=4","gravatar_id":"","url":"https://api.github.com/users/Gusted","html_url":"https://github.com/Gusted","followers_url":"https://api.github.com/users/Gusted/followers","following_url":"https://api.github.com/users/Gusted/following{/other_user}","gists_url":"https://api.github.com/users/Gusted/gists{/gist_id}","starred_url":"https://api.github.com/users/Gusted/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Gusted/subscriptions","organizations_url":"https://api.github.com/users/Gusted/orgs","repos_url":"https://api.github.com/users/Gusted/repos","events_url":"https://api.github.com/users/Gusted/events{/privacy}","received_events_url":"https://api.github.com/users/Gusted/received_events","type":"User","user_view_type":"public","site_admin":false},"node_id":"RE_kwDOPZ8tBM4ONE6e","tag_name":"v1.0","target_commitish":"main","name":"First Release","draft":false,"immutable":false,"prerelease":false,"created_at":"2025-08-07T13:02:19Z","updated_at":"2025-08-12T11:24:30Z","published_at":"2025-08-07T13:07:49Z","assets":[{"url":"https://api.github.com/repos/forgejo/test_repo/releases/assets/280443629","id":280443629,"node_id":"RA_kwDOPZ8tBM4Qtzrt","name":"wireguard.pdf","label":null,"uploader":{"login":"Gusted","id":25481501,"node_id":"MDQ6VXNlcjI1NDgxNTAx","avatar_url":"https://avatars.githubusercontent.com/u/25481501?v=4","gravatar_id":"","url":"https://api.github.com/users/Gusted","html_url":"https://github.com/Gusted","followers_url":"https://api.github.com/users/Gusted/followers","following_url":"https://api.github.com/users/Gusted/following{/other_user}","gists_url":"https://api.github.com/users/Gusted/gists{/gist_id}","starred_url":"https://api.github.com/users/Gusted/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Gusted/subscriptions","organizations_url":"https://api.github.com/users/Gusted/orgs","repos_url":"https://api.github.com/users/Gusted/repos","events_url":"https://api.github.com/users/Gusted/events{/privacy}","received_events_url":"https://api.github.com/users/Gusted/received_events","type":"User","user_view_type":"public","site_admin":false},"content_type":"application/pdf","state":"uploaded","size":550175,"digest":"sha256:b4cf398c21d054e8774af568395b0f7cd0e2b01322809c5dbd66c4135021ca57","download_count":0,"created_at":"2025-08-07T23:39:27Z","updated_at":"2025-08-07T23:39:29Z","browser_download_url":"https://github.com/forgejo/test_repo/releases/download/v1.0/wireguard.pdf"}],"tarball_url":"https://api.github.com/repos/forgejo/test_repo/tarball/v1.0","zipball_url":"https://api.github.com/repos/forgejo/test_repo/zipball/v1.0","body":"Hi, this is the first release! The asset contains the wireguard whitepaper, amazing read for such a simple protocol."}]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo
new file mode 100644
index 0000000000..78fde4d424
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo
@@ -0,0 +1,25 @@
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Resource: core
+Access-Control-Allow-Origin: *
+X-Github-Request-Id: C7CC:3118FC:3F5EFD7:403585D:6729E6B3
+Cache-Control: private, max-age=60, s-maxage=60
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+X-Xss-Protection: 0
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+X-Github-Media-Type: github.v3; param=scarlet-witch-preview; format=json, github.mercy-preview; param=baptiste-preview.nebula-preview; format=json
+Etag: W/"bb1c9e0186e52dbd9f2c34aaf0827517384a15fd0cee7b81ad13784901db15c0"
+X-Oauth-Scopes:
+X-Accepted-Oauth-Scopes: repo
+X-Ratelimit-Limit: 5000
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+X-Content-Type-Options: nosniff
+Content-Type: application/json; charset=utf-8
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+Last-Modified: Thu, 02 Mar 2023 14:02:26 GMT
+X-Ratelimit-Remaining: 4928
+X-Ratelimit-Reset: 1730800941
+X-Ratelimit-Used: 72
+X-Frame-Options: deny
+Content-Security-Policy: default-src 'none'
+
+{"id":220672974,"node_id":"MDEwOlJlcG9zaXRvcnkyMjA2NzI5NzQ=","name":"test_repo","full_name":"go-gitea/test_repo","private":false,"owner":{"login":"go-gitea","id":12724356,"node_id":"MDEyOk9yZ2FuaXphdGlvbjEyNzI0MzU2","avatar_url":"https://avatars.githubusercontent.com/u/12724356?v=4","gravatar_id":"","url":"https://api.github.com/users/go-gitea","html_url":"https://github.com/go-gitea","followers_url":"https://api.github.com/users/go-gitea/followers","following_url":"https://api.github.com/users/go-gitea/following{/other_user}","gists_url":"https://api.github.com/users/go-gitea/gists{/gist_id}","starred_url":"https://api.github.com/users/go-gitea/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/go-gitea/subscriptions","organizations_url":"https://api.github.com/users/go-gitea/orgs","repos_url":"https://api.github.com/users/go-gitea/repos","events_url":"https://api.github.com/users/go-gitea/events{/privacy}","received_events_url":"https://api.github.com/users/go-gitea/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/go-gitea/test_repo","description":"Test repository for testing migration from github to gitea","fork":false,"url":"https://api.github.com/repos/go-gitea/test_repo","forks_url":"https://api.github.com/repos/go-gitea/test_repo/forks","keys_url":"https://api.github.com/repos/go-gitea/test_repo/keys{/key_id}","collaborators_url":"https://api.github.com/repos/go-gitea/test_repo/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/go-gitea/test_repo/teams","hooks_url":"https://api.github.com/repos/go-gitea/test_repo/hooks","issue_events_url":"https://api.github.com/repos/go-gitea/test_repo/issues/events{/number}","events_url":"https://api.github.com/repos/go-gitea/test_repo/events","assignees_url":"https://api.github.com/repos/go-gitea/test_repo/assignees{/user}","branches_url":"https://api.github.com/repos/go-gitea/test_repo/branches{/branch}","tags_url":"https://api.github.com/repos/go-gitea/test_repo/tags","blobs_url":"https://api.github.com/repos/go-gitea/test_repo/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/go-gitea/test_repo/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/go-gitea/test_repo/git/refs{/sha}","trees_url":"https://api.github.com/repos/go-gitea/test_repo/git/trees{/sha}","statuses_url":"https://api.github.com/repos/go-gitea/test_repo/statuses/{sha}","languages_url":"https://api.github.com/repos/go-gitea/test_repo/languages","stargazers_url":"https://api.github.com/repos/go-gitea/test_repo/stargazers","contributors_url":"https://api.github.com/repos/go-gitea/test_repo/contributors","subscribers_url":"https://api.github.com/repos/go-gitea/test_repo/subscribers","subscription_url":"https://api.github.com/repos/go-gitea/test_repo/subscription","commits_url":"https://api.github.com/repos/go-gitea/test_repo/commits{/sha}","git_commits_url":"https://api.github.com/repos/go-gitea/test_repo/git/commits{/sha}","comments_url":"https://api.github.com/repos/go-gitea/test_repo/comments{/number}","issue_comment_url":"https://api.github.com/repos/go-gitea/test_repo/issues/comments{/number}","contents_url":"https://api.github.com/repos/go-gitea/test_repo/contents/{+path}","compare_url":"https://api.github.com/repos/go-gitea/test_repo/compare/{base}...{head}","merges_url":"https://api.github.com/repos/go-gitea/test_repo/merges","archive_url":"https://api.github.com/repos/go-gitea/test_repo/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/go-gitea/test_repo/downloads","issues_url":"https://api.github.com/repos/go-gitea/test_repo/issues{/number}","pulls_url":"https://api.github.com/repos/go-gitea/test_repo/pulls{/number}","milestones_url":"https://api.github.com/repos/go-gitea/test_repo/milestones{/number}","notifications_url":"https://api.github.com/repos/go-gitea/test_repo/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/go-gitea/test_repo/labels{/name}","releases_url":"https://api.github.com/repos/go-gitea/test_repo/releases{/id}","deployments_url":"https://api.github.com/repos/go-gitea/test_repo/deployments","created_at":"2019-11-09T16:49:20Z","updated_at":"2023-03-02T14:02:26Z","pushed_at":"2019-11-12T21:54:19Z","git_url":"git://github.com/go-gitea/test_repo.git","ssh_url":"git@github.com:go-gitea/test_repo.git","clone_url":"https://github.com/go-gitea/test_repo.git","svn_url":"https://github.com/go-gitea/test_repo","homepage":"https://codeberg.org/forgejo/forgejo/","size":1,"stargazers_count":3,"watchers_count":3,"language":null,"has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"has_discussions":false,"forks_count":6,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":2,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit","node_id":"MDc6TGljZW5zZTEz"},"allow_forking":true,"is_template":false,"web_commit_signoff_required":false,"topics":["gitea"],"visibility":"public","forks":6,"open_issues":2,"watchers":3,"default_branch":"master","permissions":{"admin":false,"maintain":false,"push":false,"triage":false,"pull":true},"temp_clone_token":"","custom_properties":{},"organization":{"login":"go-gitea","id":12724356,"node_id":"MDEyOk9yZ2FuaXphdGlvbjEyNzI0MzU2","avatar_url":"https://avatars.githubusercontent.com/u/12724356?v=4","gravatar_id":"","url":"https://api.github.com/users/go-gitea","html_url":"https://github.com/go-gitea","followers_url":"https://api.github.com/users/go-gitea/followers","following_url":"https://api.github.com/users/go-gitea/following{/other_user}","gists_url":"https://api.github.com/users/go-gitea/gists{/gist_id}","starred_url":"https://api.github.com/users/go-gitea/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/go-gitea/subscriptions","organizations_url":"https://api.github.com/users/go-gitea/orgs","repos_url":"https://api.github.com/users/go-gitea/repos","events_url":"https://api.github.com/users/go-gitea/events{/privacy}","received_events_url":"https://api.github.com/users/go-gitea/received_events","type":"Organization","user_view_type":"public","site_admin":false},"network_count":6,"subscribers_count":6}
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F1%2Freactions%3Fpage=1&per_page=2 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F1%2Freactions%3Fpage=1&per_page=2
new file mode 100644
index 0000000000..f1f9afee15
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F1%2Freactions%3Fpage=1&per_page=2
@@ -0,0 +1,24 @@
+Cache-Control: private, max-age=60, s-maxage=60
+X-Ratelimit-Remaining: 4923
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+X-Accepted-Oauth-Scopes: repo
+X-Github-Media-Type: github.v3; param=squirrel-girl-preview
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Reset: 1730800941
+X-Ratelimit-Resource: core
+Content-Security-Policy: default-src 'none'
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Ratelimit-Used: 77
+Access-Control-Allow-Origin: *
+X-Xss-Protection: 0
+X-Github-Request-Id: C7CC:3118FC:3F5F8DA:403618E:6729E6B6
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+Content-Type: application/json; charset=utf-8
+Etag: W/"07b6d56c5fdc728f96fceef3d45d26b4ebac96ef5138156668055f7d496c9a75"
+X-Oauth-Scopes:
+X-Ratelimit-Limit: 5000
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+X-Frame-Options: deny
+X-Content-Type-Options: nosniff
+
+[{"id":55441655,"node_id":"MDEzOklzc3VlUmVhY3Rpb241NTQ0MTY1NQ==","user":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?u=7c1ba931adbdd9bab5be1a41d244425d463568cd&v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"content":"+1","created_at":"2019-11-12T20:22:13Z"}]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fissues%2F1%2Freactions%3Fpage=1&per_page=2 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F1%2Freactions%3Fpage=2&per_page=2
similarity index 65%
rename from services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fissues%2F1%2Freactions%3Fpage=1&per_page=2
rename to services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F1%2Freactions%3Fpage=2&per_page=2
index 2af575abc9..fe993d3c3b 100644
--- a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fissues%2F1%2Freactions%3Fpage=1&per_page=2
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F1%2Freactions%3Fpage=2&per_page=2
@@ -1,26 +1,26 @@
+Etag: "f87b0fd59e59458a9a808311324b873c6baf3fde861298a99de9986270dd4d79"
+X-Github-Media-Type: github.v3; param=squirrel-girl-preview
X-Github-Api-Version-Selected: 2022-11-28
-Content-Security-Policy: default-src 'none'
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+X-Content-Type-Options: nosniff
Content-Type: application/json; charset=utf-8
Content-Length: 2
-Etag: "578cfdf865ccd59faa414c655476c87af814e220755c938b9545967521b6f14b"
-X-Ratelimit-Remaining: 4875
-Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
-X-Github-Request-Id: E80A:118F3A:20652B:1E80D9:689B401D
-Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
-X-Oauth-Scopes: public_repo, repo:status
-X-Accepted-Oauth-Scopes: repo
-X-Ratelimit-Limit: 5000
-X-Ratelimit-Reset: 1755007969
-Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
-X-Frame-Options: deny
Cache-Control: private, max-age=60, s-maxage=60
-X-Ratelimit-Used: 125
-X-Ratelimit-Resource: core
-Access-Control-Allow-Origin: *
-X-Content-Type-Options: nosniff
+Link: ; rel="prev", ; rel="last", ; rel="first"
+X-Ratelimit-Limit: 5000
+X-Ratelimit-Remaining: 4922
+X-Ratelimit-Reset: 1730800941
X-Xss-Protection: 0
+X-Github-Request-Id: C7CC:3118FC:3F5FA7C:403633C:6729E6B6
+X-Oauth-Scopes:
+X-Ratelimit-Used: 78
+X-Frame-Options: deny
Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
-Github-Authentication-Token-Expiration: 2025-09-11 10:37:11 UTC
-X-Github-Media-Type: github.v3; param=squirrel-girl-preview
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Accepted-Oauth-Scopes: repo
+X-Ratelimit-Resource: core
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+Access-Control-Allow-Origin: *
+Content-Security-Policy: default-src 'none'
[]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F2%2Fcomments%3Fdirection=asc&per_page=100&sort=created b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F2%2Fcomments%3Fdirection=asc&per_page=100&sort=created
new file mode 100644
index 0000000000..61867c5ae6
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F2%2Fcomments%3Fdirection=asc&per_page=100&sort=created
@@ -0,0 +1,24 @@
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Github-Media-Type: github.v3; param=squirrel-girl-preview
+X-Ratelimit-Remaining: 4917
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+Content-Type: application/json; charset=utf-8
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Limit: 5000
+X-Ratelimit-Reset: 1730800941
+X-Ratelimit-Used: 83
+X-Content-Type-Options: nosniff
+X-Github-Request-Id: C7CC:3118FC:3F60409:4036CD0:6729E6B8
+Etag: W/"5f4d715f2578719997e324fe7b29e7eeeec048288237b44d4f320666514813ad"
+X-Accepted-Oauth-Scopes:
+X-Frame-Options: deny
+X-Xss-Protection: 0
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+X-Ratelimit-Resource: core
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+Access-Control-Allow-Origin: *
+Content-Security-Policy: default-src 'none'
+Cache-Control: private, max-age=60, s-maxage=60
+X-Oauth-Scopes:
+
+[{"url":"https://api.github.com/repos/go-gitea/test_repo/issues/comments/553111966","html_url":"https://github.com/go-gitea/test_repo/issues/2#issuecomment-553111966","issue_url":"https://api.github.com/repos/go-gitea/test_repo/issues/2","id":553111966,"node_id":"MDEyOklzc3VlQ29tbWVudDU1MzExMTk2Ng==","user":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"created_at":"2019-11-12T21:00:13Z","updated_at":"2019-11-12T21:00:13Z","author_association":"MEMBER","body":"This is a comment","reactions":{"url":"https://api.github.com/repos/go-gitea/test_repo/issues/comments/553111966/reactions","total_count":1,"+1":1,"-1":0,"laugh":0,"hooray":0,"confused":0,"heart":0,"rocket":0,"eyes":0},"performed_via_github_app":null},{"url":"https://api.github.com/repos/go-gitea/test_repo/issues/comments/553138856","html_url":"https://github.com/go-gitea/test_repo/issues/2#issuecomment-553138856","issue_url":"https://api.github.com/repos/go-gitea/test_repo/issues/2","id":553138856,"node_id":"MDEyOklzc3VlQ29tbWVudDU1MzEzODg1Ng==","user":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"created_at":"2019-11-12T22:07:14Z","updated_at":"2019-11-12T22:07:14Z","author_association":"MEMBER","body":"A second comment","reactions":{"url":"https://api.github.com/repos/go-gitea/test_repo/issues/comments/553138856/reactions","total_count":0,"+1":0,"-1":0,"laugh":0,"hooray":0,"confused":0,"heart":0,"rocket":0,"eyes":0},"performed_via_github_app":null}]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F2%2Freactions%3Fpage=1&per_page=2 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F2%2Freactions%3Fpage=1&per_page=2
new file mode 100644
index 0000000000..bb9dea395c
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F2%2Freactions%3Fpage=1&per_page=2
@@ -0,0 +1,25 @@
+X-Ratelimit-Resource: core
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+X-Xss-Protection: 0
+X-Accepted-Oauth-Scopes: repo
+Link: ; rel="next", ; rel="last"
+X-Ratelimit-Remaining: 4921
+X-Ratelimit-Reset: 1730800941
+X-Github-Request-Id: C7CC:3118FC:3F5FC1A:40364D4:6729E6B6
+Content-Security-Policy: default-src 'none'
+X-Oauth-Scopes:
+X-Ratelimit-Used: 79
+X-Frame-Options: deny
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+X-Github-Api-Version-Selected: 2022-11-28
+Content-Type: application/json; charset=utf-8
+Etag: W/"27408cb5dd95878d6267de226341c84fd1d2c49695867baecf930579608e16a5"
+X-Github-Media-Type: github.v3; param=squirrel-girl-preview
+X-Content-Type-Options: nosniff
+Cache-Control: private, max-age=60, s-maxage=60
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Ratelimit-Limit: 5000
+Access-Control-Allow-Origin: *
+
+[{"id":55445108,"node_id":"MDEzOklzc3VlUmVhY3Rpb241NTQ0NTEwOA==","user":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?u=7c1ba931adbdd9bab5be1a41d244425d463568cd&v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"content":"heart","created_at":"2019-11-12T21:02:05Z"},{"id":55445150,"node_id":"MDEzOklzc3VlUmVhY3Rpb241NTQ0NTE1MA==","user":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?u=7c1ba931adbdd9bab5be1a41d244425d463568cd&v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"content":"laugh","created_at":"2019-11-12T21:02:35Z"}]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F2%2Freactions%3Fpage=2&per_page=2 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F2%2Freactions%3Fpage=2&per_page=2
new file mode 100644
index 0000000000..e59fc93546
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F2%2Freactions%3Fpage=2&per_page=2
@@ -0,0 +1,25 @@
+X-Ratelimit-Reset: 1730800941
+X-Ratelimit-Resource: core
+X-Frame-Options: deny
+Etag: W/"cb64a4e91ab70a1ab9fe2f77cdbf7452120169f4c2cce397014efe94cc0d60bb"
+Link: ; rel="prev", ; rel="next", ; rel="last", ; rel="first"
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Oauth-Scopes:
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+X-Content-Type-Options: nosniff
+Content-Security-Policy: default-src 'none'
+Content-Type: application/json; charset=utf-8
+Cache-Control: private, max-age=60, s-maxage=60
+X-Xss-Protection: 0
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+X-Github-Request-Id: C7CC:3118FC:3F5FDBD:4036670:6729E6B7
+X-Github-Media-Type: github.v3; param=squirrel-girl-preview
+Access-Control-Allow-Origin: *
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Limit: 5000
+X-Ratelimit-Remaining: 4920
+X-Ratelimit-Used: 80
+X-Accepted-Oauth-Scopes: repo
+
+[{"id":55445169,"node_id":"MDEzOklzc3VlUmVhY3Rpb241NTQ0NTE2OQ==","user":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?u=7c1ba931adbdd9bab5be1a41d244425d463568cd&v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"content":"-1","created_at":"2019-11-12T21:02:47Z"},{"id":55445177,"node_id":"MDEzOklzc3VlUmVhY3Rpb241NTQ0NTE3Nw==","user":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?u=7c1ba931adbdd9bab5be1a41d244425d463568cd&v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"content":"confused","created_at":"2019-11-12T21:02:52Z"}]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F2%2Freactions%3Fpage=3&per_page=2 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F2%2Freactions%3Fpage=3&per_page=2
new file mode 100644
index 0000000000..57f03c8a64
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F2%2Freactions%3Fpage=3&per_page=2
@@ -0,0 +1,25 @@
+Etag: W/"17b0dca978a885d2234548248a7d5c22264c161b73e28c5cd144e33a24dd9ed4"
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Reset: 1730800941
+X-Ratelimit-Used: 81
+Content-Security-Policy: default-src 'none'
+Content-Type: application/json; charset=utf-8
+X-Oauth-Scopes:
+Link: ; rel="prev", ; rel="first"
+X-Ratelimit-Limit: 5000
+X-Frame-Options: deny
+X-Content-Type-Options: nosniff
+X-Accepted-Oauth-Scopes: repo
+X-Github-Media-Type: github.v3; param=squirrel-girl-preview
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+X-Xss-Protection: 0
+Access-Control-Allow-Origin: *
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+Cache-Control: private, max-age=60, s-maxage=60
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Ratelimit-Remaining: 4919
+X-Ratelimit-Resource: core
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+X-Github-Request-Id: C7CC:3118FC:3F5FF70:403681F:6729E6B7
+
+[{"id":55445188,"node_id":"MDEzOklzc3VlUmVhY3Rpb241NTQ0NTE4OA==","user":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?u=7c1ba931adbdd9bab5be1a41d244425d463568cd&v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"content":"hooray","created_at":"2019-11-12T21:02:58Z"},{"id":55445441,"node_id":"MDEzOklzc3VlUmVhY3Rpb241NTQ0NTQ0MQ==","user":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?u=7c1ba931adbdd9bab5be1a41d244425d463568cd&v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"content":"+1","created_at":"2019-11-12T21:06:04Z"}]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fissues%2F2%2Freactions%3Fpage=1&per_page=2 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F2%2Freactions%3Fpage=4&per_page=2
similarity index 65%
rename from services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fissues%2F2%2Freactions%3Fpage=1&per_page=2
rename to services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F2%2Freactions%3Fpage=4&per_page=2
index ecaafa82e4..f14d4ba904 100644
--- a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fissues%2F2%2Freactions%3Fpage=1&per_page=2
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F2%2Freactions%3Fpage=4&per_page=2
@@ -1,26 +1,26 @@
-Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
-X-Frame-Options: deny
-X-Content-Type-Options: nosniff
-X-Accepted-Oauth-Scopes: repo
-X-Ratelimit-Reset: 1755007969
-Access-Control-Allow-Origin: *
-Content-Type: application/json; charset=utf-8
-Content-Length: 2
-Cache-Control: private, max-age=60, s-maxage=60
-Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
-X-Oauth-Scopes: public_repo, repo:status
-Github-Authentication-Token-Expiration: 2025-09-11 10:37:11 UTC
-X-Github-Media-Type: github.v3; param=squirrel-girl-preview
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+X-Oauth-Scopes:
X-Ratelimit-Limit: 5000
-Etag: "578cfdf865ccd59faa414c655476c87af814e220755c938b9545967521b6f14b"
-X-Ratelimit-Remaining: 4874
-X-Ratelimit-Used: 126
+X-Ratelimit-Remaining: 4918
+X-Ratelimit-Reset: 1730800941
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+X-Content-Type-Options: nosniff
+X-Github-Request-Id: C7CC:3118FC:3F60229:4036AE8:6729E6B8
+Etag: "f87b0fd59e59458a9a808311324b873c6baf3fde861298a99de9986270dd4d79"
+Link: ; rel="prev", ; rel="last", ; rel="first"
+X-Accepted-Oauth-Scopes: repo
+X-Github-Media-Type: github.v3; param=squirrel-girl-preview
+X-Ratelimit-Used: 82
+X-Frame-Options: deny
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+Cache-Control: private, max-age=60, s-maxage=60
+X-Github-Api-Version-Selected: 2022-11-28
X-Ratelimit-Resource: core
+Access-Control-Allow-Origin: *
X-Xss-Protection: 0
Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+Content-Type: application/json; charset=utf-8
+Content-Length: 2
Content-Security-Policy: default-src 'none'
-X-Github-Request-Id: E80A:118F3A:206814:1E83B2:689B401E
-X-Github-Api-Version-Selected: 2022-11-28
-Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
[]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fissues%2F3%2Freactions%3Fpage=1&per_page=2 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F3%2Freactions%3Fpage=1&per_page=2
similarity index 76%
rename from services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fissues%2F3%2Freactions%3Fpage=1&per_page=2
rename to services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F3%2Freactions%3Fpage=1&per_page=2
index a900075c9b..a7a105b3e7 100644
--- a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fissues%2F3%2Freactions%3Fpage=1&per_page=2
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F3%2Freactions%3Fpage=1&per_page=2
@@ -1,26 +1,25 @@
-Content-Type: application/json; charset=utf-8
-Content-Length: 2
-Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
-X-Github-Media-Type: github.v3; param=squirrel-girl-preview
+X-Ratelimit-Used: 88
X-Ratelimit-Resource: core
-Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
-X-Github-Request-Id: E80A:118F3A:20758C:1E9080:689B401F
-X-Oauth-Scopes: public_repo, repo:status
-Github-Authentication-Token-Expiration: 2025-09-11 10:37:11 UTC
-X-Ratelimit-Limit: 5000
-X-Ratelimit-Reset: 1755007969
-Access-Control-Allow-Origin: *
-Content-Security-Policy: default-src 'none'
-Cache-Control: private, max-age=60, s-maxage=60
-X-Github-Api-Version-Selected: 2022-11-28
-X-Ratelimit-Remaining: 4870
-X-Ratelimit-Used: 130
X-Content-Type-Options: nosniff
+Content-Security-Policy: default-src 'none'
+X-Github-Request-Id: C7CC:3118FC:3F60B4F:403741E:6729E6BA
+Content-Type: application/json; charset=utf-8
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Ratelimit-Reset: 1730800941
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+Cache-Control: private, max-age=60, s-maxage=60
+X-Github-Media-Type: github.v3; param=squirrel-girl-preview
+Access-Control-Allow-Origin: *
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+X-Frame-Options: deny
X-Xss-Protection: 0
Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
-Etag: "578cfdf865ccd59faa414c655476c87af814e220755c938b9545967521b6f14b"
+Etag: "f87b0fd59e59458a9a808311324b873c6baf3fde861298a99de9986270dd4d79"
+X-Oauth-Scopes:
X-Accepted-Oauth-Scopes: repo
-Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
-X-Frame-Options: deny
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Limit: 5000
+X-Ratelimit-Remaining: 4912
+Content-Length: 2
[]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F4%2Freactions%3Fpage=1&per_page=2 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F4%2Freactions%3Fpage=1&per_page=2
new file mode 100644
index 0000000000..f5398c3a9f
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F4%2Freactions%3Fpage=1&per_page=2
@@ -0,0 +1,24 @@
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+Etag: W/"dc9d10e1714eadc1507466c7d11d2dd84ae539a378835f8763b9948da44b22e1"
+X-Accepted-Oauth-Scopes: repo
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+Access-Control-Allow-Origin: *
+X-Frame-Options: deny
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Reset: 1730800941
+Content-Type: application/json; charset=utf-8
+X-Github-Media-Type: github.v3; param=squirrel-girl-preview
+X-Ratelimit-Remaining: 4911
+X-Ratelimit-Used: 89
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+X-Content-Type-Options: nosniff
+X-Xss-Protection: 0
+Content-Security-Policy: default-src 'none'
+X-Github-Request-Id: C7CC:3118FC:3F60D0F:40375F2:6729E6BB
+Cache-Control: private, max-age=60, s-maxage=60
+X-Oauth-Scopes:
+X-Ratelimit-Limit: 5000
+X-Ratelimit-Resource: core
+
+[{"id":59496724,"node_id":"MDEzOklzc3VlUmVhY3Rpb241OTQ5NjcyNA==","user":{"login":"lunny","id":81045,"node_id":"MDQ6VXNlcjgxMDQ1","avatar_url":"https://avatars.githubusercontent.com/u/81045?u=99b64f0ca6ef63643c7583ab87dd31c52d28e673&v=4","gravatar_id":"","url":"https://api.github.com/users/lunny","html_url":"https://github.com/lunny","followers_url":"https://api.github.com/users/lunny/followers","following_url":"https://api.github.com/users/lunny/following{/other_user}","gists_url":"https://api.github.com/users/lunny/gists{/gist_id}","starred_url":"https://api.github.com/users/lunny/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lunny/subscriptions","organizations_url":"https://api.github.com/users/lunny/orgs","repos_url":"https://api.github.com/users/lunny/repos","events_url":"https://api.github.com/users/lunny/events{/privacy}","received_events_url":"https://api.github.com/users/lunny/received_events","type":"User","user_view_type":"public","site_admin":false},"content":"heart","created_at":"2020-01-10T08:31:30Z"},{"id":59496731,"node_id":"MDEzOklzc3VlUmVhY3Rpb241OTQ5NjczMQ==","user":{"login":"lunny","id":81045,"node_id":"MDQ6VXNlcjgxMDQ1","avatar_url":"https://avatars.githubusercontent.com/u/81045?u=99b64f0ca6ef63643c7583ab87dd31c52d28e673&v=4","gravatar_id":"","url":"https://api.github.com/users/lunny","html_url":"https://github.com/lunny","followers_url":"https://api.github.com/users/lunny/followers","following_url":"https://api.github.com/users/lunny/following{/other_user}","gists_url":"https://api.github.com/users/lunny/gists{/gist_id}","starred_url":"https://api.github.com/users/lunny/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lunny/subscriptions","organizations_url":"https://api.github.com/users/lunny/orgs","repos_url":"https://api.github.com/users/lunny/repos","events_url":"https://api.github.com/users/lunny/events{/privacy}","received_events_url":"https://api.github.com/users/lunny/received_events","type":"User","user_view_type":"public","site_admin":false},"content":"+1","created_at":"2020-01-10T08:31:39Z"}]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fissues%2F7%2Freactions%3Fpage=1&per_page=2 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F4%2Freactions%3Fpage=2&per_page=2
similarity index 65%
rename from services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fissues%2F7%2Freactions%3Fpage=1&per_page=2
rename to services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F4%2Freactions%3Fpage=2&per_page=2
index 694c612697..79b506ea55 100644
--- a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fissues%2F7%2Freactions%3Fpage=1&per_page=2
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F4%2Freactions%3Fpage=2&per_page=2
@@ -1,26 +1,26 @@
-Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Oauth-Scopes:
X-Accepted-Oauth-Scopes: repo
-Github-Authentication-Token-Expiration: 2025-09-11 10:37:11 UTC
-X-Github-Media-Type: github.v3; param=squirrel-girl-preview
-X-Github-Api-Version-Selected: 2022-11-28
-X-Ratelimit-Resource: core
-Access-Control-Allow-Origin: *
-X-Frame-Options: deny
-Cache-Control: private, max-age=60, s-maxage=60
-Etag: "578cfdf865ccd59faa414c655476c87af814e220755c938b9545967521b6f14b"
-X-Ratelimit-Reset: 1755007969
-X-Xss-Protection: 0
-X-Github-Request-Id: E80A:118F3A:207936:1E936E:689B4020
-X-Oauth-Scopes: public_repo, repo:status
-X-Ratelimit-Remaining: 4869
+X-Ratelimit-Limit: 5000
Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+Content-Length: 2
+Cache-Control: private, max-age=60, s-maxage=60
+Etag: "f87b0fd59e59458a9a808311324b873c6baf3fde861298a99de9986270dd4d79"
X-Content-Type-Options: nosniff
Content-Security-Policy: default-src 'none'
+X-Ratelimit-Remaining: 4910
+X-Ratelimit-Reset: 1730800941
+X-Frame-Options: deny
Content-Type: application/json; charset=utf-8
-Content-Length: 2
-X-Ratelimit-Limit: 5000
-X-Ratelimit-Used: 131
-Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+Link: ; rel="prev", ; rel="last", ; rel="first"
+X-Xss-Protection: 0
Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+X-Github-Request-Id: C7CC:3118FC:3F60EE6:40377B6:6729E6BB
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Ratelimit-Used: 90
+X-Ratelimit-Resource: core
+X-Github-Media-Type: github.v3; param=squirrel-girl-preview
+X-Github-Api-Version-Selected: 2022-11-28
+Access-Control-Allow-Origin: *
[]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2Fcomments%2F553111966%2Freactions%3Fpage=1&per_page=100 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2Fcomments%2F553111966%2Freactions%3Fpage=1&per_page=100
new file mode 100644
index 0000000000..b55068a718
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2Fcomments%2F553111966%2Freactions%3Fpage=1&per_page=100
@@ -0,0 +1,24 @@
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+X-Accepted-Oauth-Scopes:
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Limit: 5000
+X-Ratelimit-Used: 84
+X-Ratelimit-Resource: core
+X-Content-Type-Options: nosniff
+Cache-Control: private, max-age=60, s-maxage=60
+Etag: W/"d2410fc0792a61666c06ed757aa53a273165d4f14f7d5259095b7a4f3a959121"
+X-Xss-Protection: 0
+Content-Security-Policy: default-src 'none'
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Oauth-Scopes:
+X-Github-Media-Type: github.v3; param=squirrel-girl-preview
+X-Ratelimit-Remaining: 4916
+X-Frame-Options: deny
+X-Github-Request-Id: C7CC:3118FC:3F60583:4036E51:6729E6B9
+Content-Type: application/json; charset=utf-8
+X-Ratelimit-Reset: 1730800941
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+Access-Control-Allow-Origin: *
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+
+[{"id":55446208,"node_id":"MDIwOklzc3VlQ29tbWVudFJlYWN0aW9uNTU0NDYyMDg=","user":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"content":"+1","created_at":"2019-11-12T21:13:22Z"}]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2Fcomments%2F553111966%2Freactions%3Fpage=2&per_page=100 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2Fcomments%2F553111966%2Freactions%3Fpage=2&per_page=100
new file mode 100644
index 0000000000..1e46f438e5
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2Fcomments%2F553111966%2Freactions%3Fpage=2&per_page=100
@@ -0,0 +1,26 @@
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Github-Media-Type: github.v3; param=squirrel-girl-preview
+Cache-Control: private, max-age=60, s-maxage=60
+X-Ratelimit-Used: 85
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+X-Github-Request-Id: C7CC:3118FC:3F606F2:4036FB5:6729E6B9
+X-Xss-Protection: 0
+Content-Type: application/json; charset=utf-8
+Etag: "f87b0fd59e59458a9a808311324b873c6baf3fde861298a99de9986270dd4d79"
+X-Oauth-Scopes:
+Link: ; rel="prev", ; rel="last", ; rel="first"
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Resource: core
+X-Frame-Options: deny
+Content-Length: 2
+X-Accepted-Oauth-Scopes:
+X-Ratelimit-Limit: 5000
+X-Ratelimit-Remaining: 4915
+X-Ratelimit-Reset: 1730800941
+Access-Control-Allow-Origin: *
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+X-Content-Type-Options: nosniff
+Content-Security-Policy: default-src 'none'
+
+[]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fissues%2Fcomments%2F3164123494%2Freactions%3Fpage=1&per_page=100 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2Fcomments%2F553138856%2Freactions%3Fpage=1&per_page=100
similarity index 76%
rename from services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fissues%2Fcomments%2F3164123494%2Freactions%3Fpage=1&per_page=100
rename to services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2Fcomments%2F553138856%2Freactions%3Fpage=1&per_page=100
index 4ee1c6bc52..ac446b3586 100644
--- a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fissues%2Fcomments%2F3164123494%2Freactions%3Fpage=1&per_page=100
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2Fcomments%2F553138856%2Freactions%3Fpage=1&per_page=100
@@ -1,26 +1,25 @@
-Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
-Content-Security-Policy: default-src 'none'
-Content-Type: application/json; charset=utf-8
-X-Oauth-Scopes: public_repo, repo:status
-X-Ratelimit-Remaining: 4872
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+X-Github-Media-Type: github.v3; param=squirrel-girl-preview
+X-Ratelimit-Remaining: 4914
X-Frame-Options: deny
X-Xss-Protection: 0
-Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
-X-Github-Media-Type: github.v3; param=squirrel-girl-preview
+X-Ratelimit-Reset: 1730800941
+X-Ratelimit-Resource: core
+X-Content-Type-Options: nosniff
+Content-Type: application/json; charset=utf-8
+Etag: "f87b0fd59e59458a9a808311324b873c6baf3fde861298a99de9986270dd4d79"
+X-Accepted-Oauth-Scopes:
X-Github-Api-Version-Selected: 2022-11-28
X-Ratelimit-Limit: 5000
-X-Ratelimit-Used: 128
-X-Content-Type-Options: nosniff
-Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
-Cache-Control: private, max-age=60, s-maxage=60
-X-Ratelimit-Reset: 1755007969
-X-Ratelimit-Resource: core
-Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
-X-Github-Request-Id: E80A:118F3A:206DA5:1E890E:689B401E
Content-Length: 2
-Etag: "578cfdf865ccd59faa414c655476c87af814e220755c938b9545967521b6f14b"
-X-Accepted-Oauth-Scopes:
-Github-Authentication-Token-Expiration: 2025-09-11 10:37:11 UTC
Access-Control-Allow-Origin: *
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+Content-Security-Policy: default-src 'none'
+X-Github-Request-Id: C7CC:3118FC:3F60858:4037116:6729E6B9
+Cache-Control: private, max-age=60, s-maxage=60
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Oauth-Scopes:
+X-Ratelimit-Used: 86
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
[]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%3Fdirection=asc&page=1&per_page=2&sort=created&state=all b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%3Fdirection=asc&page=1&per_page=2&sort=created&state=all
new file mode 100644
index 0000000000..80d2f90dbc
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%3Fdirection=asc&page=1&per_page=2&sort=created&state=all
@@ -0,0 +1,25 @@
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+Content-Type: application/json; charset=utf-8
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Ratelimit-Limit: 5000
+X-Ratelimit-Resource: core
+Access-Control-Allow-Origin: *
+X-Frame-Options: deny
+X-Xss-Protection: 0
+Cache-Control: private, max-age=60, s-maxage=60
+Etag: W/"40580a89c26a3f7793cea4e59315e52e1106be32ded27b3ab822b7d7f74a1ecf"
+X-Github-Media-Type: github.v3; param=squirrel-girl-preview
+Link: ; rel="next", ; rel="last"
+X-Ratelimit-Reset: 1730800941
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+X-Content-Type-Options: nosniff
+X-Oauth-Scopes:
+X-Accepted-Oauth-Scopes: repo
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Remaining: 4924
+X-Ratelimit-Used: 76
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+Content-Security-Policy: default-src 'none'
+X-Github-Request-Id: C7CC:3118FC:3F5F5B9:4035E6C:6729E6B5
+
+[{"url":"https://api.github.com/repos/go-gitea/test_repo/issues/1","repository_url":"https://api.github.com/repos/go-gitea/test_repo","labels_url":"https://api.github.com/repos/go-gitea/test_repo/issues/1/labels{/name}","comments_url":"https://api.github.com/repos/go-gitea/test_repo/issues/1/comments","events_url":"https://api.github.com/repos/go-gitea/test_repo/issues/1/events","html_url":"https://github.com/go-gitea/test_repo/issues/1","id":520479843,"node_id":"MDU6SXNzdWU1MjA0Nzk4NDM=","number":1,"title":"Please add an animated gif icon to the merge button","user":{"login":"guillep2k","id":18600385,"node_id":"MDQ6VXNlcjE4NjAwMzg1","avatar_url":"https://avatars.githubusercontent.com/u/18600385?v=4","gravatar_id":"","url":"https://api.github.com/users/guillep2k","html_url":"https://github.com/guillep2k","followers_url":"https://api.github.com/users/guillep2k/followers","following_url":"https://api.github.com/users/guillep2k/following{/other_user}","gists_url":"https://api.github.com/users/guillep2k/gists{/gist_id}","starred_url":"https://api.github.com/users/guillep2k/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/guillep2k/subscriptions","organizations_url":"https://api.github.com/users/guillep2k/orgs","repos_url":"https://api.github.com/users/guillep2k/repos","events_url":"https://api.github.com/users/guillep2k/events{/privacy}","received_events_url":"https://api.github.com/users/guillep2k/received_events","type":"User","user_view_type":"public","site_admin":false},"labels":[{"id":1667254252,"node_id":"MDU6TGFiZWwxNjY3MjU0MjUy","url":"https://api.github.com/repos/go-gitea/test_repo/labels/bug","name":"bug","color":"d73a4a","default":true,"description":"Something isn't working"},{"id":1667254261,"node_id":"MDU6TGFiZWwxNjY3MjU0MjYx","url":"https://api.github.com/repos/go-gitea/test_repo/labels/good%20first%20issue","name":"good first issue","color":"7057ff","default":true,"description":"Good for newcomers"}],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":{"url":"https://api.github.com/repos/go-gitea/test_repo/milestones/1","html_url":"https://github.com/go-gitea/test_repo/milestone/1","labels_url":"https://api.github.com/repos/go-gitea/test_repo/milestones/1/labels","id":4839941,"node_id":"MDk6TWlsZXN0b25lNDgzOTk0MQ==","number":1,"title":"1.0.0","description":"Milestone 1.0.0","creator":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"open_issues":1,"closed_issues":1,"state":"closed","created_at":"2019-11-12T19:37:08Z","updated_at":"2019-11-12T21:56:17Z","due_on":"2019-11-11T08:00:00Z","closed_at":"2019-11-12T19:45:49Z"},"comments":0,"created_at":"2019-11-09T17:00:29Z","updated_at":"2019-11-12T20:29:53Z","closed_at":"2019-11-12T20:22:22Z","author_association":"MEMBER","active_lock_reason":null,"body":"I just want the merge button to hurt my eyes a little. 😠","closed_by":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"reactions":{"url":"https://api.github.com/repos/go-gitea/test_repo/issues/1/reactions","total_count":1,"+1":1,"-1":0,"laugh":0,"hooray":0,"confused":0,"heart":0,"rocket":0,"eyes":0},"timeline_url":"https://api.github.com/repos/go-gitea/test_repo/issues/1/timeline","performed_via_github_app":null,"state_reason":"completed"},{"url":"https://api.github.com/repos/go-gitea/test_repo/issues/2","repository_url":"https://api.github.com/repos/go-gitea/test_repo","labels_url":"https://api.github.com/repos/go-gitea/test_repo/issues/2/labels{/name}","comments_url":"https://api.github.com/repos/go-gitea/test_repo/issues/2/comments","events_url":"https://api.github.com/repos/go-gitea/test_repo/issues/2/events","html_url":"https://github.com/go-gitea/test_repo/issues/2","id":521799485,"node_id":"MDU6SXNzdWU1MjE3OTk0ODU=","number":2,"title":"Test issue","user":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"labels":[{"id":1667254257,"node_id":"MDU6TGFiZWwxNjY3MjU0MjU3","url":"https://api.github.com/repos/go-gitea/test_repo/labels/duplicate","name":"duplicate","color":"cfd3d7","default":true,"description":"This issue or pull request already exists"}],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":{"url":"https://api.github.com/repos/go-gitea/test_repo/milestones/2","html_url":"https://github.com/go-gitea/test_repo/milestone/2","labels_url":"https://api.github.com/repos/go-gitea/test_repo/milestones/2/labels","id":4839942,"node_id":"MDk6TWlsZXN0b25lNDgzOTk0Mg==","number":2,"title":"1.1.0","description":"Milestone 1.1.0","creator":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"open_issues":0,"closed_issues":2,"state":"closed","created_at":"2019-11-12T19:37:25Z","updated_at":"2019-11-12T21:39:27Z","due_on":"2019-11-12T08:00:00Z","closed_at":"2019-11-12T19:45:46Z"},"comments":2,"created_at":"2019-11-12T21:00:06Z","updated_at":"2019-11-12T22:07:14Z","closed_at":"2019-11-12T21:01:31Z","author_association":"MEMBER","active_lock_reason":null,"body":"This is test issue 2, do not touch!","closed_by":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"reactions":{"url":"https://api.github.com/repos/go-gitea/test_repo/issues/2/reactions","total_count":6,"+1":1,"-1":1,"laugh":1,"hooray":1,"confused":1,"heart":1,"rocket":0,"eyes":0},"timeline_url":"https://api.github.com/repos/go-gitea/test_repo/issues/2/timeline","performed_via_github_app":null,"state_reason":"completed"}]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Flabels%3Fpage=1&per_page=100 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Flabels%3Fpage=1&per_page=100
new file mode 100644
index 0000000000..f1d483aacb
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Flabels%3Fpage=1&per_page=100
@@ -0,0 +1,24 @@
+X-Ratelimit-Reset: 1730800941
+Access-Control-Allow-Origin: *
+Content-Security-Policy: default-src 'none'
+X-Github-Api-Version-Selected: 2022-11-28
+Etag: W/"01cc307b238564f2a086999fed53e0d5c880b8ec1d8d2256d99188ff47ff0ea0"
+X-Github-Media-Type: github.v3; format=json
+X-Ratelimit-Used: 74
+X-Ratelimit-Resource: core
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+X-Ratelimit-Limit: 5000
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+X-Xss-Protection: 0
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+Cache-Control: private, max-age=60, s-maxage=60
+X-Oauth-Scopes:
+X-Accepted-Oauth-Scopes: repo
+X-Ratelimit-Remaining: 4926
+X-Frame-Options: deny
+X-Content-Type-Options: nosniff
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+Content-Type: application/json; charset=utf-8
+X-Github-Request-Id: C7CC:3118FC:3F5F29C:4035B65:6729E6B4
+
+[{"id":1667254252,"node_id":"MDU6TGFiZWwxNjY3MjU0MjUy","url":"https://api.github.com/repos/go-gitea/test_repo/labels/bug","name":"bug","color":"d73a4a","default":true,"description":"Something isn't working"},{"id":1667254254,"node_id":"MDU6TGFiZWwxNjY3MjU0MjU0","url":"https://api.github.com/repos/go-gitea/test_repo/labels/documentation","name":"documentation","color":"0075ca","default":true,"description":"Improvements or additions to documentation"},{"id":1667254257,"node_id":"MDU6TGFiZWwxNjY3MjU0MjU3","url":"https://api.github.com/repos/go-gitea/test_repo/labels/duplicate","name":"duplicate","color":"cfd3d7","default":true,"description":"This issue or pull request already exists"},{"id":1667254260,"node_id":"MDU6TGFiZWwxNjY3MjU0MjYw","url":"https://api.github.com/repos/go-gitea/test_repo/labels/enhancement","name":"enhancement","color":"a2eeef","default":true,"description":"New feature or request"},{"id":1667254261,"node_id":"MDU6TGFiZWwxNjY3MjU0MjYx","url":"https://api.github.com/repos/go-gitea/test_repo/labels/good%20first%20issue","name":"good first issue","color":"7057ff","default":true,"description":"Good for newcomers"},{"id":1667254265,"node_id":"MDU6TGFiZWwxNjY3MjU0MjY1","url":"https://api.github.com/repos/go-gitea/test_repo/labels/help%20wanted","name":"help wanted","color":"008672","default":true,"description":"Extra attention is needed"},{"id":1667254269,"node_id":"MDU6TGFiZWwxNjY3MjU0MjY5","url":"https://api.github.com/repos/go-gitea/test_repo/labels/invalid","name":"invalid","color":"e4e669","default":true,"description":"This doesn't seem right"},{"id":1667254273,"node_id":"MDU6TGFiZWwxNjY3MjU0Mjcz","url":"https://api.github.com/repos/go-gitea/test_repo/labels/question","name":"question","color":"d876e3","default":true,"description":"Further information is requested"},{"id":1667254276,"node_id":"MDU6TGFiZWwxNjY3MjU0Mjc2","url":"https://api.github.com/repos/go-gitea/test_repo/labels/wontfix","name":"wontfix","color":"ffffff","default":true,"description":"This will not be worked on"}]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fmilestones%3Fpage=1&per_page=100&state=all b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fmilestones%3Fpage=1&per_page=100&state=all
new file mode 100644
index 0000000000..50b90ad4ab
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fmilestones%3Fpage=1&per_page=100&state=all
@@ -0,0 +1,24 @@
+X-Ratelimit-Remaining: 4927
+X-Ratelimit-Used: 73
+X-Frame-Options: deny
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Oauth-Scopes:
+X-Accepted-Oauth-Scopes: repo
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+Access-Control-Allow-Origin: *
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+X-Content-Type-Options: nosniff
+Content-Type: application/json; charset=utf-8
+X-Ratelimit-Limit: 5000
+X-Ratelimit-Resource: core
+X-Github-Request-Id: C7CC:3118FC:3F5F16C:40359F7:6729E6B4
+X-Github-Media-Type: github.v3; format=json
+X-Ratelimit-Reset: 1730800941
+Content-Security-Policy: default-src 'none'
+X-Github-Api-Version-Selected: 2022-11-28
+X-Xss-Protection: 0
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+Cache-Control: private, max-age=60, s-maxage=60
+Etag: W/"d6d673f0622636217ee3df16cdabbfea8402d3e8d1abbabe007108267b01f3e9"
+
+[{"url":"https://api.github.com/repos/go-gitea/test_repo/milestones/1","html_url":"https://github.com/go-gitea/test_repo/milestone/1","labels_url":"https://api.github.com/repos/go-gitea/test_repo/milestones/1/labels","id":4839941,"node_id":"MDk6TWlsZXN0b25lNDgzOTk0MQ==","number":1,"title":"1.0.0","description":"Milestone 1.0.0","creator":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"open_issues":1,"closed_issues":1,"state":"closed","created_at":"2019-11-12T19:37:08Z","updated_at":"2019-11-12T21:56:17Z","due_on":"2019-11-11T08:00:00Z","closed_at":"2019-11-12T19:45:49Z"},{"url":"https://api.github.com/repos/go-gitea/test_repo/milestones/2","html_url":"https://github.com/go-gitea/test_repo/milestone/2","labels_url":"https://api.github.com/repos/go-gitea/test_repo/milestones/2/labels","id":4839942,"node_id":"MDk6TWlsZXN0b25lNDgzOTk0Mg==","number":2,"title":"1.1.0","description":"Milestone 1.1.0","creator":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"open_issues":0,"closed_issues":2,"state":"closed","created_at":"2019-11-12T19:37:25Z","updated_at":"2019-11-12T21:39:27Z","due_on":"2019-11-12T08:00:00Z","closed_at":"2019-11-12T19:45:46Z"}]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fpulls%2F7%2Frequested_reviewers%3Fper_page=100 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F3%2Frequested_reviewers%3Fper_page=100
similarity index 75%
rename from services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fpulls%2F7%2Frequested_reviewers%3Fper_page=100
rename to services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F3%2Frequested_reviewers%3Fper_page=100
index f3bef5c3bd..1b4481f890 100644
--- a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fpulls%2F7%2Frequested_reviewers%3Fper_page=100
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F3%2Frequested_reviewers%3Fper_page=100
@@ -1,25 +1,24 @@
-X-Ratelimit-Remaining: 4958
-X-Content-Type-Options: nosniff
-Content-Security-Policy: default-src 'none'
-X-Oauth-Scopes: public_repo, repo:status
-X-Accepted-Oauth-Scopes:
-Github-Authentication-Token-Expiration: 2025-09-11 10:37:11 UTC
-X-Github-Media-Type: github.v3; format=json
-X-Github-Api-Version-Selected: 2022-11-28
-X-Ratelimit-Reset: 1755007969
-X-Ratelimit-Used: 42
-X-Ratelimit-Resource: core
-Etag: W/"bf72ef7e37aa7c7a418e89035db9d7f23b969af0705f1e9c7ee692aad6c272f7"
-Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
-Access-Control-Allow-Origin: *
-Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
-X-Frame-Options: deny
-X-Xss-Protection: 0
Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
-Cache-Control: private, max-age=60, s-maxage=60
-X-Github-Request-Id: F852:1553BC:10F18A:FD450:689B3DFF
-Content-Type: application/json; charset=utf-8
+Etag: W/"21730161122bd4f229e886dd4a85b45fa575182d6dcef7aa0016a5d21353c9ab"
+X-Oauth-Scopes:
+X-Github-Media-Type: github.v3; format=json
+Access-Control-Allow-Origin: *
+X-Frame-Options: deny
+X-Content-Type-Options: nosniff
+X-Xss-Protection: 0
+X-Github-Request-Id: C7CC:3118FC:3F6187A:4038171:6729E6BD
Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Github-Api-Version-Selected: 2022-11-28
X-Ratelimit-Limit: 5000
+X-Ratelimit-Resource: core
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+Content-Security-Policy: default-src 'none'
+Content-Type: application/json; charset=utf-8
+Cache-Control: private, max-age=60, s-maxage=60
+X-Accepted-Oauth-Scopes:
+X-Ratelimit-Remaining: 4905
+X-Ratelimit-Reset: 1730800941
+X-Ratelimit-Used: 95
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
{"users":[],"teams":[]}
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fpulls%2F7%2Freviews%3Fper_page=100 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F3%2Freviews%2F315859956%2Fcomments%3Fper_page=100
similarity index 75%
rename from services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fpulls%2F7%2Freviews%3Fper_page=100
rename to services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F3%2Freviews%2F315859956%2Fcomments%3Fper_page=100
index fea2907aa4..435e1a0ee0 100644
--- a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fpulls%2F7%2Freviews%3Fper_page=100
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F3%2Freviews%2F315859956%2Fcomments%3Fper_page=100
@@ -1,26 +1,25 @@
-X-Xss-Protection: 0
-Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
-X-Oauth-Scopes: public_repo, repo:status
-Github-Authentication-Token-Expiration: 2025-09-11 10:37:11 UTC
-X-Github-Media-Type: github.v3; format=json
-Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
-X-Github-Request-Id: F852:1553BC:10EEC0:FD190:689B3DFE
-Content-Type: application/json; charset=utf-8
Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Github-Media-Type: github.v3; format=json
+X-Ratelimit-Used: 92
X-Frame-Options: deny
-Content-Security-Policy: default-src 'none'
+X-Content-Type-Options: nosniff
Content-Length: 2
-X-Accepted-Oauth-Scopes:
+X-Oauth-Scopes:
+X-Ratelimit-Remaining: 4908
+X-Ratelimit-Reset: 1730800941
+X-Github-Request-Id: C7CC:3118FC:3F612D6:4037BAC:6729E6BC
+Etag: "450a1c087fec81e5b86092ff5372c3db8ca834c1e23c03c6b06ecca33cefd665"
X-Github-Api-Version-Selected: 2022-11-28
X-Ratelimit-Limit: 5000
-X-Ratelimit-Remaining: 4959
-X-Ratelimit-Used: 41
X-Ratelimit-Resource: core
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
Access-Control-Allow-Origin: *
Cache-Control: private, max-age=60, s-maxage=60
-Etag: "bb321a3b596949885b60e203a5ea335475c7ac9e2364d10f463cb934490c25a5"
-X-Ratelimit-Reset: 1755007969
+X-Accepted-Oauth-Scopes:
Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
-X-Content-Type-Options: nosniff
+X-Xss-Protection: 0
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+Content-Security-Policy: default-src 'none'
+Content-Type: application/json; charset=utf-8
[]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F3%2Freviews%2F315860062%2Fcomments%3Fper_page=100 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F3%2Freviews%2F315860062%2Fcomments%3Fper_page=100
new file mode 100644
index 0000000000..389c1b7567
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F3%2Freviews%2F315860062%2Fcomments%3Fper_page=100
@@ -0,0 +1,25 @@
+Content-Length: 2
+X-Frame-Options: deny
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Limit: 5000
+X-Ratelimit-Used: 93
+X-Ratelimit-Resource: core
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+Content-Type: application/json; charset=utf-8
+X-Accepted-Oauth-Scopes:
+X-Xss-Protection: 0
+X-Oauth-Scopes:
+X-Ratelimit-Remaining: 4907
+X-Ratelimit-Reset: 1730800941
+Access-Control-Allow-Origin: *
+X-Content-Type-Options: nosniff
+Content-Security-Policy: default-src 'none'
+Cache-Control: private, max-age=60, s-maxage=60
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Github-Request-Id: C7CC:3118FC:3F614AA:4037DB7:6729E6BD
+X-Github-Media-Type: github.v3; format=json
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+Etag: "450a1c087fec81e5b86092ff5372c3db8ca834c1e23c03c6b06ecca33cefd665"
+
+[]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F3%2Freviews%2F315861440%2Fcomments%3Fper_page=100 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F3%2Freviews%2F315861440%2Fcomments%3Fper_page=100
new file mode 100644
index 0000000000..e52428a5af
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F3%2Freviews%2F315861440%2Fcomments%3Fper_page=100
@@ -0,0 +1,25 @@
+Content-Type: application/json; charset=utf-8
+Cache-Control: private, max-age=60, s-maxage=60
+X-Ratelimit-Reset: 1730800941
+X-Content-Type-Options: nosniff
+Content-Security-Policy: default-src 'none'
+X-Accepted-Oauth-Scopes:
+X-Xss-Protection: 0
+X-Github-Request-Id: C7CC:3118FC:3F61690:4037F90:6729E6BD
+Content-Length: 2
+X-Oauth-Scopes:
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Limit: 5000
+X-Frame-Options: deny
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+Access-Control-Allow-Origin: *
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+Etag: "450a1c087fec81e5b86092ff5372c3db8ca834c1e23c03c6b06ecca33cefd665"
+X-Github-Media-Type: github.v3; format=json
+X-Ratelimit-Remaining: 4906
+X-Ratelimit-Used: 94
+X-Ratelimit-Resource: core
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+
+[]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F3%2Freviews%3Fper_page=100 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F3%2Freviews%3Fper_page=100
new file mode 100644
index 0000000000..203c363ffa
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F3%2Freviews%3Fper_page=100
@@ -0,0 +1,24 @@
+Cache-Control: private, max-age=60, s-maxage=60
+Etag: W/"e38ac3d6f3e77a469f9836bfa52a0b756b9ac8fdc4347530e1cb1072bbb77b46"
+X-Github-Media-Type: github.v3; format=json
+X-Frame-Options: deny
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+Access-Control-Allow-Origin: *
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Accepted-Oauth-Scopes:
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Remaining: 4909
+X-Ratelimit-Reset: 1730800941
+Content-Security-Policy: default-src 'none'
+X-Github-Request-Id: C7CC:3118FC:3F6108F:403797A:6729E6BC
+Content-Type: application/json; charset=utf-8
+X-Ratelimit-Limit: 5000
+X-Ratelimit-Resource: core
+X-Content-Type-Options: nosniff
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+X-Oauth-Scopes:
+X-Ratelimit-Used: 91
+X-Xss-Protection: 0
+
+[{"id":315859956,"node_id":"MDE3OlB1bGxSZXF1ZXN0UmV2aWV3MzE1ODU5OTU2","user":{"login":"jolheiser","id":42128690,"node_id":"MDQ6VXNlcjQyMTI4Njkw","avatar_url":"https://avatars.githubusercontent.com/u/42128690?u=0ee1052506846129445fa12a76cd9ad9d305de71&v=4","gravatar_id":"","url":"https://api.github.com/users/jolheiser","html_url":"https://github.com/jolheiser","followers_url":"https://api.github.com/users/jolheiser/followers","following_url":"https://api.github.com/users/jolheiser/following{/other_user}","gists_url":"https://api.github.com/users/jolheiser/gists{/gist_id}","starred_url":"https://api.github.com/users/jolheiser/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jolheiser/subscriptions","organizations_url":"https://api.github.com/users/jolheiser/orgs","repos_url":"https://api.github.com/users/jolheiser/repos","events_url":"https://api.github.com/users/jolheiser/events{/privacy}","received_events_url":"https://api.github.com/users/jolheiser/received_events","type":"User","user_view_type":"public","site_admin":false},"body":"","state":"APPROVED","html_url":"https://github.com/go-gitea/test_repo/pull/3#pullrequestreview-315859956","pull_request_url":"https://api.github.com/repos/go-gitea/test_repo/pulls/3","author_association":"MEMBER","_links":{"html":{"href":"https://github.com/go-gitea/test_repo/pull/3#pullrequestreview-315859956"},"pull_request":{"href":"https://api.github.com/repos/go-gitea/test_repo/pulls/3"}},"submitted_at":"2019-11-12T21:35:24Z","commit_id":"076160cf0b039f13e5eff19619932d181269414b"},{"id":315860062,"node_id":"MDE3OlB1bGxSZXF1ZXN0UmV2aWV3MzE1ODYwMDYy","user":{"login":"zeripath","id":1824502,"node_id":"MDQ6VXNlcjE4MjQ1MDI=","avatar_url":"https://avatars.githubusercontent.com/u/1824502?u=fcd8a9dba8714edf6ac3f87596eb72149911c720&v=4","gravatar_id":"","url":"https://api.github.com/users/zeripath","html_url":"https://github.com/zeripath","followers_url":"https://api.github.com/users/zeripath/followers","following_url":"https://api.github.com/users/zeripath/following{/other_user}","gists_url":"https://api.github.com/users/zeripath/gists{/gist_id}","starred_url":"https://api.github.com/users/zeripath/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zeripath/subscriptions","organizations_url":"https://api.github.com/users/zeripath/orgs","repos_url":"https://api.github.com/users/zeripath/repos","events_url":"https://api.github.com/users/zeripath/events{/privacy}","received_events_url":"https://api.github.com/users/zeripath/received_events","type":"User","user_view_type":"public","site_admin":false},"body":"","state":"APPROVED","html_url":"https://github.com/go-gitea/test_repo/pull/3#pullrequestreview-315860062","pull_request_url":"https://api.github.com/repos/go-gitea/test_repo/pulls/3","author_association":"NONE","_links":{"html":{"href":"https://github.com/go-gitea/test_repo/pull/3#pullrequestreview-315860062"},"pull_request":{"href":"https://api.github.com/repos/go-gitea/test_repo/pulls/3"}},"submitted_at":"2019-11-12T21:35:36Z","commit_id":"076160cf0b039f13e5eff19619932d181269414b"},{"id":315861440,"node_id":"MDE3OlB1bGxSZXF1ZXN0UmV2aWV3MzE1ODYxNDQw","user":{"login":"lafriks","id":165205,"node_id":"MDQ6VXNlcjE2NTIwNQ==","avatar_url":"https://avatars.githubusercontent.com/u/165205?u=efe2335d2197f524c25caa7abdfcb90b77eb8d98&v=4","gravatar_id":"","url":"https://api.github.com/users/lafriks","html_url":"https://github.com/lafriks","followers_url":"https://api.github.com/users/lafriks/followers","following_url":"https://api.github.com/users/lafriks/following{/other_user}","gists_url":"https://api.github.com/users/lafriks/gists{/gist_id}","starred_url":"https://api.github.com/users/lafriks/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lafriks/subscriptions","organizations_url":"https://api.github.com/users/lafriks/orgs","repos_url":"https://api.github.com/users/lafriks/repos","events_url":"https://api.github.com/users/lafriks/events{/privacy}","received_events_url":"https://api.github.com/users/lafriks/received_events","type":"User","user_view_type":"public","site_admin":false},"body":"","state":"APPROVED","html_url":"https://github.com/go-gitea/test_repo/pull/3#pullrequestreview-315861440","pull_request_url":"https://api.github.com/repos/go-gitea/test_repo/pulls/3","author_association":"MEMBER","_links":{"html":{"href":"https://github.com/go-gitea/test_repo/pull/3#pullrequestreview-315861440"},"pull_request":{"href":"https://api.github.com/repos/go-gitea/test_repo/pulls/3"}},"submitted_at":"2019-11-12T21:38:00Z","commit_id":"076160cf0b039f13e5eff19619932d181269414b"}]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fpulls%2F3%2Frequested_reviewers%3Fper_page=100 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F4%2Frequested_reviewers%3Fper_page=100
similarity index 75%
rename from services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fpulls%2F3%2Frequested_reviewers%3Fper_page=100
rename to services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F4%2Frequested_reviewers%3Fper_page=100
index 5d382a0ed1..676e326094 100644
--- a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fpulls%2F3%2Frequested_reviewers%3Fper_page=100
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F4%2Frequested_reviewers%3Fper_page=100
@@ -1,25 +1,24 @@
-Content-Type: application/json; charset=utf-8
-X-Oauth-Scopes: public_repo, repo:status
-Access-Control-Allow-Origin: *
-Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
-Content-Security-Policy: default-src 'none'
-Cache-Control: private, max-age=60, s-maxage=60
-X-Accepted-Oauth-Scopes:
-Github-Authentication-Token-Expiration: 2025-09-11 10:37:11 UTC
-X-Github-Api-Version-Selected: 2022-11-28
-X-Ratelimit-Resource: core
-Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
-X-Frame-Options: deny
-X-Content-Type-Options: nosniff
Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
-X-Github-Media-Type: github.v3; format=json
+X-Oauth-Scopes:
X-Ratelimit-Limit: 5000
-X-Ratelimit-Remaining: 4863
-X-Ratelimit-Reset: 1755007969
-X-Ratelimit-Used: 137
+X-Ratelimit-Remaining: 4898
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
X-Xss-Protection: 0
Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
-Etag: W/"bf72ef7e37aa7c7a418e89035db9d7f23b969af0705f1e9c7ee692aad6c272f7"
-X-Github-Request-Id: E80A:118F3A:208A8A:1EA3C0:689B4023
+Content-Security-Policy: default-src 'none'
+X-Github-Request-Id: C7CC:3118FC:3F623DF:4038CEB:6729E6C0
+Etag: W/"21730161122bd4f229e886dd4a85b45fa575182d6dcef7aa0016a5d21353c9ab"
+X-Accepted-Oauth-Scopes:
+X-Github-Media-Type: github.v3; format=json
+X-Ratelimit-Resource: core
+Access-Control-Allow-Origin: *
+X-Frame-Options: deny
+Content-Type: application/json; charset=utf-8
+Cache-Control: private, max-age=60, s-maxage=60
+X-Ratelimit-Used: 102
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Reset: 1730800941
+X-Content-Type-Options: nosniff
{"users":[],"teams":[]}
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F4%2Freviews%2F338338740%2Fcomments%3Fper_page=100 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F4%2Freviews%2F338338740%2Fcomments%3Fper_page=100
new file mode 100644
index 0000000000..48e5b2c3d9
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F4%2Freviews%2F338338740%2Fcomments%3Fper_page=100
@@ -0,0 +1,24 @@
+Access-Control-Allow-Origin: *
+X-Content-Type-Options: nosniff
+Content-Security-Policy: default-src 'none'
+X-Ratelimit-Resource: core
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Accepted-Oauth-Scopes:
+X-Github-Media-Type: github.v3; format=json
+X-Ratelimit-Remaining: 4903
+X-Ratelimit-Reset: 1730800941
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+X-Frame-Options: deny
+X-Github-Request-Id: C7CC:3118FC:3F61BAA:40384A5:6729E6BE
+Cache-Control: private, max-age=60, s-maxage=60
+Etag: W/"ff77892df2ec7f6eb61416e0f384ce0a6e8fbbbc1287f5d09b1980ebe9856750"
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Limit: 5000
+X-Ratelimit-Used: 97
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+Content-Type: application/json; charset=utf-8
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+X-Xss-Protection: 0
+X-Oauth-Scopes:
+
+[{"id":363017488,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDM2MzAxNzQ4OA==","url":"https://api.github.com/repos/go-gitea/test_repo/pulls/comments/363017488","pull_request_review_id":338338740,"diff_hunk":"@@ -1,2 +1,4 @@\n # test_repo\n Test repository for testing migration from github to gitea\n+","path":"README.md","position":3,"original_position":3,"commit_id":"2be9101c543658591222acbee3eb799edfc3853d","user":{"login":"lunny","id":81045,"node_id":"MDQ6VXNlcjgxMDQ1","avatar_url":"https://avatars.githubusercontent.com/u/81045?u=99b64f0ca6ef63643c7583ab87dd31c52d28e673&v=4","gravatar_id":"","url":"https://api.github.com/users/lunny","html_url":"https://github.com/lunny","followers_url":"https://api.github.com/users/lunny/followers","following_url":"https://api.github.com/users/lunny/following{/other_user}","gists_url":"https://api.github.com/users/lunny/gists{/gist_id}","starred_url":"https://api.github.com/users/lunny/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lunny/subscriptions","organizations_url":"https://api.github.com/users/lunny/orgs","repos_url":"https://api.github.com/users/lunny/repos","events_url":"https://api.github.com/users/lunny/events{/privacy}","received_events_url":"https://api.github.com/users/lunny/received_events","type":"User","user_view_type":"public","site_admin":false},"body":"This is a good pull request.","created_at":"2020-01-04T05:33:06Z","updated_at":"2020-01-04T05:33:18Z","html_url":"https://github.com/go-gitea/test_repo/pull/4#discussion_r363017488","pull_request_url":"https://api.github.com/repos/go-gitea/test_repo/pulls/4","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/go-gitea/test_repo/pulls/comments/363017488"},"html":{"href":"https://github.com/go-gitea/test_repo/pull/4#discussion_r363017488"},"pull_request":{"href":"https://api.github.com/repos/go-gitea/test_repo/pulls/4"}},"original_commit_id":"2be9101c543658591222acbee3eb799edfc3853d","reactions":{"url":"https://api.github.com/repos/go-gitea/test_repo/pulls/comments/363017488/reactions","total_count":0,"+1":0,"-1":0,"laugh":0,"hooray":0,"confused":0,"heart":0,"rocket":0,"eyes":0}}]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F4%2Freviews%2F338339651%2Fcomments%3Fper_page=100 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F4%2Freviews%2F338339651%2Fcomments%3Fper_page=100
new file mode 100644
index 0000000000..4cc66424f0
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F4%2Freviews%2F338339651%2Fcomments%3Fper_page=100
@@ -0,0 +1,25 @@
+X-Github-Api-Version-Selected: 2022-11-28
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+X-Frame-Options: deny
+X-Content-Type-Options: nosniff
+Cache-Control: private, max-age=60, s-maxage=60
+Etag: "450a1c087fec81e5b86092ff5372c3db8ca834c1e23c03c6b06ecca33cefd665"
+X-Github-Media-Type: github.v3; format=json
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+X-Ratelimit-Reset: 1730800941
+X-Xss-Protection: 0
+X-Oauth-Scopes:
+X-Accepted-Oauth-Scopes:
+X-Ratelimit-Limit: 5000
+Access-Control-Allow-Origin: *
+Content-Length: 2
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Ratelimit-Resource: core
+Content-Security-Policy: default-src 'none'
+X-Github-Request-Id: C7CC:3118FC:3F61EBA:40387A6:6729E6BF
+Content-Type: application/json; charset=utf-8
+X-Ratelimit-Remaining: 4901
+X-Ratelimit-Used: 99
+
+[]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F4%2Freviews%2F338349019%2Fcomments%3Fper_page=100 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F4%2Freviews%2F338349019%2Fcomments%3Fper_page=100
new file mode 100644
index 0000000000..f13d4addc7
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F4%2Freviews%2F338349019%2Fcomments%3Fper_page=100
@@ -0,0 +1,24 @@
+Etag: W/"f74a383d4c87ae26d218fc087bef2c41a12637dff81fd8642f59708adca1a14e"
+X-Ratelimit-Remaining: 4900
+X-Content-Type-Options: nosniff
+X-Ratelimit-Limit: 5000
+X-Ratelimit-Reset: 1730800941
+X-Xss-Protection: 0
+Content-Type: application/json; charset=utf-8
+X-Oauth-Scopes:
+X-Accepted-Oauth-Scopes:
+X-Github-Api-Version-Selected: 2022-11-28
+Access-Control-Allow-Origin: *
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+X-Frame-Options: deny
+X-Github-Media-Type: github.v3; format=json
+X-Ratelimit-Used: 100
+X-Ratelimit-Resource: core
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+X-Github-Request-Id: C7CC:3118FC:3F62065:4038955:6729E6C0
+Content-Security-Policy: default-src 'none'
+Cache-Control: private, max-age=60, s-maxage=60
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+
+[{"id":363029944,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDM2MzAyOTk0NA==","url":"https://api.github.com/repos/go-gitea/test_repo/pulls/comments/363029944","pull_request_review_id":338349019,"diff_hunk":"@@ -19,3 +19,5 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n SOFTWARE.\n+","path":"LICENSE","position":4,"original_position":4,"commit_id":"2be9101c543658591222acbee3eb799edfc3853d","user":{"login":"lunny","id":81045,"node_id":"MDQ6VXNlcjgxMDQ1","avatar_url":"https://avatars.githubusercontent.com/u/81045?u=99b64f0ca6ef63643c7583ab87dd31c52d28e673&v=4","gravatar_id":"","url":"https://api.github.com/users/lunny","html_url":"https://github.com/lunny","followers_url":"https://api.github.com/users/lunny/followers","following_url":"https://api.github.com/users/lunny/following{/other_user}","gists_url":"https://api.github.com/users/lunny/gists{/gist_id}","starred_url":"https://api.github.com/users/lunny/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lunny/subscriptions","organizations_url":"https://api.github.com/users/lunny/orgs","repos_url":"https://api.github.com/users/lunny/repos","events_url":"https://api.github.com/users/lunny/events{/privacy}","received_events_url":"https://api.github.com/users/lunny/received_events","type":"User","user_view_type":"public","site_admin":false},"body":"test a single comment.","created_at":"2020-01-04T11:21:41Z","updated_at":"2020-01-04T11:21:41Z","html_url":"https://github.com/go-gitea/test_repo/pull/4#discussion_r363029944","pull_request_url":"https://api.github.com/repos/go-gitea/test_repo/pulls/4","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/go-gitea/test_repo/pulls/comments/363029944"},"html":{"href":"https://github.com/go-gitea/test_repo/pull/4#discussion_r363029944"},"pull_request":{"href":"https://api.github.com/repos/go-gitea/test_repo/pulls/4"}},"original_commit_id":"2be9101c543658591222acbee3eb799edfc3853d","reactions":{"url":"https://api.github.com/repos/go-gitea/test_repo/pulls/comments/363029944/reactions","total_count":0,"+1":0,"-1":0,"laugh":0,"hooray":0,"confused":0,"heart":0,"rocket":0,"eyes":0}}]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F4%2Freviews%3Fper_page=100 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F4%2Freviews%3Fper_page=100
new file mode 100644
index 0000000000..c4484e078a
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F4%2Freviews%3Fper_page=100
@@ -0,0 +1,24 @@
+Cache-Control: private, max-age=60, s-maxage=60
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+X-Xss-Protection: 0
+Content-Security-Policy: default-src 'none'
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Github-Media-Type: github.v3; format=json
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Reset: 1730800941
+X-Frame-Options: deny
+X-Github-Request-Id: C7CC:3118FC:3F619C6:40382C4:6729E6BE
+Access-Control-Allow-Origin: *
+X-Content-Type-Options: nosniff
+Content-Type: application/json; charset=utf-8
+X-Accepted-Oauth-Scopes:
+X-Ratelimit-Used: 96
+X-Ratelimit-Resource: core
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+Etag: W/"a47623061be83c50d3932baf8c5961386d2d45c32c42b504122c9a1359efd515"
+X-Oauth-Scopes:
+X-Ratelimit-Limit: 5000
+X-Ratelimit-Remaining: 4904
+
+[{"id":338338740,"node_id":"MDE3OlB1bGxSZXF1ZXN0UmV2aWV3MzM4MzM4NzQw","user":{"login":"lunny","id":81045,"node_id":"MDQ6VXNlcjgxMDQ1","avatar_url":"https://avatars.githubusercontent.com/u/81045?u=99b64f0ca6ef63643c7583ab87dd31c52d28e673&v=4","gravatar_id":"","url":"https://api.github.com/users/lunny","html_url":"https://github.com/lunny","followers_url":"https://api.github.com/users/lunny/followers","following_url":"https://api.github.com/users/lunny/following{/other_user}","gists_url":"https://api.github.com/users/lunny/gists{/gist_id}","starred_url":"https://api.github.com/users/lunny/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lunny/subscriptions","organizations_url":"https://api.github.com/users/lunny/orgs","repos_url":"https://api.github.com/users/lunny/repos","events_url":"https://api.github.com/users/lunny/events{/privacy}","received_events_url":"https://api.github.com/users/lunny/received_events","type":"User","user_view_type":"public","site_admin":false},"body":"","state":"APPROVED","html_url":"https://github.com/go-gitea/test_repo/pull/4#pullrequestreview-338338740","pull_request_url":"https://api.github.com/repos/go-gitea/test_repo/pulls/4","author_association":"MEMBER","_links":{"html":{"href":"https://github.com/go-gitea/test_repo/pull/4#pullrequestreview-338338740"},"pull_request":{"href":"https://api.github.com/repos/go-gitea/test_repo/pulls/4"}},"submitted_at":"2020-01-04T05:33:18Z","commit_id":"2be9101c543658591222acbee3eb799edfc3853d"},{"id":338339651,"node_id":"MDE3OlB1bGxSZXF1ZXN0UmV2aWV3MzM4MzM5NjUx","user":{"login":"lunny","id":81045,"node_id":"MDQ6VXNlcjgxMDQ1","avatar_url":"https://avatars.githubusercontent.com/u/81045?u=99b64f0ca6ef63643c7583ab87dd31c52d28e673&v=4","gravatar_id":"","url":"https://api.github.com/users/lunny","html_url":"https://github.com/lunny","followers_url":"https://api.github.com/users/lunny/followers","following_url":"https://api.github.com/users/lunny/following{/other_user}","gists_url":"https://api.github.com/users/lunny/gists{/gist_id}","starred_url":"https://api.github.com/users/lunny/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lunny/subscriptions","organizations_url":"https://api.github.com/users/lunny/orgs","repos_url":"https://api.github.com/users/lunny/repos","events_url":"https://api.github.com/users/lunny/events{/privacy}","received_events_url":"https://api.github.com/users/lunny/received_events","type":"User","user_view_type":"public","site_admin":false},"body":"Don't add more reviews","state":"CHANGES_REQUESTED","html_url":"https://github.com/go-gitea/test_repo/pull/4#pullrequestreview-338339651","pull_request_url":"https://api.github.com/repos/go-gitea/test_repo/pulls/4","author_association":"MEMBER","_links":{"html":{"href":"https://github.com/go-gitea/test_repo/pull/4#pullrequestreview-338339651"},"pull_request":{"href":"https://api.github.com/repos/go-gitea/test_repo/pulls/4"}},"submitted_at":"2020-01-04T06:07:06Z","commit_id":"2be9101c543658591222acbee3eb799edfc3853d"},{"id":338349019,"node_id":"MDE3OlB1bGxSZXF1ZXN0UmV2aWV3MzM4MzQ5MDE5","user":{"login":"lunny","id":81045,"node_id":"MDQ6VXNlcjgxMDQ1","avatar_url":"https://avatars.githubusercontent.com/u/81045?u=99b64f0ca6ef63643c7583ab87dd31c52d28e673&v=4","gravatar_id":"","url":"https://api.github.com/users/lunny","html_url":"https://github.com/lunny","followers_url":"https://api.github.com/users/lunny/followers","following_url":"https://api.github.com/users/lunny/following{/other_user}","gists_url":"https://api.github.com/users/lunny/gists{/gist_id}","starred_url":"https://api.github.com/users/lunny/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lunny/subscriptions","organizations_url":"https://api.github.com/users/lunny/orgs","repos_url":"https://api.github.com/users/lunny/repos","events_url":"https://api.github.com/users/lunny/events{/privacy}","received_events_url":"https://api.github.com/users/lunny/received_events","type":"User","user_view_type":"public","site_admin":false},"body":"","state":"COMMENTED","html_url":"https://github.com/go-gitea/test_repo/pull/4#pullrequestreview-338349019","pull_request_url":"https://api.github.com/repos/go-gitea/test_repo/pulls/4","author_association":"MEMBER","_links":{"html":{"href":"https://github.com/go-gitea/test_repo/pull/4#pullrequestreview-338349019"},"pull_request":{"href":"https://api.github.com/repos/go-gitea/test_repo/pulls/4"}},"submitted_at":"2020-01-04T11:21:41Z","commit_id":"2be9101c543658591222acbee3eb799edfc3853d"}]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fpulls%2Fcomments%2F2260216729%2Freactions%3Fpage=1&per_page=100 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2Fcomments%2F363017488%2Freactions%3Fpage=1&per_page=100
similarity index 76%
rename from services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fpulls%2Fcomments%2F2260216729%2Freactions%3Fpage=1&per_page=100
rename to services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2Fcomments%2F363017488%2Freactions%3Fpage=1&per_page=100
index 39a6e753b9..748ae93381 100644
--- a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fpulls%2Fcomments%2F2260216729%2Freactions%3Fpage=1&per_page=100
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2Fcomments%2F363017488%2Freactions%3Fpage=1&per_page=100
@@ -1,26 +1,25 @@
-Content-Type: application/json; charset=utf-8
Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
-Github-Authentication-Token-Expiration: 2025-09-11 10:37:11 UTC
-X-Github-Api-Version-Selected: 2022-11-28
-Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
-X-Frame-Options: deny
-X-Github-Request-Id: E80A:118F3A:2082EC:1E9C92:689B4022
-Content-Length: 2
-X-Ratelimit-Remaining: 4866
-X-Ratelimit-Resource: core
-Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
-Cache-Control: private, max-age=60, s-maxage=60
-X-Oauth-Scopes: public_repo, repo:status
+Etag: "f87b0fd59e59458a9a808311324b873c6baf3fde861298a99de9986270dd4d79"
X-Accepted-Oauth-Scopes:
+X-Ratelimit-Remaining: 4902
+X-Ratelimit-Reset: 1730800941
+X-Ratelimit-Resource: core
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
X-Github-Media-Type: github.v3; param=squirrel-girl-preview
-X-Ratelimit-Limit: 5000
-X-Ratelimit-Reset: 1755007969
-X-Ratelimit-Used: 134
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
Access-Control-Allow-Origin: *
-Etag: "578cfdf865ccd59faa414c655476c87af814e220755c938b9545967521b6f14b"
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+X-Github-Request-Id: C7CC:3118FC:3F61D73:4038667:6729E6BF
+Content-Type: application/json; charset=utf-8
+X-Ratelimit-Limit: 5000
+Content-Length: 2
+Cache-Control: private, max-age=60, s-maxage=60
+X-Oauth-Scopes:
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Used: 98
+X-Frame-Options: deny
X-Content-Type-Options: nosniff
X-Xss-Protection: 0
-Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
Content-Security-Policy: default-src 'none'
[]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fpulls%2Fcomments%2F2260221159%2Freactions%3Fpage=1&per_page=100 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2Fcomments%2F363029944%2Freactions%3Fpage=1&per_page=100
similarity index 76%
rename from services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fpulls%2Fcomments%2F2260221159%2Freactions%3Fpage=1&per_page=100
rename to services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2Fcomments%2F363029944%2Freactions%3Fpage=1&per_page=100
index 1c80bb32d7..0b0ae88deb 100644
--- a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fforgejo%2Ftest_repo%2Fpulls%2Fcomments%2F2260221159%2Freactions%3Fpage=1&per_page=100
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2Fcomments%2F363029944%2Freactions%3Fpage=1&per_page=100
@@ -1,26 +1,25 @@
-X-Ratelimit-Used: 136
-X-Frame-Options: deny
+X-Accepted-Oauth-Scopes:
+X-Ratelimit-Remaining: 4899
Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
-X-Github-Request-Id: E80A:118F3A:20881D:1EA17C:689B4022
-Content-Type: application/json; charset=utf-8
-X-Github-Media-Type: github.v3; param=squirrel-girl-preview
-Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+Content-Length: 2
+X-Ratelimit-Used: 101
Access-Control-Allow-Origin: *
+X-Frame-Options: deny
+X-Content-Type-Options: nosniff
+X-Xss-Protection: 0
Content-Security-Policy: default-src 'none'
Cache-Control: private, max-age=60, s-maxage=60
-X-Oauth-Scopes: public_repo, repo:status
-Github-Authentication-Token-Expiration: 2025-09-11 10:37:11 UTC
+Etag: "f87b0fd59e59458a9a808311324b873c6baf3fde861298a99de9986270dd4d79"
+X-Oauth-Scopes:
X-Github-Api-Version-Selected: 2022-11-28
-X-Content-Type-Options: nosniff
-Content-Length: 2
-Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
-Etag: "578cfdf865ccd59faa414c655476c87af814e220755c938b9545967521b6f14b"
-X-Ratelimit-Remaining: 4864
-X-Ratelimit-Reset: 1755007969
-X-Ratelimit-Resource: core
-Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
-X-Xss-Protection: 0
-X-Accepted-Oauth-Scopes:
X-Ratelimit-Limit: 5000
+X-Ratelimit-Reset: 1730800941
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+Content-Type: application/json; charset=utf-8
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Github-Media-Type: github.v3; param=squirrel-girl-preview
+X-Ratelimit-Resource: core
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+X-Github-Request-Id: C7CC:3118FC:3F622AC:4038BA5:6729E6C0
[]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%3Fdirection=asc&page=1&per_page=2&sort=created&state=all b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%3Fdirection=asc&page=1&per_page=2&sort=created&state=all
new file mode 100644
index 0000000000..30883cc283
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%3Fdirection=asc&page=1&per_page=2&sort=created&state=all
@@ -0,0 +1,24 @@
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Used: 87
+X-Frame-Options: deny
+X-Github-Media-Type: github.v3; format=json
+X-Ratelimit-Remaining: 4913
+X-Ratelimit-Reset: 1730800941
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+Content-Security-Policy: default-src 'none'
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Oauth-Scopes:
+X-Ratelimit-Limit: 5000
+X-Ratelimit-Resource: core
+Access-Control-Allow-Origin: *
+X-Github-Request-Id: C7CC:3118FC:3F6099B:403726B:6729E6BA
+X-Xss-Protection: 0
+Content-Type: application/json; charset=utf-8
+Cache-Control: private, max-age=60, s-maxage=60
+Etag: W/"fed37ab8ce0b78e713030ff3e601f540b7f71243ab788b477f6885119bd691c5"
+X-Accepted-Oauth-Scopes:
+X-Content-Type-Options: nosniff
+
+[{"url":"https://api.github.com/repos/go-gitea/test_repo/pulls/3","id":340118745,"node_id":"MDExOlB1bGxSZXF1ZXN0MzQwMTE4NzQ1","html_url":"https://github.com/go-gitea/test_repo/pull/3","diff_url":"https://github.com/go-gitea/test_repo/pull/3.diff","patch_url":"https://github.com/go-gitea/test_repo/pull/3.patch","issue_url":"https://api.github.com/repos/go-gitea/test_repo/issues/3","number":3,"state":"closed","locked":false,"title":"Update README.md","user":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"body":"add warning to readme","created_at":"2019-11-12T21:21:43Z","updated_at":"2019-11-12T21:39:28Z","closed_at":"2019-11-12T21:39:27Z","merged_at":"2019-11-12T21:39:27Z","merge_commit_sha":"f32b0a9dfd09a60f616f29158f772cedd89942d2","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":1667254254,"node_id":"MDU6TGFiZWwxNjY3MjU0MjU0","url":"https://api.github.com/repos/go-gitea/test_repo/labels/documentation","name":"documentation","color":"0075ca","default":true,"description":"Improvements or additions to documentation"}],"milestone":{"url":"https://api.github.com/repos/go-gitea/test_repo/milestones/2","html_url":"https://github.com/go-gitea/test_repo/milestone/2","labels_url":"https://api.github.com/repos/go-gitea/test_repo/milestones/2/labels","id":4839942,"node_id":"MDk6TWlsZXN0b25lNDgzOTk0Mg==","number":2,"title":"1.1.0","description":"Milestone 1.1.0","creator":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"open_issues":0,"closed_issues":2,"state":"closed","created_at":"2019-11-12T19:37:25Z","updated_at":"2019-11-12T21:39:27Z","due_on":"2019-11-12T08:00:00Z","closed_at":"2019-11-12T19:45:46Z"},"draft":false,"commits_url":"https://api.github.com/repos/go-gitea/test_repo/pulls/3/commits","review_comments_url":"https://api.github.com/repos/go-gitea/test_repo/pulls/3/comments","review_comment_url":"https://api.github.com/repos/go-gitea/test_repo/pulls/comments{/number}","comments_url":"https://api.github.com/repos/go-gitea/test_repo/issues/3/comments","statuses_url":"https://api.github.com/repos/go-gitea/test_repo/statuses/076160cf0b039f13e5eff19619932d181269414b","head":{"label":"mrsdizzie:master","ref":"master","sha":"076160cf0b039f13e5eff19619932d181269414b","user":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"repo":{"id":221313794,"node_id":"MDEwOlJlcG9zaXRvcnkyMjEzMTM3OTQ=","name":"test_repo","full_name":"mrsdizzie/test_repo","private":false,"owner":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"html_url":"https://github.com/mrsdizzie/test_repo","description":"Test repository for testing migration from github to gitea","fork":true,"url":"https://api.github.com/repos/mrsdizzie/test_repo","forks_url":"https://api.github.com/repos/mrsdizzie/test_repo/forks","keys_url":"https://api.github.com/repos/mrsdizzie/test_repo/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mrsdizzie/test_repo/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mrsdizzie/test_repo/teams","hooks_url":"https://api.github.com/repos/mrsdizzie/test_repo/hooks","issue_events_url":"https://api.github.com/repos/mrsdizzie/test_repo/issues/events{/number}","events_url":"https://api.github.com/repos/mrsdizzie/test_repo/events","assignees_url":"https://api.github.com/repos/mrsdizzie/test_repo/assignees{/user}","branches_url":"https://api.github.com/repos/mrsdizzie/test_repo/branches{/branch}","tags_url":"https://api.github.com/repos/mrsdizzie/test_repo/tags","blobs_url":"https://api.github.com/repos/mrsdizzie/test_repo/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mrsdizzie/test_repo/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mrsdizzie/test_repo/git/refs{/sha}","trees_url":"https://api.github.com/repos/mrsdizzie/test_repo/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mrsdizzie/test_repo/statuses/{sha}","languages_url":"https://api.github.com/repos/mrsdizzie/test_repo/languages","stargazers_url":"https://api.github.com/repos/mrsdizzie/test_repo/stargazers","contributors_url":"https://api.github.com/repos/mrsdizzie/test_repo/contributors","subscribers_url":"https://api.github.com/repos/mrsdizzie/test_repo/subscribers","subscription_url":"https://api.github.com/repos/mrsdizzie/test_repo/subscription","commits_url":"https://api.github.com/repos/mrsdizzie/test_repo/commits{/sha}","git_commits_url":"https://api.github.com/repos/mrsdizzie/test_repo/git/commits{/sha}","comments_url":"https://api.github.com/repos/mrsdizzie/test_repo/comments{/number}","issue_comment_url":"https://api.github.com/repos/mrsdizzie/test_repo/issues/comments{/number}","contents_url":"https://api.github.com/repos/mrsdizzie/test_repo/contents/{+path}","compare_url":"https://api.github.com/repos/mrsdizzie/test_repo/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mrsdizzie/test_repo/merges","archive_url":"https://api.github.com/repos/mrsdizzie/test_repo/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mrsdizzie/test_repo/downloads","issues_url":"https://api.github.com/repos/mrsdizzie/test_repo/issues{/number}","pulls_url":"https://api.github.com/repos/mrsdizzie/test_repo/pulls{/number}","milestones_url":"https://api.github.com/repos/mrsdizzie/test_repo/milestones{/number}","notifications_url":"https://api.github.com/repos/mrsdizzie/test_repo/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mrsdizzie/test_repo/labels{/name}","releases_url":"https://api.github.com/repos/mrsdizzie/test_repo/releases{/id}","deployments_url":"https://api.github.com/repos/mrsdizzie/test_repo/deployments","created_at":"2019-11-12T21:17:42Z","updated_at":"2019-11-12T21:18:46Z","pushed_at":"2019-11-12T21:53:39Z","git_url":"git://github.com/mrsdizzie/test_repo.git","ssh_url":"git@github.com:mrsdizzie/test_repo.git","clone_url":"https://github.com/mrsdizzie/test_repo.git","svn_url":"https://github.com/mrsdizzie/test_repo","homepage":"https://codeberg.org/forgejo/forgejo/","size":3,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"has_discussions":false,"forks_count":0,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":0,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit","node_id":"MDc6TGljZW5zZTEz"},"allow_forking":true,"is_template":false,"web_commit_signoff_required":false,"topics":[],"visibility":"public","forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"go-gitea:master","ref":"master","sha":"72866af952e98d02a73003501836074b286a78f6","user":{"login":"go-gitea","id":12724356,"node_id":"MDEyOk9yZ2FuaXphdGlvbjEyNzI0MzU2","avatar_url":"https://avatars.githubusercontent.com/u/12724356?v=4","gravatar_id":"","url":"https://api.github.com/users/go-gitea","html_url":"https://github.com/go-gitea","followers_url":"https://api.github.com/users/go-gitea/followers","following_url":"https://api.github.com/users/go-gitea/following{/other_user}","gists_url":"https://api.github.com/users/go-gitea/gists{/gist_id}","starred_url":"https://api.github.com/users/go-gitea/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/go-gitea/subscriptions","organizations_url":"https://api.github.com/users/go-gitea/orgs","repos_url":"https://api.github.com/users/go-gitea/repos","events_url":"https://api.github.com/users/go-gitea/events{/privacy}","received_events_url":"https://api.github.com/users/go-gitea/received_events","type":"Organization","user_view_type":"public","site_admin":false},"repo":{"id":220672974,"node_id":"MDEwOlJlcG9zaXRvcnkyMjA2NzI5NzQ=","name":"test_repo","full_name":"go-gitea/test_repo","private":false,"owner":{"login":"go-gitea","id":12724356,"node_id":"MDEyOk9yZ2FuaXphdGlvbjEyNzI0MzU2","avatar_url":"https://avatars.githubusercontent.com/u/12724356?v=4","gravatar_id":"","url":"https://api.github.com/users/go-gitea","html_url":"https://github.com/go-gitea","followers_url":"https://api.github.com/users/go-gitea/followers","following_url":"https://api.github.com/users/go-gitea/following{/other_user}","gists_url":"https://api.github.com/users/go-gitea/gists{/gist_id}","starred_url":"https://api.github.com/users/go-gitea/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/go-gitea/subscriptions","organizations_url":"https://api.github.com/users/go-gitea/orgs","repos_url":"https://api.github.com/users/go-gitea/repos","events_url":"https://api.github.com/users/go-gitea/events{/privacy}","received_events_url":"https://api.github.com/users/go-gitea/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/go-gitea/test_repo","description":"Test repository for testing migration from github to gitea","fork":false,"url":"https://api.github.com/repos/go-gitea/test_repo","forks_url":"https://api.github.com/repos/go-gitea/test_repo/forks","keys_url":"https://api.github.com/repos/go-gitea/test_repo/keys{/key_id}","collaborators_url":"https://api.github.com/repos/go-gitea/test_repo/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/go-gitea/test_repo/teams","hooks_url":"https://api.github.com/repos/go-gitea/test_repo/hooks","issue_events_url":"https://api.github.com/repos/go-gitea/test_repo/issues/events{/number}","events_url":"https://api.github.com/repos/go-gitea/test_repo/events","assignees_url":"https://api.github.com/repos/go-gitea/test_repo/assignees{/user}","branches_url":"https://api.github.com/repos/go-gitea/test_repo/branches{/branch}","tags_url":"https://api.github.com/repos/go-gitea/test_repo/tags","blobs_url":"https://api.github.com/repos/go-gitea/test_repo/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/go-gitea/test_repo/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/go-gitea/test_repo/git/refs{/sha}","trees_url":"https://api.github.com/repos/go-gitea/test_repo/git/trees{/sha}","statuses_url":"https://api.github.com/repos/go-gitea/test_repo/statuses/{sha}","languages_url":"https://api.github.com/repos/go-gitea/test_repo/languages","stargazers_url":"https://api.github.com/repos/go-gitea/test_repo/stargazers","contributors_url":"https://api.github.com/repos/go-gitea/test_repo/contributors","subscribers_url":"https://api.github.com/repos/go-gitea/test_repo/subscribers","subscription_url":"https://api.github.com/repos/go-gitea/test_repo/subscription","commits_url":"https://api.github.com/repos/go-gitea/test_repo/commits{/sha}","git_commits_url":"https://api.github.com/repos/go-gitea/test_repo/git/commits{/sha}","comments_url":"https://api.github.com/repos/go-gitea/test_repo/comments{/number}","issue_comment_url":"https://api.github.com/repos/go-gitea/test_repo/issues/comments{/number}","contents_url":"https://api.github.com/repos/go-gitea/test_repo/contents/{+path}","compare_url":"https://api.github.com/repos/go-gitea/test_repo/compare/{base}...{head}","merges_url":"https://api.github.com/repos/go-gitea/test_repo/merges","archive_url":"https://api.github.com/repos/go-gitea/test_repo/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/go-gitea/test_repo/downloads","issues_url":"https://api.github.com/repos/go-gitea/test_repo/issues{/number}","pulls_url":"https://api.github.com/repos/go-gitea/test_repo/pulls{/number}","milestones_url":"https://api.github.com/repos/go-gitea/test_repo/milestones{/number}","notifications_url":"https://api.github.com/repos/go-gitea/test_repo/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/go-gitea/test_repo/labels{/name}","releases_url":"https://api.github.com/repos/go-gitea/test_repo/releases{/id}","deployments_url":"https://api.github.com/repos/go-gitea/test_repo/deployments","created_at":"2019-11-09T16:49:20Z","updated_at":"2023-03-02T14:02:26Z","pushed_at":"2019-11-12T21:54:19Z","git_url":"git://github.com/go-gitea/test_repo.git","ssh_url":"git@github.com:go-gitea/test_repo.git","clone_url":"https://github.com/go-gitea/test_repo.git","svn_url":"https://github.com/go-gitea/test_repo","homepage":"https://codeberg.org/forgejo/forgejo/","size":1,"stargazers_count":3,"watchers_count":3,"language":null,"has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"has_discussions":false,"forks_count":6,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":2,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit","node_id":"MDc6TGljZW5zZTEz"},"allow_forking":true,"is_template":false,"web_commit_signoff_required":false,"topics":["gitea"],"visibility":"public","forks":6,"open_issues":2,"watchers":3,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/go-gitea/test_repo/pulls/3"},"html":{"href":"https://github.com/go-gitea/test_repo/pull/3"},"issue":{"href":"https://api.github.com/repos/go-gitea/test_repo/issues/3"},"comments":{"href":"https://api.github.com/repos/go-gitea/test_repo/issues/3/comments"},"review_comments":{"href":"https://api.github.com/repos/go-gitea/test_repo/pulls/3/comments"},"review_comment":{"href":"https://api.github.com/repos/go-gitea/test_repo/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/go-gitea/test_repo/pulls/3/commits"},"statuses":{"href":"https://api.github.com/repos/go-gitea/test_repo/statuses/076160cf0b039f13e5eff19619932d181269414b"}},"author_association":"MEMBER","auto_merge":null,"active_lock_reason":null},{"url":"https://api.github.com/repos/go-gitea/test_repo/pulls/4","id":340131577,"node_id":"MDExOlB1bGxSZXF1ZXN0MzQwMTMxNTc3","html_url":"https://github.com/go-gitea/test_repo/pull/4","diff_url":"https://github.com/go-gitea/test_repo/pull/4.diff","patch_url":"https://github.com/go-gitea/test_repo/pull/4.patch","issue_url":"https://api.github.com/repos/go-gitea/test_repo/issues/4","number":4,"state":"open","locked":false,"title":"Test branch","user":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"body":"do not merge this PR","created_at":"2019-11-12T21:54:18Z","updated_at":"2020-01-04T11:30:01Z","closed_at":null,"merged_at":null,"merge_commit_sha":"565d1208f5fffdc1c5ae1a2436491eb9a5e4ebae","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":1667254252,"node_id":"MDU6TGFiZWwxNjY3MjU0MjUy","url":"https://api.github.com/repos/go-gitea/test_repo/labels/bug","name":"bug","color":"d73a4a","default":true,"description":"Something isn't working"}],"milestone":{"url":"https://api.github.com/repos/go-gitea/test_repo/milestones/1","html_url":"https://github.com/go-gitea/test_repo/milestone/1","labels_url":"https://api.github.com/repos/go-gitea/test_repo/milestones/1/labels","id":4839941,"node_id":"MDk6TWlsZXN0b25lNDgzOTk0MQ==","number":1,"title":"1.0.0","description":"Milestone 1.0.0","creator":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"open_issues":1,"closed_issues":1,"state":"closed","created_at":"2019-11-12T19:37:08Z","updated_at":"2019-11-12T21:56:17Z","due_on":"2019-11-11T08:00:00Z","closed_at":"2019-11-12T19:45:49Z"},"draft":false,"commits_url":"https://api.github.com/repos/go-gitea/test_repo/pulls/4/commits","review_comments_url":"https://api.github.com/repos/go-gitea/test_repo/pulls/4/comments","review_comment_url":"https://api.github.com/repos/go-gitea/test_repo/pulls/comments{/number}","comments_url":"https://api.github.com/repos/go-gitea/test_repo/issues/4/comments","statuses_url":"https://api.github.com/repos/go-gitea/test_repo/statuses/2be9101c543658591222acbee3eb799edfc3853d","head":{"label":"mrsdizzie:test-branch","ref":"test-branch","sha":"2be9101c543658591222acbee3eb799edfc3853d","user":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"repo":{"id":221313794,"node_id":"MDEwOlJlcG9zaXRvcnkyMjEzMTM3OTQ=","name":"test_repo","full_name":"mrsdizzie/test_repo","private":false,"owner":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"html_url":"https://github.com/mrsdizzie/test_repo","description":"Test repository for testing migration from github to gitea","fork":true,"url":"https://api.github.com/repos/mrsdizzie/test_repo","forks_url":"https://api.github.com/repos/mrsdizzie/test_repo/forks","keys_url":"https://api.github.com/repos/mrsdizzie/test_repo/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mrsdizzie/test_repo/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mrsdizzie/test_repo/teams","hooks_url":"https://api.github.com/repos/mrsdizzie/test_repo/hooks","issue_events_url":"https://api.github.com/repos/mrsdizzie/test_repo/issues/events{/number}","events_url":"https://api.github.com/repos/mrsdizzie/test_repo/events","assignees_url":"https://api.github.com/repos/mrsdizzie/test_repo/assignees{/user}","branches_url":"https://api.github.com/repos/mrsdizzie/test_repo/branches{/branch}","tags_url":"https://api.github.com/repos/mrsdizzie/test_repo/tags","blobs_url":"https://api.github.com/repos/mrsdizzie/test_repo/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mrsdizzie/test_repo/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mrsdizzie/test_repo/git/refs{/sha}","trees_url":"https://api.github.com/repos/mrsdizzie/test_repo/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mrsdizzie/test_repo/statuses/{sha}","languages_url":"https://api.github.com/repos/mrsdizzie/test_repo/languages","stargazers_url":"https://api.github.com/repos/mrsdizzie/test_repo/stargazers","contributors_url":"https://api.github.com/repos/mrsdizzie/test_repo/contributors","subscribers_url":"https://api.github.com/repos/mrsdizzie/test_repo/subscribers","subscription_url":"https://api.github.com/repos/mrsdizzie/test_repo/subscription","commits_url":"https://api.github.com/repos/mrsdizzie/test_repo/commits{/sha}","git_commits_url":"https://api.github.com/repos/mrsdizzie/test_repo/git/commits{/sha}","comments_url":"https://api.github.com/repos/mrsdizzie/test_repo/comments{/number}","issue_comment_url":"https://api.github.com/repos/mrsdizzie/test_repo/issues/comments{/number}","contents_url":"https://api.github.com/repos/mrsdizzie/test_repo/contents/{+path}","compare_url":"https://api.github.com/repos/mrsdizzie/test_repo/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mrsdizzie/test_repo/merges","archive_url":"https://api.github.com/repos/mrsdizzie/test_repo/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mrsdizzie/test_repo/downloads","issues_url":"https://api.github.com/repos/mrsdizzie/test_repo/issues{/number}","pulls_url":"https://api.github.com/repos/mrsdizzie/test_repo/pulls{/number}","milestones_url":"https://api.github.com/repos/mrsdizzie/test_repo/milestones{/number}","notifications_url":"https://api.github.com/repos/mrsdizzie/test_repo/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mrsdizzie/test_repo/labels{/name}","releases_url":"https://api.github.com/repos/mrsdizzie/test_repo/releases{/id}","deployments_url":"https://api.github.com/repos/mrsdizzie/test_repo/deployments","created_at":"2019-11-12T21:17:42Z","updated_at":"2019-11-12T21:18:46Z","pushed_at":"2019-11-12T21:53:39Z","git_url":"git://github.com/mrsdizzie/test_repo.git","ssh_url":"git@github.com:mrsdizzie/test_repo.git","clone_url":"https://github.com/mrsdizzie/test_repo.git","svn_url":"https://github.com/mrsdizzie/test_repo","homepage":"https://codeberg.org/forgejo/forgejo/","size":3,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"has_discussions":false,"forks_count":0,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":0,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit","node_id":"MDc6TGljZW5zZTEz"},"allow_forking":true,"is_template":false,"web_commit_signoff_required":false,"topics":[],"visibility":"public","forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"go-gitea:master","ref":"master","sha":"f32b0a9dfd09a60f616f29158f772cedd89942d2","user":{"login":"go-gitea","id":12724356,"node_id":"MDEyOk9yZ2FuaXphdGlvbjEyNzI0MzU2","avatar_url":"https://avatars.githubusercontent.com/u/12724356?v=4","gravatar_id":"","url":"https://api.github.com/users/go-gitea","html_url":"https://github.com/go-gitea","followers_url":"https://api.github.com/users/go-gitea/followers","following_url":"https://api.github.com/users/go-gitea/following{/other_user}","gists_url":"https://api.github.com/users/go-gitea/gists{/gist_id}","starred_url":"https://api.github.com/users/go-gitea/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/go-gitea/subscriptions","organizations_url":"https://api.github.com/users/go-gitea/orgs","repos_url":"https://api.github.com/users/go-gitea/repos","events_url":"https://api.github.com/users/go-gitea/events{/privacy}","received_events_url":"https://api.github.com/users/go-gitea/received_events","type":"Organization","user_view_type":"public","site_admin":false},"repo":{"id":220672974,"node_id":"MDEwOlJlcG9zaXRvcnkyMjA2NzI5NzQ=","name":"test_repo","full_name":"go-gitea/test_repo","private":false,"owner":{"login":"go-gitea","id":12724356,"node_id":"MDEyOk9yZ2FuaXphdGlvbjEyNzI0MzU2","avatar_url":"https://avatars.githubusercontent.com/u/12724356?v=4","gravatar_id":"","url":"https://api.github.com/users/go-gitea","html_url":"https://github.com/go-gitea","followers_url":"https://api.github.com/users/go-gitea/followers","following_url":"https://api.github.com/users/go-gitea/following{/other_user}","gists_url":"https://api.github.com/users/go-gitea/gists{/gist_id}","starred_url":"https://api.github.com/users/go-gitea/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/go-gitea/subscriptions","organizations_url":"https://api.github.com/users/go-gitea/orgs","repos_url":"https://api.github.com/users/go-gitea/repos","events_url":"https://api.github.com/users/go-gitea/events{/privacy}","received_events_url":"https://api.github.com/users/go-gitea/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/go-gitea/test_repo","description":"Test repository for testing migration from github to gitea","fork":false,"url":"https://api.github.com/repos/go-gitea/test_repo","forks_url":"https://api.github.com/repos/go-gitea/test_repo/forks","keys_url":"https://api.github.com/repos/go-gitea/test_repo/keys{/key_id}","collaborators_url":"https://api.github.com/repos/go-gitea/test_repo/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/go-gitea/test_repo/teams","hooks_url":"https://api.github.com/repos/go-gitea/test_repo/hooks","issue_events_url":"https://api.github.com/repos/go-gitea/test_repo/issues/events{/number}","events_url":"https://api.github.com/repos/go-gitea/test_repo/events","assignees_url":"https://api.github.com/repos/go-gitea/test_repo/assignees{/user}","branches_url":"https://api.github.com/repos/go-gitea/test_repo/branches{/branch}","tags_url":"https://api.github.com/repos/go-gitea/test_repo/tags","blobs_url":"https://api.github.com/repos/go-gitea/test_repo/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/go-gitea/test_repo/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/go-gitea/test_repo/git/refs{/sha}","trees_url":"https://api.github.com/repos/go-gitea/test_repo/git/trees{/sha}","statuses_url":"https://api.github.com/repos/go-gitea/test_repo/statuses/{sha}","languages_url":"https://api.github.com/repos/go-gitea/test_repo/languages","stargazers_url":"https://api.github.com/repos/go-gitea/test_repo/stargazers","contributors_url":"https://api.github.com/repos/go-gitea/test_repo/contributors","subscribers_url":"https://api.github.com/repos/go-gitea/test_repo/subscribers","subscription_url":"https://api.github.com/repos/go-gitea/test_repo/subscription","commits_url":"https://api.github.com/repos/go-gitea/test_repo/commits{/sha}","git_commits_url":"https://api.github.com/repos/go-gitea/test_repo/git/commits{/sha}","comments_url":"https://api.github.com/repos/go-gitea/test_repo/comments{/number}","issue_comment_url":"https://api.github.com/repos/go-gitea/test_repo/issues/comments{/number}","contents_url":"https://api.github.com/repos/go-gitea/test_repo/contents/{+path}","compare_url":"https://api.github.com/repos/go-gitea/test_repo/compare/{base}...{head}","merges_url":"https://api.github.com/repos/go-gitea/test_repo/merges","archive_url":"https://api.github.com/repos/go-gitea/test_repo/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/go-gitea/test_repo/downloads","issues_url":"https://api.github.com/repos/go-gitea/test_repo/issues{/number}","pulls_url":"https://api.github.com/repos/go-gitea/test_repo/pulls{/number}","milestones_url":"https://api.github.com/repos/go-gitea/test_repo/milestones{/number}","notifications_url":"https://api.github.com/repos/go-gitea/test_repo/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/go-gitea/test_repo/labels{/name}","releases_url":"https://api.github.com/repos/go-gitea/test_repo/releases{/id}","deployments_url":"https://api.github.com/repos/go-gitea/test_repo/deployments","created_at":"2019-11-09T16:49:20Z","updated_at":"2023-03-02T14:02:26Z","pushed_at":"2019-11-12T21:54:19Z","git_url":"git://github.com/go-gitea/test_repo.git","ssh_url":"git@github.com:go-gitea/test_repo.git","clone_url":"https://github.com/go-gitea/test_repo.git","svn_url":"https://github.com/go-gitea/test_repo","homepage":"https://codeberg.org/forgejo/forgejo/","size":1,"stargazers_count":3,"watchers_count":3,"language":null,"has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"has_discussions":false,"forks_count":6,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":2,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit","node_id":"MDc6TGljZW5zZTEz"},"allow_forking":true,"is_template":false,"web_commit_signoff_required":false,"topics":["gitea"],"visibility":"public","forks":6,"open_issues":2,"watchers":3,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/go-gitea/test_repo/pulls/4"},"html":{"href":"https://github.com/go-gitea/test_repo/pull/4"},"issue":{"href":"https://api.github.com/repos/go-gitea/test_repo/issues/4"},"comments":{"href":"https://api.github.com/repos/go-gitea/test_repo/issues/4/comments"},"review_comments":{"href":"https://api.github.com/repos/go-gitea/test_repo/pulls/4/comments"},"review_comment":{"href":"https://api.github.com/repos/go-gitea/test_repo/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/go-gitea/test_repo/pulls/4/commits"},"statuses":{"href":"https://api.github.com/repos/go-gitea/test_repo/statuses/2be9101c543658591222acbee3eb799edfc3853d"}},"author_association":"MEMBER","auto_merge":null,"active_lock_reason":null}]
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Freleases%3Fpage=1&per_page=100 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Freleases%3Fpage=1&per_page=100
new file mode 100644
index 0000000000..470f5c5769
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Freleases%3Fpage=1&per_page=100
@@ -0,0 +1,24 @@
+Access-Control-Allow-Origin: *
+X-Frame-Options: deny
+Etag: W/"2986c85fcc06cc478457abb86a88ac7f065b6861e873ae0eeb9ac16a22efca45"
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Used: 75
+X-Ratelimit-Resource: core
+Content-Type: application/json; charset=utf-8
+Cache-Control: private, max-age=60, s-maxage=60
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Accepted-Oauth-Scopes: repo
+X-Ratelimit-Limit: 5000
+X-Ratelimit-Reset: 1730800941
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+X-Xss-Protection: 0
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+Content-Security-Policy: default-src 'none'
+X-Oauth-Scopes:
+X-Github-Media-Type: github.v3; format=json
+X-Ratelimit-Remaining: 4925
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+X-Content-Type-Options: nosniff
+X-Github-Request-Id: C7CC:3118FC:3F5F41A:4035CB2:6729E6B4
+
+[{"url":"https://api.github.com/repos/go-gitea/test_repo/releases/21419432","assets_url":"https://api.github.com/repos/go-gitea/test_repo/releases/21419432/assets","upload_url":"https://uploads.github.com/repos/go-gitea/test_repo/releases/21419432/assets{?name,label}","html_url":"https://github.com/go-gitea/test_repo/releases/tag/v0.9.99","id":21419432,"author":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"node_id":"MDc6UmVsZWFzZTIxNDE5NDMy","tag_name":"v0.9.99","target_commitish":"master","name":"First Release","draft":false,"prerelease":false,"created_at":"2019-11-09T16:49:21Z","published_at":"2019-11-12T20:12:10Z","assets":[],"tarball_url":"https://api.github.com/repos/go-gitea/test_repo/tarball/v0.9.99","zipball_url":"https://api.github.com/repos/go-gitea/test_repo/zipball/v0.9.99","body":"A test release"}]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/forgejo/test_repo.git/HEAD b/services/migrations/testdata/github/full_download/forgejo/test_repo.git/HEAD
deleted file mode 100644
index b870d82622..0000000000
--- a/services/migrations/testdata/github/full_download/forgejo/test_repo.git/HEAD
+++ /dev/null
@@ -1 +0,0 @@
-ref: refs/heads/main
diff --git a/services/migrations/testdata/github/full_download/forgejo/test_repo.git/config b/services/migrations/testdata/github/full_download/forgejo/test_repo.git/config
deleted file mode 100644
index 07d359d07c..0000000000
--- a/services/migrations/testdata/github/full_download/forgejo/test_repo.git/config
+++ /dev/null
@@ -1,4 +0,0 @@
-[core]
- repositoryformatversion = 0
- filemode = true
- bare = true
diff --git a/services/migrations/testdata/github/full_download/forgejo/test_repo.git/description b/services/migrations/testdata/github/full_download/forgejo/test_repo.git/description
deleted file mode 100644
index 498b267a8c..0000000000
--- a/services/migrations/testdata/github/full_download/forgejo/test_repo.git/description
+++ /dev/null
@@ -1 +0,0 @@
-Unnamed repository; edit this file 'description' to name the repository.
diff --git a/services/migrations/testdata/github/full_download/forgejo/test_repo.git/info/exclude b/services/migrations/testdata/github/full_download/forgejo/test_repo.git/info/exclude
deleted file mode 100644
index a5196d1be8..0000000000
--- a/services/migrations/testdata/github/full_download/forgejo/test_repo.git/info/exclude
+++ /dev/null
@@ -1,6 +0,0 @@
-# git ls-files --others --exclude-from=.git/info/exclude
-# Lines that start with '#' are comments.
-# For a project mostly in C, the following would be a good set of
-# exclude patterns (uncomment them if you want to use them):
-# *.[oa]
-# *~
diff --git a/services/migrations/testdata/github/full_download/forgejo/test_repo.git/info/refs b/services/migrations/testdata/github/full_download/forgejo/test_repo.git/info/refs
deleted file mode 100644
index 07fe1b45cd..0000000000
--- a/services/migrations/testdata/github/full_download/forgejo/test_repo.git/info/refs
+++ /dev/null
@@ -1 +0,0 @@
-ca43b48ca2c461f9a5cb66500a154b23d07c9f90 refs/heads/main
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/forgejo/test_repo.git/objects/17/58ff42c9ab82988ad33d211ef5433afd779a9e b/services/migrations/testdata/github/full_download/forgejo/test_repo.git/objects/17/58ff42c9ab82988ad33d211ef5433afd779a9e
deleted file mode 100644
index 5a598008b9..0000000000
Binary files a/services/migrations/testdata/github/full_download/forgejo/test_repo.git/objects/17/58ff42c9ab82988ad33d211ef5433afd779a9e and /dev/null differ
diff --git a/services/migrations/testdata/github/full_download/forgejo/test_repo.git/objects/1a/0f6de7bb300de4a569371cfedf1c6ff189d374 b/services/migrations/testdata/github/full_download/forgejo/test_repo.git/objects/1a/0f6de7bb300de4a569371cfedf1c6ff189d374
deleted file mode 100644
index e296f574da..0000000000
Binary files a/services/migrations/testdata/github/full_download/forgejo/test_repo.git/objects/1a/0f6de7bb300de4a569371cfedf1c6ff189d374 and /dev/null differ
diff --git a/services/migrations/testdata/github/full_download/forgejo/test_repo.git/objects/44/2d28a55b842472c95bead51a4c61f209ac1636 b/services/migrations/testdata/github/full_download/forgejo/test_repo.git/objects/44/2d28a55b842472c95bead51a4c61f209ac1636
deleted file mode 100644
index f7aae32db0..0000000000
Binary files a/services/migrations/testdata/github/full_download/forgejo/test_repo.git/objects/44/2d28a55b842472c95bead51a4c61f209ac1636 and /dev/null differ
diff --git a/services/migrations/testdata/github/full_download/forgejo/test_repo.git/objects/56/38cb8f3278e467fc1eefcac14d3c0d5d91601f b/services/migrations/testdata/github/full_download/forgejo/test_repo.git/objects/56/38cb8f3278e467fc1eefcac14d3c0d5d91601f
deleted file mode 100644
index b7d43b3d6d..0000000000
Binary files a/services/migrations/testdata/github/full_download/forgejo/test_repo.git/objects/56/38cb8f3278e467fc1eefcac14d3c0d5d91601f and /dev/null differ
diff --git a/services/migrations/testdata/github/full_download/forgejo/test_repo.git/objects/59/93b8814449c4cc660132613c12cf6b26c9824c b/services/migrations/testdata/github/full_download/forgejo/test_repo.git/objects/59/93b8814449c4cc660132613c12cf6b26c9824c
deleted file mode 100644
index a995c75bf7..0000000000
Binary files a/services/migrations/testdata/github/full_download/forgejo/test_repo.git/objects/59/93b8814449c4cc660132613c12cf6b26c9824c and /dev/null differ
diff --git a/services/migrations/testdata/github/full_download/forgejo/test_repo.git/objects/6d/d0c6801ddbb7333787e73e99581279492ff449 b/services/migrations/testdata/github/full_download/forgejo/test_repo.git/objects/6d/d0c6801ddbb7333787e73e99581279492ff449
deleted file mode 100644
index aaccbfefb4..0000000000
Binary files a/services/migrations/testdata/github/full_download/forgejo/test_repo.git/objects/6d/d0c6801ddbb7333787e73e99581279492ff449 and /dev/null differ
diff --git a/services/migrations/testdata/github/full_download/forgejo/test_repo.git/objects/76/5f7381bf10911971845cc881fa54a93389a270 b/services/migrations/testdata/github/full_download/forgejo/test_repo.git/objects/76/5f7381bf10911971845cc881fa54a93389a270
deleted file mode 100644
index 2dfcea6cd3..0000000000
Binary files a/services/migrations/testdata/github/full_download/forgejo/test_repo.git/objects/76/5f7381bf10911971845cc881fa54a93389a270 and /dev/null differ
diff --git a/services/migrations/testdata/github/full_download/forgejo/test_repo.git/objects/7c/93d105d3ee6af50705c4d2cc8dd548c2f9edc9 b/services/migrations/testdata/github/full_download/forgejo/test_repo.git/objects/7c/93d105d3ee6af50705c4d2cc8dd548c2f9edc9
deleted file mode 100644
index 0fe680ed57..0000000000
Binary files a/services/migrations/testdata/github/full_download/forgejo/test_repo.git/objects/7c/93d105d3ee6af50705c4d2cc8dd548c2f9edc9 and /dev/null differ
diff --git a/services/migrations/testdata/github/full_download/forgejo/test_repo.git/objects/7d/c3f365f3bc83011f0df5ee8637de7dd9487c04 b/services/migrations/testdata/github/full_download/forgejo/test_repo.git/objects/7d/c3f365f3bc83011f0df5ee8637de7dd9487c04
deleted file mode 100644
index 385dfc7fe7..0000000000
--- a/services/migrations/testdata/github/full_download/forgejo/test_repo.git/objects/7d/c3f365f3bc83011f0df5ee8637de7dd9487c04
+++ /dev/null
@@ -1,3 +0,0 @@
-xUPÛŠÛ0ís¾â°O-˜´,téC)Ør,¥T’7ìc.JâÒ‚°äï;r»t†ñØç6gû+nñððå]/·¡?žÞ—pÿéþ3¶7Ôq8†ŸtM§8Œøº‹ç´Ù¥ï‡??æ<¾Íf«0<÷ãØÇ3RÄuv¬Wà9îûÏÍyÿ1Ø÷cúí5¤S?bŒ‡ô²XŽ17\®Ã%Ž/}:¿å¯ ‡ÀøS§:›s
-ûùlægj¿&+ VÖ<ÊJT¸#ÇûHWÈ ê|c,*éJE²u ¥À,KÚKá°–¾K²Œ7La±ÂºT]%õrbÉv¥$[¼a›°eÃb´Jú§É¸–^çæÚ@<
-íášlý&ÓB@IZ(š’~‚[‰R’*8®¥/˜ÿúƈÒh'~t¬ÅTÔÒ’øK}]×
ygØÑòU®S>§¯i¡ŒctÎ 6 O™Ê½qXW`ÝŽfsbâ§ôÒèŒfSoy- ÅRɥХÈD3¡½±ì¸Õ‰P€¬tÙÑt>³È‚¬¡ùœ¬8Õ;à“¿°||K“jýýóÙoQwÃÛ
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/forgejo/test_repo.git/objects/9b/fcee0cb75322db96a76b49faa222e2c59f485d b/services/migrations/testdata/github/full_download/forgejo/test_repo.git/objects/9b/fcee0cb75322db96a76b49faa222e2c59f485d
deleted file mode 100644
index 64a7a811da..0000000000
Binary files a/services/migrations/testdata/github/full_download/forgejo/test_repo.git/objects/9b/fcee0cb75322db96a76b49faa222e2c59f485d and /dev/null differ
diff --git a/services/migrations/testdata/github/full_download/forgejo/test_repo.git/objects/ba/96372ae89cfd798c343542d898da029e2d8a02 b/services/migrations/testdata/github/full_download/forgejo/test_repo.git/objects/ba/96372ae89cfd798c343542d898da029e2d8a02
deleted file mode 100644
index c39c6e8a75..0000000000
--- a/services/migrations/testdata/github/full_download/forgejo/test_repo.git/objects/ba/96372ae89cfd798c343542d898da029e2d8a02
+++ /dev/null
@@ -1,2 +0,0 @@
-x-A
-Ã0{ö+z-?ô\B> WÂQh¬b©”ü¾.ä´Ã°ùeã8]®¸[+²ñÀ,oKiYÕÑ:¢ïÇ…†øû]K£P«~ªž+Õ"ÐÎ0kàKbîe>@Ø¥0ó~¥¢(<
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/forgejo/test_repo.git/objects/bf/2e0fd70c6ef1ab5240a340ba38eb47b3e8409f b/services/migrations/testdata/github/full_download/forgejo/test_repo.git/objects/bf/2e0fd70c6ef1ab5240a340ba38eb47b3e8409f
deleted file mode 100644
index e92cf50fa5..0000000000
Binary files a/services/migrations/testdata/github/full_download/forgejo/test_repo.git/objects/bf/2e0fd70c6ef1ab5240a340ba38eb47b3e8409f and /dev/null differ
diff --git a/services/migrations/testdata/github/full_download/forgejo/test_repo.git/objects/ca/43b48ca2c461f9a5cb66500a154b23d07c9f90 b/services/migrations/testdata/github/full_download/forgejo/test_repo.git/objects/ca/43b48ca2c461f9a5cb66500a154b23d07c9f90
deleted file mode 100644
index 467ab42ca3..0000000000
Binary files a/services/migrations/testdata/github/full_download/forgejo/test_repo.git/objects/ca/43b48ca2c461f9a5cb66500a154b23d07c9f90 and /dev/null differ
diff --git a/services/migrations/testdata/github/full_download/forgejo/test_repo.git/refs/heads/main b/services/migrations/testdata/github/full_download/forgejo/test_repo.git/refs/heads/main
deleted file mode 100644
index fe8dc33916..0000000000
--- a/services/migrations/testdata/github/full_download/forgejo/test_repo.git/refs/heads/main
+++ /dev/null
@@ -1 +0,0 @@
-ca43b48ca2c461f9a5cb66500a154b23d07c9f90
diff --git a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce b/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce
deleted file mode 100644
index d1693ef67f..0000000000
--- a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce
+++ /dev/null
@@ -1,84 +0,0 @@
-date: Wed, 23 Jul 2025 06:51:21 GMT
-server: Apache/2.4.37 (Red Hat Enterprise Linux) OpenSSL/1.1.1k mod_wsgi/4.6.4 Python/3.6
-x-xss-protection: 1; mode=block
-x-content-type-options: nosniff
-referrer-policy: same-origin
-x-frame-options: ALLOW-FROM https://pagure.io/
-strict-transport-security: max-age=31536000; includeSubDomains; preload
-content-length: 1464
-content-security-policy: default-src 'self';script-src 'self' 'nonce-Tr8ktNGt3XoBWQBIXrrPTeA1v'; style-src 'self' 'nonce-Tr8ktNGt3XoBWQBIXrrPTeA1v'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-set-cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiYmI4NGRmYWMyY2Q2MzVlOWRkOTQwMGYwNzk2NzdlOGQxN2UxYTJlMCJ9.G2IX6Q.ETAG_sYgE1V9xYQNy_CD4HOP32Q; Expires=Sat, 23-Aug-2025 06:51:21 GMT; Secure; HttpOnly; Path=/
-content-type: application/json
-
-{
- "access_groups": {
- "admin": [],
- "collaborator": [],
- "commit": [],
- "ticket": []
- },
- "access_users": {
- "admin": [
- "ryanlerch"
- ],
- "collaborator": [],
- "commit": [],
- "owner": [
- "t0xic0der"
- ],
- "ticket": []
- },
- "close_status": [
- "Complete",
- "Baseless"
- ],
- "custom_keys": [],
- "date_created": "1697168063",
- "date_modified": "1744795940",
- "description": "The source namespace for the Pagure Exporter project to run tests against",
- "full_url": "https://pagure.io/protop2g-test-srce",
- "fullname": "protop2g-test-srce",
- "id": 17042,
- "milestones": {
- "Milestone AAAA": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone BBBB": {
- "active": false,
- "date": "1765497600"
- },
- "Milestone CCCC": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone DDDD": {
- "active": false,
- "date": "1765497600"
- }
- },
- "name": "protop2g-test-srce",
- "namespace": null,
- "parent": null,
- "priorities": {
- "": "",
- "1": "Common",
- "2": "Uncommon",
- "3": "Rare",
- "4": "Epic",
- "5": "Mythic"
- },
- "tags": [
- "srce",
- "test",
- "gridhead",
- "protop2g"
- ],
- "url_path": "protop2g-test-srce",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
-}
diff --git a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fc%2F01b420e2964928a15f790f9b7c1a0053e7b5f0a5%2Finfo b/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fc%2F01b420e2964928a15f790f9b7c1a0053e7b5f0a5%2Finfo
deleted file mode 100644
index 063950557b..0000000000
--- a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fc%2F01b420e2964928a15f790f9b7c1a0053e7b5f0a5%2Finfo
+++ /dev/null
@@ -1,24 +0,0 @@
-date: Wed, 23 Jul 2025 06:44:23 GMT
-server: Apache/2.4.37 (Red Hat Enterprise Linux) OpenSSL/1.1.1k mod_wsgi/4.6.4 Python/3.6
-x-xss-protection: 1; mode=block
-x-content-type-options: nosniff
-referrer-policy: same-origin
-x-frame-options: ALLOW-FROM https://pagure.io/
-strict-transport-security: max-age=31536000; includeSubDomains; preload
-content-length: 452
-content-security-policy: default-src 'self';script-src 'self' 'nonce-jtS0HiLSSKCUK3FUuLv7XD9KG'; style-src 'self' 'nonce-jtS0HiLSSKCUK3FUuLv7XD9KG'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-set-cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiY2EzN2Y5MTI1ZjkxNTkzMDViMWQ5ZGVhYjkyNzVlZTkwNmVjYzgzYiJ9.G2IWRw.1ZmhWySKFk3Lw_bA-EwmcNCgcz0; Expires=Sat, 23-Aug-2025 06:44:23 GMT; Secure; HttpOnly; Path=/
-content-type: application/json
-
-{
- "author": "Akashdeep Dhar",
- "commit_time": 1747635011,
- "commit_time_offset": 0,
- "committer": "Akashdeep Dhar",
- "hash": "01b420e2964928a15f790f9b7c1a0053e7b5f0a5",
- "message": "Change the branch identity to `test-eeee` in the README.md file\n\nSigned-off-by: Akashdeep Dhar \n",
- "parent_ids": [
- "3f12d300f62f1c5b8a1d3265bd85d61cf6d924d7"
- ],
- "tree_id": "1e8fa9a17b4b4ddde50f334626b0a5497070cff7"
-}
diff --git a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fc%2F0bc8b0c38e0790e9ef5c8d512a00b9c4dd048160%2Finfo b/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fc%2F0bc8b0c38e0790e9ef5c8d512a00b9c4dd048160%2Finfo
deleted file mode 100644
index dbd4992dbd..0000000000
--- a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fc%2F0bc8b0c38e0790e9ef5c8d512a00b9c4dd048160%2Finfo
+++ /dev/null
@@ -1,24 +0,0 @@
-date: Wed, 23 Jul 2025 06:44:57 GMT
-server: Apache/2.4.37 (Red Hat Enterprise Linux) OpenSSL/1.1.1k mod_wsgi/4.6.4 Python/3.6
-x-xss-protection: 1; mode=block
-x-content-type-options: nosniff
-referrer-policy: same-origin
-x-frame-options: ALLOW-FROM https://pagure.io/
-strict-transport-security: max-age=31536000; includeSubDomains; preload
-content-length: 454
-content-security-policy: default-src 'self';script-src 'self' 'nonce-6gKus9S40eu36HFYePUnyxB36'; style-src 'self' 'nonce-6gKus9S40eu36HFYePUnyxB36'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-set-cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiZjM5ZTYyYWM5NDViYTYwMjg1MjFlMTAzNjU4OWQ3Zjc1NjA5ZmUzMSJ9.G2IWaQ._b9edyW_4DSX-umHlyVib496s00; Expires=Sat, 23-Aug-2025 06:44:57 GMT; Secure; HttpOnly; Path=/
-content-type: application/json
-
-{
- "author": "Akashdeep Dhar",
- "commit_time": 1697169509,
- "commit_time_offset": 330,
- "committer": "Akashdeep Dhar",
- "hash": "0bc8b0c38e0790e9ef5c8d512a00b9c4dd048160",
- "message": "Change the branch identity to `test-dddd` in the README.md file\n\nSigned-off-by: Akashdeep Dhar \n",
- "parent_ids": [
- "3f12d300f62f1c5b8a1d3265bd85d61cf6d924d7"
- ],
- "tree_id": "586a1e8a79e572691dc086ef7bf4e2f6d34c5254"
-}
diff --git a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fc%2F1a6ccc212aa958a0fe76155c2907c889969a7224%2Finfo b/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fc%2F1a6ccc212aa958a0fe76155c2907c889969a7224%2Finfo
deleted file mode 100644
index ce899b5e29..0000000000
--- a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fc%2F1a6ccc212aa958a0fe76155c2907c889969a7224%2Finfo
+++ /dev/null
@@ -1,24 +0,0 @@
-date: Wed, 23 Jul 2025 06:43:47 GMT
-server: Apache/2.4.37 (Red Hat Enterprise Linux) OpenSSL/1.1.1k mod_wsgi/4.6.4 Python/3.6
-x-xss-protection: 1; mode=block
-x-content-type-options: nosniff
-referrer-policy: same-origin
-x-frame-options: ALLOW-FROM https://pagure.io/
-strict-transport-security: max-age=31536000; includeSubDomains; preload
-content-length: 452
-content-security-policy: default-src 'self';script-src 'self' 'nonce-bDXeQlGZOYsS26Mr1BJPgodzY'; style-src 'self' 'nonce-bDXeQlGZOYsS26Mr1BJPgodzY'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-set-cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiNDRkYmIwMjQwODI1ODc4MGUzYWM4ZDZhZTkxYWQ2NTkyMDFhNTg0ZSJ9.G2IWIw.U2Rb6xUm4Wk9ODweB3hH1cggWkM; Expires=Sat, 23-Aug-2025 06:43:47 GMT; Secure; HttpOnly; Path=/
-content-type: application/json
-
-{
- "author": "Akashdeep Dhar",
- "commit_time": 1747635352,
- "commit_time_offset": 0,
- "committer": "Akashdeep Dhar",
- "hash": "1a6ccc212aa958a0fe76155c2907c889969a7224",
- "message": "Change the branch identity to `test-ffff` in the README.md file\n\nSigned-off-by: Akashdeep Dhar \n",
- "parent_ids": [
- "01b420e2964928a15f790f9b7c1a0053e7b5f0a5"
- ],
- "tree_id": "0c5e64a6b912cb0c3d66e66896fa98a98da69fe4"
-}
diff --git a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fc%2F2d40761dc53e6fa060ac49d88e1452c6751d4b1c%2Finfo b/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fc%2F2d40761dc53e6fa060ac49d88e1452c6751d4b1c%2Finfo
deleted file mode 100644
index 412298b22c..0000000000
--- a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fc%2F2d40761dc53e6fa060ac49d88e1452c6751d4b1c%2Finfo
+++ /dev/null
@@ -1,24 +0,0 @@
-date: Wed, 23 Jul 2025 06:46:23 GMT
-server: Apache/2.4.37 (Red Hat Enterprise Linux) OpenSSL/1.1.1k mod_wsgi/4.6.4 Python/3.6
-x-xss-protection: 1; mode=block
-x-content-type-options: nosniff
-referrer-policy: same-origin
-x-frame-options: ALLOW-FROM https://pagure.io/
-strict-transport-security: max-age=31536000; includeSubDomains; preload
-content-length: 454
-content-security-policy: default-src 'self';script-src 'self' 'nonce-JLGc3LbKkMMzOnQTvUIIZbAwF'; style-src 'self' 'nonce-JLGc3LbKkMMzOnQTvUIIZbAwF'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-set-cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiYTE0Y2EzMTZiMWRkZGZjOTJjMjkwZTkyNjM5OWEzYWZiNjA0OTZiMCJ9.G2IWvw.SNBn8NelY5GBQ-8SmLY-Uwy-uq0; Expires=Sat, 23-Aug-2025 06:46:23 GMT; Secure; HttpOnly; Path=/
-content-type: application/json
-
-{
- "author": "Akashdeep Dhar",
- "commit_time": 1697169040,
- "commit_time_offset": 330,
- "committer": "Akashdeep Dhar",
- "hash": "2d40761dc53e6fa060ac49d88e1452c6751d4b1c",
- "message": "Change the branch identity to `test-bbbb` in the README.md file\n\nSigned-off-by: Akashdeep Dhar \n",
- "parent_ids": [
- "3f12d300f62f1c5b8a1d3265bd85d61cf6d924d7"
- ],
- "tree_id": "7a23fc15f5a1463f2c425f0146def7c19ecf6c88"
-}
diff --git a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fc%2Fb55e5c91d2572d60a8d7e71b3d3003e523127bd4%2Finfo b/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fc%2Fb55e5c91d2572d60a8d7e71b3d3003e523127bd4%2Finfo
deleted file mode 100644
index 6ac5ccf674..0000000000
--- a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fc%2Fb55e5c91d2572d60a8d7e71b3d3003e523127bd4%2Finfo
+++ /dev/null
@@ -1,24 +0,0 @@
-date: Wed, 23 Jul 2025 06:46:59 GMT
-server: Apache/2.4.37 (Red Hat Enterprise Linux) OpenSSL/1.1.1k mod_wsgi/4.6.4 Python/3.6
-x-xss-protection: 1; mode=block
-x-content-type-options: nosniff
-referrer-policy: same-origin
-x-frame-options: ALLOW-FROM https://pagure.io/
-strict-transport-security: max-age=31536000; includeSubDomains; preload
-content-length: 454
-content-security-policy: default-src 'self';script-src 'self' 'nonce-ORfdixyFztBA0Sx54SlhQuMio'; style-src 'self' 'nonce-ORfdixyFztBA0Sx54SlhQuMio'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-set-cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiYmY2MjEyYzNmMDkzMmZkZDMxYjYwYzVmMDdjYzEzY2JhZTJkMjVmZCJ9.G2IW4w.JCI6ih36NlW5IPwNX1LaCbb6v5U; Expires=Sat, 23-Aug-2025 06:46:59 GMT; Secure; HttpOnly; Path=/
-content-type: application/json
-
-{
- "author": "Akashdeep Dhar",
- "commit_time": 1697169185,
- "commit_time_offset": 330,
- "committer": "Akashdeep Dhar",
- "hash": "b55e5c91d2572d60a8d7e71b3d3003e523127bd4",
- "message": "Change the branch identity to `test-aaaa` in the README.md file\n\nSigned-off-by: Akashdeep Dhar \n",
- "parent_ids": [
- "3f12d300f62f1c5b8a1d3265bd85d61cf6d924d7"
- ],
- "tree_id": "e7911825d29e73f260de95d5070898ccbe6340a6"
-}
diff --git a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fc%2Ff1246e331cade9341b9e4f311b7a134f99893d21%2Finfo b/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fc%2Ff1246e331cade9341b9e4f311b7a134f99893d21%2Finfo
deleted file mode 100644
index 3505297407..0000000000
--- a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fc%2Ff1246e331cade9341b9e4f311b7a134f99893d21%2Finfo
+++ /dev/null
@@ -1,24 +0,0 @@
-date: Wed, 23 Jul 2025 06:45:31 GMT
-server: Apache/2.4.37 (Red Hat Enterprise Linux) OpenSSL/1.1.1k mod_wsgi/4.6.4 Python/3.6
-x-xss-protection: 1; mode=block
-x-content-type-options: nosniff
-referrer-policy: same-origin
-x-frame-options: ALLOW-FROM https://pagure.io/
-strict-transport-security: max-age=31536000; includeSubDomains; preload
-content-length: 454
-content-security-policy: default-src 'self';script-src 'self' 'nonce-chsmQCN0V1J9MIqK5NU6MqBJv'; style-src 'self' 'nonce-chsmQCN0V1J9MIqK5NU6MqBJv'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-set-cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiZDNmYWUzNTBlOWZkNDY0MTJlOWNkMjQ0M2FjZmYyY2VkZjBlY2ZiYSJ9.G2IWjA.co1poP1T_e07frtYRBAkxcp2RTM; Expires=Sat, 23-Aug-2025 06:45:32 GMT; Secure; HttpOnly; Path=/
-content-type: application/json
-
-{
- "author": "Akashdeep Dhar",
- "commit_time": 1697169354,
- "commit_time_offset": 330,
- "committer": "Akashdeep Dhar",
- "hash": "f1246e331cade9341b9e4f311b7a134f99893d21",
- "message": "Change the branch identity to `test-cccc` in the README.md file\n\nSigned-off-by: Akashdeep Dhar \n",
- "parent_ids": [
- "3f12d300f62f1c5b8a1d3265bd85d61cf6d924d7"
- ],
- "tree_id": "f1e37736d409bb136451dfc8e3a2017d3af2ce7d"
-}
diff --git a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fissue%2F3 b/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fissue%2F3
deleted file mode 100644
index a5116fa017..0000000000
--- a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fissue%2F3
+++ /dev/null
@@ -1,16 +0,0 @@
-date: Wed, 23 Jul 2025 06:17:46 GMT
-server: Apache/2.4.37 (Red Hat Enterprise Linux) OpenSSL/1.1.1k mod_wsgi/4.6.4 Python/3.6
-x-xss-protection: 1; mode=block
-x-content-type-options: nosniff
-referrer-policy: same-origin
-x-frame-options: ALLOW-FROM https://pagure.io/
-strict-transport-security: max-age=31536000; includeSubDomains; preload
-content-length: 233
-content-security-policy: default-src 'self';script-src 'self' 'nonce-AyzMgRLEDXIM7Oiv1cbBRx6WC'; style-src 'self' 'nonce-AyzMgRLEDXIM7Oiv1cbBRx6WC'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-set-cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiMGMxMmJkYmFmNWY1ODBiNzQxY2Q2Y2RiODk1OTRmOWMwOGY1OWM2ZSJ9.G2IQCg.BSeYpRe9-FITZnjNS1EKHjwOFmM; Expires=Sat, 23-Aug-2025 06:17:46 GMT; Secure; HttpOnly; Path=/
-content-type: text/html; charset=UTF-8
-
-
-404 Not Found
-Not Found
-The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
diff --git a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fissue%2F4 b/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fissue%2F4
deleted file mode 100644
index e4dbc1976d..0000000000
--- a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fissue%2F4
+++ /dev/null
@@ -1,16 +0,0 @@
-date: Wed, 23 Jul 2025 06:17:58 GMT
-server: Apache/2.4.37 (Red Hat Enterprise Linux) OpenSSL/1.1.1k mod_wsgi/4.6.4 Python/3.6
-x-xss-protection: 1; mode=block
-x-content-type-options: nosniff
-referrer-policy: same-origin
-x-frame-options: ALLOW-FROM https://pagure.io/
-strict-transport-security: max-age=31536000; includeSubDomains; preload
-content-length: 233
-content-security-policy: default-src 'self';script-src 'self' 'nonce-F7TmwHL5oVhCcN5Mddi8OGms7'; style-src 'self' 'nonce-F7TmwHL5oVhCcN5Mddi8OGms7'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-set-cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiOTYwOWIyN2EzYjA4NmE5OTZhNjk3NWU5ZWM4OTI1MWNkN2U5OWYyMiJ9.G2IQFg.qReOtqa1f6EAhBqYOj_aQRCvgac; Expires=Sat, 23-Aug-2025 06:17:58 GMT; Secure; HttpOnly; Path=/
-content-type: text/html; charset=UTF-8
-
-
-404 Not Found
-Not Found
-The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
diff --git a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fissues b/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fissues
deleted file mode 100644
index e04d6fd928..0000000000
--- a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fissues
+++ /dev/null
@@ -1,298 +0,0 @@
-date: Wed, 30 Jul 2025 05:15:59 GMT
-server: Apache/2.4.37 (Red Hat Enterprise Linux) OpenSSL/1.1.1k mod_wsgi/4.6.4 Python/3.6
-x-xss-protection: 1; mode=block
-x-content-type-options: nosniff
-referrer-policy: same-origin
-x-frame-options: ALLOW-FROM https://pagure.io/
-strict-transport-security: max-age=31536000; includeSubDomains; preload
-content-length: 18702
-content-security-policy: default-src 'self';script-src 'self' 'nonce-SA5GWMgMPH5tNiDy97SIr6jxM'; style-src 'self' 'nonce-SA5GWMgMPH5tNiDy97SIr6jxM'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-set-cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiOTA1NjdkYzFjN2QyMjFhMGU3NTVmN2ZlMDYzZTgyMTQ0ZTM3NzFkNiJ9.G2s8Dw.36fFhcCc63_kPkxcJp8tz-ufC8Y; Expires=Sat, 30-Aug-2025 05:15:59 GMT; Secure; HttpOnly; Path=/
-content-type: application/json
-
-{
- "args": {
- "assignee": null,
- "author": null,
- "milestones": [],
- "no_stones": null,
- "order": null,
- "priority": null,
- "since": null,
- "status": "all",
- "tags": []
- },
- "issues": [
- {
- "assignee": null,
- "blocks": [],
- "close_status": "Baseless",
- "closed_at": "1750832631",
- "closed_by": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- },
- "comments": [
- {
- "comment": "This is the first comment under the fourth test issue",
- "date_created": "1700554045",
- "edited_on": null,
- "editor": null,
- "id": 885231,
- "notification": false,
- "parent": null,
- "reactions": {},
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "This is the second comment under the fourth test issue",
- "date_created": "1700554054",
- "edited_on": null,
- "editor": null,
- "id": 885232,
- "notification": false,
- "parent": null,
- "reactions": {},
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "**Metadata Update from @t0xic0der**:\n- Issue status updated to: Closed (was: Open)",
- "date_created": "1700554081",
- "edited_on": null,
- "editor": null,
- "id": 885233,
- "notification": true,
- "parent": null,
- "reactions": {},
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "**Metadata Update from @t0xic0der**:\n- Issue set to the milestone: Milestone DDDD",
- "date_created": "1746679846",
- "edited_on": null,
- "editor": null,
- "id": 971680,
- "notification": true,
- "parent": null,
- "reactions": {},
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "**Metadata Update from @t0xic0der**:\n- Issue set to the milestone: None (was: Milestone DDDD)\n- Issue status updated to: Open (was: Closed)",
- "date_created": "1750832626",
- "edited_on": null,
- "editor": null,
- "id": 976715,
- "notification": true,
- "parent": null,
- "reactions": {},
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "**Metadata Update from @t0xic0der**:\n- Issue close_status updated to: Baseless\n- Issue status updated to: Closed (was: Open)",
- "date_created": "1750832632",
- "edited_on": null,
- "editor": null,
- "id": 976716,
- "notification": true,
- "parent": null,
- "reactions": {},
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "**Metadata Update from @t0xic0der**:\n- Issue set to the milestone: Milestone DDDD",
- "date_created": "1750832695",
- "edited_on": null,
- "editor": null,
- "id": 976718,
- "notification": true,
- "parent": null,
- "reactions": {},
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "**Metadata Update from @t0xic0der**:\n- Issue priority set to: Common",
- "date_created": "1750832786",
- "edited_on": null,
- "editor": null,
- "id": 976722,
- "notification": true,
- "parent": null,
- "reactions": {},
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- }
- ],
- "content": "This is the body of the fourth test issue",
- "custom_fields": [],
- "date_created": "1700554016",
- "depends": [],
- "full_url": "https://pagure.io/protop2g-test-srce/issue/4",
- "id": 4,
- "last_updated": "1750832786",
- "milestone": "Milestone DDDD",
- "priority": 1,
- "private": true,
- "related_prs": [],
- "status": "Closed",
- "tags": [
- "gggg",
- "hhhh"
- ],
- "title": "This is the title of the fourth test issue",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "assignee": null,
- "blocks": [],
- "close_status": null,
- "closed_at": null,
- "closed_by": null,
- "comments": [
- {
- "comment": "This is the first comment under the third test issue",
- "date_created": "1700553880",
- "edited_on": null,
- "editor": null,
- "id": 885229,
- "notification": false,
- "parent": null,
- "reactions": {},
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "This is the second comment under the third test issue",
- "date_created": "1700553892",
- "edited_on": null,
- "editor": null,
- "id": 885230,
- "notification": false,
- "parent": null,
- "reactions": {},
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "**Metadata Update from @t0xic0der**:\n- Issue set to the milestone: Milestone CCCC",
- "date_created": "1746679833",
- "edited_on": null,
- "editor": null,
- "id": 971679,
- "notification": true,
- "parent": null,
- "reactions": {},
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "**Metadata Update from @t0xic0der**:\n- Issue priority set to: Uncommon",
- "date_created": "1750832767",
- "edited_on": null,
- "editor": null,
- "id": 976721,
- "notification": true,
- "parent": null,
- "reactions": {},
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- }
- ],
- "content": "This is the body of the third test issue",
- "custom_fields": [],
- "date_created": "1700553837",
- "depends": [],
- "full_url": "https://pagure.io/protop2g-test-srce/issue/3",
- "id": 3,
- "last_updated": "1750832767",
- "milestone": "Milestone CCCC",
- "priority": 2,
- "private": true,
- "related_prs": [],
- "status": "Open",
- "tags": [
- "eeee",
- "ffff"
- ],
- "title": "This is the title of the third test issue",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- ],
- "pagination": {
- "first": "https://pagure.io/api/0/protop2g-test-srce/issues?per_page=20&status=all&page=1",
- "last": "https://pagure.io/api/0/protop2g-test-srce/issues?per_page=20&status=all&page=1",
- "next": null,
- "page": 1,
- "pages": 1,
- "per_page": 20,
- "prev": null
- },
- "total_issues": 2
-}
diff --git a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fpull-request%2F10 b/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fpull-request%2F10
deleted file mode 100644
index 9c2bd27396..0000000000
--- a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fpull-request%2F10
+++ /dev/null
@@ -1,258 +0,0 @@
-date: Wed, 23 Jul 2025 06:21:04 GMT
-server: Apache/2.4.37 (Red Hat Enterprise Linux) OpenSSL/1.1.1k mod_wsgi/4.6.4 Python/3.6
-x-xss-protection: 1; mode=block
-x-content-type-options: nosniff
-referrer-policy: same-origin
-x-frame-options: ALLOW-FROM https://pagure.io/
-strict-transport-security: max-age=31536000; includeSubDomains; preload
-content-length: 6179
-content-security-policy: default-src 'self';script-src 'self' 'nonce-BK18r6rq2MUNhc0CXTZKJQyJY'; style-src 'self' 'nonce-BK18r6rq2MUNhc0CXTZKJQyJY'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-set-cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiOTQ3NGFiNjdkNjdlZjNiNWNmOWYwZGFmODg1MDMxMTYzNTc5OTkxMyJ9.G2IQ0A.97bsQ3k_CAN3UOID130UESba38M; Expires=Sat, 23-Aug-2025 06:21:04 GMT; Secure; HttpOnly; Path=/
-content-type: application/json
-
-{
- "assignee": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- },
- "branch": "main",
- "branch_from": "test-ffff",
- "cached_merge_status": "unknown",
- "closed_at": "1747635431",
- "closed_by": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- },
- "comments": [
- {
- "comment": "**Metadata Update from @t0xic0der**:\n- Pull-request tagged with: ffff\n- Request assigned",
- "commit": null,
- "date_created": "1747635211",
- "edited_on": null,
- "editor": null,
- "filename": null,
- "id": 219623,
- "line": null,
- "notification": true,
- "parent": null,
- "reactions": {},
- "tree": null,
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "rebased onto 01b420e2964928a15f790f9b7c1a0053e7b5f0a5",
- "commit": null,
- "date_created": "1747635389",
- "edited_on": null,
- "editor": null,
- "filename": null,
- "id": 219625,
- "line": null,
- "notification": true,
- "parent": null,
- "reactions": {},
- "tree": null,
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "Pull-Request has been merged by t0xic0der",
- "commit": null,
- "date_created": "1747635431",
- "edited_on": null,
- "editor": null,
- "filename": null,
- "id": 219626,
- "line": null,
- "notification": true,
- "parent": null,
- "reactions": {},
- "tree": null,
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- }
- ],
- "commit_start": "1a6ccc212aa958a0fe76155c2907c889969a7224",
- "commit_stop": "1a6ccc212aa958a0fe76155c2907c889969a7224",
- "date_created": "1747635165",
- "full_url": "https://pagure.io/protop2g-test-srce/pull-request/10",
- "id": 10,
- "initial_comment": "Signed-off-by: Akashdeep Dhar ",
- "last_updated": "1747635431",
- "project": {
- "access_groups": {
- "admin": [],
- "collaborator": [],
- "commit": [],
- "ticket": []
- },
- "access_users": {
- "admin": [
- "ryanlerch"
- ],
- "collaborator": [],
- "commit": [],
- "owner": [
- "t0xic0der"
- ],
- "ticket": []
- },
- "close_status": [
- "Complete",
- "Baseless"
- ],
- "custom_keys": [],
- "date_created": "1697168063",
- "date_modified": "1744795940",
- "description": "The source namespace for the Pagure Exporter project to run tests against",
- "full_url": "https://pagure.io/protop2g-test-srce",
- "fullname": "protop2g-test-srce",
- "id": 17042,
- "milestones": {
- "Milestone AAAA": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone BBBB": {
- "active": false,
- "date": "1765497600"
- },
- "Milestone CCCC": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone DDDD": {
- "active": false,
- "date": "1765497600"
- }
- },
- "name": "protop2g-test-srce",
- "namespace": null,
- "parent": null,
- "priorities": {
- "": "",
- "1": "Common",
- "2": "Uncommon",
- "3": "Rare",
- "4": "Epic",
- "5": "Mythic"
- },
- "tags": [
- "srce",
- "test",
- "gridhead",
- "protop2g"
- ],
- "url_path": "protop2g-test-srce",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- "remote_git": null,
- "repo_from": {
- "access_groups": {
- "admin": [],
- "collaborator": [],
- "commit": [],
- "ticket": []
- },
- "access_users": {
- "admin": [
- "ryanlerch"
- ],
- "collaborator": [],
- "commit": [],
- "owner": [
- "t0xic0der"
- ],
- "ticket": []
- },
- "close_status": [
- "Complete",
- "Baseless"
- ],
- "custom_keys": [],
- "date_created": "1697168063",
- "date_modified": "1744795940",
- "description": "The source namespace for the Pagure Exporter project to run tests against",
- "full_url": "https://pagure.io/protop2g-test-srce",
- "fullname": "protop2g-test-srce",
- "id": 17042,
- "milestones": {
- "Milestone AAAA": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone BBBB": {
- "active": false,
- "date": "1765497600"
- },
- "Milestone CCCC": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone DDDD": {
- "active": false,
- "date": "1765497600"
- }
- },
- "name": "protop2g-test-srce",
- "namespace": null,
- "parent": null,
- "priorities": {
- "": "",
- "1": "Common",
- "2": "Uncommon",
- "3": "Rare",
- "4": "Epic",
- "5": "Mythic"
- },
- "tags": [
- "srce",
- "test",
- "gridhead",
- "protop2g"
- ],
- "url_path": "protop2g-test-srce",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- "status": "Merged",
- "tags": [
- "ffff"
- ],
- "threshold_reached": null,
- "title": "Change the branch identity to `test-ffff` in the README.md file",
- "uid": "d3b7100abf8b4b02aa220d899e063295",
- "updated_on": "1747635431",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
-}
diff --git a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fpull-request%2F5 b/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fpull-request%2F5
deleted file mode 100644
index 3fc0a4be13..0000000000
--- a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fpull-request%2F5
+++ /dev/null
@@ -1,248 +0,0 @@
-date: Wed, 23 Jul 2025 06:19:26 GMT
-server: Apache/2.4.37 (Red Hat Enterprise Linux) OpenSSL/1.1.1k mod_wsgi/4.6.4 Python/3.6
-x-xss-protection: 1; mode=block
-x-content-type-options: nosniff
-referrer-policy: same-origin
-x-frame-options: ALLOW-FROM https://pagure.io/
-strict-transport-security: max-age=31536000; includeSubDomains; preload
-content-length: 5859
-content-security-policy: default-src 'self';script-src 'self' 'nonce-x3rXi7f95hPSGE2mV9PPJv0Db'; style-src 'self' 'nonce-x3rXi7f95hPSGE2mV9PPJv0Db'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-set-cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiODFiMTQzZWQwZGEzMWIxNmE3NTk1ODYyNWE0MGZjNjcwNThmMDc3ZSJ9.G2IQbg.9qdYqcrGIqnCKtjsWYjcfMCTzok; Expires=Sat, 23-Aug-2025 06:19:26 GMT; Secure; HttpOnly; Path=/
-content-type: application/json
-
-{
- "assignee": null,
- "branch": "main",
- "branch_from": "test-aaaa",
- "cached_merge_status": "CONFLICTS",
- "closed_at": null,
- "closed_by": null,
- "comments": [
- {
- "comment": "**Metadata Update from @t0xic0der**:\n- Pull-request tagged with: aaaa",
- "commit": null,
- "date_created": "1746427453",
- "edited_on": null,
- "editor": null,
- "filename": null,
- "id": 219086,
- "line": null,
- "notification": true,
- "parent": null,
- "reactions": {},
- "tree": null,
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "This is the first comment under this pull request.",
- "commit": null,
- "date_created": "1746595521",
- "edited_on": null,
- "editor": null,
- "filename": null,
- "id": 219190,
- "line": null,
- "notification": false,
- "parent": null,
- "reactions": {},
- "tree": null,
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "This is the second comment under this pull request.",
- "commit": null,
- "date_created": "1746595529",
- "edited_on": null,
- "editor": null,
- "filename": null,
- "id": 219191,
- "line": null,
- "notification": false,
- "parent": null,
- "reactions": {},
- "tree": null,
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- }
- ],
- "commit_start": "b55e5c91d2572d60a8d7e71b3d3003e523127bd4",
- "commit_stop": "b55e5c91d2572d60a8d7e71b3d3003e523127bd4",
- "date_created": "1746427437",
- "full_url": "https://pagure.io/protop2g-test-srce/pull-request/5",
- "id": 5,
- "initial_comment": "Signed-off-by: Akashdeep Dhar ",
- "last_updated": "1747636185",
- "project": {
- "access_groups": {
- "admin": [],
- "collaborator": [],
- "commit": [],
- "ticket": []
- },
- "access_users": {
- "admin": [
- "ryanlerch"
- ],
- "collaborator": [],
- "commit": [],
- "owner": [
- "t0xic0der"
- ],
- "ticket": []
- },
- "close_status": [
- "Complete",
- "Baseless"
- ],
- "custom_keys": [],
- "date_created": "1697168063",
- "date_modified": "1744795940",
- "description": "The source namespace for the Pagure Exporter project to run tests against",
- "full_url": "https://pagure.io/protop2g-test-srce",
- "fullname": "protop2g-test-srce",
- "id": 17042,
- "milestones": {
- "Milestone AAAA": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone BBBB": {
- "active": false,
- "date": "1765497600"
- },
- "Milestone CCCC": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone DDDD": {
- "active": false,
- "date": "1765497600"
- }
- },
- "name": "protop2g-test-srce",
- "namespace": null,
- "parent": null,
- "priorities": {
- "": "",
- "1": "Common",
- "2": "Uncommon",
- "3": "Rare",
- "4": "Epic",
- "5": "Mythic"
- },
- "tags": [
- "srce",
- "test",
- "gridhead",
- "protop2g"
- ],
- "url_path": "protop2g-test-srce",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- "remote_git": null,
- "repo_from": {
- "access_groups": {
- "admin": [],
- "collaborator": [],
- "commit": [],
- "ticket": []
- },
- "access_users": {
- "admin": [
- "ryanlerch"
- ],
- "collaborator": [],
- "commit": [],
- "owner": [
- "t0xic0der"
- ],
- "ticket": []
- },
- "close_status": [
- "Complete",
- "Baseless"
- ],
- "custom_keys": [],
- "date_created": "1697168063",
- "date_modified": "1744795940",
- "description": "The source namespace for the Pagure Exporter project to run tests against",
- "full_url": "https://pagure.io/protop2g-test-srce",
- "fullname": "protop2g-test-srce",
- "id": 17042,
- "milestones": {
- "Milestone AAAA": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone BBBB": {
- "active": false,
- "date": "1765497600"
- },
- "Milestone CCCC": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone DDDD": {
- "active": false,
- "date": "1765497600"
- }
- },
- "name": "protop2g-test-srce",
- "namespace": null,
- "parent": null,
- "priorities": {
- "": "",
- "1": "Common",
- "2": "Uncommon",
- "3": "Rare",
- "4": "Epic",
- "5": "Mythic"
- },
- "tags": [
- "srce",
- "test",
- "gridhead",
- "protop2g"
- ],
- "url_path": "protop2g-test-srce",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- "status": "Open",
- "tags": [
- "aaaa"
- ],
- "threshold_reached": null,
- "title": "Change the branch identity to `test-aaaa` in the README.md file",
- "uid": "f9e737c5ccc1434e9798cfd49d192538",
- "updated_on": "1746595529",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
-}
diff --git a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fpull-request%2F6 b/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fpull-request%2F6
deleted file mode 100644
index 46a27d2130..0000000000
--- a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fpull-request%2F6
+++ /dev/null
@@ -1,248 +0,0 @@
-date: Wed, 23 Jul 2025 06:19:47 GMT
-server: Apache/2.4.37 (Red Hat Enterprise Linux) OpenSSL/1.1.1k mod_wsgi/4.6.4 Python/3.6
-x-xss-protection: 1; mode=block
-x-content-type-options: nosniff
-referrer-policy: same-origin
-x-frame-options: ALLOW-FROM https://pagure.io/
-strict-transport-security: max-age=31536000; includeSubDomains; preload
-content-length: 5859
-content-security-policy: default-src 'self';script-src 'self' 'nonce-3mH3rM1hwmaCorIQiTfUsFwdZ'; style-src 'self' 'nonce-3mH3rM1hwmaCorIQiTfUsFwdZ'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-set-cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiNWY5OWMwYjViOTkzZjM0YTY3OTJiYTZmNDk4YzY3MzUwMzY3MzY2OCJ9.G2IQgw.dxyk0aB89uDJGN15BTWrZEvCFWg; Expires=Sat, 23-Aug-2025 06:19:47 GMT; Secure; HttpOnly; Path=/
-content-type: application/json
-
-{
- "assignee": null,
- "branch": "main",
- "branch_from": "test-bbbb",
- "cached_merge_status": "CONFLICTS",
- "closed_at": null,
- "closed_by": null,
- "comments": [
- {
- "comment": "**Metadata Update from @t0xic0der**:\n- Pull-request tagged with: bbbb",
- "commit": null,
- "date_created": "1746427480",
- "edited_on": null,
- "editor": null,
- "filename": null,
- "id": 219087,
- "line": null,
- "notification": true,
- "parent": null,
- "reactions": {},
- "tree": null,
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "This is the first comment under this pull request.",
- "commit": null,
- "date_created": "1746595539",
- "edited_on": null,
- "editor": null,
- "filename": null,
- "id": 219192,
- "line": null,
- "notification": false,
- "parent": null,
- "reactions": {},
- "tree": null,
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "This is the second comment under this pull request.",
- "commit": null,
- "date_created": "1746595552",
- "edited_on": null,
- "editor": null,
- "filename": null,
- "id": 219193,
- "line": null,
- "notification": false,
- "parent": null,
- "reactions": {},
- "tree": null,
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- }
- ],
- "commit_start": "2d40761dc53e6fa060ac49d88e1452c6751d4b1c",
- "commit_stop": "2d40761dc53e6fa060ac49d88e1452c6751d4b1c",
- "date_created": "1746427470",
- "full_url": "https://pagure.io/protop2g-test-srce/pull-request/6",
- "id": 6,
- "initial_comment": "Signed-off-by: Akashdeep Dhar ",
- "last_updated": "1747643450",
- "project": {
- "access_groups": {
- "admin": [],
- "collaborator": [],
- "commit": [],
- "ticket": []
- },
- "access_users": {
- "admin": [
- "ryanlerch"
- ],
- "collaborator": [],
- "commit": [],
- "owner": [
- "t0xic0der"
- ],
- "ticket": []
- },
- "close_status": [
- "Complete",
- "Baseless"
- ],
- "custom_keys": [],
- "date_created": "1697168063",
- "date_modified": "1744795940",
- "description": "The source namespace for the Pagure Exporter project to run tests against",
- "full_url": "https://pagure.io/protop2g-test-srce",
- "fullname": "protop2g-test-srce",
- "id": 17042,
- "milestones": {
- "Milestone AAAA": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone BBBB": {
- "active": false,
- "date": "1765497600"
- },
- "Milestone CCCC": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone DDDD": {
- "active": false,
- "date": "1765497600"
- }
- },
- "name": "protop2g-test-srce",
- "namespace": null,
- "parent": null,
- "priorities": {
- "": "",
- "1": "Common",
- "2": "Uncommon",
- "3": "Rare",
- "4": "Epic",
- "5": "Mythic"
- },
- "tags": [
- "srce",
- "test",
- "gridhead",
- "protop2g"
- ],
- "url_path": "protop2g-test-srce",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- "remote_git": null,
- "repo_from": {
- "access_groups": {
- "admin": [],
- "collaborator": [],
- "commit": [],
- "ticket": []
- },
- "access_users": {
- "admin": [
- "ryanlerch"
- ],
- "collaborator": [],
- "commit": [],
- "owner": [
- "t0xic0der"
- ],
- "ticket": []
- },
- "close_status": [
- "Complete",
- "Baseless"
- ],
- "custom_keys": [],
- "date_created": "1697168063",
- "date_modified": "1744795940",
- "description": "The source namespace for the Pagure Exporter project to run tests against",
- "full_url": "https://pagure.io/protop2g-test-srce",
- "fullname": "protop2g-test-srce",
- "id": 17042,
- "milestones": {
- "Milestone AAAA": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone BBBB": {
- "active": false,
- "date": "1765497600"
- },
- "Milestone CCCC": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone DDDD": {
- "active": false,
- "date": "1765497600"
- }
- },
- "name": "protop2g-test-srce",
- "namespace": null,
- "parent": null,
- "priorities": {
- "": "",
- "1": "Common",
- "2": "Uncommon",
- "3": "Rare",
- "4": "Epic",
- "5": "Mythic"
- },
- "tags": [
- "srce",
- "test",
- "gridhead",
- "protop2g"
- ],
- "url_path": "protop2g-test-srce",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- "status": "Open",
- "tags": [
- "bbbb"
- ],
- "threshold_reached": null,
- "title": "Change the branch identity to `test-bbbb` in the README.md file",
- "uid": "9cab89d6bb8c499e8fcb47926f1f5806",
- "updated_on": "1746595552",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
-}
diff --git a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fpull-request%2F7 b/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fpull-request%2F7
deleted file mode 100644
index 0693dc39f3..0000000000
--- a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fpull-request%2F7
+++ /dev/null
@@ -1,233 +0,0 @@
-date: Wed, 23 Jul 2025 06:20:00 GMT
-server: Apache/2.4.37 (Red Hat Enterprise Linux) OpenSSL/1.1.1k mod_wsgi/4.6.4 Python/3.6
-x-xss-protection: 1; mode=block
-x-content-type-options: nosniff
-referrer-policy: same-origin
-x-frame-options: ALLOW-FROM https://pagure.io/
-strict-transport-security: max-age=31536000; includeSubDomains; preload
-content-length: 5458
-content-security-policy: default-src 'self';script-src 'self' 'nonce-Bq1C3s4EngIGuBgtUcYdmK2M8'; style-src 'self' 'nonce-Bq1C3s4EngIGuBgtUcYdmK2M8'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-set-cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiZjUwNDcwNWQ4Y2UxZTRjODRlNjQxYTA0NzVlNDA5NGQwNzI4YTY1NyJ9.G2IQkA.KtxZfzau2wOwMTyfG_xNBHTMHSI; Expires=Sat, 23-Aug-2025 06:20:00 GMT; Secure; HttpOnly; Path=/
-content-type: application/json
-
-{
- "assignee": null,
- "branch": "main",
- "branch_from": "test-cccc",
- "cached_merge_status": "FFORWARD",
- "closed_at": "1746428043",
- "closed_by": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- },
- "comments": [
- {
- "comment": "**Metadata Update from @t0xic0der**:\n- Pull-request tagged with: cccc",
- "commit": null,
- "date_created": "1746427513",
- "edited_on": null,
- "editor": null,
- "filename": null,
- "id": 219088,
- "line": null,
- "notification": true,
- "parent": null,
- "reactions": {},
- "tree": null,
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "Pull-Request has been closed by t0xic0der",
- "commit": null,
- "date_created": "1746428043",
- "edited_on": null,
- "editor": null,
- "filename": null,
- "id": 219090,
- "line": null,
- "notification": true,
- "parent": null,
- "reactions": {},
- "tree": null,
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- }
- ],
- "commit_start": "f1246e331cade9341b9e4f311b7a134f99893d21",
- "commit_stop": "f1246e331cade9341b9e4f311b7a134f99893d21",
- "date_created": "1746427506",
- "full_url": "https://pagure.io/protop2g-test-srce/pull-request/7",
- "id": 7,
- "initial_comment": "Signed-off-by: Akashdeep Dhar ",
- "last_updated": "1746428043",
- "project": {
- "access_groups": {
- "admin": [],
- "collaborator": [],
- "commit": [],
- "ticket": []
- },
- "access_users": {
- "admin": [
- "ryanlerch"
- ],
- "collaborator": [],
- "commit": [],
- "owner": [
- "t0xic0der"
- ],
- "ticket": []
- },
- "close_status": [
- "Complete",
- "Baseless"
- ],
- "custom_keys": [],
- "date_created": "1697168063",
- "date_modified": "1744795940",
- "description": "The source namespace for the Pagure Exporter project to run tests against",
- "full_url": "https://pagure.io/protop2g-test-srce",
- "fullname": "protop2g-test-srce",
- "id": 17042,
- "milestones": {
- "Milestone AAAA": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone BBBB": {
- "active": false,
- "date": "1765497600"
- },
- "Milestone CCCC": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone DDDD": {
- "active": false,
- "date": "1765497600"
- }
- },
- "name": "protop2g-test-srce",
- "namespace": null,
- "parent": null,
- "priorities": {
- "": "",
- "1": "Common",
- "2": "Uncommon",
- "3": "Rare",
- "4": "Epic",
- "5": "Mythic"
- },
- "tags": [
- "srce",
- "test",
- "gridhead",
- "protop2g"
- ],
- "url_path": "protop2g-test-srce",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- "remote_git": null,
- "repo_from": {
- "access_groups": {
- "admin": [],
- "collaborator": [],
- "commit": [],
- "ticket": []
- },
- "access_users": {
- "admin": [
- "ryanlerch"
- ],
- "collaborator": [],
- "commit": [],
- "owner": [
- "t0xic0der"
- ],
- "ticket": []
- },
- "close_status": [
- "Complete",
- "Baseless"
- ],
- "custom_keys": [],
- "date_created": "1697168063",
- "date_modified": "1744795940",
- "description": "The source namespace for the Pagure Exporter project to run tests against",
- "full_url": "https://pagure.io/protop2g-test-srce",
- "fullname": "protop2g-test-srce",
- "id": 17042,
- "milestones": {
- "Milestone AAAA": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone BBBB": {
- "active": false,
- "date": "1765497600"
- },
- "Milestone CCCC": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone DDDD": {
- "active": false,
- "date": "1765497600"
- }
- },
- "name": "protop2g-test-srce",
- "namespace": null,
- "parent": null,
- "priorities": {
- "": "",
- "1": "Common",
- "2": "Uncommon",
- "3": "Rare",
- "4": "Epic",
- "5": "Mythic"
- },
- "tags": [
- "srce",
- "test",
- "gridhead",
- "protop2g"
- ],
- "url_path": "protop2g-test-srce",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- "status": "Closed",
- "tags": [
- "cccc"
- ],
- "threshold_reached": null,
- "title": "Change the branch identity to `test-cccc` in the README.md file",
- "uid": "f696feab56b84557b4d4a8a4462420ee",
- "updated_on": "1746428043",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
-}
diff --git a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fpull-request%2F8 b/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fpull-request%2F8
deleted file mode 100644
index f5a3ad4712..0000000000
--- a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fpull-request%2F8
+++ /dev/null
@@ -1,233 +0,0 @@
-date: Wed, 23 Jul 2025 06:20:17 GMT
-server: Apache/2.4.37 (Red Hat Enterprise Linux) OpenSSL/1.1.1k mod_wsgi/4.6.4 Python/3.6
-x-xss-protection: 1; mode=block
-x-content-type-options: nosniff
-referrer-policy: same-origin
-x-frame-options: ALLOW-FROM https://pagure.io/
-strict-transport-security: max-age=31536000; includeSubDomains; preload
-content-length: 5458
-content-security-policy: default-src 'self';script-src 'self' 'nonce-OxOLryXyFpTZ0hyi7t17U5IG0'; style-src 'self' 'nonce-OxOLryXyFpTZ0hyi7t17U5IG0'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-set-cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiM2I3NWQwYzBhY2YxMjhmYTU0YmU5NzEzYzcyNjNjZTQ4NjFlNDE5ZCJ9.G2IQoQ.Ds29JFMXbO3q2kBPxmfx2kQ7YjA; Expires=Sat, 23-Aug-2025 06:20:17 GMT; Secure; HttpOnly; Path=/
-content-type: application/json
-
-{
- "assignee": null,
- "branch": "main",
- "branch_from": "test-dddd",
- "cached_merge_status": "FFORWARD",
- "closed_at": "1746428053",
- "closed_by": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- },
- "comments": [
- {
- "comment": "**Metadata Update from @t0xic0der**:\n- Pull-request tagged with: dddd",
- "commit": null,
- "date_created": "1746427540",
- "edited_on": null,
- "editor": null,
- "filename": null,
- "id": 219089,
- "line": null,
- "notification": true,
- "parent": null,
- "reactions": {},
- "tree": null,
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "Pull-Request has been closed by t0xic0der",
- "commit": null,
- "date_created": "1746428053",
- "edited_on": null,
- "editor": null,
- "filename": null,
- "id": 219091,
- "line": null,
- "notification": true,
- "parent": null,
- "reactions": {},
- "tree": null,
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- }
- ],
- "commit_start": "0bc8b0c38e0790e9ef5c8d512a00b9c4dd048160",
- "commit_stop": "0bc8b0c38e0790e9ef5c8d512a00b9c4dd048160",
- "date_created": "1746427532",
- "full_url": "https://pagure.io/protop2g-test-srce/pull-request/8",
- "id": 8,
- "initial_comment": "Signed-off-by: Akashdeep Dhar ",
- "last_updated": "1746428053",
- "project": {
- "access_groups": {
- "admin": [],
- "collaborator": [],
- "commit": [],
- "ticket": []
- },
- "access_users": {
- "admin": [
- "ryanlerch"
- ],
- "collaborator": [],
- "commit": [],
- "owner": [
- "t0xic0der"
- ],
- "ticket": []
- },
- "close_status": [
- "Complete",
- "Baseless"
- ],
- "custom_keys": [],
- "date_created": "1697168063",
- "date_modified": "1744795940",
- "description": "The source namespace for the Pagure Exporter project to run tests against",
- "full_url": "https://pagure.io/protop2g-test-srce",
- "fullname": "protop2g-test-srce",
- "id": 17042,
- "milestones": {
- "Milestone AAAA": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone BBBB": {
- "active": false,
- "date": "1765497600"
- },
- "Milestone CCCC": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone DDDD": {
- "active": false,
- "date": "1765497600"
- }
- },
- "name": "protop2g-test-srce",
- "namespace": null,
- "parent": null,
- "priorities": {
- "": "",
- "1": "Common",
- "2": "Uncommon",
- "3": "Rare",
- "4": "Epic",
- "5": "Mythic"
- },
- "tags": [
- "srce",
- "test",
- "gridhead",
- "protop2g"
- ],
- "url_path": "protop2g-test-srce",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- "remote_git": null,
- "repo_from": {
- "access_groups": {
- "admin": [],
- "collaborator": [],
- "commit": [],
- "ticket": []
- },
- "access_users": {
- "admin": [
- "ryanlerch"
- ],
- "collaborator": [],
- "commit": [],
- "owner": [
- "t0xic0der"
- ],
- "ticket": []
- },
- "close_status": [
- "Complete",
- "Baseless"
- ],
- "custom_keys": [],
- "date_created": "1697168063",
- "date_modified": "1744795940",
- "description": "The source namespace for the Pagure Exporter project to run tests against",
- "full_url": "https://pagure.io/protop2g-test-srce",
- "fullname": "protop2g-test-srce",
- "id": 17042,
- "milestones": {
- "Milestone AAAA": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone BBBB": {
- "active": false,
- "date": "1765497600"
- },
- "Milestone CCCC": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone DDDD": {
- "active": false,
- "date": "1765497600"
- }
- },
- "name": "protop2g-test-srce",
- "namespace": null,
- "parent": null,
- "priorities": {
- "": "",
- "1": "Common",
- "2": "Uncommon",
- "3": "Rare",
- "4": "Epic",
- "5": "Mythic"
- },
- "tags": [
- "srce",
- "test",
- "gridhead",
- "protop2g"
- ],
- "url_path": "protop2g-test-srce",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- "status": "Closed",
- "tags": [
- "dddd"
- ],
- "threshold_reached": null,
- "title": "Change the branch identity to `test-dddd` in the README.md file",
- "uid": "493b294044fd48e18f424210c919d8de",
- "updated_on": "1746428053",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
-}
diff --git a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fpull-request%2F9 b/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fpull-request%2F9
deleted file mode 100644
index f65e51e90d..0000000000
--- a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fpull-request%2F9
+++ /dev/null
@@ -1,238 +0,0 @@
-date: Wed, 23 Jul 2025 06:20:51 GMT
-server: Apache/2.4.37 (Red Hat Enterprise Linux) OpenSSL/1.1.1k mod_wsgi/4.6.4 Python/3.6
-x-xss-protection: 1; mode=block
-x-content-type-options: nosniff
-referrer-policy: same-origin
-x-frame-options: ALLOW-FROM https://pagure.io/
-strict-transport-security: max-age=31536000; includeSubDomains; preload
-content-length: 5628
-content-security-policy: default-src 'self';script-src 'self' 'nonce-RVreTe5AdtWf0rvyk7mxX40mb'; style-src 'self' 'nonce-RVreTe5AdtWf0rvyk7mxX40mb'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-set-cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiM2MyYzdlY2E0MDYzNWRmZjRhMDc2MGE0OTg2MjNhMTU4MWNhZDg4OSJ9.G2IQww.VZpiXbZftgigHkiS15g8DF6iQSY; Expires=Sat, 23-Aug-2025 06:20:51 GMT; Secure; HttpOnly; Path=/
-content-type: application/json
-
-{
- "assignee": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- },
- "branch": "main",
- "branch_from": "test-eeee",
- "cached_merge_status": "unknown",
- "closed_at": "1747635243",
- "closed_by": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- },
- "comments": [
- {
- "comment": "**Metadata Update from @t0xic0der**:\n- Pull-request tagged with: eeee\n- Request assigned",
- "commit": null,
- "date_created": "1747635200",
- "edited_on": null,
- "editor": null,
- "filename": null,
- "id": 219622,
- "line": null,
- "notification": true,
- "parent": null,
- "reactions": {},
- "tree": null,
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "Pull-Request has been merged by t0xic0der",
- "commit": null,
- "date_created": "1747635243",
- "edited_on": null,
- "editor": null,
- "filename": null,
- "id": 219624,
- "line": null,
- "notification": true,
- "parent": null,
- "reactions": {},
- "tree": null,
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- }
- ],
- "commit_start": "01b420e2964928a15f790f9b7c1a0053e7b5f0a5",
- "commit_stop": "01b420e2964928a15f790f9b7c1a0053e7b5f0a5",
- "date_created": "1747635161",
- "full_url": "https://pagure.io/protop2g-test-srce/pull-request/9",
- "id": 9,
- "initial_comment": "Signed-off-by: Akashdeep Dhar ",
- "last_updated": "1747635243",
- "project": {
- "access_groups": {
- "admin": [],
- "collaborator": [],
- "commit": [],
- "ticket": []
- },
- "access_users": {
- "admin": [
- "ryanlerch"
- ],
- "collaborator": [],
- "commit": [],
- "owner": [
- "t0xic0der"
- ],
- "ticket": []
- },
- "close_status": [
- "Complete",
- "Baseless"
- ],
- "custom_keys": [],
- "date_created": "1697168063",
- "date_modified": "1744795940",
- "description": "The source namespace for the Pagure Exporter project to run tests against",
- "full_url": "https://pagure.io/protop2g-test-srce",
- "fullname": "protop2g-test-srce",
- "id": 17042,
- "milestones": {
- "Milestone AAAA": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone BBBB": {
- "active": false,
- "date": "1765497600"
- },
- "Milestone CCCC": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone DDDD": {
- "active": false,
- "date": "1765497600"
- }
- },
- "name": "protop2g-test-srce",
- "namespace": null,
- "parent": null,
- "priorities": {
- "": "",
- "1": "Common",
- "2": "Uncommon",
- "3": "Rare",
- "4": "Epic",
- "5": "Mythic"
- },
- "tags": [
- "srce",
- "test",
- "gridhead",
- "protop2g"
- ],
- "url_path": "protop2g-test-srce",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- "remote_git": null,
- "repo_from": {
- "access_groups": {
- "admin": [],
- "collaborator": [],
- "commit": [],
- "ticket": []
- },
- "access_users": {
- "admin": [
- "ryanlerch"
- ],
- "collaborator": [],
- "commit": [],
- "owner": [
- "t0xic0der"
- ],
- "ticket": []
- },
- "close_status": [
- "Complete",
- "Baseless"
- ],
- "custom_keys": [],
- "date_created": "1697168063",
- "date_modified": "1744795940",
- "description": "The source namespace for the Pagure Exporter project to run tests against",
- "full_url": "https://pagure.io/protop2g-test-srce",
- "fullname": "protop2g-test-srce",
- "id": 17042,
- "milestones": {
- "Milestone AAAA": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone BBBB": {
- "active": false,
- "date": "1765497600"
- },
- "Milestone CCCC": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone DDDD": {
- "active": false,
- "date": "1765497600"
- }
- },
- "name": "protop2g-test-srce",
- "namespace": null,
- "parent": null,
- "priorities": {
- "": "",
- "1": "Common",
- "2": "Uncommon",
- "3": "Rare",
- "4": "Epic",
- "5": "Mythic"
- },
- "tags": [
- "srce",
- "test",
- "gridhead",
- "protop2g"
- ],
- "url_path": "protop2g-test-srce",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- "status": "Merged",
- "tags": [
- "eeee"
- ],
- "threshold_reached": null,
- "title": "Change the branch identity to `test-eeee` in the README.md file",
- "uid": "f2ad806e430a40bd8ee5894484338df4",
- "updated_on": "1747635243",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
-}
diff --git a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fpull-requests b/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fpull-requests
deleted file mode 100644
index a047968f02..0000000000
--- a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fpull-requests
+++ /dev/null
@@ -1,506 +0,0 @@
-date: Wed, 23 Jul 2025 06:18:47 GMT
-server: Apache/2.4.37 (Red Hat Enterprise Linux) OpenSSL/1.1.1k mod_wsgi/4.6.4 Python/3.6
-x-xss-protection: 1; mode=block
-x-content-type-options: nosniff
-referrer-policy: same-origin
-x-frame-options: ALLOW-FROM https://pagure.io/
-strict-transport-security: max-age=31536000; includeSubDomains; preload
-content-length: 14090
-content-security-policy: default-src 'self';script-src 'self' 'nonce-t1H8BCX7kXOBmXS0wHPpBrAhK'; style-src 'self' 'nonce-t1H8BCX7kXOBmXS0wHPpBrAhK'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-set-cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiODAwYWYyZGI3MjZlMzA2ZTdmNTdlMmIwNGVkNmU3YTBmNDYwZDUyMyJ9.G2IQRw.EDXBH36zsKcHKDETH_g7miO_r_w; Expires=Sat, 23-Aug-2025 06:18:47 GMT; Secure; HttpOnly; Path=/
-content-type: application/json
-
-{
- "args": {
- "assignee": null,
- "author": null,
- "page": 1,
- "per_page": 20,
- "status": true,
- "tags": []
- },
- "pagination": {
- "first": "https://pagure.io/api/0/protop2g-test-srce/pull-requests?per_page=20&page=1",
- "last": "https://pagure.io/api/0/protop2g-test-srce/pull-requests?per_page=20&page=1",
- "next": null,
- "page": 1,
- "pages": 1,
- "per_page": 20,
- "prev": null
- },
- "requests": [
- {
- "assignee": null,
- "branch": "main",
- "branch_from": "test-bbbb",
- "cached_merge_status": "CONFLICTS",
- "closed_at": null,
- "closed_by": null,
- "comments": [
- {
- "comment": "**Metadata Update from @t0xic0der**:\n- Pull-request tagged with: bbbb",
- "commit": null,
- "date_created": "1746427480",
- "edited_on": null,
- "editor": null,
- "filename": null,
- "id": 219087,
- "line": null,
- "notification": true,
- "parent": null,
- "reactions": {},
- "tree": null,
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "This is the first comment under this pull request.",
- "commit": null,
- "date_created": "1746595539",
- "edited_on": null,
- "editor": null,
- "filename": null,
- "id": 219192,
- "line": null,
- "notification": false,
- "parent": null,
- "reactions": {},
- "tree": null,
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "This is the second comment under this pull request.",
- "commit": null,
- "date_created": "1746595552",
- "edited_on": null,
- "editor": null,
- "filename": null,
- "id": 219193,
- "line": null,
- "notification": false,
- "parent": null,
- "reactions": {},
- "tree": null,
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- }
- ],
- "commit_start": "2d40761dc53e6fa060ac49d88e1452c6751d4b1c",
- "commit_stop": "2d40761dc53e6fa060ac49d88e1452c6751d4b1c",
- "date_created": "1746427470",
- "full_url": "https://pagure.io/protop2g-test-srce/pull-request/6",
- "id": 6,
- "initial_comment": "Signed-off-by: Akashdeep Dhar ",
- "last_updated": "1747643450",
- "project": {
- "access_groups": {
- "admin": [],
- "collaborator": [],
- "commit": [],
- "ticket": []
- },
- "access_users": {
- "admin": [
- "ryanlerch"
- ],
- "collaborator": [],
- "commit": [],
- "owner": [
- "t0xic0der"
- ],
- "ticket": []
- },
- "close_status": [
- "Complete",
- "Baseless"
- ],
- "custom_keys": [],
- "date_created": "1697168063",
- "date_modified": "1744795940",
- "description": "The source namespace for the Pagure Exporter project to run tests against",
- "full_url": "https://pagure.io/protop2g-test-srce",
- "fullname": "protop2g-test-srce",
- "id": 17042,
- "milestones": {
- "Milestone AAAA": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone BBBB": {
- "active": false,
- "date": "1765497600"
- },
- "Milestone CCCC": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone DDDD": {
- "active": false,
- "date": "1765497600"
- }
- },
- "name": "protop2g-test-srce",
- "namespace": null,
- "parent": null,
- "priorities": {
- "": "",
- "1": "Common",
- "2": "Uncommon",
- "3": "Rare",
- "4": "Epic",
- "5": "Mythic"
- },
- "tags": [
- "srce",
- "test",
- "gridhead",
- "protop2g"
- ],
- "url_path": "protop2g-test-srce",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- "remote_git": null,
- "repo_from": {
- "access_groups": {
- "admin": [],
- "collaborator": [],
- "commit": [],
- "ticket": []
- },
- "access_users": {
- "admin": [
- "ryanlerch"
- ],
- "collaborator": [],
- "commit": [],
- "owner": [
- "t0xic0der"
- ],
- "ticket": []
- },
- "close_status": [
- "Complete",
- "Baseless"
- ],
- "custom_keys": [],
- "date_created": "1697168063",
- "date_modified": "1744795940",
- "description": "The source namespace for the Pagure Exporter project to run tests against",
- "full_url": "https://pagure.io/protop2g-test-srce",
- "fullname": "protop2g-test-srce",
- "id": 17042,
- "milestones": {
- "Milestone AAAA": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone BBBB": {
- "active": false,
- "date": "1765497600"
- },
- "Milestone CCCC": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone DDDD": {
- "active": false,
- "date": "1765497600"
- }
- },
- "name": "protop2g-test-srce",
- "namespace": null,
- "parent": null,
- "priorities": {
- "": "",
- "1": "Common",
- "2": "Uncommon",
- "3": "Rare",
- "4": "Epic",
- "5": "Mythic"
- },
- "tags": [
- "srce",
- "test",
- "gridhead",
- "protop2g"
- ],
- "url_path": "protop2g-test-srce",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- "status": "Open",
- "tags": [
- "bbbb"
- ],
- "threshold_reached": null,
- "title": "Change the branch identity to `test-bbbb` in the README.md file",
- "uid": "9cab89d6bb8c499e8fcb47926f1f5806",
- "updated_on": "1746595552",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "assignee": null,
- "branch": "main",
- "branch_from": "test-aaaa",
- "cached_merge_status": "CONFLICTS",
- "closed_at": null,
- "closed_by": null,
- "comments": [
- {
- "comment": "**Metadata Update from @t0xic0der**:\n- Pull-request tagged with: aaaa",
- "commit": null,
- "date_created": "1746427453",
- "edited_on": null,
- "editor": null,
- "filename": null,
- "id": 219086,
- "line": null,
- "notification": true,
- "parent": null,
- "reactions": {},
- "tree": null,
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "This is the first comment under this pull request.",
- "commit": null,
- "date_created": "1746595521",
- "edited_on": null,
- "editor": null,
- "filename": null,
- "id": 219190,
- "line": null,
- "notification": false,
- "parent": null,
- "reactions": {},
- "tree": null,
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "This is the second comment under this pull request.",
- "commit": null,
- "date_created": "1746595529",
- "edited_on": null,
- "editor": null,
- "filename": null,
- "id": 219191,
- "line": null,
- "notification": false,
- "parent": null,
- "reactions": {},
- "tree": null,
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- }
- ],
- "commit_start": "b55e5c91d2572d60a8d7e71b3d3003e523127bd4",
- "commit_stop": "b55e5c91d2572d60a8d7e71b3d3003e523127bd4",
- "date_created": "1746427437",
- "full_url": "https://pagure.io/protop2g-test-srce/pull-request/5",
- "id": 5,
- "initial_comment": "Signed-off-by: Akashdeep Dhar ",
- "last_updated": "1747636185",
- "project": {
- "access_groups": {
- "admin": [],
- "collaborator": [],
- "commit": [],
- "ticket": []
- },
- "access_users": {
- "admin": [
- "ryanlerch"
- ],
- "collaborator": [],
- "commit": [],
- "owner": [
- "t0xic0der"
- ],
- "ticket": []
- },
- "close_status": [
- "Complete",
- "Baseless"
- ],
- "custom_keys": [],
- "date_created": "1697168063",
- "date_modified": "1744795940",
- "description": "The source namespace for the Pagure Exporter project to run tests against",
- "full_url": "https://pagure.io/protop2g-test-srce",
- "fullname": "protop2g-test-srce",
- "id": 17042,
- "milestones": {
- "Milestone AAAA": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone BBBB": {
- "active": false,
- "date": "1765497600"
- },
- "Milestone CCCC": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone DDDD": {
- "active": false,
- "date": "1765497600"
- }
- },
- "name": "protop2g-test-srce",
- "namespace": null,
- "parent": null,
- "priorities": {
- "": "",
- "1": "Common",
- "2": "Uncommon",
- "3": "Rare",
- "4": "Epic",
- "5": "Mythic"
- },
- "tags": [
- "srce",
- "test",
- "gridhead",
- "protop2g"
- ],
- "url_path": "protop2g-test-srce",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- "remote_git": null,
- "repo_from": {
- "access_groups": {
- "admin": [],
- "collaborator": [],
- "commit": [],
- "ticket": []
- },
- "access_users": {
- "admin": [
- "ryanlerch"
- ],
- "collaborator": [],
- "commit": [],
- "owner": [
- "t0xic0der"
- ],
- "ticket": []
- },
- "close_status": [
- "Complete",
- "Baseless"
- ],
- "custom_keys": [],
- "date_created": "1697168063",
- "date_modified": "1744795940",
- "description": "The source namespace for the Pagure Exporter project to run tests against",
- "full_url": "https://pagure.io/protop2g-test-srce",
- "fullname": "protop2g-test-srce",
- "id": 17042,
- "milestones": {
- "Milestone AAAA": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone BBBB": {
- "active": false,
- "date": "1765497600"
- },
- "Milestone CCCC": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone DDDD": {
- "active": false,
- "date": "1765497600"
- }
- },
- "name": "protop2g-test-srce",
- "namespace": null,
- "parent": null,
- "priorities": {
- "": "",
- "1": "Common",
- "2": "Uncommon",
- "3": "Rare",
- "4": "Epic",
- "5": "Mythic"
- },
- "tags": [
- "srce",
- "test",
- "gridhead",
- "protop2g"
- ],
- "url_path": "protop2g-test-srce",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- "status": "Open",
- "tags": [
- "aaaa"
- ],
- "threshold_reached": null,
- "title": "Change the branch identity to `test-aaaa` in the README.md file",
- "uid": "f9e737c5ccc1434e9798cfd49d192538",
- "updated_on": "1746595529",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- }
- ],
- "total_requests": 2
-}
diff --git a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Faaaa b/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Faaaa
deleted file mode 100644
index 5afe87654e..0000000000
--- a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Faaaa
+++ /dev/null
@@ -1,17 +0,0 @@
-date: Wed, 23 Jul 2025 05:34:39 GMT
-server: Apache/2.4.37 (Red Hat Enterprise Linux) OpenSSL/1.1.1k mod_wsgi/4.6.4 Python/3.6
-x-xss-protection: 1; mode=block
-x-content-type-options: nosniff
-referrer-policy: same-origin
-x-frame-options: ALLOW-FROM https://pagure.io/
-strict-transport-security: max-age=31536000; includeSubDomains; preload
-content-length: 77
-content-security-policy: default-src 'self';script-src 'self' 'nonce-gI8Srx27RgY20Zqw5vVkWVORV'; style-src 'self' 'nonce-gI8Srx27RgY20Zqw5vVkWVORV'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-set-cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiZmJhYTlmMTAzYzYxMWE5NmZiZDNkZjE1ZmRiZGQzYTA5YTQ1YTM2YyJ9.G2IF7w.CLP1edDfZSoJcXjoUNt40swcBV8; Expires=Sat, 23-Aug-2025 05:34:39 GMT; Secure; HttpOnly; Path=/
-content-type: application/json
-
-{
- "tag": "aaaa",
- "tag_color": "#ff0000",
- "tag_description": "aaaa"
-}
diff --git a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Fbbbb b/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Fbbbb
deleted file mode 100644
index 37d40b9c6e..0000000000
--- a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Fbbbb
+++ /dev/null
@@ -1,17 +0,0 @@
-date: Wed, 23 Jul 2025 05:34:50 GMT
-server: Apache/2.4.37 (Red Hat Enterprise Linux) OpenSSL/1.1.1k mod_wsgi/4.6.4 Python/3.6
-x-xss-protection: 1; mode=block
-x-content-type-options: nosniff
-referrer-policy: same-origin
-x-frame-options: ALLOW-FROM https://pagure.io/
-strict-transport-security: max-age=31536000; includeSubDomains; preload
-content-length: 77
-content-security-policy: default-src 'self';script-src 'self' 'nonce-wgQpgRvwBbyoY9WWTv55wb8Dd'; style-src 'self' 'nonce-wgQpgRvwBbyoY9WWTv55wb8Dd'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-set-cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiZWU4ZDUxYzY4NmUzMzM4ODg4YmRmMjQwYmU3ODVhOTA4MzQ4N2Q2NiJ9.G2IF-g.nG1k1zU4b9Eo9WFGCas8R9a5-Vg; Expires=Sat, 23-Aug-2025 05:34:50 GMT; Secure; HttpOnly; Path=/
-content-type: application/json
-
-{
- "tag": "bbbb",
- "tag_color": "#ff0000",
- "tag_description": "bbbb"
-}
diff --git a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Fcccc b/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Fcccc
deleted file mode 100644
index 4f170a50fe..0000000000
--- a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Fcccc
+++ /dev/null
@@ -1,17 +0,0 @@
-date: Wed, 23 Jul 2025 05:35:02 GMT
-server: Apache/2.4.37 (Red Hat Enterprise Linux) OpenSSL/1.1.1k mod_wsgi/4.6.4 Python/3.6
-x-xss-protection: 1; mode=block
-x-content-type-options: nosniff
-referrer-policy: same-origin
-x-frame-options: ALLOW-FROM https://pagure.io/
-strict-transport-security: max-age=31536000; includeSubDomains; preload
-content-length: 77
-content-security-policy: default-src 'self';script-src 'self' 'nonce-kAxTKES1vWlzLCIScejGQ5JpX'; style-src 'self' 'nonce-kAxTKES1vWlzLCIScejGQ5JpX'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-set-cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiYjhhM2YxNjJhZDYwYWU5NzE4NmQ4NDBkMzJlOWNkYmYxN2Y2NjBmMyJ9.G2IGBg.oA7d9DJHW4_ilpbiVkbveF5dM3Q; Expires=Sat, 23-Aug-2025 05:35:02 GMT; Secure; HttpOnly; Path=/
-content-type: application/json
-
-{
- "tag": "cccc",
- "tag_color": "#ffff00",
- "tag_description": "cccc"
-}
diff --git a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Fdddd b/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Fdddd
deleted file mode 100644
index fb79ce7a97..0000000000
--- a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Fdddd
+++ /dev/null
@@ -1,17 +0,0 @@
-date: Wed, 23 Jul 2025 05:36:23 GMT
-server: Apache/2.4.37 (Red Hat Enterprise Linux) OpenSSL/1.1.1k mod_wsgi/4.6.4 Python/3.6
-x-xss-protection: 1; mode=block
-x-content-type-options: nosniff
-referrer-policy: same-origin
-x-frame-options: ALLOW-FROM https://pagure.io/
-strict-transport-security: max-age=31536000; includeSubDomains; preload
-content-length: 77
-content-security-policy: default-src 'self';script-src 'self' 'nonce-rzXQsxeaBjeye4rVcEn3aSWKa'; style-src 'self' 'nonce-rzXQsxeaBjeye4rVcEn3aSWKa'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-set-cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiY2VhZjRhOTlkZWUxZDcxODg2NWIyN2JhZGY4ZjUyMjcxZTdkZGU0MyJ9.G2IGVw.JCK3tXfD0aOgDdIAMv5MlFkl-SY; Expires=Sat, 23-Aug-2025 05:36:23 GMT; Secure; HttpOnly; Path=/
-content-type: application/json
-
-{
- "tag": "dddd",
- "tag_color": "#ffff00",
- "tag_description": "dddd"
-}
diff --git a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Feeee b/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Feeee
deleted file mode 100644
index 5e968f23b9..0000000000
--- a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Feeee
+++ /dev/null
@@ -1,17 +0,0 @@
-date: Wed, 23 Jul 2025 05:36:34 GMT
-server: Apache/2.4.37 (Red Hat Enterprise Linux) OpenSSL/1.1.1k mod_wsgi/4.6.4 Python/3.6
-x-xss-protection: 1; mode=block
-x-content-type-options: nosniff
-referrer-policy: same-origin
-x-frame-options: ALLOW-FROM https://pagure.io/
-strict-transport-security: max-age=31536000; includeSubDomains; preload
-content-length: 77
-content-security-policy: default-src 'self';script-src 'self' 'nonce-gs07ooad3wPkkzZKAQDHDTrMl'; style-src 'self' 'nonce-gs07ooad3wPkkzZKAQDHDTrMl'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-set-cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiOGEyNDUwYzk5MDY2ZjJhZGQyNDhlZmZmM2QxN2UxZTM0ODI2NWFhZiJ9.G2IGYg.hM6ZKEPDXtOvTWlSPeQBLiZjCO4; Expires=Sat, 23-Aug-2025 05:36:34 GMT; Secure; HttpOnly; Path=/
-content-type: application/json
-
-{
- "tag": "eeee",
- "tag_color": "#00ff00",
- "tag_description": "eeee"
-}
diff --git a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Fffff b/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Fffff
deleted file mode 100644
index 83d48ee851..0000000000
--- a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Fffff
+++ /dev/null
@@ -1,17 +0,0 @@
-date: Wed, 23 Jul 2025 05:36:48 GMT
-server: Apache/2.4.37 (Red Hat Enterprise Linux) OpenSSL/1.1.1k mod_wsgi/4.6.4 Python/3.6
-x-xss-protection: 1; mode=block
-x-content-type-options: nosniff
-referrer-policy: same-origin
-x-frame-options: ALLOW-FROM https://pagure.io/
-strict-transport-security: max-age=31536000; includeSubDomains; preload
-content-length: 77
-content-security-policy: default-src 'self';script-src 'self' 'nonce-hiIOP1ZdLfgxJERlzriEOATjs'; style-src 'self' 'nonce-hiIOP1ZdLfgxJERlzriEOATjs'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-set-cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiYWMyNjBhNjE5MjI0OTQ0YTU2Yzc5YjNmNzU3ZTU2MTYzZGQwMGMwNSJ9.G2IGcQ.22KbaZBjPxJkpIoTBIn1UtVzEjI; Expires=Sat, 23-Aug-2025 05:36:49 GMT; Secure; HttpOnly; Path=/
-content-type: application/json
-
-{
- "tag": "ffff",
- "tag_color": "#00ff00",
- "tag_description": "ffff"
-}
diff --git a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Fgggg b/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Fgggg
deleted file mode 100644
index 85a07333f8..0000000000
--- a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Fgggg
+++ /dev/null
@@ -1,17 +0,0 @@
-date: Wed, 23 Jul 2025 05:37:23 GMT
-server: Apache/2.4.37 (Red Hat Enterprise Linux) OpenSSL/1.1.1k mod_wsgi/4.6.4 Python/3.6
-x-xss-protection: 1; mode=block
-x-content-type-options: nosniff
-referrer-policy: same-origin
-x-frame-options: ALLOW-FROM https://pagure.io/
-strict-transport-security: max-age=31536000; includeSubDomains; preload
-content-length: 77
-content-security-policy: default-src 'self';script-src 'self' 'nonce-FYnaELqaJomAM4RnLtKUr7gbE'; style-src 'self' 'nonce-FYnaELqaJomAM4RnLtKUr7gbE'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-set-cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiOGExMmI2MGZhYTQyYTY5MmQ0MzNkNWFlZTU0YjE4M2NjY2NmYjI3MCJ9.G2IGkw.9-wL70lPAOlpIv8cusGLLA0Np_U; Expires=Sat, 23-Aug-2025 05:37:23 GMT; Secure; HttpOnly; Path=/
-content-type: application/json
-
-{
- "tag": "gggg",
- "tag_color": "#0000ff",
- "tag_description": "gggg"
-}
diff --git a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftags b/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftags
deleted file mode 100644
index 131f4b34a8..0000000000
--- a/services/migrations/testdata/pagure/full_download/authorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftags
+++ /dev/null
@@ -1,25 +0,0 @@
-date: Wed, 23 Jul 2025 05:16:48 GMT
-server: Apache/2.4.37 (Red Hat Enterprise Linux) OpenSSL/1.1.1k mod_wsgi/4.6.4 Python/3.6
-x-xss-protection: 1; mode=block
-x-content-type-options: nosniff
-referrer-policy: same-origin
-x-frame-options: ALLOW-FROM https://pagure.io/
-strict-transport-security: max-age=31536000; includeSubDomains; preload
-content-length: 142
-content-security-policy: default-src 'self';script-src 'self' 'nonce-T8LPhGGs1acv00t58vtBtVmwC'; style-src 'self' 'nonce-T8LPhGGs1acv00t58vtBtVmwC'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-set-cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiYmQ2NTQ1MmFhZWJjZjA0OWIxNTI5MjBjODQyYzUzOGRkYmYyYTkwOSJ9.G2IBwA.pKqOBVDJrtKfyrbJPyuaRfFjnR4; Expires=Sat, 23-Aug-2025 05:16:48 GMT; Secure; HttpOnly; Path=/
-content-type: application/json
-
-{
- "tags": [
- "aaaa",
- "bbbb",
- "cccc",
- "dddd",
- "eeee",
- "ffff",
- "gggg",
- "hhhh"
- ],
- "total_tags": 8
-}
diff --git a/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce b/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce
deleted file mode 100644
index ef69d4bdb8..0000000000
--- a/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce
+++ /dev/null
@@ -1,82 +0,0 @@
-Content-Length: 1464
-Content-Security-Policy: default-src 'self';script-src 'self' 'nonce-tnXvEZGNmF5HI1BOPEvAXnIFi'; style-src 'self' 'nonce-tnXvEZGNmF5HI1BOPEvAXnIFi'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-Set-Cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiOGEzYjk3NGI3NWM1MjdjYzY5MjdhM2E5MjZhNjZiZTBlNWFmYjM5MCJ9.G4-gsg.8A24PiXaZg1Cu-jRIk80lUXLWFo; Expires=Fri, 26-Sep-2025 19:46:58 GMT; Secure; HttpOnly; Path=/
-Content-Type: application/json
-X-Xss-Protection: 1; mode=block
-X-Content-Type-Options: nosniff
-Referrer-Policy: same-origin
-X-Frame-Options: ALLOW-FROM https://pagure.io/
-Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
-
-{
- "access_groups": {
- "admin": [],
- "collaborator": [],
- "commit": [],
- "ticket": []
- },
- "access_users": {
- "admin": [
- "ryanlerch"
- ],
- "collaborator": [],
- "commit": [],
- "owner": [
- "t0xic0der"
- ],
- "ticket": []
- },
- "close_status": [
- "Complete",
- "Baseless"
- ],
- "custom_keys": [],
- "date_created": "1697168063",
- "date_modified": "1744795940",
- "description": "The source namespace for the Pagure Exporter project to run tests against",
- "full_url": "https://pagure.io/protop2g-test-srce",
- "fullname": "protop2g-test-srce",
- "id": 17042,
- "milestones": {
- "Milestone AAAA": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone BBBB": {
- "active": false,
- "date": "1765497600"
- },
- "Milestone CCCC": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone DDDD": {
- "active": false,
- "date": "1765497600"
- }
- },
- "name": "protop2g-test-srce",
- "namespace": null,
- "parent": null,
- "priorities": {
- "": "",
- "1": "Common",
- "2": "Uncommon",
- "3": "Rare",
- "4": "Epic",
- "5": "Mythic"
- },
- "tags": [
- "srce",
- "test",
- "gridhead",
- "protop2g"
- ],
- "url_path": "protop2g-test-srce",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
-}
diff --git a/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fc%2F01b420e2964928a15f790f9b7c1a0053e7b5f0a5%2Finfo b/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fc%2F01b420e2964928a15f790f9b7c1a0053e7b5f0a5%2Finfo
deleted file mode 100644
index 2501f4f6e3..0000000000
--- a/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fc%2F01b420e2964928a15f790f9b7c1a0053e7b5f0a5%2Finfo
+++ /dev/null
@@ -1,22 +0,0 @@
-Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
-X-Xss-Protection: 1; mode=block
-Referrer-Policy: same-origin
-Content-Length: 452
-Content-Security-Policy: default-src 'self';script-src 'self' 'nonce-Y3ZN3d6QZqSLwh8xAkWYBzeiT'; style-src 'self' 'nonce-Y3ZN3d6QZqSLwh8xAkWYBzeiT'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-Set-Cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiMzJiMzRmYTllNjVkMTQzYjQzNGIxOTlmNzliODZlOTRjMzA3NmQ1MiJ9.G4-gtg.PdKDFShx8RPQiN9BHaw7eAf_uzI; Expires=Fri, 26-Sep-2025 19:47:02 GMT; Secure; HttpOnly; Path=/
-Content-Type: application/json
-X-Content-Type-Options: nosniff
-X-Frame-Options: ALLOW-FROM https://pagure.io/
-
-{
- "author": "Akashdeep Dhar",
- "commit_time": 1747635011,
- "commit_time_offset": 0,
- "committer": "Akashdeep Dhar",
- "hash": "01b420e2964928a15f790f9b7c1a0053e7b5f0a5",
- "message": "Change the branch identity to `test-eeee` in the README.md file\n\nSigned-off-by: Akashdeep Dhar \n",
- "parent_ids": [
- "3f12d300f62f1c5b8a1d3265bd85d61cf6d924d7"
- ],
- "tree_id": "1e8fa9a17b4b4ddde50f334626b0a5497070cff7"
-}
diff --git a/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fc%2F0bc8b0c38e0790e9ef5c8d512a00b9c4dd048160%2Finfo b/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fc%2F0bc8b0c38e0790e9ef5c8d512a00b9c4dd048160%2Finfo
deleted file mode 100644
index 89e6c4cae6..0000000000
--- a/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fc%2F0bc8b0c38e0790e9ef5c8d512a00b9c4dd048160%2Finfo
+++ /dev/null
@@ -1,22 +0,0 @@
-Referrer-Policy: same-origin
-X-Frame-Options: ALLOW-FROM https://pagure.io/
-Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
-Set-Cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiNGU2MzY4YmE0MGE3NDdhYWVlZDUwNDczOTlhMWZiZGY5YjhjNWJjMSJ9.G4-gtg.nsP6pJHATDf8xW73FOOSlwhGUkE; Expires=Fri, 26-Sep-2025 19:47:02 GMT; Secure; HttpOnly; Path=/
-Content-Length: 454
-Content-Security-Policy: default-src 'self';script-src 'self' 'nonce-LfLHOABekbvGWQH4XCgWCCMsc'; style-src 'self' 'nonce-LfLHOABekbvGWQH4XCgWCCMsc'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-Content-Type: application/json
-X-Xss-Protection: 1; mode=block
-X-Content-Type-Options: nosniff
-
-{
- "author": "Akashdeep Dhar",
- "commit_time": 1697169509,
- "commit_time_offset": 330,
- "committer": "Akashdeep Dhar",
- "hash": "0bc8b0c38e0790e9ef5c8d512a00b9c4dd048160",
- "message": "Change the branch identity to `test-dddd` in the README.md file\n\nSigned-off-by: Akashdeep Dhar \n",
- "parent_ids": [
- "3f12d300f62f1c5b8a1d3265bd85d61cf6d924d7"
- ],
- "tree_id": "586a1e8a79e572691dc086ef7bf4e2f6d34c5254"
-}
diff --git a/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fc%2F1a6ccc212aa958a0fe76155c2907c889969a7224%2Finfo b/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fc%2F1a6ccc212aa958a0fe76155c2907c889969a7224%2Finfo
deleted file mode 100644
index 5fc6687589..0000000000
--- a/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fc%2F1a6ccc212aa958a0fe76155c2907c889969a7224%2Finfo
+++ /dev/null
@@ -1,22 +0,0 @@
-X-Xss-Protection: 1; mode=block
-Content-Length: 452
-Set-Cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiZDAxNjdjNGQwYTI4ZDRiY2RlNDVmN2NmMjE4YmExOTEyZDQyMTNhMCJ9.G4-gtQ.pOTn9bI3Kb4T50pd_-8wV840Reg; Expires=Fri, 26-Sep-2025 19:47:01 GMT; Secure; HttpOnly; Path=/
-Content-Type: application/json
-X-Content-Type-Options: nosniff
-Referrer-Policy: same-origin
-X-Frame-Options: ALLOW-FROM https://pagure.io/
-Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
-Content-Security-Policy: default-src 'self';script-src 'self' 'nonce-ye8eyhQR7cRy062VVRWLSeYzI'; style-src 'self' 'nonce-ye8eyhQR7cRy062VVRWLSeYzI'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-
-{
- "author": "Akashdeep Dhar",
- "commit_time": 1747635352,
- "commit_time_offset": 0,
- "committer": "Akashdeep Dhar",
- "hash": "1a6ccc212aa958a0fe76155c2907c889969a7224",
- "message": "Change the branch identity to `test-ffff` in the README.md file\n\nSigned-off-by: Akashdeep Dhar \n",
- "parent_ids": [
- "01b420e2964928a15f790f9b7c1a0053e7b5f0a5"
- ],
- "tree_id": "0c5e64a6b912cb0c3d66e66896fa98a98da69fe4"
-}
diff --git a/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fc%2F2d40761dc53e6fa060ac49d88e1452c6751d4b1c%2Finfo b/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fc%2F2d40761dc53e6fa060ac49d88e1452c6751d4b1c%2Finfo
deleted file mode 100644
index 637f9b44da..0000000000
--- a/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fc%2F2d40761dc53e6fa060ac49d88e1452c6751d4b1c%2Finfo
+++ /dev/null
@@ -1,22 +0,0 @@
-Content-Type: application/json
-X-Xss-Protection: 1; mode=block
-Referrer-Policy: same-origin
-X-Frame-Options: ALLOW-FROM https://pagure.io/
-Content-Security-Policy: default-src 'self';script-src 'self' 'nonce-z4zIwQCgXhVVY9lil5w37aAVg'; style-src 'self' 'nonce-z4zIwQCgXhVVY9lil5w37aAVg'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-X-Content-Type-Options: nosniff
-Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
-Content-Length: 454
-Set-Cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiNzRiY2Q2NzUzYmMyMDgyZmNmYTQ2NGQ0N2Y5ODhmNjhiMzYxMjMwMyJ9.G4-gtg.mUZvuxqGocR65nDhnE43Iwl7qtQ; Expires=Fri, 26-Sep-2025 19:47:02 GMT; Secure; HttpOnly; Path=/
-
-{
- "author": "Akashdeep Dhar",
- "commit_time": 1697169040,
- "commit_time_offset": 330,
- "committer": "Akashdeep Dhar",
- "hash": "2d40761dc53e6fa060ac49d88e1452c6751d4b1c",
- "message": "Change the branch identity to `test-bbbb` in the README.md file\n\nSigned-off-by: Akashdeep Dhar \n",
- "parent_ids": [
- "3f12d300f62f1c5b8a1d3265bd85d61cf6d924d7"
- ],
- "tree_id": "7a23fc15f5a1463f2c425f0146def7c19ecf6c88"
-}
diff --git a/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fc%2Fb55e5c91d2572d60a8d7e71b3d3003e523127bd4%2Finfo b/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fc%2Fb55e5c91d2572d60a8d7e71b3d3003e523127bd4%2Finfo
deleted file mode 100644
index 5f04c62717..0000000000
--- a/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fc%2Fb55e5c91d2572d60a8d7e71b3d3003e523127bd4%2Finfo
+++ /dev/null
@@ -1,22 +0,0 @@
-X-Content-Type-Options: nosniff
-Content-Length: 454
-Set-Cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiZGYyYjkwMjU1YWI2MTU1MGMzN2IwNDk5NDMyNmQ5MDhjOTQwNDM1MCJ9.G4-gtg.lauXHyPuU-GpljnUX7l5muhxnQ4; Expires=Fri, 26-Sep-2025 19:47:02 GMT; Secure; HttpOnly; Path=/
-Content-Type: application/json
-X-Xss-Protection: 1; mode=block
-Referrer-Policy: same-origin
-X-Frame-Options: ALLOW-FROM https://pagure.io/
-Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
-Content-Security-Policy: default-src 'self';script-src 'self' 'nonce-gTkLO2hyzMbZ7VoCsariFBw5p'; style-src 'self' 'nonce-gTkLO2hyzMbZ7VoCsariFBw5p'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-
-{
- "author": "Akashdeep Dhar",
- "commit_time": 1697169185,
- "commit_time_offset": 330,
- "committer": "Akashdeep Dhar",
- "hash": "b55e5c91d2572d60a8d7e71b3d3003e523127bd4",
- "message": "Change the branch identity to `test-aaaa` in the README.md file\n\nSigned-off-by: Akashdeep Dhar \n",
- "parent_ids": [
- "3f12d300f62f1c5b8a1d3265bd85d61cf6d924d7"
- ],
- "tree_id": "e7911825d29e73f260de95d5070898ccbe6340a6"
-}
diff --git a/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fc%2Ff1246e331cade9341b9e4f311b7a134f99893d21%2Finfo b/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fc%2Ff1246e331cade9341b9e4f311b7a134f99893d21%2Finfo
deleted file mode 100644
index a0f1ee088e..0000000000
--- a/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fc%2Ff1246e331cade9341b9e4f311b7a134f99893d21%2Finfo
+++ /dev/null
@@ -1,22 +0,0 @@
-Content-Length: 454
-Set-Cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiYWQyOWJlMDZjOTE5OTdlMGJjZDY5Y2U2NWZiZDQ1N2I0YzFjNzcyYiJ9.G4-gtg.AcC4LKuD5ETKZhTYsrK7sIMQTkU; Expires=Fri, 26-Sep-2025 19:47:02 GMT; Secure; HttpOnly; Path=/
-Content-Type: application/json
-X-Xss-Protection: 1; mode=block
-X-Content-Type-Options: nosniff
-Referrer-Policy: same-origin
-X-Frame-Options: ALLOW-FROM https://pagure.io/
-Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
-Content-Security-Policy: default-src 'self';script-src 'self' 'nonce-7wtiizCOJwkK1brnaNWuEQwLc'; style-src 'self' 'nonce-7wtiizCOJwkK1brnaNWuEQwLc'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-
-{
- "author": "Akashdeep Dhar",
- "commit_time": 1697169354,
- "commit_time_offset": 330,
- "committer": "Akashdeep Dhar",
- "hash": "f1246e331cade9341b9e4f311b7a134f99893d21",
- "message": "Change the branch identity to `test-cccc` in the README.md file\n\nSigned-off-by: Akashdeep Dhar \n",
- "parent_ids": [
- "3f12d300f62f1c5b8a1d3265bd85d61cf6d924d7"
- ],
- "tree_id": "f1e37736d409bb136451dfc8e3a2017d3af2ce7d"
-}
diff --git a/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fissue%2F2 b/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fissue%2F2
deleted file mode 100644
index 34547248b4..0000000000
--- a/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fissue%2F2
+++ /dev/null
@@ -1,191 +0,0 @@
-X-Xss-Protection: 1; mode=block
-X-Content-Type-Options: nosniff
-Referrer-Policy: same-origin
-Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
-Content-Length: 5327
-Content-Security-Policy: default-src 'self';script-src 'self' 'nonce-ZantBGThWBCI2APLt4SMU7xGo'; style-src 'self' 'nonce-ZantBGThWBCI2APLt4SMU7xGo'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-Set-Cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiN2MyZWQyMWNlNTAyMDZhYTNlNjY2MThhZWE1ODJhM2Q0YjNlYWJiOCJ9.G4-gtQ.qChOO4poXg469ntQDFbUfu7Cdoo; Expires=Fri, 26-Sep-2025 19:47:01 GMT; Secure; HttpOnly; Path=/
-X-Frame-Options: ALLOW-FROM https://pagure.io/
-Content-Type: application/json
-
-{
- "assignee": null,
- "blocks": [],
- "close_status": "Complete",
- "closed_at": "1750832579",
- "closed_by": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- },
- "comments": [
- {
- "comment": "**Metadata Update from @t0xic0der**:\n- Issue tagged with: cccc, dddd",
- "date_created": "1697169810",
- "edited_on": null,
- "editor": null,
- "id": 878472,
- "notification": true,
- "parent": null,
- "reactions": {},
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "The is the first comment under the second test issue",
- "date_created": "1697169964",
- "edited_on": null,
- "editor": null,
- "id": 878475,
- "notification": false,
- "parent": null,
- "reactions": {},
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "The is the second comment under the second test issue",
- "date_created": "1697169976",
- "edited_on": null,
- "editor": null,
- "id": 878476,
- "notification": false,
- "parent": null,
- "reactions": {},
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "**Metadata Update from @t0xic0der**:\n- Issue status updated to: Closed (was: Open)",
- "date_created": "1697170032",
- "edited_on": null,
- "editor": null,
- "id": 878477,
- "notification": true,
- "parent": null,
- "reactions": {},
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "**Metadata Update from @t0xic0der**:\n- Issue set to the milestone: Milestone BBBB",
- "date_created": "1746679821",
- "edited_on": null,
- "editor": null,
- "id": 971678,
- "notification": true,
- "parent": null,
- "reactions": {},
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "**Metadata Update from @t0xic0der**:\n- Issue set to the milestone: None (was: Milestone BBBB)\n- Issue status updated to: Open (was: Closed)",
- "date_created": "1750832572",
- "edited_on": null,
- "editor": null,
- "id": 976713,
- "notification": true,
- "parent": null,
- "reactions": {},
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "**Metadata Update from @t0xic0der**:\n- Issue close_status updated to: Complete\n- Issue status updated to: Closed (was: Open)",
- "date_created": "1750832582",
- "edited_on": null,
- "editor": null,
- "id": 976714,
- "notification": true,
- "parent": null,
- "reactions": {},
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "**Metadata Update from @t0xic0der**:\n- Issue set to the milestone: Milestone BBBB",
- "date_created": "1750832674",
- "edited_on": null,
- "editor": null,
- "id": 976717,
- "notification": true,
- "parent": null,
- "reactions": {},
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "**Metadata Update from @t0xic0der**:\n- Issue priority set to: Rare",
- "date_created": "1750832757",
- "edited_on": null,
- "editor": null,
- "id": 976720,
- "notification": true,
- "parent": null,
- "reactions": {},
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- }
- ],
- "content": "This is the body of the second test issue",
- "custom_fields": [],
- "date_created": "1697169676",
- "depends": [],
- "full_url": "https://pagure.io/protop2g-test-srce/issue/2",
- "id": 2,
- "last_updated": "1750832757",
- "milestone": "Milestone BBBB",
- "priority": 3,
- "private": false,
- "related_prs": [],
- "status": "Closed",
- "tags": [
- "cccc",
- "dddd"
- ],
- "title": "This is the title of the second test issue",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
-}
diff --git a/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fissues%3Fpage=1&per_page=20&status=all b/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fissues%3Fpage=1&per_page=20&status=all
deleted file mode 100644
index 683954bdfa..0000000000
--- a/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fissues%3Fpage=1&per_page=20&status=all
+++ /dev/null
@@ -1,328 +0,0 @@
-Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
-Content-Length: 10166
-Content-Security-Policy: default-src 'self';script-src 'self' 'nonce-PksumVGOMvBkmvCTEaSHSrExE'; style-src 'self' 'nonce-PksumVGOMvBkmvCTEaSHSrExE'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-Set-Cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiZDRiMzUyNTA1NDU0MDU4ZTJhNjA5NWFkZjNkYjRkMmUwYjYzZGZkNCJ9.G4-gtA.hMuX3dKcBI5jKIZp5DlZWJhSDPw; Expires=Fri, 26-Sep-2025 19:47:00 GMT; Secure; HttpOnly; Path=/
-X-Frame-Options: ALLOW-FROM https://pagure.io/
-Content-Type: application/json
-X-Xss-Protection: 1; mode=block
-X-Content-Type-Options: nosniff
-Referrer-Policy: same-origin
-
-{
- "args": {
- "assignee": null,
- "author": null,
- "milestones": [],
- "no_stones": null,
- "order": null,
- "priority": null,
- "since": null,
- "status": "all",
- "tags": []
- },
- "issues": [
- {
- "assignee": null,
- "blocks": [],
- "close_status": "Complete",
- "closed_at": "1750832579",
- "closed_by": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- },
- "comments": [
- {
- "comment": "**Metadata Update from @t0xic0der**:\n- Issue tagged with: cccc, dddd",
- "date_created": "1697169810",
- "edited_on": null,
- "editor": null,
- "id": 878472,
- "notification": true,
- "parent": null,
- "reactions": {},
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "The is the first comment under the second test issue",
- "date_created": "1697169964",
- "edited_on": null,
- "editor": null,
- "id": 878475,
- "notification": false,
- "parent": null,
- "reactions": {},
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "The is the second comment under the second test issue",
- "date_created": "1697169976",
- "edited_on": null,
- "editor": null,
- "id": 878476,
- "notification": false,
- "parent": null,
- "reactions": {},
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "**Metadata Update from @t0xic0der**:\n- Issue status updated to: Closed (was: Open)",
- "date_created": "1697170032",
- "edited_on": null,
- "editor": null,
- "id": 878477,
- "notification": true,
- "parent": null,
- "reactions": {},
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "**Metadata Update from @t0xic0der**:\n- Issue set to the milestone: Milestone BBBB",
- "date_created": "1746679821",
- "edited_on": null,
- "editor": null,
- "id": 971678,
- "notification": true,
- "parent": null,
- "reactions": {},
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "**Metadata Update from @t0xic0der**:\n- Issue set to the milestone: None (was: Milestone BBBB)\n- Issue status updated to: Open (was: Closed)",
- "date_created": "1750832572",
- "edited_on": null,
- "editor": null,
- "id": 976713,
- "notification": true,
- "parent": null,
- "reactions": {},
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "**Metadata Update from @t0xic0der**:\n- Issue close_status updated to: Complete\n- Issue status updated to: Closed (was: Open)",
- "date_created": "1750832582",
- "edited_on": null,
- "editor": null,
- "id": 976714,
- "notification": true,
- "parent": null,
- "reactions": {},
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "**Metadata Update from @t0xic0der**:\n- Issue set to the milestone: Milestone BBBB",
- "date_created": "1750832674",
- "edited_on": null,
- "editor": null,
- "id": 976717,
- "notification": true,
- "parent": null,
- "reactions": {},
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "**Metadata Update from @t0xic0der**:\n- Issue priority set to: Rare",
- "date_created": "1750832757",
- "edited_on": null,
- "editor": null,
- "id": 976720,
- "notification": true,
- "parent": null,
- "reactions": {},
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- }
- ],
- "content": "This is the body of the second test issue",
- "custom_fields": [],
- "date_created": "1697169676",
- "depends": [],
- "full_url": "https://pagure.io/protop2g-test-srce/issue/2",
- "id": 2,
- "last_updated": "1750832757",
- "milestone": "Milestone BBBB",
- "priority": 3,
- "private": false,
- "related_prs": [],
- "status": "Closed",
- "tags": [
- "cccc",
- "dddd"
- ],
- "title": "This is the title of the second test issue",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "assignee": null,
- "blocks": [],
- "close_status": null,
- "closed_at": null,
- "closed_by": null,
- "comments": [
- {
- "comment": "**Metadata Update from @t0xic0der**:\n- Issue tagged with: aaaa, bbbb",
- "date_created": "1697169699",
- "edited_on": null,
- "editor": null,
- "id": 878471,
- "notification": true,
- "parent": null,
- "reactions": {},
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "This is the first comment under the first test issue",
- "date_created": "1697169880",
- "edited_on": null,
- "editor": null,
- "id": 878473,
- "notification": false,
- "parent": null,
- "reactions": {},
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "This is the second comment under the first test issue",
- "date_created": "1697169924",
- "edited_on": null,
- "editor": null,
- "id": 878474,
- "notification": false,
- "parent": null,
- "reactions": {},
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "**Metadata Update from @t0xic0der**:\n- Issue set to the milestone: Milestone AAAA",
- "date_created": "1746679806",
- "edited_on": null,
- "editor": null,
- "id": 971677,
- "notification": true,
- "parent": null,
- "reactions": {},
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "**Metadata Update from @t0xic0der**:\n- Issue priority set to: Epic",
- "date_created": "1750832745",
- "edited_on": null,
- "editor": null,
- "id": 976719,
- "notification": true,
- "parent": null,
- "reactions": {},
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- }
- ],
- "content": "This is the body of the first test issue",
- "custom_fields": [],
- "date_created": "1697169462",
- "depends": [],
- "full_url": "https://pagure.io/protop2g-test-srce/issue/1",
- "id": 1,
- "last_updated": "1750832745",
- "milestone": "Milestone AAAA",
- "priority": 4,
- "private": false,
- "related_prs": [],
- "status": "Open",
- "tags": [
- "aaaa",
- "bbbb"
- ],
- "title": "This is the title of the first test issue",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- }
- ],
- "pagination": {
- "first": "https://pagure.io/api/0/protop2g-test-srce/issues?per_page=20&status=all&page=1",
- "last": "https://pagure.io/api/0/protop2g-test-srce/issues?per_page=20&status=all&page=1",
- "next": null,
- "page": 1,
- "pages": 1,
- "per_page": 20,
- "prev": null
- },
- "total_issues": 2
-}
diff --git a/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fpull-request%2F5 b/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fpull-request%2F5
deleted file mode 100644
index 18475372de..0000000000
--- a/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fpull-request%2F5
+++ /dev/null
@@ -1,246 +0,0 @@
-X-Xss-Protection: 1; mode=block
-X-Content-Type-Options: nosniff
-X-Frame-Options: ALLOW-FROM https://pagure.io/
-Content-Length: 5859
-Referrer-Policy: same-origin
-Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
-Content-Security-Policy: default-src 'self';script-src 'self' 'nonce-cKJRnMfn3wZ2XOdNVb5fJc3EU'; style-src 'self' 'nonce-cKJRnMfn3wZ2XOdNVb5fJc3EU'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-Set-Cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiNDI2OTlmMzdkNzliNDBhZTNjNWVjMzI0ZjJiZTZhZTRiOTllMDc1YiJ9.G4-gtw.IeZ5E3NAmb0f8u4EtYgCVD8wupw; Expires=Fri, 26-Sep-2025 19:47:03 GMT; Secure; HttpOnly; Path=/
-Content-Type: application/json
-
-{
- "assignee": null,
- "branch": "main",
- "branch_from": "test-aaaa",
- "cached_merge_status": "CONFLICTS",
- "closed_at": null,
- "closed_by": null,
- "comments": [
- {
- "comment": "**Metadata Update from @t0xic0der**:\n- Pull-request tagged with: aaaa",
- "commit": null,
- "date_created": "1746427453",
- "edited_on": null,
- "editor": null,
- "filename": null,
- "id": 219086,
- "line": null,
- "notification": true,
- "parent": null,
- "reactions": {},
- "tree": null,
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "This is the first comment under this pull request.",
- "commit": null,
- "date_created": "1746595521",
- "edited_on": null,
- "editor": null,
- "filename": null,
- "id": 219190,
- "line": null,
- "notification": false,
- "parent": null,
- "reactions": {},
- "tree": null,
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "This is the second comment under this pull request.",
- "commit": null,
- "date_created": "1746595529",
- "edited_on": null,
- "editor": null,
- "filename": null,
- "id": 219191,
- "line": null,
- "notification": false,
- "parent": null,
- "reactions": {},
- "tree": null,
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- }
- ],
- "commit_start": "b55e5c91d2572d60a8d7e71b3d3003e523127bd4",
- "commit_stop": "b55e5c91d2572d60a8d7e71b3d3003e523127bd4",
- "date_created": "1746427437",
- "full_url": "https://pagure.io/protop2g-test-srce/pull-request/5",
- "id": 5,
- "initial_comment": "Signed-off-by: Akashdeep Dhar ",
- "last_updated": "1747636185",
- "project": {
- "access_groups": {
- "admin": [],
- "collaborator": [],
- "commit": [],
- "ticket": []
- },
- "access_users": {
- "admin": [
- "ryanlerch"
- ],
- "collaborator": [],
- "commit": [],
- "owner": [
- "t0xic0der"
- ],
- "ticket": []
- },
- "close_status": [
- "Complete",
- "Baseless"
- ],
- "custom_keys": [],
- "date_created": "1697168063",
- "date_modified": "1744795940",
- "description": "The source namespace for the Pagure Exporter project to run tests against",
- "full_url": "https://pagure.io/protop2g-test-srce",
- "fullname": "protop2g-test-srce",
- "id": 17042,
- "milestones": {
- "Milestone AAAA": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone BBBB": {
- "active": false,
- "date": "1765497600"
- },
- "Milestone CCCC": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone DDDD": {
- "active": false,
- "date": "1765497600"
- }
- },
- "name": "protop2g-test-srce",
- "namespace": null,
- "parent": null,
- "priorities": {
- "": "",
- "1": "Common",
- "2": "Uncommon",
- "3": "Rare",
- "4": "Epic",
- "5": "Mythic"
- },
- "tags": [
- "srce",
- "test",
- "gridhead",
- "protop2g"
- ],
- "url_path": "protop2g-test-srce",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- "remote_git": null,
- "repo_from": {
- "access_groups": {
- "admin": [],
- "collaborator": [],
- "commit": [],
- "ticket": []
- },
- "access_users": {
- "admin": [
- "ryanlerch"
- ],
- "collaborator": [],
- "commit": [],
- "owner": [
- "t0xic0der"
- ],
- "ticket": []
- },
- "close_status": [
- "Complete",
- "Baseless"
- ],
- "custom_keys": [],
- "date_created": "1697168063",
- "date_modified": "1744795940",
- "description": "The source namespace for the Pagure Exporter project to run tests against",
- "full_url": "https://pagure.io/protop2g-test-srce",
- "fullname": "protop2g-test-srce",
- "id": 17042,
- "milestones": {
- "Milestone AAAA": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone BBBB": {
- "active": false,
- "date": "1765497600"
- },
- "Milestone CCCC": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone DDDD": {
- "active": false,
- "date": "1765497600"
- }
- },
- "name": "protop2g-test-srce",
- "namespace": null,
- "parent": null,
- "priorities": {
- "": "",
- "1": "Common",
- "2": "Uncommon",
- "3": "Rare",
- "4": "Epic",
- "5": "Mythic"
- },
- "tags": [
- "srce",
- "test",
- "gridhead",
- "protop2g"
- ],
- "url_path": "protop2g-test-srce",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- "status": "Open",
- "tags": [
- "aaaa"
- ],
- "threshold_reached": null,
- "title": "Change the branch identity to `test-aaaa` in the README.md file",
- "uid": "f9e737c5ccc1434e9798cfd49d192538",
- "updated_on": "1746595529",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
-}
diff --git a/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fpull-requests%3Fpage=1&per_page=20&status=all b/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fpull-requests%3Fpage=1&per_page=20&status=all
deleted file mode 100644
index f9127f0899..0000000000
--- a/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Fpull-requests%3Fpage=1&per_page=20&status=all
+++ /dev/null
@@ -1,1418 +0,0 @@
-Set-Cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiMGIxOTQwMmQ5ZGRhMjk4NDZhM2VkNTFhMWI0MzZjNWQ4MTZmNTczYSJ9.G4-gtQ.NMS0gvCElG-a6Nm6IwwBJi3TSUM; Expires=Fri, 26-Sep-2025 19:47:01 GMT; Secure; HttpOnly; Path=/
-Content-Type: application/json
-X-Xss-Protection: 1; mode=block
-X-Content-Type-Options: nosniff
-X-Frame-Options: ALLOW-FROM https://pagure.io/
-Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
-Referrer-Policy: same-origin
-Content-Length: 40500
-Content-Security-Policy: default-src 'self';script-src 'self' 'nonce-wa5O4laHUSWMEwIK4wwBWPPTY'; style-src 'self' 'nonce-wa5O4laHUSWMEwIK4wwBWPPTY'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-
-{
- "args": {
- "assignee": null,
- "author": null,
- "page": 1,
- "per_page": 20,
- "status": "all",
- "tags": []
- },
- "pagination": {
- "first": "https://pagure.io/api/0/protop2g-test-srce/pull-requests?per_page=20&status=all&page=1",
- "last": "https://pagure.io/api/0/protop2g-test-srce/pull-requests?per_page=20&status=all&page=1",
- "next": null,
- "page": 1,
- "pages": 1,
- "per_page": 20,
- "prev": null
- },
- "requests": [
- {
- "assignee": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- },
- "branch": "main",
- "branch_from": "test-ffff",
- "cached_merge_status": "unknown",
- "closed_at": "1747635431",
- "closed_by": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- },
- "comments": [
- {
- "comment": "**Metadata Update from @t0xic0der**:\n- Pull-request tagged with: ffff\n- Request assigned",
- "commit": null,
- "date_created": "1747635211",
- "edited_on": null,
- "editor": null,
- "filename": null,
- "id": 219623,
- "line": null,
- "notification": true,
- "parent": null,
- "reactions": {},
- "tree": null,
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "rebased onto 01b420e2964928a15f790f9b7c1a0053e7b5f0a5",
- "commit": null,
- "date_created": "1747635389",
- "edited_on": null,
- "editor": null,
- "filename": null,
- "id": 219625,
- "line": null,
- "notification": true,
- "parent": null,
- "reactions": {},
- "tree": null,
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "Pull-Request has been merged by t0xic0der",
- "commit": null,
- "date_created": "1747635431",
- "edited_on": null,
- "editor": null,
- "filename": null,
- "id": 219626,
- "line": null,
- "notification": true,
- "parent": null,
- "reactions": {},
- "tree": null,
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- }
- ],
- "commit_start": "1a6ccc212aa958a0fe76155c2907c889969a7224",
- "commit_stop": "1a6ccc212aa958a0fe76155c2907c889969a7224",
- "date_created": "1747635165",
- "full_url": "https://pagure.io/protop2g-test-srce/pull-request/10",
- "id": 10,
- "initial_comment": "Signed-off-by: Akashdeep Dhar ",
- "last_updated": "1747635431",
- "project": {
- "access_groups": {
- "admin": [],
- "collaborator": [],
- "commit": [],
- "ticket": []
- },
- "access_users": {
- "admin": [
- "ryanlerch"
- ],
- "collaborator": [],
- "commit": [],
- "owner": [
- "t0xic0der"
- ],
- "ticket": []
- },
- "close_status": [
- "Complete",
- "Baseless"
- ],
- "custom_keys": [],
- "date_created": "1697168063",
- "date_modified": "1744795940",
- "description": "The source namespace for the Pagure Exporter project to run tests against",
- "full_url": "https://pagure.io/protop2g-test-srce",
- "fullname": "protop2g-test-srce",
- "id": 17042,
- "milestones": {
- "Milestone AAAA": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone BBBB": {
- "active": false,
- "date": "1765497600"
- },
- "Milestone CCCC": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone DDDD": {
- "active": false,
- "date": "1765497600"
- }
- },
- "name": "protop2g-test-srce",
- "namespace": null,
- "parent": null,
- "priorities": {
- "": "",
- "1": "Common",
- "2": "Uncommon",
- "3": "Rare",
- "4": "Epic",
- "5": "Mythic"
- },
- "tags": [
- "srce",
- "test",
- "gridhead",
- "protop2g"
- ],
- "url_path": "protop2g-test-srce",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- "remote_git": null,
- "repo_from": {
- "access_groups": {
- "admin": [],
- "collaborator": [],
- "commit": [],
- "ticket": []
- },
- "access_users": {
- "admin": [
- "ryanlerch"
- ],
- "collaborator": [],
- "commit": [],
- "owner": [
- "t0xic0der"
- ],
- "ticket": []
- },
- "close_status": [
- "Complete",
- "Baseless"
- ],
- "custom_keys": [],
- "date_created": "1697168063",
- "date_modified": "1744795940",
- "description": "The source namespace for the Pagure Exporter project to run tests against",
- "full_url": "https://pagure.io/protop2g-test-srce",
- "fullname": "protop2g-test-srce",
- "id": 17042,
- "milestones": {
- "Milestone AAAA": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone BBBB": {
- "active": false,
- "date": "1765497600"
- },
- "Milestone CCCC": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone DDDD": {
- "active": false,
- "date": "1765497600"
- }
- },
- "name": "protop2g-test-srce",
- "namespace": null,
- "parent": null,
- "priorities": {
- "": "",
- "1": "Common",
- "2": "Uncommon",
- "3": "Rare",
- "4": "Epic",
- "5": "Mythic"
- },
- "tags": [
- "srce",
- "test",
- "gridhead",
- "protop2g"
- ],
- "url_path": "protop2g-test-srce",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- "status": "Merged",
- "tags": [
- "ffff"
- ],
- "threshold_reached": null,
- "title": "Change the branch identity to `test-ffff` in the README.md file",
- "uid": "d3b7100abf8b4b02aa220d899e063295",
- "updated_on": "1747635431",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "assignee": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- },
- "branch": "main",
- "branch_from": "test-eeee",
- "cached_merge_status": "unknown",
- "closed_at": "1747635243",
- "closed_by": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- },
- "comments": [
- {
- "comment": "**Metadata Update from @t0xic0der**:\n- Pull-request tagged with: eeee\n- Request assigned",
- "commit": null,
- "date_created": "1747635200",
- "edited_on": null,
- "editor": null,
- "filename": null,
- "id": 219622,
- "line": null,
- "notification": true,
- "parent": null,
- "reactions": {},
- "tree": null,
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "Pull-Request has been merged by t0xic0der",
- "commit": null,
- "date_created": "1747635243",
- "edited_on": null,
- "editor": null,
- "filename": null,
- "id": 219624,
- "line": null,
- "notification": true,
- "parent": null,
- "reactions": {},
- "tree": null,
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- }
- ],
- "commit_start": "01b420e2964928a15f790f9b7c1a0053e7b5f0a5",
- "commit_stop": "01b420e2964928a15f790f9b7c1a0053e7b5f0a5",
- "date_created": "1747635161",
- "full_url": "https://pagure.io/protop2g-test-srce/pull-request/9",
- "id": 9,
- "initial_comment": "Signed-off-by: Akashdeep Dhar ",
- "last_updated": "1747635243",
- "project": {
- "access_groups": {
- "admin": [],
- "collaborator": [],
- "commit": [],
- "ticket": []
- },
- "access_users": {
- "admin": [
- "ryanlerch"
- ],
- "collaborator": [],
- "commit": [],
- "owner": [
- "t0xic0der"
- ],
- "ticket": []
- },
- "close_status": [
- "Complete",
- "Baseless"
- ],
- "custom_keys": [],
- "date_created": "1697168063",
- "date_modified": "1744795940",
- "description": "The source namespace for the Pagure Exporter project to run tests against",
- "full_url": "https://pagure.io/protop2g-test-srce",
- "fullname": "protop2g-test-srce",
- "id": 17042,
- "milestones": {
- "Milestone AAAA": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone BBBB": {
- "active": false,
- "date": "1765497600"
- },
- "Milestone CCCC": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone DDDD": {
- "active": false,
- "date": "1765497600"
- }
- },
- "name": "protop2g-test-srce",
- "namespace": null,
- "parent": null,
- "priorities": {
- "": "",
- "1": "Common",
- "2": "Uncommon",
- "3": "Rare",
- "4": "Epic",
- "5": "Mythic"
- },
- "tags": [
- "srce",
- "test",
- "gridhead",
- "protop2g"
- ],
- "url_path": "protop2g-test-srce",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- "remote_git": null,
- "repo_from": {
- "access_groups": {
- "admin": [],
- "collaborator": [],
- "commit": [],
- "ticket": []
- },
- "access_users": {
- "admin": [
- "ryanlerch"
- ],
- "collaborator": [],
- "commit": [],
- "owner": [
- "t0xic0der"
- ],
- "ticket": []
- },
- "close_status": [
- "Complete",
- "Baseless"
- ],
- "custom_keys": [],
- "date_created": "1697168063",
- "date_modified": "1744795940",
- "description": "The source namespace for the Pagure Exporter project to run tests against",
- "full_url": "https://pagure.io/protop2g-test-srce",
- "fullname": "protop2g-test-srce",
- "id": 17042,
- "milestones": {
- "Milestone AAAA": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone BBBB": {
- "active": false,
- "date": "1765497600"
- },
- "Milestone CCCC": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone DDDD": {
- "active": false,
- "date": "1765497600"
- }
- },
- "name": "protop2g-test-srce",
- "namespace": null,
- "parent": null,
- "priorities": {
- "": "",
- "1": "Common",
- "2": "Uncommon",
- "3": "Rare",
- "4": "Epic",
- "5": "Mythic"
- },
- "tags": [
- "srce",
- "test",
- "gridhead",
- "protop2g"
- ],
- "url_path": "protop2g-test-srce",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- "status": "Merged",
- "tags": [
- "eeee"
- ],
- "threshold_reached": null,
- "title": "Change the branch identity to `test-eeee` in the README.md file",
- "uid": "f2ad806e430a40bd8ee5894484338df4",
- "updated_on": "1747635243",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "assignee": null,
- "branch": "main",
- "branch_from": "test-dddd",
- "cached_merge_status": "FFORWARD",
- "closed_at": "1746428053",
- "closed_by": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- },
- "comments": [
- {
- "comment": "**Metadata Update from @t0xic0der**:\n- Pull-request tagged with: dddd",
- "commit": null,
- "date_created": "1746427540",
- "edited_on": null,
- "editor": null,
- "filename": null,
- "id": 219089,
- "line": null,
- "notification": true,
- "parent": null,
- "reactions": {},
- "tree": null,
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "Pull-Request has been closed by t0xic0der",
- "commit": null,
- "date_created": "1746428053",
- "edited_on": null,
- "editor": null,
- "filename": null,
- "id": 219091,
- "line": null,
- "notification": true,
- "parent": null,
- "reactions": {},
- "tree": null,
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- }
- ],
- "commit_start": "0bc8b0c38e0790e9ef5c8d512a00b9c4dd048160",
- "commit_stop": "0bc8b0c38e0790e9ef5c8d512a00b9c4dd048160",
- "date_created": "1746427532",
- "full_url": "https://pagure.io/protop2g-test-srce/pull-request/8",
- "id": 8,
- "initial_comment": "Signed-off-by: Akashdeep Dhar ",
- "last_updated": "1746428053",
- "project": {
- "access_groups": {
- "admin": [],
- "collaborator": [],
- "commit": [],
- "ticket": []
- },
- "access_users": {
- "admin": [
- "ryanlerch"
- ],
- "collaborator": [],
- "commit": [],
- "owner": [
- "t0xic0der"
- ],
- "ticket": []
- },
- "close_status": [
- "Complete",
- "Baseless"
- ],
- "custom_keys": [],
- "date_created": "1697168063",
- "date_modified": "1744795940",
- "description": "The source namespace for the Pagure Exporter project to run tests against",
- "full_url": "https://pagure.io/protop2g-test-srce",
- "fullname": "protop2g-test-srce",
- "id": 17042,
- "milestones": {
- "Milestone AAAA": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone BBBB": {
- "active": false,
- "date": "1765497600"
- },
- "Milestone CCCC": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone DDDD": {
- "active": false,
- "date": "1765497600"
- }
- },
- "name": "protop2g-test-srce",
- "namespace": null,
- "parent": null,
- "priorities": {
- "": "",
- "1": "Common",
- "2": "Uncommon",
- "3": "Rare",
- "4": "Epic",
- "5": "Mythic"
- },
- "tags": [
- "srce",
- "test",
- "gridhead",
- "protop2g"
- ],
- "url_path": "protop2g-test-srce",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- "remote_git": null,
- "repo_from": {
- "access_groups": {
- "admin": [],
- "collaborator": [],
- "commit": [],
- "ticket": []
- },
- "access_users": {
- "admin": [
- "ryanlerch"
- ],
- "collaborator": [],
- "commit": [],
- "owner": [
- "t0xic0der"
- ],
- "ticket": []
- },
- "close_status": [
- "Complete",
- "Baseless"
- ],
- "custom_keys": [],
- "date_created": "1697168063",
- "date_modified": "1744795940",
- "description": "The source namespace for the Pagure Exporter project to run tests against",
- "full_url": "https://pagure.io/protop2g-test-srce",
- "fullname": "protop2g-test-srce",
- "id": 17042,
- "milestones": {
- "Milestone AAAA": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone BBBB": {
- "active": false,
- "date": "1765497600"
- },
- "Milestone CCCC": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone DDDD": {
- "active": false,
- "date": "1765497600"
- }
- },
- "name": "protop2g-test-srce",
- "namespace": null,
- "parent": null,
- "priorities": {
- "": "",
- "1": "Common",
- "2": "Uncommon",
- "3": "Rare",
- "4": "Epic",
- "5": "Mythic"
- },
- "tags": [
- "srce",
- "test",
- "gridhead",
- "protop2g"
- ],
- "url_path": "protop2g-test-srce",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- "status": "Closed",
- "tags": [
- "dddd"
- ],
- "threshold_reached": null,
- "title": "Change the branch identity to `test-dddd` in the README.md file",
- "uid": "493b294044fd48e18f424210c919d8de",
- "updated_on": "1746428053",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "assignee": null,
- "branch": "main",
- "branch_from": "test-cccc",
- "cached_merge_status": "FFORWARD",
- "closed_at": "1746428043",
- "closed_by": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- },
- "comments": [
- {
- "comment": "**Metadata Update from @t0xic0der**:\n- Pull-request tagged with: cccc",
- "commit": null,
- "date_created": "1746427513",
- "edited_on": null,
- "editor": null,
- "filename": null,
- "id": 219088,
- "line": null,
- "notification": true,
- "parent": null,
- "reactions": {},
- "tree": null,
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "Pull-Request has been closed by t0xic0der",
- "commit": null,
- "date_created": "1746428043",
- "edited_on": null,
- "editor": null,
- "filename": null,
- "id": 219090,
- "line": null,
- "notification": true,
- "parent": null,
- "reactions": {},
- "tree": null,
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- }
- ],
- "commit_start": "f1246e331cade9341b9e4f311b7a134f99893d21",
- "commit_stop": "f1246e331cade9341b9e4f311b7a134f99893d21",
- "date_created": "1746427506",
- "full_url": "https://pagure.io/protop2g-test-srce/pull-request/7",
- "id": 7,
- "initial_comment": "Signed-off-by: Akashdeep Dhar ",
- "last_updated": "1746428043",
- "project": {
- "access_groups": {
- "admin": [],
- "collaborator": [],
- "commit": [],
- "ticket": []
- },
- "access_users": {
- "admin": [
- "ryanlerch"
- ],
- "collaborator": [],
- "commit": [],
- "owner": [
- "t0xic0der"
- ],
- "ticket": []
- },
- "close_status": [
- "Complete",
- "Baseless"
- ],
- "custom_keys": [],
- "date_created": "1697168063",
- "date_modified": "1744795940",
- "description": "The source namespace for the Pagure Exporter project to run tests against",
- "full_url": "https://pagure.io/protop2g-test-srce",
- "fullname": "protop2g-test-srce",
- "id": 17042,
- "milestones": {
- "Milestone AAAA": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone BBBB": {
- "active": false,
- "date": "1765497600"
- },
- "Milestone CCCC": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone DDDD": {
- "active": false,
- "date": "1765497600"
- }
- },
- "name": "protop2g-test-srce",
- "namespace": null,
- "parent": null,
- "priorities": {
- "": "",
- "1": "Common",
- "2": "Uncommon",
- "3": "Rare",
- "4": "Epic",
- "5": "Mythic"
- },
- "tags": [
- "srce",
- "test",
- "gridhead",
- "protop2g"
- ],
- "url_path": "protop2g-test-srce",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- "remote_git": null,
- "repo_from": {
- "access_groups": {
- "admin": [],
- "collaborator": [],
- "commit": [],
- "ticket": []
- },
- "access_users": {
- "admin": [
- "ryanlerch"
- ],
- "collaborator": [],
- "commit": [],
- "owner": [
- "t0xic0der"
- ],
- "ticket": []
- },
- "close_status": [
- "Complete",
- "Baseless"
- ],
- "custom_keys": [],
- "date_created": "1697168063",
- "date_modified": "1744795940",
- "description": "The source namespace for the Pagure Exporter project to run tests against",
- "full_url": "https://pagure.io/protop2g-test-srce",
- "fullname": "protop2g-test-srce",
- "id": 17042,
- "milestones": {
- "Milestone AAAA": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone BBBB": {
- "active": false,
- "date": "1765497600"
- },
- "Milestone CCCC": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone DDDD": {
- "active": false,
- "date": "1765497600"
- }
- },
- "name": "protop2g-test-srce",
- "namespace": null,
- "parent": null,
- "priorities": {
- "": "",
- "1": "Common",
- "2": "Uncommon",
- "3": "Rare",
- "4": "Epic",
- "5": "Mythic"
- },
- "tags": [
- "srce",
- "test",
- "gridhead",
- "protop2g"
- ],
- "url_path": "protop2g-test-srce",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- "status": "Closed",
- "tags": [
- "cccc"
- ],
- "threshold_reached": null,
- "title": "Change the branch identity to `test-cccc` in the README.md file",
- "uid": "f696feab56b84557b4d4a8a4462420ee",
- "updated_on": "1746428043",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "assignee": null,
- "branch": "main",
- "branch_from": "test-bbbb",
- "cached_merge_status": "CONFLICTS",
- "closed_at": null,
- "closed_by": null,
- "comments": [
- {
- "comment": "**Metadata Update from @t0xic0der**:\n- Pull-request tagged with: bbbb",
- "commit": null,
- "date_created": "1746427480",
- "edited_on": null,
- "editor": null,
- "filename": null,
- "id": 219087,
- "line": null,
- "notification": true,
- "parent": null,
- "reactions": {},
- "tree": null,
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "This is the first comment under this pull request.",
- "commit": null,
- "date_created": "1746595539",
- "edited_on": null,
- "editor": null,
- "filename": null,
- "id": 219192,
- "line": null,
- "notification": false,
- "parent": null,
- "reactions": {},
- "tree": null,
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "This is the second comment under this pull request.",
- "commit": null,
- "date_created": "1746595552",
- "edited_on": null,
- "editor": null,
- "filename": null,
- "id": 219193,
- "line": null,
- "notification": false,
- "parent": null,
- "reactions": {},
- "tree": null,
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- }
- ],
- "commit_start": "2d40761dc53e6fa060ac49d88e1452c6751d4b1c",
- "commit_stop": "2d40761dc53e6fa060ac49d88e1452c6751d4b1c",
- "date_created": "1746427470",
- "full_url": "https://pagure.io/protop2g-test-srce/pull-request/6",
- "id": 6,
- "initial_comment": "Signed-off-by: Akashdeep Dhar ",
- "last_updated": "1747643450",
- "project": {
- "access_groups": {
- "admin": [],
- "collaborator": [],
- "commit": [],
- "ticket": []
- },
- "access_users": {
- "admin": [
- "ryanlerch"
- ],
- "collaborator": [],
- "commit": [],
- "owner": [
- "t0xic0der"
- ],
- "ticket": []
- },
- "close_status": [
- "Complete",
- "Baseless"
- ],
- "custom_keys": [],
- "date_created": "1697168063",
- "date_modified": "1744795940",
- "description": "The source namespace for the Pagure Exporter project to run tests against",
- "full_url": "https://pagure.io/protop2g-test-srce",
- "fullname": "protop2g-test-srce",
- "id": 17042,
- "milestones": {
- "Milestone AAAA": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone BBBB": {
- "active": false,
- "date": "1765497600"
- },
- "Milestone CCCC": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone DDDD": {
- "active": false,
- "date": "1765497600"
- }
- },
- "name": "protop2g-test-srce",
- "namespace": null,
- "parent": null,
- "priorities": {
- "": "",
- "1": "Common",
- "2": "Uncommon",
- "3": "Rare",
- "4": "Epic",
- "5": "Mythic"
- },
- "tags": [
- "srce",
- "test",
- "gridhead",
- "protop2g"
- ],
- "url_path": "protop2g-test-srce",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- "remote_git": null,
- "repo_from": {
- "access_groups": {
- "admin": [],
- "collaborator": [],
- "commit": [],
- "ticket": []
- },
- "access_users": {
- "admin": [
- "ryanlerch"
- ],
- "collaborator": [],
- "commit": [],
- "owner": [
- "t0xic0der"
- ],
- "ticket": []
- },
- "close_status": [
- "Complete",
- "Baseless"
- ],
- "custom_keys": [],
- "date_created": "1697168063",
- "date_modified": "1744795940",
- "description": "The source namespace for the Pagure Exporter project to run tests against",
- "full_url": "https://pagure.io/protop2g-test-srce",
- "fullname": "protop2g-test-srce",
- "id": 17042,
- "milestones": {
- "Milestone AAAA": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone BBBB": {
- "active": false,
- "date": "1765497600"
- },
- "Milestone CCCC": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone DDDD": {
- "active": false,
- "date": "1765497600"
- }
- },
- "name": "protop2g-test-srce",
- "namespace": null,
- "parent": null,
- "priorities": {
- "": "",
- "1": "Common",
- "2": "Uncommon",
- "3": "Rare",
- "4": "Epic",
- "5": "Mythic"
- },
- "tags": [
- "srce",
- "test",
- "gridhead",
- "protop2g"
- ],
- "url_path": "protop2g-test-srce",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- "status": "Open",
- "tags": [
- "bbbb"
- ],
- "threshold_reached": null,
- "title": "Change the branch identity to `test-bbbb` in the README.md file",
- "uid": "9cab89d6bb8c499e8fcb47926f1f5806",
- "updated_on": "1746595552",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "assignee": null,
- "branch": "main",
- "branch_from": "test-aaaa",
- "cached_merge_status": "CONFLICTS",
- "closed_at": null,
- "closed_by": null,
- "comments": [
- {
- "comment": "**Metadata Update from @t0xic0der**:\n- Pull-request tagged with: aaaa",
- "commit": null,
- "date_created": "1746427453",
- "edited_on": null,
- "editor": null,
- "filename": null,
- "id": 219086,
- "line": null,
- "notification": true,
- "parent": null,
- "reactions": {},
- "tree": null,
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "This is the first comment under this pull request.",
- "commit": null,
- "date_created": "1746595521",
- "edited_on": null,
- "editor": null,
- "filename": null,
- "id": 219190,
- "line": null,
- "notification": false,
- "parent": null,
- "reactions": {},
- "tree": null,
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- {
- "comment": "This is the second comment under this pull request.",
- "commit": null,
- "date_created": "1746595529",
- "edited_on": null,
- "editor": null,
- "filename": null,
- "id": 219191,
- "line": null,
- "notification": false,
- "parent": null,
- "reactions": {},
- "tree": null,
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- }
- ],
- "commit_start": "b55e5c91d2572d60a8d7e71b3d3003e523127bd4",
- "commit_stop": "b55e5c91d2572d60a8d7e71b3d3003e523127bd4",
- "date_created": "1746427437",
- "full_url": "https://pagure.io/protop2g-test-srce/pull-request/5",
- "id": 5,
- "initial_comment": "Signed-off-by: Akashdeep Dhar ",
- "last_updated": "1747636185",
- "project": {
- "access_groups": {
- "admin": [],
- "collaborator": [],
- "commit": [],
- "ticket": []
- },
- "access_users": {
- "admin": [
- "ryanlerch"
- ],
- "collaborator": [],
- "commit": [],
- "owner": [
- "t0xic0der"
- ],
- "ticket": []
- },
- "close_status": [
- "Complete",
- "Baseless"
- ],
- "custom_keys": [],
- "date_created": "1697168063",
- "date_modified": "1744795940",
- "description": "The source namespace for the Pagure Exporter project to run tests against",
- "full_url": "https://pagure.io/protop2g-test-srce",
- "fullname": "protop2g-test-srce",
- "id": 17042,
- "milestones": {
- "Milestone AAAA": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone BBBB": {
- "active": false,
- "date": "1765497600"
- },
- "Milestone CCCC": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone DDDD": {
- "active": false,
- "date": "1765497600"
- }
- },
- "name": "protop2g-test-srce",
- "namespace": null,
- "parent": null,
- "priorities": {
- "": "",
- "1": "Common",
- "2": "Uncommon",
- "3": "Rare",
- "4": "Epic",
- "5": "Mythic"
- },
- "tags": [
- "srce",
- "test",
- "gridhead",
- "protop2g"
- ],
- "url_path": "protop2g-test-srce",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- "remote_git": null,
- "repo_from": {
- "access_groups": {
- "admin": [],
- "collaborator": [],
- "commit": [],
- "ticket": []
- },
- "access_users": {
- "admin": [
- "ryanlerch"
- ],
- "collaborator": [],
- "commit": [],
- "owner": [
- "t0xic0der"
- ],
- "ticket": []
- },
- "close_status": [
- "Complete",
- "Baseless"
- ],
- "custom_keys": [],
- "date_created": "1697168063",
- "date_modified": "1744795940",
- "description": "The source namespace for the Pagure Exporter project to run tests against",
- "full_url": "https://pagure.io/protop2g-test-srce",
- "fullname": "protop2g-test-srce",
- "id": 17042,
- "milestones": {
- "Milestone AAAA": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone BBBB": {
- "active": false,
- "date": "1765497600"
- },
- "Milestone CCCC": {
- "active": true,
- "date": "1765497600"
- },
- "Milestone DDDD": {
- "active": false,
- "date": "1765497600"
- }
- },
- "name": "protop2g-test-srce",
- "namespace": null,
- "parent": null,
- "priorities": {
- "": "",
- "1": "Common",
- "2": "Uncommon",
- "3": "Rare",
- "4": "Epic",
- "5": "Mythic"
- },
- "tags": [
- "srce",
- "test",
- "gridhead",
- "protop2g"
- ],
- "url_path": "protop2g-test-srce",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- },
- "status": "Open",
- "tags": [
- "aaaa"
- ],
- "threshold_reached": null,
- "title": "Change the branch identity to `test-aaaa` in the README.md file",
- "uid": "f9e737c5ccc1434e9798cfd49d192538",
- "updated_on": "1746595529",
- "user": {
- "full_url": "https://pagure.io/user/t0xic0der",
- "fullname": "Akashdeep Dhar",
- "name": "t0xic0der",
- "url_path": "user/t0xic0der"
- }
- }
- ],
- "total_requests": 6
-}
diff --git a/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Faaaa b/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Faaaa
deleted file mode 100644
index 416eb8be84..0000000000
--- a/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Faaaa
+++ /dev/null
@@ -1,15 +0,0 @@
-X-Xss-Protection: 1; mode=block
-Referrer-Policy: same-origin
-X-Frame-Options: ALLOW-FROM https://pagure.io/
-Content-Length: 77
-Content-Security-Policy: default-src 'self';script-src 'self' 'nonce-NY1utFEeOZi2ktclBSK9yPBbQ'; style-src 'self' 'nonce-NY1utFEeOZi2ktclBSK9yPBbQ'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-Set-Cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiNDUzNjY2Zjg4OGI5YThiNjU4N2Y3YzU1ZTk4ZTEwZGZhMGZiM2Q1MSJ9.G4-gsw.MW8WhWH9mQd10iDTu49EExAjtOU; Expires=Fri, 26-Sep-2025 19:46:59 GMT; Secure; HttpOnly; Path=/
-X-Content-Type-Options: nosniff
-Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
-Content-Type: application/json
-
-{
- "tag": "aaaa",
- "tag_color": "#ff0000",
- "tag_description": "aaaa"
-}
diff --git a/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Fbbbb b/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Fbbbb
deleted file mode 100644
index b0bea5052f..0000000000
--- a/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Fbbbb
+++ /dev/null
@@ -1,15 +0,0 @@
-X-Xss-Protection: 1; mode=block
-Referrer-Policy: same-origin
-Content-Length: 77
-Content-Security-Policy: default-src 'self';script-src 'self' 'nonce-3WQfyrKHlOVMS6hbVxdWffV0z'; style-src 'self' 'nonce-3WQfyrKHlOVMS6hbVxdWffV0z'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-Set-Cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiYzM2NjVjMjRkYjU5Nzk2NzBiZjRlMmY4NWNmYTIwMGU3NWFjNTg2MiJ9.G4-gsw.wmhIp0DsAhRYagA9qZFYM5jWWt0; Expires=Fri, 26-Sep-2025 19:46:59 GMT; Secure; HttpOnly; Path=/
-Content-Type: application/json
-X-Content-Type-Options: nosniff
-X-Frame-Options: ALLOW-FROM https://pagure.io/
-Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
-
-{
- "tag": "bbbb",
- "tag_color": "#ff0000",
- "tag_description": "bbbb"
-}
diff --git a/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Fcccc b/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Fcccc
deleted file mode 100644
index 378d374b36..0000000000
--- a/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Fcccc
+++ /dev/null
@@ -1,15 +0,0 @@
-Content-Length: 77
-Content-Type: application/json
-X-Xss-Protection: 1; mode=block
-Content-Security-Policy: default-src 'self';script-src 'self' 'nonce-n8CH3n7QkxYS4ITojGCPv0Qaf'; style-src 'self' 'nonce-n8CH3n7QkxYS4ITojGCPv0Qaf'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-Set-Cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiMDQyNDhlM2I3NDMzNWU3MDNkOWQ4MDk5M2FhNmYzZTk1N2M3NWFiNiJ9.G4-gsw.fIL0G11hmPPmHfKgqa3UGbhc3Wg; Expires=Fri, 26-Sep-2025 19:46:59 GMT; Secure; HttpOnly; Path=/
-X-Content-Type-Options: nosniff
-Referrer-Policy: same-origin
-X-Frame-Options: ALLOW-FROM https://pagure.io/
-Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
-
-{
- "tag": "cccc",
- "tag_color": "#ffff00",
- "tag_description": "cccc"
-}
diff --git a/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Fdddd b/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Fdddd
deleted file mode 100644
index fa6d75ff1d..0000000000
--- a/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Fdddd
+++ /dev/null
@@ -1,15 +0,0 @@
-Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
-Content-Length: 77
-Content-Type: application/json
-X-Xss-Protection: 1; mode=block
-X-Content-Type-Options: nosniff
-X-Frame-Options: ALLOW-FROM https://pagure.io/
-Content-Security-Policy: default-src 'self';script-src 'self' 'nonce-Paip3h7855Wqz66JatzO28HOo'; style-src 'self' 'nonce-Paip3h7855Wqz66JatzO28HOo'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-Set-Cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiYjIxMzk4ZjQwMDM3NjdmMWY0MjI5YTExYTVlNDQwODlhYWJhNTgyOSJ9.G4-gsw.cpd52huyCk-zDHjOrMBhHmL5STo; Expires=Fri, 26-Sep-2025 19:46:59 GMT; Secure; HttpOnly; Path=/
-Referrer-Policy: same-origin
-
-{
- "tag": "dddd",
- "tag_color": "#ffff00",
- "tag_description": "dddd"
-}
diff --git a/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Feeee b/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Feeee
deleted file mode 100644
index 2f4045095b..0000000000
--- a/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Feeee
+++ /dev/null
@@ -1,15 +0,0 @@
-X-Xss-Protection: 1; mode=block
-X-Content-Type-Options: nosniff
-Referrer-Policy: same-origin
-X-Frame-Options: ALLOW-FROM https://pagure.io/
-Content-Length: 77
-Content-Security-Policy: default-src 'self';script-src 'self' 'nonce-IeZeJPDSNyxAmSQ2Pe27r2Pkh'; style-src 'self' 'nonce-IeZeJPDSNyxAmSQ2Pe27r2Pkh'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
-Set-Cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiNWQ1NzQ3Yzg5ZDlkZGI2ZTVhNzUyYTk4YzAyMGFiYjg2Mzg1ZWFiYiJ9.G4-gsw.4o-K9_mwm_kGFNG-SVoQTu-nCGI; Expires=Fri, 26-Sep-2025 19:46:59 GMT; Secure; HttpOnly; Path=/
-Content-Type: application/json
-
-{
- "tag": "eeee",
- "tag_color": "#00ff00",
- "tag_description": "eeee"
-}
diff --git a/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Fffff b/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Fffff
deleted file mode 100644
index 2261d20aa7..0000000000
--- a/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Fffff
+++ /dev/null
@@ -1,15 +0,0 @@
-X-Frame-Options: ALLOW-FROM https://pagure.io/
-Content-Length: 77
-Content-Type: application/json
-X-Xss-Protection: 1; mode=block
-X-Content-Type-Options: nosniff
-Referrer-Policy: same-origin
-Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
-Content-Security-Policy: default-src 'self';script-src 'self' 'nonce-Uha6unaW4OnQWiyBCgumrISPz'; style-src 'self' 'nonce-Uha6unaW4OnQWiyBCgumrISPz'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-Set-Cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiODQzMWM2NjIzMjhlN2RhZjE0Y2JhZDQyZGJmMzEwYTdmMWViYzY5NyJ9.G4-gtA.uJpeS8gZ7_ApSzx9_9YXrVsord8; Expires=Fri, 26-Sep-2025 19:47:00 GMT; Secure; HttpOnly; Path=/
-
-{
- "tag": "ffff",
- "tag_color": "#00ff00",
- "tag_description": "ffff"
-}
diff --git a/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Fgggg b/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Fgggg
deleted file mode 100644
index c18309ee1e..0000000000
--- a/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Fgggg
+++ /dev/null
@@ -1,15 +0,0 @@
-X-Frame-Options: ALLOW-FROM https://pagure.io/
-Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
-Content-Type: application/json
-X-Xss-Protection: 1; mode=block
-X-Content-Type-Options: nosniff
-Referrer-Policy: same-origin
-Content-Length: 77
-Content-Security-Policy: default-src 'self';script-src 'self' 'nonce-osDml6SVKadPzyuwCkKx7Tzp3'; style-src 'self' 'nonce-osDml6SVKadPzyuwCkKx7Tzp3'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-Set-Cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiZjUwMDIxYjVhOWE4ZDA2ZTFiMjlkMzRhM2U1N2U1NGFlZmMwZjE1ZSJ9.G4-gtA.67dL477zv1XhBvSAhCpCBM5Jk8Y; Expires=Fri, 26-Sep-2025 19:47:00 GMT; Secure; HttpOnly; Path=/
-
-{
- "tag": "gggg",
- "tag_color": "#0000ff",
- "tag_description": "gggg"
-}
diff --git a/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Fhhhh b/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Fhhhh
deleted file mode 100644
index 92888037b2..0000000000
--- a/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftag%2Fhhhh
+++ /dev/null
@@ -1,15 +0,0 @@
-Content-Length: 77
-Content-Security-Policy: default-src 'self';script-src 'self' 'nonce-lDad6e2jG7okmGyGV9ITt9k8w'; style-src 'self' 'nonce-lDad6e2jG7okmGyGV9ITt9k8w'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-Set-Cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiYjhkZTg4NzJlYjkzMGM5ODZkOTZlNzYyZTJlMWE1ZWEyODk5MzU3NCJ9.G4-gtA.cWHYAAufMpUOgFp0oG7rpf_2k-0; Expires=Fri, 26-Sep-2025 19:47:00 GMT; Secure; HttpOnly; Path=/
-Content-Type: application/json
-X-Xss-Protection: 1; mode=block
-X-Content-Type-Options: nosniff
-Referrer-Policy: same-origin
-X-Frame-Options: ALLOW-FROM https://pagure.io/
-Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
-
-{
- "tag": "hhhh",
- "tag_color": "#0000ff",
- "tag_description": "hhhh"
-}
diff --git a/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftags b/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftags
deleted file mode 100644
index c648a8f338..0000000000
--- a/services/migrations/testdata/pagure/full_download/unauthorized/GET_%2Fapi%2F0%2Fprotop2g-test-srce%2Ftags
+++ /dev/null
@@ -1,23 +0,0 @@
-X-Content-Type-Options: nosniff
-Referrer-Policy: same-origin
-Content-Length: 142
-Content-Type: application/json
-X-Xss-Protection: 1; mode=block
-X-Frame-Options: ALLOW-FROM https://pagure.io/
-Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
-Content-Security-Policy: default-src 'self';script-src 'self' 'nonce-Kt2w1Q1kvLm2O7sDAV0XtpAWM'; style-src 'self' 'nonce-Kt2w1Q1kvLm2O7sDAV0XtpAWM'; object-src 'none';base-uri 'self';img-src 'self' https:;connect-src 'self' https://pagure.io:8088;frame-src https://docs.pagure.org;frame-ancestors https://pagure.io;
-Set-Cookie: pagure=eyJfcGVybWFuZW50Ijp0cnVlLCJjc3JmX3Rva2VuIjoiN2QyN2Y0NDIyM2ViZGJhZWRhMTg3NTc2NGY3MWYzMDVmOTgzNmI5ZSJ9.G4-gsg.Pl5rcBYRhcmWvmmUa6D-05E20KI; Expires=Fri, 26-Sep-2025 19:46:58 GMT; Secure; HttpOnly; Path=/
-
-{
- "tags": [
- "aaaa",
- "bbbb",
- "cccc",
- "dddd",
- "eeee",
- "ffff",
- "gggg",
- "hhhh"
- ],
- "total_tags": 8
-}
diff --git a/services/migrations/update.go b/services/migrations/update.go
index 4d497c1e2e..4a49206f82 100644
--- a/services/migrations/update.go
+++ b/services/migrations/update.go
@@ -6,11 +6,11 @@ package migrations
import (
"context"
- "forgejo.org/models/db"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/log"
- "forgejo.org/modules/structs"
- "forgejo.org/services/externalaccount"
+ "code.gitea.io/gitea/models/db"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/services/externalaccount"
)
// UpdateMigrationPosterID updates all migrated repositories' issues and comments posterID
diff --git a/services/mirror/mirror.go b/services/mirror/mirror.go
index 514b7c3969..bc2d6711cf 100644
--- a/services/mirror/mirror.go
+++ b/services/mirror/mirror.go
@@ -5,14 +5,14 @@ package mirror
import (
"context"
- "errors"
+ "fmt"
- quota_model "forgejo.org/models/quota"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/modules/graceful"
- "forgejo.org/modules/log"
- "forgejo.org/modules/queue"
- "forgejo.org/modules/setting"
+ quota_model "code.gitea.io/gitea/models/quota"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/modules/graceful"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/queue"
+ "code.gitea.io/gitea/modules/setting"
)
// doMirrorSync causes this request to mirror itself
@@ -31,7 +31,7 @@ func doMirrorSync(ctx context.Context, req *SyncRequest) {
}
}
-var errLimit = errors.New("reached limit")
+var errLimit = fmt.Errorf("reached limit")
// Update checks and updates mirror repositories.
func Update(ctx context.Context, pullLimit, pushLimit int) error {
@@ -70,7 +70,7 @@ func Update(ctx context.Context, pullLimit, pushLimit int) error {
// Check we've not been cancelled
select {
case <-ctx.Done():
- return errors.New("aborted")
+ return fmt.Errorf("aborted")
default:
}
diff --git a/services/mirror/mirror_pull.go b/services/mirror/mirror_pull.go
index c46323f283..085995df4f 100644
--- a/services/mirror/mirror_pull.go
+++ b/services/mirror/mirror_pull.go
@@ -9,21 +9,21 @@ import (
"strings"
"time"
- repo_model "forgejo.org/models/repo"
- system_model "forgejo.org/models/system"
- "forgejo.org/modules/cache"
- "forgejo.org/modules/git"
- giturl "forgejo.org/modules/git/url"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/lfs"
- "forgejo.org/modules/log"
- "forgejo.org/modules/process"
- "forgejo.org/modules/proxy"
- repo_module "forgejo.org/modules/repository"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/timeutil"
- "forgejo.org/modules/util"
- notify_service "forgejo.org/services/notify"
+ repo_model "code.gitea.io/gitea/models/repo"
+ system_model "code.gitea.io/gitea/models/system"
+ "code.gitea.io/gitea/modules/cache"
+ "code.gitea.io/gitea/modules/git"
+ giturl "code.gitea.io/gitea/modules/git/url"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/lfs"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/process"
+ "code.gitea.io/gitea/modules/proxy"
+ repo_module "code.gitea.io/gitea/modules/repository"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/timeutil"
+ "code.gitea.io/gitea/modules/util"
+ notify_service "code.gitea.io/gitea/services/notify"
)
// gitShortEmptySha Git short empty SHA
@@ -244,24 +244,6 @@ func pruneBrokenReferences(ctx context.Context,
return pruneErr
}
-// checkRecoverableSyncError takes an error message from a git fetch command and returns false if it should be a fatal/blocking error
-func checkRecoverableSyncError(stderrMessage string) bool {
- switch {
- case strings.Contains(stderrMessage, "unable to resolve reference") && strings.Contains(stderrMessage, "reference broken"):
- return true
- case strings.Contains(stderrMessage, "remote error") && strings.Contains(stderrMessage, "not our ref"):
- return true
- case strings.Contains(stderrMessage, "cannot lock ref") && strings.Contains(stderrMessage, "but expected"):
- return true
- case strings.Contains(stderrMessage, "cannot lock ref") && strings.Contains(stderrMessage, "unable to resolve reference"):
- return true
- case strings.Contains(stderrMessage, "Unable to create") && strings.Contains(stderrMessage, ".lock"):
- return true
- default:
- return false
- }
-}
-
// runSync returns true if sync finished without error.
func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bool) {
repoPath := m.Repo.RepoPath()
@@ -304,7 +286,7 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo
stdoutMessage := util.SanitizeCredentialURLs(stdout)
// Now check if the error is a resolve reference due to broken reference
- if checkRecoverableSyncError(stderr) {
+ if strings.Contains(stderr, "unable to resolve reference") && strings.Contains(stderr, "reference broken") {
log.Warn("SyncMirrors [repo: %-v]: failed to update mirror repository due to broken references:\nStdout: %s\nStderr: %s\nErr: %v\nAttempting Prune", m.Repo, stdoutMessage, stderrMessage, err)
err = nil
@@ -355,15 +337,6 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo
return nil, false
}
- if m.LFS && setting.LFS.StartServer {
- log.Trace("SyncMirrors [repo: %-v]: syncing LFS objects...", m.Repo)
- endpoint := lfs.DetermineEndpoint(remoteURL.String(), m.LFSEndpoint)
- lfsClient := lfs.NewClient(endpoint, nil)
- if err = repo_module.StoreMissingLfsObjectsInRepository(ctx, m.Repo, gitRepo, lfsClient); err != nil {
- log.Error("SyncMirrors [repo: %-v]: failed to synchronize LFS objects for repository: %v", m.Repo, err)
- }
- }
-
log.Trace("SyncMirrors [repo: %-v]: syncing branches...", m.Repo)
if _, err = repo_module.SyncRepoBranchesWithRepo(ctx, m.Repo, gitRepo, 0); err != nil {
log.Error("SyncMirrors [repo: %-v]: failed to synchronize branches: %v", m.Repo, err)
@@ -373,6 +346,15 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo
if err = repo_module.SyncReleasesWithTags(ctx, m.Repo, gitRepo); err != nil {
log.Error("SyncMirrors [repo: %-v]: failed to synchronize tags to releases: %v", m.Repo, err)
}
+
+ if m.LFS && setting.LFS.StartServer {
+ log.Trace("SyncMirrors [repo: %-v]: syncing LFS objects...", m.Repo)
+ endpoint := lfs.DetermineEndpoint(remoteURL.String(), m.LFSEndpoint)
+ lfsClient := lfs.NewClient(endpoint, nil)
+ if err = repo_module.StoreMissingLfsObjectsInRepository(ctx, m.Repo, gitRepo, lfsClient); err != nil {
+ log.Error("SyncMirrors [repo: %-v]: failed to synchronize LFS objects for repository: %v", m.Repo, err)
+ }
+ }
gitRepo.Close()
log.Trace("SyncMirrors [repo: %-v]: updating size of repository", m.Repo)
@@ -400,7 +382,7 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo
stdoutMessage := util.SanitizeCredentialURLs(stdout)
// Now check if the error is a resolve reference due to broken reference
- if checkRecoverableSyncError(stderrMessage) {
+ if strings.Contains(stderrMessage, "unable to resolve reference") && strings.Contains(stderrMessage, "reference broken") {
log.Warn("SyncMirrors [repo: %-v Wiki]: failed to update mirror wiki repository due to broken references:\nStdout: %s\nStderr: %s\nErr: %v\nAttempting Prune", m.Repo, stdoutMessage, stderrMessage, err)
err = nil
diff --git a/services/mirror/mirror_pull_test.go b/services/mirror/mirror_pull_test.go
deleted file mode 100644
index 97859be5b0..0000000000
--- a/services/mirror/mirror_pull_test.go
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 2023 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package mirror
-
-import (
- "testing"
-
- "github.com/stretchr/testify/assert"
-)
-
-func Test_parseRemoteUpdateOutput(t *testing.T) {
- output := `
- * [new tag] v0.1.8 -> v0.1.8
- * [new branch] master -> origin/master
- - [deleted] (none) -> origin/test1
- - [deleted] (none) -> tag1
- + f895a1e...957a993 test2 -> origin/test2 (forced update)
- 957a993..a87ba5f test3 -> origin/test3
- * [new ref] refs/pull/26595/head -> refs/pull/26595/head
- * [new ref] refs/pull/26595/merge -> refs/pull/26595/merge
- e0639e38fb..6db2410489 refs/pull/25873/head -> refs/pull/25873/head
- + 1c97ebc746...976d27d52f refs/pull/25873/merge -> refs/pull/25873/merge (forced update)
-`
- results := parseRemoteUpdateOutput(output, "origin")
- assert.Len(t, results, 10)
- assert.Equal(t, "refs/tags/v0.1.8", results[0].refName.String())
- assert.Equal(t, gitShortEmptySha, results[0].oldCommitID)
- assert.Empty(t, results[0].newCommitID)
-
- assert.Equal(t, "refs/heads/master", results[1].refName.String())
- assert.Equal(t, gitShortEmptySha, results[1].oldCommitID)
- assert.Empty(t, results[1].newCommitID)
-
- assert.Equal(t, "refs/heads/test1", results[2].refName.String())
- assert.Empty(t, results[2].oldCommitID)
- assert.Equal(t, gitShortEmptySha, results[2].newCommitID)
-
- assert.Equal(t, "refs/tags/tag1", results[3].refName.String())
- assert.Empty(t, results[3].oldCommitID)
- assert.Equal(t, gitShortEmptySha, results[3].newCommitID)
-
- assert.Equal(t, "refs/heads/test2", results[4].refName.String())
- assert.Equal(t, "f895a1e", results[4].oldCommitID)
- assert.Equal(t, "957a993", results[4].newCommitID)
-
- assert.Equal(t, "refs/heads/test3", results[5].refName.String())
- assert.Equal(t, "957a993", results[5].oldCommitID)
- assert.Equal(t, "a87ba5f", results[5].newCommitID)
-
- assert.Equal(t, "refs/pull/26595/head", results[6].refName.String())
- assert.Equal(t, gitShortEmptySha, results[6].oldCommitID)
- assert.Empty(t, results[6].newCommitID)
-
- assert.Equal(t, "refs/pull/26595/merge", results[7].refName.String())
- assert.Equal(t, gitShortEmptySha, results[7].oldCommitID)
- assert.Empty(t, results[7].newCommitID)
-
- assert.Equal(t, "refs/pull/25873/head", results[8].refName.String())
- assert.Equal(t, "e0639e38fb", results[8].oldCommitID)
- assert.Equal(t, "6db2410489", results[8].newCommitID)
-
- assert.Equal(t, "refs/pull/25873/merge", results[9].refName.String())
- assert.Equal(t, "1c97ebc746", results[9].oldCommitID)
- assert.Equal(t, "976d27d52f", results[9].newCommitID)
-}
-
-func Test_checkRecoverableSyncError(t *testing.T) {
- cases := []struct {
- recoverable bool
- message string
- }{
- // A race condition in http git-fetch where certain refs were listed on the remote and are no longer there, would exit status 128
- {true, "fatal: remote error: upload-pack: not our ref 988881adc9fc3655077dc2d4d757d480b5ea0e11"},
- // A race condition where a local gc/prune removes a named ref during a git-fetch would exit status 1
- {true, "cannot lock ref 'refs/pull/123456/merge': unable to resolve reference 'refs/pull/134153/merge'"},
- // A race condition in http git-fetch where named refs were listed on the remote and are no longer there
- {true, "error: cannot lock ref 'refs/remotes/origin/foo': unable to resolve reference 'refs/remotes/origin/foo': reference broken"},
- // A race condition in http git-fetch where named refs were force-pushed during the update, would exit status 128
- {true, "error: cannot lock ref 'refs/pull/123456/merge': is at 988881adc9fc3655077dc2d4d757d480b5ea0e11 but expected 7f894307ffc9553edbd0b671cab829786866f7b2"},
- // A race condition with other local git operations, such as git-maintenance, would exit status 128 (well, "Unable" the "U" is uppercase)
- {true, "fatal: Unable to create '/data/gitea-repositories/foo-org/bar-repo.git/./objects/info/commit-graphs/commit-graph-chain.lock': File exists."},
- // Missing or unauthorized credentials, would exit status 128
- {false, "fatal: Authentication failed for 'https://example.com/foo-does-not-exist/bar.git/'"},
- // A non-existent remote repository, would exit status 128
- {false, "fatal: Could not read from remote repository."},
- // A non-functioning proxy, would exit status 128
- {false, "fatal: unable to access 'https://example.com/foo-does-not-exist/bar.git/': Failed to connect to configured-https-proxy port 1080 after 0 ms: Couldn't connect to server"},
- }
-
- for _, c := range cases {
- assert.Equal(t, c.recoverable, checkRecoverableSyncError(c.message), "test case: %s", c.message)
- }
-}
diff --git a/services/mirror/mirror_push.go b/services/mirror/mirror_push.go
index fdd02dedea..4b1d7718b6 100644
--- a/services/mirror/mirror_push.go
+++ b/services/mirror/mirror_push.go
@@ -13,17 +13,17 @@ import (
"strings"
"time"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/lfs"
- "forgejo.org/modules/log"
- "forgejo.org/modules/process"
- "forgejo.org/modules/repository"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/timeutil"
- "forgejo.org/modules/util"
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/lfs"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/process"
+ "code.gitea.io/gitea/modules/repository"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/timeutil"
+ "code.gitea.io/gitea/modules/util"
)
var stripExitStatus = regexp.MustCompile(`exit status \d+ - `)
@@ -33,22 +33,19 @@ var AddPushMirrorRemote = addPushMirrorRemote
func addPushMirrorRemote(ctx context.Context, m *repo_model.PushMirror, addr string) error {
addRemoteAndConfig := func(addr, path string) error {
- var cmd *git.Command
- if m.BranchFilter == "" {
- cmd = git.NewCommand(ctx, "remote", "add", "--mirror").AddDynamicArguments(m.RemoteName, addr)
- } else {
- cmd = git.NewCommand(ctx, "remote", "add").AddDynamicArguments(m.RemoteName, addr)
- }
+ cmd := git.NewCommand(ctx, "remote", "add", "--mirror=push").AddDynamicArguments(m.RemoteName, addr)
if strings.Contains(addr, "://") && strings.Contains(addr, "@") {
- cmd.SetDescription(fmt.Sprintf("remote add %s %s [repo_path: %s]", m.RemoteName, util.SanitizeCredentialURLs(addr), path))
+ cmd.SetDescription(fmt.Sprintf("remote add %s --mirror=push %s [repo_path: %s]", m.RemoteName, util.SanitizeCredentialURLs(addr), path))
} else {
- cmd.SetDescription(fmt.Sprintf("remote add %s %s [repo_path: %s]", m.RemoteName, addr, path))
+ cmd.SetDescription(fmt.Sprintf("remote add %s --mirror=push %s [repo_path: %s]", m.RemoteName, addr, path))
}
if _, _, err := cmd.RunStdString(&git.RunOpts{Dir: path}); err != nil {
return err
}
- err := addRemotePushRefSpecs(ctx, path, m)
- if err != nil {
+ if _, _, err := git.NewCommand(ctx, "config", "--add").AddDynamicArguments("remote."+m.RemoteName+".push", "+refs/heads/*:refs/heads/*").RunStdString(&git.RunOpts{Dir: path}); err != nil {
+ return err
+ }
+ if _, _, err := git.NewCommand(ctx, "config", "--add").AddDynamicArguments("remote."+m.RemoteName+".push", "+refs/tags/*:refs/tags/*").RunStdString(&git.RunOpts{Dir: path}); err != nil {
return err
}
return nil
@@ -70,49 +67,6 @@ func addPushMirrorRemote(ctx context.Context, m *repo_model.PushMirror, addr str
return nil
}
-func addRemotePushRefSpecs(ctx context.Context, path string, m *repo_model.PushMirror) error {
- if m.BranchFilter == "" {
- // If there is no branch filter, set the push refspecs to mirror all branches and tags.
- if _, _, err := git.NewCommand(ctx, "config", "--add").AddDynamicArguments("remote."+m.RemoteName+".push", "+refs/heads/*:refs/heads/*").RunStdString(&git.RunOpts{Dir: path}); err != nil {
- return err
- }
- } else {
- branches := strings.SplitSeq(m.BranchFilter, ",")
- for branch := range branches {
- branch = strings.TrimSpace(branch)
- if branch == "" {
- continue
- }
- refspec := fmt.Sprintf("+refs/heads/%s:refs/heads/%s", branch, branch)
- if _, _, err := git.NewCommand(ctx, "config", "--add").AddDynamicArguments("remote."+m.RemoteName+".push", refspec).RunStdString(&git.RunOpts{Dir: path}); err != nil {
- return err
- }
- }
- }
- if _, _, err := git.NewCommand(ctx, "config", "--add").AddDynamicArguments("remote."+m.RemoteName+".push", "+refs/tags/*:refs/tags/*").RunStdString(&git.RunOpts{Dir: path}); err != nil {
- return err
- }
- return nil
-}
-
-func UpdatePushMirrorBranchFilter(ctx context.Context, m *repo_model.PushMirror) error {
- path := m.Repo.RepoPath()
-
- // First, remove all existing push refspecs for this remote
- cmd := git.NewCommand(ctx, "config", "--unset-all").AddDynamicArguments("remote." + m.RemoteName + ".push")
- if _, _, err := cmd.RunStdString(&git.RunOpts{Dir: path}); err != nil {
- // Ignore error if the key doesn't exist
- if !strings.Contains(err.Error(), "does not exist") {
- return err
- }
- }
- err := addRemotePushRefSpecs(ctx, path, m)
- if err != nil {
- return err
- }
- return nil
-}
-
// RemovePushMirrorRemote removes the push mirror remote.
func RemovePushMirrorRemote(ctx context.Context, m *repo_model.PushMirror) error {
cmd := git.NewCommand(ctx, "remote", "rm").AddDynamicArguments(m.RemoteName)
@@ -258,6 +212,7 @@ func runPushSync(ctx context.Context, m *repo_model.PushMirror) error {
return util.SanitizeErrorCredentialURLs(err)
}
+
return nil
}
diff --git a/services/mirror/mirror_test.go b/services/mirror/mirror_test.go
new file mode 100644
index 0000000000..76632b6872
--- /dev/null
+++ b/services/mirror/mirror_test.go
@@ -0,0 +1,66 @@
+// Copyright 2023 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package mirror
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func Test_parseRemoteUpdateOutput(t *testing.T) {
+ output := `
+ * [new tag] v0.1.8 -> v0.1.8
+ * [new branch] master -> origin/master
+ - [deleted] (none) -> origin/test1
+ - [deleted] (none) -> tag1
+ + f895a1e...957a993 test2 -> origin/test2 (forced update)
+ 957a993..a87ba5f test3 -> origin/test3
+ * [new ref] refs/pull/26595/head -> refs/pull/26595/head
+ * [new ref] refs/pull/26595/merge -> refs/pull/26595/merge
+ e0639e38fb..6db2410489 refs/pull/25873/head -> refs/pull/25873/head
+ + 1c97ebc746...976d27d52f refs/pull/25873/merge -> refs/pull/25873/merge (forced update)
+`
+ results := parseRemoteUpdateOutput(output, "origin")
+ assert.Len(t, results, 10)
+ assert.EqualValues(t, "refs/tags/v0.1.8", results[0].refName.String())
+ assert.EqualValues(t, gitShortEmptySha, results[0].oldCommitID)
+ assert.EqualValues(t, "", results[0].newCommitID)
+
+ assert.EqualValues(t, "refs/heads/master", results[1].refName.String())
+ assert.EqualValues(t, gitShortEmptySha, results[1].oldCommitID)
+ assert.EqualValues(t, "", results[1].newCommitID)
+
+ assert.EqualValues(t, "refs/heads/test1", results[2].refName.String())
+ assert.EqualValues(t, "", results[2].oldCommitID)
+ assert.EqualValues(t, gitShortEmptySha, results[2].newCommitID)
+
+ assert.EqualValues(t, "refs/tags/tag1", results[3].refName.String())
+ assert.EqualValues(t, "", results[3].oldCommitID)
+ assert.EqualValues(t, gitShortEmptySha, results[3].newCommitID)
+
+ assert.EqualValues(t, "refs/heads/test2", results[4].refName.String())
+ assert.EqualValues(t, "f895a1e", results[4].oldCommitID)
+ assert.EqualValues(t, "957a993", results[4].newCommitID)
+
+ assert.EqualValues(t, "refs/heads/test3", results[5].refName.String())
+ assert.EqualValues(t, "957a993", results[5].oldCommitID)
+ assert.EqualValues(t, "a87ba5f", results[5].newCommitID)
+
+ assert.EqualValues(t, "refs/pull/26595/head", results[6].refName.String())
+ assert.EqualValues(t, gitShortEmptySha, results[6].oldCommitID)
+ assert.EqualValues(t, "", results[6].newCommitID)
+
+ assert.EqualValues(t, "refs/pull/26595/merge", results[7].refName.String())
+ assert.EqualValues(t, gitShortEmptySha, results[7].oldCommitID)
+ assert.EqualValues(t, "", results[7].newCommitID)
+
+ assert.EqualValues(t, "refs/pull/25873/head", results[8].refName.String())
+ assert.EqualValues(t, "e0639e38fb", results[8].oldCommitID)
+ assert.EqualValues(t, "6db2410489", results[8].newCommitID)
+
+ assert.EqualValues(t, "refs/pull/25873/merge", results[9].refName.String())
+ assert.EqualValues(t, "1c97ebc746", results[9].oldCommitID)
+ assert.EqualValues(t, "976d27d52f", results[9].newCommitID)
+}
diff --git a/services/mirror/notifier.go b/services/mirror/notifier.go
index 8f8552f419..93d904470d 100644
--- a/services/mirror/notifier.go
+++ b/services/mirror/notifier.go
@@ -6,10 +6,10 @@ package mirror
import (
"context"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/repository"
- notify_service "forgejo.org/services/notify"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/repository"
+ notify_service "code.gitea.io/gitea/services/notify"
)
func init() {
diff --git a/services/mirror/queue.go b/services/mirror/queue.go
index b4869cf8c0..0d9a624730 100644
--- a/services/mirror/queue.go
+++ b/services/mirror/queue.go
@@ -4,10 +4,10 @@
package mirror
import (
- "forgejo.org/modules/graceful"
- "forgejo.org/modules/log"
- "forgejo.org/modules/queue"
- "forgejo.org/modules/setting"
+ "code.gitea.io/gitea/modules/graceful"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/queue"
+ "code.gitea.io/gitea/modules/setting"
)
var mirrorQueue *queue.WorkerPoolQueue[*SyncRequest]
diff --git a/services/moderation/main_test.go b/services/moderation/main_test.go
deleted file mode 100644
index 3a268260d2..0000000000
--- a/services/moderation/main_test.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2025 The Forgejo Authors. All rights reserved.
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-package moderation
-
-import (
- "testing"
-
- "forgejo.org/models/unittest"
-
- _ "forgejo.org/models/forgefed"
- _ "forgejo.org/models/moderation"
-)
-
-func TestMain(m *testing.M) {
- unittest.MainTest(m)
-}
diff --git a/services/moderation/moderating.go b/services/moderation/moderating.go
deleted file mode 100644
index f329070963..0000000000
--- a/services/moderation/moderating.go
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2025 The Forgejo Authors. All rights reserved.
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-package moderation
-
-import (
- "forgejo.org/models/issues"
- "forgejo.org/models/moderation"
- "forgejo.org/models/repo"
- "forgejo.org/models/user"
- "forgejo.org/modules/json"
- "forgejo.org/modules/log"
- "forgejo.org/services/context"
-)
-
-// GetShadowCopyMap unmarshals the shadow copy raw value of the given abuse report and returns a list of pairs
-// (to be rendered when the report is reviewed by an admin).
-// If the report does not have a shadow copy ID or the raw value is empty, returns nil.
-// If the unmarshal fails a warning is added in the logs and returns nil.
-func GetShadowCopyMap(ctx *context.Context, ard *moderation.AbuseReportDetailed) []moderation.ShadowCopyField {
- if ard.ShadowCopyID.Valid && len(ard.ShadowCopyRawValue) > 0 {
- var data moderation.ShadowCopyData
-
- switch ard.ContentType {
- case moderation.ReportedContentTypeUser:
- data = new(user.UserData)
- case moderation.ReportedContentTypeRepository:
- data = new(repo.RepositoryData)
- case moderation.ReportedContentTypeIssue:
- data = new(issues.IssueData)
- case moderation.ReportedContentTypeComment:
- data = new(issues.CommentData)
- }
- if err := json.Unmarshal([]byte(ard.ShadowCopyRawValue), &data); err != nil {
- log.Warn("Unmarshal failed for shadow copy #%d. %v", ard.ShadowCopyID.Int64, err)
- return nil
- }
- return data.GetFieldsMap()
- }
- return nil
-}
diff --git a/services/moderation/reporting.go b/services/moderation/reporting.go
deleted file mode 100644
index 3d1bb5b32c..0000000000
--- a/services/moderation/reporting.go
+++ /dev/null
@@ -1,170 +0,0 @@
-// Copyright 2025 The Forgejo Authors. All rights reserved.
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-package moderation
-
-import (
- stdCtx "context"
- "errors"
- "time"
-
- "forgejo.org/models/db"
- "forgejo.org/models/issues"
- "forgejo.org/models/moderation"
- "forgejo.org/models/perm"
- access_model "forgejo.org/models/perm/access"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unit"
- "forgejo.org/models/user"
- "forgejo.org/modules/log"
- "forgejo.org/services/context"
-)
-
-var (
- ErrContentDoesNotExist = errors.New("the content to be reported does not exist")
- ErrDoerNotAllowed = errors.New("doer not allowed to access the content to be reported")
-)
-
-// CanReport checks if doer has access to the content they are reporting
-// (user, organization, repository, issue, pull request or comment).
-// When reporting repositories the user should have at least read access to any repo unit type.
-// When reporting issues, pull requests or comments the user should have at least read access
-// to 'TypeIssues', respectively 'TypePullRequests' unit for the repository where the content belongs.
-// When reporting users or organizations doer should be able to view the reported entity.
-func CanReport(ctx context.Context, doer *user.User, contentType moderation.ReportedContentType, contentID int64) (bool, error) {
- hasAccess := false
- var issueID int64
- var repoID int64
- unitType := unit.TypeInvalid // used when checking access for issues, pull requests or comments
-
- if contentType == moderation.ReportedContentTypeUser {
- reportedUser, err := user.GetUserByID(ctx, contentID)
- if err != nil {
- if user.IsErrUserNotExist(err) {
- log.Warn("User #%d wanted to report user #%d but it does not exist.", doer.ID, contentID)
- return false, ErrContentDoesNotExist
- }
- return false, err
- }
-
- hasAccess = user.IsUserVisibleToViewer(ctx, reportedUser, ctx.Doer)
- if !hasAccess {
- log.Warn("User #%d wanted to report user/org #%d but they are not able to see that profile.", doer.ID, contentID)
- return false, ErrDoerNotAllowed
- }
- } else {
- // for comments and issues/pulls we need to get the parent repository
- switch contentType {
- case moderation.ReportedContentTypeComment:
- comment, err := issues.GetCommentByID(ctx, contentID)
- if err != nil {
- if issues.IsErrCommentNotExist(err) {
- log.Warn("User #%d wanted to report comment #%d but it does not exist.", doer.ID, contentID)
- return false, ErrContentDoesNotExist
- }
- return false, err
- }
- if !comment.Type.HasContentSupport() {
- // this is not a comment with text and/or attachments
- log.Warn("User #%d wanted to report comment #%d but it is not a comment with content.", doer.ID, contentID)
- return false, nil
- }
- issueID = comment.IssueID
- case moderation.ReportedContentTypeIssue:
- issueID = contentID
- case moderation.ReportedContentTypeRepository:
- repoID = contentID
- }
-
- if issueID > 0 {
- issue, err := issues.GetIssueByID(ctx, issueID)
- if err != nil {
- if issues.IsErrIssueNotExist(err) {
- log.Warn("User #%d wanted to report issue #%d (or one of its comments) but it does not exist.", doer.ID, issueID)
- return false, ErrContentDoesNotExist
- }
- return false, err
- }
-
- repoID = issue.RepoID
- if issue.IsPull {
- unitType = unit.TypePullRequests
- } else {
- unitType = unit.TypeIssues
- }
- }
-
- if repoID > 0 {
- repo, err := repo_model.GetRepositoryByID(ctx, repoID)
- if err != nil {
- if repo_model.IsErrRepoNotExist(err) {
- log.Warn("User #%d wanted to report repository #%d (or one of its issues / comments) but it does not exist.", doer.ID, repoID)
- return false, ErrContentDoesNotExist
- }
- return false, err
- }
-
- if issueID > 0 {
- // for comments and issues/pulls doer should have at least read access to the corresponding repo unit (issues, respectively pull requests)
- hasAccess, err = access_model.HasAccessUnit(ctx, doer, repo, unitType, perm.AccessModeRead)
- if err != nil {
- return false, err
- } else if !hasAccess {
- log.Warn("User #%d wanted to report issue #%d or one of its comments from repository #%d but they don't have access to it.", doer.ID, issueID, repoID)
- return false, ErrDoerNotAllowed
- }
- } else {
- // for repositories doer should have at least read access to at least one repo unit
- perm, err := access_model.GetUserRepoPermission(ctx, repo, doer)
- if err != nil {
- return false, err
- }
- hasAccess = perm.CanReadAny(unit.AllRepoUnitTypes...)
- if !hasAccess {
- log.Warn("User #%d wanted to report repository #%d but they don't have access to it.", doer.ID, repoID)
- return false, ErrDoerNotAllowed
- }
- }
- }
- }
-
- return hasAccess, nil
-}
-
-// RemoveResolvedReports removes resolved reports
-func RemoveResolvedReports(ctx stdCtx.Context, keepReportsFor time.Duration) error {
- log.Trace("Doing: RemoveResolvedReports")
-
- if keepReportsFor <= 0 {
- return nil
- }
-
- err := db.WithTx(ctx, func(ctx stdCtx.Context) error {
- resolvedReports, err := moderation.GetResolvedReports(ctx, keepReportsFor)
- if err != nil {
- return err
- }
-
- for _, report := range resolvedReports {
- _, err := db.GetEngine(ctx).ID(report.ID).Delete(&moderation.AbuseReport{})
- if err != nil {
- return err
- }
-
- if report.ShadowCopyID.Valid {
- _, err := db.GetEngine(ctx).ID(report.ShadowCopyID).Delete(&moderation.AbuseReportShadowCopy{})
- if err != nil {
- return err
- }
- }
- }
-
- return nil
- })
- if err != nil {
- return err
- }
-
- log.Trace("Finished: RemoveResolvedReports")
- return nil
-}
diff --git a/services/moderation/reporting_test.go b/services/moderation/reporting_test.go
deleted file mode 100644
index 70925bf184..0000000000
--- a/services/moderation/reporting_test.go
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2025 The Forgejo Authors. All rights reserved.
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-package moderation
-
-import (
- "testing"
- "time"
-
- "forgejo.org/models/db"
- report_model "forgejo.org/models/moderation"
- "forgejo.org/models/unittest"
- "forgejo.org/modules/timeutil"
-
- "github.com/stretchr/testify/require"
-)
-
-func TestRemoveResolvedReportsWhenNoTimeSet(t *testing.T) {
- require.NoError(t, unittest.PrepareTestDatabase())
- // reportAge needs to be an int64 to match what timeutil.Day expects so we cast the value
- reportAge := int64(20)
- resolvedReport := &report_model.AbuseReport{
- Status: report_model.ReportStatusTypeHandled,
- ReporterID: 1, ContentType: report_model.ReportedContentTypeRepository,
- ContentID: 2, Category: report_model.AbuseCategoryTypeOther,
- CreatedUnix: timeutil.TimeStampNow(),
- ResolvedUnix: timeutil.TimeStamp(time.Now().Unix() - timeutil.Day*reportAge),
- }
- _, err := db.GetEngine(db.DefaultContext).NoAutoTime().Insert(resolvedReport)
- require.NoError(t, err)
-
- // No reports should be deleted when the default time to keep is 0
- err = RemoveResolvedReports(db.DefaultContext, time.Second*0)
- require.NoError(t, err)
- unittest.AssertExistsIf(t, true, resolvedReport)
-}
-
-func TestRemoveResolvedReportsWhenMatchTimeSet(t *testing.T) {
- require.NoError(t, unittest.PrepareTestDatabase())
- // keepReportsFor needs to an int64 to match what timeutil.Day expects so we cast the value
- keepReportsFor := int64(4)
- resolvedReport := &report_model.AbuseReport{
- Status: report_model.ReportStatusTypeHandled,
- ReporterID: 1, ContentType: report_model.ReportedContentTypeRepository,
- ContentID: 2, Category: report_model.AbuseCategoryTypeOther,
- CreatedUnix: timeutil.TimeStampNow(),
- ResolvedUnix: timeutil.TimeStamp(time.Now().Unix() - timeutil.Day*keepReportsFor),
- }
-
- _, err := db.GetEngine(db.DefaultContext).NoAutoTime().Insert(resolvedReport)
- require.NoError(t, err)
-
- // Report should be deleted when older than the default time to keep
- err = RemoveResolvedReports(db.DefaultContext, time.Second*4)
- require.NoError(t, err)
- unittest.AssertExistsIf(t, false, resolvedReport)
-}
-
-func TestRemoveResolvedReportsWhenTimeSetButReportNew(t *testing.T) {
- require.NoError(t, unittest.PrepareTestDatabase())
- resolvedReport := &report_model.AbuseReport{
- Status: report_model.ReportStatusTypeHandled,
- ReporterID: 1, ContentType: report_model.ReportedContentTypeRepository,
- ContentID: 2, Category: report_model.AbuseCategoryTypeOther,
- CreatedUnix: timeutil.TimeStampNow(),
- ResolvedUnix: timeutil.TimeStampNow(),
- }
- _, err := db.GetEngine(db.DefaultContext).NoAutoTime().Insert(resolvedReport)
- require.NoError(t, err)
-
- // Report should not be deleted when newer than the default time to keep
- err = RemoveResolvedReports(db.DefaultContext, time.Second*4)
- require.NoError(t, err)
- unittest.AssertExistsIf(t, true, resolvedReport)
-}
-
-func TestDoesNotRemoveOpenReports(t *testing.T) {
- require.NoError(t, unittest.PrepareTestDatabase())
- // keepReportsFor needs to an int64 to match what timeutil.Day expects so we cast the value
- keepReportsFor := int64(4)
- resolvedReport := &report_model.AbuseReport{
- Status: report_model.ReportStatusTypeOpen,
- ReporterID: 1, ContentType: report_model.ReportedContentTypeRepository,
- ContentID: 2, Category: report_model.AbuseCategoryTypeOther,
- CreatedUnix: timeutil.TimeStampNow(),
- ResolvedUnix: timeutil.TimeStamp(time.Now().Unix() - timeutil.Day*keepReportsFor),
- }
-
- _, err := db.GetEngine(db.DefaultContext).NoAutoTime().Insert(resolvedReport)
- require.NoError(t, err)
-
- // Report should not be deleted when open
- // and older than the default time to keep
- err = RemoveResolvedReports(db.DefaultContext, time.Second*4)
- require.NoError(t, err)
- unittest.AssertExistsIf(t, true, resolvedReport)
-}
diff --git a/services/notify/notifier.go b/services/notify/notifier.go
index 4d88a7ab95..3230a5e5f5 100644
--- a/services/notify/notifier.go
+++ b/services/notify/notifier.go
@@ -6,13 +6,12 @@ package notify
import (
"context"
- actions_model "forgejo.org/models/actions"
- issues_model "forgejo.org/models/issues"
- packages_model "forgejo.org/models/packages"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/repository"
+ issues_model "code.gitea.io/gitea/models/issues"
+ packages_model "code.gitea.io/gitea/models/packages"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/repository"
)
// Notifier defines an interface to notify receiver
@@ -77,6 +76,4 @@ type Notifier interface {
PackageDelete(ctx context.Context, doer *user_model.User, pd *packages_model.PackageDescriptor)
ChangeDefaultBranch(ctx context.Context, repo *repo_model.Repository)
-
- ActionRunNowDone(ctx context.Context, run *actions_model.ActionRun, priorStatus actions_model.Status, lastRun *actions_model.ActionRun)
}
diff --git a/services/notify/notify.go b/services/notify/notify.go
index 02c18272cb..5ed63646aa 100644
--- a/services/notify/notify.go
+++ b/services/notify/notify.go
@@ -6,14 +6,13 @@ package notify
import (
"context"
- actions_model "forgejo.org/models/actions"
- issues_model "forgejo.org/models/issues"
- packages_model "forgejo.org/models/packages"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/log"
- "forgejo.org/modules/repository"
+ issues_model "code.gitea.io/gitea/models/issues"
+ packages_model "code.gitea.io/gitea/models/packages"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/repository"
)
var notifiers []Notifier
@@ -375,15 +374,3 @@ func ChangeDefaultBranch(ctx context.Context, repo *repo_model.Repository) {
notifier.ChangeDefaultBranch(ctx, repo)
}
}
-
-// ActionRunNowDone notifies that the old status priorStatus with (priorStatus.isDone() == false) of an ActionRun changed to run.Status with (run.Status.isDone() == true)
-// run represents the new state of the ActionRun.
-// lastRun represents the ActionRun of the same workflow that finished before run.
-// lastRun might be nil (e.g. when the run is the first for this workflow). It is the last run of the same workflow for the same repo.
-// It can be used to figure out if a successful run follows a failed one.
-// Both run and lastRun need their attributes loaded.
-func ActionRunNowDone(ctx context.Context, run *actions_model.ActionRun, priorStatus actions_model.Status, lastRun *actions_model.ActionRun) {
- for _, notifier := range notifiers {
- notifier.ActionRunNowDone(ctx, run, priorStatus, lastRun)
- }
-}
diff --git a/services/notify/null.go b/services/notify/null.go
index 9c76e5cbd3..894d118eac 100644
--- a/services/notify/null.go
+++ b/services/notify/null.go
@@ -6,13 +6,12 @@ package notify
import (
"context"
- actions_model "forgejo.org/models/actions"
- issues_model "forgejo.org/models/issues"
- packages_model "forgejo.org/models/packages"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/repository"
+ issues_model "code.gitea.io/gitea/models/issues"
+ packages_model "code.gitea.io/gitea/models/packages"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/repository"
)
// NullNotifier implements a blank notifier
@@ -212,7 +211,3 @@ func (*NullNotifier) PackageDelete(ctx context.Context, doer *user_model.User, p
// ChangeDefaultBranch places a place holder function
func (*NullNotifier) ChangeDefaultBranch(ctx context.Context, repo *repo_model.Repository) {
}
-
-// ActionRunNowDone places a place holder function
-func (*NullNotifier) ActionRunNowDone(ctx context.Context, run *actions_model.ActionRun, priorStatus actions_model.Status, lastRun *actions_model.ActionRun) {
-}
diff --git a/services/org/org.go b/services/org/org.go
index b1bbe43046..dca7794b47 100644
--- a/services/org/org.go
+++ b/services/org/org.go
@@ -7,15 +7,15 @@ import (
"context"
"fmt"
- "forgejo.org/models"
- "forgejo.org/models/db"
- org_model "forgejo.org/models/organization"
- packages_model "forgejo.org/models/packages"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/storage"
- "forgejo.org/modules/util"
- repo_service "forgejo.org/services/repository"
+ "code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/models/db"
+ org_model "code.gitea.io/gitea/models/organization"
+ packages_model "code.gitea.io/gitea/models/packages"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/storage"
+ "code.gitea.io/gitea/modules/util"
+ repo_service "code.gitea.io/gitea/services/repository"
)
// DeleteOrganization completely and permanently deletes everything of organization.
diff --git a/services/org/org_test.go b/services/org/org_test.go
index b0f591c745..07358438f6 100644
--- a/services/org/org_test.go
+++ b/services/org/org_test.go
@@ -6,11 +6,11 @@ package org
import (
"testing"
- "forgejo.org/models"
- "forgejo.org/models/db"
- "forgejo.org/models/organization"
- "forgejo.org/models/unittest"
- user_model "forgejo.org/models/user"
+ "code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/organization"
+ "code.gitea.io/gitea/models/unittest"
+ user_model "code.gitea.io/gitea/models/user"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
diff --git a/services/org/repo.go b/services/org/repo.go
index 33f55b1191..78a829ef25 100644
--- a/services/org/repo.go
+++ b/services/org/repo.go
@@ -7,10 +7,10 @@ import (
"context"
"errors"
- "forgejo.org/models"
- "forgejo.org/models/db"
- "forgejo.org/models/organization"
- repo_model "forgejo.org/models/repo"
+ "code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/organization"
+ repo_model "code.gitea.io/gitea/models/repo"
)
// TeamAddRepository adds new repository to team of organization.
diff --git a/services/org/repo_test.go b/services/org/repo_test.go
index c51cbf4c28..2ddb8f9045 100644
--- a/services/org/repo_test.go
+++ b/services/org/repo_test.go
@@ -6,10 +6,10 @@ package org
import (
"testing"
- "forgejo.org/models/db"
- "forgejo.org/models/organization"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unittest"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/organization"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unittest"
"github.com/stretchr/testify/require"
)
diff --git a/services/org/team_invite.go b/services/org/team_invite.go
index 9c5da25522..3f28044dbf 100644
--- a/services/org/team_invite.go
+++ b/services/org/team_invite.go
@@ -6,9 +6,9 @@ package org
import (
"context"
- org_model "forgejo.org/models/organization"
- user_model "forgejo.org/models/user"
- "forgejo.org/services/mailer"
+ org_model "code.gitea.io/gitea/models/organization"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/services/mailer"
)
// CreateTeamInvite make a persistent invite in db and mail it
diff --git a/services/packages/alpine/repository.go b/services/packages/alpine/repository.go
index dd66c7d74e..92f475bb7b 100644
--- a/services/packages/alpine/repository.go
+++ b/services/packages/alpine/repository.go
@@ -20,14 +20,14 @@ import (
"io"
"strings"
- packages_model "forgejo.org/models/packages"
- alpine_model "forgejo.org/models/packages/alpine"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/json"
- packages_module "forgejo.org/modules/packages"
- alpine_module "forgejo.org/modules/packages/alpine"
- "forgejo.org/modules/util"
- packages_service "forgejo.org/services/packages"
+ packages_model "code.gitea.io/gitea/models/packages"
+ alpine_model "code.gitea.io/gitea/models/packages/alpine"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/json"
+ packages_module "code.gitea.io/gitea/modules/packages"
+ alpine_module "code.gitea.io/gitea/modules/packages/alpine"
+ "code.gitea.io/gitea/modules/util"
+ packages_service "code.gitea.io/gitea/services/packages"
)
const (
@@ -258,7 +258,7 @@ func buildPackagesIndex(ctx context.Context, ownerID int64, repoVersion *package
privPem, _ := pem.Decode([]byte(priv))
if privPem == nil {
- return errors.New("failed to decode private key pem")
+ return fmt.Errorf("failed to decode private key pem")
}
privKey, err := x509.ParsePKCS1PrivateKey(privPem.Bytes)
diff --git a/services/packages/alt/repository.go b/services/packages/alt/repository.go
index 9693f4322e..f49c435e64 100644
--- a/services/packages/alt/repository.go
+++ b/services/packages/alt/repository.go
@@ -14,15 +14,15 @@ import (
"path"
"time"
- packages_model "forgejo.org/models/packages"
- alt_model "forgejo.org/models/packages/alt"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/container"
- "forgejo.org/modules/json"
- packages_module "forgejo.org/modules/packages"
- rpm_module "forgejo.org/modules/packages/rpm"
- "forgejo.org/modules/setting"
- packages_service "forgejo.org/services/packages"
+ packages_model "code.gitea.io/gitea/models/packages"
+ alt_model "code.gitea.io/gitea/models/packages/alt"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/container"
+ "code.gitea.io/gitea/modules/json"
+ packages_module "code.gitea.io/gitea/modules/packages"
+ rpm_module "code.gitea.io/gitea/modules/packages/rpm"
+ "code.gitea.io/gitea/modules/setting"
+ packages_service "code.gitea.io/gitea/services/packages"
"github.com/ulikunitz/xz"
)
@@ -714,23 +714,21 @@ func buildRelease(ctx context.Context, pv *packages_model.PackageVersion, pfs []
for architecture := range architectures.Seq() {
version := time.Now().Unix()
label := setting.AppName
- origin := setting.AppName
- archive := setting.AppName
-
- data := fmt.Sprintf(`Archive: %s
+ data := fmt.Sprintf(`Archive: Alt Linux Team
Component: classic
Version: %d
-Origin: %s
+Origin: Alt Linux Team
Label: %s
Architecture: %s
NotAutomatic: false
`,
- archive, version, origin, label, architecture)
+ version, label, architecture)
fileInfo, err := addReleaseAsFileToRepo(ctx, pv, "release.classic", data, group, architecture)
if err != nil {
return err
}
+ origin := setting.AppName
codename := time.Now().Unix()
date := time.Now().UTC().Format(time.RFC1123)
@@ -746,7 +744,7 @@ NotAutomatic: false
data = fmt.Sprintf(`Origin: %s
Label: %s
-Suite: Unknown
+Suite: Sisyphus
Codename: %d
Date: %s
Architectures: %s
diff --git a/services/packages/arch/repository.go b/services/packages/arch/repository.go
index 2a865e6dbd..e681f24561 100644
--- a/services/packages/arch/repository.go
+++ b/services/packages/arch/repository.go
@@ -16,14 +16,14 @@ import (
"sort"
"strings"
- packages_model "forgejo.org/models/packages"
- user_model "forgejo.org/models/user"
- packages_module "forgejo.org/modules/packages"
- arch_module "forgejo.org/modules/packages/arch"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/sync"
- "forgejo.org/modules/util"
- packages_service "forgejo.org/services/packages"
+ packages_model "code.gitea.io/gitea/models/packages"
+ user_model "code.gitea.io/gitea/models/user"
+ packages_module "code.gitea.io/gitea/modules/packages"
+ arch_module "code.gitea.io/gitea/modules/packages/arch"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/sync"
+ "code.gitea.io/gitea/modules/util"
+ packages_service "code.gitea.io/gitea/services/packages"
"github.com/ProtonMail/go-crypto/openpgp"
"github.com/ProtonMail/go-crypto/openpgp/armor"
diff --git a/services/packages/auth.go b/services/packages/auth.go
index 205125cf8b..c5bf5af532 100644
--- a/services/packages/auth.go
+++ b/services/packages/auth.go
@@ -4,16 +4,15 @@
package packages
import (
- "errors"
"fmt"
"net/http"
"strings"
"time"
- auth_model "forgejo.org/models/auth"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
+ auth_model "code.gitea.io/gitea/models/auth"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
"github.com/golang-jwt/jwt/v5"
)
@@ -54,7 +53,7 @@ func ParseAuthorizationToken(req *http.Request) (int64, auth_model.AccessTokenSc
parts := strings.SplitN(h, " ", 2)
if len(parts) != 2 {
log.Error("split token failed: %s", h)
- return 0, "", errors.New("split token failed")
+ return 0, "", fmt.Errorf("split token failed")
}
token, err := jwt.ParseWithClaims(parts[1], &packageClaims{}, func(t *jwt.Token) (any, error) {
@@ -69,7 +68,7 @@ func ParseAuthorizationToken(req *http.Request) (int64, auth_model.AccessTokenSc
c, ok := token.Claims.(*packageClaims)
if !token.Valid || !ok {
- return 0, "", errors.New("invalid token claim")
+ return 0, "", fmt.Errorf("invalid token claim")
}
return c.UserID, c.Scope, nil
diff --git a/services/packages/cargo/index.go b/services/packages/cargo/index.go
index 9afcd79571..59823cd3de 100644
--- a/services/packages/cargo/index.go
+++ b/services/packages/cargo/index.go
@@ -13,17 +13,17 @@ import (
"strconv"
"time"
- packages_model "forgejo.org/models/packages"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/json"
- cargo_module "forgejo.org/modules/packages/cargo"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/structs"
- "forgejo.org/modules/util"
- repo_service "forgejo.org/services/repository"
- files_service "forgejo.org/services/repository/files"
+ packages_model "code.gitea.io/gitea/models/packages"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/json"
+ cargo_module "code.gitea.io/gitea/modules/packages/cargo"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/util"
+ repo_service "code.gitea.io/gitea/services/repository"
+ files_service "code.gitea.io/gitea/services/repository/files"
)
const (
diff --git a/services/packages/cleanup/cleanup.go b/services/packages/cleanup/cleanup.go
index 03ad853216..d84bdf1b03 100644
--- a/services/packages/cleanup/cleanup.go
+++ b/services/packages/cleanup/cleanup.go
@@ -8,20 +8,20 @@ import (
"fmt"
"time"
- "forgejo.org/models/db"
- packages_model "forgejo.org/models/packages"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/log"
- "forgejo.org/modules/optional"
- packages_module "forgejo.org/modules/packages"
- packages_service "forgejo.org/services/packages"
- alpine_service "forgejo.org/services/packages/alpine"
- alt_service "forgejo.org/services/packages/alt"
- arch_service "forgejo.org/services/packages/arch"
- cargo_service "forgejo.org/services/packages/cargo"
- container_service "forgejo.org/services/packages/container"
- debian_service "forgejo.org/services/packages/debian"
- rpm_service "forgejo.org/services/packages/rpm"
+ "code.gitea.io/gitea/models/db"
+ packages_model "code.gitea.io/gitea/models/packages"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/optional"
+ packages_module "code.gitea.io/gitea/modules/packages"
+ packages_service "code.gitea.io/gitea/services/packages"
+ alpine_service "code.gitea.io/gitea/services/packages/alpine"
+ alt_service "code.gitea.io/gitea/services/packages/alt"
+ arch_service "code.gitea.io/gitea/services/packages/arch"
+ cargo_service "code.gitea.io/gitea/services/packages/cargo"
+ container_service "code.gitea.io/gitea/services/packages/container"
+ debian_service "code.gitea.io/gitea/services/packages/debian"
+ rpm_service "code.gitea.io/gitea/services/packages/rpm"
)
// Task method to execute cleanup rules and cleanup expired package data
@@ -64,12 +64,13 @@ func ExecuteCleanupRules(outerCtx context.Context) error {
PackageID: p.ID,
IsInternal: optional.Some(false),
Sort: packages_model.SortCreatedDesc,
+ Paginator: db.NewAbsoluteListOptions(pcr.KeepCount, 200),
})
if err != nil {
return fmt.Errorf("CleanupRule [%d]: SearchVersions failed: %w", pcr.ID, err)
}
versionDeleted := false
- for _, pv := range pvs[pcr.KeepCount:] {
+ for _, pv := range pvs {
if pcr.Type == packages_model.TypeContainer {
if skip, err := container_service.ShouldBeSkipped(ctx, pcr, p, pv); err != nil {
return fmt.Errorf("CleanupRule [%d]: container.ShouldBeSkipped failed: %w", pcr.ID, err)
@@ -121,24 +122,23 @@ func ExecuteCleanupRules(outerCtx context.Context) error {
}
if anyVersionDeleted {
- switch pcr.Type {
- case packages_model.TypeDebian:
+ if pcr.Type == packages_model.TypeDebian {
if err := debian_service.BuildAllRepositoryFiles(ctx, pcr.OwnerID); err != nil {
return fmt.Errorf("CleanupRule [%d]: debian.BuildAllRepositoryFiles failed: %w", pcr.ID, err)
}
- case packages_model.TypeAlpine:
+ } else if pcr.Type == packages_model.TypeAlpine {
if err := alpine_service.BuildAllRepositoryFiles(ctx, pcr.OwnerID); err != nil {
return fmt.Errorf("CleanupRule [%d]: alpine.BuildAllRepositoryFiles failed: %w", pcr.ID, err)
}
- case packages_model.TypeRpm:
+ } else if pcr.Type == packages_model.TypeRpm {
if err := rpm_service.BuildAllRepositoryFiles(ctx, pcr.OwnerID); err != nil {
return fmt.Errorf("CleanupRule [%d]: rpm.BuildAllRepositoryFiles failed: %w", pcr.ID, err)
}
- case packages_model.TypeArch:
+ } else if pcr.Type == packages_model.TypeArch {
if err := arch_service.BuildAllRepositoryFiles(ctx, pcr.OwnerID); err != nil {
return fmt.Errorf("CleanupRule [%d]: arch.BuildAllRepositoryFiles failed: %w", pcr.ID, err)
}
- case packages_model.TypeAlt:
+ } else if pcr.Type == packages_model.TypeAlt {
if err := alt_service.BuildAllRepositoryFiles(ctx, pcr.OwnerID); err != nil {
return fmt.Errorf("CleanupRule [%d]: alt.BuildAllRepositoryFiles failed: %w", pcr.ID, err)
}
diff --git a/services/packages/cleanup/cleanup_sha256_test.go b/services/packages/cleanup/cleanup_sha256_test.go
index efa254fc68..41dde28248 100644
--- a/services/packages/cleanup/cleanup_sha256_test.go
+++ b/services/packages/cleanup/cleanup_sha256_test.go
@@ -7,15 +7,15 @@ import (
"testing"
"time"
- "forgejo.org/models/db"
- "forgejo.org/models/packages"
- "forgejo.org/models/unittest"
- "forgejo.org/modules/json"
- "forgejo.org/modules/log"
- container_module "forgejo.org/modules/packages/container"
- "forgejo.org/modules/test"
- "forgejo.org/modules/timeutil"
- container_service "forgejo.org/services/packages/container"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/packages"
+ "code.gitea.io/gitea/models/unittest"
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/log"
+ container_module "code.gitea.io/gitea/modules/packages/container"
+ "code.gitea.io/gitea/modules/test"
+ "code.gitea.io/gitea/modules/timeutil"
+ container_service "code.gitea.io/gitea/services/packages/container"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -78,7 +78,7 @@ func TestCleanupSHA256(t *testing.T) {
for range expected {
filtered = append(filtered, true)
}
- assert.Equal(t, filtered, logFiltered, expected)
+ assert.EqualValues(t, filtered, logFiltered, expected)
}
ancient := 1 * time.Hour
diff --git a/services/packages/cleanup/main_test.go b/services/packages/cleanup/main_test.go
index e9135c147a..ded3d76c83 100644
--- a/services/packages/cleanup/main_test.go
+++ b/services/packages/cleanup/main_test.go
@@ -6,7 +6,7 @@ package container
import (
"testing"
- "forgejo.org/models/unittest"
+ "code.gitea.io/gitea/models/unittest"
)
func TestMain(m *testing.M) {
diff --git a/services/packages/container/blob_uploader.go b/services/packages/container/blob_uploader.go
index ffc47f3853..bae2e2d6af 100644
--- a/services/packages/container/blob_uploader.go
+++ b/services/packages/container/blob_uploader.go
@@ -9,10 +9,10 @@ import (
"io"
"os"
- packages_model "forgejo.org/models/packages"
- packages_module "forgejo.org/modules/packages"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/util"
+ packages_model "code.gitea.io/gitea/models/packages"
+ packages_module "code.gitea.io/gitea/modules/packages"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/util"
)
var (
@@ -92,7 +92,7 @@ func (u *BlobUploader) Append(ctx context.Context, r io.Reader) error {
u.BytesReceived += n
- u.HashStateBytes, err = u.MarshalBinary()
+ u.HashStateBytes, err = u.MultiHasher.MarshalBinary()
if err != nil {
return err
}
diff --git a/services/packages/container/cleanup.go b/services/packages/container/cleanup.go
index a4ae7118f5..b5563c688f 100644
--- a/services/packages/container/cleanup.go
+++ b/services/packages/container/cleanup.go
@@ -7,11 +7,11 @@ import (
"context"
"time"
- packages_model "forgejo.org/models/packages"
- container_model "forgejo.org/models/packages/container"
- "forgejo.org/modules/optional"
- container_module "forgejo.org/modules/packages/container"
- packages_service "forgejo.org/services/packages"
+ packages_model "code.gitea.io/gitea/models/packages"
+ container_model "code.gitea.io/gitea/models/packages/container"
+ "code.gitea.io/gitea/modules/optional"
+ container_module "code.gitea.io/gitea/modules/packages/container"
+ packages_service "code.gitea.io/gitea/services/packages"
digest "github.com/opencontainers/go-digest"
)
diff --git a/services/packages/container/cleanup_sha256.go b/services/packages/container/cleanup_sha256.go
index 5d0d02c22d..16afc74b18 100644
--- a/services/packages/container/cleanup_sha256.go
+++ b/services/packages/container/cleanup_sha256.go
@@ -8,12 +8,12 @@ import (
"strings"
"time"
- "forgejo.org/models/db"
- "forgejo.org/models/packages"
- "forgejo.org/modules/json"
- "forgejo.org/modules/log"
- container_module "forgejo.org/modules/packages/container"
- "forgejo.org/modules/timeutil"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/packages"
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/log"
+ container_module "code.gitea.io/gitea/modules/packages/container"
+ "code.gitea.io/gitea/modules/timeutil"
)
var (
diff --git a/services/packages/container/common.go b/services/packages/container/common.go
index 758ef51721..5a14ed5b7a 100644
--- a/services/packages/container/common.go
+++ b/services/packages/container/common.go
@@ -7,9 +7,9 @@ import (
"context"
"strings"
- packages_model "forgejo.org/models/packages"
- user_model "forgejo.org/models/user"
- container_module "forgejo.org/modules/packages/container"
+ packages_model "code.gitea.io/gitea/models/packages"
+ user_model "code.gitea.io/gitea/models/user"
+ container_module "code.gitea.io/gitea/modules/packages/container"
)
// UpdateRepositoryNames updates the repository name property for all packages of the specific owner
diff --git a/services/packages/debian/repository.go b/services/packages/debian/repository.go
index a8a401662e..e400f1e924 100644
--- a/services/packages/debian/repository.go
+++ b/services/packages/debian/repository.go
@@ -14,14 +14,14 @@ import (
"strings"
"time"
- packages_model "forgejo.org/models/packages"
- debian_model "forgejo.org/models/packages/debian"
- user_model "forgejo.org/models/user"
- packages_module "forgejo.org/modules/packages"
- debian_module "forgejo.org/modules/packages/debian"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/util"
- packages_service "forgejo.org/services/packages"
+ packages_model "code.gitea.io/gitea/models/packages"
+ debian_model "code.gitea.io/gitea/models/packages/debian"
+ user_model "code.gitea.io/gitea/models/user"
+ packages_module "code.gitea.io/gitea/modules/packages"
+ debian_module "code.gitea.io/gitea/modules/packages/debian"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/util"
+ packages_service "code.gitea.io/gitea/services/packages"
"github.com/ProtonMail/go-crypto/openpgp"
"github.com/ProtonMail/go-crypto/openpgp/armor"
diff --git a/services/packages/package_update.go b/services/packages/package_update.go
index 7fa938e260..4a22ee7a62 100644
--- a/services/packages/package_update.go
+++ b/services/packages/package_update.go
@@ -7,13 +7,13 @@ import (
"context"
"fmt"
- org_model "forgejo.org/models/organization"
- packages_model "forgejo.org/models/packages"
- access_model "forgejo.org/models/perm/access"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unit"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/util"
+ org_model "code.gitea.io/gitea/models/organization"
+ packages_model "code.gitea.io/gitea/models/packages"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unit"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/util"
)
func LinkToRepository(ctx context.Context, pkg *packages_model.Package, repo *repo_model.Repository, doer *user_model.User) error {
diff --git a/services/packages/packages.go b/services/packages/packages.go
index 418ceab798..bf89b6ad35 100644
--- a/services/packages/packages.go
+++ b/services/packages/packages.go
@@ -12,17 +12,17 @@ import (
"net/url"
"strings"
- "forgejo.org/models/db"
- packages_model "forgejo.org/models/packages"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/json"
- "forgejo.org/modules/log"
- "forgejo.org/modules/optional"
- packages_module "forgejo.org/modules/packages"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/storage"
- notify_service "forgejo.org/services/notify"
+ "code.gitea.io/gitea/models/db"
+ packages_model "code.gitea.io/gitea/models/packages"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/optional"
+ packages_module "code.gitea.io/gitea/modules/packages"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/storage"
+ notify_service "code.gitea.io/gitea/services/notify"
)
var (
@@ -127,12 +127,12 @@ func createPackageAndVersion(ctx context.Context, pvci *PackageCreationInfo, all
OwnerID: pvci.Owner.ID,
Type: pvci.PackageType,
Name: pvci.Name,
- LowerName: packages_model.ResolvePackageName(pvci.Name, pvci.PackageType),
+ LowerName: strings.ToLower(pvci.Name),
SemverCompatible: pvci.SemverCompatible,
}
var err error
if p, err = packages_model.TryInsertPackage(ctx, p); err != nil {
- if errors.Is(err, packages_model.ErrDuplicatePackage) {
+ if err == packages_model.ErrDuplicatePackage {
packageCreated = false
} else {
log.Error("Error inserting package: %v", err)
@@ -208,7 +208,7 @@ func AddFileToExistingPackage(ctx context.Context, pvi *PackageInfo, pfci *Packa
// This method skips quota checks and should only be used for system-managed packages.
func AddFileToPackageVersionInternal(ctx context.Context, pv *packages_model.PackageVersion, pfci *PackageFileCreationInfo) (*packages_model.PackageFile, error) {
return addFileToPackageWrapper(ctx, func(ctx context.Context) (*packages_model.PackageFile, *packages_model.PackageBlob, bool, error) {
- return addFileToPackageVersionUnchecked(ctx, pv, pfci, "")
+ return addFileToPackageVersionUnchecked(ctx, pv, pfci)
})
}
@@ -261,10 +261,10 @@ func addFileToPackageVersion(ctx context.Context, pv *packages_model.PackageVers
return nil, nil, false, err
}
- return addFileToPackageVersionUnchecked(ctx, pv, pfci, pvi.PackageType)
+ return addFileToPackageVersionUnchecked(ctx, pv, pfci)
}
-func addFileToPackageVersionUnchecked(ctx context.Context, pv *packages_model.PackageVersion, pfci *PackageFileCreationInfo, packageType packages_model.Type) (*packages_model.PackageFile, *packages_model.PackageBlob, bool, error) {
+func addFileToPackageVersionUnchecked(ctx context.Context, pv *packages_model.PackageVersion, pfci *PackageFileCreationInfo) (*packages_model.PackageFile, *packages_model.PackageBlob, bool, error) {
log.Trace("Adding package file: %v, %s", pv.ID, pfci.Filename)
pb, exists, err := packages_model.GetOrInsertBlob(ctx, NewPackageBlob(pfci.Data))
@@ -304,7 +304,7 @@ func addFileToPackageVersionUnchecked(ctx context.Context, pv *packages_model.Pa
VersionID: pv.ID,
BlobID: pb.ID,
Name: pfci.Filename,
- LowerName: packages_model.ResolvePackageName(pfci.Filename, packageType),
+ LowerName: strings.ToLower(pfci.Filename),
CompositeKey: pfci.CompositeKey,
IsLead: pfci.IsLead,
}
diff --git a/services/packages/rpm/repository.go b/services/packages/rpm/repository.go
index 26f34be2bc..705876e5c0 100644
--- a/services/packages/rpm/repository.go
+++ b/services/packages/rpm/repository.go
@@ -16,20 +16,20 @@ import (
"strings"
"time"
- packages_model "forgejo.org/models/packages"
- rpm_model "forgejo.org/models/packages/rpm"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/json"
- "forgejo.org/modules/log"
- packages_module "forgejo.org/modules/packages"
- rpm_module "forgejo.org/modules/packages/rpm"
- "forgejo.org/modules/util"
- packages_service "forgejo.org/services/packages"
+ packages_model "code.gitea.io/gitea/models/packages"
+ rpm_model "code.gitea.io/gitea/models/packages/rpm"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/log"
+ packages_module "code.gitea.io/gitea/modules/packages"
+ rpm_module "code.gitea.io/gitea/modules/packages/rpm"
+ "code.gitea.io/gitea/modules/util"
+ packages_service "code.gitea.io/gitea/services/packages"
- "code.forgejo.org/forgejo/go-rpmutils"
"github.com/ProtonMail/go-crypto/openpgp"
"github.com/ProtonMail/go-crypto/openpgp/armor"
"github.com/ProtonMail/go-crypto/openpgp/packet"
+ "github.com/sassoftware/go-rpmutils"
)
// GetOrCreateRepositoryVersion gets or creates the internal repository package
@@ -410,6 +410,7 @@ func buildPrimary(ctx context.Context, pv *packages_model.PackageVersion, pfs []
files = append(files, f)
}
}
+ packageVersion := fmt.Sprintf("%s-%s", pd.FileMetadata.Version, pd.FileMetadata.Release)
packages = append(packages, &Package{
Type: "rpm",
Name: pd.Package.Name,
@@ -438,7 +439,7 @@ func buildPrimary(ctx context.Context, pv *packages_model.PackageVersion, pfs []
Archive: pd.FileMetadata.ArchiveSize,
},
Location: Location{
- Href: fmt.Sprintf("package/%s/%s/%s/%s-%s.%s.rpm", pd.Package.Name, pd.Version.Version, pd.FileMetadata.Architecture, pd.Package.Name, pd.Version.Version, pd.FileMetadata.Architecture),
+ Href: fmt.Sprintf("package/%s/%s/%s/%s-%s.%s.rpm", pd.Package.Name, packageVersion, pd.FileMetadata.Architecture, pd.Package.Name, packageVersion, pd.FileMetadata.Architecture),
},
Format: Format{
License: pd.VersionMetadata.License,
diff --git a/services/pull/check.go b/services/pull/check.go
index c31d107605..2d91ed07f5 100644
--- a/services/pull/check.go
+++ b/services/pull/check.go
@@ -11,24 +11,23 @@ import (
"strconv"
"strings"
- "forgejo.org/models"
- "forgejo.org/models/db"
- git_model "forgejo.org/models/git"
- issues_model "forgejo.org/models/issues"
- access_model "forgejo.org/models/perm/access"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unit"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/graceful"
- "forgejo.org/modules/log"
- "forgejo.org/modules/process"
- "forgejo.org/modules/queue"
- "forgejo.org/modules/timeutil"
- asymkey_service "forgejo.org/services/asymkey"
- notify_service "forgejo.org/services/notify"
- shared_automerge "forgejo.org/services/shared/automerge"
+ "code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/models/db"
+ git_model "code.gitea.io/gitea/models/git"
+ issues_model "code.gitea.io/gitea/models/issues"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unit"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/graceful"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/process"
+ "code.gitea.io/gitea/modules/queue"
+ "code.gitea.io/gitea/modules/timeutil"
+ asymkey_service "code.gitea.io/gitea/services/asymkey"
+ notify_service "code.gitea.io/gitea/services/notify"
)
// prPatchCheckerQueue represents a queue to handle update pull request tests
@@ -171,7 +170,7 @@ func isSignedIfRequired(ctx context.Context, pr *issues_model.PullRequest, doer
// checkAndUpdateStatus checks if pull request is possible to leaving checking status,
// and set to be either conflict or mergeable.
-func checkAndUpdateStatus(ctx context.Context, pr *issues_model.PullRequest) bool {
+func checkAndUpdateStatus(ctx context.Context, pr *issues_model.PullRequest) {
// If status has not been changed to conflict by testPatch then we are mergeable
if pr.Status == issues_model.PullRequestStatusChecking {
pr.Status = issues_model.PullRequestStatusMergeable
@@ -185,15 +184,12 @@ func checkAndUpdateStatus(ctx context.Context, pr *issues_model.PullRequest) boo
if has {
log.Trace("Not updating status for %-v as it is due to be rechecked", pr)
- return false
+ return
}
if err := pr.UpdateColsIfNotMerged(ctx, "merge_base", "status", "conflicted_files", "changed_protected_files"); err != nil {
log.Error("Update[%-v]: %v", pr, err)
- return false
}
-
- return true
}
// getMergeCommit checks if a pull request has been merged
@@ -343,22 +339,15 @@ func handler(items ...string) []string {
}
func testPR(id int64) {
- ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("Test PR[%d] from patch checking queue", id))
- defer finished()
-
- if pr, updated := testPRProtected(ctx, id); pr != nil && updated {
- shared_automerge.AddToQueueIfMergeable(ctx, pr)
- }
-}
-
-func testPRProtected(ctx context.Context, id int64) (*issues_model.PullRequest, bool) {
pullWorkingPool.CheckIn(fmt.Sprint(id))
defer pullWorkingPool.CheckOut(fmt.Sprint(id))
+ ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("Test PR[%d] from patch checking queue", id))
+ defer finished()
pr, err := issues_model.GetPullRequestByID(ctx, id)
if err != nil {
log.Error("Unable to GetPullRequestByID[%d] for testPR: %v", id, err)
- return nil, false
+ return
}
log.Trace("Testing %-v", pr)
@@ -368,12 +357,12 @@ func testPRProtected(ctx context.Context, id int64) (*issues_model.PullRequest,
if pr.HasMerged {
log.Trace("%-v is already merged (status: %s, merge commit: %s)", pr, pr.Status, pr.MergedCommitID)
- return nil, false
+ return
}
if manuallyMerged(ctx, pr) {
log.Trace("%-v is manually merged (status: %s, merge commit: %s)", pr, pr.Status, pr.MergedCommitID)
- return nil, false
+ return
}
if err := TestPatch(pr); err != nil {
@@ -382,10 +371,9 @@ func testPRProtected(ctx context.Context, id int64) (*issues_model.PullRequest,
if err := pr.UpdateCols(ctx, "status"); err != nil {
log.Error("update pr [%-v] status to PullRequestStatusError failed: %v", pr, err)
}
- return nil, false
+ return
}
-
- return pr, checkAndUpdateStatus(ctx, pr)
+ checkAndUpdateStatus(ctx, pr)
}
// CheckPRsForBaseBranch check all pulls with baseBrannch
@@ -404,14 +392,10 @@ func CheckPRsForBaseBranch(ctx context.Context, baseRepo *repo_model.Repository,
// Init runs the task queue to test all the checking status pull requests
func Init() error {
- if err := LoadMergeMessageTemplates(); err != nil {
- return err
- }
-
prPatchCheckerQueue = queue.CreateUniqueQueue(graceful.GetManager().ShutdownContext(), "pr_patch_checker", handler)
if prPatchCheckerQueue == nil {
- return errors.New("unable to create pr_patch_checker queue")
+ return fmt.Errorf("unable to create pr_patch_checker queue")
}
go graceful.GetManager().RunWithCancel(prPatchCheckerQueue)
diff --git a/services/pull/check_test.go b/services/pull/check_test.go
index 9b7e1660bc..dfb8ff708b 100644
--- a/services/pull/check_test.go
+++ b/services/pull/check_test.go
@@ -9,11 +9,11 @@ import (
"testing"
"time"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- "forgejo.org/models/unittest"
- "forgejo.org/modules/queue"
- "forgejo.org/modules/setting"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ "code.gitea.io/gitea/models/unittest"
+ "code.gitea.io/gitea/modules/queue"
+ "code.gitea.io/gitea/modules/setting"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -52,7 +52,7 @@ func TestPullRequest_AddToTaskQueue(t *testing.T) {
select {
case id := <-idChan:
- assert.Equal(t, pr.ID, id)
+ assert.EqualValues(t, pr.ID, id)
case <-time.After(time.Second):
assert.FailNow(t, "Timeout: nothing was added to pullRequestQueue")
}
diff --git a/services/pull/comment.go b/services/pull/comment.go
index 25542daa9f..53587d4f54 100644
--- a/services/pull/comment.go
+++ b/services/pull/comment.go
@@ -6,11 +6,11 @@ package pull
import (
"context"
- issues_model "forgejo.org/models/issues"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/json"
+ issues_model "code.gitea.io/gitea/models/issues"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/json"
)
// getCommitIDsFromRepo get commit IDs from repo in between oldCommitID and newCommitID
diff --git a/services/pull/commit_status.go b/services/pull/commit_status.go
index 0a95ea1152..2c77d9cf4e 100644
--- a/services/pull/commit_status.go
+++ b/services/pull/commit_status.go
@@ -9,12 +9,13 @@ import (
"errors"
"fmt"
- "forgejo.org/models/db"
- git_model "forgejo.org/models/git"
- issues_model "forgejo.org/models/issues"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/log"
- "forgejo.org/modules/structs"
+ "code.gitea.io/gitea/models/db"
+ git_model "code.gitea.io/gitea/models/git"
+ issues_model "code.gitea.io/gitea/models/issues"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/structs"
"github.com/gobwas/glob"
)
@@ -104,7 +105,7 @@ func GetPullRequestCommitStatusState(ctx context.Context, pr *issues_model.PullR
if pr.Flow == issues_model.PullRequestFlowGithub && !headGitRepo.IsBranchExist(pr.HeadBranch) {
return "", errors.New("head branch does not exist, can not merge")
}
- if pr.Flow == issues_model.PullRequestFlowAGit && !headGitRepo.IsReferenceExist(pr.GetGitRefName()) {
+ if pr.Flow == issues_model.PullRequestFlowAGit && !git.IsReferenceExist(ctx, headGitRepo.Path, pr.GetGitRefName()) {
return "", errors.New("head branch does not exist, can not merge")
}
diff --git a/services/pull/commit_status_test.go b/services/pull/commit_status_test.go
index 593c88fb19..592acdd55c 100644
--- a/services/pull/commit_status_test.go
+++ b/services/pull/commit_status_test.go
@@ -7,8 +7,8 @@ package pull
import (
"testing"
- git_model "forgejo.org/models/git"
- "forgejo.org/modules/structs"
+ git_model "code.gitea.io/gitea/models/git"
+ "code.gitea.io/gitea/modules/structs"
"github.com/stretchr/testify/assert"
)
diff --git a/services/pull/edits.go b/services/pull/edits.go
index dbf08e6851..c7550dcb07 100644
--- a/services/pull/edits.go
+++ b/services/pull/edits.go
@@ -8,10 +8,10 @@ import (
"context"
"errors"
- issues_model "forgejo.org/models/issues"
- access_model "forgejo.org/models/perm/access"
- unit_model "forgejo.org/models/unit"
- user_model "forgejo.org/models/user"
+ issues_model "code.gitea.io/gitea/models/issues"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ unit_model "code.gitea.io/gitea/models/unit"
+ user_model "code.gitea.io/gitea/models/user"
)
var ErrUserHasNoPermissionForAction = errors.New("user not allowed to do this action")
diff --git a/services/pull/lfs.go b/services/pull/lfs.go
index 8d9f401641..ed03583d4f 100644
--- a/services/pull/lfs.go
+++ b/services/pull/lfs.go
@@ -11,12 +11,12 @@ import (
"strconv"
"sync"
- "forgejo.org/models/db"
- git_model "forgejo.org/models/git"
- issues_model "forgejo.org/models/issues"
- "forgejo.org/modules/git/pipeline"
- "forgejo.org/modules/lfs"
- "forgejo.org/modules/log"
+ "code.gitea.io/gitea/models/db"
+ git_model "code.gitea.io/gitea/models/git"
+ issues_model "code.gitea.io/gitea/models/issues"
+ "code.gitea.io/gitea/modules/git/pipeline"
+ "code.gitea.io/gitea/modules/lfs"
+ "code.gitea.io/gitea/modules/log"
)
// LFSPush pushes lfs objects referred to in new commits in the head repository from the base repository
diff --git a/services/pull/main_test.go b/services/pull/main_test.go
index 5262b5be50..4bcb50fb96 100644
--- a/services/pull/main_test.go
+++ b/services/pull/main_test.go
@@ -7,10 +7,10 @@ package pull
import (
"testing"
- "forgejo.org/models/unittest"
+ "code.gitea.io/gitea/models/unittest"
- _ "forgejo.org/models/actions"
- _ "forgejo.org/models/forgefed"
+ _ "code.gitea.io/gitea/models/actions"
+ _ "code.gitea.io/gitea/models/forgefed"
)
func TestMain(m *testing.M) {
diff --git a/services/pull/merge.go b/services/pull/merge.go
index a2542176f0..a1585e64ab 100644
--- a/services/pull/merge.go
+++ b/services/pull/merge.go
@@ -6,7 +6,6 @@ package pull
import (
"context"
- "errors"
"fmt"
"net/url"
"os"
@@ -14,51 +13,26 @@ import (
"regexp"
"strconv"
"strings"
- "unicode"
- "forgejo.org/models"
- "forgejo.org/models/db"
- git_model "forgejo.org/models/git"
- issues_model "forgejo.org/models/issues"
- access_model "forgejo.org/models/perm/access"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unit"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/cache"
- "forgejo.org/modules/git"
- "forgejo.org/modules/log"
- "forgejo.org/modules/references"
- repo_module "forgejo.org/modules/repository"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/timeutil"
- issue_service "forgejo.org/services/issue"
- notify_service "forgejo.org/services/notify"
+ "code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/models/db"
+ git_model "code.gitea.io/gitea/models/git"
+ issues_model "code.gitea.io/gitea/models/issues"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unit"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/cache"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/references"
+ repo_module "code.gitea.io/gitea/modules/repository"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/timeutil"
+ issue_service "code.gitea.io/gitea/services/issue"
+ notify_service "code.gitea.io/gitea/services/notify"
)
-var mergeMessageTemplates = make(map[repo_model.MergeStyle]string, len(repo_model.MergeStyles))
-
-func LoadMergeMessageTemplates() error {
- // Load templates for all known merge styles
- for _, mergeStyle := range repo_model.MergeStyles {
- templateFilename := filepath.Join(
- setting.CustomPath,
- "default_merge_message",
- fmt.Sprintf("%s_TEMPLATE.md", strings.ToUpper(string(mergeStyle))),
- )
-
- content, err := os.ReadFile(templateFilename)
- if err == nil {
- mergeMessageTemplates[mergeStyle] = string(content)
- } else if os.IsNotExist(err) {
- // The file no longer exists, so delete any previous content
- delete(mergeMessageTemplates, mergeStyle)
- } else {
- return err
- }
- }
- return nil
-}
-
// getMergeMessage composes the message used when merging a pull request.
func getMergeMessage(ctx context.Context, baseGitRepo *git.Repository, pr *issues_model.PullRequest, mergeStyle repo_model.MergeStyle, extraVars map[string]string) (message, body string, err error) {
if err := pr.LoadBaseRepo(ctx); err != nil {
@@ -103,13 +77,6 @@ func getMergeMessage(ctx context.Context, baseGitRepo *git.Repository, pr *issue
if _, ok := err.(git.ErrNotExist); ok {
templateContent, err = commit.GetFileContent(templateFilepathGitea, setting.Repository.PullRequest.DefaultMergeMessageSize)
}
-
- if _, ok := err.(git.ErrNotExist); ok {
- if preloadedContent, ok := mergeMessageTemplates[mergeStyle]; ok {
- templateContent, err = preloadedContent, nil
- }
- }
-
if err != nil {
if !git.IsErrNotExist(err) {
return "", "", err
@@ -201,68 +168,10 @@ func GetDefaultMergeMessage(ctx context.Context, baseGitRepo *git.Repository, pr
return getMergeMessage(ctx, baseGitRepo, pr, mergeStyle, nil)
}
-func AddCommitMessageTrailer(message, tailerKey, tailerValue string) string {
- trailerLine := tailerKey + ": " + tailerValue
- message = strings.ReplaceAll(message, "\r\n", "\n")
- message = strings.ReplaceAll(message, "\r", "\n")
- if strings.Contains(message, "\n"+trailerLine+"\n") || strings.HasSuffix(message, "\n"+trailerLine) {
- return message
- }
-
- if !strings.HasSuffix(message, "\n") {
- message += "\n"
- }
- lastNewLine := strings.LastIndexByte(message[:len(message)-1], '\n')
- keyEnd := -1
- if lastNewLine != -1 {
- keyEnd = strings.IndexByte(message[lastNewLine:], ':')
- if keyEnd != -1 {
- keyEnd += lastNewLine
- }
- }
- var lastLineKey string
- if lastNewLine != -1 && keyEnd != -1 {
- lastLineKey = message[lastNewLine+1 : keyEnd]
- }
-
- isLikelyTrailerLine := lastLineKey != "" && unicode.IsUpper(rune(lastLineKey[0])) && strings.Contains(message, "-")
- for i := 0; isLikelyTrailerLine && i < len(lastLineKey); i++ {
- r := rune(lastLineKey[i])
- isLikelyTrailerLine = unicode.IsLetter(r) || unicode.IsDigit(r) || r == '-'
- }
- if !strings.HasSuffix(message, "\n\n") && !isLikelyTrailerLine {
- message += "\n"
- }
- return message + trailerLine
-}
-
// Merge merges pull request to base repository.
// Caller should check PR is ready to be merged (review and status checks)
func Merge(ctx context.Context, pr *issues_model.PullRequest, doer *user_model.User, baseGitRepo *git.Repository, mergeStyle repo_model.MergeStyle, expectedHeadCommitID, message string, wasAutoMerged bool) error {
- pullWorkingPool.CheckIn(fmt.Sprint(pr.ID))
- defer pullWorkingPool.CheckOut(fmt.Sprint(pr.ID))
-
- pr, err := issues_model.GetPullRequestByID(ctx, pr.ID)
- if err != nil {
- log.Error("Unable to load pull request itself: %v", err)
- return fmt.Errorf("unable to load pull request itself: %w", err)
- }
-
- if pr.HasMerged {
- return models.ErrPullRequestHasMerged{
- ID: pr.ID,
- IssueID: pr.IssueID,
- HeadRepoID: pr.HeadRepoID,
- BaseRepoID: pr.BaseRepoID,
- HeadBranch: pr.HeadBranch,
- BaseBranch: pr.BaseBranch,
- }
- }
-
- if err := pr.LoadIssue(ctx); err != nil {
- log.Error("Unable to load issue: %v", err)
- return fmt.Errorf("unable to load issue: %w", err)
- } else if err := pr.LoadBaseRepo(ctx); err != nil {
+ if err := pr.LoadBaseRepo(ctx); err != nil {
log.Error("Unable to load base repo: %v", err)
return fmt.Errorf("unable to load base repo: %w", err)
} else if err := pr.LoadHeadRepo(ctx); err != nil {
@@ -270,6 +179,9 @@ func Merge(ctx context.Context, pr *issues_model.PullRequest, doer *user_model.U
return fmt.Errorf("unable to load head repo: %w", err)
}
+ pullWorkingPool.CheckIn(fmt.Sprint(pr.ID))
+ defer pullWorkingPool.CheckOut(fmt.Sprint(pr.ID))
+
prUnit, err := pr.BaseRepo.GetUnit(ctx, unit.TypePullRequests)
if err != nil {
log.Error("pr.BaseRepo.GetUnit(unit.TypePullRequests): %v", err)
@@ -606,13 +518,13 @@ func MergedManually(ctx context.Context, pr *issues_model.PullRequest, doer *use
objectFormat := git.ObjectFormatFromName(pr.BaseRepo.ObjectFormatName)
if len(commitID) != objectFormat.FullLength() {
- return errors.New("Wrong commit ID")
+ return fmt.Errorf("Wrong commit ID")
}
commit, err := baseGitRepo.GetCommit(commitID)
if err != nil {
if git.IsErrNotExist(err) {
- return errors.New("Wrong commit ID")
+ return fmt.Errorf("Wrong commit ID")
}
return err
}
@@ -623,7 +535,7 @@ func MergedManually(ctx context.Context, pr *issues_model.PullRequest, doer *use
return err
}
if !ok {
- return errors.New("Wrong commit ID")
+ return fmt.Errorf("Wrong commit ID")
}
pr.MergedCommitID = commitID
@@ -636,7 +548,7 @@ func MergedManually(ctx context.Context, pr *issues_model.PullRequest, doer *use
if merged, err = pr.SetMerged(ctx); err != nil {
return err
} else if !merged {
- return errors.New("SetMerged failed")
+ return fmt.Errorf("SetMerged failed")
}
return nil
}); err != nil {
diff --git a/services/pull/merge_ff_only.go b/services/pull/merge_ff_only.go
index 1e1c337889..f57c732104 100644
--- a/services/pull/merge_ff_only.go
+++ b/services/pull/merge_ff_only.go
@@ -4,9 +4,9 @@
package pull
import (
- repo_model "forgejo.org/models/repo"
- "forgejo.org/modules/git"
- "forgejo.org/modules/log"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/log"
)
// doMergeStyleFastForwardOnly merges the tracking into the current HEAD - which is assumed to be staging branch (equal to the pr.BaseBranch)
diff --git a/services/pull/merge_merge.go b/services/pull/merge_merge.go
index 713e1f175d..bf56c071db 100644
--- a/services/pull/merge_merge.go
+++ b/services/pull/merge_merge.go
@@ -4,9 +4,9 @@
package pull
import (
- repo_model "forgejo.org/models/repo"
- "forgejo.org/modules/git"
- "forgejo.org/modules/log"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/log"
)
// doMergeStyleMerge merges the tracking branch into the current HEAD - which is assumed to be the staging branch (equal to the pr.BaseBranch)
diff --git a/services/pull/merge_prepare.go b/services/pull/merge_prepare.go
index 4598d57b7a..88f6c037eb 100644
--- a/services/pull/merge_prepare.go
+++ b/services/pull/merge_prepare.go
@@ -14,13 +14,13 @@ import (
"strings"
"time"
- "forgejo.org/models"
- issues_model "forgejo.org/models/issues"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/log"
- asymkey_service "forgejo.org/services/asymkey"
+ "code.gitea.io/gitea/models"
+ issues_model "code.gitea.io/gitea/models/issues"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/log"
+ asymkey_service "code.gitea.io/gitea/services/asymkey"
)
type mergeContext struct {
@@ -236,77 +236,10 @@ func getDiffTree(ctx context.Context, repoPath, baseBranch, headBranch string, o
// rebaseTrackingOnToBase checks out the tracking branch as staging and rebases it on to the base branch
// if there is a conflict it will return a models.ErrRebaseConflicts
func rebaseTrackingOnToBase(ctx *mergeContext, mergeStyle repo_model.MergeStyle) error {
- // Create staging branch
- if err := git.NewCommand(ctx, "branch").AddDynamicArguments(stagingBranch, trackingBranch).
- Run(ctx.RunOpts()); err != nil {
- return fmt.Errorf(
- "unable to git branch tracking as staging in temp repo for %v: %w\n%s\n%s",
- ctx.pr, err,
- ctx.outbuf.String(),
- ctx.errbuf.String(),
- )
- }
- ctx.outbuf.Reset()
- ctx.errbuf.Reset()
-
- // If the pull request is zero commits behind, then no rebasing needs to be done.
- if ctx.pr.CommitsBehind == 0 {
- return nil
- }
-
- // Check git version for availability of git-replay. If it is available, we use
- // it for performance and to preserve unknown commit headers like the
- // "change-id" header used by Jujutsu and GitButler to track changes across
- // rebase, amend etc.
- if err := git.CheckGitVersionAtLeast("2.44"); err == nil {
- // Use git-replay for performance and to preserve unknown headers,
- // like the "change-id" header used by Jujutsu and GitButler.
- if err := git.NewCommand(ctx, "replay", "--onto").AddDynamicArguments(baseBranch).
- AddDynamicArguments(fmt.Sprintf("%s..%s", baseBranch, stagingBranch)).
- Run(ctx.RunOpts()); err != nil {
- // git-replay doesn't tell us which commit first created a merge conflict.
- // In order to preserve the quality of our error messages, fall back to
- // regular git-rebase.
- goto regular_rebase
- }
- // git-replay worked, stdout contains the instructions for update-ref
- updateRefInstructions := ctx.outbuf.String()
- opts := ctx.RunOpts()
- opts.Stdin = strings.NewReader(updateRefInstructions)
- if err := git.NewCommand(ctx, "update-ref", "--stdin").Run(opts); err != nil {
- return fmt.Errorf(
- "Failed to update ref for %v: %w\n%s\n%s",
- ctx.pr,
- err,
- ctx.outbuf.String(),
- ctx.errbuf.String(),
- )
- }
- // Checkout staging branch
- if err := git.NewCommand(ctx, "checkout").AddDynamicArguments(stagingBranch).
- Run(ctx.RunOpts()); err != nil {
- return fmt.Errorf(
- "unable to git checkout staging in temp repo for %v: %w\n%s\n%s",
- ctx.pr,
- err,
- ctx.outbuf.String(),
- ctx.errbuf.String(),
- )
- }
- ctx.outbuf.Reset()
- ctx.errbuf.Reset()
- return nil
- }
-
- // The available git version is too old to support git-replay, or git-replay
- // failed and we want to determine the first commit that produced a
- // merge-conflict. Fall back to regular rebase.
-regular_rebase:
-
// Checkout head branch
- if err := git.NewCommand(ctx, "checkout").AddDynamicArguments(stagingBranch).
+ if err := git.NewCommand(ctx, "checkout", "-b").AddDynamicArguments(stagingBranch, trackingBranch).
Run(ctx.RunOpts()); err != nil {
- return fmt.Errorf("unable to git checkout staging in temp repo for %v: %w\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String())
+ return fmt.Errorf("unable to git checkout tracking as staging in temp repo for %v: %w\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String())
}
ctx.outbuf.Reset()
ctx.errbuf.Reset()
diff --git a/services/pull/merge_rebase.go b/services/pull/merge_rebase.go
index 088934cdfb..ecf376220e 100644
--- a/services/pull/merge_rebase.go
+++ b/services/pull/merge_rebase.go
@@ -7,10 +7,10 @@ import (
"fmt"
"strings"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/log"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/log"
)
// getRebaseAmendMessage composes the message to amend commits in rebase merge of a pull request.
diff --git a/services/pull/merge_squash.go b/services/pull/merge_squash.go
index f655224c5e..6dda46eaec 100644
--- a/services/pull/merge_squash.go
+++ b/services/pull/merge_squash.go
@@ -5,14 +5,15 @@ package pull
import (
"fmt"
+ "strings"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/container"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/container"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
)
// doMergeStyleSquash gets a commit author signature for squash commits
@@ -66,8 +67,10 @@ func doMergeStyleSquash(ctx *mergeContext, message string) error {
if setting.Repository.PullRequest.AddCoCommitterTrailers && ctx.committer.String() != sig.String() {
// add trailer
- message = AddCommitMessageTrailer(message, "Co-authored-by", sig.String())
- message = AddCommitMessageTrailer(message, "Co-committed-by", sig.String()) // FIXME: this one should be removed, it is not really used or widely used
+ if !strings.Contains(message, fmt.Sprintf("Co-authored-by: %s", sig.String())) {
+ message += fmt.Sprintf("\nCo-authored-by: %s", sig.String())
+ }
+ message += fmt.Sprintf("\nCo-committed-by: %s\n", sig.String())
}
cmdCommit := git.NewCommand(ctx, "commit").
AddOptionFormat("--author='%s <%s>'", sig.Name, sig.Email).
diff --git a/services/pull/merge_test.go b/services/pull/merge_test.go
index aa033b8cdb..6df6f55d46 100644
--- a/services/pull/merge_test.go
+++ b/services/pull/merge_test.go
@@ -4,22 +4,9 @@
package pull
import (
- "os"
- "path"
- "strings"
"testing"
- "forgejo.org/models"
- issues_model "forgejo.org/models/issues"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unittest"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/test"
-
"github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
)
func Test_expandDefaultMergeMessage(t *testing.T) {
@@ -78,102 +65,3 @@ func Test_expandDefaultMergeMessage(t *testing.T) {
})
}
}
-
-func TestAddCommitMessageTailer(t *testing.T) {
- // add tailer for empty message
- assert.Equal(t, "\n\nTest-tailer: TestValue", AddCommitMessageTrailer("", "Test-tailer", "TestValue"))
-
- // add tailer for message without newlines
- assert.Equal(t, "title\n\nTest-tailer: TestValue", AddCommitMessageTrailer("title", "Test-tailer", "TestValue"))
- assert.Equal(t, "title\n\nNot tailer: xxx\n\nTest-tailer: TestValue", AddCommitMessageTrailer("title\n\nNot tailer: xxx", "Test-tailer", "TestValue"))
- assert.Equal(t, "title\n\nNotTailer: xxx\n\nTest-tailer: TestValue", AddCommitMessageTrailer("title\n\nNotTailer: xxx", "Test-tailer", "TestValue"))
- assert.Equal(t, "title\n\nnot-tailer: xxx\n\nTest-tailer: TestValue", AddCommitMessageTrailer("title\n\nnot-tailer: xxx", "Test-tailer", "TestValue"))
-
- // add tailer for message with one EOL
- assert.Equal(t, "title\n\nTest-tailer: TestValue", AddCommitMessageTrailer("title\n", "Test-tailer", "TestValue"))
-
- // add tailer for message with two EOLs
- assert.Equal(t, "title\n\nTest-tailer: TestValue", AddCommitMessageTrailer("title\n\n", "Test-tailer", "TestValue"))
-
- // add tailer for message with existing tailer (won't duplicate)
- assert.Equal(t, "title\n\nTest-tailer: TestValue", AddCommitMessageTrailer("title\n\nTest-tailer: TestValue", "Test-tailer", "TestValue"))
- assert.Equal(t, "title\n\nTest-tailer: TestValue\n", AddCommitMessageTrailer("title\n\nTest-tailer: TestValue\n", "Test-tailer", "TestValue"))
-
- // add tailer for message with existing tailer and different value (will append)
- assert.Equal(t, "title\n\nTest-tailer: v1\nTest-tailer: v2", AddCommitMessageTrailer("title\n\nTest-tailer: v1", "Test-tailer", "v2"))
- assert.Equal(t, "title\n\nTest-tailer: v1\nTest-tailer: v2", AddCommitMessageTrailer("title\n\nTest-tailer: v1\n", "Test-tailer", "v2"))
-}
-
-func prepareLoadMergeMessageTemplates(targetDir string) error {
- for _, template := range []string{"MERGE", "REBASE", "REBASE-MERGE", "SQUASH", "MANUALLY-MERGED", "REBASE-UPDATE-ONLY"} {
- file, err := os.Create(path.Join(targetDir, template+"_TEMPLATE.md"))
- defer file.Close()
-
- if err == nil {
- _, err = file.WriteString("Contents for " + template)
- }
-
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-func TestLoadMergeMessageTemplates(t *testing.T) {
- defer test.MockVariableValue(&setting.CustomPath, t.TempDir())()
- templateTemp := path.Join(setting.CustomPath, "default_merge_message")
-
- require.NoError(t, os.MkdirAll(templateTemp, 0o755))
- require.NoError(t, prepareLoadMergeMessageTemplates(templateTemp))
-
- testStyles := []repo_model.MergeStyle{
- repo_model.MergeStyleMerge,
- repo_model.MergeStyleRebase,
- repo_model.MergeStyleRebaseMerge,
- repo_model.MergeStyleSquash,
- repo_model.MergeStyleManuallyMerged,
- repo_model.MergeStyleRebaseUpdate,
- }
-
- // Load all templates
- require.NoError(t, LoadMergeMessageTemplates())
-
- // Check their correctness
- assert.Len(t, mergeMessageTemplates, len(testStyles))
- for _, mergeStyle := range testStyles {
- assert.Equal(t, "Contents for "+strings.ToUpper(string(mergeStyle)), mergeMessageTemplates[mergeStyle])
- }
-
- // Unload all templates
- require.NoError(t, os.RemoveAll(templateTemp))
- require.NoError(t, LoadMergeMessageTemplates())
- assert.Empty(t, mergeMessageTemplates)
-}
-
-func TestMergeMergedPR(t *testing.T) {
- require.NoError(t, unittest.PrepareTestDatabase())
- pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1})
- doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
-
- require.NoError(t, pr.LoadBaseRepo(t.Context()))
-
- gitRepo, err := gitrepo.OpenRepository(t.Context(), pr.BaseRepo)
- require.NoError(t, err)
- defer gitRepo.Close()
-
- assert.True(t, pr.HasMerged)
- pr.HasMerged = false
-
- err = Merge(t.Context(), pr, doer, gitRepo, repo_model.MergeStyleRebase, "", "I should not exist", false)
- require.Error(t, err)
- assert.True(t, models.IsErrPullRequestHasMerged(err))
-
- if mergeErr, ok := err.(models.ErrPullRequestHasMerged); ok {
- assert.Equal(t, pr.ID, mergeErr.ID)
- assert.Equal(t, pr.IssueID, mergeErr.IssueID)
- assert.Equal(t, pr.HeadBranch, mergeErr.HeadBranch)
- assert.Equal(t, pr.BaseBranch, mergeErr.BaseBranch)
- }
-}
diff --git a/services/pull/patch.go b/services/pull/patch.go
index 89581c916b..e90b4bdbbe 100644
--- a/services/pull/patch.go
+++ b/services/pull/patch.go
@@ -5,7 +5,7 @@
package pull
import (
- "bytes"
+ "bufio"
"context"
"fmt"
"io"
@@ -13,15 +13,18 @@ import (
"path/filepath"
"strings"
- "forgejo.org/models"
- git_model "forgejo.org/models/git"
- issues_model "forgejo.org/models/issues"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/graceful"
- "forgejo.org/modules/log"
- "forgejo.org/modules/process"
- "forgejo.org/modules/util"
+ "code.gitea.io/gitea/models"
+ git_model "code.gitea.io/gitea/models/git"
+ issues_model "code.gitea.io/gitea/models/issues"
+ "code.gitea.io/gitea/models/unit"
+ "code.gitea.io/gitea/modules/container"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/graceful"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/process"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/util"
"github.com/gobwas/glob"
)
@@ -46,162 +49,66 @@ func DownloadDiffOrPatch(ctx context.Context, pr *issues_model.PullRequest, w io
return nil
}
+var patchErrorSuffices = []string{
+ ": already exists in index",
+ ": patch does not apply",
+ ": already exists in working directory",
+ "unrecognized input",
+ ": No such file or directory",
+ ": does not exist in index",
+}
+
// TestPatch will test whether a simple patch will apply
func TestPatch(pr *issues_model.PullRequest) error {
ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("TestPatch: %s", pr))
defer finished()
- testPatchCtx, err := testPatch(ctx, pr)
- testPatchCtx.close()
- return err
-}
-
-type testPatchContext struct {
- headRev string
- headIsCommitID bool
- baseRev string
- env []string
- gitRepo *git.Repository
- close func()
-}
-
-// LoadHeadRevision loads the necessary information to access the head revision.
-func (t *testPatchContext) LoadHeadRevision(ctx context.Context, pr *issues_model.PullRequest) error {
- // If AGit, then use HeadCommitID if set (AGit flow creates pull request),
- // otherwise use the pull request reference.
- if pr.Flow == issues_model.PullRequestFlowAGit {
- if len(pr.HeadCommitID) > 0 {
- t.headRev = pr.HeadCommitID
- t.headIsCommitID = true
- return nil
- }
- t.headRev = pr.GetGitRefName()
- return nil
- }
-
- // If it is within the same repository, simply return the branch name.
- if pr.BaseRepoID == pr.HeadRepoID {
- t.headRev = pr.GetGitHeadBranchRefName()
- return nil
- }
-
- // We are in Github flow, head and base repository are different.
- // Resolve the head branch to a commitID and return a Git alternate
- // environment for the head repository.
- gitRepo, err := git.OpenRepository(ctx, pr.HeadRepo.RepoPath())
+ prCtx, cancel, err := createTemporaryRepoForPR(ctx, pr)
if err != nil {
+ if !git_model.IsErrBranchNotExist(err) {
+ log.Error("CreateTemporaryRepoForPR %-v: %v", pr, err)
+ }
return err
}
+ defer cancel()
+
+ return testPatch(ctx, prCtx, pr)
+}
+
+func testPatch(ctx context.Context, prCtx *prContext, pr *issues_model.PullRequest) error {
+ gitRepo, err := git.OpenRepository(ctx, prCtx.tmpBasePath)
+ if err != nil {
+ return fmt.Errorf("OpenRepository: %w", err)
+ }
defer gitRepo.Close()
- headCommitID, err := gitRepo.GetRefCommitID(pr.GetGitHeadBranchRefName())
- if err != nil {
- return err
- }
-
- t.headRev = headCommitID
- t.headIsCommitID = true
- t.env = append(os.Environ(), `GIT_ALTERNATE_OBJECT_DIRECTORIES=`+pr.HeadRepo.RepoPath()+"/objects")
- return nil
-}
-
-// getTestPatchCtx constructs a new testpatch context for the given pull request.
-// If `onBare` is true, then the context will use the base repository that does
-// not contain a working tree. Otherwise a temprorary repository is created that
-// contains a working tree.
-func getTestPatchCtx(ctx context.Context, pr *issues_model.PullRequest, onBare bool) (*testPatchContext, error) {
- testPatchCtx := &testPatchContext{
- close: func() {},
- }
-
- if onBare {
- if err := pr.LoadBaseRepo(ctx); err != nil {
- return testPatchCtx, fmt.Errorf("LoadBaseRepo: %w", err)
- }
- if err := pr.LoadHeadRepo(ctx); err != nil {
- return testPatchCtx, fmt.Errorf("LoadHeadRepo: %w", err)
- }
-
- if err := testPatchCtx.LoadHeadRevision(ctx, pr); err != nil {
- return testPatchCtx, fmt.Errorf("LoadHeadRevision: %w", err)
- }
-
- gitRepo, err := git.OpenRepository(ctx, pr.BaseRepo.RepoPath())
- if err != nil {
- return testPatchCtx, fmt.Errorf("OpenRepository: %w", err)
- }
-
- testPatchCtx.baseRev = git.BranchPrefix + pr.BaseBranch
- testPatchCtx.gitRepo = gitRepo
- testPatchCtx.close = func() {
- gitRepo.Close()
- }
- } else {
- prCtx, cancel, err := createTemporaryRepoForPR(ctx, pr)
- if err != nil {
- return testPatchCtx, fmt.Errorf("createTemporaryRepoForPR: %w", err)
- }
- testPatchCtx.close = cancel
-
- gitRepo, err := git.OpenRepository(ctx, prCtx.tmpBasePath)
- if err != nil {
- return testPatchCtx, fmt.Errorf("OpenRepository: %w", err)
- }
-
- testPatchCtx.baseRev = git.BranchPrefix + baseBranch
- testPatchCtx.headRev = git.BranchPrefix + trackingBranch
- testPatchCtx.gitRepo = gitRepo
- testPatchCtx.close = func() {
- cancel()
- gitRepo.Close()
- }
- }
- return testPatchCtx, nil
-}
-
-func testPatch(ctx context.Context, pr *issues_model.PullRequest) (*testPatchContext, error) {
- testPatchCtx, err := getTestPatchCtx(ctx, pr, git.SupportGitMergeTree)
- if err != nil {
- return testPatchCtx, fmt.Errorf("getTestPatchCtx: %w", err)
- }
-
// 1. update merge base
- pr.MergeBase, _, err = git.NewCommand(ctx, "merge-base").AddDashesAndList(testPatchCtx.baseRev, testPatchCtx.headRev).RunStdString(&git.RunOpts{Dir: testPatchCtx.gitRepo.Path, Env: testPatchCtx.env})
+ pr.MergeBase, _, err = git.NewCommand(ctx, "merge-base", "--", "base", "tracking").RunStdString(&git.RunOpts{Dir: prCtx.tmpBasePath})
if err != nil {
var err2 error
- pr.MergeBase, err2 = testPatchCtx.gitRepo.GetRefCommitID(testPatchCtx.baseRev)
+ pr.MergeBase, err2 = gitRepo.GetRefCommitID(git.BranchPrefix + "base")
if err2 != nil {
- return testPatchCtx, fmt.Errorf("GetMergeBase: %v and can't find commit ID for base: %w", err, err2)
+ return fmt.Errorf("GetMergeBase: %v and can't find commit ID for base: %w", err, err2)
}
}
pr.MergeBase = strings.TrimSpace(pr.MergeBase)
-
- if testPatchCtx.headIsCommitID {
- pr.HeadCommitID = testPatchCtx.headRev
- } else {
- if pr.HeadCommitID, err = testPatchCtx.gitRepo.GetRefCommitID(testPatchCtx.headRev); err != nil {
- return testPatchCtx, fmt.Errorf("GetRefCommitID: can't find commit ID for head: %w", err)
- }
+ if pr.HeadCommitID, err = gitRepo.GetRefCommitID(git.BranchPrefix + "tracking"); err != nil {
+ return fmt.Errorf("GetBranchCommitID: can't find commit ID for head: %w", err)
}
- // If the head commit is equal to the merge base it roughly means that the
- // head commit is a parent of the base commit.
if pr.HeadCommitID == pr.MergeBase {
pr.Status = issues_model.PullRequestStatusAncestor
- return testPatchCtx, nil
+ return nil
}
// 2. Check for conflicts
- if conflicts, err := checkConflicts(ctx, pr, testPatchCtx); err != nil || conflicts || pr.Status == issues_model.PullRequestStatusEmpty {
- if err != nil {
- return testPatchCtx, fmt.Errorf("checkConflicts: %w", err)
- }
- return testPatchCtx, nil
+ if conflicts, err := checkConflicts(ctx, pr, gitRepo, prCtx.tmpBasePath); err != nil || conflicts || pr.Status == issues_model.PullRequestStatusEmpty {
+ return err
}
// 3. Check for protected files changes
- if err = checkPullFilesProtection(ctx, pr, testPatchCtx); err != nil {
- return testPatchCtx, fmt.Errorf("checkPullFilesProtection: %v", err)
+ if err = checkPullFilesProtection(ctx, pr, gitRepo); err != nil {
+ return fmt.Errorf("pr.CheckPullFilesProtection(): %v", err)
}
if len(pr.ChangedProtectedFiles) > 0 {
@@ -210,7 +117,7 @@ func testPatch(ctx context.Context, pr *issues_model.PullRequest) (*testPatchCon
pr.Status = issues_model.PullRequestStatusMergeable
- return testPatchCtx, nil
+ return nil
}
type errMergeConflict struct {
@@ -329,12 +236,12 @@ func attemptMerge(ctx context.Context, file *unmergedFile, tmpBasePath string, f
}
// AttemptThreeWayMerge will attempt to three way merge using git read-tree and then follow the git merge-one-file algorithm to attempt to resolve basic conflicts
-func AttemptThreeWayMerge(ctx context.Context, gitRepo *git.Repository, base, ours, theirs, description string) (bool, []string, error) {
+func AttemptThreeWayMerge(ctx context.Context, gitPath string, gitRepo *git.Repository, base, ours, theirs, description string) (bool, []string, error) {
ctx, cancel := context.WithCancel(ctx)
defer cancel()
// First we use read-tree to do a simple three-way merge
- if _, _, err := git.NewCommand(ctx, "read-tree", "-m").AddDynamicArguments(base, ours, theirs).RunStdString(&git.RunOpts{Dir: gitRepo.Path}); err != nil {
+ if _, _, err := git.NewCommand(ctx, "read-tree", "-m").AddDynamicArguments(base, ours, theirs).RunStdString(&git.RunOpts{Dir: gitPath}); err != nil {
log.Error("Unable to run read-tree -m! Error: %v", err)
return false, nil, fmt.Errorf("unable to run read-tree -m! Error: %w", err)
}
@@ -344,7 +251,7 @@ func AttemptThreeWayMerge(ctx context.Context, gitRepo *git.Repository, base, ou
// Then we use git ls-files -u to list the unmerged files and collate the triples in unmergedfiles
unmerged := make(chan *unmergedFile)
- go unmergedFiles(ctx, gitRepo.Path, unmerged)
+ go unmergedFiles(ctx, gitPath, unmerged)
defer func() {
cancel()
@@ -367,7 +274,7 @@ func AttemptThreeWayMerge(ctx context.Context, gitRepo *git.Repository, base, ou
}
// OK now we have the unmerged file triplet attempt to merge it
- if err := attemptMerge(ctx, file, gitRepo.Path, &filesToRemove, &filesToAdd); err != nil {
+ if err := attemptMerge(ctx, file, gitPath, &filesToRemove, &filesToAdd); err != nil {
if conflictErr, ok := err.(*errMergeConflict); ok {
log.Trace("Conflict: %s in %s", conflictErr.filename, description)
conflict = true
@@ -392,82 +299,14 @@ func AttemptThreeWayMerge(ctx context.Context, gitRepo *git.Repository, base, ou
return conflict, conflictedFiles, nil
}
-// MergeTree runs a 3-way merge between `ours` and `theirs` with
-// `base` as the merge base.
-//
-// It uses git-merge-tree(1) to do this merge without requiring a work-tree and
-// can run in a base repository. It returns the object ID of the merge tree, if
-// there are any conflicts and conflicted files.
-func MergeTree(ctx context.Context, gitRepo *git.Repository, base, ours, theirs string, env []string) (string, bool, []string, error) {
- cmd := git.NewCommand(ctx, "merge-tree", "--write-tree", "-z", "--name-only", "--no-messages")
- if git.CheckGitVersionAtLeast("2.40") == nil {
- cmd.AddOptionFormat("--merge-base=%s", base)
- }
-
- stdout := &bytes.Buffer{}
- gitErr := cmd.AddDynamicArguments(ours, theirs).Run(&git.RunOpts{Dir: gitRepo.Path, Stdout: stdout, Env: env})
- if gitErr != nil && !git.IsErrorExitCode(gitErr, 1) {
- log.Error("Unable to run merge-tree: %v", gitErr)
- return "", false, nil, fmt.Errorf("unable to run merge-tree: %w", gitErr)
- }
-
- // There are two situations that we consider for the output:
- // 1. Clean merge and the output is NUL
- // 2. Merge conflict and the output is NULNUL
- treeOID, conflictedFileInfo, _ := strings.Cut(stdout.String(), "\x00")
- if len(conflictedFileInfo) == 0 {
- return treeOID, git.IsErrorExitCode(gitErr, 1), nil, nil
- }
-
- // Remove last NULL-byte from conflicted file info, then split with NULL byte as seperator.
- return treeOID, true, strings.Split(conflictedFileInfo[:len(conflictedFileInfo)-1], "\x00"), nil
-}
-
-// checkConflicts takes a pull request and checks if merging it would result in
-// merge conflicts and checks if the diff is empty; the status is set accordingly.
-func checkConflicts(ctx context.Context, pr *issues_model.PullRequest, testPatchCtx *testPatchContext) (bool, error) {
- // Resets the conflict status.
+func checkConflicts(ctx context.Context, pr *issues_model.PullRequest, gitRepo *git.Repository, tmpBasePath string) (bool, error) {
+ // 1. checkConflicts resets the conflict status - therefore - reset the conflict status
pr.ConflictedFiles = nil
- if git.SupportGitMergeTree {
- // Check for conflicts via a merge-tree.
- treeHash, conflict, conflictFiles, err := MergeTree(ctx, testPatchCtx.gitRepo, pr.MergeBase, testPatchCtx.baseRev, testPatchCtx.headRev, testPatchCtx.env)
- if err != nil {
- return false, fmt.Errorf("MergeTree: %w", err)
- }
-
- if !conflict {
- // No conflicts were detected, now check if the pull request actually
- // contains anything useful via a diff. git-diff-tree(1) with --quiet
- // will return exit code 0 if there's no diff and exit code 1 if there's
- // a diff.
- err := git.NewCommand(ctx, "diff-tree", "--quiet").AddDynamicArguments(treeHash, pr.MergeBase).Run(&git.RunOpts{Dir: testPatchCtx.gitRepo.Path, Env: testPatchCtx.env})
- isEmpty := true
- if err != nil {
- if git.IsErrorExitCode(err, 1) {
- isEmpty = false
- } else {
- return false, fmt.Errorf("DiffTree: %w", err)
- }
- }
-
- if isEmpty {
- log.Debug("PullRequest[%d]: Patch is empty - ignoring", pr.ID)
- pr.Status = issues_model.PullRequestStatusEmpty
- }
- return false, nil
- }
-
- pr.Status = issues_model.PullRequestStatusConflict
- pr.ConflictedFiles = conflictFiles
-
- log.Trace("Found %d files conflicted: %v", len(pr.ConflictedFiles), pr.ConflictedFiles)
- return true, nil
- }
-
// 2. AttemptThreeWayMerge first - this is much quicker than plain patch to base
description := fmt.Sprintf("PR[%d] %s/%s#%d", pr.ID, pr.BaseRepo.OwnerName, pr.BaseRepo.Name, pr.Index)
- conflict, conflictFiles, err := AttemptThreeWayMerge(ctx, testPatchCtx.gitRepo, pr.MergeBase, testPatchCtx.baseRev, testPatchCtx.headRev, description)
+ conflict, conflictFiles, err := AttemptThreeWayMerge(ctx,
+ tmpBasePath, gitRepo, pr.MergeBase, "base", "tracking", description)
if err != nil {
return false, err
}
@@ -476,13 +315,13 @@ func checkConflicts(ctx context.Context, pr *issues_model.PullRequest, testPatch
// No conflicts detected so we need to check if the patch is empty...
// a. Write the newly merged tree and check the new tree-hash
var treeHash string
- treeHash, _, err = git.NewCommand(ctx, "write-tree").RunStdString(&git.RunOpts{Dir: testPatchCtx.gitRepo.Path})
+ treeHash, _, err = git.NewCommand(ctx, "write-tree").RunStdString(&git.RunOpts{Dir: tmpBasePath})
if err != nil {
- lsfiles, _, _ := git.NewCommand(ctx, "ls-files", "-u").RunStdString(&git.RunOpts{Dir: testPatchCtx.gitRepo.Path})
+ lsfiles, _, _ := git.NewCommand(ctx, "ls-files", "-u").RunStdString(&git.RunOpts{Dir: tmpBasePath})
return false, fmt.Errorf("unable to write unconflicted tree: %w\n`git ls-files -u`:\n%s", err, lsfiles)
}
treeHash = strings.TrimSpace(treeHash)
- baseTree, err := testPatchCtx.gitRepo.GetTree(testPatchCtx.baseRev)
+ baseTree, err := gitRepo.GetTree("base")
if err != nil {
return false, err
}
@@ -496,11 +335,171 @@ func checkConflicts(ctx context.Context, pr *issues_model.PullRequest, testPatch
return false, nil
}
- pr.Status = issues_model.PullRequestStatusConflict
- pr.ConflictedFiles = conflictFiles
+ // 3. OK the three-way merge method has detected conflicts
+ // 3a. Are still testing with GitApply? If not set the conflict status and move on
+ if !setting.Repository.PullRequest.TestConflictingPatchesWithGitApply {
+ pr.Status = issues_model.PullRequestStatusConflict
+ pr.ConflictedFiles = conflictFiles
- log.Trace("Found %d files conflicted: %v", len(pr.ConflictedFiles), pr.ConflictedFiles)
- return true, nil
+ log.Trace("Found %d files conflicted: %v", len(pr.ConflictedFiles), pr.ConflictedFiles)
+ return true, nil
+ }
+
+ // 3b. Create a plain patch from head to base
+ tmpPatchFile, err := os.CreateTemp("", "patch")
+ if err != nil {
+ log.Error("Unable to create temporary patch file! Error: %v", err)
+ return false, fmt.Errorf("unable to create temporary patch file! Error: %w", err)
+ }
+ defer func() {
+ _ = util.Remove(tmpPatchFile.Name())
+ }()
+
+ if err := gitRepo.GetDiffBinary(pr.MergeBase, "tracking", tmpPatchFile); err != nil {
+ tmpPatchFile.Close()
+ log.Error("Unable to get patch file from %s to %s in %s Error: %v", pr.MergeBase, pr.HeadBranch, pr.BaseRepo.FullName(), err)
+ return false, fmt.Errorf("unable to get patch file from %s to %s in %s Error: %w", pr.MergeBase, pr.HeadBranch, pr.BaseRepo.FullName(), err)
+ }
+ stat, err := tmpPatchFile.Stat()
+ if err != nil {
+ tmpPatchFile.Close()
+ return false, fmt.Errorf("unable to stat patch file: %w", err)
+ }
+ patchPath := tmpPatchFile.Name()
+ tmpPatchFile.Close()
+
+ // 3c. if the size of that patch is 0 - there can be no conflicts!
+ if stat.Size() == 0 {
+ log.Debug("PullRequest[%d]: Patch is empty - ignoring", pr.ID)
+ pr.Status = issues_model.PullRequestStatusEmpty
+ return false, nil
+ }
+
+ log.Trace("PullRequest[%d].testPatch (patchPath): %s", pr.ID, patchPath)
+
+ // 4. Read the base branch in to the index of the temporary repository
+ _, _, err = git.NewCommand(gitRepo.Ctx, "read-tree", "base").RunStdString(&git.RunOpts{Dir: tmpBasePath})
+ if err != nil {
+ return false, fmt.Errorf("git read-tree %s: %w", pr.BaseBranch, err)
+ }
+
+ // 5. Now get the pull request configuration to check if we need to ignore whitespace
+ prUnit, err := pr.BaseRepo.GetUnit(ctx, unit.TypePullRequests)
+ if err != nil {
+ return false, err
+ }
+ prConfig := prUnit.PullRequestsConfig()
+
+ // 6. Prepare the arguments to apply the patch against the index
+ cmdApply := git.NewCommand(gitRepo.Ctx, "apply", "--check", "--cached")
+ if prConfig.IgnoreWhitespaceConflicts {
+ cmdApply.AddArguments("--ignore-whitespace")
+ }
+ is3way := false
+ if git.CheckGitVersionAtLeast("2.32.0") == nil {
+ cmdApply.AddArguments("--3way")
+ is3way = true
+ }
+ cmdApply.AddDynamicArguments(patchPath)
+
+ // 7. Prep the pipe:
+ // - Here we could do the equivalent of:
+ // `git apply --check --cached patch_file > conflicts`
+ // Then iterate through the conflicts. However, that means storing all the conflicts
+ // in memory - which is very wasteful.
+ // - alternatively we can do the equivalent of:
+ // `git apply --check ... | grep ...`
+ // meaning we don't store all of the conflicts unnecessarily.
+ stderrReader, stderrWriter, err := os.Pipe()
+ if err != nil {
+ log.Error("Unable to open stderr pipe: %v", err)
+ return false, fmt.Errorf("unable to open stderr pipe: %w", err)
+ }
+ defer func() {
+ _ = stderrReader.Close()
+ _ = stderrWriter.Close()
+ }()
+
+ // 8. Run the check command
+ conflict = false
+ err = cmdApply.Run(&git.RunOpts{
+ Dir: tmpBasePath,
+ Stderr: stderrWriter,
+ PipelineFunc: func(ctx context.Context, cancel context.CancelFunc) error {
+ // Close the writer end of the pipe to begin processing
+ _ = stderrWriter.Close()
+ defer func() {
+ // Close the reader on return to terminate the git command if necessary
+ _ = stderrReader.Close()
+ }()
+
+ const prefix = "error: patch failed:"
+ const errorPrefix = "error: "
+ const threewayFailed = "Failed to perform three-way merge..."
+ const appliedPatchPrefix = "Applied patch to '"
+ const withConflicts = "' with conflicts."
+
+ conflicts := make(container.Set[string])
+
+ // Now scan the output from the command
+ scanner := bufio.NewScanner(stderrReader)
+ for scanner.Scan() {
+ line := scanner.Text()
+ log.Trace("PullRequest[%d].testPatch: stderr: %s", pr.ID, line)
+ if strings.HasPrefix(line, prefix) {
+ conflict = true
+ filepath := strings.TrimSpace(strings.Split(line[len(prefix):], ":")[0])
+ conflicts.Add(filepath)
+ } else if is3way && line == threewayFailed {
+ conflict = true
+ } else if strings.HasPrefix(line, errorPrefix) {
+ conflict = true
+ for _, suffix := range patchErrorSuffices {
+ if strings.HasSuffix(line, suffix) {
+ filepath := strings.TrimSpace(strings.TrimSuffix(line[len(errorPrefix):], suffix))
+ if filepath != "" {
+ conflicts.Add(filepath)
+ }
+ break
+ }
+ }
+ } else if is3way && strings.HasPrefix(line, appliedPatchPrefix) && strings.HasSuffix(line, withConflicts) {
+ conflict = true
+ filepath := strings.TrimPrefix(strings.TrimSuffix(line, withConflicts), appliedPatchPrefix)
+ if filepath != "" {
+ conflicts.Add(filepath)
+ }
+ }
+ // only list 10 conflicted files
+ if len(conflicts) >= 10 {
+ break
+ }
+ }
+
+ if len(conflicts) > 0 {
+ pr.ConflictedFiles = make([]string, 0, len(conflicts))
+ for key := range conflicts {
+ pr.ConflictedFiles = append(pr.ConflictedFiles, key)
+ }
+ }
+
+ return nil
+ },
+ })
+
+ // 9. Check if the found conflictedfiles is non-zero, "err" could be non-nil, so we should ignore it if we found conflicts.
+ // Note: `"err" could be non-nil` is due that if enable 3-way merge, it doesn't return any error on found conflicts.
+ if len(pr.ConflictedFiles) > 0 {
+ if conflict {
+ pr.Status = issues_model.PullRequestStatusConflict
+ log.Trace("Found %d files conflicted: %v", len(pr.ConflictedFiles), pr.ConflictedFiles)
+
+ return true, nil
+ }
+ } else if err != nil {
+ return false, fmt.Errorf("git apply --check: %w", err)
+ }
+ return false, nil
}
// CheckFileProtection check file Protection
@@ -559,7 +558,7 @@ func CheckUnprotectedFiles(repo *git.Repository, oldCommitID, newCommitID string
}
// checkPullFilesProtection check if pr changed protected files and save results
-func checkPullFilesProtection(ctx context.Context, pr *issues_model.PullRequest, testPatchCtx *testPatchContext) error {
+func checkPullFilesProtection(ctx context.Context, pr *issues_model.PullRequest, gitRepo *git.Repository) error {
if pr.Status == issues_model.PullRequestStatusEmpty {
pr.ChangedProtectedFiles = nil
return nil
@@ -575,7 +574,7 @@ func checkPullFilesProtection(ctx context.Context, pr *issues_model.PullRequest,
return nil
}
- pr.ChangedProtectedFiles, err = CheckFileProtection(testPatchCtx.gitRepo, pr.MergeBase, testPatchCtx.headRev, pb.GetProtectedFilePatterns(), 10, testPatchCtx.env)
+ pr.ChangedProtectedFiles, err = CheckFileProtection(gitRepo, pr.MergeBase, "tracking", pb.GetProtectedFilePatterns(), 10, os.Environ())
if err != nil && !models.IsErrFilePathProtected(err) {
return err
}
diff --git a/services/pull/patch_test.go b/services/pull/patch_test.go
deleted file mode 100644
index bcab19fc58..0000000000
--- a/services/pull/patch_test.go
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2025 The Forgejo Authors. All rights reserved.
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-package pull
-
-import (
- "fmt"
- "testing"
-
- issues_model "forgejo.org/models/issues"
- "forgejo.org/models/unittest"
- "forgejo.org/modules/setting"
-
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
-)
-
-func TestLoadHeadRevision(t *testing.T) {
- require.NoError(t, unittest.PrepareTestDatabase())
-
- t.Run("AGit", func(t *testing.T) {
- t.Run("New", func(t *testing.T) {
- ctx := &testPatchContext{}
- require.NoError(t, ctx.LoadHeadRevision(t.Context(), &issues_model.PullRequest{Flow: issues_model.PullRequestFlowAGit, HeadCommitID: "Commit!"}))
-
- assert.Empty(t, ctx.env)
- assert.Equal(t, "Commit!", ctx.headRev)
- assert.True(t, ctx.headIsCommitID)
- })
- t.Run("Existing", func(t *testing.T) {
- ctx := &testPatchContext{}
- require.NoError(t, ctx.LoadHeadRevision(t.Context(), &issues_model.PullRequest{Flow: issues_model.PullRequestFlowAGit, Index: 371}))
-
- assert.Empty(t, ctx.env)
- assert.Equal(t, "refs/pull/371/head", ctx.headRev)
- assert.False(t, ctx.headIsCommitID)
- })
- })
-
- t.Run("Same repository", func(t *testing.T) {
- ctx := &testPatchContext{}
- require.NoError(t, ctx.LoadHeadRevision(t.Context(), unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1})))
-
- assert.Empty(t, ctx.env)
- assert.Equal(t, "refs/heads/branch1", ctx.headRev)
- assert.False(t, ctx.headIsCommitID)
- })
-
- t.Run("Across repository", func(t *testing.T) {
- pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 3})
- require.NoError(t, pr.LoadHeadRepo(t.Context()))
-
- ctx := &testPatchContext{}
- require.NoError(t, ctx.LoadHeadRevision(t.Context(), pr))
-
- if assert.NotEmpty(t, ctx.env) {
- assert.Equal(t, fmt.Sprintf("GIT_ALTERNATE_OBJECT_DIRECTORIES=%s/user13/repo11.git/objects", setting.RepoRootPath), ctx.env[len(ctx.env)-1])
- }
- assert.Equal(t, "0abcb056019adb8336cf9db3ad9d9cf80cd4b141", ctx.headRev)
- assert.True(t, ctx.headIsCommitID)
- })
-}
diff --git a/services/pull/patch_unmerged.go b/services/pull/patch_unmerged.go
index caa0318c48..c60c48d923 100644
--- a/services/pull/patch_unmerged.go
+++ b/services/pull/patch_unmerged.go
@@ -13,8 +13,8 @@ import (
"strconv"
"strings"
- "forgejo.org/modules/git"
- "forgejo.org/modules/log"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/log"
)
// lsFileLine is a Quadruplet struct (+error) representing a partially parsed line from ls-files
diff --git a/services/pull/pull.go b/services/pull/pull.go
index c1fe6c6b55..6af7d8ba0c 100644
--- a/services/pull/pull.go
+++ b/services/pull/pull.go
@@ -4,33 +4,36 @@
package pull
import (
+ "bytes"
"context"
"fmt"
"io"
+ "os"
"regexp"
"strings"
"time"
- "forgejo.org/models"
- "forgejo.org/models/db"
- git_model "forgejo.org/models/git"
- issues_model "forgejo.org/models/issues"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/base"
- "forgejo.org/modules/container"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/graceful"
- "forgejo.org/modules/json"
- "forgejo.org/modules/log"
- "forgejo.org/modules/process"
- repo_module "forgejo.org/modules/repository"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/sync"
- gitea_context "forgejo.org/services/context"
- issue_service "forgejo.org/services/issue"
- notify_service "forgejo.org/services/notify"
+ "code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/models/db"
+ git_model "code.gitea.io/gitea/models/git"
+ issues_model "code.gitea.io/gitea/models/issues"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/container"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/graceful"
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/process"
+ repo_module "code.gitea.io/gitea/modules/repository"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/sync"
+ "code.gitea.io/gitea/modules/util"
+ gitea_context "code.gitea.io/gitea/services/context"
+ issue_service "code.gitea.io/gitea/services/issue"
+ notify_service "code.gitea.io/gitea/services/notify"
)
// TODO: use clustered lock (unique queue? or *abuse* cache)
@@ -43,15 +46,22 @@ func NewPullRequest(ctx context.Context, repo *repo_model.Repository, issue *iss
return user_model.ErrBlockedByUser
}
- testPatchCtx, err := testPatch(ctx, pr)
- defer testPatchCtx.close()
+ prCtx, cancel, err := createTemporaryRepoForPR(ctx, pr)
if err != nil {
- return fmt.Errorf("testPatch: %w", err)
+ if !git_model.IsErrBranchNotExist(err) {
+ log.Error("CreateTemporaryRepoForPR %-v: %v", pr, err)
+ }
+ return err
+ }
+ defer cancel()
+
+ if err := testPatch(ctx, prCtx, pr); err != nil {
+ return err
}
- divergence, err := git.GetDivergingCommits(ctx, testPatchCtx.gitRepo.Path, testPatchCtx.baseRev, testPatchCtx.headRev, testPatchCtx.env)
+ divergence, err := git.GetDivergingCommits(ctx, prCtx.tmpBasePath, baseBranch, trackingBranch)
if err != nil {
- return fmt.Errorf("GetDivergingCommits: %w", err)
+ return err
}
pr.CommitsAhead = divergence.Ahead
pr.CommitsBehind = divergence.Behind
@@ -381,49 +391,96 @@ func TestPullRequest(ctx context.Context, doer *user_model.User, repoID, olderTh
// Update commit divergence.
func ValidatePullRequest(ctx context.Context, pr *issues_model.PullRequest, newCommitID, oldCommitID string, doer *user_model.User) {
objectFormat := git.ObjectFormatFromName(pr.BaseRepo.ObjectFormatName)
- if newCommitID == "" || newCommitID == objectFormat.EmptyObjectID().String() {
- return
- }
-
- testPatchCtx, err := getTestPatchCtx(ctx, pr, true)
- defer testPatchCtx.close()
- if err != nil {
- log.Error("testPatchCtx: %v", err)
- return
- }
-
- changed, err := testPatchCtx.gitRepo.CheckIfDiffDiffers(testPatchCtx.baseRev, oldCommitID, newCommitID, testPatchCtx.env)
- if err != nil {
- log.Error("CheckIfDiffDiffers: %v", err)
- }
- if changed {
- if err := issues_model.MarkReviewsAsStale(ctx, pr.IssueID); err != nil {
- log.Error("MarkReviewsAsStale: %v", err)
- }
-
- pb, err := git_model.GetFirstMatchProtectedBranchRule(ctx, pr.BaseRepoID, pr.BaseBranch)
+ if newCommitID != "" && newCommitID != objectFormat.EmptyObjectID().String() {
+ changed, err := checkIfPRContentChanged(ctx, pr, oldCommitID, newCommitID)
if err != nil {
- log.Error("GetFirstMatchProtectedBranchRule: %v", err)
+ log.Error("checkIfPRContentChanged: %v", err)
}
- if pb != nil && pb.DismissStaleApprovals {
- if err := DismissApprovalReviews(ctx, doer, pr); err != nil {
- log.Error("DismissApprovalReviews: %v", err)
+ if changed {
+ if err := issues_model.MarkReviewsAsStale(ctx, pr.IssueID); err != nil {
+ log.Error("MarkReviewsAsStale: %v", err)
+ }
+
+ pb, err := git_model.GetFirstMatchProtectedBranchRule(ctx, pr.BaseRepoID, pr.BaseBranch)
+ if err != nil {
+ log.Error("GetFirstMatchProtectedBranchRule: %v", err)
+ }
+ if pb != nil && pb.DismissStaleApprovals {
+ if err := DismissApprovalReviews(ctx, doer, pr); err != nil {
+ log.Error("DismissApprovalReviews: %v", err)
+ }
+ }
+ }
+ if err := issues_model.MarkReviewsAsNotStale(ctx, pr.IssueID, newCommitID); err != nil {
+ log.Error("MarkReviewsAsNotStale: %v", err)
+ }
+ divergence, err := GetDiverging(ctx, pr)
+ if err != nil {
+ log.Error("GetDiverging: %v", err)
+ } else {
+ err = pr.UpdateCommitDivergence(ctx, divergence.Ahead, divergence.Behind)
+ if err != nil {
+ log.Error("UpdateCommitDivergence: %v", err)
}
}
}
- if err := issues_model.MarkReviewsAsNotStale(ctx, pr.IssueID, newCommitID); err != nil {
- log.Error("MarkReviewsAsNotStale: %v", err)
+}
+
+// checkIfPRContentChanged checks if diff to target branch has changed by push
+// A commit can be considered to leave the PR untouched if the patch/diff with its merge base is unchanged
+func checkIfPRContentChanged(ctx context.Context, pr *issues_model.PullRequest, oldCommitID, newCommitID string) (hasChanged bool, err error) {
+ prCtx, cancel, err := createTemporaryRepoForPR(ctx, pr)
+ if err != nil {
+ log.Error("CreateTemporaryRepoForPR %-v: %v", pr, err)
+ return false, err
+ }
+ defer cancel()
+
+ tmpRepo, err := git.OpenRepository(ctx, prCtx.tmpBasePath)
+ if err != nil {
+ return false, fmt.Errorf("OpenRepository: %w", err)
+ }
+ defer tmpRepo.Close()
+
+ // Find the merge-base
+ _, base, err := tmpRepo.GetMergeBase("", "base", "tracking")
+ if err != nil {
+ return false, fmt.Errorf("GetMergeBase: %w", err)
}
- divergence, err := git.GetDivergingCommits(ctx, testPatchCtx.gitRepo.Path, testPatchCtx.baseRev, testPatchCtx.headRev, testPatchCtx.env)
+ cmd := git.NewCommand(ctx, "diff", "--name-only", "-z").AddDynamicArguments(newCommitID, oldCommitID, base)
+ stdoutReader, stdoutWriter, err := os.Pipe()
if err != nil {
- log.Error("GetDivergingCommits: %v", err)
- } else {
- err = pr.UpdateCommitDivergence(ctx, divergence.Ahead, divergence.Behind)
- if err != nil {
- log.Error("UpdateCommitDivergence: %v", err)
- }
+ return false, fmt.Errorf("unable to open pipe for to run diff: %w", err)
}
+
+ stderr := new(bytes.Buffer)
+ if err := cmd.Run(&git.RunOpts{
+ Dir: prCtx.tmpBasePath,
+ Stdout: stdoutWriter,
+ Stderr: stderr,
+ PipelineFunc: func(ctx context.Context, cancel context.CancelFunc) error {
+ _ = stdoutWriter.Close()
+ defer func() {
+ _ = stdoutReader.Close()
+ }()
+ return util.IsEmptyReader(stdoutReader)
+ },
+ }); err != nil {
+ if err == util.ErrNotEmpty {
+ return true, nil
+ }
+ err = git.ConcatenateError(err, stderr.String())
+
+ log.Error("Unable to run diff on %s %s %s in tempRepo for PR[%d]%s/%s...%s/%s: Error: %v",
+ newCommitID, oldCommitID, base,
+ pr.ID, pr.BaseRepo.FullName(), pr.BaseBranch, pr.HeadRepo.FullName(), pr.HeadBranch,
+ err)
+
+ return false, fmt.Errorf("Unable to run git diff --name-only -z %s %s %s: %w", newCommitID, oldCommitID, base, err)
+ }
+
+ return false, nil
}
// PushToBaseRepo pushes commits from branches of head repository to
diff --git a/services/pull/pull_test.go b/services/pull/pull_test.go
index 99607c5b35..c51619e7f6 100644
--- a/services/pull/pull_test.go
+++ b/services/pull/pull_test.go
@@ -7,13 +7,13 @@ package pull
import (
"testing"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unit"
- "forgejo.org/models/unittest"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unit"
+ "code.gitea.io/gitea/models/unittest"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -92,39 +92,3 @@ func TestPullRequest_GetDefaultMergeMessage_ExternalTracker(t *testing.T) {
assert.Equal(t, "Merge pull request 'issue3' (#3) from user2/repo2:branch2 into master", mergeMessage)
}
-
-func TestPullRequest_GetDefaultMergeMessage_GlobalTemplate(t *testing.T) {
- require.NoError(t, unittest.PrepareTestDatabase())
- pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2})
-
- require.NoError(t, pr.LoadBaseRepo(t.Context()))
- gitRepo, err := gitrepo.OpenRepository(t.Context(), pr.BaseRepo)
- require.NoError(t, err)
- defer gitRepo.Close()
-
- templateRepo, err := git.OpenRepository(t.Context(), "./../../modules/git/tests/repos/templates_repo")
- require.NoError(t, err)
- defer templateRepo.Close()
-
- mergeMessageTemplates[repo_model.MergeStyleMerge] = "${PullRequestTitle} (${PullRequestReference})\n${PullRequestDescription}"
-
- // Check template is used for Merge...
- mergeMessage, body, err := GetDefaultMergeMessage(t.Context(), gitRepo, pr, repo_model.MergeStyleMerge)
- require.NoError(t, err)
-
- assert.Equal(t, "issue3 (#3)", mergeMessage)
- assert.Equal(t, "content for the third issue", body)
-
- // ...but not for RebaseMerge
- mergeMessage, _, err = GetDefaultMergeMessage(t.Context(), gitRepo, pr, repo_model.MergeStyleRebaseMerge)
- require.NoError(t, err)
-
- assert.Equal(t, "Merge pull request 'issue3' (#3) from branch2 into master", mergeMessage)
-
- // ...and that custom Merge template takes priority
- mergeMessage, body, err = GetDefaultMergeMessage(t.Context(), templateRepo, pr, repo_model.MergeStyleMerge)
- require.NoError(t, err)
-
- assert.Equal(t, "Default merge message template", mergeMessage)
- assert.Equal(t, "This line was read from .forgejo/default_merge_message/MERGE_TEMPLATE.md", body)
-}
diff --git a/services/pull/review.go b/services/pull/review.go
index b0ab700fa6..927c43150b 100644
--- a/services/pull/review.go
+++ b/services/pull/review.go
@@ -6,23 +6,26 @@ package pull
import (
"context"
- "errors"
"fmt"
"io"
+ "regexp"
+ "strings"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/log"
- "forgejo.org/modules/optional"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/util"
- notify_service "forgejo.org/services/notify"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/optional"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/util"
+ notify_service "code.gitea.io/gitea/services/notify"
)
+var notEnoughLines = regexp.MustCompile(`fatal: file .* has only \d+ lines?`)
+
// ErrDismissRequestOnClosedPR represents an error when an user tries to dismiss a review associated to a closed or merged PR.
type ErrDismissRequestOnClosedPR struct{}
@@ -44,8 +47,8 @@ func (err ErrDismissRequestOnClosedPR) Unwrap() error {
// If the line got changed the comment is going to be invalidated.
func checkInvalidation(ctx context.Context, c *issues_model.Comment, repo *git.Repository, branch string) error {
// FIXME differentiate between previous and proposed line
- commit, err := repo.LineBlame(branch, c.TreePath, c.UnsignedLine())
- if err != nil && (errors.Is(err, git.ErrBlameFileDoesNotExist) || errors.Is(err, git.ErrBlameFileNotEnoughLines)) {
+ commit, err := repo.LineBlame(branch, repo.Path, c.TreePath, uint(c.UnsignedLine()))
+ if err != nil && (strings.Contains(err.Error(), "fatal: no such path") || notEnoughLines.MatchString(err.Error())) {
c.Invalidated = true
return issues_model.UpdateCommentInvalidate(ctx, c)
}
@@ -226,10 +229,10 @@ func CreateCodeCommentKnownReviewID(ctx context.Context, doer *user_model.User,
// FIXME validate treePath
// Get latest commit referencing the commented line
// No need for get commit for base branch changes
- commit, err := gitRepo.LineBlame(head, treePath, uint64(line))
+ commit, err := gitRepo.LineBlame(head, gitRepo.Path, treePath, uint(line))
if err == nil {
commitID = commit.ID.String()
- } else if !errors.Is(err, git.ErrBlameFileDoesNotExist) && !errors.Is(err, git.ErrBlameFileNotEnoughLines) {
+ } else if !(strings.Contains(err.Error(), "exit status 128 - fatal: no such path") || notEnoughLines.MatchString(err.Error())) {
return nil, fmt.Errorf("LineBlame[%s, %s, %s, %d]: %w", pr.GetGitRefName(), gitRepo.Path, treePath, line, err)
}
}
@@ -298,16 +301,10 @@ func SubmitReview(ctx context.Context, doer *user_model.User, gitRepo *git.Repos
if headCommitID == commitID {
stale = false
} else {
- testPatchCtx, err := getTestPatchCtx(ctx, pr, true)
- defer testPatchCtx.close()
+ stale, err = checkIfPRContentChanged(ctx, pr, commitID, headCommitID)
if err != nil {
return nil, nil, err
}
-
- stale, err = testPatchCtx.gitRepo.CheckIfDiffDiffers(testPatchCtx.baseRev, commitID, headCommitID, testPatchCtx.env)
- if err != nil {
- return nil, nil, fmt.Errorf("CheckIfDiffDiffers: %w", err)
- }
}
}
@@ -390,7 +387,7 @@ func DismissReview(ctx context.Context, reviewID, repoID int64, message string,
}
if review.Type != issues_model.ReviewTypeApprove && review.Type != issues_model.ReviewTypeReject {
- return nil, errors.New("not need to dismiss this review because it's type is not Approve or change request")
+ return nil, fmt.Errorf("not need to dismiss this review because it's type is not Approve or change request")
}
// load data for notify
@@ -400,7 +397,7 @@ func DismissReview(ctx context.Context, reviewID, repoID int64, message string,
// Check if the review's repoID is the one we're currently expecting.
if review.Issue.RepoID != repoID {
- return nil, errors.New("reviews's repository is not the same as the one we expect")
+ return nil, fmt.Errorf("reviews's repository is not the same as the one we expect")
}
issue := review.Issue
diff --git a/services/pull/review_test.go b/services/pull/review_test.go
index 0d9fe7f902..4cb3ad007c 100644
--- a/services/pull/review_test.go
+++ b/services/pull/review_test.go
@@ -6,11 +6,11 @@ package pull_test
import (
"testing"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- "forgejo.org/models/unittest"
- user_model "forgejo.org/models/user"
- pull_service "forgejo.org/services/pull"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ "code.gitea.io/gitea/models/unittest"
+ user_model "code.gitea.io/gitea/models/user"
+ pull_service "code.gitea.io/gitea/services/pull"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
diff --git a/services/pull/temp_repo.go b/services/pull/temp_repo.go
index 76ae0df018..36bdbde55c 100644
--- a/services/pull/temp_repo.go
+++ b/services/pull/temp_repo.go
@@ -11,12 +11,12 @@ import (
"path/filepath"
"strings"
- git_model "forgejo.org/models/git"
- issues_model "forgejo.org/models/issues"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/modules/git"
- "forgejo.org/modules/log"
- repo_module "forgejo.org/modules/repository"
+ git_model "code.gitea.io/gitea/models/git"
+ issues_model "code.gitea.io/gitea/models/issues"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/log"
+ repo_module "code.gitea.io/gitea/modules/repository"
)
// Temporary repos created here use standard branch names to help simplify
@@ -103,7 +103,11 @@ func createTemporaryRepoForPR(ctx context.Context, pr *issues_model.PullRequest)
remoteRepoName := "head_repo"
baseBranch := "base"
- fetchArgs := git.TrustedCmdArgs{"--no-tags", "--no-write-commit-graph"}
+ fetchArgs := git.TrustedCmdArgs{"--no-tags"}
+ if git.CheckGitVersionAtLeast("2.25.0") == nil {
+ // Writing the commit graph can be slow and is not needed here
+ fetchArgs = append(fetchArgs, "--no-write-commit-graph")
+ }
// addCacheRepo adds git alternatives for the cacheRepoPath in the repoPath
addCacheRepo := func(repoPath, cacheRepoPath string) error {
diff --git a/services/pull/update.go b/services/pull/update.go
index 563c11fff3..dbc1b711e2 100644
--- a/services/pull/update.go
+++ b/services/pull/update.go
@@ -5,25 +5,24 @@ package pull
import (
"context"
- "errors"
"fmt"
- git_model "forgejo.org/models/git"
- issues_model "forgejo.org/models/issues"
- access_model "forgejo.org/models/perm/access"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unit"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/log"
- "forgejo.org/modules/repository"
+ git_model "code.gitea.io/gitea/models/git"
+ issues_model "code.gitea.io/gitea/models/issues"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unit"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/repository"
)
// Update updates pull request with base branch.
func Update(ctx context.Context, pr *issues_model.PullRequest, doer *user_model.User, message string, rebase bool) error {
if pr.Flow == issues_model.PullRequestFlowAGit {
// TODO: update of agit flow pull request's head branch is unsupported
- return errors.New("update of agit flow pull request's head branch is unsupported")
+ return fmt.Errorf("update of agit flow pull request's head branch is unsupported")
}
pullWorkingPool.CheckIn(fmt.Sprint(pr.ID))
@@ -176,6 +175,6 @@ func GetDiverging(ctx context.Context, pr *issues_model.PullRequest) (*git.Diver
}
defer cancel()
- diff, err := git.GetDivergingCommits(ctx, prCtx.tmpBasePath, baseBranch, trackingBranch, nil)
+ diff, err := git.GetDivergingCommits(ctx, prCtx.tmpBasePath, baseBranch, trackingBranch)
return &diff, err
}
diff --git a/services/pull/update_rebase.go b/services/pull/update_rebase.go
index b12613985a..3e2a7be132 100644
--- a/services/pull/update_rebase.go
+++ b/services/pull/update_rebase.go
@@ -8,13 +8,13 @@ import (
"fmt"
"strings"
- issues_model "forgejo.org/models/issues"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/log"
- repo_module "forgejo.org/modules/repository"
- "forgejo.org/modules/setting"
+ issues_model "code.gitea.io/gitea/models/issues"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/log"
+ repo_module "code.gitea.io/gitea/modules/repository"
+ "code.gitea.io/gitea/modules/setting"
)
// updateHeadByRebaseOnToBase handles updating a PR's head branch by rebasing it on the PR current base branch
diff --git a/services/redirect/main_test.go b/services/redirect/main_test.go
deleted file mode 100644
index 7363791caa..0000000000
--- a/services/redirect/main_test.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2025 The Forgejo Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-package redirect
-
-import (
- "testing"
-
- "forgejo.org/models/unittest"
-
- _ "forgejo.org/models"
- _ "forgejo.org/models/actions"
- _ "forgejo.org/models/activities"
- _ "forgejo.org/models/forgefed"
-)
-
-func TestMain(m *testing.M) {
- unittest.MainTest(m)
-}
diff --git a/services/redirect/repo.go b/services/redirect/repo.go
deleted file mode 100644
index 7070ab4e2f..0000000000
--- a/services/redirect/repo.go
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2025 The Forgejo Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-package redirect
-
-import (
- "context"
-
- access_model "forgejo.org/models/perm/access"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
-)
-
-// LookupRepoRedirect returns the repository ID if there's a redirect registered for
-// the ownerID repository name pair. It checks if the doer has permission to view
-// the new repository.
-func LookupRepoRedirect(ctx context.Context, doer *user_model.User, ownerID int64, repoName string) (int64, error) {
- redirectID, err := repo_model.GetRedirect(ctx, ownerID, repoName)
- if err != nil {
- return 0, err
- }
-
- redirectRepo, err := repo_model.GetRepositoryByID(ctx, redirectID)
- if err != nil {
- return 0, err
- }
-
- perm, err := access_model.GetUserRepoPermission(ctx, redirectRepo, doer)
- if err != nil {
- return 0, err
- }
-
- if !perm.HasAccess() {
- return 0, repo_model.ErrRedirectNotExist{OwnerID: ownerID, RepoName: repoName, MissingPermission: true}
- }
-
- return redirectID, nil
-}
diff --git a/services/redirect/repo_test.go b/services/redirect/repo_test.go
deleted file mode 100644
index cad8414035..0000000000
--- a/services/redirect/repo_test.go
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2025 The Forgejo Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-package redirect
-
-import (
- "testing"
-
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unittest"
- user_model "forgejo.org/models/user"
-
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
-)
-
-func TestLookupRepoRedirect(t *testing.T) {
- require.NoError(t, unittest.PrepareTestDatabase())
-
- normalUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5})
- ownerUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 20})
-
- testOk := func(t *testing.T, doer *user_model.User, ownerID int64, repoName string, expectedRedirectID int64) {
- t.Helper()
-
- redirectID, err := LookupRepoRedirect(t.Context(), doer, ownerID, repoName)
- require.NoError(t, err)
- assert.Equal(t, expectedRedirectID, redirectID)
- }
-
- testFail := func(t *testing.T, doer *user_model.User, ownerID int64, repoName string) {
- t.Helper()
-
- redirectID, err := LookupRepoRedirect(t.Context(), doer, ownerID, repoName)
- require.ErrorIs(t, err, repo_model.ErrRedirectNotExist{OwnerID: ownerID, RepoName: repoName, MissingPermission: true})
- assert.Zero(t, redirectID)
- }
-
- t.Run("Public repository", func(t *testing.T) {
- ownerID := int64(2)
- reponame := "oldrepo1"
-
- testOk(t, nil, ownerID, reponame, 1)
- testOk(t, normalUser, ownerID, reponame, 1)
- testOk(t, ownerUser, ownerID, reponame, 1)
- })
-
- t.Run("Private repository", func(t *testing.T) {
- ownerID := int64(17)
- reponame := "oldrepo24"
-
- testFail(t, nil, ownerID, reponame)
- testFail(t, normalUser, ownerID, reponame)
- testOk(t, ownerUser, ownerID, reponame, 24)
- })
-}
diff --git a/services/redirect/user.go b/services/redirect/user.go
deleted file mode 100644
index 2b1d38bbc0..0000000000
--- a/services/redirect/user.go
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2025 The Forgejo Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-package redirect
-
-import (
- "context"
-
- user_model "forgejo.org/models/user"
-)
-
-// LookupUserRedirect returns the userID if there's a redirect registered for the
-// username. It additionally checks if the doer has permission to view the new
-// user.
-func LookupUserRedirect(ctx context.Context, doer *user_model.User, userName string) (int64, error) {
- redirect, err := user_model.GetUserRedirect(ctx, userName)
- if err != nil {
- return 0, err
- }
-
- redirectUser, err := user_model.GetUserByID(ctx, redirect.RedirectUserID)
- if err != nil {
- return 0, err
- }
-
- if !user_model.IsUserVisibleToViewer(ctx, redirectUser, doer) {
- return 0, user_model.ErrUserRedirectNotExist{Name: userName, MissingPermission: true}
- }
-
- return redirect.RedirectUserID, nil
-}
diff --git a/services/redirect/user_test.go b/services/redirect/user_test.go
deleted file mode 100644
index d1ddcc2ebf..0000000000
--- a/services/redirect/user_test.go
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2025 The Forgejo Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-package redirect
-
-import (
- "testing"
-
- "forgejo.org/models/unittest"
- user_model "forgejo.org/models/user"
-
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
-)
-
-func TestLookupUserRedirect(t *testing.T) {
- require.NoError(t, unittest.PrepareTestDatabase())
-
- adminUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
- normalUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
-
- testOk := func(t *testing.T, doer *user_model.User, username string, expectedRedirectID int64) {
- t.Helper()
-
- redirectID, err := LookupUserRedirect(t.Context(), doer, username)
- require.NoError(t, err)
- assert.Equal(t, expectedRedirectID, redirectID)
- }
-
- testFail := func(t *testing.T, doer *user_model.User, username string) {
- t.Helper()
-
- redirectID, err := LookupUserRedirect(t.Context(), doer, username)
- require.ErrorIs(t, err, user_model.ErrUserRedirectNotExist{Name: username, MissingPermission: true})
- assert.Zero(t, redirectID)
- }
-
- t.Run("Public visibility", func(t *testing.T) {
- username := "olduser1"
- redirectID := int64(1)
-
- testOk(t, nil, username, redirectID)
- testOk(t, normalUser, username, redirectID)
- testOk(t, adminUser, username, redirectID)
- })
-
- t.Run("Limited visibility", func(t *testing.T) {
- username := "oldorg22"
- redirectID := int64(22)
-
- testFail(t, nil, username)
- testOk(t, normalUser, username, redirectID)
- testOk(t, adminUser, username, redirectID)
- })
-
- t.Run("Private visibility", func(t *testing.T) {
- orgUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5})
- username := "oldorg23"
- redirectID := int64(23)
-
- testFail(t, nil, username)
- testFail(t, normalUser, username)
- testOk(t, orgUser, username, redirectID)
- testOk(t, adminUser, username, redirectID)
- })
-}
diff --git a/services/release/release.go b/services/release/release.go
index 90eb1320ed..b52e4b124e 100644
--- a/services/release/release.go
+++ b/services/release/release.go
@@ -9,22 +9,22 @@ import (
"fmt"
"strings"
- "forgejo.org/models"
- "forgejo.org/models/db"
- git_model "forgejo.org/models/git"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/container"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/graceful"
- "forgejo.org/modules/log"
- "forgejo.org/modules/repository"
- "forgejo.org/modules/storage"
- "forgejo.org/modules/timeutil"
- "forgejo.org/modules/util"
- "forgejo.org/services/attachment"
- notify_service "forgejo.org/services/notify"
+ "code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/models/db"
+ git_model "code.gitea.io/gitea/models/git"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/container"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/graceful"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/repository"
+ "code.gitea.io/gitea/modules/storage"
+ "code.gitea.io/gitea/modules/timeutil"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/services/attachment"
+ notify_service "code.gitea.io/gitea/services/notify"
)
type AttachmentChange struct {
@@ -161,17 +161,17 @@ func CreateRelease(gitRepo *git.Repository, rel *repo_model.Release, msg string,
for _, attachmentChange := range attachmentChanges {
if attachmentChange.Action != "add" {
- return errors.New("can only create new attachments when creating release")
+ return fmt.Errorf("can only create new attachments when creating release")
}
switch attachmentChange.Type {
case "attachment":
if attachmentChange.UUID == "" {
- return errors.New("new attachment should have a uuid")
+ return fmt.Errorf("new attachment should have a uuid")
}
addAttachmentUUIDs.Add(attachmentChange.UUID)
case "external":
if attachmentChange.Name == "" || attachmentChange.ExternalURL == "" {
- return errors.New("new external attachment should have a name and external url")
+ return fmt.Errorf("new external attachment should have a name and external url")
}
_, err = attachment.NewExternalAttachment(gitRepo.Ctx, &repo_model.Attachment{
@@ -186,7 +186,7 @@ func CreateRelease(gitRepo *git.Repository, rel *repo_model.Release, msg string,
}
default:
if attachmentChange.Type == "" {
- return errors.New("missing attachment type")
+ return fmt.Errorf("missing attachment type")
}
return fmt.Errorf("unknown attachment type: '%q'", attachmentChange.Type)
}
@@ -280,7 +280,7 @@ func UpdateRelease(ctx context.Context, doer *user_model.User, gitRepo *git.Repo
addAttachmentUUIDs.Add(attachmentChange.UUID)
case "external":
if attachmentChange.Name == "" || attachmentChange.ExternalURL == "" {
- return errors.New("new external attachment should have a name and external url")
+ return fmt.Errorf("new external attachment should have a name and external url")
}
_, err := attachment.NewExternalAttachment(ctx, &repo_model.Attachment{
Name: attachmentChange.Name,
@@ -294,13 +294,13 @@ func UpdateRelease(ctx context.Context, doer *user_model.User, gitRepo *git.Repo
}
default:
if attachmentChange.Type == "" {
- return errors.New("missing attachment type")
+ return fmt.Errorf("missing attachment type")
}
return fmt.Errorf("unknown attachment type: %q", attachmentChange.Type)
}
case "delete":
if attachmentChange.UUID == "" {
- return errors.New("attachment deletion should have a uuid")
+ return fmt.Errorf("attachment deletion should have a uuid")
}
delAttachmentUUIDs.Add(attachmentChange.UUID)
case "update":
@@ -308,7 +308,7 @@ func UpdateRelease(ctx context.Context, doer *user_model.User, gitRepo *git.Repo
updateAttachments.Add(attachmentChange)
default:
if attachmentChange.Action == "" {
- return errors.New("missing attachment action")
+ return fmt.Errorf("missing attachment action")
}
return fmt.Errorf("unknown attachment action: %q", attachmentChange.Action)
}
diff --git a/services/release/release_test.go b/services/release/release_test.go
index f03b4d42b8..5a22c473cf 100644
--- a/services/release/release_test.go
+++ b/services/release/release_test.go
@@ -6,18 +6,18 @@ package release
import (
"strings"
"testing"
+ "time"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unittest"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/test"
- "forgejo.org/services/attachment"
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unittest"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/services/attachment"
- _ "forgejo.org/models/actions"
- _ "forgejo.org/models/forgefed"
+ _ "code.gitea.io/gitea/models/actions"
+ _ "code.gitea.io/gitea/models/forgefed"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -138,9 +138,9 @@ func TestRelease_Create(t *testing.T) {
}))
assert.NoError(t, repo_model.GetReleaseAttachments(db.DefaultContext, &release))
assert.Len(t, release.Attachments, 1)
- assert.Equal(t, attach.UUID, release.Attachments[0].UUID)
- assert.Equal(t, attach.Name, release.Attachments[0].Name)
- assert.Equal(t, attach.ExternalURL, release.Attachments[0].ExternalURL)
+ assert.EqualValues(t, attach.UUID, release.Attachments[0].UUID)
+ assert.EqualValues(t, attach.Name, release.Attachments[0].Name)
+ assert.EqualValues(t, attach.ExternalURL, release.Attachments[0].ExternalURL)
release = repo_model.Release{
RepoID: repo.ID,
@@ -165,8 +165,8 @@ func TestRelease_Create(t *testing.T) {
}))
assert.NoError(t, repo_model.GetReleaseAttachments(db.DefaultContext, &release))
assert.Len(t, release.Attachments, 1)
- assert.Equal(t, "test", release.Attachments[0].Name)
- assert.Equal(t, "https://forgejo.org/", release.Attachments[0].ExternalURL)
+ assert.EqualValues(t, "test", release.Attachments[0].Name)
+ assert.EqualValues(t, "https://forgejo.org/", release.Attachments[0].ExternalURL)
release = repo_model.Release{
RepoID: repo.ID,
@@ -219,7 +219,7 @@ func TestRelease_Update(t *testing.T) {
release, err := repo_model.GetRelease(db.DefaultContext, repo.ID, "v1.1.1")
require.NoError(t, err)
releaseCreatedUnix := release.CreatedUnix
- test.SleepTillNextSecond()
+ time.Sleep(2 * time.Second) // sleep 2 seconds to ensure a different timestamp
release.Note = "Changed note"
require.NoError(t, UpdateRelease(db.DefaultContext, user, gitRepo, release, false, []*AttachmentChange{}))
release, err = repo_model.GetReleaseByID(db.DefaultContext, release.ID)
@@ -243,7 +243,7 @@ func TestRelease_Update(t *testing.T) {
release, err = repo_model.GetRelease(db.DefaultContext, repo.ID, "v1.2.1")
require.NoError(t, err)
releaseCreatedUnix = release.CreatedUnix
- test.SleepTillNextSecond()
+ time.Sleep(2 * time.Second) // sleep 2 seconds to ensure a different timestamp
release.Title = "Changed title"
require.NoError(t, UpdateRelease(db.DefaultContext, user, gitRepo, release, false, []*AttachmentChange{}))
release, err = repo_model.GetReleaseByID(db.DefaultContext, release.ID)
@@ -267,7 +267,7 @@ func TestRelease_Update(t *testing.T) {
release, err = repo_model.GetRelease(db.DefaultContext, repo.ID, "v1.3.1")
require.NoError(t, err)
releaseCreatedUnix = release.CreatedUnix
- test.SleepTillNextSecond()
+ time.Sleep(2 * time.Second) // sleep 2 seconds to ensure a different timestamp
release.Title = "Changed title"
release.Note = "Changed note"
require.NoError(t, UpdateRelease(db.DefaultContext, user, gitRepo, release, false, []*AttachmentChange{}))
@@ -318,10 +318,10 @@ func TestRelease_Update(t *testing.T) {
}))
require.NoError(t, repo_model.GetReleaseAttachments(db.DefaultContext, release))
assert.Len(t, release.Attachments, 1)
- assert.Equal(t, attach.UUID, release.Attachments[0].UUID)
- assert.Equal(t, release.ID, release.Attachments[0].ReleaseID)
- assert.Equal(t, attach.Name, release.Attachments[0].Name)
- assert.Equal(t, attach.ExternalURL, release.Attachments[0].ExternalURL)
+ assert.EqualValues(t, attach.UUID, release.Attachments[0].UUID)
+ assert.EqualValues(t, release.ID, release.Attachments[0].ReleaseID)
+ assert.EqualValues(t, attach.Name, release.Attachments[0].Name)
+ assert.EqualValues(t, attach.ExternalURL, release.Attachments[0].ExternalURL)
// update the attachment name
require.NoError(t, UpdateRelease(db.DefaultContext, user, gitRepo, release, false, []*AttachmentChange{
@@ -334,10 +334,10 @@ func TestRelease_Update(t *testing.T) {
release.Attachments = nil
require.NoError(t, repo_model.GetReleaseAttachments(db.DefaultContext, release))
assert.Len(t, release.Attachments, 1)
- assert.Equal(t, attach.UUID, release.Attachments[0].UUID)
- assert.Equal(t, release.ID, release.Attachments[0].ReleaseID)
- assert.Equal(t, "test2.txt", release.Attachments[0].Name)
- assert.Equal(t, attach.ExternalURL, release.Attachments[0].ExternalURL)
+ assert.EqualValues(t, attach.UUID, release.Attachments[0].UUID)
+ assert.EqualValues(t, release.ID, release.Attachments[0].ReleaseID)
+ assert.EqualValues(t, "test2.txt", release.Attachments[0].Name)
+ assert.EqualValues(t, attach.ExternalURL, release.Attachments[0].ExternalURL)
// delete the attachment
require.NoError(t, UpdateRelease(db.DefaultContext, user, gitRepo, release, false, []*AttachmentChange{
@@ -361,9 +361,9 @@ func TestRelease_Update(t *testing.T) {
}))
assert.NoError(t, repo_model.GetReleaseAttachments(db.DefaultContext, release))
assert.Len(t, release.Attachments, 1)
- assert.Equal(t, release.ID, release.Attachments[0].ReleaseID)
- assert.Equal(t, "test", release.Attachments[0].Name)
- assert.Equal(t, "https://forgejo.org/", release.Attachments[0].ExternalURL)
+ assert.EqualValues(t, release.ID, release.Attachments[0].ReleaseID)
+ assert.EqualValues(t, "test", release.Attachments[0].Name)
+ assert.EqualValues(t, "https://forgejo.org/", release.Attachments[0].ExternalURL)
externalAttachmentUUID := release.Attachments[0].UUID
// update the attachment name
@@ -378,10 +378,10 @@ func TestRelease_Update(t *testing.T) {
release.Attachments = nil
assert.NoError(t, repo_model.GetReleaseAttachments(db.DefaultContext, release))
assert.Len(t, release.Attachments, 1)
- assert.Equal(t, externalAttachmentUUID, release.Attachments[0].UUID)
- assert.Equal(t, release.ID, release.Attachments[0].ReleaseID)
- assert.Equal(t, "test2", release.Attachments[0].Name)
- assert.Equal(t, "https://about.gitea.com/", release.Attachments[0].ExternalURL)
+ assert.EqualValues(t, externalAttachmentUUID, release.Attachments[0].UUID)
+ assert.EqualValues(t, release.ID, release.Attachments[0].ReleaseID)
+ assert.EqualValues(t, "test2", release.Attachments[0].Name)
+ assert.EqualValues(t, "https://about.gitea.com/", release.Attachments[0].ExternalURL)
}
func TestRelease_createTag(t *testing.T) {
@@ -412,7 +412,7 @@ func TestRelease_createTag(t *testing.T) {
require.NoError(t, err)
assert.NotEmpty(t, release.CreatedUnix)
releaseCreatedUnix := release.CreatedUnix
- test.SleepTillNextSecond()
+ time.Sleep(2 * time.Second) // sleep 2 seconds to ensure a different timestamp
release.Note = "Changed note"
_, err = createTag(db.DefaultContext, gitRepo, release, "")
require.NoError(t, err)
@@ -435,7 +435,7 @@ func TestRelease_createTag(t *testing.T) {
_, err = createTag(db.DefaultContext, gitRepo, release, "")
require.NoError(t, err)
releaseCreatedUnix = release.CreatedUnix
- test.SleepTillNextSecond()
+ time.Sleep(2 * time.Second) // sleep 2 seconds to ensure a different timestamp
release.Title = "Changed title"
_, err = createTag(db.DefaultContext, gitRepo, release, "")
require.NoError(t, err)
@@ -458,7 +458,7 @@ func TestRelease_createTag(t *testing.T) {
_, err = createTag(db.DefaultContext, gitRepo, release, "")
require.NoError(t, err)
releaseCreatedUnix = release.CreatedUnix
- test.SleepTillNextSecond()
+ time.Sleep(2 * time.Second) // sleep 2 seconds to ensure a different timestamp
release.Title = "Changed title"
release.Note = "Changed note"
_, err = createTag(db.DefaultContext, gitRepo, release, "")
diff --git a/services/release/tag.go b/services/release/tag.go
index e1608d1897..dae2b70f76 100644
--- a/services/release/tag.go
+++ b/services/release/tag.go
@@ -8,12 +8,12 @@ import (
"errors"
"fmt"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/modules/graceful"
- "forgejo.org/modules/log"
- "forgejo.org/modules/queue"
- repo_module "forgejo.org/modules/repository"
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/modules/graceful"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/queue"
+ repo_module "code.gitea.io/gitea/modules/repository"
"xorm.io/builder"
)
diff --git a/services/remote/promote.go b/services/remote/promote.go
index f37d00168c..eb41ace462 100644
--- a/services/remote/promote.go
+++ b/services/remote/promote.go
@@ -6,12 +6,12 @@ package remote
import (
"context"
- auth_model "forgejo.org/models/auth"
- "forgejo.org/models/db"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/log"
- "forgejo.org/services/auth/source/oauth2"
- remote_source "forgejo.org/services/auth/source/remote"
+ auth_model "code.gitea.io/gitea/models/auth"
+ "code.gitea.io/gitea/models/db"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/services/auth/source/oauth2"
+ remote_source "code.gitea.io/gitea/services/auth/source/remote"
)
type Reason int
@@ -98,7 +98,7 @@ func getRemoteUserToPromote(ctx context.Context, source *auth_model.Source, logi
return nil, NewReason(log.ERROR, ReasonErrorLoginName, "getUserByLoginName('%s') %v", loginName, err), err
}
if len(users) == 0 {
- return nil, NewReason(log.DEBUG, ReasonLoginNameNotExists, "no user with LoginType UserTypeRemoteUser and LoginName '%s'", loginName), nil
+ return nil, NewReason(log.ERROR, ReasonLoginNameNotExists, "no user with LoginType UserTypeRemoteUser and LoginName '%s'", loginName), nil
}
reason := ReasonNoSource
diff --git a/services/repository/adopt.go b/services/repository/adopt.go
index 3651b018e6..3d6fe71a09 100644
--- a/services/repository/adopt.go
+++ b/services/repository/adopt.go
@@ -11,19 +11,19 @@ import (
"path/filepath"
"strings"
- "forgejo.org/models/db"
- git_model "forgejo.org/models/git"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/container"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/log"
- "forgejo.org/modules/optional"
- repo_module "forgejo.org/modules/repository"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/util"
- notify_service "forgejo.org/services/notify"
+ "code.gitea.io/gitea/models/db"
+ git_model "code.gitea.io/gitea/models/git"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/container"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/optional"
+ repo_module "code.gitea.io/gitea/modules/repository"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/util"
+ notify_service "code.gitea.io/gitea/services/notify"
"github.com/gobwas/glob"
)
diff --git a/services/repository/adopt_test.go b/services/repository/adopt_test.go
index a66b4c5ac0..71fb1fc885 100644
--- a/services/repository/adopt_test.go
+++ b/services/repository/adopt_test.go
@@ -8,11 +8,11 @@ import (
"path"
"testing"
- "forgejo.org/models/db"
- "forgejo.org/models/unittest"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/setting"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/unittest"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/setting"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
diff --git a/services/repository/archiver/archiver.go b/services/repository/archiver/archiver.go
index cffb07210f..279067c002 100644
--- a/services/repository/archiver/archiver.go
+++ b/services/repository/archiver/archiver.go
@@ -12,16 +12,16 @@ import (
"strings"
"time"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/graceful"
- "forgejo.org/modules/log"
- "forgejo.org/modules/process"
- "forgejo.org/modules/queue"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/storage"
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/graceful"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/process"
+ "code.gitea.io/gitea/modules/queue"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/storage"
)
// ArchiveRequest defines the parameters of an archive request, which notably
diff --git a/services/repository/archiver/archiver_test.go b/services/repository/archiver/archiver_test.go
index 00d82267c9..e7a2422e55 100644
--- a/services/repository/archiver/archiver_test.go
+++ b/services/repository/archiver/archiver_test.go
@@ -7,13 +7,13 @@ import (
"testing"
"time"
- "forgejo.org/models/db"
- "forgejo.org/models/unittest"
- "forgejo.org/modules/git"
- "forgejo.org/services/contexttest"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/unittest"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/services/contexttest"
- _ "forgejo.org/models/actions"
- _ "forgejo.org/models/forgefed"
+ _ "code.gitea.io/gitea/models/actions"
+ _ "code.gitea.io/gitea/models/forgefed"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -36,7 +36,7 @@ func TestArchive_Basic(t *testing.T) {
bogusReq, err := NewRequest(ctx, ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit, git.ZIP)
require.NoError(t, err)
assert.NotNil(t, bogusReq)
- assert.Equal(t, firstCommit+".zip", bogusReq.GetArchiveName())
+ assert.EqualValues(t, firstCommit+".zip", bogusReq.GetArchiveName())
// Check a series of bogus requests.
// Step 1, valid commit with a bad extension.
@@ -57,12 +57,12 @@ func TestArchive_Basic(t *testing.T) {
bogusReq, err = NewRequest(ctx, ctx.Repo.Repository.ID, ctx.Repo.GitRepo, "master", git.ZIP)
require.NoError(t, err)
assert.NotNil(t, bogusReq)
- assert.Equal(t, "master.zip", bogusReq.GetArchiveName())
+ assert.EqualValues(t, "master.zip", bogusReq.GetArchiveName())
bogusReq, err = NewRequest(ctx, ctx.Repo.Repository.ID, ctx.Repo.GitRepo, "test/archive", git.ZIP)
require.NoError(t, err)
assert.NotNil(t, bogusReq)
- assert.Equal(t, "test-archive.zip", bogusReq.GetArchiveName())
+ assert.EqualValues(t, "test-archive.zip", bogusReq.GetArchiveName())
// Now two valid requests, firstCommit with valid extensions.
zipReq, err := NewRequest(ctx, ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit, git.ZIP)
diff --git a/services/repository/avatar.go b/services/repository/avatar.go
index a1cd3228df..32940a7aa3 100644
--- a/services/repository/avatar.go
+++ b/services/repository/avatar.go
@@ -9,11 +9,11 @@ import (
"io"
"strconv"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/modules/avatar"
- "forgejo.org/modules/log"
- "forgejo.org/modules/storage"
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/modules/avatar"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/storage"
)
// UploadAvatar saves custom avatar for repository.
diff --git a/services/repository/avatar_test.go b/services/repository/avatar_test.go
index 6f28113286..b3c498dfc8 100644
--- a/services/repository/avatar_test.go
+++ b/services/repository/avatar_test.go
@@ -9,10 +9,10 @@ import (
"image/png"
"testing"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unittest"
- "forgejo.org/modules/avatar"
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unittest"
+ "code.gitea.io/gitea/modules/avatar"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -60,7 +60,7 @@ func TestDeleteAvatar(t *testing.T) {
err = DeleteAvatar(db.DefaultContext, repo)
require.NoError(t, err)
- assert.Empty(t, repo.Avatar)
+ assert.Equal(t, "", repo.Avatar)
}
func TestTemplateGenerateAvatar(t *testing.T) {
diff --git a/services/repository/branch.go b/services/repository/branch.go
index bc739825a5..8e1a6cd27f 100644
--- a/services/repository/branch.go
+++ b/services/repository/branch.go
@@ -9,29 +9,28 @@ import (
"fmt"
"strings"
- "forgejo.org/models"
- actions_model "forgejo.org/models/actions"
- "forgejo.org/models/db"
- git_model "forgejo.org/models/git"
- issues_model "forgejo.org/models/issues"
- "forgejo.org/models/perm/access"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unit"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/graceful"
- "forgejo.org/modules/log"
- "forgejo.org/modules/optional"
- "forgejo.org/modules/queue"
- repo_module "forgejo.org/modules/repository"
- "forgejo.org/modules/timeutil"
- "forgejo.org/modules/util"
- webhook_module "forgejo.org/modules/webhook"
- actions_service "forgejo.org/services/actions"
- notify_service "forgejo.org/services/notify"
- pull_service "forgejo.org/services/pull"
- files_service "forgejo.org/services/repository/files"
+ "code.gitea.io/gitea/models"
+ actions_model "code.gitea.io/gitea/models/actions"
+ "code.gitea.io/gitea/models/db"
+ git_model "code.gitea.io/gitea/models/git"
+ issues_model "code.gitea.io/gitea/models/issues"
+ "code.gitea.io/gitea/models/perm/access"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unit"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/graceful"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/optional"
+ "code.gitea.io/gitea/modules/queue"
+ repo_module "code.gitea.io/gitea/modules/repository"
+ "code.gitea.io/gitea/modules/timeutil"
+ "code.gitea.io/gitea/modules/util"
+ webhook_module "code.gitea.io/gitea/modules/webhook"
+ notify_service "code.gitea.io/gitea/services/notify"
+ pull_service "code.gitea.io/gitea/services/pull"
+ files_service "code.gitea.io/gitea/services/repository/files"
"xorm.io/builder"
)
@@ -251,7 +250,7 @@ func SyncBranchesToDB(ctx context.Context, repoID, pusherID int64, branchNames,
// For other batches, it will hit optimization 4.
if len(branchNames) != len(commitIDs) {
- return errors.New("branchNames and commitIDs length not match")
+ return fmt.Errorf("branchNames and commitIDs length not match")
}
return db.WithTx(ctx, func(ctx context.Context) error {
@@ -378,7 +377,7 @@ func RenameBranch(ctx context.Context, repo *repo_model.Repository, doer *user_m
log.Error("DeleteCronTaskByRepo: %v", err)
}
// cancel running cron jobs of this repository and delete old schedules
- if err := actions_service.CancelPreviousJobs(
+ if err := actions_model.CancelPreviousJobs(
ctx,
repo.ID,
from,
@@ -579,7 +578,7 @@ func SetRepoDefaultBranch(ctx context.Context, repo *repo_model.Repository, gitR
log.Error("DeleteCronTaskByRepo: %v", err)
}
// cancel running cron jobs of this repository and delete old schedules
- if err := actions_service.CancelPreviousJobs(
+ if err := actions_model.CancelPreviousJobs(
ctx,
repo.ID,
oldDefaultBranchName,
diff --git a/services/repository/cache.go b/services/repository/cache.go
index cd5b95afa3..b0811a99fc 100644
--- a/services/repository/cache.go
+++ b/services/repository/cache.go
@@ -6,9 +6,9 @@ package repository
import (
"context"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/modules/cache"
- "forgejo.org/modules/git"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/modules/cache"
+ "code.gitea.io/gitea/modules/git"
)
// CacheRef cachhe last commit information of the branch or the tag
diff --git a/services/repository/check.go b/services/repository/check.go
index 7e680f3c58..5cdcc14679 100644
--- a/services/repository/check.go
+++ b/services/repository/check.go
@@ -9,14 +9,14 @@ import (
"strings"
"time"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
- system_model "forgejo.org/models/system"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/log"
- repo_module "forgejo.org/modules/repository"
- "forgejo.org/modules/util"
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
+ system_model "code.gitea.io/gitea/models/system"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/log"
+ repo_module "code.gitea.io/gitea/modules/repository"
+ "code.gitea.io/gitea/modules/util"
"xorm.io/builder"
)
diff --git a/services/repository/collaboration.go b/services/repository/collaboration.go
index 7a0d7edb7f..dccc124748 100644
--- a/services/repository/collaboration.go
+++ b/services/repository/collaboration.go
@@ -7,10 +7,10 @@ package repository
import (
"context"
- "forgejo.org/models"
- "forgejo.org/models/db"
- access_model "forgejo.org/models/perm/access"
- repo_model "forgejo.org/models/repo"
+ "code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/models/db"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ repo_model "code.gitea.io/gitea/models/repo"
)
// DeleteCollaboration removes collaboration relation between the user and repository.
diff --git a/services/repository/collaboration_test.go b/services/repository/collaboration_test.go
index b27b91be23..c087018be4 100644
--- a/services/repository/collaboration_test.go
+++ b/services/repository/collaboration_test.go
@@ -6,9 +6,9 @@ package repository
import (
"testing"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unittest"
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unittest"
"github.com/stretchr/testify/require"
)
diff --git a/services/repository/commit.go b/services/repository/commit.go
index 0ff4ea701e..e8c0262ef4 100644
--- a/services/repository/commit.go
+++ b/services/repository/commit.go
@@ -7,8 +7,8 @@ import (
"context"
"fmt"
- "forgejo.org/modules/util"
- gitea_ctx "forgejo.org/services/context"
+ "code.gitea.io/gitea/modules/util"
+ gitea_ctx "code.gitea.io/gitea/services/context"
)
type ContainedLinks struct { // TODO: better name?
diff --git a/services/repository/commitstatus/commitstatus.go b/services/repository/commitstatus/commitstatus.go
index 03a62d0410..635b0b108e 100644
--- a/services/repository/commitstatus/commitstatus.go
+++ b/services/repository/commitstatus/commitstatus.go
@@ -9,17 +9,17 @@ import (
"fmt"
"slices"
- "forgejo.org/models/db"
- git_model "forgejo.org/models/git"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/cache"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/json"
- "forgejo.org/modules/log"
- api "forgejo.org/modules/structs"
- shared_automerge "forgejo.org/services/shared/automerge"
+ "code.gitea.io/gitea/models/db"
+ git_model "code.gitea.io/gitea/models/git"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/cache"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/log"
+ api "code.gitea.io/gitea/modules/structs"
+ shared_automerge "code.gitea.io/gitea/services/shared/automerge"
)
func getCacheKey(repoID int64, brancheName string) string {
diff --git a/services/repository/contributors_graph.go b/services/repository/contributors_graph.go
index 1805bd5960..48871813bd 100644
--- a/services/repository/contributors_graph.go
+++ b/services/repository/contributors_graph.go
@@ -14,16 +14,16 @@ import (
"sync"
"time"
- "forgejo.org/models/avatars"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/graceful"
- "forgejo.org/modules/json"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- api "forgejo.org/modules/structs"
+ "code.gitea.io/gitea/models/avatars"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/graceful"
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ api "code.gitea.io/gitea/modules/structs"
"code.forgejo.org/go-chi/cache"
)
@@ -111,7 +111,7 @@ func GetContributorStats(ctx context.Context, cache cache.Cache, repo *repo_mode
var cachedStats map[string]*ContributorData
return cachedStats, json.Unmarshal([]byte(v), &cachedStats)
default:
- return nil, errors.New("unexpected type in cache detected")
+ return nil, fmt.Errorf("unexpected type in cache detected")
}
}
diff --git a/services/repository/contributors_graph_test.go b/services/repository/contributors_graph_test.go
index 45af85272d..c62bef25a1 100644
--- a/services/repository/contributors_graph_test.go
+++ b/services/repository/contributors_graph_test.go
@@ -8,12 +8,12 @@ import (
"testing"
"time"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unittest"
- "forgejo.org/modules/json"
- "forgejo.org/modules/log"
- "forgejo.org/modules/test"
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unittest"
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/test"
"code.forgejo.org/go-chi/cache"
"github.com/stretchr/testify/assert"
@@ -53,14 +53,14 @@ func TestRepository_ContributorsGraph(t *testing.T) {
keys = append(keys, k)
}
slices.Sort(keys)
- assert.Equal(t, []string{
+ assert.EqualValues(t, []string{
"ethantkoenig@gmail.com",
"jimmy.praet@telenet.be",
"jon@allspice.io",
"total", // generated summary
}, keys)
- assert.Equal(t, &ContributorData{
+ assert.EqualValues(t, &ContributorData{
Name: "Ethan Koenig",
AvatarLink: "/assets/img/avatar_default.png",
TotalCommits: 1,
@@ -73,7 +73,7 @@ func TestRepository_ContributorsGraph(t *testing.T) {
},
},
}, data["ethantkoenig@gmail.com"])
- assert.Equal(t, &ContributorData{
+ assert.EqualValues(t, &ContributorData{
Name: "Total",
AvatarLink: "",
TotalCommits: 3,
diff --git a/services/repository/create.go b/services/repository/create.go
index 4491b12497..8a1118cc2b 100644
--- a/services/repository/create.go
+++ b/services/repository/create.go
@@ -12,18 +12,18 @@ import (
"strings"
"time"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/log"
- "forgejo.org/modules/options"
- repo_module "forgejo.org/modules/repository"
- "forgejo.org/modules/setting"
- api "forgejo.org/modules/structs"
- "forgejo.org/modules/templates/vars"
- "forgejo.org/modules/util"
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/options"
+ repo_module "code.gitea.io/gitea/modules/repository"
+ "code.gitea.io/gitea/modules/setting"
+ api "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/templates/vars"
+ "code.gitea.io/gitea/modules/util"
)
// CreateRepoOptions contains the create repository options
diff --git a/services/repository/create_test.go b/services/repository/create_test.go
index 0a6c34b6fe..9cde285181 100644
--- a/services/repository/create_test.go
+++ b/services/repository/create_test.go
@@ -7,13 +7,13 @@ import (
"fmt"
"testing"
- "forgejo.org/models"
- "forgejo.org/models/db"
- "forgejo.org/models/organization"
- "forgejo.org/models/perm"
- "forgejo.org/models/unittest"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/structs"
+ "code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/organization"
+ "code.gitea.io/gitea/models/perm"
+ "code.gitea.io/gitea/models/unittest"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/structs"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -147,13 +147,3 @@ func TestIncludesAllRepositoriesTeams(t *testing.T) {
}
require.NoError(t, organization.DeleteOrganization(db.DefaultContext, org), "DeleteOrganization")
}
-
-func TestCreateRepository(t *testing.T) {
- require.NoError(t, unittest.PrepareTestDatabase())
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
-
- r, err := CreateRepositoryDirectly(db.DefaultContext, user, user, CreateRepoOptions{Name: "repo-last"})
- require.NoError(t, err)
- require.NotNil(t, r.Topics)
- require.Empty(t, r.Topics)
-}
diff --git a/services/repository/delete.go b/services/repository/delete.go
index f4124fb9e2..09213e5c65 100644
--- a/services/repository/delete.go
+++ b/services/repository/delete.go
@@ -1,5 +1,4 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
-// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package repository
@@ -8,29 +7,29 @@ import (
"context"
"fmt"
- "forgejo.org/models"
- actions_model "forgejo.org/models/actions"
- activities_model "forgejo.org/models/activities"
- admin_model "forgejo.org/models/admin"
- asymkey_model "forgejo.org/models/asymkey"
- "forgejo.org/models/db"
- git_model "forgejo.org/models/git"
- issues_model "forgejo.org/models/issues"
- "forgejo.org/models/organization"
- packages_model "forgejo.org/models/packages"
- access_model "forgejo.org/models/perm/access"
- project_model "forgejo.org/models/project"
- repo_model "forgejo.org/models/repo"
- secret_model "forgejo.org/models/secret"
- system_model "forgejo.org/models/system"
- user_model "forgejo.org/models/user"
- "forgejo.org/models/webhook"
- actions_module "forgejo.org/modules/actions"
- "forgejo.org/modules/lfs"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/storage"
- federation_service "forgejo.org/services/federation"
+ "code.gitea.io/gitea/models"
+ actions_model "code.gitea.io/gitea/models/actions"
+ activities_model "code.gitea.io/gitea/models/activities"
+ admin_model "code.gitea.io/gitea/models/admin"
+ asymkey_model "code.gitea.io/gitea/models/asymkey"
+ "code.gitea.io/gitea/models/db"
+ git_model "code.gitea.io/gitea/models/git"
+ issues_model "code.gitea.io/gitea/models/issues"
+ "code.gitea.io/gitea/models/organization"
+ packages_model "code.gitea.io/gitea/models/packages"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ project_model "code.gitea.io/gitea/models/project"
+ repo_model "code.gitea.io/gitea/models/repo"
+ secret_model "code.gitea.io/gitea/models/secret"
+ system_model "code.gitea.io/gitea/models/system"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/models/webhook"
+ actions_module "code.gitea.io/gitea/modules/actions"
+ "code.gitea.io/gitea/modules/lfs"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/storage"
+ federation_service "code.gitea.io/gitea/services/federation"
"xorm.io/builder"
)
@@ -90,11 +89,6 @@ func DeleteRepositoryDirectly(ctx context.Context, doer *user_model.User, repoID
}
}
- // If the repository was reported as abusive, a shadow copy should be created before deletion.
- if err := repo_model.IfNeededCreateShadowCopyForRepository(ctx, repo, false); err != nil {
- return err
- }
-
if cnt, err := sess.ID(repoID).Delete(&repo_model.Repository{}); err != nil {
return err
} else if cnt != 1 {
diff --git a/services/repository/files/cherry_pick.go b/services/repository/files/cherry_pick.go
index 0e88a29230..451a182155 100644
--- a/services/repository/files/cherry_pick.go
+++ b/services/repository/files/cherry_pick.go
@@ -5,17 +5,16 @@ package files
import (
"context"
- "errors"
"fmt"
"strings"
- "forgejo.org/models"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/log"
- "forgejo.org/modules/structs"
- "forgejo.org/services/pull"
+ "code.gitea.io/gitea/models"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/services/pull"
)
// CherryPick cherrypicks or reverts a commit to the given repository
@@ -80,33 +79,21 @@ func CherryPick(ctx context.Context, repo *repo_model.Repository, doer *user_mod
right, base = base, right
}
- var treeHash string
- if git.SupportGitMergeTree {
- var conflict bool
- treeHash, conflict, _, err = pull.MergeTree(ctx, t.gitRepo, base, opts.LastCommitID, right, nil)
- if err != nil {
- return nil, fmt.Errorf("failed to three-way merge %s onto %s: %w", right, opts.OldBranch, err)
- }
+ description := fmt.Sprintf("CherryPick %s onto %s", right, opts.OldBranch)
+ conflict, _, err := pull.AttemptThreeWayMerge(ctx,
+ t.basePath, t.gitRepo, base, opts.LastCommitID, right, description)
+ if err != nil {
+ return nil, fmt.Errorf("failed to three-way merge %s onto %s: %w", right, opts.OldBranch, err)
+ }
- if conflict {
- return nil, errors.New("failed to merge due to conflicts")
- }
- } else {
- description := fmt.Sprintf("CherryPick %s onto %s", right, opts.OldBranch)
- conflict, _, err := pull.AttemptThreeWayMerge(ctx, t.gitRepo, base, opts.LastCommitID, right, description)
- if err != nil {
- return nil, fmt.Errorf("failed to three-way merge %s onto %s: %w", right, opts.OldBranch, err)
- }
+ if conflict {
+ return nil, fmt.Errorf("failed to merge due to conflicts")
+ }
- if conflict {
- return nil, errors.New("failed to merge due to conflicts")
- }
-
- treeHash, err = t.WriteTree()
- if err != nil {
- // likely non-sensical tree due to merge conflicts...
- return nil, err
- }
+ treeHash, err := t.WriteTree()
+ if err != nil {
+ // likely non-sensical tree due to merge conflicts...
+ return nil, err
}
// Now commit the tree
diff --git a/services/repository/files/commit.go b/services/repository/files/commit.go
index 43c9048aaf..e0dad29273 100644
--- a/services/repository/files/commit.go
+++ b/services/repository/files/commit.go
@@ -1,5 +1,4 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
-// Copyright 2025 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package files
@@ -7,15 +6,15 @@ package files
import (
"context"
- asymkey_model "forgejo.org/models/asymkey"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/modules/git"
- "forgejo.org/modules/structs"
+ asymkey_model "code.gitea.io/gitea/models/asymkey"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/structs"
)
// CountDivergingCommits determines how many commits a branch is ahead or behind the repository's base branch
func CountDivergingCommits(ctx context.Context, repo *repo_model.Repository, branch string) (*git.DivergeObject, error) {
- divergence, err := git.GetDivergingCommits(ctx, repo.RepoPath(), repo.DefaultBranch, branch, nil)
+ divergence, err := git.GetDivergingCommits(ctx, repo.RepoPath(), repo.DefaultBranch, branch)
if err != nil {
return nil, err
}
@@ -39,7 +38,7 @@ func GetPayloadCommitVerification(ctx context.Context, commit *git.Commit) *stru
verification.Verified = commitVerification.Verified
verification.Reason = commitVerification.Reason
if verification.Reason == "" && !verification.Verified {
- verification.Reason = asymkey_model.NotSigned
+ verification.Reason = "gpg.error.not_signed_commit"
}
return verification
}
diff --git a/services/repository/files/content.go b/services/repository/files/content.go
index d701508ff0..32517e8d91 100644
--- a/services/repository/files/content.go
+++ b/services/repository/files/content.go
@@ -5,19 +5,18 @@ package files
import (
"context"
- "errors"
"fmt"
"net/url"
"path"
"strings"
- "forgejo.org/models"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/setting"
- api "forgejo.org/modules/structs"
- "forgejo.org/modules/util"
+ "code.gitea.io/gitea/models"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/setting"
+ api "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/util"
)
// ContentType repo content type
@@ -108,7 +107,7 @@ func GetObjectTypeFromTreeEntry(entry *git.TreeEntry) ContentType {
switch {
case entry.IsDir():
return ContentTypeDir
- case entry.IsSubmodule():
+ case entry.IsSubModule():
return ContentTypeSubmodule
case entry.IsExecutable(), entry.IsRegular():
return ContentTypeRegular
@@ -179,13 +178,12 @@ func GetContents(ctx context.Context, repo *repo_model.Repository, treePath, ref
// All content types have these fields in populated
contentsResponse := &api.ContentsResponse{
- Name: entry.Name(),
- Path: treePath,
- SHA: entry.ID.String(),
- LastCommitSHA: lastCommit.ID.String(),
- LastCommitWhen: lastCommit.Committer.When,
- Size: entry.Size(),
- URL: &selfURLString,
+ Name: entry.Name(),
+ Path: treePath,
+ SHA: entry.ID.String(),
+ LastCommitSHA: lastCommit.ID.String(),
+ Size: entry.Size(),
+ URL: &selfURLString,
Links: &api.FileLinksResponse{
Self: &selfURLString,
},
@@ -206,19 +204,19 @@ func GetContents(ctx context.Context, repo *repo_model.Repository, treePath, ref
} else if entry.IsLink() {
contentsResponse.Type = string(ContentTypeLink)
// The target of a symlink file is the content of the file
- targetFromContent, err := entry.LinkTarget()
+ targetFromContent, err := entry.Blob().GetBlobContent(1024)
if err != nil {
return nil, err
}
contentsResponse.Target = &targetFromContent
- } else if entry.IsSubmodule() {
+ } else if entry.IsSubModule() {
contentsResponse.Type = string(ContentTypeSubmodule)
- submodule, err := commit.GetSubmodule(treePath, entry)
+ submoduleURL, err := commit.GetSubModule(treePath)
if err != nil {
return nil, err
}
- if submodule.URL != "" {
- contentsResponse.SubmoduleGitURL = &submodule.URL
+ if submoduleURL != "" {
+ contentsResponse.SubmoduleGitURL = &submoduleURL
}
}
// Handle links
@@ -230,7 +228,7 @@ func GetContents(ctx context.Context, repo *repo_model.Repository, treePath, ref
downloadURLString := downloadURL.String()
contentsResponse.DownloadURL = &downloadURLString
}
- if !entry.IsSubmodule() {
+ if !entry.IsSubModule() {
htmlURL, err := url.Parse(repo.HTMLURL() + "/src/" + url.PathEscape(string(refType)) + "/" + util.PathEscapeSegments(ref) + "/" + util.PathEscapeSegments(treePath))
if err != nil {
return nil, err
@@ -251,35 +249,20 @@ func GetContents(ctx context.Context, repo *repo_model.Repository, treePath, ref
return contentsResponse, nil
}
-// GetBlobsBySHA gets multiple GitBlobs of a repository by sha hash.
-func GetBlobsBySHA(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, shas []string) ([]*api.GitBlob, error) {
- if len(shas) > setting.API.MaxResponseItems {
- shas = shas[:setting.API.MaxResponseItems]
- }
-
- blobs := make([]*api.GitBlob, 0, len(shas))
- for _, sha := range shas {
- blob, err := GetBlobBySHA(ctx, repo, gitRepo, sha)
- if err != nil {
- return nil, err
- }
- blobs = append(blobs, blob)
- }
- return blobs, nil
-}
-
-// GetBlobBySHA get the GitBlob of a repository using a sha hash.
-func GetBlobBySHA(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, sha string) (*api.GitBlob, error) {
+// GetBlobBySHA get the GitBlobResponse of a repository using a sha hash.
+func GetBlobBySHA(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, sha string) (*api.GitBlobResponse, error) {
gitBlob, err := gitRepo.GetBlob(sha)
if err != nil {
return nil, err
}
- content, err := gitBlob.GetContentBase64(setting.API.DefaultMaxBlobSize)
- if err != nil && !errors.As(err, &git.BlobTooLargeError{}) {
- return nil, err
+ content := ""
+ if gitBlob.Size() <= setting.API.DefaultMaxBlobSize {
+ content, err = gitBlob.GetBlobContentBase64()
+ if err != nil {
+ return nil, err
+ }
}
-
- return &api.GitBlob{
+ return &api.GitBlobResponse{
SHA: gitBlob.ID.String(),
URL: repo.APIURL() + "/git/blobs/" + url.PathEscape(gitBlob.ID.String()),
Size: gitBlob.Size(),
diff --git a/services/repository/files/content_test.go b/services/repository/files/content_test.go
index 8fc8f56b4f..f5e2b84690 100644
--- a/services/repository/files/content_test.go
+++ b/services/repository/files/content_test.go
@@ -5,16 +5,15 @@ package files
import (
"testing"
- "time"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unittest"
- "forgejo.org/modules/gitrepo"
- api "forgejo.org/modules/structs"
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unittest"
+ "code.gitea.io/gitea/modules/gitrepo"
+ api "code.gitea.io/gitea/modules/structs"
- _ "forgejo.org/models/actions"
- _ "forgejo.org/models/forgefed"
+ _ "code.gitea.io/gitea/models/actions"
+ _ "code.gitea.io/gitea/models/forgefed"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -34,19 +33,18 @@ func getExpectedReadmeContentsResponse() *api.ContentsResponse {
gitURL := "https://try.gitea.io/api/v1/repos/user2/repo1/git/blobs/" + sha
downloadURL := "https://try.gitea.io/user2/repo1/raw/branch/master/" + treePath
return &api.ContentsResponse{
- Name: treePath,
- Path: treePath,
- SHA: "4b4851ad51df6a7d9f25c979345979eaeb5b349f",
- LastCommitSHA: "65f1bf27bc3bf70f64657658635e66094edbcb4d",
- LastCommitWhen: time.Date(2017, time.March, 19, 16, 47, 59, 0, time.FixedZone("", -14400)),
- Type: "file",
- Size: 30,
- Encoding: &encoding,
- Content: &content,
- URL: &selfURL,
- HTMLURL: &htmlURL,
- GitURL: &gitURL,
- DownloadURL: &downloadURL,
+ Name: treePath,
+ Path: treePath,
+ SHA: "4b4851ad51df6a7d9f25c979345979eaeb5b349f",
+ LastCommitSHA: "65f1bf27bc3bf70f64657658635e66094edbcb4d",
+ Type: "file",
+ Size: 30,
+ Encoding: &encoding,
+ Content: &content,
+ URL: &selfURL,
+ HTMLURL: &htmlURL,
+ GitURL: &gitURL,
+ DownloadURL: &downloadURL,
Links: &api.FileLinksResponse{
Self: &selfURL,
GitURL: &gitURL,
@@ -66,13 +64,13 @@ func TestGetContents(t *testing.T) {
t.Run("Get README.md contents with GetContents(ctx, )", func(t *testing.T) {
fileContentResponse, err := GetContents(db.DefaultContext, repo, treePath, ref, false)
- assert.Equal(t, expectedContentsResponse, fileContentResponse)
+ assert.EqualValues(t, expectedContentsResponse, fileContentResponse)
require.NoError(t, err)
})
t.Run("Get README.md contents with ref as empty string (should then use the repo's default branch) with GetContents(ctx, )", func(t *testing.T) {
fileContentResponse, err := GetContents(db.DefaultContext, repo, treePath, "", false)
- assert.Equal(t, expectedContentsResponse, fileContentResponse)
+ assert.EqualValues(t, expectedContentsResponse, fileContentResponse)
require.NoError(t, err)
})
}
@@ -192,7 +190,7 @@ func TestGetBlobBySHA(t *testing.T) {
defer gitRepo.Close()
gbr, err := GetBlobBySHA(db.DefaultContext, repo, gitRepo, "65f1bf27bc3bf70f64657658635e66094edbcb4d")
- expectedGBR := &api.GitBlob{
+ expectedGBR := &api.GitBlobResponse{
Content: "dHJlZSAyYTJmMWQ0NjcwNzI4YTJlMTAwNDllMzQ1YmQ3YTI3NjQ2OGJlYWI2CmF1dGhvciB1c2VyMSA8YWRkcmVzczFAZXhhbXBsZS5jb20+IDE0ODk5NTY0NzkgLTA0MDAKY29tbWl0dGVyIEV0aGFuIEtvZW5pZyA8ZXRoYW50a29lbmlnQGdtYWlsLmNvbT4gMTQ4OTk1NjQ3OSAtMDQwMAoKSW5pdGlhbCBjb21taXQK",
Encoding: "base64",
URL: "https://try.gitea.io/api/v1/repos/user2/repo1/git/blobs/65f1bf27bc3bf70f64657658635e66094edbcb4d",
@@ -202,43 +200,3 @@ func TestGetBlobBySHA(t *testing.T) {
require.NoError(t, err)
assert.Equal(t, expectedGBR, gbr)
}
-
-func TestGetBlobsBySHA(t *testing.T) {
- unittest.PrepareTestEnv(t)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
-
- gitRepo, err := gitrepo.OpenRepository(db.DefaultContext, repo)
- require.NoError(t, err)
- defer gitRepo.Close()
-
- gbr, err := GetBlobsBySHA(db.DefaultContext, repo, gitRepo, []string{
- "ea82fc8777a24b07c26b3a4bf4e2742c03733eab", // Home.md
- "6395b68e1feebb1e4c657b4f9f6ba2676a283c0b", // line.svg
- "26f842bcad37fa40a1bb34cbb5ee219ee35d863d", // test.xml
- })
- expectedGBR := []*api.GitBlob{
- {
- Content: "IyBIb21lIHBhZ2UKClRoaXMgaXMgdGhlIGhvbWUgcGFnZSEK",
- Encoding: "base64",
- URL: "https://try.gitea.io/api/v1/repos/user2/repo2/git/blobs/ea82fc8777a24b07c26b3a4bf4e2742c03733eab",
- SHA: "ea82fc8777a24b07c26b3a4bf4e2742c03733eab",
- Size: 36,
- },
- {
- Content: "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZwogICB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHdpZHRoPSIxMjgiCiAgIGhlaWdodD0iMTI4IgogICB2aWV3Qm94PSIwIDAgMTI4IDEyOCI+CgogIDxsaW5lIHgxPSIwIiB5MT0iNyIgeDI9IjEwIiB5Mj0iNyIgc3Ryb2tlLXdpZHRoPSIxLjUiLz4KPC9zdmc+",
- Encoding: "base64",
- URL: "https://try.gitea.io/api/v1/repos/user2/repo2/git/blobs/6395b68e1feebb1e4c657b4f9f6ba2676a283c0b",
- SHA: "6395b68e1feebb1e4c657b4f9f6ba2676a283c0b",
- Size: 246,
- },
- {
- Content: "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHRlc3Q+VGhpcyBpcyBYTUw8L3Rlc3Q+Cg==",
- Encoding: "base64",
- URL: "https://try.gitea.io/api/v1/repos/user2/repo2/git/blobs/26f842bcad37fa40a1bb34cbb5ee219ee35d863d",
- SHA: "26f842bcad37fa40a1bb34cbb5ee219ee35d863d",
- Size: 64,
- },
- }
- require.NoError(t, err)
- assert.Equal(t, expectedGBR, gbr)
-}
diff --git a/services/repository/files/diff.go b/services/repository/files/diff.go
index 354a343d12..bf8b938e21 100644
--- a/services/repository/files/diff.go
+++ b/services/repository/files/diff.go
@@ -7,8 +7,8 @@ import (
"context"
"strings"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/services/gitdiff"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/services/gitdiff"
)
// GetDiffPreview produces and returns diff result of a file which is not yet committed.
diff --git a/services/repository/files/diff_test.go b/services/repository/files/diff_test.go
index 67c63803d3..95de10e07e 100644
--- a/services/repository/files/diff_test.go
+++ b/services/repository/files/diff_test.go
@@ -6,12 +6,12 @@ package files
import (
"testing"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unittest"
- "forgejo.org/modules/json"
- "forgejo.org/services/contexttest"
- "forgejo.org/services/gitdiff"
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unittest"
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/services/contexttest"
+ "code.gitea.io/gitea/services/gitdiff"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -124,7 +124,7 @@ func TestGetDiffPreview(t *testing.T) {
require.NoError(t, err)
bs, err := json.Marshal(diff)
require.NoError(t, err)
- assert.Equal(t, string(expectedBs), string(bs))
+ assert.EqualValues(t, string(expectedBs), string(bs))
})
t.Run("empty branch, same results", func(t *testing.T) {
@@ -134,7 +134,7 @@ func TestGetDiffPreview(t *testing.T) {
require.NoError(t, err)
bs, err := json.Marshal(diff)
require.NoError(t, err)
- assert.Equal(t, expectedBs, bs)
+ assert.EqualValues(t, expectedBs, bs)
})
}
diff --git a/services/repository/files/file.go b/services/repository/files/file.go
index 5b93258840..7884d880e0 100644
--- a/services/repository/files/file.go
+++ b/services/repository/files/file.go
@@ -5,16 +5,16 @@ package files
import (
"context"
- "errors"
+ "fmt"
"net/url"
"strings"
"time"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- api "forgejo.org/modules/structs"
- "forgejo.org/modules/util"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ api "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/util"
)
func GetFilesResponseFromCommit(ctx context.Context, repo *repo_model.Repository, commit *git.Commit, branch string, treeNames []string) (*api.FilesResponse, error) {
@@ -50,10 +50,10 @@ func GetFileResponseFromFilesResponse(filesResponse *api.FilesResponse, index in
// GetFileCommitResponse Constructs a FileCommitResponse from a Commit object
func GetFileCommitResponse(repo *repo_model.Repository, commit *git.Commit) (*api.FileCommitResponse, error) {
if repo == nil {
- return nil, errors.New("repo cannot be nil")
+ return nil, fmt.Errorf("repo cannot be nil")
}
if commit == nil {
- return nil, errors.New("commit cannot be nil")
+ return nil, fmt.Errorf("commit cannot be nil")
}
commitURL, _ := url.Parse(repo.APIURL() + "/git/commits/" + url.PathEscape(commit.ID.String()))
commitTreeURL, _ := url.Parse(repo.APIURL() + "/git/trees/" + url.PathEscape(commit.Tree.ID.String()))
@@ -104,35 +104,36 @@ func GetAuthorAndCommitterUsers(author, committer *IdentityOptions, doer *user_m
// then we use bogus User objects for them to store their FullName and Email.
// If only one of the two are provided, we set both of them to it.
// If neither are provided, both are the doer.
- getUser := func(identity *IdentityOptions) *user_model.User {
- if identity == nil || identity.Email == "" {
- return nil
- }
-
- if doer != nil && strings.EqualFold(doer.Email, identity.Email) {
- user := doer // the committer is the doer, so will use their user object
- if identity.Name != "" {
- user.FullName = identity.Name
+ if committer != nil && committer.Email != "" {
+ if doer != nil && strings.EqualFold(doer.Email, committer.Email) {
+ committerUser = doer // the committer is the doer, so will use their user object
+ if committer.Name != "" {
+ committerUser.FullName = committer.Name
}
// Use the provided email and not revert to placeholder mail.
- user.KeepEmailPrivate = false
- return user
- }
-
- var id int64
- if doer != nil {
- id = doer.ID
- }
- return &user_model.User{
- ID: id, // Needed to ensure the doer is checked to pass rules for instance signing of CRUD actions.
- FullName: identity.Name,
- Email: identity.Email,
+ committerUser.KeepEmailPrivate = false
+ } else {
+ committerUser = &user_model.User{
+ FullName: committer.Name,
+ Email: committer.Email,
+ }
+ }
+ }
+ if author != nil && author.Email != "" {
+ if doer != nil && strings.EqualFold(doer.Email, author.Email) {
+ authorUser = doer // the author is the doer, so will use their user object
+ if authorUser.Name != "" {
+ authorUser.FullName = author.Name
+ }
+ // Use the provided email and not revert to placeholder mail.
+ authorUser.KeepEmailPrivate = false
+ } else {
+ authorUser = &user_model.User{
+ FullName: author.Name,
+ Email: author.Email,
+ }
}
}
-
- committerUser = getUser(committer)
- authorUser = getUser(author)
-
if authorUser == nil {
if committerUser != nil {
authorUser = committerUser // No valid author was given so use the committer
diff --git a/services/repository/files/file_test.go b/services/repository/files/file_test.go
index 169cafba0d..db2f4403f4 100644
--- a/services/repository/files/file_test.go
+++ b/services/repository/files/file_test.go
@@ -14,13 +14,13 @@ func TestCleanUploadFileName(t *testing.T) {
name := "this/is/test"
cleanName := CleanUploadFileName(name)
expectedCleanName := name
- assert.Equal(t, expectedCleanName, cleanName)
+ assert.EqualValues(t, expectedCleanName, cleanName)
})
t.Run("Clean a .git path", func(t *testing.T) {
name := "this/is/test/.git"
cleanName := CleanUploadFileName(name)
expectedCleanName := ""
- assert.Equal(t, expectedCleanName, cleanName)
+ assert.EqualValues(t, expectedCleanName, cleanName)
})
}
diff --git a/services/repository/files/patch.go b/services/repository/files/patch.go
index 18b5226c02..e5f7e2af96 100644
--- a/services/repository/files/patch.go
+++ b/services/repository/files/patch.go
@@ -8,15 +8,15 @@ import (
"fmt"
"strings"
- "forgejo.org/models"
- git_model "forgejo.org/models/git"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/log"
- "forgejo.org/modules/structs"
- asymkey_service "forgejo.org/services/asymkey"
+ "code.gitea.io/gitea/models"
+ git_model "code.gitea.io/gitea/models/git"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/structs"
+ asymkey_service "code.gitea.io/gitea/services/asymkey"
)
// ApplyDiffPatchOptions holds the repository diff patch update options
@@ -147,7 +147,11 @@ func ApplyDiffPatch(ctx context.Context, repo *repo_model.Repository, doer *user
stdout := &strings.Builder{}
stderr := &strings.Builder{}
- cmdApply := git.NewCommand(ctx, "apply", "--index", "--recount", "--cached", "--ignore-whitespace", "--whitespace=fix", "--binary", "-3")
+ cmdApply := git.NewCommand(ctx, "apply", "--index", "--recount", "--cached", "--ignore-whitespace", "--whitespace=fix", "--binary")
+ if git.CheckGitVersionAtLeast("2.32") == nil {
+ cmdApply.AddArguments("-3")
+ }
+
if err := cmdApply.Run(&git.RunOpts{
Dir: t.basePath,
Stdout: stdout,
diff --git a/services/repository/files/temp_repo.go b/services/repository/files/temp_repo.go
index 64d3e5887d..30d95ba9ab 100644
--- a/services/repository/files/temp_repo.go
+++ b/services/repository/files/temp_repo.go
@@ -6,7 +6,6 @@ package files
import (
"bytes"
"context"
- "errors"
"fmt"
"io"
"os"
@@ -14,15 +13,15 @@ import (
"strings"
"time"
- "forgejo.org/models"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/log"
- repo_module "forgejo.org/modules/repository"
- "forgejo.org/modules/setting"
- asymkey_service "forgejo.org/services/asymkey"
- "forgejo.org/services/gitdiff"
+ "code.gitea.io/gitea/models"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/log"
+ repo_module "code.gitea.io/gitea/modules/repository"
+ "code.gitea.io/gitea/modules/setting"
+ asymkey_service "code.gitea.io/gitea/services/asymkey"
+ "code.gitea.io/gitea/services/gitdiff"
)
// TemporaryUploadRepository is a type to wrap our upload repositories as a shallow clone
@@ -369,7 +368,7 @@ func (t *TemporaryUploadRepository) DiffIndex() (*gitdiff.Diff, error) {
// GetBranchCommit Gets the commit object of the given branch
func (t *TemporaryUploadRepository) GetBranchCommit(branch string) (*git.Commit, error) {
if t.gitRepo == nil {
- return nil, errors.New("repository has not been cloned")
+ return nil, fmt.Errorf("repository has not been cloned")
}
return t.gitRepo.GetBranchCommit(branch)
}
@@ -377,7 +376,7 @@ func (t *TemporaryUploadRepository) GetBranchCommit(branch string) (*git.Commit,
// GetCommit Gets the commit object of the given commit ID
func (t *TemporaryUploadRepository) GetCommit(commitID string) (*git.Commit, error) {
if t.gitRepo == nil {
- return nil, errors.New("repository has not been cloned")
+ return nil, fmt.Errorf("repository has not been cloned")
}
return t.gitRepo.GetCommit(commitID)
}
diff --git a/services/repository/files/temp_repo_test.go b/services/repository/files/temp_repo_test.go
index 852e762267..e7d85ea3cc 100644
--- a/services/repository/files/temp_repo_test.go
+++ b/services/repository/files/temp_repo_test.go
@@ -6,10 +6,10 @@ package files
import (
"testing"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unittest"
- "forgejo.org/modules/git"
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unittest"
+ "code.gitea.io/gitea/modules/git"
"github.com/stretchr/testify/require"
)
diff --git a/services/repository/files/tree.go b/services/repository/files/tree.go
index 5a369b27a5..e3a7f3b8b0 100644
--- a/services/repository/files/tree.go
+++ b/services/repository/files/tree.go
@@ -8,11 +8,11 @@ import (
"fmt"
"net/url"
- "forgejo.org/models"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/modules/git"
- "forgejo.org/modules/setting"
- api "forgejo.org/modules/structs"
+ "code.gitea.io/gitea/models"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/setting"
+ api "code.gitea.io/gitea/modules/structs"
)
// GetTreeBySHA get the GitTreeResponse of a repository using a sha hash.
@@ -87,7 +87,7 @@ func GetTreeBySHA(ctx context.Context, repo *repo_model.Repository, gitRepo *git
if entries[e].IsDir() {
copy(treeURL[copyPos:], entries[e].ID.String())
tree.Entries[i].URL = string(treeURL)
- } else if entries[e].IsSubmodule() {
+ } else if entries[e].IsSubModule() {
// In Github Rest API Version=2022-11-28, if a tree entry is a submodule,
// its url will be returned as an empty string.
// So the URL will be set to "" here.
diff --git a/services/repository/files/tree_test.go b/services/repository/files/tree_test.go
index 5cd628722b..9e5c5c1701 100644
--- a/services/repository/files/tree_test.go
+++ b/services/repository/files/tree_test.go
@@ -6,9 +6,9 @@ package files
import (
"testing"
- "forgejo.org/models/unittest"
- api "forgejo.org/modules/structs"
- "forgejo.org/services/contexttest"
+ "code.gitea.io/gitea/models/unittest"
+ api "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/services/contexttest"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -48,5 +48,5 @@ func TestGetTreeBySHA(t *testing.T) {
TotalCount: 1,
}
- assert.Equal(t, expectedTree, tree)
+ assert.EqualValues(t, expectedTree, tree)
}
diff --git a/services/repository/files/update.go b/services/repository/files/update.go
index 8fb9644fa4..d6025b6ced 100644
--- a/services/repository/files/update.go
+++ b/services/repository/files/update.go
@@ -11,17 +11,17 @@ import (
"strings"
"time"
- "forgejo.org/models"
- git_model "forgejo.org/models/git"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/lfs"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/structs"
- asymkey_service "forgejo.org/services/asymkey"
+ "code.gitea.io/gitea/models"
+ git_model "code.gitea.io/gitea/models/git"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/lfs"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/structs"
+ asymkey_service "code.gitea.io/gitea/services/asymkey"
)
// IdentityOptions for a person's identity like an author or committer
@@ -193,34 +193,28 @@ func ChangeRepoFiles(ctx context.Context, repo *repo_model.Repository, doer *use
}
if hasOldBranch {
- // Get the current commit of the original branch
- actualBaseCommit, err := t.GetBranchCommit(opts.OldBranch)
+ // Get the commit of the original branch
+ commit, err := t.GetBranchCommit(opts.OldBranch)
if err != nil {
return nil, err // Couldn't get a commit for the branch
}
- var lastKnownCommit git.ObjectID // when nil, the sha provided in the opts.Files must match the current blob-sha
- if opts.OldBranch != opts.NewBranch {
- // when creating a new branch, ignore if a file has been changed in the meantime
- // (such changes will visible when doing the merge)
- lastKnownCommit = actualBaseCommit.ID
- } else if opts.LastCommitID != "" {
- lastKnownCommit, err = t.gitRepo.ConvertToGitID(opts.LastCommitID)
+ // Assigned LastCommitID in opts if it hasn't been set
+ if opts.LastCommitID == "" {
+ opts.LastCommitID = commit.ID.String()
+ } else {
+ lastCommitID, err := t.gitRepo.ConvertToGitID(opts.LastCommitID)
if err != nil {
return nil, fmt.Errorf("ConvertToSHA1: Invalid last commit ID: %w", err)
}
+ opts.LastCommitID = lastCommitID.String()
}
for _, file := range opts.Files {
- if err := handleCheckErrors(file, actualBaseCommit, lastKnownCommit); err != nil {
+ if err := handleCheckErrors(file, commit, opts); err != nil {
return nil, err
}
}
-
- if opts.LastCommitID == "" {
- // needed for t.CommitTree
- opts.LastCommitID = actualBaseCommit.ID.String()
- }
}
contentStore := lfs.NewContentStore()
@@ -283,9 +277,9 @@ func ChangeRepoFiles(ctx context.Context, repo *repo_model.Repository, doer *use
}
// handles the check for various issues for ChangeRepoFiles
-func handleCheckErrors(file *ChangeRepoFile, actualBaseCommit *git.Commit, lastKnownCommit git.ObjectID) error {
+func handleCheckErrors(file *ChangeRepoFile, commit *git.Commit, opts *ChangeRepoFilesOptions) error {
if file.Operation == "update" || file.Operation == "delete" {
- fromEntry, err := actualBaseCommit.GetTreeEntryByPath(file.Options.fromTreePath)
+ fromEntry, err := commit.GetTreeEntryByPath(file.Options.fromTreePath)
if err != nil {
return err
}
@@ -298,22 +292,22 @@ func handleCheckErrors(file *ChangeRepoFile, actualBaseCommit *git.Commit, lastK
CurrentSHA: fromEntry.ID.String(),
}
}
- } else if lastKnownCommit != nil {
- if actualBaseCommit.ID.String() != lastKnownCommit.String() {
- // If a lastKnownCommit was given and it doesn't match the actualBaseCommit,
- // check if the file has been changed in between
- if changed, err := actualBaseCommit.FileChangedSinceCommit(file.Options.treePath, lastKnownCommit.String()); err != nil {
+ } else if opts.LastCommitID != "" {
+ // If a lastCommitID was given and it doesn't match the commitID of the head of the branch throw
+ // an error, but only if we aren't creating a new branch.
+ if commit.ID.String() != opts.LastCommitID && opts.OldBranch == opts.NewBranch {
+ if changed, err := commit.FileChangedSinceCommit(file.Options.treePath, opts.LastCommitID); err != nil {
return err
} else if changed {
return models.ErrCommitIDDoesNotMatch{
- GivenCommitID: lastKnownCommit.String(),
- CurrentCommitID: actualBaseCommit.ID.String(),
+ GivenCommitID: opts.LastCommitID,
+ CurrentCommitID: opts.LastCommitID,
}
}
- // The file wasn't modified, so we are good to update it
+ // The file wasn't modified, so we are good to delete it
}
} else {
- // When updating a file, a lastKnownCommit or SHA needs to be given to make sure other commits
+ // When updating a file, a lastCommitID or SHA needs to be given to make sure other commits
// haven't been made. We throw an error if one wasn't provided.
return models.ErrSHAOrCommitIDNotProvided{}
}
@@ -328,7 +322,7 @@ func handleCheckErrors(file *ChangeRepoFile, actualBaseCommit *git.Commit, lastK
subTreePath := ""
for index, part := range treePathParts {
subTreePath = path.Join(subTreePath, part)
- entry, err := actualBaseCommit.GetTreeEntryByPath(subTreePath)
+ entry, err := commit.GetTreeEntryByPath(subTreePath)
if err != nil {
if git.IsErrNotExist(err) {
// Means there is no item with that name, so we're good
diff --git a/services/repository/files/upload.go b/services/repository/files/upload.go
index 6359087e88..1330116889 100644
--- a/services/repository/files/upload.go
+++ b/services/repository/files/upload.go
@@ -10,12 +10,12 @@ import (
"path"
"strings"
- git_model "forgejo.org/models/git"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/lfs"
- "forgejo.org/modules/setting"
+ git_model "code.gitea.io/gitea/models/git"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/lfs"
+ "code.gitea.io/gitea/modules/setting"
)
// UploadRepoFileOptions contains the uploaded repository file options
diff --git a/services/repository/fork.go b/services/repository/fork.go
index 9d15b6207d..0378f7bae6 100644
--- a/services/repository/fork.go
+++ b/services/repository/fork.go
@@ -9,17 +9,17 @@ import (
"strings"
"time"
- "forgejo.org/models/db"
- git_model "forgejo.org/models/git"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/log"
- repo_module "forgejo.org/modules/repository"
- "forgejo.org/modules/structs"
- "forgejo.org/modules/util"
- notify_service "forgejo.org/services/notify"
+ "code.gitea.io/gitea/models/db"
+ git_model "code.gitea.io/gitea/models/git"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/log"
+ repo_module "code.gitea.io/gitea/modules/repository"
+ "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/util"
+ notify_service "code.gitea.io/gitea/services/notify"
)
// ErrForkAlreadyExist represents a "ForkAlreadyExist" kind of error.
diff --git a/services/repository/fork_test.go b/services/repository/fork_test.go
index 6de241e4d4..2e1e72aaad 100644
--- a/services/repository/fork_test.go
+++ b/services/repository/fork_test.go
@@ -6,12 +6,11 @@ package repository
import (
"testing"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unittest"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/test"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unittest"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/setting"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -37,7 +36,7 @@ func TestForkRepository(t *testing.T) {
assert.False(t, repo_model.IsErrReachLimitOfRepo(err))
// change AllowForkWithoutMaximumLimit to false for the test
- defer test.MockVariableValue(&setting.Repository.AllowForkWithoutMaximumLimit, false)()
+ setting.Repository.AllowForkWithoutMaximumLimit = false
// user has reached maximum limit of repositories
user.MaxRepoCreation = 0
fork2, err := ForkRepositoryAndUpdates(git.DefaultContext, user, user, ForkRepoOptions{
diff --git a/services/repository/generate.go b/services/repository/generate.go
index e23e294de1..4a312a33c3 100644
--- a/services/repository/generate.go
+++ b/services/repository/generate.go
@@ -16,14 +16,14 @@ import (
"strings"
"time"
- git_model "forgejo.org/models/git"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/log"
- repo_module "forgejo.org/modules/repository"
- "forgejo.org/modules/util"
+ git_model "code.gitea.io/gitea/models/git"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/log"
+ repo_module "code.gitea.io/gitea/modules/repository"
+ "code.gitea.io/gitea/modules/util"
"github.com/gobwas/glob"
"github.com/huandu/xstrings"
@@ -43,8 +43,12 @@ type expansion struct {
var defaultTransformers = []transformer{
{Name: "SNAKE", Transform: xstrings.ToSnakeCase},
{Name: "KEBAB", Transform: xstrings.ToKebabCase},
- {Name: "CAMEL", Transform: xstrings.ToCamelCase},
- {Name: "PASCAL", Transform: xstrings.ToPascalCase},
+ // as of xstrings v1.5.0 the CAMEL & PASCAL workarounds are no longer necessary
+ // and can be removed https://codeberg.org/forgejo/forgejo/pulls/4050
+ {Name: "CAMEL", Transform: func(str string) string {
+ return xstrings.FirstRuneToLower(xstrings.ToCamelCase(str))
+ }},
+ {Name: "PASCAL", Transform: xstrings.ToCamelCase},
{Name: "LOWER", Transform: strings.ToLower},
{Name: "UPPER", Transform: strings.ToUpper},
{Name: "TITLE", Transform: util.ToTitleCase},
diff --git a/services/repository/generate_test.go b/services/repository/generate_test.go
index 2eb3a55e96..b0f97d0ffb 100644
--- a/services/repository/generate_test.go
+++ b/services/repository/generate_test.go
@@ -65,30 +65,3 @@ func TestFileNameSanitize(t *testing.T) {
assert.Equal(t, "_", fileNameSanitize("\u0000"))
assert.Equal(t, "ç›®æ ‡", fileNameSanitize("ç›®æ ‡"))
}
-
-func TestTransformers(t *testing.T) {
- input := "Foo_Forgejo-BAR"
-
- tests := []struct {
- name string
- expected string
- }{
- {"SNAKE", "foo_forgejo_bar"},
- {"KEBAB", "foo-forgejo-bar"},
- {"CAMEL", "fooForgejoBar"},
- {"PASCAL", "FooForgejoBar"},
- {"LOWER", "foo_forgejo-bar"},
- {"UPPER", "FOO_FORGEJO-BAR"},
- {"TITLE", "Foo_forgejo-Bar"},
- }
-
- for i, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- tranform := defaultTransformers[i]
- assert.Equal(t, tt.name, tranform.Name)
-
- got := tranform.Transform(input)
- assert.Equal(t, tt.expected, got)
- })
- }
-}
diff --git a/services/repository/gitgraph/graph.go b/services/repository/gitgraph/graph.go
index bf15baed2a..4db5598015 100644
--- a/services/repository/gitgraph/graph.go
+++ b/services/repository/gitgraph/graph.go
@@ -10,8 +10,8 @@ import (
"os"
"strings"
- "forgejo.org/modules/git"
- "forgejo.org/modules/setting"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/setting"
)
// GetCommitGraph return a list of commit (GraphItems) from all branches
diff --git a/services/repository/gitgraph/graph_models.go b/services/repository/gitgraph/graph_models.go
index 20107cc646..4e94468205 100644
--- a/services/repository/gitgraph/graph_models.go
+++ b/services/repository/gitgraph/graph_models.go
@@ -10,13 +10,13 @@ import (
"strings"
"time"
- asymkey_model "forgejo.org/models/asymkey"
- "forgejo.org/models/db"
- git_model "forgejo.org/models/git"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/log"
+ asymkey_model "code.gitea.io/gitea/models/asymkey"
+ "code.gitea.io/gitea/models/db"
+ git_model "code.gitea.io/gitea/models/git"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/log"
)
// NewGraph creates a basic graph
diff --git a/services/repository/gitgraph/graph_test.go b/services/repository/gitgraph/graph_test.go
index 374341b276..e7e437e42d 100644
--- a/services/repository/gitgraph/graph_test.go
+++ b/services/repository/gitgraph/graph_test.go
@@ -9,7 +9,7 @@ import (
"strings"
"testing"
- "forgejo.org/modules/git"
+ "code.gitea.io/gitea/modules/git"
)
func BenchmarkGetCommitGraph(b *testing.B) {
diff --git a/services/repository/hooks.go b/services/repository/hooks.go
index d3021414cf..97e9e290a3 100644
--- a/services/repository/hooks.go
+++ b/services/repository/hooks.go
@@ -7,12 +7,12 @@ import (
"context"
"fmt"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/webhook"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/log"
- repo_module "forgejo.org/modules/repository"
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/log"
+ repo_module "code.gitea.io/gitea/modules/repository"
"xorm.io/builder"
)
diff --git a/services/repository/init.go b/services/repository/init.go
index 525b322752..817fa4abd7 100644
--- a/services/repository/init.go
+++ b/services/repository/init.go
@@ -9,13 +9,13 @@ import (
"os"
"time"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/log"
- repo_module "forgejo.org/modules/repository"
- "forgejo.org/modules/setting"
- asymkey_service "forgejo.org/services/asymkey"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/log"
+ repo_module "code.gitea.io/gitea/modules/repository"
+ "code.gitea.io/gitea/modules/setting"
+ asymkey_service "code.gitea.io/gitea/services/asymkey"
)
// initRepoCommit temporarily changes with work directory.
diff --git a/services/repository/lfs.go b/services/repository/lfs.go
index 2e090290a7..4cd1110e55 100644
--- a/services/repository/lfs.go
+++ b/services/repository/lfs.go
@@ -8,14 +8,14 @@ import (
"fmt"
"time"
- git_model "forgejo.org/models/git"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/lfs"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/timeutil"
+ git_model "code.gitea.io/gitea/models/git"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/lfs"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/timeutil"
)
// GarbageCollectLFSMetaObjectsOptions provides options for GarbageCollectLFSMetaObjects function
@@ -76,7 +76,7 @@ func GarbageCollectLFSMetaObjectsForRepo(ctx context.Context, repo *repo_model.R
err = git_model.IterateLFSMetaObjectsForRepo(ctx, repo.ID, func(ctx context.Context, metaObject *git_model.LFSMetaObject) error {
total++
- pointerSha := git.ComputeBlobHash(objectFormat, []byte(metaObject.StringContent()))
+ pointerSha := git.ComputeBlobHash(objectFormat, []byte(metaObject.Pointer.StringContent()))
if gitRepo.IsObjectExist(pointerSha.String()) {
return git_model.MarkLFSMetaObject(ctx, metaObject.ID)
diff --git a/services/repository/lfs_test.go b/services/repository/lfs_test.go
index e38c38e29c..838386d845 100644
--- a/services/repository/lfs_test.go
+++ b/services/repository/lfs_test.go
@@ -8,14 +8,14 @@ import (
"testing"
"time"
- "forgejo.org/models/db"
- git_model "forgejo.org/models/git"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unittest"
- "forgejo.org/modules/lfs"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/storage"
- repo_service "forgejo.org/services/repository"
+ "code.gitea.io/gitea/models/db"
+ git_model "code.gitea.io/gitea/models/git"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unittest"
+ "code.gitea.io/gitea/modules/lfs"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/storage"
+ repo_service "code.gitea.io/gitea/services/repository"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
diff --git a/services/repository/main_test.go b/services/repository/main_test.go
index 942a805638..7ad1540aee 100644
--- a/services/repository/main_test.go
+++ b/services/repository/main_test.go
@@ -6,7 +6,7 @@ package repository
import (
"testing"
- "forgejo.org/models/unittest"
+ "code.gitea.io/gitea/models/unittest"
)
func TestMain(m *testing.M) {
diff --git a/services/repository/migrate.go b/services/repository/migrate.go
index 80f5d68231..c8f65dd63d 100644
--- a/services/repository/migrate.go
+++ b/services/repository/migrate.go
@@ -10,18 +10,18 @@ import (
"net/http"
"time"
- "forgejo.org/models/db"
- "forgejo.org/models/organization"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/lfs"
- "forgejo.org/modules/log"
- "forgejo.org/modules/migration"
- repo_module "forgejo.org/modules/repository"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/timeutil"
- "forgejo.org/modules/util"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/organization"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/lfs"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/migration"
+ repo_module "code.gitea.io/gitea/modules/repository"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/timeutil"
+ "code.gitea.io/gitea/modules/util"
)
// MigrateRepositoryGitData starts migrating git related data after created migrating repository
diff --git a/services/repository/push.go b/services/repository/push.go
index eaedd80e1f..924f365c05 100644
--- a/services/repository/push.go
+++ b/services/repository/push.go
@@ -10,23 +10,23 @@ import (
"strings"
"time"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/cache"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/graceful"
- "forgejo.org/modules/log"
- "forgejo.org/modules/process"
- "forgejo.org/modules/queue"
- repo_module "forgejo.org/modules/repository"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/timeutil"
- "forgejo.org/modules/util"
- issue_service "forgejo.org/services/issue"
- notify_service "forgejo.org/services/notify"
- pull_service "forgejo.org/services/pull"
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/cache"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/graceful"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/process"
+ "code.gitea.io/gitea/modules/queue"
+ repo_module "code.gitea.io/gitea/modules/repository"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/timeutil"
+ "code.gitea.io/gitea/modules/util"
+ issue_service "code.gitea.io/gitea/services/issue"
+ notify_service "code.gitea.io/gitea/services/notify"
+ pull_service "code.gitea.io/gitea/services/pull"
)
// pushQueue represents a queue to handle update pull request tests
@@ -66,7 +66,7 @@ func PushUpdates(opts []*repo_module.PushUpdateOptions) error {
for _, opt := range opts {
if opt.IsNewRef() && opt.IsDelRef() {
- return errors.New("Old and new revisions are both NULL")
+ return fmt.Errorf("Old and new revisions are both NULL")
}
}
diff --git a/services/repository/repository.go b/services/repository/repository.go
index 0d5ce647e0..35bcdfd528 100644
--- a/services/repository/repository.go
+++ b/services/repository/repository.go
@@ -6,24 +6,23 @@ package repository
import (
"context"
- "errors"
"fmt"
- "forgejo.org/models/db"
- "forgejo.org/models/git"
- issues_model "forgejo.org/models/issues"
- "forgejo.org/models/organization"
- repo_model "forgejo.org/models/repo"
- system_model "forgejo.org/models/system"
- "forgejo.org/models/unit"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/graceful"
- "forgejo.org/modules/log"
- repo_module "forgejo.org/modules/repository"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/structs"
- notify_service "forgejo.org/services/notify"
- pull_service "forgejo.org/services/pull"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/git"
+ issues_model "code.gitea.io/gitea/models/issues"
+ "code.gitea.io/gitea/models/organization"
+ repo_model "code.gitea.io/gitea/models/repo"
+ system_model "code.gitea.io/gitea/models/system"
+ "code.gitea.io/gitea/models/unit"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/graceful"
+ "code.gitea.io/gitea/modules/log"
+ repo_module "code.gitea.io/gitea/modules/repository"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/structs"
+ notify_service "code.gitea.io/gitea/services/notify"
+ pull_service "code.gitea.io/gitea/services/pull"
)
// WebSearchRepository represents a repository returned by web search
@@ -73,10 +72,10 @@ func PushCreateRepo(ctx context.Context, authUser, owner *user_model.User, repoN
if ok, err := organization.CanCreateOrgRepo(ctx, owner.ID, authUser.ID); err != nil {
return nil, err
} else if !ok {
- return nil, errors.New("cannot push-create repository for org")
+ return nil, fmt.Errorf("cannot push-create repository for org")
}
} else if authUser.ID != owner.ID {
- return nil, errors.New("cannot push-create repository for another user")
+ return nil, fmt.Errorf("cannot push-create repository for another user")
}
}
@@ -119,17 +118,6 @@ func UpdateRepository(ctx context.Context, repo *repo_model.Repository, visibili
return committer.Commit()
}
-// ConvertMirrorToNormalRepo converts a mirror to a normal repo
-func ConvertMirrorToNormalRepo(ctx context.Context, repo *repo_model.Repository) (err error) {
- repo.IsMirror = false
-
- if _, err := CleanUpMigrateInfo(ctx, repo); err != nil {
- return err
- }
-
- return repo_model.DeleteMirrorByRepoID(ctx, repo.ID)
-}
-
// LinkedRepository returns the linked repo if any
func LinkedRepository(ctx context.Context, a *repo_model.Attachment) (*repo_model.Repository, unit.Type, error) {
if a.IssueID != 0 {
diff --git a/services/repository/repository_test.go b/services/repository/repository_test.go
index 9f71bdec23..a5c0b3efcd 100644
--- a/services/repository/repository_test.go
+++ b/services/repository/repository_test.go
@@ -6,10 +6,10 @@ package repository
import (
"testing"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unit"
- "forgejo.org/models/unittest"
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unit"
+ "code.gitea.io/gitea/models/unittest"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -41,16 +41,3 @@ func TestLinkedRepository(t *testing.T) {
})
}
}
-
-func TestConvertMirrorToNormalRepo(t *testing.T) {
- require.NoError(t, unittest.PrepareTestDatabase())
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
- repo.IsMirror = true
- err := repo_model.UpdateRepositoryCols(db.DefaultContext, repo, "is_mirror")
-
- require.NoError(t, err)
-
- err = ConvertMirrorToNormalRepo(db.DefaultContext, repo)
- require.NoError(t, err)
- assert.False(t, repo.IsMirror)
-}
diff --git a/services/repository/review.go b/services/repository/review.go
index c4000a2846..40513e6bc6 100644
--- a/services/repository/review.go
+++ b/services/repository/review.go
@@ -6,9 +6,9 @@ package repository
import (
"context"
- "forgejo.org/models/organization"
- "forgejo.org/models/perm"
- repo_model "forgejo.org/models/repo"
+ "code.gitea.io/gitea/models/organization"
+ "code.gitea.io/gitea/models/perm"
+ repo_model "code.gitea.io/gitea/models/repo"
)
// GetReviewerTeams get all teams can be requested to review
diff --git a/services/repository/review_test.go b/services/repository/review_test.go
index 5ece99a2e3..eb1712c2ce 100644
--- a/services/repository/review_test.go
+++ b/services/repository/review_test.go
@@ -6,9 +6,9 @@ package repository
import (
"testing"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unittest"
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unittest"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
diff --git a/services/repository/setting.go b/services/repository/setting.go
index 68cdfc370b..33b00cca8c 100644
--- a/services/repository/setting.go
+++ b/services/repository/setting.go
@@ -7,11 +7,12 @@ import (
"context"
"slices"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unit"
- "forgejo.org/modules/log"
- actions_service "forgejo.org/services/actions"
+ actions_model "code.gitea.io/gitea/models/actions"
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unit"
+ "code.gitea.io/gitea/modules/log"
+ actions_service "code.gitea.io/gitea/services/actions"
)
// UpdateRepositoryUnits updates a repository's units
@@ -28,7 +29,7 @@ func UpdateRepositoryUnits(ctx context.Context, repo *repo_model.Repository, uni
}
if slices.Contains(deleteUnitTypes, unit.TypeActions) {
- if err := actions_service.CleanRepoScheduleTasks(ctx, repo, true); err != nil {
+ if err := actions_model.CleanRepoScheduleTasks(ctx, repo, true); err != nil {
log.Error("CleanRepoScheduleTasks: %v", err)
}
}
diff --git a/services/repository/star.go b/services/repository/star.go
index 8cc2e0a243..505da0f099 100644
--- a/services/repository/star.go
+++ b/services/repository/star.go
@@ -6,10 +6,10 @@ package repository
import (
"context"
- "forgejo.org/models/repo"
- "forgejo.org/models/user"
- "forgejo.org/modules/setting"
- "forgejo.org/services/federation"
+ "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/services/federation"
)
func StarRepoAndSendLikeActivities(ctx context.Context, doer user.User, repoID int64, star bool) error {
diff --git a/services/repository/sync_fork.go b/services/repository/sync_fork.go
deleted file mode 100644
index ebcac76136..0000000000
--- a/services/repository/sync_fork.go
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright 2025 The Forgejo Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package repository
-
-import (
- "context"
- "fmt"
- "slices"
-
- git_model "forgejo.org/models/git"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- repo_module "forgejo.org/modules/repository"
- api "forgejo.org/modules/structs"
-)
-
-// SyncFork syncs a branch of a fork with the base repo
-func SyncFork(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, branch string) error {
- err := repo.MustNotBeArchived()
- if err != nil {
- return err
- }
-
- err = repo.GetBaseRepo(ctx)
- if err != nil {
- return err
- }
-
- err = git.Push(ctx, repo.BaseRepo.RepoPath(), git.PushOptions{
- Remote: repo.RepoPath(),
- Branch: fmt.Sprintf("%s:%s", branch, branch),
- Env: repo_module.PushingEnvironment(doer, repo),
- })
-
- return err
-}
-
-// CanSyncFork returns information about syncing a fork
-func GetSyncForkInfo(ctx context.Context, repo *repo_model.Repository, branch string) (*api.SyncForkInfo, error) {
- info := new(api.SyncForkInfo)
-
- if !repo.IsFork {
- return info, nil
- }
-
- if repo.IsArchived {
- return info, nil
- }
-
- err := repo.GetBaseRepo(ctx)
- if err != nil {
- return nil, err
- }
-
- forkBranch, err := git_model.GetBranch(ctx, repo.ID, branch)
- if err != nil {
- return nil, err
- }
-
- info.ForkCommit = forkBranch.CommitID
-
- baseBranch, err := git_model.GetBranch(ctx, repo.BaseRepo.ID, branch)
- if err != nil {
- if git_model.IsErrBranchNotExist(err) {
- // If the base repo don't have the branch, we don't need to continue
- return info, nil
- }
- return nil, err
- }
-
- info.BaseCommit = baseBranch.CommitID
-
- // If both branches has the same latest commit, we don't need to sync
- if forkBranch.CommitID == baseBranch.CommitID {
- return info, nil
- }
-
- // Check if the latest commit of the fork is also in the base
- gitRepo, err := git.OpenRepository(ctx, repo.BaseRepo.RepoPath())
- if err != nil {
- return nil, err
- }
- defer gitRepo.Close()
-
- commit, err := gitRepo.GetCommit(forkBranch.CommitID)
- if err != nil {
- if git.IsErrNotExist(err) {
- return info, nil
- }
- return nil, err
- }
-
- branchList, err := commit.GetAllBranches()
- if err != nil {
- return nil, err
- }
-
- if !slices.Contains(branchList, branch) {
- return info, nil
- }
-
- diff, err := git.GetDivergingCommits(ctx, repo.BaseRepo.RepoPath(), baseBranch.CommitID, forkBranch.CommitID, nil)
- if err != nil {
- return nil, err
- }
-
- info.Allowed = true
- info.CommitsBehind = diff.Behind
-
- return info, nil
-}
diff --git a/services/repository/template.go b/services/repository/template.go
index 3566aa2b7e..36a680c8e2 100644
--- a/services/repository/template.go
+++ b/services/repository/template.go
@@ -6,12 +6,12 @@ package repository
import (
"context"
- "forgejo.org/models/db"
- git_model "forgejo.org/models/git"
- issues_model "forgejo.org/models/issues"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- notify_service "forgejo.org/services/notify"
+ "code.gitea.io/gitea/models/db"
+ git_model "code.gitea.io/gitea/models/git"
+ issues_model "code.gitea.io/gitea/models/issues"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ notify_service "code.gitea.io/gitea/services/notify"
)
// GenerateIssueLabels generates issue labels from a template repository
diff --git a/services/repository/transfer.go b/services/repository/transfer.go
index 6026d85ae1..467c85ef6f 100644
--- a/services/repository/transfer.go
+++ b/services/repository/transfer.go
@@ -9,19 +9,19 @@ import (
"os"
"strings"
- "forgejo.org/models"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- "forgejo.org/models/organization"
- "forgejo.org/models/perm"
- access_model "forgejo.org/models/perm/access"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/log"
- repo_module "forgejo.org/modules/repository"
- "forgejo.org/modules/sync"
- "forgejo.org/modules/util"
- notify_service "forgejo.org/services/notify"
+ "code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ "code.gitea.io/gitea/models/organization"
+ "code.gitea.io/gitea/models/perm"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/log"
+ repo_module "code.gitea.io/gitea/modules/repository"
+ "code.gitea.io/gitea/modules/sync"
+ "code.gitea.io/gitea/modules/util"
+ notify_service "code.gitea.io/gitea/services/notify"
)
// repoWorkingPool represents a working pool to order the parallel changes to the same repository
diff --git a/services/repository/transfer_test.go b/services/repository/transfer_test.go
index 4bb0fc140c..cc51a05781 100644
--- a/services/repository/transfer_test.go
+++ b/services/repository/transfer_test.go
@@ -7,17 +7,17 @@ import (
"sync"
"testing"
- "forgejo.org/models"
- activities_model "forgejo.org/models/activities"
- "forgejo.org/models/db"
- "forgejo.org/models/organization"
- access_model "forgejo.org/models/perm/access"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unittest"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/util"
- "forgejo.org/services/feed"
- notify_service "forgejo.org/services/notify"
+ "code.gitea.io/gitea/models"
+ activities_model "code.gitea.io/gitea/models/activities"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/organization"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unittest"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/services/feed"
+ notify_service "code.gitea.io/gitea/services/notify"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
diff --git a/services/secrets/secrets.go b/services/secrets/secrets.go
index 2de83ef5a2..031c474dd7 100644
--- a/services/secrets/secrets.go
+++ b/services/secrets/secrets.go
@@ -6,8 +6,8 @@ package secrets
import (
"context"
- "forgejo.org/models/db"
- secret_model "forgejo.org/models/secret"
+ "code.gitea.io/gitea/models/db"
+ secret_model "code.gitea.io/gitea/models/secret"
)
func CreateOrUpdateSecret(ctx context.Context, ownerID, repoID int64, name, data string) (*secret_model.Secret, bool, error) {
@@ -15,16 +15,16 @@ func CreateOrUpdateSecret(ctx context.Context, ownerID, repoID int64, name, data
return nil, false, err
}
- s, exists, err := db.Get[secret_model.Secret](ctx, secret_model.FindSecretsOptions{
+ s, err := db.Find[secret_model.Secret](ctx, secret_model.FindSecretsOptions{
OwnerID: ownerID,
RepoID: repoID,
Name: name,
- }.ToConds())
+ })
if err != nil {
return nil, false, err
}
- if !exists {
+ if len(s) == 0 {
s, err := secret_model.InsertEncryptedSecret(ctx, ownerID, repoID, name, data)
if err != nil {
return nil, false, err
@@ -32,11 +32,11 @@ func CreateOrUpdateSecret(ctx context.Context, ownerID, repoID int64, name, data
return s, true, nil
}
- s.SetSecret(data)
- if _, err := db.GetEngine(ctx).Cols("data").ID(s.ID).Update(s); err != nil {
+ if err := secret_model.UpdateSecret(ctx, s[0].ID, data); err != nil {
return nil, false, err
}
- return s, false, nil
+
+ return s[0], false, nil
}
func DeleteSecretByID(ctx context.Context, ownerID, repoID, secretID int64) error {
diff --git a/services/secrets/validation.go b/services/secrets/validation.go
index 44250ba87b..3db5b96452 100644
--- a/services/secrets/validation.go
+++ b/services/secrets/validation.go
@@ -6,7 +6,7 @@ package secrets
import (
"regexp"
- "forgejo.org/modules/util"
+ "code.gitea.io/gitea/modules/util"
)
// https://docs.github.com/en/actions/security-guides/encrypted-secrets#naming-your-secrets
diff --git a/services/shared/automerge/automerge.go b/services/shared/automerge/automerge.go
index be7b2f6eb4..8f38cf260a 100644
--- a/services/shared/automerge/automerge.go
+++ b/services/shared/automerge/automerge.go
@@ -9,21 +9,21 @@ import (
"strconv"
"strings"
- issues_model "forgejo.org/models/issues"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/log"
- "forgejo.org/modules/queue"
+ issues_model "code.gitea.io/gitea/models/issues"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/queue"
)
// PRAutoMergeQueue represents a queue to handle update pull request tests
var PRAutoMergeQueue *queue.WorkerPoolQueue[string]
func addToQueue(pr *issues_model.PullRequest, sha string) {
- log.Trace("Adding pullID: %d to the automerge queue with sha %s", pr.ID, sha)
+ log.Trace("Adding pullID: %d to the pull requests patch checking queue with sha %s", pr.ID, sha)
if err := PRAutoMergeQueue.Push(fmt.Sprintf("%d_%s", pr.ID, sha)); err != nil {
- log.Error("Error adding pullID: %d to the automerge queue %v", pr.ID, err)
+ log.Error("Error adding pullID: %d to the pull requests patch checking queue %v", pr.ID, err)
}
}
@@ -43,29 +43,32 @@ func StartPRCheckAndAutoMergeBySHA(ctx context.Context, sha string, repo *repo_m
return nil
}
+// StartPRCheckAndAutoMerge start an automerge check and auto merge task for a pull request
func StartPRCheckAndAutoMerge(ctx context.Context, pull *issues_model.PullRequest) {
if pull == nil || pull.HasMerged || !pull.CanAutoMerge() {
return
}
- commitID := pull.HeadCommitID
- if commitID == "" {
- commitID = getCommitIDFromRefName(ctx, pull)
+ if err := pull.LoadBaseRepo(ctx); err != nil {
+ log.Error("LoadBaseRepo: %v", err)
+ return
}
- if commitID == "" {
+ gitRepo, err := gitrepo.OpenRepository(ctx, pull.BaseRepo)
+ if err != nil {
+ log.Error("OpenRepository: %v", err)
+ return
+ }
+ defer gitRepo.Close()
+ commitID, err := gitRepo.GetRefCommitID(pull.GetGitRefName())
+ if err != nil {
+ log.Error("GetRefCommitID: %v", err)
return
}
addToQueue(pull, commitID)
}
-var AddToQueueIfMergeable = func(ctx context.Context, pull *issues_model.PullRequest) {
- if pull.Status == issues_model.PullRequestStatusMergeable {
- StartPRCheckAndAutoMerge(ctx, pull)
- }
-}
-
func getPullRequestsByHeadSHA(ctx context.Context, sha string, repo *repo_model.Repository, filter func(*issues_model.PullRequest) bool) (map[int64]*issues_model.PullRequest, error) {
gitRepo, err := gitrepo.OpenRepository(ctx, repo)
if err != nil {
@@ -115,24 +118,3 @@ func getPullRequestsByHeadSHA(ctx context.Context, sha string, repo *repo_model.
return pulls, nil
}
-
-func getCommitIDFromRefName(ctx context.Context, pull *issues_model.PullRequest) string {
- if err := pull.LoadBaseRepo(ctx); err != nil {
- log.Error("LoadBaseRepo: %v", err)
- return ""
- }
-
- gitRepo, err := gitrepo.OpenRepository(ctx, pull.BaseRepo)
- if err != nil {
- log.Error("OpenRepository: %v", err)
- return ""
- }
- defer gitRepo.Close()
- commitID, err := gitRepo.GetRefCommitID(pull.GetGitRefName())
- if err != nil {
- log.Error("GetRefCommitID: %v", err)
- return ""
- }
-
- return commitID
-}
diff --git a/services/task/migrate.go b/services/task/migrate.go
index a9f76299fd..9cef77a6c8 100644
--- a/services/task/migrate.go
+++ b/services/task/migrate.go
@@ -10,20 +10,20 @@ import (
"strings"
"time"
- admin_model "forgejo.org/models/admin"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/graceful"
- "forgejo.org/modules/json"
- "forgejo.org/modules/log"
- "forgejo.org/modules/migration"
- "forgejo.org/modules/process"
- "forgejo.org/modules/structs"
- "forgejo.org/modules/timeutil"
- "forgejo.org/modules/util"
- "forgejo.org/services/migrations"
- notify_service "forgejo.org/services/notify"
+ admin_model "code.gitea.io/gitea/models/admin"
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/graceful"
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/migration"
+ "code.gitea.io/gitea/modules/process"
+ "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/timeutil"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/services/migrations"
+ notify_service "code.gitea.io/gitea/services/notify"
)
func handleCreateError(owner *user_model.User, err error) error {
diff --git a/services/task/task.go b/services/task/task.go
index f030bdb38c..ac659ac3e5 100644
--- a/services/task/task.go
+++ b/services/task/task.go
@@ -5,24 +5,23 @@ package task
import (
"context"
- "errors"
"fmt"
- admin_model "forgejo.org/models/admin"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/graceful"
- "forgejo.org/modules/json"
- "forgejo.org/modules/log"
- base "forgejo.org/modules/migration"
- "forgejo.org/modules/queue"
- "forgejo.org/modules/secret"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/structs"
- "forgejo.org/modules/timeutil"
- "forgejo.org/modules/util"
- repo_service "forgejo.org/services/repository"
+ admin_model "code.gitea.io/gitea/models/admin"
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/graceful"
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/log"
+ base "code.gitea.io/gitea/modules/migration"
+ "code.gitea.io/gitea/modules/queue"
+ "code.gitea.io/gitea/modules/secret"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/timeutil"
+ "code.gitea.io/gitea/modules/util"
+ repo_service "code.gitea.io/gitea/services/repository"
)
// taskQueue is a global queue of tasks
@@ -42,7 +41,7 @@ func Run(ctx context.Context, t *admin_model.Task) error {
func Init() error {
taskQueue = queue.CreateSimpleQueue(graceful.GetManager().ShutdownContext(), "task", handler)
if taskQueue == nil {
- return errors.New("unable to create task queue")
+ return fmt.Errorf("unable to create task queue")
}
go graceful.GetManager().RunWithCancel(taskQueue)
return nil
diff --git a/services/uinotification/notify.go b/services/uinotification/notify.go
index 25048e7b53..be5f7019a2 100644
--- a/services/uinotification/notify.go
+++ b/services/uinotification/notify.go
@@ -6,16 +6,16 @@ package uinotification
import (
"context"
- activities_model "forgejo.org/models/activities"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/container"
- "forgejo.org/modules/graceful"
- "forgejo.org/modules/log"
- "forgejo.org/modules/queue"
- notify_service "forgejo.org/services/notify"
+ activities_model "code.gitea.io/gitea/models/activities"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/container"
+ "code.gitea.io/gitea/modules/graceful"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/queue"
+ notify_service "code.gitea.io/gitea/services/notify"
)
type (
diff --git a/services/user/TestReplaceInactivePrimaryEmail/forgejo_auth_token.yml b/services/user/TestReplaceInactivePrimaryEmail/forgejo_auth_token.yml
deleted file mode 100644
index 93a6c184b6..0000000000
--- a/services/user/TestReplaceInactivePrimaryEmail/forgejo_auth_token.yml
+++ /dev/null
@@ -1,5 +0,0 @@
--
- id: 1001
- uid: 10
- lookup_key: unique
- purpose: user_activation
diff --git a/services/user/avatar.go b/services/user/avatar.go
index 79dfc76503..3f87466eaa 100644
--- a/services/user/avatar.go
+++ b/services/user/avatar.go
@@ -10,11 +10,11 @@ import (
"io"
"os"
- "forgejo.org/models/db"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/avatar"
- "forgejo.org/modules/log"
- "forgejo.org/modules/storage"
+ "code.gitea.io/gitea/models/db"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/avatar"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/storage"
)
// UploadAvatar saves custom avatar for user.
diff --git a/services/user/avatar_test.go b/services/user/avatar_test.go
index 17132a74ab..21fca8dd09 100644
--- a/services/user/avatar_test.go
+++ b/services/user/avatar_test.go
@@ -10,11 +10,11 @@ import (
"os"
"testing"
- "forgejo.org/models/db"
- "forgejo.org/models/unittest"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/storage"
- "forgejo.org/modules/test"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/unittest"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/storage"
+ "code.gitea.io/gitea/modules/test"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -42,7 +42,7 @@ func TestUserDeleteAvatar(t *testing.T) {
err := UploadAvatar(db.DefaultContext, user, buff.Bytes())
require.NoError(t, err)
verification := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
- assert.NotEmpty(t, verification.Avatar)
+ assert.NotEqual(t, "", verification.Avatar)
// fail to delete ...
storage.Avatars = storage.UninitializedStorage
@@ -60,7 +60,7 @@ func TestUserDeleteAvatar(t *testing.T) {
// ... the avatar is removed from the database
verification = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
- assert.Empty(t, verification.Avatar)
+ assert.Equal(t, "", verification.Avatar)
})
t.Run("Success", func(t *testing.T) {
@@ -70,12 +70,12 @@ func TestUserDeleteAvatar(t *testing.T) {
err := UploadAvatar(db.DefaultContext, user, buff.Bytes())
require.NoError(t, err)
verification := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
- assert.NotEmpty(t, verification.Avatar)
+ assert.NotEqual(t, "", verification.Avatar)
err = DeleteAvatar(db.DefaultContext, user)
require.NoError(t, err)
verification = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
- assert.Empty(t, verification.Avatar)
+ assert.Equal(t, "", verification.Avatar)
})
}
diff --git a/services/user/block.go b/services/user/block.go
index 6be8dc5f70..0b31119dfb 100644
--- a/services/user/block.go
+++ b/services/user/block.go
@@ -5,10 +5,10 @@ package user
import (
"context"
- model "forgejo.org/models"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
+ model "code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
"xorm.io/builder"
)
diff --git a/services/user/block_test.go b/services/user/block_test.go
index a2ba5d71a7..13959e56b4 100644
--- a/services/user/block_test.go
+++ b/services/user/block_test.go
@@ -6,12 +6,12 @@ package user
import (
"testing"
- model "forgejo.org/models"
- "forgejo.org/models/db"
- issues_model "forgejo.org/models/issues"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unittest"
- user_model "forgejo.org/models/user"
+ model "code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/models/db"
+ issues_model "code.gitea.io/gitea/models/issues"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unittest"
+ user_model "code.gitea.io/gitea/models/user"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
diff --git a/services/user/delete.go b/services/user/delete.go
index bed7abde07..587e3c2a8f 100644
--- a/services/user/delete.go
+++ b/services/user/delete.go
@@ -1,5 +1,4 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
-// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package user
@@ -11,20 +10,20 @@ import (
_ "image/jpeg" // Needed for jpeg support
- actions_model "forgejo.org/models/actions"
- activities_model "forgejo.org/models/activities"
- asymkey_model "forgejo.org/models/asymkey"
- auth_model "forgejo.org/models/auth"
- "forgejo.org/models/db"
- git_model "forgejo.org/models/git"
- issues_model "forgejo.org/models/issues"
- "forgejo.org/models/organization"
- access_model "forgejo.org/models/perm/access"
- pull_model "forgejo.org/models/pull"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/setting"
- issue_service "forgejo.org/services/issue"
+ actions_model "code.gitea.io/gitea/models/actions"
+ activities_model "code.gitea.io/gitea/models/activities"
+ asymkey_model "code.gitea.io/gitea/models/asymkey"
+ auth_model "code.gitea.io/gitea/models/auth"
+ "code.gitea.io/gitea/models/db"
+ git_model "code.gitea.io/gitea/models/git"
+ issues_model "code.gitea.io/gitea/models/issues"
+ "code.gitea.io/gitea/models/organization"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ pull_model "code.gitea.io/gitea/models/pull"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/setting"
+ issue_service "code.gitea.io/gitea/services/issue"
"xorm.io/builder"
)
@@ -217,11 +216,6 @@ func deleteUser(ctx context.Context, u *user_model.User, purge bool) (err error)
}
// ***** END: ExternalLoginUser *****
- // If the user was reported as abusive, a shadow copy should be created before deletion.
- if err = user_model.IfNeededCreateShadowCopyForUser(ctx, u.ID, u); err != nil {
- return err
- }
-
if _, err = db.DeleteByID[user_model.User](ctx, u.ID); err != nil {
return fmt.Errorf("delete: %w", err)
}
diff --git a/services/user/email.go b/services/user/email.go
index cc38dacf95..31404aadaa 100644
--- a/services/user/email.go
+++ b/services/user/email.go
@@ -1,5 +1,4 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
-// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package user
@@ -9,13 +8,12 @@ import (
"errors"
"strings"
- auth_model "forgejo.org/models/auth"
- "forgejo.org/models/db"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/util"
- "forgejo.org/modules/validation"
- "forgejo.org/services/mailer"
+ "code.gitea.io/gitea/models/db"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/modules/validation"
+ "code.gitea.io/gitea/services/mailer"
)
// AdminAddOrSetPrimaryEmailAddress is used by admins to add or set a user's primary email address
@@ -172,11 +170,6 @@ func ReplaceInactivePrimaryEmail(ctx context.Context, oldEmail string, email *us
return err
}
- // Delete previous activation token.
- if err := auth_model.DeleteAuthTokenByUser(ctx, user.ID); err != nil {
- return err
- }
-
return DeleteEmailAddresses(ctx, user, []string{oldEmail})
}
@@ -210,11 +203,6 @@ func MakeEmailAddressPrimary(ctx context.Context, u *user_model.User, newPrimary
oldPrimaryEmail := u.Email
- // If the user was reported as abusive, a shadow copy should be created before first update (of certain columns).
- if err = user_model.IfNeededCreateShadowCopyForUser(ctx, u.ID, u, "email"); err != nil {
- return err
- }
-
// 1. Update user table
u.Email = newPrimaryEmail.Email
if _, err = sess.ID(u.ID).Cols("email").Update(u); err != nil {
diff --git a/services/user/email_test.go b/services/user/email_test.go
index d2cff22696..86f31a8984 100644
--- a/services/user/email_test.go
+++ b/services/user/email_test.go
@@ -6,12 +6,11 @@ package user
import (
"testing"
- auth_model "forgejo.org/models/auth"
- "forgejo.org/models/db"
- organization_model "forgejo.org/models/organization"
- "forgejo.org/models/unittest"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/setting"
+ "code.gitea.io/gitea/models/db"
+ organization_model "code.gitea.io/gitea/models/organization"
+ "code.gitea.io/gitea/models/unittest"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/setting"
"github.com/gobwas/glob"
"github.com/stretchr/testify/assert"
@@ -124,34 +123,25 @@ func TestAddEmailAddresses(t *testing.T) {
}
func TestReplaceInactivePrimaryEmail(t *testing.T) {
- defer unittest.OverrideFixtures("services/user/TestReplaceInactivePrimaryEmail/")()
require.NoError(t, unittest.PrepareTestDatabase())
- t.Run("User doesn't exist", func(t *testing.T) {
- email := &user_model.EmailAddress{
- Email: "user9999999@example.com",
- UID: 9999999,
- }
- err := ReplaceInactivePrimaryEmail(db.DefaultContext, "user10@example.com", email)
- require.Error(t, err)
- assert.True(t, user_model.IsErrUserNotExist(err))
- })
+ email := &user_model.EmailAddress{
+ Email: "user9999999@example.com",
+ UID: 9999999,
+ }
+ err := ReplaceInactivePrimaryEmail(db.DefaultContext, "user10@example.com", email)
+ require.Error(t, err)
+ assert.True(t, user_model.IsErrUserNotExist(err))
- t.Run("Normal", func(t *testing.T) {
- unittest.AssertExistsIf(t, true, &auth_model.AuthorizationToken{UID: 10})
+ email = &user_model.EmailAddress{
+ Email: "user201@example.com",
+ UID: 10,
+ }
+ err = ReplaceInactivePrimaryEmail(db.DefaultContext, "user10@example.com", email)
+ require.NoError(t, err)
- email := &user_model.EmailAddress{
- Email: "user201@example.com",
- UID: 10,
- }
- err := ReplaceInactivePrimaryEmail(db.DefaultContext, "user10@example.com", email)
- require.NoError(t, err)
-
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 10})
- assert.Equal(t, "user201@example.com", user.Email)
-
- unittest.AssertExistsIf(t, false, &auth_model.AuthorizationToken{UID: 10})
- })
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 10})
+ assert.Equal(t, "user201@example.com", user.Email)
}
func TestDeleteEmailAddresses(t *testing.T) {
diff --git a/services/user/update.go b/services/user/update.go
index 65d3992751..62c30ac05f 100644
--- a/services/user/update.go
+++ b/services/user/update.go
@@ -7,14 +7,14 @@ import (
"context"
"fmt"
- "forgejo.org/models"
- auth_model "forgejo.org/models/auth"
- user_model "forgejo.org/models/user"
- password_module "forgejo.org/modules/auth/password"
- "forgejo.org/modules/optional"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/structs"
- "forgejo.org/services/mailer"
+ "code.gitea.io/gitea/models"
+ auth_model "code.gitea.io/gitea/models/auth"
+ user_model "code.gitea.io/gitea/models/user"
+ password_module "code.gitea.io/gitea/modules/auth/password"
+ "code.gitea.io/gitea/modules/optional"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/services/mailer"
)
type UpdateOptions struct {
diff --git a/services/user/update_test.go b/services/user/update_test.go
index f1754b2db9..11379d4508 100644
--- a/services/user/update_test.go
+++ b/services/user/update_test.go
@@ -6,12 +6,12 @@ package user
import (
"testing"
- "forgejo.org/models/db"
- "forgejo.org/models/unittest"
- user_model "forgejo.org/models/user"
- password_module "forgejo.org/modules/auth/password"
- "forgejo.org/modules/optional"
- "forgejo.org/modules/structs"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/unittest"
+ user_model "code.gitea.io/gitea/models/user"
+ password_module "code.gitea.io/gitea/modules/auth/password"
+ "code.gitea.io/gitea/modules/optional"
+ "code.gitea.io/gitea/modules/structs"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
diff --git a/services/user/user.go b/services/user/user.go
index 9cb6858f0c..62fe44ca27 100644
--- a/services/user/user.go
+++ b/services/user/user.go
@@ -11,26 +11,24 @@ import (
"strings"
"time"
- "forgejo.org/models"
- asymkey_model "forgejo.org/models/asymkey"
- "forgejo.org/models/auth"
- "forgejo.org/models/db"
- "forgejo.org/models/organization"
- packages_model "forgejo.org/models/packages"
- repo_model "forgejo.org/models/repo"
- system_model "forgejo.org/models/system"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/eventsource"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/storage"
- "forgejo.org/modules/util"
- "forgejo.org/services/agit"
- "forgejo.org/services/auth/source/oauth2"
- org_service "forgejo.org/services/org"
- "forgejo.org/services/packages"
- container_service "forgejo.org/services/packages/container"
- repo_service "forgejo.org/services/repository"
+ "code.gitea.io/gitea/models"
+ asymkey_model "code.gitea.io/gitea/models/asymkey"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/organization"
+ packages_model "code.gitea.io/gitea/models/packages"
+ repo_model "code.gitea.io/gitea/models/repo"
+ system_model "code.gitea.io/gitea/models/system"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/eventsource"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/storage"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/services/agit"
+ org_service "code.gitea.io/gitea/services/org"
+ "code.gitea.io/gitea/services/packages"
+ container_service "code.gitea.io/gitea/services/packages/container"
+ repo_service "code.gitea.io/gitea/services/repository"
)
// RenameUser renames a user
@@ -49,28 +47,10 @@ func renameUser(ctx context.Context, u *user_model.User, newUserName string, doe
}
// Non-local users are not allowed to change their username.
- // If the doer is an admin, then allow the rename - they know better.
- if !doerIsAdmin && !u.IsOrganization() && !u.IsLocal() {
- // If the user's authentication source is OAuth2 and that source allows for
- // username changes then don't make a fuzz about it.
-
- if !u.IsOAuth2() {
- return user_model.ErrUserIsNotLocal{
- UID: u.ID,
- Name: u.Name,
- }
- }
-
- source, err := auth.GetSourceByID(ctx, u.LoginSource)
- if err != nil {
- return err
- }
- sourceCfg := source.Cfg.(*oauth2.Source)
- if !sourceCfg.AllowUsernameChange {
- return user_model.ErrUserIsNotLocal{
- UID: u.ID,
- Name: u.Name,
- }
+ if !u.IsOrganization() && !u.IsLocal() {
+ return user_model.ErrUserIsNotLocal{
+ UID: u.ID,
+ Name: u.Name,
}
}
diff --git a/services/user/user_test.go b/services/user/user_test.go
index 7240813411..058ff7b6ed 100644
--- a/services/user/user_test.go
+++ b/services/user/user_test.go
@@ -11,22 +11,17 @@ import (
"testing"
"time"
- "forgejo.org/models"
- asymkey_model "forgejo.org/models/asymkey"
- "forgejo.org/models/auth"
- "forgejo.org/models/db"
- "forgejo.org/models/moderation"
- "forgejo.org/models/organization"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unittest"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/json"
- "forgejo.org/modules/optional"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/test"
- "forgejo.org/modules/timeutil"
- "forgejo.org/services/auth/source/oauth2"
- redirect_service "forgejo.org/services/redirect"
+ "code.gitea.io/gitea/models"
+ asymkey_model "code.gitea.io/gitea/models/asymkey"
+ "code.gitea.io/gitea/models/auth"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/organization"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unittest"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/test"
+ "code.gitea.io/gitea/modules/timeutil"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -72,7 +67,13 @@ func TestDeleteUser(t *testing.T) {
}
func TestPurgeUser(t *testing.T) {
- defer unittest.OverrideFixtures("services/user/TestPurgeUser")()
+ defer unittest.OverrideFixtures(
+ unittest.FixturesOptions{
+ Dir: filepath.Join(setting.AppWorkPath, "models/fixtures/"),
+ Base: setting.AppWorkPath,
+ Dirs: []string{"services/user/TestPurgeUser/"},
+ },
+ )()
require.NoError(t, unittest.PrepareTestDatabase())
defer test.MockVariableValue(&setting.SSH.RootPath, t.TempDir())()
defer test.MockVariableValue(&setting.SSH.CreateAuthorizedKeysFile, true)()
@@ -142,10 +143,17 @@ func TestCreateUser(t *testing.T) {
}
func TestRenameUser(t *testing.T) {
- defer unittest.OverrideFixtures("models/user/fixtures/")()
require.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 21})
+ t.Run("Non-Local", func(t *testing.T) {
+ u := &user_model.User{
+ Type: user_model.UserTypeIndividual,
+ LoginType: auth.OAuth2,
+ }
+ require.ErrorIs(t, RenameUser(db.DefaultContext, u, "user_rename"), user_model.ErrUserIsNotLocal{})
+ })
+
t.Run("Same username", func(t *testing.T) {
require.NoError(t, RenameUser(db.DefaultContext, user, user.Name))
})
@@ -185,9 +193,9 @@ func TestRenameUser(t *testing.T) {
require.NoError(t, RenameUser(db.DefaultContext, user, newUsername))
unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: user.ID, Name: newUsername, LowerName: strings.ToLower(newUsername)})
- redirectUID, err := redirect_service.LookupUserRedirect(db.DefaultContext, user, oldUsername)
+ redirectUID, err := user_model.LookupUserRedirect(db.DefaultContext, oldUsername)
require.NoError(t, err)
- assert.Equal(t, user.ID, redirectUID)
+ assert.EqualValues(t, user.ID, redirectUID)
unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: user.ID, OwnerName: user.Name})
})
@@ -203,41 +211,17 @@ func TestRenameUser(t *testing.T) {
unittest.AssertExistsIf(t, true, &user_model.Redirect{LowerName: "user_rename"})
// The granularity of created_unix is a second.
- test.SleepTillNextSecond()
+ time.Sleep(time.Second)
require.NoError(t, RenameUser(db.DefaultContext, user, "redirect-2"))
unittest.AssertExistsIf(t, false, &user_model.Redirect{LowerName: "user_rename"})
unittest.AssertExistsIf(t, true, &user_model.Redirect{LowerName: "redirect-1"})
setting.Service.MaxUserRedirects = 2
- test.SleepTillNextSecond()
+ time.Sleep(time.Second)
require.NoError(t, RenameUser(db.DefaultContext, user, "redirect-3"))
unittest.AssertExistsIf(t, true, &user_model.Redirect{LowerName: "redirect-1"})
unittest.AssertExistsIf(t, true, &user_model.Redirect{LowerName: "redirect-2"})
})
-
- t.Run("Non-local", func(t *testing.T) {
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1041, LoginSource: 1001})
- authSource := unittest.AssertExistsAndLoadBean(t, &auth.Source{ID: user.LoginSource})
- assert.False(t, user.IsLocal())
- assert.True(t, user.IsOAuth2())
-
- t.Run("Allowed", func(t *testing.T) {
- require.NoError(t, RenameUser(t.Context(), user, "I-am-a-local-username"))
- })
-
- t.Run("Not allowed", func(t *testing.T) {
- authSourceCfg := authSource.Cfg.(*oauth2.Source)
- authSourceCfg.AllowUsernameChange = false
- authSource.Cfg = authSourceCfg
- _, err := db.GetEngine(t.Context()).Cols("cfg").ID(authSource.ID).Update(authSource)
- require.NoError(t, err)
-
- require.ErrorIs(t, RenameUser(t.Context(), user, "Another-username-change"), user_model.ErrUserIsNotLocal{UID: user.ID, Name: user.Name})
- t.Run("Admin", func(t *testing.T) {
- require.NoError(t, AdminRenameUser(t.Context(), user, "Another-username-change"))
- })
- })
- })
}
func TestCreateUser_Issue5882(t *testing.T) {
@@ -299,56 +283,3 @@ func TestDeleteInactiveUsers(t *testing.T) {
unittest.AssertExistsIf(t, true, newUser)
unittest.AssertExistsIf(t, true, newEmail)
}
-
-func TestCreateShadowCopyOnUserUpdate(t *testing.T) {
- defer unittest.OverrideFixtures("models/fixtures/ModerationFeatures")()
- require.NoError(t, unittest.PrepareTestDatabase())
-
- userAlexSmithID := int64(1002)
- abuseReportID := int64(2) // submitted for @alexsmith
- newDummyValue := "[REDACTED]" // used for updating profile text fields
-
- // Retrieve the abusive user (@alexsmith) and the abuse report already created for this user.
- abuser := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: userAlexSmithID})
- report := unittest.AssertExistsAndLoadBean(t, &moderation.AbuseReport{
- ID: abuseReportID,
- ContentType: moderation.ReportedContentTypeUser,
- ContentID: abuser.ID,
- })
- // The report should not already have a shadow copy linked.
- assert.False(t, report.ShadowCopyID.Valid)
-
- // Keep a copy of old field values before updating them.
- oldUserData := user_model.UserData{
- FullName: abuser.FullName,
- Location: abuser.Location,
- Website: abuser.Website,
- Pronouns: abuser.Pronouns,
- Description: abuser.Description,
- }
-
- // The abusive user is updating their profile.
- opts := &UpdateOptions{
- FullName: optional.Some(newDummyValue),
- Location: optional.Some(newDummyValue),
- Website: optional.Some(newDummyValue),
- Pronouns: optional.Some(newDummyValue),
- Description: optional.Some(newDummyValue),
- }
- require.NoError(t, UpdateUser(t.Context(), abuser, opts))
-
- // Reload the report.
- report = unittest.AssertExistsAndLoadBean(t, &moderation.AbuseReport{ID: report.ID})
- // A shadow copy should have been created and linked to our report.
- assert.True(t, report.ShadowCopyID.Valid)
- // Retrieve the newly created shadow copy and unmarshal the stored JSON so that we can check the values.
- shadowCopy := unittest.AssertExistsAndLoadBean(t, &moderation.AbuseReportShadowCopy{ID: report.ShadowCopyID.Int64})
- shadowCopyUserData := new(user_model.UserData)
- require.NoError(t, json.Unmarshal([]byte(shadowCopy.RawValue), &shadowCopyUserData))
- // Check to see if the initial field values of the user were stored within the shadow copy.
- assert.Equal(t, oldUserData.FullName, shadowCopyUserData.FullName)
- assert.Equal(t, oldUserData.Location, shadowCopyUserData.Location)
- assert.Equal(t, oldUserData.Website, shadowCopyUserData.Website)
- assert.Equal(t, oldUserData.Pronouns, shadowCopyUserData.Pronouns)
- assert.Equal(t, oldUserData.Description, shadowCopyUserData.Description)
-}
diff --git a/services/webhook/default.go b/services/webhook/default.go
index 797b98f99a..089ff8bae3 100644
--- a/services/webhook/default.go
+++ b/services/webhook/default.go
@@ -11,14 +11,14 @@ import (
"net/url"
"strings"
- webhook_model "forgejo.org/models/webhook"
- "forgejo.org/modules/git"
- "forgejo.org/modules/json"
- "forgejo.org/modules/log"
- "forgejo.org/modules/svg"
- webhook_module "forgejo.org/modules/webhook"
- "forgejo.org/services/forms"
- "forgejo.org/services/webhook/shared"
+ webhook_model "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/svg"
+ webhook_module "code.gitea.io/gitea/modules/webhook"
+ "code.gitea.io/gitea/services/forms"
+ "code.gitea.io/gitea/services/webhook/shared"
)
var _ Handler = defaultHandler{}
@@ -36,7 +36,8 @@ func (dh defaultHandler) Type() webhook_module.HookType {
func (dh defaultHandler) Icon(size int) template.HTML {
if dh.forgejo {
- return svg.RenderHTML("gitea-forgejo", size, "img")
+ // forgejo.svg is not in web_src/svg/, so svg.RenderHTML does not work
+ return shared.ImgIcon("forgejo.svg", size)
}
return svg.RenderHTML("gitea-gitea", size, "img")
}
diff --git a/services/webhook/default_test.go b/services/webhook/default_test.go
index fcef4612e1..7056e77b47 100644
--- a/services/webhook/default_test.go
+++ b/services/webhook/default_test.go
@@ -6,9 +6,9 @@ package webhook
import (
"testing"
- webhook_model "forgejo.org/models/webhook"
- "forgejo.org/modules/json"
- webhook_module "forgejo.org/modules/webhook"
+ webhook_model "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/json"
+ webhook_module "code.gitea.io/gitea/modules/webhook"
jsoniter "github.com/json-iterator/go"
"github.com/stretchr/testify/assert"
@@ -237,7 +237,7 @@ func TestOpenProjectPayload(t *testing.T) {
assert.Equal(t, 12, j.Get("number").MustBeValid().ToInt())
assert.Equal(t, "http://localhost:3000/test/repo/pulls/12", j.Get("html_url").MustBeValid().ToString())
assert.Equal(t, jsoniter.NilValue, j.Get("updated_at").ValueType())
- assert.Empty(t, j.Get("state").MustBeValid().ToString())
+ assert.Equal(t, "", j.Get("state").MustBeValid().ToString())
assert.Equal(t, "Fix bug", j.Get("title").MustBeValid().ToString())
assert.Equal(t, "fixes bug #2", j.Get("body").MustBeValid().ToString())
diff --git a/services/webhook/deliver.go b/services/webhook/deliver.go
index 23aca80345..25668143e6 100644
--- a/services/webhook/deliver.go
+++ b/services/webhook/deliver.go
@@ -6,7 +6,6 @@ package webhook
import (
"context"
"crypto/tls"
- "errors"
"fmt"
"io"
"net/http"
@@ -15,16 +14,16 @@ import (
"sync"
"time"
- webhook_model "forgejo.org/models/webhook"
- "forgejo.org/modules/graceful"
- "forgejo.org/modules/hostmatcher"
- "forgejo.org/modules/log"
- "forgejo.org/modules/process"
- "forgejo.org/modules/proxy"
- "forgejo.org/modules/queue"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/timeutil"
- webhook_module "forgejo.org/modules/webhook"
+ webhook_model "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/graceful"
+ "code.gitea.io/gitea/modules/hostmatcher"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/process"
+ "code.gitea.io/gitea/modules/proxy"
+ "code.gitea.io/gitea/modules/queue"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/timeutil"
+ webhook_module "code.gitea.io/gitea/modules/webhook"
"github.com/gobwas/glob"
)
@@ -219,7 +218,7 @@ func Init() error {
hookQueue = queue.CreateUniqueQueue(graceful.GetManager().ShutdownContext(), "webhook_sender", handler)
if hookQueue == nil {
- return errors.New("unable to create webhook_sender queue")
+ return fmt.Errorf("unable to create webhook_sender queue")
}
go graceful.GetManager().RunWithCancel(hookQueue)
diff --git a/services/webhook/deliver_test.go b/services/webhook/deliver_test.go
index 1a9ce05de4..c6d1cb60dc 100644
--- a/services/webhook/deliver_test.go
+++ b/services/webhook/deliver_test.go
@@ -12,13 +12,13 @@ import (
"testing"
"time"
- "forgejo.org/models/db"
- "forgejo.org/models/unittest"
- webhook_model "forgejo.org/models/webhook"
- "forgejo.org/modules/hostmatcher"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/test"
- webhook_module "forgejo.org/modules/webhook"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/unittest"
+ webhook_model "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/hostmatcher"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/test"
+ webhook_module "code.gitea.io/gitea/modules/webhook"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -137,7 +137,7 @@ func TestWebhookDeliverHookTask(t *testing.T) {
case "/webhook/66d222a5d6349e1311f551e50722d837e30fce98":
// Version 1
assert.Equal(t, "push", r.Header.Get("X-GitHub-Event"))
- assert.Empty(t, r.Header.Get("Content-Type"))
+ assert.Equal(t, "", r.Header.Get("Content-Type"))
body, err := io.ReadAll(r.Body)
require.NoError(t, err)
assert.Equal(t, `{"data": 42}`, string(body))
diff --git a/services/webhook/dingtalk.go b/services/webhook/dingtalk.go
index ec53c79c2c..899c5b2d9f 100644
--- a/services/webhook/dingtalk.go
+++ b/services/webhook/dingtalk.go
@@ -11,13 +11,13 @@ import (
"net/url"
"strings"
- webhook_model "forgejo.org/models/webhook"
- "forgejo.org/modules/git"
- api "forgejo.org/modules/structs"
- "forgejo.org/modules/util"
- webhook_module "forgejo.org/modules/webhook"
- "forgejo.org/services/forms"
- "forgejo.org/services/webhook/shared"
+ webhook_model "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/git"
+ api "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/util"
+ webhook_module "code.gitea.io/gitea/modules/webhook"
+ "code.gitea.io/gitea/services/forms"
+ "code.gitea.io/gitea/services/webhook/shared"
)
type dingtalkHandler struct{}
@@ -207,12 +207,6 @@ func (dc dingtalkConvertor) Package(p *api.PackagePayload) (DingtalkPayload, err
return createDingtalkPayload(text, text, "view package", p.Package.HTMLURL), nil
}
-func (dc dingtalkConvertor) Action(p *api.ActionPayload) (DingtalkPayload, error) {
- text, _ := getActionPayloadInfo(p, noneLinkFormatter)
-
- return createDingtalkPayload(text, text, "view action", p.Run.HTMLURL), nil
-}
-
func createDingtalkPayload(title, text, singleTitle, singleURL string) DingtalkPayload {
return DingtalkPayload{
MsgType: "actionCard",
diff --git a/services/webhook/dingtalk_test.go b/services/webhook/dingtalk_test.go
index 5d2a240660..762d29dddc 100644
--- a/services/webhook/dingtalk_test.go
+++ b/services/webhook/dingtalk_test.go
@@ -7,10 +7,10 @@ import (
"net/url"
"testing"
- webhook_model "forgejo.org/models/webhook"
- "forgejo.org/modules/json"
- api "forgejo.org/modules/structs"
- webhook_module "forgejo.org/modules/webhook"
+ webhook_model "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/json"
+ api "code.gitea.io/gitea/modules/structs"
+ webhook_module "code.gitea.io/gitea/modules/webhook"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
diff --git a/services/webhook/discord.go b/services/webhook/discord.go
index 7259c4a995..cd25175ea1 100644
--- a/services/webhook/discord.go
+++ b/services/webhook/discord.go
@@ -15,18 +15,17 @@ import (
"strings"
"unicode/utf8"
- webhook_model "forgejo.org/models/webhook"
- "forgejo.org/modules/base"
- "forgejo.org/modules/git"
- "forgejo.org/modules/json"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- api "forgejo.org/modules/structs"
- "forgejo.org/modules/util"
- webhook_module "forgejo.org/modules/webhook"
- gitea_context "forgejo.org/services/context"
- "forgejo.org/services/forms"
- "forgejo.org/services/webhook/shared"
+ webhook_model "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ api "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/util"
+ webhook_module "code.gitea.io/gitea/modules/webhook"
+ gitea_context "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/forms"
+ "code.gitea.io/gitea/services/webhook/shared"
"code.forgejo.org/go-chi/binding"
)
@@ -152,18 +151,6 @@ var (
redColor = color("ff3232")
)
-// https://discord.com/developers/docs/resources/message#embed-object-embed-limits
-// Discord has some limits in place for the embeds.
-// According to some tests, there is no consistent limit for different character sets.
-// For example: 4096 ASCII letters are allowed, but only 2490 emoji characters are allowed.
-// To keep it simple, we currently truncate at 2000.
-const discordDescriptionCharactersLimit = 2000
-
-type discordConvertor struct {
- Username string
- AvatarURL string
-}
-
// Create implements PayloadConvertor Create method
func (d discordConvertor) Create(p *api.CreatePayload) (DiscordPayload, error) {
// created tag/branch
@@ -325,10 +312,9 @@ func (d discordConvertor) Package(p *api.PackagePayload) (DiscordPayload, error)
return d.createPayload(p.Sender, text, "", p.Package.HTMLURL, color), nil
}
-func (d discordConvertor) Action(p *api.ActionPayload) (DiscordPayload, error) {
- text, color := getActionPayloadInfo(p, noneLinkFormatter)
-
- return d.createPayload(p.Run.TriggerUser, text, "", p.Run.HTMLURL, color), nil
+type discordConvertor struct {
+ Username string
+ AvatarURL string
}
var _ shared.PayloadConvertor[DiscordPayload] = discordConvertor{}
@@ -350,7 +336,7 @@ func parseHookPullRequestEventType(event webhook_module.HookEventType) (string,
case webhook_module.HookEventPullRequestReviewApproved:
return "approved", nil
case webhook_module.HookEventPullRequestReviewRejected:
- return "requested changes", nil
+ return "rejected", nil
case webhook_module.HookEventPullRequestReviewComment:
return "comment", nil
default:
@@ -371,7 +357,7 @@ func (d discordConvertor) createPayload(s *api.User, title, text, url string, co
Embeds: []DiscordEmbed{
{
Title: title,
- Description: base.TruncateString(text, discordDescriptionCharactersLimit),
+ Description: text,
URL: url,
Color: color,
Author: DiscordEmbedAuthor{
diff --git a/services/webhook/discord_test.go b/services/webhook/discord_test.go
index b04be30bc6..e0bb2225f7 100644
--- a/services/webhook/discord_test.go
+++ b/services/webhook/discord_test.go
@@ -6,11 +6,11 @@ package webhook
import (
"testing"
- webhook_model "forgejo.org/models/webhook"
- "forgejo.org/modules/json"
- "forgejo.org/modules/setting"
- api "forgejo.org/modules/structs"
- webhook_module "forgejo.org/modules/webhook"
+ webhook_model "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/setting"
+ api "code.gitea.io/gitea/modules/structs"
+ webhook_module "code.gitea.io/gitea/modules/webhook"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -175,7 +175,7 @@ func TestDiscordPayload(t *testing.T) {
require.NoError(t, err)
assert.Len(t, pl.Embeds, 1)
- assert.Len(t, pl.Embeds[0].Description, 2000)
+ assert.Len(t, pl.Embeds[0].Description, 4096)
})
t.Run("IssueComment", func(t *testing.T) {
diff --git a/services/webhook/feishu.go b/services/webhook/feishu.go
index 57f2362783..f77c3bbd65 100644
--- a/services/webhook/feishu.go
+++ b/services/webhook/feishu.go
@@ -10,12 +10,12 @@ import (
"net/http"
"strings"
- webhook_model "forgejo.org/models/webhook"
- "forgejo.org/modules/git"
- api "forgejo.org/modules/structs"
- webhook_module "forgejo.org/modules/webhook"
- "forgejo.org/services/forms"
- "forgejo.org/services/webhook/shared"
+ webhook_model "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/git"
+ api "code.gitea.io/gitea/modules/structs"
+ webhook_module "code.gitea.io/gitea/modules/webhook"
+ "code.gitea.io/gitea/services/forms"
+ "code.gitea.io/gitea/services/webhook/shared"
)
type feishuHandler struct{}
@@ -191,12 +191,6 @@ func (fc feishuConvertor) Package(p *api.PackagePayload) (FeishuPayload, error)
return newFeishuTextPayload(text), nil
}
-func (fc feishuConvertor) Action(p *api.ActionPayload) (FeishuPayload, error) {
- text, _ := getActionPayloadInfo(p, noneLinkFormatter)
-
- return newFeishuTextPayload(text), nil
-}
-
type feishuConvertor struct{}
var _ shared.PayloadConvertor[FeishuPayload] = feishuConvertor{}
diff --git a/services/webhook/feishu_test.go b/services/webhook/feishu_test.go
index 7cf24b84ed..614e0f1ef4 100644
--- a/services/webhook/feishu_test.go
+++ b/services/webhook/feishu_test.go
@@ -6,10 +6,10 @@ package webhook
import (
"testing"
- webhook_model "forgejo.org/models/webhook"
- "forgejo.org/modules/json"
- api "forgejo.org/modules/structs"
- webhook_module "forgejo.org/modules/webhook"
+ webhook_model "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/json"
+ api "code.gitea.io/gitea/modules/structs"
+ webhook_module "code.gitea.io/gitea/modules/webhook"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
diff --git a/services/webhook/general.go b/services/webhook/general.go
index c728b6ba1a..ef68f2885b 100644
--- a/services/webhook/general.go
+++ b/services/webhook/general.go
@@ -9,11 +9,11 @@ import (
"net/url"
"strings"
- webhook_model "forgejo.org/models/webhook"
- "forgejo.org/modules/setting"
- api "forgejo.org/modules/structs"
- "forgejo.org/modules/util"
- webhook_module "forgejo.org/modules/webhook"
+ webhook_model "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/setting"
+ api "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/util"
+ webhook_module "code.gitea.io/gitea/modules/webhook"
)
type linkFormatter = func(string, string) string
@@ -37,12 +37,11 @@ func getPullRequestInfo(p *api.PullRequestPayload) (title, link, by, operator, o
for i, user := range assignList {
assignStringList[i] = user.UserName
}
- switch p.Action {
- case api.HookIssueAssigned:
+ if p.Action == api.HookIssueAssigned {
operateResult = fmt.Sprintf("%s assign this to %s", p.Sender.UserName, assignList[len(assignList)-1].UserName)
- case api.HookIssueUnassigned:
+ } else if p.Action == api.HookIssueUnassigned {
operateResult = fmt.Sprintf("%s unassigned this for someone", p.Sender.UserName)
- case api.HookIssueMilestoned:
+ } else if p.Action == api.HookIssueMilestoned {
operateResult = fmt.Sprintf("%s/milestone/%d", p.Repository.HTMLURL, p.PullRequest.Milestone.ID)
}
link = p.PullRequest.HTMLURL
@@ -63,12 +62,11 @@ func getIssuesInfo(p *api.IssuePayload) (issueTitle, link, by, operator, operate
for i, user := range assignList {
assignStringList[i] = user.UserName
}
- switch p.Action {
- case api.HookIssueAssigned:
+ if p.Action == api.HookIssueAssigned {
operateResult = fmt.Sprintf("%s assign this to %s", p.Sender.UserName, assignList[len(assignList)-1].UserName)
- case api.HookIssueUnassigned:
+ } else if p.Action == api.HookIssueUnassigned {
operateResult = fmt.Sprintf("%s unassigned this for someone", p.Sender.UserName)
- case api.HookIssueMilestoned:
+ } else if p.Action == api.HookIssueMilestoned {
operateResult = fmt.Sprintf("%s/milestone/%d", p.Repository.HTMLURL, p.Issue.Milestone.ID)
}
link = p.Issue.HTMLURL
@@ -304,25 +302,6 @@ func getPackagePayloadInfo(p *api.PackagePayload, linkFormatter linkFormatter, w
return text, color
}
-func getActionPayloadInfo(p *api.ActionPayload, linkFormatter linkFormatter) (text string, color int) {
- runLink := linkFormatter(p.Run.HTMLURL, p.Run.Title)
- repoLink := linkFormatter(p.Run.Repo.HTMLURL, p.Run.Repo.FullName)
-
- switch p.Action {
- case api.HookActionFailure:
- text = fmt.Sprintf("%s Action Failed in %s %s", runLink, repoLink, p.Run.PrettyRef)
- color = redColor
- case api.HookActionRecover:
- text = fmt.Sprintf("%s Action Recovered in %s %s", runLink, repoLink, p.Run.PrettyRef)
- color = greenColor
- case api.HookActionSuccess:
- text = fmt.Sprintf("%s Action Succeeded in %s %s", runLink, repoLink, p.Run.PrettyRef)
- color = greenColor
- }
-
- return text, color
-}
-
// ToHook convert models.Webhook to api.Hook
// This function is not part of the convert package to prevent an import cycle
func ToHook(repoLink string, w *webhook_model.Webhook) (*api.Hook, error) {
diff --git a/services/webhook/general_test.go b/services/webhook/general_test.go
index 10c779742d..8412293708 100644
--- a/services/webhook/general_test.go
+++ b/services/webhook/general_test.go
@@ -7,7 +7,7 @@ import (
"strings"
"testing"
- api "forgejo.org/modules/structs"
+ api "code.gitea.io/gitea/modules/structs"
"github.com/stretchr/testify/assert"
)
@@ -270,22 +270,6 @@ func pullReleaseTestPayload() *api.ReleasePayload {
}
}
-func ActionTestPayload() *api.ActionPayload {
- // this is not a complete action payload but enough for testing purposes
- return &api.ActionPayload{
- Run: &api.ActionRun{
- Repo: &api.Repository{
- HTMLURL: "http://localhost:3000/test/repo",
- Name: "repo",
- FullName: "test/repo",
- },
- PrettyRef: "main",
- HTMLURL: "http://localhost:3000/test/repo/actions/runs/69",
- Title: "Build release",
- },
- }
-}
-
func pullRequestTestPayload() *api.PullRequestPayload {
return &api.PullRequestPayload{
Action: api.HookIssueOpened,
@@ -691,36 +675,3 @@ func TestGetIssueCommentPayloadInfo(t *testing.T) {
assert.Equal(t, c.color, color, "case %d", i)
}
}
-
-func TestGetActionPayloadInfo(t *testing.T) {
- p := ActionTestPayload()
-
- cases := []struct {
- action api.HookActionAction
- text string
- color int
- }{
- {
- api.HookActionFailure,
- "Build release Action Failed in test/repo main",
- redColor,
- },
- {
- api.HookActionSuccess,
- "Build release Action Succeeded in test/repo main",
- greenColor,
- },
- {
- api.HookActionRecover,
- "Build release Action Recovered in test/repo main",
- greenColor,
- },
- }
-
- for i, c := range cases {
- p.Action = c.action
- text, color := getActionPayloadInfo(p, noneLinkFormatter)
- assert.Equal(t, c.text, text, "case %d", i)
- assert.Equal(t, c.color, color, "case %d", i)
- }
-}
diff --git a/services/webhook/gogs.go b/services/webhook/gogs.go
index bbab1ad41d..7dbf64343f 100644
--- a/services/webhook/gogs.go
+++ b/services/webhook/gogs.go
@@ -7,10 +7,10 @@ import (
"html/template"
"net/http"
- webhook_model "forgejo.org/models/webhook"
- webhook_module "forgejo.org/modules/webhook"
- "forgejo.org/services/forms"
- "forgejo.org/services/webhook/shared"
+ webhook_model "code.gitea.io/gitea/models/webhook"
+ webhook_module "code.gitea.io/gitea/modules/webhook"
+ "code.gitea.io/gitea/services/forms"
+ "code.gitea.io/gitea/services/webhook/shared"
)
type gogsHandler struct{ defaultHandler }
diff --git a/services/webhook/main_test.go b/services/webhook/main_test.go
index 97957291ca..6147aac499 100644
--- a/services/webhook/main_test.go
+++ b/services/webhook/main_test.go
@@ -6,13 +6,13 @@ package webhook
import (
"testing"
- "forgejo.org/models/unittest"
- "forgejo.org/modules/hostmatcher"
- "forgejo.org/modules/setting"
+ "code.gitea.io/gitea/models/unittest"
+ "code.gitea.io/gitea/modules/hostmatcher"
+ "code.gitea.io/gitea/modules/setting"
- _ "forgejo.org/models"
- _ "forgejo.org/models/actions"
- _ "forgejo.org/models/forgefed"
+ _ "code.gitea.io/gitea/models"
+ _ "code.gitea.io/gitea/models/actions"
+ _ "code.gitea.io/gitea/models/forgefed"
)
func TestMain(m *testing.M) {
diff --git a/services/webhook/matrix.go b/services/webhook/matrix.go
index bdb0c292ab..4b33bfb1d3 100644
--- a/services/webhook/matrix.go
+++ b/services/webhook/matrix.go
@@ -16,16 +16,16 @@ import (
"regexp"
"strings"
- webhook_model "forgejo.org/models/webhook"
- "forgejo.org/modules/git"
- "forgejo.org/modules/json"
- "forgejo.org/modules/log"
- api "forgejo.org/modules/structs"
- "forgejo.org/modules/svg"
- "forgejo.org/modules/util"
- webhook_module "forgejo.org/modules/webhook"
- "forgejo.org/services/forms"
- "forgejo.org/services/webhook/shared"
+ webhook_model "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/log"
+ api "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/svg"
+ "code.gitea.io/gitea/modules/util"
+ webhook_module "code.gitea.io/gitea/modules/webhook"
+ "code.gitea.io/gitea/services/forms"
+ "code.gitea.io/gitea/services/webhook/shared"
)
type matrixHandler struct{}
@@ -273,12 +273,6 @@ func (m matrixConvertor) Package(p *api.PackagePayload) (MatrixPayload, error) {
return m.newPayload(text)
}
-func (m matrixConvertor) Action(p *api.ActionPayload) (MatrixPayload, error) {
- text, _ := getActionPayloadInfo(p, htmlLinkFormatter)
-
- return m.newPayload(text)
-}
-
var urlRegex = regexp.MustCompile(`]*?href="([^">]*?)">(.*?) `)
func getMessageBody(htmlText string) string {
diff --git a/services/webhook/matrix_test.go b/services/webhook/matrix_test.go
index 1644def0e1..46e0041a34 100644
--- a/services/webhook/matrix_test.go
+++ b/services/webhook/matrix_test.go
@@ -6,10 +6,10 @@ package webhook
import (
"testing"
- webhook_model "forgejo.org/models/webhook"
- "forgejo.org/modules/json"
- api "forgejo.org/modules/structs"
- webhook_module "forgejo.org/modules/webhook"
+ webhook_model "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/json"
+ api "code.gitea.io/gitea/modules/structs"
+ webhook_module "code.gitea.io/gitea/modules/webhook"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
diff --git a/services/webhook/msteams.go b/services/webhook/msteams.go
index 3b35c407e1..736d084a8c 100644
--- a/services/webhook/msteams.go
+++ b/services/webhook/msteams.go
@@ -11,13 +11,13 @@ import (
"net/url"
"strings"
- webhook_model "forgejo.org/models/webhook"
- "forgejo.org/modules/git"
- api "forgejo.org/modules/structs"
- "forgejo.org/modules/util"
- webhook_module "forgejo.org/modules/webhook"
- "forgejo.org/services/forms"
- "forgejo.org/services/webhook/shared"
+ webhook_model "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/git"
+ api "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/util"
+ webhook_module "code.gitea.io/gitea/modules/webhook"
+ "code.gitea.io/gitea/services/forms"
+ "code.gitea.io/gitea/services/webhook/shared"
)
type msteamsHandler struct{}
@@ -326,23 +326,6 @@ func (m msteamsConvertor) Package(p *api.PackagePayload) (MSTeamsPayload, error)
), nil
}
-func (m msteamsConvertor) Action(p *api.ActionPayload) (MSTeamsPayload, error) {
- title, color := getActionPayloadInfo(p, noneLinkFormatter)
-
- // TODO: is TriggerUser correct here?
- // if you'd like to test these proprietary services, see the discussion on: https://codeberg.org/forgejo/forgejo/pulls/7508
- return createMSTeamsPayload(
- p.Run.Repo,
- p.Run.TriggerUser,
- title,
- "",
- p.Run.HTMLURL,
- color,
- // TODO: does this make any sense?
- &MSTeamsFact{"Action:", p.Run.Title},
- ), nil
-}
-
func createMSTeamsPayload(r *api.Repository, s *api.User, title, text, actionTarget string, color int, fact *MSTeamsFact) MSTeamsPayload {
facts := make([]MSTeamsFact, 0, 2)
if r != nil {
diff --git a/services/webhook/msteams_test.go b/services/webhook/msteams_test.go
index da6439f198..d9a9724e5b 100644
--- a/services/webhook/msteams_test.go
+++ b/services/webhook/msteams_test.go
@@ -6,10 +6,10 @@ package webhook
import (
"testing"
- webhook_model "forgejo.org/models/webhook"
- "forgejo.org/modules/json"
- api "forgejo.org/modules/structs"
- webhook_module "forgejo.org/modules/webhook"
+ webhook_model "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/json"
+ api "code.gitea.io/gitea/modules/structs"
+ webhook_module "code.gitea.io/gitea/modules/webhook"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -335,7 +335,7 @@ func TestMSTeamsPayload(t *testing.T) {
assert.Equal(t, "[test/repo] New wiki page 'index' (Wiki change comment)", pl.Summary)
assert.Len(t, pl.Sections, 1)
assert.Equal(t, "user1", pl.Sections[0].ActivitySubtitle)
- assert.Empty(t, pl.Sections[0].Text)
+ assert.Equal(t, "", pl.Sections[0].Text)
assert.Len(t, pl.Sections[0].Facts, 2)
for _, fact := range pl.Sections[0].Facts {
if fact.Name == "Repository:" {
@@ -356,7 +356,7 @@ func TestMSTeamsPayload(t *testing.T) {
assert.Equal(t, "[test/repo] Wiki page 'index' edited (Wiki change comment)", pl.Summary)
assert.Len(t, pl.Sections, 1)
assert.Equal(t, "user1", pl.Sections[0].ActivitySubtitle)
- assert.Empty(t, pl.Sections[0].Text)
+ assert.Equal(t, "", pl.Sections[0].Text)
assert.Len(t, pl.Sections[0].Facts, 2)
for _, fact := range pl.Sections[0].Facts {
if fact.Name == "Repository:" {
diff --git a/services/webhook/notifier.go b/services/webhook/notifier.go
index 009efc994f..ddd7002890 100644
--- a/services/webhook/notifier.go
+++ b/services/webhook/notifier.go
@@ -6,21 +6,20 @@ package webhook
import (
"context"
- actions_model "forgejo.org/models/actions"
- issues_model "forgejo.org/models/issues"
- packages_model "forgejo.org/models/packages"
- "forgejo.org/models/perm"
- access_model "forgejo.org/models/perm/access"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/log"
- "forgejo.org/modules/repository"
- "forgejo.org/modules/setting"
- api "forgejo.org/modules/structs"
- webhook_module "forgejo.org/modules/webhook"
- "forgejo.org/services/convert"
- notify_service "forgejo.org/services/notify"
+ issues_model "code.gitea.io/gitea/models/issues"
+ packages_model "code.gitea.io/gitea/models/packages"
+ "code.gitea.io/gitea/models/perm"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/repository"
+ "code.gitea.io/gitea/modules/setting"
+ api "code.gitea.io/gitea/modules/structs"
+ webhook_module "code.gitea.io/gitea/modules/webhook"
+ "code.gitea.io/gitea/services/convert"
+ notify_service "code.gitea.io/gitea/services/notify"
)
func init() {
@@ -888,45 +887,6 @@ func (m *webhookNotifier) PackageDelete(ctx context.Context, doer *user_model.Us
notifyPackage(ctx, doer, pd, api.HookPackageDeleted)
}
-func (m *webhookNotifier) ActionRunNowDone(ctx context.Context, run *actions_model.ActionRun, priorStatus actions_model.Status, lastRun *actions_model.ActionRun) {
- source := EventSource{
- Repository: run.Repo,
- Owner: run.TriggerUser,
- }
-
- // The doer is the one whose perspective is used to view this ActionRun.
- // In the best case we use the user that created the webhook.
- // Unfortunately we don't know who that was.
- // So instead we use the repo owner, who is able to create webhooks and allow others to do so by making them repo admins.
- // This is pretty close to perfect.
- doer := run.Repo.Owner
-
- payload := &api.ActionPayload{
- Run: convert.ToActionRun(ctx, run, doer),
- LastRun: convert.ToActionRun(ctx, lastRun, doer),
- PriorStatus: priorStatus.String(),
- }
-
- if run.Status.IsSuccess() {
- payload.Action = api.HookActionSuccess
- if err := PrepareWebhooks(ctx, source, webhook_module.HookEventActionRunSuccess, payload); err != nil {
- log.Error("PrepareWebhooks: %v", err)
- }
- // send another event when this is a recover
- if lastRun != nil && !lastRun.Status.IsSuccess() {
- payload.Action = api.HookActionRecover
- if err := PrepareWebhooks(ctx, source, webhook_module.HookEventActionRunRecover, payload); err != nil {
- log.Error("PrepareWebhooks: %v", err)
- }
- }
- } else {
- payload.Action = api.HookActionFailure
- if err := PrepareWebhooks(ctx, source, webhook_module.HookEventActionRunFailure, payload); err != nil {
- log.Error("PrepareWebhooks: %v", err)
- }
- }
-}
-
func notifyPackage(ctx context.Context, sender *user_model.User, pd *packages_model.PackageDescriptor, action api.HookPackageAction) {
source := EventSource{
Repository: pd.Repository,
diff --git a/services/webhook/notifier_test.go b/services/webhook/notifier_test.go
index a810de91c1..36ec3b8bf1 100644
--- a/services/webhook/notifier_test.go
+++ b/services/webhook/notifier_test.go
@@ -4,22 +4,20 @@
package webhook
import (
+ "path/filepath"
"testing"
- actions_model "forgejo.org/models/actions"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unittest"
- user_model "forgejo.org/models/user"
- webhook_model "forgejo.org/models/webhook"
- "forgejo.org/modules/git"
- "forgejo.org/modules/json"
- "forgejo.org/modules/log"
- "forgejo.org/modules/repository"
- "forgejo.org/modules/setting"
- "forgejo.org/modules/structs"
- "forgejo.org/modules/test"
- webhook_module "forgejo.org/modules/webhook"
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unittest"
+ user_model "code.gitea.io/gitea/models/user"
+ webhook_model "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/repository"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/test"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -58,7 +56,13 @@ func pushCommits() *repository.PushCommits {
}
func TestSyncPushCommits(t *testing.T) {
- defer unittest.OverrideFixtures("services/webhook/TestPushCommits")()
+ defer unittest.OverrideFixtures(
+ unittest.FixturesOptions{
+ Dir: filepath.Join(setting.AppWorkPath, "models/fixtures/"),
+ Base: setting.AppWorkPath,
+ Dirs: []string{"services/webhook/TestPushCommits"},
+ },
+ )()
require.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
@@ -86,12 +90,18 @@ func TestSyncPushCommits(t *testing.T) {
var payloadContent structs.PushPayload
require.NoError(t, json.Unmarshal([]byte(hookTask.PayloadContent), &payloadContent))
assert.Len(t, payloadContent.Commits, 1)
- assert.Equal(t, "2c54faec6c45d31c1abfaecdab471eac6633738a", payloadContent.Commits[0].ID)
+ assert.EqualValues(t, "2c54faec6c45d31c1abfaecdab471eac6633738a", payloadContent.Commits[0].ID)
})
}
func TestPushCommits(t *testing.T) {
- defer unittest.OverrideFixtures("services/webhook/TestPushCommits")()
+ defer unittest.OverrideFixtures(
+ unittest.FixturesOptions{
+ Dir: filepath.Join(setting.AppWorkPath, "models/fixtures/"),
+ Base: setting.AppWorkPath,
+ Dirs: []string{"services/webhook/TestPushCommits"},
+ },
+ )()
require.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
@@ -119,193 +129,6 @@ func TestPushCommits(t *testing.T) {
var payloadContent structs.PushPayload
require.NoError(t, json.Unmarshal([]byte(hookTask.PayloadContent), &payloadContent))
assert.Len(t, payloadContent.Commits, 1)
- assert.Equal(t, "2c54faec6c45d31c1abfaecdab471eac6633738a", payloadContent.Commits[0].ID)
- })
-}
-
-func assertActionEqual(t *testing.T, expectedRun *actions_model.ActionRun, actualRun *structs.ActionRun) {
- assert.NotNil(t, expectedRun)
- assert.NotNil(t, actualRun)
- // only test a few things
- assert.Equal(t, expectedRun.ID, actualRun.ID)
- assert.Equal(t, expectedRun.Status.String(), actualRun.Status)
- assert.Equal(t, expectedRun.Index, actualRun.Index)
- assert.Equal(t, expectedRun.RepoID, actualRun.Repo.ID)
- // convert to unix because of time zones
- assert.Equal(t, expectedRun.Stopped.AsTime().Unix(), actualRun.Stopped.Unix())
- assert.Equal(t, expectedRun.Title, actualRun.Title)
- assert.Equal(t, expectedRun.WorkflowID, actualRun.WorkflowID)
-}
-
-func TestAction(t *testing.T) {
- defer unittest.OverrideFixtures("services/webhook/TestPushCommits")()
- require.NoError(t, unittest.PrepareTestDatabase())
-
- triggerUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2, OwnerID: triggerUser.ID})
-
- oldSuccessRun := &actions_model.ActionRun{
- ID: 1,
- Status: actions_model.StatusSuccess,
- Index: 1,
- RepoID: repo.ID,
- Stopped: 1693648027,
- WorkflowID: "some_workflow",
- Title: "oldSuccessRun",
- TriggerUser: triggerUser,
- TriggerUserID: triggerUser.ID,
- TriggerEvent: "push",
- }
- oldSuccessRun.LoadAttributes(db.DefaultContext)
- oldFailureRun := &actions_model.ActionRun{
- ID: 1,
- Status: actions_model.StatusFailure,
- Index: 1,
- RepoID: repo.ID,
- Stopped: 1693648027,
- WorkflowID: "some_workflow",
- Title: "oldFailureRun",
- TriggerUser: triggerUser,
- TriggerUserID: triggerUser.ID,
- TriggerEvent: "push",
- }
- oldFailureRun.LoadAttributes(db.DefaultContext)
- newSuccessRun := &actions_model.ActionRun{
- ID: 1,
- Status: actions_model.StatusSuccess,
- Index: 1,
- RepoID: repo.ID,
- Stopped: 1693648327,
- WorkflowID: "some_workflow",
- Title: "newSuccessRun",
- TriggerUser: triggerUser,
- TriggerUserID: triggerUser.ID,
- TriggerEvent: "push",
- }
- newSuccessRun.LoadAttributes(db.DefaultContext)
- newFailureRun := &actions_model.ActionRun{
- ID: 1,
- Status: actions_model.StatusFailure,
- Index: 1,
- RepoID: repo.ID,
- Stopped: 1693648327,
- WorkflowID: "some_workflow",
- Title: "newFailureRun",
- TriggerUser: triggerUser,
- TriggerUserID: triggerUser.ID,
- TriggerEvent: "push",
- }
- newFailureRun.LoadAttributes(db.DefaultContext)
-
- t.Run("Successful Run after Nothing", func(t *testing.T) {
- defer test.MockVariableValue(&setting.Webhook.PayloadCommitLimit, 10)()
-
- NewNotifier().ActionRunNowDone(db.DefaultContext, newSuccessRun, actions_model.StatusWaiting, nil)
-
- // there's only one of these at the time
- hookTask := unittest.AssertExistsAndLoadBean(t, &webhook_model.HookTask{}, unittest.Cond("event_type == 'action_run_success' AND payload_content LIKE '%success%newSuccessRun%'"))
- assert.Equal(t, webhook_module.HookEventActionRunSuccess, hookTask.EventType)
-
- var payloadContent structs.ActionPayload
- require.NoError(t, json.Unmarshal([]byte(hookTask.PayloadContent), &payloadContent))
- assert.Equal(t, structs.HookActionSuccess, payloadContent.Action)
- assert.Equal(t, actions_model.StatusWaiting.String(), payloadContent.PriorStatus)
- assertActionEqual(t, newSuccessRun, payloadContent.Run)
- assert.Nil(t, payloadContent.LastRun)
- })
-
- t.Run("Successful Run after Failure", func(t *testing.T) {
- defer test.MockVariableValue(&setting.Webhook.PayloadCommitLimit, 10)()
-
- NewNotifier().ActionRunNowDone(db.DefaultContext, newSuccessRun, actions_model.StatusWaiting, oldFailureRun)
-
- {
- hookTask := unittest.AssertExistsAndLoadBean(t, &webhook_model.HookTask{}, unittest.Cond("event_type == 'action_run_success' AND payload_content LIKE '%success%newSuccessRun%oldFailureRun%'"))
- assert.Equal(t, webhook_module.HookEventActionRunSuccess, hookTask.EventType)
-
- var payloadContent structs.ActionPayload
- require.NoError(t, json.Unmarshal([]byte(hookTask.PayloadContent), &payloadContent))
- assert.Equal(t, structs.HookActionSuccess, payloadContent.Action)
- assert.Equal(t, actions_model.StatusWaiting.String(), payloadContent.PriorStatus)
- assertActionEqual(t, newSuccessRun, payloadContent.Run)
- assertActionEqual(t, oldFailureRun, payloadContent.LastRun)
- }
- {
- hookTask := unittest.AssertExistsAndLoadBean(t, &webhook_model.HookTask{}, unittest.Cond("event_type == 'action_run_recover' AND payload_content LIKE '%recover%newSuccessRun%oldFailureRun%'"))
- assert.Equal(t, webhook_module.HookEventActionRunRecover, hookTask.EventType)
-
- log.Error("something: %s", hookTask.PayloadContent)
- var payloadContent structs.ActionPayload
- require.NoError(t, json.Unmarshal([]byte(hookTask.PayloadContent), &payloadContent))
- assert.Equal(t, structs.HookActionRecover, payloadContent.Action)
- assert.Equal(t, actions_model.StatusWaiting.String(), payloadContent.PriorStatus)
- assertActionEqual(t, newSuccessRun, payloadContent.Run)
- assertActionEqual(t, oldFailureRun, payloadContent.LastRun)
- }
- })
-
- t.Run("Successful Run after Success", func(t *testing.T) {
- defer test.MockVariableValue(&setting.Webhook.PayloadCommitLimit, 10)()
-
- NewNotifier().ActionRunNowDone(db.DefaultContext, newSuccessRun, actions_model.StatusWaiting, oldSuccessRun)
-
- hookTask := unittest.AssertExistsAndLoadBean(t, &webhook_model.HookTask{}, unittest.Cond("event_type == 'action_run_success' AND payload_content LIKE '%success%newSuccessRun%oldSuccessRun%'"))
- assert.Equal(t, webhook_module.HookEventActionRunSuccess, hookTask.EventType)
-
- var payloadContent structs.ActionPayload
- require.NoError(t, json.Unmarshal([]byte(hookTask.PayloadContent), &payloadContent))
- assert.Equal(t, structs.HookActionSuccess, payloadContent.Action)
- assert.Equal(t, actions_model.StatusWaiting.String(), payloadContent.PriorStatus)
- assertActionEqual(t, newSuccessRun, payloadContent.Run)
- assertActionEqual(t, oldSuccessRun, payloadContent.LastRun)
- })
-
- t.Run("Failed Run after Nothing", func(t *testing.T) {
- defer test.MockVariableValue(&setting.Webhook.PayloadCommitLimit, 10)()
-
- NewNotifier().ActionRunNowDone(db.DefaultContext, newFailureRun, actions_model.StatusWaiting, nil)
-
- // there should only be this one at the time
- hookTask := unittest.AssertExistsAndLoadBean(t, &webhook_model.HookTask{}, unittest.Cond("event_type == 'action_run_failure' AND payload_content LIKE '%failure%newFailureRun%'"))
- assert.Equal(t, webhook_module.HookEventActionRunFailure, hookTask.EventType)
-
- var payloadContent structs.ActionPayload
- require.NoError(t, json.Unmarshal([]byte(hookTask.PayloadContent), &payloadContent))
- assert.Equal(t, structs.HookActionFailure, payloadContent.Action)
- assert.Equal(t, actions_model.StatusWaiting.String(), payloadContent.PriorStatus)
- assertActionEqual(t, newFailureRun, payloadContent.Run)
- assert.Nil(t, payloadContent.LastRun)
- })
-
- t.Run("Failed Run after Failure", func(t *testing.T) {
- defer test.MockVariableValue(&setting.Webhook.PayloadCommitLimit, 10)()
-
- NewNotifier().ActionRunNowDone(db.DefaultContext, newFailureRun, actions_model.StatusWaiting, oldFailureRun)
-
- hookTask := unittest.AssertExistsAndLoadBean(t, &webhook_model.HookTask{}, unittest.Cond("event_type == 'action_run_failure' AND payload_content LIKE '%failure%newFailureRun%oldFailureRun%'"))
- assert.Equal(t, webhook_module.HookEventActionRunFailure, hookTask.EventType)
-
- var payloadContent structs.ActionPayload
- require.NoError(t, json.Unmarshal([]byte(hookTask.PayloadContent), &payloadContent))
- assert.Equal(t, structs.HookActionFailure, payloadContent.Action)
- assert.Equal(t, actions_model.StatusWaiting.String(), payloadContent.PriorStatus)
- assertActionEqual(t, newFailureRun, payloadContent.Run)
- assertActionEqual(t, oldFailureRun, payloadContent.LastRun)
- })
-
- t.Run("Failed Run after Success", func(t *testing.T) {
- defer test.MockVariableValue(&setting.Webhook.PayloadCommitLimit, 10)()
-
- NewNotifier().ActionRunNowDone(db.DefaultContext, newFailureRun, actions_model.StatusWaiting, oldSuccessRun)
-
- hookTask := unittest.AssertExistsAndLoadBean(t, &webhook_model.HookTask{}, unittest.Cond("event_type == 'action_run_failure' AND payload_content LIKE '%failure%newFailureRun%oldSuccessRun%'"))
- assert.Equal(t, webhook_module.HookEventActionRunFailure, hookTask.EventType)
-
- var payloadContent structs.ActionPayload
- require.NoError(t, json.Unmarshal([]byte(hookTask.PayloadContent), &payloadContent))
- assert.Equal(t, structs.HookActionFailure, payloadContent.Action)
- assert.Equal(t, actions_model.StatusWaiting.String(), payloadContent.PriorStatus)
- assertActionEqual(t, newFailureRun, payloadContent.Run)
- assertActionEqual(t, oldSuccessRun, payloadContent.LastRun)
+ assert.EqualValues(t, "2c54faec6c45d31c1abfaecdab471eac6633738a", payloadContent.Commits[0].ID)
})
}
diff --git a/services/webhook/packagist.go b/services/webhook/packagist.go
index 7ae3e0c48f..9831a4e008 100644
--- a/services/webhook/packagist.go
+++ b/services/webhook/packagist.go
@@ -10,12 +10,12 @@ import (
"net/http"
"net/url"
- webhook_model "forgejo.org/models/webhook"
- "forgejo.org/modules/json"
- "forgejo.org/modules/log"
- webhook_module "forgejo.org/modules/webhook"
- "forgejo.org/services/forms"
- "forgejo.org/services/webhook/shared"
+ webhook_model "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/log"
+ webhook_module "code.gitea.io/gitea/modules/webhook"
+ "code.gitea.io/gitea/services/forms"
+ "code.gitea.io/gitea/services/webhook/shared"
)
type packagistHandler struct{}
diff --git a/services/webhook/packagist_test.go b/services/webhook/packagist_test.go
index e5bf4ec8d1..0f696f1b99 100644
--- a/services/webhook/packagist_test.go
+++ b/services/webhook/packagist_test.go
@@ -7,10 +7,10 @@ import (
"fmt"
"testing"
- webhook_model "forgejo.org/models/webhook"
- "forgejo.org/modules/json"
- api "forgejo.org/modules/structs"
- webhook_module "forgejo.org/modules/webhook"
+ webhook_model "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/json"
+ api "code.gitea.io/gitea/modules/structs"
+ webhook_module "code.gitea.io/gitea/modules/webhook"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
diff --git a/services/webhook/shared/img.go b/services/webhook/shared/img.go
index 95286c563e..2d65ba4e0f 100644
--- a/services/webhook/shared/img.go
+++ b/services/webhook/shared/img.go
@@ -5,7 +5,7 @@ import (
"html/template"
"strconv"
- "forgejo.org/modules/setting"
+ "code.gitea.io/gitea/modules/setting"
)
func ImgIcon(name string, size int) template.HTML {
diff --git a/services/webhook/shared/payloader.go b/services/webhook/shared/payloader.go
index e3be4c4b4c..cf0bfa82cb 100644
--- a/services/webhook/shared/payloader.go
+++ b/services/webhook/shared/payloader.go
@@ -14,10 +14,10 @@ import (
"io"
"net/http"
- webhook_model "forgejo.org/models/webhook"
- "forgejo.org/modules/json"
- api "forgejo.org/modules/structs"
- webhook_module "forgejo.org/modules/webhook"
+ webhook_model "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/json"
+ api "code.gitea.io/gitea/modules/structs"
+ webhook_module "code.gitea.io/gitea/modules/webhook"
)
var ErrPayloadTypeNotSupported = errors.New("unsupported webhook event")
@@ -36,7 +36,6 @@ type PayloadConvertor[T any] interface {
Release(*api.ReleasePayload) (T, error)
Wiki(*api.WikiPayload) (T, error)
Package(*api.PackagePayload) (T, error)
- Action(*api.ActionPayload) (T, error)
}
func convertUnmarshalledJSON[T, P any](convert func(P) (T, error), data []byte) (T, error) {
@@ -87,8 +86,6 @@ func NewPayload[T any](rc PayloadConvertor[T], data []byte, event webhook_module
return convertUnmarshalledJSON(rc.Wiki, data)
case webhook_module.HookEventPackage:
return convertUnmarshalledJSON(rc.Package, data)
- case webhook_module.HookEventActionRunFailure, webhook_module.HookEventActionRunRecover, webhook_module.HookEventActionRunSuccess:
- return convertUnmarshalledJSON(rc.Action, data)
}
var t T
return t, fmt.Errorf("newPayload unsupported event: %s", event)
diff --git a/services/webhook/slack.go b/services/webhook/slack.go
index 8c61e7ba25..5ef3e4e06f 100644
--- a/services/webhook/slack.go
+++ b/services/webhook/slack.go
@@ -11,15 +11,15 @@ import (
"regexp"
"strings"
- webhook_model "forgejo.org/models/webhook"
- "forgejo.org/modules/git"
- "forgejo.org/modules/json"
- "forgejo.org/modules/log"
- api "forgejo.org/modules/structs"
- webhook_module "forgejo.org/modules/webhook"
- gitea_context "forgejo.org/services/context"
- "forgejo.org/services/forms"
- "forgejo.org/services/webhook/shared"
+ webhook_model "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/log"
+ api "code.gitea.io/gitea/modules/structs"
+ webhook_module "code.gitea.io/gitea/modules/webhook"
+ gitea_context "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/forms"
+ "code.gitea.io/gitea/services/webhook/shared"
"code.forgejo.org/go-chi/binding"
)
@@ -142,7 +142,6 @@ func SlackLinkToRef(repoURL, ref string) string {
return SlackLinkFormatter(url, refName)
}
-// TODO: fix spelling to Converter
// Create implements payloadConvertor Create method
func (s slackConvertor) Create(p *api.CreatePayload) (SlackPayload, error) {
refLink := SlackLinkToRef(p.Repo.HTMLURL, p.Ref)
@@ -312,12 +311,6 @@ func (s slackConvertor) Repository(p *api.RepositoryPayload) (SlackPayload, erro
return s.createPayload(text, nil), nil
}
-func (s slackConvertor) Action(p *api.ActionPayload) (SlackPayload, error) {
- text, _ := getActionPayloadInfo(p, SlackLinkFormatter)
-
- return s.createPayload(text, nil), nil
-}
-
func (s slackConvertor) createPayload(text string, attachments []SlackAttachment) SlackPayload {
return SlackPayload{
Channel: s.Channel,
diff --git a/services/webhook/slack_test.go b/services/webhook/slack_test.go
index 62090fd310..ecc11d541f 100644
--- a/services/webhook/slack_test.go
+++ b/services/webhook/slack_test.go
@@ -6,10 +6,10 @@ package webhook
import (
"testing"
- webhook_model "forgejo.org/models/webhook"
- "forgejo.org/modules/json"
- api "forgejo.org/modules/structs"
- webhook_module "forgejo.org/modules/webhook"
+ webhook_model "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/json"
+ api "code.gitea.io/gitea/modules/structs"
+ webhook_module "code.gitea.io/gitea/modules/webhook"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
diff --git a/services/webhook/sourcehut/builds.go b/services/webhook/sourcehut/builds.go
index 96ed55c8ff..346ccd3c0b 100644
--- a/services/webhook/sourcehut/builds.go
+++ b/services/webhook/sourcehut/builds.go
@@ -13,20 +13,20 @@ import (
"net/http"
"strings"
- webhook_model "forgejo.org/models/webhook"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/json"
- "forgejo.org/modules/log"
- "forgejo.org/modules/setting"
- api "forgejo.org/modules/structs"
- webhook_module "forgejo.org/modules/webhook"
- gitea_context "forgejo.org/services/context"
- "forgejo.org/services/forms"
- "forgejo.org/services/webhook/shared"
+ webhook_model "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ api "code.gitea.io/gitea/modules/structs"
+ webhook_module "code.gitea.io/gitea/modules/webhook"
+ gitea_context "code.gitea.io/gitea/services/context"
+ "code.gitea.io/gitea/services/forms"
+ "code.gitea.io/gitea/services/webhook/shared"
"code.forgejo.org/go-chi/binding"
- "go.yaml.in/yaml/v3"
+ "gopkg.in/yaml.v3"
)
type BuildsHandler struct{}
@@ -190,10 +190,6 @@ func (pc sourcehutConvertor) Package(_ *api.PackagePayload) (graphqlPayload[buil
return graphqlPayload[buildsVariables]{}, shared.ErrPayloadTypeNotSupported
}
-func (pc sourcehutConvertor) Action(_ *api.ActionPayload) (graphqlPayload[buildsVariables], error) {
- return graphqlPayload[buildsVariables]{}, shared.ErrPayloadTypeNotSupported
-}
-
// newPayload opens and adjusts the manifest to submit to the builds service
//
// in case of an error the Error field will be set, to be visible by the end-user under recent deliveries
diff --git a/services/webhook/sourcehut/builds_test.go b/services/webhook/sourcehut/builds_test.go
index ac4172f5ff..689c369a7f 100644
--- a/services/webhook/sourcehut/builds_test.go
+++ b/services/webhook/sourcehut/builds_test.go
@@ -7,14 +7,14 @@ import (
"strings"
"testing"
- webhook_model "forgejo.org/models/webhook"
- "forgejo.org/modules/git"
- "forgejo.org/modules/json"
- "forgejo.org/modules/setting"
- api "forgejo.org/modules/structs"
- "forgejo.org/modules/test"
- webhook_module "forgejo.org/modules/webhook"
- "forgejo.org/services/webhook/shared"
+ webhook_model "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/setting"
+ api "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/test"
+ webhook_module "code.gitea.io/gitea/modules/webhook"
+ "code.gitea.io/gitea/services/webhook/shared"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
diff --git a/services/webhook/telegram.go b/services/webhook/telegram.go
index e6897f68bc..a02a7691e9 100644
--- a/services/webhook/telegram.go
+++ b/services/webhook/telegram.go
@@ -11,15 +11,15 @@ import (
"net/url"
"strings"
- webhook_model "forgejo.org/models/webhook"
- "forgejo.org/modules/git"
- "forgejo.org/modules/json"
- "forgejo.org/modules/log"
- "forgejo.org/modules/markup"
- api "forgejo.org/modules/structs"
- webhook_module "forgejo.org/modules/webhook"
- "forgejo.org/services/forms"
- "forgejo.org/services/webhook/shared"
+ webhook_model "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/markup"
+ api "code.gitea.io/gitea/modules/structs"
+ webhook_module "code.gitea.io/gitea/modules/webhook"
+ "code.gitea.io/gitea/services/forms"
+ "code.gitea.io/gitea/services/webhook/shared"
)
type telegramHandler struct{}
@@ -205,12 +205,6 @@ func (t telegramConvertor) Package(p *api.PackagePayload) (TelegramPayload, erro
return createTelegramPayload(text), nil
}
-func (telegramConvertor) Action(p *api.ActionPayload) (TelegramPayload, error) {
- text, _ := getActionPayloadInfo(p, htmlLinkFormatter)
-
- return createTelegramPayload(text), nil
-}
-
func createTelegramPayload(message string) TelegramPayload {
return TelegramPayload{
Message: markup.Sanitize(strings.TrimSpace(message)),
diff --git a/services/webhook/telegram_test.go b/services/webhook/telegram_test.go
index 5066e55b8c..85a62f7615 100644
--- a/services/webhook/telegram_test.go
+++ b/services/webhook/telegram_test.go
@@ -6,10 +6,10 @@ package webhook
import (
"testing"
- webhook_model "forgejo.org/models/webhook"
- "forgejo.org/modules/json"
- api "forgejo.org/modules/structs"
- webhook_module "forgejo.org/modules/webhook"
+ webhook_model "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/json"
+ api "code.gitea.io/gitea/modules/structs"
+ webhook_module "code.gitea.io/gitea/modules/webhook"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
diff --git a/services/webhook/webhook.go b/services/webhook/webhook.go
index ecbbfcfbd6..1366ea8e8f 100644
--- a/services/webhook/webhook.go
+++ b/services/webhook/webhook.go
@@ -11,21 +11,21 @@ import (
"net/http"
"strings"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
- user_model "forgejo.org/models/user"
- webhook_model "forgejo.org/models/webhook"
- "forgejo.org/modules/git"
- "forgejo.org/modules/graceful"
- "forgejo.org/modules/log"
- "forgejo.org/modules/optional"
- "forgejo.org/modules/queue"
- "forgejo.org/modules/setting"
- api "forgejo.org/modules/structs"
- "forgejo.org/modules/util"
- webhook_module "forgejo.org/modules/webhook"
- "forgejo.org/services/forms"
- "forgejo.org/services/webhook/sourcehut"
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ webhook_model "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/graceful"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/optional"
+ "code.gitea.io/gitea/modules/queue"
+ "code.gitea.io/gitea/modules/setting"
+ api "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/util"
+ webhook_module "code.gitea.io/gitea/modules/webhook"
+ "code.gitea.io/gitea/services/forms"
+ "code.gitea.io/gitea/services/webhook/sourcehut"
"github.com/gobwas/glob"
)
@@ -103,7 +103,7 @@ type EventSource struct {
Owner *user_model.User
}
-// handler delivers hook tasks
+// handle delivers hook tasks
func handler(items ...int64) []int64 {
ctx := graceful.GetManager().HammerContext()
diff --git a/services/webhook/webhook_test.go b/services/webhook/webhook_test.go
index 15cb8f620c..2ebbbe4a51 100644
--- a/services/webhook/webhook_test.go
+++ b/services/webhook/webhook_test.go
@@ -7,16 +7,15 @@ import (
"fmt"
"testing"
- "forgejo.org/models/db"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unittest"
- user_model "forgejo.org/models/user"
- webhook_model "forgejo.org/models/webhook"
- "forgejo.org/modules/setting"
- api "forgejo.org/modules/structs"
- "forgejo.org/modules/test"
- webhook_module "forgejo.org/modules/webhook"
- "forgejo.org/services/convert"
+ "code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unittest"
+ user_model "code.gitea.io/gitea/models/user"
+ webhook_model "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/setting"
+ api "code.gitea.io/gitea/modules/structs"
+ webhook_module "code.gitea.io/gitea/modules/webhook"
+ "code.gitea.io/gitea/services/convert"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -105,8 +104,7 @@ func TestPrepareWebhooksBranchFilterNoMatch(t *testing.T) {
func TestWebhookUserMail(t *testing.T) {
require.NoError(t, unittest.PrepareTestDatabase())
- defer test.MockVariableValue(&setting.Service.NoReplyAddress, "no-reply.com")()
-
+ setting.Service.NoReplyAddress = "no-reply.com"
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
assert.Equal(t, user.GetPlaceholderEmail(), convert.ToUser(db.DefaultContext, user, nil).Email)
assert.Equal(t, user.Email, convert.ToUser(db.DefaultContext, user, user).Email)
diff --git a/services/webhook/wechatwork.go b/services/webhook/wechatwork.go
index 5c765b0754..87f8bb8b18 100644
--- a/services/webhook/wechatwork.go
+++ b/services/webhook/wechatwork.go
@@ -10,12 +10,12 @@ import (
"net/http"
"strings"
- webhook_model "forgejo.org/models/webhook"
- "forgejo.org/modules/git"
- api "forgejo.org/modules/structs"
- webhook_module "forgejo.org/modules/webhook"
- "forgejo.org/services/forms"
- "forgejo.org/services/webhook/shared"
+ webhook_model "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/git"
+ api "code.gitea.io/gitea/modules/structs"
+ webhook_module "code.gitea.io/gitea/modules/webhook"
+ "code.gitea.io/gitea/services/forms"
+ "code.gitea.io/gitea/services/webhook/shared"
)
type wechatworkHandler struct{}
@@ -201,12 +201,6 @@ func (wc wechatworkConvertor) Package(p *api.PackagePayload) (WechatworkPayload,
return newWechatworkMarkdownPayload(text), nil
}
-func (wc wechatworkConvertor) Action(p *api.ActionPayload) (WechatworkPayload, error) {
- text, _ := getActionPayloadInfo(p, noneLinkFormatter)
-
- return newWechatworkMarkdownPayload(text), nil
-}
-
type wechatworkConvertor struct{}
var _ shared.PayloadConvertor[WechatworkPayload] = wechatworkConvertor{}
diff --git a/services/wiki/wiki.go b/services/wiki/wiki.go
index cf1477e72c..63196aa862 100644
--- a/services/wiki/wiki.go
+++ b/services/wiki/wiki.go
@@ -11,17 +11,17 @@ import (
"os"
"strings"
- repo_model "forgejo.org/models/repo"
- system_model "forgejo.org/models/system"
- "forgejo.org/models/unit"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
- "forgejo.org/modules/log"
- repo_module "forgejo.org/modules/repository"
- "forgejo.org/modules/sync"
- asymkey_service "forgejo.org/services/asymkey"
- repo_service "forgejo.org/services/repository"
+ repo_model "code.gitea.io/gitea/models/repo"
+ system_model "code.gitea.io/gitea/models/system"
+ "code.gitea.io/gitea/models/unit"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/log"
+ repo_module "code.gitea.io/gitea/modules/repository"
+ "code.gitea.io/gitea/modules/sync"
+ asymkey_service "code.gitea.io/gitea/services/asymkey"
+ repo_service "code.gitea.io/gitea/services/repository"
)
// TODO: use clustered lock (unique queue? or *abuse* cache)
diff --git a/services/wiki/wiki_path.go b/services/wiki/wiki_path.go
index ca312388af..74c7064043 100644
--- a/services/wiki/wiki_path.go
+++ b/services/wiki/wiki_path.go
@@ -8,11 +8,11 @@ import (
"path"
"strings"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/modules/git"
- api "forgejo.org/modules/structs"
- "forgejo.org/modules/util"
- "forgejo.org/services/convert"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/modules/git"
+ api "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/services/convert"
)
// To define the wiki related concepts:
diff --git a/services/wiki/wiki_test.go b/services/wiki/wiki_test.go
index cb984425af..efcc13db99 100644
--- a/services/wiki/wiki_test.go
+++ b/services/wiki/wiki_test.go
@@ -8,13 +8,13 @@ import (
"strings"
"testing"
- repo_model "forgejo.org/models/repo"
- "forgejo.org/models/unittest"
- user_model "forgejo.org/models/user"
- "forgejo.org/modules/git"
- "forgejo.org/modules/gitrepo"
+ repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unittest"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
- _ "forgejo.org/models/actions"
+ _ "code.gitea.io/gitea/models/actions"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -26,7 +26,7 @@ func TestMain(m *testing.M) {
func TestWebPathSegments(t *testing.T) {
a := WebPathSegments("a%2Fa/b+c/d-e/f-g.-")
- assert.Equal(t, []string{"a/a", "b c", "d e", "f-g"}, a)
+ assert.EqualValues(t, []string{"a/a", "b c", "d e", "f-g"}, a)
}
func TestUserTitleToWebPath(t *testing.T) {
@@ -63,7 +63,7 @@ func TestWebPathToDisplayName(t *testing.T) {
{"a b", "a%20b.md"},
} {
_, displayName := WebPathToUserTitle(test.WebPath)
- assert.Equal(t, test.Expected, displayName)
+ assert.EqualValues(t, test.Expected, displayName)
}
}
@@ -80,7 +80,7 @@ func TestWebPathToGitPath(t *testing.T) {
{"2000-01-02-meeting.md", "2000-01-02+meeting"},
{"2000-01-02 meeting.-.md", "2000-01-02%20meeting.-"},
} {
- assert.Equal(t, test.Expected, WebPathToGitPath(test.WikiName))
+ assert.EqualValues(t, test.Expected, WebPathToGitPath(test.WikiName))
}
}
@@ -134,9 +134,9 @@ func TestUserWebGitPathConsistency(t *testing.T) {
_, userTitle1 := WebPathToUserTitle(webPath1)
gitPath1 := WebPathToGitPath(webPath1)
- assert.Equal(t, userTitle, userTitle1, "UserTitle for userTitle: %q", userTitle)
- assert.Equal(t, webPath, webPath1, "WebPath for userTitle: %q", userTitle)
- assert.Equal(t, gitPath, gitPath1, "GitPath for userTitle: %q", userTitle)
+ assert.EqualValues(t, userTitle, userTitle1, "UserTitle for userTitle: %q", userTitle)
+ assert.EqualValues(t, webPath, webPath1, "WebPath for userTitle: %q", userTitle)
+ assert.EqualValues(t, gitPath, gitPath1, "GitPath for userTitle: %q", userTitle)
}
}
@@ -175,7 +175,7 @@ func TestRepository_AddWikiPage(t *testing.T) {
gitPath := WebPathToGitPath(webPath)
entry, err := masterTree.GetTreeEntryByPath(gitPath)
require.NoError(t, err)
- assert.Equal(t, gitPath, entry.Name(), "%s not added correctly", userTitle)
+ assert.EqualValues(t, gitPath, entry.Name(), "%s not added correctly", userTitle)
})
}
@@ -220,7 +220,7 @@ func TestRepository_EditWikiPage(t *testing.T) {
gitPath := WebPathToGitPath(webPath)
entry, err := masterTree.GetTreeEntryByPath(gitPath)
require.NoError(t, err)
- assert.Equal(t, gitPath, entry.Name(), "%s not edited correctly", newWikiName)
+ assert.EqualValues(t, gitPath, entry.Name(), "%s not edited correctly", newWikiName)
if newWikiName != "Home" {
_, err := masterTree.GetTreeEntryByPath("Home.md")
@@ -284,12 +284,12 @@ func TestPrepareWikiFileName(t *testing.T) {
}
if existence != tt.existence {
if existence {
- t.Error("expect to find no escaped file but we detect one")
+ t.Errorf("expect to find no escaped file but we detect one")
} else {
- t.Error("expect to find an escaped file but we could not detect one")
+ t.Errorf("expect to find an escaped file but we could not detect one")
}
}
- assert.Equal(t, tt.wikiPath, newWikiPath)
+ assert.EqualValues(t, tt.wikiPath, newWikiPath)
})
}
}
@@ -311,13 +311,13 @@ func TestPrepareWikiFileName_FirstPage(t *testing.T) {
existence, newWikiPath, err := prepareGitPath(gitRepo, "master", "Home")
assert.False(t, existence)
require.NoError(t, err)
- assert.Equal(t, "Home.md", newWikiPath)
+ assert.EqualValues(t, "Home.md", newWikiPath)
}
func TestWebPathConversion(t *testing.T) {
assert.Equal(t, "path/wiki", WebPathToURLPath(WebPath("path/wiki")))
assert.Equal(t, "wiki", WebPathToURLPath(WebPath("wiki")))
- assert.Empty(t, WebPathToURLPath(WebPath("")))
+ assert.Equal(t, "", WebPathToURLPath(WebPath("")))
}
func TestWebPathFromRequest(t *testing.T) {
diff --git a/shell.nix b/shell.nix
deleted file mode 100644
index a96ef516a2..0000000000
--- a/shell.nix
+++ /dev/null
@@ -1,29 +0,0 @@
-{
- pkgs ? import { },
-}:
-
-pkgs.mkShell {
- name = "forgejo";
- nativeBuildInputs = with pkgs; [
- # generic
- git
- git-lfs
- gnumake
- gnused
- gnutar
- gzip
-
- # frontend
- nodejs
-
- # backend
- gofumpt
- sqlite
- go
- gopls
- gotestsum
-
- # tests
- openssh
- ];
-}
diff --git a/templates/admin/auth/edit.tmpl b/templates/admin/auth/edit.tmpl
index d4eaa29117..1ca5573cae 100644
--- a/templates/admin/auth/edit.tmpl
+++ b/templates/admin/auth/edit.tmpl
@@ -299,13 +299,6 @@
{{ctx.Locale.Tr "admin.auths.skip_local_two_fa_helper"}}
-
-
-
{{ctx.Locale.Tr "admin.auths.allow_username_change"}}
-
-
{{ctx.Locale.Tr "admin.auths.allow_username_change.description"}}
-
-
{{ctx.Locale.Tr "admin.auths.oauth2_use_custom_url"}}
@@ -404,7 +397,7 @@
{{ctx.Locale.Tr "admin.auths.update"}}
- {{ctx.Locale.Tr "admin.auths.delete"}}
+ {{ctx.Locale.Tr "admin.auths.delete"}}
@@ -421,7 +414,7 @@
-
+
-
-
-
{{ctx.Locale.Tr "admin.auths.allow_username_change"}}
-
-
{{ctx.Locale.Tr "admin.auths.allow_username_change.description"}}
-
-
diff --git a/templates/admin/config.tmpl b/templates/admin/config.tmpl
index 36d44f21f3..8f2b1c12e3 100644
--- a/templates/admin/config.tmpl
+++ b/templates/admin/config.tmpl
@@ -51,16 +51,6 @@
-
-
-
- {{ctx.Locale.Tr "admin.config.global_2fa_requirement.title"}}
- {{ctx.Locale.Tr (print "admin.config.global_2fa_requirement." .GlobalTwoFactorRequirement)}}
-
-
-
@@ -257,16 +247,6 @@
-
-
-
- {{ctx.Locale.Tr "enabled"}}
- {{if .Moderation.Enabled}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}
-
-
-
diff --git a/templates/admin/emails/list.tmpl b/templates/admin/emails/list.tmpl
index 0a9a28fa2d..8796794aee 100644
--- a/templates/admin/emails/list.tmpl
+++ b/templates/admin/emails/list.tmpl
@@ -62,12 +62,12 @@
{{else}}
-
{{ctx.Locale.Tr "repo.pulls.no_results"}}
+
{{ctx.Locale.Tr "no_results_found"}}
{{end}}
@@ -104,7 +104,7 @@
-
diff --git a/templates/admin/notice.tmpl b/templates/admin/notice.tmpl
index 08f0a4f204..4f8783dd42 100644
--- a/templates/admin/notice.tmpl
+++ b/templates/admin/notice.tmpl
@@ -25,7 +25,7 @@
{{svg "octicon-note" 16}}
{{else}}
- {{ctx.Locale.Tr "repo.pulls.no_results"}}
+ {{ctx.Locale.Tr "no_results_found"}}
{{end}}
{{if .Notices}}
diff --git a/templates/admin/org/list.tmpl b/templates/admin/org/list.tmpl
index 8c9c198897..b719d259e0 100644
--- a/templates/admin/org/list.tmpl
+++ b/templates/admin/org/list.tmpl
@@ -67,7 +67,7 @@
{{svg "octicon-pencil"}}
{{else}}
- {{ctx.Locale.Tr "repo.pulls.no_results"}}
+ {{ctx.Locale.Tr "no_results_found"}}
{{end}}
diff --git a/templates/admin/packages/list.tmpl b/templates/admin/packages/list.tmpl
index 6b6b463a6b..f22600a449 100644
--- a/templates/admin/packages/list.tmpl
+++ b/templates/admin/packages/list.tmpl
@@ -72,10 +72,10 @@
{{ctx.Locale.TrSize .CalculateBlobSize}}
{{DateUtils.AbsoluteShort .Version.CreatedUnix}}
- {{svg "octicon-trash"}}
+ {{svg "octicon-trash"}}
{{else}}
- {{ctx.Locale.Tr "repo.pulls.no_results"}}
+ {{ctx.Locale.Tr "no_results_found"}}
{{end}}
@@ -84,7 +84,7 @@
{{template "base/paginate" .}}
-
+
-
+
diff --git a/templates/admin/stacktrace.tmpl b/templates/admin/stacktrace.tmpl
index 57c0c210cc..afe8e6942a 100644
--- a/templates/admin/stacktrace.tmpl
+++ b/templates/admin/stacktrace.tmpl
@@ -35,7 +35,7 @@
{{end}}
-