From 1540f623ac20850f44f1265507eca1e18a25336e Mon Sep 17 00:00:00 2001 From: Steve Keppeler Date: Mon, 13 May 2024 07:50:53 -0400 Subject: [PATCH] fix(launch): track instantiated commit * add function to allow author's to include additional data in options.json * store the commit hash at time of cloning * durning the ancestor phase of resynth use that hash to checkout the repository --- .../blueprints/blueprint/src/blueprint.ts | 27 +++++++++++-- .../launch-blueprint/src/blueprint.ts | 38 +++++++++++++++++-- 2 files changed, 57 insertions(+), 8 deletions(-) diff --git a/packages/blueprints/blueprint/src/blueprint.ts b/packages/blueprints/blueprint/src/blueprint.ts index 6d672158f..0824375e2 100644 --- a/packages/blueprints/blueprint/src/blueprint.ts +++ b/packages/blueprints/blueprint/src/blueprint.ts @@ -23,6 +23,7 @@ export interface Options extends ParentOptions {} export class Blueprint extends Project { public readonly context: Context; + private readonly OPTIONS_FILE = 'options.json'; protected strategies: StrategyLocations | undefined; /** * Set information used on the pull request generated by resynthesis @@ -39,8 +40,6 @@ export class Blueprint extends Project { name: 'CodeCatalystBlueprint', ...options, }); - - const OPTIONS_FILE = 'options.json'; const rootDir = path.resolve(this.outdir); this.context = { rootDir, @@ -59,7 +58,7 @@ export class Blueprint extends Project { project: { name: process.env.CONTEXT_PROJECTNAME, bundlepath: process.env.EXISTING_BUNDLE_ABS, - options: getOptions(path.join(process.env.EXISTING_BUNDLE_ABS || '', OPTIONS_FILE)), + options: getOptions(path.join(process.env.EXISTING_BUNDLE_ABS || '', this.OPTIONS_FILE)), blueprint: { instantiationId: process.env.CUR_INSTANTIATION_ID, instantiations: structureExistingBlueprints(process.env.INSTANTIATIONS_ABS), @@ -87,7 +86,7 @@ export class Blueprint extends Project { } // write the options to the bundle - const optionsRecordPath = path.join(this.outdir, OPTIONS_FILE); + const optionsRecordPath = path.join(this.outdir, this.OPTIONS_FILE); fs.mkdirSync(path.dirname(optionsRecordPath), { recursive: true }); fs.writeFileSync(optionsRecordPath, JSON.stringify(options, null, 2)); @@ -120,6 +119,26 @@ export class Blueprint extends Project { fs.writeFileSync(instantiationRecordPath, JSON.stringify(configurableOptions, null, 2)); } + /** + * Writes the provided `options` to the generated `options.json` file + * under `authorDefined` key. + * @param options + */ + augmentOptions(options: { [key: string]: any }) { + const optionsRecordPath = path.join(this.outdir, this.OPTIONS_FILE); + fs.writeFileSync( + optionsRecordPath, + JSON.stringify( + { + ...getOptions(optionsRecordPath), + authorDefined: options, + }, + null, + 2, + ), + ); + } + getResynthStrategies(bundlepath: string): Strategy[] { return (this.strategies || {})[bundlepath] || []; } diff --git a/packages/blueprints/launch-blueprint/src/blueprint.ts b/packages/blueprints/launch-blueprint/src/blueprint.ts index e89742cb5..d5139e094 100644 --- a/packages/blueprints/launch-blueprint/src/blueprint.ts +++ b/packages/blueprints/launch-blueprint/src/blueprint.ts @@ -117,12 +117,42 @@ export class Blueprint extends ParentBlueprint { timeout: GIT_CLONE_TIMEOUT, }); - // remove .git - we have no use for it and the large number of objects - // contained within it could slow down the copying of sources to our workspace - fs.rmSync(path.join(pathToRepository, '.git'), { recursive: true, force: true }); + if (this.context.resynthesisPhase === 'PROPOSED') { + const revParse = cp.spawnSync('git', ['rev-parse', 'HEAD'], { + cwd: pathToRepository, + }); + + this.augmentOptions({ commit: revParse.stdout.toString('utf-8').trim() }); + } + } + + const currentInstantiation = this.context.project?.blueprint?.instantiationId + ? this.context.project.blueprint.instantiations?.find(i => i.id === this.context.project.blueprint.instantiationId) + : undefined; + const commitHash = currentInstantiation?.options?.authorDefined?.commit; + if (this.context.resynthesisPhase === 'ANCESTOR' && commitHash) { + // need to refetch since we previously just cloned at --depth=1 + cp.spawnSync('git', ['fetch', '--depth', '1', 'origin', commitHash], { + cwd: pathToRepository, + stdio: [0, 1, 1], + timeout: GIT_CLONE_TIMEOUT, + }); + cp.spawnSync('git', ['checkout', commitHash], { + cwd: pathToRepository, + stdio: [0, 1, 1], + }); + } else if (commitHash) { + // ensure repo is checked out at HEAD if phase is not ancestor + const branch = this.state.options.sourceBranch ?? 'HEAD'; + cp.spawnSync('git', ['checkout', `refs/remotes/origin/${branch}`], { + cwd: pathToRepository, + stdio: [0, 1, 1], + }); } - fs.cpSync(pathToRepository, this.state.repository.path, { recursive: true }); + // exclude .git - we have no use for it and the large number of objects + // contained within it could slow down the copying of sources to our workspace + fs.cpSync(pathToRepository, this.state.repository.path, { recursive: true, filter: src => src.indexOf('.git/') === -1 }); //map options and environments to workflows const workflowPath = path.join(this.state.repository.path, '.codecatalyst', 'workflows');