Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add 'conda-remove-defaults' setting and support 'nodefaults' as a keyword channel #367

Merged
merged 23 commits into from
Oct 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions .github/workflows/example-14.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
name: "Example 14: Remove defaults channel"

on:
pull_request:
branches:
- "*"
push:
branches:
- "develop"
- "main"
- "master"
schedule:
# Note that cronjobs run on master/main by default
- cron: "0 0 * * *"

concurrency:
group:
${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
cancel-in-progress: true

jobs:
example-14:
# prevent cronjobs from running on forks
if:
(github.event_name == 'schedule' && github.repository ==
'conda-incubator/setup-miniconda') || (github.event_name != 'schedule')
name:
Ex14 (${{ matrix.os }}, remove=${{ matrix.conda-remove-defaults }},
channels=${{ matrix.channels }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: ["ubuntu-latest", "macos-latest", "windows-latest"]
conda-remove-defaults: ["true", "false"]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about something like

Suggested change
conda-remove-defaults: ["true", "false"]
explicitly-listed-channels-only: ["true", "false"]

Admittedly verby, but I think we can write this in a way that gets closer to the long-term intended behavior

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See #367 (review). I don't particularly care about the name itself, given it'll be probably be obsolete by March next year.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the long-term future for this feature is only to migrate conda users to the same pattern as mamba and pixi follow, setting a default channel in the distribution/bootstrapper layer and not hard-coding it in the codebase. That's why I think the name of the parameter for setup-miniconda is okay to focus on conda only, and not required to be named generically.

channels:
[
"conda-forge",
"conda-forge,nodefaults",
"conda-forge,defaults,nodefaults",
]
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: ./
id: setup-miniconda
continue-on-error: true
with:
channels: ${{ matrix.channels }}
conda-remove-defaults: ${{ matrix.conda-remove-defaults }}
python-version: "3.12"
- shell: bash -el {0}
run: |
cat <<EOF | python
import json
import os
from subprocess import check_output

out = check_output(
[
os.environ["CONDA_EXE"],
"config",
"--show",
"channels",
"--json",
]
)
channels = json.loads(out)["channels"]
input_channels = "${{ matrix.channels }}".split(",")
remove_defaults = "${{ matrix.conda-remove-defaults }}" == "true"

print("Input channels:", input_channels)
print("Input remove-defaults:", remove_defaults)
print("Computed channels:", channels)

assert "nodefaults" not in channels
if "defaults" in input_channels:
assert "defaults" in channels
elif "nodefaults" in input_channels or remove_defaults:
assert "defaults" not in channels
EOF
7 changes: 7 additions & 0 deletions .github/workflows/example-6.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ jobs:
- uses: ./
with:
miniforge-variant: Miniforge3
# Use an old Miniforge (without conda-libmamba-solver) to allow updates to mamba v2.
# Set the solver to classic for those too. This can be removed when
# conda-libmamba-solver is released with libmamba v2 compatibility.
miniforge-version:
${{ matrix.mamba-version == '2' && '23.1.0-0' || 'latest' }}
conda-solver:
${{ matrix.mamba-version == '2' && 'classic' || 'libmamba' }}
python-version: "3.11"
mamba-version: ${{ matrix.mamba-version }}
channels: conda-forge,nodefaults
Expand Down
34 changes: 34 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ possibility of automatically activating the `test` environment on all shells.
| [Caching packages](#caching-packages) | [![Caching Example Status][caching-badge]][caching] |
| [Caching environments](#caching-environments) | [![Caching Env Example Status][caching-env-badge]][caching-env] |
| [Apple Silicon](#example-13-apple-silicon) | [![Apple Silicon][ex13-badge]][ex13] |
| [Remove defaults](#example-14-conda-remove-defaults) | [![Remove defaults][ex14-badge]][ex14] |

[ex1]:
https://github.com/conda-incubator/setup-miniconda/actions/workflows/example-1.yml
Expand Down Expand Up @@ -112,6 +113,10 @@ possibility of automatically activating the `test` environment on all shells.
https://github.com/conda-incubator/setup-miniconda/actions/workflows/example-13.yml
[ex13-badge]:
https://github.com/conda-incubator/setup-miniconda/actions/workflows/example-13.yml/badge.svg?branch=main
[ex14]:
https://github.com/conda-incubator/setup-miniconda/actions/workflows/example-14.yml
[ex14-badge]:
https://github.com/conda-incubator/setup-miniconda/actions/workflows/example-14.yml/badge.svg?branch=main

## Other Workflows

Expand Down Expand Up @@ -598,6 +603,35 @@ jobs:
python -c "import platform; assert platform.machine() == 'arm64', platform.machine()"
```

### Example 14: Remove `defaults` channel

Workaround for this bug:
[conda#12356](https://github.com/conda/conda/issues/12356).

```yaml
jobs:
example-13:
name: Ex14 (os=${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: ["ubuntu-latest"]
steps:
- uses: actions/checkout@v4
- uses: ./
id: setup-miniconda
continue-on-error: true
with:
miniforge-version: latest
channels: conda-forge
conda-remove-defaults: "true"
- name: Check config
shell: bash -el {0}
run: |
conda config --show-sources
```

## Caching

### Caching packages
Expand Down
7 changes: 7 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,13 @@ inputs:
for more information."
required: false
default: ""
conda-remove-defaults:
description:
"Postprocess channels list to remove 'defaults' if it was added implicitly
to the 'channels' setting. Will default to 'true' to align with related
changes in conda 25.3.0."
required: false
default: ""
show-channel-urls:
description:
'Conda configuration. Show channel URLs when displaying what is going to
Expand Down
26 changes: 26 additions & 0 deletions dist/setup/index.js

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

34 changes: 34 additions & 0 deletions src/conda.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,13 +159,47 @@ export async function applyCondaConfiguration(
channels = options.envSpec.yaml.channels;
}

// This can be enabled via conda-remove-defaults and channels = nodefaults
let removeDefaults: boolean = inputs.condaRemoveDefaults === "true";

// LIFO: reverse order to preserve higher priority as listed in the option
// .slice ensures working against a copy
for (const channel of channels.slice().reverse()) {
if (channel === "nodefaults") {
core.warning(
"'nodefaults' channel detected: will remove 'defaults' if added implicitly. " +
"In the future, 'nodefaults' as a way of removing 'defaults' won't be supported. " +
"Please set 'conda-remove-defaults' = 'true' to remove this warning.",
);
removeDefaults = true;
continue;
}
core.info(`Adding channel '${channel}'`);
await condaCommand(["config", "--add", "channels", channel], options);
}

if (!channels.includes("defaults")) {
if (removeDefaults) {
core.info("Removing implicitly added 'defaults' channel");
try {
await condaCommand(
["config", "--remove", "channels", "defaults"],
options,
);
} catch (err) {
core.info(
"Removing defaults raised an error -- it was probably not present.",
);
}
} else {
core.warning(
"The 'defaults' channel might have been added implicitly. " +
"If this is intentional, add 'defaults' to the 'channels' list. " +
"Otherwise, consider setting 'conda-remove-defaults' to 'true'.",
);
}
}

// All other options are just passed as their string representations
for (const [key, value] of configEntries) {
if (value.trim().length === 0 || key === "channels") {
Expand Down
1 change: 1 addition & 0 deletions src/input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ export async function parseInputs(): Promise<types.IActionInputs> {
minicondaVersion: core.getInput("miniconda-version"),
miniforgeVariant: core.getInput("miniforge-variant"),
miniforgeVersion: core.getInput("miniforge-version"),
condaRemoveDefaults: core.getInput("conda-remove-defaults"),
pythonVersion: core.getInput("python-version"),
removeProfiles: core.getInput("remove-profiles"),
condaConfig: Object.freeze({
Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ export interface IActionInputs {
readonly minicondaVersion: string;
readonly miniforgeVariant: string;
readonly miniforgeVersion: string;
readonly condaRemoveDefaults: string;
readonly pythonVersion: string;
readonly removeProfiles: string;
readonly useMamba: string;
Expand Down
Loading