fix(git): handle Git redirects and improve URL parsing for tangled.sh and other Git hosts

Fixes deployment failures when Git repositories redirect (e.g., tangled.sh → tangled.org)
and improves security by adding proper shell escaping for repository URLs.

**Root Cause:**
Git redirect warnings can appear on the same line as ls-remote output with no newline:
`warning: redirecting to https://tangled.org/...196d3df...	refs/heads/master`

The previous parsing logic split by newlines and extracted text before tabs, which
included the entire warning message instead of just the 40-character commit SHA.

**Changes:**

1. **Fixed commit SHA extraction** (ApplicationDeploymentJob.php):
   - Changed from line-based parsing to regex pattern matching
   - Uses `/([0-9a-f]{40})\s*\t/` to find valid 40-char hex commit SHA before tab
   - Handles warnings on same line, separate lines, multiple warnings, and whitespace
   - Added comprehensive Ray debug logs for troubleshooting

2. **Added security fix** (Application.php):
   - Added `escapeshellarg()` for repository URLs in 'other' deployment type
   - Prevents shell injection and fixes parsing issues with special characters like `@`
   - Added Ray debug logs for deployment type tracking

3. **Comprehensive test coverage** (GitLsRemoteParsingTest.php):
   - Tests normal output without warnings
   - Tests redirect warning on separate line
   - Tests redirect warning on same line (actual tangled.sh format)
   - Tests multiple warning lines
   - Tests extra whitespace handling

**Resolves:**
- Linear issue COOLGH-53: Valid git URLs are rejected as being invalid
- GitHub issue #6568: tangled.sh deployments failing
- Handles Git redirects universally for all Git hosting services

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Andras Bacsai
2025-10-14 11:55:17 +02:00
parent 2aef2c383c
commit bf00405971
3 changed files with 72 additions and 4 deletions

View File

@@ -1892,9 +1892,27 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
);
}
if ($this->saved_outputs->get('git_commit_sha') && ! $this->rollback) {
$this->commit = $this->saved_outputs->get('git_commit_sha')->before("\t");
$this->application_deployment_queue->commit = $this->commit;
$this->application_deployment_queue->save();
// Extract commit SHA from git ls-remote output, handling multi-line output (e.g., redirect warnings)
// Expected format: "commit_sha\trefs/heads/branch" possibly preceded by warning lines
// Note: Git warnings can be on the same line as the result (no newline)
$lsRemoteOutput = $this->saved_outputs->get('git_commit_sha');
// Find the part containing a tab (the actual ls-remote result)
// Handle cases where warning is on the same line as the result
if ($lsRemoteOutput->contains("\t")) {
// Get everything from the last occurrence of a valid commit SHA pattern before the tab
// A valid commit SHA is 40 hex characters
$output = $lsRemoteOutput->value();
// Extract the line with the tab (actual ls-remote result)
preg_match('/([0-9a-f]{40})\s*\t/', $output, $matches);
if (isset($matches[1])) {
$this->commit = $matches[1];
$this->application_deployment_queue->commit = $this->commit;
$this->application_deployment_queue->save();
}
}
}
$this->set_coolify_variables();