Skip to content

Commit 9e6b3ef

Browse files
authored
Merge branch 'main' into update_atom_enthalpies
2 parents 2a16b73 + 1d67d94 commit 9e6b3ef

File tree

303 files changed

+1217493
-2521
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

303 files changed

+1217493
-2521
lines changed

.github/workflows/CI.yml

Lines changed: 272 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,298 @@
1-
name: CI Tests
1+
# CI.yml
2+
# This file contains the script used by GitHub actions to execute the Continuous Integration (CI)
3+
# for RMG-Py. This includes building RMG and its dependencies, executing the unit tests,
4+
# functional tests, database tests, and regression tests.
5+
#
6+
# This will run automatically on any push to any branch, but will only run one instance of
7+
# itself at a time per branch (to avoid spawning tons of runners, which prevents them from
8+
# executing).
9+
#
10+
# In the regression testing section of the action the term "Stable" or "Reference" refers to
11+
# the 'correct answers' to the regression tests, i.e. the way that the main branch executes
12+
# them. These 'answers' are re-generated daily, or on any push to main, and retrieved whenever
13+
# a push is made to a non-main branch. The new proposed changes are referred to as "Dynamic".
14+
#
15+
# Changelog:
16+
# 2023-04 - Jackson Burns - Added this header, regression tests, cleanup of action in
17+
# in general, and documentation throughout the file.
18+
# 2023-05 - added Docker build steps
19+
# 2023-05-12 - added changes to allow running on forks
20+
# 2023-06-06 - added matrix build for libstdcxx-ng versions 12 and 13 on ubuntu. Only expect 12 to work.
21+
# 2023-06-07 - updated regression testing. Now fails if significant changes are detected.
22+
# 2023-06-15 - revert changes from 06-06, both now work
23+
name: Continuous Integration
224

325
on:
26+
schedule:
27+
# * is a special character in YAML so you have to quote this string
28+
- cron: "0 8 * * *"
29+
# runs on all branches on both RMG-Py and forks
430
push:
31+
# runs on PRs against RMG-Py (and anywhere else, but we add this for RMG-Py)
532
pull_request:
6-
branches:
7-
- main
8-
types: [opened, synchronize, reopened, ready_for_review, review_requested]
33+
# allow calling from other repos in the ReactionMechanismGenerator organization
34+
workflow_call:
35+
36+
# this prevents one PR from simultaneously running multiple runners, which will clog up the queue
37+
# and prevent other PRs from running the CI
38+
concurrency:
39+
group: ${{ github.workflow }}-${{ github.ref }}
40+
cancel-in-progress: true
41+
942
jobs:
10-
build-and-test-linux:
11-
runs-on: ubuntu-latest
43+
build-and-test-unix:
1244
strategy:
13-
max-parallel: 5
14-
env: # update this if needed to match a pull request on the RMG-database
45+
matrix:
46+
os: [ubuntu-latest, macos-latest]
47+
runs-on: ${{ matrix.os }}
48+
continue-on-error: ${{ matrix.os == 'macos-latest' }}
49+
# skip scheduled runs from forks
50+
if: ${{ !( github.repository != 'ReactionMechanismGenerator/RMG-Py' && github.event_name == 'schedule' ) }}
51+
env:
52+
# Update this if needed to match a pull request on the RMG-database:
1553
RMG_DATABASE_BRANCH: update_atom_enthalpies
54+
# This is true only if this is a reference case for the regression testing:
55+
REFERENCE_JOB: ${{ github.ref == 'refs/heads/main' && matrix.os =='ubuntu-latest' && github.repository == 'ReactionMechanismGenerator/RMG-Py' }}
1656
defaults:
1757
run:
1858
shell: bash -l {0}
1959
steps:
20-
- uses: actions/checkout@v2
21-
- uses: conda-incubator/setup-miniconda@v2
60+
- uses: actions/checkout@v3
61+
62+
# configures the mamba environment manager and builds the environment
63+
- name: Setup Mambaforge Python 3.7
64+
uses: conda-incubator/setup-miniconda@v2
2265
with:
2366
environment-file: environment.yml
67+
miniforge-variant: Mambaforge
68+
miniforge-version: latest
2469
python-version: 3.7
2570
activate-environment: rmg_env
26-
- name: Install codecov
27-
run: conda install -y -c conda-forge codecov
28-
- name: Conda info
29-
run: |
30-
conda info
31-
conda list
32-
- name: Install and link Julia dependencies
33-
run: |
34-
julia -e "using Pkg; Pkg.add(PackageSpec(url=\"https://github.com/ReactionMechanismGenerator/ReactionMechanismSimulator.jl\", rev=\"main\"))"
35-
julia -e "using Pkg; Pkg.add(\"PyCall\"); Pkg.add(\"DifferentialEquations\")"
36-
python -c "import julia; julia.install()"
37-
ln -sfn $(which python-jl) $(which python)
38-
- name: Install MOPAC
39-
env:
40-
MOPACKEY: ${{ secrets.MOPACKEY }}
41-
timeout-minutes: 1
42-
continue-on-error: true # allowed to fail on pull request from a forked repository
71+
use-mamba: true
72+
73+
# list the environment for debugging purposes
74+
- name: mamba info
4375
run: |
44-
set +o pipefail
45-
yes 'Yes' | ${CONDA_PREFIX}/bin/mopac "$MOPACKEY"
46-
- name: Install and compile RMG
76+
mamba info
77+
mamba list
78+
79+
# Clone the other needed repository
80+
- name: Clone RMG-Database
4781
run: |
4882
cd ..
4983
git clone -b $RMG_DATABASE_BRANCH https://github.com/ReactionMechanismGenerator/RMG-database.git
50-
cd RMG-Py
51-
git clone -b arkanepy3 https://github.com/mjohnson541/Q2DTor.git external/Q2DTor
84+
85+
# modify env variables as directed in the RMG installation instructions
86+
- name: Set Environment Variables
87+
run: |
88+
RUNNER_CWD=$(pwd)
89+
echo "PYTHONPATH=$RUNNER_CWD/RMG-Py:$PYTHONPATH" >> $GITHUB_ENV
90+
echo "$RUNNER_CWD/RMG-Py" >> $GITHUB_PATH
91+
92+
# RMG build step
93+
- name: make RMG
94+
run: |
95+
make clean
5296
make
53-
- name: Trigger RMG-tests
54-
if: ${{ github.event_name == 'push' && github.ref != 'refs/heads/main' && github.ref != 'refs/heads/stable' }} # only push events to branches other than main and stable
55-
env:
56-
GH_TOKEN: ${{ secrets.RMG_DEV_TOKEN }}
57-
run: ./trigger-rmg-tests.sh
97+
98+
# RMS installation and linking to Julia
99+
# Allow these installs to 'fail' (as they do in RMG-Tests) with the command || True trick
100+
- name: Install and link Julia dependencies
101+
timeout-minutes: 120 # this usually takes 20-45 minutes (or hangs for 6+ hours).
102+
run: |
103+
python -c "import julia; julia.install(); import diffeqpy; diffeqpy.install()" || true
104+
julia -e 'using Pkg; Pkg.add(PackageSpec(name="ReactionMechanismSimulator",rev="main")); using ReactionMechanismSimulator' || true
105+
106+
# non-regression testing
58107
- name: Unit tests
59108
run: make test-unittests
60109
- name: Functional tests
61-
if: ${{ success() || failure() }} # Run even if the unit tests failed (but not if they were cancelled)
62110
run: make test-functional
63111
- name: Database tests
64-
if: ${{ success() || failure() }} # Run even if the functional tests failed (but not if they were cancelled)
65112
run: make test-database
66-
- name: Code coverage
67-
run: codecov
113+
114+
# Regression Testing - Test Execution
115+
- name: Regression Tests - Execution
116+
id: regression-execution
117+
timeout-minutes: 60
118+
run: |
119+
for regr_test in aromatics liquid_oxidation nitrogen oxidation sulfur superminimal RMS_constantVIdealGasReactor_superminimal RMS_CSTR_liquid_oxidation RMS_liquidSurface_ch4o2cat;
120+
do
121+
if python-jl rmg.py test/regression/"$regr_test"/input.py; then
122+
echo "$regr_test" "Executed Successfully"
123+
else
124+
echo "$regr_test" "Failed to Execute" | tee -a $GITHUB_STEP_SUMMARY
125+
export FAILED=Yes
126+
fi
127+
done
128+
if [[ ${FAILED} ]]; then
129+
echo "One or more regression tests could not be executed." | tee -a $GITHUB_STEP_SUMMARY
130+
echo "Please download the failed results or check the above log to see why." | tee -a $GITHUB_STEP_SUMMARY
131+
exit 1
132+
fi
133+
134+
# Upload Regression Results as Failed if above step failed
135+
- name: Upload Failed Results
136+
if: ${{ failure() && steps.regression-execution.conclusion == 'failure' }}
137+
uses: actions/upload-artifact@v3
138+
with:
139+
name: failed regression results ${{ matrix.os }}
140+
path: |
141+
test/regression
142+
143+
# Upload Regression Results as Stable if Scheduled or Push to Main
144+
- name: Upload Results as Reference
145+
# upload the results for scheduled CI (on main) and pushes to main
146+
if: ${{ env.REFERENCE_JOB == 'true' }}
147+
uses: actions/upload-artifact@v3
148+
with:
149+
name: stable_regression_results
150+
path: |
151+
test/regression
152+
153+
# Upload Regression Results as Dynamic if Push to non-main Branch
154+
- name: Upload Results as Dynamic
155+
if: ${{ env.REFERENCE_JOB == 'false' }}
156+
uses: actions/upload-artifact@v3
157+
with:
158+
name: dynamic regression results ${{ matrix.os }}
159+
path: |
160+
test/regression
161+
162+
- name: mkdir stable_regression_results
163+
if: ${{ env.REFERENCE_JOB == 'false' }}
164+
run: mkdir stable_regression_results
165+
166+
# Retrieve Stable Results for reference
167+
# Will need to use this -> https://github.com/dawidd6/action-download-artifact
168+
- name: Retrieve Stable Regression Results
169+
if: ${{ env.REFERENCE_JOB == 'false' }}
170+
uses: dsnopek/action-download-artifact@91dda23aa09c68860977dd0ed11d93c0ed3795e7 # see https://github.com/ReactionMechanismGenerator/RMG-Py/pull/2459#issuecomment-1582850815
171+
with:
172+
# this will search for the last successful execution of CI on main and download
173+
# the stable regression results
174+
workflow: CI.yml
175+
workflow_conclusion: success
176+
repo: ReactionMechanismGenerator/RMG-Py
177+
branch: main
178+
name: stable_regression_results
179+
path: stable_regression_results
180+
search_artifacts: true # retrieves the last run result, either scheduled daily or on push to main
181+
ensure_latest: true # ensures that the latest run is retrieved
182+
# should result in a set of folders inside stable_regression_results
183+
# each of which has the stable result for that example/test
184+
185+
# Regression Testing - Actual Comparisons
186+
- name: Regression Tests - Compare to Baseline
187+
id: regression-comparison
188+
if: ${{ env.REFERENCE_JOB == 'false' }}
189+
env:
190+
REFERENCE: stable_regression_results
191+
run: |
192+
mkdir -p "test/regression-diff"
193+
for regr_test in aromatics liquid_oxidation nitrogen oxidation sulfur superminimal RMS_constantVIdealGasReactor_superminimal RMS_CSTR_liquid_oxidation;
194+
do
195+
echo ""
196+
echo "## Regression test $regr_test:"
197+
# Memory Usage and Execution Time
198+
echo -n 'Reference: '
199+
grep "Execution time" $REFERENCE/"$regr_test"/RMG.log | tail -1
200+
echo -n 'Current: '
201+
grep "Execution time" test/regression/"$regr_test"/RMG.log | tail -1
202+
echo -n 'Reference: '
203+
grep "Memory used:" $REFERENCE/"$regr_test"/RMG.log | tail -1
204+
echo -n 'Current: '
205+
grep "Memory used:" test/regression/"$regr_test"/RMG.log | tail -1
206+
207+
# Compare the edge and core
208+
if python-jl scripts/checkModels.py \
209+
"$regr_test-core" \
210+
$REFERENCE/"$regr_test"/chemkin/chem_annotated.inp \
211+
$REFERENCE/"$regr_test"/chemkin/species_dictionary.txt \
212+
test/regression/"$regr_test"/chemkin/chem_annotated.inp \
213+
test/regression/"$regr_test"/chemkin/species_dictionary.txt
214+
then
215+
echo "$regr_test Passed Core Comparison"
216+
else
217+
echo "$regr_test Failed Core Comparison" | tee -a $GITHUB_STEP_SUMMARY
218+
cp "$regr_test-core.log" test/regression-diff/
219+
export FAILED=Yes
220+
fi
221+
if python-jl scripts/checkModels.py \
222+
"$regr_test-edge" \
223+
$REFERENCE/"$regr_test"/chemkin/chem_edge_annotated.inp \
224+
$REFERENCE/"$regr_test"/chemkin/species_edge_dictionary.txt \
225+
test/regression/"$regr_test"/chemkin/chem_edge_annotated.inp \
226+
test/regression/"$regr_test"/chemkin/species_edge_dictionary.txt
227+
then
228+
echo "$regr_test Passed Edge Comparison"
229+
else
230+
echo "$regr_test Failed Edge Comparison" | tee -a $GITHUB_STEP_SUMMARY
231+
cp "$regr_test-edge.log" test/regression-diff/
232+
export FAILED=Yes
233+
fi
234+
235+
# Check for Regression between Reference and Dynamic (skip superminimal)
236+
if [ -f test/regression/"$regr_test"/regression_input.py ];
237+
then
238+
if python-jl rmgpy/tools/regression.py \
239+
test/regression/"$regr_test"/regression_input.py \
240+
$REFERENCE/"$regr_test"/chemkin \
241+
test/regression/"$regr_test"/chemkin
242+
then
243+
echo "$regr_test Passed Observable Testing"
244+
else
245+
echo "$regr_test Failed Observable Testing" | tee -a $GITHUB_STEP_SUMMARY
246+
export FAILED=Yes
247+
fi
248+
fi
249+
echo ""
250+
done
251+
if [[ ${FAILED} ]]; then
252+
echo "One or more regression tests failed." | tee -a $GITHUB_STEP_SUMMARY
253+
echo "Please download the failed results and run the tests locally or check the above log to see why." | tee -a $GITHUB_STEP_SUMMARY
254+
exit 1
255+
fi
256+
# Upload Regression Results as Failed if above step failed
257+
- name: Upload Failed Comparison Results
258+
if: ${{ failure() && steps.regression-comparison.conclusion == 'failure' }}
259+
uses: actions/upload-artifact@v3
260+
with:
261+
name: failed regression comparison results ${{ matrix.os }}
262+
path: |
263+
test/regression-diff
264+
# Install and Call codecov only if the tests were successful (permitting failures in the regression comparison tests)
265+
- name: Code coverage install and run
266+
if: success() || ( failure() && steps.regression-execution.conclusion == 'success' )
267+
run: |
268+
mamba install -y -c conda-forge codecov
269+
codecov
270+
271+
build-and-push-docker:
272+
# after testing and on pushes to main, build and push docker image
273+
# technically we could live without the 'needs' since _in theory_
274+
# nothing will ever be merged into main that fails the tests, but
275+
# who knows ¯\_(ツ)_/¯
276+
#
277+
# taken from https://github.com/docker/build-push-action
278+
needs: build-and-test-unix
279+
runs-on: ubuntu-latest
280+
if: github.ref == 'refs/heads/main' && github.repository == 'ReactionMechanismGenerator/RMG-Py'
281+
steps:
282+
- name: Set up QEMU
283+
uses: docker/setup-qemu-action@v2
284+
285+
- name: Set up Docker Buildx
286+
uses: docker/setup-buildx-action@v2
287+
288+
- name: Login to Docker Hub
289+
uses: docker/login-action@v2
290+
with:
291+
username: ${{ secrets.DOCKERHUB_USERNAME }}
292+
password: ${{ secrets.DOCKERHUB_TOKEN }}
293+
294+
- name: Build and Push
295+
uses: docker/build-push-action@v4
296+
with:
297+
push: true
298+
tags: reactionmechanismgenerator/rmg:latest

0 commit comments

Comments
 (0)