Skip to content

Commit 881c75e

Browse files
committed
use version tags for packages and builds
1 parent 0cda0d3 commit 881c75e

File tree

1 file changed

+133
-26
lines changed

1 file changed

+133
-26
lines changed

scripts/package_automation.ts

Lines changed: 133 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const separator = "-".repeat(50);
66

77
const entrypoint = async () => {
88
try {
9-
const config = await ConfigParser.parseFromArgs();
9+
const config = ConfigParser.parseFromArgs();
1010
await config.validateTangram();
1111
log(`Starting! Configuration:\n${config.summarize()}\n${separator}`);
1212
const executor = new PackageExecutor(config);
@@ -310,6 +310,7 @@ interface ActionContext {
310310
dryRun: boolean;
311311
verbose: boolean;
312312
recursive: boolean;
313+
versionedName?: string;
313314
}
314315

315316
type ActionResultKind =
@@ -394,8 +395,15 @@ class BuildAction extends Action {
394395
async execute(context: ActionContext): Promise<ActionResult> {
395396
const results: string[] = [];
396397

398+
// Get the package version first
399+
const versionResult = await getPackageVersion(context);
400+
if (versionResult.kind !== "ok") {
401+
return versionResult;
402+
}
403+
const version = versionResult.message as string;
404+
397405
for (const target of context.buildTargets) {
398-
const result = await this.buildTarget(context, target);
406+
const result = await this.buildTarget(context, target, version);
399407
if (result.kind !== "ok") {
400408
return result;
401409
}
@@ -410,18 +418,19 @@ class BuildAction extends Action {
410418
private async buildTarget(
411419
context: ActionContext,
412420
target: BuildTarget,
421+
version: string,
413422
): Promise<ActionResult> {
414423
const exportName = target.export || "default";
415424
const platform = target.platform || context.platform;
416425
const exportSuffix = exportName !== "default" ? `#${exportName}` : "";
417-
const tag =
418-
target.tag || `${context.packageName}/${exportName}/${platform}`;
426+
const buildTag = `${context.packageName}/builds/${version}/${exportName}/${platform}`;
427+
const tag = target.tag || buildTag;
419428

420-
this.log(`building ${tag}...`);
429+
this.log(`building ${buildTag}...`);
421430

422431
if (context.dryRun) {
423-
this.log(`would build ${tag} (dry run)`);
424-
return { kind: "ok", message: `would build ${tag} (dry run)` };
432+
this.log(`would build ${buildTag} (dry run)`);
433+
return { kind: "ok", message: `would build ${buildTag} (dry run)` };
425434
}
426435

427436
let processId: string | undefined;
@@ -435,13 +444,18 @@ class BuildAction extends Action {
435444
context.processTracker.add(processId);
436445
}
437446

438-
this.log(`${tag}: ${processId}`);
447+
this.log(`${buildTag}: ${processId}`);
439448
await $`${context.tangram} process output ${processId}`.quiet();
440-
this.log(`finished building ${tag}`);
449+
this.log(`finished building ${buildTag}`);
450+
451+
// Tag the build process
452+
if (processId) {
453+
await this.tagBuildProcess(context, processId, buildTag);
454+
}
441455

442-
return { kind: "ok", message: tag };
456+
return { kind: "ok", message: buildTag };
443457
} catch (err) {
444-
this.log(`error building ${tag}`);
458+
this.log(`error building ${buildTag}`);
445459
const stderr = err.stderr?.toString() || "";
446460

447461
if (stderr.includes("not found in supported hosts")) {
@@ -456,6 +470,52 @@ class BuildAction extends Action {
456470
}
457471
}
458472
}
473+
474+
private async tagBuildProcess(
475+
context: ActionContext,
476+
processId: string,
477+
buildTag: string,
478+
): Promise<void> {
479+
if (context.dryRun) {
480+
this.log(`would tag build process ${processId} as ${buildTag} (dry run)`);
481+
return;
482+
}
483+
484+
this.log(`tagging build process ${processId} as ${buildTag}`);
485+
486+
try {
487+
// Check if the tag already exists and matches this process ID
488+
const existing = await this.getExistingBuildTag(context, buildTag);
489+
490+
if (processId === existing) {
491+
this.log(
492+
`Existing tag for ${buildTag} matches current process ID:`,
493+
existing,
494+
);
495+
return;
496+
}
497+
498+
await $`${context.tangram} tag ${buildTag} ${processId}`.quiet();
499+
this.log(`tagged build process ${buildTag}: ${processId}`);
500+
} catch (err) {
501+
this.log(`error tagging build process ${buildTag}: ${err}`);
502+
}
503+
}
504+
505+
private async getExistingBuildTag(
506+
context: ActionContext,
507+
tagName: string,
508+
): Promise<string> {
509+
this.log("checking for existing build tag", tagName);
510+
try {
511+
const result = await $`${context.tangram} tag get ${tagName}`
512+
.text()
513+
.then((t) => t.trim());
514+
return result;
515+
} catch (err) {
516+
return "not found";
517+
}
518+
}
459519
}
460520

461521
class TestAction extends Action {
@@ -491,13 +551,15 @@ class PublishAction extends Action {
491551
return pushResult;
492552
}
493553

494-
return { kind: "ok", message: `published ${context.packageName}` };
554+
const tagName = context.versionedName || context.packageName;
555+
return { kind: "ok", message: `published ${tagName}` };
495556
}
496557

497558
private async pushTag(context: ActionContext): Promise<ActionResult> {
498-
this.log(`pushing ${context.packageName}`);
559+
const tagName = context.versionedName || context.packageName;
560+
this.log(`pushing ${tagName}`);
499561
try {
500-
await $`${context.tangram} push ${context.packageName}`.quiet();
562+
await $`${context.tangram} push ${tagName}`.quiet();
501563
return { kind: "ok" };
502564
} catch (err) {
503565
return { kind: "pushError", message: err.stderr?.toString() };
@@ -760,8 +822,19 @@ class PackageExecutor {
760822
private async tagPackage(context: ActionContext): Promise<ActionResult> {
761823
log(`[tag] processing ${context.packageName}`);
762824

825+
// Get the package version from metadata
826+
const versionResult = await getPackageVersion(context);
827+
if (versionResult.kind !== "ok") {
828+
return versionResult;
829+
}
830+
const version = versionResult.message as string;
831+
const versionedName = `${context.packageName}/${version}`;
832+
833+
// Update context with versioned name for other actions to use
834+
context.versionedName = versionedName;
835+
763836
if (context.dryRun) {
764-
log(`[tag] would check in and tag ${context.packageName} (dry run)`);
837+
log(`[tag] would check in and tag ${versionedName} (dry run)`);
765838
return { kind: "ok", message: "would check in and tag (dry run)" };
766839
}
767840

@@ -776,27 +849,27 @@ class PackageExecutor {
776849
}
777850

778851
// Check if the tag already matches this ID.
779-
const existing = await this.getExistingTag(context);
852+
const existing = await this.getExistingTag(context, versionedName);
780853

781854
if (packageId === existing) {
782855
log(
783-
`[tag] Existing tag for ${context.packageName} matches current ID:`,
856+
`[tag] Existing tag for ${versionedName} matches current ID:`,
784857
existing,
785858
);
786859
return {
787860
kind: "ok",
788-
message: `${context.packageName} unchanged, no action taken.`,
861+
message: `${versionedName} unchanged, no action taken.`,
789862
};
790863
}
791864

792-
log(`[tag] tagging ${context.packageName}: ${packageId}...`);
793-
const tagResult = await this.tagItem(context, packageId);
865+
log(`[tag] tagging ${versionedName}: ${packageId}...`);
866+
const tagResult = await this.tagItem(context, packageId, versionedName);
794867
if (tagResult.kind !== "ok") {
795868
return tagResult;
796869
}
797870
return {
798871
kind: "ok",
799-
message: `tagged ${context.packageName}: ${packageId}`,
872+
message: `tagged ${versionedName}: ${packageId}`,
800873
};
801874
}
802875

@@ -816,10 +889,13 @@ class PackageExecutor {
816889
}
817890

818891
/** Get the existing tagged item for a given name, if present. */
819-
private async getExistingTag(context: ActionContext): Promise<string> {
820-
log("[tag] checking for existing tag", context.packageName);
892+
private async getExistingTag(
893+
context: ActionContext,
894+
tagName: string,
895+
): Promise<string> {
896+
log("[tag] checking for existing tag", tagName);
821897
try {
822-
const result = await $`${context.tangram} tag get ${context.packageName}`
898+
const result = await $`${context.tangram} tag get ${tagName}`
823899
.text()
824900
.then((t) => t.trim());
825901
return result;
@@ -832,10 +908,11 @@ class PackageExecutor {
832908
private async tagItem(
833909
context: ActionContext,
834910
packageId: string,
911+
tagName: string,
835912
): Promise<ActionResult> {
836-
log("[tag] tagging", context.packageName, context.packagePath);
913+
log("[tag] tagging", tagName, context.packagePath);
837914
try {
838-
await $`${context.tangram} tag ${context.packageName} ${context.packagePath}`.quiet();
915+
await $`${context.tangram} tag ${tagName} ${context.packagePath}`.quiet();
839916
return { kind: "ok" };
840917
} catch (err) {
841918
return { kind: "tagError" };
@@ -886,6 +963,36 @@ const packagesPath = () => path.join(path.dirname(import.meta.dir), "packages");
886963

887964
export const getPackagePath = (name: string) => path.join(packagesPath(), name);
888965

966+
/** Get the package version from metadata. */
967+
async function getPackageVersion(
968+
context: ActionContext,
969+
): Promise<ActionResult> {
970+
log("getting version from metadata for", context.packagePath);
971+
try {
972+
const metadataJson =
973+
await $`${context.tangram} build ${context.packagePath}#metadata`
974+
.text()
975+
.then((t) => t.trim());
976+
977+
const metadata = JSON.parse(metadataJson);
978+
if (!metadata.version) {
979+
return {
980+
kind: "tagError",
981+
message: `no version found in metadata for ${context.packagePath}`,
982+
};
983+
}
984+
985+
log(`found version ${metadata.version} for ${context.packagePath}`);
986+
return { kind: "ok", message: metadata.version };
987+
} catch (err) {
988+
log(`error getting version for ${context.packagePath}: ${err}`);
989+
return {
990+
kind: "tagError",
991+
message: err.stderr?.toString() || err.toString(),
992+
};
993+
}
994+
}
995+
889996
const log = (...data: any[]) => {
890997
const timestamp = `[${new Date().toUTCString()}]`;
891998
console.log(timestamp, ...data);

0 commit comments

Comments
 (0)