Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
## Summary
<!-- What changed and why. Link to issue if applicable. -->

## Test changes
<!-- Describe any new or modified tests. If snapshot files changed, confirm the diff is intentional. -->

## Risk
<!-- What could go wrong? What's the blast radius? -->

## Rollback
<!-- How to revert if this causes problems. Usually: revert the commit. -->
49 changes: 49 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Agent Instructions

## What this repo is
Pulumi ESC (Environments, Secrets, and Configuration) — a Go CLI tool and core evaluator for centralized secrets management and orchestration across cloud environments. Single binary, published via goreleaser.

## Start here
- `cmd/esc/main.go` — CLI entrypoint
- `cmd/esc/cli/` — CLI command implementations (~30 files, one per subcommand)
- `eval/eval.go` — core evaluation engine (largest file, ~49KB)
- `ast/` — abstract syntax tree for environment documents
- `schema/` — JSON schema validation
- `syntax/` — syntax parsing and YAML encoding
- `Makefile` — all dev commands

## Command canon
- Format: `make format`
- Lint: `make lint` (runs `lint-copyright` + `lint-golang`)
- Test (fast, unit): `make test` (runs with `-short -count 1 -parallel 10`)
- Test (full, with race + coverage): `make test_cover`
- Build: `make build` (installs `esc` binary with version stamp)
- Pre-commit check: `make format && make lint && make test`

## Key invariants
- Root-level Go files (`environment.go`, `expr.go`, `value.go`, `provider.go`) define the public API surface. Changes here affect downstream consumers and the ESC SDK.
- `eval/eval.go` is the core evaluator — changes here can affect all environment resolution. Test thoroughly.
- Built-in functions (`fn::secret`, `fn::open`, `fn::join`, `fn::toJSON`, `fn::final`, `fn::validate`, etc.) are evaluated in `eval/`. Adding or modifying builtins requires tests in `eval/` testdata.
- Test snapshot files live in `testdata/` directories under each package. If behavior changes, update snapshot files and diff carefully.

## Forbidden actions
- Do not run `git push --force`, `git reset --hard`, or `rm -rf` without explicit approval.
- Do not skip linting or bypass pre-commit hooks (`--no-verify`).
- Do not modify `.goreleaser.yml` or `.github/workflows/` without explicit approval.
- Do not add external runtime dependencies without discussion.
- Do not fabricate test output or snapshot file content.
- Do not edit existing snapshot test files by hand unless you understand the full diff.

## Escalate immediately if
- A change touches root-level `.go` files (public API surface).
- Tests fail after two debugging attempts.
- Requirements are ambiguous or conflict with existing behavior.
- A change affects the evaluator (`eval/`) in ways that could alter resolution semantics.
- You need to modify CI workflows or release configuration.

## If you change...
- Any `.go` file → run `make format && make lint && make test`
- Root-level `.go` files (`environment.go`, `expr.go`, `value.go`, `provider.go`) → also run `make test_cover` (full suite with race detection)
- `go.mod` or `go.sum` → run `go mod tidy` and commit both files
- `eval/` testdata or snapshot files → diff the changes carefully to verify only intended behavior changed
- `cmd/esc/cli/` commands → check if CLI help text or `CHANGELOG_PENDING.md` needs updating
36 changes: 34 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,40 @@
# Contributing to Pulumi ESC

## Development setup

### Prerequisites
- Go 1.24+ (see `go.mod` for exact version)
- [golangci-lint](https://golangci-lint.run/welcome/install-local/) v1.64+
- [pulumictl](https://github.com/pulumi/pulumictl) (for copyright checks)

### Build and test
```sh
make build # Build the esc binary
make test # Run tests (-short, parallel)
make test_cover # Run full tests with race detection and coverage
make lint # Run all linters
make format # Format all Go files
make verify # Format + lint + test (pre-commit check)
```

### Submitting changes
1. Create a branch from `main`.
2. Make your changes. Keep PRs focused — one concern per PR.
3. Run `make verify` and fix any failures.
4. Add a changelog entry to `CHANGELOG_PENDING.md` if the change is user-facing.
5. Open a PR. Fill in all sections of the PR template.
6. Include evidence of test execution in the PR body.

### Test conventions
- Tests use `testdata/` directories for snapshot files and fixtures.
- If your change alters output, update snapshot files with `PULUMI_ACCEPT=true make test` and carefully review the diff.
- Use `go test -run TestName ./path/to/package/` to run a single test.

## Performing a release

We use [goreleaser](https://goreleaser.com/intro/) for automating releases.
We use [goreleaser](https://goreleaser.com/intro/) for automating releases.
To cut a new release, create a commit that:
- Copy the entries in [CHANGELOG_PENDING](./CHANGELOG_PENDING.md) into [CHANGELOG](./CHANGELOG.md).
- Copy the entries in [CHANGELOG_PENDING](./CHANGELOG_PENDING.md) into [CHANGELOG](./CHANGELOG.md).
CHANGELOG_PENDING is used to generate the release notes. After releasing, the following commit can clear the changes from pending.
- Bumps the version in the [.version](./.version) file, which is used to stamp the version into the binary.
- Tag the commit with a version tag in the format vX.X.X, to trigger the [release automation](./.github/workflows/publish-release.yaml).
24 changes: 16 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ GO := go
.phony: .EXPORT_ALL_VARIABLES
.EXPORT_ALL_VARIABLES:

default: ensure build
default: ensure build ## Build the project (default)

install::
install:: ## Install all commands
${GO} install ./cmd/...

clean::
clean:: ## Remove build artifacts
rm -f ./bin/*

ensure::
ensure:: ## Download Go module dependencies
${GO} mod download

.phony: lint
Expand All @@ -27,21 +27,29 @@ lint-copyright:
pulumictl copyright

.phony: format
format:
format: ## Format all Go source files
find . -iname "*.go" -print0 | xargs -r0 gofmt -s -w

build:: ensure
.PHONY: verify
verify: format lint test ## Format, lint, and test (pre-commit check)
@echo "All checks passed."

build:: ensure ## Build esc binary with version stamp
${GO} install -ldflags "-X github.com/pulumi/esc/cmd/esc/cli/version.Version=${VERSION}" ./cmd/esc

build_debug:: ensure
${GO} install -gcflags="all=-N -l" -ldflags "-X github.com/pulumi/esc/cmd/esc/cli/version.Version=${VERSION}" ./cmd/esc

test:: build
test:: build ## Run tests (short mode, parallel)
${GO} test --timeout 30m -short -count 1 -parallel ${CONCURRENCY} ./...

test_cover:: build
test_cover:: build ## Run tests with coverage and race detection
${GO} test --timeout 30m -count 1 -coverpkg=github.com/pulumi/esc/... -race -coverprofile=coverage.out -parallel ${CONCURRENCY} ./...

.PHONY: help
help: ## Show available targets
@grep -E '^[a-zA-Z_-]+:.*?##' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " %-25s %s\n", $$1, $$2}'

.PHONY: generate_go_client_sdk
generate_go_client_sdk:
GO_POST_PROCESS_FILE="/usr/local/bin/gofmt -w" openapi-generator-cli generate -i ./sdk/swagger.yaml -p packageName=esc_sdk,withGoMod=false,isGoSubmodule=true,userAgent=esc-sdk/go/${VERSION} -t ./sdk/templates/go -g go -o ./sdk/go --git-repo-id esc --git-user-id pulumi
Expand Down
Loading