Skip to content

Commit 298ef8a

Browse files
committed
Merge remote-tracking branch 'origin' into json-format
2 parents abe452b + cadabb4 commit 298ef8a

File tree

7 files changed

+127
-28
lines changed

7 files changed

+127
-28
lines changed

.github/workflows/prauto.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: PR Automation
22
on:
3-
pull_request:
3+
pull_request_target:
44
types: [ready_for_review, opened, reopened]
55
jobs:
66
pr-auto:

pkg/cmd/actions/actions.go

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ func NewCmdActions(f *cmdutil.Factory) *cobra.Command {
2121
cmd := &cobra.Command{
2222
Use: "actions",
2323
Short: "Learn about working with GitHub actions",
24-
Args: cobra.ExactArgs(0),
24+
Long: actionsExplainer(nil),
2525
Hidden: true,
2626
Run: func(cmd *cobra.Command, args []string) {
2727
actionsRun(opts)
@@ -34,28 +34,45 @@ func NewCmdActions(f *cmdutil.Factory) *cobra.Command {
3434
return cmd
3535
}
3636

37-
func actionsRun(opts ActionsOptions) {
38-
cs := opts.IO.ColorScheme()
39-
fmt.Fprint(opts.IO.Out, heredoc.Docf(`
40-
Welcome to GitHub Actions on the command line.
37+
func actionsExplainer(cs *iostreams.ColorScheme) string {
38+
header := "Welcome to GitHub Actions on the command line."
39+
runHeader := "Interacting with workflow runs"
40+
workflowHeader := "Interacting with workflow files"
41+
if cs != nil {
42+
header = cs.Bold(header)
43+
runHeader = cs.Bold(runHeader)
44+
workflowHeader = cs.Bold(workflowHeader)
45+
}
4146

42-
This part of gh is in beta and subject to change!
47+
return heredoc.Docf(`
48+
%s
4349
44-
To follow along while we get to GA, please see this
45-
tracking issue: https://github.com/cli/cli/issues/2889
50+
gh integrates with Actions to help you manage runs and workflows.
4651
4752
%s
48-
gh run list: List recent workflow runs
49-
gh run view: View details for a workflow run or one of its jobs
50-
gh run watch: Watch a workflow run while it executes
51-
gh run rerun: Rerun a failed workflow run
53+
gh run list: List recent workflow runs
54+
gh run view: View details for a workflow run or one of its jobs
55+
gh run watch: Watch a workflow run while it executes
56+
gh run rerun: Rerun a failed workflow run
57+
gh run download: Download artifacts generated by runs
58+
59+
To see more help, run 'gh help run <subcommand>'
5260
5361
%s
54-
gh workflow list: List all the workflow files in your repository
55-
gh workflow enable: Enable a workflow file
56-
gh workflow disable: Disable a workflow file
57-
gh workflow run: Trigger a workflow_dispatch run for a workflow file
58-
`,
59-
cs.Bold("Interacting with workflow runs"),
60-
cs.Bold("Interacting with workflow files")))
62+
gh workflow list: List all the workflow files in your repository
63+
gh workflow view: View details for a workflow file
64+
gh workflow enable: Enable a workflow file
65+
gh workflow disable: Disable a workflow file
66+
gh workflow run: Trigger a workflow_dispatch run for a workflow file
67+
68+
To see more help, run 'gh help workflow <subcommand>'
69+
70+
For more in depth help including examples, see online documentation at:
71+
https://docs.github.com/en/actions/guides/managing-github-actions-with-github-cli
72+
`, header, runHeader, workflowHeader)
73+
}
74+
75+
func actionsRun(opts ActionsOptions) {
76+
cs := opts.IO.ColorScheme()
77+
fmt.Fprintln(opts.IO.Out, actionsExplainer(cs))
6178
}

pkg/cmd/run/download/zip.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,13 @@ const (
1616
)
1717

1818
func extractZip(zr *zip.Reader, destDir string) error {
19-
pathPrefix := filepath.Clean(destDir) + string(filepath.Separator)
19+
destDirAbs, err := filepath.Abs(destDir)
20+
if err != nil {
21+
return err
22+
}
23+
pathPrefix := destDirAbs + string(filepath.Separator)
2024
for _, zf := range zr.File {
21-
fpath := filepath.Join(destDir, filepath.FromSlash(zf.Name))
25+
fpath := filepath.Join(destDirAbs, filepath.FromSlash(zf.Name))
2226
if !strings.HasPrefix(fpath, pathPrefix) {
2327
continue
2428
}

pkg/cmd/run/download/zip_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package download
2+
3+
import (
4+
"archive/zip"
5+
"os"
6+
"path/filepath"
7+
"testing"
8+
9+
"github.com/stretchr/testify/require"
10+
)
11+
12+
func Test_extractZip(t *testing.T) {
13+
tmpDir := t.TempDir()
14+
wd, err := os.Getwd()
15+
require.NoError(t, err)
16+
t.Cleanup(func() { _ = os.Chdir(wd) })
17+
18+
zipFile, err := zip.OpenReader("./fixtures/myproject.zip")
19+
require.NoError(t, err)
20+
defer zipFile.Close()
21+
22+
extractPath := filepath.Join(tmpDir, "artifact")
23+
err = os.MkdirAll(extractPath, 0700)
24+
require.NoError(t, err)
25+
require.NoError(t, os.Chdir(extractPath))
26+
27+
err = extractZip(&zipFile.Reader, ".")
28+
require.NoError(t, err)
29+
30+
_, err = os.Stat(filepath.Join("src", "main.go"))
31+
require.NoError(t, err)
32+
}

pkg/cmd/run/shared/shared.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,14 +257,15 @@ func GetJobs(client *api.Client, repo ghrepo.Interface, run Run) ([]Job, error)
257257

258258
func PromptForRun(cs *iostreams.ColorScheme, runs []Run) (string, error) {
259259
var selected int
260+
now := time.Now()
260261

261262
candidates := []string{}
262263

263264
for _, run := range runs {
264265
symbol, _ := Symbol(cs, run.Status, run.Conclusion)
265266
candidates = append(candidates,
266267
// TODO truncate commit message, long ones look terrible
267-
fmt.Sprintf("%s %s, %s (%s)", symbol, run.CommitMsg(), run.Name, run.HeadBranch))
268+
fmt.Sprintf("%s %s, %s (%s) %s", symbol, run.CommitMsg(), run.Name, run.HeadBranch, preciseAgo(now, run.CreatedAt)))
268269
}
269270

270271
// TODO consider custom filter so it's fuzzier. right now matches start anywhere in string but
@@ -380,3 +381,14 @@ func PullRequestForRun(client *api.Client, repo ghrepo.Interface, run Run) (int,
380381

381382
return number, nil
382383
}
384+
385+
func preciseAgo(now time.Time, createdAt time.Time) string {
386+
ago := now.Sub(createdAt)
387+
388+
if ago < 30*24*time.Hour {
389+
s := ago.Truncate(time.Second).String()
390+
return fmt.Sprintf("%s ago", s)
391+
}
392+
393+
return createdAt.Format("Jan _2, 2006")
394+
}

pkg/cmd/run/shared/shared_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package shared
2+
3+
import (
4+
"testing"
5+
"time"
6+
)
7+
8+
func TestPreciseAgo(t *testing.T) {
9+
const form = "2006-Jan-02 15:04:05"
10+
now, _ := time.Parse(form, "2021-Apr-12 14:00:00")
11+
12+
cases := map[string]string{
13+
"2021-Apr-12 14:00:00": "0s ago",
14+
"2021-Apr-12 13:59:30": "30s ago",
15+
"2021-Apr-12 13:59:00": "1m0s ago",
16+
"2021-Apr-12 13:30:15": "29m45s ago",
17+
"2021-Apr-12 13:00:00": "1h0m0s ago",
18+
"2021-Apr-12 02:30:45": "11h29m15s ago",
19+
"2021-Apr-11 14:00:00": "24h0m0s ago",
20+
"2021-Apr-01 14:00:00": "264h0m0s ago",
21+
"2021-Mar-12 14:00:00": "Mar 12, 2021",
22+
}
23+
24+
for createdAt, expected := range cases {
25+
d, _ := time.Parse(form, createdAt)
26+
got := preciseAgo(now, d)
27+
if got != expected {
28+
t.Errorf("expected %s but got %s for %s", expected, got, createdAt)
29+
}
30+
}
31+
}

pkg/cmd/run/view/view.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ func NewCmdView(f *cmdutil.Factory, runF func(*ViewOptions) error) *cobra.Comman
105105
$ gh run view --log --job 456789
106106
107107
# Exit non-zero if a run failed
108-
$ gh run view 0451 -e && echo "run pending or passed"
108+
$ gh run view 0451 --exit-status && echo "run pending or passed"
109109
`),
110110
RunE: func(cmd *cobra.Command, args []string) error {
111111
// support `-R, --repo` override
@@ -256,7 +256,7 @@ func runView(opts *ViewOptions) error {
256256
}
257257

258258
opts.IO.StartProgressIndicator()
259-
runLogZip, err := getRunLog(opts.RunLogCache, httpClient, repo, run.ID)
259+
runLogZip, err := getRunLog(opts.RunLogCache, httpClient, repo, run)
260260
opts.IO.StopProgressIndicator()
261261
if err != nil {
262262
return fmt.Errorf("failed to get run log: %w", err)
@@ -408,13 +408,13 @@ func getLog(httpClient *http.Client, logURL string) (io.ReadCloser, error) {
408408
return resp.Body, nil
409409
}
410410

411-
func getRunLog(cache runLogCache, httpClient *http.Client, repo ghrepo.Interface, runID int) (*zip.ReadCloser, error) {
412-
filename := fmt.Sprintf("run-log-%d.zip", runID)
411+
func getRunLog(cache runLogCache, httpClient *http.Client, repo ghrepo.Interface, run *shared.Run) (*zip.ReadCloser, error) {
412+
filename := fmt.Sprintf("run-log-%d-%d.zip", run.ID, run.CreatedAt.Unix())
413413
filepath := filepath.Join(os.TempDir(), "gh-cli-cache", filename)
414414
if !cache.Exists(filepath) {
415415
// Run log does not exist in cache so retrieve and store it
416416
logURL := fmt.Sprintf("%srepos/%s/actions/runs/%d/logs",
417-
ghinstance.RESTPrefix(repo.RepoHost()), ghrepo.FullName(repo), runID)
417+
ghinstance.RESTPrefix(repo.RepoHost()), ghrepo.FullName(repo), run.ID)
418418

419419
resp, err := getLog(httpClient, logURL)
420420
if err != nil {
@@ -498,6 +498,9 @@ func displayRunLog(io *iostreams.IOStreams, jobs []shared.Job, failed bool) erro
498498
if failed && !shared.IsFailureState(step.Conclusion) {
499499
continue
500500
}
501+
if step.Log == nil {
502+
continue
503+
}
501504
prefix := fmt.Sprintf("%s\t%s\t", job.Name, step.Name)
502505
f, err := step.Log.Open()
503506
if err != nil {

0 commit comments

Comments
 (0)