From 1c4e8e9e3cbcd34b9248f36ddc83fb24f0783b97 Mon Sep 17 00:00:00 2001 From: Hugo Heuzard Date: Wed, 15 May 2024 10:08:43 +0200 Subject: [PATCH] Add initial support for opam 2.2 on Windows Co-authored-by: Kate Co-authored-by: Sora Morimoto Co-authored-by: David Allsopp --- .github/workflows/workflow.yml | 17 +- CHANGELOG.md | 4 + EXAMPLES.md | 49 -- README.md | 27 +- action.yml | 10 +- analysis/dist/index.js | 13 +- biome.json | 5 +- dist/index.js | 946 ++++++++++---------------- dist/post/LICENSE.txt | 25 - dist/post/index.js | 878 +++--------------------- lint-doc/dist/index.js | 20 +- lint-fmt/dist/index.js | 3 +- lint-opam/dist/index.js | 4 +- packages/analysis/src/analysis.ts | 11 +- packages/analysis/src/index.ts | 2 - packages/analysis/src/opam.ts | 2 +- packages/analysis/tsconfig.json | 6 +- packages/lint-doc/src/index.ts | 2 - packages/lint-doc/src/odoc.ts | 13 +- packages/lint-doc/src/opam.ts | 10 +- packages/lint-doc/tsconfig.json | 4 +- packages/lint-fmt/src/index.ts | 2 - packages/lint-fmt/src/ocamlformat.ts | 4 +- packages/lint-fmt/tsconfig.json | 4 +- packages/lint-opam/src/index.ts | 2 - packages/lint-opam/src/opam.ts | 4 +- packages/lint-opam/tsconfig.json | 4 +- packages/setup-ocaml/README.md | 55 +- packages/setup-ocaml/src/cache.ts | 146 ++-- packages/setup-ocaml/src/constants.ts | 74 +- packages/setup-ocaml/src/depext.ts | 35 - packages/setup-ocaml/src/dune.ts | 12 +- packages/setup-ocaml/src/index.ts | 2 - packages/setup-ocaml/src/installer.ts | 68 +- packages/setup-ocaml/src/opam.ts | 291 ++------ packages/setup-ocaml/src/packages.ts | 1 - packages/setup-ocaml/src/post.ts | 5 +- packages/setup-ocaml/src/system.ts | 17 +- packages/setup-ocaml/src/unix.ts | 42 ++ packages/setup-ocaml/src/version.ts | 29 +- packages/setup-ocaml/src/win32.ts | 26 - packages/setup-ocaml/src/windows.ts | 76 +++ packages/setup-ocaml/tsconfig.json | 4 +- 43 files changed, 775 insertions(+), 2179 deletions(-) mode change 100644 => 120000 packages/setup-ocaml/README.md delete mode 100644 packages/setup-ocaml/src/depext.ts create mode 100644 packages/setup-ocaml/src/unix.ts delete mode 100644 packages/setup-ocaml/src/win32.ts create mode 100644 packages/setup-ocaml/src/windows.ts diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index c6e85598..8877b7c6 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -49,21 +49,12 @@ jobs: os: - macos-latest - ubuntu-latest + - windows-latest ocaml-compiler: - "5.2" - allow-prerelease-opam: - - false include: - - os: windows-latest - ocaml-compiler: ocaml-variants.5.2.0+options,ocaml-option-mingw - allow-prerelease-opam: false - opam-repositories: | - windows-5.0: https://github.com/dra27/opam-repository.git#windows-5.0 - sunset: https://github.com/ocaml-opam/opam-repository-mingw.git#sunset - default: https://github.com/ocaml/opam-repository.git - os: ubuntu-latest ocaml-compiler: ocaml-variants.5.2.0+options,ocaml-option-flambda - allow-prerelease-opam: true runs-on: ${{ matrix.os }} @@ -75,8 +66,6 @@ jobs: uses: ./ with: ocaml-compiler: ${{ matrix.ocaml-compiler }} - allow-prerelease-opam: ${{ matrix.allow-prerelease-opam }} - dune-cache: ${{ runner.os != 'Windows' }} - opam-repositories: ${{ matrix.opam-repositories }} + allow-prerelease-opam: true - - run: opam depext --install uri + - run: opam install uri diff --git a/CHANGELOG.md b/CHANGELOG.md index ec850c69..74b50b43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ and this project adheres to ## [unreleased] +### Added + +- Add initial support for opam 2.2 on Windows. + ## [2.2.10] ### Changed diff --git a/EXAMPLES.md b/EXAMPLES.md index 7798b252..db75c5ca 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -59,55 +59,6 @@ jobs: uses: actions/deploy-pages@v4 ``` -## Using several conditional setup steps - -```yml -steps: - - name: Checkout tree - uses: actions/checkout@v4 - - - name: Set-up OCaml on Windows - uses: ocaml/setup-ocaml@v2 - if: runner.os == 'Windows' - with: - opam-repositories: | - sunset: https://github.com/ocaml-opam/opam-repository-mingw.git#sunset - default: https://github.com/ocaml/opam-repository.git - - - name: Set-up OCaml on Unix - uses: ocaml/setup-ocaml@v2 - if: runner.os != 'Windows' - with: - opam-repositories: | - default: https://github.com/ocaml/opam-repository.git -``` - -## Using a custom step to choose between the values - -```yml -steps: - - name: Checkout tree - uses: actions/checkout@v4 - - - name: Set opam repository url - id: repository - shell: bash - run: | - if [ "$RUNNER_OS" == "Windows" ]; then - echo "::set-output name=url::https://github.com/ocaml-opam/opam-repository-mingw.git#sunset" - elif [ "$RUNNER_OS" == "macOS" ]; then - echo "::set-output name=url::https://github.com/custom/opam-repository.git#macOS" - else - echo "::set-output name=url::https://github.com/ocaml/opam-repository.git" - fi - - - name: Set-up OCaml with repository ${{ steps.repository.outputs.url }} - uses: ocaml/setup-ocaml@v2 - with: - opam-repositories: | - default: ${{ steps.repository.outputs.url }} -``` - ## Using glob patterns to filter local packages Consult the diff --git a/README.md b/README.md index 83d94d5f..c7dac2d5 100644 --- a/README.md +++ b/README.md @@ -97,18 +97,16 @@ steps: ## Inputs -| Name | Required | Description | Type | Default | -| ------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | -------- | -| `ocaml-compiler` | Yes | The OCaml compiler packages to initialise. Consult the [supported version syntax](#supported-version-syntax) section. | string | | -| `opam-repositories` | No | The name and URL pair of the repository to fetch the packages from. | string | | -| `opam-pin` | No | Enable the automation feature for opam pin. | bool | `true` | -| `opam-depext` | No | Enable the automation feature for opam depext. | bool | `true` | -| `opam-depext-flags` | No | The flags for the opam depext command. The flags must be separated by the comma. | string | | -| `opam-local-packages` | No | The local packages to be used by `opam-pin` or `opam-depext`. Consult the [`@actions/glob` documentation](https://github.com/actions/toolkit/tree/main/packages/glob) package for supported patterns. | string | `*.opam` | -| `opam-disable-sandboxing` | No | Disable the opam sandboxing feature. | bool | `false` | -| `dune-cache` | No | Enable the dune cache feature. This feature **_requires_** dune 2.8.5 or later on the Windows runners. | bool | `false` | -| `cache-prefix` | No | The prefix of the cache keys. | string | `v1` | -| `allow-prerelease-opam` | No | Allow to use a pre-release version of opam. | bool | `false` | +| Name | Required | Description | Type | Default | +| ------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------ | -------- | +| `ocaml-compiler` | Yes | The OCaml compiler packages to initialise. Consult the [supported version syntax](#supported-version-syntax) section. | string | | +| `opam-repositories` | No | The name and URL pair of the repository to fetch the packages from. | string | | +| `opam-pin` | No | Enable the automation feature for opam pin. | bool | `true` | +| `opam-local-packages` | No | The local packages to be used by `opam-pin`. Consult the [`@actions/glob` documentation](https://github.com/actions/toolkit/tree/main/packages/glob) package for supported patterns. | string | `*.opam` | +| `opam-disable-sandboxing` | No | Disable the opam sandboxing feature. | bool | `false` | +| `dune-cache` | No | Enable the dune cache feature. This feature **_requires_** dune 2.8.5 or later on the Windows runners. | bool | `false` | +| `cache-prefix` | No | The prefix of the cache keys. | string | `v1` | +| `allow-prerelease-opam` | No | Allow to use a pre-release version of opam. | bool | `false` | ### Supported version syntax @@ -122,12 +120,11 @@ more detailed examples please refer to the Examples: -- Exact package name: `ocaml-base-compiler.5.2.0`, - `ocaml-variants.4.14.2+mingw64c` +- Exact package name: `ocaml-base-compiler.5.2.0` - Combine multiple packages: `ocaml-variants.5.2.0+options,ocaml-option-flambda,ocaml-option-musl,ocaml-option-static` - Minor versions: `4.08`, `4.14`, `5.2`, `5.2.x` -- More specific versions: `~4.02.2`, `5.1.0`, +- More specific versions: `~4.02.2`, `5.1.0` ## Advanced Configurations diff --git a/action.yml b/action.yml index 28ed311d..d8ad08fe 100644 --- a/action.yml +++ b/action.yml @@ -20,16 +20,8 @@ inputs: description: Enable the automation feature for opam pin. required: false default: "true" - opam-depext: - description: Enable the automation feature for opam depext. - required: false - default: "true" - opam-depext-flags: - description: The flags for the opam depext command. - required: false - default: "" opam-local-packages: - description: The local packages to be used by `opam-pin` or `opam-depext`. + description: The local packages to be used by `opam-pin`. required: false default: "*.opam" opam-disable-sandboxing: diff --git a/analysis/dist/index.js b/analysis/dist/index.js index 980e6d10..2024d4b0 100644 --- a/analysis/dist/index.js +++ b/analysis/dist/index.js @@ -34939,6 +34939,7 @@ function createBuildTarget(output, filePath) { + async function getOpamLocalPackages() { const globber = await glob.create("*.opam"); const fpaths = await globber.glob(); @@ -34957,21 +34958,21 @@ async function analysis() { const { name } = external_node_path_namespaceObject.parse(fpath); await (0,exec.exec)("opam", [ "tree", - name, + `--json=${tempJson}`, "--with-dev-setup", // [NOTE] https://github.com/ocaml/opam/issues/4541 // "--with-doc", "--with-test", - `--json=${tempJson}`, + name, ], { env: { - ...process.env, - PATH: process.env["PATH"] ?? "", + ...external_node_process_namespaceObject.env, + PATH: external_node_process_namespaceObject.env.PATH ?? "", }, silent: true, }); const output = JSON.parse(await promises_namespaceObject.readFile(tempJson, "utf8")); - const githubWorkspace = process.env["GITHUB_WORKSPACE"] ?? process.cwd(); + const githubWorkspace = external_node_process_namespaceObject.env.GITHUB_WORKSPACE ?? external_node_process_namespaceObject.cwd(); const opamPackagePath = external_node_path_namespaceObject.normalize(external_node_path_namespaceObject.relative(githubWorkspace, fpath)); const buildTarget = createBuildTarget(output, opamPackagePath); snapshot.addManifest(buildTarget); @@ -34986,12 +34987,12 @@ async function installOpamPackages() { await core.group("Install opam packages", async () => { await (0,exec.exec)("opam", [ "install", - ".", "--deps-only", "--with-dev-setup", // [NOTE] https://github.com/ocaml/opam/issues/4541 // "--with-doc", "--with-test", + ".", ]); }); } diff --git a/biome.json b/biome.json index ae049bfd..d3bb7f9d 100644 --- a/biome.json +++ b/biome.json @@ -10,10 +10,7 @@ "linter": { "enabled": true, "rules": { - "recommended": true, - "complexity": { - "useLiteralKeys": "off" - } + "recommended": true } }, "organizeImports": { diff --git a/dist/index.js b/dist/index.js index d75be056..f9c3efc7 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1813,7 +1813,7 @@ const fs = __importStar(__nccwpck_require__(7147)); const globOptionsHelper = __importStar(__nccwpck_require__(9303)); const path = __importStar(__nccwpck_require__(1017)); const patternHelper = __importStar(__nccwpck_require__(1361)); -const internal_match_kind_1 = __nccwpck_require__(6839); +const internal_match_kind_1 = __nccwpck_require__(3086); const internal_pattern_1 = __nccwpck_require__(6372); const internal_search_state_1 = __nccwpck_require__(8625); const IS_WINDOWS = process.platform === 'win32'; @@ -1996,7 +1996,7 @@ exports.DefaultGlobber = DefaultGlobber; /***/ }), -/***/ 6839: +/***/ 3086: /***/ ((__unused_webpack_module, exports) => { @@ -2369,7 +2369,7 @@ var __importStar = (this && this.__importStar) || function (mod) { Object.defineProperty(exports, "__esModule", ({ value: true })); exports.partialMatch = exports.match = exports.getSearchPaths = void 0; const pathHelper = __importStar(__nccwpck_require__(8886)); -const internal_match_kind_1 = __nccwpck_require__(6839); +const internal_match_kind_1 = __nccwpck_require__(3086); const IS_WINDOWS = process.platform === 'win32'; /** * Given an array of patterns, returns an array of paths to search. @@ -2476,7 +2476,7 @@ const path = __importStar(__nccwpck_require__(1017)); const pathHelper = __importStar(__nccwpck_require__(8886)); const assert_1 = __importDefault(__nccwpck_require__(9491)); const minimatch_1 = __nccwpck_require__(9566); -const internal_match_kind_1 = __nccwpck_require__(6839); +const internal_match_kind_1 = __nccwpck_require__(3086); const internal_path_1 = __nccwpck_require__(3851); const IS_WINDOWS = process.platform === 'win32'; class Pattern { @@ -91873,10 +91873,10 @@ var external_node_process_ = __nccwpck_require__(7742); var lib_core = __nccwpck_require__(7117); // EXTERNAL MODULE: external "node:os" var external_node_os_ = __nccwpck_require__(612); -;// CONCATENATED MODULE: external "node:path" -const external_node_path_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("node:path"); // EXTERNAL MODULE: ../../node_modules/@actions/exec/lib/exec.js var lib_exec = __nccwpck_require__(6473); +;// CONCATENATED MODULE: external "node:path" +const external_node_path_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("node:path"); // EXTERNAL MODULE: ../../node_modules/@actions/cache/lib/cache.js var cache = __nccwpck_require__(6930); // EXTERNAL MODULE: ../../node_modules/@actions/github/lib/github.js @@ -92580,22 +92580,24 @@ const PLATFORM = (() => { return "macos"; } case "win32": { - return "win32"; + return "windows"; } default: { throw new Error("The platform is not supported."); } } })(); +const CYGWIN_MIRROR = "https://cygwin.mirror.constant.com/"; +// [HACK] https://github.com/ocaml/setup-ocaml/pull/55 const CYGWIN_ROOT = external_node_path_namespaceObject.join("D:", "cygwin"); -const CYGWIN_ROOT_BIN = external_node_path_namespaceObject.join(CYGWIN_ROOT, "bin"); -const CYGWIN_ROOT_WRAPPERBIN = external_node_path_namespaceObject.join(CYGWIN_ROOT, "wrapperbin"); -// [todo] remove the branch for Windows once opam 2.2 is released as stable. -const ALLOW_PRERELEASE_OPAM = PLATFORM !== "win32" && - lib_core.getBooleanInput("allow-prerelease-opam", { - required: false, - trimWhitespace: true, - }); +const OPAM_ROOT = PLATFORM === "windows" + ? // [HACK] https://github.com/ocaml/setup-ocaml/pull/55 + external_node_path_namespaceObject.join("D:", ".opam") + : external_node_path_namespaceObject.join(external_node_os_.homedir(), ".opam"); +const ALLOW_PRERELEASE_OPAM = lib_core.getBooleanInput("allow-prerelease-opam", { + required: false, + trimWhitespace: true, +}); const CACHE_PREFIX = lib_core.getInput("cache-prefix", { required: false, trimWhitespace: true, @@ -92612,17 +92614,14 @@ const OCAML_COMPILER = lib_core.getInput("ocaml-compiler", { required: true, trimWhitespace: true, }); -// [todo] remove this once opam 2.2 is released as stable. -const OPAM_DEPEXT = !ALLOW_PRERELEASE_OPAM && - lib_core.getBooleanInput("opam-depext", { +const OPAM_DISABLE_SANDBOXING = +// [TODO] unlock this once sandboxing is supported on Windows +PLATFORM === "windows" + ? true + : lib_core.getBooleanInput("opam-disable-sandboxing", { required: false, trimWhitespace: true, }); -const OPAM_DEPEXT_FLAGS = lib_core.getInput("opam-depext-flags", { required: false, trimWhitespace: true }) - .split(",") - .map((f) => f.trim()) - .filter((f) => f.length > 0); -const OPAM_DISABLE_SANDBOXING = lib_core.getBooleanInput("opam-disable-sandboxing", { required: false, trimWhitespace: true }); const OPAM_LOCAL_PACKAGES = lib_core.getInput("opam-local-packages", { required: false, trimWhitespace: true, @@ -92631,18 +92630,18 @@ const OPAM_PIN = lib_core.getBooleanInput("opam-pin", { required: false, trimWhitespace: true, }); -const repositories_yaml = dist/* parse */.Qc(lib_core.getInput("opam-repositories", { required: false, trimWhitespace: true })); -const defaultRepository = PLATFORM === "win32" - ? "https://github.com/ocaml-opam/opam-repository-mingw.git#sunset" - : "https://github.com/ocaml/opam-repository.git"; -const OPAM_REPOSITORIES = repositories_yaml - ? Object.entries(repositories_yaml).reverse() - : [["default", defaultRepository]]; +const OPAM_REPOSITORIES = (() => { + const repositories_yaml = dist/* parse */.Qc(lib_core.getInput("opam-repositories", { + required: false, + trimWhitespace: true, + })); + return repositories_yaml + ? Object.entries(repositories_yaml).reverse() + : [["default", "https://github.com/ocaml/opam-repository.git"]]; +})(); ;// CONCATENATED MODULE: external "node:fs" const external_node_fs_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("node:fs"); -// EXTERNAL MODULE: ../../node_modules/@actions/io/lib/io.js -var io = __nccwpck_require__(47); // EXTERNAL MODULE: ../../node_modules/@actions/tool-cache/lib/tool-cache.js var tool_cache = __nccwpck_require__(834); // EXTERNAL MODULE: ../../node_modules/semver/index.js @@ -92670,7 +92669,7 @@ async function getSystemIdentificationInfo() { return { id, version }; } if (PLATFORM === "macos") { - const swVers = await (0,lib_exec.getExecOutput)("sw_vers"); + const swVers = await (0,lib_exec.getExecOutput)("sw_vers", [], { silent: true }); const lines = swVers.stdout.split(external_node_os_.EOL); let version = ""; for (const line of lines) { @@ -92683,8 +92682,41 @@ async function getSystemIdentificationInfo() { } throw new Error("The system is not supported."); } + +;// CONCATENATED MODULE: ./src/unix.ts + + + + +async function installUnixSystemPackages() { + const isGitHubRunner = external_node_process_.env.GITHUB_ACTIONS === "true"; + if (isGitHubRunner) { + if (PLATFORM === "linux") { + const { version: systemVersion } = await getSystemIdentificationInfo(); + if (systemVersion === "18.04") { + // [INFO]: musl-tools bug in ubuntu 18.04 https://github.com/ocaml/ocaml/issues/9131#issuecomment-599765888 + await (0,lib_exec.exec)("sudo", ["add-apt-repository", "ppa:avsm/musl"]); + } + await (0,lib_exec.exec)("sudo", [ + "apt-get", + "--yes", + "install", + "bubblewrap", + "darcs", + "g++-multilib", + "gcc-multilib", + "mercurial", + "musl-tools", + "rsync", + ]); + } + else if (PLATFORM === "macos") { + await (0,lib_exec.exec)("brew", ["install", "darcs", "gpatch", "mercurial"]); + } + } +} async function updateUnixPackageIndexFiles() { - const isGitHubRunner = process.env["GITHUB_ACTIONS"] === "true"; + const isGitHubRunner = external_node_process_.env.GITHUB_ACTIONS === "true"; if (isGitHubRunner) { if (PLATFORM === "linux") { await (0,lib_exec.exec)("sudo", ["apt-get", "update"]); @@ -92695,8 +92727,208 @@ async function updateUnixPackageIndexFiles() { } } +;// CONCATENATED MODULE: ./src/opam.ts + + + + + + + + + +async function getLatestOpamRelease() { + const semverRange = ALLOW_PRERELEASE_OPAM ? "*" : "<2.3.0"; + const octokit = lib_github.getOctokit(constants_GITHUB_TOKEN); + const { data: releases } = await octokit.rest.repos.listReleases({ + owner: "ocaml", + repo: "opam", + }); + const matchedReleases = releases + .filter((release) => semver.satisfies(release.tag_name, semverRange, { + includePrerelease: ALLOW_PRERELEASE_OPAM, + loose: true, + })) + .sort(({ tag_name: v1 }, { tag_name: v2 }) => semver.rcompare(v1, v2, { loose: true })); + const latestRelease = matchedReleases.at(0); + if (!latestRelease) { + throw new Error("Could not retrieve the opam release matching the version constraint"); + } + const matchedAssets = latestRelease.assets.find((asset) => asset.browser_download_url.includes(`${ARCHITECTURE}-${PLATFORM}`)); + if (!matchedAssets) { + throw new Error("Could not find any assets matching the current platform or architecture"); + } + return { + version: latestRelease.tag_name, + browserDownloadUrl: matchedAssets.browser_download_url, + }; +} +async function acquireOpam() { + const { version, browserDownloadUrl } = await getLatestOpamRelease(); + const cachedPath = tool_cache.find("opam", version, ARCHITECTURE); + const opam = PLATFORM !== "windows" ? "opam" : "opam.exe"; + if (cachedPath === "") { + const downloadedPath = await tool_cache.downloadTool(browserDownloadUrl); + lib_core.info(`Acquired ${version} from ${browserDownloadUrl}`); + const cachedPath = await tool_cache.cacheFile(downloadedPath, opam, "opam", version, ARCHITECTURE); + lib_core.info(`Successfully cached opam to ${cachedPath}`); + await external_node_fs_namespaceObject.promises.chmod(external_node_path_namespaceObject.join(cachedPath, opam), 0o755); + lib_core.addPath(cachedPath); + lib_core.info("Added opam to the path"); + } + else { + lib_core.addPath(cachedPath); + lib_core.info("Added cached opam to the path"); + } +} +async function initializeOpam() { + if (PLATFORM !== "windows") { + try { + await installUnixSystemPackages(); + } + catch (error) { + if (error instanceof Error) { + lib_core.notice(`An error has been caught in some system package index files, so the system package index files have been re-synchronised, and the system package installation has been retried: ${error.message.toLocaleLowerCase()}`); + } + await updateUnixPackageIndexFiles(); + await installUnixSystemPackages(); + } + } + const extraOptions = []; + if (PLATFORM === "windows") { + extraOptions.push("--cygwin-local-install"); + extraOptions.push(`--cygwin-location=${CYGWIN_ROOT}`); + } + if (OPAM_DISABLE_SANDBOXING) { + extraOptions.push("--disable-sandboxing"); + } + await (0,lib_exec.exec)("opam", [ + "init", + "--auto-setup", + "--bare", + ...extraOptions, + "--enable-shell-hook", + ]); +} +async function setupOpam() { + await lib_core.group("Install opam", async () => { + await acquireOpam(); + }); + await lib_core.group("Initialise the opam state", async () => { + await initializeOpam(); + }); +} +async function installOcaml(ocamlCompiler) { + await lib_core.group("Install OCaml", async () => { + await (0,lib_exec.exec)("opam", [ + "switch", + "--no-install", + `--packages=${ocamlCompiler}`, + "create", + ".", + ]); + }); +} +async function pin(fpaths) { + await lib_core.group("Pin local packages", async () => { + for (const fpath of fpaths) { + const fname = external_node_path_namespaceObject.basename(fpath, ".opam"); + const dname = external_node_path_namespaceObject.dirname(fpath); + await (0,lib_exec.exec)("opam", ["pin", "--no-action", "add", `${fname}.dev`, "."], { + cwd: dname, + }); + } + }); +} +async function repositoryAdd(name, address) { + await (0,lib_exec.exec)("opam", [ + "repository", + "--all-switches", + "--set-default", + "add", + name, + address, + ]); +} +async function repositoryAddAll(repositories) { + await lib_core.group("Initialise the opam repositories", async () => { + for (const [name, address] of repositories) { + await repositoryAdd(name, address); + } + }); +} +async function repositoryRemove(name) { + await (0,lib_exec.exec)("opam", ["repository", "--all-switches", "remove", name]); +} +async function repositoryList() { + const repositoryList = await (0,lib_exec.getExecOutput)("opam", ["repository", "--all-switches", "--short", "list"], { ignoreReturnCode: true, silent: true }); + if (repositoryList.exitCode === 0) { + return repositoryList.stdout + .split("\n") + .map((repository) => repository.trim()) + .filter((repository) => repository.length > 0); + } + return []; +} +async function repositoryRemoveAll() { + await lib_core.group("Remove the opam repositories", async () => { + const repositories = await repositoryList(); + for (const repository of repositories) { + await repositoryRemove(repository); + } + }); +} + +;// CONCATENATED MODULE: ./src/version.ts + + + + +function isSemverValidRange(semverVersion) { + return semver.validRange(semverVersion, { loose: true }) !== null; +} +async function getAllCompilerVersions() { + const octokit = lib_github.getOctokit(constants_GITHUB_TOKEN); + const { data: packages } = await octokit.rest.repos.getContent({ + owner: "ocaml", + repo: "opam-repository", + path: "packages/ocaml-base-compiler", + }); + const versions = new Set(); + if (Array.isArray(packages)) { + for (const { path: p } of packages) { + const basename = external_node_path_namespaceObject.basename(p); + const version = basename.replace("ocaml-base-compiler.", ""); + const parsed = semver.parse(version, { loose: true }); + if (parsed !== null) { + const { major, minor: _minor, patch } = parsed; + const minor = _minor.toString().length > 1 ? _minor : `0${_minor}`; + const version = `${major}.${minor}.${patch}`; + versions.add(version); + } + } + } + return [...versions]; +} +async function resolveVersion(semverVersion) { + const compilerVersions = await getAllCompilerVersions(); + const matchedFullCompilerVersion = semver.maxSatisfying(compilerVersions, semverVersion, { loose: true }); + if (matchedFullCompilerVersion === null) { + throw new Error(`No OCaml base compiler packages matched the version ${semverVersion} in the opam-repository.`); + } + return matchedFullCompilerVersion; +} +async function resolveCompiler(compiler) { + const resolvedCompiler = isSemverValidRange(compiler) + ? `ocaml-base-compiler.${await resolveVersion(compiler)}` + : compiler; + return resolvedCompiler; +} + // EXTERNAL MODULE: ../../node_modules/@actions/http-client/lib/index.js var lib = __nccwpck_require__(7301); +// EXTERNAL MODULE: ../../node_modules/@actions/io/lib/io.js +var io = __nccwpck_require__(47); ;// CONCATENATED MODULE: ../../node_modules/cheerio/lib/esm/options.js const defaultOpts = { xml: false, @@ -109975,7 +110207,12 @@ const { parseHTML: esm_parseHTML } = static_namespaceObject; */ const { root: esm_root } = static_namespaceObject; //# sourceMappingURL=index.js.map -;// CONCATENATED MODULE: ./src/win32.ts +;// CONCATENATED MODULE: ./src/windows.ts + + + + + @@ -109996,400 +110233,44 @@ async function getCygwinVersion() { }); return version; } - -;// CONCATENATED MODULE: ./src/opam.ts - - - - - - - - - - - - - - -async function getLatestOpamRelease() { - const semverRange = ALLOW_PRERELEASE_OPAM ? "*" : "<2.2.0"; - const octokit = lib_github.getOctokit(constants_GITHUB_TOKEN); - const { data: releases } = await octokit.rest.repos.listReleases({ - owner: "ocaml", - repo: "opam", - }); - const matchedReleases = releases - .filter((release) => semver.satisfies(release.tag_name, semverRange, { - includePrerelease: ALLOW_PRERELEASE_OPAM, - loose: true, - })) - .sort(({ tag_name: v1 }, { tag_name: v2 }) => semver.rcompare(v1, v2, { loose: true })); - const latestRelease = matchedReleases.at(0); - if (!latestRelease) { - throw new Error("Could not retrieve the opam release matching the version constraint"); - } - const matchedAssets = latestRelease.assets.find((asset) => asset.browser_download_url.includes(`${ARCHITECTURE}-${PLATFORM}`)); - if (!matchedAssets) { - throw new Error("Could not find any assets matching the current platform or architecture"); - } - return { - version: latestRelease.tag_name, - browserDownloadUrl: matchedAssets.browser_download_url, - }; -} -async function findOpam() { - if (PLATFORM === "win32") { - const opamPath = external_node_path_namespaceObject.join(CYGWIN_ROOT, "bin", "opam.exe"); - return opamPath; - } - const opamPath = await io.which("opam"); - return opamPath; -} -async function acquireOpamUnix() { - const { version, browserDownloadUrl } = await getLatestOpamRelease(); - const cachedPath = tool_cache.find("opam", version, ARCHITECTURE); - if (cachedPath === "") { - const downloadedPath = await tool_cache.downloadTool(browserDownloadUrl); - lib_core.info(`Acquired ${version} from ${browserDownloadUrl}`); - const cachedPath = await tool_cache.cacheFile(downloadedPath, "opam", "opam", version, ARCHITECTURE); - lib_core.info(`Successfully cached opam to ${cachedPath}`); - await external_node_fs_namespaceObject.promises.chmod(`${cachedPath}/opam`, 0o755); - lib_core.addPath(cachedPath); - lib_core.info("Added opam to the path"); - } - else { - lib_core.addPath(cachedPath); - lib_core.info("Added cached opam to the path"); - } -} -async function installUnixSystemPackages() { - const isGitHubRunner = external_node_process_.env.GITHUB_ACTIONS === "true"; - if (isGitHubRunner) { - if (PLATFORM === "linux") { - const { version: systemVersion } = await getSystemIdentificationInfo(); - if (systemVersion === "18.04") { - // [info]: musl-tools bug in ubuntu 18.04; - // - await (0,lib_exec.exec)("sudo", ["add-apt-repository", "ppa:avsm/musl"]); - } - await (0,lib_exec.exec)("sudo", [ - "apt-get", - "--yes", - "install", - "bubblewrap", - "darcs", - "g++-multilib", - "gcc-multilib", - "mercurial", - "musl-tools", - "rsync", - ]); - } - else if (PLATFORM === "macos") { - await (0,lib_exec.exec)("brew", ["install", "darcs", "gpatch", "mercurial"]); - } - } -} -async function initializeOpamUnix() { - try { - await installUnixSystemPackages(); - } - catch (error) { - if (error instanceof Error) { - lib_core.notice(`An error has been caught in some system package index files, so the system package index files have been re-synchronised, and the system package installation has been retried: ${error.message.toLocaleLowerCase()}`); - } - await updateUnixPackageIndexFiles(); - await installUnixSystemPackages(); - } - const disableSandboxing = []; - if (OPAM_DISABLE_SANDBOXING) { - disableSandboxing.push("--disable-sandboxing"); - } - await (0,lib_exec.exec)("opam", [ - "init", - "--auto-setup", - "--bare", - ...disableSandboxing, - "--enable-shell-hook", - ]); -} -async function setupOpamUnix() { - await lib_core.group("Install opam", async () => { - await acquireOpamUnix(); - }); - await lib_core.group("Initialise the opam state", async () => { - await initializeOpamUnix(); - }); -} async function setupCygwin() { - const version = await getCygwinVersion(); - const cachedPath = tool_cache.find("cygwin", version, "x86_64"); - if (cachedPath === "") { - const downloadedPath = await tool_cache.downloadTool("https://cygwin.com/setup-x86_64.exe"); - const cachedPath = await tool_cache.cacheFile(downloadedPath, "setup-x86_64.exe", "cygwin", version, "x86_64"); - lib_core.addPath(cachedPath); - } - else { - lib_core.addPath(cachedPath); - } - const site = "https://mirrors.kernel.org/sourceware/cygwin"; - const packages = [ - "curl", - "diffutils", - "m4", - "make", - "mingw64-i686-gcc-core", - "mingw64-i686-gcc-g++", - "mingw64-x86_64-gcc-core", - "mingw64-x86_64-gcc-g++", - "patch", - "perl", - "rsync", - "unzip", - ].join(","); - await (0,lib_exec.exec)("setup-x86_64.exe", [ - "--quiet-mode", - "--root", - CYGWIN_ROOT, - "--site", - site, - "--packages", - packages, - "--symlink-type=sys", - ]); - const setupExePath = await io.which("setup-x86_64.exe"); - await io.cp(setupExePath, CYGWIN_ROOT); -} -async function acquireOpamWindows() { - const opamVersion = "0.0.0.2"; - const cachedPath = tool_cache.find("opam", opamVersion); - if (cachedPath === "") { - const downloadedPath = await tool_cache.downloadTool(`https://github.com/fdopen/opam-repository-mingw/releases/download/${opamVersion}/opam64.zip`); - const extractedPath = await tool_cache.extractZip(downloadedPath); - const cachedPath = await tool_cache.cacheDir(extractedPath, "opam", opamVersion); - const installSh = external_node_path_namespaceObject.join(cachedPath, "opam64", "install.sh"); - await external_node_fs_namespaceObject.promises.chmod(installSh, 0o755); - await (0,lib_exec.exec)("bash", [installSh, "--prefix", "/usr"]); - } - else { - const installSh = external_node_path_namespaceObject.join(cachedPath, "opam64", "install.sh"); - await external_node_fs_namespaceObject.promises.chmod(installSh, 0o755); - await (0,lib_exec.exec)("bash", [installSh, "--prefix", "/usr"]); - } -} -async function initializeOpamWindows() { - await (0,lib_exec.exec)("git", ["config", "--global", "--add", "safe.directory", "'*'"]); - await (0,lib_exec.exec)("opam", [ - "init", - "--auto-setup", - "--bare", - "--disable-sandboxing", - "--enable-shell-hook", - ]); - await io.mkdirP(CYGWIN_ROOT_WRAPPERBIN); - const opamCmd = external_node_path_namespaceObject.join(CYGWIN_ROOT_WRAPPERBIN, "opam.cmd"); - const data = [ - "@setlocal", - "@echo off", - "set PATH=%CYGWIN_ROOT_BIN%;%PATH%", - "ocaml-env exec -- opam.exe %*", - ].join(external_node_os_.EOL); - await external_node_fs_namespaceObject.promises.writeFile(opamCmd, data, { mode: 0o755 }); -} -async function setupOpamWindows() { await lib_core.group("Prepare the Cygwin environment", async () => { - lib_core.exportVariable("CYGWIN", "winsymlinks:native"); - lib_core.exportVariable("CYGWIN_ROOT", CYGWIN_ROOT); - lib_core.exportVariable("CYGWIN_ROOT_BIN", CYGWIN_ROOT_BIN); - lib_core.exportVariable("CYGWIN_ROOT_WRAPPERBIN", CYGWIN_ROOT_WRAPPERBIN); - lib_core.addPath(CYGWIN_ROOT_WRAPPERBIN); - await setupCygwin(); - }); - await saveCygwinCache(); - const originalPath = external_node_process_.env.PATH?.split(external_node_path_namespaceObject.delimiter) ?? []; - const patchedPath = [CYGWIN_ROOT_BIN, ...originalPath]; - external_node_process_.env.PATH = patchedPath.join(external_node_path_namespaceObject.delimiter); - await lib_core.group("Install opam", async () => { - await acquireOpamWindows(); - }); - await lib_core.group("Initialise the opam state", async () => { - await initializeOpamWindows(); - }); - external_node_process_.env.PATH = originalPath.join(external_node_path_namespaceObject.delimiter); -} -async function setupOpam() { - if (PLATFORM === "win32") { - await setupOpamWindows(); - } - else { - await setupOpamUnix(); - } -} -async function installOcaml(ocamlCompiler) { - await lib_core.group("Install OCaml", async () => { - if (PLATFORM === "win32") { - const originalPath = external_node_process_.env.PATH?.split(external_node_path_namespaceObject.delimiter) ?? []; - const patchedPath = [CYGWIN_ROOT_BIN, ...originalPath]; - external_node_process_.env.PATH = patchedPath.join(external_node_path_namespaceObject.delimiter); - await (0,lib_exec.exec)("opam", [ - "switch", - "create", - ".", - "--no-install", - "--packages", - ocamlCompiler, - ]); - external_node_process_.env.PATH = originalPath.join(external_node_path_namespaceObject.delimiter); + const version = await getCygwinVersion(); + const cachedPath = tool_cache.find("cygwin", version, "x86_64"); + if (cachedPath === "") { + const downloadedPath = await tool_cache.downloadTool("https://cygwin.com/setup-x86_64.exe"); + const cachedPath = await tool_cache.cacheFile(downloadedPath, "setup-x86_64.exe", "cygwin", version, "x86_64"); + lib_core.addPath(cachedPath); } else { - await (0,lib_exec.exec)("opam", [ - "switch", - "create", - ".", - "--no-install", - "--packages", - ocamlCompiler, - ]); - } - }); -} -async function pin(fpaths) { - await lib_core.group("Pin local packages", async () => { - const opam = await findOpam(); - for (const fpath of fpaths) { - const fname = external_node_path_namespaceObject.basename(fpath, ".opam"); - const dname = external_node_path_namespaceObject.dirname(fpath); - await (0,lib_exec.exec)(opam, ["pin", "add", `${fname}.dev`, ".", "--no-action"], { - cwd: dname, - }); - } - }); -} -async function repositoryAdd(name, address) { - const opam = await findOpam(); - await (0,lib_exec.exec)(opam, [ - "repository", - "add", - name, - address, - "--all-switches", - "--set-default", - ]); -} -async function repositoryAddAll(repositories) { - await lib_core.group("Initialise the opam repositories", async () => { - let restore_autocrlf = undefined; - // Works around the lack of https://github.com/ocaml/opam/pull/3882 when - // adding ocaml/opam-repository on Windows. Can be removed when the action - // switches to opam 2.2 - if (PLATFORM === "win32") { - const autocrlf = await (0,lib_exec.getExecOutput)("git", ["config", "--global", "core.autocrlf"], { ignoreReturnCode: true }); - if (autocrlf.stdout.trim() !== "input") { - if (autocrlf.exitCode === 0) { - restore_autocrlf = autocrlf.stdout.trim(); - } - else { - restore_autocrlf = null; // Unset the value at the end - } - } - await (0,lib_exec.exec)("git", ["config", "--global", "core.autocrlf", "input"]); - } - for (const [name, address] of repositories) { - await repositoryAdd(name, address); - } - if (restore_autocrlf === null) { - await (0,lib_exec.exec)("git", ["config", "--global", "--unset", "core.autocrlf"]); - } - else if (restore_autocrlf !== undefined) { - await (0,lib_exec.exec)("git", [ - "config", - "--global", - "core.autocrlf", - restore_autocrlf, - ]); - } - }); -} -async function repositoryRemove(name) { - const opam = await findOpam(); - await (0,lib_exec.exec)(opam, ["repository", "remove", name, "--all-switches"]); -} -async function repositoryList() { - const opam = await findOpam(); - const repositoryList = await (0,lib_exec.getExecOutput)(opam, ["repository", "list", "--all-switches", "--short"], { ignoreReturnCode: true }); - if (repositoryList.exitCode === 0) { - return repositoryList.stdout - .split("\n") - .map((repository) => repository.trim()) - .filter((repository) => repository.length > 0); - } - return []; -} -async function repositoryRemoveAll() { - await lib_core.group("Remove the opam repositories", async () => { - const repositories = await repositoryList(); - for (const repository of repositories) { - await repositoryRemove(repository); - } + lib_core.addPath(cachedPath); + } + const packages = [ + "curl", + "diffutils", + "m4", + "make", + "mingw64-i686-gcc-core", + "mingw64-i686-gcc-g++", + "mingw64-x86_64-gcc-core", + "mingw64-x86_64-gcc-g++", + "patch", + "perl", + "rsync", + "unzip", + ].join(","); + await (0,lib_exec.exec)("setup-x86_64", [ + `--packages=${packages}`, + "--quiet-mode", + `--root=${CYGWIN_ROOT}`, + `--site=${CYGWIN_MIRROR}`, + "--symlink-type=sys", + ]); + const setup = await io.which("setup-x86_64"); + await io.cp(setup, CYGWIN_ROOT); }); } -;// CONCATENATED MODULE: ./src/version.ts - - - - -function isSemverValidRange(semverVersion) { - const isValidSemver = semver.validRange(semverVersion, { loose: true }) !== null; - // [NOTE] explicitly deny compilers like "4.14.0+mingw64c" as invalid semver - // syntax even though it's valid... - const plus = !semverVersion.includes("+"); - return isValidSemver && plus; -} -async function getAllCompilerVersions() { - const octokit = lib_github.getOctokit(constants_GITHUB_TOKEN); - const owner = PLATFORM === "win32" ? "ocaml-opam" : "ocaml"; - const repo = PLATFORM === "win32" ? "opam-repository-mingw" : "opam-repository"; - const prefix = PLATFORM === "win32" ? "ocaml-variants" : "ocaml-base-compiler"; - const { data: packages } = await octokit.rest.repos.getContent({ - owner, - repo, - path: `packages/${prefix}`, - }); - const versions = new Set(); - if (Array.isArray(packages)) { - for (const { path: p } of packages) { - const basename = external_node_path_namespaceObject.basename(p); - const version = basename.replace(`${prefix}.`, ""); - const parsed = semver.parse(version, { loose: true }); - if (parsed !== null) { - const { major, minor: _minor, patch } = parsed; - const minor = _minor.toString().length > 1 ? _minor : `0${_minor}`; - const version = `${major}.${minor}.${patch}`; - versions.add(version); - } - } - } - return [...versions]; -} -async function resolveVersion(semverVersion) { - const compilerVersions = await getAllCompilerVersions(); - const matchedFullCompilerVersion = semver.maxSatisfying(compilerVersions, semverVersion, { loose: true }); - if (matchedFullCompilerVersion === null) { - throw new Error(`No OCaml base compiler packages matched the version ${semverVersion} in the opam-repository.`); - } - return matchedFullCompilerVersion; -} -async function resolveCompiler(compiler) { - const resolvedCompiler = isSemverValidRange(compiler) - ? PLATFORM === "win32" - ? `ocaml-variants.${await resolveVersion(compiler)}+mingw64c` - : `ocaml-base-compiler.${await resolveVersion(compiler)}` - : compiler; - return resolvedCompiler; -} - ;// CONCATENATED MODULE: ./src/cache.ts @@ -110414,15 +110295,8 @@ function composeDate() { } async function composeCygwinCacheKeys() { const cygwinVersion = await getCygwinVersion(); - // Bump cygwinEpoch when a new release requires the existing Cygwin caches to - // be invalidated. - const cygwinEpoch = "1"; - const { year, week } = composeDate(); - const key = `${CACHE_PREFIX}-setup-ocaml-cygwin-${cygwinEpoch}-${cygwinVersion}-${year}-${week}`; - const restoreKeys = [ - `${CACHE_PREFIX}-setup-ocaml-cygwin-${cygwinEpoch}-${cygwinVersion}-${year}-${week}`, - `${CACHE_PREFIX}-setup-ocaml-cygwin-${cygwinEpoch}-${cygwinVersion}-${year}-`, - ]; + const key = `${CACHE_PREFIX}-setup-ocaml-cygwin-${cygwinVersion}`; + const restoreKeys = [key]; return { key, restoreKeys }; } function composeDuneCacheKeys() { @@ -110441,10 +110315,10 @@ function composeDuneCacheKeys() { return { key, restoreKeys }; } async function composeOpamCacheKeys() { - const fullPlatform = PLATFORM === "win32" + const fullPlatform = PLATFORM === "windows" ? PLATFORM : `${PLATFORM}-${(await getSystemIdentificationInfo()).version}`; - const opamVersion = PLATFORM === "win32" ? "0.0.0.2" : (await getLatestOpamRelease()).version; + const { version: opamVersion } = await getLatestOpamRelease(); const ocamlCompiler = await resolveCompiler(OCAML_COMPILER); const ocamlVersion = ocamlCompiler.toLowerCase().replaceAll(/\W/g, "_"); const sandboxed = OPAM_DISABLE_SANDBOXING ? "nosandbox" : "sandbox"; @@ -110457,37 +110331,13 @@ async function composeOpamCacheKeys() { ]; return { key, restoreKeys }; } -function composeOpamDownloadCacheKeys() { - const repositories = OPAM_REPOSITORIES.map(([, u]) => { - try { - const url = new URL(u); - const urn = external_node_path_namespaceObject.join(url.hostname, url.pathname); - return urn; - } - catch { - return external_node_path_namespaceObject.resolve(u); - } - }).join("_"); - const ocamlVersion = OCAML_COMPILER.toLowerCase().replaceAll(/\W/g, "_"); - const { year, month, date } = composeDate(); - const { runId, runNumber } = lib_github.context; - const key = `${CACHE_PREFIX}-setup-ocaml-opam-download-${repositories}-${ocamlVersion}-${year}-${month}-${date}-${runId}-${runNumber}`; - const restoreKeys = [ - `${CACHE_PREFIX}-setup-ocaml-opam-download-${repositories}-${ocamlVersion}-${year}-${month}-${date}-${runId}-${runNumber}`, - `${CACHE_PREFIX}-setup-ocaml-opam-download-${repositories}-${ocamlVersion}-${year}-${month}-${date}-${runId}-`, - `${CACHE_PREFIX}-setup-ocaml-opam-download-${repositories}-${ocamlVersion}-${year}-${month}-${date}-`, - `${CACHE_PREFIX}-setup-ocaml-opam-download-${repositories}-${ocamlVersion}-${year}-${month}-`, - ]; - return { key, restoreKeys }; -} function composeCygwinCachePaths() { const paths = []; const githubWorkspace = external_node_process_.env.GITHUB_WORKSPACE ?? external_node_process_.cwd(); - const cygwinRoot = external_node_path_namespaceObject.join("D:", "cygwin"); - paths.push(cygwinRoot); + paths.push(CYGWIN_ROOT); const cygwinRootSymlinkPath = external_node_path_namespaceObject.posix.join("/cygdrive", "d", "cygwin"); paths.push(cygwinRootSymlinkPath); - const cygwinEncodedUri = encodeURIComponent("https://mirrors.kernel.org/sourceware/cygwin/").toLowerCase(); + const cygwinEncodedUri = encodeURIComponent(CYGWIN_MIRROR).toLowerCase(); const cygwinPackageRoot = external_node_path_namespaceObject.join(githubWorkspace, cygwinEncodedUri); paths.push(cygwinPackageRoot); return paths; @@ -110495,7 +110345,7 @@ function composeCygwinCachePaths() { function composeDuneCachePaths() { const paths = []; const homeDir = external_node_os_.homedir(); - if (PLATFORM === "win32") { + if (PLATFORM === "windows") { const duneCacheDir = external_node_path_namespaceObject.join(homeDir, "Local Settings", "Cache", "dune"); paths.push(duneCacheDir); } @@ -110509,48 +110359,45 @@ function composeDuneCachePaths() { return paths; } function composeOpamCachePaths() { - const paths = []; - if (PLATFORM === "win32") { - const opamRootCachePath = external_node_path_namespaceObject.join("D:", ".opam"); - paths.push(opamRootCachePath); + const paths = [OPAM_ROOT]; + if (PLATFORM === "windows") { const { repo: { repo }, } = lib_github.context; const opamCygwinLocalCachePath = external_node_path_namespaceObject.posix.join("/cygdrive", "d", "a", repo, repo, "_opam"); paths.push(opamCygwinLocalCachePath); } - else { - const homeDir = external_node_os_.homedir(); - const opamRootCachePath = external_node_path_namespaceObject.join(homeDir, ".opam"); - paths.push(opamRootCachePath); - } const githubWorkspace = external_node_process_.env.GITHUB_WORKSPACE ?? external_node_process_.cwd(); const opamLocalCachePath = external_node_path_namespaceObject.join(githubWorkspace, "_opam"); paths.push(opamLocalCachePath); return paths; } -function composeOpamDownloadCachePaths() { - const paths = []; - if (PLATFORM === "win32") { - const opamDownloadCachePath = external_node_path_namespaceObject.join("D:", ".opam", "download-cache"); - paths.push(opamDownloadCachePath); - } - else { - const homeDir = external_node_os_.homedir(); - const opamDownloadCachePath = external_node_path_namespaceObject.join(homeDir, ".opam", "download-cache"); - paths.push(opamDownloadCachePath); - } - return paths; -} async function restoreCache(key, restoreKeys, paths) { - const cacheKey = await cache.restoreCache(paths, key, restoreKeys); - if (cacheKey) { - lib_core.info(`Cache restored from key: ${cacheKey}`); + if (!cache.isFeatureAvailable()) { + lib_core.info("Actions cache service feature is unavailable"); + return; } - else { - lib_core.info(`Cache not found for input keys: ${[key, ...restoreKeys].join(", ")}`); + try { + const cacheKey = await cache.restoreCache(paths, key, restoreKeys); + if (cacheKey) { + lib_core.info(`Cache restored from key: ${cacheKey}`); + } + else { + lib_core.info(`Cache not found for input keys: ${[key, ...restoreKeys].join(", ")}`); + } + return cacheKey; + } + catch (error) { + if (error instanceof Error) { + lib_core.info(error.message); + } + lib_core.warning("An internal error has occurred in cache backend. Please check https://www.githubstatus.com for any ongoing issue in actions."); + return; } - return cacheKey; } async function saveCache(key, paths) { + if (!cache.isFeatureAvailable()) { + lib_core.info("Actions cache service feature is unavailable"); + return; + } try { await cache.saveCache(paths, key); } @@ -110558,13 +110405,15 @@ async function saveCache(key, paths) { if (error instanceof Error) { lib_core.info(error.message); } + lib_core.warning("An internal error has occurred in cache backend. Please check https://www.githubstatus.com for any ongoing issue in actions."); } } async function restoreCygwinCache() { - await lib_core.group("Retrieve the Cygwin cache", async () => { + return await lib_core.group("Retrieve the Cygwin cache", async () => { const { key, restoreKeys } = await composeCygwinCacheKeys(); const paths = composeCygwinCachePaths(); - await restoreCache(key, restoreKeys, paths); + const cacheKey = await restoreCache(key, restoreKeys, paths); + return cacheKey; }); } async function saveCygwinCache() { @@ -110575,10 +110424,11 @@ async function saveCygwinCache() { }); } async function restoreDuneCache() { - await lib_core.group("Retrieve the dune cache", async () => { + return await lib_core.group("Retrieve the dune cache", async () => { const { key, restoreKeys } = composeDuneCacheKeys(); const paths = composeDuneCachePaths(); - await restoreCache(key, restoreKeys, paths); + const cacheKey = await restoreCache(key, restoreKeys, paths); + return cacheKey; }); } async function saveDuneCache() { @@ -110611,49 +110461,6 @@ async function saveOpamCache() { await saveCache(key, paths); }); } -async function restoreOpamDownloadCache() { - return await lib_core.group("Retrieve the opam download cache", async () => { - const { key, restoreKeys } = composeOpamDownloadCacheKeys(); - const paths = composeOpamDownloadCachePaths(); - const cacheKey = await restoreCache(key, restoreKeys, paths); - return cacheKey; - }); -} -async function saveOpamDownloadCache() { - await core.group("Save the opam download cache", async () => { - const { key } = composeOpamDownloadCacheKeys(); - const paths = composeOpamDownloadCachePaths(); - await saveCache(key, paths); - }); -} - -;// CONCATENATED MODULE: ./src/depext.ts - - - - -async function installDepext(ocamlVersion) { - await lib_core.group("Install depext", async () => { - const depextCygwinports = PLATFORM === "win32" ? ["depext-cygwinports"] : []; - await (0,lib_exec.exec)("opam", ["install", "opam-depext", ...depextCygwinports]); - if (PLATFORM === "win32") { - let base = ""; - if (ocamlVersion.includes("mingw64")) { - base = "x86_64-w64-mingw32"; - } - else if (ocamlVersion.includes("mingw32")) { - base = "i686-w64-mingw32"; - } - lib_core.addPath(external_node_path_namespaceObject.posix.join("/", "usr", base, "sys-root", "mingw", "bin")); - } - }); -} -async function installDepextPackages(fpaths) { - await lib_core.group("Install system packages required by opam packages", async () => { - const fnames = fpaths.map((fpath) => external_node_path_namespaceObject.basename(fpath, ".opam")); - await (0,lib_exec.exec)("opam", ["depext", ...fnames, ...OPAM_DEPEXT_FLAGS]); - }); -} ;// CONCATENATED MODULE: ./src/dune.ts @@ -110663,12 +110470,7 @@ async function installDepextPackages(fpaths) { const { repo: { owner, repo }, runId: run_id, } = lib_github.context; async function installDune() { await lib_core.group("Install dune", async () => { - if (OPAM_DEPEXT) { - await (0,lib_exec.exec)("opam", ["depext", "--install", "dune"]); - } - else { - await (0,lib_exec.exec)("opam", ["install", "dune"]); - } + await (0,lib_exec.exec)("opam", ["install", "dune"]); }); } async function trimDuneCache() { @@ -110686,8 +110488,7 @@ async function trimDuneCache() { "dune", "cache", "trim", - "--size", - `${cacheSize}MB`, + `--size=${cacheSize}MB`, ]); }); } @@ -110715,36 +110516,24 @@ async function getOpamLocalPackages() { - - async function installer() { if (lib_core.isDebug()) { lib_core.exportVariable("OPAMVERBOSE", 1); } - if (ALLOW_PRERELEASE_OPAM) { - lib_core.exportVariable("OPAMCONFIRMLEVEL", "unsafe-yes"); - } - else { - // [todo] remove this once opam 2.2 is released as stable. - // https://github.com/ocaml/setup-ocaml/issues/299 - lib_core.exportVariable("OPAMCLI", "2.0"); - } lib_core.exportVariable("OPAMCOLOR", "always"); + lib_core.exportVariable("OPAMCONFIRMLEVEL", "unsafe-yes"); + lib_core.exportVariable("OPAMDOWNLOADJOBS", external_node_os_.cpus().length * 2); lib_core.exportVariable("OPAMERRLOGLEN", 0); - lib_core.exportVariable("OPAMJOBS", external_node_os_.cpus().length); lib_core.exportVariable("OPAMPRECISETRACKING", 1); - // [todo] remove this once opam 2.2 is released as stable. - // https://github.com/ocaml/opam/issues/3447 - lib_core.exportVariable("OPAMSOLVERTIMEOUT", 1000); + lib_core.exportVariable("OPAMROOT", OPAM_ROOT); lib_core.exportVariable("OPAMYES", 1); - if (PLATFORM === "win32") { - const opamRoot = external_node_path_namespaceObject.join("D:", ".opam"); - lib_core.exportVariable("OPAMROOT", opamRoot); - } - if (PLATFORM === "win32") { + if (PLATFORM === "windows") { + lib_core.exportVariable("CYGWIN", "winsymlinks:native"); + lib_core.exportVariable("HOME", external_node_process_.env.USERPROFILE); + lib_core.exportVariable("MSYS", "winsymlinks:native"); await lib_core.group("Change the file system behavior parameters", async () => { await (0,lib_exec.exec)("fsutil", ["behavior", "query", "SymlinkEvaluation"]); - // https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/fsutil-behavior + // [INFO] https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/fsutil-behavior await (0,lib_exec.exec)("fsutil", [ "behavior", "set", @@ -110754,13 +110543,11 @@ async function installer() { ]); await (0,lib_exec.exec)("fsutil", ["behavior", "query", "SymlinkEvaluation"]); }); - } - if (PLATFORM === "win32") { - lib_core.exportVariable("HOME", external_node_process_.env.USERPROFILE); - lib_core.exportVariable("MSYS", "winsymlinks:native"); - } - if (PLATFORM === "win32") { - await restoreCygwinCache(); + const cygwinCacheHit = await restoreCygwinCache(); + if (!cygwinCacheHit) { + await setupCygwin(); + await saveCygwinCache(); + } } const opamCacheHit = await restoreOpamCache(); await setupOpam(); @@ -110771,10 +110558,6 @@ async function installer() { await installOcaml(ocamlCompiler); await saveOpamCache(); } - await restoreOpamDownloadCache(); - if (OPAM_DEPEXT) { - await installDepext(ocamlCompiler); - } if (DUNE_CACHE) { await restoreDuneCache(); await installDune(); @@ -110788,23 +110571,8 @@ async function installer() { if (OPAM_PIN) { await pin(fnames); } - if (OPAM_DEPEXT) { - try { - await installDepextPackages(fnames); - } - catch (error) { - if (error instanceof Error) { - lib_core.notice(`An error has been caught in some system package index files, so the system package index files have been re-synchronised, and the system package installation has been retried: ${error.message.toLocaleLowerCase()}`); - } - await updateUnixPackageIndexFiles(); - await installDepextPackages(fnames); - } - } } await (0,lib_exec.exec)("opam", ["--version"]); - if (OPAM_DEPEXT) { - await (0,lib_exec.exec)("opam", ["depext", "--version"]); - } await (0,lib_exec.exec)("opam", ["exec", "--", "ocaml", "-version"]); } diff --git a/dist/post/LICENSE.txt b/dist/post/LICENSE.txt index e104a378..f9e6f2b3 100644 --- a/dist/post/LICENSE.txt +++ b/dist/post/LICENSE.txt @@ -876,31 +876,6 @@ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -date-fns -MIT -MIT License - -Copyright (c) 2021 Sasha Koss and Lesha Koss https://kossnocorp.mit-license.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - debug MIT (The MIT License) diff --git a/dist/post/index.js b/dist/post/index.js index 81310885..3d77ca75 100644 --- a/dist/post/index.js +++ b/dist/post/index.js @@ -61995,7 +61995,7 @@ module.exports = { const { Transform } = __nccwpck_require__(2781) -const { Console } = __nccwpck_require__(6206) +const { Console } = __nccwpck_require__(1807) /** * Gets the output of `console.table(…)` as a string. @@ -65542,7 +65542,7 @@ module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("child_proces /***/ }), -/***/ 6206: +/***/ 1807: /***/ ((module) => { module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("console"); @@ -66326,7 +66326,7 @@ exports.decodeStringToString = decodeStringToString; /***/ }), -/***/ 4609: +/***/ 7692: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { @@ -66606,7 +66606,7 @@ Object.defineProperty(exports, "createClientPipeline", ({ enumerable: true, get: var interfaces_js_1 = __nccwpck_require__(7154); Object.defineProperty(exports, "XML_ATTRKEY", ({ enumerable: true, get: function () { return interfaces_js_1.XML_ATTRKEY; } })); Object.defineProperty(exports, "XML_CHARKEY", ({ enumerable: true, get: function () { return interfaces_js_1.XML_CHARKEY; } })); -var deserializationPolicy_js_1 = __nccwpck_require__(4609); +var deserializationPolicy_js_1 = __nccwpck_require__(7692); Object.defineProperty(exports, "deserializationPolicy", ({ enumerable: true, get: function () { return deserializationPolicy_js_1.deserializationPolicy; } })); Object.defineProperty(exports, "deserializationPolicyName", ({ enumerable: true, get: function () { return deserializationPolicy_js_1.deserializationPolicyName; } })); var serializationPolicy_js_1 = __nccwpck_require__(8912); @@ -66817,7 +66817,7 @@ exports.getOperationRequestInfo = getOperationRequestInfo; // Licensed under the MIT license. Object.defineProperty(exports, "__esModule", ({ value: true })); exports.createClientPipeline = void 0; -const deserializationPolicy_js_1 = __nccwpck_require__(4609); +const deserializationPolicy_js_1 = __nccwpck_require__(7692); const core_rest_pipeline_1 = __nccwpck_require__(1547); const serializationPolicy_js_1 = __nccwpck_require__(8912); /** @@ -84685,676 +84685,6 @@ var lib_cache = __nccwpck_require__(6930); var lib_exec = __nccwpck_require__(6473); // EXTERNAL MODULE: ../../node_modules/@actions/github/lib/github.js var lib_github = __nccwpck_require__(4005); -;// CONCATENATED MODULE: ../../node_modules/date-fns/toDate.mjs -/** - * @name toDate - * @category Common Helpers - * @summary Convert the given argument to an instance of Date. - * - * @description - * Convert the given argument to an instance of Date. - * - * If the argument is an instance of Date, the function returns its clone. - * - * If the argument is a number, it is treated as a timestamp. - * - * If the argument is none of the above, the function returns Invalid Date. - * - * **Note**: *all* Date arguments passed to any *date-fns* function is processed by `toDate`. - * - * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc). - * - * @param argument - The value to convert - * - * @returns The parsed date in the local time zone - * - * @example - * // Clone the date: - * const result = toDate(new Date(2014, 1, 11, 11, 30, 30)) - * //=> Tue Feb 11 2014 11:30:30 - * - * @example - * // Convert the timestamp to date: - * const result = toDate(1392098430000) - * //=> Tue Feb 11 2014 11:30:30 - */ -function toDate(argument) { - const argStr = Object.prototype.toString.call(argument); - - // Clone the date - if ( - argument instanceof Date || - (typeof argument === "object" && argStr === "[object Date]") - ) { - // Prevent the date to lose the milliseconds when passed to new Date() in IE10 - return new argument.constructor(+argument); - } else if ( - typeof argument === "number" || - argStr === "[object Number]" || - typeof argument === "string" || - argStr === "[object String]" - ) { - // TODO: Can we get rid of as? - return new Date(argument); - } else { - // TODO: Can we get rid of as? - return new Date(NaN); - } -} - -// Fallback for modularized imports: -/* harmony default export */ const date_fns_toDate = ((/* unused pure expression or super */ null && (toDate))); - -;// CONCATENATED MODULE: ../../node_modules/date-fns/getYear.mjs - - -/** - * @name getYear - * @category Year Helpers - * @summary Get the year of the given date. - * - * @description - * Get the year of the given date. - * - * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc). - * - * @param date - The given date - * - * @returns The year - * - * @example - * // Which year is 2 July 2014? - * const result = getYear(new Date(2014, 6, 2)) - * //=> 2014 - */ -function getYear(date) { - return toDate(date).getFullYear(); -} - -// Fallback for modularized imports: -/* harmony default export */ const date_fns_getYear = ((/* unused pure expression or super */ null && (getYear))); - -;// CONCATENATED MODULE: ../../node_modules/date-fns/getMonth.mjs - - -/** - * @name getMonth - * @category Month Helpers - * @summary Get the month of the given date. - * - * @description - * Get the month of the given date. - * - * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc). - * - * @param date - The given date - * - * @returns The month index (0-11) - * - * @example - * // Which month is 29 February 2012? - * const result = getMonth(new Date(2012, 1, 29)) - * //=> 1 - */ -function getMonth(date) { - const _date = toDate(date); - const month = _date.getMonth(); - return month; -} - -// Fallback for modularized imports: -/* harmony default export */ const date_fns_getMonth = ((/* unused pure expression or super */ null && (getMonth))); - -;// CONCATENATED MODULE: ../../node_modules/date-fns/getDate.mjs - - -/** - * @name getDate - * @category Day Helpers - * @summary Get the day of the month of the given date. - * - * @description - * Get the day of the month of the given date. - * - * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc). - * - * @param date - The given date - * - * @returns The day of month - * - * @example - * // Which day of the month is 29 February 2012? - * const result = getDate(new Date(2012, 1, 29)) - * //=> 29 - */ -function getDate(date) { - const _date = toDate(date); - const dayOfMonth = _date.getDate(); - return dayOfMonth; -} - -// Fallback for modularized imports: -/* harmony default export */ const date_fns_getDate = ((/* unused pure expression or super */ null && (getDate))); - -;// CONCATENATED MODULE: ../../node_modules/date-fns/constants.mjs -/** - * @module constants - * @summary Useful constants - * @description - * Collection of useful date constants. - * - * The constants could be imported from `date-fns/constants`: - * - * ```ts - * import { maxTime, minTime } from "./constants/date-fns/constants"; - * - * function isAllowedTime(time) { - * return time <= maxTime && time >= minTime; - * } - * ``` - */ - -/** - * @constant - * @name daysInWeek - * @summary Days in 1 week. - */ -const daysInWeek = 7; - -/** - * @constant - * @name daysInYear - * @summary Days in 1 year. - * - * @description - * How many days in a year. - * - * One years equals 365.2425 days according to the formula: - * - * > Leap year occures every 4 years, except for years that are divisable by 100 and not divisable by 400. - * > 1 mean year = (365+1/4-1/100+1/400) days = 365.2425 days - */ -const daysInYear = 365.2425; - -/** - * @constant - * @name maxTime - * @summary Maximum allowed time. - * - * @example - * import { maxTime } from "./constants/date-fns/constants"; - * - * const isValid = 8640000000000001 <= maxTime; - * //=> false - * - * new Date(8640000000000001); - * //=> Invalid Date - */ -const maxTime = Math.pow(10, 8) * 24 * 60 * 60 * 1000; - -/** - * @constant - * @name minTime - * @summary Minimum allowed time. - * - * @example - * import { minTime } from "./constants/date-fns/constants"; - * - * const isValid = -8640000000000001 >= minTime; - * //=> false - * - * new Date(-8640000000000001) - * //=> Invalid Date - */ -const minTime = -maxTime; - -/** - * @constant - * @name millisecondsInWeek - * @summary Milliseconds in 1 week. - */ -const millisecondsInWeek = 604800000; - -/** - * @constant - * @name millisecondsInDay - * @summary Milliseconds in 1 day. - */ -const millisecondsInDay = 86400000; - -/** - * @constant - * @name millisecondsInMinute - * @summary Milliseconds in 1 minute - */ -const millisecondsInMinute = 60000; - -/** - * @constant - * @name millisecondsInHour - * @summary Milliseconds in 1 hour - */ -const millisecondsInHour = 3600000; - -/** - * @constant - * @name millisecondsInSecond - * @summary Milliseconds in 1 second - */ -const millisecondsInSecond = 1000; - -/** - * @constant - * @name minutesInYear - * @summary Minutes in 1 year. - */ -const minutesInYear = 525600; - -/** - * @constant - * @name minutesInMonth - * @summary Minutes in 1 month. - */ -const minutesInMonth = 43200; - -/** - * @constant - * @name minutesInDay - * @summary Minutes in 1 day. - */ -const minutesInDay = 1440; - -/** - * @constant - * @name minutesInHour - * @summary Minutes in 1 hour. - */ -const minutesInHour = 60; - -/** - * @constant - * @name monthsInQuarter - * @summary Months in 1 quarter. - */ -const monthsInQuarter = 3; - -/** - * @constant - * @name monthsInYear - * @summary Months in 1 year. - */ -const monthsInYear = 12; - -/** - * @constant - * @name quartersInYear - * @summary Quarters in 1 year - */ -const quartersInYear = 4; - -/** - * @constant - * @name secondsInHour - * @summary Seconds in 1 hour. - */ -const secondsInHour = 3600; - -/** - * @constant - * @name secondsInMinute - * @summary Seconds in 1 minute. - */ -const secondsInMinute = 60; - -/** - * @constant - * @name secondsInDay - * @summary Seconds in 1 day. - */ -const secondsInDay = secondsInHour * 24; - -/** - * @constant - * @name secondsInWeek - * @summary Seconds in 1 week. - */ -const secondsInWeek = secondsInDay * 7; - -/** - * @constant - * @name secondsInYear - * @summary Seconds in 1 year. - */ -const secondsInYear = secondsInDay * daysInYear; - -/** - * @constant - * @name secondsInMonth - * @summary Seconds in 1 month - */ -const secondsInMonth = secondsInYear / 12; - -/** - * @constant - * @name secondsInQuarter - * @summary Seconds in 1 quarter. - */ -const secondsInQuarter = secondsInMonth * 3; - -;// CONCATENATED MODULE: ../../node_modules/date-fns/_lib/defaultOptions.mjs -let defaultOptions = {}; - -function getDefaultOptions() { - return defaultOptions; -} - -function setDefaultOptions(newOptions) { - defaultOptions = newOptions; -} - -;// CONCATENATED MODULE: ../../node_modules/date-fns/startOfWeek.mjs - - - -/** - * The {@link startOfWeek} function options. - */ - -/** - * @name startOfWeek - * @category Week Helpers - * @summary Return the start of a week for the given date. - * - * @description - * Return the start of a week for the given date. - * The result will be in the local timezone. - * - * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc). - * - * @param date - The original date - * @param options - An object with options - * - * @returns The start of a week - * - * @example - * // The start of a week for 2 September 2014 11:55:00: - * const result = startOfWeek(new Date(2014, 8, 2, 11, 55, 0)) - * //=> Sun Aug 31 2014 00:00:00 - * - * @example - * // If the week starts on Monday, the start of the week for 2 September 2014 11:55:00: - * const result = startOfWeek(new Date(2014, 8, 2, 11, 55, 0), { weekStartsOn: 1 }) - * //=> Mon Sep 01 2014 00:00:00 - */ -function startOfWeek(date, options) { - const defaultOptions = getDefaultOptions(); - const weekStartsOn = - options?.weekStartsOn ?? - options?.locale?.options?.weekStartsOn ?? - defaultOptions.weekStartsOn ?? - defaultOptions.locale?.options?.weekStartsOn ?? - 0; - - const _date = toDate(date); - const day = _date.getDay(); - const diff = (day < weekStartsOn ? 7 : 0) + day - weekStartsOn; - - _date.setDate(_date.getDate() - diff); - _date.setHours(0, 0, 0, 0); - return _date; -} - -// Fallback for modularized imports: -/* harmony default export */ const date_fns_startOfWeek = ((/* unused pure expression or super */ null && (startOfWeek))); - -;// CONCATENATED MODULE: ../../node_modules/date-fns/constructFrom.mjs -/** - * @name constructFrom - * @category Generic Helpers - * @summary Constructs a date using the reference date and the value - * - * @description - * The function constructs a new date using the constructor from the reference - * date and the given value. It helps to build generic functions that accept - * date extensions. - * - * It defaults to `Date` if the passed reference date is a number or a string. - * - * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc). - * - * @param date - The reference date to take constructor from - * @param value - The value to create the date - * - * @returns Date initialized using the given date and value - * - * @example - * import { constructFrom } from 'date-fns' - * - * // A function that clones a date preserving the original type - * function cloneDate 2005 - * - * @example - * // Which week numbering year is 26 December 2004 if week starts on Saturday? - * const result = getWeekYear(new Date(2004, 11, 26), { weekStartsOn: 6 }) - * //=> 2004 - * - * @example - * // Which week numbering year is 26 December 2004 if the first week contains 4 January? - * const result = getWeekYear(new Date(2004, 11, 26), { firstWeekContainsDate: 4 }) - * //=> 2004 - */ -function getWeekYear(date, options) { - const _date = toDate(date); - const year = _date.getFullYear(); - - const defaultOptions = getDefaultOptions(); - const firstWeekContainsDate = - options?.firstWeekContainsDate ?? - options?.locale?.options?.firstWeekContainsDate ?? - defaultOptions.firstWeekContainsDate ?? - defaultOptions.locale?.options?.firstWeekContainsDate ?? - 1; - - const firstWeekOfNextYear = constructFrom(date, 0); - firstWeekOfNextYear.setFullYear(year + 1, 0, firstWeekContainsDate); - firstWeekOfNextYear.setHours(0, 0, 0, 0); - const startOfNextYear = startOfWeek(firstWeekOfNextYear, options); - - const firstWeekOfThisYear = constructFrom(date, 0); - firstWeekOfThisYear.setFullYear(year, 0, firstWeekContainsDate); - firstWeekOfThisYear.setHours(0, 0, 0, 0); - const startOfThisYear = startOfWeek(firstWeekOfThisYear, options); - - if (_date.getTime() >= startOfNextYear.getTime()) { - return year + 1; - } else if (_date.getTime() >= startOfThisYear.getTime()) { - return year; - } else { - return year - 1; - } -} - -// Fallback for modularized imports: -/* harmony default export */ const date_fns_getWeekYear = ((/* unused pure expression or super */ null && (getWeekYear))); - -;// CONCATENATED MODULE: ../../node_modules/date-fns/startOfWeekYear.mjs - - - - - -/** - * The {@link startOfWeekYear} function options. - */ - -/** - * @name startOfWeekYear - * @category Week-Numbering Year Helpers - * @summary Return the start of a local week-numbering year for the given date. - * - * @description - * Return the start of a local week-numbering year. - * The exact calculation depends on the values of - * `options.weekStartsOn` (which is the index of the first day of the week) - * and `options.firstWeekContainsDate` (which is the day of January, which is always in - * the first week of the week-numbering year) - * - * Week numbering: https://en.wikipedia.org/wiki/Week#The_ISO_week_date_system - * - * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc). - * - * @param date - The original date - * @param options - An object with options - * - * @returns The start of a week-numbering year - * - * @example - * // The start of an a week-numbering year for 2 July 2005 with default settings: - * const result = startOfWeekYear(new Date(2005, 6, 2)) - * //=> Sun Dec 26 2004 00:00:00 - * - * @example - * // The start of a week-numbering year for 2 July 2005 - * // if Monday is the first day of week - * // and 4 January is always in the first week of the year: - * const result = startOfWeekYear(new Date(2005, 6, 2), { - * weekStartsOn: 1, - * firstWeekContainsDate: 4 - * }) - * //=> Mon Jan 03 2005 00:00:00 - */ -function startOfWeekYear(date, options) { - const defaultOptions = getDefaultOptions(); - const firstWeekContainsDate = - options?.firstWeekContainsDate ?? - options?.locale?.options?.firstWeekContainsDate ?? - defaultOptions.firstWeekContainsDate ?? - defaultOptions.locale?.options?.firstWeekContainsDate ?? - 1; - - const year = getWeekYear(date, options); - const firstWeek = constructFrom(date, 0); - firstWeek.setFullYear(year, 0, firstWeekContainsDate); - firstWeek.setHours(0, 0, 0, 0); - const _date = startOfWeek(firstWeek, options); - return _date; -} - -// Fallback for modularized imports: -/* harmony default export */ const date_fns_startOfWeekYear = ((/* unused pure expression or super */ null && (startOfWeekYear))); - -;// CONCATENATED MODULE: ../../node_modules/date-fns/getWeek.mjs - - - - - -/** - * The {@link getWeek} function options. - */ - -/** - * @name getWeek - * @category Week Helpers - * @summary Get the local week index of the given date. - * - * @description - * Get the local week index of the given date. - * The exact calculation depends on the values of - * `options.weekStartsOn` (which is the index of the first day of the week) - * and `options.firstWeekContainsDate` (which is the day of January, which is always in - * the first week of the week-numbering year) - * - * Week numbering: https://en.wikipedia.org/wiki/Week#The_ISO_week_date_system - * - * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc). - * - * @param date - The given date - * @param options - An object with options - * - * @returns The week - * - * @example - * // Which week of the local week numbering year is 2 January 2005 with default options? - * const result = getWeek(new Date(2005, 0, 2)) - * //=> 2 - * - * @example - * // Which week of the local week numbering year is 2 January 2005, - * // if Monday is the first day of the week, - * // and the first week of the year always contains 4 January? - * const result = getWeek(new Date(2005, 0, 2), { - * weekStartsOn: 1, - * firstWeekContainsDate: 4 - * }) - * //=> 53 - */ - -function getWeek(date, options) { - const _date = toDate(date); - const diff = +startOfWeek(_date, options) - +startOfWeekYear(_date, options); - - // Round the number of weeks to the nearest integer because the number of - // milliseconds in a week is not constant (e.g. it's different in the week of - // the daylight saving time clock shift). - return Math.round(diff / millisecondsInWeek) + 1; -} - -// Fallback for modularized imports: -/* harmony default export */ const date_fns_getWeek = ((/* unused pure expression or super */ null && (getWeek))); - // EXTERNAL MODULE: ../../node_modules/yaml/dist/index.js var dist = __nccwpck_require__(8447); ;// CONCATENATED MODULE: ./src/constants.ts @@ -85384,22 +84714,24 @@ const constants_PLATFORM = (() => { return "macos"; } case "win32": { - return "win32"; + return "windows"; } default: { throw new Error("The platform is not supported."); } } })(); -const CYGWIN_ROOT = external_node_path_namespaceObject.join("D:", "cygwin"); -const CYGWIN_ROOT_BIN = external_node_path_namespaceObject.join(CYGWIN_ROOT, "bin"); -const CYGWIN_ROOT_WRAPPERBIN = external_node_path_namespaceObject.join(CYGWIN_ROOT, "wrapperbin"); -// [todo] remove the branch for Windows once opam 2.2 is released as stable. -const ALLOW_PRERELEASE_OPAM = constants_PLATFORM !== "win32" && - lib_core.getBooleanInput("allow-prerelease-opam", { - required: false, - trimWhitespace: true, - }); +const constants_CYGWIN_MIRROR = "https://cygwin.mirror.constant.com/"; +// [HACK] https://github.com/ocaml/setup-ocaml/pull/55 +const constants_CYGWIN_ROOT = external_node_path_namespaceObject.join("D:", "cygwin"); +const constants_OPAM_ROOT = constants_PLATFORM === "windows" + ? // [HACK] https://github.com/ocaml/setup-ocaml/pull/55 + external_node_path_namespaceObject.join("D:", ".opam") + : external_node_path_namespaceObject.join(external_node_os_.homedir(), ".opam"); +const ALLOW_PRERELEASE_OPAM = lib_core.getBooleanInput("allow-prerelease-opam", { + required: false, + trimWhitespace: true, +}); const constants_CACHE_PREFIX = lib_core.getInput("cache-prefix", { required: false, trimWhitespace: true, @@ -85416,17 +84748,14 @@ const constants_OCAML_COMPILER = lib_core.getInput("ocaml-compiler", { required: true, trimWhitespace: true, }); -// [todo] remove this once opam 2.2 is released as stable. -const constants_OPAM_DEPEXT = !ALLOW_PRERELEASE_OPAM && - lib_core.getBooleanInput("opam-depext", { +const constants_OPAM_DISABLE_SANDBOXING = +// [TODO] unlock this once sandboxing is supported on Windows +constants_PLATFORM === "windows" + ? true + : lib_core.getBooleanInput("opam-disable-sandboxing", { required: false, trimWhitespace: true, }); -const OPAM_DEPEXT_FLAGS = lib_core.getInput("opam-depext-flags", { required: false, trimWhitespace: true }) - .split(",") - .map((f) => f.trim()) - .filter((f) => f.length > 0); -const constants_OPAM_DISABLE_SANDBOXING = lib_core.getBooleanInput("opam-disable-sandboxing", { required: false, trimWhitespace: true }); const OPAM_LOCAL_PACKAGES = lib_core.getInput("opam-local-packages", { required: false, trimWhitespace: true, @@ -85435,13 +84764,15 @@ const OPAM_PIN = lib_core.getBooleanInput("opam-pin", { required: false, trimWhitespace: true, }); -const repositories_yaml = dist/* parse */.Qc(lib_core.getInput("opam-repositories", { required: false, trimWhitespace: true })); -const defaultRepository = constants_PLATFORM === "win32" - ? "https://github.com/ocaml-opam/opam-repository-mingw.git#sunset" - : "https://github.com/ocaml/opam-repository.git"; -const OPAM_REPOSITORIES = repositories_yaml - ? Object.entries(repositories_yaml).reverse() - : [["default", defaultRepository]]; +const OPAM_REPOSITORIES = (() => { + const repositories_yaml = dist/* parse */.Qc(lib_core.getInput("opam-repositories", { + required: false, + trimWhitespace: true, + })); + return repositories_yaml + ? Object.entries(repositories_yaml).reverse() + : [["default", "https://github.com/ocaml/opam-repository.git"]]; +})(); ;// CONCATENATED MODULE: ./src/cache.ts @@ -85459,23 +84790,16 @@ const OPAM_REPOSITORIES = repositories_yaml function composeDate() { const d = new Date(); - const year = getYear(d); - const month = getMonth(d); - const date = getDate(d); - const week = getWeek(d); + const year = datefns.getYear(d); + const month = datefns.getMonth(d); + const date = datefns.getDate(d); + const week = datefns.getWeek(d); return { year, month, date, week }; } async function composeCygwinCacheKeys() { const cygwinVersion = await getCygwinVersion(); - // Bump cygwinEpoch when a new release requires the existing Cygwin caches to - // be invalidated. - const cygwinEpoch = "1"; - const { year, week } = composeDate(); - const key = `${CACHE_PREFIX}-setup-ocaml-cygwin-${cygwinEpoch}-${cygwinVersion}-${year}-${week}`; - const restoreKeys = [ - `${CACHE_PREFIX}-setup-ocaml-cygwin-${cygwinEpoch}-${cygwinVersion}-${year}-${week}`, - `${CACHE_PREFIX}-setup-ocaml-cygwin-${cygwinEpoch}-${cygwinVersion}-${year}-`, - ]; + const key = `${CACHE_PREFIX}-setup-ocaml-cygwin-${cygwinVersion}`; + const restoreKeys = [key]; return { key, restoreKeys }; } function composeDuneCacheKeys() { @@ -85494,10 +84818,10 @@ function composeDuneCacheKeys() { return { key, restoreKeys }; } async function composeOpamCacheKeys() { - const fullPlatform = PLATFORM === "win32" + const fullPlatform = PLATFORM === "windows" ? PLATFORM : `${PLATFORM}-${(await getSystemIdentificationInfo()).version}`; - const opamVersion = PLATFORM === "win32" ? "0.0.0.2" : (await getLatestOpamRelease()).version; + const { version: opamVersion } = await getLatestOpamRelease(); const ocamlCompiler = await resolveCompiler(OCAML_COMPILER); const ocamlVersion = ocamlCompiler.toLowerCase().replaceAll(/\W/g, "_"); const sandboxed = OPAM_DISABLE_SANDBOXING ? "nosandbox" : "sandbox"; @@ -85510,37 +84834,13 @@ async function composeOpamCacheKeys() { ]; return { key, restoreKeys }; } -function composeOpamDownloadCacheKeys() { - const repositories = OPAM_REPOSITORIES.map(([, u]) => { - try { - const url = new URL(u); - const urn = external_node_path_namespaceObject.join(url.hostname, url.pathname); - return urn; - } - catch { - return external_node_path_namespaceObject.resolve(u); - } - }).join("_"); - const ocamlVersion = constants_OCAML_COMPILER.toLowerCase().replaceAll(/\W/g, "_"); - const { year, month, date } = composeDate(); - const { runId, runNumber } = lib_github.context; - const key = `${constants_CACHE_PREFIX}-setup-ocaml-opam-download-${repositories}-${ocamlVersion}-${year}-${month}-${date}-${runId}-${runNumber}`; - const restoreKeys = [ - `${constants_CACHE_PREFIX}-setup-ocaml-opam-download-${repositories}-${ocamlVersion}-${year}-${month}-${date}-${runId}-${runNumber}`, - `${constants_CACHE_PREFIX}-setup-ocaml-opam-download-${repositories}-${ocamlVersion}-${year}-${month}-${date}-${runId}-`, - `${constants_CACHE_PREFIX}-setup-ocaml-opam-download-${repositories}-${ocamlVersion}-${year}-${month}-${date}-`, - `${constants_CACHE_PREFIX}-setup-ocaml-opam-download-${repositories}-${ocamlVersion}-${year}-${month}-`, - ]; - return { key, restoreKeys }; -} function composeCygwinCachePaths() { const paths = []; - const githubWorkspace = process.env["GITHUB_WORKSPACE"] ?? process.cwd(); - const cygwinRoot = path.join("D:", "cygwin"); - paths.push(cygwinRoot); + const githubWorkspace = process.env.GITHUB_WORKSPACE ?? process.cwd(); + paths.push(CYGWIN_ROOT); const cygwinRootSymlinkPath = path.posix.join("/cygdrive", "d", "cygwin"); paths.push(cygwinRootSymlinkPath); - const cygwinEncodedUri = encodeURIComponent("https://mirrors.kernel.org/sourceware/cygwin/").toLowerCase(); + const cygwinEncodedUri = encodeURIComponent(CYGWIN_MIRROR).toLowerCase(); const cygwinPackageRoot = path.join(githubWorkspace, cygwinEncodedUri); paths.push(cygwinPackageRoot); return paths; @@ -85548,7 +84848,7 @@ function composeCygwinCachePaths() { function composeDuneCachePaths() { const paths = []; const homeDir = external_node_os_.homedir(); - if (constants_PLATFORM === "win32") { + if (constants_PLATFORM === "windows") { const duneCacheDir = external_node_path_namespaceObject.join(homeDir, "Local Settings", "Cache", "dune"); paths.push(duneCacheDir); } @@ -85562,48 +84862,45 @@ function composeDuneCachePaths() { return paths; } function composeOpamCachePaths() { - const paths = []; - if (PLATFORM === "win32") { - const opamRootCachePath = path.join("D:", ".opam"); - paths.push(opamRootCachePath); + const paths = [OPAM_ROOT]; + if (PLATFORM === "windows") { const { repo: { repo }, } = github.context; const opamCygwinLocalCachePath = path.posix.join("/cygdrive", "d", "a", repo, repo, "_opam"); paths.push(opamCygwinLocalCachePath); } - else { - const homeDir = os.homedir(); - const opamRootCachePath = path.join(homeDir, ".opam"); - paths.push(opamRootCachePath); - } - const githubWorkspace = process.env["GITHUB_WORKSPACE"] ?? process.cwd(); + const githubWorkspace = process.env.GITHUB_WORKSPACE ?? process.cwd(); const opamLocalCachePath = path.join(githubWorkspace, "_opam"); paths.push(opamLocalCachePath); return paths; } -function composeOpamDownloadCachePaths() { - const paths = []; - if (constants_PLATFORM === "win32") { - const opamDownloadCachePath = external_node_path_namespaceObject.join("D:", ".opam", "download-cache"); - paths.push(opamDownloadCachePath); - } - else { - const homeDir = external_node_os_.homedir(); - const opamDownloadCachePath = external_node_path_namespaceObject.join(homeDir, ".opam", "download-cache"); - paths.push(opamDownloadCachePath); - } - return paths; -} async function restoreCache(key, restoreKeys, paths) { - const cacheKey = await cache.restoreCache(paths, key, restoreKeys); - if (cacheKey) { - core.info(`Cache restored from key: ${cacheKey}`); + if (!cache.isFeatureAvailable()) { + core.info("Actions cache service feature is unavailable"); + return; } - else { - core.info(`Cache not found for input keys: ${[key, ...restoreKeys].join(", ")}`); + try { + const cacheKey = await cache.restoreCache(paths, key, restoreKeys); + if (cacheKey) { + core.info(`Cache restored from key: ${cacheKey}`); + } + else { + core.info(`Cache not found for input keys: ${[key, ...restoreKeys].join(", ")}`); + } + return cacheKey; + } + catch (error) { + if (error instanceof Error) { + core.info(error.message); + } + core.warning("An internal error has occurred in cache backend. Please check https://www.githubstatus.com for any ongoing issue in actions."); + return; } - return cacheKey; } async function saveCache(key, paths) { + if (!lib_cache.isFeatureAvailable()) { + lib_core.info("Actions cache service feature is unavailable"); + return; + } try { await lib_cache.saveCache(paths, key); } @@ -85611,13 +84908,15 @@ async function saveCache(key, paths) { if (error instanceof Error) { lib_core.info(error.message); } + lib_core.warning("An internal error has occurred in cache backend. Please check https://www.githubstatus.com for any ongoing issue in actions."); } } async function restoreCygwinCache() { - await core.group("Retrieve the Cygwin cache", async () => { + return await core.group("Retrieve the Cygwin cache", async () => { const { key, restoreKeys } = await composeCygwinCacheKeys(); const paths = composeCygwinCachePaths(); - await restoreCache(key, restoreKeys, paths); + const cacheKey = await restoreCache(key, restoreKeys, paths); + return cacheKey; }); } async function saveCygwinCache() { @@ -85628,10 +84927,11 @@ async function saveCygwinCache() { }); } async function restoreDuneCache() { - await core.group("Retrieve the dune cache", async () => { + return await core.group("Retrieve the dune cache", async () => { const { key, restoreKeys } = composeDuneCacheKeys(); const paths = composeDuneCachePaths(); - await restoreCache(key, restoreKeys, paths); + const cacheKey = await restoreCache(key, restoreKeys, paths); + return cacheKey; }); } async function saveDuneCache() { @@ -85664,21 +84964,6 @@ async function saveOpamCache() { await saveCache(key, paths); }); } -async function restoreOpamDownloadCache() { - return await core.group("Retrieve the opam download cache", async () => { - const { key, restoreKeys } = composeOpamDownloadCacheKeys(); - const paths = composeOpamDownloadCachePaths(); - const cacheKey = await restoreCache(key, restoreKeys, paths); - return cacheKey; - }); -} -async function saveOpamDownloadCache() { - await lib_core.group("Save the opam download cache", async () => { - const { key } = composeOpamDownloadCacheKeys(); - const paths = composeOpamDownloadCachePaths(); - await saveCache(key, paths); - }); -} ;// CONCATENATED MODULE: ./src/dune.ts @@ -85688,12 +84973,7 @@ async function saveOpamDownloadCache() { const { repo: { owner, repo }, runId: run_id, } = lib_github.context; async function installDune() { await core.group("Install dune", async () => { - if (OPAM_DEPEXT) { - await exec("opam", ["depext", "--install", "dune"]); - } - else { - await exec("opam", ["install", "dune"]); - } + await exec("opam", ["install", "dune"]); }); } async function trimDuneCache() { @@ -85711,8 +84991,7 @@ async function trimDuneCache() { "dune", "cache", "trim", - "--size", - `${cacheSize}MB`, + `--size=${cacheSize}MB`, ]); }); } @@ -85729,7 +85008,6 @@ async function run() { await trimDuneCache(); await saveDuneCache(); } - await saveOpamDownloadCache(); external_node_process_.exit(0); } catch (error) { diff --git a/lint-doc/dist/index.js b/lint-doc/dist/index.js index 400a473d..ac1c2a25 100644 --- a/lint-doc/dist/index.js +++ b/lint-doc/dist/index.js @@ -27918,15 +27918,15 @@ var core = __nccwpck_require__(7117); var exec = __nccwpck_require__(6473); ;// CONCATENATED MODULE: ./src/odoc.ts + async function lintOdoc() { - const options = { + const exitCode = await (0,exec.exec)("opam", ["exec", "--", "dune", "build", "@doc"], { env: { - ...process.env, - PATH: process.env["PATH"] ?? "", + ...external_node_process_namespaceObject.env, + PATH: external_node_process_namespaceObject.env.PATH ?? "", ODOC_WARN_ERROR: "true", }, - }; - const exitCode = await (0,exec.exec)("opam", ["exec", "--", "dune", "build", "@doc"], options); + }); if (exitCode !== 0) { throw new Error("dune build @doc failed"); } @@ -27937,18 +27937,12 @@ async function lintOdoc() { async function installOpamPackages() { await core.group("Install opam packages", async () => { - await (0,exec.exec)("opam", ["install", ".", "--deps-only", "--with-doc"]); + await (0,exec.exec)("opam", ["install", "--deps-only", "--with-doc", "."]); }); } async function installOdoc() { await core.group("Install odoc", async () => { - await (0,exec.exec)("opam", [ - "depext", - "--install", - "conf-m4", - "dune", - "odoc>=1.5.0", - ]); + await (0,exec.exec)("opam", ["install", "dune", "odoc>=1.5.0"]); }); } diff --git a/lint-fmt/dist/index.js b/lint-fmt/dist/index.js index a2d6fe6f..4168291c 100644 --- a/lint-fmt/dist/index.js +++ b/lint-fmt/dist/index.js @@ -27937,8 +27937,9 @@ function convertToUnix(str) { + async function parse() { - const githubWorkspace = process.env["GITHUB_WORKSPACE"] ?? process.cwd(); + const githubWorkspace = external_node_process_namespaceObject.env.GITHUB_WORKSPACE ?? external_node_process_namespaceObject.cwd(); const fpath = external_node_path_namespaceObject.join(githubWorkspace, ".ocamlformat"); const buf = await external_node_fs_namespaceObject.promises.readFile(fpath); const str = buf.toString(); diff --git a/lint-opam/dist/index.js b/lint-opam/dist/index.js index 5c3c23fd..dbb4929b 100644 --- a/lint-opam/dist/index.js +++ b/lint-opam/dist/index.js @@ -27932,10 +27932,10 @@ async function installOpamPackages() { await core.group("Install opam packages", async () => { await (0,exec.exec)("opam", [ "install", - ".", "--deps-only", - "--with-test", "--with-doc", + "--with-test", + ".", ]); }); } diff --git a/packages/analysis/src/analysis.ts b/packages/analysis/src/analysis.ts index 7c061eb0..05cd398c 100644 --- a/packages/analysis/src/analysis.ts +++ b/packages/analysis/src/analysis.ts @@ -1,14 +1,13 @@ import * as fs from "node:fs/promises"; import * as os from "node:os"; import * as path from "node:path"; - +import * as process from "node:process"; import { exec } from "@actions/exec"; import * as glob from "@actions/glob"; import { Snapshot, submitSnapshot, } from "@github/dependency-submission-toolkit"; - import type { Output } from "./opam-detector"; import { createBuildTarget } from "./opam-detector"; @@ -35,17 +34,17 @@ export async function analysis() { "opam", [ "tree", - name, + `--json=${tempJson}`, "--with-dev-setup", // [NOTE] https://github.com/ocaml/opam/issues/4541 // "--with-doc", "--with-test", - `--json=${tempJson}`, + name, ], { env: { ...process.env, - PATH: process.env["PATH"] ?? "", + PATH: process.env.PATH ?? "", }, silent: true, }, @@ -53,7 +52,7 @@ export async function analysis() { const output = JSON.parse( await fs.readFile(tempJson, "utf8"), ) as unknown as Output; - const githubWorkspace = process.env["GITHUB_WORKSPACE"] ?? process.cwd(); + const githubWorkspace = process.env.GITHUB_WORKSPACE ?? process.cwd(); const opamPackagePath = path.normalize( path.relative(githubWorkspace, fpath), ); diff --git a/packages/analysis/src/index.ts b/packages/analysis/src/index.ts index 6ea550f9..0f0a370b 100644 --- a/packages/analysis/src/index.ts +++ b/packages/analysis/src/index.ts @@ -1,7 +1,5 @@ import * as process from "node:process"; - import * as core from "@actions/core"; - import { analysis } from "./analysis"; import { installOpamPackages } from "./opam"; diff --git a/packages/analysis/src/opam.ts b/packages/analysis/src/opam.ts index d9d99729..1847b994 100644 --- a/packages/analysis/src/opam.ts +++ b/packages/analysis/src/opam.ts @@ -5,12 +5,12 @@ export async function installOpamPackages() { await core.group("Install opam packages", async () => { await exec("opam", [ "install", - ".", "--deps-only", "--with-dev-setup", // [NOTE] https://github.com/ocaml/opam/issues/4541 // "--with-doc", "--with-test", + ".", ]); }); } diff --git a/packages/analysis/tsconfig.json b/packages/analysis/tsconfig.json index 22a529ea..d963b5da 100644 --- a/packages/analysis/tsconfig.json +++ b/packages/analysis/tsconfig.json @@ -9,7 +9,7 @@ "moduleDetection": "force", "moduleResolution": "Bundler", "noEmit": true, - "resolveJsonModule": true - }, - "exclude": ["node_modules"] + "noPropertyAccessFromIndexSignature": false, + "verbatimModuleSyntax": true + } } diff --git a/packages/lint-doc/src/index.ts b/packages/lint-doc/src/index.ts index 8e9552dc..27930653 100644 --- a/packages/lint-doc/src/index.ts +++ b/packages/lint-doc/src/index.ts @@ -1,7 +1,5 @@ import * as process from "node:process"; - import * as core from "@actions/core"; - import { lintOdoc } from "./odoc.js"; import { installOdoc, installOpamPackages } from "./opam.js"; diff --git a/packages/lint-doc/src/odoc.ts b/packages/lint-doc/src/odoc.ts index 511b05c7..2514f916 100644 --- a/packages/lint-doc/src/odoc.ts +++ b/packages/lint-doc/src/odoc.ts @@ -1,19 +1,14 @@ -import type { ExecOptions } from "@actions/exec"; +import * as process from "node:process"; import { exec } from "@actions/exec"; export async function lintOdoc() { - const options: ExecOptions = { + const exitCode = await exec("opam", ["exec", "--", "dune", "build", "@doc"], { env: { ...process.env, - PATH: process.env["PATH"] ?? "", + PATH: process.env.PATH ?? "", ODOC_WARN_ERROR: "true", }, - }; - const exitCode = await exec( - "opam", - ["exec", "--", "dune", "build", "@doc"], - options, - ); + }); if (exitCode !== 0) { throw new Error("dune build @doc failed"); } diff --git a/packages/lint-doc/src/opam.ts b/packages/lint-doc/src/opam.ts index 63b9c447..f3c1f880 100644 --- a/packages/lint-doc/src/opam.ts +++ b/packages/lint-doc/src/opam.ts @@ -3,18 +3,12 @@ import { exec } from "@actions/exec"; export async function installOpamPackages() { await core.group("Install opam packages", async () => { - await exec("opam", ["install", ".", "--deps-only", "--with-doc"]); + await exec("opam", ["install", "--deps-only", "--with-doc", "."]); }); } export async function installOdoc() { await core.group("Install odoc", async () => { - await exec("opam", [ - "depext", - "--install", - "conf-m4", - "dune", - "odoc>=1.5.0", - ]); + await exec("opam", ["install", "dune", "odoc>=1.5.0"]); }); } diff --git a/packages/lint-doc/tsconfig.json b/packages/lint-doc/tsconfig.json index 8c14d0c2..d963b5da 100644 --- a/packages/lint-doc/tsconfig.json +++ b/packages/lint-doc/tsconfig.json @@ -9,7 +9,7 @@ "moduleDetection": "force", "moduleResolution": "Bundler", "noEmit": true, + "noPropertyAccessFromIndexSignature": false, "verbatimModuleSyntax": true - }, - "exclude": ["node_modules"] + } } diff --git a/packages/lint-fmt/src/index.ts b/packages/lint-fmt/src/index.ts index 6e9236a5..bc507c9a 100644 --- a/packages/lint-fmt/src/index.ts +++ b/packages/lint-fmt/src/index.ts @@ -1,7 +1,5 @@ import * as process from "node:process"; - import * as core from "@actions/core"; - import { checkFmt } from "./lint.js"; import { getOcamlformatVersion } from "./ocamlformat.js"; import { installOcamlformat } from "./opam.js"; diff --git a/packages/lint-fmt/src/ocamlformat.ts b/packages/lint-fmt/src/ocamlformat.ts index 26c088b1..2656404b 100644 --- a/packages/lint-fmt/src/ocamlformat.ts +++ b/packages/lint-fmt/src/ocamlformat.ts @@ -1,10 +1,10 @@ import { promises as fs } from "node:fs"; import * as path from "node:path"; - +import * as process from "node:process"; import { convertToUnix } from "./compat.js"; async function parse() { - const githubWorkspace = process.env["GITHUB_WORKSPACE"] ?? process.cwd(); + const githubWorkspace = process.env.GITHUB_WORKSPACE ?? process.cwd(); const fpath = path.join(githubWorkspace, ".ocamlformat"); const buf = await fs.readFile(fpath); const str = buf.toString(); diff --git a/packages/lint-fmt/tsconfig.json b/packages/lint-fmt/tsconfig.json index 8c14d0c2..d963b5da 100644 --- a/packages/lint-fmt/tsconfig.json +++ b/packages/lint-fmt/tsconfig.json @@ -9,7 +9,7 @@ "moduleDetection": "force", "moduleResolution": "Bundler", "noEmit": true, + "noPropertyAccessFromIndexSignature": false, "verbatimModuleSyntax": true - }, - "exclude": ["node_modules"] + } } diff --git a/packages/lint-opam/src/index.ts b/packages/lint-opam/src/index.ts index 88c4145d..374a261b 100644 --- a/packages/lint-opam/src/index.ts +++ b/packages/lint-opam/src/index.ts @@ -1,7 +1,5 @@ import * as process from "node:process"; - import * as core from "@actions/core"; - import { opamDuneLint, opamLint } from "./lint.js"; import { installOpamDuneLint, installOpamPackages } from "./opam.js"; diff --git a/packages/lint-opam/src/opam.ts b/packages/lint-opam/src/opam.ts index 9ccca264..513598c6 100644 --- a/packages/lint-opam/src/opam.ts +++ b/packages/lint-opam/src/opam.ts @@ -5,10 +5,10 @@ export async function installOpamPackages() { await core.group("Install opam packages", async () => { await exec("opam", [ "install", - ".", "--deps-only", - "--with-test", "--with-doc", + "--with-test", + ".", ]); }); } diff --git a/packages/lint-opam/tsconfig.json b/packages/lint-opam/tsconfig.json index 8c14d0c2..d963b5da 100644 --- a/packages/lint-opam/tsconfig.json +++ b/packages/lint-opam/tsconfig.json @@ -9,7 +9,7 @@ "moduleDetection": "force", "moduleResolution": "Bundler", "noEmit": true, + "noPropertyAccessFromIndexSignature": false, "verbatimModuleSyntax": true - }, - "exclude": ["node_modules"] + } } diff --git a/packages/setup-ocaml/README.md b/packages/setup-ocaml/README.md deleted file mode 100644 index 437ca1bf..00000000 --- a/packages/setup-ocaml/README.md +++ /dev/null @@ -1,54 +0,0 @@ -# setup-ocaml - -The action does the following: - -### Main - -1. Change the file system behavioural parameters - - **Windows only** -1. Retrieve the Cygwin cache - - **Windows only** - - If the cache already exists -1. Retrieve the opam cache - - If the cache already exists -1. Prepare the Cygwin environment - - **Windows only** -1. Save the Cygwin cache - - **Windows only** -1. Install opam -1. Initialise the opam state -1. Install the OCaml compiler - - If the opam cache was not hit -1. Remove the opam repositories -1. Save the opam cache - - If the opam cache was not hit -1. Initialise the opam repositories -1. Retrieve the opam download cache -1. Install depext - - On Windows, not only `opam-depext` is installed, but `depext-cygwinports` is installed as well -1. Retrieve the dune cache - - If the dune cache feature is enabled - - If the cache already exists -1. Install the latest dune and enable the dune cache feature - - If the dune cache feature is enabled -1. Pin the opam files, if they exist - - If the opam pin feature is not disabled - - If there is an opam file in the workspace that matches the glob pattern -1. Install the system dependencies required by the opam files via depext - - If the opam depext feature is enabled - - If there is an opam file in the workspace that matches the glob pattern - -### Post - -The reason for not caching opam stuff in the post-stage (more precisely, why you can't) is due to the size of the cache and repeatability. They should be cached immediately after initialisation to minimize the size of the cache. - -1. Remove oldest dune cache files to free space - - If the dune cache feature is enabled -1. Save the dune cache - - If the dune cache feature is enabled -1. Save the opam download cache - -## What is the difference between opam dependencies and depext dependencies? - -- opam dependencies: opam packages installed by `opam install`. -- depext dependencies: System packages installed by `apt-get install`, `yum install`, `brew install`, etc. diff --git a/packages/setup-ocaml/README.md b/packages/setup-ocaml/README.md new file mode 120000 index 00000000..fe840054 --- /dev/null +++ b/packages/setup-ocaml/README.md @@ -0,0 +1 @@ +../../README.md \ No newline at end of file diff --git a/packages/setup-ocaml/src/cache.ts b/packages/setup-ocaml/src/cache.ts index fcb01125..4d87c529 100644 --- a/packages/setup-ocaml/src/cache.ts +++ b/packages/setup-ocaml/src/cache.ts @@ -1,7 +1,6 @@ import * as os from "node:os"; import * as path from "node:path"; import * as process from "node:process"; - import * as cache from "@actions/cache"; import * as core from "@actions/core"; import { exec } from "@actions/exec"; @@ -11,15 +10,17 @@ import * as datefns from "date-fns"; import { ARCHITECTURE, CACHE_PREFIX, + CYGWIN_MIRROR, + CYGWIN_ROOT, OCAML_COMPILER, OPAM_DISABLE_SANDBOXING, - OPAM_REPOSITORIES, + OPAM_ROOT, PLATFORM, } from "./constants.js"; import { getLatestOpamRelease } from "./opam.js"; import { getSystemIdentificationInfo } from "./system.js"; import { resolveCompiler } from "./version.js"; -import { getCygwinVersion } from "./win32.js"; +import { getCygwinVersion } from "./windows.js"; function composeDate() { const d = new Date(); @@ -32,15 +33,8 @@ function composeDate() { async function composeCygwinCacheKeys() { const cygwinVersion = await getCygwinVersion(); - // Bump cygwinEpoch when a new release requires the existing Cygwin caches to - // be invalidated. - const cygwinEpoch = "1"; - const { year, week } = composeDate(); - const key = `${CACHE_PREFIX}-setup-ocaml-cygwin-${cygwinEpoch}-${cygwinVersion}-${year}-${week}`; - const restoreKeys = [ - `${CACHE_PREFIX}-setup-ocaml-cygwin-${cygwinEpoch}-${cygwinVersion}-${year}-${week}`, - `${CACHE_PREFIX}-setup-ocaml-cygwin-${cygwinEpoch}-${cygwinVersion}-${year}-`, - ]; + const key = `${CACHE_PREFIX}-setup-ocaml-cygwin-${cygwinVersion}`; + const restoreKeys = [key]; return { key, restoreKeys }; } @@ -62,11 +56,10 @@ function composeDuneCacheKeys() { async function composeOpamCacheKeys() { const fullPlatform = - PLATFORM === "win32" + PLATFORM === "windows" ? PLATFORM : `${PLATFORM}-${(await getSystemIdentificationInfo()).version}`; - const opamVersion = - PLATFORM === "win32" ? "0.0.0.2" : (await getLatestOpamRelease()).version; + const { version: opamVersion } = await getLatestOpamRelease(); const ocamlCompiler = await resolveCompiler(OCAML_COMPILER); const ocamlVersion = ocamlCompiler.toLowerCase().replaceAll(/\W/g, "_"); const sandboxed = OPAM_DISABLE_SANDBOXING ? "nosandbox" : "sandbox"; @@ -80,39 +73,13 @@ async function composeOpamCacheKeys() { return { key, restoreKeys }; } -function composeOpamDownloadCacheKeys() { - const repositories = OPAM_REPOSITORIES.map(([, u]) => { - try { - const url = new URL(u); - const urn = path.join(url.hostname, url.pathname); - return urn; - } catch { - return path.resolve(u); - } - }).join("_"); - const ocamlVersion = OCAML_COMPILER.toLowerCase().replaceAll(/\W/g, "_"); - const { year, month, date } = composeDate(); - const { runId, runNumber } = github.context; - const key = `${CACHE_PREFIX}-setup-ocaml-opam-download-${repositories}-${ocamlVersion}-${year}-${month}-${date}-${runId}-${runNumber}`; - const restoreKeys = [ - `${CACHE_PREFIX}-setup-ocaml-opam-download-${repositories}-${ocamlVersion}-${year}-${month}-${date}-${runId}-${runNumber}`, - `${CACHE_PREFIX}-setup-ocaml-opam-download-${repositories}-${ocamlVersion}-${year}-${month}-${date}-${runId}-`, - `${CACHE_PREFIX}-setup-ocaml-opam-download-${repositories}-${ocamlVersion}-${year}-${month}-${date}-`, - `${CACHE_PREFIX}-setup-ocaml-opam-download-${repositories}-${ocamlVersion}-${year}-${month}-`, - ]; - return { key, restoreKeys }; -} - function composeCygwinCachePaths() { const paths = []; - const githubWorkspace = process.env["GITHUB_WORKSPACE"] ?? process.cwd(); - const cygwinRoot = path.join("D:", "cygwin"); - paths.push(cygwinRoot); + const githubWorkspace = process.env.GITHUB_WORKSPACE ?? process.cwd(); + paths.push(CYGWIN_ROOT); const cygwinRootSymlinkPath = path.posix.join("/cygdrive", "d", "cygwin"); paths.push(cygwinRootSymlinkPath); - const cygwinEncodedUri = encodeURIComponent( - "https://mirrors.kernel.org/sourceware/cygwin/", - ).toLowerCase(); + const cygwinEncodedUri = encodeURIComponent(CYGWIN_MIRROR).toLowerCase(); const cygwinPackageRoot = path.join(githubWorkspace, cygwinEncodedUri); paths.push(cygwinPackageRoot); return paths; @@ -121,11 +88,11 @@ function composeCygwinCachePaths() { function composeDuneCachePaths() { const paths = []; const homeDir = os.homedir(); - if (PLATFORM === "win32") { + if (PLATFORM === "windows") { const duneCacheDir = path.join(homeDir, "Local Settings", "Cache", "dune"); paths.push(duneCacheDir); } else { - const xdgCacheHome = process.env["XDG_CACHE_HOME"]; + const xdgCacheHome = process.env.XDG_CACHE_HOME; const duneCacheDir = xdgCacheHome ? path.join(xdgCacheHome, "dune") : path.join(homeDir, ".cache", "dune"); @@ -135,10 +102,8 @@ function composeDuneCachePaths() { } function composeOpamCachePaths() { - const paths = []; - if (PLATFORM === "win32") { - const opamRootCachePath = path.join("D:", ".opam"); - paths.push(opamRootCachePath); + const paths = [OPAM_ROOT]; + if (PLATFORM === "windows") { const { repo: { repo }, } = github.context; @@ -151,61 +116,66 @@ function composeOpamCachePaths() { "_opam", ); paths.push(opamCygwinLocalCachePath); - } else { - const homeDir = os.homedir(); - const opamRootCachePath = path.join(homeDir, ".opam"); - paths.push(opamRootCachePath); } - const githubWorkspace = process.env["GITHUB_WORKSPACE"] ?? process.cwd(); + const githubWorkspace = process.env.GITHUB_WORKSPACE ?? process.cwd(); const opamLocalCachePath = path.join(githubWorkspace, "_opam"); paths.push(opamLocalCachePath); return paths; } -function composeOpamDownloadCachePaths() { - const paths = []; - if (PLATFORM === "win32") { - const opamDownloadCachePath = path.join("D:", ".opam", "download-cache"); - paths.push(opamDownloadCachePath); - } else { - const homeDir = os.homedir(); - const opamDownloadCachePath = path.join(homeDir, ".opam", "download-cache"); - paths.push(opamDownloadCachePath); - } - return paths; -} - async function restoreCache( key: string, restoreKeys: string[], paths: string[], ) { - const cacheKey = await cache.restoreCache(paths, key, restoreKeys); - if (cacheKey) { - core.info(`Cache restored from key: ${cacheKey}`); - } else { - core.info( - `Cache not found for input keys: ${[key, ...restoreKeys].join(", ")}`, + if (!cache.isFeatureAvailable()) { + core.info("Actions cache service feature is unavailable"); + return; + } + try { + const cacheKey = await cache.restoreCache(paths, key, restoreKeys); + if (cacheKey) { + core.info(`Cache restored from key: ${cacheKey}`); + } else { + core.info( + `Cache not found for input keys: ${[key, ...restoreKeys].join(", ")}`, + ); + } + return cacheKey; + } catch (error) { + if (error instanceof Error) { + core.info(error.message); + } + core.warning( + "An internal error has occurred in cache backend. Please check https://www.githubstatus.com for any ongoing issue in actions.", ); + return; } - return cacheKey; } async function saveCache(key: string, paths: string[]) { + if (!cache.isFeatureAvailable()) { + core.info("Actions cache service feature is unavailable"); + return; + } try { await cache.saveCache(paths, key); } catch (error) { if (error instanceof Error) { core.info(error.message); } + core.warning( + "An internal error has occurred in cache backend. Please check https://www.githubstatus.com for any ongoing issue in actions.", + ); } } export async function restoreCygwinCache() { - await core.group("Retrieve the Cygwin cache", async () => { + return await core.group("Retrieve the Cygwin cache", async () => { const { key, restoreKeys } = await composeCygwinCacheKeys(); const paths = composeCygwinCachePaths(); - await restoreCache(key, restoreKeys, paths); + const cacheKey = await restoreCache(key, restoreKeys, paths); + return cacheKey; }); } @@ -218,10 +188,11 @@ export async function saveCygwinCache() { } export async function restoreDuneCache() { - await core.group("Retrieve the dune cache", async () => { + return await core.group("Retrieve the dune cache", async () => { const { key, restoreKeys } = composeDuneCacheKeys(); const paths = composeDuneCachePaths(); - await restoreCache(key, restoreKeys, paths); + const cacheKey = await restoreCache(key, restoreKeys, paths); + return cacheKey; }); } @@ -257,20 +228,3 @@ export async function saveOpamCache() { await saveCache(key, paths); }); } - -export async function restoreOpamDownloadCache() { - return await core.group("Retrieve the opam download cache", async () => { - const { key, restoreKeys } = composeOpamDownloadCacheKeys(); - const paths = composeOpamDownloadCachePaths(); - const cacheKey = await restoreCache(key, restoreKeys, paths); - return cacheKey; - }); -} - -export async function saveOpamDownloadCache() { - await core.group("Save the opam download cache", async () => { - const { key } = composeOpamDownloadCacheKeys(); - const paths = composeOpamDownloadCachePaths(); - await saveCache(key, paths); - }); -} diff --git a/packages/setup-ocaml/src/constants.ts b/packages/setup-ocaml/src/constants.ts index 1876da7d..0bacb55a 100644 --- a/packages/setup-ocaml/src/constants.ts +++ b/packages/setup-ocaml/src/constants.ts @@ -1,6 +1,5 @@ import * as os from "node:os"; import * as path from "node:path"; - import * as core from "@actions/core"; import * as yaml from "yaml"; @@ -27,7 +26,7 @@ export const PLATFORM = (() => { return "macos"; } case "win32": { - return "win32"; + return "windows"; } default: { throw new Error("The platform is not supported."); @@ -35,19 +34,24 @@ export const PLATFORM = (() => { } })(); -export const CYGWIN_ROOT = path.join("D:", "cygwin"); +export const CYGWIN_MIRROR = "https://cygwin.mirror.constant.com/"; -export const CYGWIN_ROOT_BIN = path.join(CYGWIN_ROOT, "bin"); +// [HACK] https://github.com/ocaml/setup-ocaml/pull/55 +export const CYGWIN_ROOT = path.join("D:", "cygwin"); -export const CYGWIN_ROOT_WRAPPERBIN = path.join(CYGWIN_ROOT, "wrapperbin"); +export const OPAM_ROOT = + PLATFORM === "windows" + ? // [HACK] https://github.com/ocaml/setup-ocaml/pull/55 + path.join("D:", ".opam") + : path.join(os.homedir(), ".opam"); -// [todo] remove the branch for Windows once opam 2.2 is released as stable. -export const ALLOW_PRERELEASE_OPAM = - PLATFORM !== "win32" && - core.getBooleanInput("allow-prerelease-opam", { +export const ALLOW_PRERELEASE_OPAM = core.getBooleanInput( + "allow-prerelease-opam", + { required: false, trimWhitespace: true, - }); + }, +); export const CACHE_PREFIX = core.getInput("cache-prefix", { required: false, @@ -69,24 +73,14 @@ export const OCAML_COMPILER = core.getInput("ocaml-compiler", { trimWhitespace: true, }); -// [todo] remove this once opam 2.2 is released as stable. -export const OPAM_DEPEXT = - !ALLOW_PRERELEASE_OPAM && - core.getBooleanInput("opam-depext", { - required: false, - trimWhitespace: true, - }); - -export const OPAM_DEPEXT_FLAGS = core - .getInput("opam-depext-flags", { required: false, trimWhitespace: true }) - .split(",") - .map((f) => f.trim()) - .filter((f) => f.length > 0); - -export const OPAM_DISABLE_SANDBOXING = core.getBooleanInput( - "opam-disable-sandboxing", - { required: false, trimWhitespace: true }, -); +export const OPAM_DISABLE_SANDBOXING = + // [TODO] unlock this once sandboxing is supported on Windows + PLATFORM === "windows" + ? true + : core.getBooleanInput("opam-disable-sandboxing", { + required: false, + trimWhitespace: true, + }); export const OPAM_LOCAL_PACKAGES = core.getInput("opam-local-packages", { required: false, @@ -98,15 +92,15 @@ export const OPAM_PIN = core.getBooleanInput("opam-pin", { trimWhitespace: true, }); -const repositories_yaml = yaml.parse( - core.getInput("opam-repositories", { required: false, trimWhitespace: true }), -) as Record | null; - -const defaultRepository = - PLATFORM === "win32" - ? "https://github.com/ocaml-opam/opam-repository-mingw.git#sunset" - : "https://github.com/ocaml/opam-repository.git"; - -export const OPAM_REPOSITORIES: [string, string][] = repositories_yaml - ? Object.entries(repositories_yaml).reverse() - : [["default", defaultRepository]]; +export const OPAM_REPOSITORIES: [string, string][] = (() => { + const repositories_yaml = yaml.parse( + core.getInput("opam-repositories", { + required: false, + trimWhitespace: true, + }), + ) as Record | null; + + return repositories_yaml + ? Object.entries(repositories_yaml).reverse() + : [["default", "https://github.com/ocaml/opam-repository.git"]]; +})(); diff --git a/packages/setup-ocaml/src/depext.ts b/packages/setup-ocaml/src/depext.ts deleted file mode 100644 index d92b4b0b..00000000 --- a/packages/setup-ocaml/src/depext.ts +++ /dev/null @@ -1,35 +0,0 @@ -import * as path from "node:path"; - -import * as core from "@actions/core"; -import { exec } from "@actions/exec"; - -import { OPAM_DEPEXT_FLAGS, PLATFORM } from "./constants.js"; - -export async function installDepext(ocamlVersion: string) { - await core.group("Install depext", async () => { - const depextCygwinports = - PLATFORM === "win32" ? ["depext-cygwinports"] : []; - await exec("opam", ["install", "opam-depext", ...depextCygwinports]); - if (PLATFORM === "win32") { - let base = ""; - if (ocamlVersion.includes("mingw64")) { - base = "x86_64-w64-mingw32"; - } else if (ocamlVersion.includes("mingw32")) { - base = "i686-w64-mingw32"; - } - core.addPath( - path.posix.join("/", "usr", base, "sys-root", "mingw", "bin"), - ); - } - }); -} - -export async function installDepextPackages(fpaths: string[]) { - await core.group( - "Install system packages required by opam packages", - async () => { - const fnames = fpaths.map((fpath) => path.basename(fpath, ".opam")); - await exec("opam", ["depext", ...fnames, ...OPAM_DEPEXT_FLAGS]); - }, - ); -} diff --git a/packages/setup-ocaml/src/dune.ts b/packages/setup-ocaml/src/dune.ts index 272903cf..2c3c49bd 100644 --- a/packages/setup-ocaml/src/dune.ts +++ b/packages/setup-ocaml/src/dune.ts @@ -1,8 +1,7 @@ import * as core from "@actions/core"; import { exec } from "@actions/exec"; import * as github from "@actions/github"; - -import { GITHUB_TOKEN, OPAM_DEPEXT } from "./constants.js"; +import { GITHUB_TOKEN } from "./constants.js"; const { repo: { owner, repo }, @@ -11,11 +10,7 @@ const { export async function installDune() { await core.group("Install dune", async () => { - if (OPAM_DEPEXT) { - await exec("opam", ["depext", "--install", "dune"]); - } else { - await exec("opam", ["install", "dune"]); - } + await exec("opam", ["install", "dune"]); }); } @@ -38,8 +33,7 @@ export async function trimDuneCache() { "dune", "cache", "trim", - "--size", - `${cacheSize}MB`, + `--size=${cacheSize}MB`, ]); }, ); diff --git a/packages/setup-ocaml/src/index.ts b/packages/setup-ocaml/src/index.ts index 862c066e..e13cee9a 100644 --- a/packages/setup-ocaml/src/index.ts +++ b/packages/setup-ocaml/src/index.ts @@ -1,7 +1,5 @@ import * as process from "node:process"; - import * as core from "@actions/core"; - import { installer } from "./installer.js"; async function run() { diff --git a/packages/setup-ocaml/src/installer.ts b/packages/setup-ocaml/src/installer.ts index 68ef64c1..3e271a0f 100644 --- a/packages/setup-ocaml/src/installer.ts +++ b/packages/setup-ocaml/src/installer.ts @@ -1,27 +1,22 @@ import * as os from "node:os"; -import * as path from "node:path"; import * as process from "node:process"; - import * as core from "@actions/core"; import { exec } from "@actions/exec"; - import { restoreCygwinCache, restoreDuneCache, restoreOpamCache, - restoreOpamDownloadCache, + saveCygwinCache, saveOpamCache, } from "./cache.js"; import { - ALLOW_PRERELEASE_OPAM, DUNE_CACHE, OCAML_COMPILER, - OPAM_DEPEXT, OPAM_PIN, OPAM_REPOSITORIES, + OPAM_ROOT, PLATFORM, } from "./constants.js"; -import { installDepext, installDepextPackages } from "./depext.js"; import { installDune } from "./dune.js"; import { installOcaml, @@ -31,36 +26,27 @@ import { setupOpam, } from "./opam.js"; import { getOpamLocalPackages } from "./packages.js"; -import { updateUnixPackageIndexFiles } from "./system.js"; import { resolveCompiler } from "./version.js"; +import { setupCygwin } from "./windows.js"; export async function installer() { if (core.isDebug()) { core.exportVariable("OPAMVERBOSE", 1); } - if (ALLOW_PRERELEASE_OPAM) { - core.exportVariable("OPAMCONFIRMLEVEL", "unsafe-yes"); - } else { - // [todo] remove this once opam 2.2 is released as stable. - // https://github.com/ocaml/setup-ocaml/issues/299 - core.exportVariable("OPAMCLI", "2.0"); - } core.exportVariable("OPAMCOLOR", "always"); + core.exportVariable("OPAMCONFIRMLEVEL", "unsafe-yes"); + core.exportVariable("OPAMDOWNLOADJOBS", os.cpus().length * 2); core.exportVariable("OPAMERRLOGLEN", 0); - core.exportVariable("OPAMJOBS", os.cpus().length); core.exportVariable("OPAMPRECISETRACKING", 1); - // [todo] remove this once opam 2.2 is released as stable. - // https://github.com/ocaml/opam/issues/3447 - core.exportVariable("OPAMSOLVERTIMEOUT", 1000); + core.exportVariable("OPAMROOT", OPAM_ROOT); core.exportVariable("OPAMYES", 1); - if (PLATFORM === "win32") { - const opamRoot = path.join("D:", ".opam"); - core.exportVariable("OPAMROOT", opamRoot); - } - if (PLATFORM === "win32") { + if (PLATFORM === "windows") { + core.exportVariable("CYGWIN", "winsymlinks:native"); + core.exportVariable("HOME", process.env.USERPROFILE); + core.exportVariable("MSYS", "winsymlinks:native"); await core.group("Change the file system behavior parameters", async () => { await exec("fsutil", ["behavior", "query", "SymlinkEvaluation"]); - // https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/fsutil-behavior + // [INFO] https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/fsutil-behavior await exec("fsutil", [ "behavior", "set", @@ -70,13 +56,11 @@ export async function installer() { ]); await exec("fsutil", ["behavior", "query", "SymlinkEvaluation"]); }); - } - if (PLATFORM === "win32") { - core.exportVariable("HOME", process.env["USERPROFILE"]); - core.exportVariable("MSYS", "winsymlinks:native"); - } - if (PLATFORM === "win32") { - await restoreCygwinCache(); + const cygwinCacheHit = await restoreCygwinCache(); + if (!cygwinCacheHit) { + await setupCygwin(); + await saveCygwinCache(); + } } const opamCacheHit = await restoreOpamCache(); await setupOpam(); @@ -87,10 +71,6 @@ export async function installer() { await installOcaml(ocamlCompiler); await saveOpamCache(); } - await restoreOpamDownloadCache(); - if (OPAM_DEPEXT) { - await installDepext(ocamlCompiler); - } if (DUNE_CACHE) { await restoreDuneCache(); await installDune(); @@ -104,23 +84,7 @@ export async function installer() { if (OPAM_PIN) { await pin(fnames); } - if (OPAM_DEPEXT) { - try { - await installDepextPackages(fnames); - } catch (error) { - if (error instanceof Error) { - core.notice( - `An error has been caught in some system package index files, so the system package index files have been re-synchronised, and the system package installation has been retried: ${error.message.toLocaleLowerCase()}`, - ); - } - await updateUnixPackageIndexFiles(); - await installDepextPackages(fnames); - } - } } await exec("opam", ["--version"]); - if (OPAM_DEPEXT) { - await exec("opam", ["depext", "--version"]); - } await exec("opam", ["exec", "--", "ocaml", "-version"]); } diff --git a/packages/setup-ocaml/src/opam.ts b/packages/setup-ocaml/src/opam.ts index a1f33bde..a3e8bdfc 100644 --- a/packages/setup-ocaml/src/opam.ts +++ b/packages/setup-ocaml/src/opam.ts @@ -1,34 +1,26 @@ import { promises as fs } from "node:fs"; -import * as os from "node:os"; import * as path from "node:path"; -import * as process from "node:process"; - import * as core from "@actions/core"; import { exec, getExecOutput } from "@actions/exec"; import * as github from "@actions/github"; -import * as io from "@actions/io"; import * as toolCache from "@actions/tool-cache"; import * as semver from "semver"; -import { saveCygwinCache } from "./cache.js"; import { ALLOW_PRERELEASE_OPAM, ARCHITECTURE, CYGWIN_ROOT, - CYGWIN_ROOT_BIN, - CYGWIN_ROOT_WRAPPERBIN, GITHUB_TOKEN, OPAM_DISABLE_SANDBOXING, PLATFORM, } from "./constants.js"; import { - getSystemIdentificationInfo, + installUnixSystemPackages, updateUnixPackageIndexFiles, -} from "./system.js"; -import { getCygwinVersion } from "./win32.js"; +} from "./unix.js"; export async function getLatestOpamRelease() { - const semverRange = ALLOW_PRERELEASE_OPAM ? "*" : "<2.2.0"; + const semverRange = ALLOW_PRERELEASE_OPAM ? "*" : "<2.3.0"; const octokit = github.getOctokit(GITHUB_TOKEN); const { data: releases } = await octokit.rest.repos.listReleases({ owner: "ocaml", @@ -64,30 +56,22 @@ export async function getLatestOpamRelease() { }; } -async function findOpam() { - if (PLATFORM === "win32") { - const opamPath = path.join(CYGWIN_ROOT, "bin", "opam.exe"); - return opamPath; - } - const opamPath = await io.which("opam"); - return opamPath; -} - -async function acquireOpamUnix() { +async function acquireOpam() { const { version, browserDownloadUrl } = await getLatestOpamRelease(); const cachedPath = toolCache.find("opam", version, ARCHITECTURE); + const opam = PLATFORM !== "windows" ? "opam" : "opam.exe"; if (cachedPath === "") { const downloadedPath = await toolCache.downloadTool(browserDownloadUrl); core.info(`Acquired ${version} from ${browserDownloadUrl}`); const cachedPath = await toolCache.cacheFile( downloadedPath, - "opam", + opam, "opam", version, ARCHITECTURE, ); core.info(`Successfully cached opam to ${cachedPath}`); - await fs.chmod(`${cachedPath}/opam`, 0o755); + await fs.chmod(path.join(cachedPath, opam), 0o755); core.addPath(cachedPath); core.info("Added opam to the path"); } else { @@ -96,223 +80,64 @@ async function acquireOpamUnix() { } } -async function installUnixSystemPackages() { - const isGitHubRunner = process.env["GITHUB_ACTIONS"] === "true"; - if (isGitHubRunner) { - if (PLATFORM === "linux") { - const { version: systemVersion } = await getSystemIdentificationInfo(); - if (systemVersion === "18.04") { - // [info]: musl-tools bug in ubuntu 18.04; - // - await exec("sudo", ["add-apt-repository", "ppa:avsm/musl"]); +async function initializeOpam() { + if (PLATFORM !== "windows") { + try { + await installUnixSystemPackages(); + } catch (error) { + if (error instanceof Error) { + core.notice( + `An error has been caught in some system package index files, so the system package index files have been re-synchronised, and the system package installation has been retried: ${error.message.toLocaleLowerCase()}`, + ); } - await exec("sudo", [ - "apt-get", - "--yes", - "install", - "bubblewrap", - "darcs", - "g++-multilib", - "gcc-multilib", - "mercurial", - "musl-tools", - "rsync", - ]); - } else if (PLATFORM === "macos") { - await exec("brew", ["install", "darcs", "gpatch", "mercurial"]); + await updateUnixPackageIndexFiles(); + await installUnixSystemPackages(); } } -} - -async function initializeOpamUnix() { - try { - await installUnixSystemPackages(); - } catch (error) { - if (error instanceof Error) { - core.notice( - `An error has been caught in some system package index files, so the system package index files have been re-synchronised, and the system package installation has been retried: ${error.message.toLocaleLowerCase()}`, - ); - } - await updateUnixPackageIndexFiles(); - await installUnixSystemPackages(); + const extraOptions = []; + if (PLATFORM === "windows") { + extraOptions.push("--cygwin-local-install"); + extraOptions.push(`--cygwin-location=${CYGWIN_ROOT}`); } - const disableSandboxing = []; if (OPAM_DISABLE_SANDBOXING) { - disableSandboxing.push("--disable-sandboxing"); + extraOptions.push("--disable-sandboxing"); } await exec("opam", [ "init", "--auto-setup", "--bare", - ...disableSandboxing, + ...extraOptions, "--enable-shell-hook", ]); } -async function setupOpamUnix() { - await core.group("Install opam", async () => { - await acquireOpamUnix(); - }); - await core.group("Initialise the opam state", async () => { - await initializeOpamUnix(); - }); -} - -async function setupCygwin() { - const version = await getCygwinVersion(); - const cachedPath = toolCache.find("cygwin", version, "x86_64"); - if (cachedPath === "") { - const downloadedPath = await toolCache.downloadTool( - "https://cygwin.com/setup-x86_64.exe", - ); - const cachedPath = await toolCache.cacheFile( - downloadedPath, - "setup-x86_64.exe", - "cygwin", - version, - "x86_64", - ); - core.addPath(cachedPath); - } else { - core.addPath(cachedPath); - } - const site = "https://mirrors.kernel.org/sourceware/cygwin"; - const packages = [ - "curl", - "diffutils", - "m4", - "make", - "mingw64-i686-gcc-core", - "mingw64-i686-gcc-g++", - "mingw64-x86_64-gcc-core", - "mingw64-x86_64-gcc-g++", - "patch", - "perl", - "rsync", - "unzip", - ].join(","); - await exec("setup-x86_64.exe", [ - "--quiet-mode", - "--root", - CYGWIN_ROOT, - "--site", - site, - "--packages", - packages, - "--symlink-type=sys", - ]); - const setupExePath = await io.which("setup-x86_64.exe"); - await io.cp(setupExePath, CYGWIN_ROOT); -} - -async function acquireOpamWindows() { - const opamVersion = "0.0.0.2"; - const cachedPath = toolCache.find("opam", opamVersion); - if (cachedPath === "") { - const downloadedPath = await toolCache.downloadTool( - `https://github.com/fdopen/opam-repository-mingw/releases/download/${opamVersion}/opam64.zip`, - ); - const extractedPath = await toolCache.extractZip(downloadedPath); - const cachedPath = await toolCache.cacheDir( - extractedPath, - "opam", - opamVersion, - ); - const installSh = path.join(cachedPath, "opam64", "install.sh"); - await fs.chmod(installSh, 0o755); - await exec("bash", [installSh, "--prefix", "/usr"]); - } else { - const installSh = path.join(cachedPath, "opam64", "install.sh"); - await fs.chmod(installSh, 0o755); - await exec("bash", [installSh, "--prefix", "/usr"]); - } -} - -async function initializeOpamWindows() { - await exec("git", ["config", "--global", "--add", "safe.directory", "'*'"]); - await exec("opam", [ - "init", - "--auto-setup", - "--bare", - "--disable-sandboxing", - "--enable-shell-hook", - ]); - await io.mkdirP(CYGWIN_ROOT_WRAPPERBIN); - const opamCmd = path.join(CYGWIN_ROOT_WRAPPERBIN, "opam.cmd"); - const data = [ - "@setlocal", - "@echo off", - "set PATH=%CYGWIN_ROOT_BIN%;%PATH%", - "ocaml-env exec -- opam.exe %*", - ].join(os.EOL); - await fs.writeFile(opamCmd, data, { mode: 0o755 }); -} - -async function setupOpamWindows() { - await core.group("Prepare the Cygwin environment", async () => { - core.exportVariable("CYGWIN", "winsymlinks:native"); - core.exportVariable("CYGWIN_ROOT", CYGWIN_ROOT); - core.exportVariable("CYGWIN_ROOT_BIN", CYGWIN_ROOT_BIN); - core.exportVariable("CYGWIN_ROOT_WRAPPERBIN", CYGWIN_ROOT_WRAPPERBIN); - core.addPath(CYGWIN_ROOT_WRAPPERBIN); - await setupCygwin(); - }); - await saveCygwinCache(); - const originalPath = process.env["PATH"]?.split(path.delimiter) ?? []; - const patchedPath = [CYGWIN_ROOT_BIN, ...originalPath]; - process.env["PATH"] = patchedPath.join(path.delimiter); +export async function setupOpam() { await core.group("Install opam", async () => { - await acquireOpamWindows(); + await acquireOpam(); }); await core.group("Initialise the opam state", async () => { - await initializeOpamWindows(); + await initializeOpam(); }); - process.env["PATH"] = originalPath.join(path.delimiter); -} - -export async function setupOpam() { - if (PLATFORM === "win32") { - await setupOpamWindows(); - } else { - await setupOpamUnix(); - } } export async function installOcaml(ocamlCompiler: string) { await core.group("Install OCaml", async () => { - if (PLATFORM === "win32") { - const originalPath = process.env["PATH"]?.split(path.delimiter) ?? []; - const patchedPath = [CYGWIN_ROOT_BIN, ...originalPath]; - process.env["PATH"] = patchedPath.join(path.delimiter); - await exec("opam", [ - "switch", - "create", - ".", - "--no-install", - "--packages", - ocamlCompiler, - ]); - process.env["PATH"] = originalPath.join(path.delimiter); - } else { - await exec("opam", [ - "switch", - "create", - ".", - "--no-install", - "--packages", - ocamlCompiler, - ]); - } + await exec("opam", [ + "switch", + "--no-install", + `--packages=${ocamlCompiler}`, + "create", + ".", + ]); }); } export async function pin(fpaths: string[]) { await core.group("Pin local packages", async () => { - const opam = await findOpam(); for (const fpath of fpaths) { const fname = path.basename(fpath, ".opam"); const dname = path.dirname(fpath); - await exec(opam, ["pin", "add", `${fname}.dev`, ".", "--no-action"], { + await exec("opam", ["pin", "--no-action", "add", `${fname}.dev`, "."], { cwd: dname, }); } @@ -320,65 +145,33 @@ export async function pin(fpaths: string[]) { } async function repositoryAdd(name: string, address: string) { - const opam = await findOpam(); - await exec(opam, [ + await exec("opam", [ "repository", + "--all-switches", + "--set-default", "add", name, address, - "--all-switches", - "--set-default", ]); } export async function repositoryAddAll(repositories: [string, string][]) { await core.group("Initialise the opam repositories", async () => { - let restore_autocrlf: string | null | undefined = undefined; - // Works around the lack of https://github.com/ocaml/opam/pull/3882 when - // adding ocaml/opam-repository on Windows. Can be removed when the action - // switches to opam 2.2 - if (PLATFORM === "win32") { - const autocrlf = await getExecOutput( - "git", - ["config", "--global", "core.autocrlf"], - { ignoreReturnCode: true }, - ); - if (autocrlf.stdout.trim() !== "input") { - if (autocrlf.exitCode === 0) { - restore_autocrlf = autocrlf.stdout.trim(); - } else { - restore_autocrlf = null; // Unset the value at the end - } - } - await exec("git", ["config", "--global", "core.autocrlf", "input"]); - } for (const [name, address] of repositories) { await repositoryAdd(name, address); } - if (restore_autocrlf === null) { - await exec("git", ["config", "--global", "--unset", "core.autocrlf"]); - } else if (restore_autocrlf !== undefined) { - await exec("git", [ - "config", - "--global", - "core.autocrlf", - restore_autocrlf, - ]); - } }); } async function repositoryRemove(name: string) { - const opam = await findOpam(); - await exec(opam, ["repository", "remove", name, "--all-switches"]); + await exec("opam", ["repository", "--all-switches", "remove", name]); } async function repositoryList() { - const opam = await findOpam(); const repositoryList = await getExecOutput( - opam, - ["repository", "list", "--all-switches", "--short"], - { ignoreReturnCode: true }, + "opam", + ["repository", "--all-switches", "--short", "list"], + { ignoreReturnCode: true, silent: true }, ); if (repositoryList.exitCode === 0) { return repositoryList.stdout diff --git a/packages/setup-ocaml/src/packages.ts b/packages/setup-ocaml/src/packages.ts index bebf22b5..a3e1ba1e 100644 --- a/packages/setup-ocaml/src/packages.ts +++ b/packages/setup-ocaml/src/packages.ts @@ -1,5 +1,4 @@ import * as glob from "@actions/glob"; - import { OPAM_LOCAL_PACKAGES } from "./constants.js"; export async function getOpamLocalPackages() { diff --git a/packages/setup-ocaml/src/post.ts b/packages/setup-ocaml/src/post.ts index 28f04dd8..a2269e4a 100644 --- a/packages/setup-ocaml/src/post.ts +++ b/packages/setup-ocaml/src/post.ts @@ -1,8 +1,6 @@ import * as process from "node:process"; - import * as core from "@actions/core"; - -import { saveDuneCache, saveOpamDownloadCache } from "./cache.js"; +import { saveDuneCache } from "./cache.js"; import { DUNE_CACHE } from "./constants.js"; import { trimDuneCache } from "./dune.js"; @@ -12,7 +10,6 @@ async function run() { await trimDuneCache(); await saveDuneCache(); } - await saveOpamDownloadCache(); process.exit(0); } catch (error) { if (error instanceof Error) { diff --git a/packages/setup-ocaml/src/system.ts b/packages/setup-ocaml/src/system.ts index 9f38dc3f..5dc876b9 100644 --- a/packages/setup-ocaml/src/system.ts +++ b/packages/setup-ocaml/src/system.ts @@ -1,8 +1,6 @@ import { promises as fs } from "node:fs"; import * as os from "node:os"; - -import { exec, getExecOutput } from "@actions/exec"; - +import { getExecOutput } from "@actions/exec"; import { PLATFORM } from "./constants.js"; export async function getSystemIdentificationInfo() { @@ -22,7 +20,7 @@ export async function getSystemIdentificationInfo() { return { id, version }; } if (PLATFORM === "macos") { - const swVers = await getExecOutput("sw_vers"); + const swVers = await getExecOutput("sw_vers", [], { silent: true }); const lines = swVers.stdout.split(os.EOL); let version = ""; for (const line of lines) { @@ -35,14 +33,3 @@ export async function getSystemIdentificationInfo() { } throw new Error("The system is not supported."); } - -export async function updateUnixPackageIndexFiles() { - const isGitHubRunner = process.env["GITHUB_ACTIONS"] === "true"; - if (isGitHubRunner) { - if (PLATFORM === "linux") { - await exec("sudo", ["apt-get", "update"]); - } else if (PLATFORM === "macos") { - await exec("brew", ["update"]); - } - } -} diff --git a/packages/setup-ocaml/src/unix.ts b/packages/setup-ocaml/src/unix.ts new file mode 100644 index 00000000..c762ef17 --- /dev/null +++ b/packages/setup-ocaml/src/unix.ts @@ -0,0 +1,42 @@ +import * as process from "node:process"; +import { exec } from "@actions/exec"; +import { PLATFORM } from "./constants.js"; +import { getSystemIdentificationInfo } from "./system.js"; + +export async function installUnixSystemPackages() { + const isGitHubRunner = process.env.GITHUB_ACTIONS === "true"; + if (isGitHubRunner) { + if (PLATFORM === "linux") { + const { version: systemVersion } = await getSystemIdentificationInfo(); + if (systemVersion === "18.04") { + // [INFO]: musl-tools bug in ubuntu 18.04 https://github.com/ocaml/ocaml/issues/9131#issuecomment-599765888 + await exec("sudo", ["add-apt-repository", "ppa:avsm/musl"]); + } + await exec("sudo", [ + "apt-get", + "--yes", + "install", + "bubblewrap", + "darcs", + "g++-multilib", + "gcc-multilib", + "mercurial", + "musl-tools", + "rsync", + ]); + } else if (PLATFORM === "macos") { + await exec("brew", ["install", "darcs", "gpatch", "mercurial"]); + } + } +} + +export async function updateUnixPackageIndexFiles() { + const isGitHubRunner = process.env.GITHUB_ACTIONS === "true"; + if (isGitHubRunner) { + if (PLATFORM === "linux") { + await exec("sudo", ["apt-get", "update"]); + } else if (PLATFORM === "macos") { + await exec("brew", ["update"]); + } + } +} diff --git a/packages/setup-ocaml/src/version.ts b/packages/setup-ocaml/src/version.ts index 5be82618..727f9d49 100644 --- a/packages/setup-ocaml/src/version.ts +++ b/packages/setup-ocaml/src/version.ts @@ -1,37 +1,24 @@ import * as path from "node:path"; - import * as github from "@actions/github"; import * as semver from "semver"; - -import { GITHUB_TOKEN, PLATFORM } from "./constants.js"; +import { GITHUB_TOKEN } from "./constants.js"; function isSemverValidRange(semverVersion: string) { - const isValidSemver = - semver.validRange(semverVersion, { loose: true }) !== null; - // [NOTE] explicitly deny compilers like "4.14.0+mingw64c" as invalid semver - // syntax even though it's valid... - const plus = !semverVersion.includes("+"); - return isValidSemver && plus; + return semver.validRange(semverVersion, { loose: true }) !== null; } async function getAllCompilerVersions() { const octokit = github.getOctokit(GITHUB_TOKEN); - - const owner = PLATFORM === "win32" ? "ocaml-opam" : "ocaml"; - const repo = - PLATFORM === "win32" ? "opam-repository-mingw" : "opam-repository"; - const prefix = - PLATFORM === "win32" ? "ocaml-variants" : "ocaml-base-compiler"; const { data: packages } = await octokit.rest.repos.getContent({ - owner, - repo, - path: `packages/${prefix}`, + owner: "ocaml", + repo: "opam-repository", + path: "packages/ocaml-base-compiler", }); const versions = new Set(); if (Array.isArray(packages)) { for (const { path: p } of packages) { const basename = path.basename(p); - const version = basename.replace(`${prefix}.`, ""); + const version = basename.replace("ocaml-base-compiler.", ""); const parsed = semver.parse(version, { loose: true }); if (parsed !== null) { const { major, minor: _minor, patch } = parsed; @@ -61,9 +48,7 @@ async function resolveVersion(semverVersion: string) { export async function resolveCompiler(compiler: string) { const resolvedCompiler = isSemverValidRange(compiler) - ? PLATFORM === "win32" - ? `ocaml-variants.${await resolveVersion(compiler)}+mingw64c` - : `ocaml-base-compiler.${await resolveVersion(compiler)}` + ? `ocaml-base-compiler.${await resolveVersion(compiler)}` : compiler; return resolvedCompiler; } diff --git a/packages/setup-ocaml/src/win32.ts b/packages/setup-ocaml/src/win32.ts deleted file mode 100644 index ecc37db4..00000000 --- a/packages/setup-ocaml/src/win32.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { HttpClient } from "@actions/http-client"; -import * as cheerio from "cheerio"; -import * as semver from "semver"; - -function createHttpClient() { - return new HttpClient( - "OCamlBot (+https://github.com/ocaml/setup-ocaml)", - [], - { allowRetries: true, maxRetries: 5 }, - ); -} - -export async function getCygwinVersion() { - const httpClient = createHttpClient(); - const response = await httpClient.get("https://www.cygwin.com"); - const body = await response.readBody(); - const $ = cheerio.load(body); - let version = ""; - $("a").each((_index, element) => { - const text = $(element).text(); - if (semver.valid(text) === text) { - version = text; - } - }); - return version; -} diff --git a/packages/setup-ocaml/src/windows.ts b/packages/setup-ocaml/src/windows.ts new file mode 100644 index 00000000..666f20c3 --- /dev/null +++ b/packages/setup-ocaml/src/windows.ts @@ -0,0 +1,76 @@ +import * as core from "@actions/core"; +import { exec } from "@actions/exec"; +import { HttpClient } from "@actions/http-client"; +import * as io from "@actions/io"; +import * as toolCache from "@actions/tool-cache"; +import * as cheerio from "cheerio"; +import * as semver from "semver"; +import { CYGWIN_MIRROR, CYGWIN_ROOT } from "./constants.js"; + +function createHttpClient() { + return new HttpClient( + "OCamlBot (+https://github.com/ocaml/setup-ocaml)", + [], + { allowRetries: true, maxRetries: 5 }, + ); +} + +export async function getCygwinVersion() { + const httpClient = createHttpClient(); + const response = await httpClient.get("https://www.cygwin.com"); + const body = await response.readBody(); + const $ = cheerio.load(body); + let version = ""; + $("a").each((_index, element) => { + const text = $(element).text(); + if (semver.valid(text) === text) { + version = text; + } + }); + return version; +} + +export async function setupCygwin() { + await core.group("Prepare the Cygwin environment", async () => { + const version = await getCygwinVersion(); + const cachedPath = toolCache.find("cygwin", version, "x86_64"); + if (cachedPath === "") { + const downloadedPath = await toolCache.downloadTool( + "https://cygwin.com/setup-x86_64.exe", + ); + const cachedPath = await toolCache.cacheFile( + downloadedPath, + "setup-x86_64.exe", + "cygwin", + version, + "x86_64", + ); + core.addPath(cachedPath); + } else { + core.addPath(cachedPath); + } + const packages = [ + "curl", + "diffutils", + "m4", + "make", + "mingw64-i686-gcc-core", + "mingw64-i686-gcc-g++", + "mingw64-x86_64-gcc-core", + "mingw64-x86_64-gcc-g++", + "patch", + "perl", + "rsync", + "unzip", + ].join(","); + await exec("setup-x86_64", [ + `--packages=${packages}`, + "--quiet-mode", + `--root=${CYGWIN_ROOT}`, + `--site=${CYGWIN_MIRROR}`, + "--symlink-type=sys", + ]); + const setup = await io.which("setup-x86_64"); + await io.cp(setup, CYGWIN_ROOT); + }); +} diff --git a/packages/setup-ocaml/tsconfig.json b/packages/setup-ocaml/tsconfig.json index 8c14d0c2..d963b5da 100644 --- a/packages/setup-ocaml/tsconfig.json +++ b/packages/setup-ocaml/tsconfig.json @@ -9,7 +9,7 @@ "moduleDetection": "force", "moduleResolution": "Bundler", "noEmit": true, + "noPropertyAccessFromIndexSignature": false, "verbatimModuleSyntax": true - }, - "exclude": ["node_modules"] + } }