fix: don't push LFS when using SSH authentication (#10475)

We would need to understand LFS over SSH, which is not implemented.
Ref: forgejo/forgejo#5925

Skip pushing LFS when SSH authentication is used.
Resolves: Codeberg/Community#2156

Add a test to verify that you can push mirror a LFS repository

Documentation: forgejo/docs!1639
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10475
Reviewed-by: Mathieu Fenniak <mfenniak@noreply.codeberg.org>
Co-authored-by: Gusted <postmaster@gusted.xyz>
Co-committed-by: Gusted <postmaster@gusted.xyz>
This commit is contained in:
Gusted 2025-12-18 23:23:07 +01:00 committed by Gusted
parent 8473d08445
commit b069daf2ec
2 changed files with 31 additions and 8 deletions

View file

@ -192,7 +192,9 @@ func runPushSync(ctx context.Context, m *repo_model.PushMirror) error {
return errors.New("Unexpected error")
}
if setting.LFS.StartServer {
useSSHAuthentication := len(m.PublicKey) != 0
if setting.LFS.StartServer && !useSSHAuthentication {
log.Trace("SyncMirrors [repo: %-v]: syncing LFS objects...", m.Repo)
var gitRepo *git.Repository
@ -220,7 +222,7 @@ func runPushSync(ctx context.Context, m *repo_model.PushMirror) error {
// Therefore, we need to create a temporary file that stores the private key, so that OpenSSH can use it.
// We delete the temporary file afterwards.
privateKeyPath := ""
if m.PublicKey != "" {
if useSSHAuthentication {
f, err := os.CreateTemp(os.TempDir(), m.RemoteName)
if err != nil {
log.Error("os.CreateTemp: %v", err)

View file

@ -227,14 +227,15 @@ func TestSSHPushMirror(t *testing.T) {
srcRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
assert.False(t, srcRepo.HasWiki())
sess := loginUser(t, user.Name)
pushToRepo, _, f := tests.CreateDeclarativeRepoWithOptions(t, user, tests.DeclarativeRepoOptions{
Name: optional.Some("push-mirror-test"),
Name: optional.Some("push-mirror-misc-test"),
AutoInit: optional.Some(false),
EnabledUnits: optional.Some([]unit.Type{unit.TypeCode}),
})
defer f()
sshURL := fmt.Sprintf("ssh://%s@%s/%s.git", setting.SSH.User, net.JoinHostPort(setting.SSH.ListenHost, strconv.Itoa(setting.SSH.ListenPort)), pushToRepo.FullName())
t.Run("Mutual exclusive", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
@ -282,7 +283,17 @@ func TestSSHPushMirror(t *testing.T) {
htmlDoc.AssertElement(t, inputSelector, true)
})
t.Run("Normal", func(t *testing.T) {
testMirrorPush := func(t *testing.T, srcRepo *repo_model.Repository, expectedSHA string) {
t.Helper()
pushToRepo, _, f := tests.CreateDeclarativeRepoWithOptions(t, user, tests.DeclarativeRepoOptions{
Name: optional.Some("push-mirror-test"),
AutoInit: optional.Some(false),
EnabledUnits: optional.Some([]unit.Type{unit.TypeCode}),
})
defer f()
sshURL := fmt.Sprintf("ssh://%s@%s/%s.git", setting.SSH.User, net.JoinHostPort(setting.SSH.ListenHost, strconv.Itoa(setting.SSH.ListenPort)), pushToRepo.FullName())
var pushMirror *repo_model.PushMirror
t.Run("Adding", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
@ -341,20 +352,19 @@ func TestSSHPushMirror(t *testing.T) {
t.Run("Check mirrored content", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
shortSHA := "1032bbf17f"
req := NewRequest(t, "GET", fmt.Sprintf("/%s", srcRepo.FullName()))
resp := sess.MakeRequest(t, req, http.StatusOK)
htmlDoc := NewHTMLParser(t, resp.Body)
assert.Contains(t, htmlDoc.Find(".shortsha").Text(), shortSHA)
assert.Contains(t, htmlDoc.Find(".shortsha").Text(), expectedSHA)
assert.Eventually(t, func() bool {
req = NewRequest(t, "GET", fmt.Sprintf("/%s", pushToRepo.FullName()))
resp = sess.MakeRequest(t, req, NoExpectedStatus)
htmlDoc = NewHTMLParser(t, resp.Body)
return resp.Code == http.StatusOK && htmlDoc.Find(".shortsha").Text() == shortSHA
return resp.Code == http.StatusOK && htmlDoc.Find(".shortsha").Text() == expectedSHA
}, time.Second*30, time.Second)
})
@ -369,6 +379,17 @@ func TestSSHPushMirror(t *testing.T) {
assert.Contains(t, string(knownHosts), string(publicKey))
})
}
t.Run("Normal", func(t *testing.T) {
testMirrorPush(t, srcRepo, "1032bbf17f")
})
t.Run("LFS", func(t *testing.T) {
defer test.MockVariableValue(&setting.LFS.StartServer, true)()
srcRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 54})
testMirrorPush(t, srcRepo, "e9c32647ba")
})
})
}