hashicorp/terraform
Development workflow
The day-to-day cycle of building, testing, and submitting a change to Terraform Core.
One-time setup
git clone https://github.com/hashicorp/terraform.git
cd terraform
go install . # builds the binary
go test ./... # baseline run; ensures the working tree is cleanThe first go install downloads ~1100 module dependencies. Allow a few minutes the first time.
The inner loop
- Branch.
git checkout -b descriptive-branch-name. There's no enforced naming convention, but maintainers tend to use<author>/<short-description>orfix-<issue-number>. - Edit, build, test. While iterating on one package:
Most contributors keep the failing tests in scope and run only those:go install . # rebuild the CLI go test ./internal/terraform/... # run the relevant testsgo test ./internal/terraform -run TestContext2Plan_someCase -v - Format and vet. The repo enforces
gofmt,goimports,go vet,staticcheck, andexhaustive:make fmtcheck make importscheck make vetcheck make staticcheck make exhaustive - Copyright headers. New files need HashiCorp's copyright headers. The script applies them:
make copyrightfix - Generated code. If you change anything that uses
go:generate(string-enum stringers, mocks), run:
For protobuf changes, runmake generatemake protobuf(requiresprotoc).
CHANGELOG entry
If your change is user-facing, generate an entry:
npx changie newThis prompts for kind/description/PR number and writes the YAML into .changes/v1.XX/. Pick the version that matches version/VERSION on main.
If the change is not user-facing, label the PR no-changelog-needed once it's open. CI will fail if neither a change entry nor that label is present.
Pre-PR checklist
Before pushing:
go test ./... # full suite
make fmtcheck importscheck # linters
make vetcheck staticcheck # static analysis
make exhaustive # exhaustive enum-switch checker
make copyright # report missing/outdated headersIf you've touched anything that lives behind a build tag (e.g. Solaris-specific files in internal/command/console_interactive_solaris.go), rebuild on the relevant platform or rely on CI to surface the failure.
Pushing and opening a PR
git push -u origin <branch>Open the PR via the GitHub UI. Required pieces:
- A description that explains why and links the issue you discussed the change in.
- A passing test for any user-visible behavior.
- The change-file from
npx changie new(or theno-changelog-neededlabel). - A CLA signature on first contribution; the bot will leave a comment.
CI runs unit tests, lint checks, the changelog check, and a Vercel preview that won't work for external PRs (ignore the failure — maintainers do).
Working with branches and backports
If your change should ship in a patch release, add the appropriate 1.XX-backport label. Maintainers handle the actual backport. Place the change file in .changes/v1.XX/ for the earliest targeted version.
Working from a fork
When your work depends on changes that haven't merged yet:
git remote add upstream git@github.com:hashicorp/terraform.git
git fetch upstream
git rebase upstream/mainRebasing rather than merging keeps the eventual squash-merge clean.
Common cleanups before review
go mod tidyafter anygo get.- Re-running
make generateif you touchedgo:generatedirectives. - Removing left-over
fmt.Printlndebugging — the project usestfdiagsfor user-visible messages and the standardlogpackage (with[DEBUG]/[TRACE]prefixes) for tracing. - Updating fixture testdata if the test file references new files.
For the conventions used inside the code itself — tfdiags, the view layer, expression evaluation patterns — see patterns and conventions.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.