diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index c431f6a..03efb29 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -55,18 +55,15 @@ Code Reviewer: - [ ] Performance of the code has been considered and, if applicable, suitable performance measurements have been conducted -## Contributor License Agreement (CLA) - -- [ ] **Required** - I confirm that I have read and agree to the project's - [Contributor License Agreement](todo-enter-link-to-cla) - ## AI Assistance and Attribution - [ ] Some of the content of this change has been produced with the assistance of _Generative AI tool name_ (e.g., Met Office Github Copilot Enterprise, Github Copilot Personal, ChatGPT GPT-4, etc) and I have followed the - [Simulation Systems AI policy](todo-enter-link-to-policy-page) (including - attribution labels) + [Simulation Systems AI policy](https://metoffice.github.io/simulation-systems/FurtherDetails/ai.html) + (including attribution labels) + + ## Documentation @@ -78,10 +75,10 @@ Code Reviewer: - [ ] All dependencies have been resolved -- [ ] Related Issues are properly linked and addressed -- [ ] CLA compliance is confirmed -- [ ] Code quality standards are met -- [ ] Tests are adequate and passing +- [ ] Related Issues have been properly linked and addressed +- [ ] CLA compliance has been confirmed +- [ ] Code quality standards have been met +- [ ] Tests are adequate and have passed - [ ] Documentation is complete and accurate - [ ] Security considerations have been addressed - [ ] Performance impact is acceptable diff --git a/.github/workflows/check-cr-approved.yaml b/.github/workflows/check-cr-approved.yaml new file mode 100644 index 0000000..9b66712 --- /dev/null +++ b/.github/workflows/check-cr-approved.yaml @@ -0,0 +1,11 @@ +name: Check CR approved + +on: + pull_request_review: + types: [submitted, edited, dismissed] + workflow_dispatch: + +jobs: + check_cr_approved: + if: ${{ github.event.pull_request.number }} + uses: MetOffice/growss/.github/workflows/check-cr-approved.yaml@main diff --git a/.github/workflows/checks.yaml b/.github/workflows/checks.yaml index 889e038..1661b58 100644 --- a/.github/workflows/checks.yaml +++ b/.github/workflows/checks.yaml @@ -2,6 +2,10 @@ name: Quality on: # yamllint disable-line rule:truthy + push: + branches: + - main + - 'releases/**' pull_request: types: [opened, synchronize, reopened] workflow_dispatch: diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 91fdf7c..edd67ac 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -18,15 +18,24 @@ jobs: strategy: max-parallel: 4 matrix: - python-version: ['3.12', '3.13'] - numpy-version: ['1.26.4', '2.2.6'] + python-version: ['3.12', '3.13', '3.14'] + numpy-version: ['1.26.4', '2.3.4'] exclude: - python-version: '3.13' numpy-version: '1.26.4' + - python-version: '3.14' + numpy-version: '1.26.4' steps: - name: Checkout Mule - uses: actions/checkout@v4 + uses: actions/checkout@v6 + with: + path: mule + - name: Checkout Shumlib + uses: actions/checkout@v6 + with: + repository: "MetOffice/shumlib" + path: shumlib - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: @@ -37,12 +46,20 @@ jobs: pip install setuptools pip install six pip install numpy==${{ matrix.numpy-version }} - - name: Build python-${{ matrix.python-version }}_numpy-${{ matrix.numpy-version }} + - name: Install shumlib + working-directory: ./shumlib + run: | + echo "Compiling shumlib using $(gfortran --version)" + make -f ./make/vm-x86-gfortran-gcc.mk check + - name: Install Mule with python-${{ matrix.python-version }}_numpy-${{ matrix.numpy-version }} + working-directory: ./mule run: | - ./admin/install_mule.sh ./_build/lib ./_build/bin - - name: Test python-${{ matrix.python-version }}_numpy-${{ matrix.numpy-version }} + ./admin/install_mule.sh --spiral_lib --packing_lib \ + --shumlib_path $GITHUB_WORKSPACE/shumlib/build/vm-x86-gfortran-gcc \ + ./_build/lib ./_build/bin + - name: Test Mule with python-${{ matrix.python-version }}_numpy-${{ matrix.numpy-version }} + working-directory: ./mule/_build/lib run: | - cd _build/lib for name in ./*; do python -m unittest discover -v ${name##*/}.tests done diff --git a/.github/workflows/cla-check.yaml b/.github/workflows/cla-check.yaml new file mode 100644 index 0000000..3d28d73 --- /dev/null +++ b/.github/workflows/cla-check.yaml @@ -0,0 +1,10 @@ +name: Legal + +on: + pull_request_target: + +jobs: + cla: + uses: MetOffice/growss/.github/workflows/cla-check.yaml@main + with: + runner: 'ubuntu-24.04' diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 809eb27..602fca8 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -24,25 +24,41 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 + - name: Setup uv uses: astral-sh/setup-uv@v6 + - name: Install dependencies run: uv sync && uv pip install ./mule ./um_utils + - name: Build mule docs run: uv run make clean html --directory ./mule/docs working-directory: ${{ github.workspace }} + - name: Build um_utils docs run: uv run make clean html --directory ./um_utils/docs working-directory: ${{ github.workspace }} - # - id: permissions - # name: Set permissions - # run: | - # chmod -c -R +rX "./doc/_build/html/" + + # Deploy Steps + - name: Copy Built Documentation + if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request' + run: | + mkdir _docs + cp -r ./mule/docs/build/html _docs/mule + cp -r ./um_utils/docs/build/html _docs/um_utils + + echo '
' > _docs/index.html + - name: Upload artifacts + if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request' uses: actions/upload-pages-artifact@v4 with: name: github-pages - path: ./mule/docs/build/html + path: ./_docs + - name: Minimize uv cache if: always() run: uv cache prune --ci @@ -50,17 +66,21 @@ jobs: # Deploy job deploy: if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request' + # Add a dependency to the build job needs: build-docs permissions: pages: write # to deploy to Pages id-token: write # to verify the deployment originates from an appropriate source + # Deploy to the github-pages environment environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} + # Specify runner + deployment step runs-on: ubuntu-latest + steps: - name: Deploy to GitHub Pages id: deployment diff --git a/.github/workflows/track-review-project.yaml b/.github/workflows/track-review-project.yaml new file mode 100644 index 0000000..639477c --- /dev/null +++ b/.github/workflows/track-review-project.yaml @@ -0,0 +1,17 @@ +name: Track Review Project + +on: + workflow_run: + workflows: [Trigger Review Project] + types: + - completed + +permissions: + actions: read + contents: read + pull-requests: write + +jobs: + track_review_project: + uses: MetOffice/growss/.github/workflows/track-review-project.yaml@main + secrets: inherit diff --git a/.github/workflows/trigger-project-workflow.yaml b/.github/workflows/trigger-project-workflow.yaml new file mode 100644 index 0000000..ccb7a55 --- /dev/null +++ b/.github/workflows/trigger-project-workflow.yaml @@ -0,0 +1,17 @@ +name: Trigger Review Project + +on: + pull_request_target: + types: ["opened", "synchronize", "reopened", "edited", "review_requested", "review_request_removed", "closed"] + pull_request_review: + pull_request_review_comment: + +permissions: + actions: read + contents: read + pull-requests: write + +jobs: + trigger_project_workflow: + uses: MetOffice/growss/.github/workflows/trigger-project-workflow.yaml@main + secrets: inherit diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 4823ba9..0000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,13 +0,0 @@ -# Contributing Guidelines - -Please follow the -[simulation-systems working practices](https://metoffice.github.io/simulation-systems/index.html) - -By contributing you agree to the -[simulation-systems Contributor Licence Agreement](https://metoffice.github.io/simulation-systems/FurtherDetails/contributing.html) - -Please be aware of and follow the -[simulation-systems Code of Conduct](https://metoffice.github.io/simulation-systems/FurtherDetails/code_of_conduct.html) - -Please be aware of and follow the -[simulation-systems AI Policy](https://metoffice.github.io/simulation-systems/FurtherDetails/ai.html) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md new file mode 100644 index 0000000..dfe0f41 --- /dev/null +++ b/CONTRIBUTORS.md @@ -0,0 +1,6 @@ +# Contributors + +| GitHub user | Real Name | Affiliation | Date | +| ----------- | --------- | ----------- | ---- | +| james-bruten-mo | James Bruten | Met Office | 2025-12-09 | +| jennyhickson | Jenny Hickson | Met Office | 2026-03-02 | diff --git a/LICENCE b/LICENCE index f3865e0..5f36cd7 100644 --- a/LICENCE +++ b/LICENCE @@ -2,8 +2,8 @@ BSD 3-Clause Licence Crown Copyright (c) Met Office -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. @@ -12,17 +12,17 @@ are permitted provided that the following conditions are met: this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without - specific prior written permission. +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md index 73dd921..c9d2903 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,43 @@ # Mule +[](https://github.com/MetOffice/mule/actions/workflows/ci.yaml) +[](https://github.com/MetOffice/mule/actions/workflows/docs.yaml) +[](https://github.com/MetOffice/mule/actions/workflows/checks.yaml) + Mule is an API written in Python which allows you to access and manipulate files produced by the UM (Unified Model, of the Met Office (UK)). -Please follow the -[simulation-systems working practices](https://metoffice.github.io/simulation-systems/index.html) +## Contributing Guidelines + +Welcome! + +The following links are here to help set clear expectations for everyone +contributing to this project. By working together under a shared understanding, +we can continuously improve the project while creating a friendly, inclusive +space for all contributors. + +### Contributors Licence Agreement + +Please see the +[Momentum Contributors Licence Agreement](https://github.com/MetOffice/Momentum/blob/main/CLA.md) + +Agreement of the CLA can be shown by adding yourself to the CONTRIBUTORS file +alongside this one, and is a requirement for contributing to this project. + +### Code of Conduct + +Please be aware of and follow the +[Momentum Code of Coduct](https://github.com/MetOffice/Momentum/blob/main/docs/CODE_OF_CONDUCT.md) + +### Working Practices + +This project is managed as part of the Simulation Systems group of repositories. + +Please follow the Simulation Systems +[Working Practices.](https://metoffice.github.io/simulation-systems/index.html) + +Questions are encouraged in the Simulation Systems +[Discussions.](https://github.com/MetOffice/simulation-systems/discussions) + +Please be aware of and follow the Simulation Systems +[AI Policy.](https://metoffice.github.io/simulation-systems/FurtherDetails/ai.html) diff --git a/admin/meto_install_mule.sh b/admin/meto_install_mule.sh index c6dbddd..9c621c7 100755 --- a/admin/meto_install_mule.sh +++ b/admin/meto_install_mule.sh @@ -39,7 +39,7 @@ shum_ver=2025.10.1 # Set library locations and which specific builds to use on each platform hostname=$(hostname) if [[ $hostname == caz* ]] && [[ $hostname != cazccylc* ]] ; then # AZSPICE - shum=$UMDIR/shumlib/shumlib-2024.03.1/azspice-gfortran-12.2.0-gcc-12.2.0 + shum=$UMDIR/shumlib/shumlib-$shum_ver/azspice-gfortran-12.2.0-gcc-12.2.0 sst=$UMDIR/$um_ver/linux/sstpert_gnu wafc=$UMDIR/$um_ver/linux/wafccb_gnu diff --git a/mule/lib/mule/packing.py b/mule/lib/mule/packing.py index b28d239..98a82ef 100644 --- a/mule/lib/mule/packing.py +++ b/mule/lib/mule/packing.py @@ -38,10 +38,10 @@ """ import os -import pkgutil +import importlib # First establish whether the SHUMlib packing library is available -if not pkgutil.get_loader("um_packing") is None: +if importlib.util.find_spec("um_packing") is not None: try: import um_packing # Since the SHUMlib packing employs OpenMP for speed, make sure the @@ -106,7 +106,7 @@ def _wgdos_pack_field(data, mdi, acc): msg = "SHUMlib Packing library found, but failed to import" raise ImportError(err.args + (msg,)) -elif not pkgutil.get_loader("mo_pack") is None: +elif importlib.util.find_spec("mo_pack") is not None: # If the UM library wasn't found, try the MO packing library instead try: import mo_pack