diff --git a/.changeset/scaffolder-source-of-truth.md b/.changeset/scaffolder-source-of-truth.md new file mode 100644 index 0000000000..43ea2ff954 --- /dev/null +++ b/.changeset/scaffolder-source-of-truth.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend': patch +--- + +The `catalog:write` action now automatically adds a `backstage.io/template-source` annotation, indicating which Scaffolder template was used to create the entity. diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.test.ts index cc22b75da2..658e4365bf 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.test.ts @@ -94,4 +94,34 @@ describe('catalog:write', () => { yaml.stringify(entity), ); }); + + it('should add backstage.io/source-template if provided', async () => { + const entity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + name: 'n', + namespace: 'ns', + annotations: {}, + }, + spec: {}, + }; + + await action.handler({ + ...mockContext, + templateInfo: { entityRef: 'template:default/test-skeleton' }, + input: { entity }, + }); + + const expectedEntity = JSON.parse(JSON.stringify(entity)); + expectedEntity.metadata.annotations = { + 'backstage.io/source-template': 'template:default/test-skeleton', + }; + + expect(fsMock.writeFile).toHaveBeenCalledTimes(1); + expect(fsMock.writeFile).toHaveBeenCalledWith( + resolvePath(mockContext.workspacePath, 'catalog-info.yaml'), + yaml.stringify(expectedEntity), + ); + }); }); diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.ts index 3a11fcd946..27c39dd098 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.ts @@ -51,11 +51,25 @@ export function createCatalogWriteAction() { async handler(ctx) { ctx.logger.info(`Writing catalog-info.yaml`); const { filePath, entity } = ctx.input; + const entityRef = ctx.templateInfo?.entityRef; const path = filePath ?? 'catalog-info.yaml'; await fs.writeFile( resolveSafeChildPath(ctx.workspacePath, path), - yaml.stringify(entity), + yaml.stringify({ + ...entity, + metadata: { + ...entity.metadata, + ...(entityRef + ? { + annotations: { + ...entity.metadata.annotations, + 'backstage.io/source-template': entityRef, + }, + } + : undefined), + }, + }), ); }, });