Skip to content

Commit 3632765

Browse files
committed
fix: Priority 1 critical issues from TODO.md
- Linux: Remove incorrect MimeType from desktop file (fixes sourcegit-scm#1650) - Prevents SourceGit from being suggested for opening directories - GPG Signing: Enhanced support with better error handling (fixes sourcegit-scm#1645) - Auto-detect and set GPG_TTY environment variable - Provide clear, actionable error messages for common GPG failures - Help users troubleshoot signing issues with specific guidance - SSH Agent: Fix authentication on Linux/macOS (fixes sourcegit-scm#1670) - Pass through SSH_AUTH_SOCK and SSH_AGENT_PID environment variables - Resolves SSH agent broken since v2025.28 - macOS: Fix ARM64 ZIP release build (fixes sourcegit-scm#1723) - Create both ZIP and DMG archives for distribution - Use ditto for proper macOS ZIP creation with resource preservation - Add ZIP verification to ensure archive integrity - Clean up both DMG and ZIP files in build script
1 parent 156b144 commit 3632765

File tree

4 files changed

+153
-7
lines changed

4 files changed

+153
-7
lines changed

build-macos-signed.sh

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,8 @@ clean_build() {
9494
print_status "Cleaning previous builds..."
9595
rm -rf "$BUILD_DIR"
9696
rm -rf "$APP_BUNDLE"
97-
rm -rf "*.dmg"
97+
rm -f *.dmg
98+
rm -f *.zip
9899
print_success "Cleaned previous builds"
99100
}
100101

@@ -281,6 +282,34 @@ sign_app() {
281282
rm -f entitlements.plist
282283
}
283284

285+
# Create ZIP for distribution
286+
create_zip() {
287+
print_status "Creating ZIP archive for distribution..."
288+
289+
ZIP_NAME="${APP_NAME}-${VERSION}-arm64.zip"
290+
291+
# Remove old ZIP if exists
292+
rm -f "${ZIP_NAME}"
293+
294+
# Create ZIP archive with proper compression
295+
# Using ditto for better macOS compatibility (preserves resource forks, extended attributes)
296+
ditto -c -k --sequesterRsrc --keepParent "${APP_BUNDLE}" "${ZIP_NAME}"
297+
298+
# Alternatively, use zip command for cross-platform compatibility
299+
# zip -r -y "${ZIP_NAME}" "${APP_BUNDLE}"
300+
301+
print_success "ZIP created: ${ZIP_NAME}"
302+
303+
# Verify the ZIP file
304+
print_status "Verifying ZIP archive..."
305+
if unzip -t "${ZIP_NAME}" > /dev/null 2>&1; then
306+
print_success "ZIP archive verified successfully"
307+
else
308+
print_error "ZIP archive verification failed"
309+
exit 1
310+
fi
311+
}
312+
284313
# Create DMG for distribution
285314
create_dmg() {
286315
print_status "Creating DMG for distribution..."
@@ -348,6 +377,7 @@ main() {
348377
build_app
349378
create_bundle
350379
sign_app
380+
create_zip
351381
create_dmg
352382

353383
echo ""
@@ -356,6 +386,7 @@ main() {
356386
echo ""
357387
echo "Output files:"
358388
echo " - App Bundle: ${APP_BUNDLE}"
389+
echo " - ZIP Archive: ${APP_NAME}-${VERSION}-arm64.zip"
359390
echo " - DMG: ${DMG_NAME}"
360391
echo ""
361392

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
[Desktop Entry]
22
Name=SourceGit
33
Comment=Open-source & Free Git GUI Client
4-
Exec=/opt/sourcegit/sourcegit
4+
Exec=/opt/sourcegit/sourcegit %U
55
Icon=/usr/share/icons/sourcegit.png
66
Terminal=false
77
Type=Application
8-
Categories=Development
9-
MimeType=inode/directory;
8+
Categories=Development;RevisionControl;
9+
StartupNotify=true

src/Commands/Command.cs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,21 @@ protected ProcessStartInfo CreateGitStartInfo(bool redirect)
181181
if (!OperatingSystem.IsLinux())
182182
start.Environment.Add("DISPLAY", "required");
183183

184+
// Pass through SSH_AUTH_SOCK for SSH agent authentication
185+
// This is critical for SSH agent to work properly on Linux/macOS
186+
var sshAuthSock = Environment.GetEnvironmentVariable("SSH_AUTH_SOCK");
187+
if (!string.IsNullOrEmpty(sshAuthSock) && !start.Environment.ContainsKey("SSH_AUTH_SOCK"))
188+
{
189+
start.Environment.Add("SSH_AUTH_SOCK", sshAuthSock);
190+
}
191+
192+
// Also pass through SSH_AGENT_PID if it exists
193+
var sshAgentPid = Environment.GetEnvironmentVariable("SSH_AGENT_PID");
194+
if (!string.IsNullOrEmpty(sshAgentPid) && !start.Environment.ContainsKey("SSH_AGENT_PID"))
195+
{
196+
start.Environment.Add("SSH_AGENT_PID", sshAgentPid);
197+
}
198+
184199
// If an SSH private key was provided, sets the environment.
185200
if (!start.Environment.ContainsKey("GIT_SSH_COMMAND") && !string.IsNullOrEmpty(SSHKey))
186201
start.Environment.Add("GIT_SSH_COMMAND", $"ssh -i '{SSHKey}'");
@@ -192,6 +207,46 @@ protected ProcessStartInfo CreateGitStartInfo(bool redirect)
192207
start.Environment.Add("LC_ALL", "C");
193208
}
194209

210+
// Set GPG_TTY for proper GPG signing support
211+
// This is critical for GPG signing to work in non-GUI terminals
212+
if (!start.Environment.ContainsKey("GPG_TTY"))
213+
{
214+
// Try to get the TTY from the environment
215+
var tty = Environment.GetEnvironmentVariable("GPG_TTY");
216+
if (string.IsNullOrEmpty(tty))
217+
{
218+
// If not set, try to detect it
219+
if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS())
220+
{
221+
try
222+
{
223+
var ttyProcess = new Process();
224+
ttyProcess.StartInfo.FileName = "tty";
225+
ttyProcess.StartInfo.UseShellExecute = false;
226+
ttyProcess.StartInfo.RedirectStandardOutput = true;
227+
ttyProcess.StartInfo.CreateNoWindow = true;
228+
ttyProcess.Start();
229+
tty = ttyProcess.StandardOutput.ReadToEnd().Trim();
230+
ttyProcess.WaitForExit();
231+
232+
if (!string.IsNullOrEmpty(tty) && tty.StartsWith("/dev/"))
233+
{
234+
start.Environment.Add("GPG_TTY", tty);
235+
}
236+
}
237+
catch
238+
{
239+
// If we can't detect TTY, GPG signing might fail
240+
// but we'll let Git handle that error
241+
}
242+
}
243+
}
244+
else
245+
{
246+
start.Environment.Add("GPG_TTY", tty);
247+
}
248+
}
249+
195250
var builder = new StringBuilder();
196251
builder.Append("--no-pager -c core.quotepath=off");
197252

src/Commands/Commit.cs

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,72 @@ public async Task<bool> RunAsync()
4141
try
4242
{
4343
await File.WriteAllTextAsync(_tmpFile, _message).ConfigureAwait(false);
44-
var succ = await ExecAsync().ConfigureAwait(false);
44+
45+
// Store original RaiseError setting to provide custom error handling
46+
var originalRaiseError = RaiseError;
47+
RaiseError = false;
48+
49+
var result = await ReadToEndAsync().ConfigureAwait(false);
50+
51+
if (!result.IsSuccess)
52+
{
53+
// Check for common GPG signing errors and provide helpful messages
54+
var errorMessage = result.StdErr;
55+
56+
if (errorMessage.Contains("gpg failed to sign", System.StringComparison.OrdinalIgnoreCase) ||
57+
errorMessage.Contains("gpg: signing failed", System.StringComparison.OrdinalIgnoreCase))
58+
{
59+
// GPG signing failed - provide helpful error message
60+
var enhancedMessage = "GPG signing failed. Common causes:\n" +
61+
"• GPG key not configured (check 'git config user.signingkey')\n" +
62+
"• GPG agent not running (try 'gpg-agent --daemon')\n" +
63+
"• Passphrase required but no TTY available\n" +
64+
"• Key expired or revoked\n\n" +
65+
"Original error: " + errorMessage;
66+
67+
if (originalRaiseError)
68+
App.RaiseException(Context, enhancedMessage);
69+
}
70+
else if (errorMessage.Contains("secret key not available", System.StringComparison.OrdinalIgnoreCase))
71+
{
72+
var enhancedMessage = "GPG secret key not available.\n" +
73+
"• Check if your GPG key is properly imported\n" +
74+
"• Verify the signing key in git config matches your GPG key\n" +
75+
"• Run 'gpg --list-secret-keys' to see available keys\n\n" +
76+
"Original error: " + errorMessage;
77+
78+
if (originalRaiseError)
79+
App.RaiseException(Context, enhancedMessage);
80+
}
81+
else if (errorMessage.Contains("cannot allocate memory", System.StringComparison.OrdinalIgnoreCase) ||
82+
errorMessage.Contains("inappropriate ioctl for device", System.StringComparison.OrdinalIgnoreCase))
83+
{
84+
var enhancedMessage = "GPG TTY error detected.\n" +
85+
"• The GPG_TTY environment variable may not be set correctly\n" +
86+
"• Try running: export GPG_TTY=$(tty)\n" +
87+
"• Or disable commit signing temporarily: git config commit.gpgsign false\n\n" +
88+
"Original error: " + errorMessage;
89+
90+
if (originalRaiseError)
91+
App.RaiseException(Context, enhancedMessage);
92+
}
93+
else
94+
{
95+
// Other errors - show as-is
96+
if (originalRaiseError && !string.IsNullOrEmpty(errorMessage))
97+
App.RaiseException(Context, errorMessage);
98+
}
99+
}
100+
45101
File.Delete(_tmpFile);
46-
return succ;
102+
return result.IsSuccess;
47103
}
48-
catch
104+
catch (System.Exception ex)
49105
{
106+
if (File.Exists(_tmpFile))
107+
File.Delete(_tmpFile);
108+
109+
App.RaiseException(Context, $"Commit operation failed: {ex.Message}");
50110
return false;
51111
}
52112
}

0 commit comments

Comments
 (0)