Skip to content

Optimize conda configuration: write .condarc directly instead of spawning subprocesses#453

Open
jezdez wants to merge 5 commits intomainfrom
perf/optimize-conda-config
Open

Optimize conda configuration: write .condarc directly instead of spawning subprocesses#453
jezdez wants to merge 5 commits intomainfrom
perf/optimize-conda-config

Conversation

@jezdez
Copy link
Member

@jezdez jezdez commented Feb 26, 2026

Note: The breaking changes in this PR (minimum conda version bump, config key rename) warrant a major version bump of the action (v4).

Fixes

  • Replace applyCondaConfiguration() (which spawned ~13 sequential conda config subprocesses per run, each paying 2-5s of Python startup) with writeCondaConfig() that builds the complete .condarc in memory and writes it once via fs.writeFileSync.
  • Remove redundant second applyCondaConfiguration call after base tool installation.
  • Replace conda config --show --json subprocess in isDefaultEnvironment with direct YAML reads of condarc files.
  • Remove minicondaVersions() which downloaded and parsed the full repo.anaconda.com HTML index page for version validation. Now attempts the download directly with a clear error on failure.
  • Parallelize Windows takeown calls with Promise.all.

Breaking changes

  • Minimum miniconda-version bumped from 4.6.0 to 25.5.0 (required for auto_activate config key support).
  • Writes auto_activate (canonical name since conda 25.5.0) instead of the deprecated auto_activate_base (removal scheduled for conda 26.3).

Stability

  • Existing ~/.condarc written by the installer is now read as base config before applying action inputs, preserving installer-embedded settings (e.g., Miniforge's channels: [conda-forge]).
  • removeDefaults now also strips defaults from prefix-level condarc files, matching the old behavior.
  • Warns on unrecognized condarc keys to catch typos.
  • Handles all YAML 1.1 boolean literals (on/off/y/n/1/0) in boolean config values.

Tasks and Maintenance

  • Remove get-hrefs and normalize-url dependencies.
  • Remove src/typings.d.ts (only contained get-hrefs type declarations).

@jezdez jezdez requested a review from a team as a code owner February 26, 2026 10:21
Replace ~26 sequential `conda config` subprocess calls with a single
direct YAML file write using js-yaml. Each conda subprocess incurs 2-5s
of Python/conda startup overhead, so this eliminates 60-130s of wall
time for configuration alone.

Key changes:
- Replace applyCondaConfiguration with writeCondaConfig that builds the
  complete .condarc in memory and writes it once via fs.writeFileSync
- Merge user condarc file (if provided) with action inputs in memory
  instead of copying then modifying via subprocess calls
- Remove redundant second applyCondaConfiguration call after base tool
  installation (no longer needed since config is file-based)
- Replace isDefaultEnvironment conda subprocess with local YAML parsing
  of user-level and prefix-level condarc files
- Remove HTML index page download for Miniconda version validation;
  let the actual download fail with a clear HTTP error instead
- Scope macOS chown -R to specific directories (bin, condabin, etc)
  instead of the entire conda tree, and run them in parallel
- Parallelize Windows takeown calls with Promise.all
- Remove get-hrefs and normalize-url dependencies (73 packages removed)
Address 8 stability concerns identified during review of the
direct .condarc writing optimization:

1. Document channel priority order equivalence (comment)
2. Merge installer-written condarc as base instead of overwriting
3. Warn on unrecognized condarc keys (catches typos)
4. Strip 'defaults' from prefix-level condarc when removeDefaults set
5. Handle all YAML 1.1 boolean literals (on/off/y/n/1/0)
6. Bump minimum miniconda version to 25.5.0 (for auto_activate)
7. Revert macOS chown to full base path for safety
8. Improve error message when miniconda download fails

Also switches condarc key from deprecated auto_activate_base to the
canonical auto_activate (introduced in conda 25.5.0, old name removed
in 26.3).
- Do not strip 'defaults' from channels when the user explicitly listed
  it alongside 'nodefaults' (matches old behavior where conda config
  --add would add defaults first, then the removeDefaults guard checked
  `!channels.includes("defaults")` before removing).
- Bump Issue 261 test from miniconda py312_25.3.1-1 to py312_25.11.1-1
  to satisfy the new >= 25.5.0 minimum version requirement.
Miniconda py312_25.11.1-1 doesn't publish macOS x86_64 builds.
Remove the hardcoded architecture: x64 so the test uses the
runner's native arch (arm64 on macOS, x64 on Linux/Windows).
@jezdez jezdez force-pushed the perf/optimize-conda-config branch from d68e536 to daa14fc Compare February 26, 2026 11:10
@jezdez jezdez force-pushed the perf/optimize-conda-config branch from daa14fc to a2fca81 Compare February 26, 2026 12:08
Copy link
Member

@goanpeca goanpeca left a comment

Choose a reason for hiding this comment

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

Awesome work @jezdez Thanks!

Is this good to merge? or is there anything else you want to tackle?

@jezdez
Copy link
Member Author

jezdez commented Feb 27, 2026

@goanpeca Waiting to see if conda/conda#15741 is successful..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants