Skip to content

Commit

Permalink
Merge pull request #29 from casper-network/feature/fetch-versions-github
Browse files Browse the repository at this point in the history
Fetch available versions from GitHub tags
  • Loading branch information
Ryo Kanazawa authored Aug 1, 2023
2 parents fef7b9a + 62677d2 commit d201c7e
Show file tree
Hide file tree
Showing 9 changed files with 138 additions and 82 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"@oclif/core": "^2",
"@oclif/plugin-help": "^5",
"@oclif/plugin-plugins": "^2.4.7",
"axios": "^1.4.0",
"chokidar": "^3.5.3",
"envsub": "^4.1.0",
"kleur": "^4.1.5",
Expand Down
24 changes: 16 additions & 8 deletions src/commands/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,36 +7,44 @@ import { Args, Command } from "@oclif/core";
// @ts-ignore
import envsub from "envsub";

import { CONFIG_DIR, NETWORK_NAMES, NODE_VERSIONS, WORK_DIR } from "../config";
import { CONFIG_DIR, NETWORK_NAMES, WORK_DIR } from "../config";
import { checkVersion, fetchLatestVersion } from "../utils/check-version";

export default class Config extends Command {
static description = "Generate config files";

static args = {
branch: Args.string({
name: "branch", // name of arg to show in help and reference with args[name]
version: Args.string({
name: "version", // name of arg to show in help and reference with args[name]
required: false, // make the arg required with `required: true`
description: "The branch to use", // help description
default: NODE_VERSIONS.at(-2)!, // use the latest release version
options: NODE_VERSIONS, // only allow input to be from a discrete set
description: "The version to use", // help description
}),
networkName: Args.string({
name: "networkName", // name of arg to show in help and reference with args[name]
required: false, // make the arg required with `required: true`
description: "The default network name", // help description
default: NETWORK_NAMES.at(-2)!, // use the latest release version
default: NETWORK_NAMES.at(-2)!,
options: NETWORK_NAMES, // only allow input to be from a discrete set
}),
};

async run(): Promise<void> {
const { args } = await this.parse(Config);

// checks the version
const version = args.version || (await fetchLatestVersion());
const isValidVersion = await checkVersion(version);

if (!isValidVersion) {
this.logToStderr(`Not found version: ${version}`);
this.exit(-1);
}

const configDir = path.resolve(
__dirname,
"../..",
WORK_DIR,
args.branch,
version,
CONFIG_DIR
);
if (!fs.existsSync(configDir)) {
Expand Down
27 changes: 17 additions & 10 deletions src/commands/download.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,33 @@ import {
CONFIG_DIR,
chainSpecTemplate,
configFile,
NODE_VERSIONS,
} from "../config";
import { checkVersion, fetchLatestVersion } from "../utils/check-version";

export default class Download extends Command {
static description = "Download required assets for running casper node.";

static args = {
branch: Args.string({
name: "branch", // name of arg to show in help and reference with args[name]
version: Args.string({
name: "version", // name of arg to show in help and reference with args[name]
required: false, // make the arg required with `required: true`
description: "The branch to use", // help description
default: NODE_VERSIONS.at(-2)!, // use the latest release version
options: NODE_VERSIONS, // only allow input to be from a discrete set
description: "The version to use", // help description
}),
};

async run(): Promise<void> {
const { args } = await this.parse(Download);

const workDir = path.resolve(__dirname, "../..", WORK_DIR, args.branch);
// checks the version
const version = args.version || (await fetchLatestVersion());
const isValidVersion = await checkVersion(version);

if (!isValidVersion) {
this.logToStderr(`Not found version: ${version}`);
this.exit(-1);
}

const workDir = path.resolve(__dirname, "../..", WORK_DIR, version);
const binDir = path.resolve(workDir, BIN_DIR);
const configDir = path.resolve(workDir, CONFIG_DIR);

Expand All @@ -43,7 +50,7 @@ export default class Download extends Command {

if (!fs.existsSync(binaryPath)) {
await download(
nodeUrl.replace("{GH_BRANCH}", args.branch),
nodeUrl.replace("{GH_BRANCH}", version),
binaryPath,
console.error
);
Expand All @@ -57,15 +64,15 @@ export default class Download extends Command {

if (!fs.existsSync(specPath)) {
await download(
chainSpecTemplate.replace("{GH_BRANCH}", args.branch),
chainSpecTemplate.replace("{GH_BRANCH}", version),
specPath,
console.error
);
}

if (!fs.existsSync(configPath)) {
await download(
configFile.replace("{GH_BRANCH}", args.branch),
configFile.replace("{GH_BRANCH}", version),
configPath,
console.error
);
Expand Down
39 changes: 30 additions & 9 deletions src/commands/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,18 @@ import {
CONFIG_DIR,
FUNDED_KEYS,
NETWORK_NAMES,
NODE_VERSIONS,
WORK_DIR,
} from "../config";
import { checkVersion, fetchLatestVersion } from "../utils/check-version";

export default class Node extends Command {
static description = "Starts a single Casper node.";

static args = {
branch: Args.string({
name: "branch", // name of arg to show in help and reference with args[name]
version: Args.string({
name: "version", // name of arg to show in help and reference with args[name]
required: false, // make the arg required with `required: true`
description: "The branch to use", // help description
default: NODE_VERSIONS.at(-2)!, // use the latest release version
options: NODE_VERSIONS, // only allow input to be from a discrete set
description: "The version to use", // help description
}),
networkName: Args.string({
name: "networkName", // name of arg to show in help and reference with args[name]
Expand All @@ -38,20 +36,30 @@ export default class Node extends Command {
static flags = {
// can pass either --force or -f
daemon: Flags.boolean({ char: "d" }),
"force-download": Flags.boolean({ char: "f" }),
};

async run(): Promise<void> {
const { args, flags } = await this.parse(Node);

// checks the version
const version = args.version || (await fetchLatestVersion());
const isValidVersion = await checkVersion(version);

if (!isValidVersion) {
this.logToStderr(`Not found version: ${version}`);
this.exit(-1);
}

ux.action.start("Donwloading assets");
await this.config.runCommand("download", [args.branch]);
await this.config.runCommand("download", [version]);
ux.action.stop();

ux.action.start("Generating config files to run node");
await this.config.runCommand("config", [args.branch, args.networkName]);
await this.config.runCommand("config", [version, args.networkName]);
ux.action.stop();

const workDir = path.resolve(__dirname, "../..", WORK_DIR, args.branch);
const workDir = path.resolve(__dirname, "../..", WORK_DIR, version);
const binDir = path.resolve(workDir, BIN_DIR);
const configDir = path.resolve(workDir, CONFIG_DIR);
const binaryPath = path.resolve(binDir, "casper-node");
Expand Down Expand Up @@ -107,6 +115,7 @@ export default class Node extends Command {
});

let rpcStarted = false;
let speculativeStarted = false;
let restStarted = false;
let eventStreamStarted = false;

Expand Down Expand Up @@ -144,6 +153,18 @@ export default class Node extends Command {
kleur.green(`Started event stream server at http://127.0.0.1:9999`)
);
}

if (
data.includes("started speculative execution server") &&
!speculativeStarted
) {
speculativeStarted = true;
console.info(
kleur.green(
`Started speculative execution server at http://127.0.0.1:7778`
)
);
}
});

// log pid for further stop
Expand Down
21 changes: 2 additions & 19 deletions src/commands/stop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,13 @@ import * as fs from "node:fs";
import * as path from "node:path";

import shell from "shelljs";
import { Args, Command } from "@oclif/core";
import { Command } from "@oclif/core";

import { NETWORK_NAMES, NODE_VERSIONS, WORK_DIR } from "../config";
import { WORK_DIR } from "../config";

export default class Stop extends Command {
static description = "Stop running node in background.";

static args = {
branch: Args.string({
name: "branch", // name of arg to show in help and reference with args[name]
required: false, // make the arg required with `required: true`
description: "The branch to use", // help description
default: NODE_VERSIONS.at(-2)!, // use the latest release version
options: NODE_VERSIONS, // only allow input to be from a discrete set
}),
networkName: Args.string({
name: "networkName", // name of arg to show in help and reference with args[name]
required: false, // make the arg required with `required: true`
description: "The default network name", // help description
default: NETWORK_NAMES.at(-2)!, // use the latest release version
options: NETWORK_NAMES, // only allow input to be from a discrete set
}),
};

async run(): Promise<void> {
const { args } = await this.parse(Stop);

Expand Down
36 changes: 1 addition & 35 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,41 +5,7 @@ export const CONFIG_DIR = `config/1_0_0`;
export const nodeUrl = `https://s3.us-east-2.amazonaws.com/nctl.casperlabs.io/{GH_BRANCH}/casper-node`;
export const chainSpecTemplate = `https://raw.githubusercontent.com/casper-network/casper-node/{GH_BRANCH}/resources/local/chainspec.toml.in`;
export const configFile = `https://raw.githubusercontent.com/casper-network/casper-node/{GH_BRANCH}/resources/local/config.toml`;

export const NODE_VERSIONS = [
"v0.9.0",
"v0.9.3",
"v0.9.3.1",
"v0.9.4",
"v1.0.0",
"v1.0.1",
"v1.1.0",
"v1.1.1",
"v1.1.2",
"v1.2.0",
"v1.2.1",
"v1.3.0",
"v1.3.1",
"v1.3.2",
"v1.3.3",
"v1.3.4",
"v1.4.0",
"v1.4.1",
"v1.4.2",
"v1.4.3",
"v1.4.4",
"v1.4.5",
"v1.4.6",
"v1.4.8",
"v1.4.9",
"v1.4.13",
"v1.4.14",
"v1.4.15",
"v1.4.15-alt",
"v1.5.0-rc.1",
"v1.5.1",
"dev",
];
export const githubTag = `https://api.github.com/repos/casper-network/casper-node/tags`;

export const FUNDED_KEYS = [
{
Expand Down
42 changes: 42 additions & 0 deletions src/utils/check-version.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/* eslint-disable camelcase */
import * as fs from "node:fs";
import * as path from "node:path";
import axios from "axios";

import { WORK_DIR, githubTag } from "../config";

export interface Tag {
name: string;
zipball_url: string;
tarball_url: string;
commit: Commit;
node_id: string;
}

export interface Commit {
sha: string;
url: string;
}

export const getVersions = async (): Promise<string[]> => {
const { data } = await axios.get<Tag[]>(githubTag);
const versions = data.map((tag) => tag.name);

return versions;
};

export const checkVersion = async (version: string): Promise<boolean> => {
if (version === "dev") return true;
const workDir = path.resolve(__dirname, "../..", WORK_DIR);

// Return true for downloaded version
if (fs.existsSync(path.resolve(workDir, version))) return true;

const versions = await getVersions();
return versions.includes(version);
};

export const fetchLatestVersion = async (): Promise<string> => {
const versions = await getVersions();
return versions[0];
};
2 changes: 1 addition & 1 deletion src/utils/download.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default async function download(
const response = await fetch(url);

if (!response.ok) {
throw new Error("Unable to access");
throw new Error(`Unable to access to ${url}`);
}

return new Promise<void>((resolve) => {
Expand Down
28 changes: 28 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1308,6 +1308,15 @@ aws-sdk@^2.1231.0:
uuid "8.0.0"
xml2js "0.4.19"

axios@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.4.0.tgz#38a7bf1224cd308de271146038b551d725f0be1f"
integrity sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==
dependencies:
follow-redirects "^1.15.0"
form-data "^4.0.0"
proxy-from-env "^1.1.0"

balanced-match@^1.0.0:
version "1.0.2"
resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz"
Expand Down Expand Up @@ -2623,6 +2632,11 @@ flatted@^3.1.0:
resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.4.tgz"
integrity sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==

follow-redirects@^1.15.0:
version "1.15.2"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13"
integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==

for-each@^0.3.3:
version "0.3.3"
resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e"
Expand All @@ -2647,6 +2661,15 @@ form-data@^3.0.0:
combined-stream "^1.0.8"
mime-types "^2.1.12"

form-data@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452"
integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==
dependencies:
asynckit "^0.4.0"
combined-stream "^1.0.8"
mime-types "^2.1.12"

fs-extra@^8.1:
version "8.1.0"
resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz"
Expand Down Expand Up @@ -4859,6 +4882,11 @@ propagate@^2.0.0:
resolved "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz"
integrity sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==

proxy-from-env@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==

pump@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz"
Expand Down

0 comments on commit d201c7e

Please sign in to comment.