forked from gitea/gitea
Allow to sync tags from admin dashboard (#28045)
Inspired by #28043 This PR adds a option to the Admin Dashboard to sync all tags to the database. ![grafik](https://github.com/go-gitea/gitea/assets/15185051/26ac51ef-82a4-4fd9-a6a6-5aefec612ff6)
This commit is contained in:
parent
f3ba3e922d
commit
4567a3a1ad
|
@ -284,6 +284,22 @@ func CleanUpMigrateInfo(ctx context.Context, repo *repo_model.Repository) (*repo
|
||||||
return repo, UpdateRepository(ctx, repo, false)
|
return repo, UpdateRepository(ctx, repo, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SyncRepoTags synchronizes releases table with repository tags
|
||||||
|
func SyncRepoTags(ctx context.Context, repoID int64) error {
|
||||||
|
repo, err := repo_model.GetRepositoryByID(ctx, repoID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
gitRepo, err := git.OpenRepository(ctx, repo.RepoPath())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer gitRepo.Close()
|
||||||
|
|
||||||
|
return SyncReleasesWithTags(ctx, repo, gitRepo)
|
||||||
|
}
|
||||||
|
|
||||||
// SyncReleasesWithTags synchronizes release table with repository tags
|
// SyncReleasesWithTags synchronizes release table with repository tags
|
||||||
func SyncReleasesWithTags(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository) error {
|
func SyncReleasesWithTags(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository) error {
|
||||||
log.Debug("SyncReleasesWithTags: in Repo[%d:%s/%s]", repo.ID, repo.OwnerName, repo.Name)
|
log.Debug("SyncReleasesWithTags: in Repo[%d:%s/%s]", repo.ID, repo.OwnerName, repo.Name)
|
||||||
|
|
|
@ -2748,6 +2748,7 @@ dashboard.delete_missing_repos = Delete all repositories missing their Git files
|
||||||
dashboard.delete_missing_repos.started = Delete all repositories missing their Git files task started.
|
dashboard.delete_missing_repos.started = Delete all repositories missing their Git files task started.
|
||||||
dashboard.delete_generated_repository_avatars = Delete generated repository avatars
|
dashboard.delete_generated_repository_avatars = Delete generated repository avatars
|
||||||
dashboard.sync_repo_branches = Sync missed branches from git data to databases
|
dashboard.sync_repo_branches = Sync missed branches from git data to databases
|
||||||
|
dashboard.sync_repo_tags = Sync tags from git data to database
|
||||||
dashboard.update_mirrors = Update Mirrors
|
dashboard.update_mirrors = Update Mirrors
|
||||||
dashboard.repo_health_check = Health check all repositories
|
dashboard.repo_health_check = Health check all repositories
|
||||||
dashboard.check_repo_stats = Check all repository statistics
|
dashboard.check_repo_stats = Check all repository statistics
|
||||||
|
@ -2802,6 +2803,7 @@ dashboard.stop_endless_tasks = Stop endless tasks
|
||||||
dashboard.cancel_abandoned_jobs = Cancel abandoned jobs
|
dashboard.cancel_abandoned_jobs = Cancel abandoned jobs
|
||||||
dashboard.start_schedule_tasks = Start schedule tasks
|
dashboard.start_schedule_tasks = Start schedule tasks
|
||||||
dashboard.sync_branch.started = Branches Sync started
|
dashboard.sync_branch.started = Branches Sync started
|
||||||
|
dashboard.sync_tag.started = Tags Sync started
|
||||||
dashboard.rebuild_issue_indexer = Rebuild issue indexer
|
dashboard.rebuild_issue_indexer = Rebuild issue indexer
|
||||||
|
|
||||||
users.user_manage_panel = User Account Management
|
users.user_manage_panel = User Account Management
|
||||||
|
|
|
@ -45,6 +45,7 @@ import (
|
||||||
repo_migrations "code.gitea.io/gitea/services/migrations"
|
repo_migrations "code.gitea.io/gitea/services/migrations"
|
||||||
mirror_service "code.gitea.io/gitea/services/mirror"
|
mirror_service "code.gitea.io/gitea/services/mirror"
|
||||||
pull_service "code.gitea.io/gitea/services/pull"
|
pull_service "code.gitea.io/gitea/services/pull"
|
||||||
|
release_service "code.gitea.io/gitea/services/release"
|
||||||
repo_service "code.gitea.io/gitea/services/repository"
|
repo_service "code.gitea.io/gitea/services/repository"
|
||||||
"code.gitea.io/gitea/services/repository/archiver"
|
"code.gitea.io/gitea/services/repository/archiver"
|
||||||
"code.gitea.io/gitea/services/task"
|
"code.gitea.io/gitea/services/task"
|
||||||
|
@ -138,6 +139,8 @@ func InitWebInstalled(ctx context.Context) {
|
||||||
mustInit(system.Init)
|
mustInit(system.Init)
|
||||||
mustInitCtx(ctx, oauth2.Init)
|
mustInitCtx(ctx, oauth2.Init)
|
||||||
|
|
||||||
|
mustInit(release_service.Init)
|
||||||
|
|
||||||
mustInitCtx(ctx, models.Init)
|
mustInitCtx(ctx, models.Init)
|
||||||
mustInitCtx(ctx, authmodel.Init)
|
mustInitCtx(ctx, authmodel.Init)
|
||||||
mustInitCtx(ctx, repo_service.Init)
|
mustInitCtx(ctx, repo_service.Init)
|
||||||
|
|
|
@ -23,6 +23,7 @@ import (
|
||||||
"code.gitea.io/gitea/modules/web"
|
"code.gitea.io/gitea/modules/web"
|
||||||
"code.gitea.io/gitea/services/cron"
|
"code.gitea.io/gitea/services/cron"
|
||||||
"code.gitea.io/gitea/services/forms"
|
"code.gitea.io/gitea/services/forms"
|
||||||
|
release_service "code.gitea.io/gitea/services/release"
|
||||||
repo_service "code.gitea.io/gitea/services/repository"
|
repo_service "code.gitea.io/gitea/services/repository"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -157,6 +158,13 @@ func DashboardPost(ctx *context.Context) {
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
ctx.Flash.Success(ctx.Tr("admin.dashboard.sync_branch.started"))
|
ctx.Flash.Success(ctx.Tr("admin.dashboard.sync_branch.started"))
|
||||||
|
case "sync_repo_tags":
|
||||||
|
go func() {
|
||||||
|
if err := release_service.AddAllRepoTagsToSyncQueue(graceful.GetManager().ShutdownContext()); err != nil {
|
||||||
|
log.Error("AddAllRepoTagsToSyncQueue: %v: %v", ctx.Doer.ID, err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
ctx.Flash.Success(ctx.Tr("admin.dashboard.sync_tag.started"))
|
||||||
default:
|
default:
|
||||||
task := cron.GetTask(form.Op)
|
task := cron.GetTask(form.Op)
|
||||||
if task != nil {
|
if task != nil {
|
||||||
|
|
|
@ -16,6 +16,7 @@ import (
|
||||||
user_model "code.gitea.io/gitea/models/user"
|
user_model "code.gitea.io/gitea/models/user"
|
||||||
"code.gitea.io/gitea/modules/container"
|
"code.gitea.io/gitea/modules/container"
|
||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/git"
|
||||||
|
"code.gitea.io/gitea/modules/graceful"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/repository"
|
"code.gitea.io/gitea/modules/repository"
|
||||||
"code.gitea.io/gitea/modules/storage"
|
"code.gitea.io/gitea/modules/storage"
|
||||||
|
@ -370,3 +371,8 @@ func DeleteReleaseByID(ctx context.Context, repo *repo_model.Repository, rel *re
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Init start release service
|
||||||
|
func Init() error {
|
||||||
|
return initTagSyncQueue(graceful.GetManager().ShutdownContext())
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package release
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"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"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TagSyncOptions struct {
|
||||||
|
RepoID int64
|
||||||
|
}
|
||||||
|
|
||||||
|
// tagSyncQueue represents a queue to handle tag sync jobs.
|
||||||
|
var tagSyncQueue *queue.WorkerPoolQueue[*TagSyncOptions]
|
||||||
|
|
||||||
|
func handlerTagSync(items ...*TagSyncOptions) []*TagSyncOptions {
|
||||||
|
for _, opts := range items {
|
||||||
|
err := repo_module.SyncRepoTags(graceful.GetManager().ShutdownContext(), opts.RepoID)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("syncRepoTags [%d] failed: %v", opts.RepoID, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func addRepoToTagSyncQueue(repoID int64) error {
|
||||||
|
return tagSyncQueue.Push(&TagSyncOptions{
|
||||||
|
RepoID: repoID,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func initTagSyncQueue(ctx context.Context) error {
|
||||||
|
tagSyncQueue = queue.CreateUniqueQueue(ctx, "tag_sync", handlerTagSync)
|
||||||
|
if tagSyncQueue == nil {
|
||||||
|
return errors.New("unable to create tag_sync queue")
|
||||||
|
}
|
||||||
|
go graceful.GetManager().RunWithCancel(tagSyncQueue)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func AddAllRepoTagsToSyncQueue(ctx context.Context) error {
|
||||||
|
if err := db.Iterate(ctx, builder.Eq{"is_empty": false}, func(ctx context.Context, repo *repo_model.Repository) error {
|
||||||
|
return addRepoToTagSyncQueue(repo.ID)
|
||||||
|
}); err != nil {
|
||||||
|
return fmt.Errorf("run sync all tags failed: %v", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -63,6 +63,10 @@
|
||||||
<td>{{ctx.Locale.Tr "admin.dashboard.sync_repo_branches"}}</td>
|
<td>{{ctx.Locale.Tr "admin.dashboard.sync_repo_branches"}}</td>
|
||||||
<td class="text right"><button type="submit" class="ui primary button" name="op" value="sync_repo_branches">{{svg "octicon-play"}} {{ctx.Locale.Tr "admin.dashboard.operation_run"}}</button></td>
|
<td class="text right"><button type="submit" class="ui primary button" name="op" value="sync_repo_branches">{{svg "octicon-play"}} {{ctx.Locale.Tr "admin.dashboard.operation_run"}}</button></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{{ctx.Locale.Tr "admin.dashboard.sync_repo_tags"}}</td>
|
||||||
|
<td class="text right"><button type="submit" class="ui primary button" name="op" value="sync_repo_tags">{{svg "octicon-play"}} {{ctx.Locale.Tr "admin.dashboard.operation_run"}}</button></td>
|
||||||
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</form>
|
</form>
|
||||||
|
|
Loading…
Reference in New Issue