Skip to content

Commit

Permalink
Merge pull request #1707 from emlys/use-new-micromamba-version
Browse files Browse the repository at this point in the history
Distribute micromamba executable for plugins
  • Loading branch information
dcdenu4 authored Jan 6, 2025
2 parents 7474a60 + dbd6419 commit 595684b
Show file tree
Hide file tree
Showing 8 changed files with 44 additions and 48 deletions.
2 changes: 1 addition & 1 deletion .github/actions/setup_env/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ runs:
cat environment.yml
- name: Setup conda environment
uses: mamba-org/setup-micromamba@v1
uses: mamba-org/setup-micromamba@v2
with:
environment-file: environment.yml
environment-name: env
Expand Down
25 changes: 12 additions & 13 deletions .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -367,22 +367,21 @@ jobs:
yarn config set network-timeout 600000 -g
yarn install
- name: Download mamba installer for distribution (MacOS)
- name: Download micromamba for distribution (MacOS)
if: matrix.os == 'macos-13'
run: curl -fsSLo Miniforge3-MacOSX-x86_64.sh "https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-MacOSX-x86_64.sh"

- name: Install mamba for MacOS
if: matrix.os == 'macos-13'
run: bash Miniforge3-MacOSX-x86_64.sh -b -p dist/miniforge3

- name: Download mamba installer for distribution (Windows)
if: matrix.os == 'windows-latest'
run: curl -fsSLo Miniforge3-Windows-x86_64.exe "https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-Windows-x86_64.exe"
run: |
curl -Ls https://micro.mamba.pm/api/micromamba/osx-64/latest | tar -xvj bin/micromamba
mv bin/micromamba dist/
./dist/micromamba --help # make sure the executable works
- name: Install mamba for Windows
- name: Download micromamba for distribution (Windows)
if: matrix.os == 'windows-latest'
shell: cmd
run: Miniforge3-Windows-x86_64.exe /InstallationType=JustMe /RegisterPython=0 /S /D=%cd%\dist\miniforge3
shell: pwsh
run: |
Invoke-Webrequest -URI https://micro.mamba.pm/api/micromamba/win-64/latest -OutFile micromamba.tar.bz2
tar xf micromamba.tar.bz2
MOVE -Force Library\bin\micromamba.exe dist\micromamba.exe
.\dist\micromamba.exe --help # make sure the executable works
- name: Authenticate GCP
if: github.event_name != 'pull_request'
Expand Down
8 changes: 6 additions & 2 deletions workbench/electron-builder-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,12 @@ const config = {
to: 'invest',
},
{
from: '../dist/Miniforge3',
to: 'Miniforge3',
from: '../dist/micromamba', // mac
to: 'micromamba',
},
{
from: '../dist/micromamba.exe', // windows
to: 'micromamba.exe',
},
{
from: '../dist/userguide',
Expand Down
6 changes: 3 additions & 3 deletions workbench/src/main/createPythonFlaskProcess.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,14 +123,14 @@ export async function createPluginServerProcess(modelName, _port = undefined) {
}

logger.debug('creating invest plugin server process');
const mamba = settingsStore.get('mamba');
const micromamba = settingsStore.get('micromamba');
const modelEnvPath = settingsStore.get(`plugins.${modelName}.env`);
const args = [
'run', '--prefix', `"${modelEnvPath}"`,
'invest', '--debug', 'serve', '--port', port];
logger.debug('spawning command:', mamba, args);
logger.debug('spawning command:', micromamba, args);
// shell mode is necessary in dev mode & relying on a conda env
const pythonServerProcess = spawn(mamba, args, { shell: true });
const pythonServerProcess = spawn(micromamba, args, { shell: true });
settingsStore.set(`plugins.${modelName}.port`, port);
settingsStore.set(`plugins.${modelName}.pid`, pythonServerProcess.pid);

Expand Down
26 changes: 10 additions & 16 deletions workbench/src/main/findBinaries.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,32 +54,26 @@ export function findInvestBinaries(isDevMode) {
return investExe;
}


/**
* Return the available mamba executable.
* Return the available micromamba executable.
*
* @param {boolean} isDevMode - a boolean designating dev mode or not.
* @returns {string} mamba executable.
* @returns {string} micromamba executable.
*/
export function findMambaExecutable(isDevMode) {
let mambaExe;
export function findMicromambaExecutable(isDevMode) {
let micromambaExe;
if (isDevMode) {
mambaExe = 'mamba'; // assume that mamba is available
micromambaExe = 'micromamba'; // assume that micromamba is available
} else {
if (process.platform === 'win32') {
mambaExe = `"${upath.join(process.resourcesPath, 'miniforge3', 'condabin', 'mamba.bat')}"`;
} else {
// Quote the path in case of spaces
mambaExe = `"${upath.join(process.resourcesPath, 'miniforge3', 'condabin', 'mamba')}"`;
}
micromambaExe = `"${upath.join(process.resourcesPath, 'micromamba')}"`;
}
// Check that the executable is working
const { stderr, error } = spawnSync(mambaExe, ['--help'], { shell: true });
const { stderr, error } = spawnSync(micromambaExe, ['--help'], { shell: true });
if (error) {
logger.error(stderr.toString());
logger.error('mamba executable is not where we expected it.');
logger.error('micromamba executable is not where we expected it.');
throw error;
}
logger.info(`using mamba executable '${mambaExe}'`);
return mambaExe;
logger.info(`using micromamba executable '${micromambaExe}'`);
return micromambaExe;
}
4 changes: 2 additions & 2 deletions workbench/src/main/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
createCoreServerProcess,
shutdownPythonProcess
} from './createPythonFlaskProcess';
import { findInvestBinaries, findMambaExecutable } from './findBinaries';
import { findInvestBinaries, findMicromambaExecutable } from './findBinaries';
import setupDownloadHandlers from './setupDownloadHandlers';
import setupDialogs from './setupDialogs';
import setupContextMenu from './setupContextMenu';
Expand Down Expand Up @@ -80,7 +80,7 @@ export const createWindow = async () => {
splashScreen.loadURL(path.join(BASE_URL, 'splash.html'));

settingsStore.set('investExe', findInvestBinaries(ELECTRON_DEV_MODE));
settingsStore.set('mamba', findMambaExecutable(ELECTRON_DEV_MODE));
settingsStore.set('micromamba', findMicromambaExecutable(ELECTRON_DEV_MODE));
// No plugin server processes should persist between workbench sessions
// In case any were left behind, remove them
const plugins = settingsStore.get('plugins');
Expand Down
18 changes: 9 additions & 9 deletions workbench/src/main/setupAddRemovePlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export function setupAddPlugin() {
async (e, pluginURL) => {
try {
logger.info('adding plugin at', pluginURL);
const mamba = settingsStore.get('mamba');
const micromamba = settingsStore.get('micromamba');
// Create a temporary directory and check out the plugin's pyproject.toml
const tmpPluginDir = fs.mkdtempSync(upath.join(tmpdir(), 'natcap-invest-'));
await spawnWithLogging(
Expand All @@ -81,19 +81,19 @@ export function setupAddPlugin() {
// Create a conda env containing the plugin and its dependencies
const envName = `invest_plugin_${pluginID}`;
await spawnWithLogging(
mamba,
micromamba,
['create', '--yes', '--name', envName, '-c', 'conda-forge', '"python<3.12"', '"gdal<3.6"']
);
logger.info('created mamba env for plugin');
logger.info('created micromamba env for plugin');
await spawnWithLogging(
mamba,
['run', '--verbose', '--no-capture-output', '--name', envName, 'pip', 'install', `git+${pluginURL}`]
micromamba,
['run', '--name', envName, 'pip', 'install', `git+${pluginURL}`]
);
logger.info('installed plugin into its env');
// Write plugin metadata to the workbench's config.json
const envInfo = execSync(`${mamba} info --envs`, { windowsHide: true }).toString();
const envInfo = execSync(`${micromamba} info --name ${envName}`, { windowsHide: true }).toString();
logger.info(`env info:\n${envInfo}`);
const regex = new RegExp(String.raw`^${envName} +(.+)$`, 'm');
const regex = /env location : (.+)/;
const envPath = envInfo.match(regex)[1];
logger.info(`env path:\n${envPath}`);
logger.info('writing plugin info to settings store');
Expand Down Expand Up @@ -123,8 +123,8 @@ export function setupRemovePlugin() {
try {
// Delete the plugin's conda env
const env = settingsStore.get(`plugins.${pluginID}.env`);
const mamba = settingsStore.get('mamba');
await spawnWithLogging(mamba, ['remove', '--yes', '--prefix', `"${env}"`, '--all']);
const micromamba = settingsStore.get('micromamba');
await spawnWithLogging(micromamba, ['remove', '--yes', '--prefix', `"${env}"`, '--all']);
// Delete the plugin's data from storage
settingsStore.delete(`plugins.${pluginID}`);
logger.info('successfully removed plugin');
Expand Down
3 changes: 1 addition & 2 deletions workbench/src/main/setupInvestHandlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,10 @@ export function setupInvestRunHandlers() {
let port;
const plugins = settingsStore.get('plugins');
if (plugins && Object.keys(plugins).includes(modelRunName)) {
cmd = settingsStore.get('mamba');
cmd = settingsStore.get('micromamba');
cmdArgs = [
'run',
`--prefix "${settingsStore.get(`plugins.${modelRunName}.env`)}"`,
'--live-stream',
'invest',
LOGLEVELMAP[loggingLevel],
TGLOGLEVELMAP[taskgraphLoggingLevel],
Expand Down

0 comments on commit 595684b

Please sign in to comment.