Skip to content

Commit 3b2fa61

Browse files
feat: add remote cache provider setup to the create-app command (#551)
* feat: add remote cache provider setup to the create-app command * chore: refactor remote provider config gen for easier setup * fix: tests * feat: better defaults * fix: tests * feat: better hints * feat: add optional endpoint param to s3 args * added a changeset * simplify github token flow; fix providerGitHub name * add templates * add deprecation warning for github-actions * fix: tests for s3 templates * fix: rename repo to repository * fix: args.endpoint is always returned but as undefined when empty * feat: add notes on env viariables when prompting prodiver args * nits --------- Co-authored-by: Michał Pierzchała <[email protected]>
1 parent b7a14a3 commit 3b2fa61

File tree

14 files changed

+332
-59
lines changed

14 files changed

+332
-59
lines changed

.changeset/sixty-cases-fry.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'create-rock': patch
3+
---
4+
5+
feat: add remote cache provider setup

packages/config/src/lib/config.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,13 @@ export async function getConfig(
172172
getRemoteCacheProvider: async () => {
173173
// special case for github-actions
174174
if (validatedConfig.remoteCacheProvider === 'github-actions') {
175+
logger.warnOnce('github-actions')(
176+
`Using shorthand "github-actions" as "remoteCacheProvider" value in ${colorLink(
177+
'rock.config.mjs',
178+
)} is deprecated. It will be removed in future releases.
179+
Please use "@rock-js/provider-github" plugin explicitly instead.
180+
Read more: ${colorLink('https://rockjs.dev/docs/configuration#github-actions-provider')}`,
181+
);
175182
const { providerGitHub } = await import('@rock-js/provider-github');
176183
return providerGitHub();
177184
}

packages/create-app/src/lib/__tests__/bin.test.ts

Lines changed: 81 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ test('should format config without plugins', () => {
1515
ios: platformIOS(),
1616
android: platformAndroid(),
1717
},
18-
remoteCacheProvider: null,
1918
};
2019
"
2120
`);
@@ -33,7 +32,7 @@ test('should format config with plugins', () => {
3332
},
3433
];
3534

36-
expect(formatConfig([PLATFORMS[0]], plugins, BUNDLERS[1], 'github-actions'))
35+
expect(formatConfig([PLATFORMS[0]], plugins, BUNDLERS[1], null))
3736
.toMatchInlineSnapshot(`
3837
"import { platformIOS } from '@rock-js/platform-ios';
3938
import { pluginTest } from '@rock-js/plugin-test';
@@ -47,7 +46,86 @@ test('should format config with plugins', () => {
4746
platforms: {
4847
ios: platformIOS(),
4948
},
50-
remoteCacheProvider: 'github-actions',
49+
};
50+
"
51+
`);
52+
});
53+
54+
test(`should format config with the 'github-actions' provider`, () => {
55+
expect(
56+
formatConfig([PLATFORMS[0]], null, BUNDLERS[1], {
57+
name: 'github-actions',
58+
args: { owner: 'custom-owner', repository: 'repository-name' },
59+
}),
60+
).toMatchInlineSnapshot(`
61+
"import { platformIOS } from '@rock-js/platform-ios';
62+
import { pluginRepack } from '@rock-js/plugin-repack';
63+
import { providerGitHub } from '@rock-js/provider-github';
64+
65+
export default {
66+
bundler: pluginRepack(),
67+
platforms: {
68+
ios: platformIOS(),
69+
},
70+
remoteCacheProvider: providerGitHub({
71+
owner: 'custom-owner',
72+
repository: 'repository-name',
73+
}),
74+
};
75+
"
76+
`);
77+
});
78+
79+
test(`should format config with the 's3' provider`, () => {
80+
expect(
81+
formatConfig([PLATFORMS[0]], null, BUNDLERS[1], {
82+
name: 's3',
83+
args: { bucket: 'custom-bucket', region: 'us-east-1' },
84+
}),
85+
).toMatchInlineSnapshot(`
86+
"import { platformIOS } from '@rock-js/platform-ios';
87+
import { pluginRepack } from '@rock-js/plugin-repack';
88+
import { providerS3 } from '@rock-js/provider-s3';
89+
90+
export default {
91+
bundler: pluginRepack(),
92+
platforms: {
93+
ios: platformIOS(),
94+
},
95+
remoteCacheProvider: providerS3({
96+
bucket: 'custom-bucket',
97+
region: 'us-east-1',
98+
}),
99+
};
100+
"
101+
`);
102+
});
103+
104+
test(`should format config with the 's3' provider using a custom endpoint`, () => {
105+
expect(
106+
formatConfig([PLATFORMS[0]], null, BUNDLERS[1], {
107+
name: 's3',
108+
args: {
109+
bucket: 'custom-bucket',
110+
region: 'us-east-1',
111+
endpoint: 'https://custom-endpoint.com',
112+
},
113+
}),
114+
).toMatchInlineSnapshot(`
115+
"import { platformIOS } from '@rock-js/platform-ios';
116+
import { pluginRepack } from '@rock-js/plugin-repack';
117+
import { providerS3 } from '@rock-js/provider-s3';
118+
119+
export default {
120+
bundler: pluginRepack(),
121+
platforms: {
122+
ios: platformIOS(),
123+
},
124+
remoteCacheProvider: providerS3({
125+
bucket: 'custom-bucket',
126+
region: 'us-east-1',
127+
endpoint: 'https://custom-endpoint.com',
128+
}),
51129
};
52130
"
53131
`);

packages/create-app/src/lib/bin.ts

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import {
1616
BUNDLERS,
1717
PLATFORMS,
1818
PLUGINS,
19+
remoteCacheProviderToConfigTemplate,
20+
remoteCacheProviderToImportTemplate,
1921
resolveTemplate,
2022
TEMPLATES,
2123
} from './templates.js';
@@ -46,6 +48,7 @@ import {
4648
promptPlugins,
4749
promptProjectName,
4850
promptRemoteCacheProvider,
51+
promptRemoteCacheProviderArgs,
4952
promptTemplate,
5053
} from './utils/prompts.js';
5154
import {
@@ -146,6 +149,10 @@ export async function run() {
146149
? null
147150
: await promptRemoteCacheProvider();
148151

152+
const remoteCacheProviderArgs = remoteCacheProvider
153+
? await promptRemoteCacheProviderArgs(remoteCacheProvider)
154+
: null;
155+
149156
const shouldInstallDependencies =
150157
options.install || isInteractive()
151158
? await promptInstallDependencies()
@@ -172,7 +179,12 @@ export async function run() {
172179
platforms,
173180
plugins,
174181
bundler,
175-
remoteCacheProvider,
182+
remoteCacheProvider && remoteCacheProviderArgs
183+
? {
184+
name: remoteCacheProvider,
185+
args: remoteCacheProviderArgs,
186+
}
187+
: null,
176188
);
177189
loader.stop('Applied template, platforms and plugins.');
178190

@@ -296,7 +308,10 @@ function createConfig(
296308
platforms: TemplateInfo[],
297309
plugins: TemplateInfo[] | null,
298310
bundler: TemplateInfo,
299-
remoteCacheProvider: SupportedRemoteCacheProviders | null,
311+
remoteCacheProvider: {
312+
name: SupportedRemoteCacheProviders;
313+
args: Record<string, string>;
314+
} | null,
300315
) {
301316
const rockConfig = path.join(absoluteTargetDir, 'rock.config.mjs');
302317
fs.writeFileSync(
@@ -309,40 +324,54 @@ export function formatConfig(
309324
platforms: TemplateInfo[],
310325
plugins: TemplateInfo[] | null,
311326
bundler: TemplateInfo,
312-
remoteCacheProvider: SupportedRemoteCacheProviders | null,
327+
remoteCacheProvider: {
328+
name: SupportedRemoteCacheProviders;
329+
args: Record<string, string>;
330+
} | null,
313331
) {
314332
const platformsWithImports = platforms.filter(
315333
(template) => template.importName,
316334
);
317335
const pluginsWithImports = plugins
318336
? plugins.filter((template) => template.importName)
319337
: null;
320-
return `${[...platformsWithImports, ...(pluginsWithImports ?? []), bundler]
321-
.map(
338+
339+
return `${[
340+
...[...platformsWithImports, ...(pluginsWithImports ?? []), bundler].map(
322341
(template) =>
323342
`import { ${template.importName} } from '${template.packageName}';`,
324-
)
343+
),
344+
remoteCacheProvider?.name
345+
? remoteCacheProviderToImportTemplate(remoteCacheProvider.name)
346+
: '',
347+
]
348+
.filter(Boolean)
325349
.join('\n')}
326350
327-
export default {${
351+
export default {
352+
${[
328353
pluginsWithImports && pluginsWithImports.length > 0
329-
? `
330-
plugins: [
354+
? `plugins: [
331355
${pluginsWithImports
332356
.map((template) => `${template.importName}(),`)
333357
.join('\n ')}
334358
],`
335-
: ''
336-
}
337-
bundler: ${bundler.importName}(),
338-
platforms: {
359+
: '',
360+
`bundler: ${bundler.importName}(),`,
361+
`platforms: {
339362
${platformsWithImports
340363
.map((template) => `${template.name}: ${template.importName}(),`)
341364
.join('\n ')}
342-
},
343-
remoteCacheProvider: ${
344-
remoteCacheProvider === null ? null : `'${remoteCacheProvider}'`
345-
},
365+
},`,
366+
remoteCacheProvider?.name
367+
? remoteCacheProviderToConfigTemplate(
368+
remoteCacheProvider.name,
369+
remoteCacheProvider.args,
370+
)
371+
: '',
372+
]
373+
.filter(Boolean)
374+
.join('\n ')}
346375
};
347376
`;
348377
}

packages/create-app/src/lib/templates.ts

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import * as path from 'node:path';
2-
import { resolveAbsolutePath } from '@rock-js/tools';
2+
import {
3+
resolveAbsolutePath,
4+
type SupportedRemoteCacheProviders,
5+
} from '@rock-js/tools';
36

47
export type TemplateInfo = NpmTemplateInfo | LocalTemplateInfo;
58

@@ -93,6 +96,58 @@ export const PLATFORMS: TemplateInfo[] = [
9396
},
9497
];
9598

99+
export function remoteCacheProviderToImportTemplate(
100+
provider: SupportedRemoteCacheProviders,
101+
) {
102+
switch (provider) {
103+
case 'github-actions':
104+
return `import { providerGitHub } from '@rock-js/provider-github';`;
105+
case 's3':
106+
return `import { providerS3 } from '@rock-js/provider-s3';`;
107+
}
108+
}
109+
110+
export function remoteCacheProviderToConfigTemplate(
111+
provider: SupportedRemoteCacheProviders,
112+
args: Record<string, string>,
113+
) {
114+
switch (provider) {
115+
case 'github-actions':
116+
return template([
117+
'remoteCacheProvider: providerGitHub({',
118+
` owner: '${args['owner']}',`,
119+
` repository: '${args['repository']}',`,
120+
'}),',
121+
]);
122+
case 's3':
123+
return template([
124+
'remoteCacheProvider: providerS3({',
125+
` bucket: '${args['bucket']}',`,
126+
` region: '${args['region']}',`,
127+
[` endpoint: '${args['endpoint']}',`, Boolean(args['endpoint'])],
128+
'}),',
129+
]);
130+
}
131+
}
132+
133+
export function template(lines: Array<string | [string, boolean]>) {
134+
return lines
135+
.filter((line) => {
136+
// If it's a [content, condition] pair, check the condition
137+
if (Array.isArray(line)) {
138+
return Boolean(line[1]);
139+
}
140+
// If it's just a string, always include it
141+
return true;
142+
})
143+
.map((line) => {
144+
// Extract content from [content, condition] pair or use string directly
145+
const content = Array.isArray(line) ? line[0] : line;
146+
return content;
147+
})
148+
.join('\n ');
149+
}
150+
96151
export function resolveTemplate(
97152
templates: TemplateInfo[],
98153
name: string,

0 commit comments

Comments
 (0)