diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 91e556c42..a641f9a2c 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -8,6 +8,18 @@ on:
       - '**'
       - '!doc/**'
 jobs:
+  sanity:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+      - uses: actions/setup-go@v2
+        with:
+          go-version: '~1.16'
+      - name: Install goimports
+        run: go install golang.org/x/tools/cmd/goimports@latest
+      - name: Run sanity checks
+        run: make vendor && make lint && git diff --exit-code
+
   build:
     runs-on: ubuntu-latest
     steps:
diff --git a/Makefile b/Makefile
index bb2d5e0ce..b762717ef 100644
--- a/Makefile
+++ b/Makefile
@@ -70,6 +70,10 @@ vendor:
 	$(GO) mod vendor
 	$(GO) mod verify
 
+.PHONY: lint
+lint:
+	find . -name '*.go' -not -path "./vendor/*" | xargs goimports -w
+
 .PHONY: codegen
 codegen:
 	protoc -I pkg/api/ --go_out=pkg/api pkg/api/*.proto
diff --git a/pkg/api/grpc_health_v1/health.pb.go b/pkg/api/grpc_health_v1/health.pb.go
index 77a709be3..bbb79b4ae 100644
--- a/pkg/api/grpc_health_v1/health.pb.go
+++ b/pkg/api/grpc_health_v1/health.pb.go
@@ -7,11 +7,12 @@
 package grpc_health_v1
 
 import (
+	reflect "reflect"
+	sync "sync"
+
 	proto "github.com/golang/protobuf/proto"
 	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
 	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
-	reflect "reflect"
-	sync "sync"
 )
 
 const (
diff --git a/pkg/api/grpc_health_v1/health_grpc.pb.go b/pkg/api/grpc_health_v1/health_grpc.pb.go
index 1911f0ac3..f24b73112 100644
--- a/pkg/api/grpc_health_v1/health_grpc.pb.go
+++ b/pkg/api/grpc_health_v1/health_grpc.pb.go
@@ -4,6 +4,7 @@ package grpc_health_v1
 
 import (
 	context "context"
+
 	grpc "google.golang.org/grpc"
 	codes "google.golang.org/grpc/codes"
 	status "google.golang.org/grpc/status"
diff --git a/pkg/api/registry.pb.go b/pkg/api/registry.pb.go
index 84f3b9091..265475692 100644
--- a/pkg/api/registry.pb.go
+++ b/pkg/api/registry.pb.go
@@ -7,11 +7,12 @@
 package api
 
 import (
+	reflect "reflect"
+	sync "sync"
+
 	proto "github.com/golang/protobuf/proto"
 	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
 	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
-	reflect "reflect"
-	sync "sync"
 )
 
 const (
diff --git a/pkg/api/registry_grpc.pb.go b/pkg/api/registry_grpc.pb.go
index dba2e1ee0..47b680c59 100644
--- a/pkg/api/registry_grpc.pb.go
+++ b/pkg/api/registry_grpc.pb.go
@@ -4,6 +4,7 @@ package api
 
 import (
 	context "context"
+
 	grpc "google.golang.org/grpc"
 	codes "google.golang.org/grpc/codes"
 	status "google.golang.org/grpc/status"
diff --git a/pkg/image/containerdregistry/resolver.go b/pkg/image/containerdregistry/resolver.go
index 43969e753..9ac771dde 100644
--- a/pkg/image/containerdregistry/resolver.go
+++ b/pkg/image/containerdregistry/resolver.go
@@ -28,7 +28,7 @@ func NewResolver(configDir string, insecure bool, roots *x509.CertPool) (remotes
 		ExpectContinueTimeout: 5 * time.Second,
 		TLSClientConfig: &tls.Config{
 			InsecureSkipVerify: false,
-			RootCAs: roots,
+			RootCAs:            roots,
 		},
 	}
 
@@ -60,7 +60,7 @@ func NewResolver(configDir string, insecure bool, roots *x509.CertPool) (remotes
 	}
 
 	opts := docker.ResolverOptions{
-		Hosts: docker.ConfigureDefaultRegistries(regopts...),
+		Hosts:   docker.ConfigureDefaultRegistries(regopts...),
 		Headers: headers,
 	}
 
diff --git a/pkg/image/registry.go b/pkg/image/registry.go
index d47507ab2..e7c365720 100644
--- a/pkg/image/registry.go
+++ b/pkg/image/registry.go
@@ -29,4 +29,3 @@ type Registry interface {
 	// If it exists, it's used as the base image.
 	// Pack(ctx context.Context, ref Reference, from io.Reader) (next string, err error)
 }
-
diff --git a/pkg/lib/bundle/interfaces.go b/pkg/lib/bundle/interfaces.go
index 7157c5eae..79a69159d 100644
--- a/pkg/lib/bundle/interfaces.go
+++ b/pkg/lib/bundle/interfaces.go
@@ -25,6 +25,6 @@ func NewImageValidator(registry image.Registry, logger *logrus.Entry, options ..
 	return imageValidator{
 		registry: registry,
 		logger:   logger,
-		optional:  options,
+		optional: options,
 	}
 }
diff --git a/pkg/lib/dns/nsswitch_test.go b/pkg/lib/dns/nsswitch_test.go
index ecbb92a01..02eb12eb9 100644
--- a/pkg/lib/dns/nsswitch_test.go
+++ b/pkg/lib/dns/nsswitch_test.go
@@ -1,10 +1,11 @@
 package dns
 
 import (
-	"github.com/stretchr/testify/require"
 	"io/ioutil"
 	"os"
 	"testing"
+
+	"github.com/stretchr/testify/require"
 )
 
 func TestEnsureNsswitch(t *testing.T) {
diff --git a/pkg/lib/indexer/indexer_test.go b/pkg/lib/indexer/indexer_test.go
index 63696be7d..365b929c2 100644
--- a/pkg/lib/indexer/indexer_test.go
+++ b/pkg/lib/indexer/indexer_test.go
@@ -29,7 +29,7 @@ func TestGetBundlesToExport(t *testing.T) {
 		t.Fatalf("creating querier: %s", err)
 	}
 
-	bundleMap, err := getBundlesToExport(dbQuerier, []string {"etcd"})
+	bundleMap, err := getBundlesToExport(dbQuerier, []string{"etcd"})
 	if err != nil {
 		t.Fatalf("exporting bundles from db: %s", err)
 	}
diff --git a/pkg/registry/bundlegraphloader_test.go b/pkg/registry/bundlegraphloader_test.go
index 5bad751d5..8bc5d03c1 100644
--- a/pkg/registry/bundlegraphloader_test.go
+++ b/pkg/registry/bundlegraphloader_test.go
@@ -2,9 +2,10 @@ package registry
 
 import (
 	"encoding/json"
-	"github.com/blang/semver"
 	"testing"
 
+	"github.com/blang/semver"
+
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
@@ -315,55 +316,55 @@ func TestBundleGraphLoader(t *testing.T) {
 }
 
 func TestIsSkipPatchCandidate(t *testing.T) {
-	tests := []struct{
-		name     string
-		added     string
-		compare  string
-		expected bool
+	tests := []struct {
+		name        string
+		added       string
+		compare     string
+		expected    bool
 		commutative bool
 	}{
 		{
-			name: "equal versions",
-			added: "0.0.0",
-			compare: "0.0.0",
-			expected: false,
+			name:        "equal versions",
+			added:       "0.0.0",
+			compare:     "0.0.0",
+			expected:    false,
 			commutative: true,
 		},
 		{
-			name: "do not accept different major/minor version",
-			added: "0.1.0",
-			compare: "0.2.0",
-			expected: false,
+			name:        "do not accept different major/minor version",
+			added:       "0.1.0",
+			compare:     "0.2.0",
+			expected:    false,
 			commutative: true,
 		},
 		{
-			name: "accept larger patch version",
-			added: "0.0.1",
-			compare: "0.0.0",
+			name:     "accept larger patch version",
+			added:    "0.0.1",
+			compare:  "0.0.0",
 			expected: true,
 		},
 		{
-			name: "accept patch version without pre-release",
-			added: "0.0.0",
-			compare: "0.0.0-1",
+			name:     "accept patch version without pre-release",
+			added:    "0.0.0",
+			compare:  "0.0.0-1",
 			expected: true,
 		},
 		{
-			name: "accept longer pre-release with same prefix",
-			added: "0.0.1-1.2",
-			compare: "0.0.1-1",
+			name:     "accept longer pre-release with same prefix",
+			added:    "0.0.1-1.2",
+			compare:  "0.0.1-1",
 			expected: true,
 		},
 		{
-			name: "accept numerically larger pre-release",
-			added: "0.0.1-11",
-			compare: "0.0.1-2",
+			name:     "accept numerically larger pre-release",
+			added:    "0.0.1-11",
+			compare:  "0.0.1-2",
 			expected: true,
 		},
 		{
-			name: "accept lexicographically larger pre-release",
-			added: "0.0.1-beta.1",
-			compare: "0.0.1-alpha.1",
+			name:     "accept lexicographically larger pre-release",
+			added:    "0.0.1-beta.1",
+			compare:  "0.0.1-alpha.1",
 			expected: true,
 		},
 	}
@@ -382,4 +383,4 @@ func TestIsSkipPatchCandidate(t *testing.T) {
 			}
 		})
 	}
-}
\ No newline at end of file
+}
diff --git a/pkg/registry/csv_test.go b/pkg/registry/csv_test.go
index 892c6f8d4..caa7f18d7 100644
--- a/pkg/registry/csv_test.go
+++ b/pkg/registry/csv_test.go
@@ -7,7 +7,7 @@ import (
 
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
-	"k8s.io/apimachinery/pkg/apis/meta/v1"
+	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
 func TestClusterServiceVersion_GetApiServiceDefinitions(t *testing.T) {
diff --git a/pkg/registry/decode_test.go b/pkg/registry/decode_test.go
index 0d0e08667..351b2e2c8 100644
--- a/pkg/registry/decode_test.go
+++ b/pkg/registry/decode_test.go
@@ -1,12 +1,13 @@
 package registry
 
 import (
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
 	"io"
-	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
 	"os"
 	"testing"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
 )
 
 func TestDecodeUnstructured(t *testing.T) {
diff --git a/pkg/server/server.go b/pkg/server/server.go
index 190347862..a90599c27 100644
--- a/pkg/server/server.go
+++ b/pkg/server/server.go
@@ -15,7 +15,7 @@ type RegistryServer struct {
 var _ api.RegistryServer = &RegistryServer{}
 
 func NewRegistryServer(store registry.Query) *RegistryServer {
-	return &RegistryServer{UnimplementedRegistryServer: api.UnimplementedRegistryServer{},  store: store}
+	return &RegistryServer{UnimplementedRegistryServer: api.UnimplementedRegistryServer{}, store: store}
 }
 
 func (s *RegistryServer) ListPackages(req *api.ListPackageRequest, stream api.Registry_ListPackagesServer) error {
diff --git a/pkg/sqlite/db.go b/pkg/sqlite/db.go
index 4f9826b02..6426e6944 100644
--- a/pkg/sqlite/db.go
+++ b/pkg/sqlite/db.go
@@ -2,6 +2,7 @@ package sqlite
 
 import (
 	"database/sql"
+
 	_ "github.com/mattn/go-sqlite3"
 )
 
@@ -19,11 +20,10 @@ func OpenReadOnly(fileName string) (*sql.DB, error) {
 // EnableForeignKeys appends the option to enable foreign keys on connections
 // note that without this option, PRAGMAs about foreign keys will lie.
 func EnableForeignKeys(fileName string) string {
-	return "file:"+fileName+"?_foreign_keys=on"
+	return "file:" + fileName + "?_foreign_keys=on"
 }
 
 // Immutable appends the option to mark the db immutable on connections
 func EnableImmutable(fileName string) string {
-	return "file:"+fileName+"?immutable=true"
+	return "file:" + fileName + "?immutable=true"
 }
-
diff --git a/pkg/sqlite/migrations/006_associate_apis_with_bundle.go b/pkg/sqlite/migrations/006_associate_apis_with_bundle.go
index 221d90e48..f70436f1d 100644
--- a/pkg/sqlite/migrations/006_associate_apis_with_bundle.go
+++ b/pkg/sqlite/migrations/006_associate_apis_with_bundle.go
@@ -3,6 +3,7 @@ package migrations
 import (
 	"context"
 	"database/sql"
+
 	"github.com/operator-framework/operator-registry/pkg/registry"
 )
 
diff --git a/pkg/sqlite/migrations/006_associate_apis_with_bundle_test.go b/pkg/sqlite/migrations/006_associate_apis_with_bundle_test.go
index 698ce8023..b5ea2eb18 100644
--- a/pkg/sqlite/migrations/006_associate_apis_with_bundle_test.go
+++ b/pkg/sqlite/migrations/006_associate_apis_with_bundle_test.go
@@ -4,9 +4,10 @@ import (
 	"context"
 	"database/sql"
 	"fmt"
-	"github.com/operator-framework/operator-registry/pkg/registry"
 	"testing"
 
+	"github.com/operator-framework/operator-registry/pkg/registry"
+
 	"github.com/stretchr/testify/require"
 
 	"github.com/operator-framework/operator-registry/pkg/sqlite/migrations"
diff --git a/pkg/sqlite/remove_test.go b/pkg/sqlite/remove_test.go
index 6f1311435..e4b8063eb 100644
--- a/pkg/sqlite/remove_test.go
+++ b/pkg/sqlite/remove_test.go
@@ -2,9 +2,10 @@ package sqlite
 
 import (
 	"context"
-	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
 	"testing"
 
+	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
+
 	"github.com/operator-framework/operator-registry/pkg/image"
 	"github.com/operator-framework/operator-registry/pkg/registry"
 
diff --git a/tools.go b/tools.go
index ebfcb98eb..9f6bea3e4 100644
--- a/tools.go
+++ b/tools.go
@@ -3,9 +3,9 @@
 package tools
 
 import (
-	_ "google.golang.org/protobuf/cmd/protoc-gen-go"
-	_ "google.golang.org/grpc/cmd/protoc-gen-go-grpc"
 	_ "github.com/grpc-ecosystem/grpc-health-probe"
 	_ "github.com/maxbrunsfeld/counterfeiter/v6"
 	_ "github.com/onsi/ginkgo/ginkgo"
-)
\ No newline at end of file
+	_ "google.golang.org/grpc/cmd/protoc-gen-go-grpc"
+	_ "google.golang.org/protobuf/cmd/protoc-gen-go"
+)