Skip to content

Commit 33ca914

Browse files
committed
Merge branch 'master' into v1
2 parents 4db98f1 + ae882ab commit 33ca914

File tree

6 files changed

+72
-18
lines changed

6 files changed

+72
-18
lines changed

.github/workflows/main.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,8 @@ jobs:
1818
- run: npm install
1919
- uses: ./
2020
- run: crystal eval "puts 1337"
21+
- uses: ./
22+
with:
23+
crystal: nightly
2124
- run: npm test
2225
- run: npm audit --audit-level=moderate

.github/workflows/release.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,6 @@ jobs:
1717
steps:
1818
- uses: oprypin/install-crystal@v1
1919
- run: crystal eval "puts 1337"
20+
- uses: oprypin/install-crystal@v1
21+
with:
22+
crystal: nightly

.util/release.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@ git add -f node_modules package.json package-lock.json
1515
git diff --quiet
1616
git commit -m "v$1"
1717
git tag "v$1"
18-
echo git push --follow-tags
18+
echo git push origin master v1 --tags

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ steps:
2525

2626
Install the latest released version of Crystal.
2727

28-
* **`crystal: nightly`** (default on Windows; not supported on other systems)
28+
* **`crystal: nightly`** (default on Windows)
2929

3030
Install Crystal from the latest continuous build on [crystal.git][] master.
3131

index.js

Lines changed: 62 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
const Core = require("@actions/core");
22
const ToolCache = require("@actions/tool-cache");
33
const Octokit = require("@octokit/request");
4+
const fetch = require("node-fetch");
45
const Path = require("path");
56
const ChildProcess = require("child_process");
67
const Util = require("util");
78
const FS = require("fs").promises;
89

10+
const exec = Util.promisify(ChildProcess.exec);
11+
const execFile = Util.promisify(ChildProcess.execFile);
12+
913
async function run() {
1014
try {
1115
const params = {};
@@ -24,6 +28,10 @@ async function run() {
2428
throw `Platform "${getPlatform()}" is not supported`;
2529
}
2630
await func(params);
31+
32+
Core.info("[command]crystal --version");
33+
const {stdout} = await execFile("crystal", ["--version"]);
34+
Core.info(stdout);
2735
} catch (error) {
2836
Core.setFailed(error);
2937
process.exit(1);
@@ -69,7 +77,7 @@ async function installCrystalForLinux({
6977
arch = getArch(),
7078
destination = null,
7179
}) {
72-
checkVersion(crystal, [Latest, NumericVersion]);
80+
checkVersion(crystal, [Latest, Nightly, NumericVersion]);
7381
const suffixes = {"x86_64": "linux-x86_64", "x86": "linux-i686"};
7482
checkArch(arch, Object.keys(suffixes));
7583

@@ -86,13 +94,12 @@ async function installCrystalForMac({
8694
arch = "x86_64",
8795
destination = null,
8896
}) {
89-
checkVersion(crystal, [Latest, NumericVersion]);
97+
checkVersion(crystal, [Latest, Nightly, NumericVersion]);
9098
checkArch(arch, ["x86_64"]);
9199
return installBinaryRelease({crystal, suffix: "darwin-x86_64", destination});
92100
}
93101

94102
async function installAptPackages(packages) {
95-
const execFile = Util.promisify(ChildProcess.execFile);
96103
Core.info("Installing package dependencies");
97104
const args = [
98105
"-n", "apt-get", "install", "-qy", "--no-install-recommends", "--no-upgrade", "--",
@@ -105,20 +112,28 @@ async function installAptPackages(packages) {
105112
}
106113

107114
async function installBinaryRelease({crystal, suffix, destination}) {
108-
if (crystal === Latest) {
109-
crystal = null;
115+
let path;
116+
if (crystal === Nightly) {
117+
path = await downloadCrystalNightly(suffix, destination);
118+
} else {
119+
if (crystal === Latest) {
120+
crystal = null;
121+
}
122+
path = await downloadCrystalRelease(suffix, crystal, destination);
110123
}
111-
const path = await downloadCrystalRelease({suffix, tag: crystal, destination});
112124

113125
Core.info("Setting up environment");
114126
Core.addPath(Path.join(path, "bin"));
115127
}
116128

117-
async function downloadCrystalRelease({suffix, tag = null, destination = null}) {
129+
const GitHubApiBase = "/repos/crystal-lang/crystal";
130+
const CircleApiBase = "https://circleci.com/api/v1.1/project/github/crystal-lang/crystal";
131+
132+
async function downloadCrystalRelease(suffix, tag = null, destination = null) {
118133
Core.info("Looking for latest Crystal release");
119134

120135
const releasesResp = await githubGet({
121-
url: "/repos/crystal-lang/crystal/releases/" + (tag ? "tags/" + tag : "latest"),
136+
url: GitHubApiBase + "/releases/" + (tag ? "tags/" + tag : "latest"),
122137
});
123138
const release = releasesResp.data;
124139
Core.info("Found " + release["html_url"]);
@@ -133,14 +148,47 @@ async function downloadCrystalRelease({suffix, tag = null, destination = null})
133148
return onlySubdir(await ToolCache.extractTar(downloadedPath, destination));
134149
}
135150

151+
async function downloadCrystalNightly(suffix, destination = null) {
152+
Core.info("Looking for latest Crystal build");
153+
154+
let build;
155+
for (let offset = 0; ;) {
156+
const req = `/tree/master?filter=successful&shallow=true&limit=100&offset=${offset}`;
157+
const resp = await fetch(CircleApiBase + req);
158+
const builds = await resp.json();
159+
build = builds.find((b) => b["workflows"]["job_name"] === "dist_artifacts");
160+
if (build) {
161+
break;
162+
}
163+
offset += builds.length;
164+
if (offset >= 1000) {
165+
throw "Could not find a matching nightly build";
166+
}
167+
}
168+
Core.info("Found " + build["build_url"]);
169+
Core.setOutput("crystal", build["vcs_revision"]);
170+
171+
const req = `/${build["build_num"]}/artifacts`;
172+
const resp = await fetch(CircleApiBase + req);
173+
const artifacts = await resp.json();
174+
const artifact = artifacts.find((a) => a["path"].endsWith(`-${suffix}.tar.gz`));
175+
Core.info("Found " + artifact["url"]);
176+
177+
Core.info("Downloading Crystal build");
178+
const downloadedPath = await ToolCache.downloadTool(artifact["url"]);
179+
180+
Core.info("Extracting Crystal build");
181+
return onlySubdir(await ToolCache.extractTar(downloadedPath, destination));
182+
}
183+
136184
async function installCrystalForWindows({
137185
crystal = Nightly,
138186
arch = "x86_64",
139187
destination = null,
140188
}) {
141189
checkVersion(crystal, [Nightly]);
142190
checkArch(arch, ["x86_64"]);
143-
const path = await downloadCrystalForWindows(destination);
191+
const path = await downloadCrystalNightlyForWindows(destination);
144192
await setupCrystalForWindows(path);
145193
}
146194

@@ -169,7 +217,6 @@ const outputSep = "---";
169217
const vcvarsPath = String.raw`C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat`;
170218

171219
async function variablesForVCBuildTools() {
172-
const exec = Util.promisify(ChildProcess.exec);
173220
const command = `set && echo ${outputSep} && "${vcvarsPath}" >nul && set`;
174221
Core.info(`[command]cmd /c "${command}"`);
175222
const {stdout} = await exec(command, {shell: "cmd"});
@@ -197,11 +244,11 @@ function* getChangedVars(lines) {
197244
}
198245
}
199246

200-
async function downloadCrystalForWindows(destination = null) {
247+
async function downloadCrystalNightlyForWindows(destination = null) {
201248
Core.info("Looking for latest Crystal build");
202249

203250
const runsResp = await githubGet({
204-
url: "/repos/crystal-lang/crystal/actions/workflows/win.yml/runs?branch=master&event=push&status=success",
251+
url: GitHubApiBase + "/actions/workflows/win.yml/runs?branch=master&event=push&status=success",
205252
"per_page": 1,
206253
});
207254
const [workflowRun] = runsResp.data["workflow_runs"];
@@ -211,7 +258,7 @@ async function downloadCrystalForWindows(destination = null) {
211258

212259
const fetchSrcTask = async (destDir) => {
213260
const zipballLinkResp = await githubGet({
214-
url: "/repos/crystal-lang/crystal/zipball/:ref",
261+
url: GitHubApiBase + "/zipball/:ref",
215262
"ref": ref,
216263
request: {redirect: "manual"},
217264
});
@@ -227,13 +274,13 @@ async function downloadCrystalForWindows(destination = null) {
227274

228275
const fetchExeTask = async () => {
229276
const artifactsResp = await githubGet({
230-
url: "/repos/crystal-lang/crystal/actions/runs/:run_id/artifacts",
277+
url: GitHubApiBase + "/actions/runs/:run_id/artifacts",
231278
"run_id": runId,
232279
});
233280
const artifact = artifactsResp.data["artifacts"].find((x) => x.name === "crystal");
234281

235282
const artifactLinkResp = await githubGet({
236-
url: "/repos/crystal-lang/crystal/actions/artifacts/:artifact_id/zip",
283+
url: GitHubApiBase + "/actions/artifacts/:artifact_id/zip",
237284
"artifact_id": artifact.id,
238285
request: {redirect: "manual"},
239286
});

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
"dependencies": {
2828
"@actions/core": "^1.2",
2929
"@actions/tool-cache": "^1.3",
30-
"@octokit/request": "^5.4"
30+
"@octokit/request": "^5.4",
31+
"node-fetch": "^2.6.0"
3132
},
3233
"devDependencies": {
3334
"eslint": "^6.8.0",

0 commit comments

Comments
 (0)