Skip to content

Commit a76bfc3

Browse files
authored
Merge pull request #1643 from diggerhq/feat/dgctl-support-streaming
support logs streaming in dgctl
2 parents eadcbf7 + 114c982 commit a76bfc3

File tree

2 files changed

+81
-7
lines changed

2 files changed

+81
-7
lines changed

cli/pkg/spec/spec.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,9 @@ func RunSpecManualCommand(
200200

201201
commentUpdater := comment_summary.NoopCommentUpdater{}
202202
// TODO: do not require conversion to gh service
203+
log.Printf("<========= DIGGER RUNNING IN MANUAL MODE =========>")
203204
allAppliesSuccess, _, err := digger.RunJobs(jobs, prService, orgService, lock, reporter, planStorage, policyChecker, commentUpdater, backendApi, spec.JobId, false, false, commentId, currentDir)
205+
log.Printf("<========= DIGGER COMPLETED =========>")
204206
if err != nil || allAppliesSuccess == false {
205207
usage.ReportErrorAndExit(spec.VCS.RepoOwner, "Terraform execution failed", 1)
206208
}

dgctl/cmd/exec.go

Lines changed: 79 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,22 @@ func getRepoFullname() (string, error) {
7676
return repoFullname, nil
7777
}
7878

79+
func GetUrlContents(url string) (string, error) {
80+
resp, err := http.Get(url)
81+
if err != nil {
82+
return "", fmt.Errorf("%v", err)
83+
}
84+
defer resp.Body.Close()
85+
86+
body, err := io.ReadAll(resp.Body)
87+
if err != nil {
88+
return "", fmt.Errorf("%v", err)
89+
}
90+
91+
content := string(body)
92+
return content, nil
93+
}
94+
7995
func GetSpec(diggerUrl string, authToken string, command string, actor string, projectMarshalled string, diggerConfigMarshalled string, repoFullName string, defaultBanch string, prBranch string) ([]byte, error) {
8096
payload := spec.GetSpecPayload{
8197
Command: command,
@@ -132,32 +148,57 @@ func pushToBranch(prBranch string) error {
132148
return err
133149
}
134150

135-
func GetWorkflowIdAndUrlFromDiggerJobId(client *github.Client, repoOwner string, repoName string, diggerJobID string) (*int64, *string, error) {
151+
func GetWorkflowIdAndUrlFromDiggerJobId(client *github.Client, repoOwner string, repoName string, diggerJobID string) (*int64, *int64, *string, error) {
136152
timeFilter := time.Now().Add(-5 * time.Minute)
137153
runs, _, err := client.Actions.ListRepositoryWorkflowRuns(context.Background(), repoOwner, repoName, &github.ListWorkflowRunsOptions{
138154
Created: ">=" + timeFilter.Format(time.RFC3339),
139155
})
140156
if err != nil {
141-
return nil, nil, fmt.Errorf("error listing workflow runs %v", err)
157+
return nil, nil, nil, fmt.Errorf("error listing workflow runs %v", err)
142158
}
143159

144160
for _, workflowRun := range runs.WorkflowRuns {
145161
workflowjobs, _, err := client.Actions.ListWorkflowJobs(context.Background(), repoOwner, repoName, *workflowRun.ID, nil)
146162
if err != nil {
147-
return nil, nil, fmt.Errorf("error listing workflow jobs for run %v %v", workflowRun.ID, err)
163+
return nil, nil, nil, fmt.Errorf("error listing workflow jobs for run %v %v", workflowRun.ID, err)
148164
}
149165

150166
for _, workflowjob := range workflowjobs.Jobs {
151167
for _, step := range workflowjob.Steps {
152168
if strings.Contains(*step.Name, diggerJobID) {
153169
url := fmt.Sprintf("https://github.com/%v/%v/actions/runs/%v", repoOwner, repoName, *workflowRun.ID)
154-
return workflowRun.ID, &url, nil
170+
return workflowRun.ID, workflowjob.ID, &url, nil
155171
}
156172
}
157173
}
158174

159175
}
160-
return nil, nil, fmt.Errorf("workflow not found")
176+
return nil, nil, nil, fmt.Errorf("workflow not found")
177+
}
178+
179+
func cleanupDiggerOutput(output string) string {
180+
181+
startingDelimeter := "<========= DIGGER RUNNING IN MANUAL MODE =========>"
182+
endingDelimiter := "<========= DIGGER COMPLETED =========>"
183+
184+
startPos := 0
185+
endPos := len(output)
186+
// removes output of terraform -version command that terraform-exec executes on every run
187+
i := strings.Index(output, startingDelimeter)
188+
if i != -1 {
189+
startPos = i + len(startingDelimeter)
190+
}
191+
192+
e := strings.Index(output, endingDelimiter)
193+
if e != -1 {
194+
endPos = e
195+
}
196+
197+
// This should not happen but in case we get here we avoid slice bounds out of range exception by resetting endPos
198+
if endPos <= startPos {
199+
endPos = len(output)
200+
}
201+
return output[startPos:endPos]
161202
}
162203

163204
// validateCmd represents the validate command
@@ -169,6 +210,12 @@ var execCmd = &cobra.Command{
169210
var execConfig execConfig
170211
viperExec.Unmarshal(&execConfig)
171212
log.Printf("%v - %v ", execConfig.Project, execConfig.Command)
213+
214+
if execConfig.Command != "digger plan" {
215+
log.Printf("ERROR: currently only 'digger plan' supported with exec command")
216+
os.Exit(1)
217+
}
218+
172219
config, _, _, err := digger_config.LoadDiggerConfig("./", true, nil)
173220
if err != nil {
174221
log.Printf("Invalid digger config file: %v. Exiting.", err)
@@ -266,16 +313,41 @@ var execCmd = &cobra.Command{
266313
repoOwner, repoName, _ := strings.Cut(repoFullname, "/")
267314
var logsUrl *string
268315
var runId *int64
316+
var jobId *int64
269317
for {
270-
runId, logsUrl, err = GetWorkflowIdAndUrlFromDiggerJobId(client, repoOwner, repoName, spec.JobId)
318+
runId, jobId, logsUrl, err = GetWorkflowIdAndUrlFromDiggerJobId(client, repoOwner, repoName, spec.JobId)
271319
if err == nil {
272320
break
273321
}
274322
time.Sleep(time.Second * 1)
275323
}
276324

277-
log.Printf("logs url: %v runId %v", *logsUrl, *runId)
325+
log.Printf("waiting for logs to be available, you can view job in this url: %v runId %v", *logsUrl, *runId)
326+
log.Printf("......")
327+
328+
for {
329+
j, _, err := client.Actions.GetWorkflowJobByID(context.Background(), repoOwner, repoName, *jobId)
330+
if err != nil {
331+
log.Printf("GetWorkflowJobByID error: %v please view the logs in the job directly", err)
332+
os.Exit(1)
333+
}
334+
if *j.Status == "completed" {
335+
break
336+
}
337+
time.Sleep(time.Second * 1)
338+
}
339+
340+
logs, _, err := client.Actions.GetWorkflowJobLogs(context.Background(), repoOwner, repoName, *jobId, 1)
278341

342+
log.Printf("streaming logs from remote job:")
343+
logsContent, err := GetUrlContents(logs.String())
344+
345+
if err != nil {
346+
log.Printf("error while fetching logs: %v", err)
347+
os.Exit(1)
348+
}
349+
cleanedLogs := cleanupDiggerOutput(logsContent)
350+
log.Printf("logsContent is: %v", cleanedLogs)
279351
},
280352
}
281353

0 commit comments

Comments
 (0)