Skip to content

Commit

Permalink
infra: Add copyright headers check, copyright headers (#18)
Browse files Browse the repository at this point in the history
This change adds:

* a Go tool to check for copyright headers
* a Github job to run the check in presubmit and postsubmit
* copyright headers to all files, to satisfy the check

Because this check necessarily depends on all source files, it can't be
implemented as a bazel test, so it is instead designed to be invoked via
`bazel run` (depends on an environment var that locates the workspace
root). Go was chosen over bash to avoid complicated pipelines and
array/associative array bash syntax.

Tested: Wrote the tool first; it identified all the source files in the
repo, which were resolved either by adding a header, or by adding an
exception inside the `generatedFiles` var.
  • Loading branch information
minor-fixes authored Jul 31, 2024
1 parent e78edce commit ddfce52
Show file tree
Hide file tree
Showing 22 changed files with 454 additions and 0 deletions.
31 changes: 31 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
# Copyright 2024 EngFlow Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Postsubmit checks that run on the `main` branch after merge.
name: "main"

Expand Down Expand Up @@ -73,3 +87,20 @@ jobs:
# TODO(CUS-345): Enable remote execution
bazel run --config=noninteractive @rules_go//go -- test ./...
bazel run --config=noninteractive @rules_go//go -- clean -cache -modcache
copyright-headers-check:
runs-on:
- self-hosted
- os=linux
- arch=x64
- os_distribution=debian
- os_version=12
- revision=d04e89854b3931f4aaced77aa3a2fcad5834b3a6
timeout-minutes: 10

steps:
- uses: actions/checkout@v4

- name: Check copyright headers
run: |
bazel run --config=noninteractive //infra/internal/check_copyright_headers
31 changes: 31 additions & 0 deletions .github/workflows/presubmit.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
# Copyright 2024 EngFlow Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Presubmit checks for PRs
name: "presubmit"

Expand Down Expand Up @@ -75,3 +89,20 @@ jobs:
# TODO(CUS-345): Enable remote execution
bazel run --config=noninteractive @rules_go//go -- test ./...
bazel run --config=noninteractive @rules_go//go -- clean -cache -modcache
copyright-headers-check:
runs-on:
- self-hosted
- os=linux
- arch=x64
- os_distribution=debian
- os_version=12
- revision=d04e89854b3931f4aaced77aa3a2fcad5834b3a6
timeout-minutes: 10

steps:
- uses: actions/checkout@v4

- name: Check copyright headers
run: |
bazel run --config=noninteractive //infra/internal/check_copyright_headers
14 changes: 14 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
# Copyright 2024 EngFlow Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

name: "release"

on:
Expand Down
14 changes: 14 additions & 0 deletions cmd/engflow_auth/main.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
// Copyright 2024 EngFlow Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
Expand Down
14 changes: 14 additions & 0 deletions cmd/engflow_auth/main_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
// Copyright 2024 EngFlow Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
Expand Down
14 changes: 14 additions & 0 deletions infra/get_workspace_status
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
#!/bin/bash

# Copyright 2024 EngFlow Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# The variables defined here are available not only in BES logs, but also for
# stamping into built binaries (version information, etc.). Removing vars or
# changing var names may break these version stamping libraries; if this script
Expand Down
14 changes: 14 additions & 0 deletions infra/internal/check_copyright_headers/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
load("@rules_go//go:def.bzl", "go_binary", "go_library")

go_library(
name = "check_copyright_headers_lib",
srcs = ["main.go"],
importpath = "github.com/EngFlow/auth/infra/internal/check_copyright_headers",
visibility = ["//infra:__subpackages__"],
)

go_binary(
name = "check_copyright_headers",
embed = [":check_copyright_headers_lib"],
visibility = ["//infra:__subpackages__"],
)
126 changes: 126 additions & 0 deletions infra/internal/check_copyright_headers/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
// Copyright 2024 EngFlow Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
"bufio"
"errors"
"fmt"
"os"
"os/exec"
"path/filepath"
"regexp"
"sort"
"strings"
)

var (
skipRegexps = []*regexp.Regexp{
regexp.MustCompile(`^go\.mod$`),
regexp.MustCompile(`^go\.sum$`),
regexp.MustCompile(`^LICENSE$`),
regexp.MustCompile(`^MODULE\.bazel\.lock$`),
regexp.MustCompile(`^MODULE\.bazel$`),
regexp.MustCompile(`^README.md$`),
regexp.MustCompile(`^WORKSPACE$`),
regexp.MustCompile(`(/|^)BUILD$`),
regexp.MustCompile(`^\.bazelrc$`),
regexp.MustCompile(`^\.gitignore$`),
regexp.MustCompile(`\.bzl$`),
}
copyrightRegexp = regexp.MustCompile(`^(#|//) Copyright [0-9-]+ EngFlow Inc\.`)
)

type checkerFunc func(string) bool

// listSourceFiles returns the list of files that git cares about in the current
// commit.
func listSourceFiles(repoRoot string) ([]string, error) {
cmd := exec.Command("git", "ls-tree", "-r", "--name-only", "HEAD")
cmd.Dir = repoRoot
output, err := cmd.Output()
if err != nil {
return nil, fmt.Errorf("`git ls-tree` failed: %w", err)
}
return strings.Split(strings.TrimSpace(string(output)), "\n"), nil
}

// filterStrings returns strings in `universe` that don't match any regexps in
// `remove`.
func filterStrings(universe []string, remove []*regexp.Regexp) []string {
var filtered []string
nextStr:
for _, s := range universe {
for _, r := range remove {
if r.MatchString(s) {
continue nextStr
}
}
filtered = append(filtered, s)
}
return filtered
}

// checkCopyright runs the supplied checker on each line of the file, returning
// an error if the checker never returns true.
func checkCopyright(path string, checker checkerFunc) error {
f, err := os.Open(path)
if err != nil {
return err
}
defer f.Close()
scanner := bufio.NewScanner(f)
for scanner.Scan() {
if checker(scanner.Text()) {
return nil
}
}
return fmt.Errorf("%s: missing copyright header", path)
}

func run() error {
workspaceRoot := os.Getenv("BUILD_WORKSPACE_DIRECTORY")
if workspaceRoot == "" {
return fmt.Errorf("$BUILD_WORKSPACE_DIRECTORY is not set; please run this script via `bazel run`")
}
srcFiles, err := listSourceFiles(workspaceRoot)
if err != nil {
return err
}

srcFiles = filterStrings(srcFiles, skipRegexps)

var errs []error
for _, f := range srcFiles {
if err := checkCopyright(filepath.Join(workspaceRoot, f), copyrightRegexp.MatchString); err != nil {
errs = append(errs, err)
continue
}
}

if len(errs) == 0 {
return nil
}

sort.Slice(errs, func(i, j int) bool { return errs[i].Error() < errs[j].Error() })
return fmt.Errorf("copyright header check failed:\n%v", errors.Join(errs...))
}

func main() {
if err := run(); err != nil {
fmt.Fprintf(os.Stderr, "ERROR: %v\n", err)
os.Exit(1)
}
}
14 changes: 14 additions & 0 deletions infra/release.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
#!/usr/bin/env bash

# Copyright 2024 EngFlow Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

set -o nounset -o pipefail -o errexit
[[ "${SCRIPT_DEBUG:-"off"}" == "on" ]] && set -o xtrace

Expand Down
14 changes: 14 additions & 0 deletions internal/autherr/coded_error.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
// Copyright 2024 EngFlow Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package autherr

import (
Expand Down
14 changes: 14 additions & 0 deletions internal/autherr/coded_error_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
// Copyright 2024 EngFlow Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package autherr

import (
Expand Down
14 changes: 14 additions & 0 deletions internal/browser/browser.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
// Copyright 2024 EngFlow Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package browser

import (
Expand Down
14 changes: 14 additions & 0 deletions internal/buildstamp/buildstamp.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
// Copyright 2024 EngFlow Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package buildstamp exports build metadata values that may be optionally set
// by the build system, for runtime inspection. The primary usecase is for
// identifying application provenance (e.g. what branch, user built the code).
Expand Down
Loading

0 comments on commit ddfce52

Please sign in to comment.