Skip to content

Commit

Permalink
Add new ghcup-release-channels input
Browse files Browse the repository at this point in the history
  • Loading branch information
brandonchinn178 committed Jul 13, 2023
1 parent c5343c2 commit a709f1e
Show file tree
Hide file tree
Showing 9 changed files with 131 additions and 86 deletions.
19 changes: 18 additions & 1 deletion .github/workflows/workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,29 @@ jobs:
# and of cabal just 2.4, 3.0, 3.2, 3.4
# according to https://launchpad.net/~hvr/+archive/ubuntu/ghc?field.series_filter=focal

# Test ghcup pre-release channel
# Any matrix combinations with latest-nightly should add the appropriate release channel
- plan:
ghc: latest-nightly
ghcup_release_channels: >
https://ghc.gitlab.haskell.org/ghcup-metadata/ghcup-nightlies-0.0.7.yaml
# Test deprecated release channel still works for now
- os: ubuntu-latest
ghcup_release_channel: "https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-prereleases-0.0.7.yaml"
plan:
ghc: "9.6.0.20230111"
cabal: "3.8"

# Test ghcup release channels
- os: ubuntu-latest
ghcup_release_channels: >
https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-0.0.7.yaml,
https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-prereleases-0.0.7.yaml,
https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-vanilla-0.0.7.yaml,
plan:
ghc: "9.6.0.20230111"
cabal: "3.8"

# setup does something special for 7.10.3 (issue #79)
- os: ubuntu-20.04
plan:
Expand Down Expand Up @@ -148,6 +164,7 @@ jobs:
with:
ghc-version: ${{ matrix.plan.ghc }}
ghcup-release-channel: ${{ matrix.ghcup_release_channel }}
ghcup-release-channels: ${{ matrix.ghcup_release_channels }}
cabal-version: ${{ matrix.plan.cabal }}
cabal-update: ${{ matrix.cabal_update }}

Expand Down
47 changes: 30 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,23 +184,35 @@ jobs:
## Inputs
| Name | Description | Type | Default |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | --------- | ----------- |
| `ghc-version` | GHC version to use, e.g. `9.2` or `9.2.5`. | `string` | `latest` |
| `cabal-version` | Cabal version to use, e.g. `3.6`. | `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.
However, to avoid confusion and for forward compatibility, it is still recommended to **only use value `true` to set a "boolean" flag.**

In contrast, a proper `boolean` input like `cabal-update` only accepts values `true` and `false`.
| Name | Description | Type | Default |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------- | --------- | ----------- |
| `ghc-version` | GHC version to use, e.g. `9.2` or `9.2.5`. | `string` | `latest` |
| `cabal-version` | Cabal version to use, e.g. `3.6`. | `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-channels` | If set, add [release channels](https://www.haskell.org/ghcup/guide/#pre-release-channels) to ghcup. | `URL[]` | none |

Notes:

- "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.
However, to avoid confusion and for forward compatibility, it is still recommended to **only use value `true` to set a "boolean" flag.**

In contrast, a proper `boolean` input like `cabal-update` only accepts values `true` and `false`.

- Inputs that can take multiple values (like `ghcup-release-channels`) should be specified as a comma separated list, e.g.

```yaml
- uses: haskell-actions/setup@v2
with:
ghcup-release-channels: >
https://example.com/channel1,
https://example.com/channel2,
https://example.com/channel3,
```

## Outputs

Expand Down Expand Up @@ -237,6 +249,7 @@ E.g., `8.10` will be resolved to `8.10.7`, and so will `8`.
**GHC:**

- `latest-nightly`
- This requires adding https://ghc.gitlab.haskell.org/ghcup-metadata/ghcup-nightlies-0.0.7.yaml to `ghcup-release-channels`
- `latest` (default)
- `9.6.2` `9.6`
- `9.6.1`
Expand Down
5 changes: 4 additions & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,12 @@ 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-channels:
required: false
description: "Release channel URLs to add to ghcup via `ghcup config add-release-channel`."
ghcup-release-channel:
required: false
description: "A release channel URL to add to ghcup via `ghcup config add-release-channel`."
description: "Deprecated by ghcup-release-channels."
disable-matcher:
required: false
description: 'If specified, disables match messages from GHC as GitHub CI annotations.'
Expand Down
45 changes: 24 additions & 21 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13665,7 +13665,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
return result;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getOpts = exports.parseURL = exports.parseYAMLBoolean = exports.releaseRevision = exports.getDefaults = exports.yamlInputs = exports.ghcup_version = exports.supported_versions = exports.release_revisions = void 0;
exports.getOpts = exports.parseYAMLBoolean = exports.releaseRevision = exports.getDefaults = exports.yamlInputs = exports.ghcup_version = exports.supported_versions = exports.release_revisions = void 0;
const core = __importStar(__nccwpck_require__(2186));
const fs_1 = __nccwpck_require__(7147);
const js_yaml_1 = __nccwpck_require__(1917);
Expand Down Expand Up @@ -13765,24 +13765,33 @@ function parseYAMLBoolean(name, val) {
`Supported boolean values: \`true | True | TRUE | false | False | FALSE\``);
}
exports.parseYAMLBoolean = parseYAMLBoolean;
function parseURL(name, val) {
if (val === '')
return null;
try {
return new URL(val);
}
catch (e) {
throw new TypeError(`Action input "${name}" is not a valid URL`);
}
/**
* Parse a string as a comma-separated list.
*/
function parseCSV(val) {
return val
.split(',')
.map(s => s.trim())
.filter(s => s != '');
}
exports.parseURL = parseURL;
function getOpts({ ghc, cabal, stack }, os, inputs) {
core.debug(`Inputs are: ${JSON.stringify(inputs)}`);
const stackNoGlobal = (inputs['stack-no-global'] || '') !== '';
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'] || '');
if (inputs['ghcup-release-channel']) {
core.warning('ghcup-release-channel is deprecated in favor of ghcup-release-channels');
inputs['ghcup-release-channels'] = inputs['ghcup-release-channel'];
}
const ghcupReleaseChannels = parseCSV(inputs['ghcup-release-channels'] ?? '').map(v => {
try {
return new URL(v);
}
catch (e) {
throw new TypeError(`Not a valid URL: ${v}`);
}
});
// 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 @@ -13814,7 +13823,7 @@ function getOpts({ ghc, cabal, stack }, os, inputs) {
enable: ghcEnable
},
ghcup: {
releaseChannel: ghcupReleaseChannel
releaseChannels: ghcupReleaseChannels
},
cabal: {
raw: verInpt.cabal,
Expand Down Expand Up @@ -13898,15 +13907,9 @@ async function run(inputs) {
core.debug(`run: inputs = ${JSON.stringify(inputs)}`);
core.debug(`run: os = ${JSON.stringify(os)}`);
core.debug(`run: opts = ${JSON.stringify(opts)}`);
const releaseChannels = [
opts.ghcup.releaseChannel,
opts.ghc.raw === 'latest-nightly'
? new URL('https://ghc.gitlab.haskell.org/ghcup-metadata/ghcup-nightlies-0.0.7.yaml')
: null
].filter((v) => v !== null);
if (releaseChannels.length > 0) {
if (opts.ghcup.releaseChannels.length > 0) {
await core.group(`Setting release channels`, async () => {
for (const channel of releaseChannels) {
for (const channel of opts.ghcup.releaseChannels) {
await (0, installer_1.addGhcupReleaseChannel)(channel, os);
}
});
Expand Down
3 changes: 1 addition & 2 deletions lib/opts.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export interface ProgramOpt {
export interface Options {
ghc: ProgramOpt;
ghcup: {
releaseChannel: URL | null;
releaseChannels: URL[];
};
cabal: ProgramOpt & {
update: boolean;
Expand Down Expand Up @@ -85,6 +85,5 @@ export declare function releaseRevision(version: string, tool: Tool, os: OS): st
* @returns boolean
*/
export declare function parseYAMLBoolean(name: string, val: string): boolean;
export declare function parseURL(name: string, val: string): URL | null;
export declare function getOpts({ ghc, cabal, stack }: Defaults, os: OS, inputs: Record<string, string>): Options;
export {};
35 changes: 22 additions & 13 deletions lib/opts.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getOpts = exports.parseURL = exports.parseYAMLBoolean = exports.releaseRevision = exports.getDefaults = exports.yamlInputs = exports.ghcup_version = exports.supported_versions = exports.release_revisions = void 0;
exports.getOpts = exports.parseYAMLBoolean = exports.releaseRevision = exports.getDefaults = exports.yamlInputs = exports.ghcup_version = exports.supported_versions = exports.release_revisions = void 0;
const core = __importStar(require("@actions/core"));
const fs_1 = require("fs");
const js_yaml_1 = require("js-yaml");
Expand Down Expand Up @@ -123,24 +123,33 @@ function parseYAMLBoolean(name, val) {
`Supported boolean values: \`true | True | TRUE | false | False | FALSE\``);
}
exports.parseYAMLBoolean = parseYAMLBoolean;
function parseURL(name, val) {
if (val === '')
return null;
try {
return new URL(val);
}
catch (e) {
throw new TypeError(`Action input "${name}" is not a valid URL`);
}
/**
* Parse a string as a comma-separated list.
*/
function parseCSV(val) {
return val
.split(',')
.map(s => s.trim())
.filter(s => s != '');
}
exports.parseURL = parseURL;
function getOpts({ ghc, cabal, stack }, os, inputs) {
core.debug(`Inputs are: ${JSON.stringify(inputs)}`);
const stackNoGlobal = (inputs['stack-no-global'] || '') !== '';
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'] || '');
if (inputs['ghcup-release-channel']) {
core.warning('ghcup-release-channel is deprecated in favor of ghcup-release-channels');
inputs['ghcup-release-channels'] = inputs['ghcup-release-channel'];
}
const ghcupReleaseChannels = parseCSV(inputs['ghcup-release-channels'] ?? '').map(v => {
try {
return new URL(v);
}
catch (e) {
throw new TypeError(`Not a valid URL: ${v}`);
}
});
// 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 @@ -172,7 +181,7 @@ function getOpts({ ghc, cabal, stack }, os, inputs) {
enable: ghcEnable
},
ghcup: {
releaseChannel: ghcupReleaseChannel
releaseChannels: ghcupReleaseChannels
},
cabal: {
raw: verInpt.cabal,
Expand Down
10 changes: 2 additions & 8 deletions lib/setup-haskell.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,9 @@ async function run(inputs) {
core.debug(`run: inputs = ${JSON.stringify(inputs)}`);
core.debug(`run: os = ${JSON.stringify(os)}`);
core.debug(`run: opts = ${JSON.stringify(opts)}`);
const releaseChannels = [
opts.ghcup.releaseChannel,
opts.ghc.raw === 'latest-nightly'
? new URL('https://ghc.gitlab.haskell.org/ghcup-metadata/ghcup-nightlies-0.0.7.yaml')
: null
].filter((v) => v !== null);
if (releaseChannels.length > 0) {
if (opts.ghcup.releaseChannels.length > 0) {
await core.group(`Setting release channels`, async () => {
for (const channel of releaseChannels) {
for (const channel of opts.ghcup.releaseChannels) {
await (0, installer_1.addGhcupReleaseChannel)(channel, os);
}
});
Expand Down
41 changes: 28 additions & 13 deletions src/opts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export interface ProgramOpt {

export interface Options {
ghc: ProgramOpt;
ghcup: {releaseChannel: URL | null};
ghcup: {releaseChannels: URL[]};
cabal: ProgramOpt & {update: boolean};
stack: ProgramOpt & {setup: boolean};
general: {matcher: {enable: boolean}};
Expand Down Expand Up @@ -138,13 +138,14 @@ export function parseYAMLBoolean(name: string, val: string): boolean {
);
}

export function parseURL(name: string, val: string): URL | null {
if (val === '') return null;
try {
return new URL(val);
} catch (e) {
throw new TypeError(`Action input "${name}" is not a valid URL`);
}
/**
* Parse a string as a comma-separated list.
*/
function parseCSV(val: string): string[] {
return val
.split(',')
.map(s => s.trim())
.filter(s => s != '');
}

export function getOpts(
Expand All @@ -157,10 +158,24 @@ 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'] || ''
);

if (inputs['ghcup-release-channel']) {
core.warning(
'ghcup-release-channel is deprecated in favor of ghcup-release-channels'
);
inputs['ghcup-release-channels'] = inputs['ghcup-release-channel'];
}

const ghcupReleaseChannels = parseCSV(
inputs['ghcup-release-channels'] ?? ''
).map(v => {
try {
return new URL(v);
} catch (e) {
throw new TypeError(`Not a valid URL: ${v}`);
}
});

// 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 @@ -204,7 +219,7 @@ export function getOpts(
enable: ghcEnable
},
ghcup: {
releaseChannel: ghcupReleaseChannel
releaseChannels: ghcupReleaseChannels
},
cabal: {
raw: verInpt.cabal,
Expand Down
12 changes: 2 additions & 10 deletions src/setup-haskell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,9 @@ export default async function run(
core.debug(`run: os = ${JSON.stringify(os)}`);
core.debug(`run: opts = ${JSON.stringify(opts)}`);

const releaseChannels = [
opts.ghcup.releaseChannel,
opts.ghc.raw === 'latest-nightly'
? new URL(
'https://ghc.gitlab.haskell.org/ghcup-metadata/ghcup-nightlies-0.0.7.yaml'
)
: null
].filter((v): v is URL => v !== null);
if (releaseChannels.length > 0) {
if (opts.ghcup.releaseChannels.length > 0) {
await core.group(`Setting release channels`, async () => {
for (const channel of releaseChannels) {
for (const channel of opts.ghcup.releaseChannels) {
await addGhcupReleaseChannel(channel, os);
}
});
Expand Down

0 comments on commit a709f1e

Please sign in to comment.