Skip to content

Commit 611064b

Browse files
Support latest-nightly
1 parent 14547ab commit 611064b

File tree

9 files changed

+134
-33
lines changed

9 files changed

+134
-33
lines changed

Diff for: README.md

+1
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ E.g., `8.10` will be resolved to `8.10.7`, and so will `8`.
236236

237237
**GHC:**
238238

239+
- `latest-nightly`
239240
- `latest` (default)
240241
- `9.6.2` `9.6`
241242
- `9.6.1`

Diff for: action.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ author: 'GitHub'
44
inputs:
55
ghc-version:
66
required: false
7-
description: 'Version of GHC to use. If set to "latest", it will always get the latest stable version.'
7+
description: 'Version of GHC to use. If set to "latest", it will always get the latest stable version. If set to "latest-nightly", it will always get the latest nightly version of GHC'
88
default: 'latest'
99
cabal-version:
1010
required: false

Diff for: dist/index.js

+40-9
Original file line numberDiff line numberDiff line change
@@ -13276,6 +13276,7 @@ const core = __importStar(__nccwpck_require__(2186));
1327613276
const exec_1 = __nccwpck_require__(1514);
1327713277
const io_1 = __nccwpck_require__(7436);
1327813278
const tc = __importStar(__nccwpck_require__(7784));
13279+
const child_process = __importStar(__nccwpck_require__(2081));
1327913280
const fs_1 = __nccwpck_require__(7147);
1328013281
const path_1 = __nccwpck_require__(1017);
1328113282
const opts_1 = __nccwpck_require__(8131);
@@ -13298,7 +13299,25 @@ async function configureOutputs(tool, version, path, os) {
1329813299
if (os === 'win32')
1329913300
core.exportVariable('STACK_ROOT', sr);
1330013301
}
13301-
core.setOutput(`${tool}-version`, version);
13302+
// can't put this in resolve() because it might run before ghcup is installed
13303+
let resolvedVersion = version;
13304+
if (version === 'latest-nightly') {
13305+
try {
13306+
const ghcupExe = await ghcupBin(os);
13307+
const out = await new Promise((resolve, reject) => child_process.execFile(ghcupExe, ['list', '-nr'], { encoding: 'utf-8' }, (error, stdout) => (error ? reject(error) : resolve(stdout))));
13308+
resolvedVersion =
13309+
out
13310+
.split('\n')
13311+
.map(line => line.split(' '))
13312+
.filter(line => line[2] === 'latest-nightly')
13313+
.map(line => line[1])
13314+
.at(0) ?? version;
13315+
}
13316+
catch (error) {
13317+
// swallow failures, just leave version as 'latest-nightly'
13318+
}
13319+
}
13320+
core.setOutput(`${tool}-version`, resolvedVersion);
1330213321
}
1330313322
async function success(tool, version, path, os) {
1330413323
core.addPath(path);
@@ -13400,12 +13419,14 @@ async function installTool(tool, version, os) {
1340013419
}
1340113420
switch (os) {
1340213421
case 'linux':
13403-
if (tool === 'ghc' && (0, compare_versions_1.compareVersions)('8.3', version)) {
13404-
// Andreas, 2022-12-09: The following errors out if we are not ubuntu-20.04.
13405-
// Atm, I do not know how to check whether we are on ubuntu-20.04.
13406-
// So, ignore the error.
13407-
// if (!(await aptLibCurses5())) break;
13408-
await aptLibNCurses5();
13422+
if (tool === 'ghc') {
13423+
if (version !== 'latest-nightly' && (0, compare_versions_1.compareVersions)('8.3', version)) {
13424+
// Andreas, 2022-12-09: The following errors out if we are not ubuntu-20.04.
13425+
// Atm, I do not know how to check whether we are on ubuntu-20.04.
13426+
// So, ignore the error.
13427+
// if (!(await aptLibCurses5())) break;
13428+
await aptLibNCurses5();
13429+
}
1340913430
}
1341013431
await ghcup(tool, version, os);
1341113432
if (await isInstalled(tool, version, os))
@@ -13862,8 +13883,18 @@ async function run(inputs) {
1386213883
core.debug(`run: inputs = ${JSON.stringify(inputs)}`);
1386313884
core.debug(`run: os = ${JSON.stringify(os)}`);
1386413885
core.debug(`run: opts = ${JSON.stringify(opts)}`);
13865-
if (opts.ghcup.releaseChannel) {
13866-
await core.group(`Preparing ghcup environment`, async () => (0, installer_1.addGhcupReleaseChannel)(opts.ghcup.releaseChannel, os));
13886+
const releaseChannels = [
13887+
opts.ghcup.releaseChannel,
13888+
opts.ghc.raw === 'latest-nightly'
13889+
? new URL('https://ghc.gitlab.haskell.org/ghcup-metadata/ghcup-nightlies-0.0.7.yaml')
13890+
: null
13891+
].filter((v) => v !== null);
13892+
if (releaseChannels.length > 0) {
13893+
await core.group(`Setting release channels`, async () => {
13894+
for (const channel of releaseChannels) {
13895+
await (0, installer_1.addGhcupReleaseChannel)(channel, os);
13896+
}
13897+
});
1386713898
}
1386813899
for (const [t, { resolved }] of Object.entries(opts).filter(o => o[1].enable)) {
1386913900
await core.group(`Preparing ${t} environment`, async () => (0, installer_1.resetTool)(t, resolved, os));

Diff for: lib/installer.js

+28-7
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ const core = __importStar(require("@actions/core"));
3131
const exec_1 = require("@actions/exec");
3232
const io_1 = require("@actions/io");
3333
const tc = __importStar(require("@actions/tool-cache"));
34+
const child_process = __importStar(require("child_process"));
3435
const fs_1 = require("fs");
3536
const path_1 = require("path");
3637
const opts_1 = require("./opts");
@@ -53,7 +54,25 @@ async function configureOutputs(tool, version, path, os) {
5354
if (os === 'win32')
5455
core.exportVariable('STACK_ROOT', sr);
5556
}
56-
core.setOutput(`${tool}-version`, version);
57+
// can't put this in resolve() because it might run before ghcup is installed
58+
let resolvedVersion = version;
59+
if (version === 'latest-nightly') {
60+
try {
61+
const ghcupExe = await ghcupBin(os);
62+
const out = await new Promise((resolve, reject) => child_process.execFile(ghcupExe, ['list', '-nr'], { encoding: 'utf-8' }, (error, stdout) => (error ? reject(error) : resolve(stdout))));
63+
resolvedVersion =
64+
out
65+
.split('\n')
66+
.map(line => line.split(' '))
67+
.filter(line => line[2] === 'latest-nightly')
68+
.map(line => line[1])
69+
.at(0) ?? version;
70+
}
71+
catch (error) {
72+
// swallow failures, just leave version as 'latest-nightly'
73+
}
74+
}
75+
core.setOutput(`${tool}-version`, resolvedVersion);
5776
}
5877
async function success(tool, version, path, os) {
5978
core.addPath(path);
@@ -155,12 +174,14 @@ async function installTool(tool, version, os) {
155174
}
156175
switch (os) {
157176
case 'linux':
158-
if (tool === 'ghc' && (0, compare_versions_1.compareVersions)('8.3', version)) {
159-
// Andreas, 2022-12-09: The following errors out if we are not ubuntu-20.04.
160-
// Atm, I do not know how to check whether we are on ubuntu-20.04.
161-
// So, ignore the error.
162-
// if (!(await aptLibCurses5())) break;
163-
await aptLibNCurses5();
177+
if (tool === 'ghc') {
178+
if (version !== 'latest-nightly' && (0, compare_versions_1.compareVersions)('8.3', version)) {
179+
// Andreas, 2022-12-09: The following errors out if we are not ubuntu-20.04.
180+
// Atm, I do not know how to check whether we are on ubuntu-20.04.
181+
// So, ignore the error.
182+
// if (!(await aptLibCurses5())) break;
183+
await aptLibNCurses5();
184+
}
164185
}
165186
await ghcup(tool, version, os);
166187
if (await isInstalled(tool, version, os))

Diff for: lib/opts.d.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export interface ProgramOpt {
1616
export interface Options {
1717
ghc: ProgramOpt;
1818
ghcup: {
19-
releaseChannel?: URL;
19+
releaseChannel: URL | null;
2020
};
2121
cabal: ProgramOpt & {
2222
update: boolean;
@@ -85,6 +85,6 @@ export declare function releaseRevision(version: string, tool: Tool, os: OS): st
8585
* @returns boolean
8686
*/
8787
export declare function parseYAMLBoolean(name: string, val: string): boolean;
88-
export declare function parseURL(name: string, val: string): URL | undefined;
88+
export declare function parseURL(name: string, val: string): URL | null;
8989
export declare function getOpts({ ghc, cabal, stack }: Defaults, os: OS, inputs: Record<string, string>): Options;
9090
export {};

Diff for: lib/opts.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ function parseYAMLBoolean(name, val) {
125125
exports.parseYAMLBoolean = parseYAMLBoolean;
126126
function parseURL(name, val) {
127127
if (val === '')
128-
return undefined;
128+
return null;
129129
try {
130130
return new URL(val);
131131
}

Diff for: lib/setup-haskell.js

+12-2
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,18 @@ async function run(inputs) {
5252
core.debug(`run: inputs = ${JSON.stringify(inputs)}`);
5353
core.debug(`run: os = ${JSON.stringify(os)}`);
5454
core.debug(`run: opts = ${JSON.stringify(opts)}`);
55-
if (opts.ghcup.releaseChannel) {
56-
await core.group(`Preparing ghcup environment`, async () => (0, installer_1.addGhcupReleaseChannel)(opts.ghcup.releaseChannel, os));
55+
const releaseChannels = [
56+
opts.ghcup.releaseChannel,
57+
opts.ghc.raw === 'latest-nightly'
58+
? new URL('https://ghc.gitlab.haskell.org/ghcup-metadata/ghcup-nightlies-0.0.7.yaml')
59+
: null
60+
].filter((v) => v !== null);
61+
if (releaseChannels.length > 0) {
62+
await core.group(`Setting release channels`, async () => {
63+
for (const channel of releaseChannels) {
64+
await (0, installer_1.addGhcupReleaseChannel)(channel, os);
65+
}
66+
});
5767
}
5868
for (const [t, { resolved }] of Object.entries(opts).filter(o => o[1].enable)) {
5969
await core.group(`Preparing ${t} environment`, async () => (0, installer_1.resetTool)(t, resolved, os));

Diff for: src/installer.ts

+35-7
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as core from '@actions/core';
22
import {exec as e} from '@actions/exec';
33
import {which} from '@actions/io';
44
import * as tc from '@actions/tool-cache';
5+
import * as child_process from 'child_process';
56
import {promises as afs} from 'fs';
67
import {join, dirname} from 'path';
78
import {ghcup_version, OS, Tool, releaseRevision} from './opts';
@@ -33,7 +34,32 @@ async function configureOutputs(
3334
core.setOutput('stack-root', sr);
3435
if (os === 'win32') core.exportVariable('STACK_ROOT', sr);
3536
}
36-
core.setOutput(`${tool}-version`, version);
37+
38+
// can't put this in resolve() because it might run before ghcup is installed
39+
let resolvedVersion = version;
40+
if (version === 'latest-nightly') {
41+
try {
42+
const ghcupExe = await ghcupBin(os);
43+
const out = await new Promise<string>((resolve, reject) =>
44+
child_process.execFile(
45+
ghcupExe,
46+
['list', '-nr'],
47+
{encoding: 'utf-8'},
48+
(error, stdout) => (error ? reject(error) : resolve(stdout))
49+
)
50+
);
51+
resolvedVersion =
52+
out
53+
.split('\n')
54+
.map(line => line.split(' '))
55+
.filter(line => line[2] === 'latest-nightly')
56+
.map(line => line[1])
57+
.at(0) ?? version;
58+
} catch (error) {
59+
// swallow failures, just leave version as 'latest-nightly'
60+
}
61+
}
62+
core.setOutput(`${tool}-version`, resolvedVersion);
3763
}
3864

3965
async function success(
@@ -165,12 +191,14 @@ export async function installTool(
165191

166192
switch (os) {
167193
case 'linux':
168-
if (tool === 'ghc' && compareVersions('8.3', version)) {
169-
// Andreas, 2022-12-09: The following errors out if we are not ubuntu-20.04.
170-
// Atm, I do not know how to check whether we are on ubuntu-20.04.
171-
// So, ignore the error.
172-
// if (!(await aptLibCurses5())) break;
173-
await aptLibNCurses5();
194+
if (tool === 'ghc') {
195+
if (version !== 'latest-nightly' && compareVersions('8.3', version)) {
196+
// Andreas, 2022-12-09: The following errors out if we are not ubuntu-20.04.
197+
// Atm, I do not know how to check whether we are on ubuntu-20.04.
198+
// So, ignore the error.
199+
// if (!(await aptLibCurses5())) break;
200+
await aptLibNCurses5();
201+
}
174202
}
175203
await ghcup(tool, version, os);
176204
if (await isInstalled(tool, version, os)) return;

Diff for: src/setup-haskell.ts

+14-4
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,20 @@ export default async function run(
3030
core.debug(`run: os = ${JSON.stringify(os)}`);
3131
core.debug(`run: opts = ${JSON.stringify(opts)}`);
3232

33-
if (opts.ghcup.releaseChannel) {
34-
await core.group(`Preparing ghcup environment`, async () =>
35-
addGhcupReleaseChannel(opts.ghcup.releaseChannel!, os)
36-
);
33+
const releaseChannels = [
34+
opts.ghcup.releaseChannel,
35+
opts.ghc.raw === 'latest-nightly'
36+
? new URL(
37+
'https://ghc.gitlab.haskell.org/ghcup-metadata/ghcup-nightlies-0.0.7.yaml'
38+
)
39+
: null
40+
].filter((v): v is URL => v !== null);
41+
if (releaseChannels.length > 0) {
42+
await core.group(`Setting release channels`, async () => {
43+
for (const channel of releaseChannels) {
44+
await addGhcupReleaseChannel(channel, os);
45+
}
46+
});
3747
}
3848

3949
for (const [t, {resolved}] of Object.entries(opts).filter(

0 commit comments

Comments
 (0)