Create abstract client steps infrastracture to externalize the ap modules client configurations#6965
Conversation
|
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
|
We detected some changes at Caution DO NOT create changesets for features which you do not wish to be included in the public changelog of the next CLI release. |
| FlattenedRemoteSpecification | ||
|
|
||
| // Not all the specs are moved to remote definition yet | ||
| merged.clientSteps ??= localSpec.clientSteps ?? [] |
There was a problem hiding this comment.
Is this necessary? :thinking_face:
when merging in the previous step, is remoteSpec setting this to undefined? or is it preserving the localSpec value?
| interface StepResult { | ||
| readonly id: string | ||
| readonly success: boolean | ||
| readonly duration: number | ||
| readonly output?: unknown | ||
| readonly error?: Error | ||
| } |
There was a problem hiding this comment.
We should be more strict with this type:
type StepResult = StepError | StepSuccess
interface StepResultMetadata {
readonly id: string
readonly duration: number
}
type StepError = StepResultMetadata & {
readonly success: false
readonly error: Error
}
type StepSuccess = StepResultMetadata & {
readonly success: true
readonly output: unknown
}Which can also me simplified into:
type StepResult = {
readonly id: string
readonly duration: number
} & ({
readonly success: false
readonly error: Error
} | {
readonly success: true
readonly output: unknown
})| * The full client steps configuration for an extension. | ||
| * Replaces the old buildConfig contract. | ||
| */ | ||
| export type ClientSteps = ReadonlyArray<ClientLifecycleGroup> |
There was a problem hiding this comment.
is a bit weird that ClientSteps is not array of ClientStep, but an array of ClientLifecycleGroupthat then contains an array of ClientStep :thinking_face:
Not sure if we should find a different name for either ClientSteps or ClientStep
| type BuildMode = 'copy_files' | 'theme' | 'function' | 'ui' | 'tax_calculation' | 'hosted_app_home' | 'none' | ||
|
|
||
| interface BuildConfig { | ||
| mode: BuildMode | ||
| filePatterns?: string[] | ||
| ignoredFilePatterns?: string[] | ||
| } |
There was a problem hiding this comment.
Why this change? is it necessary? it is technically wrong to express the type like this (with optional patterns for every mode)
16768f3 to
59f0139
Compare
59f0139 to
f9f9e63
Compare
7b68eb7 to
c3ee349
Compare
f9f9e63 to
59dcaa7
Compare
| case 'validate': | ||
| case 'transform': | ||
| case 'custom': | ||
| throw new Error(`Build step type "${step.type}" is not yet implemented.`) |
There was a problem hiding this comment.
Step router makes all step types unusable (always throws)
executeStepByType explicitly throws for every declared step type (including include_assets, bundle_ui, bundle_theme, etc.), so the new ClientSteps pipeline cannot execute any step successfully.
Evidence:
case 'include_assets':
...
throw new Error(`Build step type "${step.type}" is not yet implemented.`)Impact:
- Any runtime path using
clientStepswill fail during build/deploy. - CI/build pipelines will error; deploys could be blocked broadly once enabled.
|
These findings are in files not modified by this PR and cannot be posted as inline comments.
The integration test calls Evidence: await executeStep({ ..., type: 'include_assets', ... }, context)
...
expect(await fileExists(joinPath(outputDir, 'logo.png'))).toBe(true)Impact:
|
| success: true, | ||
| duration: Date.now() - startTime, | ||
| output, | ||
| } |
There was a problem hiding this comment.
BuildContext.stepResults is never written to, despite being part of the contract
BuildContext includes stepResults: Map<string, StepResult> and ClientStep.id is described as the “key in the stepResults map”, but executeStep never stores the produced result into context.stepResults. This breaks intended pipeline behavior (later steps can’t inspect prior outputs/errors) and can cause subtle bugs once steps depend on previous results.
|
🤖 Code Review · #projects-dev-ai for questions ✅ Complete - No issues 📋 History❌ Failed → ❌ Failed → ❌ Failed → ✅ 2 findings → ✅ No issues → ❌ Failed → ❌ Failed → ✅ No issues → ✅ No issues |
59dcaa7 to
fb4c01d
Compare
|
These findings are in files not modified by this PR and cannot be posted as inline comments.
BuildConfig.mode includes 'hosted_app_home', but ExtensionInstance.build() does not handle it. The extension may not be built, producing missing artifacts. Impact: Specs setting mode=hosted_app_home can lead to deploy failures or missing runtime resources. |
fb4c01d to
68f4751
Compare
24fb214 to
ecf7d0f
Compare
9257821 to
596be94
Compare
596be94 to
e088f88
Compare
Coverage report
Test suite run success3795 tests passing in 1452 suites. Report generated by 🧪jest coverage report action from b42a87b |
…ules client configurations
e088f88 to
b42a87b
Compare
| export function createConfigExtensionSpecification<TConfiguration extends BaseConfigType = BaseConfigType>(spec: { | ||
| identifier: string | ||
| schema: ZodSchemaType<TConfiguration> | ||
| clientSteps?: ClientSteps |
There was a problem hiding this comment.
is clientSteps meant to eventually replace buildconfig or are we intending to support both?
| readonly extension: ExtensionInstance | ||
| readonly options: ExtensionBuildOptions | ||
| readonly stepResults: Map<string, StepResult> | ||
| [key: string]: unknown |
There was a problem hiding this comment.
ideally outputs are not unknown if there is a finite amount of valid steps
| * Context passed through the step pipeline. | ||
| * Each step can read from and write to the context. | ||
| */ | ||
| export interface BuildContext { |
There was a problem hiding this comment.
i'm unclear on why an additional stateful context is necessary. can we not iterate through the steps just using the data already available and the step i/o?

WHY are these changes introduced?
This introduces a new client-side build pipeline system to replace the existing buildConfig approach for extensions. The current system is limited and doesn't provide enough flexibility for complex build scenarios.
WHAT is this pull request doing?
ClientStepsinterface that defines build steps as configuration objects with execution handled separatelyBuildContextto pass data through the step pipeline and store resultsbuild_function,build_theme,bundle_theme, andbundle_uioperationsinclude_assetsstep type with support for pattern-based and config-key-based file inclusionsExtensionSpecificationto include optionalclientStepsfield alongside existingbuildConfigbuildForBundlemethod to handle app config extensions differently by using the extension UID as the output pathfilePatternsandignoredFilePatternsare not definedHow to test your changes?
clientStepsconfigurationinclude_assetsstep with both pattern and configKey inclusion typescontinueOnErrorflagbuildConfigcontinue to work unchangedMeasuring impact
How do we know this change was effective? Please choose one:
Checklist