Skip to content

Asset pipeline flow for hosted static app#6806

Open
elanalynn wants to merge 2 commits intomainfrom
proj-48450/asset-pipeline-for-hosted-apps
Open

Asset pipeline flow for hosted static app#6806
elanalynn wants to merge 2 commits intomainfrom
proj-48450/asset-pipeline-for-hosted-apps

Conversation

@elanalynn
Copy link
Contributor

@elanalynn elanalynn commented Jan 30, 2026

WHY are these changes introduced?

Related to Hosted app project.

Related to https://github.com/shop/world/pull/382743

Closes https://github.com/shop/issues-admin-extensibility/issues/2186

WHAT is this pull request doing?

This PR introduces the asset pipeline flow for hosted static apps, enabling static asset copying during the build process.

  • New hosted_app specification (app_config_hosted_app_home.ts): Adds a configuration extension specification for hosted apps with a static_root field
  • New static_app build mode: Extends the build config modes to include static_app, which triggers static asset copying
  • Enhanced config extension specifications:
    • Added optional buildConfig and copyStaticAssets parameters to createConfigExtensionSpecification()
    • Config extensions can now define custom build behavior

How it works

When a hosted app defines a static_root in its configuration:

  1. The hosted_app specification is loaded with build mode static_app
  2. During build, copyStaticAssets() is invoked
  3. Contents from the configured static_root directory are copied to the output directory

How to test your changes?

  • Configure a hosted app with static_root pointing to a static assets directory
  • Run shopify app deploy and verify assets are copied to the output directory - .shopify/deploy-bundle
  • Verify deploy works when static_root is not specified
  • TODO: Verify appropriate error handling when source directory doesn't exist

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

@github-actions
Copy link
Contributor

github-actions bot commented Jan 30, 2026

Coverage report

St.
Category Percentage Covered / Total
🟡 Statements 78.8% 14511/18415
🟡 Branches 73.13% 7214/9865
🟡 Functions 79.01% 3690/4670
🟡 Lines 79.14% 13718/17334

Test suite run success

3783 tests passing in 1455 suites.

Report generated by 🧪jest coverage report action from 66deccf

@elanalynn elanalynn force-pushed the proj-48450/asset-pipeline-for-hosted-apps branch from e165a9d to 5b7340f Compare January 30, 2026 22:26
@alfonso-noriega alfonso-noriega force-pushed the proj-48450/asset-pipeline-for-hosted-apps branch from cd9fc6e to 4dd73b7 Compare February 10, 2026 16:01
Copy link
Contributor

alfonso-noriega commented Feb 10, 2026

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

@elanalynn elanalynn force-pushed the proj-48450/asset-pipeline-for-hosted-apps branch 2 times, most recently from 4a80cd2 to ae0d089 Compare February 13, 2026 16:36
@elanalynn elanalynn marked this pull request as ready for review February 13, 2026 16:37
@elanalynn elanalynn requested a review from a team as a code owner February 13, 2026 16:37
@github-actions
Copy link
Contributor

We detected some changes at packages/*/src and there are no updates in the .changeset.
If the changes are user-facing, run pnpm changeset add to track your changes and include them in the next release CHANGELOG.

Caution

DO NOT create changesets for features which you do not wish to be included in the public changelog of the next CLI release.

@elanalynn
Copy link
Contributor Author

/snapit

@github-actions
Copy link
Contributor

🫰✨ Thanks @elanalynn! Your snapshot has been published to npm.

Test the snapshot by installing your package globally:

npm i -g --@shopify:registry=https://registry.npmjs.org @shopify/cli@0.0.0-snapshot-20260222203314

Caution

After installing, validate the version by running shopify version in your terminal.
If the versions don't match, you might have multiple global instances installed.
Use which shopify to find out which one you are running and uninstall it.

@alfonso-noriega alfonso-noriega force-pushed the proj-48450/asset-pipeline-for-hosted-apps branch 2 times, most recently from ff3f4e0 to 635fedb Compare February 25, 2026 16:39
@JoshuaWhite1 JoshuaWhite1 force-pushed the proj-48450/asset-pipeline-for-hosted-apps branch from 635fedb to d296cb0 Compare February 26, 2026 23:44
copyStaticAssets: async (config, directory, outputPath) => {
if (!config.static_root) return
const sourceDir = joinPath(directory, config.static_root)
const outputDir = dirname(outputPath)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Validate static_root to prevent path traversal/arbitrary file copying

static_root is taken directly from config and joined into sourceDir (joinPath(directory, config.static_root)). If misconfigured or attacker-controlled, values like ../.., absolute paths, or symlinks can escape the app directory and copy arbitrary filesystem contents into the deploy bundle. This is risky even if developer-controlled (CI agents often have adjacent secrets). Recursive copy may amplify impact, especially if symlinks are followed.

@binks-code-reviewer
Copy link

binks-code-reviewer bot commented Feb 27, 2026

🤖 Code Review · #projects-dev-ai for questions
React with 👍/👎 or reply — all feedback helps improve the agent.

Complete - No issues

📋 History

✅ 1 findings → ✅ 1 findings → ✅ No issues

@alfonso-noriega alfonso-noriega force-pushed the proj-48450/asset-pipeline-for-hosted-apps branch from d296cb0 to 635fedb Compare February 27, 2026 08:39

return copyDirectoryContents(sourceDir, outputDir).catch((error) => {
throw new Error(`Failed to copy static assets from ${sourceDir} to ${outputDir}: ${error.message}`)
})

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Catch handler assumes error.message exists and can mask root cause

The catch handler assumes error has a .message field. If the underlying promise rejects with a non-Error (string/object), this code can throw a secondary error (e.g., reading message), masking the original failure.

Evidence:

.catch((error) => {
  throw new Error(`...: ${error.message}`)
})

Impact:

  • Failures become harder to debug; incorrect/noisy diagnostics.

@alfonso-noriega alfonso-noriega force-pushed the proj-48450/asset-pipeline-for-hosted-apps branch from 635fedb to 66deccf Compare February 27, 2026 11:33
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.

2 participants