Coder Social home page Coder Social logo

mszostok / codeowners-validator Goto Github PK

View Code? Open in Web Editor NEW
204.0 5.0 48.0 3.67 MB

The GitHub CODEOWNERS file validator

License: Apache License 2.0

Go 82.36% Shell 15.98% Dockerfile 0.53% Makefile 1.14%
codeowners validator go checker github github-action github-codeowners codeowners-validator hacktoberfest golang

codeowners-validator's Introduction



logo

Ensures the correctness of your CODEOWNERS file.





Codeowners Validator

Software License Go Report Card Twitter Follow

The Codeowners Validator project validates the GitHub CODEOWNERS file based on specified checks. It supports public and private GitHub repositories and also GitHub Enterprise installations.

usage

Usage

Docker

export GH_TOKEN=<your_token>
docker run --rm -v $(pwd):/repo -w /repo \
  -e REPOSITORY_PATH="." \
  -e GITHUB_ACCESS_TOKEN="$GH_TOKEN" \
  -e EXPERIMENTAL_CHECKS="notowned" \
  -e OWNER_CHECKER_REPOSITORY="org-name/rep-name" \
  mszostok/codeowners-validator:v0.7.4

Command line

export GH_TOKEN=<your_token>
env REPOSITORY_PATH="." \
    GITHUB_ACCESS_TOKEN="$GH_TOKEN" \
    EXPERIMENTAL_CHECKS="notowned" \
    OWNER_CHECKER_REPOSITORY="org-name/rep-name" \
  codeowners-validator

GitHub Action

- uses: mszostok/[email protected]
  with:
    checks: "files,owners,duppatterns,syntax"
    experimental_checks: "notowned,avoid-shadowing"
    # GitHub access token is required only if the `owners` check is enabled
    github_access_token: "${{ secrets.OWNERS_VALIDATOR_GITHUB_SECRET }}"

Check this document for more information about GitHub Action.


Check the Configuration section for more info on how to enable and configure given checks.

Installation

It's highly recommended to install a fixed version of codeowners-validator. Releases are available on the releases page.

macOS & Linux

codeowners-validator is available via Homebrew.

Homebrew

Install Upgrade
brew install mszostok/tap/codeowners-validator brew upgrade mszostok/tap/codeowners-validator

Install script

# binary installed into ./bin/
curl -sfL https://raw.githubusercontent.com/mszostok/codeowners-validator/main/install.sh | sh -s v0.7.4

# binary installed into $(go env GOPATH)/bin/codeowners-validator
curl -sfL https://raw.githubusercontent.com/mszostok/codeowners-validator/main/install.sh | sh -s -- -b $(go env GOPATH)/bin v0.7.4

# In alpine linux (as it does not come with curl by default)
wget -O - -q https://raw.githubusercontent.com/mszostok/codeowners-validator/main/install.sh | sh -s v0.7.4

# Print version. Add `--oshort` to print just the version number.
codeowners-validator version

You can also download latest version from release page manually.

From Sources

You can install codeowners-validator with go install github.com/mszostok/[email protected].

NOTE: please use Go 1.16 or greater.

This will put codeowners-validator in $(go env GOPATH)/bin.

Checks

The following checks are enabled by default:

Name Description
duppatterns [Duplicated Pattern Checker]

Reports if CODEOWNERS file contain duplicated lines with the same file pattern.
files [File Exist Checker]

Reports if CODEOWNERS file contain lines with the file pattern that do not exist in a given repository.
owners [Valid Owner Checker]

Reports if CODEOWNERS file contain invalid owners definition. Allowed owner syntax: @username, @org/team-name or [email protected]
source: https://help.github.com/articles/about-code-owners/#codeowners-syntax.

Checks:
    1. Check if the owner's definition is valid (is either a GitHub user name, an organization team name or an email address).

    2. Check if a GitHub owner has a GitHub account

    3. Check if a GitHub owner is in a given organization

    4. Check if an organization team exists
syntax [Valid Syntax Checker]

Reports if CODEOWNERS file contain invalid syntax definition. It is imported as:
    "If any line in your CODEOWNERS file contains invalid syntax, the file will not be detected
    and will not be used to request reviews. Invalid syntax includes inline comments
    and user or team names that do not exist on GitHub."

source: https://help.github.com/articles/about-code-owners/#codeowners-syntax.

The experimental checks are disabled by default:

Name Description
notowned [Not Owned File Checker]

Reports if a given repository contain files that do not have specified owners in CODEOWNERS file.
avoid-shadowing [Avoid Shadowing Checker]

Reports if entries go from least specific to most specific. Otherwise, earlier entries are completely ignored.

For example:
     # First entry
     /build/logs/ @octocat
     # Shadows
     * @s1
     /b*/logs @s5
     # OK
     /b*/other @o1
     /script/* @o2

To enable experimental check set EXPERIMENTAL_CHECKS=notowned environment variable.

Check the Configuration section for more info on how to enable and configure given checks.

Configuration

Use the following environment variables to configure the application:

Name Default Description
REPOSITORY_PATH * Path to your repository on your local machine.
GITHUB_ACCESS_TOKEN GitHub access token. Instruction for creating a token can be found here. If not provided, the owners validating functionality may not work properly. For example, you may reach the API calls quota or, if you are setting GitHub Enterprise base URL, an unauthorized error may occur.
GITHUB_BASE_URL https://api.github.com/ GitHub base URL for API requests. Defaults to the public GitHub API but can be set to a domain endpoint to use with GitHub Enterprise.
GITHUB_UPLOAD_URL https://uploads.github.com/ GitHub upload URL for uploading files.

It is taken into account only when GITHUB_BASE_URL is also set. If only GITHUB_BASE_URL is provided, this parameter defaults to the GITHUB_BASE_URL value.
GITHUB_APP_ID Github App ID for authentication. This replaces the GITHUB_ACCESS_TOKEN. Instruction for creating a Github App can be found here
GITHUB_APP_INSTALLATION_ID Github App Installation ID. Required when GITHUB_APP_ID is set.
GITHUB_APP_PRIVATE_KEY Github App private key in PEM format. Required when GITHUB_APP_ID is set.
CHECKS List of checks to be executed. By default, all checks are executed. Possible values: files,owners,duppatterns,syntax.
EXPERIMENTAL_CHECKS The comma-separated list of experimental checks that should be executed. By default, all experimental checks are turned off. Possible values: notowned.
CHECK_FAILURE_LEVEL warning Defines the level on which the application should treat check issues as failures. Defaults to warning, which treats both errors and warnings as failures, and exits with error code 3. Possible values are error and warning.
OWNER_CHECKER_REPOSITORY * The owner and repository name separated by slash. For example, gh-codeowners/codeowners-samples. Used to check if GitHub owner is in the given organization.
OWNER_CHECKER_IGNORED_OWNERS @ghost The comma-separated list of owners that should not be validated. Example: "@owner1,@owner2,@org/team1,[email protected]".
OWNER_CHECKER_ALLOW_UNOWNED_PATTERNS true Specifies whether CODEOWNERS may have unowned files. For example:

/infra/oncall-rotator/ @sre-team
/infra/oncall-rotator/oncall-config.yml

The /infra/oncall-rotator/oncall-config.yml file is not owned by anyone.
OWNER_CHECKER_OWNERS_MUST_BE_TEAMS false Specifies whether only teams are allowed as owners of files.
NOT_OWNED_CHECKER_SKIP_PATTERNS The comma-separated list of patterns that should be ignored by not-owned-checker. For example, you can specify * and as a result, the * pattern from the CODEOWNERS file will be ignored and files owned by this pattern will be reported as unowned unless a later specific pattern will match that path. It's useful because often we have default owners entry at the begging of the CODOEWNERS file, e.g. * @global-owner1 @global-owner2
NOT_OWNED_CHECKER_SUBDIRECTORIES The comma-separated list of subdirectories to check in not-owned-checker. When specified, only files in the listed subdirectories will be checked if they do not have specified owners in CODEOWNERS.
NOT_OWNED_CHECKER_TRUST_WORKSPACE false Specifies whether the repository path should be marked as safe. See: actions/checkout#766.

* - Required

Exit status codes

Application exits with different status codes which allow you to easily distinguish between error categories.

Code Description
1 The application startup failed due to the wrong configuration or internal error.
2 The application was closed because the OS sends a termination signal (SIGINT or SIGTERM).
3 The CODEOWNERS validation failed - executed checks found some issues.

Contributing

Contributions are greatly appreciated! The project follows the typical GitHub pull request model. See CONTRIBUTING.md for more details.

Roadmap

The codeowners-validator roadmap uses GitHub milestones to track the progress of the project.

They are sorted with priority. First are most important.

codeowners-validator's People

Contributors

athtran avatar dependabot[bot] avatar highb avatar jhump avatar jsoref avatar jspiro avatar julienduchesne avatar knl avatar kyleellman avatar lukasz-mitka avatar majakurcius avatar miguelslemos avatar mszostok avatar njegosrailic avatar rmax avatar seveas avatar sgmitchell avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

codeowners-validator's Issues

notowned with an empty codeowners file

Description

Using version 0.7.1 with an empty CODEOWNERS file and setting experimental_checks: notowned displays an error and it does not fail the execution (see Actual result for the error message).

Expected result

If there is an error, the validator should fail with non zero exit code

Actual result

time="2022-02-27T09:21:01Z" level=error msg="while executing checker [Experimental] Not Owned File Checker: 1 error occurred:\n\t* fatal: No pathspec was given. Which files should I remove?\n: command \"xargs\": exit status 123\n\n" service="check:runner"

Steps to reproduce

Use the same setup as #121 with an empty CODEOWNERS file.

Troubleshooting

  • Used the same setup with a CODEOWNERS with a single line * @org/team and the error did not appear

Possibility to execute `codeowners-validator` online

Description

Possibility to execute codeowners-validator online.

Automatically integrates with your GitHub account and allows you to check any repository online without the need to download and execute binary locally.

This is a nice way to show features of this tool to potential clients.

Document what permissions are needed for a PAT

Description

The documentation doesn't explain very well what permissions you need to grant a Personal Access Token in order to have it work with your tool. More specific documentation around what permissions need to be granted, perhaps with a screenshot of the checkboxes, would be ideal.

Reasons

When it errors, it does not specify what permissions are needed, so remediating this becomes a process of trial-and-error to add more permissions to a token than is probably necessary, just to have it be able to pass one of the checks.

Try to move from API Rest calls to GraphQL call.

Description

Currently, we are using the API Rest calls to check if defined owners are the valid ones. This generated the problem with a lot of requests. GitHub expose also the GraphQL to call their apis. We need to investigate if they expose their functionality. If yes, that we can switch to graphql call to significantly reduce the number of calls.

Console to test GraphQL: https://developer.github.com/v4/explorer/

Acceptance Criteria

  • reduce the number of GitHub API calls

Add example showcase recorded by asciinema

Description

Currently, in the README.md there is only the screenshot of the codeowners-validator execution. It does not show the underlying envs and cloning action. The full showcase should be recorded by asciinema or posted as some GIF.

Validation doesn't fail on invalid syntax with EOL comments

Description

If CODEOWNERS file contains a comment towards the end of the line, the validator doesn't flag it as invalid. In case of such comments, GitHub will skip the rest of the file.

Example:

# This comment is ok
* @someorg/someteam  # this comment is a syntax error

Expected result

I would expect the above snippet to be marked as problematic.

Actual result

env REPOSITORY_PATH="." OWNER_CHECKER_REPOSITORY="someorg/somerepo" CHECKS="files,duppatterns" $(go env GOPATH)/bin/codeowners-validator
==> Executing Duplicated Pattern Checker (30.265µs)
    Check OK
==> Executing File Exist Checker (40.374µs)
    Check OK

Note that I'm not using owners check, as it is not clear what kind of right are needed for the token (but that is a separate issue).

Steps to reproduce

Write a comment after a correct line (so that # is not the first character in the line).

Troubleshooting

Add test coverage to internal pkg

Description

Currently, only the pkg package has full test coverage. The internal pkg also should be full-tested. The coverage reports should be generated and reported on some external services that we do not have to manage.

Choose one of the following services:

Acceptance Criteria

  • test coverage for internal pkg to never regress, and ensure that the contract will not be broken in the future releases
  • publish report coverage on external platform
  • integration tests against the real organization

Periodically validate if GitHub is case-insensitive for teams and orgs names

Description

We don't have access to GitHub code, which is responsible for assigning owners. As a result, we need to create yet another e2e test that will be executed periodically to:

  • Create a sample PR against files where @GiTHubCodeOwners/A-TeAm is specified and check whether GitHub is still case-insensitive and assigns @GitHubCodeowners/a-team properly.

Reasons

Ensure that validator matches GitHub behavior and doesn't produce false positives.

Redesing the codeowners documentation

Description

Currently, most of the validator documentation is placed in main README.md file. This makes it hard to read and check which sections are described.

In this task documentation should be split to a dedicated .md files. The ToC in /docs folder should be updated.

Scratch: expose documentation using some static state generator, e.g.:

Reasons

It needs to be more readable to the user. Necessary information should be available in easy way.

Validate that only a single CODEOWNERS file exists in the repository

Description

As you know Github documents that the CODEOWNERS file to be placed in the root, docs/, or .github/ directory of the repository.

It however does not state anything pertaining to whether multiple CODEOWNERS files exist.

What I have observed is that on Github CODEOWNERS is looked for in .github/ -> docs/ -> root order. However codeowners-validator prioritizes it in the reverse order.

We use Github's protected-branch logic that requires reviews from code owners, in order to ensure that owners are required to approve of changes to their code. However, we have realized that should an additional CODEOWNERS file get committed to a project, it could subvert that incidentally and be a source of future confusion.

Reasons

While the order preference of the possible file locations could be updated - I think it would be preferable to validate against the case of multiple CODEOWNERS files altogether.

There isn't any valid use-case for multiple CODEOWNERS files, and having codeowners-validator continue to be the sole point of CODEOWNERS related validation in our Github CI would be ideal.

I'm looking to see if there is positive reception to having this kind of validation added to the project - if so, I can see about creating a PR to do so.

invalid email addresses are an error

Hi,
I tried this tool out and it seems cool. But it seems like github treats a file with an invalid email address in it as an invalid file, which this didn't seem to catch.

/projects/foo foo@bar

instead of

/projects/foo [email protected]

would not work.

Just wanted to let you know in case you wanted to add in a check for that.

410 Gone from reading https://sum.golang.org/lookup/github.com/mszostok/[email protected]

Can't go get -u github.com/mszostok/codeowners-validator as of v0.5.0

~/src/mn/projects/fullstory go get -u github.com/mszostok/codeowners-validator
go: finding github.com/mszostok/codeowners-validator v0.5.1
go: finding github.com/mszostok/codeowners-validator v0.5.1
verifying github.com/mszostok/[email protected]/go.mod: github.com/mszostok/[email protected]/go.mod: reading https://sum.golang.org/lookup/github.com/mszostok/[email protected]: 410 Gone

Directly hitting https://sum.golang.org/lookup/github.com/mszostok/[email protected]

not found: create zip: malformed file path "internal/printer/testdata/TestTTYPrinterPrintSummary/Should_print_'no'_when_there_is_no_failures.golden.txt": invalid char '\''

It seems that sum.golang.org doesn't like this package right now. The last one I can actually pull is v0.4.0
Unsure whether this is a bug with sum.golang.org or not.

Option to disable Check if a GitHub owner is in a given organization

Description

Please provide an option to disable only the "Check if a GitHub owner is in a given organization" part of the Valid Owner Checker.

Reasons

I frequently work in repos that have an outside collaborator as a Code Owner (sometimes it is me). I would like to be able to keep the other checks in the Valid Owner Checker active and disable only the "Check if a GitHub owner is in a given organization" part. It is excessive to completely disable all checks for outside collaborators.

Gitlab API support for owners check

Description
For owners checks using your CLI, it'd be great if we can specify whether it is for a gitlab or github repository. I'm looking for an equivalent validator for gitlab that supports the checks mentioned in your repo -

1. Check if the owner's definition is valid (is either a GitHub user name, an organization team name or an email address).

2. Check if a GitHub owner has a GitHub account

3. Check if a GitHub owner is in a given organization

4. Check if an organization team exists

Reasons

  • There's no good gitlab alternative like this package
  • Efforts wise it should not be hard to integrate a gitlab client like gitbeaker

Add native support for pre-commit hook

Description

The native support for pre-commit hook was requested by external users.

To integrate with https://pre-commit.com/ the .pre-commit-hooks.yaml file needs to be added to the root for repository.

Example:

- id: codeowners-validator-docker
  name: Validate CODEOWNERS file
  description: Ensures the correctness of your CODEOWNERS file.
  language: docker_image
  # TODO: types: hardcode expected file location?
  entry:  ghcr.io/mszostok/codeowners-validator:stable
- id: codeowners-validator
  name: Validate CODEOWNERS file
  description: Ensures the correctness of your CODEOWNERS file.
  language: golang
  # TODO: types: hardcode expected file location?
  entry: codeowners-validator

To support the input parameters, the codeowners-validator CLI should accept flags or config file.

Reasons

Support https://pre-commit.com/ out of the box to simplify external user workflow.

Validation fails on files with escaped spaces

Description

Our repository includes many files that have spaces in them. GitHub allows spaces in paths in CODEOWNER files but requires them to be escaped with \. A valid CODEOWNER file path like /Testing/Path\ With\ Space.cs shows the correct CODEOWNER in GitHub but our mszostok/[email protected] GitHub Action fails with the message

==> Executing Valid Syntax Checker
    [err] line 13: Owner 'With\' does not look like an email
    [err] line 13: Owner 'Space.cs' does not look like an email

If there are multiple lines in the CODEOWNER file like

/Testing/Path\ With\ Space.cs    @ian-azyra
/Testing/Path\ With\ More\ Spaces.cs    @ian-azyra

The GitHub Action also states

==> Executing Duplicated Pattern Checker
    [err] Pattern "/Testing/Path\\" is defined 2 times in lines:
        * 13: with owners: [With\ Space.cs @ian-azyra]
        * 14: with owners: [With\ More\ Spaces.cs @ian-azyra]

The following checks also fail

==> Executing File Exist Checker
    [err] line 13: "/Testing/Path\\" does not match any files in repository
    [err] line 14: "/Testing/Path\\" does not match any files in repository

==> Executing Valid Owner Checker
    [err] line 13: Not valid owner definition "With\\"
    [err] line 13: Not valid owner definition "Space.cs"
    [err] line 14: Not valid owner definition "With\\"
    [err] line 14: Not valid owner definition "More\\"
    [err] line 14: Not valid owner definition "Spaces.prg"

Expected result

I would expect file patterns with properly escaped spaces to pass all tests. File paths without escaped spaces should fail.

Actual result

The checks above all fail because they don't recognise the \ character as an escape character.

Steps to reproduce

To reproduce the bug

  1. Create a GitHub Action based on the example in this repository
  2. Create a file path with spaces in a test repository
  3. Add a CODEOWNERS file with a file path that has spaces properly escaped
  4. Run the GitHub Action and it should fail
  5. The code owners displayed on GitHub accept the escaped file

Troubleshooting

For the moment, I have used /Testing/Path*.cs but this isn't granular enough for our repository.

Add examples how to use codeowners-validator on CI

Description
We need to document the examples how to execute the codeowners-validator check on different CI systems (the most popular):

  • TravisCI,
  • CircleCI,
  • Prow,
  • GitHub Actions

Acceptance Criteria

  • Documentation is updated with the copy-paste examples

Verify code owners against a set list of owners?

Hi @mszostok,

This action is quite useful for us, thanks!
I had question, can we verify/validate the code owners present in the CODEOWNERS file against against a set list of users.
I was not able to find such a feature in the documentation.

Thanks

Valid Owner Checker should report if the owner doesn't have Write access

Currently, the Valid Owner Checker performs the following checks:

1. Check if the owner's definition is valid (is either a GitHub user name, an organization team name or an email address).

2. Check if a GitHub owner has a GitHub account

3. Check if a GitHub owner is in a given organization

4. Check if an organization team exists

In Step 3, instead of checking whether the owner is a member of the organization, the Valid Owner Checker should check whether the owner has Write or Admin access to the repository.

Reasons

This is consistent with the native GitHub codeowners validation check that appears in the GitHub web interface. Only a code owner with Write access or greater can approve PRs: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/approving-a-pull-request-with-required-reviews

This change would lead the codeowners validator status check to report failure under the following scenarios, consistent with the native validation check:

  1. A code owner is added who does not have access, or who only has Read access
  2. A code owner's access is removed (explicitly or when their team membership is changed)

In the GitHub native codeowners validator, each of these would result in the following error:

image

Clicking the ellipsis shows more details about the error.

image

[Valid Owner Checker] Make the ignored owners configurable

Description

As a part of #52 issue, there was an interesting problem regarding the @ghost user which was solved by #53. This issue is about making implemented logic a little more generic and instead of hard-coding the @ghost username, it would be better to export the option which takes a list of owners e.g. users, teams, etc. that should be ignored by Valid Owner Checker.

Reasons

It's always better to have customizable logic in the library which is used by the broader community, so we can handle more custom scenarios :)

TODO

  1. Add IgnoreOwners []string `envconfig:"default=@ghost"` property in line 15 in file internal/check/valid_owner.go. In this way, this property can be automatically set by environment variable OWNER_CHECKER_IGNORE_OWNERS which can be populated with a list of owners names that should be ignored and not validated e.g. "@user,@org/team1,@ghost"

  2. In constructor NewValidOwner handle new cfg property and provide a func shouldIgnoreGitHubOwner(name) which can be used in for _, ownerName := range entry.Owners loop in line 63:

			if v.shouldIgnoreGitHubOwner(ownerName) {
				continue
			}
  1. Update README.md and describe a new environment variable OWNER_CHECKER_IGNORE_OWNERS which can be used

  2. Update action.yml with new property

Document which scopes are needed for owners verification

Description

Consider documenting which scopes are needed for the github action to validate owner teams. This may actually also be a bug report for the action

Reasons

It's not currently documented and it's not clear to me which ones should be selected.

In fact, the URL it's trying doesn't appear correct to me 🤔

https://api.github.com/repos/<org>/<repo>/teams?per_page=100

Shouldn't this use the org/teams endpoint? https://docs.github.com/en/free-pro-team@latest/rest/reference/teams#list-teams

https://api.github.com/orgs/<org>/teams

Document how to configure GitHub action

Description

We have multiple outside contributors added to a github org repo. The github org does not contain the outside contributors and so complains even tho we have OWNER_CHECKER_IGNORED_OWNERS set.

Expected result

It should ignore the users that are outside contributors.

Actual result

==> Executing Valid Owner Checker (1.05608306s)
    [err] line 19: User "@user1" is not a member of the organization
    [err] line 19: User "@user2" is not a member of the organization
    [err] line 19: User "@user3" is not a member of the organization

Steps to reproduce

.github/CODEOWNERS

* @user1 @user2 @user3 @githuborg/otherteam

.github/workflows/validate-codeowners.yml

name: Validate Codeowners
on:
  pull_request:

jobs:
  validate-codeowners:
    runs-on: ubuntu-latest
    env:
      OWNER_CHECKER_IGNORED_OWNERS: "@user1,@user2,@user3"
    steps:
    - name: "Checkout source code at current commit"
      uses: actions/checkout@v2
    - uses: mszostok/[email protected]
      with:
        checks: "syntax,owners,duppatterns"
        github_access_token: "${{ secrets.CODE_OWNER_VALIDATION }}"

Troubleshooting

Tried OWNER_CHECKER_IGNORED_OWNERS

What are some ways around this besides disabling the owners check ?

Move from dep to go modules

Description

The go modules becomes the standard package manager. We need to move to this solution to be up to date with the Go ecosystem.

Syntax Checker errors with "missing owner" on valid CODEOWNERS

Description

It's totally valid to list a directory/file/pattern and leave off an owner as a way of specifying "no owner".
See the docs: https://github.com/github/docs/blob/209c340039acc4c2f73c2eb1fcd607af00911118/content/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners.md#L103

# In this example, @octocat owns any file in the `/apps` 
# directory in the root of your repository except for the `/apps/github` 
# subdirectory, as its owners are left empty.
/apps/ @octocat
/apps/github 

Notice the last line has no owner.

Expected result

No error when leaving off owner.

Actual result

Error 😞

Steps to reproduce

Run the tool on a CODEOWNERS file which leaves off the owner

Troubleshooting

Syntax checker doesn't capture parse error due to tilde (~) in paths

Description

It's rare, but can still happen, that you have paths with ~ in the path of the CODEOWNERS file. This makes GitHub's CODEOWNERS stop working silently. Unfortunately, this case is not caught by the Valid syntax checker.

Expected result

The checker should fail and point at the faulty line in CODEOWNERS.

Actual result

All checks are OK.

Steps to reproduce

Add a line like

/foo/bar/Documentation~/                            @mszostok 

then run

env REPOSITORY_PATH="." \
    GITHUB_ACCESS_TOKEN="$GH_TOKEN" \
    OWNER_CHECKER_REPOSITORY="mszostok/codeowners-validator" \
~/bin/codeowners-validator

Troubleshooting

Add test coverage report from integration tests

Description

The test coverage is pushed to the codecov.io platform: https://codecov.io/gh/mszostok/codeowners-validator

But the coverage raport is generated only from the unit-test. The problem is that not every checker is easy to test with unit test. For example, the owners_check executes external calls and mocking that does not make sens. Instead the integration testing is ensuring that the contract is fulfilled.

As a part of that task we should add the coverage report for the integration tests. There is already an option to do that:

Acceptance Criteria:
[ ] Add coverage report for integration tests
[ ] Push to the codecov.io coverage report which contains both the unit-test and integration-test coverage
[ ] Add test coverage badge to README.md

Reasons

We should be able to detect which part of the validator is not covered by our tests and be able to write a missing tests.

Add contributing documentation

Description

We need to add the developer documentation for new contributors.

Describe:

  • cloning
  • vendoring
  • building
  • testing (add info that the test-integration is failing on PRs, can be executed locally)

Add support for outside collaborators

Description

There is an option to add people as outside collaborators.

The codeowners-validator should include those members when in owners check as currently they are ignored.

Reasons

Currently, owners check my produce false negatives when CODEOWNRES files has outside collaborators as owners.

Discussion: Support to ignore @ghost

I have a scenario in my CODEOWNERS file, which I define as the owner of a path is @ghost because it's a trick to avoid getting review requests. The problem is that when I run the checker through GH actions, it returns this error:

[err] line 13: User "@ghost" is not a member of the organization

(because in fact, this "user" does not exist)

Reading the documentation, I thought that perhaps not_owned_checker_skip_patterns could solve this problem. But I couldn't solve it 😢

Do you have any other ideas?

Thanks 🌷

CODEOWNERS templates

Description

I propose this tool generates a good template to start with, which include human readable rules and instructions. I will share the one I have written for @OpenGov as a basis for discussion and improvement.

Reasons

  • GitHub provides exceptionally poor documentation
  • Over the last year of working with them over many different codeowners issues, their support has implicitly assured me they are not going to improve it and don't take it very seriously, even as they promote infra as code, where a missing code review could be the difference between success and calamity.

Template
For discussion. This is what I inferred from practice.

###
# Keep this organized alphabetically by team (except where noted),
# read the NOTES, and leave meaningful comments.
# ----------------------------------------------------------------
#
# NOTES ABOUT HOW THIS FILE WORKS
# - Validate all changes with https://github.com/mszostok/codeowners-validator
#
# - Most rules should start with a slash unless you intentionally
#   want ownership of that pattern _anywhere_ in the repo.
#   Leave a comment if this is the case.
#
# - The last matching rule is the one applied. Examples:
#   1) CoreTeam takes ownership of all files with * at the top,
#      and any rule below for another team will take precedence.
#   2) CoreTeam is the last listed owner/match for things like Dockerfile
#      and helm, so it will be the owning team for changes to those files
#      even if they're part of another team's service in a higher match.
#
# - As a result of the matching rules above, DO NOT ADD ! (negation) rules.
#
# - The base branch's CODEOWNERS file takes precedence over changes
#   to the CODEOWNERS files in a branch, meaning you can't remove
#   a base team without their approval.
#
# - Changes to CODEOWNERS in a branch are reflected in the PR,
#   meaning newly added teams will be requested for review in the PR.
#
# - Reviewers only get updated when a push occurs to the branch.
#
# - ALL TEAMS MUST BE EXPLICITLY GIVEN WRITE ACCESS TO THE REPO
#   (or they must be a child team of a team that has write access)
# ----------------------------------------------------------------
#
# RESOURCES
# - https://git-scm.com/docs/gitignore#_pattern_format
# - https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners
# ----------------------------------------------------------------
###

###
# CoreTeam is the default owner if no one else takes ownership below.
# This is to ensure that someone owns everything eventually.
#
# DO NOT MOVE THIS FROM THE TOP OF THE FILE.
###
* @CoreTeam

###
# SubTeam
###
/source/bar-service  @SubTeam

# !!! KEEP CoreTeam LAST !!!
# (These are overrides.)

###
# CoreTeam
###
# All root dotfiles.
/.*  @CoreTeam

# All repository integrations with GitHub.
/.github  @CoreTeam

# All .gitignores
**/.gitignore  @OpenGov/CoreTeam

Feature request: support custom GitHub URLs

I'd like to use this against my company's internal enterprise github instance, but it looks like api.github.com is hardcoded in. It'd be great if I could pass a github URL in as an env param. This is a really useful package btw, thanks 👍

Team does not belong to organization

Description

Upgrading to version 0.7.0 makes the Github action fail, whereas version 0.6.0 passed. The action is configured as follows

- uses: mszostok/[email protected]
  with:
    checks: files,duppatterns,syntax,owners
    experimental_checks: notowned
    github_access_token: ${{ secrets.GITHUB_PAT }}

With a CODEOWNERS file that looks like so

* @org/team

Expected result

The action should not fail

Actual result

The action fails with the following message

[err] line 1: Team "@org/team" does not belong to "Org" organization.

Steps to reproduce

Since the issue relates to Github organization, unable to share a repository for reproduction

Troubleshooting

  • Read the release notes
  • Verified that the team exists
  • Verified that the action passes when changing only the version back to 0.6.0
  • Verified that the organization and teams in the codeowners file is written with the same case as it appears in Github

Is this a bug in version 0.7.0?
Is something missing in the action configuration?

Thank you for your work

Filepath Checker incorrect

There is a bug when checking if a certain filepath exists.

Please run the codeowners-validator against https://github.com/lswith/codeowners-validator-test

You will see:

==> Executing File Exist Checker (2.828984ms)
    [err] line 1: "*.js" does not match any files in repository

1 check(s) executed, 1 failure(s)

When it should see that this CODEOWNER file exists should include all js files in all directories.

Who is using Codeowners Validator?

Who is using Codeowners Validator?

I want to sincerely thank everyone who constantly keeps on using and supporting Codeowners Validator! 🚀

This project is developed 100% in my spare time, but I try to keep Codeowners Validator actively developed and maintained.

Reasoning behind this issue

  • Find out how many people out there are using this tool to ensure that the time spent on this project is valuable.
  • Learn more about the practical usage and be able to prioritize the next step of development. This will impact the v1.0 release. Also, I will be able to note which checks are mostly used and which not.
  • Be able to ping users whenever a new version of Codeowners Validator will be released.

Call for action

Add a comment to this issue including the following information:

  • GitHub organization
  • Link to the repositories where codeowners-validator is used. It doesn't necessarily need to be CI.

Valid Owner Checker should ignore team name casing

Description

We have a code owners file with the following entries:

src/somefile1.txt @someorg/teamreviewers
src/somefile2.txt @someorg/TeamReviewers

Under the "someorg" organization we have a team called "TeamReviewers". The validator currently issues an error for the second entry above. It appears that we expect to use only lowercase names.

version.Info{Version:"0.6.0", GitCommit:"2f6e3bb", BuildDate:"2021-01-22T09:50:03Z", GoVersion:"go1.15.2", Compiler:"gc", Platform:"linux/amd64"}
==> Executing Valid Syntax Checker (530.724µs)
    Check OK
==> Executing Duplicated Pattern Checker (356.498µs)
    Check OK
==> Executing File Exist Checker (23.789863ms)
    Check OK
==> Executing Valid Owner Checker (670.5905ms)
    [err] line 2: Team "TeamReviewers" does not exist in organization "someorg".

Expected result

In the instance described above both entries should ignore casing and match "TeamReviewers".

Actual result

==> Executing Valid Owner Checker (670.5905ms)
    [err] line 2: Team "TeamReviewers" does not exist in organization "someorg".

Steps to reproduce

  1. Setup a team name that is not all lower case.
  2. Add an entry to the CODEOWNERS file using the non-lowercase format.
  3. Run the validator.

Troubleshooting

We have changed our CODEOWNERS file to use all lowercase names, but this isn't ideal.

Release v1

Description

This tool was created a long time ago, and I already got a lot of feedback.

I plan to release the v1 once:

  • All bugs will be fixed

  • Such enhancements:

    • New checks:
    • UX:
      • #16 && #73
        This is important as this will change the way how validator is configured. It will give users a lot of freedom for customization ( with sensible defaults). Here we will move away from environment variables, and instead we will introduce support for YAML files configuration. Format is not yet defined, but to give you the overall idea, see:
        # config.yaml
        
        # all available settings of specific linters
        checks-settings:
        
          owner:
            # The owner and repository name separated by slash. Used to check if GitHub owner is in the given organization.
            # (required)
            repository: "gh-codeowners/codeowners-samples"
        
            # Excluding configuration
            exclude-rules: # support excluded only for some users so outside collaborators are not check but the rest are validated
        
              # excluded for all as no owners provided
              - rule: valid-definition
              - rule: has-github-account
              - rule: team-exists
        
        
              # excluded only for a given owners
              - rule: is-in-organization
                owners:
                  - @owner1
                  - @owner2
                  - @owner3
      • #50. In general, documentation will be moved to a dedicated website with more readable interface.
      • #61

    Other:

    • #49 to ensure no regression on v1.
    • add benchmarks and ensure no regression on execution time.

Additionally, I would like to:

  • add an option to format CODEOWNERS files.
  • and an option to add/remove a given owner from CODEOWNERS files and create related PRs automatically. For example, with such (draft) config:
    updateRepositories:
      - path: "/tmp/cloned/repository" # local repository
      - url: "org/repo" # clone to temp dir
      - url: "org/other-repo" # clone to temp dir
      - url: "org/*" # maybe in the next version add pattern support?
    
    insert:
      - owners: [ "@hakuna", "@matata" ]
        condition:
          pattern: "*.go"
      - owners: [ "@baz", "@bar" ]
        condition:
          associatedWithOwner: "@ghost"
    
    pullRequest:
      titleFormat: "Add {{ .NewOwner }} as a code owner in {{ .RepoName }}"
    Pull requests will be created in dedicated repositories.

As a result, maybe this project will be changed to codeowners-manager or simply codeowners as the spectrum of responsibilities will be much wider:

  • codeowners fmt
  • codeowners validate
  • codeowners add # across repositories
  • codeowners remove # across repositories
  • codeowners fix

Owners check does not support child teams with inherited repo perms

Description

When running the "owners" check on a child GitHub team which has inherited its repo perms from a parent, the GitHub action reports:

Team "engineering-foo" does not exist in organization "some-org" or has no permissions associated with the repository.

I took a look through the code, and I think the issue comes down to the generation of the teams list here. That appears to be making a call to the /repos/{owner}/{repo}/teams GitHub API endpoint, which, as far as I can tell, does not return teams that have inherited their repo permissions from another team.

This is for version 4.0 of this repo.

Expected result

This is a team that has access to the repo (indirectly), so I'd expect it the "owners" check to pass.

Actual result

The "owners" check fails with the error message above.

Steps to reproduce

I've created an example PR here: test-verify-codeowners/owners-bug#1.

For posterity, to setup that org, I:

  1. Created it, added a repo, and added the parent-team team
  2. Created child-team-inherit which just inherits parent-team's perms, and a child-team-override, where I overwrote the inherited perms to explicitly give it access (described in the workaround section below.)
  3. Added the appropriate personal access token to the orgs' secrets.
  4. Made the changes visible in that PR and opened the PR (more info in that PR's description).

Troubleshooting

Curling the repos endpoint with curl -H "Authorization: token <token>" https://api.github.com/repos/test-verify-codeowners/owners-bug/teams gives us:

[
  {
    "name": "parent-team",
    "id": 3934999,
    "node_id": "MDQ6VGVhbTM5MzQ5OTk=",
    "slug": "parent-team",
    "description": "",
    "privacy": "closed",
    "url": "https://api.github.com/organizations/68017749/team/3934999",
    "html_url": "https://github.com/orgs/test-verify-codeowners/teams/parent-team",
    "members_url": "https://api.github.com/organizations/68017749/team/3934999/members{/member}",
    "repositories_url": "https://api.github.com/organizations/68017749/team/3934999/repos",
    "permission": "pull",
    "parent": null
  },
  {
    "name": "child-team-override",
    "id": 3935004,
    "node_id": "MDQ6VGVhbTM5MzUwMDQ=",
    "slug": "child-team-override",
    "description": "This one also inherits, but also overrides.",
    "privacy": "closed",
    "url": "https://api.github.com/organizations/68017749/team/3935004",
    "html_url": "https://github.com/orgs/test-verify-codeowners/teams/child-team-override",
    "members_url": "https://api.github.com/organizations/68017749/team/3935004/members{/member}",
    "repositories_url": "https://api.github.com/organizations/68017749/team/3935004/repos",
    "permission": "pull",
    "parent": {
      "name": "parent-team",
      "id": 3934999,
      "node_id": "MDQ6VGVhbTM5MzQ5OTk=",
      "slug": "parent-team",
      "description": "",
      "privacy": "closed",
      "url": "https://api.github.com/organizations/68017749/team/3934999",
      "html_url": "https://github.com/orgs/test-verify-codeowners/teams/parent-team",
      "members_url": "https://api.github.com/organizations/68017749/team/3934999/members{/member}",
      "repositories_url": "https://api.github.com/organizations/68017749/team/3934999/repos",
      "permission": "pull"
    }
  }
]

Note that child-team-override's repo list is visually the same as child-team-inherit's repo list, but only parent-team and child-team-override show up in the above response.

Workarounds

We've found a workaround for this, which is to manually give the child teams perms on the repo in question.

  1. Go to the team's repository settings (e.g. https://github.com/orgs/test-verify-codeowners/teams/child-team-override/repositories.

  2. Find the repo in question

  3. Open its permissions dropdown and select the level of perms you want to give it (which should already be selected).

    image

It will look basically the same, but it you cURL the endpoint again, it should now show up in the response, and the action will work.

Potential Solutions

I'm not really sure if this counts as a bug on your side. I haven't found any references to this behavior in the GitHub API docs, it seems strange, so it could be a bug on their end. I'm planning to reach out to GitHub support today and see what they say.

However, I thought I'd open this and see what you think (and in case others run into this issue.) If this behavior is intentional on their end (or just unlikely to change in the near future), I wonder if it would be possible to substitute calls to other endpoints. For example, hitting https://api.github.com/orgs/test-verify-codeowners/teams gives us a repositories url of https://api.github.com/organizations/68017749/team/3935001/repos for child-team-inherit, which does return the repo.

Also, thank you! This project is very helpful for us.

Support user repositories which are not under organization

I'm trying to use codeowners-validator for my own repository, which is not owned by an organisation, with default settings like this:

name: 'Codeowners validation'

on:
  push:
    paths:
    - '.github/CODEOWNERS'
    - '.github/workflows/codeowners-validator.yml'
    branches:
    - '**'
    tags-ignore:
    - '**'
  schedule:
  - cron: '37 4 * * *'
  workflow_dispatch: { }

jobs:
  codeowners-validation:
    runs-on: ubuntu-latest
    timeout-minutes: 15
    steps:
    - name: Checkout repository
      uses: actions/checkout@v2
      with:
        fetch-depth: 1

    - name: CODEOWNERS validation
      uses: mszostok/[email protected]
      with:
        github_access_token: '${{ github.token }}'

Expected result

The validation is performed successfully.

Actual result

The validation fails with this error:

==> Executing Valid Owner Checker (64.079355ms)
    [err] line 1: Cannot initialize organization member list: GET https://api.github.com/orgs/remal/members?per_page=100: 404 Not Found []

Validate GitHub token scopes when `owners` check is enabled

Description

Currently, if you will pass GitHub token, it won't be validated. If it lacks necessary scopes, a misleading error can be returned. For example:

==> Executing Valid Owner Checker (184.722866ms)
    [err] line 8: User "@mszostok" is not a member of the organization
    [err] line 11: HTTP error occurred while calling GitHub: GET https://api.github.com/orgs/GitHubCODEOWNERS/teams?per_page=100: 403 Must have admin rights to Repository. []

but in real, the problem is that the token doesn't have the "read:org" scope.

To avoid such problems, we need to check if token has the "read:org" and "public_repo" scopes when owners check is enabled.

File Exist Checker fails on valid relative paths checked in all directories by CODEOWNERS

First of all thank you for this tool, it helped me fixed CODEOWNERS for https://github.com/godotengine/godot
Turns out that review-requests don't work for teams without Write permission for some reason (as if a review from someone not able to press "Merge" is not valid), but your tool caught it + more issues :)

Version
0.6.0, installed in ./bin with curl instructions.

Description

There seems to be a false positive report from the File Exist Checker when using relative paths which are then checked in all directories by CODEOWNERS.
What I mean is what is described here: https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners#codeowners-syntax

# In this example, @octocat owns any file in an apps directory
# anywhere in your repository.
apps/ @octocat

This will successfully match apps/ directories in any directory of the repository, even if there's no apps/ directory in the root.
But codeowners-validator issues a warning about this case.

Expected result
No warning if any nested directory matches the pattern.

Actual result

==> Executing File Exist Checker (45.227677ms)
    [err] line 11: "SCsub" does not match any files in repository
    [err] line 23: "doc_classes/*" does not match any files in repository

Yet:

$ find -type f -name SCsub | wc -l
124
$ find -type d -name doc_classes | wc -l
19

(This is on https://github.com/godotengine/godot/)

Steps to reproduce

Troubleshooting
n/a

Move to cobra library.

Description

Currently the codeowners-validator allows you to specify the configuration only via environment variables.

Moving to cobra library will allow us to use the codeowners-validator as a full CLI app.

Acceptance Criteria

  • user can user codeowners-validator as CLI
  • user can specify configuration via cli flags
  • user can specify configuration via env variables

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.