From 2f29a0ccdddf39884b337de8e6345a2e69b788d7 Mon Sep 17 00:00:00 2001 From: Thomas Lorreyte Date: Wed, 10 Jan 2024 09:29:31 +0100 Subject: [PATCH] fix: unnamed jobs in ui --- server/controllers/templates/web_templates.go | 24 ++++++--- .../templates/web_templates_test.go | 16 ++++++ server/events/models/models.go | 30 ++++++++---- .../post_workflow_hooks_command_runner.go | 20 ++++---- .../pre_workflow_hooks_command_runner.go | 20 ++++---- server/jobs/project_command_output_handler.go | 49 +++++++++++-------- server/static/css/custom.css | 2 - 7 files changed, 106 insertions(+), 55 deletions(-) diff --git a/server/controllers/templates/web_templates.go b/server/controllers/templates/web_templates.go index 177a6428b4..ef9736fbba 100644 --- a/server/controllers/templates/web_templates.go +++ b/server/controllers/templates/web_templates.go @@ -161,21 +161,33 @@ var IndexTemplate = template.Must(template.New("index.html.tmpl").Parse(`

Jobs

{{ if .PullToJobMapping }} -
+
Repository Project Workspace - Jobs + Date/Time + Step + Description
{{ range .PullToJobMapping }}
- {{.Pull.RepoFullName}} #{{.Pull.PullNum}} - {{.Pull.Path}} - {{.Pull.Workspace}} + {{ .Pull.RepoFullName }} #{{ .Pull.PullNum }} + {{ .Pull.Path }} + {{ .Pull.Workspace }} + + {{ range .JobIDInfos }} +
{{ .TimeFormatted }}
+ {{ end }} +
+ + {{ range .JobIDInfos }} + + {{ end }} + {{ range .JobIDInfos }} - +
{{ .JobDescription }}
{{ end }}
diff --git a/server/controllers/templates/web_templates_test.go b/server/controllers/templates/web_templates_test.go index 091f3db275..5b88c3e1d9 100644 --- a/server/controllers/templates/web_templates_test.go +++ b/server/controllers/templates/web_templates_test.go @@ -5,6 +5,7 @@ import ( "testing" "time" + "github.com/runatlantis/atlantis/server/jobs" . "github.com/runatlantis/atlantis/testing" ) @@ -28,6 +29,21 @@ func TestIndexTemplate(t *testing.T) { }, AtlantisVersion: "v0.0.0", CleanedBasePath: "/path", + PullToJobMapping: []jobs.PullInfoWithJobIDs{ + { + Pull: jobs.PullInfo{ + PullNum: 1, + Repo: "repo", + RepoFullName: "repo full name", + ProjectName: "project name", + Path: "path", + Workspace: "workspace", + }, + JobIDInfos: []jobs.JobIDInfo{ + {JobID: "job id", JobIDUrl: "job id url", JobDescription: "job description", Time: time.Now(), TimeFormatted: "02-01-2006 15:04:05", JobStep: "job step"}, + }, + }, + }, }) Ok(t, err) } diff --git a/server/events/models/models.go b/server/events/models/models.go index 549e06a6af..7c17461c69 100644 --- a/server/events/models/models.go +++ b/server/events/models/models.go @@ -611,27 +611,39 @@ func (p ProjectPlanStatus) String() string { type WorkflowHookCommandContext struct { // BaseRepo is the repository that the pull request will be merged into. BaseRepo Repo + // The name of the command that is being executed, i.e. 'plan', 'apply' etc. + CommandName string + // EscapedCommentArgs are the extra arguments that were added to the atlantis + // command, ex. atlantis plan -- -target=resource. We then escape them + // by adding a \ before each character so that they can be used within + // sh -c safely, i.e. sh -c "terraform plan $(touch bad)". + EscapedCommentArgs []string // HeadRepo is the repository that is getting merged into the BaseRepo. // If the pull request branch is from the same repository then HeadRepo will // be the same as BaseRepo. HeadRepo Repo + // HookDescription is a description of the hook that is being executed. + HookDescription string + // UUID for reference + HookID string + // HookStepName is the name of the step that is being executed. + HookStepName string // Log is a logger that's been set up for this context. Log logging.SimpleLogging // Pull is the pull request we're responding to. Pull PullRequest + // ProjectName is the name of the project set in atlantis.yaml. If there was + // no name this will be an empty string. + ProjectName string + // RepoRelDir is the directory of this project relative to the repo root. + RepoRelDir string // User is the user that triggered this command. User User // Verbose is true when the user would like verbose output. Verbose bool - // EscapedCommentArgs are the extra arguments that were added to the atlantis - // command, ex. atlantis plan -- -target=resource. We then escape them - // by adding a \ before each character so that they can be used within - // sh -c safely, i.e. sh -c "terraform plan $(touch bad)". - EscapedCommentArgs []string - // UUID for reference - HookID string - // The name of the command that is being executed, i.e. 'plan', 'apply' etc. - CommandName string + // Workspace is the Terraform workspace this project is in. It will always + // be set. + Workspace string } // PlanSuccessStats holds stats for a plan. diff --git a/server/events/post_workflow_hooks_command_runner.go b/server/events/post_workflow_hooks_command_runner.go index 6af9d6a499..4a7a587292 100644 --- a/server/events/post_workflow_hooks_command_runner.go +++ b/server/events/post_workflow_hooks_command_runner.go @@ -104,20 +104,22 @@ func (w *DefaultPostWorkflowHooksCommandRunner) runHooks( ) error { for i, hook := range postWorkflowHooks { - hookDescription := hook.StepDescription - if hookDescription == "" { - hookDescription = fmt.Sprintf("Post workflow hook #%d", i) + ctx.HookDescription = hook.StepDescription + if ctx.HookDescription == "" { + ctx.HookDescription = fmt.Sprintf("Post workflow hook #%d", i) } + ctx.HookStepName = fmt.Sprintf("post %s #%d", ctx.CommandName, i) + ctx.Log.Debug("Processing post workflow hook '%s', Command '%s', Target commands [%s]", - hookDescription, ctx.CommandName, hook.Commands) + ctx.HookDescription, ctx.CommandName, hook.Commands) if hook.Commands != "" && !strings.Contains(hook.Commands, ctx.CommandName) { ctx.Log.Debug("Skipping post workflow hook '%s' as command '%s' is not in Commands [%s]", - hookDescription, ctx.CommandName, hook.Commands) + ctx.HookDescription, ctx.CommandName, hook.Commands) continue } - ctx.Log.Debug("Running post workflow hook: '%s'", hookDescription) + ctx.Log.Debug("Running post workflow hook: '%s'", ctx.HookDescription) ctx.HookID = uuid.NewString() shell := hook.Shell if shell == "" { @@ -134,20 +136,20 @@ func (w *DefaultPostWorkflowHooksCommandRunner) runHooks( return err } - if err := w.CommitStatusUpdater.UpdatePostWorkflowHook(ctx.Pull, models.PendingCommitStatus, hookDescription, "", url); err != nil { + if err := w.CommitStatusUpdater.UpdatePostWorkflowHook(ctx.Pull, models.PendingCommitStatus, ctx.HookDescription, "", url); err != nil { ctx.Log.Warn("unable to update post workflow hook status: %s", err) } _, runtimeDesc, err := w.PostWorkflowHookRunner.Run(ctx, hook.RunCommand, shell, shellArgs, repoDir) if err != nil { - if err := w.CommitStatusUpdater.UpdatePostWorkflowHook(ctx.Pull, models.FailedCommitStatus, hookDescription, runtimeDesc, url); err != nil { + if err := w.CommitStatusUpdater.UpdatePostWorkflowHook(ctx.Pull, models.FailedCommitStatus, ctx.HookDescription, runtimeDesc, url); err != nil { ctx.Log.Warn("unable to update post workflow hook status: %s", err) } return err } - if err := w.CommitStatusUpdater.UpdatePostWorkflowHook(ctx.Pull, models.SuccessCommitStatus, hookDescription, runtimeDesc, url); err != nil { + if err := w.CommitStatusUpdater.UpdatePostWorkflowHook(ctx.Pull, models.SuccessCommitStatus, ctx.HookDescription, runtimeDesc, url); err != nil { ctx.Log.Warn("unable to update post workflow hook status: %s", err) } } diff --git a/server/events/pre_workflow_hooks_command_runner.go b/server/events/pre_workflow_hooks_command_runner.go index daa50df8ba..e73f0c5037 100644 --- a/server/events/pre_workflow_hooks_command_runner.go +++ b/server/events/pre_workflow_hooks_command_runner.go @@ -113,20 +113,22 @@ func (w *DefaultPreWorkflowHooksCommandRunner) runHooks( repoDir string, ) error { for i, hook := range preWorkflowHooks { - hookDescription := hook.StepDescription - if hookDescription == "" { - hookDescription = fmt.Sprintf("Pre workflow hook #%d", i) + ctx.HookDescription = hook.StepDescription + if ctx.HookDescription == "" { + ctx.HookDescription = fmt.Sprintf("Pre workflow hook #%d", i) } + ctx.HookStepName = fmt.Sprintf("pre %s #%d", ctx.CommandName, i) + ctx.Log.Debug("Processing pre workflow hook '%s', Command '%s', Target commands [%s]", - hookDescription, ctx.CommandName, hook.Commands) + ctx.HookDescription, ctx.CommandName, hook.Commands) if hook.Commands != "" && !strings.Contains(hook.Commands, ctx.CommandName) { ctx.Log.Debug("Skipping pre workflow hook '%s' as command '%s' is not in Commands [%s]", - hookDescription, ctx.CommandName, hook.Commands) + ctx.HookDescription, ctx.CommandName, hook.Commands) continue } - ctx.Log.Debug("Running pre workflow hook: '%s'", hookDescription) + ctx.Log.Debug("Running pre workflow hook: '%s'", ctx.HookDescription) ctx.HookID = uuid.NewString() shell := hook.Shell if shell == "" { @@ -143,7 +145,7 @@ func (w *DefaultPreWorkflowHooksCommandRunner) runHooks( return err } - if err := w.CommitStatusUpdater.UpdatePreWorkflowHook(ctx.Pull, models.PendingCommitStatus, hookDescription, "", url); err != nil { + if err := w.CommitStatusUpdater.UpdatePreWorkflowHook(ctx.Pull, models.PendingCommitStatus, ctx.HookDescription, "", url); err != nil { ctx.Log.Warn("unable to update pre workflow hook status: %s", err) return err } @@ -151,13 +153,13 @@ func (w *DefaultPreWorkflowHooksCommandRunner) runHooks( _, runtimeDesc, err := w.PreWorkflowHookRunner.Run(ctx, hook.RunCommand, shell, shellArgs, repoDir) if err != nil { - if err := w.CommitStatusUpdater.UpdatePreWorkflowHook(ctx.Pull, models.FailedCommitStatus, hookDescription, runtimeDesc, url); err != nil { + if err := w.CommitStatusUpdater.UpdatePreWorkflowHook(ctx.Pull, models.FailedCommitStatus, ctx.HookDescription, runtimeDesc, url); err != nil { ctx.Log.Warn("unable to update pre workflow hook status: %s", err) } return err } - if err := w.CommitStatusUpdater.UpdatePreWorkflowHook(ctx.Pull, models.SuccessCommitStatus, hookDescription, runtimeDesc, url); err != nil { + if err := w.CommitStatusUpdater.UpdatePreWorkflowHook(ctx.Pull, models.SuccessCommitStatus, ctx.HookDescription, runtimeDesc, url); err != nil { ctx.Log.Warn("unable to update pre workflow hook status: %s", err) return err } diff --git a/server/jobs/project_command_output_handler.go b/server/jobs/project_command_output_handler.go index 758889a2c9..ede262de9b 100644 --- a/server/jobs/project_command_output_handler.go +++ b/server/jobs/project_command_output_handler.go @@ -24,10 +24,12 @@ type PullInfo struct { } type JobIDInfo struct { - JobID string - JobIDUrl string - Time time.Time - TimeFormatted string + JobID string + JobIDUrl string + JobDescription string + Time time.Time + TimeFormatted string + JobStep string } type PullInfoWithJobIDs struct { @@ -37,7 +39,9 @@ type PullInfoWithJobIDs struct { type JobInfo struct { PullInfo - HeadCommit string + HeadCommit string + JobDescription string + JobStep string } type ProjectCmdOutputLine struct { @@ -111,19 +115,15 @@ func (p *AsyncProjectCommandOutputHandler) GetPullToJobMapping() []PullInfoWithJ p.pullToJobMapping.Range(func(key, value interface{}) bool { pullInfo := key.(PullInfo) - jobIDMap := value.(map[string]time.Time) + jobIDMap := value.(map[string]JobIDInfo) p := PullInfoWithJobIDs{ Pull: pullInfo, JobIDInfos: make([]JobIDInfo, 0, len(jobIDMap)), } - for jobID, theTime := range jobIDMap { - jobIDInfo := JobIDInfo{ - JobID: jobID, - Time: theTime, - } - p.JobIDInfos = append(p.JobIDInfos, jobIDInfo) + for _, JobIDInfo := range jobIDMap { + p.JobIDInfos = append(p.JobIDInfos, JobIDInfo) } pullToJobMappings = append(pullToJobMappings, p) @@ -154,6 +154,7 @@ func (p *AsyncProjectCommandOutputHandler) Send(ctx command.ProjectContext, msg Path: ctx.RepoRelDir, Workspace: ctx.Workspace, }, + JobStep: ctx.CommandName.String(), }, Line: msg, OperationComplete: operationComplete, @@ -166,9 +167,12 @@ func (p *AsyncProjectCommandOutputHandler) SendWorkflowHook(ctx models.WorkflowH JobInfo: JobInfo{ HeadCommit: ctx.Pull.HeadCommit, PullInfo: PullInfo{ - PullNum: ctx.Pull.Num, - Repo: ctx.BaseRepo.Name, + PullNum: ctx.Pull.Num, + Repo: ctx.BaseRepo.Name, + RepoFullName: ctx.BaseRepo.FullName, }, + JobDescription: ctx.HookDescription, + JobStep: ctx.HookStepName, }, Line: msg, OperationComplete: operationComplete, @@ -188,11 +192,16 @@ func (p *AsyncProjectCommandOutputHandler) Handle() { // Add job to pullToJob mapping if _, ok := p.pullToJobMapping.Load(msg.JobInfo.PullInfo); !ok { - p.pullToJobMapping.Store(msg.JobInfo.PullInfo, map[string]time.Time{}) + p.pullToJobMapping.Store(msg.JobInfo.PullInfo, map[string]JobIDInfo{}) } value, _ := p.pullToJobMapping.Load(msg.JobInfo.PullInfo) - jobMapping := value.(map[string]time.Time) - jobMapping[msg.JobID] = time.Now() + jobMapping := value.(map[string]JobIDInfo) + jobMapping[msg.JobID] = JobIDInfo{ + JobID: msg.JobID, + JobDescription: msg.JobInfo.JobDescription, + Time: time.Now(), + JobStep: msg.JobInfo.JobStep, + } // Forward new message to all receiver channels and output buffer p.writeLogLine(msg.JobID, msg.Line) @@ -289,16 +298,16 @@ func (p *AsyncProjectCommandOutputHandler) GetProjectOutputBuffer(jobID string) return p.projectOutputBuffers[jobID] } -func (p *AsyncProjectCommandOutputHandler) GetJobIDMapForPull(pullInfo PullInfo) map[string]time.Time { +func (p *AsyncProjectCommandOutputHandler) GetJobIDMapForPull(pullInfo PullInfo) map[string]JobIDInfo { if value, ok := p.pullToJobMapping.Load(pullInfo); ok { - return value.(map[string]time.Time) + return value.(map[string]JobIDInfo) } return nil } func (p *AsyncProjectCommandOutputHandler) CleanUp(pullInfo PullInfo) { if value, ok := p.pullToJobMapping.Load(pullInfo); ok { - jobMapping := value.(map[string]time.Time) + jobMapping := value.(map[string]JobIDInfo) for jobID := range jobMapping { p.projectOutputBuffersLock.Lock() delete(p.projectOutputBuffers, jobID) diff --git a/server/static/css/custom.css b/server/static/css/custom.css index dbcea1e2f1..830398c4a8 100644 --- a/server/static/css/custom.css +++ b/server/static/css/custom.css @@ -256,7 +256,6 @@ tbody { .lock-row { display: contents; - text-transform: uppercase; } .lock-row a { @@ -311,7 +310,6 @@ tbody { .pulls-row { display: contents; - text-transform: uppercase; } .pulls-element {