[gitea] week 2025-09 cherry pick (gitea/main -> forgejo) (#7031)
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7031 Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org> Reviewed-by: 0ko <0ko@noreply.codeberg.org>
This commit is contained in:
commit
2212923de0
25 changed files with 523 additions and 169 deletions
107
services/actions/task.go
Normal file
107
services/actions/task.go
Normal file
|
@ -0,0 +1,107 @@
|
|||
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package actions
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
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"
|
||||
)
|
||||
|
||||
func PickTask(ctx context.Context, runner *actions_model.ActionRunner) (*runnerv1.Task, bool, error) {
|
||||
var (
|
||||
task *runnerv1.Task
|
||||
job *actions_model.ActionRunJob
|
||||
)
|
||||
|
||||
if err := db.WithTx(ctx, func(ctx context.Context) error {
|
||||
t, ok, err := actions_model.CreateTaskForRunner(ctx, runner)
|
||||
if err != nil {
|
||||
return fmt.Errorf("CreateTaskForRunner: %w", err)
|
||||
}
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := t.LoadAttributes(ctx); err != nil {
|
||||
return fmt.Errorf("task LoadAttributes: %w", err)
|
||||
}
|
||||
job = t.Job
|
||||
|
||||
secrets, err := secret_model.GetSecretsOfTask(ctx, t)
|
||||
if err != nil {
|
||||
return fmt.Errorf("GetSecretsOfTask: %w", err)
|
||||
}
|
||||
|
||||
vars, err := actions_model.GetVariablesOfRun(ctx, t.Job.Run)
|
||||
if err != nil {
|
||||
return fmt.Errorf("GetVariablesOfRun: %w", err)
|
||||
}
|
||||
|
||||
needs, err := findTaskNeeds(ctx, job)
|
||||
if err != nil {
|
||||
return fmt.Errorf("findTaskNeeds: %w", err)
|
||||
}
|
||||
|
||||
taskContext, err := generateTaskContext(t)
|
||||
if err != nil {
|
||||
return fmt.Errorf("generateTaskContext: %w", err)
|
||||
}
|
||||
|
||||
task = &runnerv1.Task{
|
||||
Id: t.ID,
|
||||
WorkflowPayload: t.Job.WorkflowPayload,
|
||||
Context: taskContext,
|
||||
Secrets: secrets,
|
||||
Vars: vars,
|
||||
Needs: needs,
|
||||
}
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
if task == nil {
|
||||
return nil, false, nil
|
||||
}
|
||||
|
||||
CreateCommitStatus(ctx, job)
|
||||
|
||||
return task, true, nil
|
||||
}
|
||||
|
||||
func generateTaskContext(t *actions_model.ActionTask) (*structpb.Struct, error) {
|
||||
giteaRuntimeToken, err := CreateAuthorizationToken(t.ID, t.Job.RunID, t.JobID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
gitCtx := GenerateGiteaContext(t.Job.Run, t.Job)
|
||||
gitCtx["token"] = t.Token
|
||||
gitCtx["gitea_runtime_token"] = giteaRuntimeToken
|
||||
|
||||
return structpb.NewStruct(gitCtx)
|
||||
}
|
||||
|
||||
func findTaskNeeds(ctx context.Context, taskJob *actions_model.ActionRunJob) (map[string]*runnerv1.TaskNeed, error) {
|
||||
taskNeeds, err := FindTaskNeeds(ctx, taskJob)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := make(map[string]*runnerv1.TaskNeed, len(taskNeeds))
|
||||
for jobID, taskNeed := range taskNeeds {
|
||||
ret[jobID] = &runnerv1.TaskNeed{
|
||||
Outputs: taskNeed.Outputs,
|
||||
Result: runnerv1.Result(taskNeed.Result),
|
||||
}
|
||||
}
|
||||
return ret, nil
|
||||
}
|
|
@ -54,7 +54,7 @@ func registerRepoHealthCheck() {
|
|||
RunAtStart: false,
|
||||
Schedule: "@midnight",
|
||||
},
|
||||
Timeout: 60 * time.Second,
|
||||
Timeout: time.Duration(setting.Git.Timeout.Default) * time.Second,
|
||||
Args: []string{},
|
||||
}, func(ctx context.Context, _ *user_model.User, config Config) error {
|
||||
rhcConfig := config.(*RepoHealthCheckConfig)
|
||||
|
|
|
@ -135,7 +135,9 @@ func parseRemoteUpdateOutput(output, remoteName string) []*mirrorSyncResult {
|
|||
case strings.HasPrefix(lines[i], " - "): // Delete reference
|
||||
isTag := !strings.HasPrefix(refName, remoteName+"/")
|
||||
var refFullName git.RefName
|
||||
if isTag {
|
||||
if strings.HasPrefix(refName, "refs/") {
|
||||
refFullName = git.RefName(refName)
|
||||
} else if isTag {
|
||||
refFullName = git.RefNameFromTag(refName)
|
||||
} else {
|
||||
refFullName = git.RefNameFromBranch(strings.TrimPrefix(refName, remoteName+"/"))
|
||||
|
@ -158,8 +160,15 @@ func parseRemoteUpdateOutput(output, remoteName string) []*mirrorSyncResult {
|
|||
log.Error("Expect two SHAs but not what found: %q", lines[i])
|
||||
continue
|
||||
}
|
||||
var refFullName git.RefName
|
||||
if strings.HasPrefix(refName, "refs/") {
|
||||
refFullName = git.RefName(refName)
|
||||
} else {
|
||||
refFullName = git.RefNameFromBranch(strings.TrimPrefix(refName, remoteName+"/"))
|
||||
}
|
||||
|
||||
results = append(results, &mirrorSyncResult{
|
||||
refName: git.RefNameFromBranch(strings.TrimPrefix(refName, remoteName+"/")),
|
||||
refName: refFullName,
|
||||
oldCommitID: shas[0],
|
||||
newCommitID: shas[1],
|
||||
})
|
||||
|
|
|
@ -17,11 +17,13 @@ func Test_parseRemoteUpdateOutput(t *testing.T) {
|
|||
- [deleted] (none) -> tag1
|
||||
+ f895a1e...957a993 test2 -> origin/test2 (forced update)
|
||||
957a993..a87ba5f test3 -> origin/test3
|
||||
* [new ref] refs/pull/27/merge -> refs/pull/27/merge
|
||||
* [new ref] refs/pull/516/head -> refs/pull/516/head
|
||||
`
|
||||
* [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, 8)
|
||||
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)
|
||||
|
@ -46,11 +48,19 @@ func Test_parseRemoteUpdateOutput(t *testing.T) {
|
|||
assert.EqualValues(t, "957a993", results[5].oldCommitID)
|
||||
assert.EqualValues(t, "a87ba5f", results[5].newCommitID)
|
||||
|
||||
assert.EqualValues(t, "refs/pull/27/merge", results[6].refName.String())
|
||||
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/516/head", results[7].refName.String())
|
||||
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)
|
||||
}
|
||||
|
|
78
services/packages/package_update.go
Normal file
78
services/packages/package_update.go
Normal file
|
@ -0,0 +1,78 @@
|
|||
// Copyright 2025 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package packages
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
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 {
|
||||
if pkg.OwnerID != repo.OwnerID {
|
||||
return util.ErrPermissionDenied
|
||||
}
|
||||
if pkg.RepoID > 0 {
|
||||
return util.ErrInvalidArgument
|
||||
}
|
||||
|
||||
perms, err := access_model.GetUserRepoPermission(ctx, repo, doer)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error getting permissions for user %d on repository %d: %w", doer.ID, repo.ID, err)
|
||||
}
|
||||
if !perms.CanWrite(unit.TypePackages) {
|
||||
return util.ErrPermissionDenied
|
||||
}
|
||||
|
||||
if err := packages_model.SetRepositoryLink(ctx, pkg.ID, repo.ID); err != nil {
|
||||
return fmt.Errorf("error while linking package '%v' to repo '%v' : %w", pkg.Name, repo.FullName(), err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func UnlinkFromRepository(ctx context.Context, pkg *packages_model.Package, doer *user_model.User) error {
|
||||
if pkg.RepoID == 0 {
|
||||
return util.ErrInvalidArgument
|
||||
}
|
||||
|
||||
repo, err := repo_model.GetRepositoryByID(ctx, pkg.RepoID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error getting repository %d: %w", pkg.RepoID, err)
|
||||
}
|
||||
|
||||
perms, err := access_model.GetUserRepoPermission(ctx, repo, doer)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error getting permissions for user %d on repository %d: %w", doer.ID, repo.ID, err)
|
||||
}
|
||||
if !perms.CanWrite(unit.TypePackages) {
|
||||
return util.ErrPermissionDenied
|
||||
}
|
||||
|
||||
user, err := user_model.GetUserByID(ctx, pkg.OwnerID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !doer.IsAdmin {
|
||||
if !user.IsOrganization() {
|
||||
if doer.ID != pkg.OwnerID {
|
||||
return fmt.Errorf("no permission to unlink package '%v' from its repository, or packages are disabled", pkg.Name)
|
||||
}
|
||||
} else {
|
||||
isOrgAdmin, err := org_model.OrgFromUser(user).IsOrgAdmin(ctx, doer.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if !isOrgAdmin {
|
||||
return fmt.Errorf("no permission to unlink package '%v' from its repository, or packages are disabled", pkg.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
return packages_model.UnlinkRepository(ctx, pkg.ID)
|
||||
}
|
|
@ -16,6 +16,7 @@ import (
|
|||
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"
|
||||
|
@ -28,6 +29,7 @@ import (
|
|||
"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"
|
||||
)
|
||||
|
@ -289,6 +291,15 @@ func DeleteRepositoryDirectly(ctx context.Context, doer *user_model.User, repoID
|
|||
return err
|
||||
}
|
||||
|
||||
if err := federation_service.DeleteFollowingRepos(ctx, repo.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// unlink packages linked to this repository
|
||||
if err = packages_model.UnlinkRepositoryFromAllPackages(ctx, repoID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = committer.Commit(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@ import (
|
|||
"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"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
system_model "code.gitea.io/gitea/models/system"
|
||||
"code.gitea.io/gitea/models/unit"
|
||||
|
@ -22,7 +21,6 @@ import (
|
|||
repo_module "code.gitea.io/gitea/modules/repository"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/structs"
|
||||
federation_service "code.gitea.io/gitea/services/federation"
|
||||
notify_service "code.gitea.io/gitea/services/notify"
|
||||
pull_service "code.gitea.io/gitea/services/pull"
|
||||
)
|
||||
|
@ -64,15 +62,7 @@ func DeleteRepository(ctx context.Context, doer *user_model.User, repo *repo_mod
|
|||
notify_service.DeleteRepository(ctx, doer, repo)
|
||||
}
|
||||
|
||||
if err := DeleteRepositoryDirectly(ctx, doer, repo.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := federation_service.DeleteFollowingRepos(ctx, repo.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return packages_model.UnlinkRepositoryFromAllPackages(ctx, repo.ID)
|
||||
return DeleteRepositoryDirectly(ctx, doer, repo.ID)
|
||||
}
|
||||
|
||||
// PushCreateRepo creates a repository when a new repository is pushed to an appropriate namespace
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue