Skip to content

Commit 5cd683f

Browse files
authored
Merge pull request #2828 to improve RMS and Julia installation.
Overhaul the install_rms.sh script to make RMS (ReactionMechanismSimulator) installation more robust and user-friendly: Add zsh compatibility and fix Julia heredoc escaping issues Fix detection of conda executable Support RMS_PATH and RMS_INSTALLER environment variables Make standard mode the default; add "developer" option for dev installs Add conda environment check and initialize Julia environment before installing Reorganize code with better documentation and variable grouping Update Dockerfile for the new install_rms script Also adds installation instructions for the new script to the developer documentation.
2 parents 495a5b0 + 0e32a7b commit 5cd683f

5 files changed

Lines changed: 170 additions & 13 deletions

File tree

.github/workflows/CI.yml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# This file contains the script used by GitHub actions to execute the Continuous Integration (CI)
33
# for RMG-Py. This includes building RMG and its dependencies, executing the unit tests,
44
# functional tests, database tests, and regression tests.
5-
#
5+
#
66
# This will run automatically on any push to any branch, but will only run one instance of
77
# itself at a time per branch (to avoid spawning tons of runners, which prevents them from
88
# executing).
@@ -14,7 +14,7 @@
1414
#
1515
#
1616
# Changelog:
17-
# 2023-04 - Jackson Burns - Added this header, regression tests, cleanup of action in
17+
# 2023-04 - Jackson Burns - Added this header, regression tests, cleanup of action in
1818
# in general, and documentation throughout the file.
1919
# 2023-05 - added Docker build steps
2020
# 2023-05-12 - added changes to allow running on forks
@@ -54,6 +54,8 @@ env:
5454
RMG_DATABASE_BRANCH: main
5555
# RMS branch to use for ReactionMechanismSimulator installation
5656
RMS_BRANCH: for_rmg
57+
# RMS mode used for install_rms.sh
58+
RMS_INSTALLER: continuous
5759
# julia parallel pre-compilation leads to race conditions and hangs, so we limit it to run in serial
5860
JULIA_NUM_PRECOMPILE_TASKS: 1
5961

@@ -131,7 +133,7 @@ jobs:
131133
name: Regression Test
132134
# skip scheduled runs from forks
133135
if: ${{ !( github.repository != 'ReactionMechanismGenerator/RMG-Py' && github.event_name == 'schedule' ) }}
134-
env:
136+
env:
135137
# This is true only if this is a reference case for the regression testing:
136138
REFERENCE_JOB: ${{ github.ref == 'refs/heads/main' && github.repository == 'ReactionMechanismGenerator/RMG-Py' }}
137139
defaults:
@@ -167,7 +169,7 @@ jobs:
167169
168170
# RMG build step
169171
- run: make install
170-
172+
171173
- name: Make separate No-RMS conda env
172174
run: |
173175
conda create --name rmg_env_without_rms --clone rmg_env
@@ -270,7 +272,7 @@ jobs:
270272
REFERENCE: stable_regression_results
271273
run: |
272274
conda activate rmg_env_without_rms
273-
275+
274276
exec 2> >(tee -a regression.stderr >&2) 1> >(tee -a regression.stdout)
275277
mkdir -p "test/regression-diff"
276278
for regr_test in aromatics liquid_oxidation nitrogen oxidation sulfur superminimal RMS_constantVIdealGasReactor_superminimal RMS_CSTR_liquid_oxidation fragment RMS_constantVIdealGasReactor_fragment minimal_surface;

Dockerfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,11 @@ RUN make
7777
# setting this env variable fixes an issue with Julia precompilation on Windows
7878
ENV JULIA_CPU_TARGET="x86-64,haswell,skylake,broadwell,znver1,znver2,znver3,cascadelake,icelake-client,cooperlake,generic"
7979
ENV RMS_BRANCH=${RMS_Branch}
80+
ENV RMS_INSTALLER=continuous
8081
# Usually this is set automatically, but we're not actually running
8182
# in an active conda environment when building the Docker so we need to set it manually
8283
ENV PYTHON_JULIAPKG_PROJECT="/miniconda/envs/rmg_env/julia_env"
84+
ENV JULIA_PYTHONCALL_EXE="/miniconda/envs/rmg_env/bin/python"
8385
RUN source install_rms.sh
8486

8587
# RMG-Py should now be installed and ready - trigger precompilation and test run

documentation/source/users/rmg/installation/anacondaDeveloper.rst

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,25 @@ Installation by Source Using Anaconda Environment for Unix-based Systems: Linux
129129
which can involve several steps including restarting your terminal or shell.
130130
Run the script again, until it finishes installing RMS and all of its dependencies, and reports that ReactionMechanismSimulator is installed.
131131

132+
**Advanced Usage**:
133+
The ``install_rms.sh`` script has options, that can be set as environment variables or variables to the script.
134+
By default, it installs the latest release of the ``for_rmg`` branch of RMS, from `the official GitHub fork <https://github.com/ReactionMechanismGenerator/ReactionMechanismSimulator.jl/branches>`_, which is recommended for most users.
135+
To install a different branch (from the same github repository) specify ``RMS_BRANCH``.
136+
The default installation mode is ``standard``, which prompts the user to confirm their conda environment.
137+
In an automated workflow (eg. CI/CD), you may wish to set ``RMS_INSTALLER`` to ``continuous`` to skip the prompt.
138+
If you set ``RMS_INSTALLER`` to ``developer`` then it will link to a local version of RMS,
139+
so you must also specify ``RMS_PATH`` to point to your local clone of the ReactionMechanismSimulator.jl repository.
140+
Exmaple usage: ::
141+
142+
export RMS_BRANCH=for_rmg
143+
export RMS_INSTALLER=continuous
144+
source install_rms.sh
145+
146+
or ::
147+
148+
RMS_INSTALLER=developer RMS_PATH=$HOME/Code/ReactionMechanismSimulator.jl source install_rms.sh
149+
150+
132151
#. Finally, you can run RMG from any location by typing the following (given that you have prepared the input file as ``input.py`` in the current folder). ::
133152

134153
python replace/with/path/to/rmg.py input.py

documentation/source/users/rmg/releaseNotes.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ RMG-Py Version 3.3.0
88
====================
99
Date: July 10, 2025
1010

11-
The below list is a summary. For a complete list of all changes, see the `Official Release Page <https://github.com/ReactionMechanismGenerator/RMG-Py/releases/tag/3.3.0>`_.
11+
The below list is a summary. For a complete list of all changes, see the `Official RMG-Py Release Page <https://github.com/ReactionMechanismGenerator/RMG-Py/releases/tag/3.3.0>`_.
1212

1313
- Software Improvements
1414
- RMG-Py now uses Python 3.9
@@ -33,7 +33,7 @@ RMG-Database Version 3.3.0
3333
==========================
3434
Date: July 10, 2025
3535

36-
The below list is a summary. For a complete list of all changes, see the `Official Release Page <https://github.com/ReactionMechanismGenerator/RMG-database/releases/tag/3.3.0>`_.
36+
The below list is a summary. For a complete list of all changes, see the `Official RMG-Database Release Page <https://github.com/ReactionMechanismGenerator/RMG-database/releases/tag/3.3.0>`_.
3737

3838
- Features
3939
- Electrochemistry with Lithium

install_rms.sh

100644100755
Lines changed: 140 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,43 @@
22
#
33
# Convenience script to install ReactionMechanismSimulator into an rmg_env conda environment
44
#
5+
# Usage:
6+
# source install_rms.sh
7+
# Options:
8+
# RMS_INSTALLER environment variable can be set to "continuous", "standard", or "developer"
9+
# "continuous": non-interactive install for CI environments
10+
# "standard": interactive install with user confirmation (default)
11+
# "developer": install from local RMS source code (requires RMS_PATH to be set)
12+
# RMS_PATH environment variable (required if RMS_INSTALLER="developer")
13+
# Path to local ReactionMechanismSimulator.jl source code for developer mode
14+
# RMS_BRANCH environment variable (optional), for "standard" or "continuous" modes
15+
# Git branch of ReactionMechanismSimulator.jl to install (default: for_rmg)
16+
# Example:
17+
# RMS_INSTALLER=developer RMS_PATH=/path/to/ReactionMechanismSimulator.jl source install_rms.sh
18+
19+
20+
# Defaults to "standard" if not already set via RMS_INSTALLER env variable
21+
RMS_INSTALLER=${RMS_INSTALLER:-standard}
22+
23+
# RMS branch for standard or continuous installs. Set to "for_rmg" by default.
24+
RMS_BRANCH=${RMS_BRANCH:-for_rmg}
25+
26+
# Get local RMS path if in developer mode
27+
if [ "$RMS_INSTALLER" = "developer" ]; then
28+
echo "Using developer mode for RMS installation"
29+
# Check if RMS_PATH is set
30+
if [ -z "$RMS_PATH" ]; then
31+
printf "Please enter full path to your local RMS source code: "
32+
read -r RMS_PATH
33+
fi
34+
# Validate Project.toml exists
35+
if [ ! -f "$RMS_PATH/Project.toml" ]; then
36+
echo "ERROR: '$RMS_PATH' does not contain a Project.toml file."
37+
echo "Please set RMS_PATH to a valid ReactionMechanismSimulator.jl directory."
38+
return 1
39+
fi
40+
echo "Using local RMS path: $RMS_PATH"
41+
fi
542

643
# Check if juliaup is installed
744
if ! command -v juliaup &> /dev/null; then
@@ -39,16 +76,39 @@ echo "Julia 1.10 binary path: $julia_path"
3976

4077
# Get current conda environment name
4178
current_env=$(conda info --envs | grep -v '^#' | awk '/\*/{print $1}')
42-
echo "Current conda environment: $current_env"
79+
80+
# Ask the user to confirm RMS is being installed in the correct conda environemnt.
81+
# Skip confirmation if this is run under continuous mode.
82+
if [ "$RMS_INSTALLER" = "continuous" ]; then
83+
echo "Current conda environment: $current_env"
84+
else
85+
echo " Please confirm that you want to install RMS into the current conda environment: '$current_env'"
86+
echo " If this is not correct, abort and activate the correct environment before rerunning."
87+
printf "Proceed with installation in '%s'? (y/N): " "$current_env"
88+
read confirm
89+
case "$confirm" in
90+
[yY][eE][sS]|[yY])
91+
echo "✅ Proceeding with installation in '$current_env'"
92+
;;
93+
*)
94+
echo "❌ Aborted. Please activate the correct conda environment and try again."
95+
return 1
96+
;;
97+
esac
98+
fi
4399

44100
# Set environment variables for the current environment, for future uses
45101
# https://juliapy.github.io/PythonCall.jl/stable/pythoncall/#If-you-already-have-Python-and-required-Python-packages-installed
102+
# Find the actual conda executable (not the shell function)
103+
CONDA_EXE="${CONDA_EXE:-$(conda info --base)/bin/conda}"
46104
conda env config vars set JULIA_CONDAPKG_BACKEND=Null
105+
conda env config vars set JULIA_CONDAPKG_EXE="$CONDA_EXE"
47106
conda env config vars set JULIA_PYTHONCALL_EXE=$CONDA_PREFIX/bin/python
48107
conda env config vars set PYTHON_JULIAPKG_EXE=$(which julia)
49108
conda env config vars set PYTHON_JULIAPKG_PROJECT=$CONDA_PREFIX/julia_env
50109
# Also export for current shell/session (needed for Docker/non-interactive use)
51110
export JULIA_CONDAPKG_BACKEND=Null
111+
export JULIA_CONDAPKG_EXE="$CONDA_EXE"
52112
export JULIA_PYTHONCALL_EXE="$CONDA_PREFIX/bin/python"
53113
export PYTHON_JULIAPKG_EXE="$(which julia)"
54114
export PYTHON_JULIAPKG_PROJECT="$CONDA_PREFIX/julia_env"
@@ -58,11 +118,85 @@ conda install -y conda-forge::pyjuliacall
58118
echo "Environment variables referencing JULIA:"
59119
env | grep JULIA
60120

61-
# Use RMS_BRANCH environment variable if set, otherwise default to for_rmg
62-
RMS_BRANCH=${RMS_BRANCH:-for_rmg}
63-
echo "Installing ReactionMechanismSimulator from branch: $RMS_BRANCH"
121+
# Initialize the Julia environment from Python using juliacall
122+
python << EOF || return 1
123+
import sys
124+
try:
125+
from juliacall import Main
126+
Main.seval('println("Active Julia environment: ", Base.active_project())')
127+
Main.seval('println("Julia load path: ", Base.load_path())')
128+
Main.seval('using Pkg')
129+
Main.seval('Pkg.status()')
130+
except Exception as e:
131+
print("❌ Error while initializing Julia environment:")
132+
print(e)
133+
sys.exit(1)
134+
EOF
64135

65-
julia -e "using Pkg; Pkg.add(Pkg.PackageSpec(name=\"ReactionMechanismSimulator\", url=\"https://github.com/ReactionMechanismGenerator/ReactionMechanismSimulator.jl.git\", rev=\"$RMS_BRANCH\")); using ReactionMechanismSimulator; println(read(joinpath(dirname(pathof(ReactionMechanismSimulator)), \"..\", \"Project.toml\"), String)); Pkg.instantiate()" || echo "RMS install error - continuing anyway."
136+
# Install RMS
137+
if [ "$RMS_INSTALLER" = "standard" ] || [ "$RMS_INSTALLER" = "continuous" ]; then
138+
echo "Installing RMS from branch: $RMS_BRANCH"
139+
julia << 'EOF' || echo "RMS standard install error - continuing anyway ¯\\_(ツ)_/¯"
140+
using Pkg
141+
Pkg.activate(ENV["PYTHON_JULIAPKG_PROJECT"])
142+
Pkg.add(Pkg.PackageSpec(name="ReactionMechanismSimulator", url="https://github.com/ReactionMechanismGenerator/ReactionMechanismSimulator.jl.git", rev=ENV["RMS_BRANCH"]))
143+
println(read(joinpath(dirname(pathof(ReactionMechanismSimulator)), "..", "Project.toml"), String))
144+
Pkg.instantiate()
145+
try
146+
@info "Loading RMS"
147+
using ReactionMechanismSimulator
148+
@info "RMS loaded successfully!"
149+
catch err
150+
@error "Failed to load RMS" exception=err
151+
Base.show_backtrace(stderr, catch_backtrace())
152+
exit(1)
153+
end
154+
EOF
155+
elif [ "$RMS_INSTALLER" = "developer" ]; then
156+
echo "Installing RMS in developer mode from path: $RMS_PATH"
157+
julia << 'EOF' || echo "RMS developer install error - continuing anyway ¯\\_(ツ)_/¯"
158+
using Pkg
159+
println(ENV["PYTHON_JULIAPKG_PROJECT"])
160+
Pkg.activate(ENV["PYTHON_JULIAPKG_PROJECT"])
161+
Pkg.develop(path=ENV["RMS_PATH"])
162+
Pkg.instantiate()
163+
try
164+
@info "Loading RMS"
165+
using ReactionMechanismSimulator
166+
@info "RMS loaded successfully!"
167+
catch err
168+
@error "Failed to load RMS" exception=err
169+
Base.show_backtrace(stderr, catch_backtrace())
170+
exit(1)
171+
end
172+
EOF
173+
else
174+
echo "Unknown RMS_INSTALLER mode: $RMS_INSTALLER. Must be either 'continuous', 'standard' or 'developer'."
175+
return 1
176+
fi
177+
178+
julia_status=$?
179+
if [ $julia_status -ne 0 ]; then
180+
echo "RMS installation failed!"
181+
return $julia_status
182+
fi
66183

67184
echo "Checking if ReactionMechanismSimulator is installed in the current conda environment for Python usage..."
68-
python -c "from juliacall import Main; import sys; sys.exit(0 if Main.seval('Base.identify_package(\"ReactionMechanismSimulator\") !== nothing') and print('ReactionMechanismSimulator is installed in $current_env') is None else 1)"
185+
186+
python << EOF
187+
import sys
188+
try:
189+
from juliacall import Main
190+
RMS_Pkg = Main.seval('Base.identify_package("ReactionMechanismSimulator")')
191+
print("Package identify result: ", RMS_Pkg)
192+
if RMS_Pkg is Main.nothing:
193+
print("❌ ReactionMechanismSimulator is NOT installed correctly.")
194+
sys.exit(1)
195+
else:
196+
print("✅ ReactionMechanismSimulator is succesfully installed!")
197+
sys.exit(0)
198+
except Exception as e:
199+
print("❌ Error while checking ReactionMechanismSimulator installation:")
200+
print(e)
201+
sys.exit(1)
202+
EOF

0 commit comments

Comments
 (0)