Skip to content

fix: Keep the public toggle on repository visibility rules - #4455

Merged
gmlewis merged 2 commits into
google:masterfrom
yordis:yordis/fix-repository-visibility-public
Aug 20, 2026
Merged

fix: Keep the public toggle on repository visibility rules#4455
gmlewis merged 2 commits into
google:masterfrom
yordis:yordis/fix-repository-visibility-public

Conversation

@yordis

@yordis yordis commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

RepositoryVisibilityRuleParameters models only internal and private, but the repository policy API has a third toggle, public. Because encoding/json discards unknown keys, the flag is lost on read, and since PUT /orgs/{org}/rulesets/{ruleset_id} is a full replace, writing back a ruleset the SDK just read silently resets public visibility to false.

Found while adding the repository ruleset target to the Terraform provider: integrations/terraform-provider-github#3598.

Verified against the live API

Against a real target: repository ruleset on a github.com organization on the Team plan, using a program that fetches the same ruleset twice: once over plain net/http to capture the wire bytes, and once through Organizations.GetRepositoryRuleset. Org name and ruleset ID redacted.

On v90.0.0:

1. raw HTTP body      {"public":false,"internal":true,"private":true}
2. after SDK decode   {"internal":true,"private":true}
3. struct value       {Internal:true Private:true}

The server sends the key and the SDK drops it. Since UpdateRepositoryRuleset is a full replace, a read-modify-write built from that value omits public and the API resolves it to false.

With this patch applied:

1. raw HTTP body      {"public":false,"internal":true,"private":true}
2. after SDK decode   {"internal":true,"private":true,"public":false}
3. struct value       {Internal:true Private:true Public:false}

Then a write round trip through Organizations.UpdateRepositoryRuleset, toggling only Public on the decoded struct:

--- write phase, original public=false ---
PUT public=true  -> raw GET {"public":true,"internal":true,"private":true}
PUT public=false -> raw GET {"public":false,"internal":true,"private":true}

The API accepts the field on write and echoes it back, and the "Restrict visibility" section of the org policy UI showed Public checked while it was true. After restoring, the full ruleset body diffed equal to a backup taken before the run, ignoring updated_at.

Verified in this repo

  • go build ./...
  • go test ./... -count=1
  • script/fmt.sh and script/lint.sh, including the generated-files check

github-accessors.go and github-accessors_test.go are regenerated output.

Test coverage added for the round trip: the repository_visibility cases in TestRepositoryRule now carry public: true in both the marshal and unmarshal tables, which fails without the struct field.

For context on why this was missed: repository_visibility does not appear anywhere in github/rest-api-description (zero matches in both api.github.com.json and ghec.json as of today), so there is no generated schema to check the field list against. The name and JSON shape used here come from the live responses above.

GitHub's repository policy API exposes a third visibility toggle, and dropping it on unmarshal silently revokes public visibility on any full-replace update built from a ruleset the SDK read back.

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
@alexandear

Copy link
Copy Markdown
Contributor

@yordis

yordis commented Aug 17, 2026

Copy link
Copy Markdown
Contributor Author

@alexandear what about it?

@codecov

codecov Bot commented Aug 19, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.51%. Comparing base (92c4fb9) to head (62032bb).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #4455   +/-   ##
=======================================
  Coverage   98.51%   98.51%           
=======================================
  Files         194      194           
  Lines       17603    17603           
=======================================
  Hits        17342    17342           
  Misses        261      261           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@gmlewis gmlewis changed the title fix(rules): keep the public toggle on repository visibility rules fix: Keep the public toggle on repository visibility rules Aug 19, 2026

@gmlewis gmlewis left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, @yordis!
LGTM.
Awaiting second LGTM+Approval from any other contributor to this repo before merging.

cc: @stevehipwell - @alexandear - @Not-Dhananjay-Mishra

@gmlewis gmlewis added the NeedsReview PR is awaiting a review before merging. label Aug 19, 2026
@yordis

yordis commented Aug 19, 2026

Copy link
Copy Markdown
Contributor Author

@gmlewis aye, let me know, as soon as this is merged, I will follow up on fixing the terraform provider, just so my paranoia is checked 😅

@stevehipwell stevehipwell left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@alexandear

Copy link
Copy Markdown
Contributor

@alexandear what about it?

Sorry, I should have been more specific. I was pointing at the "Assisted contributions" section:

Tools that help draft or generate code are allowed, but contributors remain responsible for understanding and testing every line they submit. If an AI/LLM tool helped with code, tests, or prose, briefly disclose what it did in the PR description. Review the rendered diff and description yourself before requesting review, remove irrelevant generated changes, and keep review comments specific and actionable.

The PR description reads as AI-assisted to me, and this is unnecessary:

image

If a tool helped here, could you add a oneline note about it? Not blocking the review - just keeping us consistent with the guideline.

@gmlewis gmlewis removed the NeedsReview PR is awaiting a review before merging. label Aug 20, 2026
@gmlewis

gmlewis commented Aug 20, 2026

Copy link
Copy Markdown
Collaborator

Thank you, @yordis, @stevehipwell, and @alexandear!
Merging.

@yordis - you can address @alexandear's comments after the merge.

@gmlewis
gmlewis merged commit 27fb78d into google:master Aug 20, 2026
15 checks passed
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.

4 participants