144 lines
3.9 KiB
Go
144 lines
3.9 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"strings"
|
|
"time"
|
|
|
|
gha "github.com/sethvargo/go-githubactions"
|
|
)
|
|
|
|
func getShortHash() string {
|
|
// Get short git commit hash
|
|
gitCmd := exec.Command("git", "rev-parse", "--short", "HEAD")
|
|
gitCmd.Dir = "."
|
|
gitCmd.Stderr = os.Stderr
|
|
hashBytes, err := gitCmd.Output()
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "Failed to get git hash: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
shortHash := string(hashBytes)
|
|
shortHash = shortHash[:len(shortHash)-1] // remove trailing newline
|
|
return shortHash
|
|
}
|
|
|
|
func parseSecrets(secretsInput string) map[string]string {
|
|
secrets := make(map[string]string)
|
|
if secretsInput != "" {
|
|
scanner := bufio.NewScanner(strings.NewReader(secretsInput))
|
|
for scanner.Scan() {
|
|
line := strings.TrimSpace(scanner.Text())
|
|
if line == "" || strings.HasPrefix(line, "#") {
|
|
continue
|
|
}
|
|
parts := strings.SplitN(line, "=", 2)
|
|
if len(parts) == 2 {
|
|
key := strings.TrimSpace(parts[0])
|
|
val := strings.Trim(strings.TrimSpace(parts[1]), `"`)
|
|
secrets[key] = val
|
|
}
|
|
}
|
|
}
|
|
|
|
return secrets
|
|
|
|
}
|
|
|
|
func buildDockerCommand(context string, dockerFile string, secrets map[string]string, tagLatest string, tagNightly string) *exec.Cmd {
|
|
// Parse secrets and write to .secrets file
|
|
buildArgs := []string{}
|
|
if len(secrets) > 0 {
|
|
f, err := os.CreateTemp("", ".secrets")
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "Failed to create .secrets file: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
defer f.Close()
|
|
for secretKey, secretVal := range secrets {
|
|
_, err := fmt.Fprintf(f, "%s=%s\n", secretKey, secretVal)
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "Failed to write secret: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
buildArgs = append(buildArgs, "--secret", "id=build_secrets,src="+f.Name())
|
|
}
|
|
|
|
// Build command
|
|
buildArgsExpanded := append([]string{"build", context, "-f", dockerFile, "-t", tagLatest, "-t", tagNightly}, buildArgs...)
|
|
buildCmd := exec.Command("docker", buildArgsExpanded...)
|
|
buildCmd.Env = append(os.Environ(), "DOCKER_BUILDKIT=1")
|
|
buildCmd.Stdout = os.Stdout
|
|
buildCmd.Stderr = os.Stderr
|
|
return buildCmd
|
|
}
|
|
|
|
func pushDockerCommand(tag string) *exec.Cmd {
|
|
// Push nightly tag
|
|
pushNightlyCmd := exec.Command("docker", "push", tag)
|
|
pushNightlyCmd.Stdout = os.Stdout
|
|
pushNightlyCmd.Stderr = os.Stderr
|
|
return pushNightlyCmd
|
|
}
|
|
|
|
func main() {
|
|
basePath := gha.GetInput("path")
|
|
imageName := gha.GetInput("image-name")
|
|
dockerFile := gha.GetInput("dockerfile")
|
|
context := gha.GetInput("context")
|
|
secrets := parseSecrets(gha.GetInput("secrets"))
|
|
date := time.Now().Format("2006-01-02")
|
|
shortHash := getShortHash()
|
|
|
|
if basePath == "" {
|
|
fmt.Fprintln(os.Stderr, "Error: 'path' input is required")
|
|
os.Exit(1)
|
|
}
|
|
|
|
if imageName == "" {
|
|
fmt.Fprintln(os.Stderr, "Error: 'image-name' input is required")
|
|
os.Exit(1)
|
|
}
|
|
|
|
if basePath[len(basePath)-1] != '/' {
|
|
basePath += "/"
|
|
}
|
|
|
|
// Construct image names
|
|
imageBase := fmt.Sprintf("%s%s", basePath, imageName)
|
|
tagLatest := fmt.Sprintf("%s:latest", imageBase)
|
|
tagNightly := fmt.Sprintf("%s:nightly-%s.%s", imageBase, date, shortHash)
|
|
|
|
// Build Docker command
|
|
buildCmd := buildDockerCommand(context, dockerFile, secrets, tagLatest, tagNightly)
|
|
fmt.Println("Running:", buildCmd.String())
|
|
if err := buildCmd.Run(); err != nil {
|
|
fmt.Fprintf(os.Stderr, "Build failed: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
// Push nightly tag
|
|
pushNightlyCmd := pushDockerCommand(tagNightly)
|
|
fmt.Println("Running:", pushNightlyCmd.String())
|
|
if err := pushNightlyCmd.Run(); err != nil {
|
|
fmt.Fprintf(os.Stderr, "Push nightly failed: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
// Push latest tag
|
|
pushLatestCmd := pushDockerCommand(tagLatest)
|
|
fmt.Println("Running:", pushLatestCmd.String())
|
|
if err := pushLatestCmd.Run(); err != nil {
|
|
fmt.Fprintf(os.Stderr, "Push latest failed: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
gha.SetOutput("image_tag", fmt.Sprintf("%s:%s", imageBase, shortHash))
|
|
gha.SetOutput("full_image_name", tagLatest)
|
|
}
|