diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 00000000..78770b39 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @conda-forge/miniforge diff --git a/.github/actions/autoupdate/environment.yml b/.github/actions/autoupdate/environment.yml new file mode 100644 index 00000000..a10ef35a --- /dev/null +++ b/.github/actions/autoupdate/environment.yml @@ -0,0 +1,7 @@ +name: miniconda-autoupdate +channels: + - conda-forge + - nodefaults +dependencies: + - packaging + - requests diff --git a/.github/actions/autoupdate/update.py b/.github/actions/autoupdate/update.py new file mode 100644 index 00000000..66b3e44d --- /dev/null +++ b/.github/actions/autoupdate/update.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python + +import re +import requests +from packaging import version + +def get_most_recent_version(name): + request = requests.get( + "https://api.anaconda.org/package/conda-forge/" + name + ) + request.raise_for_status() + + pkg = max( + request.json()["files"], key=lambda x: version.parse(x["version"]) + ) + return pkg["version"] + +mamba_version = get_most_recent_version("mamba") + +with open("Miniforge3/construct.yaml", "r") as f: + content = f.read() + +# Replace mamba version +content = re.sub(r"mamba [\d.]+$", f"mamba {mamba_version}", content, flags=re.M) + +with open("Miniforge3/construct.yaml", "w") as f: + f.write(content) diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..5ace4600 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" diff --git a/.github/shellcheck-matcher.json b/.github/shellcheck-matcher.json new file mode 100644 index 00000000..1c8be36f --- /dev/null +++ b/.github/shellcheck-matcher.json @@ -0,0 +1,17 @@ +{ + "problemMatcher": [ + { + "owner": "shellcheck", + "pattern": [ + { + "regexp": "^(.+):(\\d+):(\\d+):\\s(note|warning|error):\\s(.*)\\s\\[(SC\\d+)\\]$", + "file": 1, + "line": 2, + "column": 3, + "message": 5, + "code": 6 + } + ] + } + ] +} diff --git a/.github/workflows/autoupdate.yml b/.github/workflows/autoupdate.yml new file mode 100644 index 00000000..2a7cd1ed --- /dev/null +++ b/.github/workflows/autoupdate.yml @@ -0,0 +1,32 @@ +name: Auto-update mamba +on: + schedule: + - cron: "0 */6 * * *" +jobs: + createPullRequest: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + ssh-key: ${{ secrets.MINIFORGE_AUTOUPDATE_SSH_PRIVATE_KEY }} + - uses: conda-incubator/setup-miniconda@35d1405e78aa3f784fe3ce9a2eb378d5eeb62169 + with: + miniforge-variant: Miniforge3 + environment-file: .github/actions/autoupdate/environment.yml + - run: python .github/actions/autoupdate/update.py + - name: Create Pull Request + id: cpr + # This is the v3 tag but for security purposes we pin to the exact commit. + uses: peter-evans/create-pull-request@18f90432bedd2afd6a825469ffd38aa24712a91d + with: + commit-message: "Update mamba version" + title: "Update mamba version" + body: | + This PR was created by the autoupdate action as it detected that + the mamba version has changed and thus should be updated + in the configuration. + + Due to limitations of Github Actions, you will need to close/reopen + the PR to get the actions running. + branch: autoupdate-action + delete-branch: true diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 35b417d5..e39019ba 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,46 +11,67 @@ jobs: include: # - os: windows-latest # ARCH: x86_64 + # TARGET_PLATFORM: win-64 # MINIFORGE_NAME: "Miniforge3" # OS_NAME: "Windows" # - os: windows-latest # ARCH: x86_64 + # TARGET_PLATFORM: win-64 # MINIFORGE_NAME: "Mambaforge" # OS_NAME: "Windows" + # - os: windows-latest + # ARCH: x86_64 + # TARGET_PLATFORM: win-64 + # MINIFORGE_NAME: "Miniforge-pypy3" + # OS_NAME: "Windows" + + # - os: windows-latest + # ARCH: x86_64 + # TARGET_PLATFORM: win-64 + # MINIFORGE_NAME: "Mambaforge-pypy3" + # OS_NAME: "Windows" + # - os: macos-latest # ARCH: arm64 + # TARGET_PLATFORM: osx-arm64 # MINIFORGE_NAME: "Miniforge3" # OS_NAME: "MacOSX" # - os: macos-latest # ARCH: arm64 + # TARGET_PLATFORM: osx-arm64 # MINIFORGE_NAME: "Mambaforge" # OS_NAME: "MacOSX" # - os: macos-latest # ARCH: x86_64 + # TARGET_PLATFORM: osx-64 # MINIFORGE_NAME: "Miniforge-pypy3" # OS_NAME: "MacOSX" # - os: macos-latest # ARCH: x86_64 + # TARGET_PLATFORM: osx-64 # MINIFORGE_NAME: "Mambaforge-pypy3" # OS_NAME: "MacOSX" # - os: macos-latest # ARCH: x86_64 + # TARGET_PLATFORM: osx-64 # MINIFORGE_NAME: "Miniforge3" # OS_NAME: "MacOSX" # - os: macos-latest # ARCH: x86_64 + # TARGET_PLATFORM: osx-64 # MINIFORGE_NAME: "Mambaforge" # OS_NAME: "MacOSX" # - os: ubuntu-latest # ARCH: aarch64 + # TARGET_PLATFORM: linux-aarch64 # DOCKER_ARCH: arm64v8 # DOCKERIMAGE: condaforge/linux-anvil-aarch64 # MINIFORGE_NAME: "Miniforge3" @@ -58,27 +79,31 @@ jobs: # - os: ubuntu-latest # ARCH: aarch64 + # TARGET_PLATFORM: linux-aarch64 # DOCKER_ARCH: arm64v8 # DOCKERIMAGE: condaforge/linux-anvil-aarch64 # MINIFORGE_NAME: "Mambaforge" # OS_NAME: "Linux" - # - os: ubuntu-latest - # ARCH: x86_64 - # DOCKER_ARCH: amd64 - # DOCKERIMAGE: condaforge/linux-anvil-comp7 - # MINIFORGE_NAME: "Miniforge3" - # OS_NAME: "Linux" + - os: ubuntu-latest + ARCH: x86_64 + TARGET_PLATFORM: linux-64 + DOCKER_ARCH: amd64 + DOCKERIMAGE: condaforge/linux-anvil-comp7 + MINIFORGE_NAME: "Mambaforge-colab" + OS_NAME: "Linux" - # - os: ubuntu-latest - # ARCH: x86_64 - # DOCKER_ARCH: amd64 - # DOCKERIMAGE: condaforge/linux-anvil-comp7 - # MINIFORGE_NAME: "Mambaforge" - # OS_NAME: "Linux" + - os: ubuntu-latest + ARCH: x86_64 + TARGET_PLATFORM: linux-64 + DOCKER_ARCH: amd64 + DOCKERIMAGE: condaforge/linux-anvil-comp7 + MINIFORGE_NAME: "Miniforge-colab" + OS_NAME: "Linux" # - os: ubuntu-latest # ARCH: ppc64le + # TARGET_PLATFORM: linux-ppc64le # DOCKER_ARCH: ppc64le # DOCKERIMAGE: condaforge/linux-anvil-ppc64le # MINIFORGE_NAME: "Miniforge3" @@ -86,6 +111,7 @@ jobs: # - os: ubuntu-latest # ARCH: ppc64le + # TARGET_PLATFORM: linux-ppc64le # DOCKER_ARCH: ppc64le # DOCKERIMAGE: condaforge/linux-anvil-ppc64le # MINIFORGE_NAME: "Mambaforge" @@ -93,6 +119,7 @@ jobs: # - os: ubuntu-latest # ARCH: aarch64 + # TARGET_PLATFORM: linux-aarch64 # DOCKER_ARCH: arm64v8 # DOCKERIMAGE: condaforge/linux-anvil-aarch64 # MINIFORGE_NAME: "Miniforge-pypy3" @@ -100,6 +127,7 @@ jobs: # - os: ubuntu-latest # ARCH: aarch64 + # TARGET_PLATFORM: linux-aarch64 # DOCKER_ARCH: arm64v8 # DOCKERIMAGE: condaforge/linux-anvil-aarch64 # MINIFORGE_NAME: "Mambaforge-pypy3" @@ -107,6 +135,7 @@ jobs: # - os: ubuntu-latest # ARCH: x86_64 + # TARGET_PLATFORM: linux-64 # DOCKER_ARCH: amd64 # DOCKERIMAGE: condaforge/linux-anvil-comp7 # MINIFORGE_NAME: "Miniforge-pypy3" @@ -114,6 +143,7 @@ jobs: # - os: ubuntu-latest # ARCH: x86_64 + # TARGET_PLATFORM: linux-64 # DOCKER_ARCH: amd64 # DOCKERIMAGE: condaforge/linux-anvil-comp7 # MINIFORGE_NAME: "Mambaforge-pypy3" @@ -121,6 +151,7 @@ jobs: # - os: ubuntu-latest # ARCH: ppc64le + # TARGET_PLATFORM: linux-ppc64le # DOCKER_ARCH: ppc64le # DOCKERIMAGE: condaforge/linux-anvil-ppc64le # MINIFORGE_NAME: "Miniforge-pypy3" @@ -128,30 +159,17 @@ jobs: # - os: ubuntu-latest # ARCH: ppc64le + # TARGET_PLATFORM: linux-ppc64le # DOCKER_ARCH: ppc64le # DOCKERIMAGE: condaforge/linux-anvil-ppc64le # MINIFORGE_NAME: "Mambaforge-pypy3" # OS_NAME: "Linux" - - os: ubuntu-latest - ARCH: x86_64 - DOCKER_ARCH: amd64 - DOCKERIMAGE: condaforge/linux-anvil-comp7 - MINIFORGE_NAME: "Mambaforge-colab" - OS_NAME: "Linux" - - - os: ubuntu-latest - ARCH: x86_64 - DOCKER_ARCH: amd64 - DOCKERIMAGE: condaforge/linux-anvil-comp7 - MINIFORGE_NAME: "Miniforge-colab" - OS_NAME: "Linux" - steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v3 - - uses: conda-incubator/setup-miniconda@v2 + - uses: conda-incubator/setup-miniconda@35d1405e78aa3f784fe3ce9a2eb378d5eeb62169 with: miniconda-version: "latest" if: contains(matrix.OS_NAME, 'Windows') @@ -163,28 +181,40 @@ jobs: OS_NAME: ${{ matrix.OS_NAME }} DOCKERIMAGE: ${{ matrix.DOCKERIMAGE }} DOCKER_ARCH: ${{ matrix.DOCKER_ARCH }} + TARGET_PLATFORM: ${{ matrix.TARGET_PLATFORM }} run: | if [[ "$GITHUB_REF" == refs/tags/* ]]; then export MINIFORGE_VERSION=${GITHUB_REF##*/}; fi if [[ "$OS_NAME" == "Linux" ]]; then + export EXT=sh bash build_miniforge.sh; - EXT=sh fi if [[ "$OS_NAME" == "MacOSX" ]]; then + export EXT=sh bash build_miniforge_osx.sh; - EXT=sh fi if [[ "$OS_NAME" == "Windows" ]]; then + export EXT=exe + echo "WINDIR:$WINDIR" source /c/Miniconda3/Scripts/activate; source build_miniforge_win.sh; - EXT=exe fi # Copy for latest release cp build/$MINIFORGE_NAME-*-$OS_NAME-$ARCH.$EXT build/$MINIFORGE_NAME-$OS_NAME-$ARCH.$EXT + if [[ "$OS_NAME" == "MacOSX" ]]; then + cp build/$MINIFORGE_NAME-*-$OS_NAME-$ARCH.$EXT build/$MINIFORGE_NAME-Darwin-$ARCH.$EXT + fi ls -alh build shell: bash + - name: Upload miniforge to Github artifact + if: always() + uses: actions/upload-artifact@v3 + with: + path: build/${{ matrix.MINIFORGE_NAME }}-${{ matrix.OS_NAME }}-${{ matrix.ARCH }}* + name: ${{ matrix.MINIFORGE_NAME }}-${{ matrix.OS_NAME }}-${{ matrix.ARCH }} + - name: Upload miniforge to release uses: svenstaro/upload-release-action@v2 with: diff --git a/.github/workflows/conda_release.js b/.github/workflows/conda_release.js new file mode 100644 index 00000000..f5b23b2f --- /dev/null +++ b/.github/workflows/conda_release.js @@ -0,0 +1,72 @@ +const https = require('https') +const options = { + hostname: 'api.anaconda.org', + port: 443, + path: '/package/conda-forge/conda', + method: 'GET' +} + +function compareVersions(version1, version2) { + ver1 = version1.split(".").map(Number); + ver2 = version2.split(".").map(Number); + + const common_length = Math.min(ver1.length, ver2.length); + for (var i = 0; i < common_length; ++i) { + if (ver1[i] < ver2[i]) { + return -1; + } else if (ver1[i] > ver2[i]) { + return 1; + } + } + + if (ver1.length > common_length) { + return 1; + } else if (ver2.length > common_length) { + return -1; + } else { + return 0; + } +} + +module.exports = ({github, context}) => { + const req = https.request(options, res => { + var data = ''; + + res.on('data', chunk => { + data += chunk; + }); + + res.on('end', function () { + versions = JSON.parse(data)["files"].map(x => x["version"]); + versions.sort(compareVersions); + conda_version = versions.pop(); + + github.rest.repos.getLatestRelease({ + owner: context.repo.owner, + repo: context.repo.repo, + }).then((release) => { + const current_version = release['data']['tag_name'].split("-")[0] + if (compareVersions(conda_version, current_version) === 1) { + github.rest.issues.listForRepo({ + owner: context.repo.owner, + repo: context.repo.repo, + state: "open", + labels: "[bot] conda release" + }).then((issues) => { + if (issues.data.length === 0) { + github.rest.issues.create({ + owner: context.repo.owner, + repo: context.repo.repo, + title: "New conda release: please tag a miniforge release", + body: "A new conda release was found, please tag a new miniforge release with `" + conda_version + "-0`", + labels: ["[bot] conda release"] + }) + } + }); + } + }); + }); + }) + + req.end(); +} diff --git a/.github/workflows/conda_release.yml b/.github/workflows/conda_release.yml new file mode 100644 index 00000000..4ce6cb95 --- /dev/null +++ b/.github/workflows/conda_release.yml @@ -0,0 +1,17 @@ +name: Check for new conda releases +on: + schedule: + - cron: "0 */6 * * *" +jobs: + check_conda_release: + name: "Check for release and open issue" + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Run Actions script + uses: actions/github-script@v6 + with: + script: | + const script = require(`${process.env.GITHUB_WORKSPACE}/.github/workflows/conda_release.js`) + console.log(script({github, context})) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 00000000..12bcb9e6 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,22 @@ +name: Build docs +on: [push, pull_request] +jobs: + docs: + runs-on: ubuntu-20.04 + defaults: + run: + shell: bash -l {0} + steps: + - uses: actions/checkout@v3 + - uses: conda-incubator/setup-miniconda@35d1405e78aa3f784fe3ce9a2eb378d5eeb62169 + - run: python -m pip install -r docs/requirements.txt + - run: python docs/releases.py + - uses: actions/upload-artifact@v3 + with: + path: build/docs + name: docs + - uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: build/docs/all-releases + if: startsWith(github.ref, 'refs/tags/') diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 00000000..75a33a4b --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,20 @@ +name: Lint +on: [pull_request] +jobs: + lint: + runs-on: ubuntu-latest + defaults: + run: + shell: bash -l {0} + steps: + - uses: actions/checkout@v3 + - name: Setup Miniconda + uses: conda-incubator/setup-miniconda@v2 + - name: Install dependencies + run: | + conda install -c conda-forge shellcheck + - name: Shellcheck + run: | + echo "::add-matcher::.github/shellcheck-matcher.json" + shellcheck --format=gcc $(find . -iname "*.sh") + echo "::remove-matcher owner=shellcheck::" diff --git a/LICENSE b/LICENSE index 83a17c6f..a924cf8f 100644 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,23 @@ -BSD 3-clause license -Copyright (c) 2019-2020, conda-forge +Miniforge installer code uses BSD-3-Clause license as stated below. + +Binary packages that come with it have their own licensing terms +and by installing miniforge you agree to the licensing terms of individual +packages as well. They include different OSI-approved licenses including +the GNU General Public License and can be found in pkgs//info/licenses +folders. + +Miniforge installer comes with a boostrapping executable that is used +when installing miniforge and is deleted after miniforge is installed. +The bootstrapping executable uses micromamba, cli11, cpp-filesystem, +curl, c-ares, krb5, libarchive, libev, lz4, nghttp2, openssl, libsolv, +nlohmann-json, reproc and zstd which are licensed under BSD-3-Clause, +MIT and OpenSSL licenses. Licenses and copyright notices of these +projects can be found at the following URL. +https://github.com/conda-forge/micromamba-feedstock/tree/master/recipe. + +============================================================================= + +Copyright (c) 2019-2022, conda-forge All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/Miniforge3/construct.yaml b/Miniforge3/construct.yaml index b3da1306..1621eda1 100644 --- a/Miniforge3/construct.yaml +++ b/Miniforge3/construct.yaml @@ -1,4 +1,4 @@ -{% set version = os.environ.get("MINIFORGE_VERSION", "4.9.2-0") %} +{% set version = os.environ.get("MINIFORGE_VERSION", "4.14.0-0") %} {% set name = os.environ.get("MINIFORGE_NAME", "Miniforge3") %} name: {{ name }} @@ -10,26 +10,26 @@ channels: # when the end user adds the channel without the full URL # - https://conda.anaconda.org/conda-forge - conda-forge - - msys2 # [win] write_condarc: True # keep pkgs for space-saving implications for hardlinks when create new environments # and keep the same with Miniconda keep_pkgs: True license_file: ../LICENSE +# Blocked until https://github.com/mamba-org/mamba/issues/1497 is fixed +# transmute_file_type: .conda specs: {% if name.endswith("pypy3") %} - - python 3.6.* *_pypy + - python 3.9.* *_pypy {% elif name.endswith("colab") %} - python 3.7.* {% else %} - - python 3.8.* # [not (osx and arm64)] - - python 3.9.* # [osx and arm64] + - python 3.10.* {% endif %} {% if name.startswith("Mambaforge") %} - - mamba + - mamba 0.25.0 {% endif %} - conda {{ version.split("-")[0] }} - pip - - bzip2 + - miniforge_console_shortcut 1.* # [win] diff --git a/README.md b/README.md index baaa4c2a..b1fa72d6 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,16 @@ -# miniforge -[![Build Status](https://travis-ci.com/conda-forge/miniforge.svg?branch=master)](https://travis-ci.com/conda-forge/miniforge) +# Miniforge +![Build Miniforge](https://github.com/conda-forge/miniforge/workflows/Build%20miniforge/badge.svg) -This repository holds a minimal installer for conda specific to conda-forge. It is comparable to [Miniconda](https://docs.conda.io/en/latest/miniconda.html), but with +This repository holds a minimal installer for [Conda](https://conda.io/) specific to [conda-forge](https://conda-forge.org/). +Miniforge allows you to install the conda package manager with the following features pre-configured: -* conda-forge set as the default channel -* an emphasis on supporting various CPU architectures +* [conda-forge](https://conda-forge.org/) set as the default (and only) channel. + * Packages in the base environment are obtained from the [conda-forge channel](https://anaconda.org/conda-forge). +* Optional support for PyPy in place of standard Python interpreter (aka "CPython"). +* Optional support for [Mamba](https://github.com/mamba-org/mamba) in place of Conda. +* An emphasis on supporting various CPU architectures (x86_64, ppc64le, and aarch64 including Apple M1). + +It can be compared to the [Miniconda](https://docs.conda.io/en/latest/miniconda.html) installer. ## Download @@ -12,24 +18,31 @@ Miniforge installers are available here: https://github.com/conda-forge/miniforg #### Miniforge3 -Latest installers with python 3.8 `(*)` in the base environment `(**)` +Latest installers with Python 3.9 `(*)` in the base environment: | OS | Architecture | Download | | --------|-----------------------|-----------| | Linux | x86_64 (amd64) | [Miniforge3-Linux-x86_64](https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-Linux-x86_64.sh) | -| Linux | aarch64 (arm64) | [Miniforge3-Linux-aarch64](https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-Linux-aarch64.sh) | +| Linux | aarch64 (arm64) `(**)` | [Miniforge3-Linux-aarch64](https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-Linux-aarch64.sh) | | Linux | ppc64le (POWER8/9) | [Miniforge3-Linux-ppc64le](https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-Linux-ppc64le.sh) | | OS X | x86_64 | [Miniforge3-MacOSX-x86_64](https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-MacOSX-x86_64.sh) | -| OS X | arm64 (Apple Silicon) | [Miniforge3-MacOSX-arm64](https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-MacOSX-arm64.sh) | +| OS X | arm64 (Apple Silicon) `(***)` | [Miniforge3-MacOSX-arm64](https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-MacOSX-arm64.sh) | | Windows | x86_64 | [Miniforge3-Windows-x86_64](https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-Windows-x86_64.exe) | -`(*)` OS X arm64 will be installed with Python 3.9 +`(*)` The Python version is specific only to the base environment. Conda can create new environments with different Python versions and implementations. + +`(**)` For Raspberry PI that include a 64 bit processor, you must also use +a 64-bit operating system such as +[Raspberry Pi OS 64-bit](https://www.raspberrypi.com/software/operating-systems/#raspberry-pi-os-64-bit) +or +[Ubuntu for Raspberry PI](https://ubuntu.com/raspberry-pi). +The versions listed as "System: 32-bit" are not compatible with the installers on this website. -`(**)` the python version is specific only to the base environment. installed conda can create new environments with different python versions and implementations +`(***)` Apple silicon builds are experimental and haven't had testing like the other platforms. #### Miniforge-pypy3 -Latest installers with pypy3.6 in the base environment +Latest installers with PyPy 3.7 in the base environment: | OS | Architecture | Download | | --------|-----------------------|-----------| @@ -37,10 +50,11 @@ Latest installers with pypy3.6 in the base environment | Linux | aarch64 (arm64) | [Miniforge-pypy3-Linux-aarch64](https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge-pypy3-Linux-aarch64.sh) | | Linux | ppc64le (POWER8/9) | [Miniforge-pypy3-Linux-ppc64le](https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge-pypy3-Linux-ppc64le.sh) | | OS X | x86_64 | [Miniforge-pypy3-MacOSX-x86_64](https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge-pypy3-MacOSX-x86_64.sh) | +| Windows | x86_64 | [Miniforge-pypy3-Windows-x86_64](https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge-pypy3-Windows-x86_64.exe) | #### Mambaforge -Latest installers with mamba in the base environment +Latest installers with Mamba in the base environment: | OS | Architecture | Download | @@ -54,7 +68,7 @@ Latest installers with mamba in the base environment #### Mambaforge-pypy3 -Latest installers with mamba and pypy3.6 in the base environment +Latest installers with Mamba and PyPy 3.7 in the base environment: | OS | Architecture | Download | | --------|-----------------------|-----------| @@ -62,24 +76,100 @@ Latest installers with mamba and pypy3.6 in the base environment | Linux | aarch64 (arm64) | [Mambaforge-pypy3-Linux-aarch64](https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-pypy3-Linux-aarch64.sh) | | Linux | ppc64le (POWER8/9) | [Mambaforge-pypy3-Linux-ppc64le](https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-pypy3-Linux-ppc64le.sh) | | OS X | x86_64 | [Mambaforge-pypy3-MacOSX-x86_64](https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-pypy3-MacOSX-x86_64.sh) | +| Windows | x86_64 | [Mambaforge-pypy3-Windows-x86_64](https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-pypy3-Windows-x86_64.exe) | ## Install -To install download the installer and run, +### Unix-like platforms + +Download the installer using curl or wget or your favorite program download files and run the script. +For eg: + + curl -L -O "https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-$(uname)-$(uname -m).sh" + bash Mambaforge-$(uname)-$(uname -m).sh + +or - bash Miniforge3-Linux-x86_64.sh # or similar for other installers for unix platforms + wget "https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-$(uname)-$(uname -m).sh" + bash Mambaforge-$(uname)-$(uname -m).sh -or if you are on Windows, double click on the installer. +#### Uninstallation + +Uninstalling Miniforge means removing the files that were created during the installation process. +You will typically want to remove: + +1. Any modifications to your shell rc files that were made by Miniforge: + +```bash +# Use this first command to see what rc files will be updated +conda init --reverse --dry-run +# Use this next command to take action on the rc files listed above +conda init --reverse +# Temporarily IGNORE the shell message +# 'For changes to take effect, close and re-open your current shell.', +# and CLOSE THE SHELL ONLY AFTER the 3rd step below is completed. +``` + +2. Remove the folder and all subfolders where the base environment for Miniforge was installed: + +```bash +CONDA_BASE_ENVIRONMENT=$(conda info --base) +echo The next command will delete all files in ${CONDA_BASE_ENVIRONMENT} +# Warning, the rm command below is irreversible! +# check the output of the echo command above +# To make sure you are deleting the correct directory +rm -rf ${CONDA_BASE_ENVIRONMENT} +``` + +3. Any global conda configuration files that are left behind. + +```bash +echo ${HOME}/.condarc will be removed if it exists +rm -f "${HOME}/.condarc" +``` + +### Windows + +Download the installer and double click it on the file browser. ### Non-interactive install -For non-interactive usage, look at the options by running the following +For non-interactive usage one can use the batch install option: + + bash Miniforge3-Linux-x86_64.sh -b # or similar for other installers for unix platforms - bash Miniforge3-Linux-x86_64.sh -h # or similar for other installers for unix platforms +Look at the extra options by running the following: + + bash Miniforge3-Linux-x86_64.sh -h or if you are on windows, run: - start /wait "" build/Miniforge3-Windows-x86_64.exe /InstallationType=JustMe /RegisterPython=0 /S /D=%UserProfile%\Miniforge3 + start /wait "" Miniforge3-Windows-x86_64.exe /InstallationType=JustMe /RegisterPython=0 /S /D=%UserProfile%\Miniforge3 + +### Downloading the installer as part of a CI pipeline + +If you wish to download the appropriate installer through the command line in a +more automated fashion, you may wish to a command similar to + +For Linux, any architecture, use the following command + + wget -O Miniforge3.sh "https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-$(uname)-$(uname -m).sh" + +For MacOSX, any architecture, use the following command + + curl -fsSLo Miniforge3.sh "https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-MacOSX-$(uname -m).sh" + +This will download the appropriate installer for the present architecture with +the filename ``Miniforge3.sh``. Run the shell script with the command in batch +mode with the `-b` flash: + + bash Miniforge3.sh -b + +### Homebrew + +On macOS, you can install miniforge with [Homebrew](https://brew.sh/) by running + + brew install miniforge ## Features @@ -92,18 +182,19 @@ or if you are on windows, run: ## Testing -After construction on Travis, the installer is tested against a range of distribution that match the installer architecture (`$ARCH`). For example when architecture is `aarch64`, the constructed installer is tested against: +After construction on the CI, the installer is tested against a range of distribution that match the installer architecture (`$ARCH`). For example when architecture is `aarch64`, the constructed installer is tested against: - Centos 7 - Debian Buster (10) -- Ubuntu 16.04 -- Ubuntu 18.04 -- Ubuntu 19.10 -- Ubuntu 20.04 +- Debian Bullseye (11) +- Ubuntu 16.04 ([LTS](https://ubuntu.com/about/release-cycle)) +- Ubuntu 18.04 ([LTS](https://ubuntu.com/about/release-cycle)) +- Ubuntu 20.04 ([LTS](https://ubuntu.com/about/release-cycle)) +- Ubuntu 21.10 (Latest non-LTS version) -## Usage +## Local usage -Installers are built and uploaded via Travis but if you want to construct your own Miniforge installer, here is how: +Installers are built and uploaded via the CI but if you want to construct your own Miniforge installer, here is how: ```bash # Configuration diff --git a/build_miniforge.sh b/build_miniforge.sh index d4f8d454..fdd542df 100755 --- a/build_miniforge.sh +++ b/build_miniforge.sh @@ -1,11 +1,22 @@ #!/usr/bin/env bash - +# Build miniforge installers for Linux +# on various architectures (aarch64, x86_64, ppc64le) +# Notes: +# It uses the qemu emulator (see [1] or [2]) to enable +# the use of containers images with different architectures than the host +# [1]: https://github.com/multiarch/qemu-user-static/ +# [2]: https://github.com/tonistiigi/binfmt +# See also: [setup-qemu-action](https://github.com/docker/setup-qemu-action) set -ex # Check parameters ARCH=${ARCH:-aarch64} -DOCKER_ARCH=${DOCKER_ARCH:arm64v8} +export TARGET_PLATFORM=${TARGET_PLATFORM:-linux-aarch64} +DOCKER_ARCH=${DOCKER_ARCH:-arm64v8} DOCKERIMAGE=${DOCKERIMAGE:-condaforge/linux-anvil-aarch64} +export MINIFORGE_NAME=${MINIFORGE_NAME:-Miniforge3} +OS_NAME=${OS_NAME:-Linux} +EXT=${EXT:-sh} export CONSTRUCT_ROOT=/construct echo "============= Create build directory =============" @@ -13,18 +24,17 @@ mkdir -p build/ chmod 777 build/ echo "============= Enable QEMU =============" -docker run --rm --privileged multiarch/qemu-user-static:register --reset --credential yes +# Enable qemu in persistent mode +docker run --privileged --rm tonistiigi/binfmt --install all echo "============= Build the installer =============" -docker run --rm -v $(pwd):/construct -e CONSTRUCT_ROOT -e MINIFORGE_VERSION -e MINIFORGE_NAME $DOCKERIMAGE /construct/scripts/build.sh - -echo "============= Download QEMU static binaries =============" -bash scripts/get_qemu.sh +docker run --rm -v "$(pwd):/construct" \ + -e CONSTRUCT_ROOT -e MINIFORGE_VERSION -e MINIFORGE_NAME -e TARGET_PLATFORM \ + "${DOCKERIMAGE}" /construct/scripts/build.sh echo "============= Test the installer =============" -for TEST_IMAGE_NAME in "ubuntu:20.04" "ubuntu:19.10" "ubuntu:16.04" "ubuntu:18.04" "centos:7" "debian:buster" -do - echo "============= Test installer on $TEST_IMAGE_NAME =============" - docker run --rm -v $(pwd):/construct -e CONSTRUCT_ROOT -v $(pwd)/build/qemu/qemu-${ARCH}-static:/usr/bin/qemu-${ARCH}-static ${DOCKER_ARCH}/$TEST_IMAGE_NAME /construct/scripts/test.sh +for TEST_IMAGE_NAME in "ubuntu:21.10" "ubuntu:20.04" "ubuntu:18.04" "ubuntu:16.04" "centos:7" "debian:bullseye" "debian:buster"; do + echo "============= Test installer on ${TEST_IMAGE_NAME} =============" + docker run --rm -v "$(pwd):/construct" -e CONSTRUCT_ROOT \ + "${DOCKER_ARCH}/${TEST_IMAGE_NAME}" /construct/scripts/test.sh done - diff --git a/build_miniforge_osx.sh b/build_miniforge_osx.sh index d7a31107..66a7e1f9 100755 --- a/build_miniforge_osx.sh +++ b/build_miniforge_osx.sh @@ -4,18 +4,32 @@ set -e set -x echo "Installing a fresh version of Miniforge3." -MINIFORGE_URL="https://github.com/conda-forge/miniforge/releases/download/4.8.3-1" -MINIFORGE_FILE="Miniforge3-4.8.3-1-MacOSX-x86_64.sh" -curl -L -O "${MINIFORGE_URL}/${MINIFORGE_FILE}" -bash $MINIFORGE_FILE -b +# Keep variable names in sync with +# https://github.com/conda-forge/docker-images/blob/main/scripts/run_commands +miniforge_arch="$(uname -m)" +miniforge_version="4.10.3-10" +condapkg="https://github.com/conda-forge/miniforge/releases/download/${miniforge_version}/Mambaforge-${miniforge_version}-MacOSX-${miniforge_arch}.sh" +if [ "$(uname -m)" = "x86_64" ]; then + conda_chksum="7c44259a0982cd3ef212649678af5f0dd4e0bb7306e8fffc93601dd1d739ec0b" +elif [ "$(uname -m)" = "arm64" ]; then + conda_chksum="72bc86612ab9435915b616c2edb076737cbabe2c33fd684d58c2f9ae72e1957c" +else + exit 1 +fi +curl -s -L "$condapkg" > miniconda.sh +openssl sha256 miniconda.sh | grep $conda_chksum + +bash miniconda.sh -b -p ~/conda echo "Configuring conda." -source ~/miniforge3/bin/activate root +# shellcheck disable=SC1090 +source ~/conda/bin/activate root -export CONSTRUCT_ROOT=$PWD +export CONSTRUCT_ROOT="${PWD}" mkdir -p build bash scripts/build.sh -if [[ "$ARCH" == "$(uname -m)" ]]; then +# shellcheck disable=SC2154 +if [[ "${ARCH}" == "$(uname -m)" ]]; then bash scripts/test.sh fi diff --git a/build_miniforge_win.sh b/build_miniforge_win.sh index a4cca181..4149d316 100644 --- a/build_miniforge_win.sh +++ b/build_miniforge_win.sh @@ -1,3 +1,7 @@ +#!/usr/bin/env bash + +set -ex + conda install posix --yes source scripts/build.sh source scripts/test.sh diff --git a/docs/releases.py b/docs/releases.py new file mode 100644 index 00000000..01c7c8e3 --- /dev/null +++ b/docs/releases.py @@ -0,0 +1,77 @@ +"""render a miniforge releases page""" +import jinja2 +from pathlib import Path +import datetime +import sys +import requests_cache + +HERE = Path(__file__).parent +BUILD = HERE.parent / "build" +DOCS = BUILD / "docs" + +if not DOCS.exists(): + DOCS.mkdir(parents=True) + +# TODO: handle pagination +BASE_URL = "https://api.github.com/repos/conda-forge/miniforge/releases?per_page=100" +ENV = jinja2.Environment(loader=jinja2.FileSystemLoader([HERE / "templates"])) + + +def get_releases(): + """use the GitHub API to fetch release information""" + s = requests_cache.CachedSession(str(BUILD / "cache")) + releases = s.get(BASE_URL).json() + + new_releases = [] + + for release in releases: + if release["draft"] or release["prerelease"]: + continue + new_assets = [] + for asset in release["assets"]: + name = asset["name"] + if "sha256" in name: + continue + if release["tag_name"] not in name: + continue + if release["tag_name"] in asset["name"]: + asset["_variant"], os_plat = asset["name"].split( + f"""-{release["tag_name"]}-""" + ) + asset["_os"], asset["_arch"] = os_plat.split(".")[0].split("-") + else: + raise ValueError(f"Couldn't variant for {name}") + asset["_sha256"] = s.get( + f"""{asset["browser_download_url"]}.sha256""" + ).text.split(" ")[0] + new_assets += [asset] + release["assets"] = new_assets + new_releases += [release] + releases = new_releases + return releases + + +def render(releases): + """render the release page HTML""" + context = dict( + title="Miniforge Releases", releases=releases, year=datetime.datetime.now().year + ) + html = ENV.get_template("all-releases.html").render(**context) + + release_html = DOCS / "all-releases" / "index.html" + + if not release_html.parent.exists(): + release_html.parent.mkdir(parents=True) + + release_html.write_text(html, encoding="utf-8") + + +def main(): + """main entrypoint""" + releases = get_releases() + render(releases) + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 00000000..c9b2041a --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,2 @@ +requests_cache +jinja2 diff --git a/docs/templates/all-releases.html b/docs/templates/all-releases.html new file mode 100644 index 00000000..d1c73941 --- /dev/null +++ b/docs/templates/all-releases.html @@ -0,0 +1,205 @@ + + + + {{ title }} + + + + + + +
+

{{ title }}

+ +
+
+ {%- for release in releases %} + {% if loop.index0 == 0 %} +

Latest

+ {% elif loop.index0 == 1 %} +

History

+ {% endif %} +
+

+ Miniforge {{ release.tag_name }} + # +

+ {%- if loop.index0 %}
{% endif -%} + + {%- if loop.index0 %}{% endif %} + + + + + + + + + + + + {%- for variant, vassets in release.assets | groupby("_variant") %} + {%- set vloop = loop -%} + {%- for os, oassets in vassets | groupby("_os") -%} + {%- set oloop = loop -%} + {%- for arch, aassets in oassets | groupby("_arch") -%} + {%- set aloop = loop -%} + {% for asset in aassets %} + {%- if oloop.index0 + aloop.index0 == 0 %} + + + {%- else -%} + + {%- endif -%} + {%- if aloop.index0 == 0%} + + {% endif -%} + + + + + + {% endfor -%} + {% endfor -%} + {% endfor -%} + {% endfor -%} + +
VariantOSArchArtifactSizeSHA256 +
{{ variant }}
{{ os }} + {{ arch }} + + + {{ asset.name }} + + {{ asset.size | filesizeformat }} +
{{ asset._sha256 }}
+
+ {% if loop.index0 %}{% endif -%} +
+ {% endfor -%} +
+ + diff --git a/scripts/build.sh b/scripts/build.sh index 08a968ae..38261e9f 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -2,22 +2,26 @@ set -xe -echo "***** Start: Building Miniforge installer *****" +env | sort -CONSTRUCT_ROOT="${CONSTRUCT_ROOT:-$PWD}" +echo "***** Start: Building Miniforge installer *****" +CONSTRUCT_ROOT="${CONSTRUCT_ROOT:-${PWD}}" -cd $CONSTRUCT_ROOT +cd "${CONSTRUCT_ROOT}" # Constructor should be latest for non-native building # See https://github.com/conda/constructor echo "***** Install constructor *****" -conda install -y "constructor>=3.1.0" jinja2 -c conda-forge -c defaults --override-channels +conda install -y "constructor>=3.3.1" jinja2 curl libarchive -c conda-forge --override-channels + if [[ "$(uname)" == "Darwin" ]]; then - conda install -y coreutils -c conda-forge -c defaults --override-channels -elif [[ "$(uname)" == MINGW* ]]; then - conda install -y "nsis=3.01" -c conda-forge -c defaults --override-channels + conda install -y coreutils -c conda-forge --override-channels fi -pip install git+git://github.com/conda/constructor@8c0121d3b81846de42973b52f13135f0ffeaddda#egg=constructor --force --no-deps +# shellcheck disable=SC2154 +if [[ "${TARGET_PLATFORM}" == win-* ]]; then + conda install -y "nsis=3.01" -c conda-forge --override-channels +fi +# pip install git+git://github.com/conda/constructor@3.3.1#egg=constructor --force --no-deps conda list echo "***** Make temp directory *****" @@ -28,37 +32,54 @@ else fi echo "***** Copy file for installer construction *****" -cp -R Miniforge3 $TEMP_DIR/ -cp LICENSE $TEMP_DIR/ +cp -R Miniforge3 "${TEMP_DIR}/" +cp LICENSE "${TEMP_DIR}/" -ls -al $TEMP_DIR +ls -al "${TEMP_DIR}" -if [[ $(uname -r) != "$ARCH" ]]; then - if [[ "$ARCH" == "arm64" ]]; then - CONDA_SUBDIR=osx-arm64 conda create -n micromamba micromamba=0.6.5 -c https://conda-web.anaconda.org/conda-forge --yes - EXTRA_CONSTRUCTOR_ARGS="$EXTRA_CONSTRUCTOR_ARGS --conda-exe $CONDA_PREFIX/envs/micromamba/bin/micromamba --platform osx-arm64" +if [[ "${TARGET_PLATFORM}" != win-* ]]; then + MICROMAMBA_VERSION=0.24.0 + mkdir "${TEMP_DIR}/micromamba" + pushd "${TEMP_DIR}/micromamba" + curl -L -O "https://anaconda.org/conda-forge/micromamba/${MICROMAMBA_VERSION}/download/${TARGET_PLATFORM}/micromamba-${MICROMAMBA_VERSION}-0.tar.bz2" + bsdtar -xf "micromamba-${MICROMAMBA_VERSION}-0.tar.bz2" + if [[ "${TARGET_PLATFORM}" == win-* ]]; then + MICROMAMBA_FILE="${PWD}/Library/bin/micromamba.exe" + else + MICROMAMBA_FILE="${PWD}/bin/micromamba" fi + popd + EXTRA_CONSTRUCTOR_ARGS="${EXTRA_CONSTRUCTOR_ARGS} --conda-exe ${MICROMAMBA_FILE} --platform ${TARGET_PLATFORM}" fi echo "***** Construct the installer *****" -constructor $TEMP_DIR/Miniforge3/ --output-dir $TEMP_DIR $EXTRA_CONSTRUCTOR_ARGS +# Transmutation requires the current directory is writable +cd "${TEMP_DIR}" +# shellcheck disable=SC2086 +constructor "${TEMP_DIR}/Miniforge3/" --output-dir "${TEMP_DIR}" ${EXTRA_CONSTRUCTOR_ARGS} +cd - echo "***** Generate installer hash *****" -cd $TEMP_DIR +cd "${TEMP_DIR}" if [[ "$(uname)" == MINGW* ]]; then - EXT=exe; + EXT="exe"; else - EXT=sh; + EXT="sh"; fi # This line will break if there is more than one installer in the folder. -INSTALLER_PATH=$(find . -name "M*forge*.$EXT" | head -n 1) -HASH_PATH="$INSTALLER_PATH.sha256" -sha256sum $INSTALLER_PATH > $HASH_PATH +INSTALLER_PATH=$(find . -name "M*forge*.${EXT}" | head -n 1) +HASH_PATH="${INSTALLER_PATH}.sha256" +sha256sum "${INSTALLER_PATH}" > "${HASH_PATH}" echo "***** Move installer and hash to build folder *****" -mkdir -p $CONSTRUCT_ROOT/build -mv $INSTALLER_PATH $CONSTRUCT_ROOT/build/ -mv $HASH_PATH $CONSTRUCT_ROOT/build/ +mkdir -p "${CONSTRUCT_ROOT}/build" +mv "${INSTALLER_PATH}" "${CONSTRUCT_ROOT}/build/" +mv "${HASH_PATH}" "${CONSTRUCT_ROOT}/build/" echo "***** Done: Building Miniforge installer *****" -cd $CONSTRUCT_ROOT +cd "${CONSTRUCT_ROOT}" + +# copy the installer for latest +if [[ "${MINIFORGE_NAME:-}" != "" && "${OS_NAME:-}" != "" && "${ARCH:-}" != "" ]]; then + cp "${CONSTRUCT_ROOT}/build/${MINIFORGE_NAME}-"*"-${OS_NAME}-${ARCH}.${EXT}" "${CONSTRUCT_ROOT}/build/${MINIFORGE_NAME}-${OS_NAME}-${ARCH}.${EXT}" +fi diff --git a/scripts/get_qemu.sh b/scripts/get_qemu.sh deleted file mode 100755 index 09e7e39f..00000000 --- a/scripts/get_qemu.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env bash - -CURRENT_DIR=$(pwd) -QEMU_STATIC_VERSION=v3.1.0-3 -QEMU_DIR="./build/qemu/" - -qemu_ppc64le_sha256=d018b96e20f7aefbc50e6ba93b6cabfd53490cdf1c88b02e7d66716fa09a7a17 -qemu_aarch64_sha256=a64b39b8ce16e2285cb130bcba7143e6ad2fe19935401f01c38325febe64104b -qemu_arm_sha256=f4184c927f78d23d199056c5b0b6d75855e298410571d65582face3159117901 -qemu_x86_64_sha256=b9e444bf656c13a6db502f09e3135ef0c6045a117d5413662ba233d8b80f8fbd - -mkdir -p $QEMU_DIR/ -cd $QEMU_DIR/ - -wget https://github.com/multiarch/qemu-user-static/releases/download/${QEMU_STATIC_VERSION}/qemu-ppc64le-static -wget https://github.com/multiarch/qemu-user-static/releases/download/${QEMU_STATIC_VERSION}/qemu-aarch64-static -wget https://github.com/multiarch/qemu-user-static/releases/download/${QEMU_STATIC_VERSION}/qemu-arm-static -wget https://github.com/multiarch/qemu-user-static/releases/download/${QEMU_STATIC_VERSION}/qemu-x86_64-static - -sha256sum qemu-ppc64le-static | grep -F "${qemu_ppc64le_sha256}" -sha256sum qemu-aarch64-static | grep -F "${qemu_aarch64_sha256}" -sha256sum qemu-arm-static | grep -F "${qemu_aarch64_sha256}" -sha256sum qemu-x86_64-static | grep -F "${qemu_x86_64_sha256}" - -chmod +x qemu-ppc64le-static -chmod +x qemu-aarch64-static -chmod +x qemu-arm-static -chmod +x qemu-x86_64-static - -cd $CURRENT_DIR diff --git a/scripts/test.sh b/scripts/test.sh index 3fb48773..74a537d9 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -4,29 +4,32 @@ set -ex echo "***** Start: Testing Miniforge installer *****" -export CONDA_PATH="$HOME/miniforge" +export CONDA_PATH="${HOME}/miniforge" -CONSTRUCT_ROOT="${CONSTRUCT_ROOT:-$PWD}" +CONSTRUCT_ROOT="${CONSTRUCT_ROOT:-${PWD}}" -cd ${CONSTRUCT_ROOT} +cd "${CONSTRUCT_ROOT}" echo "***** Get the installer *****" ls build/ if [[ "$(uname)" == MINGW* ]]; then - EXT=exe; + EXT="exe"; else - EXT=sh; + EXT="sh"; fi -INSTALLER_PATH=$(find build/ -name "*forge*.$EXT" | head -n 1) +INSTALLER_PATH=$(find build/ -name "*forge*.${EXT}" | head -n 1) echo "***** Run the installer *****" -chmod +x $INSTALLER_PATH +chmod +x "${INSTALLER_PATH}" if [[ "$(uname)" == MINGW* ]]; then - echo "start /wait \"\" ${INSTALLER_PATH} /InstallationType=JustMe /RegisterPython=0 /S /D=$(cygpath -w $CONDA_PATH)" > install.bat + echo "start /wait \"\" ${INSTALLER_PATH} /InstallationType=JustMe /RegisterPython=0 /S /D=$(cygpath -w "${CONDA_PATH}")" > install.bat cmd.exe /c install.bat echo "***** Setup conda *****" - source $CONDA_PATH/Scripts/activate + # Workaround a conda bug where it uses Unix style separators, but MinGW doesn't understand them + export PATH=$CONDA_PATH/Library/bin:$PATH + # shellcheck disable=SC1091 + source "${CONDA_PATH}/Scripts/activate" conda.exe config --set show_channel_urls true echo "***** Print conda info *****" @@ -41,10 +44,11 @@ if [[ "$(uname)" == MINGW* ]]; then conda.exe install r-base --yes --quiet conda.exe list else - bash $INSTALLER_PATH -b -p $CONDA_PATH + bash "${INSTALLER_PATH}" -b -p "${CONDA_PATH}" echo "***** Setup conda *****" - source $CONDA_PATH/bin/activate + # shellcheck disable=SC1091 + source "${CONDA_PATH}/bin/activate" echo "***** Print conda info *****" conda info