Skip to content

Commit 479197c

Browse files
author
Radu M
committed
Release v0.0.8
Signed-off-by: Radu M <root@radu.sh>
1 parent 94e10ec commit 479197c

557 files changed

Lines changed: 101684 additions & 3 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ bower_components
4141
build/Release
4242

4343
# Dependency directories
44-
node_modules/
44+
# node_modules/
4545
jspm_packages/
4646

4747
# TypeScript v1 declaration files
@@ -90,5 +90,5 @@ typings/
9090
# DynamoDB Local files
9191
.dynamodb/
9292

93-
lib/
94-
test/tmp
93+
# lib/
94+
test/tmp

lib/configurator.js

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
"use strict";
2+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3+
if (k2 === undefined) k2 = k;
4+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5+
}) : (function(o, m, k, k2) {
6+
if (k2 === undefined) k2 = k;
7+
o[k2] = m[k];
8+
}));
9+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10+
Object.defineProperty(o, "default", { enumerable: true, value: v });
11+
}) : function(o, v) {
12+
o["default"] = v;
13+
});
14+
var __importStar = (this && this.__importStar) || function (mod) {
15+
if (mod && mod.__esModule) return mod;
16+
var result = {};
17+
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18+
__setModuleDefault(result, mod);
19+
return result;
20+
};
21+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
22+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
23+
return new (P || (P = Promise))(function (resolve, reject) {
24+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
25+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
26+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
27+
step((generator = generator.apply(thisArg, _arguments || [])).next());
28+
});
29+
};
30+
var __importDefault = (this && this.__importDefault) || function (mod) {
31+
return (mod && mod.__esModule) ? mod : { "default": mod };
32+
};
33+
Object.defineProperty(exports, "__esModule", { value: true });
34+
exports.ArchiveType = exports.binPath = exports.getArchiveType = exports.Configurator = exports.getConfig = void 0;
35+
const core = __importStar(require("@actions/core"));
36+
const tc = __importStar(require("@actions/tool-cache"));
37+
const exec = __importStar(require("@actions/exec"));
38+
const io = __importStar(require("@actions/io"));
39+
const path = __importStar(require("path"));
40+
const os = __importStar(require("os"));
41+
const release_1 = require("./release");
42+
const mustache_1 = __importDefault(require("mustache"));
43+
const uuid_1 = require("uuid");
44+
const NameInput = "name";
45+
const URLInput = "url";
46+
const PathInArchiveInput = "pathInArchive";
47+
const FromGitHubReleases = "fromGitHubReleases";
48+
const Token = "token";
49+
const Repo = "repo";
50+
const Version = "version";
51+
const IncludePrereleases = "includePrereleases";
52+
const URLTemplate = "urlTemplate";
53+
function getConfig() {
54+
return new Configurator(core.getInput(NameInput), core.getInput(URLInput), core.getInput(PathInArchiveInput), core.getInput(FromGitHubReleases), core.getInput(Token), core.getInput(Repo), core.getInput(Version), core.getInput(IncludePrereleases), core.getInput(URLTemplate));
55+
}
56+
exports.getConfig = getConfig;
57+
class Configurator {
58+
constructor(name, url, pathInArchive, fromGitHubRelease, token, repo, version, includePrereleases, urlTemplate) {
59+
this.name = name;
60+
this.url = url;
61+
this.pathInArchive = pathInArchive;
62+
this.fromGitHubReleases = fromGitHubRelease == "true";
63+
this.token = token;
64+
this.repo = repo;
65+
this.version = version;
66+
this.includePrereleases = includePrereleases == "true";
67+
this.urlTemplate = urlTemplate;
68+
}
69+
configure() {
70+
return __awaiter(this, void 0, void 0, function* () {
71+
this.validate();
72+
let downloadURL;
73+
if (this.fromGitHubReleases) {
74+
let tag = yield release_1.getTag(this.token, this.repo, this.version, this.includePrereleases);
75+
const rawVersion = tag.startsWith("v") ? tag.substr(1) : tag;
76+
downloadURL = mustache_1.default.render(this.urlTemplate, {
77+
version: tag,
78+
rawVersion: rawVersion,
79+
});
80+
}
81+
else {
82+
downloadURL = this.url;
83+
}
84+
console.log(`Downloading tool from ${downloadURL}`);
85+
let downloadPath = null;
86+
let archivePath = null;
87+
let randomDir = uuid_1.v4();
88+
const tempDir = path.join(os.tmpdir(), "tmp", "runner", randomDir);
89+
console.log(`Creating tempdir ${tempDir}`);
90+
yield io.mkdirP(tempDir);
91+
downloadPath = yield tc.downloadTool(downloadURL);
92+
switch (getArchiveType(downloadURL)) {
93+
case ArchiveType.None:
94+
yield this.moveToPath(downloadPath);
95+
break;
96+
case ArchiveType.TarGz:
97+
archivePath = yield tc.extractTar(downloadPath, tempDir);
98+
yield this.moveToPath(path.join(archivePath, this.pathInArchive));
99+
break;
100+
case ArchiveType.TarXz:
101+
archivePath = yield tc.extractTar(downloadPath, tempDir, "x");
102+
yield this.moveToPath(path.join(archivePath, this.pathInArchive));
103+
break;
104+
case ArchiveType.Tgz:
105+
archivePath = yield tc.extractTar(downloadPath, tempDir);
106+
yield this.moveToPath(path.join(archivePath, this.pathInArchive));
107+
break;
108+
case ArchiveType.Zip:
109+
archivePath = yield tc.extractZip(downloadPath, tempDir);
110+
yield this.moveToPath(path.join(archivePath, this.pathInArchive));
111+
break;
112+
case ArchiveType.SevenZ:
113+
archivePath = yield tc.extract7z(downloadPath, tempDir);
114+
yield this.moveToPath(path.join(archivePath, this.pathInArchive));
115+
break;
116+
}
117+
// Clean up the tempdir when done (this step is important for self-hosted runners)
118+
return io.rmRF(tempDir);
119+
});
120+
}
121+
moveToPath(downloadPath) {
122+
return __awaiter(this, void 0, void 0, function* () {
123+
let toolPath = binPath();
124+
yield io.mkdirP(toolPath);
125+
yield io.mv(downloadPath, path.join(toolPath, this.name));
126+
if (process.platform !== "win32") {
127+
yield exec.exec("chmod", ["+x", path.join(toolPath, this.name)]);
128+
}
129+
core.addPath(toolPath);
130+
});
131+
}
132+
validate() {
133+
if (!this.name) {
134+
throw new Error(`"name" is required. This is used to set the executable name of the tool.`);
135+
}
136+
if (!this.fromGitHubReleases && !this.url) {
137+
throw new Error(`"url" is required when downloading a tool directly.`);
138+
}
139+
if (!this.fromGitHubReleases && !matchesUrlRegex(this.url)) {
140+
throw new Error(`"url" supplied as input is not a valid URL.`);
141+
}
142+
if (this.fromGitHubReleases && !matchesUrlRegex(this.urlTemplate)) {
143+
throw new Error(`"urlTemplate" supplied as input is not a valid URL.`);
144+
}
145+
if (getArchiveType(this.url) !== ArchiveType.None && !this.pathInArchive) {
146+
throw new Error(`"pathInArchive" is required when "url" points to an archive file`);
147+
}
148+
if (this.fromGitHubReleases &&
149+
getArchiveType(this.urlTemplate) !== ArchiveType.None &&
150+
!this.pathInArchive) {
151+
throw new Error(`"pathInArchive" is required when "urlTemplate" points to an archive file.`);
152+
}
153+
if (this.fromGitHubReleases &&
154+
(!this.token || !this.repo || !this.version || !this.urlTemplate)) {
155+
throw new Error(`if trying to fetch version from GitHub releases, "token", "repo", "version", and "urlTemplate" are required.`);
156+
}
157+
}
158+
}
159+
exports.Configurator = Configurator;
160+
function getArchiveType(downloadURL) {
161+
if (downloadURL.endsWith(ArchiveType.TarGz))
162+
return ArchiveType.TarGz;
163+
if (downloadURL.endsWith(ArchiveType.TarXz))
164+
return ArchiveType.TarXz;
165+
if (downloadURL.endsWith(ArchiveType.Tgz))
166+
return ArchiveType.Tgz;
167+
if (downloadURL.endsWith(ArchiveType.Zip))
168+
return ArchiveType.Zip;
169+
if (downloadURL.endsWith(ArchiveType.SevenZ))
170+
return ArchiveType.SevenZ;
171+
return ArchiveType.None;
172+
}
173+
exports.getArchiveType = getArchiveType;
174+
function binPath() {
175+
let baseLocation;
176+
if (process.platform === "win32") {
177+
// On windows use the USERPROFILE env variable
178+
baseLocation = process.env["USERPROFILE"] || "C:\\";
179+
}
180+
else {
181+
if (process.platform === "darwin") {
182+
baseLocation = "/Users";
183+
}
184+
else {
185+
baseLocation = "/home";
186+
}
187+
}
188+
return path.join(baseLocation, os.userInfo().username, "configurator", "bin");
189+
}
190+
exports.binPath = binPath;
191+
var ArchiveType;
192+
(function (ArchiveType) {
193+
ArchiveType["None"] = "";
194+
ArchiveType["TarGz"] = ".tar.gz";
195+
ArchiveType["TarXz"] = ".tar.xz";
196+
ArchiveType["Tgz"] = ".tgz";
197+
ArchiveType["Zip"] = ".zip";
198+
ArchiveType["SevenZ"] = ".7z";
199+
})(ArchiveType = exports.ArchiveType || (exports.ArchiveType = {}));
200+
function matchesUrlRegex(input) {
201+
var reg = new RegExp("^(http://www.|https://www.|http://|https://)?[a-z0-9]+([-.]{1}[a-z0-9]+)*.[a-z]{2,5}(:[0-9]{1,5})?(/.*)?$");
202+
return reg.test(input);
203+
}

lib/main.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
"use strict";
2+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3+
if (k2 === undefined) k2 = k;
4+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5+
}) : (function(o, m, k, k2) {
6+
if (k2 === undefined) k2 = k;
7+
o[k2] = m[k];
8+
}));
9+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10+
Object.defineProperty(o, "default", { enumerable: true, value: v });
11+
}) : function(o, v) {
12+
o["default"] = v;
13+
});
14+
var __importStar = (this && this.__importStar) || function (mod) {
15+
if (mod && mod.__esModule) return mod;
16+
var result = {};
17+
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18+
__setModuleDefault(result, mod);
19+
return result;
20+
};
21+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
22+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
23+
return new (P || (P = Promise))(function (resolve, reject) {
24+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
25+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
26+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
27+
step((generator = generator.apply(thisArg, _arguments || [])).next());
28+
});
29+
};
30+
Object.defineProperty(exports, "__esModule", { value: true });
31+
const core = __importStar(require("@actions/core"));
32+
const cfg = __importStar(require("./configurator"));
33+
function run() {
34+
return __awaiter(this, void 0, void 0, function* () {
35+
try {
36+
yield cfg.getConfig().configure();
37+
}
38+
catch (error) {
39+
core.setFailed(error.message);
40+
}
41+
});
42+
}
43+
run();

lib/release.js

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
"use strict";
2+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3+
if (k2 === undefined) k2 = k;
4+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5+
}) : (function(o, m, k, k2) {
6+
if (k2 === undefined) k2 = k;
7+
o[k2] = m[k];
8+
}));
9+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10+
Object.defineProperty(o, "default", { enumerable: true, value: v });
11+
}) : function(o, v) {
12+
o["default"] = v;
13+
});
14+
var __importStar = (this && this.__importStar) || function (mod) {
15+
if (mod && mod.__esModule) return mod;
16+
var result = {};
17+
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18+
__setModuleDefault(result, mod);
19+
return result;
20+
};
21+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
22+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
23+
return new (P || (P = Promise))(function (resolve, reject) {
24+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
25+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
26+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
27+
step((generator = generator.apply(thisArg, _arguments || [])).next());
28+
});
29+
};
30+
Object.defineProperty(exports, "__esModule", { value: true });
31+
exports.getTag = void 0;
32+
const github = __importStar(require("@actions/github"));
33+
const semver = __importStar(require("semver"));
34+
function getTag(token, repo, version, includePrereleases) {
35+
return __awaiter(this, void 0, void 0, function* () {
36+
// the `version` input field can either be a valid semver version, or a
37+
// version range. If none of them are valid, throw an error.
38+
if (semver.valid(version) === null &&
39+
semver.validRange(version) === null &&
40+
version !== "latest") {
41+
throw new Error(`version input: ${version} is not a valid semver version or range.`);
42+
}
43+
let client = github.getOctokit(token);
44+
let owner = repo.split("/")[0];
45+
let repoName = repo.split("/")[1];
46+
// by default, the GitHub releases API returns the first 30 releases.
47+
// while we haven't found a suitable release, increment the page index
48+
// and iterate through the results.
49+
let result;
50+
let pageIndex = 1;
51+
while (result === undefined) {
52+
let releases = yield client.repos.listReleases({
53+
owner: owner,
54+
repo: repoName,
55+
page: pageIndex,
56+
});
57+
// if result is still undefined and there are no more releases it means there are actually
58+
// no releases that satisty the version constrained. If this happens, throw an error.
59+
if (releases.data.length === 0 && result === undefined) {
60+
throw new Error(`cannot find suitable release for version constraint ${version} for repo ${owner}/${repo}`);
61+
}
62+
result = searchSatisfyingRelease(releases.data, version, includePrereleases);
63+
pageIndex++;
64+
}
65+
console.log(`selected release version ${result.tag_name}, which can be viewed at ${result.url}`);
66+
return result.tag_name;
67+
});
68+
}
69+
exports.getTag = getTag;
70+
function searchSatisfyingRelease(releases, version, includePrereleases) {
71+
// normally the release array returned by the API should be ordered by the release date, so
72+
// we iterate through it until we find the latest version that satisfies the version constraint.
73+
// The initial assumption is that, given that users _should_ want to use recently released versions,
74+
// and the number of releases is not (normally) very large, the complexity of this loop should not
75+
// be an issue.
76+
// However, given that this is an ordered array, we could explore a binary search here.
77+
for (let i = 0; i < releases.length; i++) {
78+
if (version === "latest") {
79+
if ((includePrereleases && releases[i].prerelease) ||
80+
!releases[i].prerelease) {
81+
return releases[i];
82+
}
83+
}
84+
if (includePrereleases === false && releases[i].prerelease === true) {
85+
continue;
86+
}
87+
if (semver.satisfies(releases[i].tag_name, version, {
88+
includePrerelease: includePrereleases,
89+
})) {
90+
return releases[i];
91+
}
92+
}
93+
return undefined;
94+
}

node_modules/.bin/mustache

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/semver

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/uuid

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/@actions/core/LICENSE.md

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)