make deploy and promote ENVs consistent

This commit is contained in:
AJ ONeal 2020-11-30 17:49:20 -07:00
parent c3cd41a24f
commit d1631b04b5
1 changed files with 71 additions and 57 deletions

View File

@ -55,6 +55,19 @@ func init() {
log.Printf("TEMP_DIR=%s", tmpDir) log.Printf("TEMP_DIR=%s", tmpDir)
} }
// ReposResponse is the successful response to /api/repos
type ReposResponse struct {
Success bool `json:"success"`
Repos []Repo `json:"repos"`
}
// Repo is one of the elements of /api/repos
type Repo struct {
ID string `json:"id"`
CloneURL string `json:"clone_url"`
Promotions []string `json:"_promotions"`
}
// Route will set up the API and such // Route will set up the API and such
func Route(r chi.Router, runOpts *options.ServerConfig) { func Route(r chi.Router, runOpts *options.ServerConfig) {
@ -74,6 +87,7 @@ func Route(r chi.Router, runOpts *options.ServerConfig) {
webhooks.RouteHandlers(r) webhooks.RouteHandlers(r)
r.Route("/api/admin", func(r chi.Router) { r.Route("/api/admin", func(r chi.Router) {
r.Use(func(next http.Handler) http.Handler { r.Use(func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// r.Body is always .Close()ed by Go's http server // r.Body is always .Close()ed by Go's http server
@ -126,6 +140,7 @@ func Route(r chi.Router, runOpts *options.ServerConfig) {
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
w.Write(append(b, '\n')) w.Write(append(b, '\n'))
}) })
r.Get("/jobs", func(w http.ResponseWriter, r *http.Request) { r.Get("/jobs", func(w http.ResponseWriter, r *http.Request) {
// again, possible race condition, but not one that much matters // again, possible race condition, but not one that much matters
jjobs := []Job{} jjobs := []Job{}
@ -145,6 +160,7 @@ func Route(r chi.Router, runOpts *options.ServerConfig) {
}) })
w.Write(append(b, '\n')) w.Write(append(b, '\n'))
}) })
r.Post("/jobs", func(w http.ResponseWriter, r *http.Request) { r.Post("/jobs", func(w http.ResponseWriter, r *http.Request) {
defer func() { defer func() {
_ = r.Body.Close() _ = r.Body.Close()
@ -220,9 +236,16 @@ func Route(r chi.Router, runOpts *options.ServerConfig) {
func runHook(hook webhooks.Ref, runOpts *options.ServerConfig) { func runHook(hook webhooks.Ref, runOpts *options.ServerConfig) {
fmt.Printf("%#v\n", hook) fmt.Printf("%#v\n", hook)
jobID := base64.RawURLEncoding.EncodeToString([]byte( jobID := base64.RawURLEncoding.EncodeToString([]byte(
fmt.Sprintf("%s#%s", hook.HTTPSURL, hook.RefName), fmt.Sprintf("%s#%s", hook.HTTPSURL, hook.RefName),
)) ))
repoID := getRepoID(hook.HTTPSURL)
jobName := fmt.Sprintf("%s#%s", strings.ReplaceAll(repoID, "/", "-"), hook.RefName)
env := os.Environ()
envs := getEnvs(jobID, runOpts.RepoList, hook)
envs = append(envs, "GIT_DEPLOY_JOB_ID="+jobID)
args := []string{ args := []string{
runOpts.ScriptsPath + "/deploy.sh", runOpts.ScriptsPath + "/deploy.sh",
@ -234,45 +257,6 @@ func runHook(hook webhooks.Ref, runOpts *options.ServerConfig) {
hook.HTTPSURL, hook.HTTPSURL,
} }
cmd := exec.Command("bash", args...) cmd := exec.Command("bash", args...)
// https://git.example.com/example/project.git
// => git.example.com/example/project
repoID := strings.TrimPrefix(hook.HTTPSURL, "https://")
repoID = strings.TrimPrefix(repoID, "https://")
repoID = strings.TrimSuffix(repoID, ".git")
jobName := fmt.Sprintf("%s#%s", strings.ReplaceAll(repoID, "/", "-"), hook.RefName)
env := os.Environ()
envs := []string{
"GIT_DEPLOY_JOB_ID=" + jobID,
"GIT_REF_NAME=" + hook.RefName,
"GIT_REF_TYPE=" + hook.RefType,
"GIT_REPO_ID=" + repoID,
"GIT_REPO_OWNER=" + hook.Owner,
"GIT_REPO_NAME=" + hook.Repo,
"GIT_CLONE_URL=" + hook.HTTPSURL, // deprecated
"GIT_HTTPS_URL=" + hook.HTTPSURL,
"GIT_SSH_URL=" + hook.SSHURL,
}
for _, repo := range strings.Fields(runOpts.RepoList) {
last := len(repo) - 1
if len(repo) < 0 {
continue
}
repoID = strings.ToLower(repoID)
if '*' == repo[last] {
// Wildcard match a prefix, for example:
// github.com/whatever/* MATCHES github.com/whatever/foo
// github.com/whatever/ProjectX-* MATCHES github.com/whatever/ProjectX-Foo
if strings.HasPrefix(repoID, repo[:last]) {
envs = append(envs, "GIT_REPO_TRUSTED=true")
break
}
} else if repo == repoID {
envs = append(envs, "GIT_REPO_TRUSTED=true")
break
}
}
cmd.Env = append(env, envs...) cmd.Env = append(env, envs...)
cmd.Stdout = os.Stdout cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr cmd.Stderr = os.Stderr
@ -346,15 +330,8 @@ func runPromote(hook webhooks.Ref, promoteTo string, runOpts *options.ServerConf
cmd := exec.Command("bash", args...) cmd := exec.Command("bash", args...)
env := os.Environ() env := os.Environ()
envs := []string{ envs := getEnvs(jobID1, runOpts.RepoList, hook)
"GIT_DEPLOY_JOB_ID=" + jobID1, envs = append(envs, "GIT_DEPLOY_PROMOTE_TO="+promoteTo)
"GIT_DEPLOY_PROMOTE_TO=" + promoteTo,
"GIT_REF_NAME=" + hook.RefName,
"GIT_REF_TYPE=" + hook.RefType,
"GIT_REPO_OWNER=" + hook.Owner,
"GIT_REPO_NAME=" + hook.Repo,
"GIT_CLONE_URL=" + hook.HTTPSURL,
}
cmd.Env = append(env, envs...) cmd.Env = append(env, envs...)
cmd.Stdout = os.Stdout cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr cmd.Stderr = os.Stderr
@ -443,15 +420,52 @@ func restoreBacklog(jobName, jobID string) {
webhooks.Hook(ref) webhooks.Hook(ref)
} }
// ReposResponse is the successful response to /api/repos // https://git.example.com/example/project.git
type ReposResponse struct { // => git.example.com/example/project
Success bool `json:"success"` func getRepoID(httpsURL string) string {
Repos []Repo `json:"repos"` repoID := strings.TrimPrefix(httpsURL, "https://")
repoID = strings.TrimPrefix(repoID, "https://")
repoID = strings.TrimSuffix(repoID, ".git")
return repoID
} }
// Repo is one of the elements of /api/repos func getEnvs(jobID string, repoList string, hook webhooks.Ref) []string {
type Repo struct { repoID := getRepoID(hook.HTTPSURL)
ID string `json:"id"`
CloneURL string `json:"clone_url"` envs := []string{
Promotions []string `json:"_promotions"` "GIT_DEPLOY_JOB_ID=" + jobID,
"GIT_REF_NAME=" + hook.RefName,
"GIT_REF_TYPE=" + hook.RefType,
"GIT_REPO_ID=" + repoID,
"GIT_REPO_OWNER=" + hook.Owner,
"GIT_REPO_NAME=" + hook.Repo,
"GIT_CLONE_URL=" + hook.HTTPSURL, // deprecated
"GIT_HTTPS_URL=" + hook.HTTPSURL,
"GIT_SSH_URL=" + hook.SSHURL,
}
// GIT_REPO_TRUSTED
// Set GIT_REPO_TRUSTED=TRUE if the repo matches exactly, or by pattern
repoID = strings.ToLower(repoID)
for _, repo := range strings.Fields(repoList) {
last := len(repo) - 1
if len(repo) < 0 {
continue
}
repo = strings.ToLower(repo)
if '*' == repo[last] {
// Wildcard match a prefix, for example:
// github.com/whatever/* MATCHES github.com/whatever/foo
// github.com/whatever/ProjectX-* MATCHES github.com/whatever/ProjectX-Foo
if strings.HasPrefix(repoID, repo[:last]) {
envs = append(envs, "GIT_REPO_TRUSTED=true")
break
}
} else if repo == repoID {
envs = append(envs, "GIT_REPO_TRUSTED=true")
break
}
}
return envs
} }