Skip to content

Commit

Permalink
Merge pull request #13 from iotaledger/feature/env-vars
Browse files Browse the repository at this point in the history
feat(cli) Env var support
  • Loading branch information
obany authored Aug 18, 2020
2 parents 1e3a86c + 78a3a11 commit e5bd0bc
Show file tree
Hide file tree
Showing 14 changed files with 498 additions and 259 deletions.
4 changes: 2 additions & 2 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -1199,10 +1199,10 @@ module.exports = {
"error"
],
"unicorn/no-null": [
"error"
"off"
],
"unicorn/no-process-exit": [
"error"
"off"
],
"unicorn/no-reduce": [
"off"
Expand Down
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Changelog

## v0.7.1

Show additional defaults in CLI help
Fix missing address index in cli
Added env var processing for GITHUB_TOKEN, GITHUB_REPOSITORY, GITHUB_REF and GTR_SEED
As we now support env vars for the required options it is valid to have no command line parameters
All parameter validation errors shown at once
Added --no-color option

## v0.7.0

Refactored to include CLI
Expand Down
15 changes: 12 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ jobs:
steps:
- name: Tangle Release
id: tangle_release
uses: iotaledger/[email protected].0
uses: iotaledger/[email protected].1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
IOTA_SEED: ${{ secrets.IOTA_SEED }}
Expand Down Expand Up @@ -107,7 +107,7 @@ gh-tangle-release
You will then be presented with the following options.

```shell
GitHub Tangle Release v0.7.0 🚀
GitHub Tangle Release v0.7.1 🚀

Usage: gh-tangle-release [options]

Expand All @@ -123,13 +123,22 @@ Options:
"https://nodes.iota.cafe:443")
--depth <number> Depth to use for attaching the transaction to the tangle (default: "3")
--mwm <number> Minimum weight magnitude to use for attaching the transaction to the tangle (default: "14")
--seed <string> 81 Tryte seed used to generate addresses
--seed <string> 81 Tryte seed used to generate addresses (required)
--address-index <number> Index number used to generate addresses (default: "0")
--transaction-tag <string> Tag to apply to the Tangle transaction (default: "GITHUB9RELEASE")
--comment <string> An optional comment to include in the Tangle transaction payload
--explorer-url <string> Url of the explorer to use for exploration link (default: "https://utils.iota.org/transaction/:hash")
--no-color Disable colored output
--help Display help

You can also supply some of the options through environment variables:
--github-token: GITHUB_TOKEN
--owner: GITHUB_REPOSITORY[0]
--repository: GITHUB_REPOSITORY[1]
where GITHUB_REPOSITORY is formatted owner/repository
--release-tag: GITHUB_REF
--seed: GTR_SEED


Example: gh-tangle-release --github-token a4d936470cb3d66f5434f787c2500bde9764f --owner my-org --repository my-repo --release-tag v1.0.1 --seed AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
```
38 changes: 21 additions & 17 deletions action/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2458,33 +2458,34 @@ const iota_1 = __webpack_require__(586);
* @returns The config as non partial.
*/
function sanitizeInput(config) {
const errors = [];
if (!config.githubToken) {
throw new Error("You must provide the GitHub token option");
errors.push("You must provide the GitHub token option");
}
if (!config.owner) {
throw new Error("You must provide the owner option");
errors.push("You must provide the owner option");
}
if (!config.repository) {
throw new Error("You must provide the repository option");
errors.push("You must provide the repository option");
}
if (!config.releaseTag) {
throw new Error("You must provide the release tag option");
errors.push("You must provide the release tag option");
}
if (!config.seed) {
throw new Error("You must provide the seed option");
errors.push("You must provide the seed option");
}
if (!/[9A-Z]/.test(config.seed)) {
throw new Error("The seed option must be 81 trytes [A-Z9]");
else if (!/[9A-Z]/.test(config.seed)) {
errors.push("The seed option must be 81 trytes [A-Z9]");
}
if (config.seed.length !== 81) {
throw new Error(`The seed option must be 81 trytes [A-Z9], it is ${config.seed.length}`);
else if (config.seed.length !== 81) {
errors.push(`The seed option must be 81 trytes [A-Z9], it is ${config.seed.length}`);
}
config.transactionTag = config.transactionTag || "GITHUB9RELEASE";
if (!/[9A-Z]/.test(config.transactionTag)) {
throw new Error("The transaction tag option must be 27 trytes [A-Z9] or less");
errors.push("The transaction tag option must be 27 trytes [A-Z9] or less");
}
if (config.transactionTag.length >= 27) {
throw new Error(`The transaction tag option must be 27 trytes [A-Z9] or less, it is ${config.transactionTag.length}`);
if (config.transactionTag.length > 27) {
errors.push(`The transaction tag option must be 27 trytes [A-Z9] or less, it is ${config.transactionTag.length}`);
}
config.explorerUrl = config.explorerUrl || "https://utils.iota.org/transaction/:hash";
config.node = config.node || "https://nodes.iota.cafe:443";
Expand Down Expand Up @@ -2518,15 +2519,18 @@ function sanitizeInput(config) {
else {
mwm = config.mwm;
}
if (errors.length > 0) {
throw new Error(errors.join("\n"));
}
return {
githubToken: config.githubToken,
owner: config.owner,
repository: config.repository,
releaseTag: config.releaseTag,
githubToken: config.githubToken || "",
owner: config.owner || "",
repository: config.repository || "",
releaseTag: config.releaseTag || "",
node: config.node,
depth,
mwm,
seed: config.seed,
seed: config.seed || "",
addressIndex,
transactionTag: config.transactionTag,
comment: config.comment,
Expand Down
138 changes: 138 additions & 0 deletions dist/cli-core.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.cliCore = void 0;
const chalk_1 = __importDefault(require("chalk"));
const commander_1 = require("commander");
const node_emoji_1 = __importDefault(require("node-emoji"));
const core_1 = require("./core");
/**
* Execute the cli core.
* @param argv The command line arguments.
* @param env The environment variables.
* @param display Method to output display.
*/
function cliCore(argv, env, display) {
return __awaiter(this, void 0, void 0, function* () {
const program = new commander_1.Command();
try {
const version = "0.7.1";
program
.storeOptionsAsProperties(false)
.passCommandToAction(false)
.name(chalk_1.default.yellowBright("gh-tangle-release"))
.version(version, "-v, --version", chalk_1.default.yellowBright("output the current version"))
.description(chalk_1.default.cyan("An application for creating a transaction on the IOTA Tangle from a GitHub release."))
.option("--github-token <string>", chalk_1.default.yellowBright("GitHub token for accessing your repository (required)"))
.option("--owner <string>", chalk_1.default.yellowBright("GitHub repository owner (required)"))
.option("--repository <string>", chalk_1.default.yellowBright("GitHub repository (required)"))
.option("--release-tag <string>", chalk_1.default.yellowBright("The release tag from the GitHub repository (required)"))
.option("--node <string>", chalk_1.default.yellowBright("Url of the node to use for attaching the transaction to the tangle"), "https://nodes.iota.cafe:443")
.option("--depth <number>", chalk_1.default.yellowBright("Depth to use for attaching the transaction to the tangle"), "3")
.option("--mwm <number>", chalk_1.default.yellowBright("Minimum weight magnitude to use for attaching the transaction to the tangle"), "14")
.option("--seed <string>", chalk_1.default.yellowBright("81 Tryte seed used to generate addresses (required)"))
.option("--address-index <number>", chalk_1.default.yellowBright("Index number used to generate addresses"), "0")
.option("--transaction-tag <string>", chalk_1.default.yellowBright("Tag to apply to the Tangle transaction"), "GITHUB9RELEASE")
.option("--comment <string>", chalk_1.default.yellowBright("An optional comment to include in the Tangle transaction payload"))
.option("--explorer-url <string>", chalk_1.default.yellowBright("Url of the explorer to use for exploration link"), "https://utils.iota.org/transaction/:hash")
.option("--no-color", chalk_1.default.yellowBright("Disable colored output"))
.helpOption("--help", chalk_1.default.yellowBright("Display help"));
program.parse(argv);
const opts = program.opts();
console.log(opts);
display(chalk_1.default.green(`GitHub Tangle Release v${version} ${opts.color === false ? "" : node_emoji_1.default.get("rocket")}\n`));
const envRepo = env.GITHUB_REPOSITORY ? env.GITHUB_REPOSITORY.split("/") : [];
if (envRepo.length === 2) {
opts.owner = opts.owner || envRepo[0];
opts.repository = opts.repository || envRepo[1];
}
const config = core_1.sanitizeInput({
githubToken: opts.githubToken || env.GITHUB_TOKEN,
owner: opts.owner,
repository: opts.repository,
releaseTag: opts.releaseTag || env.GITHUB_REF,
node: opts.node,
depth: opts.depth,
mwm: opts.mwm,
seed: opts.seed || env.GTR_SEED,
addressIndex: opts.addressIndex,
transactionTag: opts.transactionTag,
comment: opts.comment,
explorerUrl: opts.explorerUrl
});
display("Options:");
display(chalk_1.default.cyan("\tGitHub Token"), chalk_1.default.white("*******"));
display(chalk_1.default.cyan("\tOwner"), chalk_1.default.white(config.owner));
display(chalk_1.default.cyan("\tRepository"), chalk_1.default.white(config.repository));
display(chalk_1.default.cyan("\tRelease Tag"), chalk_1.default.white(config.releaseTag));
display(chalk_1.default.cyan("\tNode"), chalk_1.default.white(config.node));
display(chalk_1.default.cyan("\tDepth"), chalk_1.default.white(config.depth));
display(chalk_1.default.cyan("\tMWM"), chalk_1.default.white(config.mwm));
display(chalk_1.default.cyan("\tSeed"), chalk_1.default.white("*******"));
display(chalk_1.default.cyan("\tAddress Index"), chalk_1.default.white(config.addressIndex));
display(chalk_1.default.cyan("\tTransaction Tag"), chalk_1.default.white(config.transactionTag));
if (config.comment) {
display(chalk_1.default.cyan("\tComment"), chalk_1.default.white(config.comment));
}
display(chalk_1.default.cyan("\tExplorer Url"), chalk_1.default.white(config.explorerUrl));
display("");
try {
const transactionDetails = yield core_1.tangleRelease(config, message => display(chalk_1.default.green(message)));
display("Transaction Hash:", chalk_1.default.cyan(transactionDetails.hash));
display("You can view the transaction on the tangle at:", chalk_1.default.cyan(transactionDetails.url));
display(chalk_1.default.green("Complete"));
}
catch (err) {
display("");
display(createErrors(err));
process.exit(1);
}
}
catch (err) {
program.help(str => `${str}${createEnvHelp()}${createExample()}${createErrors(err)}`);
process.exit(1);
}
});
}
exports.cliCore = cliCore;
/**
* Show an example on the console.
* @returns The example text.
*/
function createExample() {
// eslint-disable-next-line max-len
return chalk_1.default.magenta("\nExample: gh-tangle-release --github-token a4d936470cb3d66f5434f787c2500bde9764f --owner my-org --repository my-repo --release-tag v1.0.1 --seed AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n\n");
}
/**
* Show additional info about env vars.
* @returns The additional information.
*/
function createEnvHelp() {
return `
${chalk_1.default.cyan("You can also supply some of the options through environment variables:")}
${chalk_1.default.cyan("--github-token: GITHUB_TOKEN")}
${chalk_1.default.cyan("--owner: GITHUB_REPOSITORY[0]")}
${chalk_1.default.cyan("--repository: GITHUB_REPOSITORY[1]")}
${chalk_1.default.cyan(" where GITHUB_REPOSITORY is formatted owner/repository")}
${chalk_1.default.cyan("--release-tag: GITHUB_REF")}
${chalk_1.default.cyan("--seed: GTR_SEED")}\n\n`;
}
/**
* Show the errors.
* @param error The error that was thrown.
* @returns The formatted errors.
*/
function createErrors(error) {
return chalk_1.default.red(`The following errors occurred:\n ${error.message.replace(/\n/g, "\n ")}`);
}
Loading

0 comments on commit e5bd0bc

Please sign in to comment.