A friendly CLI tool for testing and rendering Crossplane compositions locally. Think of it as your local playground for Crossplane - you can test your compositions without needing a running cluster or dealing with complex setups.
crossbench uses the same battle-tested code from Crossplane's official render command, so you get identical behavior and results. Perfect for CI/CD pipelines, local development, or debugging compositions before deploying them.
- Auto-discover functions - It automatically figures out which functions your composition needs and fetches the right pkg versions from crossplane AND/OR upbound repositories.
- More to come...
Install crossbench using Homebrew:
brew tap gjbravi/crossbench https://github.com/gjbravi/crossbench.git
brew install crossbenchOr install directly:
brew install gjbravi/crossbench/crossbenchYou can also install directly using Go:
go install github.com/gjbravi/crossbench@latestThis will install crossbench to your $GOPATH/bin (or ~/go/bin by default). Make sure that's in your PATH!
If you prefer to build it yourself:
git clone https://github.com/gjbravi/crossbench.git
cd crossbench
go build -o crossbench .Then move the crossbench binary somewhere in your PATH, or use it directly with ./crossbench.
Out of the box, crossbench works great with sensible defaults. But if you want to customize things (like cache behavior, package registries, or GitHub settings), you can use environment variables.
If you want to customize anything, copy the example config file:
cp .env.example .env
# Then edit .env with your preferencesCache Settings:
CROSSBENCH_CACHE_EXPIRATION- How long cached versions stay valid (default:24h)CROSSBENCH_CACHE_DIR- Where to store the cache (default:~/.crossbench)CROSSBENCH_CACHE_FILENAME- Cache filename (default:function-versions.json)
GitHub API Settings:
CROSSBENCH_GITHUB_API_URL- GitHub API URL (default:https://api.github.com)CROSSBENCH_GITHUB_API_TIMEOUT- Request timeout (default:10s)CROSSBENCH_GITHUB_TOKEN- Your GitHub token (optional - it'll usegh auth tokenautomatically if you're logged in)
Package Registry Settings:
CROSSBENCH_DEFAULT_GITHUB_OWNER- Default GitHub org (default:crossplane-contrib)CROSSBENCH_DEFAULT_PACKAGE_REGISTRY- Where functions are published (default:xpkg.crossplane.io)CROSSBENCH_UPBOUND_PACKAGE_REGISTRY- Upbound registry URL (default:xpkg.upbound.io)CROSSBENCH_UPBOUND_FUNCTIONS- Functions using Upbound registry (default:function-unit-test)
Check out .env.example for all the details and examples!
At its core, crossbench needs two things: your composite resource (XR) and your composition:
crossbench render <composite-resource> <composition> [functions]The functions argument is optional - if you don't provide it, crossbench will automatically:
- Look at your composition's pipeline
- Figure out which functions you're using
- Fetch the latest versions from GitHub
- Use them to render your composition
Pretty neat, right? You can also provide a functions.yaml file if you want specific versions or need to work offline.
We've included some example files to get you started. Try this:
cd testdata
# Let crossbench figure out the functions automatically
crossbench render xr.yaml composition.yaml
# Or be explicit about which functions to use
crossbench render xr.yaml composition.yaml functions.yamlBoth commands do the same thing, but the first one is easier - crossbench handles the function discovery for you!
Just render a composition:
crossbench render xr.yaml composition.yamlTest with existing resources (simulate an update scenario):
crossbench render xr.yaml composition.yaml \
--observed-resources=existing-resources.yamlPass environment context to functions:
crossbench render xr.yaml composition.yaml \
--context-values=apiextensions.crossplane.io/environment='{"env": "production"}'Include extra resources that functions might need:
crossbench render xr.yaml composition.yaml \
--extra-resources=extra-resources.yamlProvide credentials for functions that need them:
crossbench render xr.yaml composition.yaml \
--function-credentials=credentials.yamlForce refresh cached function versions:
crossbench render xr.yaml composition.yaml --refresh-cachePro tip: Run crossbench render --help to see all options with descriptions!
Nobody likes hitting API rate limits. That's why crossbench caches function versions.
Simple and straightforward:
- First time: Fetches from GitHub and saves to cache
- Within 24 hours: Uses cached versions
- After 24 hours: Fetches fresh version from GitHub and updates cache
- If rate limited: Falls back to cached version (even if expired) so you can keep working
That's it! One check per day per function.
Force refresh everything:
crossbench render xr.yaml composition.yaml --refresh-cacheClear cache manually:
rm ~/.crossbench/function-versions.jsonCustomize cache location:
Set CROSSBENCH_CACHE_DIR in your .env file to store cache somewhere else.
Change cache expiration:
Set CROSSBENCH_CACHE_EXPIRATION in your .env file (default: 24h).
This project uses packages from the Crossplane project, which is licensed under the Apache License 2.0.