diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 3219b5e..4aeeb17 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -6,7 +6,6 @@ Please confirm that this pull request has done the following: - [ ] Tests added - [ ] Documentation added (where applicable) - - +- [ ] Changelog item added to `changelog/` ## Notes diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000..b52dde0 --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,99 @@ +name: Create release + +on: + workflow_dispatch: + inputs: + bump_rule: + type: choice + description: How to bump the project's version (see https://docs.astral.sh/uv/reference/cli/#uv-version) + options: + - patch + - minor + - major + - alpha + - beta + - rc + - dev + required: true + +jobs: + bump-version: + name: "Bump version and create changelog" + if: "!startsWith(github.event.head_commit.message, 'bump:')" + runs-on: ubuntu-latest + env: + CI_COMMIT_EMAIL: "ci-runner@openmethane.invalid" + outputs: + release-notes: ${{ steps.release-notes.outputs.RELEASE_BODY }} + release-version: ${{ steps.release-version.outputs.RELEASE_VERSION }} + steps: + - name: Check out repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.PAT }} + + - name: Install uv + uses: astral-sh/setup-uv@v7 + with: + enable-cache: true + - name: Determine release version + id: release-version + run: | + BUMP="${{ github.event.inputs.bump_rule }}" + # patch is already bumped for pre-release, "stable" will remove "dev" + [[ $BUMP == "patch" ]] && BUMP="stable" + + BASE_VERSION=`uv version --short` + NEW_VERSION=`uv version --short --bump $BUMP` + echo "BASE_VERSION=$BASE_VERSION" >> $GITHUB_ENV + echo "NEW_VERSION=$NEW_VERSION" >> $GITHUB_ENV + echo "RELEASE_VERSION=$NEW_VERSION" >> $GITHUB_OUTPUT + + # Generates changelog text without removing fragments, for use later in the release + - name: Generate release notes + id: release-notes + run: | + echo 'RELEASE_BODY<> $GITHUB_OUTPUT + uvx towncrier build --draft --version "v$NEW_VERSION" >> $GITHUB_OUTPUT + echo 'EOF' >> $GITHUB_OUTPUT + + - name: Bump version and generate changelog + run: | + git config --global user.name "$GITHUB_ACTOR" + git config --global user.email "$CI_COMMIT_EMAIL" + + # Bump + echo "Bumping version $BASE_VERSION > $NEW_VERSION" + uvx towncrier build --yes --version v$NEW_VERSION + git commit -a -m "bump: version $BASE_VERSION -> $NEW_VERSION" + git tag v$NEW_VERSION + + - name: Bump to pre-release version + run: | + git config --global user.name "$GITHUB_ACTOR" + git config --global user.email "$CI_COMMIT_EMAIL" + + # Bump to pre-release so that future commits do not have the same + # version as the tagged commit + NEXT_VERSION=`uv version --short --bump patch --bump dev` + echo "Bumping version $NEW_VERSION > $NEXT_VERSION" + git commit -a -m "bump(pre-release): version $NEW_VERSION > $NEXT_VERSION" + git push && git push --tags + + publish-release: + name: Create release + runs-on: ubuntu-latest + needs: bump-version + steps: + - name: Check out repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Create release + uses: softprops/action-gh-release@v1 + with: + tag_name: v${{ needs.bump-version.outputs.release-version }} + body: ${{ needs.bump-version.outputs.release-notes }} + token: "${{ secrets.PAT }}" diff --git a/.gitignore b/.gitignore index d999b25..bceb036 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ +# Python virtual environment +.venv + # JetBrains IDEs .idea diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..ce40395 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,20 @@ +# Changelog + +Versions follow [Semantic Versioning](https://semver.org/) (`..`). + +Backward incompatible (breaking) changes will only be introduced in major versions +with advance notice in the **Deprecations** section of releases. + + + + + diff --git a/Dockerfile b/Dockerfile index 5ec3ccb..d476c0b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM debian:bookworm-slim as builder +FROM debian:bookworm-slim AS builder ARG DEBIAN_FRONTEND=noninteractive @@ -96,8 +96,11 @@ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* EOT ENV CMAQ_VERSION="5.0.2" +ENV OPENMETHANE_CMAQ_VERSION="1.0.0" + ENV M3HOME=/opt/cmaq ENV M3LIB=/opt/lib +ENV BIN_DIR=/opt/cmaq/bin COPY --from=builder /opt/scripts/config.cmaq /opt/scripts/config.cmaq COPY --from=builder /opt/cmaq /opt/cmaq diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..7769c35 --- /dev/null +++ b/LICENSE @@ -0,0 +1,10 @@ +# MIT License + +Copyright (c) 2025 The Superpower Institute (for files/changes created from 2025 onwards) +Copyright (c) 2019 U.S. Federal Government (in countries where recognized) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index f95f683..c02e170 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,28 @@ -**Note:** this repository is a fork of U.S. EPA +# Open Methane CMAQ + +Open Methane CMAQ is a fork of US EPA [CMAQ 5.0.2](https://github.com/USEPA/CMAQ/tree/5.0.2). -Changes are limited to bug fixes and updates to build scripts to make it easier -to build the project in a modern linux / docker environment. +The primary science change is the introduction of the `CH4only` chemical +mechanism in `models/CCTM/MECHS/CH4only`, and associated profiles in +`models/BCON/prof_data` and `models/ICON/prof_data`. + +Other changes from the official CMAQ v5.0.2 release include: + - bug fixes + - support for newer file formats, ie WRFv4 + - updates to build scripts to enable building and running in docker + +## License + +US EPA did not include a definitive LICENSE in the 5.0.2 release of CMAQ. +However, the CMAQ v5.4 release (2019) includes an +[MIT license](https://github.com/USEPA/CMAQ/blob/5.4/license.md. We have +duplicated that license in a best effort to respect the intentions of the +copyright owner. + +Where individual files in this repo include their own license in headers or +comments, that license should be considered to apply to the file in place of +the general license provided in the repository LICENSE file. # CMAQ diff --git a/changelog/1.feature.1.md b/changelog/1.feature.1.md new file mode 100644 index 0000000..192561f --- /dev/null +++ b/changelog/1.feature.1.md @@ -0,0 +1 @@ +Initial fork of USEPA/CMAQ 5.0.2 \ No newline at end of file diff --git a/changelog/1.feature.2.md b/changelog/1.feature.2.md new file mode 100644 index 0000000..d9e082f --- /dev/null +++ b/changelog/1.feature.2.md @@ -0,0 +1 @@ +Add scripts to build ioapi, pario, stenex and bldmake \ No newline at end of file diff --git a/changelog/1.feature.3.md b/changelog/1.feature.3.md new file mode 100644 index 0000000..56d49c1 --- /dev/null +++ b/changelog/1.feature.3.md @@ -0,0 +1 @@ +Downgrade vendored pario and stenex to versions compatible with CMAQ adjoint (CMAQ 4.7.1) \ No newline at end of file diff --git a/changelog/1.feature.4.md b/changelog/1.feature.4.md new file mode 100644 index 0000000..5ff648b --- /dev/null +++ b/changelog/1.feature.4.md @@ -0,0 +1 @@ +Add Dockerfile to provide image with compiled libraries and CMAQ \ No newline at end of file diff --git a/changelog/2.improvement.md b/changelog/2.improvement.md new file mode 100644 index 0000000..047f519 --- /dev/null +++ b/changelog/2.improvement.md @@ -0,0 +1 @@ +Add GitHub issue and PR templates and GitHub Actions build workflow \ No newline at end of file diff --git a/changelog/3.feature.md b/changelog/3.feature.md new file mode 100644 index 0000000..af3f262 --- /dev/null +++ b/changelog/3.feature.md @@ -0,0 +1 @@ +Add CH4only chemical mechanism and bcon/icon profile data diff --git a/changelog/4.improvement.md b/changelog/4.improvement.md new file mode 100644 index 0000000..05b89b3 --- /dev/null +++ b/changelog/4.improvement.md @@ -0,0 +1 @@ +Add changelog and release process based on uv and towncrier diff --git a/changelog/README.md b/changelog/README.md new file mode 100644 index 0000000..4ffc836 --- /dev/null +++ b/changelog/README.md @@ -0,0 +1,41 @@ +# CHANGELOG + +This directory contains "news fragments", i.e. short files that contain a small markdown-formatted bit of text that will be +added to the CHANGELOG when it is next compiled. + +The CHANGELOG will be read by users, so this description should be aimed to openmethane users instead of +describing internal changes which are only relevant to developers. Merge requests in combination with our git history provides additional +developer-centric information. + +Make sure to use phrases in the past tense and use punctuation, examples: + +``` +Improved verbose diff output with sequences. + +Terminal summary statistics now use multiple colors. +``` + +Each file should have a name of the form `..md`, where `` is the merge request number, and `` is one of: + +* `feature`: new user facing features, like new command-line options and new behaviour. +* `improvement`: improvement of existing functionality, usually without requiring user intervention +* `fix`: fixes a bug. +* `docs`: documentation improvement, like rewording an entire section or adding missing docs. +* `deprecation`: feature deprecation. +* `breaking`: a change which may break existing uses, such as feature removal or behaviour change. +* `trivial`: fixing a small typo or internal change that might be noteworthy. + +So for example: `123.feature.md`, `456.fix.md`. + +Since you need the merge request number for the filename, you must submit a MR first. From this MR, you can get the MR number and then create the news file. A single MR can also have multiple news items, for example a given MR may add a feature as well as +deprecate some existing functionality. + +If you are not sure what issue type to use, don't hesitate to ask in your MR. + +`towncrier` preserves multiple paragraphs and formatting (code blocks, lists, and so on), but for entries other than +features it is usually better to stick to a single paragraph to keep it concise. You may also use `MyST` [style +cross-referencing](https://myst-parser.readthedocs.io/en/latest/syntax/cross-referencing.html) within your news items to link to other +documentation. + +You can also run `towncrier build --draft` to see the draft changelog that will be appended to [docs/source/changelog.md]() +on the next release. diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..f15ccc7 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,24 @@ +[project] +name = "cmaq" +version = "0.1.0" +dependencies = [] + +[tool.towncrier] +filename = "CHANGELOG.md" +directory = "changelog/" +title_format = "## Open Methane CMAQ {version} ({project_date})" +underlines = [ + "", + "", + "", +] +issue_format = "[#{issue}](https://github.com/openmethane/CMAQ/pull/{issue})" +type = [ + { directory = "breaking", name = "⚠️ Breaking Changes", showcontent = true }, + { directory = "deprecation", name = "🗑️ Deprecations", showcontent = true }, + { directory = "feature", name = "🆕 Features", showcontent = true }, + { directory = "improvement", name = "🎉 Improvements", showcontent = true }, + { directory = "fix", name = "🐛 Bug Fixes", showcontent = true }, + { directory = "docs", name = "📚 Improved Documentation", showcontent = true }, + { directory = "trivial", name = "🔧 Trivial/Internal Changes", showcontent = false }, +] diff --git a/scripts/config.cmaq b/scripts/config.cmaq index 14bf450..b1936f4 100755 --- a/scripts/config.cmaq +++ b/scripts/config.cmaq @@ -16,8 +16,9 @@ if (! $?M3HOME) then setenv M3HOME /opt/cmaq endif - setenv M3MODEL ${M3HOME}/models - setenv M3DATA ${M3HOME}/data + +setenv M3MODEL ${M3HOME}/models +setenv M3DATA ${M3HOME}/data #=============================================================================== @@ -25,71 +26,27 @@ endif #------------------------------------------------------------------------------- #> set the COMPILER -# setenv COMPILER intel -# setenv COMPILER pgi - setenv COMPILER gcc - - setenv system "`/bin/uname -m`" - setenv bld_os "`/bin/uname -s``/bin/uname -r | cut -d. -f1`" - setenv lib_basedir $M3HOME/lib -######## set these extra library paths only if needed for your architecture -#setenv extra_lib "-openmp" -#setenv extra_lib "-lrdmacm -libumad -lopa -lmpl -lrt -lpthread -libverbs -ldl" -#setenv extra_lib "-lrdmacm -libumad " +setenv COMPILER gcc + +setenv system "`/bin/uname -m`" +setenv bld_os "`/bin/uname -s``/bin/uname -r | cut -d. -f1`" +setenv lib_basedir $M3HOME/lib setenv extra_lib ####### MPI libraries ######## #use -lmpich for mvpich and -lmpi for openmpi setenv mpi "-lmpich" -#setenv mpi "-lmpi" - - switch ( $COMPILER ) - case intel: -##> Intel fortran compiler...................................................... - setenv compiler intel - setenv compiler_ext ifort - setenv myFC mpif90 - setenv myCC mpicc - setenv myLINK_FLAG "-i-static" - setenv myFFLAGS "-fixed -132 -O3 -override-limits -fno-alias -mp1 -fp-model precise" - setenv myFRFLAGS "-free -O3 -fno-alias -mp1 -fp-model precise" - setenv myCFLAGS "-O2" - setenv extra_lib $extra_lib - breaksw - - case pgi: -##> Portland Group fortran compiler............................................. - setenv compiler pgi - setenv compiler_ext pg - setenv myFC mpif90 - setenv myCC mpicc - setenv myLINK_FLAG "" - setenv myFFLAGS "-Mfixed -Mextend -O3" - setenv myFRFLAGS "-Mfree -O3" - setenv myCFLAGS "-O2" - setenv extra_lib $extra_lib - breaksw - - case gcc: -##> gfortran compiler...................................................... - setenv compiler gcc - setenv compiler_ext gfort - setenv myFC mpif90 #gfortran - setenv myCC mpicc - setenv myLINK_FLAG "" - setenv myFFLAGS "-ffixed-form -ffixed-line-length-132 -g -O2 -fbacktrace -fallow-argument-mismatch -funroll-loops -finit-character=32" - setenv myFRFLAGS "-ffree-form -ffree-line-length-none -g -O2 -fbacktrace -fallow-argument-mismatch -funroll-loops -finit-character=32" - setenv myCFLAGS "-g -O2" - setenv extra_lib $extra_lib - breaksw - - default: - echo "*** Compiler $COMPILER not found" - exit(2) - breaksw - - endsw - + +##> binaries and flags for gfortran compiler +setenv compiler gcc +setenv compiler_ext gfort +setenv myFC mpif90 #gfortran +setenv myCC mpicc +setenv myLINK_FLAG "" +setenv myFFLAGS "-ffixed-form -ffixed-line-length-132 -g -O2 -fbacktrace -fallow-argument-mismatch -funroll-loops -finit-character=32" +setenv myFRFLAGS "-ffree-form -ffree-line-length-none -g -O2 -fbacktrace -fallow-argument-mismatch -funroll-loops -finit-character=32" +setenv myCFLAGS "-g -O2" + #=============================================================================== #> generate library locations @@ -119,5 +76,3 @@ setenv STENEX_MOD "${M3LIB}/stenex/se_gcc8.3.0" if ( $?BIN_DIR ) then if ( ! -d $BIN_DIR ) mkdir -p "$BIN_DIR" endif - -# unset echo diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000..86dfc9d --- /dev/null +++ b/uv.lock @@ -0,0 +1,8 @@ +version = 1 +revision = 3 +requires-python = ">=3.12" + +[[package]] +name = "cmaq" +version = "1.0.0" +source = { virtual = "." }