diff --git a/setup/dist/index.js b/setup/dist/index.js index d5730606..094e1483 100644 --- a/setup/dist/index.js +++ b/setup/dist/index.js @@ -2409,16 +2409,18 @@ exports.create = create; * Computes the sha256 hash of a glob * * @param patterns Patterns separated by newlines + * @param currentWorkspace Workspace used when matching files * @param options Glob options + * @param verbose Enables verbose logging */ -function hashFiles(patterns, options, verbose = false) { +function hashFiles(patterns, currentWorkspace = '', options, verbose = false) { return __awaiter(this, void 0, void 0, function* () { let followSymbolicLinks = true; if (options && typeof options.followSymbolicLinks === 'boolean') { followSymbolicLinks = options.followSymbolicLinks; } const globber = yield create(patterns, { followSymbolicLinks }); - return internal_hash_files_1.hashFiles(globber, verbose); + return internal_hash_files_1.hashFiles(globber, currentWorkspace, verbose); }); } exports.hashFiles = hashFiles; @@ -2778,13 +2780,15 @@ const fs = __importStar(__nccwpck_require__(7147)); const stream = __importStar(__nccwpck_require__(2781)); const util = __importStar(__nccwpck_require__(3837)); const path = __importStar(__nccwpck_require__(1017)); -function hashFiles(globber, verbose = false) { +function hashFiles(globber, currentWorkspace, verbose = false) { var e_1, _a; var _b; return __awaiter(this, void 0, void 0, function* () { const writeDelegate = verbose ? core.info : core.debug; let hasMatch = false; - const githubWorkspace = (_b = process.env['GITHUB_WORKSPACE']) !== null && _b !== void 0 ? _b : process.cwd(); + const githubWorkspace = currentWorkspace + ? currentWorkspace + : (_b = process.env['GITHUB_WORKSPACE']) !== null && _b !== void 0 ? _b : process.cwd(); const result = crypto.createHash('sha256'); let count = 0; try { @@ -13313,7 +13317,6 @@ const path_1 = __nccwpck_require__(1017); const opts_1 = __nccwpck_require__(8131); const process_1 = __importDefault(__nccwpck_require__(7282)); const glob = __importStar(__nccwpck_require__(8090)); -const fs = __importStar(__nccwpck_require__(7147)); const compare_versions_1 = __nccwpck_require__(4773); // compareVersions can be used in the sense of > // Don't throw on non-zero. const exec = async (cmd, args) => (0, exec_1.exec)(cmd, args, { ignoreReturnCode: true }); @@ -13359,44 +13362,65 @@ async function isInstalled(tool, version, os) { const toolPath = tc.find(tool, version); if (toolPath) return success(tool, version, toolPath, os); - const ghcupPath = `${process_1.default.env.HOME}/.ghcup${tool === 'ghc' ? `/ghc/${version}` : ''}/bin`; + let ghcupPath = `${process_1.default.env.HOME}/.ghcup${tool === 'ghc' ? `/ghc/${version}` : ''}/bin`; + if (os === 'win32') { + ghcupPath = 'C:/ghcup/bin'; + } const v = aptVersion(tool, version); const aptPath = `/opt/${tool}/${v}/bin`; - const chocoPath = await getChocoPath(tool, version, (0, opts_1.releaseRevision)(version, tool, os)); const locations = { stack: [], cabal: { - win32: [chocoPath], - linux: [aptPath], - darwin: [] + win32: [ghcupPath], + linux: [ghcupPath, aptPath], + darwin: [ghcupPath] }[os], ghc: { - win32: [chocoPath], - linux: [aptPath, ghcupPath], + win32: [ghcupPath], + linux: [ghcupPath, aptPath], darwin: [ghcupPath] }[os] }; + core.info(`isInstalled ${tool} ${version} ${locations[tool]}`); + const f = await exec(await ghcupBin(os), ['whereis', tool, version]); + core.info(`isInstalled whereis ${f}`); for (const p of locations[tool]) { + core.info(`Attempting to access tool ${tool} at location ${p}`); const installedPath = await fs_1.promises .access(p) .then(() => p) .catch(() => undefined); + if (installedPath == undefined) { + core.info(`Failed to access tool ${tool} at location ${p}`); + } + else { + core.info(`Succeeded accessing tool ${tool} at location ${p}`); + } if (installedPath) { // Make sure that the correct ghc is used, even if ghcup has set a // default prior to this action being ran. - if (tool === 'ghc' && installedPath === ghcupPath) - await exec(await ghcupBin(os), ['set', tool, version]); - return success(tool, version, installedPath, os); - } - } - if (tool === 'cabal' && os !== 'win32') { - const installedPath = await fs_1.promises - .access(`${ghcupPath}/cabal-${version}`) - .then(() => ghcupPath) - .catch(() => undefined); - if (installedPath) { - await exec(await ghcupBin(os), ['set', tool, version]); - return success(tool, version, installedPath, os); + core.info(`isInstalled installedPath: ${installedPath}`); + if (installedPath === ghcupPath) { + // If the result of this `ghcup set` is non-zero, the version we want + // is probably not actually installed + const ghcupSetResult = await exec(await ghcupBin(os), [ + 'set', + tool, + version + ]); + if (ghcupSetResult == 0) + return success(tool, version, installedPath, os); + } + else { + const cabalPath = await fs_1.promises + .access(`${installedPath}/cabal-${version}`) + .then(() => p) + .catch(() => undefined); + core.info(`isInstalled cabalPath ${cabalPath}`); + if (cabalPath) { + return success(tool, version, installedPath, os); + } + } } } return false; @@ -13432,7 +13456,7 @@ async function installTool(tool, version, os) { await apt(tool, version); break; case 'win32': - await choco(tool, version); + await ghcup(tool, version, os); break; case 'darwin': await ghcup(tool, version, os); @@ -13499,31 +13523,11 @@ async function apt(tool, version) { // Ignore the return code so we can fall back to ghcup await exec(`sudo -- sh -c "add-apt-repository -y ppa:hvr/ghc && apt-get update && apt-get -y install ${toolName}-${v}"`); } -async function choco(tool, version) { - core.info(`Attempting to install ${tool} ${version} using chocolatey`); - // E.g. GHC version 7.10.3 on Chocolatey is revision 7.10.3.1. - const revision = (0, opts_1.releaseRevision)(version, tool, 'win32'); - // Choco tries to invoke `add-path` command on earlier versions of ghc, which has been deprecated and fails the step, so disable command execution during this. - console.log('::stop-commands::SetupHaskellStopCommands'); - const args = [ - 'choco', - 'install', - tool, - '--version', - revision, - '-m', - '--no-progress', - core.isDebug() ? '-d' : '-r' - ]; - if ((await exec('powershell', args)) !== 0) - await exec('powershell', [...args, '--pre']); - console.log('::SetupHaskellStopCommands::'); // Re-enable command execution - // Add GHC to path automatically because it does not add until the end of the step and we check the path. - const chocoPath = await getChocoPath(tool, version, revision); - if (tool == 'ghc') - core.addPath(chocoPath); -} async function ghcupBin(os) { + core.info(`ghcupBin : ${os}`); + if (os === 'win32') { + return 'ghcup'; + } const cachedBin = tc.find('ghcup', opts_1.ghcup_version); if (cachedBin) return (0, path_1.join)(cachedBin, 'ghcup'); @@ -13557,28 +13561,6 @@ async function ghcupGHCHead() { if (returnCode === 0) await exec(bin, ['set', 'ghc', 'head']); } -async function getChocoPath(tool, version, revision) { - // Environment variable 'ChocolateyToolsLocation' will be added to Hosted images soon - // fallback to C:\\tools for now until variable is available - core.debug(`getChocoPath(): ChocolateyToolsLocation = ${process_1.default.env.ChocolateyToolsLocation}`); - const chocoToolsLocation = process_1.default.env.ChocolateyToolsLocation ?? - (0, path_1.join)(`${process_1.default.env.SystemDrive}`, 'tools'); - // choco packages GHC 9.x are installed on different path (C:\\tools\ghc-9.0.1) - let chocoToolPath = (0, path_1.join)(chocoToolsLocation, `${tool}-${version}`); - // choco packages GHC < 9.x - if (!fs.existsSync(chocoToolPath)) { - chocoToolPath = (0, path_1.join)(`${process_1.default.env.ChocolateyInstall}`, 'lib', `${tool}.${revision}`); - } - core.debug(`getChocoPath(): chocoToolPath = ${chocoToolPath}`); - const pattern = `${chocoToolPath}/**/${tool}.exe`; - const globber = await glob.create(pattern); - for await (const file of globber.globGenerator()) { - core.debug(`getChocoPath(): found ${tool} at ${file}`); - return (0, path_1.dirname)(file); - } - core.debug(`getChocoPath(): cannot find binary for ${tool}`); - return ''; -} /***/ }), @@ -13662,6 +13644,34 @@ const rv = __importStar(__nccwpck_require__(8738)); exports.release_revisions = rv; exports.supported_versions = sv; exports.ghcup_version = sv.ghcup[0]; // Known to be an array of length 1 +/** + * Reads the example `actions.yml` file and selects the `inputs` key. The result + * will be a key-value map of the following shape: + * ``` + * { + * 'ghc-version': { + * required: false, + * description: '...', + * default: 'latest' + * }, + * 'cabal-version': { + * required: false, + * description: '...', + * default: 'latest' + * }, + * 'stack-version': { + * required: false, + * description: '...', + * default: 'latest' + * }, + * 'enable-stack': { + * required: false, + * default: 'latest' + * }, + * ... + * } + * ``` + */ exports.yamlInputs = (0, js_yaml_1.load)((0, fs_1.readFileSync)((0, path_1.join)(__dirname, '..', 'action.yml'), 'utf8') // The action.yml file structure is statically known. // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -13848,6 +13858,9 @@ async function run(inputs) { core.info('Preparing to setup a Haskell environment'); const os = process.platform; const opts = (0, opts_1.getOpts)((0, opts_1.getDefaults)(os), os, inputs); + core.debug(`run: inputs = ${JSON.stringify(inputs)}`); + core.debug(`run: os = ${JSON.stringify(os)}`); + core.debug(`run: opts = ${JSON.stringify(opts)}`); if (opts.ghcup.releaseChannel) { await core.group(`Preparing ghcup environment`, async () => (0, installer_1.addGhcupReleaseChannel)(opts.ghcup.releaseChannel, os)); } diff --git a/setup/lib/installer.js b/setup/lib/installer.js index 83b99aa5..43e9e67b 100644 --- a/setup/lib/installer.js +++ b/setup/lib/installer.js @@ -36,7 +36,6 @@ const path_1 = require("path"); const opts_1 = require("./opts"); const process_1 = __importDefault(require("process")); const glob = __importStar(require("@actions/glob")); -const fs = __importStar(require("fs")); const compare_versions_1 = require("compare-versions"); // compareVersions can be used in the sense of > // Don't throw on non-zero. const exec = async (cmd, args) => (0, exec_1.exec)(cmd, args, { ignoreReturnCode: true }); @@ -82,44 +81,65 @@ async function isInstalled(tool, version, os) { const toolPath = tc.find(tool, version); if (toolPath) return success(tool, version, toolPath, os); - const ghcupPath = `${process_1.default.env.HOME}/.ghcup${tool === 'ghc' ? `/ghc/${version}` : ''}/bin`; + let ghcupPath = `${process_1.default.env.HOME}/.ghcup${tool === 'ghc' ? `/ghc/${version}` : ''}/bin`; + if (os === 'win32') { + ghcupPath = 'C:/ghcup/bin'; + } const v = aptVersion(tool, version); const aptPath = `/opt/${tool}/${v}/bin`; - const chocoPath = await getChocoPath(tool, version, (0, opts_1.releaseRevision)(version, tool, os)); const locations = { stack: [], cabal: { - win32: [chocoPath], - linux: [aptPath], - darwin: [] + win32: [ghcupPath], + linux: [ghcupPath, aptPath], + darwin: [ghcupPath] }[os], ghc: { - win32: [chocoPath], - linux: [aptPath, ghcupPath], + win32: [ghcupPath], + linux: [ghcupPath, aptPath], darwin: [ghcupPath] }[os] }; + core.info(`isInstalled ${tool} ${version} ${locations[tool]}`); + const f = await exec(await ghcupBin(os), ['whereis', tool, version]); + core.info(`isInstalled whereis ${f}`); for (const p of locations[tool]) { + core.info(`Attempting to access tool ${tool} at location ${p}`); const installedPath = await fs_1.promises .access(p) .then(() => p) .catch(() => undefined); + if (installedPath == undefined) { + core.info(`Failed to access tool ${tool} at location ${p}`); + } + else { + core.info(`Succeeded accessing tool ${tool} at location ${p}`); + } if (installedPath) { // Make sure that the correct ghc is used, even if ghcup has set a // default prior to this action being ran. - if (tool === 'ghc' && installedPath === ghcupPath) - await exec(await ghcupBin(os), ['set', tool, version]); - return success(tool, version, installedPath, os); - } - } - if (tool === 'cabal' && os !== 'win32') { - const installedPath = await fs_1.promises - .access(`${ghcupPath}/cabal-${version}`) - .then(() => ghcupPath) - .catch(() => undefined); - if (installedPath) { - await exec(await ghcupBin(os), ['set', tool, version]); - return success(tool, version, installedPath, os); + core.info(`isInstalled installedPath: ${installedPath}`); + if (installedPath === ghcupPath) { + // If the result of this `ghcup set` is non-zero, the version we want + // is probably not actually installed + const ghcupSetResult = await exec(await ghcupBin(os), [ + 'set', + tool, + version + ]); + if (ghcupSetResult == 0) + return success(tool, version, installedPath, os); + } + else { + const cabalPath = await fs_1.promises + .access(`${installedPath}/cabal-${version}`) + .then(() => p) + .catch(() => undefined); + core.info(`isInstalled cabalPath ${cabalPath}`); + if (cabalPath) { + return success(tool, version, installedPath, os); + } + } } } return false; @@ -155,7 +175,7 @@ async function installTool(tool, version, os) { await apt(tool, version); break; case 'win32': - await choco(tool, version); + await ghcup(tool, version, os); break; case 'darwin': await ghcup(tool, version, os); @@ -222,31 +242,11 @@ async function apt(tool, version) { // Ignore the return code so we can fall back to ghcup await exec(`sudo -- sh -c "add-apt-repository -y ppa:hvr/ghc && apt-get update && apt-get -y install ${toolName}-${v}"`); } -async function choco(tool, version) { - core.info(`Attempting to install ${tool} ${version} using chocolatey`); - // E.g. GHC version 7.10.3 on Chocolatey is revision 7.10.3.1. - const revision = (0, opts_1.releaseRevision)(version, tool, 'win32'); - // Choco tries to invoke `add-path` command on earlier versions of ghc, which has been deprecated and fails the step, so disable command execution during this. - console.log('::stop-commands::SetupHaskellStopCommands'); - const args = [ - 'choco', - 'install', - tool, - '--version', - revision, - '-m', - '--no-progress', - core.isDebug() ? '-d' : '-r' - ]; - if ((await exec('powershell', args)) !== 0) - await exec('powershell', [...args, '--pre']); - console.log('::SetupHaskellStopCommands::'); // Re-enable command execution - // Add GHC to path automatically because it does not add until the end of the step and we check the path. - const chocoPath = await getChocoPath(tool, version, revision); - if (tool == 'ghc') - core.addPath(chocoPath); -} async function ghcupBin(os) { + core.info(`ghcupBin : ${os}`); + if (os === 'win32') { + return 'ghcup'; + } const cachedBin = tc.find('ghcup', opts_1.ghcup_version); if (cachedBin) return (0, path_1.join)(cachedBin, 'ghcup'); @@ -280,25 +280,3 @@ async function ghcupGHCHead() { if (returnCode === 0) await exec(bin, ['set', 'ghc', 'head']); } -async function getChocoPath(tool, version, revision) { - // Environment variable 'ChocolateyToolsLocation' will be added to Hosted images soon - // fallback to C:\\tools for now until variable is available - core.debug(`getChocoPath(): ChocolateyToolsLocation = ${process_1.default.env.ChocolateyToolsLocation}`); - const chocoToolsLocation = process_1.default.env.ChocolateyToolsLocation ?? - (0, path_1.join)(`${process_1.default.env.SystemDrive}`, 'tools'); - // choco packages GHC 9.x are installed on different path (C:\\tools\ghc-9.0.1) - let chocoToolPath = (0, path_1.join)(chocoToolsLocation, `${tool}-${version}`); - // choco packages GHC < 9.x - if (!fs.existsSync(chocoToolPath)) { - chocoToolPath = (0, path_1.join)(`${process_1.default.env.ChocolateyInstall}`, 'lib', `${tool}.${revision}`); - } - core.debug(`getChocoPath(): chocoToolPath = ${chocoToolPath}`); - const pattern = `${chocoToolPath}/**/${tool}.exe`; - const globber = await glob.create(pattern); - for await (const file of globber.globGenerator()) { - core.debug(`getChocoPath(): found ${tool} at ${file}`); - return (0, path_1.dirname)(file); - } - core.debug(`getChocoPath(): cannot find binary for ${tool}`); - return ''; -} diff --git a/setup/lib/opts.d.ts b/setup/lib/opts.d.ts index 9fa53c54..5b5a3603 100644 --- a/setup/lib/opts.d.ts +++ b/setup/lib/opts.d.ts @@ -41,6 +41,34 @@ export type Defaults = Record & { }; }; }; +/** + * Reads the example `actions.yml` file and selects the `inputs` key. The result + * will be a key-value map of the following shape: + * ``` + * { + * 'ghc-version': { + * required: false, + * description: '...', + * default: 'latest' + * }, + * 'cabal-version': { + * required: false, + * description: '...', + * default: 'latest' + * }, + * 'stack-version': { + * required: false, + * description: '...', + * default: 'latest' + * }, + * 'enable-stack': { + * required: false, + * default: 'latest' + * }, + * ... + * } + * ``` + */ export declare const yamlInputs: Record; diff --git a/setup/lib/opts.js b/setup/lib/opts.js index 5a388737..4ec91ee4 100644 --- a/setup/lib/opts.js +++ b/setup/lib/opts.js @@ -33,6 +33,34 @@ const rv = __importStar(require("./release-revisions.json")); exports.release_revisions = rv; exports.supported_versions = sv; exports.ghcup_version = sv.ghcup[0]; // Known to be an array of length 1 +/** + * Reads the example `actions.yml` file and selects the `inputs` key. The result + * will be a key-value map of the following shape: + * ``` + * { + * 'ghc-version': { + * required: false, + * description: '...', + * default: 'latest' + * }, + * 'cabal-version': { + * required: false, + * description: '...', + * default: 'latest' + * }, + * 'stack-version': { + * required: false, + * description: '...', + * default: 'latest' + * }, + * 'enable-stack': { + * required: false, + * default: 'latest' + * }, + * ... + * } + * ``` + */ exports.yamlInputs = (0, js_yaml_1.load)((0, fs_1.readFileSync)((0, path_1.join)(__dirname, '..', 'action.yml'), 'utf8') // The action.yml file structure is statically known. // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/setup/lib/setup-haskell.js b/setup/lib/setup-haskell.js index 0c831268..2d3fc194 100644 --- a/setup/lib/setup-haskell.js +++ b/setup/lib/setup-haskell.js @@ -48,6 +48,9 @@ async function run(inputs) { core.info('Preparing to setup a Haskell environment'); const os = process.platform; const opts = (0, opts_1.getOpts)((0, opts_1.getDefaults)(os), os, inputs); + core.debug(`run: inputs = ${JSON.stringify(inputs)}`); + core.debug(`run: os = ${JSON.stringify(os)}`); + core.debug(`run: opts = ${JSON.stringify(opts)}`); if (opts.ghcup.releaseChannel) { await core.group(`Preparing ghcup environment`, async () => (0, installer_1.addGhcupReleaseChannel)(opts.ghcup.releaseChannel, os)); } diff --git a/setup/src/installer.ts b/setup/src/installer.ts index 05755ade..ed70d11e 100644 --- a/setup/src/installer.ts +++ b/setup/src/installer.ts @@ -3,11 +3,10 @@ import {exec as e} from '@actions/exec'; import {which} from '@actions/io'; import * as tc from '@actions/tool-cache'; import {promises as afs} from 'fs'; -import {join, dirname} from 'path'; -import {ghcup_version, OS, Tool, releaseRevision} from './opts'; +import {join} from 'path'; +import {ghcup_version, OS, Tool} from './opts'; import process from 'process'; import * as glob from '@actions/glob'; -import * as fs from 'fs'; import {compareVersions} from 'compare-versions'; // compareVersions can be used in the sense of > // Don't throw on non-zero. @@ -79,57 +78,69 @@ async function isInstalled( const toolPath = tc.find(tool, version); if (toolPath) return success(tool, version, toolPath, os); - const ghcupPath = `${process.env.HOME}/.ghcup${ + let ghcupPath = `${process.env.HOME}/.ghcup${ tool === 'ghc' ? `/ghc/${version}` : '' }/bin`; + if (os === 'win32') { + ghcupPath = 'C:/ghcup/bin'; + } const v = aptVersion(tool, version); const aptPath = `/opt/${tool}/${v}/bin`; - const chocoPath = await getChocoPath( - tool, - version, - releaseRevision(version, tool, os) - ); - const locations = { stack: [], // Always installed into the tool cache cabal: { - win32: [chocoPath], - linux: [aptPath], - darwin: [] + win32: [ghcupPath], + linux: [ghcupPath, aptPath], + darwin: [ghcupPath] }[os], ghc: { - win32: [chocoPath], - linux: [aptPath, ghcupPath], + win32: [ghcupPath], + linux: [ghcupPath, aptPath], darwin: [ghcupPath] }[os] }; + core.info(`isInstalled ${tool} ${version} ${locations[tool]}`); + const f = await exec(await ghcupBin(os), ['whereis', tool, version]); + core.info(`isInstalled whereis ${f}`); for (const p of locations[tool]) { + core.info(`Attempting to access tool ${tool} at location ${p}`); const installedPath = await afs .access(p) .then(() => p) .catch(() => undefined); - if (installedPath) { - // Make sure that the correct ghc is used, even if ghcup has set a - // default prior to this action being ran. - if (tool === 'ghc' && installedPath === ghcupPath) - await exec(await ghcupBin(os), ['set', tool, version]); - - return success(tool, version, installedPath, os); + if (installedPath == undefined) { + core.info(`Failed to access tool ${tool} at location ${p}`); + } else { + core.info(`Succeeded accessing tool ${tool} at location ${p}`); } - } - - if (tool === 'cabal' && os !== 'win32') { - const installedPath = await afs - .access(`${ghcupPath}/cabal-${version}`) - .then(() => ghcupPath) - .catch(() => undefined); if (installedPath) { - await exec(await ghcupBin(os), ['set', tool, version]); - return success(tool, version, installedPath, os); + // Make sure that the correct ghc is used, even if ghcup has set a + // default prior to this action being ran. + core.info(`isInstalled installedPath: ${installedPath}`); + if (installedPath === ghcupPath) { + // If the result of this `ghcup set` is non-zero, the version we want + // is probably not actually installed + const ghcupSetResult = await exec(await ghcupBin(os), [ + 'set', + tool, + version + ]); + if (ghcupSetResult == 0) + return success(tool, version, installedPath, os); + } else { + const cabalPath = await afs + .access(`${installedPath}/cabal-${version}`) + .then(() => p) + .catch(() => undefined); + core.info(`isInstalled cabalPath ${cabalPath}`); + if (cabalPath) { + return success(tool, version, installedPath, os); + } + } } } @@ -170,7 +181,7 @@ export async function installTool( await apt(tool, version); break; case 'win32': - await choco(tool, version); + await ghcup(tool, version, os); break; case 'darwin': await ghcup(tool, version, os); @@ -259,35 +270,11 @@ async function apt(tool: Tool, version: string): Promise { ); } -async function choco(tool: Tool, version: string): Promise { - core.info(`Attempting to install ${tool} ${version} using chocolatey`); - - // E.g. GHC version 7.10.3 on Chocolatey is revision 7.10.3.1. - const revision: string = releaseRevision(version, tool, 'win32'); - - // Choco tries to invoke `add-path` command on earlier versions of ghc, which has been deprecated and fails the step, so disable command execution during this. - console.log('::stop-commands::SetupHaskellStopCommands'); - const args = [ - 'choco', - 'install', - tool, - '--version', - revision, - '-m', - '--no-progress', - core.isDebug() ? '-d' : '-r' - ]; - if ((await exec('powershell', args)) !== 0) - await exec('powershell', [...args, '--pre']); - console.log('::SetupHaskellStopCommands::'); // Re-enable command execution - // Add GHC to path automatically because it does not add until the end of the step and we check the path. - - const chocoPath = await getChocoPath(tool, version, revision); - - if (tool == 'ghc') core.addPath(chocoPath); -} - async function ghcupBin(os: OS): Promise { + core.info(`ghcupBin : ${os}`); + if (os === 'win32') { + return 'ghcup'; + } const cachedBin = tc.find('ghcup', ghcup_version); if (cachedBin) return join(cachedBin, 'ghcup'); @@ -331,42 +318,3 @@ async function ghcupGHCHead(): Promise { ]); if (returnCode === 0) await exec(bin, ['set', 'ghc', 'head']); } - -async function getChocoPath( - tool: Tool, - version: string, - revision: string -): Promise { - // Environment variable 'ChocolateyToolsLocation' will be added to Hosted images soon - // fallback to C:\\tools for now until variable is available - core.debug( - `getChocoPath(): ChocolateyToolsLocation = ${process.env.ChocolateyToolsLocation}` - ); - const chocoToolsLocation = - process.env.ChocolateyToolsLocation ?? - join(`${process.env.SystemDrive}`, 'tools'); - - // choco packages GHC 9.x are installed on different path (C:\\tools\ghc-9.0.1) - let chocoToolPath = join(chocoToolsLocation, `${tool}-${version}`); - - // choco packages GHC < 9.x - if (!fs.existsSync(chocoToolPath)) { - chocoToolPath = join( - `${process.env.ChocolateyInstall}`, - 'lib', - `${tool}.${revision}` - ); - } - core.debug(`getChocoPath(): chocoToolPath = ${chocoToolPath}`); - - const pattern = `${chocoToolPath}/**/${tool}.exe`; - const globber = await glob.create(pattern); - - for await (const file of globber.globGenerator()) { - core.debug(`getChocoPath(): found ${tool} at ${file}`); - return dirname(file); - } - - core.debug(`getChocoPath(): cannot find binary for ${tool}`); - return ''; -} diff --git a/setup/src/opts.ts b/setup/src/opts.ts index 5be74ed4..568aa1b3 100644 --- a/setup/src/opts.ts +++ b/setup/src/opts.ts @@ -35,6 +35,34 @@ export type Defaults = Record & { general: {matcher: {enable: boolean}}; }; +/** + * Reads the example `actions.yml` file and selects the `inputs` key. The result + * will be a key-value map of the following shape: + * ``` + * { + * 'ghc-version': { + * required: false, + * description: '...', + * default: 'latest' + * }, + * 'cabal-version': { + * required: false, + * description: '...', + * default: 'latest' + * }, + * 'stack-version': { + * required: false, + * description: '...', + * default: 'latest' + * }, + * 'enable-stack': { + * required: false, + * default: 'latest' + * }, + * ... + * } + * ``` + */ export const yamlInputs: Record = ( load( readFileSync(join(__dirname, '..', 'action.yml'), 'utf8') diff --git a/setup/src/setup-haskell.ts b/setup/src/setup-haskell.ts index 4b183d94..99ed0f53 100644 --- a/setup/src/setup-haskell.ts +++ b/setup/src/setup-haskell.ts @@ -25,6 +25,9 @@ export default async function run( core.info('Preparing to setup a Haskell environment'); const os = process.platform as OS; const opts = getOpts(getDefaults(os), os, inputs); + core.debug(`run: inputs = ${JSON.stringify(inputs)}`); + core.debug(`run: os = ${JSON.stringify(os)}`); + core.debug(`run: opts = ${JSON.stringify(opts)}`); if (opts.ghcup.releaseChannel) { await core.group(`Preparing ghcup environment`, async () =>