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}