Skip to content

Warn early on repos whose plan does not support branch rules#395

Open
arpitjain099 wants to merge 2 commits into
slsa-framework:mainfrom
arpitjain099:fix/warn-unsupported-private-repo
Open

Warn early on repos whose plan does not support branch rules#395
arpitjain099 wants to merge 2 commits into
slsa-framework:mainfrom
arpitjain099:fix/warn-unsupported-private-repo

Conversation

@arpitjain099
Copy link
Copy Markdown

Running sourcetool setup or sourcetool status against a private repository on a free GitHub plan crashes with the raw GitHub API error:

Error: configuring controls: creating policy for: getting branch controls: checking status: GET https://api.github.com/repos/.../rules/branches/main: 403 Upgrade to GitHub Pro or make this repository public to enable this feature. []

The 403 comes from reading the branch rulesets, which that plan does not expose, and it bubbles up as an opaque wrapped error after onboarding has already started.

This change detects that case and warns about it clearly before doing anything to the repository.

What it does:

  • Adds an ErrUnsupportedRepoPlan sentinel in the models package, next to the existing ErrRepositoryAccessDenied / ErrProtectionAlreadyInPlace errors.
  • Detects the 403 with a typed check (errors.As to *github.ErrorResponse and Response.StatusCode == http.StatusForbidden) instead of matching on the message text, so it keeps working if GitHub rewords the response. The GitHub backend converts that 403 into the sentinel.
  • Reads the current controls up front in the onboard flow, so for setup repo the warning is raised before any mutating call (ConfigureControls is never reached). status and setup controls already hit the control read first.
  • setup and status now print an actionable message: make the repository public, or move its account to a plan that includes repository rules (GitHub Pro or higher).

Testing:

  • A unit test on the typed detector (asUnsupportedPlanError) covers a plain 403, a wrapped 403, a 404, a non-GitHub error, and a 403 with no HTTP response attached, and confirms both the sentinel and the original API error stay reachable through errors.Is.
  • A tool-level test reproduces the onboarding case and asserts the flow returns ErrUnsupportedRepoPlan and does not call the backend ConfigureControls, so nothing is mutated after the warning.
  • go test ./pkg/sourcetool/... ./internal/cmd/... passes, gofmt -l is clean, and go vet ./... is clean.

Note: I could not exercise this end to end against a real private free-plan repo, so the message wording is open to adjustment if you would phrase the remediation differently.

Fixes #326

setup and status crash with a raw GitHub 403 ('Upgrade to GitHub Pro or
make this repository public') when run against a private repo on a free
plan. The 403 comes from reading branch rulesets and is surfaced as an
opaque wrapped error.

Detect that 403 with a typed check (errors.As to *github.ErrorResponse,
StatusCode 403) rather than string matching, convert it to a new
ErrUnsupportedRepoPlan sentinel, and read the controls up front in the
onboard flow so the warning is printed before any mutation. setup and
status now print an actionable message telling the user to make the repo
public or upgrade the plan.

Fixes slsa-framework#326

Signed-off-by: Arpit Jain <arpitjain099@gmail.com>
@puerco
Copy link
Copy Markdown
Member

puerco commented Jun 4, 2026

@arpitjain099 Thanks for the PR there is a minor nit error which should be easy to fix.

I am in the middle of migrating sourcetool to the latest go-github release which will be a large diff, if you fix this the merge conflict will be easier for me I think.

Address the two lint findings flagged on this branch:

- status.go: drop the trailing period from the unsupportedRepoPlanError
  message so it satisfies staticcheck ST1005 (error strings should not
  end with punctuation).
- github_test.go: use require.NoError instead of require.Nil for the
  nil-error assertion, per testifylint error-nil.

Signed-off-by: Arpit Jain <arpitjain099@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Warn early on unsupported repos

2 participants