Open-Source Wikis

/

CoreDNS

/

How to contribute

/

Tooling

coredns/coredns

Tooling

The Makefiles

Four Makefiles live at the repo root:

File Purpose
Makefile Build the binary; make, make check, make gen, make pb, make clean
Makefile.docker Build and tag Docker images for various architectures
Makefile.release Release pipeline: cross-compile binaries, create archives, sign
Makefile.doc Regenerate man/coredns-<plugin>.7 from each plugin's README.md

Top-level Makefile

make           # alias for `make coredns`
make check     # run go generate if plugin.cfg is newer
make gen       # force-run go generate
make pb        # rebuild pb/dns.pb.go and pb/dns_grpc.pb.go
make clean

The default target chains:

all -> coredns -> check -> go build

go build is invoked with -tags="$(GOTAGS)" (default grpcnotrace) and -ldflags="-s -w -X github.com/coredns/coredns/coremain.GitCommit=$(GITCOMMIT)". GITCOMMIT is whatever git describe --dirty --always produces, which is what gives the dev-build version string its commit suffix.

CGO_ENABLED=0 by default, so cross-compilation is straightforward — set GOOS and GOARCH and run make.

The Makefile pins the Go toolchain via GOTOOLCHAIN=go$(GOLANG_VERSION) where GOLANG_VERSION reads .go-version. Running make in a fresh checkout will download the right Go toolchain on demand.

Makefile.doc

Walks plugin/*/README.md and regenerates the corresponding man/coredns-<name>.7. The conversion uses pandoc per the Makefile rules. Run after editing any plugin README:

make -f Makefile.doc

The make.doc workflow runs this in CI and fails on diff.

Linters and formatters

.golangci.yml (v2 config) enables a focused set of linters:

  • gofmt for formatting (the source of truth)
  • revive for many style rules — context-as-argument, error-naming, error-strings, errorf, indent-error-flow, range, unused-parameter, use-any
  • staticcheck, govet/nilness
  • gosec (skipped in tests)
  • prealloc, wastedassign, unused, intrange, modernize
  • nakedret, whitespace
  • nolintlint, protogetter, canonicalheader, copyloopvar, durationcheck, godoclint
  • perfsprint (skipped in tests), thelper, unconvert, usetesting

Local invocation:

golangci-lint run

Some revive rules are intentionally disabled (empty-block, redefines-builtin-id, time-naming, unexported-return). These mirror long-standing codebase conventions; don't re-enable them in a one-off PR.

Code generation

Two generators live at the top level (directives_generate.go, owners_generate.go) with //go:build ignore tags so they don't compile into the binary. coredns.go references them via go:generate. See Build and code generation for what each one produces.

Plugin man pages

man/ contains one coredns-<plugin>.7 per plugin plus coredns.1 and corefile.5. They are generated from the corresponding README.md (or, for the latter two, from coredns.1.md / corefile.5.md in the repo root). The man page generation is the only reason every plugin needs a README.md.

CI workflows

.github/workflows/:

Workflow Purpose
go.test.yml go test -race ./... across a Go version matrix
golangci-lint.yml Runs golangci-lint run
verify-make-gen.yml Runs make gen and fails on diff
make.doc.yml Runs make -f Makefile.doc and fails on diff
cifuzz.yml OSS-Fuzz harness invocation on PR diffs
codeql-analysis.yml GitHub CodeQL static analysis
scorecards.yml OSSF Scorecard badge data
trivy-scan.yaml Container image scanning
release.yml Cuts release artifacts on tag push
docker.yml Docker image builds
depsreview.yml Dependency-review on PRs
stale.yml Auto-close stale issues/PRs
yamllint.yml YAML linting

What each workflow checks

  • go.test.yml — green when go test -race ./... passes. Failures are usually races in cache/forward/kubernetes or transport-test flakes.
  • golangci-lint.yml — green when the linters pass. Often surfaces unused imports or error-strings violations on new code.
  • verify-make-gen.yml — green when core/plugin/zplugin.go and core/dnsserver/zdirectives.go are up to date. Runs make gen and asserts no diff.
  • make.doc.yml — green when man/coredns-<name>.7 matches the regenerated content.
  • cifuzz.yml — green when fuzz harnesses don't find a regression on the diff.
  • codeql-analysis.yml — green when CodeQL doesn't find a new high-severity issue.

The PR template asks contributors to confirm they've run the relevant tests and updated documentation; CI enforces the rest.

Dependabot and bots

.github/dependabot.yml opens daily PRs for gomod, github-actions, and Docker base images. Roughly one third of repository commits come from Dependabot (see By the numbers). The coredns-auto-go-mod-tidy[bot] opens follow-up PRs to run go mod tidy after Dependabot's mass updates.

The Dreck bot (configured in .dreck.yaml) handles comment-driven label/assignee changes on issues and PRs.

Release artifacts

Makefile.release cross-compiles binaries for Linux, macOS, FreeBSD, and Windows on amd64/arm64, packages them into tar.gz and zip, and signs them. The release.yml workflow uploads everything to the corresponding GitHub release. Docker images are pushed by docker.yml.

Local Docker dev

make -f Makefile.docker

Builds an image tagged coredns:latest from the top-level Dockerfile. Useful for confirming the binary still builds in the same environment used by the release.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Tooling – CoreDNS wiki | Factory