Merge branch 'trunk' into kw/github-cli-590-add-search-acceptance-tests

This commit is contained in:
Kynan Ware 2024-10-21 10:23:00 -06:00 committed by GitHub
commit e39a78ea29
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 304 additions and 51 deletions

View file

@ -81,6 +81,15 @@ func TestSearches(t *testing.T) {
testscript.Run(t, testScriptParamsFor(tsEnv, "search"))
}
func TestRepo(t *testing.T) {
var tsEnv testScriptEnv
if err := tsEnv.fromEnv(); err != nil {
t.Fatal(err)
}
testscript.Run(t, testScriptParamsFor(tsEnv, "repo"))
}
func testScriptParamsFor(tsEnv testScriptEnv, command string) testscript.Params {
var files []string
if tsEnv.script != "" {

View file

@ -0,0 +1,23 @@
# Create a repository with a file so it has a default branch
exec gh repo create $ORG/$SCRIPT_NAME-$RANDOM_STRING --add-readme --private
# Defer repo cleanup
defer gh repo delete --yes $ORG/$SCRIPT_NAME-$RANDOM_STRING
# Check that the repo exists and isn't archived
exec gh repo view $ORG/$SCRIPT_NAME-$RANDOM_STRING --json=isArchived --jq='.isArchived'
stdout 'false'
# Archive the repo
exec gh repo archive $ORG/$SCRIPT_NAME-$RANDOM_STRING --yes
# Check that the repo is archived
exec gh repo view $ORG/$SCRIPT_NAME-$RANDOM_STRING --json=isArchived --jq='.isArchived'
stdout 'true'
# Unarchive the repo
exec gh repo unarchive $ORG/$SCRIPT_NAME-$RANDOM_STRING --yes
# Check that the repo is unarchived
exec gh repo view $ORG/$SCRIPT_NAME-$RANDOM_STRING --json=isArchived --jq='.isArchived'
stdout 'false'

View file

@ -0,0 +1,11 @@
# Create a repository with a file so it has a default branch
exec gh repo create $ORG/$SCRIPT_NAME-$RANDOM_STRING --add-readme --private
# Defer repo cleanup
defer gh repo delete --yes $ORG/$SCRIPT_NAME-$RANDOM_STRING
# Clone the repo
exec gh repo clone $ORG/$SCRIPT_NAME-$RANDOM_STRING
# Ensure the repo was cloned
exists $SCRIPT_NAME-$RANDOM_STRING/README.md

View file

@ -0,0 +1,9 @@
# Create a repository with a file so it has a default branch
exec gh repo create $ORG/$SCRIPT_NAME-$RANDOM_STRING --add-readme --private
# Defer repo cleanup
defer gh repo delete --yes $ORG/$SCRIPT_NAME-$RANDOM_STRING
# Check that the repo exists
exec gh repo view $ORG/$SCRIPT_NAME-$RANDOM_STRING --json=name --jq='.name'
stdout $SCRIPT_NAME-$RANDOM_STRING

View file

@ -0,0 +1,13 @@
# Create a repository with a file so it has a default branch
exec gh repo create $ORG/$SCRIPT_NAME-$RANDOM_STRING --add-readme --private
# Check that the repo exists
exec gh repo view $ORG/$SCRIPT_NAME-$RANDOM_STRING --json name --jq '.name'
stdout $SCRIPT_NAME-$RANDOM_STRING
# Delete the repo
exec gh repo delete --yes $ORG/$SCRIPT_NAME-$RANDOM_STRING
# Ensure that the repo was deleted
! exec gh repo view $ORG/$SCRIPT_NAME-$RANDOM_STRING
stderr 'Could not resolve to a Repository with the name'

View file

@ -0,0 +1,31 @@
# Create and clone a repository with a file so it has a default branch
exec gh repo create $ORG/$SCRIPT_NAME-$RANDOM_STRING --add-readme --private --clone
# Defer repo cleanup
defer gh repo delete --yes $ORG/$SCRIPT_NAME-$RANDOM_STRING
# cd to the repo and list the deploy keys. There should be no keys
cd $SCRIPT_NAME-$RANDOM_STRING
exec gh repo deploy-key list --json=title
! stdout title
# Add a deploy key
exec gh repo deploy-key add ../deployKey.pub
# Ensure the deploy key was added
exec gh repo deploy-key list --json=title --jq='.[].title'
stdout myTitle
# Get the deploy key id
exec gh repo deploy-key list --json=title,id --jq='.[].title="myTitle" | .[].id'
stdout2env DEPLOY_KEY_ID
# Delete the deploy key
exec gh repo deploy-key delete $DEPLOY_KEY_ID
# Ensure the deploy key was deleted
exec gh repo deploy-key list --json=id --jq='.[].id'
! stdout $DEPLOY_KEY_ID
-- deployKey.pub --
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAZmdeRNskfpvYL5YHB/YJaW8hTEXpnvPMkx5Ri+YwUr myTitle

View file

@ -0,0 +1,16 @@
# Create a repository with a file so it has a default branch
exec gh repo create $ORG/$SCRIPT_NAME-$RANDOM_STRING --add-readme --private
# Defer repo cleanup
defer gh repo delete --yes $ORG/$SCRIPT_NAME-$RANDOM_STRING
# Check that the repo description is empty
exec gh repo view $ORG/$SCRIPT_NAME-$RANDOM_STRING --json description --jq '.description'
! stdout '.'
# Edit the repo description
exec gh repo edit $ORG/$SCRIPT_NAME-$RANDOM_STRING --description 'newDescription'
# Check that the repo description is updated
exec gh repo view $ORG/$SCRIPT_NAME-$RANDOM_STRING --json description --jq '.description'
stdout 'newDescription'

View file

@ -0,0 +1,42 @@
# Use gh as a credential helper
exec gh auth setup-git
# Create and clone a repository with a file so it has a default branch
exec gh repo create $ORG/$SCRIPT_NAME-$RANDOM_STRING --add-readme --private --clone
# Defer repo cleanup
defer gh repo delete --yes $ORG/$SCRIPT_NAME-$RANDOM_STRING
# Fork and clone the repo
exec gh repo fork $ORG/$SCRIPT_NAME-$RANDOM_STRING --org $ORG --fork-name $SCRIPT_NAME-$RANDOM_STRING-fork --clone
# Defer fork cleanup
defer gh repo delete $ORG/$SCRIPT_NAME-$RANDOM_STRING-fork --yes
# Sleep so that the BE has time to sync
sleep 5
# Check that the repo was forked
exec gh repo view $ORG/$SCRIPT_NAME-$RANDOM_STRING-fork --json='isFork' --jq='.isFork'
stdout 'true'
# Modify original repo
cd $SCRIPT_NAME-$RANDOM_STRING
mv ../asset.txt asset.txt
exec git add .
exec git commit -m 'Add asset.txt'
exec git push
# Checkout the forked repo and ensure asset.txt is not present
cd ../$SCRIPT_NAME-$RANDOM_STRING-fork
exec git checkout main
! exists asset.txt
# Sync the forked repo with the original repo
exec gh repo sync
# Check that asset.txt now exists in the fork
exists asset.txt
-- asset.txt --
Hello, world!

View file

@ -0,0 +1,16 @@
# Create a repository with a file so it has a default branch
exec gh repo create $ORG/$SCRIPT_NAME-$RANDOM_STRING --add-readme --private
# List the repos and check for the new repo
exec gh repo list $ORG --json=name --jq='.[].name'
stdout $SCRIPT_NAME-$RANDOM_STRING
# Rename the repo
exec gh repo rename $SCRIPT_NAME-$RANDOM_STRING-renamed --repo=$ORG/$SCRIPT_NAME-$RANDOM_STRING --yes
# Defer repo deletion
defer gh repo delete $ORG/$SCRIPT_NAME-$RANDOM_STRING-renamed --yes
# List the repos and check for the renamed repo
exec gh repo list $ORG --json=name --jq='.[].name'
stdout $SCRIPT_NAME-$RANDOM_STRING-renamed

View file

@ -0,0 +1,17 @@
# Create and clone a repository with a file so it has a default branch
exec gh repo create $ORG/$SCRIPT_NAME-$RANDOM_STRING --add-readme --private --clone
# Defer repo cleanup
defer gh repo delete --yes $ORG/$SCRIPT_NAME-$RANDOM_STRING
# Ensure that no default is set
cd $SCRIPT_NAME-$RANDOM_STRING
exec gh repo set-default --view
stderr 'no default repository has been set; use `gh repo set-default` to select one'
# Set the default
exec gh repo set-default $ORG/$SCRIPT_NAME-$RANDOM_STRING
# Check that the default is set
exec gh repo set-default --view
stdout $ORG/$SCRIPT_NAME-$RANDOM_STRING

10
go.mod
View file

@ -17,7 +17,7 @@ require (
github.com/cpuguy83/go-md2man/v2 v2.0.5
github.com/creack/pty v1.1.23
github.com/distribution/reference v0.5.0
github.com/gabriel-vasile/mimetype v1.4.5
github.com/gabriel-vasile/mimetype v1.4.6
github.com/gdamore/tcell/v2 v2.5.4
github.com/google/go-cmp v0.6.0
github.com/google/go-containerregistry v0.20.2
@ -43,10 +43,10 @@ require (
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.9.0
github.com/zalando/go-keyring v0.2.5
golang.org/x/crypto v0.27.0
golang.org/x/crypto v0.28.0
golang.org/x/sync v0.8.0
golang.org/x/term v0.24.0
golang.org/x/text v0.18.0
golang.org/x/term v0.25.0
golang.org/x/text v0.19.0
google.golang.org/grpc v1.64.1
google.golang.org/protobuf v1.34.2
gopkg.in/h2non/gock.v1 v1.1.2
@ -159,7 +159,7 @@ require (
go.uber.org/zap v1.27.0 // indirect
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 // indirect
golang.org/x/mod v0.20.0 // indirect
golang.org/x/net v0.27.0 // indirect
golang.org/x/net v0.30.0 // indirect
golang.org/x/sys v0.26.0 // indirect
golang.org/x/tools v0.22.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5 // indirect

20
go.sum
View file

@ -147,8 +147,8 @@ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHk
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/gabriel-vasile/mimetype v1.4.5 h1:J7wGKdGu33ocBOhGy0z653k/lFKLFDPJMG8Gql0kxn4=
github.com/gabriel-vasile/mimetype v1.4.5/go.mod h1:ibHel+/kbxn9x2407k1izTA1S81ku1z/DlgOW2QE0M4=
github.com/gabriel-vasile/mimetype v1.4.6 h1:3+PzJTKLkvgjeTbts6msPJt4DixhT4YtFNf1gtGe3zc=
github.com/gabriel-vasile/mimetype v1.4.6/go.mod h1:JX1qVKqZd40hUPpAfiNTe0Sne7hdfKSbOqqmkq8GCXc=
github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko=
github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=
github.com/gdamore/tcell/v2 v2.5.4 h1:TGU4tSjD3sCL788vFNeJnTdzpNKIw1H5dgLnJRQVv/k=
@ -486,8 +486,8 @@ go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 h1:hNQpMuAJe5CtcUqCXaWga3FHu+kQvCqcsoVaQgSV60o=
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
@ -496,8 +496,8 @@ golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA=
golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -519,15 +519,15 @@ golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM=
golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8=
golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24=
golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

View file

@ -222,7 +222,7 @@ func createRun(opts *CreateOptions) (err error) {
defer prShared.PreserveInput(opts.IO, &tb, &err)()
if opts.Title == "" {
err = prShared.TitleSurvey(opts.Prompter, &tb)
err = prShared.TitleSurvey(opts.Prompter, opts.IO, &tb)
if err != nil {
return
}

View file

@ -611,7 +611,7 @@ func TestIssueCreate_recover(t *testing.T) {
pm := &prompter.PrompterMock{}
pm.InputFunc = func(p, d string) (string, error) {
if p == "Title" {
if p == "Title (required)" {
return d, nil
} else {
return "", prompter.NoSuchPromptErr(p)
@ -736,7 +736,7 @@ func TestIssueCreate_continueInBrowser(t *testing.T) {
pm := &prompter.PrompterMock{}
pm.InputFunc = func(p, d string) (string, error) {
if p == "Title" {
if p == "Title (required)" {
return "hello", nil
} else {
return "", prompter.NoSuchPromptErr(p)

View file

@ -379,7 +379,7 @@ func createRun(opts *CreateOptions) (err error) {
} else {
if !opts.TitleProvided {
err = shared.TitleSurvey(opts.Prompter, state)
err = shared.TitleSurvey(opts.Prompter, opts.IO, state)
if err != nil {
return
}

View file

@ -1210,7 +1210,7 @@ func Test_createRun(t *testing.T) {
},
promptStubs: func(pm *prompter.PrompterMock) {
pm.InputFunc = func(p, d string) (string, error) {
if p == "Title" {
if p == "Title (required)" {
return d, nil
} else {
return "", prompter.NoSuchPromptErr(p)
@ -1316,7 +1316,7 @@ func Test_createRun(t *testing.T) {
}
pm.InputFunc = func(p, d string) (string, error) {
if p == "Title" {
if p == "Title (required)" {
return d, nil
} else if p == "Body" {
return d, nil

View file

@ -110,10 +110,17 @@ func BodySurvey(p Prompt, state *IssueMetadataState, templateContent string) err
return nil
}
func TitleSurvey(p Prompt, state *IssueMetadataState) error {
result, err := p.Input("Title", state.Title)
if err != nil {
return err
func TitleSurvey(p Prompt, io *iostreams.IOStreams, state *IssueMetadataState) error {
var err error
result := ""
for result == "" {
result, err = p.Input("Title (required)", state.Title)
if err != nil {
return err
}
if result == "" {
fmt.Fprintf(io.ErrOut, "%s Title cannot be blank\n", io.ColorScheme().FailureIcon())
}
}
if result != state.Title {

View file

@ -158,3 +158,44 @@ type testEditor struct {
func (e testEditor) Edit(filename, text string) (string, error) {
return e.edit(text)
}
func TestTitleSurvey(t *testing.T) {
tests := []struct {
name string
prompterMockInputs []string
expectedTitle string
expectStderr bool
}{
{
name: "title provided",
prompterMockInputs: []string{"title"},
expectedTitle: "title",
},
{
name: "first input empty",
prompterMockInputs: []string{"", "title"},
expectedTitle: "title",
expectStderr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
io, _, _, stderr := iostreams.Test()
pm := prompter.NewMockPrompter(t)
for _, input := range tt.prompterMockInputs {
pm.RegisterInput("Title (required)", func(string, string) (string, error) {
return input, nil
})
}
state := &IssueMetadataState{}
err := TitleSurvey(pm, io, state)
assert.NoError(t, err)
assert.Equal(t, tt.expectedTitle, state.Title)
if tt.expectStderr {
assert.Equal(t, "X Title cannot be blank\n", stderr.String())
}
})
}
}

View file

@ -180,16 +180,22 @@ func (r *Run) ExportData(fields []string) map[string]interface{} {
for _, j := range r.Jobs {
steps := make([]interface{}, 0, len(j.Steps))
for _, s := range j.Steps {
var stepCompletedAt time.Time
if !s.CompletedAt.IsZero() {
stepCompletedAt = s.CompletedAt
}
steps = append(steps, map[string]interface{}{
"name": s.Name,
"status": s.Status,
"conclusion": s.Conclusion,
"number": s.Number,
"name": s.Name,
"status": s.Status,
"conclusion": s.Conclusion,
"number": s.Number,
"startedAt": s.StartedAt,
"completedAt": stepCompletedAt,
})
}
var completedAt time.Time
var jobCompletedAt time.Time
if !j.CompletedAt.IsZero() {
completedAt = j.CompletedAt
jobCompletedAt = j.CompletedAt
}
jobs = append(jobs, map[string]interface{}{
"databaseId": j.ID,
@ -198,7 +204,7 @@ func (r *Run) ExportData(fields []string) map[string]interface{} {
"name": j.Name,
"steps": steps,
"startedAt": j.StartedAt,
"completedAt": completedAt,
"completedAt": jobCompletedAt,
"url": j.URL,
})
}
@ -225,11 +231,13 @@ type Job struct {
}
type Step struct {
Name string
Status Status
Conclusion Conclusion
Number int
Log *zip.File
Name string
Status Status
Conclusion Conclusion
Number int
StartedAt time.Time `json:"started_at"`
CompletedAt time.Time `json:"completed_at"`
Log *zip.File
}
type Steps []Step

View file

@ -110,8 +110,12 @@ func TestRun_Duration(t *testing.T) {
func TestRunExportData(t *testing.T) {
oldestStartedAt, _ := time.Parse(time.RFC3339, "2022-07-20T11:20:13Z")
oldestStepStartedAt, _ := time.Parse(time.RFC3339, "2022-07-20T11:20:15Z")
oldestStepCompletedAt, _ := time.Parse(time.RFC3339, "2022-07-20T11:21:10Z")
oldestCompletedAt, _ := time.Parse(time.RFC3339, "2022-07-20T11:21:16Z")
newestStartedAt, _ := time.Parse(time.RFC3339, "2022-07-20T11:20:55Z")
newestStepStartedAt, _ := time.Parse(time.RFC3339, "2022-07-20T11:21:01Z")
newestStepCompletedAt, _ := time.Parse(time.RFC3339, "2022-07-20T11:23:10Z")
newestCompletedAt, _ := time.Parse(time.RFC3339, "2022-07-20T11:23:16Z")
tests := []struct {
@ -132,10 +136,12 @@ func TestRunExportData(t *testing.T) {
Name: "macos",
Steps: []Step{
{
Name: "Checkout",
Status: "completed",
Conclusion: "success",
Number: 1,
Name: "Checkout",
Status: "completed",
Conclusion: "success",
Number: 1,
StartedAt: oldestStepStartedAt,
CompletedAt: oldestStepCompletedAt,
},
},
StartedAt: oldestStartedAt,
@ -144,7 +150,7 @@ func TestRunExportData(t *testing.T) {
},
},
},
output: `{"jobs":[{"completedAt":"2022-07-20T11:21:16Z","conclusion":"success","databaseId":123456,"name":"macos","startedAt":"2022-07-20T11:20:13Z","status":"completed","steps":[{"conclusion":"success","name":"Checkout","number":1,"status":"completed"}],"url":"https://example.com/OWNER/REPO/actions/runs/123456"}]}`,
output: `{"jobs":[{"completedAt":"2022-07-20T11:21:16Z","conclusion":"success","databaseId":123456,"name":"macos","startedAt":"2022-07-20T11:20:13Z","status":"completed","steps":[{"completedAt":"2022-07-20T11:21:10Z","conclusion":"success","name":"Checkout","number":1,"startedAt":"2022-07-20T11:20:15Z","status":"completed"}],"url":"https://example.com/OWNER/REPO/actions/runs/123456"}]}`,
},
{
name: "exports workflow run's multiple jobs",
@ -158,10 +164,12 @@ func TestRunExportData(t *testing.T) {
Name: "macos",
Steps: []Step{
{
Name: "Checkout",
Status: "completed",
Conclusion: "success",
Number: 1,
Name: "Checkout",
Status: "completed",
Conclusion: "success",
Number: 1,
StartedAt: oldestStepStartedAt,
CompletedAt: oldestStepCompletedAt,
},
},
StartedAt: oldestStartedAt,
@ -175,10 +183,12 @@ func TestRunExportData(t *testing.T) {
Name: "windows",
Steps: []Step{
{
Name: "Checkout",
Status: "completed",
Conclusion: "error",
Number: 2,
Name: "Checkout",
Status: "completed",
Conclusion: "error",
Number: 2,
StartedAt: newestStepStartedAt,
CompletedAt: newestStepCompletedAt,
},
},
StartedAt: newestStartedAt,
@ -187,7 +197,7 @@ func TestRunExportData(t *testing.T) {
},
},
},
output: `{"jobs":[{"completedAt":"2022-07-20T11:21:16Z","conclusion":"success","databaseId":123456,"name":"macos","startedAt":"2022-07-20T11:20:13Z","status":"completed","steps":[{"conclusion":"success","name":"Checkout","number":1,"status":"completed"}],"url":"https://example.com/OWNER/REPO/actions/runs/123456"},{"completedAt":"2022-07-20T11:23:16Z","conclusion":"error","databaseId":234567,"name":"windows","startedAt":"2022-07-20T11:20:55Z","status":"completed","steps":[{"conclusion":"error","name":"Checkout","number":2,"status":"completed"}],"url":"https://example.com/OWNER/REPO/actions/runs/234567"}]}`,
output: `{"jobs":[{"completedAt":"2022-07-20T11:21:16Z","conclusion":"success","databaseId":123456,"name":"macos","startedAt":"2022-07-20T11:20:13Z","status":"completed","steps":[{"completedAt":"2022-07-20T11:21:10Z","conclusion":"success","name":"Checkout","number":1,"startedAt":"2022-07-20T11:20:15Z","status":"completed"}],"url":"https://example.com/OWNER/REPO/actions/runs/123456"},{"completedAt":"2022-07-20T11:23:16Z","conclusion":"error","databaseId":234567,"name":"windows","startedAt":"2022-07-20T11:20:55Z","status":"completed","steps":[{"completedAt":"2022-07-20T11:23:10Z","conclusion":"error","name":"Checkout","number":2,"startedAt":"2022-07-20T11:21:01Z","status":"completed"}],"url":"https://example.com/OWNER/REPO/actions/runs/234567"}]}`,
},
{
name: "exports workflow run with attempt count",