From 5f3a8ae1a3ca9fde98f05fe29989590769ad8dc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20Garc=C3=ADa=20Veytia=20=28Puerco=29?= Date: Thu, 24 Jul 2025 22:17:26 -0600 Subject: [PATCH 1/3] Fix options not parsing branch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Adolfo García Veytia (Puerco) --- sourcetool/internal/cmd/options.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sourcetool/internal/cmd/options.go b/sourcetool/internal/cmd/options.go index bc7fd8fa..0c4ba9fa 100644 --- a/sourcetool/internal/cmd/options.go +++ b/sourcetool/internal/cmd/options.go @@ -91,8 +91,10 @@ type branchOptions struct { branch string } +// ParseLocator parses an SPDX locator string and assigns its components +// to the branch options fields. func (bo *branchOptions) ParseLocator(lString string) error { - components, err := vcslocator.Locator(lString).Parse() + components, err := vcslocator.Locator(lString).Parse(vcslocator.WithRefAsBranch(true)) if err != nil { return fmt.Errorf("parsing repository slug: %w", err) } From de14edfd5d3fe5efb7e1d2f66e4ba3d915763666 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20Garc=C3=ADa=20Veytia=20=28Puerco=29?= Date: Thu, 24 Jul 2025 22:20:14 -0600 Subject: [PATCH 2/3] Fix bug creating local feature branch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Adolfo García Veytia (Puerco) --- sourcetool/pkg/repo/clone.go | 6 ++++++ sourcetool/pkg/repo/implementation.go | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/sourcetool/pkg/repo/clone.go b/sourcetool/pkg/repo/clone.go index 45ed7e3b..452c9fc3 100644 --- a/sourcetool/pkg/repo/clone.go +++ b/sourcetool/pkg/repo/clone.go @@ -99,8 +99,14 @@ func (c *Clone) AddRemote(name, url string) error { // PushToRemote pushes the active branch to the specified remote func (c *Clone) PushRemote(remoteName string) error { + refSpecs := []config.RefSpec{ + config.RefSpec(fmt.Sprintf( + "+refs/heads/%s:refs/heads/%s", c.FeatureBranch, c.FeatureBranch, + )), + } err := c.repo.Push(&git.PushOptions{ RemoteName: remoteName, + RefSpecs: refSpecs, }) if err != nil { return fmt.Errorf("pushing to remote: %w", err) diff --git a/sourcetool/pkg/repo/implementation.go b/sourcetool/pkg/repo/implementation.go index 4bd0d007..5c950a65 100644 --- a/sourcetool/pkg/repo/implementation.go +++ b/sourcetool/pkg/repo/implementation.go @@ -134,6 +134,12 @@ func (impl *defaultPrmImpl) CloneRepo(opts *options.PullRequestManagerOptions, a return nil, fmt.Errorf("adding remote: %w", err) } + // Create the feature branch + if err := clone.CreateFeatureBranch(); err != nil { + clone.Cleanup() + return nil, fmt.Errorf("creating feature branch locally: %w", err) + } + return clone, nil } From 7268cb843a85314697818b83d5e151f6ca8bd184 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20Garc=C3=ADa=20Veytia=20=28Puerco=29?= Date: Thu, 24 Jul 2025 22:35:11 -0600 Subject: [PATCH 3/3] Add interactive mode to policy create MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Adolfo García Veytia (Puerco) --- sourcetool/internal/cmd/policy.go | 39 ++++++++++++++++++++++++++++++- sourcetool/internal/cmd/setup.go | 8 +++---- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/sourcetool/internal/cmd/policy.go b/sourcetool/internal/cmd/policy.go index 1223f423..6abd9ade 100644 --- a/sourcetool/internal/cmd/policy.go +++ b/sourcetool/internal/cmd/policy.go @@ -7,6 +7,7 @@ import ( "os" "github.com/spf13/cobra" + "sigs.k8s.io/release-utils/util" "github.com/slsa-framework/slsa-source-poc/sourcetool/pkg/policy" "github.com/slsa-framework/slsa-source-poc/sourcetool/pkg/sourcetool" @@ -19,12 +20,14 @@ type policyViewOpts struct { type policyCreateOpts struct { branchOptions + interactive bool openPullRequest bool } func (pco *policyCreateOpts) AddFlags(cmd *cobra.Command) { pco.branchOptions.AddFlags(cmd) cmd.PersistentFlags().BoolVar(&pco.openPullRequest, "pr", true, "Open a pull request to check-in the policy") + cmd.PersistentFlags().BoolVar(&pco.interactive, "interactive", true, "confirm before performing changes") } func addPolicy(parentCmd *cobra.Command) { @@ -125,7 +128,10 @@ func addPolicyCreate(parent *cobra.Command) { policyViewCmd := &cobra.Command{ Short: "creates a source policy for a repository", Long: `The create subcommand inspects the controls in place for a repo -and creates a new policy for it. +and creates a new policy for it. By default it will create a pull request +in the community source policy repository. If you choose not to, it will +just print the generated policy. + `, Use: "create owner/repo@branch", SilenceUsage: false, @@ -143,6 +149,10 @@ and creates a new policy for it. return err } + if err := opts.EnsureDefaults(); err != nil { + return err + } + return nil }, RunE: func(cmd *cobra.Command, args []string) (err error) { @@ -161,7 +171,9 @@ and creates a new policy for it. // Create a new sourcetool object srctool, err := sourcetool.New( sourcetool.WithAuthenticator(authenticator), + // Uncomment when we want to support custom policy repos // sourcetool.WithPolicyRepo(opts.policyRepo), + sourcetool.WithCreatePolicyPR(opts.openPullRequest), ) if err != nil { return err @@ -175,6 +187,31 @@ and creates a new policy for it. return fmt.Errorf("repository already has a policy checked into the community repo") } + if opts.openPullRequest && opts.interactive { + fmt.Printf(` + +sourcetool is about to perform the following actions on your behalf: + + > Open a pull request in %s/%s checking in + a SLSA source policy for the current controls enabled + in %s/%s. + +We will push a branch to your fork of the community repository and +open the pull request from there. + +`, policy.SourcePolicyRepoOwner, policy.SourcePolicyRepo, opts.owner, opts.repository) + + _, s, err := util.Ask("Type 'yes' if you want to continue?", "yes|no|no", 3) + if err != nil { + return err + } + + if !s { + fmt.Println("Cancelled.") + return nil + } + } + // Create the policy, this will open the pull request in the community // repo if the options say so. pcy, pr, err := srctool.CreateRepositoryPolicy( diff --git a/sourcetool/internal/cmd/setup.go b/sourcetool/internal/cmd/setup.go index 054ea8be..0235d765 100644 --- a/sourcetool/internal/cmd/setup.go +++ b/sourcetool/internal/cmd/setup.go @@ -8,7 +8,6 @@ import ( "github.com/spf13/cobra" "sigs.k8s.io/release-utils/util" - "github.com/slsa-framework/slsa-source-poc/sourcetool/pkg/policy" "github.com/slsa-framework/slsa-source-poc/sourcetool/pkg/sourcetool" "github.com/slsa-framework/slsa-source-poc/sourcetool/pkg/sourcetool/models" ) @@ -30,9 +29,10 @@ func (so *setupOpts) AddFlags(cmd *cobra.Command) { cmd.PersistentFlags().StringVar( &so.userForkOrg, "user-fork", "", "GitHub organization to look for forks of repos (for pull requests)", ) - cmd.PersistentFlags().StringVar( - &so.policyRepo, "policy-repo", fmt.Sprintf("%s/%s", policy.SourcePolicyRepoOwner, policy.SourcePolicyRepo), "repository to store the SLSA source policy", - ) + // Uncomment when we support custom policy repos + // cmd.PersistentFlags().StringVar( + // &so.policyRepo, "policy-repo", fmt.Sprintf("%s/%s", policy.SourcePolicyRepoOwner, policy.SourcePolicyRepo), "repository to store the SLSA source policy", + // ) cmd.PersistentFlags().BoolVar( &so.interactive, "interactive", true, "confirm before performing changes",