actions/checkout-go/main.go
2025-04-14 14:22:37 +03:00

178 lines
4.2 KiB
Go

package main
import (
"fmt"
"log"
"os"
"os/exec"
"strings"
)
type Config struct {
Repository string
Ref string
Token string
Path string
ServerURL string
CheckoutType CheckoutType
FetchDepth string
Clean bool
LFS bool
FetchTags bool
Progress bool
SetSafeDirectory bool
}
// todo?? filter, sparse-checkout, sparse-checkout-cone-mode, submodules
type CheckoutType string
const (
HttpsType = "https"
SshType = "ssh"
)
func getConfig() Config {
fetchDepth := os.Getenv("INPUT_FETCHDEPTH")
if fetchDepth == "" || fetchDepth == "0" {
fetchDepth = "1"
}
clean := os.Getenv("INPUT_CLEAN")
cleanBool := true
if clean == "0" || clean == "false" || clean == "f" {
cleanBool = false
}
lfs := os.Getenv("INPUT_LFS")
lfsBool := false
if lfs == "1" || lfs == "true" || lfs == "t" {
lfsBool = true
}
fetchTags := os.Getenv("INPUT_FETCHTAGS")
fetchTagsBool := false
if fetchTags == "1" || fetchTags == "true" || fetchTags == "t" {
fetchTagsBool = true
}
progress := os.Getenv("INPUT_PROGRESS")
progressBool := false
if progress == "1" || progress == "true" || progress == "t" {
progressBool = true
}
setSafeDirectory := os.Getenv("INPUT_SETSAFEDIRECTORY")
setSafeDirectoryBool := true
if setSafeDirectory == "0" || setSafeDirectory == "false" || setSafeDirectory == "f" {
setSafeDirectoryBool = false
}
return Config{
Repository: os.Getenv("INPUT_REPOSITORY"),
Ref: os.Getenv("INPUT_REF"),
Token: os.Getenv("INPUT_TOKEN"),
Path: os.Getenv("INPUT_PATH"),
ServerURL: os.Getenv("INPUT_SERVERURL"),
CheckoutType: CheckoutType(os.Getenv("INPUT_CHECKOUTTYPE")),
FetchDepth: fetchDepth,
Clean: cleanBool,
LFS: lfsBool,
FetchTags: fetchTagsBool,
Progress: progressBool,
SetSafeDirectory: setSafeDirectoryBool,
}
}
func main() {
cfg := getConfig()
if cfg.Repository == "" {
log.Fatal("field repository is required")
}
if cfg.Token == "" {
log.Fatal("field token is required")
}
fmt.Println(cfg.Token)
if cfg.ServerURL == "" {
log.Fatal("field serverURL is required")
}
if cfg.SetSafeDirectory {
run("git", "config", "--global", "--add", "safe.directory", cfg.Path)
}
if cfg.Clean {
if _, err := os.Stat(cfg.Path); err == nil {
run("git", "-C", cfg.Path, "clean", "-ffdx")
run("git", "-C", cfg.Path, "reset", "--hard", "HEAD")
} else {
log.Println(fmt.Sprintf("not path-%s directory for cleaning", cfg.Path))
}
}
cloneURL := cfg.CheckoutType.GenerateCloneURL(cfg)
fmt.Println("Cloning", cloneURL, "into", cfg.Path)
cloneArgs := []string{"clone"}
if cfg.FetchTags {
cloneArgs = append(cloneArgs, "--tags")
}
if cfg.Progress {
cloneArgs = append(cloneArgs, "--progress")
}
cloneArgs = append(cloneArgs, fmt.Sprintf("--depth=%s", cfg.FetchDepth), cloneURL, cfg.Path)
run("git", cloneArgs...)
if cfg.Ref != "" {
fmt.Println("Checking out", cfg.Ref)
fetchArgs := []string{"-C", cfg.Path, "fetch"}
if cfg.FetchTags {
fetchArgs = append(fetchArgs, "--tags")
}
if cfg.Progress {
fetchArgs = append(fetchArgs, "--progress")
}
fetchArgs = append(fetchArgs, fmt.Sprintf("--depth=%s", cfg.FetchDepth), "origin", cfg.Ref)
run("git", fetchArgs...)
run("git", "-C", cfg.Path, "checkout", "FETCH_HEAD")
}
if cfg.LFS {
run("git", "-C", cfg.Path, "lfs", "install", "--local")
run("git", "-C", cfg.Path, "lfs", "pull")
}
}
func run(name string, args ...string) {
fmt.Println("git command: ", name, strings.Join(args, " "))
cmd := exec.Command(name, args...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
log.Fatalf("Command failed: %s %s Error: %v", name, strings.Join(args, " "), err)
}
}
func (t CheckoutType) GenerateCloneURL(cfg Config) string {
switch t {
case HttpsType:
return fmt.Sprintf("https://x-access-token:%s@%s/%s.git", cfg.Token,
strings.TrimPrefix(cfg.ServerURL, "https://"), cfg.Repository,
)
case SshType:
return fmt.Sprintf("git@%s:%s.git",
strings.TrimPrefix(cfg.ServerURL, "git@"),
cfg.Repository,
)
default:
log.Fatalf("Unknown checkout type: %s", t)
return ""
}
}