Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apply hot fix to resolve issue with untrusted git repository for not-owned checker #148

Merged
merged 1 commit into from
Apr 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ jobs:
with:
distribution: goreleaser
version: latest

args: release --rm-dist
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ COPY --from=deps /usr/bin/xargs /usr/bin/xargs
COPY --from=deps /lib /lib
COPY --from=deps /usr/lib /usr/lib

CMD ["/codeowners-validator"]
ENTRYPOINT ["/codeowners-validator"]
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,22 +128,23 @@ Use the following environment variables to configure the application:
| <tt>CHECK_FAILURE_LEVEL</tt> | `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`. |
| <tt>OWNER_CHECKER_REPOSITORY</tt> <b>*</b> | | 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. |
| <tt>OWNER_CHECKER_IGNORED_OWNERS</tt> | `@ghost` | The comma-separated list of owners that should not be validated. Example: `"@owner1,@owner2,@org/team1,example@email.com"`. |
| <tt>OWNER_CHECKER_ALLOW_UNOWNED_PATTERNS</tt> | `true` | Specifies whether CODEOWNERS may have unowned files. For example: <br> <br> `/infra/oncall-rotator/ @sre-team` <br> `/infra/oncall-rotator/oncall-config.yml` <br> <br> The `/infra/oncall-rotator/oncall-config.yml` file is not owned by anyone. |
| <tt>OWNER_CHECKER_ALLOW_UNOWNED_PATTERNS</tt> | `true` | Specifies whether CODEOWNERS may have unowned files. For example: <br> <br> `/infra/oncall-rotator/ @sre-team` <br> `/infra/oncall-rotator/oncall-config.yml` <br> <br> The `/infra/oncall-rotator/oncall-config.yml` file is not owned by anyone. |
| <tt>OWNER_CHEKER_OWNERS_MUST_BE_TEAMS</tt> | `false` | Specifies whether only teams are allowed as owners of files. |
| <tt>NOT_OWNED_CHECKER_SKIP_PATTERNS</tt> | - | 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` |
| <tt>NOT_OWNED_CHECKER_SUBDIRECTORIES</tt> | - | 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. |
| <tt>NOT_OWNED_CHECKER_SUBDIRECTORIES</tt> | - | 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. |
| <tt>NOT_OWNED_CHECKER_TRUST_WORKSPACE</tt> | `false` | Specifies whether the repository path should be marked as safe. See: https://github.com/actions/checkout/issues/766. |

<b>*</b> - 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. |
| 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. |
| **3** | The CODEOWNERS validation failed - executed checks found some issues. |

## Contributing

Expand Down
13 changes: 9 additions & 4 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,23 +44,28 @@ inputs:
default: "${{ github.repository }}"

owner_checker_ignored_owners:
description: "The comma-separated list of owners that should not be validated. Example: @owner1,@owner2,@org/team1,example@email.com."
description: "The comma-separated list of owners that should not be validated. Example: @owner1,@owner2,@org/team1,example@email.com."
required: false

owner_checker_allow_unowned_patterns:
description: "Specifies whether CODEOWNERS may have unowned files. For example, `/infra/oncall-rotator/oncall-config.yml` doesn't have owner and this is not reported."
description: "Specifies whether CODEOWNERS may have unowned files. For example, `/infra/oncall-rotator/oncall-config.yml` doesn't have owner and this is not reported."
default: "true"
required: false

owner_checker_owners_must_be_teams:
description: "Specifies whether only teams are allowed as owners of files."
description: "Specifies whether only teams are allowed as owners of files."
default: "false"
required: false

not_owned_checker_subdirectories:
description: "Only check listed subdirectories for CODEOWNERS ownership that don't have owners."
description: "Only check listed subdirectories for CODEOWNERS ownership that don't have owners."
required: false

not_owned_checker_trust_workspace:
description: "Specifies whether the repository path should be marked as safe. See: https://github.com/actions/checkout/issues/766"
required: false
default: "true"

runs:
using: 'docker'
image: 'docker://ghcr.io/mszostok/codeowners-validator:v0.7.3'
Expand Down
26 changes: 25 additions & 1 deletion internal/check/not_owned_file.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,18 @@ import (
)

type NotOwnedFileConfig struct {
// TrustWorkspace sets the global gif config
// to trust a given repository path
// see: https://github.com/actions/checkout/issues/766
TrustWorkspace bool `envconfig:"default=false"`
SkipPatterns []string `envconfig:"optional"`
Subdirectories []string `envconfig:"optional"`
}

type NotOwnedFile struct {
skipPatterns map[string]struct{}
subDirectories []string
trustWorkspace bool
}

func NewNotOwnedFile(cfg NotOwnedFileConfig) *NotOwnedFile {
Expand All @@ -34,6 +39,7 @@ func NewNotOwnedFile(cfg NotOwnedFileConfig) *NotOwnedFile {
return &NotOwnedFile{
skipPatterns: skip,
subDirectories: cfg.Subdirectories,
trustWorkspace: cfg.TrustWorkspace,
}
}

Expand All @@ -51,6 +57,10 @@ func (c *NotOwnedFile) Check(ctx context.Context, in Input) (output Output, err

patterns := c.patternsToBeIgnored(in.CodeownersEntries)

if err := c.trustWorkspaceIfNeeded(in.RepoDir); err != nil {
return Output{}, err
}

statusOut, err := c.GitCheckStatus(in.RepoDir)
if err != nil {
return Output{}, err
Expand Down Expand Up @@ -187,6 +197,20 @@ func (c *NotOwnedFile) GitListFiles(repoDir string) (string, error) {
return string(stdout), nil
}

func (c *NotOwnedFile) trustWorkspaceIfNeeded(repo string) error {
if !c.trustWorkspace {
return nil
}

gitadd := pipe.Exec("git", "config", "--global", "--add", "safe.directory", repo)
_, stderr, err := pipe.DividedOutput(gitadd)
if err != nil {
return errors.Wrap(err, string(stderr))
}

return nil
}

func (c *NotOwnedFile) skipPatternsList() string {
list := make([]string, 0, len(c.skipPatterns))
for k := range c.skipPatterns {
Expand All @@ -206,7 +230,7 @@ func (c *NotOwnedFile) ListFormatFunc(es []string) string {
return strings.Join(points, "\n")
}

// Name returns human readable name of the validator
// Name returns human-readable name of the validator
func (NotOwnedFile) Name() string {
return "[Experimental] Not Owned File Checker"
}
3 changes: 3 additions & 0 deletions internal/check/valid_owner.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ var reqScopes = map[github.Scope]struct{}{
}

type ValidOwnerConfig struct {
// Repository represents the GitHub repository against which
// the external checks like teams and members validation should be executed.
// It is in form 'owner/repository'.
Repository string
// IgnoredOwners contains a list of owners that should not be validated.
// Defaults to @ghost.
Expand Down