Monorepo for Tangled tangled.org
5

Configure Feed

Select the types of activity you want to include in your feed.

1package models 2 3import ( 4 "fmt" 5 "strings" 6 7 "tangled.org/core/api/tangled" 8 "tangled.org/core/hostutil" 9 "tangled.org/core/workflow" 10) 11 12type CloneStep struct { 13 name string 14 kind StepKind 15 commands []string 16} 17 18func (s CloneStep) Name() string { 19 return s.name 20} 21 22func (s CloneStep) Commands() []string { 23 return s.commands 24} 25 26func (s CloneStep) Command() string { 27 return strings.Join(s.commands, "\n") 28} 29 30func (s CloneStep) Kind() StepKind { 31 return s.kind 32} 33 34// BuildCloneStep generates git clone commands. 35// The caller must ensure the current working directory is set to the desired 36// workspace directory before executing these commands. 37// 38// The generated commands are: 39// - git init 40// - git remote add origin <url> 41// - git fetch --depth=<d> --recurse-submodules=<yes|no> <sha> 42// - git checkout FETCH_HEAD 43// 44// Supports all trigger types (push, PR, manual) and clone options. 45func BuildCloneStep(twf tangled.Pipeline_Workflow, tr tangled.Pipeline_TriggerMetadata, dev bool) CloneStep { 46 if twf.Clone != nil && twf.Clone.Skip { 47 return CloneStep{} 48 } 49 50 commitSHA, err := extractCommitSHA(tr) 51 if err != nil { 52 return CloneStep{ 53 kind: StepKindSystem, 54 name: "Clone repository into workspace (error)", 55 commands: []string{fmt.Sprintf("echo 'Failed to get clone info: %s' && exit 1", err.Error())}, 56 } 57 } 58 59 repoURL := BuildRepoURL(tr.Repo) 60 61 var cloneOpts tangled.Pipeline_CloneOpts 62 if twf.Clone != nil { 63 cloneOpts = *twf.Clone 64 } 65 fetchArgs := buildFetchArgs(cloneOpts, commitSHA) 66 67 // In dev mode we point at Caddy via host-gateway with a self-signed cert, 68 // so skip the TLS check for the fetch call. 69 fetchCmd := "git fetch" 70 if dev { 71 fetchCmd = "git -c http.sslVerify=false fetch" 72 } 73 74 return CloneStep{ 75 kind: StepKindSystem, 76 name: "Clone repository into workspace", 77 commands: []string{ 78 "git init", 79 fmt.Sprintf("git remote add origin %s", repoURL), 80 fmt.Sprintf("%s %s", fetchCmd, strings.Join(fetchArgs, " ")), 81 "git checkout FETCH_HEAD", 82 }, 83 } 84} 85 86// extractCommitSHA extracts the commit SHA from trigger metadata based on trigger type 87func extractCommitSHA(tr tangled.Pipeline_TriggerMetadata) (string, error) { 88 switch workflow.TriggerKind(tr.Kind) { 89 case workflow.TriggerKindPush: 90 if tr.Push == nil { 91 return "", fmt.Errorf("push trigger metadata is nil") 92 } 93 return tr.Push.NewSha, nil 94 95 case workflow.TriggerKindPullRequest: 96 if tr.PullRequest == nil { 97 return "", fmt.Errorf("pull request trigger metadata is nil") 98 } 99 return tr.PullRequest.SourceSha, nil 100 101 case workflow.TriggerKindManual: 102 // Manual triggers don't have an explicit SHA in the metadata 103 // For now, return empty string - could be enhanced to fetch from default branch 104 // TODO: Implement manual trigger SHA resolution (fetch default branch HEAD) 105 return "", nil 106 107 default: 108 return "", fmt.Errorf("unknown trigger kind: %s", tr.Kind) 109 } 110} 111 112// BuildRepoURL constructs the repository URL from repo metadata. 113func BuildRepoURL(repo *tangled.Pipeline_TriggerRepo) string { 114 if repo == nil { 115 return "" 116 } 117 118 host, noSSL, _ := hostutil.ParseHostname(repo.Knot) 119 scheme := "https" 120 if noSSL { 121 scheme = "http" 122 } 123 124 return fmt.Sprintf("%s://%s/%s", scheme, host, *repo.RepoDid) 125} 126 127// buildFetchArgs constructs the arguments for git fetch based on clone options 128func buildFetchArgs(clone tangled.Pipeline_CloneOpts, sha string) []string { 129 args := []string{} 130 131 // Set fetch depth (default to 1 for shallow clone) 132 depth := clone.Depth 133 if depth == 0 { 134 depth = 1 135 } 136 args = append(args, fmt.Sprintf("--depth=%d", depth)) 137 138 // Add submodules if requested 139 if clone.Submodules { 140 args = append(args, "--recurse-submodules=yes") 141 } 142 143 // Add remote and SHA 144 args = append(args, "origin") 145 if sha != "" { 146 args = append(args, sha) 147 } 148 149 return args 150}