Skip to content

feat: Add support for organization rule suites - #4642

Merged
gmlewis merged 3 commits into
google:masterfrom
JamBalaya56562:feat/4641-org-rule-suites
Oct 19, 2026
Merged

gmlewis merged 3 commits into
google:masterfrom
JamBalaya56562:feat/4641-org-rule-suites

Conversation

@JamBalaya56562

@JamBalaya56562 JamBalaya56562 commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Fixes: #4641.
Closes: #4482.

Supersedes #4482 by @ralucas, which has been inactive since the review in late August. This builds on that implementation and addresses the open review comments. Thanks to @ralucas for the original work.

This adds the organization rule suites endpoints:

Method Endpoint
OrganizationsService.ListRuleSuites GET /orgs/{org}/rulesets/rule-suites
OrganizationsService.GetRuleSuite GET /orgs/{org}/rulesets/rule-suites/{rule_suite_id}

Changes from #4482, following the review there:

  • ListRuleSuitesOptions covers all of the documented query parameters (ref, repository_name, time_period, actor_name, rule_suite_result, evaluate_status) and embeds ListOptions for page and per_page.
  • The methods are named ListRuleSuites and GetRuleSuite, since Organization is redundant on OrganizationsService.
  • The file is named orgs_rule_suites.go.
  • The URLs are built with the usual u := fmt.Sprintf(...) / addOptions(u, opts) pattern.
  • The tests check the query parameters with testFormValues and the error paths with testBadOptions/testNewRequestAndDoFailure in the main test functions, and use referenceTimestamp.

RuleSuite, RuleEvaluation, and RuleEvaluationSource have every property of the rule-suites and rule-suite response schemas. The generated ListRuleSuitesIter iterator is included.

Following the review here, GetRuleSuite also takes a GetRuleSuiteOptions for the include_metadata query parameter, and RuleEvaluation.Metadata (RuleEvaluationMetadata) holds the pull request or required status checks metadata that it returns. Neither was in the OpenAPI description I originally checked against (fetched on 2026-10-13). RuleEvaluationProofOfPresence.VerifiedAt is a *string because the API sends "" until proof of presence is completed, which Timestamp cannot parse. The ListRuleSuitesOptions fields now document their allowed and default values.

The repository-level rule suites endpoints are still missing and can be added separately.

Verified locally: go build ./..., go vet -tags integration ./test/integration/, go test ./... (100% coverage of both methods and the iterator), generated files idempotent, script/metadata.sh check, and custom-gcl 0 issues.

@codecov

codecov Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.62%. Comparing base (fef0352) to head (e5bd200).

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #4642   +/-   ##
=======================================
  Coverage   98.61%   98.62%           
=======================================
  Files         199      200    +1     
  Lines       18694    18733   +39     
=======================================
+ Hits        18436    18475   +39     
  Misses        258      258           

☔ 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 added the NeedsReview PR is awaiting a review before merging. label Oct 17, 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, @JamBalaya56562!
LGTM.
Awaiting second LGTM+Approval from any other contributor to this repo before merging.

cc: @stevehipwell - @Not-Dhananjay-Mishra


// ListRuleSuitesOptions specifies the optional parameters to the
// OrganizationsService.ListRuleSuites method.
type ListRuleSuitesOptions struct {

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.

Could u please add comments specifying "can be" and "default" values?

time_period -

Default: day
Can be one of: hour, day, week, month

rule_suite_result -

Default: all
Can be one of: pass, fail, bypass, all

etc ...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks! Documented the allowed and default values of all ListRuleSuitesOptions fields in 36e0769. (That also caught a bad evaluate_status value in the test, now "evaluate".)

Comment thread github/orgs_rule_suites.go Outdated
// GitHub API docs: https://docs.github.com/rest/orgs/rule-suites?apiVersion=2022-11-28#get-an-organization-rule-suite
//
//meta:operation GET /orgs/{org}/rulesets/rule-suites/{rule_suite_id}
func (s *OrganizationsService) GetRuleSuite(ctx context.Context, org string, ruleSuiteID int64) (*RuleSuite, *Response, error) {

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.

This endpoint has one query parameter.

Image

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks — include_metadata was added to the description after I checked it. Added GetRuleSuiteOptions{IncludeMetadata bool} as a new opts parameter of GetRuleSuite in e5bd200.

Comment on lines +30 to +36
type RuleEvaluation struct {
RuleSource *RuleEvaluationSource `json:"rule_source,omitempty"`
Enforcement *string `json:"enforcement,omitempty"`
Result *string `json:"result,omitempty"`
RuleType *string `json:"rule_type,omitempty"`
Details *string `json:"details,omitempty"`
}

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.

This struct should also include a metadata field.

          "metadata": {
            "type": [
              "object",
              "null"
            ],
            "oneOf": [
              {
                "title": "Pull request rule suite metadata",
                "description": "Metadata for a pull request rule evaluation result.",
                "type": "object",
                "properties": {
                  "pull_request": {
                    "type": "object",
                    "description": "The pull request associated with the rule evaluation.",
                    "properties": {
                      "id": {
                        "type": "integer",
                        "description": "The unique identifier of the pull request."
                      },
                      "number": {
                        "type": "integer",
                        "description": "The number of the pull request."
                      },
                      "user": {
                        "type": "object",
                        "description": "The user who created the pull request.",
                        "properties": {
                          "id": {
                            "type": "integer",
                            "description": "The unique identifier of the user."
                          },
                          "login": {
                            "type": "string",
                            "description": "The handle for the GitHub user account."
                          },
                          "type": {
                            "type": "string",
                            "description": "The type of the user."
                          }
                        }
                      },
                      "reviews": {
                        "type": "array",
                        "description": "The reviews associated with the pull request.",
                        "items": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "integer",
                              "description": "The unique identifier of the review."
                            },
                            "user": {
                              "type": "object",
                              "description": "The user who submitted the review.",
                              "properties": {
                                "id": {
                                  "type": "integer",
                                  "description": "The unique identifier of the user."
                                },
                                "login": {
                                  "type": "string",
                                  "description": "The handle for the GitHub user account."
                                },
                                "type": {
                                  "type": "string",
                                  "description": "The type of the user."
                                }
                              }
                            },
                            "state": {
                              "type": "string",
                              "description": "The state of the review."
                            }
                          }
                        }
                      },
                      "proof_of_presence": {
                        "type": [
                          "object",
                          "null"
                        ],
                        "description": "The proof of presence evaluation for the pull request. Null if proof of presence was not evaluated.",
                        "properties": {
                          "state": {
                            "type": "string",
                            "description": "The state of the proof of presence evaluation."
                          },
                          "code": {
                            "type": "string",
                            "description": "A code describing the reason for the proof of presence state."
                          },
                          "base_sha": {
                            "type": "string",
                            "description": "The base commit SHA the proof of presence evaluation applies to. Empty if unavailable."
                          },
                          "head_sha": {
                            "type": "string",
                            "description": "The head commit SHA the proof of presence evaluation applies to. Empty if unavailable."
                          },
                          "required_level": {
                            "type": "string",
                            "description": "The authentication level required by the rule. Empty if unavailable."
                          },
                          "verified_level": {
                            "type": "string",
                            "description": "The authentication level that was verified. Empty if proof of presence has not been completed."
                          },
                          "verified_at": {
                            "type": "string",
                            "description": "The time proof of presence was verified, in ISO 8601 format. Empty if proof of presence has not been completed."
                          },
                          "verifier": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "description": "The user who provided proof of presence. Null if no proof of presence was recorded.",
                            "properties": {
                              "id": {
                                "type": "integer",
                                "description": "The unique identifier of the user."
                              },
                              "login": {
                                "type": "string",
                                "description": "The handle for the GitHub user account."
                              },
                              "type": {
                                "type": "string",
                                "description": "The type of the user."
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              },
              {
                "title": "Required status checks rule suite metadata",
                "description": "Metadata for a required status checks rule evaluation result.",
                "type": "object",
                "properties": {
                  "checks": {
                    "type": "array",
                    "description": "The status checks associated with the rule evaluation.",
                    "items": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "integer",
                          "description": "The unique identifier of the status check."
                        },
                        "context": {
                          "type": "string",
                          "description": "The context name of the status check."
                        },
                        "state": {
                          "type": "string",
                          "description": "The state of the status check."
                        },
                        "type": {
                          "type": "string",
                          "description": "The type of the status check."
                        },
                        "app": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "The GitHub App associated with the status check.",
                          "properties": {
                            "id": {
                              "type": "integer",
                              "description": "The unique identifier of the GitHub App."
                            },
                            "slug": {
                              "type": "string",
                              "description": "The slug of the GitHub App."
                            },
                            "name": {
                              "type": "string",
                              "description": "The name of the GitHub App."
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            ],
            "description": "Additional metadata about the rule evaluation."
          },

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added in e5bd200 as RuleEvaluation.Metadata. The two oneOf branches have disjoint keys, so RuleEvaluationMetadata holds both PullRequest and Checks. verified_at is a *string rather than *Timestamp because the API sends "" until proof of presence is completed, which Timestamp cannot parse.

@Not-Dhananjay-Mishra Not-Dhananjay-Mishra 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

@gmlewis

gmlewis commented Oct 19, 2026

Copy link
Copy Markdown
Collaborator

Thank you, @Not-Dhananjay-Mishra!
Merging.

@gmlewis gmlewis removed the NeedsReview PR is awaiting a review before merging. label Oct 19, 2026
@gmlewis
gmlewis merged commit 909deb8 into google:master Oct 19, 2026
15 checks passed
@JamBalaya56562
JamBalaya56562 deleted the feat/4641-org-rule-suites branch October 19, 2026 12:54
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.

Add support for organization rule suites

3 participants