GitRoot
craft your forge, build your project, grow your community freely
1// SPDX-FileCopyrightText: 2025 Romain Maneschi <romain@gitroot.dev>
2//
3// SPDX-License-Identifier: EUPL-1.2
4
5package background
6
7import (
8 "github.com/go-git/go-git/v5/plumbing/protocol/packp"
9 "github.com/samber/oops"
10 "gitroot.dev/server/logger"
11 "gitroot.dev/server/plugin"
12 "gitroot.dev/server/user"
13)
14
15type postPushTaskInput struct {
16 pusher user.SimpleUser
17 repoName string
18 commands []*packp.Command
19}
20
21func (m *Manager) PostPush(pusher user.SimpleUser, repoName string, commands []*packp.Command) {
22 m.Start(Task{
23 call: m.postPush,
24 t: postPushTaskInput{
25 pusher: pusher,
26 repoName: repoName,
27 commands: commands,
28 },
29 })
30}
31
32func (m *Manager) postPush(input interface{}) error {
33 postPushInput := input.(postPushTaskInput)
34 errorHandler := oops.
35 With("pusher", postPushInput.pusher).
36 With("repoName", postPushInput.repoName).
37 With("commands", len(postPushInput.commands))
38
39 repo, err := m.repoManager.Open(logger.AddCaller(m.ctx, "postPush"), postPushInput.repoName)
40 if err != nil {
41 return errorHandler.Wrapf(err, "can't open repository")
42 }
43 defer repo.Close()
44
45 cmds, err := plugin.CommandForDiffFromPackpCmd(m.ctx, repo, postPushInput.commands, postPushInput.pusher)
46 if err != nil {
47 return errorHandler.Wrapf(err, "CommandForDiffFromPackpCmd error")
48 }
49
50 if m.conf.IsForgeRepo(postPushInput.repoName) {
51 repoConfiguration, err := repo.Configuration()
52 if err != nil {
53 return errorHandler.Wrapf(err, "can't read configuration in forgerepo")
54 }
55 forgeRepoRepositoriesFileTouched := plugin.IsFileTouched(cmds, repoConfiguration.DefaultBranch, m.conf.PathFileRepositories())
56 forgeRepoPluginsFileTouched := plugin.IsFileTouched(cmds, repoConfiguration.DefaultBranch, m.conf.PathFilePlugins())
57 m.logger.Info(
58 "postpush commands",
59 logger.NewLoggerPair("repo", postPushInput.repoName),
60 logger.NewLoggerPair("defaultBranch", repoConfiguration.DefaultBranch),
61 logger.NewLoggerPair("forgeRepoRepositoriesFileTouched", forgeRepoRepositoriesFileTouched),
62 logger.NewLoggerPair("forgeRepoPluginsFileTouched", forgeRepoPluginsFileTouched),
63 )
64
65 if forgeRepoPluginsFileTouched {
66 filePlugin, err := repo.ContentPluginsConf()
67 if err != nil {
68 return errorHandler.Wrapf(err, "can't open file plugin in forgerepo")
69 }
70 if err := m.pluginManager.Sync(filePlugin); err != nil {
71 return errorHandler.Wrapf(err, "can't sync plugins files")
72 }
73 defer m.syncPluginsInExistingRepos()
74 }
75
76 if forgeRepoRepositoriesFileTouched {
77 fileContent, err := repo.ContentRepositoriesConf()
78 if err != nil {
79 errorHandler.Wrapf(err, "can't open file repositories")
80 }
81 reposToCreate, reposToDelete, err := m.repoManager.ForgeRepoMakeDiffRepos(m.ctx, fileContent)
82 if err != nil {
83 return errorHandler.Wrapf(err, "can't diff repositories between forgeConfg and local")
84 }
85 m.logger.Debug("to create", logger.NewLoggerPair("repos", reposToCreate))
86 m.syncRepos(reposToCreate, reposToDelete, postPushInput.pusher)
87 }
88 }
89
90 if err := m.pluginManager.Run(m.ctx, postPushInput.repoName, cmds); err != nil {
91 return errorHandler.Wrapf(err, "plugin error")
92 }
93
94 return nil
95}