Skip to content

Commit

Permalink
fix(tag-from-scope), merge package.json props from the last snap (#9207)
Browse files Browse the repository at this point in the history
  • Loading branch information
davidfirst authored Sep 22, 2024
1 parent 1ee78e8 commit fb875ca
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 18 deletions.
2 changes: 1 addition & 1 deletion .bitmap
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"api-reference": {
"name": "api-reference",
"scope": "teambit.api-reference",
"version": "1.0.411",
"version": "1.0.410",
"mainFile": "index.ts",
"rootDir": "scopes/api-reference/api-reference",
"config": {
Expand Down
87 changes: 72 additions & 15 deletions scopes/component/isolator/isolator.main.runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,13 @@ export type IsolateComponentsOptions = CreateGraphOptions & {
*/
populateArtifactsFrom?: ComponentID[];

/**
* relevant when populateArtifactsFrom is set.
* by default, it uses the package.json created in the previous snap as a base and make the necessary changes.
* if this is set to true, it will ignore the package.json from the previous snap.
*/
populateArtifactsIgnorePkgJson?: boolean;

/**
* Force specific host to get the component from.
*/
Expand Down Expand Up @@ -910,6 +917,13 @@ export class IsolatorMain {
const legacyComponents = [...legacyUnmodifiedComps, ...legacyModifiedComps];
if (legacyScope && unmodifiedComps.length) await importMultipleDistsArtifacts(legacyScope, legacyUnmodifiedComps);
const allIds = ComponentIdList.fromArray(legacyComponents.map((c) => c.id));
const getParentsComp = () => {
const artifactsFrom = opts?.populateArtifactsFrom;
if (!artifactsFrom) return undefined;
if (!legacyScope) throw new Error('populateArtifactsFrom is set but legacyScope is not defined');
return Promise.all(artifactsFrom.map((id) => legacyScope.getConsumerComponent(id)));
};
const populateArtifactsFromComps = await getParentsComp();
await Promise.all(
components.map(async (component) => {
const capsule = capsuleList.getCapsule(component.id);
Expand All @@ -918,7 +932,13 @@ export class IsolatorMain {
(await CapsuleList.capsuleUsePreviouslySavedDists(component)) || opts?.populateArtifactsFrom
? legacyScope
: undefined;
const dataToPersist = await this.populateComponentsFilesToWriteForCapsule(component, allIds, scope, opts);
const dataToPersist = await this.populateComponentsFilesToWriteForCapsule(
component,
allIds,
scope,
opts,
populateArtifactsFromComps
);
await dataToPersist.persistAllToCapsule(capsule, { keepExistingCapsule: true });
})
);
Expand Down Expand Up @@ -1128,11 +1148,12 @@ export class IsolatorMain {
return packageJson;
}

async populateComponentsFilesToWriteForCapsule(
private async populateComponentsFilesToWriteForCapsule(
component: Component,
ids: ComponentIdList,
legacyScope?: Scope,
opts?: IsolateComponentsOptions
opts?: IsolateComponentsOptions,
populateArtifactsFromComps?: ConsumerComponent[]
): Promise<DataToPersist> {
const legacyComp: ConsumerComponent = component.state._consumer;
const dataToPersist = new DataToPersist();
Expand All @@ -1153,12 +1174,55 @@ export class IsolatorMain {
await PackageJsonTransformer.applyTransformers(component, packageJson);
const valuesToMerge = legacyComp.overrides.componentOverridesPackageJsonData;
packageJson.mergePackageJsonObject(valuesToMerge);
if (populateArtifactsFromComps && !opts?.populateArtifactsIgnorePkgJson) {
const compParent = this.getCompForArtifacts(component, populateArtifactsFromComps);
this.mergePkgJsonFromLastBuild(compParent, packageJson);
}
dataToPersist.addFile(packageJson.toVinylFile());
const artifacts = await this.getArtifacts(component, legacyScope, opts?.populateArtifactsFrom);
const artifacts = await this.getArtifacts(component, legacyScope, populateArtifactsFromComps);
dataToPersist.addManyFiles(artifacts);
return dataToPersist;
}

private mergePkgJsonFromLastBuild(component: ConsumerComponent, packageJson: PackageJsonFile) {
const suffix = `for ${component.id.toString()}. to workaround this, use --ignore-last-pkg-json flag`;
const aspectsData = component.extensions.findExtension('teambit.pipelines/builder')?.data?.aspectsData;
if (!aspectsData) throw new Error(`getPkgJsonFromLastBuild, unable to find builder aspects data ${suffix}`);
const data = aspectsData?.find((aspectData) => aspectData.aspectId === 'teambit.pkg/pkg');
if (!data) throw new Error(`getPkgJsonFromLastBuild, unable to find pkg aspect data ${suffix}`);
const pkgJsonLastBuild = data?.data?.pkgJson;
if (!pkgJsonLastBuild) throw new Error(`getPkgJsonFromLastBuild, unable to find pkgJson of pkg aspect ${suffix}`);
const current = packageJson.packageJsonObject;
pkgJsonLastBuild.componentId = current.componentId;
pkgJsonLastBuild.version = current.version;
const mergeDeps = (currentDeps?: Record<string, string>, depsFromLastBuild?: Record<string, string>) => {
if (!depsFromLastBuild) return;
if (!currentDeps) return depsFromLastBuild;
Object.keys(depsFromLastBuild).forEach((depName) => {
if (!currentDeps[depName]) return;
depsFromLastBuild[depName] = currentDeps[depName];
});
return depsFromLastBuild;
};
pkgJsonLastBuild.dependencies = mergeDeps(current.dependencies, pkgJsonLastBuild.dependencies);
pkgJsonLastBuild.devDependencies = mergeDeps(current.devDependencies, pkgJsonLastBuild.devDependencies);
pkgJsonLastBuild.peerDependencies = mergeDeps(current.peerDependencies, pkgJsonLastBuild.peerDependencies);
packageJson.mergePackageJsonObject(pkgJsonLastBuild);
}

private getCompForArtifacts(
component: Component,
populateArtifactsFromComps: ConsumerComponent[]
): ConsumerComponent {
const compParent = populateArtifactsFromComps.find((comp) =>
comp.id.isEqual(component.id, { ignoreVersion: true })
);
if (!compParent) {
throw new Error(`isolator, unable to find where to populate the artifacts from for ${component.id.toString()}`);
}
return compParent;
}

private preparePackageJsonToWrite(
component: Component,
bitDir: string,
Expand Down Expand Up @@ -1208,28 +1272,21 @@ export class IsolatorMain {
private async getArtifacts(
component: Component,
legacyScope?: Scope,
populateArtifactsFrom?: ComponentID[]
populateArtifactsFromComps?: ConsumerComponent[]
): Promise<AbstractVinyl[]> {
const legacyComp: ConsumerComponent = component.state._consumer;
if (!legacyScope) {
if (populateArtifactsFrom) throw new Error(`unable to fetch from parent, the legacyScope was not provided`);
// when capsules are written via the workspace, do not write artifacts, they get created by
// build-pipeline. when capsules are written via the scope, we do need the dists.
return [];
}
if (legacyComp.buildStatus !== 'succeed' && !populateArtifactsFrom) {
if (legacyComp.buildStatus !== 'succeed' && !populateArtifactsFromComps) {
// this is important for "bit sign" when on lane to not go to the original scope
return [];
}
const artifactFilesToFetch = async () => {
if (populateArtifactsFrom) {
const found = populateArtifactsFrom.find((id) => id.isEqual(component.id, { ignoreVersion: true }));
if (!found) {
throw new Error(
`getArtifacts: unable to find where to populate the artifacts from for ${component.id.toString()}`
);
}
const compParent = await legacyScope.getConsumerComponent(found);
if (populateArtifactsFromComps) {
const compParent = this.getCompForArtifacts(component, populateArtifactsFromComps);
return getArtifactFilesExcludeExtension(compParent.extensions, 'teambit.pkg/pkg');
}
const extensionsNamesForArtifacts = ['teambit.compilation/compiler'];
Expand Down
2 changes: 2 additions & 0 deletions scopes/component/snapping/snapping.main.runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ export class SnappingMain {
ignoreIssues?: string;
incrementBy?: number;
rebuildArtifacts?: boolean;
ignoreLastPkgJson?: boolean;
} & Partial<BasicTagParams>
): Promise<TagResults | null> {
if (this.workspace) {
Expand Down Expand Up @@ -340,6 +341,7 @@ if you're willing to lose the history from the head to the specified version, us
consumerComponents,
tagDataPerComp,
populateArtifactsFrom: shouldUsePopulateArtifactsFrom ? components.map((c) => c.id) : undefined,
populateArtifactsIgnorePkgJson: params.ignoreLastPkgJson,
copyLogFromPreviousSnap: true,
snapping: this,
builder: this.builder,
Expand Down
4 changes: 4 additions & 0 deletions scopes/component/snapping/tag-from-scope.cmd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ an example of the final data: '[{"componentId":"ci.remote2/comp-b","dependencies
options = [
['', 'push', 'export the updated objects to the original scopes once done'],
['', 'rebuild-artifacts', 'run the full build pipeline. do not use the saved artifacts from the last snap'],
['', 'ignore-last-pkg-json', 'ignore the package.json created by the last snap'],
...tagCmdOptions.filter((o) => !excludeOptions.includes(o[1])),
] as CommandOptions;
remoteOp = true; // In case a compiler / tester is not installed
Expand All @@ -49,6 +50,7 @@ an example of the final data: '[{"componentId":"ci.remote2/comp-b","dependencies
options: {
push?: boolean;
rebuildArtifacts?: boolean;
ignoreLastPkgJson?: boolean;
} & Partial<TagParams>
): Promise<string> {
const { releaseType, preReleaseId } = validateOptions(options);
Expand All @@ -64,6 +66,7 @@ an example of the final data: '[{"componentId":"ci.remote2/comp-b","dependencies
disableTagPipeline = false,
ignoreBuildErrors = false,
rebuildArtifacts,
ignoreLastPkgJson,
rebuildDepsGraph,
incrementBy = 1,
} = options;
Expand All @@ -85,6 +88,7 @@ an example of the final data: '[{"componentId":"ci.remote2/comp-b","dependencies
incrementBy,
version: ver,
rebuildArtifacts,
ignoreLastPkgJson,
};

const tagDataPerCompRaw = this.parseData(data);
Expand Down
4 changes: 3 additions & 1 deletion scopes/component/snapping/tag-model-component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ export async function tagModelComponent({
ids,
tagDataPerComp,
populateArtifactsFrom,
populateArtifactsIgnorePkgJson,
message,
editor,
exactVersion,
Expand Down Expand Up @@ -211,6 +212,7 @@ export async function tagModelComponent({
ids: ComponentIdList;
tagDataPerComp?: TagDataPerComp[];
populateArtifactsFrom?: ComponentID[];
populateArtifactsIgnorePkgJson?: boolean;
copyLogFromPreviousSnap?: boolean;
exactVersion?: string | null | undefined;
releaseType?: ReleaseType;
Expand Down Expand Up @@ -355,7 +357,7 @@ export async function tagModelComponent({
};
const skipTasksParsed = skipTasks ? skipTasks.split(',').map((t) => t.trim()) : undefined;
const seedersOnly = !workspace; // if tag from scope, build only the given components
const isolateOptions = { packageManagerConfigRootDir, seedersOnly };
const isolateOptions = { packageManagerConfigRootDir, seedersOnly, populateArtifactsIgnorePkgJson };
const builderOptions = { exitOnFirstFailedTask, skipTests, skipTasks: skipTasksParsed };

const componentsToBuild = allComponentsToTag.filter((c) => !c.isRemoved());
Expand Down
2 changes: 1 addition & 1 deletion scopes/lanes/merge-lanes/merge-lane.cmd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ Component pattern format: ${COMPONENT_PATTERN_HELP}`,
[
'',
'include-deps',
'relevant for "--pattern" and "--workspace". merge also dependencies of the specified components',
'relevant for "pattern" and "--workspace". merge also dependencies of the specified components',
],
[
'',
Expand Down

0 comments on commit fb875ca

Please sign in to comment.