From 17257df06458838c7c7309128ad0ca4e7f9f0457 Mon Sep 17 00:00:00 2001 From: "Babak K. Shandiz" Date: Sun, 21 Jul 2024 12:45:28 +0100 Subject: [PATCH 01/53] Verify `--body` and `--body-file` are not assignable at the same time Signed-off-by: Babak K. Shandiz --- pkg/cmd/issue/edit/edit_test.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pkg/cmd/issue/edit/edit_test.go b/pkg/cmd/issue/edit/edit_test.go index db0b09d2d..b6b7e8f18 100644 --- a/pkg/cmd/issue/edit/edit_test.go +++ b/pkg/cmd/issue/edit/edit_test.go @@ -104,6 +104,11 @@ func TestNewCmdEdit(t *testing.T) { }, wantsErr: false, }, + { + name: "both body and body-file flags", + input: "23 --body foo --body-file bar", + wantsErr: true, + }, { name: "add-assignee flag", input: "23 --add-assignee monalisa,hubot", From 9dabc3b8dd282275a785a2461370fee907af847c Mon Sep 17 00:00:00 2001 From: "Babak K. Shandiz" Date: Sun, 21 Jul 2024 12:53:15 +0100 Subject: [PATCH 02/53] Remove unused expected `output` from test case (with `wantsErr: true`) Signed-off-by: Babak K. Shandiz --- pkg/cmd/issue/edit/edit_test.go | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/pkg/cmd/issue/edit/edit_test.go b/pkg/cmd/issue/edit/edit_test.go index b6b7e8f18..a7e68cbc0 100644 --- a/pkg/cmd/issue/edit/edit_test.go +++ b/pkg/cmd/issue/edit/edit_test.go @@ -226,17 +226,8 @@ func TestNewCmdEdit(t *testing.T) { wantsErr: false, }, { - name: "interactive multiple issues", - input: "23 34", - output: EditOptions{ - SelectorArgs: []string{"23", "34"}, - Editable: prShared.Editable{ - Labels: prShared.EditableSlice{ - Add: []string{"bug"}, - Edited: true, - }, - }, - }, + name: "interactive multiple issues", + input: "23 34", wantsErr: true, }, } From 683576d6bf509e1602d38a44554a38abd6994b79 Mon Sep 17 00:00:00 2001 From: "Babak K. Shandiz" Date: Sun, 21 Jul 2024 12:54:23 +0100 Subject: [PATCH 03/53] Add `--remove-milestone` option Signed-off-by: Babak K. Shandiz --- pkg/cmd/issue/edit/edit.go | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/pkg/cmd/issue/edit/edit.go b/pkg/cmd/issue/edit/edit.go index 1b775f88b..7b9719468 100644 --- a/pkg/cmd/issue/edit/edit.go +++ b/pkg/cmd/issue/edit/edit.go @@ -32,6 +32,7 @@ type EditOptions struct { Interactive bool prShared.Editable + RemoveMilestone bool } func NewCmdEdit(f *cmdutil.Factory, runF func(*EditOptions) error) *cobra.Command { @@ -62,6 +63,7 @@ func NewCmdEdit(f *cmdutil.Factory, runF func(*EditOptions) error) *cobra.Comman $ gh issue edit 23 --add-assignee "@me" --remove-assignee monalisa,hubot $ gh issue edit 23 --add-project "Roadmap" --remove-project v1,v2 $ gh issue edit 23 --milestone "Version 1" + $ gh issue edit 23 --remove-milestone $ gh issue edit 23 --body-file body.txt $ gh issue edit 23 34 --add-label "help wanted" `), @@ -95,6 +97,14 @@ func NewCmdEdit(f *cmdutil.Factory, runF func(*EditOptions) error) *cobra.Comman } } + if err := cmdutil.MutuallyExclusive( + "specify only one of `--milestone` or `--remove-milestone`", + flags.Changed("milestone"), + opts.RemoveMilestone, + ); err != nil { + return err + } + if flags.Changed("title") { opts.Editable.Title.Edited = true } @@ -107,8 +117,12 @@ func NewCmdEdit(f *cmdutil.Factory, runF func(*EditOptions) error) *cobra.Comman if flags.Changed("add-project") || flags.Changed("remove-project") { opts.Editable.Projects.Edited = true } - if flags.Changed("milestone") { + if flags.Changed("milestone") || opts.RemoveMilestone { opts.Editable.Milestone.Edited = true + + // Note that when `--remove-milestone` is provided, the value of + // `opts.Editable.Milestone.Value` will automatically be empty, + // which results in milestone association removal. } if !opts.Editable.Dirty() { @@ -141,6 +155,7 @@ func NewCmdEdit(f *cmdutil.Factory, runF func(*EditOptions) error) *cobra.Comman cmd.Flags().StringSliceVar(&opts.Editable.Projects.Add, "add-project", nil, "Add the issue to projects by `name`") cmd.Flags().StringSliceVar(&opts.Editable.Projects.Remove, "remove-project", nil, "Remove the issue from projects by `name`") cmd.Flags().StringVarP(&opts.Editable.Milestone.Value, "milestone", "m", "", "Edit the milestone the issue belongs to by `name`") + cmd.Flags().BoolVar(&opts.RemoveMilestone, "remove-milestone", false, "Remove the milestone the issue belongs to") return cmd } From 168a8832f087ba1a3a021c16b96743c42959f0f4 Mon Sep 17 00:00:00 2001 From: "Babak K. Shandiz" Date: Sun, 21 Jul 2024 12:55:47 +0100 Subject: [PATCH 04/53] Assert correct parsing of `--remove-milestone` option Signed-off-by: Babak K. Shandiz --- pkg/cmd/issue/edit/edit_test.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pkg/cmd/issue/edit/edit_test.go b/pkg/cmd/issue/edit/edit_test.go index a7e68cbc0..1457c6464 100644 --- a/pkg/cmd/issue/edit/edit_test.go +++ b/pkg/cmd/issue/edit/edit_test.go @@ -211,6 +211,20 @@ func TestNewCmdEdit(t *testing.T) { }, wantsErr: false, }, + { + name: "remove-milestone flag", + input: "23 --remove-milestone", + output: EditOptions{ + SelectorArgs: []string{"23"}, + Editable: prShared.Editable{ + Milestone: prShared.EditableString{ + Value: "", + Edited: true, + }, + }, + }, + wantsErr: false, + }, { name: "add label to multiple issues", input: "23 34 --add-label bug", From 42da8baf7046b801e4c9c78a23effc048a2c81c5 Mon Sep 17 00:00:00 2001 From: "Babak K. Shandiz" Date: Sun, 21 Jul 2024 12:56:14 +0100 Subject: [PATCH 05/53] Verify `--milestone` and `--remove-milestone` are not assignable at the same time Signed-off-by: Babak K. Shandiz --- pkg/cmd/issue/edit/edit_test.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pkg/cmd/issue/edit/edit_test.go b/pkg/cmd/issue/edit/edit_test.go index 1457c6464..40fe6491c 100644 --- a/pkg/cmd/issue/edit/edit_test.go +++ b/pkg/cmd/issue/edit/edit_test.go @@ -225,6 +225,11 @@ func TestNewCmdEdit(t *testing.T) { }, wantsErr: false, }, + { + name: "both milestone and remove-milestone flags", + input: "23 --milestone foo --remove-milestone", + wantsErr: true, + }, { name: "add label to multiple issues", input: "23 34 --add-label bug", From 1fb6df60087a8519673954cdf825f2c6a3d8cb44 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 26 Jul 2024 14:56:47 +0000 Subject: [PATCH 06/53] build(deps): bump github.com/gabriel-vasile/mimetype from 1.4.4 to 1.4.5 Bumps [github.com/gabriel-vasile/mimetype](https://github.com/gabriel-vasile/mimetype) from 1.4.4 to 1.4.5. - [Release notes](https://github.com/gabriel-vasile/mimetype/releases) - [Commits](https://github.com/gabriel-vasile/mimetype/compare/v1.4.4...v1.4.5) --- updated-dependencies: - dependency-name: github.com/gabriel-vasile/mimetype dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 2e653052c..099ab7a2e 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/cpuguy83/go-md2man/v2 v2.0.4 github.com/creack/pty v1.1.21 github.com/distribution/reference v0.5.0 - github.com/gabriel-vasile/mimetype v1.4.4 + github.com/gabriel-vasile/mimetype v1.4.5 github.com/gdamore/tcell/v2 v2.5.4 github.com/google/go-cmp v0.6.0 github.com/google/go-containerregistry v0.20.0 @@ -158,7 +158,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.19.0 // indirect - golang.org/x/net v0.26.0 // indirect + golang.org/x/net v0.27.0 // indirect golang.org/x/sys v0.22.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240520151616-dc85e6b867a5 // indirect diff --git a/go.sum b/go.sum index 460a2f65a..3702e12c6 100644 --- a/go.sum +++ b/go.sum @@ -148,8 +148,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.4 h1:QjV6pZ7/XZ7ryI2KuyeEDE8wnh7fHP9YnQy+R0LnH8I= -github.com/gabriel-vasile/mimetype v1.4.4/go.mod h1:JwLei5XPtWdGiMFB5Pjle1oEeoSeEuJfJE+TtfvdB/s= +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/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= @@ -495,8 +495,8 @@ golang.org/x/mod v0.19.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.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +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/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= From 6e34e81b764c8587d8c5bbf7e9e2a63449e3c22a Mon Sep 17 00:00:00 2001 From: "Babak K. Shandiz" Date: Sun, 28 Jul 2024 15:22:54 +0100 Subject: [PATCH 07/53] Point to `Editable.MilestoneId` method Signed-off-by: Babak K. Shandiz --- pkg/cmd/issue/edit/edit.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/cmd/issue/edit/edit.go b/pkg/cmd/issue/edit/edit.go index 7b9719468..263a48f20 100644 --- a/pkg/cmd/issue/edit/edit.go +++ b/pkg/cmd/issue/edit/edit.go @@ -122,7 +122,8 @@ func NewCmdEdit(f *cmdutil.Factory, runF func(*EditOptions) error) *cobra.Comman // Note that when `--remove-milestone` is provided, the value of // `opts.Editable.Milestone.Value` will automatically be empty, - // which results in milestone association removal. + // which results in milestone association removal. For reference, + // see the `Editable.MilestoneId` method. } if !opts.Editable.Dirty() { From 4c8ec84e2654ad6d622107e3a8d675a2d05c1388 Mon Sep 17 00:00:00 2001 From: "Babak K. Shandiz" Date: Sun, 28 Jul 2024 15:23:19 +0100 Subject: [PATCH 08/53] Improve `--remove-milestone` option description Signed-off-by: Babak K. Shandiz --- pkg/cmd/issue/edit/edit.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/cmd/issue/edit/edit.go b/pkg/cmd/issue/edit/edit.go index 263a48f20..de334148a 100644 --- a/pkg/cmd/issue/edit/edit.go +++ b/pkg/cmd/issue/edit/edit.go @@ -156,7 +156,7 @@ func NewCmdEdit(f *cmdutil.Factory, runF func(*EditOptions) error) *cobra.Comman cmd.Flags().StringSliceVar(&opts.Editable.Projects.Add, "add-project", nil, "Add the issue to projects by `name`") cmd.Flags().StringSliceVar(&opts.Editable.Projects.Remove, "remove-project", nil, "Remove the issue from projects by `name`") cmd.Flags().StringVarP(&opts.Editable.Milestone.Value, "milestone", "m", "", "Edit the milestone the issue belongs to by `name`") - cmd.Flags().BoolVar(&opts.RemoveMilestone, "remove-milestone", false, "Remove the milestone the issue belongs to") + cmd.Flags().BoolVar(&opts.RemoveMilestone, "remove-milestone", false, "Remove the milestone association from the issue") return cmd } From 1520292726db9e5e7c0b6e35918792f34e47304d Mon Sep 17 00:00:00 2001 From: "Babak K. Shandiz" Date: Sun, 28 Jul 2024 15:40:38 +0100 Subject: [PATCH 09/53] Add `--remove-milestone` option Signed-off-by: Babak K. Shandiz --- pkg/cmd/pr/edit/edit.go | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/pkg/cmd/pr/edit/edit.go b/pkg/cmd/pr/edit/edit.go index 3f80aa80a..2f288857b 100644 --- a/pkg/cmd/pr/edit/edit.go +++ b/pkg/cmd/pr/edit/edit.go @@ -30,6 +30,7 @@ type EditOptions struct { Interactive bool shared.Editable + RemoveMilestone bool } func NewCmdEdit(f *cmdutil.Factory, runF func(*EditOptions) error) *cobra.Command { @@ -63,6 +64,7 @@ func NewCmdEdit(f *cmdutil.Factory, runF func(*EditOptions) error) *cobra.Comman $ gh pr edit 23 --add-assignee "@me" --remove-assignee monalisa,hubot $ gh pr edit 23 --add-project "Roadmap" --remove-project v1,v2 $ gh pr edit 23 --milestone "Version 1" + $ gh pr edit 23 --remove-milestone `), Args: cobra.MaximumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { @@ -95,6 +97,14 @@ func NewCmdEdit(f *cmdutil.Factory, runF func(*EditOptions) error) *cobra.Comman } } + if err := cmdutil.MutuallyExclusive( + "specify only one of `--milestone` or `--remove-milestone`", + flags.Changed("milestone"), + opts.RemoveMilestone, + ); err != nil { + return err + } + if flags.Changed("title") { opts.Editable.Title.Edited = true } @@ -116,8 +126,13 @@ func NewCmdEdit(f *cmdutil.Factory, runF func(*EditOptions) error) *cobra.Comman if flags.Changed("add-project") || flags.Changed("remove-project") { opts.Editable.Projects.Edited = true } - if flags.Changed("milestone") { + if flags.Changed("milestone") || opts.RemoveMilestone { opts.Editable.Milestone.Edited = true + + // Note that when `--remove-milestone` is provided, the value of + // `opts.Editable.Milestone.Value` will automatically be empty, + // which results in milestone association removal. For reference, + // see the `Editable.MilestoneId` method. } if !opts.Editable.Dirty() { @@ -149,6 +164,7 @@ func NewCmdEdit(f *cmdutil.Factory, runF func(*EditOptions) error) *cobra.Comman cmd.Flags().StringSliceVar(&opts.Editable.Projects.Add, "add-project", nil, "Add the pull request to projects by `name`") cmd.Flags().StringSliceVar(&opts.Editable.Projects.Remove, "remove-project", nil, "Remove the pull request from projects by `name`") cmd.Flags().StringVarP(&opts.Editable.Milestone.Value, "milestone", "m", "", "Edit the milestone the pull request belongs to by `name`") + cmd.Flags().BoolVar(&opts.RemoveMilestone, "remove-milestone", false, "Remove the milestone association from the pull request") _ = cmdutil.RegisterBranchCompletionFlags(f.GitClient, cmd, "base") From 6dc8cc41d0ed2892d14089781540fb9b4ef788d7 Mon Sep 17 00:00:00 2001 From: "Babak K. Shandiz" Date: Sun, 28 Jul 2024 15:41:54 +0100 Subject: [PATCH 10/53] Verify `--body` and `--body-file` are not assignable at the same time --- pkg/cmd/pr/edit/edit_test.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pkg/cmd/pr/edit/edit_test.go b/pkg/cmd/pr/edit/edit_test.go index 0986797ea..6884d3d6e 100644 --- a/pkg/cmd/pr/edit/edit_test.go +++ b/pkg/cmd/pr/edit/edit_test.go @@ -112,6 +112,11 @@ func TestNewCmdEdit(t *testing.T) { }, wantsErr: false, }, + { + name: "both body and body-file flags", + input: "23 --body foo --body-file bar", + wantsErr: true, + }, { name: "base flag", input: "23 --base base-branch-name", From 605b4b19e11c5c5deb50d5fc5683312620d4ec24 Mon Sep 17 00:00:00 2001 From: "Babak K. Shandiz" Date: Sun, 28 Jul 2024 15:43:38 +0100 Subject: [PATCH 11/53] Assert correct parsing of `--remove-milestone` option Signed-off-by: Babak K. Shandiz --- pkg/cmd/pr/edit/edit_test.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pkg/cmd/pr/edit/edit_test.go b/pkg/cmd/pr/edit/edit_test.go index 6884d3d6e..35840559f 100644 --- a/pkg/cmd/pr/edit/edit_test.go +++ b/pkg/cmd/pr/edit/edit_test.go @@ -261,6 +261,20 @@ func TestNewCmdEdit(t *testing.T) { }, wantsErr: false, }, + { + name: "remove-milestone flag", + input: "23 --remove-milestone", + output: EditOptions{ + SelectorArg: "23", + Editable: shared.Editable{ + Milestone: shared.EditableString{ + Value: "", + Edited: true, + }, + }, + }, + wantsErr: false, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { From c9fb4ed0996e8b56ac755fe1d0d738f893e46906 Mon Sep 17 00:00:00 2001 From: "Babak K. Shandiz" Date: Sun, 28 Jul 2024 15:44:05 +0100 Subject: [PATCH 12/53] Verify `--milestone` and `--remove-milestone` are not assignable at the same time Signed-off-by: Babak K. Shandiz --- pkg/cmd/pr/edit/edit_test.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pkg/cmd/pr/edit/edit_test.go b/pkg/cmd/pr/edit/edit_test.go index 35840559f..3c4882961 100644 --- a/pkg/cmd/pr/edit/edit_test.go +++ b/pkg/cmd/pr/edit/edit_test.go @@ -275,6 +275,11 @@ func TestNewCmdEdit(t *testing.T) { }, wantsErr: false, }, + { + name: "both milestone and remove-milestone flags", + input: "23 --milestone foo --remove-milestone", + wantsErr: true, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { From fbae0e223eb007fec12ed2dceafb91bcd6446988 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Jul 2024 19:59:50 +0000 Subject: [PATCH 13/53] build(deps): bump github.com/google/go-containerregistry Bumps [github.com/google/go-containerregistry](https://github.com/google/go-containerregistry) from 0.20.0 to 0.20.1. - [Release notes](https://github.com/google/go-containerregistry/releases) - [Changelog](https://github.com/google/go-containerregistry/blob/main/.goreleaser.yml) - [Commits](https://github.com/google/go-containerregistry/compare/v0.20.0...v0.20.1) --- updated-dependencies: - dependency-name: github.com/google/go-containerregistry dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 099ab7a2e..a607e4adf 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( github.com/gabriel-vasile/mimetype v1.4.5 github.com/gdamore/tcell/v2 v2.5.4 github.com/google/go-cmp v0.6.0 - github.com/google/go-containerregistry v0.20.0 + github.com/google/go-containerregistry v0.20.1 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 github.com/gorilla/websocket v1.5.3 github.com/hashicorp/go-multierror v1.1.1 diff --git a/go.sum b/go.sum index 3702e12c6..ffb608ffb 100644 --- a/go.sum +++ b/go.sum @@ -201,8 +201,8 @@ github.com/google/certificate-transparency-go v1.2.1 h1:4iW/NwzqOqYEEoCBEFP+jPbB github.com/google/certificate-transparency-go v1.2.1/go.mod h1:bvn/ytAccv+I6+DGkqpvSsEdiVGramgaSC6RD3tEmeE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-containerregistry v0.20.0 h1:wRqHpOeVh3DnenOrPy9xDOLdnLatiGuuNRVelR2gSbg= -github.com/google/go-containerregistry v0.20.0/go.mod h1:YCMFNQeeXeLF+dnhhWkqDItx/JSkH01j1Kis4PsjzFI= +github.com/google/go-containerregistry v0.20.1 h1:eTgx9QNYugV4DN5mz4U8hiAGTi1ybXn0TPi4Smd8du0= +github.com/google/go-containerregistry v0.20.1/go.mod h1:YCMFNQeeXeLF+dnhhWkqDItx/JSkH01j1Kis4PsjzFI= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= From 842562d3dbc6c7a0ed62d1e16a95a9dce8f1904e Mon Sep 17 00:00:00 2001 From: "Babak K. Shandiz" Date: Mon, 29 Jul 2024 21:36:48 +0100 Subject: [PATCH 14/53] Use closure-scoped variable to catch `--remove-milestone` option Signed-off-by: Babak K. Shandiz --- pkg/cmd/pr/edit/edit.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/cmd/pr/edit/edit.go b/pkg/cmd/pr/edit/edit.go index 2f288857b..21aa80c07 100644 --- a/pkg/cmd/pr/edit/edit.go +++ b/pkg/cmd/pr/edit/edit.go @@ -30,7 +30,6 @@ type EditOptions struct { Interactive bool shared.Editable - RemoveMilestone bool } func NewCmdEdit(f *cmdutil.Factory, runF func(*EditOptions) error) *cobra.Command { @@ -44,6 +43,7 @@ func NewCmdEdit(f *cmdutil.Factory, runF func(*EditOptions) error) *cobra.Comman } var bodyFile string + var removeMilestone bool cmd := &cobra.Command{ Use: "edit [ | | ]", @@ -100,7 +100,7 @@ func NewCmdEdit(f *cmdutil.Factory, runF func(*EditOptions) error) *cobra.Comman if err := cmdutil.MutuallyExclusive( "specify only one of `--milestone` or `--remove-milestone`", flags.Changed("milestone"), - opts.RemoveMilestone, + opts.removeMilestone, ); err != nil { return err } @@ -126,7 +126,7 @@ func NewCmdEdit(f *cmdutil.Factory, runF func(*EditOptions) error) *cobra.Comman if flags.Changed("add-project") || flags.Changed("remove-project") { opts.Editable.Projects.Edited = true } - if flags.Changed("milestone") || opts.RemoveMilestone { + if flags.Changed("milestone") || opts.removeMilestone { opts.Editable.Milestone.Edited = true // Note that when `--remove-milestone` is provided, the value of @@ -164,7 +164,7 @@ func NewCmdEdit(f *cmdutil.Factory, runF func(*EditOptions) error) *cobra.Comman cmd.Flags().StringSliceVar(&opts.Editable.Projects.Add, "add-project", nil, "Add the pull request to projects by `name`") cmd.Flags().StringSliceVar(&opts.Editable.Projects.Remove, "remove-project", nil, "Remove the pull request from projects by `name`") cmd.Flags().StringVarP(&opts.Editable.Milestone.Value, "milestone", "m", "", "Edit the milestone the pull request belongs to by `name`") - cmd.Flags().BoolVar(&opts.RemoveMilestone, "remove-milestone", false, "Remove the milestone association from the pull request") + cmd.Flags().BoolVar(&removeMilestone, "remove-milestone", false, "Remove the milestone association from the pull request") _ = cmdutil.RegisterBranchCompletionFlags(f.GitClient, cmd, "base") From a73ae65ca81d9c3647725ec7e3391f196dfa49b1 Mon Sep 17 00:00:00 2001 From: "Babak K. Shandiz" Date: Mon, 29 Jul 2024 21:37:55 +0100 Subject: [PATCH 15/53] Use closure-scoped variable to catch `--remove-milestone` option Signed-off-by: Babak K. Shandiz --- pkg/cmd/issue/edit/edit.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/cmd/issue/edit/edit.go b/pkg/cmd/issue/edit/edit.go index de334148a..11a69383d 100644 --- a/pkg/cmd/issue/edit/edit.go +++ b/pkg/cmd/issue/edit/edit.go @@ -32,7 +32,6 @@ type EditOptions struct { Interactive bool prShared.Editable - RemoveMilestone bool } func NewCmdEdit(f *cmdutil.Factory, runF func(*EditOptions) error) *cobra.Command { @@ -47,6 +46,7 @@ func NewCmdEdit(f *cmdutil.Factory, runF func(*EditOptions) error) *cobra.Comman } var bodyFile string + var removeMilestone bool cmd := &cobra.Command{ Use: "edit { | }", @@ -100,7 +100,7 @@ func NewCmdEdit(f *cmdutil.Factory, runF func(*EditOptions) error) *cobra.Comman if err := cmdutil.MutuallyExclusive( "specify only one of `--milestone` or `--remove-milestone`", flags.Changed("milestone"), - opts.RemoveMilestone, + removeMilestone, ); err != nil { return err } @@ -117,7 +117,7 @@ func NewCmdEdit(f *cmdutil.Factory, runF func(*EditOptions) error) *cobra.Comman if flags.Changed("add-project") || flags.Changed("remove-project") { opts.Editable.Projects.Edited = true } - if flags.Changed("milestone") || opts.RemoveMilestone { + if flags.Changed("milestone") || removeMilestone { opts.Editable.Milestone.Edited = true // Note that when `--remove-milestone` is provided, the value of @@ -156,7 +156,7 @@ func NewCmdEdit(f *cmdutil.Factory, runF func(*EditOptions) error) *cobra.Comman cmd.Flags().StringSliceVar(&opts.Editable.Projects.Add, "add-project", nil, "Add the issue to projects by `name`") cmd.Flags().StringSliceVar(&opts.Editable.Projects.Remove, "remove-project", nil, "Remove the issue from projects by `name`") cmd.Flags().StringVarP(&opts.Editable.Milestone.Value, "milestone", "m", "", "Edit the milestone the issue belongs to by `name`") - cmd.Flags().BoolVar(&opts.RemoveMilestone, "remove-milestone", false, "Remove the milestone association from the issue") + cmd.Flags().BoolVar(&removeMilestone, "remove-milestone", false, "Remove the milestone association from the issue") return cmd } From 58e61967774d93e02d5a03946a4845f0ce1814be Mon Sep 17 00:00:00 2001 From: "Babak K. Shandiz" Date: Mon, 29 Jul 2024 21:41:43 +0100 Subject: [PATCH 16/53] Fix missing variable Signed-off-by: Babak K. Shandiz --- pkg/cmd/pr/edit/edit.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/cmd/pr/edit/edit.go b/pkg/cmd/pr/edit/edit.go index 21aa80c07..9dc190011 100644 --- a/pkg/cmd/pr/edit/edit.go +++ b/pkg/cmd/pr/edit/edit.go @@ -100,7 +100,7 @@ func NewCmdEdit(f *cmdutil.Factory, runF func(*EditOptions) error) *cobra.Comman if err := cmdutil.MutuallyExclusive( "specify only one of `--milestone` or `--remove-milestone`", flags.Changed("milestone"), - opts.removeMilestone, + removeMilestone, ); err != nil { return err } @@ -126,7 +126,7 @@ func NewCmdEdit(f *cmdutil.Factory, runF func(*EditOptions) error) *cobra.Comman if flags.Changed("add-project") || flags.Changed("remove-project") { opts.Editable.Projects.Edited = true } - if flags.Changed("milestone") || opts.removeMilestone { + if flags.Changed("milestone") || removeMilestone { opts.Editable.Milestone.Edited = true // Note that when `--remove-milestone` is provided, the value of From b9963809c2e56332b2facd6699d6054ed77ecc21 Mon Sep 17 00:00:00 2001 From: "Babak K. Shandiz" Date: Mon, 29 Jul 2024 23:25:34 +0100 Subject: [PATCH 17/53] Use signature-stripped tag annotation content Signed-off-by: Babak K. Shandiz --- pkg/cmd/release/create/create.go | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/pkg/cmd/release/create/create.go b/pkg/cmd/release/create/create.go index 1cfc5ba06..132e2c801 100644 --- a/pkg/cmd/release/create/create.go +++ b/pkg/cmd/release/create/create.go @@ -516,12 +516,32 @@ func createRun(opts *CreateOptions) error { } func gitTagInfo(client *git.Client, tagName string) (string, error) { - cmd, err := client.Command(context.Background(), "tag", "--list", tagName, "--format=%(contents:subject)%0a%0a%(contents:body)") + contentCmd, err := client.Command(context.Background(), "tag", "--list", tagName, "--format=%(contents)") if err != nil { return "", err } - b, err := cmd.Output() - return string(b), err + content, err := contentCmd.Output() + if err != nil { + return "", err + } + + signatureCmd, err := client.Command(context.Background(), "tag", "--list", tagName, "--format=%(contents:signature)") + if err != nil { + return "", err + } + signature, err := signatureCmd.Output() + if err != nil { + return "", err + } + + if len(signature) == 0 { + // The tag annotation content has no trailing signature to strip out, + // so we return the entire content. + return string(content), nil + } + + body, _ := strings.CutSuffix(string(content), "\n"+string(signature)) + return body, nil } func detectPreviousTag(client *git.Client, headRef string) (string, error) { From df3b0627fd697b30bffd1f11ad887b8795f4cf7d Mon Sep 17 00:00:00 2001 From: "Babak K. Shandiz" Date: Mon, 29 Jul 2024 23:26:03 +0100 Subject: [PATCH 18/53] Add test for `gitTagInfo` Signed-off-by: Babak K. Shandiz --- pkg/cmd/release/create/create_test.go | 76 +++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/pkg/cmd/release/create/create_test.go b/pkg/cmd/release/create/create_test.go index ed7d99c1e..a66bb5899 100644 --- a/pkg/cmd/release/create/create_test.go +++ b/pkg/cmd/release/create/create_test.go @@ -1751,6 +1751,82 @@ func Test_createRun_interactive(t *testing.T) { } } +func Test_gitTagInfo(t *testing.T) { + const tagName = "foo" + const contentCmd = "git tag --list foo --format=%\\(contents\\)" + const signatureCmd = "git tag --list foo --format=%\\(contents:signature\\)" + + tests := []struct { + name string + runStubs func(*run.CommandStubber) + wantErr string + wantResult string + }{ + { + name: "no signature", + runStubs: func(cs *run.CommandStubber) { + cs.Register(contentCmd, 0, "some\nmultiline\ncontent") + cs.Register(signatureCmd, 0, "") + }, + wantResult: "some\nmultiline\ncontent", + }, + { + name: "with signature", + runStubs: func(cs *run.CommandStubber) { + cs.Register(contentCmd, 0, "some\nmultiline\ncontent\n-----BEGIN SIGNATURE-----\nfoo\n-----END SIGNATURE-----") + cs.Register(signatureCmd, 0, "-----BEGIN SIGNATURE-----\nfoo\n-----END SIGNATURE-----") + }, + wantResult: "some\nmultiline\ncontent", + }, + { + name: "with signature in content but not as true signature", + runStubs: func(cs *run.CommandStubber) { + cs.Register(contentCmd, 0, "some\nmultiline\ncontent\n-----BEGIN SIGNATURE-----\nfoo\n-----END SIGNATURE-----") + cs.Register(signatureCmd, 0, "") + }, + wantResult: "some\nmultiline\ncontent\n-----BEGIN SIGNATURE-----\nfoo\n-----END SIGNATURE-----", + }, + { + name: "error getting content", + runStubs: func(cs *run.CommandStubber) { + cs.Register(contentCmd, 1, "some error") + }, + wantErr: fmt.Sprintf("failed to run git: %s exited with status 1", contentCmd), + }, + { + name: "error getting signature", + runStubs: func(cs *run.CommandStubber) { + cs.Register(contentCmd, 0, "whatever") + cs.Register(signatureCmd, 1, "some error") + }, + wantErr: fmt.Sprintf("failed to run git: %s exited with status 1", signatureCmd), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gitClient := &git.Client{GitPath: "some/path/git"} + + rs, teardown := run.Stub() + defer teardown(t) + if tt.runStubs != nil { + tt.runStubs(rs) + } + + result, err := gitTagInfo(gitClient, tagName) + + if tt.wantErr != "" { + require.EqualError(t, err, tt.wantErr) + return + } else { + require.NoError(t, err) + } + + assert.Equal(t, tt.wantResult, result) + }) + } +} + func boolPtr(b bool) *bool { return &b } From 46814b37598c9a0dc13f4345dc6152684af93172 Mon Sep 17 00:00:00 2001 From: "Babak K. Shandiz" Date: Mon, 29 Jul 2024 23:26:19 +0100 Subject: [PATCH 19/53] Add example for `--notes-from-tag` Signed-off-by: Babak K. Shandiz --- pkg/cmd/release/create/create.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkg/cmd/release/create/create.go b/pkg/cmd/release/create/create.go index 132e2c801..412c93328 100644 --- a/pkg/cmd/release/create/create.go +++ b/pkg/cmd/release/create/create.go @@ -115,6 +115,9 @@ func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Co Use release notes from a file $ gh release create v1.2.3 -F changelog.md + + Use annotated tag notes + $ gh release create v1.2.3 --notes-from-tag Don't mark the release as latest $ gh release create v1.2.3 --latest=false From 8ea1b8973a63ccd2fd503ff60bae51d5ee17f372 Mon Sep 17 00:00:00 2001 From: "Babak K. Shandiz" Date: Tue, 30 Jul 2024 00:21:19 +0100 Subject: [PATCH 20/53] Update tests with changes to `gitTagInfo` function Signed-off-by: Babak K. Shandiz --- pkg/cmd/release/create/create_test.go | 127 +++++++++++--------------- 1 file changed, 53 insertions(+), 74 deletions(-) diff --git a/pkg/cmd/release/create/create_test.go b/pkg/cmd/release/create/create_test.go index a66bb5899..6dd2b4844 100644 --- a/pkg/cmd/release/create/create_test.go +++ b/pkg/cmd/release/create/create_test.go @@ -412,6 +412,14 @@ func Test_NewCmdCreate(t *testing.T) { } func Test_createRun(t *testing.T) { + const contentCmd = `git tag --list .* --format=%\(contents\)` + const signatureCmd = `git tag --list .* --format=%\(contents:signature\)` + + defaultRunStubs := func(rs *run.CommandStubber) { + rs.Register(contentCmd, 0, "") + rs.Register(signatureCmd, 0, "") + } + tests := []struct { name string isTTY bool @@ -432,9 +440,7 @@ func Test_createRun(t *testing.T) { BodyProvided: true, Target: "", }, - runStubs: func(rs *run.CommandStubber) { - rs.Register(`git tag --list`, 0, "") - }, + runStubs: defaultRunStubs, httpStubs: func(t *testing.T, reg *httpmock.Registry) { reg.Register(httpmock.REST("POST", "repos/OWNER/REPO/releases"), httpmock.RESTPayload(201, `{ "url": "https://api.github.com/releases/123", @@ -464,9 +470,7 @@ func Test_createRun(t *testing.T) { Target: "", DiscussionCategory: "General", }, - runStubs: func(rs *run.CommandStubber) { - rs.Register(`git tag --list`, 0, "") - }, + runStubs: defaultRunStubs, httpStubs: func(t *testing.T, reg *httpmock.Registry) { reg.Register(httpmock.REST("POST", "repos/OWNER/REPO/releases"), httpmock.RESTPayload(201, `{ "url": "https://api.github.com/releases/123", @@ -496,9 +500,7 @@ func Test_createRun(t *testing.T) { BodyProvided: true, Target: "main", }, - runStubs: func(rs *run.CommandStubber) { - rs.Register(`git tag --list`, 0, "") - }, + runStubs: defaultRunStubs, httpStubs: func(t *testing.T, reg *httpmock.Registry) { reg.Register(httpmock.REST("POST", "repos/OWNER/REPO/releases"), httpmock.RESTPayload(201, `{ "url": "https://api.github.com/releases/123", @@ -527,9 +529,7 @@ func Test_createRun(t *testing.T) { Draft: true, Target: "", }, - runStubs: func(rs *run.CommandStubber) { - rs.Register(`git tag --list`, 0, "") - }, + runStubs: defaultRunStubs, httpStubs: func(t *testing.T, reg *httpmock.Registry) { reg.Register(httpmock.REST("POST", "repos/OWNER/REPO/releases"), httpmock.RESTPayload(201, `{ "url": "https://api.github.com/releases/123", @@ -558,9 +558,7 @@ func Test_createRun(t *testing.T) { BodyProvided: true, GenerateNotes: false, }, - runStubs: func(rs *run.CommandStubber) { - rs.Register(`git tag --list`, 0, "") - }, + runStubs: defaultRunStubs, httpStubs: func(t *testing.T, reg *httpmock.Registry) { reg.Register(httpmock.REST("POST", "repos/OWNER/REPO/releases"), httpmock.RESTPayload(201, `{ "url": "https://api.github.com/releases/123", @@ -589,9 +587,7 @@ func Test_createRun(t *testing.T) { BodyProvided: true, GenerateNotes: true, }, - runStubs: func(rs *run.CommandStubber) { - rs.Register(`git tag --list`, 0, "") - }, + runStubs: defaultRunStubs, httpStubs: func(t *testing.T, reg *httpmock.Registry) { reg.Register(httpmock.REST("POST", "repos/OWNER/REPO/releases"), httpmock.RESTPayload(201, `{ "url": "https://api.github.com/releases/123", @@ -621,9 +617,7 @@ func Test_createRun(t *testing.T) { GenerateNotes: true, NotesStartTag: "v1.1.0", }, - runStubs: func(rs *run.CommandStubber) { - rs.Register(`git tag --list`, 0, "") - }, + runStubs: defaultRunStubs, httpStubs: func(t *testing.T, reg *httpmock.Registry) { reg.Register(httpmock.REST("POST", "repos/OWNER/REPO/releases/generate-notes"), httpmock.RESTPayload(200, `{ @@ -664,9 +658,7 @@ func Test_createRun(t *testing.T) { GenerateNotes: true, NotesStartTag: "v1.1.0", }, - runStubs: func(rs *run.CommandStubber) { - rs.Register(`git tag --list`, 0, "") - }, + runStubs: defaultRunStubs, httpStubs: func(t *testing.T, reg *httpmock.Registry) { reg.Register(httpmock.REST("POST", "repos/OWNER/REPO/releases/generate-notes"), httpmock.RESTPayload(200, `{ @@ -715,9 +707,7 @@ func Test_createRun(t *testing.T) { }, Concurrency: 1, }, - runStubs: func(rs *run.CommandStubber) { - rs.Register(`git tag --list`, 0, "") - }, + runStubs: defaultRunStubs, httpStubs: func(t *testing.T, reg *httpmock.Registry) { reg.Register(httpmock.REST("HEAD", "repos/OWNER/REPO/releases/tags/v1.2.3"), httpmock.StatusStringResponse(404, ``)) reg.Register(httpmock.REST("POST", "repos/OWNER/REPO/releases"), httpmock.RESTPayload(201, `{ @@ -776,9 +766,7 @@ func Test_createRun(t *testing.T) { }, Concurrency: 1, }, - runStubs: func(rs *run.CommandStubber) { - rs.Register(`git tag --list`, 0, "") - }, + runStubs: defaultRunStubs, httpStubs: func(t *testing.T, reg *httpmock.Registry) { reg.Register(httpmock.REST("HEAD", "repos/OWNER/REPO/releases/tags/v1.2.3"), httpmock.StatusStringResponse(404, ``)) reg.Register(httpmock.REST("POST", "repos/OWNER/REPO/releases"), httpmock.RESTPayload(201, `{ @@ -838,9 +826,7 @@ func Test_createRun(t *testing.T) { }, Concurrency: 1, }, - runStubs: func(rs *run.CommandStubber) { - rs.Register(`git tag --list`, 0, "") - }, + runStubs: defaultRunStubs, httpStubs: func(t *testing.T, reg *httpmock.Registry) { reg.Register(httpmock.REST("HEAD", "repos/OWNER/REPO/releases/tags/v1.2.3"), httpmock.StatusStringResponse(200, ``)) }, @@ -868,9 +854,7 @@ func Test_createRun(t *testing.T) { }, Concurrency: 1, }, - runStubs: func(rs *run.CommandStubber) { - rs.Register(`git tag --list`, 0, "") - }, + runStubs: defaultRunStubs, httpStubs: func(t *testing.T, reg *httpmock.Registry) { reg.Register(httpmock.REST("HEAD", "repos/OWNER/REPO/releases/tags/v1.2.3"), httpmock.StatusStringResponse(404, ``)) reg.Register(httpmock.REST("POST", "repos/OWNER/REPO/releases"), httpmock.StatusStringResponse(201, `{ @@ -905,9 +889,7 @@ func Test_createRun(t *testing.T) { }, Concurrency: 1, }, - runStubs: func(rs *run.CommandStubber) { - rs.Register(`git tag --list`, 0, "") - }, + runStubs: defaultRunStubs, httpStubs: func(t *testing.T, reg *httpmock.Registry) { reg.Register(httpmock.REST("HEAD", "repos/OWNER/REPO/releases/tags/v1.2.3"), httpmock.StatusStringResponse(404, ``)) reg.Register(httpmock.REST("POST", "repos/OWNER/REPO/releases"), httpmock.StatusStringResponse(201, `{ @@ -943,9 +925,7 @@ func Test_createRun(t *testing.T) { }, Concurrency: 1, }, - runStubs: func(rs *run.CommandStubber) { - rs.Register(`git tag --list`, 0, "") - }, + runStubs: defaultRunStubs, httpStubs: func(t *testing.T, reg *httpmock.Registry) { reg.Register(httpmock.REST("HEAD", "repos/OWNER/REPO/releases/tags/v1.2.3"), httpmock.StatusStringResponse(200, ``)) }, @@ -974,9 +954,7 @@ func Test_createRun(t *testing.T) { DiscussionCategory: "general", Concurrency: 1, }, - runStubs: func(rs *run.CommandStubber) { - rs.Register(`git tag --list`, 0, "") - }, + runStubs: defaultRunStubs, httpStubs: func(t *testing.T, reg *httpmock.Registry) { reg.Register(httpmock.REST("HEAD", "repos/OWNER/REPO/releases/tags/v1.2.3"), httpmock.StatusStringResponse(404, ``)) reg.Register(httpmock.REST("POST", "repos/OWNER/REPO/releases"), httpmock.RESTPayload(201, `{ @@ -1027,7 +1005,8 @@ func Test_createRun(t *testing.T) { NotesFromTag: true, }, runStubs: func(rs *run.CommandStubber) { - rs.Register(`git tag --list`, 0, "some tag message") + rs.Register(contentCmd, 0, "some tag message") + rs.Register(signatureCmd, 0, "") }, httpStubs: func(t *testing.T, reg *httpmock.Registry) { reg.Register( @@ -1064,7 +1043,8 @@ func Test_createRun(t *testing.T) { NotesFromTag: true, }, runStubs: func(rs *run.CommandStubber) { - rs.Register(`git tag --list`, 0, "some tag message") + rs.Register(contentCmd, 0, "some tag message") + rs.Register(signatureCmd, 0, "") }, httpStubs: func(t *testing.T, reg *httpmock.Registry) { reg.Register( @@ -1099,10 +1079,8 @@ func Test_createRun(t *testing.T) { Assets: []*shared.AssetForUpload(nil), NotesFromTag: true, }, - runStubs: func(rs *run.CommandStubber) { - rs.Register(`git tag --list`, 0, "") - }, - wantErr: "cannot generate release notes from tag v1.2.3 as it does not exist locally", + runStubs: defaultRunStubs, + wantErr: "cannot generate release notes from tag v1.2.3 as it does not exist locally", }, } for _, tt := range tests { @@ -1149,6 +1127,13 @@ func Test_createRun(t *testing.T) { } func Test_createRun_interactive(t *testing.T) { + const contentCmd = `git tag --list .* --format=%\(contents\)` + const signatureCmd = `git tag --list .* --format=%\(contents:signature\)` + + defaultRunStubs := func(rs *run.CommandStubber) { + rs.Register(contentCmd, 1, "") + } + tests := []struct { name string httpStubs func(*httpmock.Registry) @@ -1185,9 +1170,7 @@ func Test_createRun_interactive(t *testing.T) { return false, nil }) }, - runStubs: func(rs *run.CommandStubber) { - rs.Register(`git tag --list`, 1, "") - }, + runStubs: defaultRunStubs, httpStubs: func(reg *httpmock.Registry) { reg.Register(httpmock.REST("GET", "repos/OWNER/REPO/tags"), httpmock.StatusStringResponse(200, `[ { "name": "v1.2.3" }, { "name": "v1.2.2" }, { "name": "v1.0.0" }, { "name": "v0.1.2" } @@ -1234,9 +1217,7 @@ func Test_createRun_interactive(t *testing.T) { return false, nil }) }, - runStubs: func(rs *run.CommandStubber) { - rs.Register(`git tag --list`, 1, "") - }, + runStubs: defaultRunStubs, httpStubs: func(reg *httpmock.Registry) { reg.Register(httpmock.REST("GET", "repos/OWNER/REPO/tags"), httpmock.StatusStringResponse(200, `[ { "name": "v1.2.2" }, { "name": "v1.0.0" }, { "name": "v0.1.2" } @@ -1283,9 +1264,7 @@ func Test_createRun_interactive(t *testing.T) { return false, nil }) }, - runStubs: func(rs *run.CommandStubber) { - rs.Register(`git tag --list`, 1, "") - }, + runStubs: defaultRunStubs, httpStubs: func(reg *httpmock.Registry) { reg.Register(httpmock.REST("GET", "repos/OWNER/REPO/tags"), httpmock.StatusStringResponse(200, `[ { "name": "v1.2.2" }, { "name": "v1.0.0" }, { "name": "v0.1.2" } @@ -1332,9 +1311,7 @@ func Test_createRun_interactive(t *testing.T) { return false, nil }) }, - runStubs: func(rs *run.CommandStubber) { - rs.Register(`git tag --list`, 1, "") - }, + runStubs: defaultRunStubs, httpStubs: func(reg *httpmock.Registry) { reg.Register(httpmock.REST("POST", "repos/OWNER/REPO/releases/generate-notes"), httpmock.StatusStringResponse(200, `{ @@ -1381,7 +1358,7 @@ func Test_createRun_interactive(t *testing.T) { }) }, runStubs: func(rs *run.CommandStubber) { - rs.Register(`git tag --list`, 1, "") + defaultRunStubs(rs) rs.Register(`git describe --tags --abbrev=0 HEAD\^`, 0, "v1.2.2\n") rs.Register(`git .+log .+v1\.2\.2\.\.HEAD$`, 0, "commit subject\n\ncommit body\n") }, @@ -1427,7 +1404,8 @@ func Test_createRun_interactive(t *testing.T) { }) }, runStubs: func(rs *run.CommandStubber) { - rs.Register(`git tag --list`, 0, "hello from annotated tag") + rs.Register(contentCmd, 0, "hello from annotated tag") + rs.Register(signatureCmd, 0, "") rs.Register(`git describe --tags --abbrev=0 v1\.2\.3\^`, 1, "") }, httpStubs: func(reg *httpmock.Registry) { @@ -1456,7 +1434,8 @@ func Test_createRun_interactive(t *testing.T) { TagName: "v1.2.3", }, runStubs: func(rs *run.CommandStubber) { - rs.Register(`git tag --list`, 0, "tag exists") + rs.Register(contentCmd, 0, "tag exists") + rs.Register(signatureCmd, 0, "") }, httpStubs: func(reg *httpmock.Registry) { reg.Register(httpmock.GraphQL("RepositoryFindRef"), @@ -1489,7 +1468,8 @@ func Test_createRun_interactive(t *testing.T) { }) }, runStubs: func(rs *run.CommandStubber) { - rs.Register(`git tag --list`, 0, "tag exists") + rs.Register(contentCmd, 0, "tag exists") + rs.Register(signatureCmd, 0, "") }, httpStubs: func(reg *httpmock.Registry) { reg.Register(httpmock.REST("POST", "repos/OWNER/REPO/releases/generate-notes"), @@ -1536,9 +1516,7 @@ func Test_createRun_interactive(t *testing.T) { return false, nil }) }, - runStubs: func(rs *run.CommandStubber) { - rs.Register(`git tag --list`, 1, "") - }, + runStubs: defaultRunStubs, httpStubs: func(reg *httpmock.Registry) { reg.Register(httpmock.REST("POST", "repos/OWNER/REPO/releases/generate-notes"), httpmock.RESTPayload(200, `{ @@ -1591,7 +1569,7 @@ func Test_createRun_interactive(t *testing.T) { }) }, runStubs: func(rs *run.CommandStubber) { - rs.Register(`git tag --list`, 1, "") + defaultRunStubs(rs) rs.Register(`git .+log .+v1\.1\.0\.\.HEAD$`, 0, "commit subject\n\ncommit body\n") }, httpStubs: func(reg *httpmock.Registry) { @@ -1639,7 +1617,8 @@ func Test_createRun_interactive(t *testing.T) { }) }, runStubs: func(rs *run.CommandStubber) { - rs.Register(`git tag --list`, 0, "tag exists") + rs.Register(contentCmd, 0, "tag exists") + rs.Register(signatureCmd, 0, "") }, httpStubs: func(reg *httpmock.Registry) { reg.Register(httpmock.GraphQL("RepositoryFindRef"), @@ -1753,8 +1732,8 @@ func Test_createRun_interactive(t *testing.T) { func Test_gitTagInfo(t *testing.T) { const tagName = "foo" - const contentCmd = "git tag --list foo --format=%\\(contents\\)" - const signatureCmd = "git tag --list foo --format=%\\(contents:signature\\)" + const contentCmd = `git tag --list foo --format=%\(contents\)` + const signatureCmd = `git tag --list foo --format=%\(contents:signature\)` tests := []struct { name string From dc4e9cb5323ebbad58030a4c3bdb3930e6c54547 Mon Sep 17 00:00:00 2001 From: ejahnGithub Date: Tue, 30 Jul 2024 12:11:25 -0700 Subject: [PATCH 21/53] handle attest case insensitivity --- .../attestation/verification/extensions.go | 27 +++++++++++++++++++ pkg/cmd/attestation/verify/policy.go | 17 ++++-------- pkg/cmd/attestation/verify/verify.go | 6 +++++ 3 files changed, 38 insertions(+), 12 deletions(-) create mode 100644 pkg/cmd/attestation/verification/extensions.go diff --git a/pkg/cmd/attestation/verification/extensions.go b/pkg/cmd/attestation/verification/extensions.go new file mode 100644 index 000000000..ffbefb9d3 --- /dev/null +++ b/pkg/cmd/attestation/verification/extensions.go @@ -0,0 +1,27 @@ +package verification + +import ( + "fmt" + "strings" +) + +func VerifyCertExtensions(results []*AttestationProcessingResult, owner string, repo string) error { + for _, attestation := range results { + if owner != "" { + expectedSourceRepositoryOwnerURI := fmt.Sprintf("https://github.com/%s", owner) + sourceRepositoryOwnerURI := attestation.VerificationResult.Signature.Certificate.Extensions.SourceRepositoryOwnerURI + if !strings.EqualFold(expectedSourceRepositoryOwnerURI, sourceRepositoryOwnerURI) { + return fmt.Errorf("expected SourceRepositoryOwnerURI to be %s, got %s", expectedSourceRepositoryOwnerURI, sourceRepositoryOwnerURI) + } + } + + if repo != "" { + expectedSourceRepositoryURI := fmt.Sprintf("https://github.com/%s", repo) + sourceRepositoryURI := attestation.VerificationResult.Signature.Certificate.Extensions.SourceRepositoryURI + if !strings.EqualFold(expectedSourceRepositoryURI, sourceRepositoryURI) { + return fmt.Errorf("expected SourceRepositoryURI to be %s, got %s", expectedSourceRepositoryURI, sourceRepositoryURI) + } + } + } + return nil +} diff --git a/pkg/cmd/attestation/verify/policy.go b/pkg/cmd/attestation/verify/policy.go index 959bd08a9..938e8048f 100644 --- a/pkg/cmd/attestation/verify/policy.go +++ b/pkg/cmd/attestation/verify/policy.go @@ -21,7 +21,7 @@ const ( ) func expandToGitHubURL(ownerOrRepo string) string { - return fmt.Sprintf("^https://github.com/%s/", ownerOrRepo) + return fmt.Sprintf("(?i)^https://github.com/%s/", ownerOrRepo) } func buildSANMatcher(opts *Options) (verify.SubjectAlternativeNameMatcher, error) { @@ -42,17 +42,10 @@ func buildSANMatcher(opts *Options) (verify.SubjectAlternativeNameMatcher, error return verify.SubjectAlternativeNameMatcher{}, nil } -func buildCertExtensions(opts *Options, runnerEnv string) certificate.Extensions { - extensions := certificate.Extensions{ - SourceRepositoryOwnerURI: fmt.Sprintf("https://github.com/%s", opts.Owner), - RunnerEnvironment: runnerEnv, +func buildCertExtensions(runnerEnv string) certificate.Extensions { + return certificate.Extensions{ + RunnerEnvironment: runnerEnv, } - - // if opts.Repo is set, set the SourceRepositoryURI field before returning the extensions - if opts.Repo != "" { - extensions.SourceRepositoryURI = fmt.Sprintf("https://github.com/%s", opts.Repo) - } - return extensions } func buildCertificateIdentityOption(opts *Options, runnerEnv string) (verify.PolicyOption, error) { @@ -66,7 +59,7 @@ func buildCertificateIdentityOption(opts *Options, runnerEnv string) (verify.Pol return nil, err } - extensions := buildCertExtensions(opts, runnerEnv) + extensions := buildCertExtensions(runnerEnv) certId, err := verify.NewCertificateIdentity(sanMatcher, issuerMatcher, extensions) if err != nil { diff --git a/pkg/cmd/attestation/verify/verify.go b/pkg/cmd/attestation/verify/verify.go index 16b9477e8..e1a5b1c50 100644 --- a/pkg/cmd/attestation/verify/verify.go +++ b/pkg/cmd/attestation/verify/verify.go @@ -235,6 +235,12 @@ func runVerify(opts *Options) error { return sigstoreRes.Error } + // Verify extensions + if err := verification.VerifyCertExtensions(sigstoreRes.VerifyResults, opts.Owner, opts.Repo); err != nil { + opts.Logger.Println(opts.Logger.ColorScheme.Red("āœ— Verification failed")) + return err + } + opts.Logger.Println(opts.Logger.ColorScheme.Green("āœ“ Verification succeeded!\n")) // If an exporter is provided with the --json flag, write the results to the terminal in JSON format From c1adb1a6cfcb932660dd852bb01284a4d836de85 Mon Sep 17 00:00:00 2001 From: ejahnGithub Date: Tue, 30 Jul 2024 12:24:27 -0700 Subject: [PATCH 22/53] added --- .../verification/extensions_test.go | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 pkg/cmd/attestation/verification/extensions_test.go diff --git a/pkg/cmd/attestation/verification/extensions_test.go b/pkg/cmd/attestation/verification/extensions_test.go new file mode 100644 index 000000000..829ebb231 --- /dev/null +++ b/pkg/cmd/attestation/verification/extensions_test.go @@ -0,0 +1,41 @@ +package verification + +import ( + "testing" + + "github.com/sigstore/sigstore-go/pkg/fulcio/certificate" + "github.com/sigstore/sigstore-go/pkg/verify" + "github.com/stretchr/testify/require" +) + +func TestVerifyCertExtensions(t *testing.T) { + results := []*AttestationProcessingResult{ + { + VerificationResult: &verify.VerificationResult{ + Signature: &verify.SignatureVerificationResult{ + Certificate: &certificate.Summary{ + Extensions: certificate.Extensions{ + SourceRepositoryOwnerURI: "https://github.com/owner", + SourceRepositoryURI: "https://github.com/owner/repo", + }, + }, + }, + }, + }, + } + + err := VerifyCertExtensions(results, "owner", "owner/repo") + require.NoError(t, err) + + err = VerifyCertExtensions(results, "", "owner/repo") + require.NoError(t, err) + + err = VerifyCertExtensions(results, "owner", "") + require.NoError(t, err) + + err = VerifyCertExtensions(results, "wrong", "") + require.ErrorContains(t, err, "expected SourceRepositoryOwnerURI to be https://github.com/wrong, got https://github.com/owner") + + err = VerifyCertExtensions(results, "", "wrong") + require.ErrorContains(t, err, "expected SourceRepositoryURI to be https://github.com/wrong, got https://github.com/owner/repo") +} From e21e5ef5c5d4fabc0848b3f52b8351f3d5fa0b74 Mon Sep 17 00:00:00 2001 From: ejahnGithub Date: Tue, 30 Jul 2024 13:09:28 -0700 Subject: [PATCH 23/53] update test --- .../attestation/verification/extensions.go | 4 +-- .../verification/extensions_test.go | 31 ++++++++++++------- pkg/cmd/attestation/verify/options_test.go | 4 +-- pkg/cmd/attestation/verify/verify_test.go | 16 +++++----- 4 files changed, 32 insertions(+), 23 deletions(-) diff --git a/pkg/cmd/attestation/verification/extensions.go b/pkg/cmd/attestation/verification/extensions.go index ffbefb9d3..cadb2668f 100644 --- a/pkg/cmd/attestation/verification/extensions.go +++ b/pkg/cmd/attestation/verification/extensions.go @@ -10,7 +10,7 @@ func VerifyCertExtensions(results []*AttestationProcessingResult, owner string, if owner != "" { expectedSourceRepositoryOwnerURI := fmt.Sprintf("https://github.com/%s", owner) sourceRepositoryOwnerURI := attestation.VerificationResult.Signature.Certificate.Extensions.SourceRepositoryOwnerURI - if !strings.EqualFold(expectedSourceRepositoryOwnerURI, sourceRepositoryOwnerURI) { + if sourceRepositoryOwnerURI != "" && !strings.EqualFold(expectedSourceRepositoryOwnerURI, sourceRepositoryOwnerURI) { return fmt.Errorf("expected SourceRepositoryOwnerURI to be %s, got %s", expectedSourceRepositoryOwnerURI, sourceRepositoryOwnerURI) } } @@ -18,7 +18,7 @@ func VerifyCertExtensions(results []*AttestationProcessingResult, owner string, if repo != "" { expectedSourceRepositoryURI := fmt.Sprintf("https://github.com/%s", repo) sourceRepositoryURI := attestation.VerificationResult.Signature.Certificate.Extensions.SourceRepositoryURI - if !strings.EqualFold(expectedSourceRepositoryURI, sourceRepositoryURI) { + if sourceRepositoryURI != "" && !strings.EqualFold(expectedSourceRepositoryURI, sourceRepositoryURI) { return fmt.Errorf("expected SourceRepositoryURI to be %s, got %s", expectedSourceRepositoryURI, sourceRepositoryURI) } } diff --git a/pkg/cmd/attestation/verification/extensions_test.go b/pkg/cmd/attestation/verification/extensions_test.go index 829ebb231..c04d29664 100644 --- a/pkg/cmd/attestation/verification/extensions_test.go +++ b/pkg/cmd/attestation/verification/extensions_test.go @@ -24,18 +24,27 @@ func TestVerifyCertExtensions(t *testing.T) { }, } - err := VerifyCertExtensions(results, "owner", "owner/repo") - require.NoError(t, err) + t.Run("VerifyCertExtensions with owner and repo", func(t *testing.T) { + err := VerifyCertExtensions(results, "owner", "owner/repo") + require.NoError(t, err) + }) + t.Run("VerifyCertExtensions with repo", func(t *testing.T) { + err := VerifyCertExtensions(results, "", "owner/repo") + require.NoError(t, err) + }) - err = VerifyCertExtensions(results, "", "owner/repo") - require.NoError(t, err) + t.Run("VerifyCertExtensions with owner", func(t *testing.T) { + err := VerifyCertExtensions(results, "owner", "") + require.NoError(t, err) + }) - err = VerifyCertExtensions(results, "owner", "") - require.NoError(t, err) + t.Run("VerifyCertExtensions with wrong owner", func(t *testing.T) { + err := VerifyCertExtensions(results, "wrong", "") + require.ErrorContains(t, err, "expected SourceRepositoryOwnerURI to be https://github.com/wrong, got https://github.com/owner") + }) - err = VerifyCertExtensions(results, "wrong", "") - require.ErrorContains(t, err, "expected SourceRepositoryOwnerURI to be https://github.com/wrong, got https://github.com/owner") - - err = VerifyCertExtensions(results, "", "wrong") - require.ErrorContains(t, err, "expected SourceRepositoryURI to be https://github.com/wrong, got https://github.com/owner/repo") + t.Run("VerifyCertExtensions with wrong repo", func(t *testing.T) { + err := VerifyCertExtensions(results, "", "wrong") + require.ErrorContains(t, err, "expected SourceRepositoryURI to be https://github.com/wrong, got https://github.com/owner/repo") + }) } diff --git a/pkg/cmd/attestation/verify/options_test.go b/pkg/cmd/attestation/verify/options_test.go index a7430017e..aea131b27 100644 --- a/pkg/cmd/attestation/verify/options_test.go +++ b/pkg/cmd/attestation/verify/options_test.go @@ -70,7 +70,7 @@ func TestSetPolicyFlags(t *testing.T) { opts.SetPolicyFlags() require.Equal(t, "sigstore", opts.Owner) require.Equal(t, "sigstore/sigstore-js", opts.Repo) - require.Equal(t, "^https://github.com/sigstore/sigstore-js/", opts.SANRegex) + require.Equal(t, "(?i)^https://github.com/sigstore/sigstore-js/", opts.SANRegex) }) t.Run("does not set SANRegex when SANRegex and Repo are provided", func(t *testing.T) { @@ -99,7 +99,7 @@ func TestSetPolicyFlags(t *testing.T) { opts.SetPolicyFlags() require.Equal(t, "sigstore", opts.Owner) - require.Equal(t, "^https://github.com/sigstore/", opts.SANRegex) + require.Equal(t, "(?i)^https://github.com/sigstore/", opts.SANRegex) }) t.Run("does not set SANRegex when SANRegex and Owner are provided", func(t *testing.T) { diff --git a/pkg/cmd/attestation/verify/verify_test.go b/pkg/cmd/attestation/verify/verify_test.go index f0cc21709..182a66012 100644 --- a/pkg/cmd/attestation/verify/verify_test.go +++ b/pkg/cmd/attestation/verify/verify_test.go @@ -76,7 +76,7 @@ func TestNewVerifyCmd(t *testing.T) { Limit: 30, OIDCIssuer: GitHubOIDCIssuer, Owner: "sigstore", - SANRegex: "^https://github.com/sigstore/", + SANRegex: "(?i)^https://github.com/sigstore/", SigstoreVerifier: verification.NewMockSigstoreVerifier(t), }, wantsErr: false, @@ -91,7 +91,7 @@ func TestNewVerifyCmd(t *testing.T) { Limit: 30, OIDCIssuer: GitHubOIDCIssuer, Owner: "sigstore", - SANRegex: "^https://github.com/sigstore/", + SANRegex: "(?i)^https://github.com/sigstore/", SigstoreVerifier: verification.NewMockSigstoreVerifier(t), }, wantsErr: false, @@ -105,7 +105,7 @@ func TestNewVerifyCmd(t *testing.T) { OIDCIssuer: GitHubOIDCIssuer, Owner: "sigstore", Limit: 30, - SANRegex: "^https://github.com/sigstore/", + SANRegex: "(?i)^https://github.com/sigstore/", SigstoreVerifier: verification.NewMockSigstoreVerifier(t), }, wantsErr: true, @@ -133,7 +133,7 @@ func TestNewVerifyCmd(t *testing.T) { Limit: 30, OIDCIssuer: GitHubOIDCIssuer, Owner: "sigstore", - SANRegex: "^https://github.com/sigstore/", + SANRegex: "(?i)^https://github.com/sigstore/", SigstoreVerifier: verification.NewMockSigstoreVerifier(t), }, wantsErr: false, @@ -147,7 +147,7 @@ func TestNewVerifyCmd(t *testing.T) { OIDCIssuer: GitHubOIDCIssuer, Owner: "sigstore", Limit: 101, - SANRegex: "^https://github.com/sigstore/", + SANRegex: "(?i)^https://github.com/sigstore/", SigstoreVerifier: verification.NewMockSigstoreVerifier(t), }, wantsErr: false, @@ -161,7 +161,7 @@ func TestNewVerifyCmd(t *testing.T) { OIDCIssuer: GitHubOIDCIssuer, Owner: "sigstore", Limit: 0, - SANRegex: "^https://github.com/sigstore/", + SANRegex: "(?i)^https://github.com/sigstore/", SigstoreVerifier: verification.NewMockSigstoreVerifier(t), }, wantsErr: true, @@ -176,7 +176,7 @@ func TestNewVerifyCmd(t *testing.T) { OIDCIssuer: GitHubOIDCIssuer, Owner: "sigstore", SAN: "https://github.com/sigstore/", - SANRegex: "^https://github.com/sigstore/", + SANRegex: "(?i)^https://github.com/sigstore/", SigstoreVerifier: verification.NewMockSigstoreVerifier(t), }, wantsErr: true, @@ -191,7 +191,7 @@ func TestNewVerifyCmd(t *testing.T) { Limit: 30, OIDCIssuer: GitHubOIDCIssuer, Owner: "sigstore", - SANRegex: "^https://github.com/sigstore/", + SANRegex: "(?i)^https://github.com/sigstore/", SigstoreVerifier: verification.NewMockSigstoreVerifier(t), }, wantsExporter: true, From 580ddf69979777481acd2b4d0cff92eb8795a204 Mon Sep 17 00:00:00 2001 From: ejahnGithub Date: Tue, 30 Jul 2024 13:14:16 -0700 Subject: [PATCH 24/53] minor fix --- pkg/cmd/attestation/verification/extensions.go | 13 +++++++------ pkg/cmd/attestation/verify/policy.go | 11 ++++------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/pkg/cmd/attestation/verification/extensions.go b/pkg/cmd/attestation/verification/extensions.go index cadb2668f..6d093a5d7 100644 --- a/pkg/cmd/attestation/verification/extensions.go +++ b/pkg/cmd/attestation/verification/extensions.go @@ -7,15 +7,16 @@ import ( func VerifyCertExtensions(results []*AttestationProcessingResult, owner string, repo string) error { for _, attestation := range results { - if owner != "" { - expectedSourceRepositoryOwnerURI := fmt.Sprintf("https://github.com/%s", owner) - sourceRepositoryOwnerURI := attestation.VerificationResult.Signature.Certificate.Extensions.SourceRepositoryOwnerURI - if sourceRepositoryOwnerURI != "" && !strings.EqualFold(expectedSourceRepositoryOwnerURI, sourceRepositoryOwnerURI) { - return fmt.Errorf("expected SourceRepositoryOwnerURI to be %s, got %s", expectedSourceRepositoryOwnerURI, sourceRepositoryOwnerURI) - } + // TODO: handle proxima prefix + expectedSourceRepositoryOwnerURI := fmt.Sprintf("https://github.com/%s", owner) + sourceRepositoryOwnerURI := attestation.VerificationResult.Signature.Certificate.Extensions.SourceRepositoryOwnerURI + if sourceRepositoryOwnerURI != "" && !strings.EqualFold(expectedSourceRepositoryOwnerURI, sourceRepositoryOwnerURI) { + return fmt.Errorf("expected SourceRepositoryOwnerURI to be %s, got %s", expectedSourceRepositoryOwnerURI, sourceRepositoryOwnerURI) } + // if repo is set, check the SourceRepositoryURI field if repo != "" { + // TODO: handle proxima prefix expectedSourceRepositoryURI := fmt.Sprintf("https://github.com/%s", repo) sourceRepositoryURI := attestation.VerificationResult.Signature.Certificate.Extensions.SourceRepositoryURI if sourceRepositoryURI != "" && !strings.EqualFold(expectedSourceRepositoryURI, sourceRepositoryURI) { diff --git a/pkg/cmd/attestation/verify/policy.go b/pkg/cmd/attestation/verify/policy.go index 938e8048f..4d850ddcc 100644 --- a/pkg/cmd/attestation/verify/policy.go +++ b/pkg/cmd/attestation/verify/policy.go @@ -21,6 +21,7 @@ const ( ) func expandToGitHubURL(ownerOrRepo string) string { + // TODO: handle proxima prefix return fmt.Sprintf("(?i)^https://github.com/%s/", ownerOrRepo) } @@ -42,12 +43,6 @@ func buildSANMatcher(opts *Options) (verify.SubjectAlternativeNameMatcher, error return verify.SubjectAlternativeNameMatcher{}, nil } -func buildCertExtensions(runnerEnv string) certificate.Extensions { - return certificate.Extensions{ - RunnerEnvironment: runnerEnv, - } -} - func buildCertificateIdentityOption(opts *Options, runnerEnv string) (verify.PolicyOption, error) { sanMatcher, err := buildSANMatcher(opts) if err != nil { @@ -59,7 +54,9 @@ func buildCertificateIdentityOption(opts *Options, runnerEnv string) (verify.Pol return nil, err } - extensions := buildCertExtensions(runnerEnv) + extensions := certificate.Extensions{ + RunnerEnvironment: runnerEnv, + } certId, err := verify.NewCertificateIdentity(sanMatcher, issuerMatcher, extensions) if err != nil { From 596ee8bd7116c659e3cba95a792d327171732f15 Mon Sep 17 00:00:00 2001 From: ejahnGithub Date: Tue, 30 Jul 2024 13:22:49 -0700 Subject: [PATCH 25/53] update test --- pkg/cmd/attestation/verification/extensions_test.go | 6 +----- pkg/cmd/attestation/verify/verify_integration_test.go | 6 +++--- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/pkg/cmd/attestation/verification/extensions_test.go b/pkg/cmd/attestation/verification/extensions_test.go index c04d29664..7aec4ec45 100644 --- a/pkg/cmd/attestation/verification/extensions_test.go +++ b/pkg/cmd/attestation/verification/extensions_test.go @@ -28,10 +28,6 @@ func TestVerifyCertExtensions(t *testing.T) { err := VerifyCertExtensions(results, "owner", "owner/repo") require.NoError(t, err) }) - t.Run("VerifyCertExtensions with repo", func(t *testing.T) { - err := VerifyCertExtensions(results, "", "owner/repo") - require.NoError(t, err) - }) t.Run("VerifyCertExtensions with owner", func(t *testing.T) { err := VerifyCertExtensions(results, "owner", "") @@ -44,7 +40,7 @@ func TestVerifyCertExtensions(t *testing.T) { }) t.Run("VerifyCertExtensions with wrong repo", func(t *testing.T) { - err := VerifyCertExtensions(results, "", "wrong") + err := VerifyCertExtensions(results, "owner", "wrong") require.ErrorContains(t, err, "expected SourceRepositoryURI to be https://github.com/wrong, got https://github.com/owner/repo") }) } diff --git a/pkg/cmd/attestation/verify/verify_integration_test.go b/pkg/cmd/attestation/verify/verify_integration_test.go index 6833043b8..9ad7a87a3 100644 --- a/pkg/cmd/attestation/verify/verify_integration_test.go +++ b/pkg/cmd/attestation/verify/verify_integration_test.go @@ -60,7 +60,7 @@ func TestVerifyIntegration(t *testing.T) { err := runVerify(&opts) require.Error(t, err) - require.ErrorContains(t, err, "verifying with issuer \"sigstore.dev\": failed to verify certificate identity: no matching CertificateIdentity found, last error: expected SourceRepositoryURI to be \"https://github.com/sigstore/fakerepo\", got \"https://github.com/sigstore/sigstore-js\"") + require.ErrorContains(t, err, "expected SourceRepositoryURI to be https://github.com/sigstore/fakerepo, got https://github.com/sigstore/sigstore-js") }) t.Run("with invalid owner", func(t *testing.T) { @@ -69,7 +69,7 @@ func TestVerifyIntegration(t *testing.T) { err := runVerify(&opts) require.Error(t, err) - require.ErrorContains(t, err, "verifying with issuer \"sigstore.dev\": failed to verify certificate identity: no matching CertificateIdentity found, last error: expected SourceRepositoryOwnerURI to be \"https://github.com/fakeowner\", got \"https://github.com/sigstore\"") + require.ErrorContains(t, err, "expected SourceRepositoryOwnerURI to be https://github.com/fakeowner, got https://github.com/sigstore") }) t.Run("with invalid owner and invalid repo", func(t *testing.T) { @@ -78,7 +78,7 @@ func TestVerifyIntegration(t *testing.T) { err := runVerify(&opts) require.Error(t, err) - require.ErrorContains(t, err, "verifying with issuer \"sigstore.dev\": failed to verify certificate identity: no matching CertificateIdentity found, last error: expected SourceRepositoryURI to be \"https://github.com/fakeowner/fakerepo\"") + require.ErrorContains(t, err, "expected SourceRepositoryURI to be https://github.com/fakeowner/fakerepo, got https://github.com/sigstore/sigstore-js") }) } From 1eaf712dd13c976b5225279a5e7e66564a7f03f1 Mon Sep 17 00:00:00 2001 From: ejahnGithub Date: Wed, 31 Jul 2024 07:29:43 -0700 Subject: [PATCH 26/53] update test and remove logic to check SourceRepositoryOwnerURI is empty string --- .../attestation/verification/extensions.go | 4 ++-- .../attestation/verification/mock_verifier.go | 4 +++- pkg/cmd/attestation/verify/verify_test.go | 20 ++++++++++++++++++- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/pkg/cmd/attestation/verification/extensions.go b/pkg/cmd/attestation/verification/extensions.go index 6d093a5d7..1915152dc 100644 --- a/pkg/cmd/attestation/verification/extensions.go +++ b/pkg/cmd/attestation/verification/extensions.go @@ -10,7 +10,7 @@ func VerifyCertExtensions(results []*AttestationProcessingResult, owner string, // TODO: handle proxima prefix expectedSourceRepositoryOwnerURI := fmt.Sprintf("https://github.com/%s", owner) sourceRepositoryOwnerURI := attestation.VerificationResult.Signature.Certificate.Extensions.SourceRepositoryOwnerURI - if sourceRepositoryOwnerURI != "" && !strings.EqualFold(expectedSourceRepositoryOwnerURI, sourceRepositoryOwnerURI) { + if !strings.EqualFold(expectedSourceRepositoryOwnerURI, sourceRepositoryOwnerURI) { return fmt.Errorf("expected SourceRepositoryOwnerURI to be %s, got %s", expectedSourceRepositoryOwnerURI, sourceRepositoryOwnerURI) } @@ -19,7 +19,7 @@ func VerifyCertExtensions(results []*AttestationProcessingResult, owner string, // TODO: handle proxima prefix expectedSourceRepositoryURI := fmt.Sprintf("https://github.com/%s", repo) sourceRepositoryURI := attestation.VerificationResult.Signature.Certificate.Extensions.SourceRepositoryURI - if sourceRepositoryURI != "" && !strings.EqualFold(expectedSourceRepositoryURI, sourceRepositoryURI) { + if !strings.EqualFold(expectedSourceRepositoryURI, sourceRepositoryURI) { return fmt.Errorf("expected SourceRepositoryURI to be %s, got %s", expectedSourceRepositoryURI, sourceRepositoryURI) } } diff --git a/pkg/cmd/attestation/verification/mock_verifier.go b/pkg/cmd/attestation/verification/mock_verifier.go index a8579b578..dcbfb1ba2 100644 --- a/pkg/cmd/attestation/verification/mock_verifier.go +++ b/pkg/cmd/attestation/verification/mock_verifier.go @@ -31,7 +31,9 @@ func (v *MockSigstoreVerifier) Verify(attestations []*api.Attestation, policy ve Signature: &verify.SignatureVerificationResult{ Certificate: &certificate.Summary{ Extensions: certificate.Extensions{ - BuildSignerURI: "https://github.com/github/example/.github/workflows/release.yml@refs/heads/main", + BuildSignerURI: "https://github.com/github/example/.github/workflows/release.yml@refs/heads/main", + SourceRepositoryOwnerURI: "https://github.com/sigstore", + SourceRepositoryURI: "https://github.com/sigstore/sigstore-js", }, }, }, diff --git a/pkg/cmd/attestation/verify/verify_test.go b/pkg/cmd/attestation/verify/verify_test.go index 182a66012..8d06617f3 100644 --- a/pkg/cmd/attestation/verify/verify_test.go +++ b/pkg/cmd/attestation/verify/verify_test.go @@ -340,14 +340,32 @@ func TestRunVerify(t *testing.T) { require.Nil(t, runVerify(&opts)) }) + t.Run("with owner which not matches SourceRepositoryOwnerURI", func(t *testing.T) { + opts := publicGoodOpts + opts.BundlePath = "" + opts.Owner = "owner" + + err := runVerify(&opts) + require.ErrorContains(t, err, "expected SourceRepositoryOwnerURI to be https://github.com/owner, got https://github.com/sigstore") + }) + t.Run("with repo", func(t *testing.T) { opts := publicGoodOpts opts.BundlePath = "" - opts.Repo = "github/example" + opts.Repo = "sigstore/sigstore-js" require.Nil(t, runVerify(&opts)) }) + t.Run("with repo which not matches SourceRepositoryURI", func(t *testing.T) { + opts := publicGoodOpts + opts.BundlePath = "" + opts.Repo = "wrong/example" + + err := runVerify(&opts) + require.ErrorContains(t, err, "expected SourceRepositoryURI to be https://github.com/wrong/example, got https://github.com/sigstore/sigstore-js") + }) + t.Run("with invalid repo", func(t *testing.T) { opts := publicGoodOpts opts.BundlePath = "" From ad96ad3580a9503389745f460d45ffe1a1857802 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 31 Jul 2024 14:55:39 +0000 Subject: [PATCH 27/53] build(deps): bump actions/attest-build-provenance from 1.3.3 to 1.4.0 Bumps [actions/attest-build-provenance](https://github.com/actions/attest-build-provenance) from 1.3.3 to 1.4.0. - [Release notes](https://github.com/actions/attest-build-provenance/releases) - [Changelog](https://github.com/actions/attest-build-provenance/blob/main/RELEASE.md) - [Commits](https://github.com/actions/attest-build-provenance/compare/5e9cb68e95676991667494a6a4e59b8a2f13e1d0...210c1913531870065f03ce1f9440dd87bc0938cd) --- updated-dependencies: - dependency-name: actions/attest-build-provenance dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/deployment.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deployment.yml b/.github/workflows/deployment.yml index 2e87e2429..564eb647c 100644 --- a/.github/workflows/deployment.yml +++ b/.github/workflows/deployment.yml @@ -299,7 +299,7 @@ jobs: rpmsign --addsign dist/*.rpm - name: Attest release artifacts if: inputs.environment == 'production' - uses: actions/attest-build-provenance@5e9cb68e95676991667494a6a4e59b8a2f13e1d0 # v1.3.3 + uses: actions/attest-build-provenance@210c1913531870065f03ce1f9440dd87bc0938cd # v1.4.0 with: subject-path: "dist/gh_*" - name: Run createrepo From 22a5a4c899cec911152cbb27acb539ee7505655d Mon Sep 17 00:00:00 2001 From: Andy Feller Date: Fri, 2 Aug 2024 10:36:32 -0400 Subject: [PATCH 28/53] Update `gh variable get` to use repo host Closes #9274 This change addresses a bug where repository and repository environment variables are not being retrieved from the appropriate host, causing GHES users to fail without specifying `GH_HOST` to force `gh variable set` to do the right thing. In addition, the tests for this command have been updated to check both github.com and GHES variations to ensure this works. --- pkg/cmd/variable/get/get.go | 24 +++++++++++--------- pkg/cmd/variable/get/get_test.go | 39 ++++++++++++++++++++++++++++++-- pkg/httpmock/stub.go | 9 ++++++++ 3 files changed, 59 insertions(+), 13 deletions(-) diff --git a/pkg/cmd/variable/get/get.go b/pkg/cmd/variable/get/get.go index 32b4c5e62..e4def5a03 100644 --- a/pkg/cmd/variable/get/get.go +++ b/pkg/cmd/variable/get/get.go @@ -92,22 +92,24 @@ func getRun(opts *GetOptions) error { } } - var path string - switch variableEntity { - case shared.Organization: - path = fmt.Sprintf("orgs/%s/actions/variables/%s", orgName, opts.VariableName) - case shared.Environment: - path = fmt.Sprintf("repos/%s/environments/%s/variables/%s", ghrepo.FullName(baseRepo), envName, opts.VariableName) - case shared.Repository: - path = fmt.Sprintf("repos/%s/actions/variables/%s", ghrepo.FullName(baseRepo), opts.VariableName) - } - cfg, err := opts.Config() if err != nil { return err } - host, _ := cfg.Authentication().DefaultHost() + var path string + var host string + switch variableEntity { + case shared.Organization: + path = fmt.Sprintf("orgs/%s/actions/variables/%s", orgName, opts.VariableName) + host, _ = cfg.Authentication().DefaultHost() + case shared.Environment: + path = fmt.Sprintf("repos/%s/environments/%s/variables/%s", ghrepo.FullName(baseRepo), envName, opts.VariableName) + host = baseRepo.RepoHost() + case shared.Repository: + path = fmt.Sprintf("repos/%s/actions/variables/%s", ghrepo.FullName(baseRepo), opts.VariableName) + host = baseRepo.RepoHost() + } var variable shared.Variable if err = client.REST(host, "GET", path, nil, &variable); err != nil { diff --git a/pkg/cmd/variable/get/get_test.go b/pkg/cmd/variable/get/get_test.go index 4a03beb6a..e85910152 100644 --- a/pkg/cmd/variable/get/get_test.go +++ b/pkg/cmd/variable/get/get_test.go @@ -110,6 +110,7 @@ func Test_getRun(t *testing.T) { tests := []struct { name string opts *GetOptions + host string httpStubs func(*httpmock.Registry) jsonFields []string wantOut string @@ -120,8 +121,23 @@ func Test_getRun(t *testing.T) { opts: &GetOptions{ VariableName: "VARIABLE_ONE", }, + host: "github.com", httpStubs: func(reg *httpmock.Registry) { - reg.Register(httpmock.REST("GET", "repos/owner/repo/actions/variables/VARIABLE_ONE"), + reg.Register(httpmock.WithHost(httpmock.REST("GET", "repos/owner/repo/actions/variables/VARIABLE_ONE"), "api.github.com"), + httpmock.JSONResponse(shared.Variable{ + Value: "repo_var", + })) + }, + wantOut: "repo_var\n", + }, + { + name: "getting GHES repo variable", + opts: &GetOptions{ + VariableName: "VARIABLE_ONE", + }, + host: "ghe.io", + httpStubs: func(reg *httpmock.Registry) { + reg.Register(httpmock.WithHost(httpmock.REST("GET", "api/v3/repos/owner/repo/actions/variables/VARIABLE_ONE"), "ghe.io"), httpmock.JSONResponse(shared.Variable{ Value: "repo_var", })) @@ -148,8 +164,24 @@ func Test_getRun(t *testing.T) { EnvName: "Development", VariableName: "VARIABLE_ONE", }, + host: "github.com", httpStubs: func(reg *httpmock.Registry) { - reg.Register(httpmock.REST("GET", "repos/owner/repo/environments/Development/variables/VARIABLE_ONE"), + reg.Register(httpmock.WithHost(httpmock.REST("GET", "repos/owner/repo/environments/Development/variables/VARIABLE_ONE"), "api.github.com"), + httpmock.JSONResponse(shared.Variable{ + Value: "env_var", + })) + }, + wantOut: "env_var\n", + }, + { + name: "getting GHES env variable", + opts: &GetOptions{ + EnvName: "Development", + VariableName: "VARIABLE_ONE", + }, + host: "ghe.io", + httpStubs: func(reg *httpmock.Registry) { + reg.Register(httpmock.WithHost(httpmock.REST("GET", "api/v3/repos/owner/repo/environments/Development/variables/VARIABLE_ONE"), "ghe.io"), httpmock.JSONResponse(shared.Variable{ Value: "env_var", })) @@ -226,6 +258,9 @@ func Test_getRun(t *testing.T) { tt.opts.IO = ios tt.opts.BaseRepo = func() (ghrepo.Interface, error) { + if tt.host != "" { + return ghrepo.FromFullNameWithHost("owner/repo", tt.host) + } return ghrepo.FromFullName("owner/repo") } tt.opts.HttpClient = func() (*http.Client, error) { diff --git a/pkg/httpmock/stub.go b/pkg/httpmock/stub.go index 147d36fc8..e7534d7f8 100644 --- a/pkg/httpmock/stub.go +++ b/pkg/httpmock/stub.go @@ -123,6 +123,15 @@ func StringResponse(body string) Responder { } } +func WithHost(matcher Matcher, host string) Matcher { + return func(req *http.Request) bool { + if !strings.EqualFold(req.Host, host) { + return false + } + return matcher(req) + } +} + func WithHeader(responder Responder, header string, value string) Responder { return func(req *http.Request) (*http.Response, error) { resp, _ := responder(req) From d7b8ecf33dee8b0582e2514d9821e6225c58ab7c Mon Sep 17 00:00:00 2001 From: Yukai Chou Date: Fri, 2 Aug 2024 03:55:20 +0800 Subject: [PATCH 29/53] Unify use of tab indent in non-test source files Found with rg '(^ | \t|\t )' -g '*.go' -g '!*_test.go' Mixed indent exceptions: - wrapped long list items with extra 2-space indent - code snippets using space indent - commented code lines having "\t*// \t+" prefix --- api/queries_issue.go | 2 +- api/query_builder.go | 8 +- pkg/cmd/attestation/attestation.go | 2 +- .../attestation/trustedroot/trustedroot.go | 24 +++--- pkg/cmd/codespace/ssh.go | 2 +- pkg/cmd/pr/list/list.go | 2 +- pkg/cmd/pr/merge/merge.go | 2 +- pkg/cmd/pr/status/http.go | 34 ++++---- pkg/cmd/release/create/create.go | 2 +- pkg/cmd/repo/create/create.go | 2 +- pkg/cmd/repo/credits/credits.go | 18 ++--- pkg/cmd/root/help_topic.go | 79 +++++++++---------- pkg/cmd/run/download/download.go | 16 ++-- pkg/cmd/run/list/list.go | 2 +- pkg/cmd/search/commits/commits.go | 4 +- pkg/cmd/search/issues/issues.go | 5 +- pkg/cmd/search/prs/prs.go | 4 +- pkg/cmd/search/repos/repos.go | 4 +- pkg/cmd/variable/variable.go | 2 +- pkg/cmd/workflow/run/run.go | 2 +- pkg/cmd/workflow/view/view.go | 8 +- pkg/surveyext/editor.go | 6 +- 22 files changed, 114 insertions(+), 116 deletions(-) diff --git a/api/queries_issue.go b/api/queries_issue.go index 62531e84e..094b6b198 100644 --- a/api/queries_issue.go +++ b/api/queries_issue.go @@ -286,7 +286,7 @@ func IssueStatus(client *Client, repo ghrepo.Interface, options IssueStatusOptio } } } - }` + }` variables := map[string]interface{}{ "owner": repo.RepoOwner(), diff --git a/api/query_builder.go b/api/query_builder.go index 30dbeb869..755179396 100644 --- a/api/query_builder.go +++ b/api/query_builder.go @@ -152,13 +152,13 @@ func StatusCheckRollupGraphQLWithCountByState() string { contexts { checkRunCount, checkRunCountsByState { - state, - count + state, + count }, statusContextCount, statusContextCountsByState { - state, - count + state, + count } } } diff --git a/pkg/cmd/attestation/attestation.go b/pkg/cmd/attestation/attestation.go index ea1e0c08c..a6229e636 100644 --- a/pkg/cmd/attestation/attestation.go +++ b/pkg/cmd/attestation/attestation.go @@ -18,7 +18,7 @@ func NewCmdAttestation(f *cmdutil.Factory) *cobra.Command { Aliases: []string{"at"}, Long: heredoc.Doc(` Download and verify artifact attestations. - `), + `), } root.AddCommand(download.NewDownloadCmd(f, nil)) diff --git a/pkg/cmd/attestation/trustedroot/trustedroot.go b/pkg/cmd/attestation/trustedroot/trustedroot.go index 09ab9a6c9..e28ceab62 100644 --- a/pkg/cmd/attestation/trustedroot/trustedroot.go +++ b/pkg/cmd/attestation/trustedroot/trustedroot.go @@ -32,22 +32,22 @@ func NewTrustedRootCmd(f *cmdutil.Factory, runF func(*Options) error) *cobra.Com Long: heredoc.Docf(` ### NOTE: This feature is currently in beta, and subject to change. - Output contents for a trusted_root.jsonl file, likely for offline verification. + Output contents for a trusted_root.jsonl file, likely for offline verification. - When using %[1]sgh attestation verify%[1]s, if your machine is on the internet, - this will happen automatically. But to do offline verification, you need to - supply a trusted root file with %[1]s--custom-trusted-root%[1]s; this command - will help you fetch a %[1]strusted_root.jsonl%[1]s file for that purpose. + When using %[1]sgh attestation verify%[1]s, if your machine is on the internet, + this will happen automatically. But to do offline verification, you need to + supply a trusted root file with %[1]s--custom-trusted-root%[1]s; this command + will help you fetch a %[1]strusted_root.jsonl%[1]s file for that purpose. - You can call this command without any flags to get a trusted root file covering - the Sigstore Public Good Instance as well as GitHub's Sigstore instance. + You can call this command without any flags to get a trusted root file covering + the Sigstore Public Good Instance as well as GitHub's Sigstore instance. - Otherwise you can use %[1]s--tuf-url%[1]s to specify the URL of a custom TUF - repository mirror, and %[1]s--tuf-root%[1]s should be the path to the - %[1]sroot.json%[1]s file that you securely obtained out-of-band. + Otherwise you can use %[1]s--tuf-url%[1]s to specify the URL of a custom TUF + repository mirror, and %[1]s--tuf-root%[1]s should be the path to the + %[1]sroot.json%[1]s file that you securely obtained out-of-band. - If you just want to verify the integrity of your local TUF repository, and don't - want the contents of a trusted_root.jsonl file, use %[1]s--verify-only%[1]s. + If you just want to verify the integrity of your local TUF repository, and don't + want the contents of a trusted_root.jsonl file, use %[1]s--verify-only%[1]s. `, "`"), Example: heredoc.Doc(` # Get a trusted_root.jsonl for both Sigstore Public Good and GitHub's instance diff --git a/pkg/cmd/codespace/ssh.go b/pkg/cmd/codespace/ssh.go index 571f74267..c6c3943e2 100644 --- a/pkg/cmd/codespace/ssh.go +++ b/pkg/cmd/codespace/ssh.go @@ -60,7 +60,7 @@ func newSSHCmd(app *App) *cobra.Command { The %[1]sssh%[1]s command will automatically create a public/private ssh key pair in the %[1]s~/.ssh%[1]s directory if you do not have an existing valid key pair. When selecting the key pair to use, the preferred order is: - + 1. Key specified by %[1]s-i%[1]s in %[1]s%[1]s 2. Automatic key, if it already exists 3. First valid key pair in ssh config (according to %[1]sssh -G%[1]s) diff --git a/pkg/cmd/pr/list/list.go b/pkg/cmd/pr/list/list.go index 7721ecc1b..93a9b8b4b 100644 --- a/pkg/cmd/pr/list/list.go +++ b/pkg/cmd/pr/list/list.go @@ -72,7 +72,7 @@ func NewCmdList(f *cmdutil.Factory, runF func(*ListOptions) error) *cobra.Comman Find a PR that introduced a given commit $ gh pr list --search "" --state merged - `), + `), Aliases: []string{"ls"}, Args: cmdutil.NoArgsQuoteReminder, RunE: func(cmd *cobra.Command, args []string) error { diff --git a/pkg/cmd/pr/merge/merge.go b/pkg/cmd/pr/merge/merge.go index 1e7deabcb..e3d1a14ee 100644 --- a/pkg/cmd/pr/merge/merge.go +++ b/pkg/cmd/pr/merge/merge.go @@ -88,7 +88,7 @@ func NewCmdMerge(f *cmdutil.Factory, runF func(*MergeOptions) error) *cobra.Comm If required checks have not yet passed, auto-merge will be enabled. If required checks have passed, the pull request will be added to the merge queue. To bypass a merge queue and merge directly, pass the %[1]s--admin%[1]s flag. - `, "`"), + `, "`"), Args: cobra.MaximumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { opts.Finder = shared.NewFinder(f) diff --git a/pkg/cmd/pr/status/http.go b/pkg/cmd/pr/status/http.go index bd7eb6a78..1eb12ed74 100644 --- a/pkg/cmd/pr/status/http.go +++ b/pkg/cmd/pr/status/http.go @@ -101,23 +101,23 @@ func pullRequestStatus(httpClient *http.Client, repo ghrepo.Interface, options r } query := fragments + queryPrefix + ` - viewerCreated: search(query: $viewerQuery, type: ISSUE, first: $per_page) { - totalCount: issueCount - edges { - node { - ...prWithReviews - } - } - } - reviewRequested: search(query: $reviewerQuery, type: ISSUE, first: $per_page) { - totalCount: issueCount - edges { - node { - ...pr - } - } - } - } + viewerCreated: search(query: $viewerQuery, type: ISSUE, first: $per_page) { + totalCount: issueCount + edges { + node { + ...prWithReviews + } + } + } + reviewRequested: search(query: $reviewerQuery, type: ISSUE, first: $per_page) { + totalCount: issueCount + edges { + node { + ...pr + } + } + } + } ` currentUsername := options.Username diff --git a/pkg/cmd/release/create/create.go b/pkg/cmd/release/create/create.go index 1cfc5ba06..95453250e 100644 --- a/pkg/cmd/release/create/create.go +++ b/pkg/cmd/release/create/create.go @@ -115,7 +115,7 @@ func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Co Use release notes from a file $ gh release create v1.2.3 -F changelog.md - + Don't mark the release as latest $ gh release create v1.2.3 --latest=false diff --git a/pkg/cmd/repo/create/create.go b/pkg/cmd/repo/create/create.go index 05e8909e1..9074ea117 100644 --- a/pkg/cmd/repo/create/create.go +++ b/pkg/cmd/repo/create/create.go @@ -88,7 +88,7 @@ func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Co To create a remote repository non-interactively, supply the repository name and one of %[1]s--public%[1]s, %[1]s--private%[1]s, or %[1]s--internal%[1]s. Pass %[1]s--clone%[1]s to clone the new repository locally. - If the %[1]sOWNER/%[1]s portion of the %[1]sOWNER/REPO%[1]s name argument is omitted, it + If the %[1]sOWNER/%[1]s portion of the %[1]sOWNER/REPO%[1]s name argument is omitted, it defaults to the name of the authenticating user. To create a remote repository from an existing local repository, specify the source directory with %[1]s--source%[1]s. diff --git a/pkg/cmd/repo/credits/credits.go b/pkg/cmd/repo/credits/credits.go index 4b7b9fb28..7db08a231 100644 --- a/pkg/cmd/repo/credits/credits.go +++ b/pkg/cmd/repo/credits/credits.go @@ -79,18 +79,18 @@ func NewCmdRepoCredits(f *cmdutil.Factory, runF func(*CreditsOptions) error) *co Use: "credits []", Short: "View credits for a repository", Example: heredoc.Doc(` - # view credits for the current repository - $ gh repo credits + # view credits for the current repository + $ gh repo credits - # view credits for a specific repository - $ gh repo credits cool/repo + # view credits for a specific repository + $ gh repo credits cool/repo - # print a non-animated thank you - $ gh repo credits -s + # print a non-animated thank you + $ gh repo credits -s - # pipe to just print the contributors, one per line - $ gh repo credits | cat - `), + # pipe to just print the contributors, one per line + $ gh repo credits | cat + `), Args: cobra.MaximumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { if len(args) > 0 { diff --git a/pkg/cmd/root/help_topic.go b/pkg/cmd/root/help_topic.go index 4786a993b..3da5bf476 100644 --- a/pkg/cmd/root/help_topic.go +++ b/pkg/cmd/root/help_topic.go @@ -158,25 +158,25 @@ var HelpTopics = []helpTopic{ $ gh pr list --json number,title,author [ { - "author": { - "login": "monalisa" - }, - "number": 123, - "title": "A helpful contribution" + "author": { + "login": "monalisa" + }, + "number": 123, + "title": "A helpful contribution" }, { - "author": { - "login": "codercat" - }, - "number": 124, - "title": "Improve the docs" + "author": { + "login": "codercat" + }, + "number": 124, + "title": "Improve the docs" }, { - "author": { - "login": "cli-maintainer" - }, - "number": 125, - "title": "An exciting new feature" + "author": { + "login": "cli-maintainer" + }, + "number": 125, + "title": "An exciting new feature" } ] @@ -193,32 +193,31 @@ var HelpTopics = []helpTopic{ | map(.labels = (.labels | map(.name))) # show only the label names | .[:3] # select the first 3 results' [ - { - "labels": [ - "enhancement", - "needs triage" - ], - "number": 123, - "title": "A helpful contribution" - }, - { - "labels": [ - "help wanted", - "docs", - "good first issue" - ], - "number": 125, - "title": "Improve the docs" - }, - { - "labels": [ - "enhancement", - ], - "number": 7221, - "title": "An exciting new feature" - } + { + "labels": [ + "enhancement", + "needs triage" + ], + "number": 123, + "title": "A helpful contribution" + }, + { + "labels": [ + "help wanted", + "docs", + "good first issue" + ], + "number": 125, + "title": "Improve the docs" + }, + { + "labels": [ + "enhancement", + ], + "number": 7221, + "title": "An exciting new feature" + } ] - # using the --template flag with the hyperlink helper gh issue list --json title,url --template '{{range .}}{{hyperlink .url .title}}{{"\n"}}{{end}}' diff --git a/pkg/cmd/run/download/download.go b/pkg/cmd/run/download/download.go index 993e16e52..18a10df80 100644 --- a/pkg/cmd/run/download/download.go +++ b/pkg/cmd/run/download/download.go @@ -51,17 +51,17 @@ func NewCmdDownload(f *cmdutil.Factory, runF func(*DownloadOptions) error) *cobr `), Args: cobra.MaximumNArgs(1), Example: heredoc.Doc(` - # Download all artifacts generated by a workflow run - $ gh run download + # Download all artifacts generated by a workflow run + $ gh run download - # Download a specific artifact within a run - $ gh run download -n + # Download a specific artifact within a run + $ gh run download -n - # Download specific artifacts across all runs in a repository - $ gh run download -n -n + # Download specific artifacts across all runs in a repository + $ gh run download -n -n - # Select artifacts to download interactively - $ gh run download + # Select artifacts to download interactively + $ gh run download `), RunE: func(cmd *cobra.Command, args []string) error { if len(args) > 0 { diff --git a/pkg/cmd/run/list/list.go b/pkg/cmd/run/list/list.go index 21e6c7faf..793bfbb85 100644 --- a/pkg/cmd/run/list/list.go +++ b/pkg/cmd/run/list/list.go @@ -58,7 +58,7 @@ func NewCmdList(f *cmdutil.Factory, runF func(*ListOptions) error) *cobra.Comman Use: "list", Short: "List recent workflow runs", Long: heredoc.Docf(` - List recent workflow runs. + List recent workflow runs. Note that providing the %[1]sworkflow_name%[1]s to the %[1]s-w%[1]s flag will not fetch disabled workflows. Also pass the %[1]s-a%[1]s flag to fetch disabled workflow runs using the %[1]sworkflow_name%[1]s and the %[1]s-w%[1]s flag. diff --git a/pkg/cmd/search/commits/commits.go b/pkg/cmd/search/commits/commits.go index 698e933bb..6a9f58b86 100644 --- a/pkg/cmd/search/commits/commits.go +++ b/pkg/cmd/search/commits/commits.go @@ -45,7 +45,7 @@ func NewCmdCommits(f *cmdutil.Factory, runF func(*CommitsOptions) error) *cobra. GitHub search syntax is documented at: - `), + `), Example: heredoc.Doc(` # search commits matching set of keywords "readme" and "typo" $ gh search commits readme typo @@ -64,7 +64,7 @@ func NewCmdCommits(f *cmdutil.Factory, runF func(*CommitsOptions) error) *cobra. # search commits authored before February 1st, 2022 $ gh search commits --author-date="<2022-02-01" - `), + `), RunE: func(c *cobra.Command, args []string) error { if len(args) == 0 && c.Flags().NFlag() == 0 { return cmdutil.FlagErrorf("specify search keywords or flags") diff --git a/pkg/cmd/search/issues/issues.go b/pkg/cmd/search/issues/issues.go index ec7909747..a8be32f71 100644 --- a/pkg/cmd/search/issues/issues.go +++ b/pkg/cmd/search/issues/issues.go @@ -34,7 +34,7 @@ func NewCmdIssues(f *cmdutil.Factory, runF func(*shared.IssuesOptions) error) *c GitHub search syntax is documented at: - `), + `), Example: heredoc.Doc(` # search issues matching set of keywords "readme" and "typo" $ gh search issues readme typo @@ -56,8 +56,7 @@ func NewCmdIssues(f *cmdutil.Factory, runF func(*shared.IssuesOptions) error) *c # search issues only from un-archived repositories (default is all repositories) $ gh search issues --owner github --archived=false - - `), + `), RunE: func(c *cobra.Command, args []string) error { if len(args) == 0 && c.Flags().NFlag() == 0 { return cmdutil.FlagErrorf("specify search keywords or flags") diff --git a/pkg/cmd/search/prs/prs.go b/pkg/cmd/search/prs/prs.go index 5da7b18f7..32565a580 100644 --- a/pkg/cmd/search/prs/prs.go +++ b/pkg/cmd/search/prs/prs.go @@ -36,7 +36,7 @@ func NewCmdPrs(f *cmdutil.Factory, runF func(*shared.IssuesOptions) error) *cobr GitHub search syntax is documented at: - `), + `), Example: heredoc.Doc(` # search pull requests matching set of keywords "fix" and "bug" $ gh search prs fix bug @@ -58,7 +58,7 @@ func NewCmdPrs(f *cmdutil.Factory, runF func(*shared.IssuesOptions) error) *cobr # search pull requests only from un-archived repositories (default is all repositories) $ gh search prs --owner github --archived=false - `), + `), RunE: func(c *cobra.Command, args []string) error { if len(args) == 0 && c.Flags().NFlag() == 0 { return cmdutil.FlagErrorf("specify search keywords or flags") diff --git a/pkg/cmd/search/repos/repos.go b/pkg/cmd/search/repos/repos.go index 26bee450e..88b8db13f 100644 --- a/pkg/cmd/search/repos/repos.go +++ b/pkg/cmd/search/repos/repos.go @@ -46,7 +46,7 @@ func NewCmdRepos(f *cmdutil.Factory, runF func(*ReposOptions) error) *cobra.Comm GitHub search syntax is documented at: - `), + `), Example: heredoc.Doc(` # search repositories matching set of keywords "cli" and "shell" $ gh search repos cli shell @@ -68,7 +68,7 @@ func NewCmdRepos(f *cmdutil.Factory, runF func(*ReposOptions) error) *cobra.Comm # search repositories excluding archived repositories $ gh search repos --archived=false - `), + `), RunE: func(c *cobra.Command, args []string) error { if len(args) == 0 && c.Flags().NFlag() == 0 { return cmdutil.FlagErrorf("specify search keywords or flags") diff --git a/pkg/cmd/variable/variable.go b/pkg/cmd/variable/variable.go index 15ff38744..920268c41 100644 --- a/pkg/cmd/variable/variable.go +++ b/pkg/cmd/variable/variable.go @@ -17,7 +17,7 @@ func NewCmdVariable(f *cmdutil.Factory) *cobra.Command { Long: heredoc.Docf(` Variables can be set at the repository, environment or organization level for use in GitHub Actions or Dependabot. Run %[1]sgh help variable set%[1]s to learn how to get started. - `, "`"), + `, "`"), } cmdutil.EnableRepoOverride(cmd, f) diff --git a/pkg/cmd/workflow/run/run.go b/pkg/cmd/workflow/run/run.go index 19c650984..b7ab53098 100644 --- a/pkg/cmd/workflow/run/run.go +++ b/pkg/cmd/workflow/run/run.go @@ -64,7 +64,7 @@ func NewCmdRun(f *cmdutil.Factory, runF func(*RunOptions) error) *cobra.Command - Interactively - Via %[1]s-f/--raw-field%[1]s or %[1]s-F/--field%[1]s flags - As JSON, via standard input - `, "`"), + `, "`"), Example: heredoc.Doc(` # Have gh prompt you for what workflow you'd like to run and interactively collect inputs $ gh workflow run diff --git a/pkg/cmd/workflow/view/view.go b/pkg/cmd/workflow/view/view.go index 28e561766..188d79e22 100644 --- a/pkg/cmd/workflow/view/view.go +++ b/pkg/cmd/workflow/view/view.go @@ -56,11 +56,11 @@ func NewCmdView(f *cmdutil.Factory, runF func(*ViewOptions) error) *cobra.Comman Short: "View the summary of a workflow", Args: cobra.MaximumNArgs(1), Example: heredoc.Doc(` - # Interactively select a workflow to view - $ gh workflow view + # Interactively select a workflow to view + $ gh workflow view - # View a specific workflow - $ gh workflow view 0451 + # View a specific workflow + $ gh workflow view 0451 `), RunE: func(cmd *cobra.Command, args []string) error { // support `-R, --repo` override diff --git a/pkg/surveyext/editor.go b/pkg/surveyext/editor.go index 420ecc4e5..82533f913 100644 --- a/pkg/surveyext/editor.go +++ b/pkg/surveyext/editor.go @@ -46,10 +46,10 @@ var EditorQuestionTemplate = ` {{- color .Config.Icons.Question.Format }}{{ .Config.Icons.Question.Text }} {{color "reset"}} {{- color "default+hb"}}{{ .Message }} {{color "reset"}} {{- if .ShowAnswer}} - {{- color "cyan"}}{{.Answer}}{{color "reset"}}{{"\n"}} + {{- color "cyan"}}{{.Answer}}{{color "reset"}}{{"\n"}} {{- else }} - {{- if and .Help (not .ShowHelp)}}{{color "cyan"}}[{{ .Config.HelpInput }} for help]{{color "reset"}} {{end}} - {{- if and .Default (not .HideDefault)}}{{color "white"}}({{.Default}}) {{color "reset"}}{{end}} + {{- if and .Help (not .ShowHelp)}}{{color "cyan"}}[{{ .Config.HelpInput }} for help]{{color "reset"}} {{end}} + {{- if and .Default (not .HideDefault)}}{{color "white"}}({{.Default}}) {{color "reset"}}{{end}} {{- color "cyan"}}[(e) to launch {{ .EditorCommand }}{{- if .BlankAllowed }}, enter to skip{{ end }}] {{color "reset"}} {{- end}}` From c088951944082eb4c474097edb1861ed07d6c856 Mon Sep 17 00:00:00 2001 From: Andy Feller Date: Fri, 2 Aug 2024 15:11:22 -0400 Subject: [PATCH 30/53] Fix host handling in variable and secret delete This change updates `gh variable delete` and `gh secret delete` to use the host associated with the repository rather than the default host. Along with these changes is minor refactoring of the tests to ensure appropriate Dotcom vs GHES targeting works as expected. Minor edit to `gh variable get` testing to simplify some conditional logic in test setup. --- pkg/cmd/secret/delete/delete.go | 29 +++--- pkg/cmd/secret/delete/delete_test.go | 127 ++++++++++++++++++------- pkg/cmd/variable/delete/delete.go | 24 ++--- pkg/cmd/variable/delete/delete_test.go | 60 +++++++++--- pkg/cmd/variable/get/get_test.go | 17 ++-- 5 files changed, 176 insertions(+), 81 deletions(-) diff --git a/pkg/cmd/secret/delete/delete.go b/pkg/cmd/secret/delete/delete.go index 9a299ce4f..564e8633f 100644 --- a/pkg/cmd/secret/delete/delete.go +++ b/pkg/cmd/secret/delete/delete.go @@ -105,24 +105,27 @@ func removeRun(opts *DeleteOptions) error { } } - var path string - switch secretEntity { - case shared.Organization: - path = fmt.Sprintf("orgs/%s/%s/secrets/%s", orgName, secretApp, opts.SecretName) - case shared.Environment: - path = fmt.Sprintf("repos/%s/environments/%s/secrets/%s", ghrepo.FullName(baseRepo), envName, opts.SecretName) - case shared.User: - path = fmt.Sprintf("user/codespaces/secrets/%s", opts.SecretName) - case shared.Repository: - path = fmt.Sprintf("repos/%s/%s/secrets/%s", ghrepo.FullName(baseRepo), secretApp, opts.SecretName) - } - cfg, err := opts.Config() if err != nil { return err } - host, _ := cfg.Authentication().DefaultHost() + var path string + var host string + switch secretEntity { + case shared.Organization: + path = fmt.Sprintf("orgs/%s/%s/secrets/%s", orgName, secretApp, opts.SecretName) + host, _ = cfg.Authentication().DefaultHost() + case shared.Environment: + path = fmt.Sprintf("repos/%s/environments/%s/secrets/%s", ghrepo.FullName(baseRepo), envName, opts.SecretName) + host = baseRepo.RepoHost() + case shared.User: + path = fmt.Sprintf("user/codespaces/secrets/%s", opts.SecretName) + host, _ = cfg.Authentication().DefaultHost() + case shared.Repository: + path = fmt.Sprintf("repos/%s/%s/secrets/%s", ghrepo.FullName(baseRepo), secretApp, opts.SecretName) + host = baseRepo.RepoHost() + } err = client.REST(host, "DELETE", path, nil, nil) if err != nil { diff --git a/pkg/cmd/secret/delete/delete_test.go b/pkg/cmd/secret/delete/delete_test.go index 9d2c078c7..bd5053f4d 100644 --- a/pkg/cmd/secret/delete/delete_test.go +++ b/pkg/cmd/secret/delete/delete_test.go @@ -13,6 +13,7 @@ import ( "github.com/cli/cli/v2/pkg/iostreams" "github.com/google/shlex" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestNewCmdDelete(t *testing.T) { @@ -121,9 +122,10 @@ func TestNewCmdDelete(t *testing.T) { func Test_removeRun_repo(t *testing.T) { tests := []struct { - name string - opts *DeleteOptions - wantPath string + name string + opts *DeleteOptions + host string + httpStubs func(*httpmock.Registry) }{ { name: "Actions", @@ -131,7 +133,21 @@ func Test_removeRun_repo(t *testing.T) { Application: "actions", SecretName: "cool_secret", }, - wantPath: "repos/owner/repo/actions/secrets/cool_secret", + host: "github.com", + httpStubs: func(reg *httpmock.Registry) { + reg.Register(httpmock.WithHost(httpmock.REST("DELETE", "repos/owner/repo/actions/secrets/cool_secret"), "api.github.com"), httpmock.StatusStringResponse(204, "No Content")) + }, + }, + { + name: "Actions GHES", + opts: &DeleteOptions{ + Application: "actions", + SecretName: "cool_secret", + }, + host: "example.com", + httpStubs: func(reg *httpmock.Registry) { + reg.Register(httpmock.WithHost(httpmock.REST("DELETE", "api/v3/repos/owner/repo/actions/secrets/cool_secret"), "example.com"), httpmock.StatusStringResponse(204, "No Content")) + }, }, { name: "Dependabot", @@ -139,23 +155,38 @@ func Test_removeRun_repo(t *testing.T) { Application: "dependabot", SecretName: "cool_dependabot_secret", }, - wantPath: "repos/owner/repo/dependabot/secrets/cool_dependabot_secret", + host: "github.com", + httpStubs: func(reg *httpmock.Registry) { + reg.Register(httpmock.WithHost(httpmock.REST("DELETE", "repos/owner/repo/dependabot/secrets/cool_dependabot_secret"), "api.github.com"), httpmock.StatusStringResponse(204, "No Content")) + }, + }, + { + name: "Dependabot GHES", + opts: &DeleteOptions{ + Application: "dependabot", + SecretName: "cool_dependabot_secret", + }, + host: "example.com", + httpStubs: func(reg *httpmock.Registry) { + reg.Register(httpmock.WithHost(httpmock.REST("DELETE", "api/v3/repos/owner/repo/dependabot/secrets/cool_dependabot_secret"), "example.com"), httpmock.StatusStringResponse(204, "No Content")) + }, }, { name: "defaults to Actions", opts: &DeleteOptions{ SecretName: "cool_secret", }, - wantPath: "repos/owner/repo/actions/secrets/cool_secret", + host: "github.com", + httpStubs: func(reg *httpmock.Registry) { + reg.Register(httpmock.WithHost(httpmock.REST("DELETE", "repos/owner/repo/actions/secrets/cool_secret"), "api.github.com"), httpmock.StatusStringResponse(204, "No Content")) + }, }, } for _, tt := range tests { reg := &httpmock.Registry{} - - reg.Register( - httpmock.REST("DELETE", tt.wantPath), - httpmock.StatusStringResponse(204, "No Content")) + tt.httpStubs(reg) + defer reg.Verify(t) ios, _, _, _ := iostreams.Test() @@ -167,44 +198,70 @@ func Test_removeRun_repo(t *testing.T) { return config.NewBlankConfig(), nil } tt.opts.BaseRepo = func() (ghrepo.Interface, error) { - return ghrepo.FromFullName("owner/repo") + return ghrepo.FromFullNameWithHost("owner/repo", tt.host) } err := removeRun(tt.opts) assert.NoError(t, err) - - reg.Verify(t) } } func Test_removeRun_env(t *testing.T) { - reg := &httpmock.Registry{} - - reg.Register( - httpmock.REST("DELETE", "repos/owner/repo/environments/development/secrets/cool_secret"), - httpmock.StatusStringResponse(204, "No Content")) - - ios, _, _, _ := iostreams.Test() - - opts := &DeleteOptions{ - IO: ios, - HttpClient: func() (*http.Client, error) { - return &http.Client{Transport: reg}, nil + tests := []struct { + name string + opts *DeleteOptions + host string + httpStubs func(*httpmock.Registry) + }{ + { + name: "delete environment secret", + opts: &DeleteOptions{ + SecretName: "cool_secret", + EnvName: "development", + }, + host: "github.com", + httpStubs: func(reg *httpmock.Registry) { + reg.Register(httpmock.WithHost(httpmock.REST("DELETE", "repos/owner/repo/environments/development/secrets/cool_secret"), "api.github.com"), + httpmock.StatusStringResponse(204, "No Content")) + }, }, - Config: func() (gh.Config, error) { - return config.NewBlankConfig(), nil + { + name: "delete environment secret GHES", + opts: &DeleteOptions{ + SecretName: "cool_secret", + EnvName: "development", + }, + host: "example.com", + httpStubs: func(reg *httpmock.Registry) { + reg.Register(httpmock.WithHost(httpmock.REST("DELETE", "api/v3/repos/owner/repo/environments/development/secrets/cool_secret"), "example.com"), + httpmock.StatusStringResponse(204, "No Content")) + }, }, - BaseRepo: func() (ghrepo.Interface, error) { - return ghrepo.FromFullName("owner/repo") - }, - SecretName: "cool_secret", - EnvName: "development", } - err := removeRun(opts) - assert.NoError(t, err) + for _, tt := range tests { + reg := &httpmock.Registry{} + tt.httpStubs(reg) + defer reg.Verify(t) - reg.Verify(t) + ios, _, _, _ := iostreams.Test() + tt.opts.IO = ios + tt.opts.BaseRepo = func() (ghrepo.Interface, error) { + if tt.host != "" { + return ghrepo.FromFullNameWithHost("owner/repo", tt.host) + } + return ghrepo.FromFullName("owner/repo") + } + tt.opts.HttpClient = func() (*http.Client, error) { + return &http.Client{Transport: reg}, nil + } + tt.opts.Config = func() (gh.Config, error) { + return config.NewBlankConfig(), nil + } + + err := removeRun(tt.opts) + require.NoError(t, err) + } } func Test_removeRun_org(t *testing.T) { diff --git a/pkg/cmd/variable/delete/delete.go b/pkg/cmd/variable/delete/delete.go index 3617f3188..d51320167 100644 --- a/pkg/cmd/variable/delete/delete.go +++ b/pkg/cmd/variable/delete/delete.go @@ -91,22 +91,24 @@ func removeRun(opts *DeleteOptions) error { } } - var path string - switch variableEntity { - case shared.Organization: - path = fmt.Sprintf("orgs/%s/actions/variables/%s", orgName, opts.VariableName) - case shared.Environment: - path = fmt.Sprintf("repos/%s/environments/%s/variables/%s", ghrepo.FullName(baseRepo), envName, opts.VariableName) - case shared.Repository: - path = fmt.Sprintf("repos/%s/actions/variables/%s", ghrepo.FullName(baseRepo), opts.VariableName) - } - cfg, err := opts.Config() if err != nil { return err } - host, _ := cfg.Authentication().DefaultHost() + var path string + var host string + switch variableEntity { + case shared.Organization: + path = fmt.Sprintf("orgs/%s/actions/variables/%s", orgName, opts.VariableName) + host, _ = cfg.Authentication().DefaultHost() + case shared.Environment: + path = fmt.Sprintf("repos/%s/environments/%s/variables/%s", ghrepo.FullName(baseRepo), envName, opts.VariableName) + host = baseRepo.RepoHost() + case shared.Repository: + path = fmt.Sprintf("repos/%s/actions/variables/%s", ghrepo.FullName(baseRepo), opts.VariableName) + host = baseRepo.RepoHost() + } err = client.REST(host, "DELETE", path, nil, nil) if err != nil { diff --git a/pkg/cmd/variable/delete/delete_test.go b/pkg/cmd/variable/delete/delete_test.go index e659f96a6..d00bef8fb 100644 --- a/pkg/cmd/variable/delete/delete_test.go +++ b/pkg/cmd/variable/delete/delete_test.go @@ -13,6 +13,7 @@ import ( "github.com/cli/cli/v2/pkg/iostreams" "github.com/google/shlex" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestNewCmdDelete(t *testing.T) { @@ -87,16 +88,32 @@ func TestNewCmdDelete(t *testing.T) { func TestRemoveRun(t *testing.T) { tests := []struct { - name string - opts *DeleteOptions - wantPath string + name string + opts *DeleteOptions + host string + httpStubs func(*httpmock.Registry) }{ { name: "repo", opts: &DeleteOptions{ VariableName: "cool_variable", }, - wantPath: "repos/owner/repo/actions/variables/cool_variable", + host: "github.com", + httpStubs: func(reg *httpmock.Registry) { + reg.Register(httpmock.WithHost(httpmock.REST("DELETE", "repos/owner/repo/actions/variables/cool_variable"), "api.github.com"), + httpmock.StatusStringResponse(204, "No Content")) + }, + }, + { + name: "repo GHES", + opts: &DeleteOptions{ + VariableName: "cool_variable", + }, + host: "example.com", + httpStubs: func(reg *httpmock.Registry) { + reg.Register(httpmock.WithHost(httpmock.REST("DELETE", "api/v3/repos/owner/repo/actions/variables/cool_variable"), "example.com"), + httpmock.StatusStringResponse(204, "No Content")) + }, }, { name: "env", @@ -104,7 +121,23 @@ func TestRemoveRun(t *testing.T) { VariableName: "cool_variable", EnvName: "development", }, - wantPath: "repos/owner/repo/environments/development/variables/cool_variable", + host: "github.com", + httpStubs: func(reg *httpmock.Registry) { + reg.Register(httpmock.WithHost(httpmock.REST("DELETE", "repos/owner/repo/environments/development/variables/cool_variable"), "api.github.com"), + httpmock.StatusStringResponse(204, "No Content")) + }, + }, + { + name: "env GHES", + opts: &DeleteOptions{ + VariableName: "cool_variable", + EnvName: "development", + }, + host: "example.com", + httpStubs: func(reg *httpmock.Registry) { + reg.Register(httpmock.WithHost(httpmock.REST("DELETE", "api/v3/repos/owner/repo/environments/development/variables/cool_variable"), "example.com"), + httpmock.StatusStringResponse(204, "No Content")) + }, }, { name: "org", @@ -112,35 +145,34 @@ func TestRemoveRun(t *testing.T) { VariableName: "cool_variable", OrgName: "UmbrellaCorporation", }, - wantPath: "orgs/UmbrellaCorporation/actions/variables/cool_variable", + host: "github.com", + httpStubs: func(reg *httpmock.Registry) { + reg.Register(httpmock.WithHost(httpmock.REST("DELETE", "orgs/UmbrellaCorporation/actions/variables/cool_variable"), "api.github.com"), + httpmock.StatusStringResponse(204, "No Content")) + }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { reg := &httpmock.Registry{} + tt.httpStubs(reg) defer reg.Verify(t) - reg.Register(httpmock.REST("DELETE", tt.wantPath), - httpmock.StatusStringResponse(204, "No Content")) - ios, _, _, _ := iostreams.Test() tt.opts.IO = ios - tt.opts.HttpClient = func() (*http.Client, error) { return &http.Client{Transport: reg}, nil } - tt.opts.Config = func() (gh.Config, error) { return config.NewBlankConfig(), nil } - tt.opts.BaseRepo = func() (ghrepo.Interface, error) { - return ghrepo.FromFullName("owner/repo") + return ghrepo.FromFullNameWithHost("owner/repo", tt.host) } err := removeRun(tt.opts) - assert.NoError(t, err) + require.NoError(t, err) }) } } diff --git a/pkg/cmd/variable/get/get_test.go b/pkg/cmd/variable/get/get_test.go index e85910152..82b602c9e 100644 --- a/pkg/cmd/variable/get/get_test.go +++ b/pkg/cmd/variable/get/get_test.go @@ -135,9 +135,9 @@ func Test_getRun(t *testing.T) { opts: &GetOptions{ VariableName: "VARIABLE_ONE", }, - host: "ghe.io", + host: "example.com", httpStubs: func(reg *httpmock.Registry) { - reg.Register(httpmock.WithHost(httpmock.REST("GET", "api/v3/repos/owner/repo/actions/variables/VARIABLE_ONE"), "ghe.io"), + reg.Register(httpmock.WithHost(httpmock.REST("GET", "api/v3/repos/owner/repo/actions/variables/VARIABLE_ONE"), "example.com"), httpmock.JSONResponse(shared.Variable{ Value: "repo_var", })) @@ -150,6 +150,7 @@ func Test_getRun(t *testing.T) { OrgName: "TestOrg", VariableName: "VARIABLE_ONE", }, + host: "github.com", httpStubs: func(reg *httpmock.Registry) { reg.Register(httpmock.REST("GET", "orgs/TestOrg/actions/variables/VARIABLE_ONE"), httpmock.JSONResponse(shared.Variable{ @@ -179,9 +180,9 @@ func Test_getRun(t *testing.T) { EnvName: "Development", VariableName: "VARIABLE_ONE", }, - host: "ghe.io", + host: "example.com", httpStubs: func(reg *httpmock.Registry) { - reg.Register(httpmock.WithHost(httpmock.REST("GET", "api/v3/repos/owner/repo/environments/Development/variables/VARIABLE_ONE"), "ghe.io"), + reg.Register(httpmock.WithHost(httpmock.REST("GET", "api/v3/repos/owner/repo/environments/Development/variables/VARIABLE_ONE"), "example.com"), httpmock.JSONResponse(shared.Variable{ Value: "env_var", })) @@ -193,6 +194,7 @@ func Test_getRun(t *testing.T) { opts: &GetOptions{ VariableName: "VARIABLE_ONE", }, + host: "github.com", jsonFields: []string{"name", "value", "visibility", "updatedAt", "createdAt", "numSelectedRepos", "selectedReposURL"}, httpStubs: func(reg *httpmock.Registry) { reg.Register(httpmock.REST("GET", "repos/owner/repo/actions/variables/VARIABLE_ONE"), @@ -225,6 +227,7 @@ func Test_getRun(t *testing.T) { opts: &GetOptions{ VariableName: "VARIABLE_ONE", }, + host: "github.com", httpStubs: func(reg *httpmock.Registry) { reg.Register(httpmock.REST("GET", "repos/owner/repo/actions/variables/VARIABLE_ONE"), httpmock.StatusStringResponse(404, "not found"), @@ -237,6 +240,7 @@ func Test_getRun(t *testing.T) { opts: &GetOptions{ VariableName: "VARIABLE_ONE", }, + host: "github.com", httpStubs: func(reg *httpmock.Registry) { reg.Register(httpmock.REST("GET", "repos/owner/repo/actions/variables/VARIABLE_ONE"), httpmock.StatusStringResponse(400, "not found"), @@ -258,10 +262,7 @@ func Test_getRun(t *testing.T) { tt.opts.IO = ios tt.opts.BaseRepo = func() (ghrepo.Interface, error) { - if tt.host != "" { - return ghrepo.FromFullNameWithHost("owner/repo", tt.host) - } - return ghrepo.FromFullName("owner/repo") + return ghrepo.FromFullNameWithHost("owner/repo", tt.host) } tt.opts.HttpClient = func() (*http.Client, error) { return &http.Client{Transport: reg}, nil From 8356df0188597c9fbfc692e70e79615c596cb102 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Aug 2024 14:25:20 +0000 Subject: [PATCH 31/53] build(deps): bump github.com/google/go-containerregistry Bumps [github.com/google/go-containerregistry](https://github.com/google/go-containerregistry) from 0.20.1 to 0.20.2. - [Release notes](https://github.com/google/go-containerregistry/releases) - [Changelog](https://github.com/google/go-containerregistry/blob/main/.goreleaser.yml) - [Commits](https://github.com/google/go-containerregistry/compare/v0.20.1...v0.20.2) --- updated-dependencies: - dependency-name: github.com/google/go-containerregistry dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- go.mod | 5 ++--- go.sum | 10 ++++------ 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index a607e4adf..96935c68e 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( github.com/gabriel-vasile/mimetype v1.4.5 github.com/gdamore/tcell/v2 v2.5.4 github.com/google/go-cmp v0.6.0 - github.com/google/go-containerregistry v0.20.1 + github.com/google/go-containerregistry v0.20.2 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 github.com/gorilla/websocket v1.5.3 github.com/hashicorp/go-multierror v1.1.1 @@ -70,9 +70,8 @@ require ( github.com/digitorus/pkcs7 v0.0.0-20230818184609-3a137a874352 // indirect github.com/digitorus/timestamp v0.0.0-20231217203849-220c5c2851b7 // indirect github.com/dlclark/regexp2 v1.4.0 // indirect - github.com/docker/cli v24.0.0+incompatible // indirect + github.com/docker/cli v27.1.1+incompatible // indirect github.com/docker/distribution v2.8.2+incompatible // indirect - github.com/docker/docker v24.0.9+incompatible // indirect github.com/docker/docker-credential-helpers v0.7.0 // indirect github.com/fatih/color v1.16.0 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect diff --git a/go.sum b/go.sum index ffb608ffb..11eeb5411 100644 --- a/go.sum +++ b/go.sum @@ -131,12 +131,10 @@ github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E= github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= -github.com/docker/cli v24.0.0+incompatible h1:0+1VshNwBQzQAx9lOl+OYCTCEAD8fKs/qeXMx3O0wqM= -github.com/docker/cli v24.0.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/cli v27.1.1+incompatible h1:goaZxOqs4QKxznZjjBWKONQci/MywhtRv2oNn0GkeZE= +github.com/docker/cli v27.1.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v24.0.9+incompatible h1:HPGzNmwfLZWdxHqK9/II92pyi1EpYKsAqcl4G0Of9v0= -github.com/docker/docker v24.0.9+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= @@ -201,8 +199,8 @@ github.com/google/certificate-transparency-go v1.2.1 h1:4iW/NwzqOqYEEoCBEFP+jPbB github.com/google/certificate-transparency-go v1.2.1/go.mod h1:bvn/ytAccv+I6+DGkqpvSsEdiVGramgaSC6RD3tEmeE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-containerregistry v0.20.1 h1:eTgx9QNYugV4DN5mz4U8hiAGTi1ybXn0TPi4Smd8du0= -github.com/google/go-containerregistry v0.20.1/go.mod h1:YCMFNQeeXeLF+dnhhWkqDItx/JSkH01j1Kis4PsjzFI= +github.com/google/go-containerregistry v0.20.2 h1:B1wPJ1SN/S7pB+ZAimcciVD+r+yV/l/DSArMxlbwseo= +github.com/google/go-containerregistry v0.20.2/go.mod h1:z38EKdKh4h7IP2gSfUUqEvalZBqs6AoLeWfUy34nQC8= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= From e2275d7ef62c13fe63c80dd204e2a64417be2d8c Mon Sep 17 00:00:00 2001 From: benebsiny Date: Wed, 7 Aug 2024 23:14:15 +0800 Subject: [PATCH 32/53] Add `pr create --editor` --- pkg/cmd/pr/create/create.go | 186 ++++++++++++++++++++----------- pkg/cmd/pr/create/create_test.go | 92 +++++++++++++++ 2 files changed, 211 insertions(+), 67 deletions(-) diff --git a/pkg/cmd/pr/create/create.go b/pkg/cmd/pr/create/create.go index 23f302069..acdc0ee82 100644 --- a/pkg/cmd/pr/create/create.go +++ b/pkg/cmd/pr/create/create.go @@ -30,15 +30,16 @@ import ( type CreateOptions struct { // This struct stores user input and factory functions - HttpClient func() (*http.Client, error) - GitClient *git.Client - Config func() (gh.Config, error) - IO *iostreams.IOStreams - Remotes func() (ghContext.Remotes, error) - Branch func() (string, error) - Browser browser.Browser - Prompter shared.Prompt - Finder shared.PRFinder + HttpClient func() (*http.Client, error) + GitClient *git.Client + Config func() (gh.Config, error) + IO *iostreams.IOStreams + Remotes func() (ghContext.Remotes, error) + Branch func() (string, error) + Browser browser.Browser + Prompter shared.Prompt + Finder shared.PRFinder + TitledEditSurvey func(string, string) (string, string, error) TitleProvided bool BodyProvided bool @@ -49,6 +50,7 @@ type CreateOptions struct { Autofill bool FillVerbose bool FillFirst bool + EditorMode bool WebMode bool RecoverFile string @@ -88,14 +90,15 @@ type CreateContext struct { func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Command { opts := &CreateOptions{ - IO: f.IOStreams, - HttpClient: f.HttpClient, - GitClient: f.GitClient, - Config: f.Config, - Remotes: f.Remotes, - Branch: f.Branch, - Browser: f.Browser, - Prompter: f.Prompter, + IO: f.IOStreams, + HttpClient: f.HttpClient, + GitClient: f.GitClient, + Config: f.Config, + Remotes: f.Remotes, + Branch: f.Branch, + Browser: f.Browser, + Prompter: f.Prompter, + TitledEditSurvey: shared.TitledEditSurvey(&shared.UserEditor{Config: f.Config, IO: f.IOStreams}), } var bodyFile string @@ -177,6 +180,20 @@ func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Co return cmdutil.FlagErrorf("`--fill-verbose` is not supported with `--fill`") } + if err := cmdutil.MutuallyExclusive( + "specify only one of `--editor` or `--web`", + opts.EditorMode, + opts.WebMode, + ); err != nil { + return err + } + + config, err := f.Config() + if err != nil { + return err + } + opts.EditorMode = !opts.WebMode && (opts.EditorMode || config.PreferEditorPrompt("").Value == "enabled") + opts.BodyProvided = cmd.Flags().Changed("body") if bodyFile != "" { b, err := cmdutil.ReadFile(bodyFile, opts.IO.In) @@ -195,6 +212,10 @@ func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Co return cmdutil.FlagErrorf("must provide `--title` and `--body` (or `--fill` or `fill-first` or `--fillverbose`) when not running interactively") } + if opts.EditorMode && !opts.IO.CanPrompt() { + return errors.New("--editor or enabled prefer_editor_prompt configuration are not supported in non-tty mode") + } + if opts.DryRun && opts.WebMode { return cmdutil.FlagErrorf("`--dry-run` is not supported when using `--web`") } @@ -213,6 +234,7 @@ func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Co fl.StringVarP(&bodyFile, "body-file", "F", "", "Read body text from `file` (use \"-\" to read from standard input)") fl.StringVarP(&opts.BaseBranch, "base", "B", "", "The `branch` into which you want your code merged") fl.StringVarP(&opts.HeadBranch, "head", "H", "", "The `branch` that contains commits for your pull request (default [current branch])") + fl.BoolVarP(&opts.EditorMode, "editor", "e", false, "Skip prompts and open the text editor to write the title and body in. The first line is the title and the rest text is the body.") fl.BoolVarP(&opts.WebMode, "web", "w", false, "Open the web browser to create a pull request") fl.BoolVarP(&opts.FillVerbose, "fill-verbose", "", false, "Use commits msg+body for description") fl.BoolVarP(&opts.Autofill, "fill", "f", false, "Use commit info for title and body") @@ -315,7 +337,7 @@ func createRun(opts *CreateOptions) (err error) { ghrepo.FullName(ctx.BaseRepo)) } - if opts.FillVerbose || opts.Autofill || opts.FillFirst || (opts.TitleProvided && opts.BodyProvided) { + if !opts.EditorMode && (opts.FillVerbose || opts.Autofill || opts.FillFirst || (opts.TitleProvided && opts.BodyProvided)) { err = handlePush(*opts, *ctx) if err != nil { return @@ -330,71 +352,101 @@ func createRun(opts *CreateOptions) (err error) { } } - if !opts.TitleProvided { - err = shared.TitleSurvey(opts.Prompter, state) - if err != nil { - return - } + action := shared.SubmitAction + if opts.IsDraft { + action = shared.SubmitDraftAction } - defer shared.PreserveInput(opts.IO, state, &err)() + tpl := shared.NewTemplateManager(client.HTTP(), ctx.BaseRepo, opts.Prompter, opts.RootDirOverride, opts.RepoOverride == "", true) - if !opts.BodyProvided { - templateContent := "" - if opts.RecoverFile == "" { - tpl := shared.NewTemplateManager(client.HTTP(), ctx.BaseRepo, opts.Prompter, opts.RootDirOverride, opts.RepoOverride == "", true) + if opts.EditorMode { + if opts.Template != "" { var template shared.Template - - if opts.Template != "" { - template, err = tpl.Select(opts.Template) - if err != nil { - return - } - } else { - template, err = tpl.Choose() - if err != nil { - return - } + template, err = tpl.Select(opts.Template) + if err != nil { + return } + if state.Title == "" { + state.Title = template.Title() + } + state.Body = string(template.Body()) + } - if template != nil { - templateContent = string(template.Body()) + state.Title, state.Body, err = opts.TitledEditSurvey(state.Title, state.Body) + if err != nil { + return + } + if state.Title == "" { + err = fmt.Errorf("title can't be blank") + return + } + } else { + + if !opts.TitleProvided { + err = shared.TitleSurvey(opts.Prompter, state) + if err != nil { + return } } - err = shared.BodySurvey(opts.Prompter, state, templateContent) - if err != nil { - return + defer shared.PreserveInput(opts.IO, state, &err)() + + if !opts.BodyProvided { + templateContent := "" + if opts.RecoverFile == "" { + var template shared.Template + + if opts.Template != "" { + template, err = tpl.Select(opts.Template) + if err != nil { + return + } + } else { + template, err = tpl.Choose() + if err != nil { + return + } + } + + if template != nil { + templateContent = string(template.Body()) + } + } + + err = shared.BodySurvey(opts.Prompter, state, templateContent) + if err != nil { + return + } } - } - openURL, err = generateCompareURL(*ctx, *state) - if err != nil { - return - } - - allowPreview := !state.HasMetadata() && shared.ValidURL(openURL) && !opts.DryRun - allowMetadata := ctx.BaseRepo.ViewerCanTriage() - action, err := shared.ConfirmPRSubmission(opts.Prompter, allowPreview, allowMetadata, state.Draft) - if err != nil { - return fmt.Errorf("unable to confirm: %w", err) - } - - if action == shared.MetadataAction { - fetcher := &shared.MetadataFetcher{ - IO: opts.IO, - APIClient: client, - Repo: ctx.BaseRepo, - State: state, - } - err = shared.MetadataSurvey(opts.Prompter, opts.IO, ctx.BaseRepo, fetcher, state) + openURL, err = generateCompareURL(*ctx, *state) if err != nil { return } - action, err = shared.ConfirmPRSubmission(opts.Prompter, !state.HasMetadata() && !opts.DryRun, false, state.Draft) + allowPreview := !state.HasMetadata() && shared.ValidURL(openURL) && !opts.DryRun + allowMetadata := ctx.BaseRepo.ViewerCanTriage() + action, err = shared.ConfirmPRSubmission(opts.Prompter, allowPreview, allowMetadata, state.Draft) if err != nil { - return + return fmt.Errorf("unable to confirm: %w", err) + } + + if action == shared.MetadataAction { + fetcher := &shared.MetadataFetcher{ + IO: opts.IO, + APIClient: client, + Repo: ctx.BaseRepo, + State: state, + } + err = shared.MetadataSurvey(opts.Prompter, opts.IO, ctx.BaseRepo, fetcher, state) + if err != nil { + return + } + + action, err = shared.ConfirmPRSubmission(opts.Prompter, !state.HasMetadata() && !opts.DryRun, false, state.Draft) + if err != nil { + return + } } } diff --git a/pkg/cmd/pr/create/create_test.go b/pkg/cmd/pr/create/create_test.go index 3b64688c3..e0347945c 100644 --- a/pkg/cmd/pr/create/create_test.go +++ b/pkg/cmd/pr/create/create_test.go @@ -40,6 +40,7 @@ func TestNewCmdCreate(t *testing.T) { tty bool stdin string cli string + config string wantsErr bool wantsOpts CreateOptions }{ @@ -202,6 +203,64 @@ func TestNewCmdCreate(t *testing.T) { cli: "--web --dry-run", wantsErr: true, }, + { + name: "editor by cli", + tty: true, + cli: "--editor", + wantsErr: false, + wantsOpts: CreateOptions{ + Title: "", + Body: "", + RecoverFile: "", + WebMode: false, + EditorMode: true, + MaintainerCanModify: true, + }, + }, + { + name: "editor by config", + tty: true, + cli: "", + config: "prefer_editor_prompt: enabled", + wantsErr: false, + wantsOpts: CreateOptions{ + Title: "", + Body: "", + RecoverFile: "", + WebMode: false, + EditorMode: true, + MaintainerCanModify: true, + }, + }, + { + name: "editor and web", + tty: true, + cli: "--editor --web", + wantsErr: true, + }, + { + name: "can use web even though editor is enabled by config", + tty: true, + cli: `--web --title mytitle --body "issue body"`, + config: "prefer_editor_prompt: enabled", + wantsErr: false, + wantsOpts: CreateOptions{ + Title: "mytitle", + Body: "issue body", + TitleProvided: true, + BodyProvided: true, + RecoverFile: "", + WebMode: true, + EditorMode: false, + MaintainerCanModify: true, + }, + }, + { + name: "editor with non-tty", + tty: false, + cli: "--editor", + wantsErr: true, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -215,6 +274,12 @@ func TestNewCmdCreate(t *testing.T) { f := &cmdutil.Factory{ IOStreams: ios, + Config: func() (gh.Config, error) { + if tt.config != "" { + return config.NewFromString(tt.config), nil + } + return config.NewBlankConfig(), nil + }, } var opts *CreateOptions @@ -1372,6 +1437,33 @@ func Test_createRun(t *testing.T) { expectedOut: "https://github.com/OWNER/REPO/pull/12\n", expectedErrOut: "\nCreating pull request for feature into master in OWNER/REPO\n\n", }, + { + name: "editor", + httpStubs: func(r *httpmock.Registry, t *testing.T) { + r.Register( + httpmock.GraphQL(`mutation PullRequestCreate\b`), + httpmock.GraphQLMutation(` + { + "data": { "createPullRequest": { "pullRequest": { + "URL": "https://github.com/OWNER/REPO/pull/12" + } } } + } + `, func(inputs map[string]interface{}) { + assert.Equal(t, "title", inputs["title"]) + assert.Equal(t, "body", inputs["body"]) + })) + }, + setup: func(opts *CreateOptions, t *testing.T) func() { + opts.EditorMode = true + opts.HeadBranch = "feature" + opts.TitledEditSurvey = func(string, string) (string, string, error) { return "title", "body", nil } + return func() {} + }, + cmdStubs: func(cs *run.CommandStubber) { + cs.Register("git -c log.ShowSignature=false log --pretty=format:%H%x00%s%x00%b%x00 --cherry origin/master...feature", 0, "") + }, + expectedOut: "https://github.com/OWNER/REPO/pull/12\n", + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { From c5ea30da4789facca19aaeff6efb2acceb88a57b Mon Sep 17 00:00:00 2001 From: Tyler McGoffin Date: Wed, 7 Aug 2024 10:57:02 -0700 Subject: [PATCH 33/53] Add Acceptance Criteria requirement to triage.md for accepted issues To better facilitate community collaboration and to help reduce the amount of information any collaborator needs to peruse in a given issue, clear Acceptance Criteria on accepted issues should be included. This will reduce the amount of back and forth on PRs submitted by ensuring expectations for a given issue are clear --- docs/triage.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/triage.md b/docs/triage.md index ae9b0c15c..327756c8b 100644 --- a/docs/triage.md +++ b/docs/triage.md @@ -8,6 +8,8 @@ triage role. The initial expectation is that the person in the role for the week Review and label [open issues missing either the `enhancement`, `bug`, or `docs` label](https://github.com/cli/cli/issues?q=is%3Aopen+is%3Aissue+-label%3Abug%2Cenhancement%2Cdocs+). +Any issue that is accepted to be done as either an `enhancement`, `bug`, or `docs` requires explicit Acceptance Criteria in a comment on the issue before it is triaged. + To be considered triaged, `enhancement` issues require at least one of the following additional labels: - `core`: reserved for the core CLI team From fa06623f9b428f29aeba54c5f45c005e78334b5a Mon Sep 17 00:00:00 2001 From: Tyler McGoffin Date: Wed, 7 Aug 2024 11:46:22 -0700 Subject: [PATCH 34/53] Update docs/triage.md Co-authored-by: Andy Feller --- docs/triage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/triage.md b/docs/triage.md index 327756c8b..d78a81aed 100644 --- a/docs/triage.md +++ b/docs/triage.md @@ -8,7 +8,7 @@ triage role. The initial expectation is that the person in the role for the week Review and label [open issues missing either the `enhancement`, `bug`, or `docs` label](https://github.com/cli/cli/issues?q=is%3Aopen+is%3Aissue+-label%3Abug%2Cenhancement%2Cdocs+). -Any issue that is accepted to be done as either an `enhancement`, `bug`, or `docs` requires explicit Acceptance Criteria in a comment on the issue before it is triaged. +Any issue that is accepted to be done as either an `enhancement`, `bug`, or `docs` requires explicit Acceptance Criteria in a comment on the issue before `needs-triage` label is removed. To be considered triaged, `enhancement` issues require at least one of the following additional labels: From e18c00228314340509ec0c56f15a992a2950ba09 Mon Sep 17 00:00:00 2001 From: benebsiny Date: Thu, 8 Aug 2024 18:07:52 +0800 Subject: [PATCH 35/53] Deduplicate the initialization of editor mode --- pkg/cmd/issue/create/create.go | 15 ++------------- pkg/cmd/pr/create/create.go | 8 ++------ pkg/cmd/pr/shared/survey.go | 24 ++++++++++++++++++++++++ 3 files changed, 28 insertions(+), 19 deletions(-) diff --git a/pkg/cmd/issue/create/create.go b/pkg/cmd/issue/create/create.go index 33b583012..1af25180f 100644 --- a/pkg/cmd/issue/create/create.go +++ b/pkg/cmd/issue/create/create.go @@ -81,19 +81,11 @@ func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Co opts.BaseRepo = f.BaseRepo opts.HasRepoOverride = cmd.Flags().Changed("repo") - if err := cmdutil.MutuallyExclusive( - "specify only one of `--editor` or `--web`", - opts.EditorMode, - opts.WebMode, - ); err != nil { - return err - } - - config, err := f.Config() + var err error + opts.EditorMode, err = prShared.InitEditorMode(f, opts.EditorMode, opts.WebMode, opts.IO.CanPrompt()) if err != nil { return err } - opts.EditorMode = !opts.WebMode && (opts.EditorMode || config.PreferEditorPrompt("").Value == "enabled") titleProvided := cmd.Flags().Changed("title") bodyProvided := cmd.Flags().Changed("body") @@ -119,9 +111,6 @@ func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Co if opts.Interactive && !opts.IO.CanPrompt() { return cmdutil.FlagErrorf("must provide `--title` and `--body` when not running interactively") } - if opts.EditorMode && !opts.IO.CanPrompt() { - return errors.New("--editor or enabled prefer_editor_prompt configuration are not supported in non-tty mode") - } if runF != nil { return runF(opts) diff --git a/pkg/cmd/pr/create/create.go b/pkg/cmd/pr/create/create.go index acdc0ee82..d85400202 100644 --- a/pkg/cmd/pr/create/create.go +++ b/pkg/cmd/pr/create/create.go @@ -188,11 +188,11 @@ func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Co return err } - config, err := f.Config() + var err error + opts.EditorMode, err = shared.InitEditorMode(f, opts.EditorMode, opts.WebMode, opts.IO.CanPrompt()) if err != nil { return err } - opts.EditorMode = !opts.WebMode && (opts.EditorMode || config.PreferEditorPrompt("").Value == "enabled") opts.BodyProvided = cmd.Flags().Changed("body") if bodyFile != "" { @@ -212,10 +212,6 @@ func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Co return cmdutil.FlagErrorf("must provide `--title` and `--body` (or `--fill` or `fill-first` or `--fillverbose`) when not running interactively") } - if opts.EditorMode && !opts.IO.CanPrompt() { - return errors.New("--editor or enabled prefer_editor_prompt configuration are not supported in non-tty mode") - } - if opts.DryRun && opts.WebMode { return cmdutil.FlagErrorf("`--dry-run` is not supported when using `--web`") } diff --git a/pkg/cmd/pr/shared/survey.go b/pkg/cmd/pr/shared/survey.go index 5f4bf7dd9..5b8bde0eb 100644 --- a/pkg/cmd/pr/shared/survey.go +++ b/pkg/cmd/pr/shared/survey.go @@ -1,6 +1,7 @@ package shared import ( + "errors" "fmt" "strings" @@ -357,3 +358,26 @@ func TitledEditSurvey(editor Editor) func(string, string) (string, string, error return title, strings.TrimSuffix(body, "\n"), nil } } + +func InitEditorMode(f *cmdutil.Factory, editorMode bool, webMode bool, canPrompt bool) (bool, error) { + if err := cmdutil.MutuallyExclusive( + "specify only one of `--editor` or `--web`", + editorMode, + webMode, + ); err != nil { + return false, err + } + + config, err := f.Config() + if err != nil { + return false, err + } + + editorMode = !webMode && (editorMode || config.PreferEditorPrompt("").Value == "enabled") + + if editorMode && !canPrompt { + return false, errors.New("--editor or enabled prefer_editor_prompt configuration are not supported in non-tty mode") + } + + return editorMode, nil +} From 330a385f9e060824e63ad886bd3a97140217e6e6 Mon Sep 17 00:00:00 2001 From: Junichi Sato <22004610+sato11@users.noreply.github.com> Date: Thu, 8 Aug 2024 19:28:03 +0900 Subject: [PATCH 36/53] Document that `gh run download` downloads the latest artifact by default This commit addresses the documentation issue. The discussion at #7018 has confirmed that it is undocumented that the current behavior of `gh run download` with `-n` and no `run-id` downloads the latest artifact. Although the behavior has not been created intentionally, it is the one that should be documented and the future releases should warn before a breaking change. --- pkg/cmd/run/download/download.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pkg/cmd/run/download/download.go b/pkg/cmd/run/download/download.go index 18a10df80..99ec45bbe 100644 --- a/pkg/cmd/run/download/download.go +++ b/pkg/cmd/run/download/download.go @@ -42,13 +42,17 @@ func NewCmdDownload(f *cmdutil.Factory, runF func(*DownloadOptions) error) *cobr cmd := &cobra.Command{ Use: "download []", Short: "Download artifacts generated by a workflow run", - Long: heredoc.Doc(` + Long: heredoc.Docf(` Download artifacts generated by a GitHub Actions workflow run. The contents of each artifact will be extracted under separate directories based on the artifact name. If only a single artifact is specified, it will be extracted into the current directory. - `), + + By default, this command downloads the latest artifact created and uploaded through + GitHub Actions. Because workflows can delete or overwrite artifacts, %[1]s%[1]s + must be used to select an artifact from a specific workflow run. + `, "`"), Args: cobra.MaximumNArgs(1), Example: heredoc.Doc(` # Download all artifacts generated by a workflow run From ab34d868aa8d99fc33eedcbf5ad64122aa814a34 Mon Sep 17 00:00:00 2001 From: Prabhat Kumar Sahu Date: Fri, 9 Aug 2024 02:14:52 +0530 Subject: [PATCH 37/53] Change `gh repo set-default --view` to print to `stderr` when no default exists (#9431) Change logging of `gh repo set-default --view` to `stderr` when no default exists to better conform with expectations and unix standards. --------- Signed-off-by: Prabhat --- pkg/cmd/repo/setdefault/setdefault.go | 5 ++--- pkg/cmd/repo/setdefault/setdefault_test.go | 13 ++++++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/pkg/cmd/repo/setdefault/setdefault.go b/pkg/cmd/repo/setdefault/setdefault.go index d54d3956a..eb8fcfb5a 100644 --- a/pkg/cmd/repo/setdefault/setdefault.go +++ b/pkg/cmd/repo/setdefault/setdefault.go @@ -121,12 +121,11 @@ func setDefaultRun(opts *SetDefaultOptions) error { if opts.ViewMode { if currentDefaultRepo != nil { fmt.Fprintln(opts.IO.Out, displayRemoteRepoName(currentDefaultRepo)) - } else if opts.IO.IsStdoutTTY() { - fmt.Fprintln(opts.IO.Out, "no default repository has been set; use `gh repo set-default` to select one") + } else { + fmt.Fprintln(opts.IO.ErrOut, "no default repository has been set; use `gh repo set-default` to select one") } return nil } - cs := opts.IO.ColorScheme() if opts.UnsetMode { diff --git a/pkg/cmd/repo/setdefault/setdefault_test.go b/pkg/cmd/repo/setdefault/setdefault_test.go index a89effa14..55a0193d5 100644 --- a/pkg/cmd/repo/setdefault/setdefault_test.go +++ b/pkg/cmd/repo/setdefault/setdefault_test.go @@ -135,6 +135,7 @@ func TestDefaultRun(t *testing.T) { gitStubs func(*run.CommandStubber) prompterStubs func(*prompter.PrompterMock) wantStdout string + wantStderr string wantErr bool errMsg string }{ @@ -175,10 +176,11 @@ func TestDefaultRun(t *testing.T) { Repo: repo1, }, }, - wantStdout: "no default repository has been set; use `gh repo set-default` to select one\n", + wantStderr: "no default repository has been set; use `gh repo set-default` to select one\n", }, { name: "view mode no current default", + tty: false, opts: SetDefaultOptions{ViewMode: true}, remotes: []*context.Remote{ { @@ -186,6 +188,7 @@ func TestDefaultRun(t *testing.T) { Repo: repo1, }, }, + wantStderr: "no default repository has been set; use `gh repo set-default` to select one\n", }, { name: "view mode with base resolved current default", @@ -466,7 +469,7 @@ func TestDefaultRun(t *testing.T) { return &http.Client{Transport: reg}, nil } - io, _, stdout, _ := iostreams.Test() + io, _, stdout, stderr := iostreams.Test() io.SetStdinTTY(tt.tty) io.SetStdoutTTY(tt.tty) io.SetStderrTTY(tt.tty) @@ -498,7 +501,11 @@ func TestDefaultRun(t *testing.T) { return } assert.NoError(t, err) - assert.Equal(t, tt.wantStdout, stdout.String()) + if tt.wantStdout != "" { + assert.Equal(t, tt.wantStdout, stdout.String()) + } else { + assert.Equal(t, tt.wantStderr, stderr.String()) + } }) } } From 574e1310720e7ca120e01e58923a8c90026ece9c Mon Sep 17 00:00:00 2001 From: Cody Soyland Date: Fri, 9 Aug 2024 16:02:04 -0400 Subject: [PATCH 38/53] Require Sigstore Bundle v0.3 when verifying with `gh attestation` Signed-off-by: Cody Soyland --- ....12-py3-none-any-bundle-missing-cert.jsonl | 2 +- ...bundle-missing-verification-material.jsonl | 2 +- ...ance_demo-0.0.12-py3-none-any-bundle.jsonl | 2 +- .../data/sigstore-js-2.1.0-bundle-v0.1.json | 61 ++++++++++ .../test/data/sigstore-js-2.1.0-bundle.json | 114 +++++++++--------- .../sigstore-js-2.1.0_with_2_bundles.jsonl | 4 +- .../sigstoreBundle-invalid-signature.json | 64 +++++++--- pkg/cmd/attestation/verification/sigstore.go | 3 + .../verification/sigstore_integration_test.go | 13 ++ 9 files changed, 180 insertions(+), 85 deletions(-) create mode 100644 pkg/cmd/attestation/test/data/sigstore-js-2.1.0-bundle-v0.1.json diff --git a/pkg/cmd/attestation/test/data/github_provenance_demo-0.0.12-py3-none-any-bundle-missing-cert.jsonl b/pkg/cmd/attestation/test/data/github_provenance_demo-0.0.12-py3-none-any-bundle-missing-cert.jsonl index e07ec7eda..092383a0b 100644 --- a/pkg/cmd/attestation/test/data/github_provenance_demo-0.0.12-py3-none-any-bundle-missing-cert.jsonl +++ b/pkg/cmd/attestation/test/data/github_provenance_demo-0.0.12-py3-none-any-bundle-missing-cert.jsonl @@ -1 +1 @@ -{"mediaType":"application/vnd.dev.sigstore.bundle+json;version=0.2","verificationMaterial":{"publicKey":{},"timestampVerificationData":{"rfc3161Timestamps":[{"signedTimestamp":"MIIC0jADAgEAMIICyQYJKoZIhvcNAQcCoIICujCCArYCAQMxDTALBglghkgBZQMEAgIwgbwGCyqGSIb3DQEJEAEEoIGsBIGpMIGmAgEBBgkrBgEEAYO/MAIwMTANBglghkgBZQMEAgEFAAQgGIbhbjwKQeOttAHpYr4ZdztGymTk4PPmJo1M4wwN9s8CFQDfGDV1B9hFrCLmzlcmvopZMaQOpxgPMjAyNDA0MjIxNzMzMjZaMAMCAQGgNqQ0MDIxFTATBgNVBAoTDEdpdEh1YiwgSW5jLjEZMBcGA1UEAxMQVFNBIFRpbWVzdGFtcGluZ6AAMYIB3zCCAdsCAQEwSjAyMRUwEwYDVQQKEwxHaXRIdWIsIEluYy4xGTAXBgNVBAMTEFRTQSBpbnRlcm1lZGlhdGUCFDQ1ZZrWbr6Lo5+CsIgv6MSK/IcQMAsGCWCGSAFlAwQCAqCCAQUwGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMBwGCSqGSIb3DQEJBTEPFw0yNDA0MjIxNzMzMjZaMD8GCSqGSIb3DQEJBDEyBDAGSn57m09Ro452Mj6xp7ld68UOS58CRbsUAX0K7Oesj8Kcpo2xKRMwapTRYFWZF84wgYcGCyqGSIb3DQEJEAIvMXgwdjB0MHIEIC4X67ezV4q0OFecnkRUAx6sVRjb/Q6nZYy0cfMfHKgBME4wNqQ0MDIxFTATBgNVBAoTDEdpdEh1YiwgSW5jLjEZMBcGA1UEAxMQVFNBIGludGVybWVkaWF0ZQIUNDVlmtZuvoujn4KwiC/oxIr8hxAwCgYIKoZIzj0EAwMEaDBmAjEA0DIXC6giK74kBGL9WRcy99QAvkKWM2N20fNLFxTVrPglT0oNrTzTiyVQgIN6w1/gAjEAqxEuJp/bRj/ADIHoCBp2+K+zI2opxLbD4rj3jLaezHnoNOYpLwP3lIwFDhYU1a8a"}]}}} +{"mediaType":"application/vnd.dev.sigstore.bundle.v0.3+json","verificationMaterial":{"publicKey":{},"timestampVerificationData":{"rfc3161Timestamps":[{"signedTimestamp":"MIIC0jADAgEAMIICyQYJKoZIhvcNAQcCoIICujCCArYCAQMxDTALBglghkgBZQMEAgIwgbwGCyqGSIb3DQEJEAEEoIGsBIGpMIGmAgEBBgkrBgEEAYO/MAIwMTANBglghkgBZQMEAgEFAAQgGIbhbjwKQeOttAHpYr4ZdztGymTk4PPmJo1M4wwN9s8CFQDfGDV1B9hFrCLmzlcmvopZMaQOpxgPMjAyNDA0MjIxNzMzMjZaMAMCAQGgNqQ0MDIxFTATBgNVBAoTDEdpdEh1YiwgSW5jLjEZMBcGA1UEAxMQVFNBIFRpbWVzdGFtcGluZ6AAMYIB3zCCAdsCAQEwSjAyMRUwEwYDVQQKEwxHaXRIdWIsIEluYy4xGTAXBgNVBAMTEFRTQSBpbnRlcm1lZGlhdGUCFDQ1ZZrWbr6Lo5+CsIgv6MSK/IcQMAsGCWCGSAFlAwQCAqCCAQUwGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMBwGCSqGSIb3DQEJBTEPFw0yNDA0MjIxNzMzMjZaMD8GCSqGSIb3DQEJBDEyBDAGSn57m09Ro452Mj6xp7ld68UOS58CRbsUAX0K7Oesj8Kcpo2xKRMwapTRYFWZF84wgYcGCyqGSIb3DQEJEAIvMXgwdjB0MHIEIC4X67ezV4q0OFecnkRUAx6sVRjb/Q6nZYy0cfMfHKgBME4wNqQ0MDIxFTATBgNVBAoTDEdpdEh1YiwgSW5jLjEZMBcGA1UEAxMQVFNBIGludGVybWVkaWF0ZQIUNDVlmtZuvoujn4KwiC/oxIr8hxAwCgYIKoZIzj0EAwMEaDBmAjEA0DIXC6giK74kBGL9WRcy99QAvkKWM2N20fNLFxTVrPglT0oNrTzTiyVQgIN6w1/gAjEAqxEuJp/bRj/ADIHoCBp2+K+zI2opxLbD4rj3jLaezHnoNOYpLwP3lIwFDhYU1a8a"}]}}} diff --git a/pkg/cmd/attestation/test/data/github_provenance_demo-0.0.12-py3-none-any-bundle-missing-verification-material.jsonl b/pkg/cmd/attestation/test/data/github_provenance_demo-0.0.12-py3-none-any-bundle-missing-verification-material.jsonl index 935bc9ce8..95610f10e 100644 --- a/pkg/cmd/attestation/test/data/github_provenance_demo-0.0.12-py3-none-any-bundle-missing-verification-material.jsonl +++ b/pkg/cmd/attestation/test/data/github_provenance_demo-0.0.12-py3-none-any-bundle-missing-verification-material.jsonl @@ -1 +1 @@ -{"mediaType":"application/vnd.dev.sigstore.bundle+json;version=0.2","dsseEnvelope":{"payload":"eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjEiLCJzdWJqZWN0IjpbeyJuYW1lIjoiZ2l0aHViX3Byb3ZlbmFuY2VfZGVtby0wLjAuMTItcHkzLW5vbmUtYW55LndobCIsImRpZ2VzdCI6eyJzaGEyNTYiOiJhZTU3OTM2ZGVmNTliYzRjNzVlZGQzYTgzN2Q4OWJjZWZjNmQzYTVlMzFkNTVhNmZhN2E3MTYyNGY5MmMzYzNiIn19XSwicHJlZGljYXRlVHlwZSI6Imh0dHBzOi8vc2xzYS5kZXYvcHJvdmVuYW5jZS92MSIsInByZWRpY2F0ZSI6eyJidWlsZERlZmluaXRpb24iOnsiYnVpbGRUeXBlIjoiaHR0cHM6Ly9zbHNhLWZyYW1ld29yay5naXRodWIuaW8vZ2l0aHViLWFjdGlvbnMtYnVpbGR0eXBlcy93b3JrZmxvdy92MSIsImV4dGVybmFsUGFyYW1ldGVycyI6eyJ3b3JrZmxvdyI6eyJyZWYiOiJyZWZzL2hlYWRzL21haW4iLCJyZXBvc2l0b3J5IjoiaHR0cHM6Ly9naXRodWIuY29tL2FjdGlvbnMvYXR0ZXN0LWRlbW8iLCJwYXRoIjoiLmdpdGh1Yi93b3JrZmxvd3MvYnVpbGQtcHl0aG9uLnltbCJ9fSwiaW50ZXJuYWxQYXJhbWV0ZXJzIjp7ImdpdGh1YiI6eyJldmVudF9uYW1lIjoid29ya2Zsb3dfZGlzcGF0Y2giLCJyZXBvc2l0b3J5X2lkIjoiNzYzMjg3NTMyIiwicmVwb3NpdG9yeV9vd25lcl9pZCI6IjQ0MDM2NTYyIn19LCJyZXNvbHZlZERlcGVuZGVuY2llcyI6W3sidXJpIjoiZ2l0K2h0dHBzOi8vZ2l0aHViLmNvbS9hY3Rpb25zL2F0dGVzdC1kZW1vQHJlZnMvaGVhZHMvbWFpbiIsImRpZ2VzdCI6eyJnaXRDb21taXQiOiJhNmMyM2I5ODA2YzU5MzY2NGY2ODYzN2M4ZjlkNDVkZmNmOThiMmRiIn19XX0sInJ1bkRldGFpbHMiOnsiYnVpbGRlciI6eyJpZCI6Imh0dHBzOi8vZ2l0aHViLmNvbS9hY3Rpb25zL3J1bm5lci9naXRodWItaG9zdGVkIn0sIm1ldGFkYXRhIjp7Imludm9jYXRpb25JZCI6Imh0dHBzOi8vZ2l0aHViLmNvbS9hY3Rpb25zL2F0dGVzdC1kZW1vL2FjdGlvbnMvcnVucy84Nzg4Mzg5NjAxL2F0dGVtcHRzLzEifX19fQ==","payloadType":"application/vnd.in-toto+json","signatures":[{"sig":"MEUCIAgJYzFW0xtAGqTzSn8UWxvT16QLL1qLolcylZsN39U/AiEA/HSUE5sCPEkEHuZgsPS7LkZ9SkMlHGHhpMU3RsV/cYw="}]}} +{"mediaType":"application/vnd.dev.sigstore.bundle+json;version=0.3","dsseEnvelope":{"payload":"eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjEiLCJzdWJqZWN0IjpbeyJuYW1lIjoiZ2l0aHViX3Byb3ZlbmFuY2VfZGVtby0wLjAuMTItcHkzLW5vbmUtYW55LndobCIsImRpZ2VzdCI6eyJzaGEyNTYiOiJhZTU3OTM2ZGVmNTliYzRjNzVlZGQzYTgzN2Q4OWJjZWZjNmQzYTVlMzFkNTVhNmZhN2E3MTYyNGY5MmMzYzNiIn19XSwicHJlZGljYXRlVHlwZSI6Imh0dHBzOi8vc2xzYS5kZXYvcHJvdmVuYW5jZS92MSIsInByZWRpY2F0ZSI6eyJidWlsZERlZmluaXRpb24iOnsiYnVpbGRUeXBlIjoiaHR0cHM6Ly9zbHNhLWZyYW1ld29yay5naXRodWIuaW8vZ2l0aHViLWFjdGlvbnMtYnVpbGR0eXBlcy93b3JrZmxvdy92MSIsImV4dGVybmFsUGFyYW1ldGVycyI6eyJ3b3JrZmxvdyI6eyJyZWYiOiJyZWZzL2hlYWRzL21haW4iLCJyZXBvc2l0b3J5IjoiaHR0cHM6Ly9naXRodWIuY29tL2FjdGlvbnMvYXR0ZXN0LWRlbW8iLCJwYXRoIjoiLmdpdGh1Yi93b3JrZmxvd3MvYnVpbGQtcHl0aG9uLnltbCJ9fSwiaW50ZXJuYWxQYXJhbWV0ZXJzIjp7ImdpdGh1YiI6eyJldmVudF9uYW1lIjoid29ya2Zsb3dfZGlzcGF0Y2giLCJyZXBvc2l0b3J5X2lkIjoiNzYzMjg3NTMyIiwicmVwb3NpdG9yeV9vd25lcl9pZCI6IjQ0MDM2NTYyIn19LCJyZXNvbHZlZERlcGVuZGVuY2llcyI6W3sidXJpIjoiZ2l0K2h0dHBzOi8vZ2l0aHViLmNvbS9hY3Rpb25zL2F0dGVzdC1kZW1vQHJlZnMvaGVhZHMvbWFpbiIsImRpZ2VzdCI6eyJnaXRDb21taXQiOiJhNmMyM2I5ODA2YzU5MzY2NGY2ODYzN2M4ZjlkNDVkZmNmOThiMmRiIn19XX0sInJ1bkRldGFpbHMiOnsiYnVpbGRlciI6eyJpZCI6Imh0dHBzOi8vZ2l0aHViLmNvbS9hY3Rpb25zL3J1bm5lci9naXRodWItaG9zdGVkIn0sIm1ldGFkYXRhIjp7Imludm9jYXRpb25JZCI6Imh0dHBzOi8vZ2l0aHViLmNvbS9hY3Rpb25zL2F0dGVzdC1kZW1vL2FjdGlvbnMvcnVucy84Nzg4Mzg5NjAxL2F0dGVtcHRzLzEifX19fQ==","payloadType":"application/vnd.in-toto+json","signatures":[{"sig":"MEUCIAgJYzFW0xtAGqTzSn8UWxvT16QLL1qLolcylZsN39U/AiEA/HSUE5sCPEkEHuZgsPS7LkZ9SkMlHGHhpMU3RsV/cYw="}]}} diff --git a/pkg/cmd/attestation/test/data/github_provenance_demo-0.0.12-py3-none-any-bundle.jsonl b/pkg/cmd/attestation/test/data/github_provenance_demo-0.0.12-py3-none-any-bundle.jsonl index 209b2373e..4dffc8fd6 100644 --- a/pkg/cmd/attestation/test/data/github_provenance_demo-0.0.12-py3-none-any-bundle.jsonl +++ b/pkg/cmd/attestation/test/data/github_provenance_demo-0.0.12-py3-none-any-bundle.jsonl @@ -1 +1 @@ -{"mediaType":"application/vnd.dev.sigstore.bundle+json;version=0.2","verificationMaterial":{"x509CertificateChain":{"certificates":[{"rawBytes":"MIIGZjCCBeygAwIBAgIUZCNUZ8MMbrK0CrXtb6QFhFMAA6wwCgYIKoZIzj0EAwMwODEVMBMGA1UEChMMR2l0SHViLCBJbmMuMR8wHQYDVQQDExZGdWxjaW8gSW50ZXJtZWRpYXRlIGwyMB4XDTI0MDQyMjE3MzMyNloXDTI0MDQyMjE3NDMyNlowADBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABLq8PHWv71CECMctIxOYXeUm893MJEazyiLqAJPmEHx8oJsk+vYt8zvEjfL6OAiUpR60Cfk5moqCrr4WwvM3jPujggUKMIIFBjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwMwHQYDVR0OBBYEFK10jC8CJcrMLDA80Jf4joCWq+H5MB8GA1UdIwQYMBaAFJtL5A5EGdvYbrWHWsiaGyEZn/4jMGcGA1UdEQEB/wRdMFuGWWh0dHBzOi8vZ2l0aHViLmNvbS9hY3Rpb25zL2F0dGVzdC1kZW1vLy5naXRodWIvd29ya2Zsb3dzL2J1aWxkLXB5dGhvbi55bWxAcmVmcy9oZWFkcy9tYWluMDkGCisGAQQBg78wAQEEK2h0dHBzOi8vdG9rZW4uYWN0aW9ucy5naXRodWJ1c2VyY29udGVudC5jb20wHwYKKwYBBAGDvzABAgQRd29ya2Zsb3dfZGlzcGF0Y2gwNgYKKwYBBAGDvzABAwQoYTZjMjNiOTgwNmM1OTM2NjRmNjg2MzdjOGY5ZDQ1ZGZjZjk4YjJkYjAvBgorBgEEAYO/MAEEBCFCdWlsZCBwYWNrYWdlIGFuZCBwdWJsaXNoIHRvIFB5UEkwIQYKKwYBBAGDvzABBQQTYWN0aW9ucy9hdHRlc3QtZGVtbzAdBgorBgEEAYO/MAEGBA9yZWZzL2hlYWRzL21haW4wOwYKKwYBBAGDvzABCAQtDCtodHRwczovL3Rva2VuLmFjdGlvbnMuZ2l0aHVidXNlcmNvbnRlbnQuY29tMGkGCisGAQQBg78wAQkEWwxZaHR0cHM6Ly9naXRodWIuY29tL2FjdGlvbnMvYXR0ZXN0LWRlbW8vLmdpdGh1Yi93b3JrZmxvd3MvYnVpbGQtcHl0aG9uLnltbEByZWZzL2hlYWRzL21haW4wOAYKKwYBBAGDvzABCgQqDChhNmMyM2I5ODA2YzU5MzY2NGY2ODYzN2M4ZjlkNDVkZmNmOThiMmRiMB0GCisGAQQBg78wAQsEDwwNZ2l0aHViLWhvc3RlZDA2BgorBgEEAYO/MAEMBCgMJmh0dHBzOi8vZ2l0aHViLmNvbS9hY3Rpb25zL2F0dGVzdC1kZW1vMDgGCisGAQQBg78wAQ0EKgwoYTZjMjNiOTgwNmM1OTM2NjRmNjg2MzdjOGY5ZDQ1ZGZjZjk4YjJkYjAfBgorBgEEAYO/MAEOBBEMD3JlZnMvaGVhZHMvbWFpbjAZBgorBgEEAYO/MAEPBAsMCTc2MzI4NzUzMjAqBgorBgEEAYO/MAEQBBwMGmh0dHBzOi8vZ2l0aHViLmNvbS9hY3Rpb25zMBgGCisGAQQBg78wAREECgwINDQwMzY1NjIwaQYKKwYBBAGDvzABEgRbDFlodHRwczovL2dpdGh1Yi5jb20vYWN0aW9ucy9hdHRlc3QtZGVtby8uZ2l0aHViL3dvcmtmbG93cy9idWlsZC1weXRob24ueW1sQHJlZnMvaGVhZHMvbWFpbjA4BgorBgEEAYO/MAETBCoMKGE2YzIzYjk4MDZjNTkzNjY0ZjY4NjM3YzhmOWQ0NWRmY2Y5OGIyZGIwIQYKKwYBBAGDvzABFAQTDBF3b3JrZmxvd19kaXNwYXRjaDBZBgorBgEEAYO/MAEVBEsMSWh0dHBzOi8vZ2l0aHViLmNvbS9hY3Rpb25zL2F0dGVzdC1kZW1vL2FjdGlvbnMvcnVucy84Nzg4Mzg5NjAxL2F0dGVtcHRzLzEwFwYKKwYBBAGDvzABFgQJDAdwcml2YXRlMAoGCCqGSM49BAMDA2gAMGUCME4MEsuiTVolcvctwKJn7TEfi9mIXxhfBRcV0Nox1UPvdc4EyO/gjYPqfWVbqi74CgIxANLkoV0aAeOaIuA1srkA1uIGmhuA820pXs0kbqW06cNuJie4+3B4PydoYoJjy1BZCQ=="}]},"timestampVerificationData":{"rfc3161Timestamps":[{"signedTimestamp":"MIIC0jADAgEAMIICyQYJKoZIhvcNAQcCoIICujCCArYCAQMxDTALBglghkgBZQMEAgIwgbwGCyqGSIb3DQEJEAEEoIGsBIGpMIGmAgEBBgkrBgEEAYO/MAIwMTANBglghkgBZQMEAgEFAAQgGIbhbjwKQeOttAHpYr4ZdztGymTk4PPmJo1M4wwN9s8CFQDfGDV1B9hFrCLmzlcmvopZMaQOpxgPMjAyNDA0MjIxNzMzMjZaMAMCAQGgNqQ0MDIxFTATBgNVBAoTDEdpdEh1YiwgSW5jLjEZMBcGA1UEAxMQVFNBIFRpbWVzdGFtcGluZ6AAMYIB3zCCAdsCAQEwSjAyMRUwEwYDVQQKEwxHaXRIdWIsIEluYy4xGTAXBgNVBAMTEFRTQSBpbnRlcm1lZGlhdGUCFDQ1ZZrWbr6Lo5+CsIgv6MSK/IcQMAsGCWCGSAFlAwQCAqCCAQUwGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMBwGCSqGSIb3DQEJBTEPFw0yNDA0MjIxNzMzMjZaMD8GCSqGSIb3DQEJBDEyBDAGSn57m09Ro452Mj6xp7ld68UOS58CRbsUAX0K7Oesj8Kcpo2xKRMwapTRYFWZF84wgYcGCyqGSIb3DQEJEAIvMXgwdjB0MHIEIC4X67ezV4q0OFecnkRUAx6sVRjb/Q6nZYy0cfMfHKgBME4wNqQ0MDIxFTATBgNVBAoTDEdpdEh1YiwgSW5jLjEZMBcGA1UEAxMQVFNBIGludGVybWVkaWF0ZQIUNDVlmtZuvoujn4KwiC/oxIr8hxAwCgYIKoZIzj0EAwMEaDBmAjEA0DIXC6giK74kBGL9WRcy99QAvkKWM2N20fNLFxTVrPglT0oNrTzTiyVQgIN6w1/gAjEAqxEuJp/bRj/ADIHoCBp2+K+zI2opxLbD4rj3jLaezHnoNOYpLwP3lIwFDhYU1a8a"}]}},"dsseEnvelope":{"payload":"eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjEiLCJzdWJqZWN0IjpbeyJuYW1lIjoiZ2l0aHViX3Byb3ZlbmFuY2VfZGVtby0wLjAuMTItcHkzLW5vbmUtYW55LndobCIsImRpZ2VzdCI6eyJzaGEyNTYiOiJhZTU3OTM2ZGVmNTliYzRjNzVlZGQzYTgzN2Q4OWJjZWZjNmQzYTVlMzFkNTVhNmZhN2E3MTYyNGY5MmMzYzNiIn19XSwicHJlZGljYXRlVHlwZSI6Imh0dHBzOi8vc2xzYS5kZXYvcHJvdmVuYW5jZS92MSIsInByZWRpY2F0ZSI6eyJidWlsZERlZmluaXRpb24iOnsiYnVpbGRUeXBlIjoiaHR0cHM6Ly9zbHNhLWZyYW1ld29yay5naXRodWIuaW8vZ2l0aHViLWFjdGlvbnMtYnVpbGR0eXBlcy93b3JrZmxvdy92MSIsImV4dGVybmFsUGFyYW1ldGVycyI6eyJ3b3JrZmxvdyI6eyJyZWYiOiJyZWZzL2hlYWRzL21haW4iLCJyZXBvc2l0b3J5IjoiaHR0cHM6Ly9naXRodWIuY29tL2FjdGlvbnMvYXR0ZXN0LWRlbW8iLCJwYXRoIjoiLmdpdGh1Yi93b3JrZmxvd3MvYnVpbGQtcHl0aG9uLnltbCJ9fSwiaW50ZXJuYWxQYXJhbWV0ZXJzIjp7ImdpdGh1YiI6eyJldmVudF9uYW1lIjoid29ya2Zsb3dfZGlzcGF0Y2giLCJyZXBvc2l0b3J5X2lkIjoiNzYzMjg3NTMyIiwicmVwb3NpdG9yeV9vd25lcl9pZCI6IjQ0MDM2NTYyIn19LCJyZXNvbHZlZERlcGVuZGVuY2llcyI6W3sidXJpIjoiZ2l0K2h0dHBzOi8vZ2l0aHViLmNvbS9hY3Rpb25zL2F0dGVzdC1kZW1vQHJlZnMvaGVhZHMvbWFpbiIsImRpZ2VzdCI6eyJnaXRDb21taXQiOiJhNmMyM2I5ODA2YzU5MzY2NGY2ODYzN2M4ZjlkNDVkZmNmOThiMmRiIn19XX0sInJ1bkRldGFpbHMiOnsiYnVpbGRlciI6eyJpZCI6Imh0dHBzOi8vZ2l0aHViLmNvbS9hY3Rpb25zL3J1bm5lci9naXRodWItaG9zdGVkIn0sIm1ldGFkYXRhIjp7Imludm9jYXRpb25JZCI6Imh0dHBzOi8vZ2l0aHViLmNvbS9hY3Rpb25zL2F0dGVzdC1kZW1vL2FjdGlvbnMvcnVucy84Nzg4Mzg5NjAxL2F0dGVtcHRzLzEifX19fQ==","payloadType":"application/vnd.in-toto+json","signatures":[{"sig":"MEUCIAgJYzFW0xtAGqTzSn8UWxvT16QLL1qLolcylZsN39U/AiEA/HSUE5sCPEkEHuZgsPS7LkZ9SkMlHGHhpMU3RsV/cYw="}]}} +{"mediaType":"application/vnd.dev.sigstore.bundle.v0.3+json","verificationMaterial":{"certificate":{"rawBytes":"MIIGZjCCBeygAwIBAgIUZCNUZ8MMbrK0CrXtb6QFhFMAA6wwCgYIKoZIzj0EAwMwODEVMBMGA1UEChMMR2l0SHViLCBJbmMuMR8wHQYDVQQDExZGdWxjaW8gSW50ZXJtZWRpYXRlIGwyMB4XDTI0MDQyMjE3MzMyNloXDTI0MDQyMjE3NDMyNlowADBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABLq8PHWv71CECMctIxOYXeUm893MJEazyiLqAJPmEHx8oJsk+vYt8zvEjfL6OAiUpR60Cfk5moqCrr4WwvM3jPujggUKMIIFBjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwMwHQYDVR0OBBYEFK10jC8CJcrMLDA80Jf4joCWq+H5MB8GA1UdIwQYMBaAFJtL5A5EGdvYbrWHWsiaGyEZn/4jMGcGA1UdEQEB/wRdMFuGWWh0dHBzOi8vZ2l0aHViLmNvbS9hY3Rpb25zL2F0dGVzdC1kZW1vLy5naXRodWIvd29ya2Zsb3dzL2J1aWxkLXB5dGhvbi55bWxAcmVmcy9oZWFkcy9tYWluMDkGCisGAQQBg78wAQEEK2h0dHBzOi8vdG9rZW4uYWN0aW9ucy5naXRodWJ1c2VyY29udGVudC5jb20wHwYKKwYBBAGDvzABAgQRd29ya2Zsb3dfZGlzcGF0Y2gwNgYKKwYBBAGDvzABAwQoYTZjMjNiOTgwNmM1OTM2NjRmNjg2MzdjOGY5ZDQ1ZGZjZjk4YjJkYjAvBgorBgEEAYO/MAEEBCFCdWlsZCBwYWNrYWdlIGFuZCBwdWJsaXNoIHRvIFB5UEkwIQYKKwYBBAGDvzABBQQTYWN0aW9ucy9hdHRlc3QtZGVtbzAdBgorBgEEAYO/MAEGBA9yZWZzL2hlYWRzL21haW4wOwYKKwYBBAGDvzABCAQtDCtodHRwczovL3Rva2VuLmFjdGlvbnMuZ2l0aHVidXNlcmNvbnRlbnQuY29tMGkGCisGAQQBg78wAQkEWwxZaHR0cHM6Ly9naXRodWIuY29tL2FjdGlvbnMvYXR0ZXN0LWRlbW8vLmdpdGh1Yi93b3JrZmxvd3MvYnVpbGQtcHl0aG9uLnltbEByZWZzL2hlYWRzL21haW4wOAYKKwYBBAGDvzABCgQqDChhNmMyM2I5ODA2YzU5MzY2NGY2ODYzN2M4ZjlkNDVkZmNmOThiMmRiMB0GCisGAQQBg78wAQsEDwwNZ2l0aHViLWhvc3RlZDA2BgorBgEEAYO/MAEMBCgMJmh0dHBzOi8vZ2l0aHViLmNvbS9hY3Rpb25zL2F0dGVzdC1kZW1vMDgGCisGAQQBg78wAQ0EKgwoYTZjMjNiOTgwNmM1OTM2NjRmNjg2MzdjOGY5ZDQ1ZGZjZjk4YjJkYjAfBgorBgEEAYO/MAEOBBEMD3JlZnMvaGVhZHMvbWFpbjAZBgorBgEEAYO/MAEPBAsMCTc2MzI4NzUzMjAqBgorBgEEAYO/MAEQBBwMGmh0dHBzOi8vZ2l0aHViLmNvbS9hY3Rpb25zMBgGCisGAQQBg78wAREECgwINDQwMzY1NjIwaQYKKwYBBAGDvzABEgRbDFlodHRwczovL2dpdGh1Yi5jb20vYWN0aW9ucy9hdHRlc3QtZGVtby8uZ2l0aHViL3dvcmtmbG93cy9idWlsZC1weXRob24ueW1sQHJlZnMvaGVhZHMvbWFpbjA4BgorBgEEAYO/MAETBCoMKGE2YzIzYjk4MDZjNTkzNjY0ZjY4NjM3YzhmOWQ0NWRmY2Y5OGIyZGIwIQYKKwYBBAGDvzABFAQTDBF3b3JrZmxvd19kaXNwYXRjaDBZBgorBgEEAYO/MAEVBEsMSWh0dHBzOi8vZ2l0aHViLmNvbS9hY3Rpb25zL2F0dGVzdC1kZW1vL2FjdGlvbnMvcnVucy84Nzg4Mzg5NjAxL2F0dGVtcHRzLzEwFwYKKwYBBAGDvzABFgQJDAdwcml2YXRlMAoGCCqGSM49BAMDA2gAMGUCME4MEsuiTVolcvctwKJn7TEfi9mIXxhfBRcV0Nox1UPvdc4EyO/gjYPqfWVbqi74CgIxANLkoV0aAeOaIuA1srkA1uIGmhuA820pXs0kbqW06cNuJie4+3B4PydoYoJjy1BZCQ=="},"timestampVerificationData":{"rfc3161Timestamps":[{"signedTimestamp":"MIIC0jADAgEAMIICyQYJKoZIhvcNAQcCoIICujCCArYCAQMxDTALBglghkgBZQMEAgIwgbwGCyqGSIb3DQEJEAEEoIGsBIGpMIGmAgEBBgkrBgEEAYO/MAIwMTANBglghkgBZQMEAgEFAAQgGIbhbjwKQeOttAHpYr4ZdztGymTk4PPmJo1M4wwN9s8CFQDfGDV1B9hFrCLmzlcmvopZMaQOpxgPMjAyNDA0MjIxNzMzMjZaMAMCAQGgNqQ0MDIxFTATBgNVBAoTDEdpdEh1YiwgSW5jLjEZMBcGA1UEAxMQVFNBIFRpbWVzdGFtcGluZ6AAMYIB3zCCAdsCAQEwSjAyMRUwEwYDVQQKEwxHaXRIdWIsIEluYy4xGTAXBgNVBAMTEFRTQSBpbnRlcm1lZGlhdGUCFDQ1ZZrWbr6Lo5+CsIgv6MSK/IcQMAsGCWCGSAFlAwQCAqCCAQUwGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMBwGCSqGSIb3DQEJBTEPFw0yNDA0MjIxNzMzMjZaMD8GCSqGSIb3DQEJBDEyBDAGSn57m09Ro452Mj6xp7ld68UOS58CRbsUAX0K7Oesj8Kcpo2xKRMwapTRYFWZF84wgYcGCyqGSIb3DQEJEAIvMXgwdjB0MHIEIC4X67ezV4q0OFecnkRUAx6sVRjb/Q6nZYy0cfMfHKgBME4wNqQ0MDIxFTATBgNVBAoTDEdpdEh1YiwgSW5jLjEZMBcGA1UEAxMQVFNBIGludGVybWVkaWF0ZQIUNDVlmtZuvoujn4KwiC/oxIr8hxAwCgYIKoZIzj0EAwMEaDBmAjEA0DIXC6giK74kBGL9WRcy99QAvkKWM2N20fNLFxTVrPglT0oNrTzTiyVQgIN6w1/gAjEAqxEuJp/bRj/ADIHoCBp2+K+zI2opxLbD4rj3jLaezHnoNOYpLwP3lIwFDhYU1a8a"}]}},"dsseEnvelope":{"payload":"eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjEiLCJzdWJqZWN0IjpbeyJuYW1lIjoiZ2l0aHViX3Byb3ZlbmFuY2VfZGVtby0wLjAuMTItcHkzLW5vbmUtYW55LndobCIsImRpZ2VzdCI6eyJzaGEyNTYiOiJhZTU3OTM2ZGVmNTliYzRjNzVlZGQzYTgzN2Q4OWJjZWZjNmQzYTVlMzFkNTVhNmZhN2E3MTYyNGY5MmMzYzNiIn19XSwicHJlZGljYXRlVHlwZSI6Imh0dHBzOi8vc2xzYS5kZXYvcHJvdmVuYW5jZS92MSIsInByZWRpY2F0ZSI6eyJidWlsZERlZmluaXRpb24iOnsiYnVpbGRUeXBlIjoiaHR0cHM6Ly9zbHNhLWZyYW1ld29yay5naXRodWIuaW8vZ2l0aHViLWFjdGlvbnMtYnVpbGR0eXBlcy93b3JrZmxvdy92MSIsImV4dGVybmFsUGFyYW1ldGVycyI6eyJ3b3JrZmxvdyI6eyJyZWYiOiJyZWZzL2hlYWRzL21haW4iLCJyZXBvc2l0b3J5IjoiaHR0cHM6Ly9naXRodWIuY29tL2FjdGlvbnMvYXR0ZXN0LWRlbW8iLCJwYXRoIjoiLmdpdGh1Yi93b3JrZmxvd3MvYnVpbGQtcHl0aG9uLnltbCJ9fSwiaW50ZXJuYWxQYXJhbWV0ZXJzIjp7ImdpdGh1YiI6eyJldmVudF9uYW1lIjoid29ya2Zsb3dfZGlzcGF0Y2giLCJyZXBvc2l0b3J5X2lkIjoiNzYzMjg3NTMyIiwicmVwb3NpdG9yeV9vd25lcl9pZCI6IjQ0MDM2NTYyIn19LCJyZXNvbHZlZERlcGVuZGVuY2llcyI6W3sidXJpIjoiZ2l0K2h0dHBzOi8vZ2l0aHViLmNvbS9hY3Rpb25zL2F0dGVzdC1kZW1vQHJlZnMvaGVhZHMvbWFpbiIsImRpZ2VzdCI6eyJnaXRDb21taXQiOiJhNmMyM2I5ODA2YzU5MzY2NGY2ODYzN2M4ZjlkNDVkZmNmOThiMmRiIn19XX0sInJ1bkRldGFpbHMiOnsiYnVpbGRlciI6eyJpZCI6Imh0dHBzOi8vZ2l0aHViLmNvbS9hY3Rpb25zL3J1bm5lci9naXRodWItaG9zdGVkIn0sIm1ldGFkYXRhIjp7Imludm9jYXRpb25JZCI6Imh0dHBzOi8vZ2l0aHViLmNvbS9hY3Rpb25zL2F0dGVzdC1kZW1vL2FjdGlvbnMvcnVucy84Nzg4Mzg5NjAxL2F0dGVtcHRzLzEifX19fQ==","payloadType":"application/vnd.in-toto+json","signatures":[{"sig":"MEUCIAgJYzFW0xtAGqTzSn8UWxvT16QLL1qLolcylZsN39U/AiEA/HSUE5sCPEkEHuZgsPS7LkZ9SkMlHGHhpMU3RsV/cYw="}]}} diff --git a/pkg/cmd/attestation/test/data/sigstore-js-2.1.0-bundle-v0.1.json b/pkg/cmd/attestation/test/data/sigstore-js-2.1.0-bundle-v0.1.json new file mode 100644 index 000000000..d91176e09 --- /dev/null +++ b/pkg/cmd/attestation/test/data/sigstore-js-2.1.0-bundle-v0.1.json @@ -0,0 +1,61 @@ +{ + "mediaType": "application/vnd.dev.sigstore.bundle+json;version=0.1", + "verificationMaterial": { + "x509CertificateChain": { + "certificates": [ + { + "rawBytes": "MIIGtDCCBjugAwIBAgIUCJLipSt09KLFc0JYfuDrSan//LswCgYIKoZIzj0EAwMwNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwHhcNMjMwODI5MTU0MDIzWhcNMjMwODI5MTU1MDIzWjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEPfm6LPXQeJTC89UOqiNWmnZYGmX4T3iLZGi0EV4bfOoM86Hza94XqyuwxAoWpCPecFCEbAe8l2dg/er3O9LEFqOCBVowggVWMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUeqpCXHr3pcUaL3EFKR+KsmuKQqowHwYDVR0jBBgwFoAU39Ppz1YkEZb5qNjpKFWixi4YZD8wYwYDVR0RAQH/BFkwV4ZVaHR0cHM6Ly9naXRodWIuY29tL3NpZ3N0b3JlL3NpZ3N0b3JlLWpzLy5naXRodWIvd29ya2Zsb3dzL3JlbGVhc2UueW1sQHJlZnMvaGVhZHMvbWFpbjA5BgorBgEEAYO/MAEBBCtodHRwczovL3Rva2VuLmFjdGlvbnMuZ2l0aHVidXNlcmNvbnRlbnQuY29tMBIGCisGAQQBg78wAQIEBHB1c2gwNgYKKwYBBAGDvzABAwQoMjZkMTY1MTMzODZmZmFhNzkwYjFjMzJmOTI3NTQ0ZjEzMjJlNDE5NDAVBgorBgEEAYO/MAEEBAdSZWxlYXNlMCIGCisGAQQBg78wAQUEFHNpZ3N0b3JlL3NpZ3N0b3JlLWpzMB0GCisGAQQBg78wAQYED3JlZnMvaGVhZHMvbWFpbjA7BgorBgEEAYO/MAEIBC0MK2h0dHBzOi8vdG9rZW4uYWN0aW9ucy5naXRodWJ1c2VyY29udGVudC5jb20wZQYKKwYBBAGDvzABCQRXDFVodHRwczovL2dpdGh1Yi5jb20vc2lnc3RvcmUvc2lnc3RvcmUtanMvLmdpdGh1Yi93b3JrZmxvd3MvcmVsZWFzZS55bWxAcmVmcy9oZWFkcy9tYWluMDgGCisGAQQBg78wAQoEKgwoMjZkMTY1MTMzODZmZmFhNzkwYjFjMzJmOTI3NTQ0ZjEzMjJlNDE5NDAdBgorBgEEAYO/MAELBA8MDWdpdGh1Yi1ob3N0ZWQwNwYKKwYBBAGDvzABDAQpDCdodHRwczovL2dpdGh1Yi5jb20vc2lnc3RvcmUvc2lnc3RvcmUtanMwOAYKKwYBBAGDvzABDQQqDCgyNmQxNjUxMzM4NmZmYWE3OTBiMWMzMmY5Mjc1NDRmMTMyMmU0MTk0MB8GCisGAQQBg78wAQ4EEQwPcmVmcy9oZWFkcy9tYWluMBkGCisGAQQBg78wAQ8ECwwJNDk1NTc0NTU1MCsGCisGAQQBg78wARAEHQwbaHR0cHM6Ly9naXRodWIuY29tL3NpZ3N0b3JlMBgGCisGAQQBg78wAREECgwINzEwOTYzNTMwZQYKKwYBBAGDvzABEgRXDFVodHRwczovL2dpdGh1Yi5jb20vc2lnc3RvcmUvc2lnc3RvcmUtanMvLmdpdGh1Yi93b3JrZmxvd3MvcmVsZWFzZS55bWxAcmVmcy9oZWFkcy9tYWluMDgGCisGAQQBg78wARMEKgwoMjZkMTY1MTMzODZmZmFhNzkwYjFjMzJmOTI3NTQ0ZjEzMjJlNDE5NDAUBgorBgEEAYO/MAEUBAYMBHB1c2gwWgYKKwYBBAGDvzABFQRMDEpodHRwczovL2dpdGh1Yi5jb20vc2lnc3RvcmUvc2lnc3RvcmUtanMvYWN0aW9ucy9ydW5zLzYwMTQ0ODg2NjYvYXR0ZW1wdHMvMTAWBgorBgEEAYO/MAEWBAgMBnB1YmxpYzCBigYKKwYBBAHWeQIEAgR8BHoAeAB2AN09MGrGxxEyYxkeHJlnNwKiSl643jyt/4eKcoAvKe6OAAABikHz+vwAAAQDAEcwRQIgZEo8c0eCZHEh4uzzJzFz9T+EfSTNTtB2FIH18vXpkOsCIQDE1MTti9RoDnRO3SET1Zkad6FoTx/k6ztQcwIDPmnRxTAKBggqhkjOPQQDAwNnADBkAjBB06fmNXx6ToaClFg2kOxnfLGgrvoR3F5GjDtvDBB8m9SWQNzL211jYmS/g+YbbyUCMC+ad6jIK+efe4XOIlhLcWxeZbBtMjKSrPxmm4jR3BFQQOBR+8r27CioyhxoSqvLuw==" + } + ] + }, + "tlogEntries": [ + { + "logIndex": "33351527", + "logId": { + "keyId": "wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0=" + }, + "kindVersion": { + "kind": "intoto", + "version": "0.0.2" + }, + "integratedTime": "1693323623", + "inclusionPromise": { + "signedEntryTimestamp": "MEYCIQDhWvNSLvnq5ZS3qTIgC7K2uQFeA0g8FEEjNo1UQxeubAIhALDrD1uIiUkk3tQNp/4gKT/9j8zEyyxi9Ti+qaD8q2vI" + }, + "inclusionProof": { + "logIndex": "29188096", + "rootHash": "fbEijQTFeiQCldZqez/u/WcrNPk4nxXI5ihofHYjFUA=", + "treeSize": "29188099", + "hashes": [ + "z7VKeAC2d2x18Vtxt7n40GS3gtc1xfRwjjxxzpy/Trw=", + "/Kd8ZuCLZ7MukSwpjaSgxKFl5X2vdHWk6/qpNrkiUJo=", + "vvkKs7IShUI15nVb9c5olPgBnL9r4uP7+d5KzV0hSjs=", + "Fg4p0WJZw8Lghrpxkx1SXgzfroTeIIrEgEbfgr9IdXY=", + "bH8NahqE+hQ58Qxhg0V5fYusFQ1xsaQ/rK6slWVRT5k=", + "HplNgZ3/afEHq52zcfL2s1AKisOYDdMCWK1jOu1tGyw=", + "uOPuC2YDmwZe989ZN3Lgh5CKMXh9HETrSNgf0jV0WkM=", + "eVsvWKnEZ1+Xo3Ba15DfEiIhhmlrEaIeb+VfYmx8KhY=", + "uLuBRins5nkqq2rqd17R27pQTUF+xetttC6MsmlUzd0=", + "jRUq4D8O+FI47Wbw96s7yHCu4qzWUxpIVfxQEeprDmc=", + "rXEsmEJN4PEoTU8US4qVtdIsGB1MCiRlGOepoiC99kM=" + ], + "checkpoint": { + "envelope": "rekor.sigstore.dev - 2605736670972794746\n29188099\nfbEijQTFeiQCldZqez/u/WcrNPk4nxXI5ihofHYjFUA=\nTimestamp: 1693323623528968756\n\n— rekor.sigstore.dev wNI9ajBEAiAK0YTbxRlhOZeeP+844Y+W7iz+hsFIF8x2NYsmuaxifAIgYUFSurlKwN7j5jCwpqSVrkbouQoYIYlyWU9Om16svmI=\n" + } + }, + "canonicalizedBody": "eyJhcGlWZXJzaW9uIjoiMC4wLjIiLCJraW5kIjoiaW50b3RvIiwic3BlYyI6eyJjb250ZW50Ijp7ImVudmVsb3BlIjp7InBheWxvYWRUeXBlIjoiYXBwbGljYXRpb24vdm5kLmluLXRvdG8ranNvbiIsInNpZ25hdHVyZXMiOlt7InB1YmxpY0tleSI6IkxTMHRMUzFDUlVkSlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVWQwUkVORFFtcDFaMEYzU1VKQlowbFZRMHBNYVhCVGREQTVTMHhHWXpCS1dXWjFSSEpUWVc0dkwweHpkME5uV1VsTGIxcEplbW93UlVGM1RYY0tUbnBGVmsxQ1RVZEJNVlZGUTJoTlRXTXliRzVqTTFKMlkyMVZkVnBIVmpKTlVqUjNTRUZaUkZaUlVVUkZlRlo2WVZka2VtUkhPWGxhVXpGd1ltNVNiQXBqYlRGc1drZHNhR1JIVlhkSWFHTk9UV3BOZDA5RVNUVk5WRlV3VFVSSmVsZG9ZMDVOYWsxM1QwUkpOVTFVVlRGTlJFbDZWMnBCUVUxR2EzZEZkMWxJQ2t0dldrbDZhakJEUVZGWlNVdHZXa2w2YWpCRVFWRmpSRkZuUVVWUVptMDJURkJZVVdWS1ZFTTRPVlZQY1dsT1YyMXVXbGxIYlZnMFZETnBURnBIYVRBS1JWWTBZbVpQYjAwNE5raDZZVGswV0hGNWRYZDRRVzlYY0VOUVpXTkdRMFZpUVdVNGJESmtaeTlsY2pOUE9VeEZSbkZQUTBKV2IzZG5aMVpYVFVFMFJ3cEJNVlZrUkhkRlFpOTNVVVZCZDBsSVowUkJWRUpuVGxaSVUxVkZSRVJCUzBKblozSkNaMFZHUWxGalJFRjZRV1JDWjA1V1NGRTBSVVpuVVZWbGNYQkRDbGhJY2pOd1kxVmhURE5GUmt0U0swdHpiWFZMVVhGdmQwaDNXVVJXVWpCcVFrSm5kMFp2UVZVek9WQndlakZaYTBWYVlqVnhUbXB3UzBaWGFYaHBORmtLV2tRNGQxbDNXVVJXVWpCU1FWRklMMEpHYTNkV05GcFdZVWhTTUdOSVRUWk1lVGx1WVZoU2IyUlhTWFZaTWpsMFRETk9jRm96VGpCaU0wcHNURE5PY0FwYU0wNHdZak5LYkV4WGNIcE1lVFZ1WVZoU2IyUlhTWFprTWpsNVlUSmFjMkl6WkhwTU0wcHNZa2RXYUdNeVZYVmxWekZ6VVVoS2JGcHVUWFpoUjFab0NscElUWFppVjBad1ltcEJOVUpuYjNKQ1owVkZRVmxQTDAxQlJVSkNRM1J2WkVoU2QyTjZiM1pNTTFKMllUSldkVXh0Um1wa1IyeDJZbTVOZFZveWJEQUtZVWhXYVdSWVRteGpiVTUyWW01U2JHSnVVWFZaTWpsMFRVSkpSME5wYzBkQlVWRkNaemM0ZDBGUlNVVkNTRUl4WXpKbmQwNW5XVXRMZDFsQ1FrRkhSQXAyZWtGQ1FYZFJiMDFxV210TlZGa3hUVlJOZWs5RVdtMWFiVVpvVG5wcmQxbHFSbXBOZWtwdFQxUkpNMDVVVVRCYWFrVjZUV3BLYkU1RVJUVk9SRUZXQ2tKbmIzSkNaMFZGUVZsUEwwMUJSVVZDUVdSVFdsZDRiRmxZVG14TlEwbEhRMmx6UjBGUlVVSm5OemgzUVZGVlJVWklUbkJhTTA0d1lqTktiRXd6VG5BS1dqTk9NR0l6U214TVYzQjZUVUl3UjBOcGMwZEJVVkZDWnpjNGQwRlJXVVZFTTBwc1dtNU5kbUZIVm1oYVNFMTJZbGRHY0dKcVFUZENaMjl5UW1kRlJRcEJXVTh2VFVGRlNVSkRNRTFMTW1nd1pFaENlazlwT0haa1J6bHlXbGMwZFZsWFRqQmhWemwxWTNrMWJtRllVbTlrVjBveFl6SldlVmt5T1hWa1IxWjFDbVJETldwaU1qQjNXbEZaUzB0M1dVSkNRVWRFZG5wQlFrTlJVbGhFUmxadlpFaFNkMk42YjNaTU1tUndaRWRvTVZscE5XcGlNakIyWXpKc2JtTXpVbllLWTIxVmRtTXliRzVqTTFKMlkyMVZkR0Z1VFhaTWJXUndaRWRvTVZscE9UTmlNMHB5V20xNGRtUXpUWFpqYlZaeldsZEdlbHBUTlRWaVYzaEJZMjFXYlFwamVUbHZXbGRHYTJONU9YUlpWMngxVFVSblIwTnBjMGRCVVZGQ1p6YzRkMEZSYjBWTFozZHZUV3BhYTAxVVdURk5WRTE2VDBSYWJWcHRSbWhPZW10M0NsbHFSbXBOZWtwdFQxUkpNMDVVVVRCYWFrVjZUV3BLYkU1RVJUVk9SRUZrUW1kdmNrSm5SVVZCV1U4dlRVRkZURUpCT0UxRVYyUndaRWRvTVZscE1XOEtZak5PTUZwWFVYZE9kMWxMUzNkWlFrSkJSMFIyZWtGQ1JFRlJjRVJEWkc5a1NGSjNZM3B2ZGt3eVpIQmtSMmd4V1drMWFtSXlNSFpqTW14dVl6TlNkZ3BqYlZWMll6SnNibU16VW5aamJWVjBZVzVOZDA5QldVdExkMWxDUWtGSFJIWjZRVUpFVVZGeFJFTm5lVTV0VVhoT2FsVjRUWHBOTkU1dFdtMVpWMFV6Q2s5VVFtbE5WMDE2VFcxWk5VMXFZekZPUkZKdFRWUk5lVTF0VlRCTlZHc3dUVUk0UjBOcGMwZEJVVkZDWnpjNGQwRlJORVZGVVhkUVkyMVdiV041T1c4S1dsZEdhMk41T1hSWlYyeDFUVUpyUjBOcGMwZEJVVkZDWnpjNGQwRlJPRVZEZDNkS1RrUnJNVTVVWXpCT1ZGVXhUVU56UjBOcGMwZEJVVkZDWnpjNGR3cEJVa0ZGU0ZGM1ltRklVakJqU0UwMlRIazVibUZZVW05a1YwbDFXVEk1ZEV3elRuQmFNMDR3WWpOS2JFMUNaMGREYVhOSFFWRlJRbWMzT0hkQlVrVkZDa05uZDBsT2VrVjNUMVJaZWs1VVRYZGFVVmxMUzNkWlFrSkJSMFIyZWtGQ1JXZFNXRVJHVm05a1NGSjNZM3B2ZGt3eVpIQmtSMmd4V1drMWFtSXlNSFlLWXpKc2JtTXpVblpqYlZWMll6SnNibU16VW5aamJWVjBZVzVOZGt4dFpIQmtSMmd4V1drNU0ySXpTbkphYlhoMlpETk5kbU50Vm5OYVYwWjZXbE0xTlFwaVYzaEJZMjFXYldONU9XOWFWMFpyWTNrNWRGbFhiSFZOUkdkSFEybHpSMEZSVVVKbk56aDNRVkpOUlV0bmQyOU5hbHByVFZSWk1VMVVUWHBQUkZwdENscHRSbWhPZW10M1dXcEdhazE2U20xUFZFa3pUbFJSTUZwcVJYcE5ha3BzVGtSRk5VNUVRVlZDWjI5eVFtZEZSVUZaVHk5TlFVVlZRa0ZaVFVKSVFqRUtZekpuZDFkbldVdExkMWxDUWtGSFJIWjZRVUpHVVZKTlJFVndiMlJJVW5kamVtOTJUREprY0dSSGFERlphVFZxWWpJd2RtTXliRzVqTTFKMlkyMVZkZ3BqTW14dVl6TlNkbU50VlhSaGJrMTJXVmRPTUdGWE9YVmplVGw1WkZjMWVreDZXWGROVkZFd1QwUm5NazVxV1haWldGSXdXbGN4ZDJSSVRYWk5WRUZYQ2tKbmIzSkNaMFZGUVZsUEwwMUJSVmRDUVdkTlFtNUNNVmx0ZUhCWmVrTkNhV2RaUzB0M1dVSkNRVWhYWlZGSlJVRm5VamhDU0c5QlpVRkNNa0ZPTURrS1RVZHlSM2g0UlhsWmVHdGxTRXBzYms1M1MybFRiRFkwTTJwNWRDODBaVXRqYjBGMlMyVTJUMEZCUVVKcGEwaDZLM1ozUVVGQlVVUkJSV04zVWxGSlp3cGFSVzg0WXpCbFExcElSV2cwZFhwNlNucEdlamxVSzBWbVUxUk9WSFJDTWtaSlNERTRkbGh3YTA5elEwbFJSRVV4VFZSMGFUbFNiMFJ1VWs4elUwVlVDakZhYTJGa05rWnZWSGd2YXpaNmRGRmpkMGxFVUcxdVVuaFVRVXRDWjJkeGFHdHFUMUJSVVVSQmQwNXVRVVJDYTBGcVFrSXdObVp0VGxoNE5sUnZZVU1LYkVabk1tdFBlRzVtVEVkbmNuWnZVak5HTlVkcVJIUjJSRUpDT0cwNVUxZFJUbnBNTWpFeGFsbHRVeTluSzFsaVlubFZRMDFESzJGa05tcEpTeXRsWmdwbE5GaFBTV3hvVEdOWGVHVmFZa0owVFdwTFUzSlFlRzF0TkdwU00wSkdVVkZQUWxJck9ISXlOME5wYjNsb2VHOVRjWFpNZFhjOVBRb3RMUzB0TFVWT1JDQkRSVkpVU1VaSlEwRlVSUzB0TFMwdCIsInNpZyI6IlRVVlJRMGxEWVhSb2JsUkljMlJtV25GSWNUTnBXRXhxVFdVd1ZGVTViRXhaYmxJeGVtazNNM0JSZFZobU5VdElRV2xDTWpOS2FDdG5VMll4VVVWRGJrRlRSMlZ3TW1VeVRVZHVVRmhwYjFWTVZqUjJRMGxUU2tKdWEwcGFaejA5In1dfSwiaGFzaCI6eyJhbGdvcml0aG0iOiJzaGEyNTYiLCJ2YWx1ZSI6IjFiZDg4ZTA1NGY2OGE3ZDE3MzkzNjcyYjAzZmExOGZkNjRmMGRjZDVmY2M1NDAzNWMxOWZlNjQwMWNmMmNmNWUifSwicGF5bG9hZEhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiI4Y2ViNGFiODEyNzczMTQ3M2E5ZWM4MTE0MGNiNjg0OWNmOGU5NzBjZGEzMmJhZWYwOTlkZjQ4YmEzMjY0NDQyIn19fX0=" + } + ], + "timestampVerificationData": null + }, + "dsseEnvelope": { + "payload": "eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjEiLCJzdWJqZWN0IjpbeyJuYW1lIjoicGtnOm5wbS9zaWdzdG9yZUAyLjEuMCIsImRpZ2VzdCI6eyJzaGE1MTIiOiI5MGYyMjNmOTkyZTRjODhkZDA2OGNkMmE1ZmM1N2Y5ZDJiMzA3OTgzNDNkZDZlMzhmMjljMjQwZTA0YmEwOTBlZjgzMWY4NDQ5MDg0N2M0ZTgyYjkyMzJjNzhlOGEyNTg0NjNiMWU1NWMwZjc0NjlmNzMwMjY1MDA4ZmE2NjMzZiJ9fV0sInByZWRpY2F0ZVR5cGUiOiJodHRwczovL3Nsc2EuZGV2L3Byb3ZlbmFuY2UvdjEiLCJwcmVkaWNhdGUiOnsiYnVpbGREZWZpbml0aW9uIjp7ImJ1aWxkVHlwZSI6Imh0dHBzOi8vc2xzYS1mcmFtZXdvcmsuZ2l0aHViLmlvL2dpdGh1Yi1hY3Rpb25zLWJ1aWxkdHlwZXMvd29ya2Zsb3cvdjEiLCJleHRlcm5hbFBhcmFtZXRlcnMiOnsid29ya2Zsb3ciOnsicmVmIjoicmVmcy9oZWFkcy9tYWluIiwicmVwb3NpdG9yeSI6Imh0dHBzOi8vZ2l0aHViLmNvbS9zaWdzdG9yZS9zaWdzdG9yZS1qcyIsInBhdGgiOiIuZ2l0aHViL3dvcmtmbG93cy9yZWxlYXNlLnltbCJ9fSwiaW50ZXJuYWxQYXJhbWV0ZXJzIjp7ImdpdGh1YiI6eyJldmVudF9uYW1lIjoicHVzaCIsInJlcG9zaXRvcnlfaWQiOiI0OTU1NzQ1NTUiLCJyZXBvc2l0b3J5X293bmVyX2lkIjoiNzEwOTYzNTMifX0sInJlc29sdmVkRGVwZW5kZW5jaWVzIjpbeyJ1cmkiOiJnaXQraHR0cHM6Ly9naXRodWIuY29tL3NpZ3N0b3JlL3NpZ3N0b3JlLWpzQHJlZnMvaGVhZHMvbWFpbiIsImRpZ2VzdCI6eyJnaXRDb21taXQiOiIyNmQxNjUxMzM4NmZmYWE3OTBiMWMzMmY5Mjc1NDRmMTMyMmU0MTk0In19XX0sInJ1bkRldGFpbHMiOnsiYnVpbGRlciI6eyJpZCI6Imh0dHBzOi8vZ2l0aHViLmNvbS9hY3Rpb25zL3J1bm5lci9naXRodWItaG9zdGVkIn0sIm1ldGFkYXRhIjp7Imludm9jYXRpb25JZCI6Imh0dHBzOi8vZ2l0aHViLmNvbS9zaWdzdG9yZS9zaWdzdG9yZS1qcy9hY3Rpb25zL3J1bnMvNjAxNDQ4ODY2Ni9hdHRlbXB0cy8xIn19fX0=", + "payloadType": "application/vnd.in-toto+json", + "signatures": [ + { + "sig": "MEQCICathnTHsdfZqHq3iXLjMe0TU9lLYnR1zi73pQuXf5KHAiB23Jh+gSf1QECnASGep2e2MGnPXioULV4vCISJBnkJZg==", + "keyid": "" + } + ] + } + } diff --git a/pkg/cmd/attestation/test/data/sigstore-js-2.1.0-bundle.json b/pkg/cmd/attestation/test/data/sigstore-js-2.1.0-bundle.json index d91176e09..d318ea319 100644 --- a/pkg/cmd/attestation/test/data/sigstore-js-2.1.0-bundle.json +++ b/pkg/cmd/attestation/test/data/sigstore-js-2.1.0-bundle.json @@ -1,61 +1,55 @@ { - "mediaType": "application/vnd.dev.sigstore.bundle+json;version=0.1", - "verificationMaterial": { - "x509CertificateChain": { - "certificates": [ - { - "rawBytes": "MIIGtDCCBjugAwIBAgIUCJLipSt09KLFc0JYfuDrSan//LswCgYIKoZIzj0EAwMwNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwHhcNMjMwODI5MTU0MDIzWhcNMjMwODI5MTU1MDIzWjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEPfm6LPXQeJTC89UOqiNWmnZYGmX4T3iLZGi0EV4bfOoM86Hza94XqyuwxAoWpCPecFCEbAe8l2dg/er3O9LEFqOCBVowggVWMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUeqpCXHr3pcUaL3EFKR+KsmuKQqowHwYDVR0jBBgwFoAU39Ppz1YkEZb5qNjpKFWixi4YZD8wYwYDVR0RAQH/BFkwV4ZVaHR0cHM6Ly9naXRodWIuY29tL3NpZ3N0b3JlL3NpZ3N0b3JlLWpzLy5naXRodWIvd29ya2Zsb3dzL3JlbGVhc2UueW1sQHJlZnMvaGVhZHMvbWFpbjA5BgorBgEEAYO/MAEBBCtodHRwczovL3Rva2VuLmFjdGlvbnMuZ2l0aHVidXNlcmNvbnRlbnQuY29tMBIGCisGAQQBg78wAQIEBHB1c2gwNgYKKwYBBAGDvzABAwQoMjZkMTY1MTMzODZmZmFhNzkwYjFjMzJmOTI3NTQ0ZjEzMjJlNDE5NDAVBgorBgEEAYO/MAEEBAdSZWxlYXNlMCIGCisGAQQBg78wAQUEFHNpZ3N0b3JlL3NpZ3N0b3JlLWpzMB0GCisGAQQBg78wAQYED3JlZnMvaGVhZHMvbWFpbjA7BgorBgEEAYO/MAEIBC0MK2h0dHBzOi8vdG9rZW4uYWN0aW9ucy5naXRodWJ1c2VyY29udGVudC5jb20wZQYKKwYBBAGDvzABCQRXDFVodHRwczovL2dpdGh1Yi5jb20vc2lnc3RvcmUvc2lnc3RvcmUtanMvLmdpdGh1Yi93b3JrZmxvd3MvcmVsZWFzZS55bWxAcmVmcy9oZWFkcy9tYWluMDgGCisGAQQBg78wAQoEKgwoMjZkMTY1MTMzODZmZmFhNzkwYjFjMzJmOTI3NTQ0ZjEzMjJlNDE5NDAdBgorBgEEAYO/MAELBA8MDWdpdGh1Yi1ob3N0ZWQwNwYKKwYBBAGDvzABDAQpDCdodHRwczovL2dpdGh1Yi5jb20vc2lnc3RvcmUvc2lnc3RvcmUtanMwOAYKKwYBBAGDvzABDQQqDCgyNmQxNjUxMzM4NmZmYWE3OTBiMWMzMmY5Mjc1NDRmMTMyMmU0MTk0MB8GCisGAQQBg78wAQ4EEQwPcmVmcy9oZWFkcy9tYWluMBkGCisGAQQBg78wAQ8ECwwJNDk1NTc0NTU1MCsGCisGAQQBg78wARAEHQwbaHR0cHM6Ly9naXRodWIuY29tL3NpZ3N0b3JlMBgGCisGAQQBg78wAREECgwINzEwOTYzNTMwZQYKKwYBBAGDvzABEgRXDFVodHRwczovL2dpdGh1Yi5jb20vc2lnc3RvcmUvc2lnc3RvcmUtanMvLmdpdGh1Yi93b3JrZmxvd3MvcmVsZWFzZS55bWxAcmVmcy9oZWFkcy9tYWluMDgGCisGAQQBg78wARMEKgwoMjZkMTY1MTMzODZmZmFhNzkwYjFjMzJmOTI3NTQ0ZjEzMjJlNDE5NDAUBgorBgEEAYO/MAEUBAYMBHB1c2gwWgYKKwYBBAGDvzABFQRMDEpodHRwczovL2dpdGh1Yi5jb20vc2lnc3RvcmUvc2lnc3RvcmUtanMvYWN0aW9ucy9ydW5zLzYwMTQ0ODg2NjYvYXR0ZW1wdHMvMTAWBgorBgEEAYO/MAEWBAgMBnB1YmxpYzCBigYKKwYBBAHWeQIEAgR8BHoAeAB2AN09MGrGxxEyYxkeHJlnNwKiSl643jyt/4eKcoAvKe6OAAABikHz+vwAAAQDAEcwRQIgZEo8c0eCZHEh4uzzJzFz9T+EfSTNTtB2FIH18vXpkOsCIQDE1MTti9RoDnRO3SET1Zkad6FoTx/k6ztQcwIDPmnRxTAKBggqhkjOPQQDAwNnADBkAjBB06fmNXx6ToaClFg2kOxnfLGgrvoR3F5GjDtvDBB8m9SWQNzL211jYmS/g+YbbyUCMC+ad6jIK+efe4XOIlhLcWxeZbBtMjKSrPxmm4jR3BFQQOBR+8r27CioyhxoSqvLuw==" - } - ] - }, - "tlogEntries": [ - { - "logIndex": "33351527", - "logId": { - "keyId": "wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0=" - }, - "kindVersion": { - "kind": "intoto", - "version": "0.0.2" - }, - "integratedTime": "1693323623", - "inclusionPromise": { - "signedEntryTimestamp": "MEYCIQDhWvNSLvnq5ZS3qTIgC7K2uQFeA0g8FEEjNo1UQxeubAIhALDrD1uIiUkk3tQNp/4gKT/9j8zEyyxi9Ti+qaD8q2vI" - }, - "inclusionProof": { - "logIndex": "29188096", - "rootHash": "fbEijQTFeiQCldZqez/u/WcrNPk4nxXI5ihofHYjFUA=", - "treeSize": "29188099", - "hashes": [ - "z7VKeAC2d2x18Vtxt7n40GS3gtc1xfRwjjxxzpy/Trw=", - "/Kd8ZuCLZ7MukSwpjaSgxKFl5X2vdHWk6/qpNrkiUJo=", - "vvkKs7IShUI15nVb9c5olPgBnL9r4uP7+d5KzV0hSjs=", - "Fg4p0WJZw8Lghrpxkx1SXgzfroTeIIrEgEbfgr9IdXY=", - "bH8NahqE+hQ58Qxhg0V5fYusFQ1xsaQ/rK6slWVRT5k=", - "HplNgZ3/afEHq52zcfL2s1AKisOYDdMCWK1jOu1tGyw=", - "uOPuC2YDmwZe989ZN3Lgh5CKMXh9HETrSNgf0jV0WkM=", - "eVsvWKnEZ1+Xo3Ba15DfEiIhhmlrEaIeb+VfYmx8KhY=", - "uLuBRins5nkqq2rqd17R27pQTUF+xetttC6MsmlUzd0=", - "jRUq4D8O+FI47Wbw96s7yHCu4qzWUxpIVfxQEeprDmc=", - "rXEsmEJN4PEoTU8US4qVtdIsGB1MCiRlGOepoiC99kM=" - ], - "checkpoint": { - "envelope": "rekor.sigstore.dev - 2605736670972794746\n29188099\nfbEijQTFeiQCldZqez/u/WcrNPk4nxXI5ihofHYjFUA=\nTimestamp: 1693323623528968756\n\n— rekor.sigstore.dev wNI9ajBEAiAK0YTbxRlhOZeeP+844Y+W7iz+hsFIF8x2NYsmuaxifAIgYUFSurlKwN7j5jCwpqSVrkbouQoYIYlyWU9Om16svmI=\n" - } - }, - "canonicalizedBody": "eyJhcGlWZXJzaW9uIjoiMC4wLjIiLCJraW5kIjoiaW50b3RvIiwic3BlYyI6eyJjb250ZW50Ijp7ImVudmVsb3BlIjp7InBheWxvYWRUeXBlIjoiYXBwbGljYXRpb24vdm5kLmluLXRvdG8ranNvbiIsInNpZ25hdHVyZXMiOlt7InB1YmxpY0tleSI6IkxTMHRMUzFDUlVkSlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVWQwUkVORFFtcDFaMEYzU1VKQlowbFZRMHBNYVhCVGREQTVTMHhHWXpCS1dXWjFSSEpUWVc0dkwweHpkME5uV1VsTGIxcEplbW93UlVGM1RYY0tUbnBGVmsxQ1RVZEJNVlZGUTJoTlRXTXliRzVqTTFKMlkyMVZkVnBIVmpKTlVqUjNTRUZaUkZaUlVVUkZlRlo2WVZka2VtUkhPWGxhVXpGd1ltNVNiQXBqYlRGc1drZHNhR1JIVlhkSWFHTk9UV3BOZDA5RVNUVk5WRlV3VFVSSmVsZG9ZMDVOYWsxM1QwUkpOVTFVVlRGTlJFbDZWMnBCUVUxR2EzZEZkMWxJQ2t0dldrbDZhakJEUVZGWlNVdHZXa2w2YWpCRVFWRmpSRkZuUVVWUVptMDJURkJZVVdWS1ZFTTRPVlZQY1dsT1YyMXVXbGxIYlZnMFZETnBURnBIYVRBS1JWWTBZbVpQYjAwNE5raDZZVGswV0hGNWRYZDRRVzlYY0VOUVpXTkdRMFZpUVdVNGJESmtaeTlsY2pOUE9VeEZSbkZQUTBKV2IzZG5aMVpYVFVFMFJ3cEJNVlZrUkhkRlFpOTNVVVZCZDBsSVowUkJWRUpuVGxaSVUxVkZSRVJCUzBKblozSkNaMFZHUWxGalJFRjZRV1JDWjA1V1NGRTBSVVpuVVZWbGNYQkRDbGhJY2pOd1kxVmhURE5GUmt0U0swdHpiWFZMVVhGdmQwaDNXVVJXVWpCcVFrSm5kMFp2UVZVek9WQndlakZaYTBWYVlqVnhUbXB3UzBaWGFYaHBORmtLV2tRNGQxbDNXVVJXVWpCU1FWRklMMEpHYTNkV05GcFdZVWhTTUdOSVRUWk1lVGx1WVZoU2IyUlhTWFZaTWpsMFRETk9jRm96VGpCaU0wcHNURE5PY0FwYU0wNHdZak5LYkV4WGNIcE1lVFZ1WVZoU2IyUlhTWFprTWpsNVlUSmFjMkl6WkhwTU0wcHNZa2RXYUdNeVZYVmxWekZ6VVVoS2JGcHVUWFpoUjFab0NscElUWFppVjBad1ltcEJOVUpuYjNKQ1owVkZRVmxQTDAxQlJVSkNRM1J2WkVoU2QyTjZiM1pNTTFKMllUSldkVXh0Um1wa1IyeDJZbTVOZFZveWJEQUtZVWhXYVdSWVRteGpiVTUyWW01U2JHSnVVWFZaTWpsMFRVSkpSME5wYzBkQlVWRkNaemM0ZDBGUlNVVkNTRUl4WXpKbmQwNW5XVXRMZDFsQ1FrRkhSQXAyZWtGQ1FYZFJiMDFxV210TlZGa3hUVlJOZWs5RVdtMWFiVVpvVG5wcmQxbHFSbXBOZWtwdFQxUkpNMDVVVVRCYWFrVjZUV3BLYkU1RVJUVk9SRUZXQ2tKbmIzSkNaMFZGUVZsUEwwMUJSVVZDUVdSVFdsZDRiRmxZVG14TlEwbEhRMmx6UjBGUlVVSm5OemgzUVZGVlJVWklUbkJhTTA0d1lqTktiRXd6VG5BS1dqTk9NR0l6U214TVYzQjZUVUl3UjBOcGMwZEJVVkZDWnpjNGQwRlJXVVZFTTBwc1dtNU5kbUZIVm1oYVNFMTJZbGRHY0dKcVFUZENaMjl5UW1kRlJRcEJXVTh2VFVGRlNVSkRNRTFMTW1nd1pFaENlazlwT0haa1J6bHlXbGMwZFZsWFRqQmhWemwxWTNrMWJtRllVbTlrVjBveFl6SldlVmt5T1hWa1IxWjFDbVJETldwaU1qQjNXbEZaUzB0M1dVSkNRVWRFZG5wQlFrTlJVbGhFUmxadlpFaFNkMk42YjNaTU1tUndaRWRvTVZscE5XcGlNakIyWXpKc2JtTXpVbllLWTIxVmRtTXliRzVqTTFKMlkyMVZkR0Z1VFhaTWJXUndaRWRvTVZscE9UTmlNMHB5V20xNGRtUXpUWFpqYlZaeldsZEdlbHBUTlRWaVYzaEJZMjFXYlFwamVUbHZXbGRHYTJONU9YUlpWMngxVFVSblIwTnBjMGRCVVZGQ1p6YzRkMEZSYjBWTFozZHZUV3BhYTAxVVdURk5WRTE2VDBSYWJWcHRSbWhPZW10M0NsbHFSbXBOZWtwdFQxUkpNMDVVVVRCYWFrVjZUV3BLYkU1RVJUVk9SRUZrUW1kdmNrSm5SVVZCV1U4dlRVRkZURUpCT0UxRVYyUndaRWRvTVZscE1XOEtZak5PTUZwWFVYZE9kMWxMUzNkWlFrSkJSMFIyZWtGQ1JFRlJjRVJEWkc5a1NGSjNZM3B2ZGt3eVpIQmtSMmd4V1drMWFtSXlNSFpqTW14dVl6TlNkZ3BqYlZWMll6SnNibU16VW5aamJWVjBZVzVOZDA5QldVdExkMWxDUWtGSFJIWjZRVUpFVVZGeFJFTm5lVTV0VVhoT2FsVjRUWHBOTkU1dFdtMVpWMFV6Q2s5VVFtbE5WMDE2VFcxWk5VMXFZekZPUkZKdFRWUk5lVTF0VlRCTlZHc3dUVUk0UjBOcGMwZEJVVkZDWnpjNGQwRlJORVZGVVhkUVkyMVdiV041T1c4S1dsZEdhMk41T1hSWlYyeDFUVUpyUjBOcGMwZEJVVkZDWnpjNGQwRlJPRVZEZDNkS1RrUnJNVTVVWXpCT1ZGVXhUVU56UjBOcGMwZEJVVkZDWnpjNGR3cEJVa0ZGU0ZGM1ltRklVakJqU0UwMlRIazVibUZZVW05a1YwbDFXVEk1ZEV3elRuQmFNMDR3WWpOS2JFMUNaMGREYVhOSFFWRlJRbWMzT0hkQlVrVkZDa05uZDBsT2VrVjNUMVJaZWs1VVRYZGFVVmxMUzNkWlFrSkJSMFIyZWtGQ1JXZFNXRVJHVm05a1NGSjNZM3B2ZGt3eVpIQmtSMmd4V1drMWFtSXlNSFlLWXpKc2JtTXpVblpqYlZWMll6SnNibU16VW5aamJWVjBZVzVOZGt4dFpIQmtSMmd4V1drNU0ySXpTbkphYlhoMlpETk5kbU50Vm5OYVYwWjZXbE0xTlFwaVYzaEJZMjFXYldONU9XOWFWMFpyWTNrNWRGbFhiSFZOUkdkSFEybHpSMEZSVVVKbk56aDNRVkpOUlV0bmQyOU5hbHByVFZSWk1VMVVUWHBQUkZwdENscHRSbWhPZW10M1dXcEdhazE2U20xUFZFa3pUbFJSTUZwcVJYcE5ha3BzVGtSRk5VNUVRVlZDWjI5eVFtZEZSVUZaVHk5TlFVVlZRa0ZaVFVKSVFqRUtZekpuZDFkbldVdExkMWxDUWtGSFJIWjZRVUpHVVZKTlJFVndiMlJJVW5kamVtOTJUREprY0dSSGFERlphVFZxWWpJd2RtTXliRzVqTTFKMlkyMVZkZ3BqTW14dVl6TlNkbU50VlhSaGJrMTJXVmRPTUdGWE9YVmplVGw1WkZjMWVreDZXWGROVkZFd1QwUm5NazVxV1haWldGSXdXbGN4ZDJSSVRYWk5WRUZYQ2tKbmIzSkNaMFZGUVZsUEwwMUJSVmRDUVdkTlFtNUNNVmx0ZUhCWmVrTkNhV2RaUzB0M1dVSkNRVWhYWlZGSlJVRm5VamhDU0c5QlpVRkNNa0ZPTURrS1RVZHlSM2g0UlhsWmVHdGxTRXBzYms1M1MybFRiRFkwTTJwNWRDODBaVXRqYjBGMlMyVTJUMEZCUVVKcGEwaDZLM1ozUVVGQlVVUkJSV04zVWxGSlp3cGFSVzg0WXpCbFExcElSV2cwZFhwNlNucEdlamxVSzBWbVUxUk9WSFJDTWtaSlNERTRkbGh3YTA5elEwbFJSRVV4VFZSMGFUbFNiMFJ1VWs4elUwVlVDakZhYTJGa05rWnZWSGd2YXpaNmRGRmpkMGxFVUcxdVVuaFVRVXRDWjJkeGFHdHFUMUJSVVVSQmQwNXVRVVJDYTBGcVFrSXdObVp0VGxoNE5sUnZZVU1LYkVabk1tdFBlRzVtVEVkbmNuWnZVak5HTlVkcVJIUjJSRUpDT0cwNVUxZFJUbnBNTWpFeGFsbHRVeTluSzFsaVlubFZRMDFESzJGa05tcEpTeXRsWmdwbE5GaFBTV3hvVEdOWGVHVmFZa0owVFdwTFUzSlFlRzF0TkdwU00wSkdVVkZQUWxJck9ISXlOME5wYjNsb2VHOVRjWFpNZFhjOVBRb3RMUzB0TFVWT1JDQkRSVkpVU1VaSlEwRlVSUzB0TFMwdCIsInNpZyI6IlRVVlJRMGxEWVhSb2JsUkljMlJtV25GSWNUTnBXRXhxVFdVd1ZGVTViRXhaYmxJeGVtazNNM0JSZFZobU5VdElRV2xDTWpOS2FDdG5VMll4VVVWRGJrRlRSMlZ3TW1VeVRVZHVVRmhwYjFWTVZqUjJRMGxUU2tKdWEwcGFaejA5In1dfSwiaGFzaCI6eyJhbGdvcml0aG0iOiJzaGEyNTYiLCJ2YWx1ZSI6IjFiZDg4ZTA1NGY2OGE3ZDE3MzkzNjcyYjAzZmExOGZkNjRmMGRjZDVmY2M1NDAzNWMxOWZlNjQwMWNmMmNmNWUifSwicGF5bG9hZEhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiI4Y2ViNGFiODEyNzczMTQ3M2E5ZWM4MTE0MGNiNjg0OWNmOGU5NzBjZGEzMmJhZWYwOTlkZjQ4YmEzMjY0NDQyIn19fX0=" - } - ], - "timestampVerificationData": null - }, - "dsseEnvelope": { - "payload": "eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjEiLCJzdWJqZWN0IjpbeyJuYW1lIjoicGtnOm5wbS9zaWdzdG9yZUAyLjEuMCIsImRpZ2VzdCI6eyJzaGE1MTIiOiI5MGYyMjNmOTkyZTRjODhkZDA2OGNkMmE1ZmM1N2Y5ZDJiMzA3OTgzNDNkZDZlMzhmMjljMjQwZTA0YmEwOTBlZjgzMWY4NDQ5MDg0N2M0ZTgyYjkyMzJjNzhlOGEyNTg0NjNiMWU1NWMwZjc0NjlmNzMwMjY1MDA4ZmE2NjMzZiJ9fV0sInByZWRpY2F0ZVR5cGUiOiJodHRwczovL3Nsc2EuZGV2L3Byb3ZlbmFuY2UvdjEiLCJwcmVkaWNhdGUiOnsiYnVpbGREZWZpbml0aW9uIjp7ImJ1aWxkVHlwZSI6Imh0dHBzOi8vc2xzYS1mcmFtZXdvcmsuZ2l0aHViLmlvL2dpdGh1Yi1hY3Rpb25zLWJ1aWxkdHlwZXMvd29ya2Zsb3cvdjEiLCJleHRlcm5hbFBhcmFtZXRlcnMiOnsid29ya2Zsb3ciOnsicmVmIjoicmVmcy9oZWFkcy9tYWluIiwicmVwb3NpdG9yeSI6Imh0dHBzOi8vZ2l0aHViLmNvbS9zaWdzdG9yZS9zaWdzdG9yZS1qcyIsInBhdGgiOiIuZ2l0aHViL3dvcmtmbG93cy9yZWxlYXNlLnltbCJ9fSwiaW50ZXJuYWxQYXJhbWV0ZXJzIjp7ImdpdGh1YiI6eyJldmVudF9uYW1lIjoicHVzaCIsInJlcG9zaXRvcnlfaWQiOiI0OTU1NzQ1NTUiLCJyZXBvc2l0b3J5X293bmVyX2lkIjoiNzEwOTYzNTMifX0sInJlc29sdmVkRGVwZW5kZW5jaWVzIjpbeyJ1cmkiOiJnaXQraHR0cHM6Ly9naXRodWIuY29tL3NpZ3N0b3JlL3NpZ3N0b3JlLWpzQHJlZnMvaGVhZHMvbWFpbiIsImRpZ2VzdCI6eyJnaXRDb21taXQiOiIyNmQxNjUxMzM4NmZmYWE3OTBiMWMzMmY5Mjc1NDRmMTMyMmU0MTk0In19XX0sInJ1bkRldGFpbHMiOnsiYnVpbGRlciI6eyJpZCI6Imh0dHBzOi8vZ2l0aHViLmNvbS9hY3Rpb25zL3J1bm5lci9naXRodWItaG9zdGVkIn0sIm1ldGFkYXRhIjp7Imludm9jYXRpb25JZCI6Imh0dHBzOi8vZ2l0aHViLmNvbS9zaWdzdG9yZS9zaWdzdG9yZS1qcy9hY3Rpb25zL3J1bnMvNjAxNDQ4ODY2Ni9hdHRlbXB0cy8xIn19fX0=", - "payloadType": "application/vnd.in-toto+json", - "signatures": [ - { - "sig": "MEQCICathnTHsdfZqHq3iXLjMe0TU9lLYnR1zi73pQuXf5KHAiB23Jh+gSf1QECnASGep2e2MGnPXioULV4vCISJBnkJZg==", - "keyid": "" - } - ] - } - } + "mediaType": "application/vnd.dev.sigstore.bundle.v0.3+json", + "verificationMaterial": { + "certificate": { + "rawBytes": "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" + }, + "tlogEntries": [ + { + "logIndex": "33351527", + "logId": { + "keyId": "wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0=" + }, + "kindVersion": { + "kind": "intoto", + "version": "0.0.2" + }, + "integratedTime": "1693323623", + "inclusionPromise": { + "signedEntryTimestamp": "MEYCIQDhWvNSLvnq5ZS3qTIgC7K2uQFeA0g8FEEjNo1UQxeubAIhALDrD1uIiUkk3tQNp/4gKT/9j8zEyyxi9Ti+qaD8q2vI" + }, + "inclusionProof": { + "logIndex": "29188096", + "rootHash": "fbEijQTFeiQCldZqez/u/WcrNPk4nxXI5ihofHYjFUA=", + "treeSize": "29188099", + "hashes": [ + "z7VKeAC2d2x18Vtxt7n40GS3gtc1xfRwjjxxzpy/Trw=", + "/Kd8ZuCLZ7MukSwpjaSgxKFl5X2vdHWk6/qpNrkiUJo=", + "vvkKs7IShUI15nVb9c5olPgBnL9r4uP7+d5KzV0hSjs=", + "Fg4p0WJZw8Lghrpxkx1SXgzfroTeIIrEgEbfgr9IdXY=", + "bH8NahqE+hQ58Qxhg0V5fYusFQ1xsaQ/rK6slWVRT5k=", + "HplNgZ3/afEHq52zcfL2s1AKisOYDdMCWK1jOu1tGyw=", + "uOPuC2YDmwZe989ZN3Lgh5CKMXh9HETrSNgf0jV0WkM=", + "eVsvWKnEZ1+Xo3Ba15DfEiIhhmlrEaIeb+VfYmx8KhY=", + "uLuBRins5nkqq2rqd17R27pQTUF+xetttC6MsmlUzd0=", + "jRUq4D8O+FI47Wbw96s7yHCu4qzWUxpIVfxQEeprDmc=", + "rXEsmEJN4PEoTU8US4qVtdIsGB1MCiRlGOepoiC99kM=" + ], + "checkpoint": { + "envelope": "rekor.sigstore.dev - 2605736670972794746\n29188099\nfbEijQTFeiQCldZqez/u/WcrNPk4nxXI5ihofHYjFUA=\nTimestamp: 1693323623528968756\n\n— rekor.sigstore.dev wNI9ajBEAiAK0YTbxRlhOZeeP+844Y+W7iz+hsFIF8x2NYsmuaxifAIgYUFSurlKwN7j5jCwpqSVrkbouQoYIYlyWU9Om16svmI=\n" + } + }, + "canonicalizedBody": "eyJhcGlWZXJzaW9uIjoiMC4wLjIiLCJraW5kIjoiaW50b3RvIiwic3BlYyI6eyJjb250ZW50Ijp7ImVudmVsb3BlIjp7InBheWxvYWRUeXBlIjoiYXBwbGljYXRpb24vdm5kLmluLXRvdG8ranNvbiIsInNpZ25hdHVyZXMiOlt7InB1YmxpY0tleSI6IkxTMHRMUzFDUlVkSlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVWQwUkVORFFtcDFaMEYzU1VKQlowbFZRMHBNYVhCVGREQTVTMHhHWXpCS1dXWjFSSEpUWVc0dkwweHpkME5uV1VsTGIxcEplbW93UlVGM1RYY0tUbnBGVmsxQ1RVZEJNVlZGUTJoTlRXTXliRzVqTTFKMlkyMVZkVnBIVmpKTlVqUjNTRUZaUkZaUlVVUkZlRlo2WVZka2VtUkhPWGxhVXpGd1ltNVNiQXBqYlRGc1drZHNhR1JIVlhkSWFHTk9UV3BOZDA5RVNUVk5WRlV3VFVSSmVsZG9ZMDVOYWsxM1QwUkpOVTFVVlRGTlJFbDZWMnBCUVUxR2EzZEZkMWxJQ2t0dldrbDZhakJEUVZGWlNVdHZXa2w2YWpCRVFWRmpSRkZuUVVWUVptMDJURkJZVVdWS1ZFTTRPVlZQY1dsT1YyMXVXbGxIYlZnMFZETnBURnBIYVRBS1JWWTBZbVpQYjAwNE5raDZZVGswV0hGNWRYZDRRVzlYY0VOUVpXTkdRMFZpUVdVNGJESmtaeTlsY2pOUE9VeEZSbkZQUTBKV2IzZG5aMVpYVFVFMFJ3cEJNVlZrUkhkRlFpOTNVVVZCZDBsSVowUkJWRUpuVGxaSVUxVkZSRVJCUzBKblozSkNaMFZHUWxGalJFRjZRV1JDWjA1V1NGRTBSVVpuVVZWbGNYQkRDbGhJY2pOd1kxVmhURE5GUmt0U0swdHpiWFZMVVhGdmQwaDNXVVJXVWpCcVFrSm5kMFp2UVZVek9WQndlakZaYTBWYVlqVnhUbXB3UzBaWGFYaHBORmtLV2tRNGQxbDNXVVJXVWpCU1FWRklMMEpHYTNkV05GcFdZVWhTTUdOSVRUWk1lVGx1WVZoU2IyUlhTWFZaTWpsMFRETk9jRm96VGpCaU0wcHNURE5PY0FwYU0wNHdZak5LYkV4WGNIcE1lVFZ1WVZoU2IyUlhTWFprTWpsNVlUSmFjMkl6WkhwTU0wcHNZa2RXYUdNeVZYVmxWekZ6VVVoS2JGcHVUWFpoUjFab0NscElUWFppVjBad1ltcEJOVUpuYjNKQ1owVkZRVmxQTDAxQlJVSkNRM1J2WkVoU2QyTjZiM1pNTTFKMllUSldkVXh0Um1wa1IyeDJZbTVOZFZveWJEQUtZVWhXYVdSWVRteGpiVTUyWW01U2JHSnVVWFZaTWpsMFRVSkpSME5wYzBkQlVWRkNaemM0ZDBGUlNVVkNTRUl4WXpKbmQwNW5XVXRMZDFsQ1FrRkhSQXAyZWtGQ1FYZFJiMDFxV210TlZGa3hUVlJOZWs5RVdtMWFiVVpvVG5wcmQxbHFSbXBOZWtwdFQxUkpNMDVVVVRCYWFrVjZUV3BLYkU1RVJUVk9SRUZXQ2tKbmIzSkNaMFZGUVZsUEwwMUJSVVZDUVdSVFdsZDRiRmxZVG14TlEwbEhRMmx6UjBGUlVVSm5OemgzUVZGVlJVWklUbkJhTTA0d1lqTktiRXd6VG5BS1dqTk9NR0l6U214TVYzQjZUVUl3UjBOcGMwZEJVVkZDWnpjNGQwRlJXVVZFTTBwc1dtNU5kbUZIVm1oYVNFMTJZbGRHY0dKcVFUZENaMjl5UW1kRlJRcEJXVTh2VFVGRlNVSkRNRTFMTW1nd1pFaENlazlwT0haa1J6bHlXbGMwZFZsWFRqQmhWemwxWTNrMWJtRllVbTlrVjBveFl6SldlVmt5T1hWa1IxWjFDbVJETldwaU1qQjNXbEZaUzB0M1dVSkNRVWRFZG5wQlFrTlJVbGhFUmxadlpFaFNkMk42YjNaTU1tUndaRWRvTVZscE5XcGlNakIyWXpKc2JtTXpVbllLWTIxVmRtTXliRzVqTTFKMlkyMVZkR0Z1VFhaTWJXUndaRWRvTVZscE9UTmlNMHB5V20xNGRtUXpUWFpqYlZaeldsZEdlbHBUTlRWaVYzaEJZMjFXYlFwamVUbHZXbGRHYTJONU9YUlpWMngxVFVSblIwTnBjMGRCVVZGQ1p6YzRkMEZSYjBWTFozZHZUV3BhYTAxVVdURk5WRTE2VDBSYWJWcHRSbWhPZW10M0NsbHFSbXBOZWtwdFQxUkpNMDVVVVRCYWFrVjZUV3BLYkU1RVJUVk9SRUZrUW1kdmNrSm5SVVZCV1U4dlRVRkZURUpCT0UxRVYyUndaRWRvTVZscE1XOEtZak5PTUZwWFVYZE9kMWxMUzNkWlFrSkJSMFIyZWtGQ1JFRlJjRVJEWkc5a1NGSjNZM3B2ZGt3eVpIQmtSMmd4V1drMWFtSXlNSFpqTW14dVl6TlNkZ3BqYlZWMll6SnNibU16VW5aamJWVjBZVzVOZDA5QldVdExkMWxDUWtGSFJIWjZRVUpFVVZGeFJFTm5lVTV0VVhoT2FsVjRUWHBOTkU1dFdtMVpWMFV6Q2s5VVFtbE5WMDE2VFcxWk5VMXFZekZPUkZKdFRWUk5lVTF0VlRCTlZHc3dUVUk0UjBOcGMwZEJVVkZDWnpjNGQwRlJORVZGVVhkUVkyMVdiV041T1c4S1dsZEdhMk41T1hSWlYyeDFUVUpyUjBOcGMwZEJVVkZDWnpjNGQwRlJPRVZEZDNkS1RrUnJNVTVVWXpCT1ZGVXhUVU56UjBOcGMwZEJVVkZDWnpjNGR3cEJVa0ZGU0ZGM1ltRklVakJqU0UwMlRIazVibUZZVW05a1YwbDFXVEk1ZEV3elRuQmFNMDR3WWpOS2JFMUNaMGREYVhOSFFWRlJRbWMzT0hkQlVrVkZDa05uZDBsT2VrVjNUMVJaZWs1VVRYZGFVVmxMUzNkWlFrSkJSMFIyZWtGQ1JXZFNXRVJHVm05a1NGSjNZM3B2ZGt3eVpIQmtSMmd4V1drMWFtSXlNSFlLWXpKc2JtTXpVblpqYlZWMll6SnNibU16VW5aamJWVjBZVzVOZGt4dFpIQmtSMmd4V1drNU0ySXpTbkphYlhoMlpETk5kbU50Vm5OYVYwWjZXbE0xTlFwaVYzaEJZMjFXYldONU9XOWFWMFpyWTNrNWRGbFhiSFZOUkdkSFEybHpSMEZSVVVKbk56aDNRVkpOUlV0bmQyOU5hbHByVFZSWk1VMVVUWHBQUkZwdENscHRSbWhPZW10M1dXcEdhazE2U20xUFZFa3pUbFJSTUZwcVJYcE5ha3BzVGtSRk5VNUVRVlZDWjI5eVFtZEZSVUZaVHk5TlFVVlZRa0ZaVFVKSVFqRUtZekpuZDFkbldVdExkMWxDUWtGSFJIWjZRVUpHVVZKTlJFVndiMlJJVW5kamVtOTJUREprY0dSSGFERlphVFZxWWpJd2RtTXliRzVqTTFKMlkyMVZkZ3BqTW14dVl6TlNkbU50VlhSaGJrMTJXVmRPTUdGWE9YVmplVGw1WkZjMWVreDZXWGROVkZFd1QwUm5NazVxV1haWldGSXdXbGN4ZDJSSVRYWk5WRUZYQ2tKbmIzSkNaMFZGUVZsUEwwMUJSVmRDUVdkTlFtNUNNVmx0ZUhCWmVrTkNhV2RaUzB0M1dVSkNRVWhYWlZGSlJVRm5VamhDU0c5QlpVRkNNa0ZPTURrS1RVZHlSM2g0UlhsWmVHdGxTRXBzYms1M1MybFRiRFkwTTJwNWRDODBaVXRqYjBGMlMyVTJUMEZCUVVKcGEwaDZLM1ozUVVGQlVVUkJSV04zVWxGSlp3cGFSVzg0WXpCbFExcElSV2cwZFhwNlNucEdlamxVSzBWbVUxUk9WSFJDTWtaSlNERTRkbGh3YTA5elEwbFJSRVV4VFZSMGFUbFNiMFJ1VWs4elUwVlVDakZhYTJGa05rWnZWSGd2YXpaNmRGRmpkMGxFVUcxdVVuaFVRVXRDWjJkeGFHdHFUMUJSVVVSQmQwNXVRVVJDYTBGcVFrSXdObVp0VGxoNE5sUnZZVU1LYkVabk1tdFBlRzVtVEVkbmNuWnZVak5HTlVkcVJIUjJSRUpDT0cwNVUxZFJUbnBNTWpFeGFsbHRVeTluSzFsaVlubFZRMDFESzJGa05tcEpTeXRsWmdwbE5GaFBTV3hvVEdOWGVHVmFZa0owVFdwTFUzSlFlRzF0TkdwU00wSkdVVkZQUWxJck9ISXlOME5wYjNsb2VHOVRjWFpNZFhjOVBRb3RMUzB0TFVWT1JDQkRSVkpVU1VaSlEwRlVSUzB0TFMwdCIsInNpZyI6IlRVVlJRMGxEWVhSb2JsUkljMlJtV25GSWNUTnBXRXhxVFdVd1ZGVTViRXhaYmxJeGVtazNNM0JSZFZobU5VdElRV2xDTWpOS2FDdG5VMll4VVVWRGJrRlRSMlZ3TW1VeVRVZHVVRmhwYjFWTVZqUjJRMGxUU2tKdWEwcGFaejA5In1dfSwiaGFzaCI6eyJhbGdvcml0aG0iOiJzaGEyNTYiLCJ2YWx1ZSI6IjFiZDg4ZTA1NGY2OGE3ZDE3MzkzNjcyYjAzZmExOGZkNjRmMGRjZDVmY2M1NDAzNWMxOWZlNjQwMWNmMmNmNWUifSwicGF5bG9hZEhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiI4Y2ViNGFiODEyNzczMTQ3M2E5ZWM4MTE0MGNiNjg0OWNmOGU5NzBjZGEzMmJhZWYwOTlkZjQ4YmEzMjY0NDQyIn19fX0=" + } + ] + }, + "dsseEnvelope": { + "payload": "eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjEiLCJzdWJqZWN0IjpbeyJuYW1lIjoicGtnOm5wbS9zaWdzdG9yZUAyLjEuMCIsImRpZ2VzdCI6eyJzaGE1MTIiOiI5MGYyMjNmOTkyZTRjODhkZDA2OGNkMmE1ZmM1N2Y5ZDJiMzA3OTgzNDNkZDZlMzhmMjljMjQwZTA0YmEwOTBlZjgzMWY4NDQ5MDg0N2M0ZTgyYjkyMzJjNzhlOGEyNTg0NjNiMWU1NWMwZjc0NjlmNzMwMjY1MDA4ZmE2NjMzZiJ9fV0sInByZWRpY2F0ZVR5cGUiOiJodHRwczovL3Nsc2EuZGV2L3Byb3ZlbmFuY2UvdjEiLCJwcmVkaWNhdGUiOnsiYnVpbGREZWZpbml0aW9uIjp7ImJ1aWxkVHlwZSI6Imh0dHBzOi8vc2xzYS1mcmFtZXdvcmsuZ2l0aHViLmlvL2dpdGh1Yi1hY3Rpb25zLWJ1aWxkdHlwZXMvd29ya2Zsb3cvdjEiLCJleHRlcm5hbFBhcmFtZXRlcnMiOnsid29ya2Zsb3ciOnsicmVmIjoicmVmcy9oZWFkcy9tYWluIiwicmVwb3NpdG9yeSI6Imh0dHBzOi8vZ2l0aHViLmNvbS9zaWdzdG9yZS9zaWdzdG9yZS1qcyIsInBhdGgiOiIuZ2l0aHViL3dvcmtmbG93cy9yZWxlYXNlLnltbCJ9fSwiaW50ZXJuYWxQYXJhbWV0ZXJzIjp7ImdpdGh1YiI6eyJldmVudF9uYW1lIjoicHVzaCIsInJlcG9zaXRvcnlfaWQiOiI0OTU1NzQ1NTUiLCJyZXBvc2l0b3J5X293bmVyX2lkIjoiNzEwOTYzNTMifX0sInJlc29sdmVkRGVwZW5kZW5jaWVzIjpbeyJ1cmkiOiJnaXQraHR0cHM6Ly9naXRodWIuY29tL3NpZ3N0b3JlL3NpZ3N0b3JlLWpzQHJlZnMvaGVhZHMvbWFpbiIsImRpZ2VzdCI6eyJnaXRDb21taXQiOiIyNmQxNjUxMzM4NmZmYWE3OTBiMWMzMmY5Mjc1NDRmMTMyMmU0MTk0In19XX0sInJ1bkRldGFpbHMiOnsiYnVpbGRlciI6eyJpZCI6Imh0dHBzOi8vZ2l0aHViLmNvbS9hY3Rpb25zL3J1bm5lci9naXRodWItaG9zdGVkIn0sIm1ldGFkYXRhIjp7Imludm9jYXRpb25JZCI6Imh0dHBzOi8vZ2l0aHViLmNvbS9zaWdzdG9yZS9zaWdzdG9yZS1qcy9hY3Rpb25zL3J1bnMvNjAxNDQ4ODY2Ni9hdHRlbXB0cy8xIn19fX0=", + "payloadType": "application/vnd.in-toto+json", + "signatures": [ + { + "sig": "MEQCICathnTHsdfZqHq3iXLjMe0TU9lLYnR1zi73pQuXf5KHAiB23Jh+gSf1QECnASGep2e2MGnPXioULV4vCISJBnkJZg==" + } + ] + } +} diff --git a/pkg/cmd/attestation/test/data/sigstore-js-2.1.0_with_2_bundles.jsonl b/pkg/cmd/attestation/test/data/sigstore-js-2.1.0_with_2_bundles.jsonl index a4aca34d0..265b1666d 100644 --- a/pkg/cmd/attestation/test/data/sigstore-js-2.1.0_with_2_bundles.jsonl +++ b/pkg/cmd/attestation/test/data/sigstore-js-2.1.0_with_2_bundles.jsonl @@ -1,2 +1,2 @@ -{"mediaType":"application/vnd.dev.sigstore.bundle+json;version=0.1","verificationMaterial":{"x509CertificateChain":{"certificates":[{"rawBytes":"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"}]},"tlogEntries":[{"logIndex":"33351527","logId":{"keyId":"wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="},"kindVersion":{"kind":"intoto","version":"0.0.2"},"integratedTime":"1693323623","inclusionPromise":{"signedEntryTimestamp":"MEYCIQDhWvNSLvnq5ZS3qTIgC7K2uQFeA0g8FEEjNo1UQxeubAIhALDrD1uIiUkk3tQNp/4gKT/9j8zEyyxi9Ti+qaD8q2vI"},"inclusionProof":{"logIndex":"29188096","rootHash":"fbEijQTFeiQCldZqez/u/WcrNPk4nxXI5ihofHYjFUA=","treeSize":"29188099","hashes":["z7VKeAC2d2x18Vtxt7n40GS3gtc1xfRwjjxxzpy/Trw=","/Kd8ZuCLZ7MukSwpjaSgxKFl5X2vdHWk6/qpNrkiUJo=","vvkKs7IShUI15nVb9c5olPgBnL9r4uP7+d5KzV0hSjs=","Fg4p0WJZw8Lghrpxkx1SXgzfroTeIIrEgEbfgr9IdXY=","bH8NahqE+hQ58Qxhg0V5fYusFQ1xsaQ/rK6slWVRT5k=","HplNgZ3/afEHq52zcfL2s1AKisOYDdMCWK1jOu1tGyw=","uOPuC2YDmwZe989ZN3Lgh5CKMXh9HETrSNgf0jV0WkM=","eVsvWKnEZ1+Xo3Ba15DfEiIhhmlrEaIeb+VfYmx8KhY=","uLuBRins5nkqq2rqd17R27pQTUF+xetttC6MsmlUzd0=","jRUq4D8O+FI47Wbw96s7yHCu4qzWUxpIVfxQEeprDmc=","rXEsmEJN4PEoTU8US4qVtdIsGB1MCiRlGOepoiC99kM="],"checkpoint":{"envelope":"rekor.sigstore.dev - 2605736670972794746\n29188099\nfbEijQTFeiQCldZqez/u/WcrNPk4nxXI5ihofHYjFUA=\nTimestamp: 1693323623528968756\n\n— rekor.sigstore.dev wNI9ajBEAiAK0YTbxRlhOZeeP+844Y+W7iz+hsFIF8x2NYsmuaxifAIgYUFSurlKwN7j5jCwpqSVrkbouQoYIYlyWU9Om16svmI=\n"}},"canonicalizedBody":"eyJhcGlWZXJzaW9uIjoiMC4wLjIiLCJraW5kIjoiaW50b3RvIiwic3BlYyI6eyJjb250ZW50Ijp7ImVudmVsb3BlIjp7InBheWxvYWRUeXBlIjoiYXBwbGljYXRpb24vdm5kLmluLXRvdG8ranNvbiIsInNpZ25hdHVyZXMiOlt7InB1YmxpY0tleSI6IkxTMHRMUzFDUlVkSlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVWQwUkVORFFtcDFaMEYzU1VKQlowbFZRMHBNYVhCVGREQTVTMHhHWXpCS1dXWjFSSEpUWVc0dkwweHpkME5uV1VsTGIxcEplbW93UlVGM1RYY0tUbnBGVmsxQ1RVZEJNVlZGUTJoTlRXTXliRzVqTTFKMlkyMVZkVnBIVmpKTlVqUjNTRUZaUkZaUlVVUkZlRlo2WVZka2VtUkhPWGxhVXpGd1ltNVNiQXBqYlRGc1drZHNhR1JIVlhkSWFHTk9UV3BOZDA5RVNUVk5WRlV3VFVSSmVsZG9ZMDVOYWsxM1QwUkpOVTFVVlRGTlJFbDZWMnBCUVUxR2EzZEZkMWxJQ2t0dldrbDZhakJEUVZGWlNVdHZXa2w2YWpCRVFWRmpSRkZuUVVWUVptMDJURkJZVVdWS1ZFTTRPVlZQY1dsT1YyMXVXbGxIYlZnMFZETnBURnBIYVRBS1JWWTBZbVpQYjAwNE5raDZZVGswV0hGNWRYZDRRVzlYY0VOUVpXTkdRMFZpUVdVNGJESmtaeTlsY2pOUE9VeEZSbkZQUTBKV2IzZG5aMVpYVFVFMFJ3cEJNVlZrUkhkRlFpOTNVVVZCZDBsSVowUkJWRUpuVGxaSVUxVkZSRVJCUzBKblozSkNaMFZHUWxGalJFRjZRV1JDWjA1V1NGRTBSVVpuVVZWbGNYQkRDbGhJY2pOd1kxVmhURE5GUmt0U0swdHpiWFZMVVhGdmQwaDNXVVJXVWpCcVFrSm5kMFp2UVZVek9WQndlakZaYTBWYVlqVnhUbXB3UzBaWGFYaHBORmtLV2tRNGQxbDNXVVJXVWpCU1FWRklMMEpHYTNkV05GcFdZVWhTTUdOSVRUWk1lVGx1WVZoU2IyUlhTWFZaTWpsMFRETk9jRm96VGpCaU0wcHNURE5PY0FwYU0wNHdZak5LYkV4WGNIcE1lVFZ1WVZoU2IyUlhTWFprTWpsNVlUSmFjMkl6WkhwTU0wcHNZa2RXYUdNeVZYVmxWekZ6VVVoS2JGcHVUWFpoUjFab0NscElUWFppVjBad1ltcEJOVUpuYjNKQ1owVkZRVmxQTDAxQlJVSkNRM1J2WkVoU2QyTjZiM1pNTTFKMllUSldkVXh0Um1wa1IyeDJZbTVOZFZveWJEQUtZVWhXYVdSWVRteGpiVTUyWW01U2JHSnVVWFZaTWpsMFRVSkpSME5wYzBkQlVWRkNaemM0ZDBGUlNVVkNTRUl4WXpKbmQwNW5XVXRMZDFsQ1FrRkhSQXAyZWtGQ1FYZFJiMDFxV210TlZGa3hUVlJOZWs5RVdtMWFiVVpvVG5wcmQxbHFSbXBOZWtwdFQxUkpNMDVVVVRCYWFrVjZUV3BLYkU1RVJUVk9SRUZXQ2tKbmIzSkNaMFZGUVZsUEwwMUJSVVZDUVdSVFdsZDRiRmxZVG14TlEwbEhRMmx6UjBGUlVVSm5OemgzUVZGVlJVWklUbkJhTTA0d1lqTktiRXd6VG5BS1dqTk9NR0l6U214TVYzQjZUVUl3UjBOcGMwZEJVVkZDWnpjNGQwRlJXVVZFTTBwc1dtNU5kbUZIVm1oYVNFMTJZbGRHY0dKcVFUZENaMjl5UW1kRlJRcEJXVTh2VFVGRlNVSkRNRTFMTW1nd1pFaENlazlwT0haa1J6bHlXbGMwZFZsWFRqQmhWemwxWTNrMWJtRllVbTlrVjBveFl6SldlVmt5T1hWa1IxWjFDbVJETldwaU1qQjNXbEZaUzB0M1dVSkNRVWRFZG5wQlFrTlJVbGhFUmxadlpFaFNkMk42YjNaTU1tUndaRWRvTVZscE5XcGlNakIyWXpKc2JtTXpVbllLWTIxVmRtTXliRzVqTTFKMlkyMVZkR0Z1VFhaTWJXUndaRWRvTVZscE9UTmlNMHB5V20xNGRtUXpUWFpqYlZaeldsZEdlbHBUTlRWaVYzaEJZMjFXYlFwamVUbHZXbGRHYTJONU9YUlpWMngxVFVSblIwTnBjMGRCVVZGQ1p6YzRkMEZSYjBWTFozZHZUV3BhYTAxVVdURk5WRTE2VDBSYWJWcHRSbWhPZW10M0NsbHFSbXBOZWtwdFQxUkpNMDVVVVRCYWFrVjZUV3BLYkU1RVJUVk9SRUZrUW1kdmNrSm5SVVZCV1U4dlRVRkZURUpCT0UxRVYyUndaRWRvTVZscE1XOEtZak5PTUZwWFVYZE9kMWxMUzNkWlFrSkJSMFIyZWtGQ1JFRlJjRVJEWkc5a1NGSjNZM3B2ZGt3eVpIQmtSMmd4V1drMWFtSXlNSFpqTW14dVl6TlNkZ3BqYlZWMll6SnNibU16VW5aamJWVjBZVzVOZDA5QldVdExkMWxDUWtGSFJIWjZRVUpFVVZGeFJFTm5lVTV0VVhoT2FsVjRUWHBOTkU1dFdtMVpWMFV6Q2s5VVFtbE5WMDE2VFcxWk5VMXFZekZPUkZKdFRWUk5lVTF0VlRCTlZHc3dUVUk0UjBOcGMwZEJVVkZDWnpjNGQwRlJORVZGVVhkUVkyMVdiV041T1c4S1dsZEdhMk41T1hSWlYyeDFUVUpyUjBOcGMwZEJVVkZDWnpjNGQwRlJPRVZEZDNkS1RrUnJNVTVVWXpCT1ZGVXhUVU56UjBOcGMwZEJVVkZDWnpjNGR3cEJVa0ZGU0ZGM1ltRklVakJqU0UwMlRIazVibUZZVW05a1YwbDFXVEk1ZEV3elRuQmFNMDR3WWpOS2JFMUNaMGREYVhOSFFWRlJRbWMzT0hkQlVrVkZDa05uZDBsT2VrVjNUMVJaZWs1VVRYZGFVVmxMUzNkWlFrSkJSMFIyZWtGQ1JXZFNXRVJHVm05a1NGSjNZM3B2ZGt3eVpIQmtSMmd4V1drMWFtSXlNSFlLWXpKc2JtTXpVblpqYlZWMll6SnNibU16VW5aamJWVjBZVzVOZGt4dFpIQmtSMmd4V1drNU0ySXpTbkphYlhoMlpETk5kbU50Vm5OYVYwWjZXbE0xTlFwaVYzaEJZMjFXYldONU9XOWFWMFpyWTNrNWRGbFhiSFZOUkdkSFEybHpSMEZSVVVKbk56aDNRVkpOUlV0bmQyOU5hbHByVFZSWk1VMVVUWHBQUkZwdENscHRSbWhPZW10M1dXcEdhazE2U20xUFZFa3pUbFJSTUZwcVJYcE5ha3BzVGtSRk5VNUVRVlZDWjI5eVFtZEZSVUZaVHk5TlFVVlZRa0ZaVFVKSVFqRUtZekpuZDFkbldVdExkMWxDUWtGSFJIWjZRVUpHVVZKTlJFVndiMlJJVW5kamVtOTJUREprY0dSSGFERlphVFZxWWpJd2RtTXliRzVqTTFKMlkyMVZkZ3BqTW14dVl6TlNkbU50VlhSaGJrMTJXVmRPTUdGWE9YVmplVGw1WkZjMWVreDZXWGROVkZFd1QwUm5NazVxV1haWldGSXdXbGN4ZDJSSVRYWk5WRUZYQ2tKbmIzSkNaMFZGUVZsUEwwMUJSVmRDUVdkTlFtNUNNVmx0ZUhCWmVrTkNhV2RaUzB0M1dVSkNRVWhYWlZGSlJVRm5VamhDU0c5QlpVRkNNa0ZPTURrS1RVZHlSM2g0UlhsWmVHdGxTRXBzYms1M1MybFRiRFkwTTJwNWRDODBaVXRqYjBGMlMyVTJUMEZCUVVKcGEwaDZLM1ozUVVGQlVVUkJSV04zVWxGSlp3cGFSVzg0WXpCbFExcElSV2cwZFhwNlNucEdlamxVSzBWbVUxUk9WSFJDTWtaSlNERTRkbGh3YTA5elEwbFJSRVV4VFZSMGFUbFNiMFJ1VWs4elUwVlVDakZhYTJGa05rWnZWSGd2YXpaNmRGRmpkMGxFVUcxdVVuaFVRVXRDWjJkeGFHdHFUMUJSVVVSQmQwNXVRVVJDYTBGcVFrSXdObVp0VGxoNE5sUnZZVU1LYkVabk1tdFBlRzVtVEVkbmNuWnZVak5HTlVkcVJIUjJSRUpDT0cwNVUxZFJUbnBNTWpFeGFsbHRVeTluSzFsaVlubFZRMDFESzJGa05tcEpTeXRsWmdwbE5GaFBTV3hvVEdOWGVHVmFZa0owVFdwTFUzSlFlRzF0TkdwU00wSkdVVkZQUWxJck9ISXlOME5wYjNsb2VHOVRjWFpNZFhjOVBRb3RMUzB0TFVWT1JDQkRSVkpVU1VaSlEwRlVSUzB0TFMwdCIsInNpZyI6IlRVVlJRMGxEWVhSb2JsUkljMlJtV25GSWNUTnBXRXhxVFdVd1ZGVTViRXhaYmxJeGVtazNNM0JSZFZobU5VdElRV2xDTWpOS2FDdG5VMll4VVVWRGJrRlRSMlZ3TW1VeVRVZHVVRmhwYjFWTVZqUjJRMGxUU2tKdWEwcGFaejA5In1dfSwiaGFzaCI6eyJhbGdvcml0aG0iOiJzaGEyNTYiLCJ2YWx1ZSI6IjFiZDg4ZTA1NGY2OGE3ZDE3MzkzNjcyYjAzZmExOGZkNjRmMGRjZDVmY2M1NDAzNWMxOWZlNjQwMWNmMmNmNWUifSwicGF5bG9hZEhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiI4Y2ViNGFiODEyNzczMTQ3M2E5ZWM4MTE0MGNiNjg0OWNmOGU5NzBjZGEzMmJhZWYwOTlkZjQ4YmEzMjY0NDQyIn19fX0="}],"timestampVerificationData":null},"dsseEnvelope":{"payload":"eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjEiLCJzdWJqZWN0IjpbeyJuYW1lIjoicGtnOm5wbS9zaWdzdG9yZUAyLjEuMCIsImRpZ2VzdCI6eyJzaGE1MTIiOiI5MGYyMjNmOTkyZTRjODhkZDA2OGNkMmE1ZmM1N2Y5ZDJiMzA3OTgzNDNkZDZlMzhmMjljMjQwZTA0YmEwOTBlZjgzMWY4NDQ5MDg0N2M0ZTgyYjkyMzJjNzhlOGEyNTg0NjNiMWU1NWMwZjc0NjlmNzMwMjY1MDA4ZmE2NjMzZiJ9fV0sInByZWRpY2F0ZVR5cGUiOiJodHRwczovL3Nsc2EuZGV2L3Byb3ZlbmFuY2UvdjEiLCJwcmVkaWNhdGUiOnsiYnVpbGREZWZpbml0aW9uIjp7ImJ1aWxkVHlwZSI6Imh0dHBzOi8vc2xzYS1mcmFtZXdvcmsuZ2l0aHViLmlvL2dpdGh1Yi1hY3Rpb25zLWJ1aWxkdHlwZXMvd29ya2Zsb3cvdjEiLCJleHRlcm5hbFBhcmFtZXRlcnMiOnsid29ya2Zsb3ciOnsicmVmIjoicmVmcy9oZWFkcy9tYWluIiwicmVwb3NpdG9yeSI6Imh0dHBzOi8vZ2l0aHViLmNvbS9zaWdzdG9yZS9zaWdzdG9yZS1qcyIsInBhdGgiOiIuZ2l0aHViL3dvcmtmbG93cy9yZWxlYXNlLnltbCJ9fSwiaW50ZXJuYWxQYXJhbWV0ZXJzIjp7ImdpdGh1YiI6eyJldmVudF9uYW1lIjoicHVzaCIsInJlcG9zaXRvcnlfaWQiOiI0OTU1NzQ1NTUiLCJyZXBvc2l0b3J5X293bmVyX2lkIjoiNzEwOTYzNTMifX0sInJlc29sdmVkRGVwZW5kZW5jaWVzIjpbeyJ1cmkiOiJnaXQraHR0cHM6Ly9naXRodWIuY29tL3NpZ3N0b3JlL3NpZ3N0b3JlLWpzQHJlZnMvaGVhZHMvbWFpbiIsImRpZ2VzdCI6eyJnaXRDb21taXQiOiIyNmQxNjUxMzM4NmZmYWE3OTBiMWMzMmY5Mjc1NDRmMTMyMmU0MTk0In19XX0sInJ1bkRldGFpbHMiOnsiYnVpbGRlciI6eyJpZCI6Imh0dHBzOi8vZ2l0aHViLmNvbS9hY3Rpb25zL3J1bm5lci9naXRodWItaG9zdGVkIn0sIm1ldGFkYXRhIjp7Imludm9jYXRpb25JZCI6Imh0dHBzOi8vZ2l0aHViLmNvbS9zaWdzdG9yZS9zaWdzdG9yZS1qcy9hY3Rpb25zL3J1bnMvNjAxNDQ4ODY2Ni9hdHRlbXB0cy8xIn19fX0=","payloadType":"application/vnd.in-toto+json","signatures":[{"sig":"MEQCICathnTHsdfZqHq3iXLjMe0TU9lLYnR1zi73pQuXf5KHAiB23Jh+gSf1QECnASGep2e2MGnPXioULV4vCISJBnkJZg==","keyid":""}]}} -{"mediaType":"application/vnd.dev.sigstore.bundle+json;version=0.1","verificationMaterial":{"x509CertificateChain":{"certificates":[{"rawBytes":"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"}]},"tlogEntries":[{"logIndex":"33351527","logId":{"keyId":"wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="},"kindVersion":{"kind":"intoto","version":"0.0.2"},"integratedTime":"1693323623","inclusionPromise":{"signedEntryTimestamp":"MEYCIQDhWvNSLvnq5ZS3qTIgC7K2uQFeA0g8FEEjNo1UQxeubAIhALDrD1uIiUkk3tQNp/4gKT/9j8zEyyxi9Ti+qaD8q2vI"},"inclusionProof":{"logIndex":"29188096","rootHash":"fbEijQTFeiQCldZqez/u/WcrNPk4nxXI5ihofHYjFUA=","treeSize":"29188099","hashes":["z7VKeAC2d2x18Vtxt7n40GS3gtc1xfRwjjxxzpy/Trw=","/Kd8ZuCLZ7MukSwpjaSgxKFl5X2vdHWk6/qpNrkiUJo=","vvkKs7IShUI15nVb9c5olPgBnL9r4uP7+d5KzV0hSjs=","Fg4p0WJZw8Lghrpxkx1SXgzfroTeIIrEgEbfgr9IdXY=","bH8NahqE+hQ58Qxhg0V5fYusFQ1xsaQ/rK6slWVRT5k=","HplNgZ3/afEHq52zcfL2s1AKisOYDdMCWK1jOu1tGyw=","uOPuC2YDmwZe989ZN3Lgh5CKMXh9HETrSNgf0jV0WkM=","eVsvWKnEZ1+Xo3Ba15DfEiIhhmlrEaIeb+VfYmx8KhY=","uLuBRins5nkqq2rqd17R27pQTUF+xetttC6MsmlUzd0=","jRUq4D8O+FI47Wbw96s7yHCu4qzWUxpIVfxQEeprDmc=","rXEsmEJN4PEoTU8US4qVtdIsGB1MCiRlGOepoiC99kM="],"checkpoint":{"envelope":"rekor.sigstore.dev - 2605736670972794746\n29188099\nfbEijQTFeiQCldZqez/u/WcrNPk4nxXI5ihofHYjFUA=\nTimestamp: 1693323623528968756\n\n— rekor.sigstore.dev wNI9ajBEAiAK0YTbxRlhOZeeP+844Y+W7iz+hsFIF8x2NYsmuaxifAIgYUFSurlKwN7j5jCwpqSVrkbouQoYIYlyWU9Om16svmI=\n"}},"canonicalizedBody":"eyJhcGlWZXJzaW9uIjoiMC4wLjIiLCJraW5kIjoiaW50b3RvIiwic3BlYyI6eyJjb250ZW50Ijp7ImVudmVsb3BlIjp7InBheWxvYWRUeXBlIjoiYXBwbGljYXRpb24vdm5kLmluLXRvdG8ranNvbiIsInNpZ25hdHVyZXMiOlt7InB1YmxpY0tleSI6IkxTMHRMUzFDUlVkSlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVWQwUkVORFFtcDFaMEYzU1VKQlowbFZRMHBNYVhCVGREQTVTMHhHWXpCS1dXWjFSSEpUWVc0dkwweHpkME5uV1VsTGIxcEplbW93UlVGM1RYY0tUbnBGVmsxQ1RVZEJNVlZGUTJoTlRXTXliRzVqTTFKMlkyMVZkVnBIVmpKTlVqUjNTRUZaUkZaUlVVUkZlRlo2WVZka2VtUkhPWGxhVXpGd1ltNVNiQXBqYlRGc1drZHNhR1JIVlhkSWFHTk9UV3BOZDA5RVNUVk5WRlV3VFVSSmVsZG9ZMDVOYWsxM1QwUkpOVTFVVlRGTlJFbDZWMnBCUVUxR2EzZEZkMWxJQ2t0dldrbDZhakJEUVZGWlNVdHZXa2w2YWpCRVFWRmpSRkZuUVVWUVptMDJURkJZVVdWS1ZFTTRPVlZQY1dsT1YyMXVXbGxIYlZnMFZETnBURnBIYVRBS1JWWTBZbVpQYjAwNE5raDZZVGswV0hGNWRYZDRRVzlYY0VOUVpXTkdRMFZpUVdVNGJESmtaeTlsY2pOUE9VeEZSbkZQUTBKV2IzZG5aMVpYVFVFMFJ3cEJNVlZrUkhkRlFpOTNVVVZCZDBsSVowUkJWRUpuVGxaSVUxVkZSRVJCUzBKblozSkNaMFZHUWxGalJFRjZRV1JDWjA1V1NGRTBSVVpuVVZWbGNYQkRDbGhJY2pOd1kxVmhURE5GUmt0U0swdHpiWFZMVVhGdmQwaDNXVVJXVWpCcVFrSm5kMFp2UVZVek9WQndlakZaYTBWYVlqVnhUbXB3UzBaWGFYaHBORmtLV2tRNGQxbDNXVVJXVWpCU1FWRklMMEpHYTNkV05GcFdZVWhTTUdOSVRUWk1lVGx1WVZoU2IyUlhTWFZaTWpsMFRETk9jRm96VGpCaU0wcHNURE5PY0FwYU0wNHdZak5LYkV4WGNIcE1lVFZ1WVZoU2IyUlhTWFprTWpsNVlUSmFjMkl6WkhwTU0wcHNZa2RXYUdNeVZYVmxWekZ6VVVoS2JGcHVUWFpoUjFab0NscElUWFppVjBad1ltcEJOVUpuYjNKQ1owVkZRVmxQTDAxQlJVSkNRM1J2WkVoU2QyTjZiM1pNTTFKMllUSldkVXh0Um1wa1IyeDJZbTVOZFZveWJEQUtZVWhXYVdSWVRteGpiVTUyWW01U2JHSnVVWFZaTWpsMFRVSkpSME5wYzBkQlVWRkNaemM0ZDBGUlNVVkNTRUl4WXpKbmQwNW5XVXRMZDFsQ1FrRkhSQXAyZWtGQ1FYZFJiMDFxV210TlZGa3hUVlJOZWs5RVdtMWFiVVpvVG5wcmQxbHFSbXBOZWtwdFQxUkpNMDVVVVRCYWFrVjZUV3BLYkU1RVJUVk9SRUZXQ2tKbmIzSkNaMFZGUVZsUEwwMUJSVVZDUVdSVFdsZDRiRmxZVG14TlEwbEhRMmx6UjBGUlVVSm5OemgzUVZGVlJVWklUbkJhTTA0d1lqTktiRXd6VG5BS1dqTk9NR0l6U214TVYzQjZUVUl3UjBOcGMwZEJVVkZDWnpjNGQwRlJXVVZFTTBwc1dtNU5kbUZIVm1oYVNFMTJZbGRHY0dKcVFUZENaMjl5UW1kRlJRcEJXVTh2VFVGRlNVSkRNRTFMTW1nd1pFaENlazlwT0haa1J6bHlXbGMwZFZsWFRqQmhWemwxWTNrMWJtRllVbTlrVjBveFl6SldlVmt5T1hWa1IxWjFDbVJETldwaU1qQjNXbEZaUzB0M1dVSkNRVWRFZG5wQlFrTlJVbGhFUmxadlpFaFNkMk42YjNaTU1tUndaRWRvTVZscE5XcGlNakIyWXpKc2JtTXpVbllLWTIxVmRtTXliRzVqTTFKMlkyMVZkR0Z1VFhaTWJXUndaRWRvTVZscE9UTmlNMHB5V20xNGRtUXpUWFpqYlZaeldsZEdlbHBUTlRWaVYzaEJZMjFXYlFwamVUbHZXbGRHYTJONU9YUlpWMngxVFVSblIwTnBjMGRCVVZGQ1p6YzRkMEZSYjBWTFozZHZUV3BhYTAxVVdURk5WRTE2VDBSYWJWcHRSbWhPZW10M0NsbHFSbXBOZWtwdFQxUkpNMDVVVVRCYWFrVjZUV3BLYkU1RVJUVk9SRUZrUW1kdmNrSm5SVVZCV1U4dlRVRkZURUpCT0UxRVYyUndaRWRvTVZscE1XOEtZak5PTUZwWFVYZE9kMWxMUzNkWlFrSkJSMFIyZWtGQ1JFRlJjRVJEWkc5a1NGSjNZM3B2ZGt3eVpIQmtSMmd4V1drMWFtSXlNSFpqTW14dVl6TlNkZ3BqYlZWMll6SnNibU16VW5aamJWVjBZVzVOZDA5QldVdExkMWxDUWtGSFJIWjZRVUpFVVZGeFJFTm5lVTV0VVhoT2FsVjRUWHBOTkU1dFdtMVpWMFV6Q2s5VVFtbE5WMDE2VFcxWk5VMXFZekZPUkZKdFRWUk5lVTF0VlRCTlZHc3dUVUk0UjBOcGMwZEJVVkZDWnpjNGQwRlJORVZGVVhkUVkyMVdiV041T1c4S1dsZEdhMk41T1hSWlYyeDFUVUpyUjBOcGMwZEJVVkZDWnpjNGQwRlJPRVZEZDNkS1RrUnJNVTVVWXpCT1ZGVXhUVU56UjBOcGMwZEJVVkZDWnpjNGR3cEJVa0ZGU0ZGM1ltRklVakJqU0UwMlRIazVibUZZVW05a1YwbDFXVEk1ZEV3elRuQmFNMDR3WWpOS2JFMUNaMGREYVhOSFFWRlJRbWMzT0hkQlVrVkZDa05uZDBsT2VrVjNUMVJaZWs1VVRYZGFVVmxMUzNkWlFrSkJSMFIyZWtGQ1JXZFNXRVJHVm05a1NGSjNZM3B2ZGt3eVpIQmtSMmd4V1drMWFtSXlNSFlLWXpKc2JtTXpVblpqYlZWMll6SnNibU16VW5aamJWVjBZVzVOZGt4dFpIQmtSMmd4V1drNU0ySXpTbkphYlhoMlpETk5kbU50Vm5OYVYwWjZXbE0xTlFwaVYzaEJZMjFXYldONU9XOWFWMFpyWTNrNWRGbFhiSFZOUkdkSFEybHpSMEZSVVVKbk56aDNRVkpOUlV0bmQyOU5hbHByVFZSWk1VMVVUWHBQUkZwdENscHRSbWhPZW10M1dXcEdhazE2U20xUFZFa3pUbFJSTUZwcVJYcE5ha3BzVGtSRk5VNUVRVlZDWjI5eVFtZEZSVUZaVHk5TlFVVlZRa0ZaVFVKSVFqRUtZekpuZDFkbldVdExkMWxDUWtGSFJIWjZRVUpHVVZKTlJFVndiMlJJVW5kamVtOTJUREprY0dSSGFERlphVFZxWWpJd2RtTXliRzVqTTFKMlkyMVZkZ3BqTW14dVl6TlNkbU50VlhSaGJrMTJXVmRPTUdGWE9YVmplVGw1WkZjMWVreDZXWGROVkZFd1QwUm5NazVxV1haWldGSXdXbGN4ZDJSSVRYWk5WRUZYQ2tKbmIzSkNaMFZGUVZsUEwwMUJSVmRDUVdkTlFtNUNNVmx0ZUhCWmVrTkNhV2RaUzB0M1dVSkNRVWhYWlZGSlJVRm5VamhDU0c5QlpVRkNNa0ZPTURrS1RVZHlSM2g0UlhsWmVHdGxTRXBzYms1M1MybFRiRFkwTTJwNWRDODBaVXRqYjBGMlMyVTJUMEZCUVVKcGEwaDZLM1ozUVVGQlVVUkJSV04zVWxGSlp3cGFSVzg0WXpCbFExcElSV2cwZFhwNlNucEdlamxVSzBWbVUxUk9WSFJDTWtaSlNERTRkbGh3YTA5elEwbFJSRVV4VFZSMGFUbFNiMFJ1VWs4elUwVlVDakZhYTJGa05rWnZWSGd2YXpaNmRGRmpkMGxFVUcxdVVuaFVRVXRDWjJkeGFHdHFUMUJSVVVSQmQwNXVRVVJDYTBGcVFrSXdObVp0VGxoNE5sUnZZVU1LYkVabk1tdFBlRzVtVEVkbmNuWnZVak5HTlVkcVJIUjJSRUpDT0cwNVUxZFJUbnBNTWpFeGFsbHRVeTluSzFsaVlubFZRMDFESzJGa05tcEpTeXRsWmdwbE5GaFBTV3hvVEdOWGVHVmFZa0owVFdwTFUzSlFlRzF0TkdwU00wSkdVVkZQUWxJck9ISXlOME5wYjNsb2VHOVRjWFpNZFhjOVBRb3RMUzB0TFVWT1JDQkRSVkpVU1VaSlEwRlVSUzB0TFMwdCIsInNpZyI6IlRVVlJRMGxEWVhSb2JsUkljMlJtV25GSWNUTnBXRXhxVFdVd1ZGVTViRXhaYmxJeGVtazNNM0JSZFZobU5VdElRV2xDTWpOS2FDdG5VMll4VVVWRGJrRlRSMlZ3TW1VeVRVZHVVRmhwYjFWTVZqUjJRMGxUU2tKdWEwcGFaejA5In1dfSwiaGFzaCI6eyJhbGdvcml0aG0iOiJzaGEyNTYiLCJ2YWx1ZSI6IjFiZDg4ZTA1NGY2OGE3ZDE3MzkzNjcyYjAzZmExOGZkNjRmMGRjZDVmY2M1NDAzNWMxOWZlNjQwMWNmMmNmNWUifSwicGF5bG9hZEhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiI4Y2ViNGFiODEyNzczMTQ3M2E5ZWM4MTE0MGNiNjg0OWNmOGU5NzBjZGEzMmJhZWYwOTlkZjQ4YmEzMjY0NDQyIn19fX0="}],"timestampVerificationData":null},"dsseEnvelope":{"payload":"eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjEiLCJzdWJqZWN0IjpbeyJuYW1lIjoicGtnOm5wbS9zaWdzdG9yZUAyLjEuMCIsImRpZ2VzdCI6eyJzaGE1MTIiOiI5MGYyMjNmOTkyZTRjODhkZDA2OGNkMmE1ZmM1N2Y5ZDJiMzA3OTgzNDNkZDZlMzhmMjljMjQwZTA0YmEwOTBlZjgzMWY4NDQ5MDg0N2M0ZTgyYjkyMzJjNzhlOGEyNTg0NjNiMWU1NWMwZjc0NjlmNzMwMjY1MDA4ZmE2NjMzZiJ9fV0sInByZWRpY2F0ZVR5cGUiOiJodHRwczovL3Nsc2EuZGV2L3Byb3ZlbmFuY2UvdjEiLCJwcmVkaWNhdGUiOnsiYnVpbGREZWZpbml0aW9uIjp7ImJ1aWxkVHlwZSI6Imh0dHBzOi8vc2xzYS1mcmFtZXdvcmsuZ2l0aHViLmlvL2dpdGh1Yi1hY3Rpb25zLWJ1aWxkdHlwZXMvd29ya2Zsb3cvdjEiLCJleHRlcm5hbFBhcmFtZXRlcnMiOnsid29ya2Zsb3ciOnsicmVmIjoicmVmcy9oZWFkcy9tYWluIiwicmVwb3NpdG9yeSI6Imh0dHBzOi8vZ2l0aHViLmNvbS9zaWdzdG9yZS9zaWdzdG9yZS1qcyIsInBhdGgiOiIuZ2l0aHViL3dvcmtmbG93cy9yZWxlYXNlLnltbCJ9fSwiaW50ZXJuYWxQYXJhbWV0ZXJzIjp7ImdpdGh1YiI6eyJldmVudF9uYW1lIjoicHVzaCIsInJlcG9zaXRvcnlfaWQiOiI0OTU1NzQ1NTUiLCJyZXBvc2l0b3J5X293bmVyX2lkIjoiNzEwOTYzNTMifX0sInJlc29sdmVkRGVwZW5kZW5jaWVzIjpbeyJ1cmkiOiJnaXQraHR0cHM6Ly9naXRodWIuY29tL3NpZ3N0b3JlL3NpZ3N0b3JlLWpzQHJlZnMvaGVhZHMvbWFpbiIsImRpZ2VzdCI6eyJnaXRDb21taXQiOiIyNmQxNjUxMzM4NmZmYWE3OTBiMWMzMmY5Mjc1NDRmMTMyMmU0MTk0In19XX0sInJ1bkRldGFpbHMiOnsiYnVpbGRlciI6eyJpZCI6Imh0dHBzOi8vZ2l0aHViLmNvbS9hY3Rpb25zL3J1bm5lci9naXRodWItaG9zdGVkIn0sIm1ldGFkYXRhIjp7Imludm9jYXRpb25JZCI6Imh0dHBzOi8vZ2l0aHViLmNvbS9zaWdzdG9yZS9zaWdzdG9yZS1qcy9hY3Rpb25zL3J1bnMvNjAxNDQ4ODY2Ni9hdHRlbXB0cy8xIn19fX0=","payloadType":"application/vnd.in-toto+json","signatures":[{"sig":"MEQCICathnTHsdfZqHq3iXLjMe0TU9lLYnR1zi73pQuXf5KHAiB23Jh+gSf1QECnASGep2e2MGnPXioULV4vCISJBnkJZg==","keyid":""}]}} +{"mediaType":"application/vnd.dev.sigstore.bundle.v0.3+json","verificationMaterial":{"certificate":{"rawBytes":"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"},"tlogEntries":[{"logIndex":"33351527","logId":{"keyId":"wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="},"kindVersion":{"kind":"intoto","version":"0.0.2"},"integratedTime":"1693323623","inclusionPromise":{"signedEntryTimestamp":"MEYCIQDhWvNSLvnq5ZS3qTIgC7K2uQFeA0g8FEEjNo1UQxeubAIhALDrD1uIiUkk3tQNp/4gKT/9j8zEyyxi9Ti+qaD8q2vI"},"inclusionProof":{"logIndex":"29188096","rootHash":"fbEijQTFeiQCldZqez/u/WcrNPk4nxXI5ihofHYjFUA=","treeSize":"29188099","hashes":["z7VKeAC2d2x18Vtxt7n40GS3gtc1xfRwjjxxzpy/Trw=","/Kd8ZuCLZ7MukSwpjaSgxKFl5X2vdHWk6/qpNrkiUJo=","vvkKs7IShUI15nVb9c5olPgBnL9r4uP7+d5KzV0hSjs=","Fg4p0WJZw8Lghrpxkx1SXgzfroTeIIrEgEbfgr9IdXY=","bH8NahqE+hQ58Qxhg0V5fYusFQ1xsaQ/rK6slWVRT5k=","HplNgZ3/afEHq52zcfL2s1AKisOYDdMCWK1jOu1tGyw=","uOPuC2YDmwZe989ZN3Lgh5CKMXh9HETrSNgf0jV0WkM=","eVsvWKnEZ1+Xo3Ba15DfEiIhhmlrEaIeb+VfYmx8KhY=","uLuBRins5nkqq2rqd17R27pQTUF+xetttC6MsmlUzd0=","jRUq4D8O+FI47Wbw96s7yHCu4qzWUxpIVfxQEeprDmc=","rXEsmEJN4PEoTU8US4qVtdIsGB1MCiRlGOepoiC99kM="],"checkpoint":{"envelope":"rekor.sigstore.dev - 2605736670972794746\n29188099\nfbEijQTFeiQCldZqez/u/WcrNPk4nxXI5ihofHYjFUA=\nTimestamp: 1693323623528968756\n\n— rekor.sigstore.dev wNI9ajBEAiAK0YTbxRlhOZeeP+844Y+W7iz+hsFIF8x2NYsmuaxifAIgYUFSurlKwN7j5jCwpqSVrkbouQoYIYlyWU9Om16svmI=\n"}},"canonicalizedBody":"eyJhcGlWZXJzaW9uIjoiMC4wLjIiLCJraW5kIjoiaW50b3RvIiwic3BlYyI6eyJjb250ZW50Ijp7ImVudmVsb3BlIjp7InBheWxvYWRUeXBlIjoiYXBwbGljYXRpb24vdm5kLmluLXRvdG8ranNvbiIsInNpZ25hdHVyZXMiOlt7InB1YmxpY0tleSI6IkxTMHRMUzFDUlVkSlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVWQwUkVORFFtcDFaMEYzU1VKQlowbFZRMHBNYVhCVGREQTVTMHhHWXpCS1dXWjFSSEpUWVc0dkwweHpkME5uV1VsTGIxcEplbW93UlVGM1RYY0tUbnBGVmsxQ1RVZEJNVlZGUTJoTlRXTXliRzVqTTFKMlkyMVZkVnBIVmpKTlVqUjNTRUZaUkZaUlVVUkZlRlo2WVZka2VtUkhPWGxhVXpGd1ltNVNiQXBqYlRGc1drZHNhR1JIVlhkSWFHTk9UV3BOZDA5RVNUVk5WRlV3VFVSSmVsZG9ZMDVOYWsxM1QwUkpOVTFVVlRGTlJFbDZWMnBCUVUxR2EzZEZkMWxJQ2t0dldrbDZhakJEUVZGWlNVdHZXa2w2YWpCRVFWRmpSRkZuUVVWUVptMDJURkJZVVdWS1ZFTTRPVlZQY1dsT1YyMXVXbGxIYlZnMFZETnBURnBIYVRBS1JWWTBZbVpQYjAwNE5raDZZVGswV0hGNWRYZDRRVzlYY0VOUVpXTkdRMFZpUVdVNGJESmtaeTlsY2pOUE9VeEZSbkZQUTBKV2IzZG5aMVpYVFVFMFJ3cEJNVlZrUkhkRlFpOTNVVVZCZDBsSVowUkJWRUpuVGxaSVUxVkZSRVJCUzBKblozSkNaMFZHUWxGalJFRjZRV1JDWjA1V1NGRTBSVVpuVVZWbGNYQkRDbGhJY2pOd1kxVmhURE5GUmt0U0swdHpiWFZMVVhGdmQwaDNXVVJXVWpCcVFrSm5kMFp2UVZVek9WQndlakZaYTBWYVlqVnhUbXB3UzBaWGFYaHBORmtLV2tRNGQxbDNXVVJXVWpCU1FWRklMMEpHYTNkV05GcFdZVWhTTUdOSVRUWk1lVGx1WVZoU2IyUlhTWFZaTWpsMFRETk9jRm96VGpCaU0wcHNURE5PY0FwYU0wNHdZak5LYkV4WGNIcE1lVFZ1WVZoU2IyUlhTWFprTWpsNVlUSmFjMkl6WkhwTU0wcHNZa2RXYUdNeVZYVmxWekZ6VVVoS2JGcHVUWFpoUjFab0NscElUWFppVjBad1ltcEJOVUpuYjNKQ1owVkZRVmxQTDAxQlJVSkNRM1J2WkVoU2QyTjZiM1pNTTFKMllUSldkVXh0Um1wa1IyeDJZbTVOZFZveWJEQUtZVWhXYVdSWVRteGpiVTUyWW01U2JHSnVVWFZaTWpsMFRVSkpSME5wYzBkQlVWRkNaemM0ZDBGUlNVVkNTRUl4WXpKbmQwNW5XVXRMZDFsQ1FrRkhSQXAyZWtGQ1FYZFJiMDFxV210TlZGa3hUVlJOZWs5RVdtMWFiVVpvVG5wcmQxbHFSbXBOZWtwdFQxUkpNMDVVVVRCYWFrVjZUV3BLYkU1RVJUVk9SRUZXQ2tKbmIzSkNaMFZGUVZsUEwwMUJSVVZDUVdSVFdsZDRiRmxZVG14TlEwbEhRMmx6UjBGUlVVSm5OemgzUVZGVlJVWklUbkJhTTA0d1lqTktiRXd6VG5BS1dqTk9NR0l6U214TVYzQjZUVUl3UjBOcGMwZEJVVkZDWnpjNGQwRlJXVVZFTTBwc1dtNU5kbUZIVm1oYVNFMTJZbGRHY0dKcVFUZENaMjl5UW1kRlJRcEJXVTh2VFVGRlNVSkRNRTFMTW1nd1pFaENlazlwT0haa1J6bHlXbGMwZFZsWFRqQmhWemwxWTNrMWJtRllVbTlrVjBveFl6SldlVmt5T1hWa1IxWjFDbVJETldwaU1qQjNXbEZaUzB0M1dVSkNRVWRFZG5wQlFrTlJVbGhFUmxadlpFaFNkMk42YjNaTU1tUndaRWRvTVZscE5XcGlNakIyWXpKc2JtTXpVbllLWTIxVmRtTXliRzVqTTFKMlkyMVZkR0Z1VFhaTWJXUndaRWRvTVZscE9UTmlNMHB5V20xNGRtUXpUWFpqYlZaeldsZEdlbHBUTlRWaVYzaEJZMjFXYlFwamVUbHZXbGRHYTJONU9YUlpWMngxVFVSblIwTnBjMGRCVVZGQ1p6YzRkMEZSYjBWTFozZHZUV3BhYTAxVVdURk5WRTE2VDBSYWJWcHRSbWhPZW10M0NsbHFSbXBOZWtwdFQxUkpNMDVVVVRCYWFrVjZUV3BLYkU1RVJUVk9SRUZrUW1kdmNrSm5SVVZCV1U4dlRVRkZURUpCT0UxRVYyUndaRWRvTVZscE1XOEtZak5PTUZwWFVYZE9kMWxMUzNkWlFrSkJSMFIyZWtGQ1JFRlJjRVJEWkc5a1NGSjNZM3B2ZGt3eVpIQmtSMmd4V1drMWFtSXlNSFpqTW14dVl6TlNkZ3BqYlZWMll6SnNibU16VW5aamJWVjBZVzVOZDA5QldVdExkMWxDUWtGSFJIWjZRVUpFVVZGeFJFTm5lVTV0VVhoT2FsVjRUWHBOTkU1dFdtMVpWMFV6Q2s5VVFtbE5WMDE2VFcxWk5VMXFZekZPUkZKdFRWUk5lVTF0VlRCTlZHc3dUVUk0UjBOcGMwZEJVVkZDWnpjNGQwRlJORVZGVVhkUVkyMVdiV041T1c4S1dsZEdhMk41T1hSWlYyeDFUVUpyUjBOcGMwZEJVVkZDWnpjNGQwRlJPRVZEZDNkS1RrUnJNVTVVWXpCT1ZGVXhUVU56UjBOcGMwZEJVVkZDWnpjNGR3cEJVa0ZGU0ZGM1ltRklVakJqU0UwMlRIazVibUZZVW05a1YwbDFXVEk1ZEV3elRuQmFNMDR3WWpOS2JFMUNaMGREYVhOSFFWRlJRbWMzT0hkQlVrVkZDa05uZDBsT2VrVjNUMVJaZWs1VVRYZGFVVmxMUzNkWlFrSkJSMFIyZWtGQ1JXZFNXRVJHVm05a1NGSjNZM3B2ZGt3eVpIQmtSMmd4V1drMWFtSXlNSFlLWXpKc2JtTXpVblpqYlZWMll6SnNibU16VW5aamJWVjBZVzVOZGt4dFpIQmtSMmd4V1drNU0ySXpTbkphYlhoMlpETk5kbU50Vm5OYVYwWjZXbE0xTlFwaVYzaEJZMjFXYldONU9XOWFWMFpyWTNrNWRGbFhiSFZOUkdkSFEybHpSMEZSVVVKbk56aDNRVkpOUlV0bmQyOU5hbHByVFZSWk1VMVVUWHBQUkZwdENscHRSbWhPZW10M1dXcEdhazE2U20xUFZFa3pUbFJSTUZwcVJYcE5ha3BzVGtSRk5VNUVRVlZDWjI5eVFtZEZSVUZaVHk5TlFVVlZRa0ZaVFVKSVFqRUtZekpuZDFkbldVdExkMWxDUWtGSFJIWjZRVUpHVVZKTlJFVndiMlJJVW5kamVtOTJUREprY0dSSGFERlphVFZxWWpJd2RtTXliRzVqTTFKMlkyMVZkZ3BqTW14dVl6TlNkbU50VlhSaGJrMTJXVmRPTUdGWE9YVmplVGw1WkZjMWVreDZXWGROVkZFd1QwUm5NazVxV1haWldGSXdXbGN4ZDJSSVRYWk5WRUZYQ2tKbmIzSkNaMFZGUVZsUEwwMUJSVmRDUVdkTlFtNUNNVmx0ZUhCWmVrTkNhV2RaUzB0M1dVSkNRVWhYWlZGSlJVRm5VamhDU0c5QlpVRkNNa0ZPTURrS1RVZHlSM2g0UlhsWmVHdGxTRXBzYms1M1MybFRiRFkwTTJwNWRDODBaVXRqYjBGMlMyVTJUMEZCUVVKcGEwaDZLM1ozUVVGQlVVUkJSV04zVWxGSlp3cGFSVzg0WXpCbFExcElSV2cwZFhwNlNucEdlamxVSzBWbVUxUk9WSFJDTWtaSlNERTRkbGh3YTA5elEwbFJSRVV4VFZSMGFUbFNiMFJ1VWs4elUwVlVDakZhYTJGa05rWnZWSGd2YXpaNmRGRmpkMGxFVUcxdVVuaFVRVXRDWjJkeGFHdHFUMUJSVVVSQmQwNXVRVVJDYTBGcVFrSXdObVp0VGxoNE5sUnZZVU1LYkVabk1tdFBlRzVtVEVkbmNuWnZVak5HTlVkcVJIUjJSRUpDT0cwNVUxZFJUbnBNTWpFeGFsbHRVeTluSzFsaVlubFZRMDFESzJGa05tcEpTeXRsWmdwbE5GaFBTV3hvVEdOWGVHVmFZa0owVFdwTFUzSlFlRzF0TkdwU00wSkdVVkZQUWxJck9ISXlOME5wYjNsb2VHOVRjWFpNZFhjOVBRb3RMUzB0TFVWT1JDQkRSVkpVU1VaSlEwRlVSUzB0TFMwdCIsInNpZyI6IlRVVlJRMGxEWVhSb2JsUkljMlJtV25GSWNUTnBXRXhxVFdVd1ZGVTViRXhaYmxJeGVtazNNM0JSZFZobU5VdElRV2xDTWpOS2FDdG5VMll4VVVWRGJrRlRSMlZ3TW1VeVRVZHVVRmhwYjFWTVZqUjJRMGxUU2tKdWEwcGFaejA5In1dfSwiaGFzaCI6eyJhbGdvcml0aG0iOiJzaGEyNTYiLCJ2YWx1ZSI6IjFiZDg4ZTA1NGY2OGE3ZDE3MzkzNjcyYjAzZmExOGZkNjRmMGRjZDVmY2M1NDAzNWMxOWZlNjQwMWNmMmNmNWUifSwicGF5bG9hZEhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiI4Y2ViNGFiODEyNzczMTQ3M2E5ZWM4MTE0MGNiNjg0OWNmOGU5NzBjZGEzMmJhZWYwOTlkZjQ4YmEzMjY0NDQyIn19fX0="}]},"dsseEnvelope":{"payload":"eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjEiLCJzdWJqZWN0IjpbeyJuYW1lIjoicGtnOm5wbS9zaWdzdG9yZUAyLjEuMCIsImRpZ2VzdCI6eyJzaGE1MTIiOiI5MGYyMjNmOTkyZTRjODhkZDA2OGNkMmE1ZmM1N2Y5ZDJiMzA3OTgzNDNkZDZlMzhmMjljMjQwZTA0YmEwOTBlZjgzMWY4NDQ5MDg0N2M0ZTgyYjkyMzJjNzhlOGEyNTg0NjNiMWU1NWMwZjc0NjlmNzMwMjY1MDA4ZmE2NjMzZiJ9fV0sInByZWRpY2F0ZVR5cGUiOiJodHRwczovL3Nsc2EuZGV2L3Byb3ZlbmFuY2UvdjEiLCJwcmVkaWNhdGUiOnsiYnVpbGREZWZpbml0aW9uIjp7ImJ1aWxkVHlwZSI6Imh0dHBzOi8vc2xzYS1mcmFtZXdvcmsuZ2l0aHViLmlvL2dpdGh1Yi1hY3Rpb25zLWJ1aWxkdHlwZXMvd29ya2Zsb3cvdjEiLCJleHRlcm5hbFBhcmFtZXRlcnMiOnsid29ya2Zsb3ciOnsicmVmIjoicmVmcy9oZWFkcy9tYWluIiwicmVwb3NpdG9yeSI6Imh0dHBzOi8vZ2l0aHViLmNvbS9zaWdzdG9yZS9zaWdzdG9yZS1qcyIsInBhdGgiOiIuZ2l0aHViL3dvcmtmbG93cy9yZWxlYXNlLnltbCJ9fSwiaW50ZXJuYWxQYXJhbWV0ZXJzIjp7ImdpdGh1YiI6eyJldmVudF9uYW1lIjoicHVzaCIsInJlcG9zaXRvcnlfaWQiOiI0OTU1NzQ1NTUiLCJyZXBvc2l0b3J5X293bmVyX2lkIjoiNzEwOTYzNTMifX0sInJlc29sdmVkRGVwZW5kZW5jaWVzIjpbeyJ1cmkiOiJnaXQraHR0cHM6Ly9naXRodWIuY29tL3NpZ3N0b3JlL3NpZ3N0b3JlLWpzQHJlZnMvaGVhZHMvbWFpbiIsImRpZ2VzdCI6eyJnaXRDb21taXQiOiIyNmQxNjUxMzM4NmZmYWE3OTBiMWMzMmY5Mjc1NDRmMTMyMmU0MTk0In19XX0sInJ1bkRldGFpbHMiOnsiYnVpbGRlciI6eyJpZCI6Imh0dHBzOi8vZ2l0aHViLmNvbS9hY3Rpb25zL3J1bm5lci9naXRodWItaG9zdGVkIn0sIm1ldGFkYXRhIjp7Imludm9jYXRpb25JZCI6Imh0dHBzOi8vZ2l0aHViLmNvbS9zaWdzdG9yZS9zaWdzdG9yZS1qcy9hY3Rpb25zL3J1bnMvNjAxNDQ4ODY2Ni9hdHRlbXB0cy8xIn19fX0=","payloadType":"application/vnd.in-toto+json","signatures":[{"sig":"MEQCICathnTHsdfZqHq3iXLjMe0TU9lLYnR1zi73pQuXf5KHAiB23Jh+gSf1QECnASGep2e2MGnPXioULV4vCISJBnkJZg=="}]}} +{"mediaType":"application/vnd.dev.sigstore.bundle.v0.3+json","verificationMaterial":{"certificate":{"rawBytes":"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"},"tlogEntries":[{"logIndex":"33351527","logId":{"keyId":"wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="},"kindVersion":{"kind":"intoto","version":"0.0.2"},"integratedTime":"1693323623","inclusionPromise":{"signedEntryTimestamp":"MEYCIQDhWvNSLvnq5ZS3qTIgC7K2uQFeA0g8FEEjNo1UQxeubAIhALDrD1uIiUkk3tQNp/4gKT/9j8zEyyxi9Ti+qaD8q2vI"},"inclusionProof":{"logIndex":"29188096","rootHash":"fbEijQTFeiQCldZqez/u/WcrNPk4nxXI5ihofHYjFUA=","treeSize":"29188099","hashes":["z7VKeAC2d2x18Vtxt7n40GS3gtc1xfRwjjxxzpy/Trw=","/Kd8ZuCLZ7MukSwpjaSgxKFl5X2vdHWk6/qpNrkiUJo=","vvkKs7IShUI15nVb9c5olPgBnL9r4uP7+d5KzV0hSjs=","Fg4p0WJZw8Lghrpxkx1SXgzfroTeIIrEgEbfgr9IdXY=","bH8NahqE+hQ58Qxhg0V5fYusFQ1xsaQ/rK6slWVRT5k=","HplNgZ3/afEHq52zcfL2s1AKisOYDdMCWK1jOu1tGyw=","uOPuC2YDmwZe989ZN3Lgh5CKMXh9HETrSNgf0jV0WkM=","eVsvWKnEZ1+Xo3Ba15DfEiIhhmlrEaIeb+VfYmx8KhY=","uLuBRins5nkqq2rqd17R27pQTUF+xetttC6MsmlUzd0=","jRUq4D8O+FI47Wbw96s7yHCu4qzWUxpIVfxQEeprDmc=","rXEsmEJN4PEoTU8US4qVtdIsGB1MCiRlGOepoiC99kM="],"checkpoint":{"envelope":"rekor.sigstore.dev - 2605736670972794746\n29188099\nfbEijQTFeiQCldZqez/u/WcrNPk4nxXI5ihofHYjFUA=\nTimestamp: 1693323623528968756\n\n— rekor.sigstore.dev wNI9ajBEAiAK0YTbxRlhOZeeP+844Y+W7iz+hsFIF8x2NYsmuaxifAIgYUFSurlKwN7j5jCwpqSVrkbouQoYIYlyWU9Om16svmI=\n"}},"canonicalizedBody":"eyJhcGlWZXJzaW9uIjoiMC4wLjIiLCJraW5kIjoiaW50b3RvIiwic3BlYyI6eyJjb250ZW50Ijp7ImVudmVsb3BlIjp7InBheWxvYWRUeXBlIjoiYXBwbGljYXRpb24vdm5kLmluLXRvdG8ranNvbiIsInNpZ25hdHVyZXMiOlt7InB1YmxpY0tleSI6IkxTMHRMUzFDUlVkSlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVWQwUkVORFFtcDFaMEYzU1VKQlowbFZRMHBNYVhCVGREQTVTMHhHWXpCS1dXWjFSSEpUWVc0dkwweHpkME5uV1VsTGIxcEplbW93UlVGM1RYY0tUbnBGVmsxQ1RVZEJNVlZGUTJoTlRXTXliRzVqTTFKMlkyMVZkVnBIVmpKTlVqUjNTRUZaUkZaUlVVUkZlRlo2WVZka2VtUkhPWGxhVXpGd1ltNVNiQXBqYlRGc1drZHNhR1JIVlhkSWFHTk9UV3BOZDA5RVNUVk5WRlV3VFVSSmVsZG9ZMDVOYWsxM1QwUkpOVTFVVlRGTlJFbDZWMnBCUVUxR2EzZEZkMWxJQ2t0dldrbDZhakJEUVZGWlNVdHZXa2w2YWpCRVFWRmpSRkZuUVVWUVptMDJURkJZVVdWS1ZFTTRPVlZQY1dsT1YyMXVXbGxIYlZnMFZETnBURnBIYVRBS1JWWTBZbVpQYjAwNE5raDZZVGswV0hGNWRYZDRRVzlYY0VOUVpXTkdRMFZpUVdVNGJESmtaeTlsY2pOUE9VeEZSbkZQUTBKV2IzZG5aMVpYVFVFMFJ3cEJNVlZrUkhkRlFpOTNVVVZCZDBsSVowUkJWRUpuVGxaSVUxVkZSRVJCUzBKblozSkNaMFZHUWxGalJFRjZRV1JDWjA1V1NGRTBSVVpuVVZWbGNYQkRDbGhJY2pOd1kxVmhURE5GUmt0U0swdHpiWFZMVVhGdmQwaDNXVVJXVWpCcVFrSm5kMFp2UVZVek9WQndlakZaYTBWYVlqVnhUbXB3UzBaWGFYaHBORmtLV2tRNGQxbDNXVVJXVWpCU1FWRklMMEpHYTNkV05GcFdZVWhTTUdOSVRUWk1lVGx1WVZoU2IyUlhTWFZaTWpsMFRETk9jRm96VGpCaU0wcHNURE5PY0FwYU0wNHdZak5LYkV4WGNIcE1lVFZ1WVZoU2IyUlhTWFprTWpsNVlUSmFjMkl6WkhwTU0wcHNZa2RXYUdNeVZYVmxWekZ6VVVoS2JGcHVUWFpoUjFab0NscElUWFppVjBad1ltcEJOVUpuYjNKQ1owVkZRVmxQTDAxQlJVSkNRM1J2WkVoU2QyTjZiM1pNTTFKMllUSldkVXh0Um1wa1IyeDJZbTVOZFZveWJEQUtZVWhXYVdSWVRteGpiVTUyWW01U2JHSnVVWFZaTWpsMFRVSkpSME5wYzBkQlVWRkNaemM0ZDBGUlNVVkNTRUl4WXpKbmQwNW5XVXRMZDFsQ1FrRkhSQXAyZWtGQ1FYZFJiMDFxV210TlZGa3hUVlJOZWs5RVdtMWFiVVpvVG5wcmQxbHFSbXBOZWtwdFQxUkpNMDVVVVRCYWFrVjZUV3BLYkU1RVJUVk9SRUZXQ2tKbmIzSkNaMFZGUVZsUEwwMUJSVVZDUVdSVFdsZDRiRmxZVG14TlEwbEhRMmx6UjBGUlVVSm5OemgzUVZGVlJVWklUbkJhTTA0d1lqTktiRXd6VG5BS1dqTk9NR0l6U214TVYzQjZUVUl3UjBOcGMwZEJVVkZDWnpjNGQwRlJXVVZFTTBwc1dtNU5kbUZIVm1oYVNFMTJZbGRHY0dKcVFUZENaMjl5UW1kRlJRcEJXVTh2VFVGRlNVSkRNRTFMTW1nd1pFaENlazlwT0haa1J6bHlXbGMwZFZsWFRqQmhWemwxWTNrMWJtRllVbTlrVjBveFl6SldlVmt5T1hWa1IxWjFDbVJETldwaU1qQjNXbEZaUzB0M1dVSkNRVWRFZG5wQlFrTlJVbGhFUmxadlpFaFNkMk42YjNaTU1tUndaRWRvTVZscE5XcGlNakIyWXpKc2JtTXpVbllLWTIxVmRtTXliRzVqTTFKMlkyMVZkR0Z1VFhaTWJXUndaRWRvTVZscE9UTmlNMHB5V20xNGRtUXpUWFpqYlZaeldsZEdlbHBUTlRWaVYzaEJZMjFXYlFwamVUbHZXbGRHYTJONU9YUlpWMngxVFVSblIwTnBjMGRCVVZGQ1p6YzRkMEZSYjBWTFozZHZUV3BhYTAxVVdURk5WRTE2VDBSYWJWcHRSbWhPZW10M0NsbHFSbXBOZWtwdFQxUkpNMDVVVVRCYWFrVjZUV3BLYkU1RVJUVk9SRUZrUW1kdmNrSm5SVVZCV1U4dlRVRkZURUpCT0UxRVYyUndaRWRvTVZscE1XOEtZak5PTUZwWFVYZE9kMWxMUzNkWlFrSkJSMFIyZWtGQ1JFRlJjRVJEWkc5a1NGSjNZM3B2ZGt3eVpIQmtSMmd4V1drMWFtSXlNSFpqTW14dVl6TlNkZ3BqYlZWMll6SnNibU16VW5aamJWVjBZVzVOZDA5QldVdExkMWxDUWtGSFJIWjZRVUpFVVZGeFJFTm5lVTV0VVhoT2FsVjRUWHBOTkU1dFdtMVpWMFV6Q2s5VVFtbE5WMDE2VFcxWk5VMXFZekZPUkZKdFRWUk5lVTF0VlRCTlZHc3dUVUk0UjBOcGMwZEJVVkZDWnpjNGQwRlJORVZGVVhkUVkyMVdiV041T1c4S1dsZEdhMk41T1hSWlYyeDFUVUpyUjBOcGMwZEJVVkZDWnpjNGQwRlJPRVZEZDNkS1RrUnJNVTVVWXpCT1ZGVXhUVU56UjBOcGMwZEJVVkZDWnpjNGR3cEJVa0ZGU0ZGM1ltRklVakJqU0UwMlRIazVibUZZVW05a1YwbDFXVEk1ZEV3elRuQmFNMDR3WWpOS2JFMUNaMGREYVhOSFFWRlJRbWMzT0hkQlVrVkZDa05uZDBsT2VrVjNUMVJaZWs1VVRYZGFVVmxMUzNkWlFrSkJSMFIyZWtGQ1JXZFNXRVJHVm05a1NGSjNZM3B2ZGt3eVpIQmtSMmd4V1drMWFtSXlNSFlLWXpKc2JtTXpVblpqYlZWMll6SnNibU16VW5aamJWVjBZVzVOZGt4dFpIQmtSMmd4V1drNU0ySXpTbkphYlhoMlpETk5kbU50Vm5OYVYwWjZXbE0xTlFwaVYzaEJZMjFXYldONU9XOWFWMFpyWTNrNWRGbFhiSFZOUkdkSFEybHpSMEZSVVVKbk56aDNRVkpOUlV0bmQyOU5hbHByVFZSWk1VMVVUWHBQUkZwdENscHRSbWhPZW10M1dXcEdhazE2U20xUFZFa3pUbFJSTUZwcVJYcE5ha3BzVGtSRk5VNUVRVlZDWjI5eVFtZEZSVUZaVHk5TlFVVlZRa0ZaVFVKSVFqRUtZekpuZDFkbldVdExkMWxDUWtGSFJIWjZRVUpHVVZKTlJFVndiMlJJVW5kamVtOTJUREprY0dSSGFERlphVFZxWWpJd2RtTXliRzVqTTFKMlkyMVZkZ3BqTW14dVl6TlNkbU50VlhSaGJrMTJXVmRPTUdGWE9YVmplVGw1WkZjMWVreDZXWGROVkZFd1QwUm5NazVxV1haWldGSXdXbGN4ZDJSSVRYWk5WRUZYQ2tKbmIzSkNaMFZGUVZsUEwwMUJSVmRDUVdkTlFtNUNNVmx0ZUhCWmVrTkNhV2RaUzB0M1dVSkNRVWhYWlZGSlJVRm5VamhDU0c5QlpVRkNNa0ZPTURrS1RVZHlSM2g0UlhsWmVHdGxTRXBzYms1M1MybFRiRFkwTTJwNWRDODBaVXRqYjBGMlMyVTJUMEZCUVVKcGEwaDZLM1ozUVVGQlVVUkJSV04zVWxGSlp3cGFSVzg0WXpCbFExcElSV2cwZFhwNlNucEdlamxVSzBWbVUxUk9WSFJDTWtaSlNERTRkbGh3YTA5elEwbFJSRVV4VFZSMGFUbFNiMFJ1VWs4elUwVlVDakZhYTJGa05rWnZWSGd2YXpaNmRGRmpkMGxFVUcxdVVuaFVRVXRDWjJkeGFHdHFUMUJSVVVSQmQwNXVRVVJDYTBGcVFrSXdObVp0VGxoNE5sUnZZVU1LYkVabk1tdFBlRzVtVEVkbmNuWnZVak5HTlVkcVJIUjJSRUpDT0cwNVUxZFJUbnBNTWpFeGFsbHRVeTluSzFsaVlubFZRMDFESzJGa05tcEpTeXRsWmdwbE5GaFBTV3hvVEdOWGVHVmFZa0owVFdwTFUzSlFlRzF0TkdwU00wSkdVVkZQUWxJck9ISXlOME5wYjNsb2VHOVRjWFpNZFhjOVBRb3RMUzB0TFVWT1JDQkRSVkpVU1VaSlEwRlVSUzB0TFMwdCIsInNpZyI6IlRVVlJRMGxEWVhSb2JsUkljMlJtV25GSWNUTnBXRXhxVFdVd1ZGVTViRXhaYmxJeGVtazNNM0JSZFZobU5VdElRV2xDTWpOS2FDdG5VMll4VVVWRGJrRlRSMlZ3TW1VeVRVZHVVRmhwYjFWTVZqUjJRMGxUU2tKdWEwcGFaejA5In1dfSwiaGFzaCI6eyJhbGdvcml0aG0iOiJzaGEyNTYiLCJ2YWx1ZSI6IjFiZDg4ZTA1NGY2OGE3ZDE3MzkzNjcyYjAzZmExOGZkNjRmMGRjZDVmY2M1NDAzNWMxOWZlNjQwMWNmMmNmNWUifSwicGF5bG9hZEhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiI4Y2ViNGFiODEyNzczMTQ3M2E5ZWM4MTE0MGNiNjg0OWNmOGU5NzBjZGEzMmJhZWYwOTlkZjQ4YmEzMjY0NDQyIn19fX0="}]},"dsseEnvelope":{"payload":"eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjEiLCJzdWJqZWN0IjpbeyJuYW1lIjoicGtnOm5wbS9zaWdzdG9yZUAyLjEuMCIsImRpZ2VzdCI6eyJzaGE1MTIiOiI5MGYyMjNmOTkyZTRjODhkZDA2OGNkMmE1ZmM1N2Y5ZDJiMzA3OTgzNDNkZDZlMzhmMjljMjQwZTA0YmEwOTBlZjgzMWY4NDQ5MDg0N2M0ZTgyYjkyMzJjNzhlOGEyNTg0NjNiMWU1NWMwZjc0NjlmNzMwMjY1MDA4ZmE2NjMzZiJ9fV0sInByZWRpY2F0ZVR5cGUiOiJodHRwczovL3Nsc2EuZGV2L3Byb3ZlbmFuY2UvdjEiLCJwcmVkaWNhdGUiOnsiYnVpbGREZWZpbml0aW9uIjp7ImJ1aWxkVHlwZSI6Imh0dHBzOi8vc2xzYS1mcmFtZXdvcmsuZ2l0aHViLmlvL2dpdGh1Yi1hY3Rpb25zLWJ1aWxkdHlwZXMvd29ya2Zsb3cvdjEiLCJleHRlcm5hbFBhcmFtZXRlcnMiOnsid29ya2Zsb3ciOnsicmVmIjoicmVmcy9oZWFkcy9tYWluIiwicmVwb3NpdG9yeSI6Imh0dHBzOi8vZ2l0aHViLmNvbS9zaWdzdG9yZS9zaWdzdG9yZS1qcyIsInBhdGgiOiIuZ2l0aHViL3dvcmtmbG93cy9yZWxlYXNlLnltbCJ9fSwiaW50ZXJuYWxQYXJhbWV0ZXJzIjp7ImdpdGh1YiI6eyJldmVudF9uYW1lIjoicHVzaCIsInJlcG9zaXRvcnlfaWQiOiI0OTU1NzQ1NTUiLCJyZXBvc2l0b3J5X293bmVyX2lkIjoiNzEwOTYzNTMifX0sInJlc29sdmVkRGVwZW5kZW5jaWVzIjpbeyJ1cmkiOiJnaXQraHR0cHM6Ly9naXRodWIuY29tL3NpZ3N0b3JlL3NpZ3N0b3JlLWpzQHJlZnMvaGVhZHMvbWFpbiIsImRpZ2VzdCI6eyJnaXRDb21taXQiOiIyNmQxNjUxMzM4NmZmYWE3OTBiMWMzMmY5Mjc1NDRmMTMyMmU0MTk0In19XX0sInJ1bkRldGFpbHMiOnsiYnVpbGRlciI6eyJpZCI6Imh0dHBzOi8vZ2l0aHViLmNvbS9hY3Rpb25zL3J1bm5lci9naXRodWItaG9zdGVkIn0sIm1ldGFkYXRhIjp7Imludm9jYXRpb25JZCI6Imh0dHBzOi8vZ2l0aHViLmNvbS9zaWdzdG9yZS9zaWdzdG9yZS1qcy9hY3Rpb25zL3J1bnMvNjAxNDQ4ODY2Ni9hdHRlbXB0cy8xIn19fX0=","payloadType":"application/vnd.in-toto+json","signatures":[{"sig":"MEQCICathnTHsdfZqHq3iXLjMe0TU9lLYnR1zi73pQuXf5KHAiB23Jh+gSf1QECnASGep2e2MGnPXioULV4vCISJBnkJZg=="}]}} diff --git a/pkg/cmd/attestation/test/data/sigstoreBundle-invalid-signature.json b/pkg/cmd/attestation/test/data/sigstoreBundle-invalid-signature.json index b1275cebc..0cf79254c 100644 --- a/pkg/cmd/attestation/test/data/sigstoreBundle-invalid-signature.json +++ b/pkg/cmd/attestation/test/data/sigstoreBundle-invalid-signature.json @@ -1,6 +1,9 @@ { - "mediaType": "application/vnd.dev.sigstore.bundle+json;version=0.1", + "mediaType": "application/vnd.dev.sigstore.bundle.v0.3+json", "verificationMaterial": { + "certificate": { + "rawBytes": "MIICnzCCAiWgAwIBAgIUVHwehOtGn4KSD1H8RI581MfbyewwCgYIKoZIzj0EAwMwNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwHhcNMjIxMTA4MjI1ODA2WhcNMjIxMTA4MjMwODA2WjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEGg6Hjxt2UNiJ1kwwq5XQIIwMZnJfVQ3bF01uZKteMdcV/3qhCmWOecoxRqwrbYTshGg9NyXcBbve6zKwZVTLeqOCAUQwggFAMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQU7WpR60sCpgfu04wcsjvCFxt0fMkwHwYDVR0jBBgwFoAU39Ppz1YkEZb5qNjpKFWixi4YZD8wHwYDVR0RAQH/BBUwE4ERYnJpYW5AZGVoYW1lci5jb20wLAYKKwYBBAGDvzABAQQeaHR0cHM6Ly9naXRodWIuY29tL2xvZ2luL29hdXRoMIGJBgorBgEEAdZ5AgQCBHsEeQB3AHUA3T0wasbHETJjGR4cmWc3AqJKXrjePK3/h4pygC8p7o4AAAGEWXcR8AAABAMARjBEAiBRTrGE5Y1EnYniaJB+nsv89VaYx3QZjocEin3r91wfkAIgMss+fssu5SLQkn7WDTKXgow7SxbHYSZj3ykxArVnuzEwCgYIKoZIzj0EAwMDaAAwZQIxAPjSGddLIvyUMGIkZ+u6JhE9p1Njt3dEtwYkMxfnEV2k7MH1BVmxg9PsJjqycfi+eAIwDaKn2CdOxKsxcgYNi4HviEnZqxmeDyo2YFItzpHfIMQmcRSl91UeOSC8+PuGgwMK" + }, "tlogEntries": [ { "logIndex": "6751924", @@ -13,35 +16,56 @@ }, "integratedTime": "1667948287", "inclusionPromise": { - "signedEntryTimestamp": "MEQCIEzguFRaGzOpMw9JJGUfqSJQ11qlzpcyVCkZfZYPwpLCAiBzdU4LnjtVKYCfyoTImFh3OLFWeOKygtS47Z8fp1GYHg==" + "signedEntryTimestamp": "MEQCIFC8EPrNU+kRCqHOJaGuw3NAFkJGYu8mssUaq71sR98pAiA5+SpNdFL5RrjyhulMo3t5xcc03srLlQmKx42LRiqGew==" + }, + "inclusionProof": { + "logIndex": "2588493", + "rootHash": "N40Xn7VxprmSXoUSY27Bs6T2t0JvHShIY/7ekL0/p6U=", + "treeSize": "115826880", + "hashes": [ + "qvPXILBiRJD+OZ8vUgQLlRe5QmJsbQgoKDYXbcQplZk=", + "ian1jlZJxuli49MJF79fN6RiMaQO8dj7Wk2o/gVJqTg=", + "4L82HI4fzDUm6Jl+jPDaotc3bWW9y9h08g5sJGavPko=", + "X3+ZmsxVTa8t+uRGaK4vgzJVAxjZL+5o35ueQA3WaRc=", + "Z6I4B7xGG98tCAWz7rdIxW36r8Uz2vPr+wZAiVJqLyU=", + "WTb/xFvgwNmpinr1+xKCbNZOGo8L6GN8oZ+snwmYESw=", + "lFxAqYOFdddHV349DzPLmsyPzCfzimnNKWk1itLLwy8=", + "BbtQkfipdk2Xwc3ijUSX5V0bxHNuPvbjq6csMZGrBh4=", + "8/XdI9PzRMcytBFkEv9WbIMNJaHkkFgZV39VNAzf6ho=", + "KmwX1cdeUfdQlFjqvqLQxKaOBoZ4/aIo2bUo9WzrGRc=", + "nffHMg5IaQx0gI0QG0A2cqRlajxbh7v6kdWKpQBowKY=", + "4n+4WqZcfi237GTZjbCgWwhN/oUnzHXSh67xV3R4GTE=", + "tfxH1EZ2uVk8MeHZ/7cxcSL1NALf27pfII4YVRfrMFU=", + "bdkHN9diWTXM0z5GECHlDIMvSl8koq33Vd8mSdNrhhY=", + "abpenKLgpX4ElLQbHYkjZzj0QptcTE9yujFeVSmMOtw=", + "qeGjNnuDqq2S63UDs3gJ2cfvolHGXREL/fc30SXYbFk=", + "ucRPSmGLhm/SyHL7chQ5vBEFull08HzsqtAC0TQ91tY=", + "EiS8ntcvGnB1xcGZg9Cf3fTkV1wBcJNVtSWKIYVZqAU=", + "Mx1LEx7szsPd62CGkL6HM+NWkOy9YwZTwukJEVgH7Cw=", + "s2Z13KVYurVY6F1AUhr8Uby4RE3RXW1XEC2tWWdzCjI=", + "QRfYxLEHh/FwMZqWnxNNW+x3lY7o3LM86BW+z0MpMN4=", + "J0dGjQ7V5bETi7p7eWg2ephCQ32QBLMWY5HxFcuGfR4=", + "uFGzOQorMYmYZ2yumLpgr1tvXvZaL+tTTCqaXa7Hdds=", + "Lksw/hm/y+1p33SaEF8/60gPvFVNkueBpDWJ1tAVcAo=", + "Soaoms+sNcJd3K95DWx//GJEbZPyr/e4cUVyLXK9tnk=", + "WcosyVcuwpv56nBkSbKEnSPbHesdKOoUykqVThLEqoo=", + "gY2fcNwGuA3cp7tQHZoB084DsKFwbF4tW78KgehHwfE=" + ], + "checkpoint": { + "envelope": "rekor.sigstore.dev - 2605736670972794746\n115826880\nN40Xn7VxprmSXoUSY27Bs6T2t0JvHShIY/7ekL0/p6U=\n\n— rekor.sigstore.dev wNI9ajBEAiBNjSQhOIg1Ch0UbbX+JZj5y//ajY0isa4dJsVajHo2ogIgGDm73+f2+vbJgbSqtqmPdXfb6Rm/vEIF3cli7j1KZ0I=\n" + } }, "canonicalizedBody": "eyJhcGlWZXJzaW9uIjoiMC4wLjIiLCJraW5kIjoiaW50b3RvIiwic3BlYyI6eyJjb250ZW50Ijp7ImVudmVsb3BlIjp7InBheWxvYWRUeXBlIjoidGV4dC9wbGFpbiIsInNpZ25hdHVyZXMiOlt7InB1YmxpY0tleSI6IkxTMHRMUzFDUlVkSlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVU51ZWtORFFXbFhaMEYzU1VKQlowbFZWa2gzWldoUGRFZHVORXRUUkRGSU9GSkpOVGd4VFdaaWVXVjNkME5uV1VsTGIxcEplbW93UlVGM1RYY0tUbnBGVmsxQ1RVZEJNVlZGUTJoTlRXTXliRzVqTTFKMlkyMVZkVnBIVmpKTlVqUjNTRUZaUkZaUlVVUkZlRlo2WVZka2VtUkhPWGxhVXpGd1ltNVNiQXBqYlRGc1drZHNhR1JIVlhkSWFHTk9UV3BKZUUxVVFUUk5ha2t4VDBSQk1sZG9ZMDVOYWtsNFRWUkJORTFxVFhkUFJFRXlWMnBCUVUxR2EzZEZkMWxJQ2t0dldrbDZhakJEUVZGWlNVdHZXa2w2YWpCRVFWRmpSRkZuUVVWSFp6WklhbmgwTWxWT2FVb3hhM2QzY1RWWVVVbEpkMDFhYmtwbVZsRXpZa1l3TVhVS1drdDBaVTFrWTFZdk0zRm9RMjFYVDJWamIzaFNjWGR5WWxsVWMyaEhaemxPZVZoalFtSjJaVFo2UzNkYVZsUk1aWEZQUTBGVlVYZG5aMFpCVFVFMFJ3cEJNVlZrUkhkRlFpOTNVVVZCZDBsSVowUkJWRUpuVGxaSVUxVkZSRVJCUzBKblozSkNaMFZHUWxGalJFRjZRV1JDWjA1V1NGRTBSVVpuVVZVM1YzQlNDall3YzBOd1oyWjFNRFIzWTNOcWRrTkdlSFF3WmsxcmQwaDNXVVJXVWpCcVFrSm5kMFp2UVZVek9WQndlakZaYTBWYVlqVnhUbXB3UzBaWGFYaHBORmtLV2tRNGQwaDNXVVJXVWpCU1FWRklMMEpDVlhkRk5FVlNXVzVLY0ZsWE5VRmFSMVp2V1ZjeGJHTnBOV3BpTWpCM1RFRlpTMHQzV1VKQ1FVZEVkbnBCUWdwQlVWRmxZVWhTTUdOSVRUWk1lVGx1WVZoU2IyUlhTWFZaTWpsMFRESjRkbG95YkhWTU1qbG9aRmhTYjAxSlIwcENaMjl5UW1kRlJVRmtXalZCWjFGRENrSkljMFZsVVVJelFVaFZRVE5VTUhkaGMySklSVlJLYWtkU05HTnRWMk16UVhGS1MxaHlhbVZRU3pNdmFEUndlV2RET0hBM2J6UkJRVUZIUlZkWVkxSUtPRUZCUVVKQlRVRlNha0pGUVdsQ1VsUnlSMFUxV1RGRmJsbHVhV0ZLUWl0dWMzWTRPVlpoV1hnelVWcHFiMk5GYVc0emNqa3hkMlpyUVVsblRYTnpLd3BtYzNOMU5WTk1VV3R1TjFkRVZFdFlaMjkzTjFONFlraFpVMXBxTTNscmVFRnlWbTUxZWtWM1EyZFpTVXR2V2tsNmFqQkZRWGROUkdGQlFYZGFVVWw0Q2tGUWFsTkhaR1JNU1haNVZVMUhTV3RhSzNVMlNtaEZPWEF4VG1wME0yUkZkSGRaYTAxNFptNUZWakpyTjAxSU1VSldiWGhuT1ZCelNtcHhlV05tYVNzS1pVRkpkMFJoUzI0eVEyUlBlRXR6ZUdObldVNXBORWgyYVVWdVduRjRiV1ZFZVc4eVdVWkpkSHB3U0daSlRWRnRZMUpUYkRreFZXVlBVME00SzFCMVJ3cG5kMDFMQ2kwdExTMHRSVTVFSUVORlVsUkpSa2xEUVZSRkxTMHRMUzBLIiwic2lnIjoiVFVWVlEwbERWV2hCVm1WM1puZExiR3MxWmxaNmNGSkVWVkJvUlhjNVR6aEpNbkI0UXpWdVZHNVFabGxFUW5OUFFXbEZRVEJhUm5Gek9UbFJaMUk1YlVGMFJrMVhkRmR5VDJwdFZVTTBOM3BuWVc5dmJFdEpiMHhJTDA5M1pFMDkifV19LCJoYXNoIjp7ImFsZ29yaXRobSI6InNoYTI1NiIsInZhbHVlIjoiZGNiNDkyNTljODY2MDdjMzQ2MzVkYWJiNDQzMWYwNjVlOWE3YTczNDcwNGNiNzNmMGFhMGY2YWFhMzg5NmEwNCJ9LCJwYXlsb2FkSGFzaCI6eyJhbGdvcml0aG0iOiJzaGEyNTYiLCJ2YWx1ZSI6IjY4ZTY1NmIyNTFlNjdlODM1OGJlZjg0ODNhYjBkNTFjNjYxOWYzZTdhMWE5ZjBlNzU4MzhkNDFmZjM2OGY3MjgifX19fQ==" } ], - "timestampVerificationData": { - "rfc3161Timestamps": [] - }, - "x509CertificateChain": { - "certificates": [ - { - "rawBytes": "MIICnzCCAiWgAwIBAgIUVHwehOtGn4KSD1H8RI581MfbyewwCgYIKoZIzj0EAwMwNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwHhcNMjIxMTA4MjI1ODA2WhcNMjIxMTA4MjMwODA2WjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEGg6Hjxt2UNiJ1kwwq5XQIIwMZnJfVQ3bF01uZKteMdcV/3qhCmWOecoxRqwrbYTshGg9NyXcBbve6zKwZVTLeqOCAUQwggFAMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQU7WpR60sCpgfu04wcsjvCFxt0fMkwHwYDVR0jBBgwFoAU39Ppz1YkEZb5qNjpKFWixi4YZD8wHwYDVR0RAQH/BBUwE4ERYnJpYW5AZGVoYW1lci5jb20wLAYKKwYBBAGDvzABAQQeaHR0cHM6Ly9naXRodWIuY29tL2xvZ2luL29hdXRoMIGJBgorBgEEAdZ5AgQCBHsEeQB3AHUA3T0wasbHETJjGR4cmWc3AqJKXrjePK3/h4pygC8p7o4AAAGEWXcR8AAABAMARjBEAiBRTrGE5Y1EnYniaJB+nsv89VaYx3QZjocEin3r91wfkAIgMss+fssu5SLQkn7WDTKXgow7SxbHYSZj3ykxArVnuzEwCgYIKoZIzj0EAwMDaAAwZQIxAPjSGddLIvyUMGIkZ+u6JhE9p1Njt3dEtwYkMxfnEV2k7MH1BVmxg9PsJjqycfi+eAIwDaKn2CdOxKsxcgYNi4HviEnZqxmeDyo2YFItzpHfIMQmcRSl91UeOSC8+PuGgwMK" - }, - { - "rawBytes": "MIICGjCCAaGgAwIBAgIUALnViVfnU0brJasmRkHrn/UnfaQwCgYIKoZIzj0EAwMwKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0yMjA0MTMyMDA2MTVaFw0zMTEwMDUxMzU2NThaMDcxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEeMBwGA1UEAxMVc2lnc3RvcmUtaW50ZXJtZWRpYXRlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE8RVS/ysH+NOvuDZyPIZtilgUF9NlarYpAd9HP1vBBH1U5CV77LSS7s0ZiH4nE7Hv7ptS6LvvR/STk798LVgMzLlJ4HeIfF3tHSaexLcYpSASr1kS0N/RgBJz/9jWCiXno3sweTAOBgNVHQ8BAf8EBAMCAQYwEwYDVR0lBAwwCgYIKwYBBQUHAwMwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU39Ppz1YkEZb5qNjpKFWixi4YZD8wHwYDVR0jBBgwFoAUWMAeX5FFpWapesyQoZMi0CrFxfowCgYIKoZIzj0EAwMDZwAwZAIwPCsQK4DYiZYDPIaDi5HFKnfxXx6ASSVmERfsynYBiX2X6SJRnZU84/9DZdnFvvxmAjBOt6QpBlc4J/0DxvkTCqpclvziL6BCCPnjdlIB3Pu3BxsPmygUY7Ii2zbdCdliiow=" - }, - { - "rawBytes": "MIIB9zCCAXygAwIBAgIUALZNAPFdxHPwjeDloDwyYChAO/4wCgYIKoZIzj0EAwMwKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0yMTEwMDcxMzU2NTlaFw0zMTEwMDUxMzU2NThaMCoxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjERMA8GA1UEAxMIc2lnc3RvcmUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAT7XeFT4rb3PQGwS4IajtLk3/OlnpgangaBclYpsYBr5i+4ynB07ceb3LP0OIOZdxexX69c5iVuyJRQ+Hz05yi+UF3uBWAlHpiS5sh0+H2GHE7SXrk1EC5m1Tr19L9gg92jYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRYwB5fkUWlZql6zJChkyLQKsXF+jAfBgNVHSMEGDAWgBRYwB5fkUWlZql6zJChkyLQKsXF+jAKBggqhkjOPQQDAwNpADBmAjEAj1nHeXZp+13NWBNa+EDsDP8G1WWg1tCMWP/WHPqpaVo0jhsweNFZgSs0eE7wYI4qAjEA2WB9ot98sIkoF3vZYdd3/VtWB5b9TNMea7Ix/stJ5TfcLLeABLE4BNJOsQ4vnBHJ" - } - ] - } + "timestampVerificationData": {} }, "dsseEnvelope": { "payload": "aGVsbG8sIHdvcmxkIQ==", "payloadType": "text/plain", "signatures": [ { - "sig": "NEUCICUhAVewfwKlk5fVzpRDUPhEw9O8I2pxC5nTnPfYDBsOAiEA0ZFqs99QgR9mAtFMWtWrOjmUC47zgaoolKIoLH/OwdM=", - "keyid": "" + "sig": "NEUCICUhAVewfwKlk5fVzpRDUPhEw9O8I2pxC5nTnPfYDBsOAiEA0ZFqs99QgR9mAtFMWtWrOjmUC47zgaoolKIoLH/OwdM=" } ] } diff --git a/pkg/cmd/attestation/verification/sigstore.go b/pkg/cmd/attestation/verification/sigstore.go index 0e6d01d9b..b4e0ef8c0 100644 --- a/pkg/cmd/attestation/verification/sigstore.go +++ b/pkg/cmd/attestation/verification/sigstore.go @@ -56,6 +56,9 @@ func NewLiveSigstoreVerifier(config SigstoreConfig) *LiveSigstoreVerifier { } func (v *LiveSigstoreVerifier) chooseVerifier(b *bundle.ProtobufBundle) (*verify.SignedEntityVerifier, string, error) { + if !b.MinVersion("0.3") { + return nil, "", fmt.Errorf("unsupported bundle version: %s", b.MediaType) + } verifyContent, err := b.VerificationContent() if err != nil { return nil, "", fmt.Errorf("failed to get bundle verification content: %v", err) diff --git a/pkg/cmd/attestation/verification/sigstore_integration_test.go b/pkg/cmd/attestation/verification/sigstore_integration_test.go index 2fab9dfac..48d1f4b49 100644 --- a/pkg/cmd/attestation/verification/sigstore_integration_test.go +++ b/pkg/cmd/attestation/verification/sigstore_integration_test.go @@ -100,6 +100,19 @@ func TestLiveSigstoreVerifier(t *testing.T) { require.Len(t, res.VerifyResults, 2) require.NoError(t, res.Error) }) + + t.Run("with invalid bundle version", func(t *testing.T) { + attestations := getAttestationsFor(t, "../test/data/sigstore-js-2.1.0-bundle-v0.1.json") + require.Len(t, attestations, 1) + + verifier := NewLiveSigstoreVerifier(SigstoreConfig{ + Logger: io.NewTestHandler(), + }) + + res := verifier.Verify(attestations, publicGoodPolicy(t)) + require.Len(t, res.VerifyResults, 0) + require.ErrorContains(t, res.Error, "unsupported bundle version") + }) } func publicGoodPolicy(t *testing.T) verify.PolicyBuilder { From b783441540009cb6b58736185521778a4e70aa3c Mon Sep 17 00:00:00 2001 From: Cody Soyland Date: Fri, 9 Aug 2024 16:14:04 -0400 Subject: [PATCH 39/53] Fix tests Signed-off-by: Cody Soyland --- pkg/cmd/attestation/api/client_test.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pkg/cmd/attestation/api/client_test.go b/pkg/cmd/attestation/api/client_test.go index 7044a1cc5..693e3266e 100644 --- a/pkg/cmd/attestation/api/client_test.go +++ b/pkg/cmd/attestation/api/client_test.go @@ -62,14 +62,14 @@ func TestGetByDigest(t *testing.T) { require.Equal(t, 5, len(attestations)) bundle := (attestations)[0].Bundle - require.Equal(t, bundle.GetMediaType(), "application/vnd.dev.sigstore.bundle+json;version=0.1") + require.Equal(t, bundle.GetMediaType(), "application/vnd.dev.sigstore.bundle.v0.3+json") attestations, err = c.GetByOwnerAndDigest(testOwner, testDigest, DefaultLimit) require.NoError(t, err) require.Equal(t, 5, len(attestations)) bundle = (attestations)[0].Bundle - require.Equal(t, bundle.GetMediaType(), "application/vnd.dev.sigstore.bundle+json;version=0.1") + require.Equal(t, bundle.GetMediaType(), "application/vnd.dev.sigstore.bundle.v0.3+json") } func TestGetByDigestGreaterThanLimit(t *testing.T) { @@ -82,14 +82,14 @@ func TestGetByDigestGreaterThanLimit(t *testing.T) { require.Equal(t, 3, len(attestations)) bundle := (attestations)[0].Bundle - require.Equal(t, bundle.GetMediaType(), "application/vnd.dev.sigstore.bundle+json;version=0.1") + require.Equal(t, bundle.GetMediaType(), "application/vnd.dev.sigstore.bundle.v0.3+json") attestations, err = c.GetByOwnerAndDigest(testOwner, testDigest, limit) require.NoError(t, err) require.Equal(t, len(attestations), limit) bundle = (attestations)[0].Bundle - require.Equal(t, bundle.GetMediaType(), "application/vnd.dev.sigstore.bundle+json;version=0.1") + require.Equal(t, bundle.GetMediaType(), "application/vnd.dev.sigstore.bundle.v0.3+json") } func TestGetByDigestWithNextPage(t *testing.T) { @@ -99,14 +99,14 @@ func TestGetByDigestWithNextPage(t *testing.T) { require.Equal(t, len(attestations), 10) bundle := (attestations)[0].Bundle - require.Equal(t, bundle.GetMediaType(), "application/vnd.dev.sigstore.bundle+json;version=0.1") + require.Equal(t, bundle.GetMediaType(), "application/vnd.dev.sigstore.bundle.v0.3+json") attestations, err = c.GetByOwnerAndDigest(testOwner, testDigest, DefaultLimit) require.NoError(t, err) require.Equal(t, len(attestations), 10) bundle = (attestations)[0].Bundle - require.Equal(t, bundle.GetMediaType(), "application/vnd.dev.sigstore.bundle+json;version=0.1") + require.Equal(t, bundle.GetMediaType(), "application/vnd.dev.sigstore.bundle.v0.3+json") } func TestGetByDigestGreaterThanLimitWithNextPage(t *testing.T) { @@ -119,14 +119,14 @@ func TestGetByDigestGreaterThanLimitWithNextPage(t *testing.T) { require.Equal(t, len(attestations), limit) bundle := (attestations)[0].Bundle - require.Equal(t, bundle.GetMediaType(), "application/vnd.dev.sigstore.bundle+json;version=0.1") + require.Equal(t, bundle.GetMediaType(), "application/vnd.dev.sigstore.bundle.v0.3+json") attestations, err = c.GetByOwnerAndDigest(testOwner, testDigest, limit) require.NoError(t, err) require.Equal(t, len(attestations), limit) bundle = (attestations)[0].Bundle - require.Equal(t, bundle.GetMediaType(), "application/vnd.dev.sigstore.bundle+json;version=0.1") + require.Equal(t, bundle.GetMediaType(), "application/vnd.dev.sigstore.bundle.v0.3+json") } func TestGetByDigest_NoAttestationsFound(t *testing.T) { From 35b2cf70cf360fa8ab70d71207c7bcc087422a1a Mon Sep 17 00:00:00 2001 From: Cody Soyland Date: Fri, 9 Aug 2024 16:36:16 -0400 Subject: [PATCH 40/53] Change to requiring bundle v0.2 Signed-off-by: Cody Soyland --- pkg/cmd/attestation/verification/sigstore.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/cmd/attestation/verification/sigstore.go b/pkg/cmd/attestation/verification/sigstore.go index b4e0ef8c0..d86a709b5 100644 --- a/pkg/cmd/attestation/verification/sigstore.go +++ b/pkg/cmd/attestation/verification/sigstore.go @@ -56,7 +56,7 @@ func NewLiveSigstoreVerifier(config SigstoreConfig) *LiveSigstoreVerifier { } func (v *LiveSigstoreVerifier) chooseVerifier(b *bundle.ProtobufBundle) (*verify.SignedEntityVerifier, string, error) { - if !b.MinVersion("0.3") { + if !b.MinVersion("0.2") { return nil, "", fmt.Errorf("unsupported bundle version: %s", b.MediaType) } verifyContent, err := b.VerificationContent() From 18d58b8d84bf1998dd3a0c6a292690069cf9d6b8 Mon Sep 17 00:00:00 2001 From: Tyler McGoffin Date: Fri, 9 Aug 2024 13:55:14 -0700 Subject: [PATCH 41/53] Replace `--project.*` flags' `name` with `title` in docs (#9443) With the upcoming migration from v1 project to v2 projects, we'd like the language in our documentation to align with v2 project language. In v2, projects are referred to by `title` and not `name`, though they are functionally equivalent under the hood for the CLI --- pkg/cmd/issue/create/create.go | 2 +- pkg/cmd/issue/edit/edit.go | 4 ++-- pkg/cmd/pr/create/create.go | 2 +- pkg/cmd/pr/edit/edit.go | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pkg/cmd/issue/create/create.go b/pkg/cmd/issue/create/create.go index 33b583012..160249e09 100644 --- a/pkg/cmd/issue/create/create.go +++ b/pkg/cmd/issue/create/create.go @@ -137,7 +137,7 @@ func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Co cmd.Flags().BoolVarP(&opts.WebMode, "web", "w", false, "Open the browser to create an issue") cmd.Flags().StringSliceVarP(&opts.Assignees, "assignee", "a", nil, "Assign people by their `login`. Use \"@me\" to self-assign.") cmd.Flags().StringSliceVarP(&opts.Labels, "label", "l", nil, "Add labels by `name`") - cmd.Flags().StringSliceVarP(&opts.Projects, "project", "p", nil, "Add the issue to projects by `name`") + cmd.Flags().StringSliceVarP(&opts.Projects, "project", "p", nil, "Add the issue to projects by `title`") cmd.Flags().StringVarP(&opts.Milestone, "milestone", "m", "", "Add the issue to a milestone by `name`") cmd.Flags().StringVar(&opts.RecoverFile, "recover", "", "Recover input from a failed run of create") cmd.Flags().StringVarP(&opts.Template, "template", "T", "", "Template `file` to use as starting body text") diff --git a/pkg/cmd/issue/edit/edit.go b/pkg/cmd/issue/edit/edit.go index 11a69383d..18067319f 100644 --- a/pkg/cmd/issue/edit/edit.go +++ b/pkg/cmd/issue/edit/edit.go @@ -153,8 +153,8 @@ func NewCmdEdit(f *cmdutil.Factory, runF func(*EditOptions) error) *cobra.Comman cmd.Flags().StringSliceVar(&opts.Editable.Assignees.Remove, "remove-assignee", nil, "Remove assigned users by their `login`. Use \"@me\" to unassign yourself.") cmd.Flags().StringSliceVar(&opts.Editable.Labels.Add, "add-label", nil, "Add labels by `name`") cmd.Flags().StringSliceVar(&opts.Editable.Labels.Remove, "remove-label", nil, "Remove labels by `name`") - cmd.Flags().StringSliceVar(&opts.Editable.Projects.Add, "add-project", nil, "Add the issue to projects by `name`") - cmd.Flags().StringSliceVar(&opts.Editable.Projects.Remove, "remove-project", nil, "Remove the issue from projects by `name`") + cmd.Flags().StringSliceVar(&opts.Editable.Projects.Add, "add-project", nil, "Add the issue to projects by `title`") + cmd.Flags().StringSliceVar(&opts.Editable.Projects.Remove, "remove-project", nil, "Remove the issue from projects by `title`") cmd.Flags().StringVarP(&opts.Editable.Milestone.Value, "milestone", "m", "", "Edit the milestone the issue belongs to by `name`") cmd.Flags().BoolVar(&removeMilestone, "remove-milestone", false, "Remove the milestone association from the issue") diff --git a/pkg/cmd/pr/create/create.go b/pkg/cmd/pr/create/create.go index 23f302069..c6c49ac32 100644 --- a/pkg/cmd/pr/create/create.go +++ b/pkg/cmd/pr/create/create.go @@ -220,7 +220,7 @@ func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Co fl.StringSliceVarP(&opts.Reviewers, "reviewer", "r", nil, "Request reviews from people or teams by their `handle`") fl.StringSliceVarP(&opts.Assignees, "assignee", "a", nil, "Assign people by their `login`. Use \"@me\" to self-assign.") fl.StringSliceVarP(&opts.Labels, "label", "l", nil, "Add labels by `name`") - fl.StringSliceVarP(&opts.Projects, "project", "p", nil, "Add the pull request to projects by `name`") + fl.StringSliceVarP(&opts.Projects, "project", "p", nil, "Add the pull request to projects by `title`") fl.StringVarP(&opts.Milestone, "milestone", "m", "", "Add the pull request to a milestone by `name`") fl.Bool("no-maintainer-edit", false, "Disable maintainer's ability to modify pull request") fl.StringVar(&opts.RecoverFile, "recover", "", "Recover input from a failed run of create") diff --git a/pkg/cmd/pr/edit/edit.go b/pkg/cmd/pr/edit/edit.go index 9dc190011..3c8d73ad3 100644 --- a/pkg/cmd/pr/edit/edit.go +++ b/pkg/cmd/pr/edit/edit.go @@ -161,8 +161,8 @@ func NewCmdEdit(f *cmdutil.Factory, runF func(*EditOptions) error) *cobra.Comman cmd.Flags().StringSliceVar(&opts.Editable.Assignees.Remove, "remove-assignee", nil, "Remove assigned users by their `login`. Use \"@me\" to unassign yourself.") cmd.Flags().StringSliceVar(&opts.Editable.Labels.Add, "add-label", nil, "Add labels by `name`") cmd.Flags().StringSliceVar(&opts.Editable.Labels.Remove, "remove-label", nil, "Remove labels by `name`") - cmd.Flags().StringSliceVar(&opts.Editable.Projects.Add, "add-project", nil, "Add the pull request to projects by `name`") - cmd.Flags().StringSliceVar(&opts.Editable.Projects.Remove, "remove-project", nil, "Remove the pull request from projects by `name`") + cmd.Flags().StringSliceVar(&opts.Editable.Projects.Add, "add-project", nil, "Add the pull request to projects by `title`") + cmd.Flags().StringSliceVar(&opts.Editable.Projects.Remove, "remove-project", nil, "Remove the pull request from projects by `title`") cmd.Flags().StringVarP(&opts.Editable.Milestone.Value, "milestone", "m", "", "Edit the milestone the pull request belongs to by `name`") cmd.Flags().BoolVar(&removeMilestone, "remove-milestone", false, "Remove the milestone association from the pull request") From ac77d6750dcd148c0b58665987132e28ee56aaf0 Mon Sep 17 00:00:00 2001 From: Yukai Chou Date: Sat, 10 Aug 2024 10:20:53 +0800 Subject: [PATCH 42/53] Wrap flags with backticks, continued --- pkg/cmd/repo/view/view.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/pkg/cmd/repo/view/view.go b/pkg/cmd/repo/view/view.go index 136384152..d0370203a 100644 --- a/pkg/cmd/repo/view/view.go +++ b/pkg/cmd/repo/view/view.go @@ -45,13 +45,15 @@ func NewCmdView(f *cmdutil.Factory, runF func(*ViewOptions) error) *cobra.Comman cmd := &cobra.Command{ Use: "view []", Short: "View a repository", - Long: `Display the description and the README of a GitHub repository. + Long: heredoc.Docf(` + Display the description and the README of a GitHub repository. -With no argument, the repository for the current directory is displayed. + With no argument, the repository for the current directory is displayed. -With '--web', open the repository in a web browser instead. + With %[1]s--web%[1]s, open the repository in a web browser instead. -With '--branch', view a specific branch of the repository.`, + With %[1]s--branch%[1]s, view a specific branch of the repository. + `, "`"), Args: cobra.MaximumNArgs(1), RunE: func(c *cobra.Command, args []string) error { if len(args) > 0 { From b36b39df60f1d87c26f33a612d5e5881e125c5ca Mon Sep 17 00:00:00 2001 From: "Babak K. Shandiz" Date: Sat, 10 Aug 2024 21:29:22 +0100 Subject: [PATCH 43/53] Explain why not looking for signature begin marker Signed-off-by: Babak K. Shandiz --- pkg/cmd/release/create/create.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pkg/cmd/release/create/create.go b/pkg/cmd/release/create/create.go index 412c93328..581255c81 100644 --- a/pkg/cmd/release/create/create.go +++ b/pkg/cmd/release/create/create.go @@ -528,6 +528,12 @@ func gitTagInfo(client *git.Client, tagName string) (string, error) { return "", err } + // If there is a signature, we should strip it from the end of the content. + // Note that, we can achieve this by looking for markers like "-----BEGIN PGP + // SIGNATURE-----" and cut the remaining text from the content, but this is + // not a safe approach, because, although unlikely, the content can contain + // a signature-like section which we shouldn't leave it as is. So, we need + // to get the tag signature as a whole, if any, and remote it from the content. signatureCmd, err := client.Command(context.Background(), "tag", "--list", tagName, "--format=%(contents:signature)") if err != nil { return "", err From 668dbcefc68bf1b246b75d86b52e75160fc0cd52 Mon Sep 17 00:00:00 2001 From: "Babak K. Shandiz" Date: Sat, 10 Aug 2024 21:50:31 +0100 Subject: [PATCH 44/53] Add test cases for PGP, SSH and X.509 signatures Signed-off-by: Babak K. Shandiz --- pkg/cmd/release/create/create_test.go | 34 +++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/pkg/cmd/release/create/create_test.go b/pkg/cmd/release/create/create_test.go index 6dd2b4844..85c1c3f3f 100644 --- a/pkg/cmd/release/create/create_test.go +++ b/pkg/cmd/release/create/create_test.go @@ -1750,20 +1750,44 @@ func Test_gitTagInfo(t *testing.T) { wantResult: "some\nmultiline\ncontent", }, { - name: "with signature", + name: "with signature (PGP)", runStubs: func(cs *run.CommandStubber) { - cs.Register(contentCmd, 0, "some\nmultiline\ncontent\n-----BEGIN SIGNATURE-----\nfoo\n-----END SIGNATURE-----") - cs.Register(signatureCmd, 0, "-----BEGIN SIGNATURE-----\nfoo\n-----END SIGNATURE-----") + cs.Register(contentCmd, 0, "some\nmultiline\ncontent\n-----BEGIN PGP SIGNATURE-----\n\nfoo\n-----END PGP SIGNATURE-----") + cs.Register(signatureCmd, 0, "-----BEGIN PGP SIGNATURE-----\n\nfoo\n-----END PGP SIGNATURE-----") + }, + wantResult: "some\nmultiline\ncontent", + }, + { + name: "with signature (PGP, RFC1991)", + runStubs: func(cs *run.CommandStubber) { + cs.Register(contentCmd, 0, "some\nmultiline\ncontent\n-----BEGIN PGP MESSAGE-----\n\nfoo\n-----END PGP MESSAGE-----") + cs.Register(signatureCmd, 0, "-----BEGIN PGP MESSAGE-----\n\nfoo\n-----END PGP MESSAGE-----") + }, + wantResult: "some\nmultiline\ncontent", + }, + { + name: "with signature (SSH)", + runStubs: func(cs *run.CommandStubber) { + cs.Register(contentCmd, 0, "some\nmultiline\ncontent\n-----BEGIN SSH SIGNATURE-----\nfoo\n-----END SSH SIGNATURE-----") + cs.Register(signatureCmd, 0, "-----BEGIN SSH SIGNATURE-----\nfoo\n-----END SSH SIGNATURE-----") + }, + wantResult: "some\nmultiline\ncontent", + }, + { + name: "with signature (X.509)", + runStubs: func(cs *run.CommandStubber) { + cs.Register(contentCmd, 0, "some\nmultiline\ncontent\n-----BEGIN SIGNED MESSAGE-----\nfoo\n-----END SIGNED MESSAGE-----") + cs.Register(signatureCmd, 0, "-----BEGIN SIGNED MESSAGE-----\nfoo\n-----END SIGNED MESSAGE-----") }, wantResult: "some\nmultiline\ncontent", }, { name: "with signature in content but not as true signature", runStubs: func(cs *run.CommandStubber) { - cs.Register(contentCmd, 0, "some\nmultiline\ncontent\n-----BEGIN SIGNATURE-----\nfoo\n-----END SIGNATURE-----") + cs.Register(contentCmd, 0, "some\nmultiline\ncontent\n-----BEGIN PGP SIGNATURE-----\n\nfoo\n-----END PGP SIGNATURE-----") cs.Register(signatureCmd, 0, "") }, - wantResult: "some\nmultiline\ncontent\n-----BEGIN SIGNATURE-----\nfoo\n-----END SIGNATURE-----", + wantResult: "some\nmultiline\ncontent\n-----BEGIN PGP SIGNATURE-----\n\nfoo\n-----END PGP SIGNATURE-----", }, { name: "error getting content", From 369a105c45dc0b99dafca5c39290a1ed2f7bdfc9 Mon Sep 17 00:00:00 2001 From: Andy Feller Date: Mon, 12 Aug 2024 10:00:37 -0400 Subject: [PATCH 45/53] Minor grammatical fix --- pkg/cmd/issue/create/create.go | 2 +- pkg/cmd/pr/create/create.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/cmd/issue/create/create.go b/pkg/cmd/issue/create/create.go index 1af25180f..a5119cb54 100644 --- a/pkg/cmd/issue/create/create.go +++ b/pkg/cmd/issue/create/create.go @@ -122,7 +122,7 @@ func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Co cmd.Flags().StringVarP(&opts.Title, "title", "t", "", "Supply a title. Will prompt for one otherwise.") cmd.Flags().StringVarP(&opts.Body, "body", "b", "", "Supply a body. Will prompt for one otherwise.") cmd.Flags().StringVarP(&bodyFile, "body-file", "F", "", "Read body text from `file` (use \"-\" to read from standard input)") - cmd.Flags().BoolVarP(&opts.EditorMode, "editor", "e", false, "Skip prompts and open the text editor to write the title and body in. The first line is the title and the rest text is the body.") + cmd.Flags().BoolVarP(&opts.EditorMode, "editor", "e", false, "Skip prompts and open the text editor to write the title and body in. The first line is the title and the remaining text is the body.") cmd.Flags().BoolVarP(&opts.WebMode, "web", "w", false, "Open the browser to create an issue") cmd.Flags().StringSliceVarP(&opts.Assignees, "assignee", "a", nil, "Assign people by their `login`. Use \"@me\" to self-assign.") cmd.Flags().StringSliceVarP(&opts.Labels, "label", "l", nil, "Add labels by `name`") diff --git a/pkg/cmd/pr/create/create.go b/pkg/cmd/pr/create/create.go index d85400202..8c91713a1 100644 --- a/pkg/cmd/pr/create/create.go +++ b/pkg/cmd/pr/create/create.go @@ -230,7 +230,7 @@ func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Co fl.StringVarP(&bodyFile, "body-file", "F", "", "Read body text from `file` (use \"-\" to read from standard input)") fl.StringVarP(&opts.BaseBranch, "base", "B", "", "The `branch` into which you want your code merged") fl.StringVarP(&opts.HeadBranch, "head", "H", "", "The `branch` that contains commits for your pull request (default [current branch])") - fl.BoolVarP(&opts.EditorMode, "editor", "e", false, "Skip prompts and open the text editor to write the title and body in. The first line is the title and the rest text is the body.") + fl.BoolVarP(&opts.EditorMode, "editor", "e", false, "Skip prompts and open the text editor to write the title and body in. The first line is the title and the remaining text is the body.") fl.BoolVarP(&opts.WebMode, "web", "w", false, "Open the web browser to create a pull request") fl.BoolVarP(&opts.FillVerbose, "fill-verbose", "", false, "Use commits msg+body for description") fl.BoolVarP(&opts.Autofill, "fill", "f", false, "Use commit info for title and body") From da43f6e47692035eef91841906ecdb0ad1517e4d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 15:00:14 +0000 Subject: [PATCH 46/53] build(deps): bump actions/attest-build-provenance from 1.4.0 to 1.4.1 Bumps [actions/attest-build-provenance](https://github.com/actions/attest-build-provenance) from 1.4.0 to 1.4.1. - [Release notes](https://github.com/actions/attest-build-provenance/releases) - [Changelog](https://github.com/actions/attest-build-provenance/blob/main/RELEASE.md) - [Commits](https://github.com/actions/attest-build-provenance/compare/210c1913531870065f03ce1f9440dd87bc0938cd...310b0a4a3b0b78ef57ecda988ee04b132db73ef8) --- updated-dependencies: - dependency-name: actions/attest-build-provenance dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/deployment.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deployment.yml b/.github/workflows/deployment.yml index 564eb647c..51b47e6d8 100644 --- a/.github/workflows/deployment.yml +++ b/.github/workflows/deployment.yml @@ -299,7 +299,7 @@ jobs: rpmsign --addsign dist/*.rpm - name: Attest release artifacts if: inputs.environment == 'production' - uses: actions/attest-build-provenance@210c1913531870065f03ce1f9440dd87bc0938cd # v1.4.0 + uses: actions/attest-build-provenance@310b0a4a3b0b78ef57ecda988ee04b132db73ef8 # v1.4.1 with: subject-path: "dist/gh_*" - name: Run createrepo From 025dcc8e959d04e6017113dc5cf600c8e0839bff Mon Sep 17 00:00:00 2001 From: bagtoad <47394200+BagToad@users.noreply.github.com> Date: Wed, 14 Aug 2024 10:20:41 -0600 Subject: [PATCH 47/53] Use latest checkout version, generate attestations, and specify go version file input. --- pkg/cmd/extension/ext_tmpls/goBinWorkflow.yml | 5 ++++- pkg/cmd/extension/ext_tmpls/otherBinWorkflow.yml | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/pkg/cmd/extension/ext_tmpls/goBinWorkflow.yml b/pkg/cmd/extension/ext_tmpls/goBinWorkflow.yml index dfda64d0e..9557f7200 100644 --- a/pkg/cmd/extension/ext_tmpls/goBinWorkflow.yml +++ b/pkg/cmd/extension/ext_tmpls/goBinWorkflow.yml @@ -10,5 +10,8 @@ jobs: release: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: cli/gh-extension-precompile@v1 + with: + generate_attestations: true + go_version_file: go.mod diff --git a/pkg/cmd/extension/ext_tmpls/otherBinWorkflow.yml b/pkg/cmd/extension/ext_tmpls/otherBinWorkflow.yml index 5b7c867a1..60669be08 100644 --- a/pkg/cmd/extension/ext_tmpls/otherBinWorkflow.yml +++ b/pkg/cmd/extension/ext_tmpls/otherBinWorkflow.yml @@ -10,7 +10,8 @@ jobs: release: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: cli/gh-extension-precompile@v1 with: build_script_override: "script/build.sh" + generate_attestations: true From 820f4f34694ddfeba8f6719e863419d53dc5c956 Mon Sep 17 00:00:00 2001 From: Kynan Ware <47394200+BagToad@users.noreply.github.com> Date: Wed, 14 Aug 2024 12:02:11 -0600 Subject: [PATCH 48/53] Do not generate build attestations for otherBinWorkflow.yml --- pkg/cmd/extension/ext_tmpls/otherBinWorkflow.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/cmd/extension/ext_tmpls/otherBinWorkflow.yml b/pkg/cmd/extension/ext_tmpls/otherBinWorkflow.yml index 60669be08..78ba05171 100644 --- a/pkg/cmd/extension/ext_tmpls/otherBinWorkflow.yml +++ b/pkg/cmd/extension/ext_tmpls/otherBinWorkflow.yml @@ -14,4 +14,3 @@ jobs: - uses: cli/gh-extension-precompile@v1 with: build_script_override: "script/build.sh" - generate_attestations: true From 0835642d3f94d1d87da3fbc005c6c8d42a072679 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 11:35:19 -0700 Subject: [PATCH 49/53] build(deps): bump github.com/creack/pty from 1.1.21 to 1.1.23 (#9459) Bumps [github.com/creack/pty](https://github.com/creack/pty) from 1.1.21 to 1.1.23. - [Release notes](https://github.com/creack/pty/releases) - [Commits](https://github.com/creack/pty/compare/v1.1.21...v1.1.23) --- updated-dependencies: - dependency-name: github.com/creack/pty dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 96935c68e..68d87c034 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/cli/oauth v1.0.1 github.com/cli/safeexec v1.0.1 github.com/cpuguy83/go-md2man/v2 v2.0.4 - github.com/creack/pty v1.1.21 + github.com/creack/pty v1.1.23 github.com/distribution/reference v0.5.0 github.com/gabriel-vasile/mimetype v1.4.5 github.com/gdamore/tcell/v2 v2.5.4 diff --git a/go.sum b/go.sum index 11eeb5411..1ed19f12c 100644 --- a/go.sum +++ b/go.sum @@ -112,8 +112,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= -github.com/creack/pty v1.1.21 h1:1/QdRyBaHHJP61QkWMXlOIBfsgdDeeKfK8SYVUWJKf0= -github.com/creack/pty v1.1.21/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= +github.com/creack/pty v1.1.23 h1:4M6+isWdcStXEf15G/RbrMPOQj1dZ7HPZCGwE4kOeP0= +github.com/creack/pty v1.1.23/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE= github.com/cyberphone/json-canonicalization v0.0.0-20220623050100-57a0ce2678a7 h1:vU+EP9ZuFUCYE0NYLwTSob+3LNEJATzNfP/DC7SWGWI= github.com/cyberphone/json-canonicalization v0.0.0-20220623050100-57a0ce2678a7/go.mod h1:uzvlm1mxhHkdfqitSA92i7Se+S9ksOn3a3qmv/kyOCw= github.com/danieljoos/wincred v1.2.1 h1:dl9cBrupW8+r5250DYkYxocLeZ1Y4vB1kxgtjxw8GQs= From 5b7070f027aa7537a869dc6456640e159a303f95 Mon Sep 17 00:00:00 2001 From: Kynan Ware <47394200+BagToad@users.noreply.github.com> Date: Wed, 14 Aug 2024 15:16:45 -0600 Subject: [PATCH 50/53] include required permissions to generate attestations --- pkg/cmd/extension/ext_tmpls/goBinWorkflow.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/cmd/extension/ext_tmpls/goBinWorkflow.yml b/pkg/cmd/extension/ext_tmpls/goBinWorkflow.yml index 9557f7200..080019c2a 100644 --- a/pkg/cmd/extension/ext_tmpls/goBinWorkflow.yml +++ b/pkg/cmd/extension/ext_tmpls/goBinWorkflow.yml @@ -5,6 +5,8 @@ on: - "v*" permissions: contents: write + id-token: write + attestations: write jobs: release: From 4618a267de22bea9f348f04e591a1d32c7b0d18c Mon Sep 17 00:00:00 2001 From: Cody Soyland Date: Thu, 15 Aug 2024 13:06:54 -0400 Subject: [PATCH 51/53] Update attestation TUF root Signed-off-by: Cody Soyland --- .../embed/tuf-repo.github.com/root.json | 326 +++++++++--------- 1 file changed, 165 insertions(+), 161 deletions(-) diff --git a/pkg/cmd/attestation/verification/embed/tuf-repo.github.com/root.json b/pkg/cmd/attestation/verification/embed/tuf-repo.github.com/root.json index 2990a2665..0d20e8f50 100644 --- a/pkg/cmd/attestation/verification/embed/tuf-repo.github.com/root.json +++ b/pkg/cmd/attestation/verification/embed/tuf-repo.github.com/root.json @@ -1,163 +1,167 @@ { - "signatures": [ - { - "keyid": "a10513a5ab61acd0c6b6fbe0504856ead18f3b17c4fabbe3fa848c79a5a187cf", - "sig": "304402203c8f5f7443f7052923e82f9ca0b1bb61a33498444076a2f43e1285a47f6e562d022014de99a7e5413440896b6804944e3c49390cfe6e617211b8dc42a8e67675bc13" - }, - { - "keyid": "d6a89e23fb22801a0d1186bf1bdd007e228f65a8aa9964d24d06cb5fbb0ce91c", - "sig": "3044022009a20307f974af7e05cc9564eea497f45062e3b21272d1062713b3d22c868298022059d032ad973a28bdbd03959cf96b21398b6b6e2ca618c17ce6c13712246343a2" - }, - { - "keyid": "539dde44014c850fe6eeb8b299eb7dae2e1f4bf83454b949e98aa73542cdc65a", - "sig": "3045022100edd270d36d0c8468b9a1f2ef1c81a270c72ffd50c65bca0ed1ebd424df09f64b022002b27ffafd7bc5bdfc25281b5b9b597cf2d67d4eeb4af2ff45eb3e666b860c21" - }, - { - "keyid": "88737ccdac7b49cc237e9aaead81be2a40278b886a693d8149a19cf543f093d3", - "sig": "30460221008d7d95434e576d5876b2db30fd645505ca546618bbc7a8e4b39f64e6a36df9ad022100c00a5294e4ddd02d48d28918b87a06bdfdeccd0618ecdcec29bb2597a05fe474" - }, - { - "keyid": "5e01c9a0b2641a8965a4a74e7df0bc7b2d8278a2c3ca0cf7a3f2f783d3c69800", - "sig": "30450220215fb3d19d94560a3a2a6067a71c92daf867d13700c9500c4c32d8009a48a634022100df9fb6cee786313bf6c363daac4de39b3dd531f211f81d2391c41bd2d0f91a80" - }, - { - "keyid": "4f4d1dd75f2d7f3860e3a068d7bed90dec5f0faafcbe1ace7fb7d95d29e07228", - "sig": "304502204091ac5e61b6462d262ecc8442781dd09843bed39942a95a4884c8c6a2c212ef022100dcee86392748f48950d04d539ac1a6643ed1f0b4bd6856f8aeb5a135826c846f" - }, - { - "keyid": "eb8eff37f93af2faaba519f341decec3cecd3eeafcace32966db9723842c8a62", - "sig": "30460221009188548601a43b501223caeefca4876ae892e18a85c885004b4c8aeeb05a4421022100abdcc72d94597f8297d6297897ff96f285168dbe6b3d57f846dbc7a2948d2935" - }, - { - "keyid": "8b498a80a1b7af188c10c9abdf6aade81d14faaffcde2abcd6063baa673ebd12", - "sig": "3046022100b440561545d48759dc4140cda9f8af7c9405a101d6136dd0a26edd6562b7064f022100cafa917ed90350494e47d226b64a8ec63ef5ceebb8ba4d2dec2ce018e4ad402a" - } + "signatures": [ + { + "keyid": "4f4d1dd75f2d7f3860e3a068d7bed90dec5f0faafcbe1ace7fb7d95d29e07228", + "sig": "" + }, + { + "keyid": "eb8eff37f93af2faaba519f341decec3cecd3eeafcace32966db9723842c8a62", + "sig": "" + }, + { + "keyid": "539dde44014c850fe6eeb8b299eb7dae2e1f4bf83454b949e98aa73542cdc65a", + "sig": "" + }, + { + "keyid": "a10513a5ab61acd0c6b6fbe0504856ead18f3b17c4fabbe3fa848c79a5a187cf", + "sig": "3046022100ca341d3ba2ef7657d69c2825729959681f55aec497b612e81a547e2abb616b49022100cd605b412a3d991f92e0818e07e60383bbd23904723eec221d6e39fdfeae3104" + }, + { + "keyid": "5e01c9a0b2641a8965a4a74e7df0bc7b2d8278a2c3ca0cf7a3f2f783d3c69800", + "sig": "3046022100d0f70effe60d6a18319e2890088cd01d45c654ee6d2ce1d5c3cdcf2dc7f637570221008f947a2d7334d948f1c4794b0a465f1dfb99a578dd8d1f4563cee0581f457db2" + }, + { + "keyid": "54809115b40137aac01af4b7ac2408c77ea0d58fa4dad48fc3196497d2a26f44", + "sig": "304502201ae931db1c48020fb37af54d446ac856306f619dfc3f93ddcff70d2880e443dc022100992b70451aa74805adef24e85ec352e598812267f623979bd4ce719b66b62d22" + }, + { + "keyid": "88737ccdac7b49cc237e9aaead81be2a40278b886a693d8149a19cf543f093d3", + "sig": "3045022023bba8e14c177609f43873aa0087ef983ddd2bad9a0a832c0cf279e1be8798f2022100facfaecc1d7ee793042eaaa6970fb9ca700c3bdbf4ee43ed0f8d0fc3aef96563" + }, + { + "keyid": "d6a89e23fb22801a0d1186bf1bdd007e228f65a8aa9964d24d06cb5fbb0ce91c", + "sig": "3046022100d2f6cceb05d135ce6a6ce7fe1dc76c24508154ad71c433028e64ca95ba716ffb022100f0592d60eb67508dd5f9cc593a4cca33bbaf94882c3d74a560fda845a456c6cc" + }, + { + "keyid": "8b498a80a1b7af188c10c9abdf6aade81d14faaffcde2abcd6063baa673ebd12", + "sig": "30450221009af2f0c534ed92de909a3b727f7101319c18e10623de8f48a0eba980d3d54d830220095842b16c58567c71f9dfa0b54e79daca1b2fecf3cb2ea4ee6d8393bdf93294" + } + ], + "signed": { + "_type": "root", + "consistent_snapshot": true, + "expires": "2025-04-11T14:36:57Z", + "keys": { + "4f4d1dd75f2d7f3860e3a068d7bed90dec5f0faafcbe1ace7fb7d95d29e07228": { + "keytype": "ecdsa", + "keyval": { + "public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAENki7aZVips5SgRzCd/Om0CGzQKY/\nnv84giqVDmdwb2ys82Z6soFLasvYYEEQcwqaC170n9gr93wHUgPc796uJA==\n-----END PUBLIC KEY-----\n" + }, + "scheme": "ecdsa-sha2-nistp256", + "x-tuf-on-ci-keyowner": "@ashtom" + }, + "539dde44014c850fe6eeb8b299eb7dae2e1f4bf83454b949e98aa73542cdc65a": { + "keytype": "ecdsa", + "keyval": { + "public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAElD0o2sOZN9n3RKQ7PtMLAoXj+2Ai\nn4PKT/pfnzDlNLrD3VTQwCc4sR4t+OLu4KQ+qk+kXkR9YuBsu3bdJZ1OWw==\n-----END PUBLIC KEY-----\n" + }, + "scheme": "ecdsa-sha2-nistp256", + "x-tuf-on-ci-keyowner": "@nerdneha" + }, + "54809115b40137aac01af4b7ac2408c77ea0d58fa4dad48fc3196497d2a26f44": { + "keytype": "ecdsa", + "keyval": { + "public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEimKcdST+ORD+g0aGEFDOVZDAaIYg\nIgesNKiIe2L7MUsYx5UHhzQ08quvew13eYSCNJnfwooFZu7cdTu8AwqFjQ==\n-----END PUBLIC KEY-----\n" + }, + "scheme": "ecdsa-sha2-nistp256", + "x-tuf-on-ci-keyowner": "@alexiswales" + }, + "88737ccdac7b49cc237e9aaead81be2a40278b886a693d8149a19cf543f093d3": { + "keytype": "ecdsa", + "keyval": { + "public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEBagkskNOpOTbetTX5CdnvMy+LiWn\nonRrNrqAHL4WgiebH7Uig7GLhC3bkeA/qgb926/vr9qhOPG9Buj2HatrPw==\n-----END PUBLIC KEY-----\n" + }, + "scheme": "ecdsa-sha2-nistp256", + "x-tuf-on-ci-keyowner": "@gregose" + }, + "8b498a80a1b7af188c10c9abdf6aade81d14faaffcde2abcd6063baa673ebd12": { + "keytype": "ecdsa", + "keyval": { + "public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE7IEoVNwrprchXGhT5sAhSax7SOd3\n8duuISghCzfmHdKJWSbV2wJRamRiUVRtmA83K/qm5cT20WXMCT5QeM/D3A==\n-----END PUBLIC KEY-----\n" + }, + "scheme": "ecdsa-sha2-nistp256", + "x-tuf-on-ci-keyowner": "@trevrosen" + }, + "a10513a5ab61acd0c6b6fbe0504856ead18f3b17c4fabbe3fa848c79a5a187cf": { + "keytype": "ecdsa", + "keyval": { + "public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEC2wJ3xscyXxBLybJ9FVjwkyQMe53\nRHUz77AjMO8MzVaT8xw6ZvJqdNZiytYtigWULlINxw6frNsWJKb/f7lC8A==\n-----END PUBLIC KEY-----\n" + }, + "scheme": "ecdsa-sha2-nistp256", + "x-tuf-on-ci-keyowner": "@kommendorkapten" + }, + "d6a89e23fb22801a0d1186bf1bdd007e228f65a8aa9964d24d06cb5fbb0ce91c": { + "keytype": "ecdsa", + "keyval": { + "public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEDdORwcruW3gqAgaLjH/nNdGMB4kQ\nAvA+wD6DyO4P/wR8ee2ce83NZHq1ZADKhve0rlYKaKy3CqyQ5SmlZ36Zhw==\n-----END PUBLIC KEY-----\n" + }, + "scheme": "ecdsa-sha2-nistp256", + "x-tuf-on-ci-keyowner": "@krukow" + }, + "eb8eff37f93af2faaba519f341decec3cecd3eeafcace32966db9723842c8a62": { + "keytype": "ecdsa", + "keyval": { + "public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAENynVdQnM9h7xU71G7PiJpQaDemub\nkbjsjYwLlPJTQVuxQO8WeIpJf8MEh5rf01t2dDIuCsZ5gRx+QvDv0UzfsA==\n-----END PUBLIC KEY-----\n" + }, + "scheme": "ecdsa-sha2-nistp256", + "x-tuf-on-ci-keyowner": "@mph4" + }, + "eb9799b483affac9da87ef4c9ea467928415c961349e607e5e6e485679b07f8f": { + "keytype": "ecdsa", + "keyval": { + "public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAENKNcNcX+d73lS1TRFb9Vnp8JvOoh\nzYQ+in43iGenbG8RGo9L/6FJ2hoRbVU6xskvyuErcdPbCdI4GxrQ5i8hkw==\n-----END PUBLIC KEY-----\n" + }, + "scheme": "ecdsa-sha2-nistp256", + "x-tuf-on-ci-online-uri": "azurekms://production-tuf-root.vault.azure.net/keys/Online-Key/aaf375fd8ed24acb949a5cc173700b05" + } + }, + "roles": { + "root": { + "keyids": [ + "a10513a5ab61acd0c6b6fbe0504856ead18f3b17c4fabbe3fa848c79a5a187cf", + "4f4d1dd75f2d7f3860e3a068d7bed90dec5f0faafcbe1ace7fb7d95d29e07228", + "88737ccdac7b49cc237e9aaead81be2a40278b886a693d8149a19cf543f093d3", + "d6a89e23fb22801a0d1186bf1bdd007e228f65a8aa9964d24d06cb5fbb0ce91c", + "eb8eff37f93af2faaba519f341decec3cecd3eeafcace32966db9723842c8a62", + "8b498a80a1b7af188c10c9abdf6aade81d14faaffcde2abcd6063baa673ebd12", + "539dde44014c850fe6eeb8b299eb7dae2e1f4bf83454b949e98aa73542cdc65a", + "54809115b40137aac01af4b7ac2408c77ea0d58fa4dad48fc3196497d2a26f44" ], - "signed": { - "_type": "root", - "consistent_snapshot": true, - "expires": "2024-06-23T08:29:18Z", - "keys": { - "4f4d1dd75f2d7f3860e3a068d7bed90dec5f0faafcbe1ace7fb7d95d29e07228": { - "keytype": "ecdsa", - "keyval": { - "public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAENki7aZVips5SgRzCd/Om0CGzQKY/\nnv84giqVDmdwb2ys82Z6soFLasvYYEEQcwqaC170n9gr93wHUgPc796uJA==\n-----END PUBLIC KEY-----\n" - }, - "scheme": "ecdsa-sha2-nistp256", - "x-tuf-on-ci-keyowner": "@ashtom" - }, - "539dde44014c850fe6eeb8b299eb7dae2e1f4bf83454b949e98aa73542cdc65a": { - "keytype": "ecdsa", - "keyval": { - "public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAElD0o2sOZN9n3RKQ7PtMLAoXj+2Ai\nn4PKT/pfnzDlNLrD3VTQwCc4sR4t+OLu4KQ+qk+kXkR9YuBsu3bdJZ1OWw==\n-----END PUBLIC KEY-----\n" - }, - "scheme": "ecdsa-sha2-nistp256", - "x-tuf-on-ci-keyowner": "@nerdneha" - }, - "5e01c9a0b2641a8965a4a74e7df0bc7b2d8278a2c3ca0cf7a3f2f783d3c69800": { - "keytype": "ecdsa", - "keyval": { - "public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEC9RNAsuDCNO6T7qA7Y5F8orw2tIW\nr7rUr4ffxvzTMrbkVtjR/trtE0q0+T0zQ8TWLyI6EYMwb947ej2ItfkOyA==\n-----END PUBLIC KEY-----\n" - }, - "scheme": "ecdsa-sha2-nistp256", - "x-tuf-on-ci-keyowner": "@jacobdepriest" - }, - "88737ccdac7b49cc237e9aaead81be2a40278b886a693d8149a19cf543f093d3": { - "keytype": "ecdsa", - "keyval": { - "public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEBagkskNOpOTbetTX5CdnvMy+LiWn\nonRrNrqAHL4WgiebH7Uig7GLhC3bkeA/qgb926/vr9qhOPG9Buj2HatrPw==\n-----END PUBLIC KEY-----\n" - }, - "scheme": "ecdsa-sha2-nistp256", - "x-tuf-on-ci-keyowner": "@gregose" - }, - "8b498a80a1b7af188c10c9abdf6aade81d14faaffcde2abcd6063baa673ebd12": { - "keytype": "ecdsa", - "keyval": { - "public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE7IEoVNwrprchXGhT5sAhSax7SOd3\n8duuISghCzfmHdKJWSbV2wJRamRiUVRtmA83K/qm5cT20WXMCT5QeM/D3A==\n-----END PUBLIC KEY-----\n" - }, - "scheme": "ecdsa-sha2-nistp256", - "x-tuf-on-ci-keyowner": "@trevrosen" - }, - "a10513a5ab61acd0c6b6fbe0504856ead18f3b17c4fabbe3fa848c79a5a187cf": { - "keytype": "ecdsa", - "keyval": { - "public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEC2wJ3xscyXxBLybJ9FVjwkyQMe53\nRHUz77AjMO8MzVaT8xw6ZvJqdNZiytYtigWULlINxw6frNsWJKb/f7lC8A==\n-----END PUBLIC KEY-----\n" - }, - "scheme": "ecdsa-sha2-nistp256", - "x-tuf-on-ci-keyowner": "@kommendorkapten" - }, - "d6a89e23fb22801a0d1186bf1bdd007e228f65a8aa9964d24d06cb5fbb0ce91c": { - "keytype": "ecdsa", - "keyval": { - "public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEDdORwcruW3gqAgaLjH/nNdGMB4kQ\nAvA+wD6DyO4P/wR8ee2ce83NZHq1ZADKhve0rlYKaKy3CqyQ5SmlZ36Zhw==\n-----END PUBLIC KEY-----\n" - }, - "scheme": "ecdsa-sha2-nistp256", - "x-tuf-on-ci-keyowner": "@krukow" - }, - "eb8eff37f93af2faaba519f341decec3cecd3eeafcace32966db9723842c8a62": { - "keytype": "ecdsa", - "keyval": { - "public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAENynVdQnM9h7xU71G7PiJpQaDemub\nkbjsjYwLlPJTQVuxQO8WeIpJf8MEh5rf01t2dDIuCsZ5gRx+QvDv0UzfsA==\n-----END PUBLIC KEY-----\n" - }, - "scheme": "ecdsa-sha2-nistp256", - "x-tuf-on-ci-keyowner": "@mph4" - }, - "eb9799b483affac9da87ef4c9ea467928415c961349e607e5e6e485679b07f8f": { - "keytype": "ecdsa", - "keyval": { - "public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAENKNcNcX+d73lS1TRFb9Vnp8JvOoh\nzYQ+in43iGenbG8RGo9L/6FJ2hoRbVU6xskvyuErcdPbCdI4GxrQ5i8hkw==\n-----END PUBLIC KEY-----\n" - }, - "scheme": "ecdsa-sha2-nistp256", - "x-tuf-on-ci-online-uri": "azurekms://production-tuf-root.vault.azure.net/keys/Online-Key/aaf375fd8ed24acb949a5cc173700b05" - } - }, - "roles": { - "root": { - "keyids": [ - "a10513a5ab61acd0c6b6fbe0504856ead18f3b17c4fabbe3fa848c79a5a187cf", - "4f4d1dd75f2d7f3860e3a068d7bed90dec5f0faafcbe1ace7fb7d95d29e07228", - "88737ccdac7b49cc237e9aaead81be2a40278b886a693d8149a19cf543f093d3", - "5e01c9a0b2641a8965a4a74e7df0bc7b2d8278a2c3ca0cf7a3f2f783d3c69800", - "d6a89e23fb22801a0d1186bf1bdd007e228f65a8aa9964d24d06cb5fbb0ce91c", - "eb8eff37f93af2faaba519f341decec3cecd3eeafcace32966db9723842c8a62", - "8b498a80a1b7af188c10c9abdf6aade81d14faaffcde2abcd6063baa673ebd12", - "539dde44014c850fe6eeb8b299eb7dae2e1f4bf83454b949e98aa73542cdc65a" - ], - "threshold": 3 - }, - "snapshot": { - "keyids": [ - "eb9799b483affac9da87ef4c9ea467928415c961349e607e5e6e485679b07f8f" - ], - "threshold": 1, - "x-tuf-on-ci-expiry-period": 21, - "x-tuf-on-ci-signing-period": 7 - }, - "targets": { - "keyids": [ - "a10513a5ab61acd0c6b6fbe0504856ead18f3b17c4fabbe3fa848c79a5a187cf", - "4f4d1dd75f2d7f3860e3a068d7bed90dec5f0faafcbe1ace7fb7d95d29e07228", - "88737ccdac7b49cc237e9aaead81be2a40278b886a693d8149a19cf543f093d3", - "5e01c9a0b2641a8965a4a74e7df0bc7b2d8278a2c3ca0cf7a3f2f783d3c69800", - "d6a89e23fb22801a0d1186bf1bdd007e228f65a8aa9964d24d06cb5fbb0ce91c", - "eb8eff37f93af2faaba519f341decec3cecd3eeafcace32966db9723842c8a62", - "8b498a80a1b7af188c10c9abdf6aade81d14faaffcde2abcd6063baa673ebd12", - "539dde44014c850fe6eeb8b299eb7dae2e1f4bf83454b949e98aa73542cdc65a" - ], - "threshold": 3 - }, - "timestamp": { - "keyids": [ - "eb9799b483affac9da87ef4c9ea467928415c961349e607e5e6e485679b07f8f" - ], - "threshold": 1, - "x-tuf-on-ci-expiry-period": 7, - "x-tuf-on-ci-signing-period": 6 - } - }, - "spec_version": "1.0.31", - "version": 1, - "x-tuf-on-ci-expiry-period": 240, - "x-tuf-on-ci-signing-period": 60 - } -} + "threshold": 3 + }, + "snapshot": { + "keyids": [ + "eb9799b483affac9da87ef4c9ea467928415c961349e607e5e6e485679b07f8f" + ], + "threshold": 1, + "x-tuf-on-ci-expiry-period": 21, + "x-tuf-on-ci-signing-period": 7 + }, + "targets": { + "keyids": [ + "a10513a5ab61acd0c6b6fbe0504856ead18f3b17c4fabbe3fa848c79a5a187cf", + "4f4d1dd75f2d7f3860e3a068d7bed90dec5f0faafcbe1ace7fb7d95d29e07228", + "88737ccdac7b49cc237e9aaead81be2a40278b886a693d8149a19cf543f093d3", + "d6a89e23fb22801a0d1186bf1bdd007e228f65a8aa9964d24d06cb5fbb0ce91c", + "eb8eff37f93af2faaba519f341decec3cecd3eeafcace32966db9723842c8a62", + "8b498a80a1b7af188c10c9abdf6aade81d14faaffcde2abcd6063baa673ebd12", + "539dde44014c850fe6eeb8b299eb7dae2e1f4bf83454b949e98aa73542cdc65a", + "54809115b40137aac01af4b7ac2408c77ea0d58fa4dad48fc3196497d2a26f44" + ], + "threshold": 3 + }, + "timestamp": { + "keyids": [ + "eb9799b483affac9da87ef4c9ea467928415c961349e607e5e6e485679b07f8f" + ], + "threshold": 1, + "x-tuf-on-ci-expiry-period": 7, + "x-tuf-on-ci-signing-period": 6 + } + }, + "spec_version": "1.0.31", + "version": 3, + "x-tuf-on-ci-expiry-period": 240, + "x-tuf-on-ci-signing-period": 60 + } +} \ No newline at end of file From d707102958deda188ddd44f44854dab25394eadb Mon Sep 17 00:00:00 2001 From: Kynan Ware <47394200+BagToad@users.noreply.github.com> Date: Thu, 15 Aug 2024 11:24:40 -0600 Subject: [PATCH 52/53] Add a note about external contributors to `working-with-us.md` --- docs/working-with-us.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/working-with-us.md b/docs/working-with-us.md index b4163350b..38326921e 100644 --- a/docs/working-with-us.md +++ b/docs/working-with-us.md @@ -4,6 +4,9 @@ POV: your team at GitHub is interested in shipping a new command in `gh`. This document outlines the process the CLI team prefers for helping ensure success both for your new feature and the CLI project as a whole. +> [!NOTE] +> External contributors, please see [CONTRIBUTING.md](/.github/CONTRIBUTING.md). + ## Step 0: Create an extension Even if you want to see your code merged into `gh`, you should start with [an extension](https://docs.github.com/en/github-cli/github-cli/creating-github-cli-extensions) written in Go and leveraging [go-gh](https://github.com/cli/go-gh). Though `gh` extensions can be written in any language, we treat Go as a first class experience and ship a library of helpers for extensions written in Go. From 1886fb46aba416e01e5b6ab43fc8e744342d8fb1 Mon Sep 17 00:00:00 2001 From: Prabhat Kumar Sahu Date: Sat, 17 Aug 2024 03:00:11 +0530 Subject: [PATCH 53/53] Fix pr checks exit code (#9452) * Enhance with exit code documentation * Add new error message for PR check * Refine gh pr checks: Add exit code 8 * Update EXIT CODES section format in man page generation --- internal/docs/man.go | 10 ++++++++++ internal/docs/man_test.go | 25 +++++++++++++++++++++++++ pkg/cmd/pr/checks/checks.go | 3 +++ pkg/cmd/root/help.go | 1 + 4 files changed, 39 insertions(+) diff --git a/internal/docs/man.go b/internal/docs/man.go index 5ac353a46..66878d278 100644 --- a/internal/docs/man.go +++ b/internal/docs/man.go @@ -198,6 +198,15 @@ func manPrintJSONFields(buf *bytes.Buffer, command *cobra.Command) { buf.WriteString("\n") } +func manPrintExitCodes(buf *bytes.Buffer) { + buf.WriteString("# EXIT CODES\n") + buf.WriteString("0: Successful execution\n\n") + buf.WriteString("1: Error\n\n") + buf.WriteString("2: Command canceled\n\n") + buf.WriteString("4: Authentication required\n\n") + buf.WriteString("NOTE: Specific commands may have additional exit codes. Refer to the command's help for more information.\n\n") +} + func genMan(cmd *cobra.Command, header *GenManHeader) []byte { cmd.InitDefaultHelpCmd() cmd.InitDefaultHelpFlag() @@ -217,6 +226,7 @@ func genMan(cmd *cobra.Command, header *GenManHeader) []byte { manPrintOptions(buf, cmd) manPrintAliases(buf, cmd) manPrintJSONFields(buf, cmd) + manPrintExitCodes(buf) if len(cmd.Example) > 0 { buf.WriteString("# EXAMPLE\n") buf.WriteString(fmt.Sprintf("```\n%s\n```\n", cmd.Example)) diff --git a/internal/docs/man_test.go b/internal/docs/man_test.go index 2a0f6a7f7..4db6b7459 100644 --- a/internal/docs/man_test.go +++ b/internal/docs/man_test.go @@ -129,6 +129,31 @@ func TestGenManJSONFields(t *testing.T) { checkStringContains(t, output, "baz") } +func TestGenManDocExitCodes(t *testing.T) { + header := &GenManHeader{ + Title: "Project", + Section: "1", + } + cmd := &cobra.Command{ + Use: "test-command", + Short: "A test command", + Long: "A test command for checking exit codes section", + } + buf := new(bytes.Buffer) + if err := renderMan(cmd, header, buf); err != nil { + t.Fatal(err) + } + output := buf.String() + + // Check for the presence of the exit codes section + checkStringContains(t, output, ".SH EXIT CODES") + checkStringContains(t, output, "0: Successful execution") + checkStringContains(t, output, "1: Error") + checkStringContains(t, output, "2: Command canceled") + checkStringContains(t, output, "4: Authentication required") + checkStringContains(t, output, "NOTE: Specific commands may have additional exit codes. Refer to the command's help for more information.") +} + func TestManPrintFlagsHidesShortDeprecated(t *testing.T) { c := &cobra.Command{} c.Flags().StringP("foo", "f", "default", "Foo flag") diff --git a/pkg/cmd/pr/checks/checks.go b/pkg/cmd/pr/checks/checks.go index bbf2f453b..40b395897 100644 --- a/pkg/cmd/pr/checks/checks.go +++ b/pkg/cmd/pr/checks/checks.go @@ -66,6 +66,9 @@ func NewCmdChecks(f *cmdutil.Factory, runF func(*ChecksOptions) error) *cobra.Co Without an argument, the pull request that belongs to the current branch is selected. + + Additional exit codes: + 8: Checks pending `), Args: cobra.MaximumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { diff --git a/pkg/cmd/root/help.go b/pkg/cmd/root/help.go index ee5db5e68..a7daa7b84 100644 --- a/pkg/cmd/root/help.go +++ b/pkg/cmd/root/help.go @@ -182,6 +182,7 @@ func rootHelpFunc(f *cmdutil.Factory, command *cobra.Command, args []string) { helpEntries = append(helpEntries, helpEntry{"LEARN MORE", heredoc.Docf(` Use %[1]sgh --help%[1]s for more information about a command. Read the manual at https://cli.github.com/manual + Learn about exit codes using %[1]sgh help exit-codes%[1]s `, "`")}) out := f.IOStreams.Out