Merge branch 'main' into allow-force-push-protected-branches

This commit is contained in:
Henry Goodman
2024-01-15 18:33:43 +11:00
committed by GitHub
110 changed files with 1191 additions and 770 deletions
+15 -20
View File
@@ -117,6 +117,9 @@ func notify(ctx context.Context, input *notifyInput) error {
return nil
}
if unit_model.TypeActions.UnitGlobalDisabled() {
if err := actions_model.CleanRepoScheduleTasks(ctx, input.Repo); err != nil {
log.Error("CleanRepoScheduleTasks: %v", err)
}
return nil
}
if err := input.Repo.LoadUnits(ctx); err != nil {
@@ -153,7 +156,11 @@ func notify(ctx context.Context, input *notifyInput) error {
var detectedWorkflows []*actions_module.DetectedWorkflow
actionsConfig := input.Repo.MustGetUnit(ctx, unit_model.TypeActions).ActionsConfig()
workflows, schedules, err := actions_module.DetectWorkflows(gitRepo, commit, input.Event, input.Payload)
workflows, schedules, err := actions_module.DetectWorkflows(gitRepo, commit,
input.Event,
input.Payload,
input.Event == webhook_module.HookEventPush && input.Ref == input.Repo.DefaultBranch,
)
if err != nil {
return fmt.Errorf("DetectWorkflows: %w", err)
}
@@ -167,7 +174,7 @@ func notify(ctx context.Context, input *notifyInput) error {
continue
}
if wf.TriggerEvent != actions_module.GithubEventPullRequestTarget {
if wf.TriggerEvent.Name != actions_module.GithubEventPullRequestTarget {
detectedWorkflows = append(detectedWorkflows, wf)
}
}
@@ -180,7 +187,7 @@ func notify(ctx context.Context, input *notifyInput) error {
if err != nil {
return fmt.Errorf("gitRepo.GetCommit: %w", err)
}
baseWorkflows, _, err := actions_module.DetectWorkflows(gitRepo, baseCommit, input.Event, input.Payload)
baseWorkflows, _, err := actions_module.DetectWorkflows(gitRepo, baseCommit, input.Event, input.Payload, false)
if err != nil {
return fmt.Errorf("DetectWorkflows: %w", err)
}
@@ -188,7 +195,7 @@ func notify(ctx context.Context, input *notifyInput) error {
log.Trace("repo %s with commit %s couldn't find pull_request_target workflows", input.Repo.RepoPath(), baseCommit.ID)
} else {
for _, wf := range baseWorkflows {
if wf.TriggerEvent == actions_module.GithubEventPullRequestTarget {
if wf.TriggerEvent.Name == actions_module.GithubEventPullRequestTarget {
detectedWorkflows = append(detectedWorkflows, wf)
}
}
@@ -265,7 +272,7 @@ func handleWorkflows(
IsForkPullRequest: isForkPullRequest,
Event: input.Event,
EventPayload: string(p),
TriggerEvent: dwf.TriggerEvent,
TriggerEvent: dwf.TriggerEvent.Name,
Status: actions_model.StatusWaiting,
}
if need, err := ifNeedApproval(ctx, run, input.Repo, input.Doer); err != nil {
@@ -289,6 +296,7 @@ func handleWorkflows(
run.RepoID,
run.Ref,
run.WorkflowID,
run.Event,
); err != nil {
log.Error("CancelRunningJobs: %v", err)
}
@@ -414,8 +422,8 @@ func handleSchedules(
log.Error("CountSchedules: %v", err)
return err
} else if count > 0 {
if err := actions_model.DeleteScheduleTaskByRepo(ctx, input.Repo.ID); err != nil {
log.Error("DeleteCronTaskByRepo: %v", err)
if err := actions_model.CleanRepoScheduleTasks(ctx, input.Repo); err != nil {
log.Error("CleanRepoScheduleTasks: %v", err)
}
}
@@ -456,19 +464,6 @@ func handleSchedules(
Specs: schedules,
Content: dwf.Content,
}
// cancel running jobs if the event is push
if run.Event == webhook_module.HookEventPush {
// cancel running jobs of the same workflow
if err := actions_model.CancelRunningJobs(
ctx,
run.RepoID,
run.Ref,
run.WorkflowID,
); err != nil {
log.Error("CancelRunningJobs: %v", err)
}
}
crons = append(crons, run)
}
+2
View File
@@ -59,6 +59,7 @@ func startTasks(ctx context.Context) error {
row.RepoID,
row.Schedule.Ref,
row.Schedule.WorkflowID,
webhook_module.HookEventSchedule,
); err != nil {
log.Error("CancelRunningJobs: %v", err)
}
@@ -113,6 +114,7 @@ func CreateScheduleTask(ctx context.Context, cron *actions_model.ActionSchedule)
CommitSHA: cron.CommitSHA,
Event: cron.Event,
EventPayload: cron.EventPayload,
TriggerEvent: string(webhook_module.HookEventSchedule),
ScheduleID: cron.ID,
Status: actions_model.StatusWaiting,
}
+16 -4
View File
@@ -143,7 +143,10 @@ Loop:
case always:
break Loop
case pubkey:
keys, err := asymkey_model.ListGPGKeys(ctx, u.ID, db.ListOptions{})
keys, err := db.Find[asymkey_model.GPGKey](ctx, asymkey_model.FindGPGKeyOptions{
OwnerID: u.ID,
IncludeSubKeys: true,
})
if err != nil {
return false, "", nil, err
}
@@ -179,7 +182,10 @@ Loop:
case always:
break Loop
case pubkey:
keys, err := asymkey_model.ListGPGKeys(ctx, u.ID, db.ListOptions{})
keys, err := db.Find[asymkey_model.GPGKey](ctx, asymkey_model.FindGPGKeyOptions{
OwnerID: u.ID,
IncludeSubKeys: true,
})
if err != nil {
return false, "", nil, err
}
@@ -232,7 +238,10 @@ Loop:
case always:
break Loop
case pubkey:
keys, err := asymkey_model.ListGPGKeys(ctx, u.ID, db.ListOptions{})
keys, err := db.Find[asymkey_model.GPGKey](ctx, asymkey_model.FindGPGKeyOptions{
OwnerID: u.ID,
IncludeSubKeys: true,
})
if err != nil {
return false, "", nil, err
}
@@ -294,7 +303,10 @@ Loop:
case always:
break Loop
case pubkey:
keys, err := asymkey_model.ListGPGKeys(ctx, u.ID, db.ListOptions{})
keys, err := db.Find[asymkey_model.GPGKey](ctx, asymkey_model.FindGPGKeyOptions{
OwnerID: u.ID,
IncludeSubKeys: true,
})
if err != nil {
return false, "", nil, err
}
+19 -20
View File
@@ -171,6 +171,7 @@ func ToBranchProtection(ctx context.Context, bp *git_model.ProtectedBranch) *api
BlockOnOfficialReviewRequests: bp.BlockOnOfficialReviewRequests,
BlockOnOutdatedBranch: bp.BlockOnOutdatedBranch,
DismissStaleApprovals: bp.DismissStaleApprovals,
IgnoreStaleApprovals: bp.IgnoreStaleApprovals,
RequireSignedCommits: bp.RequireSignedCommits,
ProtectedFilePatterns: bp.ProtectedFilePatterns,
UnprotectedFilePatterns: bp.UnprotectedFilePatterns,
@@ -321,40 +322,38 @@ func ToTeam(ctx context.Context, team *organization.Team, loadOrg ...bool) (*api
// ToTeams convert models.Team list to api.Team list
func ToTeams(ctx context.Context, teams []*organization.Team, loadOrgs bool) ([]*api.Team, error) {
if len(teams) == 0 || teams[0] == nil {
return nil, nil
}
cache := make(map[int64]*api.Organization)
apiTeams := make([]*api.Team, len(teams))
for i := range teams {
if err := teams[i].LoadUnits(ctx); err != nil {
apiTeams := make([]*api.Team, 0, len(teams))
for _, t := range teams {
if err := t.LoadUnits(ctx); err != nil {
return nil, err
}
apiTeams[i] = &api.Team{
ID: teams[i].ID,
Name: teams[i].Name,
Description: teams[i].Description,
IncludesAllRepositories: teams[i].IncludesAllRepositories,
CanCreateOrgRepo: teams[i].CanCreateOrgRepo,
Permission: teams[i].AccessMode.String(),
Units: teams[i].GetUnitNames(),
UnitsMap: teams[i].GetUnitsMap(),
apiTeam := &api.Team{
ID: t.ID,
Name: t.Name,
Description: t.Description,
IncludesAllRepositories: t.IncludesAllRepositories,
CanCreateOrgRepo: t.CanCreateOrgRepo,
Permission: t.AccessMode.String(),
Units: t.GetUnitNames(),
UnitsMap: t.GetUnitsMap(),
}
if loadOrgs {
apiOrg, ok := cache[teams[i].OrgID]
apiOrg, ok := cache[t.OrgID]
if !ok {
org, err := organization.GetOrgByID(ctx, teams[i].OrgID)
org, err := organization.GetOrgByID(ctx, t.OrgID)
if err != nil {
return nil, err
}
apiOrg = ToOrganization(ctx, org)
cache[teams[i].OrgID] = apiOrg
cache[t.OrgID] = apiOrg
}
apiTeams[i].Organization = apiOrg
apiTeam.Organization = apiOrg
}
apiTeams = append(apiTeams, apiTeam)
}
return apiTeams, nil
}
+8 -6
View File
@@ -21,15 +21,9 @@ func ToPullReview(ctx context.Context, r *issues_model.Review, doer *user_model.
r.Reviewer = user_model.NewGhostUser()
}
apiTeam, err := ToTeam(ctx, r.ReviewerTeam)
if err != nil {
return nil, err
}
result := &api.PullReview{
ID: r.ID,
Reviewer: ToUser(ctx, r.Reviewer, doer),
ReviewerTeam: apiTeam,
State: api.ReviewStateUnknown,
Body: r.Content,
CommitID: r.CommitID,
@@ -43,6 +37,14 @@ func ToPullReview(ctx context.Context, r *issues_model.Review, doer *user_model.
HTMLPullURL: r.Issue.HTMLURL(),
}
if r.ReviewerTeam != nil {
var err error
result.ReviewerTeam, err = ToTeam(ctx, r.ReviewerTeam)
if err != nil {
return nil, err
}
}
switch r.Type {
case issues_model.ReviewTypeApprove:
result.State = api.ReviewStateApproved
+6 -1
View File
@@ -8,6 +8,7 @@ import (
"time"
"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"
@@ -133,7 +134,11 @@ func innerToRepo(ctx context.Context, repo *repo_model.Repository, permissionInR
return nil
}
numReleases, _ := repo_model.GetReleaseCountByRepoID(ctx, repo.ID, repo_model.FindReleasesOptions{IncludeDrafts: false, IncludeTags: false})
numReleases, _ := db.Count[repo_model.Release](ctx, repo_model.FindReleasesOptions{
IncludeDrafts: false,
IncludeTags: false,
RepoID: repo.ID,
})
mirrorInterval := ""
var mirrorUpdated time.Time
+1
View File
@@ -216,6 +216,7 @@ type ProtectBranchForm struct {
BlockOnOfficialReviewRequests bool
BlockOnOutdatedBranch bool
DismissStaleApprovals bool
IgnoreStaleApprovals bool
RequireSignedCommits bool
ProtectedFilePatterns string
UnprotectedFilePatterns string
+4 -2
View File
@@ -83,22 +83,24 @@ func TestGiteaUploadRepo(t *testing.T) {
assert.NoError(t, err)
assert.Len(t, labels, 12)
releases, err := repo_model.GetReleasesByRepoID(db.DefaultContext, repo.ID, repo_model.FindReleasesOptions{
releases, err := db.Find[repo_model.Release](db.DefaultContext, repo_model.FindReleasesOptions{
ListOptions: db.ListOptions{
PageSize: 10,
Page: 0,
},
IncludeTags: true,
RepoID: repo.ID,
})
assert.NoError(t, err)
assert.Len(t, releases, 8)
releases, err = repo_model.GetReleasesByRepoID(db.DefaultContext, repo.ID, repo_model.FindReleasesOptions{
releases, err = db.Find[repo_model.Release](db.DefaultContext, repo_model.FindReleasesOptions{
ListOptions: db.ListOptions{
PageSize: 10,
Page: 0,
},
IncludeTags: false,
RepoID: repo.ID,
})
assert.NoError(t, err)
assert.Len(t, releases, 1)
+25 -22
View File
@@ -125,17 +125,18 @@ type packageData struct {
type packageCache = map[*packages_model.PackageFile]*packageData
// BuildRepositoryFiles builds metadata files for the repository
func BuildRepositoryFiles(ctx context.Context, ownerID int64) error {
// BuildSpecificRepositoryFiles builds metadata files for the repository
func BuildRepositoryFiles(ctx context.Context, ownerID int64, compositeKey string) error {
pv, err := GetOrCreateRepositoryVersion(ctx, ownerID)
if err != nil {
return err
}
pfs, _, err := packages_model.SearchFiles(ctx, &packages_model.PackageFileSearchOptions{
OwnerID: ownerID,
PackageType: packages_model.TypeRpm,
Query: "%.rpm",
OwnerID: ownerID,
PackageType: packages_model.TypeRpm,
Query: "%.rpm",
CompositeKey: compositeKey,
})
if err != nil {
return err
@@ -194,15 +195,15 @@ func BuildRepositoryFiles(ctx context.Context, ownerID int64) error {
cache[pf] = pd
}
primary, err := buildPrimary(ctx, pv, pfs, cache)
primary, err := buildPrimary(ctx, pv, pfs, cache, compositeKey)
if err != nil {
return err
}
filelists, err := buildFilelists(ctx, pv, pfs, cache)
filelists, err := buildFilelists(ctx, pv, pfs, cache, compositeKey)
if err != nil {
return err
}
other, err := buildOther(ctx, pv, pfs, cache)
other, err := buildOther(ctx, pv, pfs, cache, compositeKey)
if err != nil {
return err
}
@@ -216,11 +217,12 @@ func BuildRepositoryFiles(ctx context.Context, ownerID int64) error {
filelists,
other,
},
compositeKey,
)
}
// https://docs.pulpproject.org/en/2.19/plugins/pulp_rpm/tech-reference/rpm.html#repomd-xml
func buildRepomd(ctx context.Context, pv *packages_model.PackageVersion, ownerID int64, data []*repoData) error {
func buildRepomd(ctx context.Context, pv *packages_model.PackageVersion, ownerID int64, data []*repoData, compositeKey string) error {
type Repomd struct {
XMLName xml.Name `xml:"repomd"`
Xmlns string `xml:"xmlns,attr"`
@@ -275,7 +277,8 @@ func buildRepomd(ctx context.Context, pv *packages_model.PackageVersion, ownerID
pv,
&packages_service.PackageFileCreationInfo{
PackageFileInfo: packages_service.PackageFileInfo{
Filename: file.Name,
Filename: file.Name,
CompositeKey: compositeKey,
},
Creator: user_model.NewGhostUser(),
Data: file.Data,
@@ -292,7 +295,7 @@ func buildRepomd(ctx context.Context, pv *packages_model.PackageVersion, ownerID
}
// https://docs.pulpproject.org/en/2.19/plugins/pulp_rpm/tech-reference/rpm.html#primary-xml
func buildPrimary(ctx context.Context, pv *packages_model.PackageVersion, pfs []*packages_model.PackageFile, c packageCache) (*repoData, error) {
func buildPrimary(ctx context.Context, pv *packages_model.PackageVersion, pfs []*packages_model.PackageFile, c packageCache, compositeKey string) (*repoData, error) {
type Version struct {
Epoch string `xml:"epoch,attr"`
Version string `xml:"ver,attr"`
@@ -372,7 +375,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,
@@ -401,7 +404,7 @@ func buildPrimary(ctx context.Context, pv *packages_model.PackageVersion, pfs []
Archive: pd.FileMetadata.ArchiveSize,
},
Location: Location{
Href: fmt.Sprintf("package/%s/%s/%s", url.PathEscape(pd.Package.Name), url.PathEscape(pd.Version.Version), url.PathEscape(pd.FileMetadata.Architecture)),
Href: fmt.Sprintf("package/%s/%s/%s/%s", url.PathEscape(pd.Package.Name), url.PathEscape(packageVersion), url.PathEscape(pd.FileMetadata.Architecture), url.PathEscape(fmt.Sprintf("%s-%s.%s.rpm", pd.Package.Name, packageVersion, pd.FileMetadata.Architecture))),
},
Format: Format{
License: pd.VersionMetadata.License,
@@ -431,11 +434,11 @@ func buildPrimary(ctx context.Context, pv *packages_model.PackageVersion, pfs []
XmlnsRpm: "http://linux.duke.edu/metadata/rpm",
PackageCount: len(pfs),
Packages: packages,
})
}, compositeKey)
}
// https://docs.pulpproject.org/en/2.19/plugins/pulp_rpm/tech-reference/rpm.html#filelists-xml
func buildFilelists(ctx context.Context, pv *packages_model.PackageVersion, pfs []*packages_model.PackageFile, c packageCache) (*repoData, error) { //nolint:dupl
func buildFilelists(ctx context.Context, pv *packages_model.PackageVersion, pfs []*packages_model.PackageFile, c packageCache, compositeKey string) (*repoData, error) { //nolint:dupl
type Version struct {
Epoch string `xml:"epoch,attr"`
Version string `xml:"ver,attr"`
@@ -478,11 +481,12 @@ func buildFilelists(ctx context.Context, pv *packages_model.PackageVersion, pfs
Xmlns: "http://linux.duke.edu/metadata/other",
PackageCount: len(pfs),
Packages: packages,
})
},
compositeKey)
}
// https://docs.pulpproject.org/en/2.19/plugins/pulp_rpm/tech-reference/rpm.html#other-xml
func buildOther(ctx context.Context, pv *packages_model.PackageVersion, pfs []*packages_model.PackageFile, c packageCache) (*repoData, error) { //nolint:dupl
func buildOther(ctx context.Context, pv *packages_model.PackageVersion, pfs []*packages_model.PackageFile, c packageCache, compositeKey string) (*repoData, error) { //nolint:dupl
type Version struct {
Epoch string `xml:"epoch,attr"`
Version string `xml:"ver,attr"`
@@ -525,7 +529,7 @@ func buildOther(ctx context.Context, pv *packages_model.PackageVersion, pfs []*p
Xmlns: "http://linux.duke.edu/metadata/other",
PackageCount: len(pfs),
Packages: packages,
})
}, compositeKey)
}
// writtenCounter counts all written bytes
@@ -545,10 +549,8 @@ func (wc *writtenCounter) Written() int64 {
return wc.written
}
func addDataAsFileToRepo(ctx context.Context, pv *packages_model.PackageVersion, filetype string, obj any) (*repoData, error) {
func addDataAsFileToRepo(ctx context.Context, pv *packages_model.PackageVersion, filetype string, obj any, compositeKey string) (*repoData, error) {
content, _ := packages_module.NewHashedBuffer()
defer content.Close()
gzw := gzip.NewWriter(content)
wc := &writtenCounter{}
h := sha256.New()
@@ -571,7 +573,8 @@ func addDataAsFileToRepo(ctx context.Context, pv *packages_model.PackageVersion,
pv,
&packages_service.PackageFileCreationInfo{
PackageFileInfo: packages_service.PackageFileInfo{
Filename: filename,
Filename: filename,
CompositeKey: compositeKey,
},
Creator: user_model.NewGhostUser(),
Data: content,
+1 -1
View File
@@ -324,7 +324,7 @@ func DeleteOldRepositoryArchives(ctx context.Context, olderThan time.Duration) e
log.Trace("Doing: ArchiveCleanup")
for {
archivers, err := repo_model.FindRepoArchives(ctx, repo_model.FindRepoArchiversOption{
archivers, err := db.Find[repo_model.RepoArchiver](ctx, repo_model.FindRepoArchiversOption{
ListOptions: db.ListOptions{
PageSize: 100,
Page: 1,
+65 -1
View File
@@ -10,6 +10,7 @@ import (
"strings"
"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"
@@ -22,6 +23,7 @@ import (
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"
files_service "code.gitea.io/gitea/services/repository/files"
@@ -308,13 +310,28 @@ func RenameBranch(ctx context.Context, repo *repo_model.Repository, doer *user_m
return "from_not_exist", nil
}
if err := git_model.RenameBranch(ctx, repo, from, to, func(isDefault bool) error {
if err := git_model.RenameBranch(ctx, repo, from, to, func(ctx context.Context, isDefault bool) error {
err2 := gitRepo.RenameBranch(from, to)
if err2 != nil {
return err2
}
if isDefault {
// if default branch changed, we need to delete all schedules and cron jobs
if err := actions_model.DeleteScheduleTaskByRepo(ctx, repo.ID); err != nil {
log.Error("DeleteCronTaskByRepo: %v", err)
}
// cancel running cron jobs of this repository and delete old schedules
if err := actions_model.CancelRunningJobs(
ctx,
repo.ID,
from,
"",
webhook_module.HookEventSchedule,
); err != nil {
log.Error("CancelRunningJobs: %v", err)
}
err2 = gitRepo.SetDefaultBranch(to)
if err2 != nil {
return err2
@@ -450,3 +467,50 @@ func AddAllRepoBranchesToSyncQueue(ctx context.Context, doerID int64) error {
}
return nil
}
func SetRepoDefaultBranch(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, newBranchName string) error {
if repo.DefaultBranch == newBranchName {
return nil
}
if !gitRepo.IsBranchExist(newBranchName) {
return git_model.ErrBranchNotExist{
BranchName: newBranchName,
}
}
oldDefaultBranchName := repo.DefaultBranch
repo.DefaultBranch = newBranchName
if err := db.WithTx(ctx, func(ctx context.Context) error {
if err := repo_model.UpdateDefaultBranch(ctx, repo); err != nil {
return err
}
if err := actions_model.DeleteScheduleTaskByRepo(ctx, repo.ID); err != nil {
log.Error("DeleteCronTaskByRepo: %v", err)
}
// cancel running cron jobs of this repository and delete old schedules
if err := actions_model.CancelRunningJobs(
ctx,
repo.ID,
oldDefaultBranchName,
"",
webhook_module.HookEventSchedule,
); err != nil {
log.Error("CancelRunningJobs: %v", err)
}
if err := gitRepo.SetDefaultBranch(newBranchName); err != nil {
if !git.IsErrUnsupportedVersion(err) {
return err
}
}
return nil
}); err != nil {
return err
}
notify_service.ChangeDefaultBranch(ctx, repo)
return nil
}
+5 -2
View File
@@ -327,9 +327,12 @@ func pushUpdateAddTags(ctx context.Context, repo *repo_model.Repository, gitRepo
lowerTags = append(lowerTags, strings.ToLower(tag))
}
releases, err := repo_model.GetReleasesByRepoIDAndNames(ctx, repo.ID, lowerTags)
releases, err := db.Find[repo_model.Release](ctx, repo_model.FindReleasesOptions{
RepoID: repo.ID,
TagNames: lowerTags,
})
if err != nil {
return fmt.Errorf("GetReleasesByRepoIDAndNames: %w", err)
return fmt.Errorf("db.Find[repo_model.Release]: %w", err)
}
relMap := make(map[string]*repo_model.Release)
for _, rel := range releases {
+47
View File
@@ -0,0 +1,47 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package repository
import (
"context"
"slices"
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"
)
// UpdateRepositoryUnits updates a repository's units
func UpdateRepositoryUnits(ctx context.Context, repo *repo_model.Repository, units []repo_model.RepoUnit, deleteUnitTypes []unit.Type) (err error) {
ctx, committer, err := db.TxContext(ctx)
if err != nil {
return err
}
defer committer.Close()
// Delete existing settings of units before adding again
for _, u := range units {
deleteUnitTypes = append(deleteUnitTypes, u.Type)
}
if slices.Contains(deleteUnitTypes, unit.TypeActions) {
if err := actions_model.CleanRepoScheduleTasks(ctx, repo); err != nil {
log.Error("CleanRepoScheduleTasks: %v", err)
}
}
if _, err = db.GetEngine(ctx).Where("repo_id = ?", repo.ID).In("type", deleteUnitTypes).Delete(new(repo_model.RepoUnit)); err != nil {
return err
}
if len(units) > 0 {
if err = db.Insert(ctx, units); err != nil {
return err
}
}
return committer.Commit()
}
+3 -1
View File
@@ -159,7 +159,9 @@ func deleteUser(ctx context.Context, u *user_model.User, purge bool) (err error)
// ***** END: PublicKey *****
// ***** START: GPGPublicKey *****
keys, err := asymkey_model.ListGPGKeys(ctx, u.ID, db.ListOptions{})
keys, err := db.Find[asymkey_model.GPGKey](ctx, asymkey_model.FindGPGKeyOptions{
OwnerID: u.ID,
})
if err != nil {
return fmt.Errorf("ListGPGKeys: %w", err)
}
+6 -1
View File
@@ -129,6 +129,10 @@ func DeleteUser(ctx context.Context, u *user_model.User, purge bool) error {
return fmt.Errorf("%s is an organization not a user", u.Name)
}
if user_model.IsLastAdminUser(ctx, u) {
return models.ErrDeleteLastAdminUser{UID: u.ID}
}
if purge {
// Disable the user first
// NOTE: This is deliberately not within a transaction as it must disable the user immediately to prevent any further action by the user to be purged.
@@ -295,7 +299,8 @@ func DeleteInactiveUsers(ctx context.Context, olderThan time.Duration) error {
}
if err := DeleteUser(ctx, u, false); err != nil {
// Ignore users that were set inactive by admin.
if models.IsErrUserOwnRepos(err) || models.IsErrUserHasOrgs(err) || models.IsErrUserOwnPackages(err) {
if models.IsErrUserOwnRepos(err) || models.IsErrUserHasOrgs(err) ||
models.IsErrUserOwnPackages(err) || models.IsErrDeleteLastAdminUser(err) {
continue
}
return err
+2 -1
View File
@@ -19,6 +19,7 @@ import (
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)
@@ -350,7 +351,7 @@ func DeleteWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model
// DeleteWiki removes the actual and local copy of repository wiki.
func DeleteWiki(ctx context.Context, repo *repo_model.Repository) error {
if err := repo_model.UpdateRepositoryUnits(ctx, repo, nil, []unit.Type{unit.TypeWiki}); err != nil {
if err := repo_service.UpdateRepositoryUnits(ctx, repo, nil, []unit.Type{unit.TypeWiki}); err != nil {
return err
}