Skip to content

Commit 3a92d03

Browse files
authored
Merge pull request #7481 from Shopify/fix/theme-push-fresh-dynamic-source-defaults
Upload settings_schema.json before validator-consumer assets
2 parents 5837ad2 + fad7904 commit 3a92d03

5 files changed

Lines changed: 71 additions & 40 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@shopify/theme': patch
3+
---
4+
5+
Upload `config/settings_schema.json` before any other theme file. Fixes `theme push` failing on the first push when blocks or sections reference a `color_palette` theme setting.

packages/theme/src/cli/utilities/theme-fs.test.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,8 @@ describe('theme-fs', () => {
473473
otherLiquidFiles,
474474
templateJsonFiles,
475475
otherJsonFiles,
476-
configFiles,
476+
configSchemaFile,
477+
configDataFile,
477478
staticAssetFiles,
478479
contextualizedJsonFiles,
479480
blockLiquidFiles,
@@ -489,10 +490,8 @@ describe('theme-fs', () => {
489490
])
490491
expect(otherJsonFiles).toEqual([{key: 'locales/en.default.json', checksum: '6'}])
491492
expect(templateJsonFiles).toEqual([{key: 'templates/404.json', checksum: '7'}])
492-
expect(configFiles).toEqual([
493-
{key: 'config/settings_schema.json', checksum: '8'},
494-
{key: 'config/settings_data.json', checksum: '9'},
495-
])
493+
expect(configSchemaFile).toEqual([{key: 'config/settings_schema.json', checksum: '8'}])
494+
expect(configDataFile).toEqual([{key: 'config/settings_data.json', checksum: '9'}])
496495
expect(staticAssetFiles).toEqual([
497496
{key: 'assets/base.css', checksum: '1'},
498497
{key: 'assets/sparkle.gif', checksum: '3'},
@@ -511,15 +510,23 @@ describe('theme-fs', () => {
511510
const files: Checksum[] = []
512511

513512
// When
514-
const {sectionLiquidFiles, otherLiquidFiles, templateJsonFiles, otherJsonFiles, configFiles, staticAssetFiles} =
515-
partitionThemeFiles(files)
513+
const {
514+
sectionLiquidFiles,
515+
otherLiquidFiles,
516+
templateJsonFiles,
517+
otherJsonFiles,
518+
configSchemaFile,
519+
configDataFile,
520+
staticAssetFiles,
521+
} = partitionThemeFiles(files)
516522

517523
// Then
518524
expect(sectionLiquidFiles).toEqual([])
519525
expect(otherLiquidFiles).toEqual([])
520526
expect(templateJsonFiles).toEqual([])
521527
expect(otherJsonFiles).toEqual([])
522-
expect(configFiles).toEqual([])
528+
expect(configSchemaFile).toEqual([])
529+
expect(configDataFile).toEqual([])
523530
expect(staticAssetFiles).toEqual([])
524531
})
525532
})

packages/theme/src/cli/utilities/theme-fs.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ const THEME_PARTITION_REGEX = {
4444
layoutLiquidRegex: /^layout\/.+\.liquid$/,
4545
sectionLiquidRegex: /^sections\/.+\.liquid$/,
4646
blockLiquidRegex: /^blocks\/.+\.liquid$/,
47-
configRegex: /^config\/(settings_schema|settings_data)\.json$/,
47+
configSchemaRegex: /^config\/settings_schema\.json$/,
48+
configDataRegex: /^config\/settings_data\.json$/,
4849
sectionJsonRegex: /^sections\/.+\.json$/,
4950
templateJsonRegex: /^templates\/.+\.json$/,
5051
jsonRegex: /^(?!config\/).*\.json$/,
@@ -465,7 +466,8 @@ export function partitionThemeFiles<T extends {key: string}>(files: T[]) {
465466
const templateJsonFiles: T[] = []
466467
const otherJsonFiles: T[] = []
467468
const contextualizedJsonFiles: T[] = []
468-
const configFiles: T[] = []
469+
const configSchemaFile: T[] = []
470+
const configDataFile: T[] = []
469471
const staticAssetFiles: T[] = []
470472
const blockLiquidFiles: T[] = []
471473
const layoutFiles: T[] = []
@@ -482,8 +484,10 @@ export function partitionThemeFiles<T extends {key: string}>(files: T[]) {
482484
} else {
483485
otherLiquidFiles.push(file)
484486
}
485-
} else if (THEME_PARTITION_REGEX.configRegex.test(fileKey)) {
486-
configFiles.push(file)
487+
} else if (THEME_PARTITION_REGEX.configSchemaRegex.test(fileKey)) {
488+
configSchemaFile.push(file)
489+
} else if (THEME_PARTITION_REGEX.configDataRegex.test(fileKey)) {
490+
configDataFile.push(file)
487491
} else if (THEME_PARTITION_REGEX.jsonRegex.test(fileKey)) {
488492
if (THEME_PARTITION_REGEX.contextualizedJsonRegex.test(fileKey)) {
489493
contextualizedJsonFiles.push(file)
@@ -506,7 +510,8 @@ export function partitionThemeFiles<T extends {key: string}>(files: T[]) {
506510
templateJsonFiles,
507511
contextualizedJsonFiles,
508512
otherJsonFiles,
509-
configFiles,
513+
configSchemaFile,
514+
configDataFile,
510515
staticAssetFiles,
511516
blockLiquidFiles,
512517
layoutFiles,

packages/theme/src/cli/utilities/theme-uploader.test.ts

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -319,17 +319,19 @@ describe('theme-uploader', () => {
319319
await renderThemeSyncProgress()
320320

321321
// Then
322-
expect(bulkUploadThemeAssets).toHaveBeenCalledTimes(9)
322+
expect(bulkUploadThemeAssets).toHaveBeenCalledTimes(10)
323323
// Minimum theme files start first
324324
expect(bulkUploadThemeAssets).toHaveBeenNthCalledWith(1, remoteTheme.id, MINIMUM_THEME_ASSETS, adminSession)
325-
// Dependent assets start second
325+
// settings_schema.json is uploaded first among dependent files so block / section /
326+
// section-group / template validators can resolve dynamic-source defaults that
327+
// reference theme-level settings declared in the schema.
326328
expect(bulkUploadThemeAssets).toHaveBeenNthCalledWith(
327329
2,
328330
remoteTheme.id,
329-
[{key: 'layout/theme.liquid'}],
331+
[{key: 'config/settings_schema.json'}],
330332
adminSession,
331333
)
332-
// Independent assets start right after dependent assets start
334+
// Independent assets fan out concurrently with the dependent chain.
333335
expect(bulkUploadThemeAssets).toHaveBeenNthCalledWith(
334336
3,
335337
remoteTheme.id,
@@ -346,16 +348,22 @@ describe('theme-uploader', () => {
346348
],
347349
adminSession,
348350
)
349-
// Dependent assets continue after the first batch of dependent assets ends
351+
// Layout files come after the schema is in place.
350352
expect(bulkUploadThemeAssets).toHaveBeenNthCalledWith(
351353
4,
352354
remoteTheme.id,
353-
[{key: 'blocks/block.liquid'}],
355+
[{key: 'layout/theme.liquid'}],
354356
adminSession,
355357
)
356358
expect(bulkUploadThemeAssets).toHaveBeenNthCalledWith(
357359
5,
358360
remoteTheme.id,
361+
[{key: 'blocks/block.liquid'}],
362+
adminSession,
363+
)
364+
expect(bulkUploadThemeAssets).toHaveBeenNthCalledWith(
365+
6,
366+
remoteTheme.id,
359367
[
360368
{
361369
key: 'sections/header.liquid',
@@ -365,7 +373,7 @@ describe('theme-uploader', () => {
365373
)
366374

367375
expect(bulkUploadThemeAssets).toHaveBeenNthCalledWith(
368-
6,
376+
7,
369377
remoteTheme.id,
370378
[
371379
{
@@ -376,7 +384,7 @@ describe('theme-uploader', () => {
376384
)
377385

378386
expect(bulkUploadThemeAssets).toHaveBeenNthCalledWith(
379-
7,
387+
8,
380388
remoteTheme.id,
381389
[
382390
{
@@ -387,7 +395,7 @@ describe('theme-uploader', () => {
387395
)
388396

389397
expect(bulkUploadThemeAssets).toHaveBeenNthCalledWith(
390-
8,
398+
9,
391399
remoteTheme.id,
392400
[
393401
{
@@ -397,17 +405,11 @@ describe('theme-uploader', () => {
397405
adminSession,
398406
)
399407

408+
// settings_data.json must be last
400409
expect(bulkUploadThemeAssets).toHaveBeenNthCalledWith(
401-
9,
410+
10,
402411
remoteTheme.id,
403-
[
404-
{
405-
key: 'config/settings_data.json',
406-
},
407-
{
408-
key: 'config/settings_schema.json',
409-
},
410-
],
412+
[{key: 'config/settings_data.json'}],
411413
adminSession,
412414
)
413415
})

packages/theme/src/cli/utilities/theme-uploader.ts

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,8 @@ function orderFilesToBeDeleted(files: Checksum[]): Checksum[] {
213213
...fileSets.blockLiquidFiles,
214214
...fileSets.layoutFiles,
215215
...fileSets.otherLiquidFiles,
216-
...fileSets.configFiles,
216+
...fileSets.configDataFile,
217+
...fileSets.configSchemaFile,
217218
...fileSets.staticAssetFiles,
218219
]
219220
}
@@ -311,13 +312,23 @@ function selectUploadableFiles(themeFileSystem: ThemeFileSystem, remoteChecksums
311312
* We use this 2d array to batch files of the same type together
312313
* while maintaining the order between file types. The files with
313314
* dependencies we have are:
314-
* 1. Layout files don't necessarily need to be the first, but they must uploaded before templates.
315-
* 2. Liquid blocks need to be uploaded before sections
316-
* 3. Liquid sections need to be uploaded afterwards
317-
* 4. JSON sections need to be uploaded after sections
318-
* 5. JSON templates need to be uploaded after all sections and layouts
319-
* 6. Contextualized templates should be uploaded after as they are variations of templates
320-
* 7. Config files must be the last ones, but we need to upload config/settings_schema.json first, followed by config/settings_data.json
315+
*
316+
* 1. config/settings_schema.json must be uploaded FIRST. It declares the
317+
* theme-level settings that block / section / section-group / template
318+
* validators resolve dynamic-source defaults against (e.g. defaults of
319+
* the form `{{ settings.<theme_setting>.<property> }}`).
320+
* 2. Layout files don't necessarily need to be the first, but they must be
321+
* uploaded before templates.
322+
* 3. Liquid blocks need to be uploaded before sections
323+
* 4. Liquid sections need to be uploaded afterwards
324+
* 5. JSON sections need to be uploaded after sections
325+
* 6. JSON templates need to be uploaded after all sections and layouts
326+
* 7. Contextualized templates should be uploaded after as they are
327+
* variations of templates
328+
* 8. config/settings_data.json must be uploaded LAST. Its current and
329+
* presets are validated against the freshly-uploaded
330+
* settings_schema.json, and presets can reference sections and
331+
* templates uploaded in earlier steps.
321332
*
322333
* The files with no dependencies we have are:
323334
* - The other Liquid files (for example, snippets, and liquid templates)
@@ -336,13 +347,14 @@ function orderFilesToBeUploaded(files: ChecksumWithSize[]): {
336347
independentFiles: [fileSets.otherLiquidFiles, fileSets.otherJsonFiles, fileSets.staticAssetFiles],
337348
// Follow order of dependencies:
338349
dependentFiles: [
350+
fileSets.configSchemaFile,
339351
fileSets.layoutFiles,
340352
fileSets.blockLiquidFiles,
341353
fileSets.sectionLiquidFiles,
342354
fileSets.sectionJsonFiles,
343355
fileSets.templateJsonFiles,
344356
fileSets.contextualizedJsonFiles,
345-
fileSets.configFiles,
357+
fileSets.configDataFile,
346358
],
347359
}
348360
}

0 commit comments

Comments
 (0)