feat(cli): split commit and release into target-based workflows
This commit is contained in:
@@ -0,0 +1,192 @@
|
||||
export const CURRENT_GITZONE_CLI_SCHEMA_VERSION = 2;
|
||||
|
||||
export interface ISmartconfigMigrationResult {
|
||||
migrated: boolean;
|
||||
fromVersion: number;
|
||||
toVersion: number;
|
||||
}
|
||||
|
||||
const CLI_NAMESPACE = "@git.zone/cli";
|
||||
|
||||
const isPlainObject = (value: unknown): value is Record<string, any> => {
|
||||
return typeof value === "object" && value !== null && !Array.isArray(value);
|
||||
};
|
||||
|
||||
const ensureObject = (parent: Record<string, any>, key: string): Record<string, any> => {
|
||||
if (!isPlainObject(parent[key])) {
|
||||
parent[key] = {};
|
||||
}
|
||||
return parent[key];
|
||||
};
|
||||
|
||||
const migrateNamespaceKeys = (smartconfigJson: Record<string, any>): boolean => {
|
||||
let migrated = false;
|
||||
const migrations = [
|
||||
{ oldKey: "gitzone", newKey: CLI_NAMESPACE },
|
||||
{ oldKey: "tsdoc", newKey: "@git.zone/tsdoc" },
|
||||
{ oldKey: "npmdocker", newKey: "@git.zone/tsdocker" },
|
||||
{ oldKey: "npmci", newKey: "@ship.zone/szci" },
|
||||
{ oldKey: "szci", newKey: "@ship.zone/szci" },
|
||||
];
|
||||
|
||||
for (const { oldKey, newKey } of migrations) {
|
||||
if (!isPlainObject(smartconfigJson[oldKey])) {
|
||||
continue;
|
||||
}
|
||||
if (!isPlainObject(smartconfigJson[newKey])) {
|
||||
smartconfigJson[newKey] = smartconfigJson[oldKey];
|
||||
} else {
|
||||
smartconfigJson[newKey] = {
|
||||
...smartconfigJson[oldKey],
|
||||
...smartconfigJson[newKey],
|
||||
};
|
||||
}
|
||||
delete smartconfigJson[oldKey];
|
||||
migrated = true;
|
||||
}
|
||||
|
||||
return migrated;
|
||||
};
|
||||
|
||||
const migrateToV2 = (smartconfigJson: Record<string, any>): boolean => {
|
||||
const cliConfig = ensureObject(smartconfigJson, CLI_NAMESPACE);
|
||||
const releaseConfig = ensureObject(cliConfig, "release");
|
||||
|
||||
let migrated = false;
|
||||
const targets = ensureObject(releaseConfig, "targets");
|
||||
const shipzoneConfig = smartconfigJson["@ship.zone/szci"];
|
||||
|
||||
if (isPlainObject(releaseConfig.git) && !isPlainObject(targets.git)) {
|
||||
targets.git = releaseConfig.git;
|
||||
delete releaseConfig.git;
|
||||
migrated = true;
|
||||
}
|
||||
|
||||
if (isPlainObject(releaseConfig.npm) && !isPlainObject(targets.npm)) {
|
||||
targets.npm = releaseConfig.npm;
|
||||
delete releaseConfig.npm;
|
||||
migrated = true;
|
||||
}
|
||||
|
||||
if (isPlainObject(releaseConfig.docker) && !isPlainObject(targets.docker)) {
|
||||
targets.docker = releaseConfig.docker;
|
||||
delete releaseConfig.docker;
|
||||
migrated = true;
|
||||
}
|
||||
|
||||
if (Array.isArray(releaseConfig.registries)) {
|
||||
const npmTarget = ensureObject(targets, "npm");
|
||||
if (!Array.isArray(npmTarget.registries)) {
|
||||
npmTarget.registries = releaseConfig.registries;
|
||||
}
|
||||
delete releaseConfig.registries;
|
||||
migrated = true;
|
||||
}
|
||||
|
||||
if (releaseConfig.accessLevel) {
|
||||
const npmTarget = ensureObject(targets, "npm");
|
||||
if (!npmTarget.accessLevel) {
|
||||
npmTarget.accessLevel = releaseConfig.accessLevel;
|
||||
}
|
||||
delete releaseConfig.accessLevel;
|
||||
migrated = true;
|
||||
}
|
||||
|
||||
if (isPlainObject(shipzoneConfig)) {
|
||||
if (shipzoneConfig.npmAccessLevel) {
|
||||
const npmTarget = ensureObject(targets, "npm");
|
||||
if (!npmTarget.accessLevel) {
|
||||
npmTarget.accessLevel = shipzoneConfig.npmAccessLevel;
|
||||
}
|
||||
delete shipzoneConfig.npmAccessLevel;
|
||||
migrated = true;
|
||||
}
|
||||
|
||||
if (shipzoneConfig.npmRegistryUrl) {
|
||||
const npmTarget = ensureObject(targets, "npm");
|
||||
const registry = normalizeRegistryUrl(shipzoneConfig.npmRegistryUrl);
|
||||
const registries = Array.isArray(npmTarget.registries) ? npmTarget.registries : [];
|
||||
if (!registries.includes(registry)) {
|
||||
registries.push(registry);
|
||||
}
|
||||
npmTarget.registries = registries;
|
||||
delete shipzoneConfig.npmRegistryUrl;
|
||||
migrated = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (Array.isArray(releaseConfig.steps)) {
|
||||
const steps = releaseConfig.steps as string[];
|
||||
const preflight = ensureObject(releaseConfig, "preflight");
|
||||
if (steps.includes("test") && preflight.test === undefined) {
|
||||
preflight.test = true;
|
||||
}
|
||||
if (steps.includes("build") && preflight.build === undefined) {
|
||||
preflight.build = true;
|
||||
}
|
||||
if (steps.includes("push")) {
|
||||
const gitTarget = ensureObject(targets, "git");
|
||||
if (gitTarget.enabled === undefined) {
|
||||
gitTarget.enabled = true;
|
||||
}
|
||||
}
|
||||
if (steps.includes("publishNpm")) {
|
||||
const npmTarget = ensureObject(targets, "npm");
|
||||
if (npmTarget.enabled === undefined) {
|
||||
npmTarget.enabled = true;
|
||||
}
|
||||
}
|
||||
if (steps.includes("publishDocker")) {
|
||||
const dockerTarget = ensureObject(targets, "docker");
|
||||
if (dockerTarget.enabled === undefined) {
|
||||
dockerTarget.enabled = true;
|
||||
}
|
||||
}
|
||||
delete releaseConfig.steps;
|
||||
migrated = true;
|
||||
}
|
||||
|
||||
if (releaseConfig.changelog) {
|
||||
delete releaseConfig.changelog;
|
||||
migrated = true;
|
||||
}
|
||||
|
||||
cliConfig.schemaVersion = 2;
|
||||
return migrated || true;
|
||||
};
|
||||
|
||||
const normalizeRegistryUrl = (url: string): string => {
|
||||
let normalizedUrl = url.trim();
|
||||
if (!normalizedUrl.startsWith("http://") && !normalizedUrl.startsWith("https://")) {
|
||||
normalizedUrl = `https://${normalizedUrl}`;
|
||||
}
|
||||
return normalizedUrl.endsWith("/") ? normalizedUrl.slice(0, -1) : normalizedUrl;
|
||||
};
|
||||
|
||||
export const migrateSmartconfigData = (
|
||||
smartconfigJson: Record<string, any>,
|
||||
targetVersion = CURRENT_GITZONE_CLI_SCHEMA_VERSION,
|
||||
): ISmartconfigMigrationResult => {
|
||||
let migrated = false;
|
||||
migrated = migrateNamespaceKeys(smartconfigJson) || migrated;
|
||||
|
||||
const cliConfig = ensureObject(smartconfigJson, CLI_NAMESPACE);
|
||||
const fromVersion = typeof cliConfig.schemaVersion === "number" ? cliConfig.schemaVersion : 1;
|
||||
let currentVersion = fromVersion;
|
||||
|
||||
if (currentVersion < 2 && targetVersion >= 2) {
|
||||
migrated = migrateToV2(smartconfigJson) || migrated;
|
||||
currentVersion = 2;
|
||||
}
|
||||
|
||||
if (targetVersion === CURRENT_GITZONE_CLI_SCHEMA_VERSION && cliConfig.schemaVersion !== targetVersion) {
|
||||
cliConfig.schemaVersion = targetVersion;
|
||||
migrated = true;
|
||||
}
|
||||
|
||||
return {
|
||||
migrated,
|
||||
fromVersion,
|
||||
toVersion: Math.min(targetVersion, CURRENT_GITZONE_CLI_SCHEMA_VERSION),
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user