pulumi/pulumi
Tooling
The build, lint, and codegen tools that ship with the repo.
Tool version manager: mise
.mise.toml pins every external tool version: Go, Node, Python, .NET, protoc, golangci-lint, gofumpt, jq, dlv, gow, and a handful of npm-distributed Go-replacements. Install with mise, then either mise activate (recommended) or prefix every command with mise exec --.
If mise is not available, you'll need to install matching tool versions manually — drift causes real bugs (e.g. mismatched protoc produces non-reproducible generated code).
Build system: GNU make + Go
The top-level Makefile is mostly orchestration. Heavy lifting lives in:
build/common.mk— shared targets imported byMakefile.- Per-SDK
Makefiles (sdk/nodejs/Makefile,sdk/python/Makefile,sdk/go/Makefile). proto/generate.sh— actual proto codegen invocation.
bin/helpmakego is a tiny tool checked in pre-built (well, built on first make ensure) that's used by sub-targets to discover Go module roots.
Linters
| Tool | Targets | Config |
|---|---|---|
golangci-lint 2.9.0 |
All Go | .golangci.yml + .golangci/ (custom plugins) |
gofumpt |
All Go | (no config — opinionated) |
biome |
TS, JSON | sdk/nodejs/biome.json |
eslint |
Node SDK only | sdk/nodejs/.eslintrc.js |
ruff |
Python | pyproject.toml per Python package |
buf/protoc |
.proto |
proto/generate.sh |
A custom requiredfield linter (go.abhg.dev/requiredfield, pinned to v0.8.0 in .mise.toml) enforces that required struct fields are populated in literals — useful for engine code where a forgotten field is a silent bug.
make lint runs everything. make lint_fix auto-fixes; make format runs only the formatters.
Code generators
Proto codegen
proto/generate.sh regenerates Go, Node, and Python proto bindings. Triggered by make build_proto. Inputs: proto/*.proto and proto/grpc_version.txt. Outputs:
sdk/proto/go/sdk/nodejs/proto/sdk/python/lib/pulumi/runtime/proto/
CI gate: make check_proto (Makefile) — fails the build if regenerated output differs from what's committed.
SDK type generators
sdk/go/pulumi/generate/ produces sdk/go/pulumi/types_builtins.go and types_builtins_test.go (~480 KB and ~435 KB respectively). The Node SDK has equivalent generation helpers, though most of its surface is hand-written.
CLI specification
make generate-cli-spec runs the CLI with a hidden flag to dump every command/flag/argument into tools/automation/specification.json. The Automation API SDKs use that spec to generate their public interfaces:
sdk/nodejs/tools/automation/→sdk/nodejs/automation/interface/sdk/python/tools/automation/→sdk/python/lib/pulumi/automation/interface/
Schema codegen
pkg/codegen/{go,nodejs,python}/ consume the pulumi.json schema (or any provider's schema) and emit a typed SDK. Programgen (PCL → user-language) is implemented in the same packages. Tests use golden files under pkg/codegen/testdata/ and accept new fixtures via PULUMI_ACCEPT=1.
CI/CD
GitHub Actions; workflows live in .github/workflows/. The big ones:
| Workflow | When | What |
|---|---|---|
ci.yml |
every PR / push | The full matrix: build, lint, test_all across OS × language |
ci-build-binaries.yml |
builds | Cross-platform CLI binaries |
ci-build-sdks.yml |
builds | Per-language SDK packages |
ci-run-test.yml |
reusable | Test runner |
ci-lint.yml |
every PR | Lint matrix |
ci-performance-gate.yml |
every PR | Benchmarks vs baseline |
release.yml |
tags | Goreleaser-driven release |
release-pr.yml |
tags | Auto-PR for go.mod cleanups + changelog |
cron-test-all.yml |
schedule | Nightly full test run |
cron-direct-build.yml |
schedule | Build matrix without tests |
Goreleaser config: .goreleaser.yml (artifacts) and scripts/prep-for-goreleaser.sh.
Renovate keeps dependencies fresh; config at renovate.json5. Renovate-issued PRs land with the pulumi-renovate[bot] author.
Documentation builds
docs/ is a Sphinx project (docs/sphinx/, docs/make.py, docs/pyproject.toml). It's published to ReadTheDocs (config: .readthedocs.yaml). Build locally:
cd docs
uv run python make.py buildInternal markdown lives in docs/architecture/, docs/contributing/, docs/debugging/, etc., and references source code via :::{toctree} directives.
Editor configuration
.vscode/— recommended VS Code settings..devcontainer/— Codespaces / Devcontainer setup..envrc.template— template for direnv users.
There is no enforced editor; .editorconfig would be a fine PR.
See also
- Patterns and conventions
- Apps: CLI for what the build actually produces.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.