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

Make the org comparison case-insensitive too #122

Merged
merged 2 commits into from
Feb 13, 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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,15 @@ builds:
post: upx -9 "{{ .Path }}"

archives:
- format: binary
name_template: "{{ .Binary }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}{{ if .Mips }}_{{ .Mips }}{{ end }}"
- replacements:
darwin: Darwin
linux: Linux
windows: Windows
386: i386
amd64: x86_64
format_overrides:
- goos: windows
format: zip

dockers:
- dockerfile: Dockerfile
Expand Down
8 changes: 4 additions & 4 deletions internal/check/valid_owner.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,21 +186,21 @@ func (v *ValidOwner) validateTeam(ctx context.Context, name string) *validateErr
}
}

// GitHub normalizes name before comparison
name = strings.ToLower(name)
// called after validation it's safe to work on `parts` slice
parts := strings.SplitN(name, "/", 2)
org := parts[0]
org = strings.TrimPrefix(org, "@")
team := parts[1]

if org != v.orgName {
// GitHub normalizes name before comparison
if !strings.EqualFold(org, v.orgName) {
return newValidateError("Team %q does not belong to %q organization.", name, v.orgName)
}

teamExists := func() bool {
for _, v := range v.orgTeams {
if v.GetSlug() == team {
// GitHub normalizes name before comparison
if strings.EqualFold(v.GetSlug(), team) {
return true
}
}
Expand Down
8 changes: 8 additions & 0 deletions tests/integration/helpers_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build integration
// +build integration

package integration
Expand Down Expand Up @@ -105,3 +106,10 @@ func (s *Executor) Binary(binaryPath string) *Executor {
s.binaryPath = binaryPath
return s
}

func stringDefault(in, def string) string {
if in == "" {
return def
}
return in
}
207 changes: 140 additions & 67 deletions tests/integration/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package integration

import (
"fmt"
"os"
"runtime"
"testing"
Expand All @@ -15,10 +16,25 @@ import (
)

const (
binaryPathEnvName = "BINARY_PATH"
codeownersSamplesRepo = "https://github.com/gh-codeowners/codeowners-samples.git"
binaryPathEnvName = "BINARY_PATH"
codeownersSamplesRepo = "https://github.com/gh-codeowners/codeowners-samples.git"
caseInsensitiveOrgCodeownersSamplesRepo = "https://github.com/GitHubCODEOWNERS/codeowners-samples.git"
)

var repositories = []struct {
name string
repo string
}{
{
name: "gh-codeowners",
repo: codeownersSamplesRepo,
},
{
name: "GitHubCODEOWNERS",
repo: caseInsensitiveOrgCodeownersSamplesRepo,
},
}

// TestCheckHappyPath tests that codeowners-validator reports no issues for valid CODEOWNERS file.
//
// This test is based on golden file.
Expand All @@ -28,74 +44,131 @@ const (
// To update golden file, run:
// UPDATE_GOLDEN=true make test-integration
func TestCheckSuccess(t *testing.T) {
type Envs map[string]string
tests := []struct {
name string
envs Envs
skipOS string
}{
{
name: "files",
envs: Envs{
"CHECKS": "files",
},
},
{
name: "owners",
envs: Envs{
"CHECKS": "owners",
"OWNER_CHECKER_REPOSITORY": "gh-codeowners/codeowners-samples",
"GITHUB_ACCESS_TOKEN": os.Getenv("GITHUB_TOKEN"),
},
},
{
name: "duppatterns",
envs: Envs{
"CHECKS": "duppatterns",
},
},
{
name: "notowned",
envs: Envs{
"PATH": os.Getenv("PATH"), // need to be set to find the `git` binary
"CHECKS": "disable-all",
"EXPERIMENTAL_CHECKS": "notowned",
},
skipOS: "windows",
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
if runtime.GOOS == tc.skipOS {
t.Skip("this test is marked as skipped for this OS")
}

type (
Envs map[string]string
testCase []struct {
name string
repo string
envs Envs
skipOS string
}
)

t.Run("offline checks", func(t *testing.T) {
for _, repoTC := range repositories {
// given
repoDir, cleanup := CloneRepo(t, codeownersSamplesRepo, "happy-path")
defer cleanup()

binaryPath := os.Getenv(binaryPathEnvName)
codeownersCmd := Exec().
Binary(binaryPath).
// codeowners-validator basic config
WithEnv("REPOSITORY_PATH", repoDir)

for k, v := range tc.envs {
codeownersCmd.WithEnv(k, v)
repoDir, cleanup := CloneRepo(t, repoTC.repo, "happy-path")

tests := testCase{
{
name: "files",
envs: Envs{
"CHECKS": "files",
},
},
{
name: "duppatterns",
envs: Envs{
"CHECKS": "duppatterns",
},
},
{
name: "notowned",
envs: Envs{
"PATH": os.Getenv("PATH"), // need to be set to find the `git` binary
"CHECKS": "disable-all",
"EXPERIMENTAL_CHECKS": "notowned",
},
skipOS: "windows",
},
}
for _, tc := range tests {
t.Run(fmt.Sprintf("%s/%s", repoTC.name, tc.name), func(t *testing.T) {
if runtime.GOOS == tc.skipOS {
t.Skip("this test is marked as skipped for this OS")
}

binaryPath := os.Getenv(binaryPathEnvName)
codeownersCmd := Exec().
Binary(binaryPath).
// codeowners-validator basic config
WithEnv("REPOSITORY_PATH", repoDir)

for k, v := range tc.envs {
codeownersCmd.WithEnv(k, v)
}

// when
result, err := codeownersCmd.AwaitResultAtMost(3 * time.Minute)

// then
require.NoError(t, err)
assert.Equal(t, 0, result.ExitCode)
normalizedOutput := normalizeTimeDurations(result.Stdout)

g := goldie.New(t, goldie.WithNameSuffix(".golden.txt"))
g.Assert(t, t.Name(), []byte(normalizedOutput))
})
}

// when
result, err := codeownersCmd.AwaitResultAtMost(3 * time.Minute)

// then
require.NoError(t, err)
assert.Equal(t, 0, result.ExitCode)
normalizedOutput := normalizeTimeDurations(result.Stdout)

g := goldie.New(t, goldie.WithNameSuffix(".golden.txt"))
g.Assert(t, t.Name(), []byte(normalizedOutput))
})
}
cleanup()
}
})

t.Run("online checks", func(t *testing.T) {
tests := testCase{
{
name: "gh-codeowners/owners",
envs: Envs{
"CHECKS": "owners",
"OWNER_CHECKER_REPOSITORY": "gh-codeowners/codeowners-samples",
"GITHUB_ACCESS_TOKEN": os.Getenv("GITHUB_TOKEN"),
},
repo: codeownersSamplesRepo,
},
{
name: "GitHubCODEOWNERS/owners",
envs: Envs{
"CHECKS": "owners",
"OWNER_CHECKER_REPOSITORY": "GitHubCODEOWNERS/codeowners-samples",
"GITHUB_ACCESS_TOKEN": os.Getenv("GITHUB_TOKEN"),
},
repo: caseInsensitiveOrgCodeownersSamplesRepo,
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
// given
repoDir, cleanup := CloneRepo(t, tc.repo, "happy-path")
defer cleanup()

if runtime.GOOS == tc.skipOS {
t.Skip("this test is marked as skipped for this OS")
}

binaryPath := os.Getenv(binaryPathEnvName)
codeownersCmd := Exec().
Binary(binaryPath).
// codeowners-validator basic config
WithEnv("REPOSITORY_PATH", repoDir)

for k, v := range tc.envs {
codeownersCmd.WithEnv(k, v)
}

// when
result, err := codeownersCmd.AwaitResultAtMost(3 * time.Minute)

// then
require.NoError(t, err)
assert.Equal(t, 0, result.ExitCode)
normalizedOutput := normalizeTimeDurations(result.Stdout)

g := goldie.New(t, goldie.WithNameSuffix(".golden.txt"))
g.Assert(t, t.Name(), []byte(normalizedOutput))
})
}
})
}

// TestCheckFailures tests that codeowners-validator reports issues for not valid CODEOWNERS file.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
==> Executing Duplicated Pattern Checker (<duration>)
Check OK

1 check(s) executed, no failure(s)
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
==> Executing File Exist Checker (<duration>)
Check OK

1 check(s) executed, no failure(s)
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
==> Executing [Experimental] Not Owned File Checker (<duration>)
Check OK

1 check(s) executed, no failure(s)
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
==> Executing Valid Owner Checker (<duration>)
Check OK

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