| 100 | } |
| 101 | |
| 102 | func NewCmdView(f *cmdutil.Factory, runF func(*ViewOptions) error) *cobra.Command { |
| 103 | opts := &ViewOptions{ |
| 104 | IO: f.IOStreams, |
| 105 | HttpClient: f.HttpClient, |
| 106 | Prompter: f.Prompter, |
| 107 | Now: time.Now, |
| 108 | Browser: f.Browser, |
| 109 | } |
| 110 | |
| 111 | cmd := &cobra.Command{ |
| 112 | Use: "view [<run-id>]", |
| 113 | Short: "View a summary of a workflow run", |
| 114 | Long: heredoc.Docf(` |
| 115 | View a summary of a workflow run. |
| 116 | |
| 117 | Due to platform limitations, %[1]sgh%[1]s may not always be able to associate jobs with their |
| 118 | corresponding logs when using the primary method of fetching logs in zip format. |
| 119 | |
| 120 | In such cases, %[1]sgh%[1]s will attempt to fetch logs for each job individually via the API. |
| 121 | This fallback is slower and more resource-intensive. If more than 25 job logs are missing, |
| 122 | the operation will fail with an error. |
| 123 | |
| 124 | Additionally, due to similar platform constraints, some log lines may not be |
| 125 | associated with a specific step within a job. In these cases, the step name will |
| 126 | appear as %[1]sUNKNOWN STEP%[1]s in the log output. |
| 127 | `, "`", maxAPILogFetchers), |
| 128 | Args: cobra.MaximumNArgs(1), |
| 129 | Example: heredoc.Doc(` |
| 130 | # Interactively select a run to view, optionally selecting a single job |
| 131 | $ gh run view |
| 132 | |
| 133 | # View a specific run |
| 134 | $ gh run view 12345 |
| 135 | |
| 136 | # View a specific run with specific attempt number |
| 137 | $ gh run view 12345 --attempt 3 |
| 138 | |
| 139 | # View a specific job within a run |
| 140 | $ gh run view --job 456789 |
| 141 | |
| 142 | # View the full log for a specific job |
| 143 | $ gh run view --log --job 456789 |
| 144 | |
| 145 | # Exit non-zero if a run failed |
| 146 | $ gh run view 0451 --exit-status && echo "run pending or passed" |
| 147 | `), |
| 148 | RunE: func(cmd *cobra.Command, args []string) error { |
| 149 | // support `-R, --repo` override |
| 150 | opts.BaseRepo = f.BaseRepo |
| 151 | |
| 152 | config, err := f.Config() |
| 153 | if err != nil { |
| 154 | return err |
| 155 | } |
| 156 | |
| 157 | opts.RunLogCache = RunLogCache{ |
| 158 | cacheDir: config.CacheDir(), |
| 159 | } |