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 <mail@vinayvinay.com>
This commit is contained in:
Vinay P
2021-03-18 13:23:30 +00:00
parent 3105b46afa
commit 673c4f7d5a
4 changed files with 25 additions and 4 deletions
@@ -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
@@ -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',
},
});
});
@@ -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
@@ -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',