diff --git a/src/commands/build/handler.ts b/src/commands/build/handler.ts index 446d993d..b84117d9 100644 --- a/src/commands/build/handler.ts +++ b/src/commands/build/handler.ts @@ -7,8 +7,9 @@ import { defaultVariantsDirName } from "../../params.js"; import { BuildCommandOptions, VerbosityOptions } from "./types.js"; -import { getVariantOptions } from "./variants.js"; +import { getPackagesToBuildProps } from "./variants.js"; import { BuildAndUploadOptions } from "../../tasks/buildAndUpload/types.js"; +import path from "path"; export async function buildHandler({ provider: contentProvider, @@ -29,6 +30,8 @@ export async function buildHandler({ }: BuildCommandOptions): Promise { const skipUpload = skip_upload || skipSave; + const variantsDirPath = path.join(dir, variantsDirName); + const buildOptions: BuildAndUploadOptions = { dir, contentProvider, @@ -39,11 +42,12 @@ export async function buildHandler({ composeFileName, requireGitData, deleteOldPins, - ...getVariantOptions({ + variantsDirPath, + packagesToBuildProps: getPackagesToBuildProps({ allVariants: Boolean(allVariants), - variantsStr: variants, + commaSeparatedVariants: variants, rootDir: dir, - variantsDirName, + variantsDirPath, composeFileName }) }; diff --git a/src/commands/build/variants.ts b/src/commands/build/variants.ts index 9abcb418..f96799d3 100644 --- a/src/commands/build/variants.ts +++ b/src/commands/build/variants.ts @@ -1,35 +1,30 @@ import chalk from "chalk"; import { getAllVariantsInPath } from "../../files/variants/getAllPackageVariants.js"; -import path from "path"; -import { BuildVariantsMap } from "../../types.js"; -import { buildVariantMap } from "../../tasks/buildAndUpload/buildVariantMap.js"; +import { PackageToBuildProps } from "../../types.js"; +import { generatePackagesProps } from "../../tasks/buildAndUpload/generatePackagesProps.js"; -export function getVariantOptions({ +export function getPackagesToBuildProps({ allVariants, - variantsStr, + commaSeparatedVariants, rootDir, - variantsDirName, + variantsDirPath, composeFileName }: { allVariants: boolean; - variantsStr?: string; + commaSeparatedVariants?: string; rootDir: string; - variantsDirName: string; + variantsDirPath: string; composeFileName: string; -}): { variantsMap: BuildVariantsMap; variantsDirPath: string } { - const variantsDirPath = path.join(rootDir, variantsDirName); +}): PackageToBuildProps[] { const buildVariantMapArgs = { rootDir, variantsDirPath, composeFileName }; - if (!allVariants && !variantsStr) - return { - variantsMap: buildVariantMap({ ...buildVariantMapArgs, variants: null }), - variantsDirPath - }; + if (!allVariants && !commaSeparatedVariants) + return generatePackagesProps({ ...buildVariantMapArgs, variants: null }); const validVariantNames = getValidVariantNames({ variantsDirPath, - variants: variantsStr + variants: commaSeparatedVariants }); if (validVariantNames.length === 0) @@ -39,17 +34,14 @@ export function getVariantOptions({ console.log( `${chalk.dim( - `Building package from template for variant(s) ${variantsStr}...` + `Building package from template for variant(s) ${commaSeparatedVariants}...` )}` ); - return { - variantsMap: buildVariantMap({ - ...buildVariantMapArgs, - variants: validVariantNames - }), - variantsDirPath - }; + return generatePackagesProps({ + ...buildVariantMapArgs, + variants: validVariantNames + }); } /** diff --git a/src/commands/publish/handler.ts b/src/commands/publish/handler.ts index 5a29c751..d01f0f07 100644 --- a/src/commands/publish/handler.ts +++ b/src/commands/publish/handler.ts @@ -1,4 +1,5 @@ import Listr from "listr"; +import path from "path"; import { defaultComposeFileName, defaultDir, @@ -9,7 +10,7 @@ import { VerbosityOptions } from "../build/types.js"; import { PublishCommandOptions } from "./types.js"; import { publish } from "../../tasks/publish/index.js"; import { parseReleaseType } from "./parseReleaseType.js"; -import { getVariantOptions } from "../build/variants.js"; +import { getPackagesToBuildProps } from "../build/variants.js"; /** * Common handler for CLI and programatic usage @@ -37,7 +38,6 @@ export async function publishHandler({ }: PublishCommandOptions): Promise { let ethProvider = provider || eth_provider; let contentProvider = provider || content_provider; - const isMultiVariant = Boolean(allVariants) || Boolean(variants); const isCi = process.env.CI; @@ -61,6 +61,8 @@ export async function publishHandler({ const releaseType = parseReleaseType({ type }); + const variantsDirPath = path.join(dir, variantsDirName); + const publishTasks = new Listr( publish({ releaseType, @@ -75,14 +77,14 @@ export async function publishHandler({ developerAddress, githubRelease, verbosityOptions, - ...getVariantOptions({ + variantsDirPath, + packagesToBuildProps: getPackagesToBuildProps({ allVariants: Boolean(allVariants), - variantsStr: variants, + commaSeparatedVariants: variants, rootDir: dir, - variantsDirName, + variantsDirPath, composeFileName - }), - isMultiVariant + }) }), verbosityOptions ); diff --git a/src/params.ts b/src/params.ts index 0712fbb7..f8330349 100644 --- a/src/params.ts +++ b/src/params.ts @@ -14,7 +14,6 @@ export const branchNameRoot = "dappnodebot/bump-upstream/"; export const defaultDir = "./"; export const defaultVariantsDirName = "package_variants"; -export const singleVariantName = "single-variant"; // This is the default name of the environment variable that will be used to select each of the variants export const defaultVariantsEnvName = "NETWORK"; export const defaultVariantsEnvValues = ["mainnet", "testnet"]; diff --git a/src/tasks/buildAndUpload/buildVariantMap.ts b/src/tasks/buildAndUpload/generatePackagesProps.ts similarity index 75% rename from src/tasks/buildAndUpload/buildVariantMap.ts rename to src/tasks/buildAndUpload/generatePackagesProps.ts index b962b594..bb0e0974 100644 --- a/src/tasks/buildAndUpload/buildVariantMap.ts +++ b/src/tasks/buildAndUpload/generatePackagesProps.ts @@ -7,10 +7,10 @@ import { readManifest } from "../../files/index.js"; import { Compose, Manifest } from "@dappnode/types"; -import { defaultComposeFileName, singleVariantName } from "../../params.js"; -import { BuildVariantsMap, BuildVariantsMapEntry } from "../../types.js"; +import { defaultComposeFileName } from "../../params.js"; +import { PackageToBuildProps } from "../../types.js"; -export function buildVariantMap({ +export function generatePackagesProps({ variants, rootDir, variantsDirPath, @@ -20,37 +20,37 @@ export function buildVariantMap({ rootDir: string; variantsDirPath: string; composeFileName?: string; -}): BuildVariantsMap { - if (!variants || variants.length === 0) - return { [singleVariantName]: createVariantMapEntry({ rootDir, composeFileName }) }; +}): PackageToBuildProps[] { + if (variants === null) + return [createPackagePropsItem({ rootDir, composeFileName, variant: null, variantsDirPath })]; - const map: BuildVariantsMap = {}; - - for (const variant of variants) { - const variantPath = path.join(variantsDirPath, variant); - map[variant] = createVariantMapEntry({ + return variants.map((variant) => + createPackagePropsItem({ rootDir, composeFileName, - variantPath - }); - } - - return map; + variant, + variantsDirPath + }) + ); } -export function createVariantMapEntry({ +function createPackagePropsItem({ rootDir, composeFileName, - variantPath + variant, + variantsDirPath }: { rootDir: string; composeFileName: string; - variantPath?: string; -}): BuildVariantsMapEntry { + variant: string | null; + variantsDirPath: string; +}): PackageToBuildProps { const manifestPaths = [{ dir: rootDir }]; const composePaths = [{ dir: rootDir, composeFileName }]; - if (variantPath) { + if (variant) { + const variantPath = path.join(variantsDirPath, variant); + manifestPaths.push({ dir: variantPath }); composePaths.push({ dir: variantPath, composeFileName }); } @@ -65,6 +65,8 @@ export function createVariantMapEntry({ manifest.upstreamVersion = getUpstreamVersion({ compose, manifest }); return { + variant, + manifest, manifestFormat, diff --git a/src/tasks/buildAndUpload/getBuildTasks.ts b/src/tasks/buildAndUpload/getBuildTasks.ts index 5032ca0c..4b4b41a6 100644 --- a/src/tasks/buildAndUpload/getBuildTasks.ts +++ b/src/tasks/buildAndUpload/getBuildTasks.ts @@ -1,6 +1,6 @@ import path from "path"; import Listr, { ListrTask } from "listr/index.js"; -import { BuildVariantsMap, BuildVariantsMapEntry, ListrContextBuild } from "../../types.js"; +import { PackageToBuildProps, ListrContextBuild } from "../../types.js"; import { buildWithBuildx } from "./buildWithBuildx.js"; import { buildWithCompose } from "./buildWithCompose.js"; import { Architecture, defaultArch } from "@dappnode/types"; @@ -14,22 +14,20 @@ import { getImageFileName } from "../../utils/getImageFileName.js"; * const imageEntry = files.find(file => /\.tar\.xz$/.test(file)); */ export function getBuildTasks({ - variantsMap, + packagesToBuildProps, buildTimeout, skipSave, rootDir }: { - variantsMap: BuildVariantsMap; + packagesToBuildProps: PackageToBuildProps[]; buildTimeout: number; skipSave?: boolean; rootDir: string; }): ListrTask[] { - const buildTasks: ListrTask[] = Object.entries( - variantsMap - ).flatMap(([, variantSpecs]) => { - return variantSpecs.architectures.map(architecture => + const buildTasks: ListrTask[] = packagesToBuildProps.flatMap((pkgProps) => { + return pkgProps.architectures.map(architecture => createBuildTask({ - variantSpecs, + pkgProps, architecture, buildTimeout, skipSave, @@ -42,19 +40,19 @@ export function getBuildTasks({ } function createBuildTask({ - variantSpecs, + pkgProps, architecture, buildTimeout, skipSave, rootDir }: { - variantSpecs: BuildVariantsMapEntry; + pkgProps: PackageToBuildProps; architecture: Architecture; buildTimeout: number; skipSave?: boolean; rootDir: string; -}): ListrTask { - const { manifest, releaseDir, images, compose } = variantSpecs; +}): ListrTask { + const { manifest, releaseDir, images, compose } = pkgProps; const { name, version } = manifest; const buildFn = architecture === defaultArch ? buildWithCompose : buildWithBuildx; diff --git a/src/tasks/buildAndUpload/getDeleteOldPinsTask.ts b/src/tasks/buildAndUpload/getDeleteOldPinsTask.ts index d9b00d03..4d253cea 100644 --- a/src/tasks/buildAndUpload/getDeleteOldPinsTask.ts +++ b/src/tasks/buildAndUpload/getDeleteOldPinsTask.ts @@ -1,16 +1,16 @@ import { ListrTask } from "listr/index.js"; -import { BuildVariantsMap, ListrContextBuild } from "../../types.js"; +import { PackageToBuildProps, ListrContextBuild } from "../../types.js"; import { getGitHead } from "../../utils/git.js"; import { fetchPinsWithBranchToDelete } from "../../pinStrategy/index.js"; import { PinataPinManager } from "../../providers/pinata/pinManager.js"; import { ReleaseUploaderProvider } from "../../releaseUploader/index.js"; export function getDeleteOldPinsTask({ - variantsMap, + packagesToBuildProps, deleteOldPins, releaseUploaderProvider }: { - variantsMap: BuildVariantsMap; + packagesToBuildProps: PackageToBuildProps[]; deleteOldPins: boolean; releaseUploaderProvider: ReleaseUploaderProvider; }): ListrTask { @@ -25,7 +25,7 @@ export function getDeleteOldPinsTask({ // Unpin items on the same branch but previous (ancestor) commits const pinata = new PinataPinManager(releaseUploaderProvider); - for (const [, { manifest }] of Object.entries(variantsMap)) { + for (const { manifest } of packagesToBuildProps) { const pinsToDelete = await fetchPinsWithBranchToDelete( pinata, manifest, diff --git a/src/tasks/buildAndUpload/getFileCopyTask.ts b/src/tasks/buildAndUpload/getFileCopyTask.ts index 6deb1291..201ba3d4 100644 --- a/src/tasks/buildAndUpload/getFileCopyTask.ts +++ b/src/tasks/buildAndUpload/getFileCopyTask.ts @@ -7,7 +7,7 @@ import { defaultComposeFileName, releaseFilesDefaultNames } from "../../params.js"; -import { BuildVariantsMap, BuildVariantsMapEntry, ListrContextBuild } from "../../types.js"; +import { PackageToBuildProps, ListrContextBuild } from "../../types.js"; import { getGitHeadIfAvailable } from "../../utils/git.js"; import { updateComposeImageTags, @@ -17,13 +17,13 @@ import { import { Compose, Manifest, releaseFiles } from "@dappnode/types"; export function getFileCopyTask({ - variantsMap, + packagesToBuildProps, variantsDirPath, rootDir, composeFileName, requireGitData }: { - variantsMap: BuildVariantsMap; + packagesToBuildProps: PackageToBuildProps[]; variantsDirPath: string; rootDir: string; composeFileName: string; @@ -33,7 +33,7 @@ export function getFileCopyTask({ title: "Copy files to release directory", task: async () => copyFilesToReleaseDir({ - variantsMap, + packagesToBuildProps, variantsDirPath, rootDir, composeFileName, @@ -43,22 +43,21 @@ export function getFileCopyTask({ } async function copyFilesToReleaseDir({ - variantsMap, + packagesToBuildProps, variantsDirPath, rootDir, composeFileName, requireGitData }: { - variantsMap: BuildVariantsMap; + packagesToBuildProps: PackageToBuildProps[]; variantsDirPath: string; rootDir: string; composeFileName: string; requireGitData?: boolean; }): Promise { - for (const [variantName, variantProps] of Object.entries(variantsMap)) { + for (const variantProps of packagesToBuildProps) { - const variantDirPath = path.join(variantsDirPath, variantName); - await copyVariantFilesToReleaseDir({ variantProps, variantDirPath: variantDirPath, rootDir, composeFileName }); + await copyVariantFilesToReleaseDir({ variantProps, rootDir, variantsDirPath, composeFileName }); // Verify avatar (throws) const avatarPath = path.join( @@ -74,16 +73,19 @@ async function copyFilesToReleaseDir({ async function copyVariantFilesToReleaseDir({ variantProps, - variantDirPath, rootDir, + variantsDirPath, composeFileName }: { - variantProps: BuildVariantsMapEntry; - variantDirPath: string; + variantProps: PackageToBuildProps; rootDir: string; + variantsDirPath: string; composeFileName: string; }): Promise { - const { manifest, manifestFormat, releaseDir, compose } = variantProps; + const { manifest, manifestFormat, releaseDir, compose, variant } = variantProps; + + // In case of single variant packages, the targets are in the root dir + const variantDirPath = variant ? path.join(variantsDirPath, variant) : rootDir; for (const [fileId, fileConfig] of Object.entries(releaseFiles)) { // For single variant packages, the targets are in the root dir diff --git a/src/tasks/buildAndUpload/getFileValidationTask.ts b/src/tasks/buildAndUpload/getFileValidationTask.ts index 3144f4c3..987005ce 100644 --- a/src/tasks/buildAndUpload/getFileValidationTask.ts +++ b/src/tasks/buildAndUpload/getFileValidationTask.ts @@ -1,5 +1,5 @@ import { ListrTask } from "listr/index.js"; -import { BuildVariantsMap, BuildVariantsMapEntry, ListrContextBuild } from "../../types.js"; +import { PackageToBuildProps, ListrContextBuild } from "../../types.js"; import { validateComposeSchema, validateManifestSchema, @@ -10,37 +10,37 @@ import { getComposePath, readSetupWizardIfExists } from "../../files/index.js"; import { CliError } from "../../params.js"; export function getFileValidationTask({ - variantsMap, + packagesToBuildProps, rootDir }: { - variantsMap: BuildVariantsMap; + packagesToBuildProps: PackageToBuildProps[]; rootDir: string; }): ListrTask { return { title: `Validate files`, - task: async () => await validatePackageFiles({ variantsMap, rootDir }) + task: async () => await validatePackageFiles({ packagesToBuildProps, rootDir }) }; } async function validatePackageFiles({ - variantsMap, + packagesToBuildProps, rootDir }: { - variantsMap: BuildVariantsMap; + packagesToBuildProps: PackageToBuildProps[]; rootDir: string; }): Promise { const setupWizard = readSetupWizardIfExists(rootDir); if (setupWizard) validateSetupWizardSchema(setupWizard); - for (const [, variant] of Object.entries(variantsMap)) - await validateVariantFiles(variant); + for (const pkgProps of packagesToBuildProps) + await validateVariantFiles(pkgProps); } async function validateVariantFiles( - variant: BuildVariantsMapEntry + pkgProps: PackageToBuildProps ): Promise { - const { manifest, compose, composePaths } = variant; + const { manifest, compose, composePaths } = pkgProps; console.log( `Validating files for ${manifest.name} (version ${manifest.version})` diff --git a/src/tasks/buildAndUpload/getReleaseDirCreationTask.ts b/src/tasks/buildAndUpload/getReleaseDirCreationTask.ts index f9e47217..af5b8f73 100644 --- a/src/tasks/buildAndUpload/getReleaseDirCreationTask.ts +++ b/src/tasks/buildAndUpload/getReleaseDirCreationTask.ts @@ -2,35 +2,33 @@ import fs from "fs"; import path from "path"; import { ListrTask } from "listr/index.js"; import rimraf from "rimraf"; -import { BuildVariantsMap, ListrContextBuild } from "../../types.js"; +import { PackageToBuildProps, ListrContextBuild } from "../../types.js"; import { getImageFileName } from "../../utils/getImageFileName.js"; export function getReleaseDirCreationTask({ - variantsMap + packagesToBuildProps }: { - variantsMap: BuildVariantsMap; + packagesToBuildProps: PackageToBuildProps[]; }): ListrTask { return { title: `Create release directories`, - task: ctx => createReleaseDirs({ ctx, variantsMap }) + task: ctx => createReleaseDirs({ ctx, packagesToBuildProps }) }; } function createReleaseDirs({ ctx, - variantsMap + packagesToBuildProps }: { ctx: ListrContextBuild; - variantsMap: BuildVariantsMap; + packagesToBuildProps: PackageToBuildProps[]; }): void { - for (const [ + for (const { variant, - { - manifest: { name, version }, - releaseDir, - architectures - } - ] of Object.entries(variantsMap)) { + manifest: { name, version }, + releaseDir, + architectures + } of packagesToBuildProps) { console.log( `Creating release directory for ${name} (version ${version}) at ${releaseDir}` ); @@ -38,8 +36,7 @@ function createReleaseDirs({ fs.mkdirSync(releaseDir, { recursive: true }); // Ok on existing dir const releaseFiles = fs.readdirSync(releaseDir); - ctx[name] = ctx[name] || { variant }; - ctx[name].releaseDir = releaseDir; + ctx[name] = { variant, releaseDir }; const imagePaths = architectures.map(arch => getImageFileName(name, version, arch) diff --git a/src/tasks/buildAndUpload/getSaveUploadResultsTask.ts b/src/tasks/buildAndUpload/getSaveUploadResultsTask.ts index c0edadbc..93706685 100644 --- a/src/tasks/buildAndUpload/getSaveUploadResultsTask.ts +++ b/src/tasks/buildAndUpload/getSaveUploadResultsTask.ts @@ -1,36 +1,34 @@ import { ListrTask } from "listr/index.js"; import { addReleaseRecord } from "../../utils/releaseRecord.js"; -import { BuildVariantsMap, ListrContextBuild } from "../../types.js"; +import { PackageToBuildProps, ListrContextBuild } from "../../types.js"; import { pruneCache } from "../../utils/cache.js"; import path from "path"; export function getSaveUploadResultsTask({ - variantsMap, + packagesToBuildProps, rootDir, variantsDirPath, contentProvider, skipUpload, - isMultiVariant }: { - variantsMap: BuildVariantsMap; + packagesToBuildProps: PackageToBuildProps[]; rootDir: string; variantsDirPath: string; contentProvider: string; skipUpload?: boolean; - isMultiVariant?: boolean; }): ListrTask { return { title: "Save upload results", skip: () => skipUpload, task: async ctx => { - for (const [variant, { manifest: { name, version } }] of Object.entries(variantsMap)) { + for (const { variant, manifest: { name, version } } of packagesToBuildProps) { const { releaseMultiHash: hash } = ctx[name]; if (!hash) continue; addReleaseRecord({ - dir: isMultiVariant ? path.join(variantsDirPath, variant) : rootDir, + dir: variant ? path.join(variantsDirPath, variant) : rootDir, version, hash, to: contentProvider diff --git a/src/tasks/buildAndUpload/getUploadTasks.ts b/src/tasks/buildAndUpload/getUploadTasks.ts index 9c26bb35..0523d4bd 100644 --- a/src/tasks/buildAndUpload/getUploadTasks.ts +++ b/src/tasks/buildAndUpload/getUploadTasks.ts @@ -1,5 +1,5 @@ import { ListrTask } from "listr/index.js"; -import { BuildVariantsMap, ListrContextBuild } from "../../types.js"; +import { PackageToBuildProps, ListrContextBuild } from "../../types.js"; import { getGitHeadIfAvailable } from "../../utils/git.js"; import { getPinMetadata } from "../../pinStrategy/index.js"; import { PinKeyvaluesDefault } from "../../releaseUploader/pinata/index.js"; @@ -7,13 +7,13 @@ import { IReleaseUploader } from "../../releaseUploader/index.js"; import { composeDeleteBuildProperties } from "../../files/index.js"; export function getUploadTasks({ - variantsMap, + packagesToBuildProps, skipUpload, releaseUploader, requireGitData, composeFileName }: { - variantsMap: BuildVariantsMap; + packagesToBuildProps: PackageToBuildProps[]; skipUpload?: boolean; releaseUploader: IReleaseUploader; requireGitData: boolean; @@ -21,9 +21,7 @@ export function getUploadTasks({ }): ListrTask[] { const uploadTasks: ListrTask[] = []; - for (const [variant, { manifest, releaseDir }] of Object.entries( - variantsMap - )) { + for (const { manifest, releaseDir } of packagesToBuildProps) { const { name: dnpName } = manifest; uploadTasks.push({ @@ -36,7 +34,6 @@ export function getUploadTasks({ // https://github.com/dappnode/DAppNode_Installer/issues/161 composeDeleteBuildProperties({ dir: releaseDir, composeFileName }); - ctx[dnpName] = ctx[dnpName] || { variant }; ctx[dnpName].releaseMultiHash = await releaseUploader.addFromFs({ dirPath: releaseDir, metadata: getPinMetadata(manifest, gitHead) as PinKeyvaluesDefault, diff --git a/src/tasks/buildAndUpload/index.ts b/src/tasks/buildAndUpload/index.ts index 139b2b61..982f284c 100644 --- a/src/tasks/buildAndUpload/index.ts +++ b/src/tasks/buildAndUpload/index.ts @@ -27,7 +27,7 @@ export function buildAndUpload({ composeFileName, dir, variantsDirPath = defaultVariantsDirName, - variantsMap + packagesToBuildProps }: BuildAndUploadOptions): ListrTask[] { const buildTimeout = parseTimeout(userTimeout); @@ -39,31 +39,31 @@ export function buildAndUpload({ const releaseUploader = getReleaseUploader(releaseUploaderProvider); return [ - getFileValidationTask({ variantsMap, rootDir: dir }), + getFileValidationTask({ packagesToBuildProps, rootDir: dir }), getVerifyConnectionTask({ releaseUploader, skipUpload }), - getReleaseDirCreationTask({ variantsMap }), + getReleaseDirCreationTask({ packagesToBuildProps }), getFileCopyTask({ - variantsMap, + packagesToBuildProps, variantsDirPath, rootDir: dir, composeFileName, requireGitData }), - ...getBuildTasks({ variantsMap, buildTimeout, skipSave, rootDir: dir }), + ...getBuildTasks({ packagesToBuildProps, buildTimeout, skipSave, rootDir: dir }), ...getUploadTasks({ - variantsMap, + packagesToBuildProps, releaseUploader, requireGitData: !!requireGitData, composeFileName, skipUpload }), getDeleteOldPinsTask({ - variantsMap, + packagesToBuildProps, deleteOldPins: !!deleteOldPins, releaseUploaderProvider }), getSaveUploadResultsTask({ - variantsMap, + packagesToBuildProps, rootDir: dir, contentProvider, variantsDirPath, diff --git a/src/tasks/buildAndUpload/types.ts b/src/tasks/buildAndUpload/types.ts index cdac9d2d..3350ae7e 100644 --- a/src/tasks/buildAndUpload/types.ts +++ b/src/tasks/buildAndUpload/types.ts @@ -1,4 +1,4 @@ -import { BuildVariantsMap, PackageImage } from "../../types.js"; +import { PackageToBuildProps } from "../../types.js"; import { UploadTo } from "../../releaseUploader/index.js"; export interface BuildAndUploadOptions { @@ -12,5 +12,5 @@ export interface BuildAndUploadOptions { composeFileName: string; dir: string; variantsDirPath?: string; - variantsMap: BuildVariantsMap; + packagesToBuildProps: PackageToBuildProps[]; } diff --git a/src/tasks/generatePublishTxs/index.ts b/src/tasks/generatePublishTxs/index.ts index ed9573e2..9369dd23 100644 --- a/src/tasks/generatePublishTxs/index.ts +++ b/src/tasks/generatePublishTxs/index.ts @@ -4,7 +4,7 @@ import { getEthereumUrl } from "../../utils/getEthereumUrl.js"; import { getPublishTxLink } from "../../utils/getLinks.js"; import { addReleaseTx } from "../../utils/releaseRecord.js"; import { defaultDir, YargsError } from "../../params.js"; -import { BuildVariantsMap, CliGlobalOptions, ListrContextPublish, TxData } from "../../types.js"; +import { PackageToBuildProps, CliGlobalOptions, ListrContextPublish, TxData } from "../../types.js"; import { ApmRepository } from "@dappnode/toolkit"; import registryAbi from "../../contracts/ApmRegistryAbi.json" assert { type: "json" }; import { semverToArray } from "../../utils/semverToArray.js"; @@ -15,10 +15,6 @@ import { Repo } from "./types.js"; const isZeroAddress = (address: string): boolean => parseInt(address) === 0; -type GenerateTxVariantsMap = { - [K in keyof BuildVariantsMap]: Pick; -} - /** * Generates the transaction data necessary to publish the package. * It will check if the repository exists first: @@ -35,12 +31,12 @@ export function generatePublishTxs({ developerAddress, ethProvider, verbosityOptions, - variantsMap + packagesToBuildProps, }: { developerAddress?: string; ethProvider: string; verbosityOptions: VerbosityOptions; - variantsMap: GenerateTxVariantsMap; + packagesToBuildProps: PackageToBuildProps[]; } & CliGlobalOptions): Listr { // Init APM instance const ethereumUrl = getEthereumUrl(ethProvider); @@ -53,7 +49,7 @@ export function generatePublishTxs({ task: async (ctx, task) => { const contractAddress = "0x0000000000000000000000000000000000000000"; - for (const [, { manifest }] of Object.entries(variantsMap)) { + for (const { manifest } of packagesToBuildProps) { const { name: dnpName, version } = manifest; const releaseMultiHash = ctx[dnpName]?.releaseMultiHash; diff --git a/src/tasks/publish/index.ts b/src/tasks/publish/index.ts index 2eb39314..c122a0ff 100644 --- a/src/tasks/publish/index.ts +++ b/src/tasks/publish/index.ts @@ -22,22 +22,20 @@ export function publish({ githubRelease, verbosityOptions, variantsDirPath, - variantsMap, - isMultiVariant + packagesToBuildProps, }: PublishOptions): ListrTask[] { return [ getVerifyEthConnectionTask({ ethProvider }), getFetchNextVersionsFromApmTask({ releaseType, ethProvider, - variantsMap + packagesToBuildProps }), getUpdateFilesTask({ rootDir: dir, variantsDirPath, composeFileName, - variantsMap, - isMultiVariant + packagesToBuildProps }), getBuildAndUploadTask({ buildOptions: { @@ -48,7 +46,7 @@ export function publish({ userTimeout, requireGitData, deleteOldPins, - variantsMap, + packagesToBuildProps, variantsDirPath }, verbosityOptions @@ -59,7 +57,7 @@ export function publish({ developerAddress, ethProvider, verbosityOptions, - variantsMap + packagesToBuildProps }), getCreateGithubReleaseTask({ dir, diff --git a/src/tasks/publish/subtasks/getBuildAndUploadTask.ts b/src/tasks/publish/subtasks/getBuildAndUploadTask.ts index a106e8da..070d09da 100644 --- a/src/tasks/publish/subtasks/getBuildAndUploadTask.ts +++ b/src/tasks/publish/subtasks/getBuildAndUploadTask.ts @@ -1,8 +1,9 @@ import Listr, { ListrTask } from "listr"; import { BuildAndUploadOptions } from "../../buildAndUpload/types.js"; -import { ListrContextBuild, ListrContextPublish } from "../../../types.js"; +import { ListrContextPublish } from "../../../types.js"; import { buildAndUpload } from "../../buildAndUpload/index.js"; import { VerbosityOptions } from "../../../commands/build/types.js"; +import { merge } from "lodash-es"; export function getBuildAndUploadTask({ buildOptions, @@ -21,24 +22,8 @@ export function getBuildAndUploadTask({ const buildResults = await buildTasks.run(); - copyBuildCtxToPublishCtx({ - buildCtx: buildResults, - publishCtx: ctx - }); + // Add build results to publish context + ctx = merge(ctx, buildResults); } }; } - -function copyBuildCtxToPublishCtx({ - buildCtx, - publishCtx -}: { - buildCtx: ListrContextBuild; - publishCtx: ListrContextPublish; -}) { - for (const [key, result] of Object.entries(buildCtx)) { - publishCtx[key] = publishCtx[key] - ? { ...publishCtx[key], ...result } - : result; - } -} diff --git a/src/tasks/publish/subtasks/getFetchApmVersionsTask.ts b/src/tasks/publish/subtasks/getFetchApmVersionsTask.ts index ff312281..c0db4f7d 100644 --- a/src/tasks/publish/subtasks/getFetchApmVersionsTask.ts +++ b/src/tasks/publish/subtasks/getFetchApmVersionsTask.ts @@ -1,31 +1,35 @@ import { ListrTask } from "listr"; -import { BuildVariantsMap, ListrContextPublish, ReleaseType } from "../../../types.js"; +import { PackageToBuildProps, ListrContextPublish, ReleaseType } from "../../../types.js"; import { getNextVersionFromApm } from "../../../utils/versions/getNextVersionFromApm.js"; import { Manifest } from "@dappnode/types"; export function getFetchNextVersionsFromApmTask({ releaseType, ethProvider, - variantsMap + packagesToBuildProps }: { releaseType: ReleaseType; ethProvider: string; - variantsMap: BuildVariantsMap; + packagesToBuildProps: PackageToBuildProps[]; }): ListrTask { return { title: "Fetch current versions from APM", task: async ctx => { - for (const [, { manifest }] of Object.entries(variantsMap)) { + for (const { manifest, variant, releaseDir } of packagesToBuildProps) { const dnpName = manifest.name; - ctx[dnpName] = ctx[dnpName] || {}; - ctx[dnpName].nextVersion = await getNextPackageVersion({ + const nextVersion = await getNextPackageVersion({ manifest, releaseType, ethProvider }); + ctx[dnpName] = { + variant, + releaseDir, + nextVersion + } } } }; diff --git a/src/tasks/publish/subtasks/getGenerateTxsTask.ts b/src/tasks/publish/subtasks/getGenerateTxsTask.ts index 5ffe70cb..154a711e 100644 --- a/src/tasks/publish/subtasks/getGenerateTxsTask.ts +++ b/src/tasks/publish/subtasks/getGenerateTxsTask.ts @@ -1,6 +1,6 @@ import { ListrTask } from "listr"; import { VerbosityOptions } from "../../../commands/build/types.js"; -import { BuildVariantsMap, ListrContextPublish } from "../../../types.js"; +import { PackageToBuildProps, ListrContextPublish } from "../../../types.js"; import { generatePublishTxs } from "../../generatePublishTxs/index.js"; export function getGenerateTxTask({ @@ -9,14 +9,14 @@ export function getGenerateTxTask({ developerAddress, ethProvider, verbosityOptions, - variantsMap + packagesToBuildProps, }: { dir: string; composeFileName: string; developerAddress?: string; ethProvider: string; verbosityOptions: VerbosityOptions; - variantsMap: BuildVariantsMap; + packagesToBuildProps: PackageToBuildProps[]; }): ListrTask { return { title: "Generate transaction", @@ -27,7 +27,7 @@ export function getGenerateTxTask({ developerAddress, ethProvider, verbosityOptions, - variantsMap + packagesToBuildProps, }); } }; diff --git a/src/tasks/publish/subtasks/getUpdateFilesTask.ts b/src/tasks/publish/subtasks/getUpdateFilesTask.ts index 9459c769..7b72d19e 100644 --- a/src/tasks/publish/subtasks/getUpdateFilesTask.ts +++ b/src/tasks/publish/subtasks/getUpdateFilesTask.ts @@ -1,6 +1,6 @@ import path from "path"; import { ListrTask } from "listr"; -import { BuildVariantsMap, ListrContextPublish } from "../../../types.js"; +import { PackageToBuildProps, ListrContextPublish } from "../../../types.js"; import { writeManifest, readCompose, @@ -14,19 +14,18 @@ export function getUpdateFilesTask({ rootDir, variantsDirPath, composeFileName, - variantsMap, - isMultiVariant + packagesToBuildProps, }: { rootDir: string; variantsDirPath: string; composeFileName: string; - variantsMap: BuildVariantsMap; - isMultiVariant: boolean; + packagesToBuildProps: PackageToBuildProps[]; }): ListrTask { return { title: "Update compose and manifest files", task: async ctx => { - for (const [variant, { manifest: { name }, composePaths, manifestPaths }] of Object.entries(variantsMap)) { + for (const pkgProps of packagesToBuildProps) { + const { variant, manifest: { name }, composePaths, manifestPaths } = pkgProps; const nextVersion = ctx[name].nextVersion; if (!nextVersion) { @@ -42,16 +41,15 @@ export function getUpdateFilesTask({ variantsDirPath, dnpName: name, nextVersion, - isMultiVariant }); const newCompose = readCompose(composePaths); const newManifest = readManifest(manifestPaths).manifest; // Update variantsMap entry - variantsMap[variant].compose = newCompose; - variantsMap[variant].manifest = newManifest; - variantsMap[variant].images = getComposePackageImages(newCompose, newManifest); + pkgProps.compose = newCompose; + pkgProps.manifest = newManifest; + pkgProps.images = getComposePackageImages(newCompose, newManifest); } } }; @@ -65,19 +63,17 @@ export function updateVariantFiles({ variantsDirPath, dnpName, nextVersion, - isMultiVariant }: { rootDir: string; composeFileName: string; - variant: string; + variant: string | null; variantsDirPath: string; dnpName: string; nextVersion: string; - isMultiVariant: boolean; }): void { // For multi-variant packages, manifest and compose files to be modified are located in the variant folder - // Single variant packages have single-variant as the variant name - const filesDir = isMultiVariant ? path.join(variantsDirPath, variant) : rootDir; + // Single variant packages have their files in the root dir + const filesDir = variant ? path.join(variantsDirPath, variant) : rootDir; updateManifestFileVersion({ manifestDir: filesDir, diff --git a/src/tasks/publish/types.ts b/src/tasks/publish/types.ts index 37b84672..6c4f3ccb 100644 --- a/src/tasks/publish/types.ts +++ b/src/tasks/publish/types.ts @@ -1,6 +1,6 @@ import { VerbosityOptions } from "../../commands/build/types.js"; import { UploadTo } from "../../releaseUploader/index.js"; -import { BuildVariantsMap, ReleaseType } from "../../types.js"; +import { PackageToBuildProps, ReleaseType } from "../../types.js"; export interface PublishOptions { releaseType: ReleaseType; @@ -16,6 +16,5 @@ export interface PublishOptions { githubRelease?: boolean; verbosityOptions: VerbosityOptions; variantsDirPath: string; - variantsMap: BuildVariantsMap; - isMultiVariant: boolean; + packagesToBuildProps: PackageToBuildProps[]; } diff --git a/src/types.ts b/src/types.ts index 7e9778eb..2ddb4575 100644 --- a/src/types.ts +++ b/src/types.ts @@ -10,9 +10,9 @@ export interface CliGlobalOptions { // TODO: Try to have all properties defined interface ListrContextBuildItem { - releaseDir?: string; + variant: string | null; + releaseDir: string; releaseMultiHash?: string; - variant?: string; } interface ListrContextPublishItem extends ListrContextBuildItem { @@ -27,13 +27,15 @@ export interface ListrContextPublish { [dnpName: string]: ListrContextPublishItem; } -interface PublishVariantsMapEntry { +export interface PackageToBuildProps { + // For packages not following multi-variant format, variant is null + // These kind of packages have all their files in the root dir + variant: string | null; + // Manifest-related manifest: Manifest; manifestFormat: ManifestFormat; -} -export interface BuildVariantsMapEntry extends PublishVariantsMapEntry { // Compose file compose: Compose; @@ -47,10 +49,6 @@ export interface BuildVariantsMapEntry extends PublishVariantsMapEntry { architectures: Architecture[]; } -export interface BuildVariantsMap { - [variant: string]: BuildVariantsMapEntry; -} - // Interal types export type ReleaseType = "major" | "minor" | "patch"; diff --git a/test/tasks/buildAndUpload/buildVariantMap.test.ts b/test/tasks/buildAndUpload/generatePackagesProps.test.ts similarity index 54% rename from test/tasks/buildAndUpload/buildVariantMap.test.ts rename to test/tasks/buildAndUpload/generatePackagesProps.test.ts index d89edf6e..e40b2fd6 100644 --- a/test/tasks/buildAndUpload/buildVariantMap.test.ts +++ b/test/tasks/buildAndUpload/generatePackagesProps.test.ts @@ -1,12 +1,11 @@ import { expect } from "chai"; -import { buildVariantMap } from "../../../src/tasks/buildAndUpload/buildVariantMap.js"; +import { generatePackagesProps } from "../../../src/tasks/buildAndUpload/generatePackagesProps.js"; import { cleanTestDir, testDir } from "../../testUtils.js"; import { initHandler } from "../../../src/commands/init/handler.js"; import { defaultComposeFileName, defaultVariantsDirName, defaultVariantsEnvValues, - singleVariantName } from "../../../src/params.js"; import { defaultArch } from "@dappnode/types"; import path from "path"; @@ -25,17 +24,19 @@ describe("buildVariantMap", function () { }); }); - it("should return a map with a single variant", function () { - const result = buildVariantMap({ + it("should return a package properties array for a single-variant package", function () { + const pkgsProps = generatePackagesProps({ rootDir: testDir, variantsDirPath: defaultVariantsDirName, variants: null }); - expect(result).to.have.all.keys(singleVariantName); - const defaultVariant = result[singleVariantName]; + expect(pkgsProps).to.be.an("array"); + expect(pkgsProps).to.have.lengthOf(1); - expect(defaultVariant).to.have.all.keys( + const pkgProps = pkgsProps[0]; + + expect(pkgProps).to.have.all.keys( "manifest", "manifestFormat", "compose", @@ -43,27 +44,28 @@ describe("buildVariantMap", function () { "manifestPaths", "composePaths", "images", - "architectures" + "architectures", + "variant" ); // Validate the properties are of correct types or formats - expect(defaultVariant.manifest).to.be.an("object"); - expect(defaultVariant.compose).to.be.an("object"); - expect(defaultVariant.releaseDir).to.be.a("string"); - expect(defaultVariant.composePaths).to.be.an("array"); - expect(defaultVariant.images).to.be.an("array"); - expect(defaultVariant.architectures).to.be.an("array"); - - expect(defaultVariant.composePaths).to.deep.include.members([ + expect(pkgProps.manifest).to.be.an("object"); + expect(pkgProps.compose).to.be.an("object"); + expect(pkgProps.releaseDir).to.be.a("string"); + expect(pkgProps.composePaths).to.be.an("array"); + expect(pkgProps.images).to.be.an("array"); + expect(pkgProps.architectures).to.be.an("array"); + + expect(pkgProps.composePaths).to.deep.include.members([ { composeFileName: defaultComposeFileName, dir: testDir } ]); - expect(defaultVariant.architectures).to.include(defaultArch); + expect(pkgProps.architectures).to.include(defaultArch); - expect(defaultVariant.manifest).to.include.keys(["name", "version"]); + expect(pkgProps.manifest).to.include.keys(["name", "version"]); }); }); @@ -78,17 +80,22 @@ describe("buildVariantMap", function () { }); it("should return a map including all specified variants", function () { - const result = buildVariantMap({ + const pkgsProps = generatePackagesProps({ variants: defaultVariantsEnvValues, rootDir: testDir, variantsDirPath: path.join(testDir, defaultVariantsDirName) }); - // Verify - expect(result).to.have.all.keys(defaultVariantsEnvValues); - defaultVariantsEnvValues.forEach(variant => { - expect(result[variant]).to.be.an("object"); - expect(result[variant]).to.include.all.keys( + expect(pkgsProps).to.be.an("array"); + expect(pkgsProps).to.have.lengthOf(defaultVariantsEnvValues.length); + expect(pkgsProps.map(pkgProps => pkgProps.variant)).to.deep.equal(defaultVariantsEnvValues); + + defaultVariantsEnvValues.forEach((variant, index) => { + const pkgProps = pkgsProps[index]; + + expect(pkgProps).to.be.an("object"); + expect(pkgProps.variant).to.equal(variant); + expect(pkgProps).to.include.all.keys( "manifest", "manifestFormat", "compose", @@ -99,15 +106,15 @@ describe("buildVariantMap", function () { ); // Validate the properties are of correct types or formats - expect(result[variant].manifest).to.be.an("object"); - expect(result[variant].compose).to.be.an("object"); - expect(result[variant].releaseDir).to.be.a("string"); - expect(result[variant].composePaths).to.be.an("array"); - expect(result[variant].images).to.be.an("array"); - expect(result[variant].architectures).to.be.an("array"); + expect(pkgProps.manifest).to.be.an("object"); + expect(pkgProps.compose).to.be.an("object"); + expect(pkgProps.releaseDir).to.be.a("string"); + expect(pkgProps.composePaths).to.be.an("array"); + expect(pkgProps.images).to.be.an("array"); + expect(pkgProps.architectures).to.be.an("array"); // Example: Validate specific variant paths - expect(result[variant].composePaths).to.deep.include.members([ + expect(pkgProps.composePaths).to.deep.include.members([ { composeFileName: defaultComposeFileName, dir: testDir @@ -119,7 +126,7 @@ describe("buildVariantMap", function () { ]); // Assuming we can check details about manifest, compose object structure if known - expect(result[variant].manifest).to.include.keys(["name", "version"]); + expect(pkgProps.manifest).to.include.keys(["name", "version"]); }); }); }); diff --git a/test/utils/versions/updateVariantFiles.test.ts b/test/utils/versions/updateVariantFiles.test.ts index 2e8cef93..9e4e9edf 100644 --- a/test/utils/versions/updateVariantFiles.test.ts +++ b/test/utils/versions/updateVariantFiles.test.ts @@ -1,7 +1,6 @@ import { expect } from "chai"; -import path from "path"; import { cleanTestDir, testDir } from "../../testUtils.js"; -import { defaultComposeFileName, singleVariantName } from "../../../src/params.js"; +import { defaultComposeFileName } from "../../../src/params.js"; import { writeManifest, readCompose, @@ -34,7 +33,7 @@ describe("Update Variant Files and Entries", function () { before("Clean testDir", () => cleanTestDir()); after("Clean testDir", () => cleanTestDir()); - it("Should update manifest and compose files correctly", async () => { + it("Should update manifest and compose files correctly for a single variant package", async () => { // Write initial manifest and compose files writeManifest(manifest, ManifestFormat.json, { dir: testDir }); writeCompose(compose, { dir: testDir }); @@ -43,11 +42,10 @@ describe("Update Variant Files and Entries", function () { updateVariantFiles({ rootDir: testDir, composeFileName: defaultComposeFileName, - variant: singleVariantName, + variant: null, variantsDirPath: testDir, dnpName, nextVersion, - isMultiVariant: false }); // Check that the manifest was updated correctly