feat: support private git repositories with token auth

- Entity: added gitToken and gitBranch columns to Application
- DTO: added gitToken and gitBranch fields to Create/Update DTOs
- Build pipeline: git-clone init container now injects token into
  HTTPS URL for private repo authentication (GitHub PAT, GitLab token, etc.)
- Build pipeline: supports cloning specific branch (default: main)
- Frontend deploy page: added Access Token (password field) and Branch
  inputs when Git Repository source is selected
- Frontend deploy page: Review step shows branch and token status
- Frontend app detail: shows branch badge and 🔑 Private indicator
  when git credentials are configured
- Works with: GitHub, GitLab, Bitbucket, any HTTPS-based git host
This commit is contained in:
keyhan
2026-04-05 16:48:35 +03:30
parent a7ef4649e5
commit 1b1ccfc18f
6 changed files with 116 additions and 9 deletions
@@ -453,6 +453,18 @@ export default function AppDetailPage() {
<div>
<p className="text-sm font-medium text-blue-800">Git repository connected</p>
<p className="text-xs text-blue-600 font-mono">{app.gitUrl}</p>
<div className="flex items-center space-x-3 mt-1">
{app.gitBranch && (
<span className="text-xs text-blue-500">
🌿 {app.gitBranch}
</span>
)}
{app.gitToken && (
<span className="text-xs text-green-600">
🔑 Private
</span>
)}
</div>
</div>
</div>
</div>
+50 -7
View File
@@ -18,6 +18,8 @@ export default function DeployPage() {
runtime: 'nodejs',
databaseType: 'none',
gitUrl: '',
gitToken: '',
gitBranch: '',
envVars: {},
cpuRequest: '100m',
cpuLimit: '500m',
@@ -207,13 +209,42 @@ export default function DeployPage() {
</div>
{sourceMethod === 'git' ? (
<div>
<input
className="input-field"
placeholder="https://github.com/user/repo.git"
value={form.gitUrl}
onChange={(e) => setForm({ ...form, gitUrl: e.target.value })}
/>
<div className="space-y-3">
<div>
<label className="block text-xs text-gray-500 mb-1">Repository URL</label>
<input
className="input-field"
placeholder="https://github.com/user/repo.git"
value={form.gitUrl}
onChange={(e) => setForm({ ...form, gitUrl: e.target.value })}
/>
</div>
<div>
<label className="block text-xs text-gray-500 mb-1">
Access Token <span className="text-gray-400">(for private repos)</span>
</label>
<input
className="input-field"
type="password"
placeholder="ghp_xxxxxxxxxxxx or glpat-xxxxxxxxxxxx"
value={form.gitToken || ''}
onChange={(e) => setForm({ ...form, gitToken: e.target.value })}
/>
<p className="mt-1 text-xs text-gray-400">
GitHub: Personal Access Token · GitLab: Project Access Token · Leave empty for public repos
</p>
</div>
<div>
<label className="block text-xs text-gray-500 mb-1">
Branch <span className="text-gray-400">(default: main)</span>
</label>
<input
className="input-field"
placeholder="main"
value={form.gitBranch || ''}
onChange={(e) => setForm({ ...form, gitBranch: e.target.value })}
/>
</div>
</div>
) : (
<div>
@@ -454,6 +485,18 @@ export default function DeployPage() {
: form.gitUrl || '—'}
</span>
</div>
{sourceMethod === 'git' && form.gitBranch && (
<div className="flex justify-between">
<span className="text-sm text-gray-500">Branch</span>
<span className="text-sm font-medium">{form.gitBranch}</span>
</div>
)}
{sourceMethod === 'git' && form.gitToken && (
<div className="flex justify-between">
<span className="text-sm text-gray-500">Auth</span>
<span className="text-sm font-medium text-green-600">🔑 Token provided</span>
</div>
)}
<div className="flex justify-between">
<span className="text-sm text-gray-500">CPU</span>
<span className="text-sm font-medium">{form.cpuRequest} / {form.cpuLimit}</span>
+4
View File
@@ -16,6 +16,8 @@ export interface Application {
runtime: 'nodejs' | 'laravel';
databaseType: 'mysql' | 'postgresql' | 'none';
gitUrl?: string;
gitToken?: string;
gitBranch?: string;
codePath?: string;
envVars?: Record<string, string>;
cpuRequest: string;
@@ -84,6 +86,8 @@ export interface CreateApplicationDto {
runtime: 'nodejs' | 'laravel';
databaseType: 'mysql' | 'postgresql' | 'none';
gitUrl?: string;
gitToken?: string;
gitBranch?: string;
envVars?: Record<string, string>;
cpuRequest?: string;
cpuLimit?: string;