Contributing Guide

Introduction

The Community Earth System Model (CIME) is a powerful, community-driven framework designed to support the development, configuration, and execution of Earth system models. As an open-source project, CIME thrives on the contributions of researchers, developers, and users worldwide. Whether you’re fixing a bug, adding new features, improving documentation, or sharing your expertise, your involvement helps advance the scientific community’s ability to understand and simulate Earth’s complex systems. This guide provides everything you need to get started—from setting up your development environment to submitting your first pull request—so you can contribute with confidence and join a vibrant community dedicated to scientific collaboration and innovation.

To get started, you can contribute by fixing issues or answering questions in the community forums. If you’re ready to dive deeper and contribute code, consider exploring these key areas:

  • The Case class, which is central to the CIME Configuration System (CCS);

  • XML classes, which form the backbone of CCS configuration;

  • SystemsTest, used to test models under specific conditions.

As you add features or bug fixes, remember the importance of adding unit tests.

Unit tests help ensure that each new change works as intended and doesn’t break existing functionality. By isolating and verifying small units of code, you catch bugs early, reduce the risk of regressions, and make your codebase more maintainable. Unit tests also act as living documentation, clarifying expected behavior for future developers and enabling safer refactoring. Investing in unit tests saves time, improves code quality, and builds confidence in your software’s reliability.

Testing

CIME splits it’s testing into two categories unit and sys.

  • The unit category covers both doctests and unit tests.

  • The sys category covers regression tests.

The tests are named accordingly e.g. unit tests are found as CIME/tests/test_unit*.

Running the tests

There are two possible methods to run these tests; pytest and scripts_regression_tests.

To run the tests with pytest you’ll need to install some packages; pytest and pytest-cov.

Warning

The scripts_regression_tests.py will be deprecated and the preferred method of running tests it pytest.

Unit Testing

Here’s an example for running the unit tests using both methods.

pytest CIME/tests/test_unit*
python CIME/tests/scripts_regression_tests.py CIME/tests/test_unit*

System Testing

pytest CIME/tests/test_sys*
python CIME/tests/scripts_regression_tests.py CIME/tests/test_sys*

Code Quality

To maintain high code quality and consistency, all code must be linted with Pylint and formatted using Black. We also use additional tools to enforce proper XML formatting, ensure files end with newlines, and eliminate trailing whitespace.

To streamline these checks, we require the use of pre-commit. While our GitHub Actions will automatically lint and check the format of every pull request, they will not fix issues for you—developers are responsible for resolving any linting or formatting errors.

We strongly recommend installing pre-commit’s Git hooks to run these checks automatically before each commit, helping you catch and fix issues early.

Installing pre-commit

pip install pre_commit
# or
# conda install -c conda-forge pre_commit

Running pre-commit

pre-commit run -a

Installing git hook scripts

If you install these scripts then pre-commit will automatically run on git commit.

pre-commit install

Docker container

CIME provides a container that is utilized by CI testing and provides developers with a consistent environment they can test in.

This container provides a GNU compiler, OpenMPI library and all confguration required to run CIME’s testing and build simple test cases. The compiler and libraries in the container is managed using Anaconda. There are currently two preloaded environments; e3sm and cesm.

Warning

Since CIME is generally provided as a sub-module in a projects repostiory the CIME containers do not provide either the project or CIME code. You’ll need to pass these through using a volume.

The provide machine configuration requires you to either set the containers hostname with --hostname docker or pass --machine docker to all CIME tooling.

It’s usually recommended to use the latest tag but if an older version is required you can find these at https://github.com/ESMCI/cime/pkgs/container/cime.

Running

The following assumes you’ve checkouted out your projects code to $HOME/model and the name of your model is stored in $TARGET_MODEL environment variable.

docker run -it --rm --hostname docker -v "$HOME/model":/home/cime/model -e USER_ID=`id -u` -e GROUP_ID=`id -g` -e CIME_MODEL="$TARGET_MODEL" ghcr.io/esmci/cime:latest bash

Warning

The -e USER_ID=`id -u` -e GROUP_ID=`id- g` is required so the containers uid/gid will match your host machines. This allows the containers user to have the correct permissions to view/edit files and if any new files are created you can access them outside the container.

While running CIME within the continer there may be a need to persist either the inputdata retrieved by CIME or the cases that are created. This can be accomplished using volumes. The following example assumes inputdata will be stored at $HOME/CIME/inputdata and cases at $HOME/CIME/cases.

docker run -it --rm --hostname docker -v "$HOME/model":/home/cime/model -v "$HOME/CIME/inputdata":/home/cime/inputdata -v "$HOME/CIME/cases":/home/cime/cases -e USER_ID=`id -u` -e GROUP_ID=`id -g` -e CIME_MODEL="$TARGET_MODEL" ghcr.io/esmci/cime:latest bash

Environment variables

The following environment variables control some aspects of the cotnainers behavior.

Name

Description

Default

USER_ID

Sets the container’s user id.

1000

GROUP_ID

Sets the container’s group id.

1000

SKIP_ENTRYPOINT

Skips entering a new shell as the container’s user.

false

Building

The container provides 3 targets.

  • base - Base image with no batch system.

  • slurm - Slurm batch system with configuration and single queue.

  • pbs - PBS batch system with configuration and single queue.

docker build -t ghcr.io/ESMCI/cime:latest --target <target> docker/