From 673c4f7d5aef19beef2772baa8415130e64534eb Mon Sep 17 00:00:00 2001 From: Vinay P Date: Thu, 18 Mar 2021 13:23:30 +0000 Subject: [PATCH] Allow overriding cookiecutter's docker imageName .. to allow running custom-built images that have cookiecutter installed alongwith extensions, for example. https://cookiecutter.readthedocs.io/en/1.7.2/advanced/template_extensions.html related to: https://github.com/backstage/backstage/pull/4956#discussion_r596846365 Signed-off-by: Vinay P --- .../cookiecutter-with-jinja2-extensions/README.md | 14 ++++++++++++-- .../actions/builtin/fetch/cookiecutter.test.ts | 2 ++ .../actions/builtin/fetch/cookiecutter.ts | 8 ++++++++ .../scaffolder/stages/templater/cookiecutter.ts | 5 +++-- 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/contrib/docker/cookiecutter-with-jinja2-extensions/README.md b/contrib/docker/cookiecutter-with-jinja2-extensions/README.md index 6b990f77a3..470694513a 100644 --- a/contrib/docker/cookiecutter-with-jinja2-extensions/README.md +++ b/contrib/docker/cookiecutter-with-jinja2-extensions/README.md @@ -39,9 +39,19 @@ jinja2_custom_filters_extension==0.0.2 #### Using a Cookiecutter Docker image -If the scaffolder doesn't find a local Cookiecutter, it pulls down the `spotify/backstage-cookiecutter` image. You can create a custom Cookiecutter image based on that, install extensions into it, and use that instead. See for example, the [`Dockerfile`](./Dockerfile) in this directory. +If the scaffolder doesn't find a local Cookiecutter, it pulls down the `spotify/backstage-cookiecutter` image. You can create a custom Cookiecutter image based on that, install extensions into it, and specify that customised image as an input `imageName` to the `fetch:cookiecutter` action: -**Note:** The [`imageName`](https://github.com/vinayvinay/backstage/blob/37e35b91/plugins/scaffolder-backend/src/scaffolder/stages/templater/cookiecutter.ts#L77) that gets pulled isn't currently configurable. So, for the time being, you might have to customise the `scaffolder-backend` plugin to fetch your customised Cookiecutter Docker image. +```yaml +steps: + - id: fetch-base + name: Fetch Base + action: fetch:cookiecutter + input: + url: https://github.com/spotify/cookiecutter-golang + imageName: 'foo/custom-built-cookiecutter-image-with-extensions' +``` + +See for example, the [`Dockerfile`](./Dockerfile) in this directory. ### Instructing Cookiecutter to use the extension diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/cookiecutter.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/cookiecutter.test.ts index 940c0f1e08..628107155d 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/cookiecutter.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/cookiecutter.test.ts @@ -117,6 +117,7 @@ describe('fetch:cookiecutter', () => { extensions: [ 'jinja2_custom_filters_extension.string_filters_extension.StringFilterExtension', ], + imageName: 'foo/cookiecutter-image-with-extensions', }, }); @@ -130,6 +131,7 @@ describe('fetch:cookiecutter', () => { _extensions: [ 'jinja2_custom_filters_extension.string_filters_extension.StringFilterExtension', ], + imageName: 'foo/cookiecutter-image-with-extensions', }, }); }); diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/cookiecutter.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/cookiecutter.ts index 404d134f6d..fca791c7bd 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/cookiecutter.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/cookiecutter.ts @@ -39,6 +39,7 @@ export function createFetchCookiecutterAction(options: { values: JsonObject; copyWithoutRender?: string[]; extensions?: string[]; + imageName?: string; }>({ id: 'fetch:cookiecutter', description: @@ -83,6 +84,12 @@ export function createFetchCookiecutterAction(options: { type: 'string', }, }, + imageName: { + title: 'Cookiecutter Docker image', + description: + "Specify a custom Docker image to run cookiecutter, to override the default: 'spotify/backstage-cookiecutter'. This can be used to execute cookiecutter with Template Extensions. Used only when a local cookiecutter is not found.", + type: 'string', + }, }, }, }, @@ -121,6 +128,7 @@ export function createFetchCookiecutterAction(options: { ...(ctx.input.values as TemplaterValues), _copy_without_render: ctx.input.copyWithoutRender, _extensions: ctx.input.extensions, + imageName: ctx.input.imageName, }; // Will execute the template in ./template and put the result in ./result diff --git a/plugins/scaffolder-backend/src/scaffolder/stages/templater/cookiecutter.ts b/plugins/scaffolder-backend/src/scaffolder/stages/templater/cookiecutter.ts index f0fbf4a708..e60c5efb4d 100644 --- a/plugins/scaffolder-backend/src/scaffolder/stages/templater/cookiecutter.ts +++ b/plugins/scaffolder-backend/src/scaffolder/stages/templater/cookiecutter.ts @@ -52,9 +52,10 @@ export class CookieCutter implements TemplaterBase { // First lets grab the default cookiecutter.json file const cookieCutterJson = await this.fetchTemplateCookieCutter(templateDir); + const { imageName, ...valuesForCookieCutterJson } = values; const cookieInfo = { ...cookieCutterJson, - ...values, + ...valuesForCookieCutterJson, }; await fs.writeJSON(path.join(templateDir, 'cookiecutter.json'), cookieInfo); @@ -74,7 +75,7 @@ export class CookieCutter implements TemplaterBase { }); } else { await runDockerContainer({ - imageName: 'spotify/backstage-cookiecutter', + imageName: imageName || 'spotify/backstage-cookiecutter', args: [ 'cookiecutter', '--no-input',