Skip to content

Commit fc0f59a

Browse files
authored
Support tag control automation in sourcetool setup repo (#246)
* onboard: Do preflight check with authenticator Signed-off-by: Adolfo García Veytia (Puerco) <[email protected]> * Regenerate fakes Signed-off-by: Adolfo García Veytia (Puerco) <[email protected]> * Add tag hygiene to repo setup Signed-off-by: Adolfo García Veytia (Puerco) <[email protected]> * Suggest policy until SLSA3+ Signed-off-by: Adolfo García Veytia (Puerco) <[email protected]> * Report all control errs, honor noop Signed-off-by: Adolfo García Veytia (Puerco) <[email protected]> * Report control config Signed-off-by: Adolfo García Veytia (Puerco) <[email protected]> --------- Signed-off-by: Adolfo García Veytia (Puerco) <[email protected]>
1 parent 10944f3 commit fc0f59a

File tree

6 files changed

+53
-41
lines changed

6 files changed

+53
-41
lines changed

sourcetool/internal/cmd/setup.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,13 @@ sourcetool is about to perform the following actions on your behalf:
180180
return fmt.Errorf("onboarding repo: %w", err)
181181
}
182182

183+
fmt.Println()
184+
fmt.Println(w("✅ Controls have been configured successfully."))
185+
fmt.Println()
186+
fmt.Printf("Please run %s\n", w2("sourcetool status "+opts.GetRepository().Path))
187+
fmt.Println("to check the status of the new controls and for the next steps.")
188+
fmt.Println()
189+
183190
return nil
184191
},
185192
}

sourcetool/internal/cmd/status.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,8 @@ sourcetool status myorg/myrepo@mybranch
171171
continue
172172
}
173173

174-
// Suggest creating the policy but only on the higher levels
175-
if status.Name == slsa.PolicyAvailable && toplevel == slsa.SlsaSourceLevel1 {
174+
// Suggest creating the policy but only when reaching SLSA3+
175+
if status.Name == slsa.PolicyAvailable && !slsa.IsLevelHigherOrEqualTo(toplevel, slsa.SlsaSourceLevel3) {
176176
continue
177177
}
178178

sourcetool/pkg/sourcetool/backends/vcs/github/manage.go

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ func (b *Backend) CreateWorkflowPR(r *models.Repository, branches []*models.Bran
5959
}
6060
workflowYAML := fmt.Sprintf(workflowData, strings.Join(quotedBranchesList, ", "))
6161

62-
// Create a PAR manager
62+
// Create a PR manager
6363
prManager := repo.NewPullRequestManager(repo.WithAuthenticator(b.authenticator))
6464

6565
// TODO(puerco): Honor forks settings, etc
@@ -191,29 +191,43 @@ func (b *Backend) CreateTagRuleset(r *models.Repository) error {
191191
return nil
192192
}
193193

194+
// ConfigureControls configure the SLSA controls in the repository
194195
func (b *Backend) ConfigureControls(r *models.Repository, branches []*models.Branch, configs []models.ControlConfiguration) error {
196+
errs := []error{}
195197
for _, config := range configs {
196198
switch config {
197199
case models.CONFIG_BRANCH_RULES:
198200
if err := b.CreateRepoRuleset(r, branches); err != nil {
199-
return fmt.Errorf("creating rules in the repository: %w", err)
201+
if !errors.Is(err, models.ErrProtectionAlreadyInPlace) {
202+
errs = append(errs, fmt.Errorf("creating rules in the repository: %w", err))
203+
}
200204
}
201205
case models.CONFIG_GEN_PROVENANCE:
202-
if err := b.CheckWorkflowFork(r); err != nil {
203-
return fmt.Errorf("checking repository fork: %w", err)
206+
pr, err := b.FindWorkflowPR(context.Background(), r)
207+
if err != nil {
208+
errs = append(errs, fmt.Errorf("checking repository pull request: %w", err))
209+
}
210+
211+
if pr != nil {
212+
continue
204213
}
214+
205215
if _, err := b.CreateWorkflowPR(r, branches); err != nil {
206-
return fmt.Errorf("opening SLSA source workflow pull request: %w", err)
216+
if !errors.Is(err, models.ErrProtectionAlreadyInPlace) {
217+
errs = append(errs, fmt.Errorf("opening SLSA source workflow pull request: %w", err))
218+
}
207219
}
208220
case models.CONFIG_TAG_RULES:
209221
if err := b.CreateTagRuleset(r); err != nil {
210-
return fmt.Errorf("opening SLSA source workflow pull request: %w", err)
222+
if !errors.Is(err, models.ErrProtectionAlreadyInPlace) {
223+
errs = append(errs, fmt.Errorf("opening SLSA source workflow pull request: %w", err))
224+
}
211225
}
212226
case models.CONFIG_POLICY:
213227
// Noop, this is not handled by the VCS handler
214228
default:
215-
return fmt.Errorf("unknown configuration flag: %q", config)
229+
errs = append(errs, fmt.Errorf("unknown configuration flag: %q", config))
216230
}
217231
}
218-
return nil
232+
return errors.Join(errs...)
219233
}

sourcetool/pkg/sourcetool/implementation.go

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66
"encoding/json"
77
"errors"
88
"fmt"
9-
"os"
109
"strings"
1110
"time"
1211

@@ -23,15 +22,11 @@ import (
2322
"github.com/slsa-framework/slsa-source-poc/sourcetool/pkg/sourcetool/options"
2423
)
2524

26-
const (
27-
tokenVar = "GITHUB_TOKEN" //nolint:gosec // This are not creds, just the name
28-
)
29-
3025
// toolImplementation defines the mockable implementation of source tool
3126
//
3227
//counterfeiter:generate . toolImplementation
3328
type toolImplementation interface {
34-
VerifyOptionsForFullOnboard(*options.Options) error
29+
VerifyOptionsForFullOnboard(*auth.Authenticator, *options.Options) error
3530
CheckPolicyFork(*options.Options) error
3631
CreatePolicyPR(*auth.Authenticator, *options.Options, *models.Repository, *policy.RepoPolicy) (*models.PullRequest, error)
3732
CheckForks(*options.Options) error
@@ -72,10 +67,14 @@ func (impl *defaultToolImplementation) GetVcsBackend(*models.Repository) (models
7267

7368
// VerifyOptions checks options are in good shape to run
7469
// TODO(puerco): To be completed
75-
func (impl *defaultToolImplementation) VerifyOptionsForFullOnboard(opts *options.Options) error {
70+
func (impl *defaultToolImplementation) VerifyOptionsForFullOnboard(a *auth.Authenticator, opts *options.Options) error {
7671
errs := []error{}
77-
if t := os.Getenv(tokenVar); t == "" {
78-
errs = append(errs, fmt.Errorf("$%s environment variable not set", tokenVar))
72+
uid, err := a.WhoAmI()
73+
if err != nil {
74+
errs = append(errs, err)
75+
}
76+
if uid == nil {
77+
errs = append(errs, errors.New("sourcetool is not logged in"))
7978
}
8079

8180
return errors.Join(errs...)

sourcetool/pkg/sourcetool/sourcetoolfakes/fake_tool_implementation.go

Lines changed: 12 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sourcetool/pkg/sourcetool/tool.go

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -80,28 +80,18 @@ func (t *Tool) OnboardRepository(repo *models.Repository, branches []*models.Bra
8080
return fmt.Errorf("getting VCS backend: %w", err)
8181
}
8282

83-
if err := t.impl.CheckForks(&t.Options); err != nil {
84-
return fmt.Errorf("checking repository forks: %w", err)
85-
}
86-
87-
if err := t.impl.VerifyOptionsForFullOnboard(&t.Options); err != nil {
83+
if err := t.impl.VerifyOptionsForFullOnboard(t.Authenticator, &t.Options); err != nil {
8884
return fmt.Errorf("verifying options: %w", err)
8985
}
9086

9187
if err = backend.ConfigureControls(
9288
repo, branches, []models.ControlConfiguration{
93-
models.CONFIG_BRANCH_RULES, models.CONFIG_GEN_PROVENANCE,
89+
models.CONFIG_BRANCH_RULES, models.CONFIG_GEN_PROVENANCE, models.CONFIG_TAG_RULES,
9490
},
9591
); err != nil {
9692
return fmt.Errorf("configuring controls: %w", err)
9793
}
9894

99-
// TODO(puerco): Compute the policy here
100-
_, err = t.impl.CreatePolicyPR(t.Authenticator, &t.Options, repo, nil)
101-
if err != nil {
102-
return fmt.Errorf("opening the policy pull request: %w", err)
103-
}
104-
10595
return nil
10696
}
10797

0 commit comments

Comments
 (0)