|
7 | 7 | "os" |
8 | 8 | "sync" |
9 | 9 |
|
| 10 | + "github.com/entireio/cli/cmd/entire/cli/logging" |
10 | 11 | "github.com/go-git/go-git/v6/config" |
| 12 | + format "github.com/go-git/go-git/v6/plumbing/format/config" |
11 | 13 | "github.com/go-git/go-git/v6/x/plugin" |
12 | 14 | "github.com/go-git/x/plugin/objectsigner/auto" |
13 | 15 | "golang.org/x/crypto/ssh/agent" |
@@ -35,6 +37,17 @@ func RegisterObjectSigner() { |
35 | 37 | return nil |
36 | 38 | } |
37 | 39 |
|
| 40 | + // When a custom gpg.ssh.program is configured (e.g. 1Password's |
| 41 | + // op-ssh-sign), signing happens via an external binary that go-git |
| 42 | + // cannot invoke. Skip native signing silently — checkpoint commits |
| 43 | + // will be unsigned, which is acceptable since signing is best-effort. |
| 44 | + // The default program is "ssh-keygen", which works with go-git's |
| 45 | + // native SSH agent signing and does not need to be skipped. |
| 46 | + if auto.Format(merged.GPG.Format) == auto.FormatSSH && hasCustomSSHSignProgram(merged.Raw) { |
| 47 | + logging.Debug(context.Background(), "skipping native SSH commit signing: custom gpg.ssh.program is configured") |
| 48 | + return nil |
| 49 | + } |
| 50 | + |
38 | 51 | cfg := auto.Config{ |
39 | 52 | SigningKey: merged.User.SigningKey, |
40 | 53 | Format: auto.Format(merged.GPG.Format), |
@@ -74,6 +87,22 @@ var scopeName = map[config.Scope]string{ |
74 | 87 | config.SystemScope: "system", |
75 | 88 | } |
76 | 89 |
|
| 90 | +// hasCustomSSHSignProgram checks whether gpg.ssh.program is set to a |
| 91 | +// non-default value in the raw config. The git default is "ssh-keygen", |
| 92 | +// which works with go-git's native SSH agent signing. Custom programs |
| 93 | +// (e.g. 1Password's op-ssh-sign) use a separate signing mechanism that |
| 94 | +// go-git cannot invoke. |
| 95 | +// go-git's Config struct does not expose this field, so we read it directly. |
| 96 | +func hasCustomSSHSignProgram(raw *format.Config) bool { |
| 97 | + if raw == nil { |
| 98 | + return false |
| 99 | + } |
| 100 | + |
| 101 | + program := raw.Section("gpg").Subsection("ssh").Option("program") |
| 102 | + |
| 103 | + return program != "" && program != "ssh-keygen" |
| 104 | +} |
| 105 | + |
77 | 106 | func loadScopedConfig(source plugin.ConfigSource, scope config.Scope) *config.Config { |
78 | 107 | name := scopeName[scope] |
79 | 108 |
|
|
0 commit comments