From fab017e0e143bb87979f37f422006bb3d3620f5d Mon Sep 17 00:00:00 2001 From: Andreas Abel Date: Tue, 3 Jan 2023 20:51:30 +0100 Subject: [PATCH 01/10] Fix #29: new input 'cabal-update: false' to turn off 'cabal update' --- setup/action.yml | 12 ++++++++---- setup/dist/index.js | 6 ++++-- setup/lib/opts.d.ts | 4 +++- setup/lib/opts.js | 4 +++- setup/lib/setup-haskell.js | 2 +- setup/src/opts.ts | 6 ++++-- setup/src/setup-haskell.ts | 2 +- 7 files changed, 24 insertions(+), 12 deletions(-) diff --git a/setup/action.yml b/setup/action.yml index 87df2eeb..02128abe 100644 --- a/setup/action.yml +++ b/setup/action.yml @@ -16,16 +16,20 @@ inputs: default: 'latest' enable-stack: required: false - description: 'If specified, will setup Stack' + description: 'If specified, will setup Stack.' stack-no-global: required: false - description: 'If specified, enable-stack must be set. Prevents installing GHC and Cabal globally' + description: 'If specified, enable-stack must be set. Prevents installing GHC and Cabal globally.' stack-setup-ghc: required: false - description: 'If specified, enable-stack must be set. Will run stack setup to install the specified GHC' + description: 'If specified, enable-stack must be set. Will run stack setup to install the specified GHC.' + cabal-update: + required: false + default: true + description: 'Set to false to prevent `cabal update` from being run.' disable-matcher: required: false - description: 'If specified, disables match messages from GHC as GitHub CI annotations' + description: 'If specified, disables match messages from GHC as GitHub CI annotations.' outputs: ghc-path: description: 'The path of the ghc executable _directory_' diff --git a/setup/dist/index.js b/setup/dist/index.js index 000e479b..ef10d587 100644 --- a/setup/dist/index.js +++ b/setup/dist/index.js @@ -13698,6 +13698,7 @@ function getOpts({ ghc, cabal, stack }, os, inputs) { const stackSetupGhc = (inputs['stack-setup-ghc'] || '') !== ''; const stackEnable = (inputs['enable-stack'] || '') !== ''; const matcherDisable = (inputs['disable-matcher'] || '') !== ''; + const cabalUpdate = inputs['cabal-update'] !== 'false'; core.debug(`${stackNoGlobal}/${stackSetupGhc}/${stackEnable}`); const verInpt = { ghc: inputs['ghc-version'] || ghc.version, @@ -13727,7 +13728,8 @@ function getOpts({ ghc, cabal, stack }, os, inputs) { raw: verInpt.cabal, resolved: resolve(verInpt.cabal, cabal.supported, 'cabal', os, cabalEnable // if true: inform user about resolution ), - enable: cabalEnable + enable: cabalEnable, + update: cabalUpdate }, stack: { raw: verInpt.stack, @@ -13831,7 +13833,7 @@ async function run(inputs) { // https://github.com/haskell/cabal/issues/6823 // await exec('cabal user-config update'); } - if (!opts.stack.enable) + if (opts.cabal.update && !opts.stack.enable) await (0, exec_1.exec)('cabal update'); }); core.info(`##[add-matcher]${path.join(__dirname, '..', 'matcher.json')}`); diff --git a/setup/lib/opts.d.ts b/setup/lib/opts.d.ts index 0c0937e9..cf66dedb 100644 --- a/setup/lib/opts.d.ts +++ b/setup/lib/opts.d.ts @@ -14,7 +14,9 @@ export interface ProgramOpt { } export interface Options { ghc: ProgramOpt; - cabal: ProgramOpt; + cabal: ProgramOpt & { + update: boolean; + }; stack: ProgramOpt & { setup: boolean; }; diff --git a/setup/lib/opts.js b/setup/lib/opts.js index 6dce63e3..d84b15ff 100644 --- a/setup/lib/opts.js +++ b/setup/lib/opts.js @@ -75,6 +75,7 @@ function getOpts({ ghc, cabal, stack }, os, inputs) { const stackSetupGhc = (inputs['stack-setup-ghc'] || '') !== ''; const stackEnable = (inputs['enable-stack'] || '') !== ''; const matcherDisable = (inputs['disable-matcher'] || '') !== ''; + const cabalUpdate = inputs['cabal-update'] !== 'false'; core.debug(`${stackNoGlobal}/${stackSetupGhc}/${stackEnable}`); const verInpt = { ghc: inputs['ghc-version'] || ghc.version, @@ -104,7 +105,8 @@ function getOpts({ ghc, cabal, stack }, os, inputs) { raw: verInpt.cabal, resolved: resolve(verInpt.cabal, cabal.supported, 'cabal', os, cabalEnable // if true: inform user about resolution ), - enable: cabalEnable + enable: cabalEnable, + update: cabalUpdate }, stack: { raw: verInpt.stack, diff --git a/setup/lib/setup-haskell.js b/setup/lib/setup-haskell.js index 0955e598..b9438e14 100644 --- a/setup/lib/setup-haskell.js +++ b/setup/lib/setup-haskell.js @@ -79,7 +79,7 @@ async function run(inputs) { // https://github.com/haskell/cabal/issues/6823 // await exec('cabal user-config update'); } - if (!opts.stack.enable) + if (opts.cabal.update && !opts.stack.enable) await (0, exec_1.exec)('cabal update'); }); core.info(`##[add-matcher]${path.join(__dirname, '..', 'matcher.json')}`); diff --git a/setup/src/opts.ts b/setup/src/opts.ts index f9b53dfe..c292ed50 100644 --- a/setup/src/opts.ts +++ b/setup/src/opts.ts @@ -24,7 +24,7 @@ export interface ProgramOpt { export interface Options { ghc: ProgramOpt; - cabal: ProgramOpt; + cabal: ProgramOpt & {update: boolean}; stack: ProgramOpt & {setup: boolean}; general: {matcher: {enable: boolean}}; } @@ -93,6 +93,7 @@ export function getOpts( const stackSetupGhc = (inputs['stack-setup-ghc'] || '') !== ''; const stackEnable = (inputs['enable-stack'] || '') !== ''; const matcherDisable = (inputs['disable-matcher'] || '') !== ''; + const cabalUpdate = inputs['cabal-update'] !== 'false'; core.debug(`${stackNoGlobal}/${stackSetupGhc}/${stackEnable}`); const verInpt = { ghc: inputs['ghc-version'] || ghc.version, @@ -136,7 +137,8 @@ export function getOpts( os, cabalEnable // if true: inform user about resolution ), - enable: cabalEnable + enable: cabalEnable, + update: cabalUpdate }, stack: { raw: verInpt.stack, diff --git a/setup/src/setup-haskell.ts b/setup/src/setup-haskell.ts index 9e5c5ab3..077c0c6b 100644 --- a/setup/src/setup-haskell.ts +++ b/setup/src/setup-haskell.ts @@ -73,7 +73,7 @@ export default async function run( // https://github.com/haskell/cabal/issues/6823 // await exec('cabal user-config update'); } - if (!opts.stack.enable) await exec('cabal update'); + if (opts.cabal.update && !opts.stack.enable) await exec('cabal update'); }); core.info(`##[add-matcher]${path.join(__dirname, '..', 'matcher.json')}`); From 93d09d349bb43c3608cc0f1909d95e8df8c7a10c Mon Sep 17 00:00:00 2001 From: Andreas Abel Date: Tue, 3 Jan 2023 20:53:29 +0100 Subject: [PATCH 02/10] Test 'cabal-update: false' --- .github/workflows/workflow.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 50074e16..2ad85f23 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -72,6 +72,7 @@ jobs: with: ghc-version: ${{ matrix.ghc }} cabal-version: ${{ matrix.cabal }} + cabal-update: false - name: Test runghc run: | runghc --version From e9dab18154a2a2a929a0432aeac7d7ff897222ae Mon Sep 17 00:00:00 2001 From: Andreas Abel Date: Fri, 6 Jan 2023 02:32:17 +0100 Subject: [PATCH 03/10] README: Add 'cabal-update' to table of inputs --- setup/README.md | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/setup/README.md b/setup/README.md index 8c08e1ca..49557a85 100644 --- a/setup/README.md +++ b/setup/README.md @@ -98,19 +98,22 @@ jobs: ## Inputs -| Name | Required | Description | Type | Default | -| ----------------- | :------: | ---------------------------------------------------------------------------------------------------------------------------------------- | --------- | ----------- | -| `ghc-version` | | GHC version to use, ex. `latest` | string | latest | -| `cabal-version` | | Cabal version to use, ex. `3.4` | string | latest | -| `stack-version` | | Stack version to use, ex. `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 | +| Name | Description | Type | Default | +| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | --------- | ----------- | +| `ghc-version` | GHC version to use, ex. `9.2` or `9.2.4`. | string | `latest` | +| `cabal-version` | Cabal version to use, ex. `3.4`. | string | `latest` | +| `stack-version` | Stack version to use, ex. `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` | 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. +In contrast, a proper `boolean` field only accepts values `true` and `false`. + ## Outputs | Name | Description | Type | From 9ad367ed9a9a755e8e0e39846989f13ea9e82828 Mon Sep 17 00:00:00 2001 From: Andreas Abel Date: Fri, 6 Jan 2023 02:34:35 +0100 Subject: [PATCH 04/10] Accept YAML 1.2 booleans as values for 'cabal-update' --- setup/dist/index.js | 27 +++++++++++++++++++++++++-- setup/lib/opts.d.ts | 11 +++++++++++ setup/lib/opts.js | 27 +++++++++++++++++++++++++-- setup/src/opts.ts | 25 ++++++++++++++++++++++++- 4 files changed, 85 insertions(+), 5 deletions(-) diff --git a/setup/dist/index.js b/setup/dist/index.js index ef10d587..b4983b81 100644 --- a/setup/dist/index.js +++ b/setup/dist/index.js @@ -13646,7 +13646,7 @@ var __importStar = (this && this.__importStar) || function (mod) { return result; }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.getOpts = 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); @@ -13692,13 +13692,36 @@ function releaseRevision(version, tool, os) { return result; } exports.releaseRevision = releaseRevision; +/** + * Convert a string input to a boolean according to the YAML 1.2 "core schema" specification. + * Supported boolean renderings: `true | True | TRUE | false | False | FALSE` . + * ref: https://yaml.org/spec/1.2/spec.html#id2804923 + * Adapted from: https://github.com/actions/toolkit/commit/fbdf27470cdcb52f16755d32082f1fee0bfb7d6d#diff-f63fb32fca85d8e177d6400ce078818a4815b80ac7a3319b60d3507354890992R94-R115 + * + * @param name name of the input + * @param val supposed string representation of a boolean + * @returns boolean + */ +function parseYAMLBoolean(name, val) { + const trueValue = ['true', 'True', 'TRUE']; + const falseValue = ['false', 'False', 'FALSE']; + if (trueValue.includes(val)) + return true; + if (falseValue.includes(val)) + return false; + throw new TypeError(`Action input "${name}" does not meet YAML 1.2 "Core Schema" specification: \n` + + `Supported boolean values: \`true | True | TRUE | false | False | FALSE\``); +} +exports.parseYAMLBoolean = parseYAMLBoolean; 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 cabalUpdate = inputs['cabal-update'] !== 'false'; + // Andreas, 2023-01-05, issue #29: + // 'cabal-update' has a default value, so we should get a proper boolean always. (Fingers crossed.) + const cabalUpdate = parseYAMLBoolean('cabal-update', inputs['cabal-update']); core.debug(`${stackNoGlobal}/${stackSetupGhc}/${stackEnable}`); const verInpt = { ghc: inputs['ghc-version'] || ghc.version, diff --git a/setup/lib/opts.d.ts b/setup/lib/opts.d.ts index cf66dedb..58ab6542 100644 --- a/setup/lib/opts.d.ts +++ b/setup/lib/opts.d.ts @@ -42,5 +42,16 @@ export declare const yamlInputs: Record; export declare function getDefaults(os: OS): Defaults; export declare function releaseRevision(version: string, tool: Tool, os: OS): string; +/** + * Convert a string input to a boolean according to the YAML 1.2 "core schema" specification. + * Supported boolean renderings: `true | True | TRUE | false | False | FALSE` . + * ref: https://yaml.org/spec/1.2/spec.html#id2804923 + * Adapted from: https://github.com/actions/toolkit/commit/fbdf27470cdcb52f16755d32082f1fee0bfb7d6d#diff-f63fb32fca85d8e177d6400ce078818a4815b80ac7a3319b60d3507354890992R94-R115 + * + * @param name name of the input + * @param val supposed string representation of a boolean + * @returns boolean + */ +export declare function parseYAMLBoolean(name: string, val: string): boolean; export declare function getOpts({ ghc, cabal, stack }: Defaults, os: OS, inputs: Record): Options; export {}; diff --git a/setup/lib/opts.js b/setup/lib/opts.js index d84b15ff..b4d40af8 100644 --- a/setup/lib/opts.js +++ b/setup/lib/opts.js @@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) { return result; }; Object.defineProperty(exports, "__esModule", { value: true }); -exports.getOpts = 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"); @@ -69,13 +69,36 @@ function releaseRevision(version, tool, os) { return result; } exports.releaseRevision = releaseRevision; +/** + * Convert a string input to a boolean according to the YAML 1.2 "core schema" specification. + * Supported boolean renderings: `true | True | TRUE | false | False | FALSE` . + * ref: https://yaml.org/spec/1.2/spec.html#id2804923 + * Adapted from: https://github.com/actions/toolkit/commit/fbdf27470cdcb52f16755d32082f1fee0bfb7d6d#diff-f63fb32fca85d8e177d6400ce078818a4815b80ac7a3319b60d3507354890992R94-R115 + * + * @param name name of the input + * @param val supposed string representation of a boolean + * @returns boolean + */ +function parseYAMLBoolean(name, val) { + const trueValue = ['true', 'True', 'TRUE']; + const falseValue = ['false', 'False', 'FALSE']; + if (trueValue.includes(val)) + return true; + if (falseValue.includes(val)) + return false; + throw new TypeError(`Action input "${name}" does not meet YAML 1.2 "Core Schema" specification: \n` + + `Supported boolean values: \`true | True | TRUE | false | False | FALSE\``); +} +exports.parseYAMLBoolean = parseYAMLBoolean; 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 cabalUpdate = inputs['cabal-update'] !== 'false'; + // Andreas, 2023-01-05, issue #29: + // 'cabal-update' has a default value, so we should get a proper boolean always. (Fingers crossed.) + const cabalUpdate = parseYAMLBoolean('cabal-update', inputs['cabal-update']); core.debug(`${stackNoGlobal}/${stackSetupGhc}/${stackEnable}`); const verInpt = { ghc: inputs['ghc-version'] || ghc.version, diff --git a/setup/src/opts.ts b/setup/src/opts.ts index c292ed50..ed555901 100644 --- a/setup/src/opts.ts +++ b/setup/src/opts.ts @@ -83,6 +83,27 @@ export function releaseRevision(version: string, tool: Tool, os: OS): string { return result; } +/** + * Convert a string input to a boolean according to the YAML 1.2 "core schema" specification. + * Supported boolean renderings: `true | True | TRUE | false | False | FALSE` . + * ref: https://yaml.org/spec/1.2/spec.html#id2804923 + * Adapted from: https://github.com/actions/toolkit/commit/fbdf27470cdcb52f16755d32082f1fee0bfb7d6d#diff-f63fb32fca85d8e177d6400ce078818a4815b80ac7a3319b60d3507354890992R94-R115 + * + * @param name name of the input + * @param val supposed string representation of a boolean + * @returns boolean + */ +export function parseYAMLBoolean(name: string, val: string): boolean { + const trueValue = ['true', 'True', 'TRUE']; + const falseValue = ['false', 'False', 'FALSE']; + if (trueValue.includes(val)) return true; + if (falseValue.includes(val)) return false; + throw new TypeError( + `Action input "${name}" does not meet YAML 1.2 "Core Schema" specification: \n` + + `Supported boolean values: \`true | True | TRUE | false | False | FALSE\`` + ); +} + export function getOpts( {ghc, cabal, stack}: Defaults, os: OS, @@ -93,7 +114,9 @@ export function getOpts( const stackSetupGhc = (inputs['stack-setup-ghc'] || '') !== ''; const stackEnable = (inputs['enable-stack'] || '') !== ''; const matcherDisable = (inputs['disable-matcher'] || '') !== ''; - const cabalUpdate = inputs['cabal-update'] !== 'false'; + // Andreas, 2023-01-05, issue #29: + // 'cabal-update' has a default value, so we should get a proper boolean always. (Fingers crossed.) + const cabalUpdate = parseYAMLBoolean('cabal-update', inputs['cabal-update']); core.debug(`${stackNoGlobal}/${stackSetupGhc}/${stackEnable}`); const verInpt = { ghc: inputs['ghc-version'] || ghc.version, From 29517550250f7552a4056f8fbfcdc448ca8b3a99 Mon Sep 17 00:00:00 2001 From: Andreas Abel Date: Fri, 6 Jan 2023 02:52:59 +0100 Subject: [PATCH 05/10] CI: test 'cabal-update: true': project with Hackage dependency --- .github/workflows/workflow.yml | 15 ++++++++++++++- .../project-with-hackage-dependency/Main.hs | 4 ++++ .../project-with-hackage-dependency/Setup.hs | 2 ++ .../project-with-hackage-dependency.cabal | 11 +++++++++++ 4 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 setup/__tests__/project-with-hackage-dependency/Main.hs create mode 100644 setup/__tests__/project-with-hackage-dependency/Setup.hs create mode 100644 setup/__tests__/project-with-hackage-dependency/project-with-hackage-dependency.cabal diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 2ad85f23..e91578e2 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -41,6 +41,8 @@ jobs: os: [ubuntu-latest, macOS-latest, windows-latest] ghc: ["latest", "8.4.4"] cabal: ["latest", "3.2.0.0"] + cabal-update: [false] + # The following tests do not set 'cabal-update', which defaults to 'true' then. include: - os: ubuntu-latest ghc: "8.2.2" @@ -68,25 +70,36 @@ jobs: cabal: "3.6" steps: - uses: actions/checkout@v3 + - uses: ./setup with: ghc-version: ${{ matrix.ghc }} cabal-version: ${{ matrix.cabal }} - cabal-update: false + cabal-update: ${{ matrix.cabal-update }} + - name: Test runghc run: | runghc --version runghc __tests__/hello.hs + - name: Build test project working-directory: setup/__tests__/project run: cabal build + - name: Run test project working-directory: setup/__tests__/project run: cabal run + + - name: Build and run test with Hackage dependency + if: ${{ matrix.cabal-update != false }} + working-directory: setup/__tests__/project-with-hackage-dependency + run: cabal build && cabal run + - name: Show installed versions run: | cabal --version ghc --version + - name: Confirm installed and expected versions match shell: bash # check that if given in the matrix, the actual version matches: diff --git a/setup/__tests__/project-with-hackage-dependency/Main.hs b/setup/__tests__/project-with-hackage-dependency/Main.hs new file mode 100644 index 00000000..29319957 --- /dev/null +++ b/setup/__tests__/project-with-hackage-dependency/Main.hs @@ -0,0 +1,4 @@ +module Main where + +main :: IO () +main = putStrLn "Hello, Hackage!" diff --git a/setup/__tests__/project-with-hackage-dependency/Setup.hs b/setup/__tests__/project-with-hackage-dependency/Setup.hs new file mode 100644 index 00000000..9a994af6 --- /dev/null +++ b/setup/__tests__/project-with-hackage-dependency/Setup.hs @@ -0,0 +1,2 @@ +import Distribution.Simple +main = defaultMain diff --git a/setup/__tests__/project-with-hackage-dependency/project-with-hackage-dependency.cabal b/setup/__tests__/project-with-hackage-dependency/project-with-hackage-dependency.cabal new file mode 100644 index 00000000..bba60ed4 --- /dev/null +++ b/setup/__tests__/project-with-hackage-dependency/project-with-hackage-dependency.cabal @@ -0,0 +1,11 @@ +cabal-version: >=1.10 +name: project +version: 0.1.0.0 +build-type: Simple + +executable project + main-is: Main.hs + build-depends: base + -- Add a package from hackage here to see whether `cabal update` ran. + , base-orphans + default-language: Haskell2010 From 2328dd780ef38ac096d149cd4d6aaef6851c3244 Mon Sep 17 00:00:00 2001 From: Andreas Abel Date: Fri, 6 Jan 2023 02:59:26 +0100 Subject: [PATCH 06/10] Default value for 'cabal-update' --- setup/dist/index.js | 6 ++++-- setup/lib/opts.js | 6 ++++-- setup/src/opts.ts | 9 +++++++-- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/setup/dist/index.js b/setup/dist/index.js index b4983b81..898a6cac 100644 --- a/setup/dist/index.js +++ b/setup/dist/index.js @@ -13720,8 +13720,10 @@ function getOpts({ ghc, cabal, stack }, os, inputs) { const stackEnable = (inputs['enable-stack'] || '') !== ''; const matcherDisable = (inputs['disable-matcher'] || '') !== ''; // Andreas, 2023-01-05, issue #29: - // 'cabal-update' has a default value, so we should get a proper boolean always. (Fingers crossed.) - const cabalUpdate = parseYAMLBoolean('cabal-update', inputs['cabal-update']); + // '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. + // Thus, need to patch with default value here. + const cabalUpdate = parseYAMLBoolean('cabal-update', inputs['cabal-update'] || 'true'); core.debug(`${stackNoGlobal}/${stackSetupGhc}/${stackEnable}`); const verInpt = { ghc: inputs['ghc-version'] || ghc.version, diff --git a/setup/lib/opts.js b/setup/lib/opts.js index b4d40af8..7ba2f4d3 100644 --- a/setup/lib/opts.js +++ b/setup/lib/opts.js @@ -97,8 +97,10 @@ function getOpts({ ghc, cabal, stack }, os, inputs) { const stackEnable = (inputs['enable-stack'] || '') !== ''; const matcherDisable = (inputs['disable-matcher'] || '') !== ''; // Andreas, 2023-01-05, issue #29: - // 'cabal-update' has a default value, so we should get a proper boolean always. (Fingers crossed.) - const cabalUpdate = parseYAMLBoolean('cabal-update', inputs['cabal-update']); + // '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. + // Thus, need to patch with default value here. + const cabalUpdate = parseYAMLBoolean('cabal-update', inputs['cabal-update'] || 'true'); core.debug(`${stackNoGlobal}/${stackSetupGhc}/${stackEnable}`); const verInpt = { ghc: inputs['ghc-version'] || ghc.version, diff --git a/setup/src/opts.ts b/setup/src/opts.ts index ed555901..987e037c 100644 --- a/setup/src/opts.ts +++ b/setup/src/opts.ts @@ -115,8 +115,13 @@ export function getOpts( const stackEnable = (inputs['enable-stack'] || '') !== ''; const matcherDisable = (inputs['disable-matcher'] || '') !== ''; // Andreas, 2023-01-05, issue #29: - // 'cabal-update' has a default value, so we should get a proper boolean always. (Fingers crossed.) - const cabalUpdate = parseYAMLBoolean('cabal-update', inputs['cabal-update']); + // '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. + // Thus, need to patch with default value here. + const cabalUpdate = parseYAMLBoolean( + 'cabal-update', + inputs['cabal-update'] || 'true' + ); core.debug(`${stackNoGlobal}/${stackSetupGhc}/${stackEnable}`); const verInpt = { ghc: inputs['ghc-version'] || ghc.version, From 78df9964cccf50efe25243150cc0d5f79afb11a0 Mon Sep 17 00:00:00 2001 From: Andreas Abel Date: Fri, 6 Jan 2023 03:10:20 +0100 Subject: [PATCH 07/10] CI: use cabal_update (underscore) in matrix --- .github/workflows/workflow.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index e91578e2..bdfe25d3 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -41,7 +41,7 @@ jobs: os: [ubuntu-latest, macOS-latest, windows-latest] ghc: ["latest", "8.4.4"] cabal: ["latest", "3.2.0.0"] - cabal-update: [false] + cabal_update: ["false"] # The following tests do not set 'cabal-update', which defaults to 'true' then. include: - os: ubuntu-latest @@ -75,7 +75,7 @@ jobs: with: ghc-version: ${{ matrix.ghc }} cabal-version: ${{ matrix.cabal }} - cabal-update: ${{ matrix.cabal-update }} + cabal-update: ${{ matrix.cabal_update }} - name: Test runghc run: | @@ -91,7 +91,7 @@ jobs: run: cabal run - name: Build and run test with Hackage dependency - if: ${{ matrix.cabal-update != false }} + if: ${{ matrix.cabal_update != 'false' }} working-directory: setup/__tests__/project-with-hackage-dependency run: cabal build && cabal run From 1aa5a5cf6734db166bee3444f450e4e35ba72048 Mon Sep 17 00:00:00 2001 From: Andreas Abel Date: Fri, 6 Jan 2023 03:22:44 +0100 Subject: [PATCH 08/10] Fixup: project with Hackage dependency --- .../project-with-hackage-dependency.cabal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/__tests__/project-with-hackage-dependency/project-with-hackage-dependency.cabal b/setup/__tests__/project-with-hackage-dependency/project-with-hackage-dependency.cabal index bba60ed4..b6e7719b 100644 --- a/setup/__tests__/project-with-hackage-dependency/project-with-hackage-dependency.cabal +++ b/setup/__tests__/project-with-hackage-dependency/project-with-hackage-dependency.cabal @@ -1,5 +1,5 @@ cabal-version: >=1.10 -name: project +name: project-with-hackage-dependency version: 0.1.0.0 build-type: Simple From dfd5a5adfbbf1e1653395a57bf65ae761b71decb Mon Sep 17 00:00:00 2001 From: Andreas Abel Date: Fri, 6 Jan 2023 03:32:14 +0100 Subject: [PATCH 09/10] Work around #158 --- .github/workflows/workflow.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index bdfe25d3..12e98a5b 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -47,6 +47,7 @@ jobs: - os: ubuntu-latest ghc: "8.2.2" cabal: "2.4.1.0" + cabal_update: "false" - os: ubuntu-18.04 ghc: "7.4.1" cabal: "3.4" From d3609b3df0873e3de97504c53df3dce2d9c26449 Mon Sep 17 00:00:00 2001 From: Andreas Abel Date: Tue, 10 Jan 2023 18:22:40 +0100 Subject: [PATCH 10/10] Extra clarification of boolean vs "boolean" inputs --- setup/README.md | 11 ++++++----- setup/action.yml | 5 ++++- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/setup/README.md b/setup/README.md index 49557a85..db41cd08 100644 --- a/setup/README.md +++ b/setup/README.md @@ -100,19 +100,20 @@ jobs: | Name | Description | Type | Default | | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | --------- | ----------- | -| `ghc-version` | GHC version to use, ex. `9.2` or `9.2.4`. | string | `latest` | -| `cabal-version` | Cabal version to use, ex. `3.4`. | string | `latest` | -| `stack-version` | Stack version to use, ex. `latest`. Stack will only be installed if `enable-stack` is set. | string | `latest` | +| `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` | +| `cabal-update` | If set to `false`, skip `cabal update` step. | `boolean` | `true` | 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` field only accepts values `true` and `false`. +In contrast, a proper `boolean` input like `cabal-update` only accepts values `true` and `false`. ## Outputs diff --git a/setup/action.yml b/setup/action.yml index 02128abe..bc047ec3 100644 --- a/setup/action.yml +++ b/setup/action.yml @@ -26,7 +26,10 @@ inputs: cabal-update: required: false default: true - description: 'Set to false to prevent `cabal update` from being run.' + description: 'Set to `false` to prevent `cabal update` from being run.' + # 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. disable-matcher: required: false description: 'If specified, disables match messages from GHC as GitHub CI annotations.'