this repo has no description
1package activities
2
3import (
4 "context"
5 "crypto/sha256"
6 "fmt"
7 "os"
8 "os/exec"
9 "path/filepath"
10 "strings"
11
12 "go.temporal.io/sdk/activity"
13)
14
15func generateRepoPath(url string, revision string) string {
16 hash := sha256.Sum256([]byte(url + ":" + revision))
17 return filepath.Join("/tmp", "cloudlab-repos", fmt.Sprintf("%x", hash)[:16])
18}
19
20func hasCorrectRevision(ctx context.Context, path, revision string) bool {
21 if _, err := os.Stat(filepath.Join(path, ".git")); os.IsNotExist(err) {
22 return false
23 }
24
25 cmd := exec.CommandContext(ctx, "git", "rev-parse", revision)
26 cmd.Dir = path
27 return cmd.Run() == nil
28}
29
30func Clone(ctx context.Context, url string, revision string) (string, error) {
31 logger := activity.GetLogger(ctx)
32 path := generateRepoPath(url, revision)
33
34 if hasCorrectRevision(ctx, path, revision) {
35 logger.Info("Repository already available", "path", path)
36 return path, nil
37 }
38
39 if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
40 return "", fmt.Errorf("failed to create parent directory: %w", err)
41 }
42 os.RemoveAll(path)
43
44 logger.Info("Cloning repository", "url", url, "revision", revision)
45
46 cmd := exec.CommandContext(ctx, "git", "clone", "--depth", "1", "--branch", revision, url, path)
47 if err := cmd.Run(); err != nil {
48 os.RemoveAll(path)
49 return "", fmt.Errorf("failed to clone repository: %w", err)
50 }
51
52 return path, nil
53}
54
55func ChangedModules(ctx context.Context, repoPath string, oldRevision string) ([]string, error) {
56 logger := activity.GetLogger(ctx)
57
58 // Since we now clone with depth 1, we need to fetch the oldRevision before we can diff against it
59 logger.Info("Fetching old revision for comparison", "oldRevision", oldRevision)
60 fetchCmd := exec.CommandContext(ctx, "git", "fetch", "origin", oldRevision)
61 fetchCmd.Dir = repoPath
62 if err := fetchCmd.Run(); err != nil {
63 return nil, fmt.Errorf("failed to fetch old revision %s: %w", oldRevision, err)
64 }
65
66 cmd := exec.CommandContext(ctx, "git", "diff", "--name-only", oldRevision, "HEAD")
67 cmd.Dir = repoPath
68 output, err := cmd.Output()
69 if err != nil {
70 return nil, fmt.Errorf("failed to run git diff: %w", err)
71 }
72
73 seen := make(map[string]struct{})
74 var modules []string
75
76 for _, file := range strings.Fields(string(output)) {
77 if file == "" {
78 continue
79 }
80
81 for dir := filepath.Dir(file); dir != "." && dir != "/"; dir = filepath.Dir(dir) {
82 if _, err := os.Stat(filepath.Join(repoPath, dir, "terragrunt.hcl")); err == nil {
83 // Remove infra/stack prefix to get module path
84 if parts := strings.Split(filepath.ToSlash(dir), "/"); len(parts) >= 3 && parts[0] == "infra" {
85 if module := strings.Join(parts[2:], "/"); module != "" {
86 if _, exists := seen[module]; !exists {
87 modules = append(modules, module)
88 seen[module] = struct{}{}
89 }
90 }
91 }
92 break
93 }
94 }
95 }
96
97 return modules, nil
98}
99
100func GitAdd(ctx context.Context, path string) error {
101 logger := activity.GetLogger(ctx)
102
103 dir := filepath.Dir(path)
104 relPath := filepath.Base(path)
105
106 cmd := exec.Command("git", "-C", dir, "add", relPath)
107 cmd.Stdout = os.Stdout
108 cmd.Stderr = os.Stderr
109 if err := cmd.Run(); err != nil {
110 logger.Error("git add failed", "error", err)
111 return fmt.Errorf("git add failed: %w", err)
112 }
113
114 return nil
115}
116
117func GitCommit(ctx context.Context, dir string, message string) error {
118 logger := activity.GetLogger(ctx)
119
120 cmd := exec.Command("git", "-C", dir, "commit", "-m", message)
121 cmd.Stdout = os.Stdout
122 cmd.Stderr = os.Stderr
123 if err := cmd.Run(); err != nil {
124 logger.Error("git commit failed", "error", err)
125 return fmt.Errorf("git commit failed: %w", err)
126 }
127
128 return nil
129}
130
131func GitPush(ctx context.Context, dir string) error {
132 logger := activity.GetLogger(ctx)
133
134 cmd := exec.Command("git", "-C", dir, "push")
135 cmd.Stdout = os.Stdout
136 cmd.Stderr = os.Stderr
137 if err := cmd.Run(); err != nil {
138 logger.Error("git push failed", "error", err)
139 return fmt.Errorf("git push failed: %w", err)
140 }
141
142 return nil
143}