Repository navigation
Resolve bundle extends at build time - #258
Merged
Merged
Conversation
A bundle can name a parent with extends: <bundle>@<constraint>. Build, lint, and publish pull the newest matching parent, merge the child's identity, dependencies, and app wiring over it, and publish one ordinary bundle carrying the parent's IaC, so application developers keep a single massdriver.yaml instead of cloning a bundle per app. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
coryodaniel
commented
Oct 8, 2026
| mass bundle build [path] [flags] | ||
| ``` | ||
|
|
||
| ## Extending a bundle |
Member
Author
There was a problem hiding this comment.
Extending shouldn't be the 'default' docs explanation. Include a regular build/publish example and we'll put the extending in docs.massdriver.cloud.
coryodaniel
commented
Oct 8, 2026
coryodaniel
commented
Oct 8, 2026
coryodaniel
commented
Oct 8, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Leaves room for per-resource settings later without breaking published bundles. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A bundle opts in with provides_runtime: true and an app block; an application names it with extends_runtime. Applications cannot run on other applications, and a bundle cannot be both. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
provides is a closed set the catalog can rely on; each value carries its own publish rules. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The other values are deferred until their names are settled. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Runtimes are often leaf nodes with nothing to emit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Scalar and null values for unlisted keys were copied over the runtime's, so `params:` alone wiped the runtime's params. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
chrisghill
approved these changes
Oct 19, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements the CLI side of massdriver-cloud/massdriver#3516. Backend validation and the
providesAPI field land in the paired massdriver PR; docs in massdriver-cloud/docs#235.New functionality
provides: an optional top-level key listing what a bundle offers.runtimeis the only accepted value; other values are deferred until their names are settled.provideslint (mass bundle lint/publish):runtimeand setapp.runtimeapp.runtime: <runtime>@<constraint>.build,lint, andpublishresolve the newest matching runtime, pull it, check it, and merge the application onto it. The result publishes as an ordinary bundle.runtime, not setapp.runtimeitself, and usedependencies/resourcesrather than legacyconnections/artifacts.steps,params,ui, itsresources, and the IaCname,version(required, semver),description,source_url,schema,provides,dependencies,resources,steps, andapp(runtime,envs,secretsonly);name,description,source_url, andschemamust be strings; any other key, including a null likeparams:, fails the builddependencies,app.envs,app.secrets, andresourcesare added to the runtime's; any name collision failsprovides, never the runtime'sapp.envsmust reference params and dependencies in the merged bundle; reading an optional dependency warnsREADME.md,CHANGELOG.md,icon.svg,operator.mdfrom the application replace the runtime'sresourcesand binds each to a runtime step with a jq template atsteps[].resources.<name>.template. Templates stay in the publishedmassdriver.yamlfor the backend to render after the step applies.massdriver.yamlpinsapp.runtimeto the exact runtime version it was built on, e.g.lambda@~1.2becomeslambda@1.2.7.buildassembles into<application>/.massdriver/build/(git-ignored);lintandpublishuse a temp dir. Bundles withoutapp.runtimeare untouched.publishreturns errors on lint failure instead ofos.Exit(1), so the temp build directory is cleaned up.Examples
A runtime:
An application that runs on it and emits its own resource:
Published
app.runtime:Rejected:
Notes
Bundles.Get("name@constraint"), the same resolver deploys use, rather thanociRepo.releaseChannels: the dev-channel SQL there ordersversion_pre_release ASC, so~X+devchannels point at the oldest dev build.🤖 Generated with Claude Code