Skip to content
This repository has been archived by the owner on Jan 5, 2024. It is now read-only.

Commit

Permalink
Add support for ghcup release channel (#175)
Browse files Browse the repository at this point in the history
New action input `ghcup-release-channel` to provide a ghc (pre)release channel for ghcup which will be added via `ghcup config add-release-channel`.  Useful for installing ghc prereleases.  
Tested with GHC 9.6.1 alpha (9.6.0.20230111).

Fixes: #108.

Co-authored-by: Andreas Abel <[email protected]>
  • Loading branch information
wismill and andreasabel authored Jan 17, 2023
1 parent 8a951d0 commit 56a793a
Show file tree
Hide file tree
Showing 12 changed files with 112 additions and 15 deletions.
6 changes: 6 additions & 0 deletions .github/workflows/workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ jobs:
- os: ubuntu-18.04
ghc: "7.4.1"
cabal: "3.4"
# Test ghcup pre-release channel
- os: ubuntu-latest
ghc: "9.6.0.20230111"
ghcup_release_channel: "https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-prereleases-0.0.7.yaml"
cabal: "3.8"
# setup does something special for 7.10.3 (issue #79)
- os: ubuntu-20.04
ghc: "7.10.3"
Expand All @@ -75,6 +80,7 @@ jobs:
- uses: ./setup
with:
ghc-version: ${{ matrix.ghc }}
ghcup-release-channel: ${{ matrix.ghcup_release_channel }}
cabal-version: ${{ matrix.cabal }}
cabal-update: ${{ matrix.cabal_update }}

Expand Down
21 changes: 11 additions & 10 deletions setup/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,16 +98,17 @@ jobs:
## Inputs
| Name | Description | Type | Default |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | --------- | ----------- |
| `ghc-version` | GHC version to use, e.g. `9.2` or `9.2.4`. | `string` | `latest` |
| `cabal-version` | Cabal version to use, e.g. `3.4`. | `string` | `latest` |
| `stack-version` | Stack version to use, e.g. `latest`. Stack will only be installed if `enable-stack` is set. | `string` | `latest` |
| `enable-stack` | If set, will setup Stack. | "boolean" | false/unset |
| `stack-no-global` | If set, `enable-stack` must be set. Prevents installing GHC and Cabal globally. | "boolean" | false/unset |
| `stack-setup-ghc` | If set, `enable-stack` must be set. Runs stack setup to install the specified GHC. (Note: setting this does _not_ imply `stack-no-global`.) | "boolean" | false/unset |
| `disable-matcher` | If set, disables match messages from GHC as GitHub CI annotations. | "boolean" | false/unset |
| `cabal-update` | If set to `false`, skip `cabal update` step. | `boolean` | `true` |
| Name | Description | Type | Default |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | --------- | ----------- |
| `ghc-version` | GHC version to use, e.g. `9.2` or `9.2.4`. | `string` | `latest` |
| `cabal-version` | Cabal version to use, e.g. `3.4`. | `string` | `latest` |
| `stack-version` | Stack version to use, e.g. `latest`. Stack will only be installed if `enable-stack` is set. | `string` | `latest` |
| `enable-stack` | If set, will setup Stack. | "boolean" | false/unset |
| `stack-no-global` | If set, `enable-stack` must be set. Prevents installing GHC and Cabal globally. | "boolean" | false/unset |
| `stack-setup-ghc` | If set, `enable-stack` must be set. Runs stack setup to install the specified GHC. (Note: setting this does _not_ imply `stack-no-global`.) | "boolean" | false/unset |
| `disable-matcher` | If set, disables match messages from GHC as GitHub CI annotations. | "boolean" | false/unset |
| `cabal-update` | If set to `false`, skip `cabal update` step. | `boolean` | `true` |
| `ghcup-release-channel` | If set, add a [release channel](https://www.haskell.org/ghcup/guide/#pre-release-channels) to ghcup. | `URL` | none |

Note: "boolean" types are set/unset, not true/false.
That is, setting any "boolean" to a value other than the empty string (`""`) will be considered true/set.
Expand Down
3 changes: 3 additions & 0 deletions setup/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ inputs:
# Note: 'cabal-update' only accepts 'true' and 'false' as values.
# This is different from the other flags ('enable-stack', 'disable-matcher' etc.)
# which are true as soon as they are not null.
ghcup-release-channel:
required: false
description: "A release channel URL to add to ghcup via `ghcup config add-release-channel`."
disable-matcher:
required: false
description: 'If specified, disables match messages from GHC as GitHub CI annotations.'
Expand Down
28 changes: 26 additions & 2 deletions setup/dist/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions setup/lib/installer.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion setup/lib/installer.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions setup/lib/opts.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 16 additions & 1 deletion setup/lib/opts.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions setup/lib/setup-haskell.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions setup/src/installer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,15 @@ async function ghcupBin(os: OS): Promise<string> {
);
}

export async function addGhcupReleaseChannel(
channel: URL,
os: OS
): Promise<void> {
core.info(`Adding ghcup release channel: ${channel}`);
const bin = await ghcupBin(os);
await exec(bin, ['config', 'add-release-channel', channel.toString()]);
}

async function ghcup(tool: Tool, version: string, os: OS): Promise<void> {
core.info(`Attempting to install ${tool} ${version} using ghcup`);
const bin = await ghcupBin(os);
Expand Down
17 changes: 17 additions & 0 deletions setup/src/opts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export interface ProgramOpt {

export interface Options {
ghc: ProgramOpt;
ghcup: {releaseChannel?: URL};
cabal: ProgramOpt & {update: boolean};
stack: ProgramOpt & {setup: boolean};
general: {matcher: {enable: boolean}};
Expand Down Expand Up @@ -104,6 +105,15 @@ export function parseYAMLBoolean(name: string, val: string): boolean {
);
}

export function parseURL(name: string, val: string): URL | undefined {
if (val === '') return undefined;
try {
return new URL(val);
} catch (e) {
throw new TypeError(`Action input "${name}" is not a valid URL`);
}
}

export function getOpts(
{ghc, cabal, stack}: Defaults,
os: OS,
Expand All @@ -114,6 +124,10 @@ export function getOpts(
const stackSetupGhc = (inputs['stack-setup-ghc'] || '') !== '';
const stackEnable = (inputs['enable-stack'] || '') !== '';
const matcherDisable = (inputs['disable-matcher'] || '') !== '';
const ghcupReleaseChannel = parseURL(
'ghcup-release-channel',
inputs['ghcup-release-channel'] || ''
);
// Andreas, 2023-01-05, issue #29:
// 'cabal-update' has a default value, so we should get a proper boolean always.
// Andreas, 2023-01-06: This is not true if we use the action as a library.
Expand Down Expand Up @@ -156,6 +170,9 @@ export function getOpts(
),
enable: ghcEnable
},
ghcup: {
releaseChannel: ghcupReleaseChannel
},
cabal: {
raw: verInpt.cabal,
resolved: resolve(
Expand Down
8 changes: 7 additions & 1 deletion setup/src/setup-haskell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as fs from 'fs';
import * as path from 'path';
import {EOL} from 'os';
import {getOpts, getDefaults, Tool} from './opts';
import {installTool, resetTool} from './installer';
import {addGhcupReleaseChannel, installTool, resetTool} from './installer';
import type {OS} from './opts';
import {exec} from '@actions/exec';

Expand All @@ -26,6 +26,12 @@ export default async function run(
const os = process.platform as OS;
const opts = getOpts(getDefaults(os), os, inputs);

if (opts.ghcup.releaseChannel) {
await core.group(`Preparing ghcup environment`, async () =>
addGhcupReleaseChannel(opts.ghcup.releaseChannel!, os)
);
}

for (const [t, {resolved}] of Object.entries(opts).filter(
o => o[1].enable
)) {
Expand Down

0 comments on commit 56a793a

Please sign in to comment.