diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 03efb299..1f88214b 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,5 +1,7 @@ # PR Summary + + Code Reviewer: @@ -25,17 +27,14 @@ Code Reviewer: - [ ] I have performed a self-review of my own code - [ ] My code follows the project's style guidelines -- [ ] Comments have been included that aid undertanding and enhance the - readability of the code +- [ ] Comments have been included that aid understanding and enhance the readability of the code - [ ] My changes generate no new warnings ## Testing - [ ] I have tested this change locally, using the rose-stem suite -- [ ] If any tests fail (rose-stem or CI) the reason is understood and - acceptable (eg. kgo changes) -- [ ] I have added tests to cover new functionality as appropriate (eg. system - tests, unit tests, etc.) +- [ ] If any tests fail (rose-stem or CI) the reason is understood and acceptable (eg. kgo changes) +- [ ] I have added tests to cover new functionality as appropriate (eg. system tests, unit tests, etc.) @@ -52,23 +51,17 @@ Code Reviewer: ## Performance Impact -- [ ] Performance of the code has been considered and, if applicable, suitable - performance measurements have been conducted +- [ ] Performance of the code has been considered and, if applicable, suitable performance measurements have been conducted ## 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](https://metoffice.github.io/simulation-systems/FurtherDetails/ai.html) - (including attribution labels) +- [ ] 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](https://metoffice.github.io/simulation-systems/FurtherDetails/ai.html) (including attribution labels) ## Documentation -- [ ] Where appropriate I have updated documentation related to this change and - confirmed that it builds correctly +- [ ] Where appropriate I have updated documentation related to this change and confirmed that it builds correctly # Code Review diff --git a/.github/workflows/check-cr-approved.yaml b/.github/workflows/check-cr-approved.yaml index 9b66712a..e4c9a213 100644 --- a/.github/workflows/check-cr-approved.yaml +++ b/.github/workflows/check-cr-approved.yaml @@ -1,11 +1,20 @@ +# ----------------------------------------------------------------------------- +# (C) Crown copyright Met Office. All rights reserved. +# The file LICENCE, distributed with this code, contains details of the terms +# under which the code may be used. +# ----------------------------------------------------------------------------- + name: Check CR approved on: - pull_request_review: - types: [submitted, edited, dismissed] - workflow_dispatch: + 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 + check_cr_approved: + permissions: + contents: read # Required to evaluate the event trigger metadata safely + pull-requests: read + if: ${{ github.event.pull_request.number }} + uses: MetOffice/growss/.github/workflows/check-cr-approved.yaml@0f9ffe6a138ae9943053621916a850a075997db8 # v1.0.0 diff --git a/.github/workflows/checks.yaml b/.github/workflows/checks.yaml index 1661b58e..ae165d5e 100644 --- a/.github/workflows/checks.yaml +++ b/.github/workflows/checks.yaml @@ -1,7 +1,7 @@ --- name: Quality -on: # yamllint disable-line rule:truthy +on: push: branches: - main @@ -14,39 +14,47 @@ concurrency: group: ${{ github.ref }} cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} -permissions: read-all +permissions: + contents: read # Required to evaluate the event trigger metadata safely jobs: - mule-checks: runs-on: ubuntu-latest timeout-minutes: 5 steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false + - name: Setup uv - uses: astral-sh/setup-uv@v6 + uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 + with: + enable-cache: false + - name: Install dependencies - run: uv sync + run: uv sync --extra lint + - name: Python Lint run: uv run ruff check . + - name: Python Format Check if: always() run: uv run ruff format --check --diff -s --respect-gitignore . + - name: Shell Check if: always() run: | find . -type f \( -name "*.*sh" -o ! -name "*.*" \) \ - -not -path "*.git/*" -not -path "*.venv/*" -print0 \ - | xargs -0 file | grep "shell script" | cut -d: -f1 \ - | xargs -r uv run shellcheck -S warning \ + -not -path "*/.git/*" -not -path "*/.venv/*" \ + -exec sh -c 'file "$1" | grep -q "shell script"' _ {} \; \ + -exec uv run shellcheck -S warning {} + \ && echo "All checks passed!" + - name: CPPLINT # See: CPPLINT.cfg if: always() run: | uv run cpplint --recursive --extensions=c,h \ --exclude=.git --exclude=.venv . - - name: Minimize uv cache - run: uv cache prune --ci diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index edd67aca..e3f50589 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1,6 +1,6 @@ --- name: CI -on: # yamllint disable-line rule:truthy +on: push: branches: - main @@ -9,7 +9,8 @@ on: # yamllint disable-line rule:truthy types: [opened, synchronize, reopened] workflow_dispatch: -permissions: read-all +permissions: + contents: read # Required to evaluate the event trigger metadata safely jobs: build-test-mule: @@ -28,38 +29,49 @@ jobs: steps: - name: Checkout Mule - uses: actions/checkout@v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: path: mule + persist-credentials: false + - name: Checkout Shumlib - uses: actions/checkout@v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: repository: "MetOffice/shumlib" path: shumlib - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 + persist-credentials: false + + - name: Set up uv and Python ${{ matrix.python-version }} + uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 with: python-version: ${{ matrix.python-version }} - cache: pip + enable-cache: false + - name: Install Python Dependencies ${{ matrix.numpy-version }} + working-directory: ./mule + env: + UV_OVERRIDE_PKG: numpy==${{ matrix.numpy-version }} run: | - pip install setuptools - pip install six - pip install numpy==${{ matrix.numpy-version }} + uv sync --upgrade-package "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 --spiral_lib --packing_lib \ - --shumlib_path $GITHUB_WORKSPACE/shumlib/build/vm-x86-gfortran-gcc \ - ./_build/lib ./_build/bin + uv run --project . ./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: | for name in ./*; do - python -m unittest discover -v ${name##*/}.tests + # uv run python -m unittest discover -v ${name##*/}.tests + uv run --project ../.. python -m unittest discover -v -s "${name}/tests" -t . done diff --git a/.github/workflows/cla-check.yaml b/.github/workflows/cla-check.yaml index 3d28d731..d4a3792e 100644 --- a/.github/workflows/cla-check.yaml +++ b/.github/workflows/cla-check.yaml @@ -1,10 +1,27 @@ +# ----------------------------------------------------------------------------- +# (C) Crown copyright Met Office. All rights reserved. +# The file LICENCE, distributed with this code, contains details of the terms +# under which the code may be used. +# ----------------------------------------------------------------------------- + +# Check Contributor Licence Agreement + name: Legal on: pull_request_target: +concurrency: + # Automatically cancels the workflow run instantly before the + # engine can parse empty jobs and generate notification emails + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} + cancel-in-progress: ${{ github.event.pull_request.head.repo.full_name != 'MetOffice/mule' }} + +permissions: {} + jobs: cla: - uses: MetOffice/growss/.github/workflows/cla-check.yaml@main - with: - runner: 'ubuntu-24.04' + permissions: + contents: read # Required to evaluate the event trigger metadata safely + pull-requests: write # Required for the downstream engine to post status comments on the PR + uses: MetOffice/growss/.github/workflows/cla-check.yaml@0f9ffe6a138ae9943053621916a850a075997db8 # v1.0.0 diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 4871b94a..6c914cfe 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -1,7 +1,7 @@ --- name: Docs -on: # yamllint disable-line rule:truthy +on: push: branches: - main @@ -30,17 +30,19 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false # Avoids exposing secrets to forks - name: Setup uv - uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 + uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 with: enable-cache: false # Disable caching to minimize storage usage - name: Install dependencies - run: uv sync && uv pip install ./mule ./um_utils + run: | + uv sync --extra docs + uv pip install ./mule ./um_utils - name: Build mule docs run: uv run make clean html --directory "${GITHUB_WORKSPACE}/mule/docs" @@ -100,10 +102,6 @@ jobs: name: github-pages path: ./_docs - - name: Minimize uv cache - if: always() - run: uv cache prune --ci - # Deploy to GitHub Pages only on main branch pushes to avoid deploying from forks or PRs deploy: name: Publish to GitHub Pages diff --git a/.github/workflows/track-review-project.yaml b/.github/workflows/track-review-project.yaml index 639477cd..1ab60122 100644 --- a/.github/workflows/track-review-project.yaml +++ b/.github/workflows/track-review-project.yaml @@ -1,3 +1,9 @@ +# ----------------------------------------------------------------------------- +# (C) Crown copyright Met Office. All rights reserved. +# The file LICENCE, distributed with this code, contains details of the terms +# under which the code may be used. +# ----------------------------------------------------------------------------- + name: Track Review Project on: @@ -7,11 +13,14 @@ on: - completed permissions: - actions: read - contents: read - pull-requests: write + contents: read # Required to evaluate the event trigger metadata safely jobs: track_review_project: - uses: MetOffice/growss/.github/workflows/track-review-project.yaml@main - secrets: inherit + permissions: + actions: read # Required to check out code or parse files safely + contents: read # Required to read the upstream triggered workflow run artifact status + pull-requests: write # Required for the downstream engine to add comments or update metadata on the PR + uses: MetOffice/growss/.github/workflows/track-review-project.yaml@0f9ffe6a138ae9943053621916a850a075997db8 # v1.0.0 + secrets: + PROJECT_ACTION_PAT: ${{ secrets.PROJECT_ACTION_PAT }} diff --git a/.github/workflows/trigger-project-workflow.yaml b/.github/workflows/trigger-project-workflow.yaml index ccb7a55b..50c283d1 100644 --- a/.github/workflows/trigger-project-workflow.yaml +++ b/.github/workflows/trigger-project-workflow.yaml @@ -1,3 +1,9 @@ +# ----------------------------------------------------------------------------- +# (C) Crown copyright Met Office. All rights reserved. +# The file LICENCE, distributed with this code, contains details of the terms +# under which the code may be used. +# ----------------------------------------------------------------------------- + name: Trigger Review Project on: @@ -7,11 +13,14 @@ on: pull_request_review_comment: permissions: - actions: read - contents: read - pull-requests: write + contents: read # Required to evaluate the event trigger metadata safely jobs: trigger_project_workflow: - uses: MetOffice/growss/.github/workflows/trigger-project-workflow.yaml@main - secrets: inherit + if: github.repository == 'MetOffice/mule' + + permissions: + actions: read # Required to check out code or parse files safely + contents: read # Required to read the upstream triggered workflow run artifact status + pull-requests: write # Required for the downstream engine to add comments or update metadata on the PR + uses: MetOffice/growss/.github/workflows/trigger-project-workflow.yaml@0f9ffe6a138ae9943053621916a850a075997db8 # v1.0.0 diff --git a/.github/zizmor.yml b/.github/zizmor.yml new file mode 100644 index 00000000..e66c5e79 --- /dev/null +++ b/.github/zizmor.yml @@ -0,0 +1,15 @@ +# ------------------------------------------------------------------------------ +# (c) Crown copyright Met Office. All rights reserved. +# The file LICENCE, distributed with this code, contains details of the terms +# under which the code may be used. +# ------------------------------------------------------------------------------ + +# Rules for Zizmor GitHub workflow linter. This file is used to configure which +# rules to ignore for specific workflow files, allowing for exceptions to be +# made where necessary while still enforcing best practices across the codebase. +rules: + dangerous-triggers: + ignore: + - "cla-check.yaml" + - "track-review-project.yaml" + - "trigger-project-workflow.yaml" diff --git a/.python-version b/.python-version deleted file mode 100644 index f3fe474a..00000000 --- a/.python-version +++ /dev/null @@ -1 +0,0 @@ -3.12.9 diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index e4db7a23..90a71b83 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -1,7 +1,7 @@ # 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 | -| yaswant | Yaswant Pradhan | Met Office | 2026-05-22 | +| GitHub user | Real Name | Affiliation | Date | +| --------------- | --------------- | ----------- | ---------- | +| james-bruten-mo | James Bruten | Met Office | 2025-12-09 | +| jennyhickson | Jenny Hickson | Met Office | 2026-03-02 | +| yaswant | Yaswant Pradhan | Met Office | 2026-05-22 | diff --git a/pyproject.toml b/pyproject.toml index f9110d0f..908f7e29 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,20 +3,53 @@ name = "mule" version = "2025.10.1" description = "API for interacting with UM output files" readme = "README.md" +license = { file = "LICENCE" } requires-python = ">=3.11" +# dependencies = [ +# "cpplint >= 2.0.2", +# "ruff >= 0.12.1", +# "shellcheck-py >= 0.10.0.1", +# "sphinx >= 8.2.3", +# "sphinx-lint >= 1.0.0", +# "pydata-sphinx-theme >= 0.16.1", +# "sphinx-design >= 0.6.1", +# "sphinx-copybutton >= 0.5.2", +# "sphinx-lint >= 1.0.0", +# "sphinx-sitemap >= 2.8.0", +# "sphinxcontrib-svg2pdfconverter >= 1.3.0", +# "setuptools >= 80.0.0", +# "numpy >= 1.26.4", +# "six >= 1.17.0", +# "pillow >= 11.3.0", +# ] dependencies = [ - "cpplint == 2.0.2", - "ruff == 0.12.1", - "shellcheck-py == 0.10.0.1", - "sphinx == 8.2.3", - "sphinx-lint == 1.0.0", - "pydata-sphinx-theme == 0.16.1", - "sphinx-design == 0.6.1", - "sphinx-copybutton == 0.5.2", - "sphinx-lint == 1.0.0", - "sphinx-sitemap == 2.8.0", - "sphinxcontrib-svg2pdfconverter == 1.3.0", - "numpy == 2.3.3", - "six == 1.17.0", - "pillow == 11.3.0", + "setuptools >= 80.0.0", + "numpy >= 1.26.4", + "six >= 1.17.0", + "pillow >= 11.3.0", ] + +[project.optional-dependencies] +docs = [ + "sphinx >= 8.2.3", + "sphinx-lint >= 1.0.0", + "pydata-sphinx-theme >= 0.16.1", + "sphinx-design >= 0.6.1", + "sphinx-copybutton >= 0.5.2", + "sphinx-lint >= 1.0.0", + "sphinx-sitemap >= 2.8.0", + "sphinxcontrib-svg2pdfconverter >= 1.3.0", +] +lint = [ + "cpplint >= 2.0.2", + "ruff >= 0.12.1", + "shellcheck-py >= 0.10.0.1", +] + +[project.urls] +repository = "https://github.com/MetOffice/mule" +documentation = "https://metoffice.github.io/mule/" +discussion = "https://github.com/MetOffice/simulation-systems/discussions/categories/mule" + +[tool.setuptools] +packages = []