From 5695bf6cfe406d84b514310b23bf9b2dcd5caec2 Mon Sep 17 00:00:00 2001 From: Silvan Mosberger Date: Fri, 4 Oct 2024 01:50:36 +0200 Subject: [PATCH] ci: Add codeowners validator --- ci/codeowners-validator/default.nix | 31 ++++++++++++++++ .../owners-file-name.patch | 15 ++++++++ ci/codeowners-validator/permissions.patch | 36 +++++++++++++++++++ ci/default.nix | 1 + 4 files changed, 83 insertions(+) create mode 100644 ci/codeowners-validator/default.nix create mode 100644 ci/codeowners-validator/owners-file-name.patch create mode 100644 ci/codeowners-validator/permissions.patch diff --git a/ci/codeowners-validator/default.nix b/ci/codeowners-validator/default.nix new file mode 100644 index 000000000000..5c2d5335c35e --- /dev/null +++ b/ci/codeowners-validator/default.nix @@ -0,0 +1,31 @@ +{ + buildGoModule, + fetchFromGitHub, + fetchpatch, +}: +buildGoModule { + name = "codeowners-validator"; + src = fetchFromGitHub { + owner = "mszostok"; + repo = "codeowners-validator"; + rev = "f3651e3810802a37bd965e6a9a7210728179d076"; + hash = "sha256-5aSmmRTsOuPcVLWfDF6EBz+6+/Qpbj66udAmi1CLmWQ="; + }; + patches = [ + # https://github.com/mszostok/codeowners-validator/pull/222 + (fetchpatch { + name = "user-write-access-check"; + url = "https://github.com/mszostok/codeowners-validator/compare/f3651e3810802a37bd965e6a9a7210728179d076...840eeb88b4da92bda3e13c838f67f6540b9e8529.patch"; + hash = "sha256-t3Dtt8SP9nbO3gBrM0nRE7+G6N/ZIaczDyVHYAG/6mU="; + }) + # Undoes part of the above PR: We don't want to require write access + # to the repository, that's only needed for GitHub's native CODEOWNERS. + # Furthermore, it removes an unneccessary check from the code + # that breaks tokens generated for GitHub Apps. + ./permissions.patch + # Allows setting a custom CODEOWNERS path using the OWNERS_FILE env var + ./owners-file-name.patch + ]; + postPatch = "rm -r docs/investigation"; + vendorHash = "sha256-R+pW3xcfpkTRqfS2ETVOwG8PZr0iH5ewroiF7u8hcYI="; +} diff --git a/ci/codeowners-validator/owners-file-name.patch b/ci/codeowners-validator/owners-file-name.patch new file mode 100644 index 000000000000..d8b87ba2f84a --- /dev/null +++ b/ci/codeowners-validator/owners-file-name.patch @@ -0,0 +1,15 @@ +diff --git a/pkg/codeowners/owners.go b/pkg/codeowners/owners.go +index 6910bd2..e0c95e9 100644 +--- a/pkg/codeowners/owners.go ++++ b/pkg/codeowners/owners.go +@@ -39,6 +39,10 @@ func NewFromPath(repoPath string) ([]Entry, error) { + // openCodeownersFile finds a CODEOWNERS file and returns content. + // see: https://help.github.com/articles/about-code-owners/#codeowners-file-location + func openCodeownersFile(dir string) (io.Reader, error) { ++ if file, ok := os.LookupEnv("OWNERS_FILE"); ok { ++ return fs.Open(file) ++ } ++ + var detectedFiles []string + for _, p := range []string{".", "docs", ".github"} { + pth := path.Join(dir, p) diff --git a/ci/codeowners-validator/permissions.patch b/ci/codeowners-validator/permissions.patch new file mode 100644 index 000000000000..38f42f483995 --- /dev/null +++ b/ci/codeowners-validator/permissions.patch @@ -0,0 +1,36 @@ +diff --git a/internal/check/valid_owner.go b/internal/check/valid_owner.go +index a264bcc..610eda8 100644 +--- a/internal/check/valid_owner.go ++++ b/internal/check/valid_owner.go +@@ -16,7 +16,6 @@ import ( + const scopeHeader = "X-OAuth-Scopes" + + var reqScopes = map[github.Scope]struct{}{ +- github.ScopeReadOrg: {}, + } + + type ValidOwnerConfig struct { +@@ -223,10 +222,7 @@ func (v *ValidOwner) validateTeam(ctx context.Context, name string) *validateErr + for _, t := range v.repoTeams { + // GitHub normalizes name before comparison + if strings.EqualFold(t.GetSlug(), team) { +- if t.Permissions["push"] { +- return nil +- } +- return newValidateError("Team %q cannot review PRs on %q as neither it nor any parent team has write permissions.", team, v.orgRepoName) ++ return nil + } + } + +@@ -245,10 +241,7 @@ func (v *ValidOwner) validateGitHubUser(ctx context.Context, name string) *valid + for _, u := range v.repoUsers { + // GitHub normalizes name before comparison + if strings.EqualFold(u.GetLogin(), userName) { +- if u.Permissions["push"] { +- return nil +- } +- return newValidateError("User %q cannot review PRs on %q as they don't have write permissions.", userName, v.orgRepoName) ++ return nil + } + } + diff --git a/ci/default.nix b/ci/default.nix index 8a4341048f67..02b2e948d17b 100644 --- a/ci/default.nix +++ b/ci/default.nix @@ -25,4 +25,5 @@ in { inherit pkgs; requestReviews = pkgs.callPackage ./request-reviews { }; + codeownersValidator = pkgs.callPackage ./codeowners-validator { }; }