diff --git a/.changeset/patch-log-gh-workflow-errors.md b/.changeset/patch-log-gh-workflow-errors.md new file mode 100644 index 0000000000..b6d2bfa641 --- /dev/null +++ b/.changeset/patch-log-gh-workflow-errors.md @@ -0,0 +1,5 @@ +--- +"gh-aw": patch +--- + +Log exit codes and stderr when `gh workflow list` and `gh workflow disable` fail, and trust every directory inside the Docker image to avoid dubious ownership errors with mounted volumes. diff --git a/Dockerfile b/Dockerfile index 8eeccbd37d..830bb088c5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,6 +25,10 @@ COPY ${BINARY} /usr/local/bin/gh-aw # Ensure the binary is executable RUN chmod +x /usr/local/bin/gh-aw +# Configure git to trust all directories to avoid "dubious ownership" errors +# This is necessary when the container runs with mounted volumes owned by different users +RUN git config --global --add safe.directory '*' + # Set working directory for users WORKDIR /workspace diff --git a/pkg/cli/workflows.go b/pkg/cli/workflows.go index 57ec44303c..80523122ed 100644 --- a/pkg/cli/workflows.go +++ b/pkg/cli/workflows.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "os" + "os/exec" "path/filepath" "strconv" "strings" @@ -84,6 +85,21 @@ func fetchGitHubWorkflows(repoOverride string, verbose bool) (map[string]*GitHub if !verbose { spinner.Stop() } + + // Extract detailed error information including exit code and stderr + var exitCode int + var stderr string + if exitErr, ok := err.(*exec.ExitError); ok { + exitCode = exitErr.ExitCode() + stderr = string(exitErr.Stderr) + workflowsLog.Printf("gh workflow list command failed with exit code %d. Command: gh %v", exitCode, args) + workflowsLog.Printf("stderr output: %s", stderr) + + return nil, fmt.Errorf("failed to execute gh workflow list command (exit code %d): %w. stderr: %s", exitCode, err, stderr) + } + + // If not an ExitError, log what we can + workflowsLog.Printf("gh workflow list command failed with error (not ExitError): %v. Command: gh %v", err, args) return nil, fmt.Errorf("failed to execute gh workflow list command: %w", err) } @@ -195,7 +211,19 @@ func restoreWorkflowState(workflowIdOrName string, workflowID int64, repoOverrid } cmd := workflow.ExecGH(args...) if err := cmd.Run(); err != nil { - fmt.Fprintln(os.Stderr, console.FormatWarningMessage(fmt.Sprintf("Failed to restore workflow '%s' to disabled state: %v", workflowIdOrName, err))) + // Extract detailed error information including exit code and stderr + var exitCode int + var stderr string + if exitErr, ok := err.(*exec.ExitError); ok { + exitCode = exitErr.ExitCode() + stderr = string(exitErr.Stderr) + workflowsLog.Printf("gh workflow disable command failed with exit code %d. Command: gh %v", exitCode, args) + workflowsLog.Printf("stderr output: %s", stderr) + fmt.Fprintln(os.Stderr, console.FormatWarningMessage(fmt.Sprintf("Failed to restore workflow '%s' to disabled state (exit code %d): %v. stderr: %s", workflowIdOrName, exitCode, err, stderr))) + } else { + workflowsLog.Printf("gh workflow disable command failed with error (not ExitError): %v. Command: gh %v", err, args) + fmt.Fprintln(os.Stderr, console.FormatWarningMessage(fmt.Sprintf("Failed to restore workflow '%s' to disabled state: %v", workflowIdOrName, err))) + } } else { fmt.Fprintln(os.Stderr, console.FormatSuccessMessage(fmt.Sprintf("Restored workflow to disabled state: %s", workflowIdOrName))) }