Something went wrong. Try again.
Pull-based GitOps-style Docker Compose deployer: polls a (private) Git repo, detects changed stacks and reconciles only the affected
Something went wrong. Try again.
2.5 kB · 96 lines
Go
at main
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697package core
import ( "fmt" "os" "os/exec" "strings")
func PullAndDetectChanges(repoPath, branch string) ([]string, error) { if err := ensureGitRepository(repoPath); err != nil { return nil, err }
prevHead, err := getGitHead(repoPath) if err != nil { return nil, fmt.Errorf("failed to get previous HEAD: %w", err) }
if err := gitFetchPull(repoPath, branch); err != nil { return nil, fmt.Errorf("failed to pull: %w", err) }
newHead, err := getGitHead(repoPath) if err != nil { return nil, fmt.Errorf("failed to get new HEAD: %w", err) } if prevHead == newHead { return []string{}, nil }
output, err := gitCommand(repoPath, "diff", "--name-only", prevHead, newHead) if err != nil { return nil, fmt.Errorf("failed to get changed files: %w", err) } changedFiles := strings.Split(strings.TrimSpace(string(output)), "\n") return changedFiles, nil}
/** * Git helper functions */
func gitCommand(repoPath string, args ...string) ([]byte, error) { cmd := exec.Command("git", args...) cmd.Dir = repoPath return cmd.Output()}
func detectCurrentBranch(repoPath string) string { output, err := gitCommand(repoPath, "rev-parse", "--abbrev-ref", "HEAD") if err != nil { return "" } return strings.TrimSpace(string(output))}
func ensureGitRepository(repoPath string) error { if _, err := os.Stat(repoPath); os.IsNotExist(err) { return fmt.Errorf("repository path does not exist: %s", repoPath) }
if _, err := os.Stat(fmt.Sprintf("%s/.git", repoPath)); os.IsNotExist(err) { return fmt.Errorf("path is not a git repository: %s", repoPath) } return nil}
func gitFetchPull(repoPath, branch string) error { if _, err := gitCommand(repoPath, "fetch", "origin", branch); err != nil { return fmt.Errorf("git fetch failed: %w", err) }
currentBranch, _ := gitCommand(repoPath, "rev-parse", "--abbrev-ref", "HEAD") if strings.TrimSpace(string(currentBranch)) != branch { if _, err := gitCommand(repoPath, "checkout", branch); err != nil { return fmt.Errorf("git checkout failed: %w", err) } }
cmd := exec.Command("git", "pull", "origin", branch) cmd.Dir = repoPath output, err := cmd.CombinedOutput() if err != nil { return fmt.Errorf("git pull failed: %s, %w", string(output), err) } return nil}
func getGitHead(repoPath string) (string, error) { output, err := gitCommand(repoPath, "rev-parse", "HEAD") if err != nil { return "", fmt.Errorf("failed to get HEAD: %w", err) } return strings.TrimSpace(string(output)), nil}