Skip to content

Abstract build steps to externalize the build configuration#6866

Draft
alfonso-noriega wants to merge 1 commit intoproj-48450/asset-pipeline-for-hosted-appsfrom
01-build-steps-infrastructure
Draft

Abstract build steps to externalize the build configuration#6866
alfonso-noriega wants to merge 1 commit intoproj-48450/asset-pipeline-for-hosted-appsfrom
01-build-steps-infrastructure

Conversation

@alfonso-noriega
Copy link
Contributor

@alfonso-noriega alfonso-noriega commented Feb 19, 2026

WHY are these changes introduced?

Fixes #0000

Build steps pipeline infrastructure

Introduces a declarative, data-driven pipeline for executing extension build steps. This is the foundational layer that the next two PRs in the stack build on.

Problem

Previously, each extension's build logic was hardcoded imperatively inside extension-instance.ts:build() via a large switch on the extension type. Adding a new extension type meant touching
core infrastructure. Build behaviour was also untestable in isolation — you couldn't verify what an extension "would do" at build time without running the full build.

Solution

A typed pipeline where build logic is expressed as configuration, not code. Each extension declares an ordered list of BuildStep objects. The pipeline engine reads that config and
dispatches to the right executor. Because steps are plain data, they are:

  • Serializable to JSON — build configs can be sent over the wire or stored externally
  • Independently testable — each step executor is a pure function, tested in isolation
  • Composable — extensions can combine steps (e.g. bundle then copy assets)
  • Extensible — new step types are added to the router without touching existing specs

Architecture

BuildConfig (spec declares this)
  └─ steps: BuildStep[]          ← plain serializable config objects
       └─ type, id, config{...}

executeBuildSteps(extension, stepsConfig, options)
  └─ for each step: executeStep(step, context)
       └─ executeStepByType(step, context)   ← router/dispatcher
            ├─ 'copy_files'        → executeCopyFilesStep
            ├─ 'build_theme'       → executeBuildThemeStep
            ├─ 'bundle_theme'      → executeBundleThemeStep
            ├─ 'bundle_ui'         → executeBundleUIStep
            ├─ 'copy_static_assets'→ executeCopyStaticAssetsStep
            ├─ 'build_function'    → executeBuildFunctionStep
            └─ 'create_tax_stub'   → executeCreateTaxStubStep

The BuildContext is threaded through every step — it carries the extension instance, build options (stdout/stderr), an abort signal, and a stepResults map so later steps can read outputs
from earlier ones.

Step configuration reference

copy_files — the most flexible step

Supports two strategies, selected via the strategy field.

strategy: 'files' — explicit file list

Each entry is one of:

Entry shape Behaviour
{source: 'path'} Copy directory contents into the output root
{source: 'path', destination: 'out/file'} Copy a single file to an explicit destination
{tomlKey: 'static_root'} Resolve the path from the extension's TOML config, then copy that directory's contents
{
  id: 'copy-static-assets',
  type: 'copy_files',
  config: {
    strategy: 'files',
    definition: {
      files: [
        {tomlKey: 'static_root'},                          // path resolved from TOML at build time
        {source: 'icons', destination: 'assets/icons'},    // explicit destination
      ],
    },
  },
}

Dot-notation is supported for nested paths ('nested.field'), and array-of-tables are automatically plucked across all entries.

strategy: 'pattern' — glob-based selection from a source directory

Field Type Description
source string Subdirectory inside the extension dir to glob from
patterns string[] Glob patterns (default **/*)
ignore string[] Patterns to exclude
destination string Output subdirectory (default: output root)
preserveStructure boolean Keep relative paths (default true)
{
  id: 'copy-files',
  type: 'copy_files',
  config: {
    strategy: 'pattern',
    definition: {
      source: 'specifications',
      patterns: ['**/*.json', '**/*.toml', '**/*.yaml', '**/*.svg'],
    },
  },
}

Other step types

These wrap the existing build functions and require no additional config beyond {}:

Type What it does
build_theme Runs buildThemeExtension
bundle_theme Runs bundleThemeExtension
bundle_ui Runs buildUIExtension
copy_static_assets Calls extension.copyStaticAssets()
build_function Runs buildFunctionExtension
create_tax_stub Writes the (()=>{})(); output stub

Step execution behaviour

BuildStep field Default Description
continueOnError false If true, a failed step is recorded but the pipeline continues
stopOnError (on BuildConfig) true If false, all steps run regardless of failures

Measuring impact

How do we know this change was effective? Please choose one:

  • n/a - this doesn't need measurement, e.g. a linting rule or a bug-fix
  • Existing analytics will cater for this addition
  • PR includes analytics changes to measure impact

Checklist

  • I've considered possible cross-platform impacts (Mac, Linux, Windows)
  • I've considered possible documentation changes

Copy link
Contributor Author

alfonso-noriega commented Feb 19, 2026

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.
Learn more

This stack of pull requests is managed by Graphite. Learn more about stacking.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 19, 2026

Coverage report

St.
Category Percentage Covered / Total
🟡 Statements 78.84% 14658/18591
🟡 Branches 73.16% 7268/9935
🟡 Functions 79.01% 3720/4708
🟡 Lines 79.2% 13861/17502

Test suite run success

3809 tests passing in 1473 suites.

Report generated by 🧪jest coverage report action from 34005f5

@alfonso-noriega alfonso-noriega force-pushed the 01-build-steps-infrastructure branch 2 times, most recently from c4c3353 to d2a2b21 Compare February 19, 2026 13:05
@alfonso-noriega alfonso-noriega force-pushed the proj-48450/asset-pipeline-for-hosted-apps branch from 510502e to f9f6e10 Compare February 19, 2026 13:27
@alfonso-noriega alfonso-noriega force-pushed the 01-build-steps-infrastructure branch 5 times, most recently from feab6d2 to 27b8cfc Compare February 19, 2026 14:33
@alfonso-noriega alfonso-noriega force-pushed the 01-build-steps-infrastructure branch from 27b8cfc to 34005f5 Compare February 19, 2026 15:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

Comments