diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/TaskWorker.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/TaskWorker.ts index 4a09149bab..1e038ba65e 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/TaskWorker.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/TaskWorker.ts @@ -117,6 +117,7 @@ export class TaskWorker { const tmpDirs = new Array(); await action.handler({ + baseUrl: task.spec.baseUrl, logger: taskLogger, logStream: stream, parameters, diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/types.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/types.ts index d7f2e6e51f..42d8179a3e 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/types.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/types.ts @@ -45,6 +45,7 @@ export type DbTaskEventRow = { }; export type TaskSpec = { + baseUrl?: string; values: JsonObject; steps: Array<{ id: string; @@ -116,6 +117,11 @@ export interface TaskStore { } export type ActionContext = { + /** + * Base URL for the location of the task spec, typically the url of the source entity file. + */ + baseUrl?: string; + logger: Logger; logStream: Writable; diff --git a/plugins/scaffolder-backend/src/service/helpers.ts b/plugins/scaffolder-backend/src/service/helpers.ts index dd3d43c6d1..905d85c35d 100644 --- a/plugins/scaffolder-backend/src/service/helpers.ts +++ b/plugins/scaffolder-backend/src/service/helpers.ts @@ -18,6 +18,11 @@ import os from 'os'; import fs from 'fs-extra'; import { Logger } from 'winston'; import { Config } from '@backstage/config'; +import { + Entity, + LOCATION_ANNOTATION, + SOURCE_LOCATION_ANNOTATION, +} from '@backstage/catalog-model'; export async function getWorkingDirectory( config: Config, @@ -42,3 +47,34 @@ export async function getWorkingDirectory( } return workingDirectory; } + +/** + * Gets the base URL of the entity location that points to the source location + * of the entity description within a repo. If there is not source location + * or if it has an invalid type, undefined will be returned instead. + * + * For file locations this will return a `file://` URL. + */ +export function getEntityBaseUrl(entity: Entity): string | undefined { + let location = entity.metadata.annotations?.[SOURCE_LOCATION_ANNOTATION]; + if (!location) { + location = entity.metadata.annotations?.[LOCATION_ANNOTATION]; + } + if (!location) { + return undefined; + } + + const [type, url] = location.split(/:(.+)/); + if (!url) { + return undefined; + } + + if (type === 'url') { + return url; + } else if (type === 'file') { + return `file://${url}`; + } + // Only url and file location are handled, as we otherwise don't know if + // what the url is pointing to makes sense to use as a baseUrl + return undefined; +} diff --git a/plugins/scaffolder-backend/src/service/router.ts b/plugins/scaffolder-backend/src/service/router.ts index db5ab28064..79ae70d694 100644 --- a/plugins/scaffolder-backend/src/service/router.ts +++ b/plugins/scaffolder-backend/src/service/router.ts @@ -41,7 +41,7 @@ import { import { templateEntityToSpec } from '../scaffolder/tasks/TemplateConverter'; import { TemplateActionRegistry } from '../scaffolder/tasks/TemplateActionRegistry'; import { registerLegacyActions } from '../scaffolder/stages/legacy'; -import { getWorkingDirectory } from './helpers'; +import { getEntityBaseUrl, getWorkingDirectory } from './helpers'; import { InputError, NotFoundError, @@ -351,7 +351,10 @@ export async function createRouter( } } + const baseUrl = getEntityBaseUrl(template); + taskSpec = { + baseUrl, values, steps: template.spec.steps.map((step, index) => ({ ...step,