diff --git a/src/commands/increase.ts b/src/commands/increase.ts deleted file mode 100644 index 80b50155..00000000 --- a/src/commands/increase.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { CommandModule } from "yargs"; -import { increaseFromLocalVersion } from "../utils/versions/increaseFromLocalVersion"; -import { CliGlobalOptions, ReleaseType } from "../types"; -import { defaultComposeFileName, defaultDir } from "../params"; - -export const command = "increase [type]"; - -export const describe = "Increases the version defined in the manifest"; - -interface CliCommandOptions extends CliGlobalOptions { - type: string; -} - -export const increase: CommandModule = { - command: "increase [type]", - describe: "Increases the version defined in the manifest", - - builder: yargs => - yargs.positional("type", { - description: "Semver update type: [ major | minor | patch ]", - choices: ["major", "minor", "patch"], - type: "string", - demandOption: true - }), - - handler: async (args): Promise => { - const nextVersion = await increaseHandler(args); - // Output result: "0.1.8" - console.log(nextVersion); - } -}; - -/** - * Common handler for CLI and programatic usage - */ -export async function increaseHandler({ - type, - dir = defaultDir, - compose_file_name = defaultComposeFileName -}: CliCommandOptions): Promise { - return await increaseFromLocalVersion({ - type: type as ReleaseType, - dir, - compose_file_name - }); -} diff --git a/src/commands/list.ts b/src/commands/list.ts new file mode 100644 index 00000000..fcd8ac60 --- /dev/null +++ b/src/commands/list.ts @@ -0,0 +1,60 @@ +import { CommandModule } from "yargs"; +import { CliGlobalOptions } from "../types"; +import { defaultDir } from "../params"; +import { readManifest } from "../utils/manifest"; +import { Apm } from "../utils/Apm"; + +interface CliCommandOptions extends CliGlobalOptions { + provider: string; + tag?: string; +} + +export const list: CommandModule = { + command: "list [tag]", + describe: "List package version tags", + + builder: yargs => + yargs + .positional("tag", { + description: "tag to print version of", + type: "string" + }) + .option("provider", { + description: `Specify an eth provider: "dappnode" (default), "infura", "localhost:8545"`, + default: "dappnode", + type: "string" + }), + + handler: async (args): Promise => { + const tagsWithVersions = await listHandler(args); + + if (args.tag) { + // Output result: "0.1.8" + const version = tagsWithVersions[args.tag]; + if (!version) { + throw Error(`Tag ${args.tag} not found`); + } else { + console.log(version); + } + } else { + for (const [tag, version] of Object.entries(tagsWithVersions)) { + // Output result: "latest: 0.1.8" + console.log(`${tag}: ${version}`); + } + } + } +}; + +/** + * Common handler for CLI and programatic usage + */ +export async function listHandler({ + provider, + dir = defaultDir +}: CliCommandOptions): Promise> { + const { manifest } = readManifest({ dir }); + + return { + latest: await new Apm(provider).getLatestVersion(manifest.name) + }; +} diff --git a/src/commands/next.ts b/src/commands/next.ts deleted file mode 100644 index d35956d6..00000000 --- a/src/commands/next.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { CommandModule } from "yargs"; -import { getNextVersionFromApm } from "../utils/versions/getNextVersionFromApm"; -import { verifyEthConnection } from "../utils/verifyEthConnection"; -import { CliGlobalOptions, ReleaseType } from "../types"; -import { defaultDir } from "../params"; - -interface CliCommandOptions extends CliGlobalOptions { - type: string; - provider: string; -} - -export const next: CommandModule = { - command: "next [type]", - describe: "Compute the next release version from local", - - builder: yargs => - yargs - .positional("type", { - description: "Semver update type: [ major | minor | patch ]", - choices: ["major", "minor", "patch"], - type: "string" - }) - .option("provider", { - alias: "p", - description: `Specify an ipfs provider: "dappnode" (default), "infura", "localhost:5002"`, - default: "dappnode", - type: "string" - }) - .require("type"), - - handler: async (args): Promise => { - const nextVersion = await nextHandler(args); - // Output result: "0.1.8" - console.log(nextVersion); - } -}; - -/** - * Common handler for CLI and programatic usage - */ -export async function nextHandler({ - type, - provider, - dir = defaultDir -}: CliCommandOptions): Promise { - const ethProvider = provider; - - await verifyEthConnection(ethProvider); - - // Execute command - return await getNextVersionFromApm({ - type: type as ReleaseType, - ethProvider, - dir - }); -} diff --git a/src/commands/publish.ts b/src/commands/publish.ts index b37922d9..5297297f 100644 --- a/src/commands/publish.ts +++ b/src/commands/publish.ts @@ -1,4 +1,3 @@ -import path from "path"; import Listr from "listr"; import chalk from "chalk"; import { CommandModule } from "yargs"; @@ -7,19 +6,14 @@ import { buildAndUpload } from "../tasks/buildAndUpload"; import { generatePublishTx } from "../tasks/generatePublishTx"; import { createGithubRelease } from "../tasks/createGithubRelease"; // Utils -import { getCurrentLocalVersion } from "../utils/versions/getCurrentLocalVersion"; -import { increaseFromApmVersion } from "../utils/versions/increaseFromApmVersion"; import { verifyEthConnection } from "../utils/verifyEthConnection"; import { getInstallDnpLink, getPublishTxLink } from "../utils/getLinks"; -import { defaultComposeFileName, defaultDir, YargsError } from "../params"; -import { CliGlobalOptions, ReleaseType, releaseTypes, TxData } from "../types"; +import { defaultComposeFileName, defaultDir } from "../params"; +import { CliGlobalOptions, TxData } from "../types"; import { printObject } from "../utils/print"; import { UploadTo } from "../releaseUploader"; -const typesList = releaseTypes.join(" | "); - interface CliCommandOptions extends CliGlobalOptions { - type?: string; provider?: string; eth_provider: string; content_provider: string; @@ -33,18 +27,12 @@ interface CliCommandOptions extends CliGlobalOptions { } export const publish: CommandModule = { - command: "publish [type]", + command: "publish", describe: "Publish a new version of the package in an Aragon Package Manager Repository", builder: yargs => yargs - // Do not add `.require("type")`, it is verified below - .positional("type", { - description: `Semver update type. Can also be provided with env RELEASE_TYPE=[type] or via TRAVIS_TAG=release (patch), TRAVIS_TAG=release/[type]`, - choices: releaseTypes, - type: "string" - }) .option("provider", { alias: "p", description: `Specify a provider (overwrittes content_provider and eth_provider): "dappnode" (default), "infura", "http://localhost:8545"`, @@ -123,7 +111,6 @@ export const publish: CommandModule = { * Common handler for CLI and programatic usage */ export async function publishHanlder({ - type, provider, eth_provider, content_provider, @@ -156,8 +143,6 @@ export async function publishHanlder({ const deleteOldPins = delete_old_pins; const isCi = process.env.CI; - const tag = process.env.TRAVIS_TAG || process.env.GITHUB_REF; - const typeFromEnv = process.env.RELEASE_TYPE; /** * Specific set of options used for internal DAppNode releases. @@ -175,54 +160,11 @@ export async function publishHanlder({ githubRelease = true; } - /** - * Custom options to pass the type argument - */ - if (!type && typeFromEnv) { - type = typeFromEnv as ReleaseType; - } - if (!type && tag && tag.includes("release")) { - type = (tag.split("release/")[1] || "patch") as ReleaseType; - } - - /** - * Make sure the release type exists and is correct - */ - if (!type) - throw new YargsError(`Missing required argument [type]: ${typesList}`); - if (!releaseTypes.includes(type as ReleaseType)) - throw new YargsError( - `Invalid release type "${type}", must be: ${typesList}` - ); - await verifyEthConnection(ethProvider); const publishTasks = new Listr( [ - // 1. Fetch current version from APM - { - title: "Fetch current version from APM", - task: async (ctx, task) => { - let nextVersion; - try { - nextVersion = await increaseFromApmVersion({ - type: type as ReleaseType, - ethProvider, - dir, - composeFileName - }); - } catch (e) { - if (e.message.includes("NOREPO")) - nextVersion = getCurrentLocalVersion({ dir }); - else throw e; - } - ctx.nextVersion = nextVersion; - ctx.buildDir = path.join(dir, `build_${nextVersion}`); - task.title = task.title + ` (next version: ${nextVersion})`; - } - }, - - // 2. Build and upload + // Build and upload { title: "Build and upload", task: ctx => @@ -241,7 +183,7 @@ export async function publishHanlder({ ) }, - // 3. Generate transaction + // Generate transaction { title: "Generate transaction", task: ctx => @@ -256,7 +198,7 @@ export async function publishHanlder({ }) }, - // 4. Create github release + // Create github release // [ONLY] add the Release task if requested { title: "Release on github", diff --git a/src/commands/version.ts b/src/commands/version.ts new file mode 100644 index 00000000..03c456c9 --- /dev/null +++ b/src/commands/version.ts @@ -0,0 +1,63 @@ +import { CommandModule } from "yargs"; +import semver from "semver"; +import { CliGlobalOptions } from "../types"; +import { defaultComposeFileName, defaultDir } from "../params"; +import { readManifest, writeManifest } from "../utils/manifest"; +import { + readCompose, + updateComposeImageTags, + writeCompose +} from "../utils/compose"; + +interface CliCommandOptions extends CliGlobalOptions { + type: string; +} + +export const version: CommandModule = { + command: "version [type]", + describe: "Bump a package version", + + builder: yargs => + yargs.positional("type", { + description: "Semver update type: [ major | minor | patch ]", + choices: ["major", "minor", "patch"], + type: "string", + demandOption: true + }), + + handler: async (args): Promise => { + const nextVersion = await versionHandler(args); + // Output result: "0.1.8" + console.log(nextVersion); + } +}; + +/** + * Common handler for CLI and programatic usage + */ +export async function versionHandler({ + type, + dir = defaultDir, + compose_file_name: composeFileName = defaultComposeFileName +}: CliCommandOptions): Promise { + // Load manifest + const { manifest, format } = readManifest({ dir }); + + // If `type` is a valid `semver.ReleaseType` the version will be bumped, else return null + const nextVersion = + semver.inc(manifest.version, type as semver.ReleaseType) || type; + if (!semver.valid(nextVersion)) { + throw Error(`Invalid semver bump or version: ${type}`); + } + + // Mofidy and write the manifest and docker-compose + manifest.version = nextVersion; + writeManifest(manifest, format, { dir }); + + const { name, version } = manifest; + const compose = readCompose({ dir, composeFileName }); + const newCompose = updateComposeImageTags(compose, { name, version }); + writeCompose(newCompose, { dir, composeFileName }); + + return nextVersion; +} diff --git a/src/dappnodesdk.ts b/src/dappnodesdk.ts index bca9e06f..76e10432 100755 --- a/src/dappnodesdk.ts +++ b/src/dappnodesdk.ts @@ -7,10 +7,10 @@ import dotenv from "dotenv"; import { build } from "./commands/build"; import { fromGithub } from "./commands/from_github"; -import { increase } from "./commands/increase"; import { init } from "./commands/init"; -import { next } from "./commands/next"; +import { list } from "./commands/list"; import { publish } from "./commands/publish"; +import { version } from "./commands/version"; import { githubActions } from "./commands/githubActions"; // "source-map-support" MUST be imported for stack traces to work properly after Typescript transpile - @@ -53,10 +53,10 @@ const dappnodesdk = yargs }) .command(build) .command(fromGithub) - .command(increase) .command(init) - .command(next) + .command(list) .command(publish) + .command(version) .command(githubActions); dappnodesdk.alias("h", "help"); diff --git a/src/index.ts b/src/index.ts index cd117834..219c216d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,15 +1,15 @@ import { buildHandler } from "./commands/build"; import { fromGithubHandler } from "./commands/from_github"; -import { increaseHandler } from "./commands/increase"; import { initHandler } from "./commands/init"; -import { nextHandler } from "./commands/next"; +import { listHandler } from "./commands/list"; import { publishHanlder } from "./commands/publish"; +import { versionHandler } from "./commands/version"; export const dappnodesdk = { build: buildHandler, fromGithub: fromGithubHandler, - increase: increaseHandler, init: initHandler, - next: nextHandler, - publish: publishHanlder + list: listHandler, + publish: publishHanlder, + version: versionHandler };