pulumi/pulumi
Development workflow
The day-to-day loop for working on pulumi/pulumi.
Branching
- Pulumi employees push directly to branches on the main repo. Nest under your own prefix:
pulumipus/<feature>. - External contributors fork and push to a branch on the fork.
Inner loop for engine / CLI work
# 1. make changes
$EDITOR pkg/...
# 2. format + lint
mise exec -- make format
mise exec -- make lint
# 3. quick tests
mise exec -- make test_fast
# 4. focused tests
cd pkg && go test -count=1 -tags all -run TestSpecific ./engine/...
# 5. rebuild CLI to dogfood
mise exec -- make bin/pulumi
./bin/pulumi up # or whateverFor SDK changes you generally need to rebuild that SDK and make install it (Node) before integration tests pick it up.
Inner loop for SDK work
Node.js — sdk/nodejs/
cd sdk/nodejs
mise exec -- make build
mise exec -- make install # required before integration tests can yarn link
mise exec -- make test_fast
mise exec -- make lintPython — sdk/python/
cd sdk/python
mise exec -- make build
mise exec -- make lint
mise exec -- make test_fastGo — sdk/go/pulumi/
Go SDK tests run inside the regular Go module test infrastructure:
cd sdk
go test -count=1 ./go/pulumi/...Working across modules
pulumi/pulumi is multiple Go modules. To edit sdk/go/pulumi and pkg/... simultaneously without replace directives:
mise exec -- make work # generates a go.work filego.work is gitignored and required only locally.
Changelog entries
Every PR needs an entry unless it has impact/no-changelog-required. Generate one interactively:
mise exec -- make changelogThe interactive prompt asks for type (feat, fix, chore), scope (e.g. cli/state, sdk/python), and a one-line message. The result lands as a YAML file in changelog/pending/. The full vocabulary is in changelog/config.yaml.
Examples (active imperative, no trailing period):
- ✅ "Exit immediately from state edit when no change was made"
- ✅ "Fix root and program paths to always be absolute"
- ❌ "Fixes a bug" (passive, vague)
- ❌ "Adds a feature." (period, vague)
Pulling in upstream changes
The default branch is master. If you've been on a topic branch for a while:
git fetch origin
git rebase origin/master
# resolve conflicts
mise exec -- make tidy_fix # re-tidy go.mod across modules
mise exec -- make build_proto # if proto/ changedForce-push your branch (force-push to your own branch is fine; never to master).
Commit hygiene
Because PRs are squash-merged, individual commit messages within a PR are not preserved. Group commits however helps you most. The PR description is what ends up in the master log.
Code review expectations
- Reviewers focus on correctness, scope creep, and public-surface changes.
- Address every comment or explicitly say why you disagree.
- Keep PRs scoped to one feature/fix. Big multi-feature PRs are hard to review and revert.
- If you're using AI assistance, you're still responsible for the diff (see
CONTRIBUTING.md"AI-Assisted Contributions").
Releasing
Release plumbing is documented at the bottom of CONTRIBUTING.md. The short version: scripts/set-version.py bumps sdk/.version, the freeze PR seals the next draft release on the GitHub Releases page, and pulumi-bot follows up with a go.mod cleanup PR that auto-merges. End-users download via curl -fsSL https://get.pulumi.com | sh.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.