package main import ( "flag" "fmt" "os" "strings" "text/template" "github.com/Masterminds/sprig" "github.com/drone/drone-go/drone" "golang.org/x/oauth2" ) const secretEnvPrefix = "DRONE_SECRET_" func main() { tplpath := flag.String("t", "template.yml", "Template file") outpath := flag.String("o", ".drone.yml", "Output .drone.yml") flag.Parse() // Get drone server and token server := os.Getenv("DRONE_SERVER") if server == "" { fatal("DRONE_SERVER missing or empty") } token := os.Getenv("DRONE_TOKEN") if token == "" { fatal("DRONE_TOKEN missing or empty") } // Authenticate and connect to drone.io server config := new(oauth2.Config) auther := config.Client( oauth2.NoContext, &oauth2.Token{ AccessToken: token, }, ) client := drone.NewClient(server, auther) user, err := client.Self() if err != nil { fatal("Connection to drone.io failed: %s", err.Error()) } // Get project projectname := flag.Arg(0) if projectname == "" { fatal("Repository name missing or empty") } parts := strings.SplitN(projectname, "/", 2) if len(parts) < 2 { parts = []string{user.Login, projectname} } namespace := parts[0] reponame := parts[1] // Enable repository on Drone.io repo, err := client.RepoEnable(namespace, reponame) if err != nil { fatal("Error enabling repository %s/%s: %s", namespace, reponame, err.Error()) } // Get secrets for _, env := range os.Environ() { // Check for the magic prefix if !strings.HasPrefix(env, secretEnvPrefix) { continue } // Split key=val parts := strings.SplitN(env, "=", 2) // Ignore weird values if len(parts) < 2 { continue } secretName := strings.ToLower(parts[0][len(secretEnvPrefix):]) secretValue := parts[1] tpl, err := template.New("secret-" + secretName).Funcs(sprig.TxtFuncMap()).Parse(secretValue) if err != nil { fatal("Secret %s is an invalid template: %s", parts[0], err.Error()) } var builder strings.Builder err = tpl.Execute(&builder, repo) if err != nil { fatal("Error while building secret %s: %s", secretName, err.Error()) } // Add secret to project client.SecretCreate(repo.Namespace, repo.Name, &drone.Secret{ Name: secretName, Data: builder.String(), }) } // Read template file tpl, err := template.ParseFiles(*tplpath) if err != nil { fatal("Cannot read template file: %s", err.Error()) } // Add sprig functions tpl = tpl.Funcs(sprig.TxtFuncMap()) // Create output file outfile, err := os.Create(*outpath) if err != nil { fatal("Cannot create output file: %s", err.Error()) } defer outfile.Close() // Generate output from template err = tpl.Execute(outfile, repo) if err != nil { fatal("Error processing template: %s", err.Error()) } } func fatal(msg string, args ...interface{}) { fmt.Fprintf(os.Stderr, "FATAL: "+msg+"\n", args...) os.Exit(1) }