diff --git a/.github/workflows/ci-locks.yml b/.github/workflows/ci-locks.yml index 6b8b0686..4ef35032 100644 --- a/.github/workflows/ci-locks.yml +++ b/.github/workflows/ci-locks.yml @@ -94,7 +94,7 @@ jobs: uses: actions/upload-artifact@v4 with: name: lock-artifact-${{ matrix.lock }} - path: ${{ github.workspace }}/requirements/locks/${{ matrix.lock }}*.txt + path: ${{ github.workspace }}/requirements/locks/${{ matrix.lock }}*.lock create-pr: @@ -124,7 +124,7 @@ jobs: uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e with: token: ${{ steps.generate-token.outputs.token }} - add-paths: ${{ github.workspace }}/requirements/locks/*.txt + add-paths: ${{ github.workspace }}/requirements/locks/*.lock commit-message: "updated conda lock files" branch: conda-lock-auto-update delete-branch: true diff --git a/.github/workflows/ci-manifest.yml b/.github/workflows/ci-manifest.yml new file mode 100644 index 00000000..c0018a47 --- /dev/null +++ b/.github/workflows/ci-manifest.yml @@ -0,0 +1,26 @@ +# Reference +# - https://github.com/actions/checkout + +name: ci-manifest + +on: + pull_request: + branches: + - "*" + + push: + branches-ignore: + - "auto-update-lockfiles" + - "pre-commit-ci-update-config" + - "dependabot/*" + + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + manifest: + name: "check-manifest" + uses: scitools/workflows/.github/workflows/ci-manifest.yml@2025.07.1 diff --git a/MANIFEST.in b/MANIFEST.in index c6e68033..1233312c 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,13 +1,97 @@ -# Top-level files -include CHANGES COPYING COPYING.LESSER INSTALL README.md -prune .github -exclude .gitignore +# A generic template for "MANIFEST.in" files in Scitools repos. +# NOTE: most of this can't be duplicated as-is into any given repo, but suggests +# guidelines + structure. +# For the syntax of "MANIFEST.in" files, see: +# https://setuptools.pypa.io/en/latest/userguide/miscellaneous.html#using-manifest-in + +# General principles +# - enable user to build locally, as well as in CI +# - make it ignore temporary files generated by dev processes, e.g. coverage checks +# - encode typical decisions, e.g. whether we package docs, requirements etc + +#--------- +# SECTION: main code sources +# +recursive-include cf_units *.c *.py *.pyx *.pxd *.so *.template +recursive-include cf_units/_udunits2_parser * + # principles: + # - *no* "prune" command is used + # - use "include-recursive", by relevant file extensions + # hints: + # - top-level dir is typically "src", but maybe "lib" or + # - default package rules mean we generally don't actually *need* a statement + # - but it's better to be explicit + # - extension filetypes are typically sources (*.py) + # - might also need testdata files, e.g. *.nc, *.npy *.npz + # - also possibly non-python, e.g. *.pyx for Cython + -# Files required for conda package management -recursive-include requirements * +#--------- +# SECTION: requirements +prune requirements +recursive-include requirements *.txt + # principles: + # include just requirements-level info, not lock files + # hints: + # - not all projects include requirements, but they can be drawn in anyway by dynamic dependencies + # in the setuptools build process, linked via config in pyproject.toml -# Files required to build docs -recursive-include docs * -prune docs/build -exclude cf_units/etc/site.cfg +#--------- +# SECTION: root files +exclude .flake8 +exclude .git-blame-ignore-revs +exclude .git_archival.txt +exclude .gitattributes +exclude .gitignore +exclude .lycheeignore +exclude .mailmap +exclude .pre-commit-config.yaml +exclude .readthedocs.yml +exclude .ruff.toml +exclude CHANGES +include CHANGELOG.md +include CITATION.cff +exclude CODE_OF_CONDUCT.md +exclude CONTRIBUTING.md +include COPYING +include COPYING.LESSER +include INSTALL +include LICENSE +exclude Makefile +exclude codecov.yml +include noxfile.py +include tox.ini +exclude pixi.lock + # principles: + # - *ANY* file in the root should be explicitly "include"- or "exclude"-d + # - EXCEPT (possibly) those covered by setuptools default rules (see above link) + # - including : README.md/.rst; pyproject.toml; setup.py/.cfg + # - N.B. a GHA "ci-manifest" check, if used, will check all this + # - the above are typical ones : given in sorted order + # - NB many will (eventually) be templated, but that is a separate issue + # - probably, this section can be included as *boilerplate* + # - i.e. it doesn't matter if some of the files mentioned don't exist + + +#--------- +# SECTION: generic exclusions +# (1) top-level directories to omit entirely +prune .github +prune .nox +prune .tox +prune .coverage +prune docs +# (2) top-level files to omit +exclude .coveragerc +# (3) file types (path patterns) to skip everywhere +global-exclude *.py[cod] +global-exclude __pycache__ + # principles: + # - common directories, files and file-types to be generally ignored + # - all outside version control, temporary non-coding output and cache data + # produced by dev processes, automation or user tools + # - by having this section LAST, it can remove files which might have been added by + # previous sections -- such as python compiler cache files + # - can include this section as **boilerplate** : + # - won't all exist in every repo, but including them all does no harm diff --git a/pyproject.toml b/pyproject.toml index 409ce4bf..7ff78bf3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -68,6 +68,13 @@ Discussions = "https://github.com/SciTools/cf-units/discussions" Documentation = "https://cf-units.readthedocs.io" Issues = "https://github.com/SciTools/cf-units/issues" +[tool.check-manifest] +ignore = [ + "cf_units/_udunits2.c", + "cf_units/_udunits2.cpython-*.so", + "cf_units/_version.py", +] + [tool.codespell] skip = 'cf_units/_udunits2_parser/parser/*,cf_units/_udunits2_parser/_antlr4_runtime/*' diff --git a/requirements/locks/py310-lock-linux-64.txt b/requirements/locks/py310-lock-linux-64.lock similarity index 100% rename from requirements/locks/py310-lock-linux-64.txt rename to requirements/locks/py310-lock-linux-64.lock diff --git a/requirements/locks/py310-lock-osx-64.txt b/requirements/locks/py310-lock-osx-64.lock similarity index 100% rename from requirements/locks/py310-lock-osx-64.txt rename to requirements/locks/py310-lock-osx-64.lock diff --git a/requirements/locks/py310-lock-win-64.txt b/requirements/locks/py310-lock-win-64.lock similarity index 100% rename from requirements/locks/py310-lock-win-64.txt rename to requirements/locks/py310-lock-win-64.lock diff --git a/requirements/locks/py311-lock-linux-64.txt b/requirements/locks/py311-lock-linux-64.lock similarity index 100% rename from requirements/locks/py311-lock-linux-64.txt rename to requirements/locks/py311-lock-linux-64.lock diff --git a/requirements/locks/py311-lock-osx-64.txt b/requirements/locks/py311-lock-osx-64.lock similarity index 100% rename from requirements/locks/py311-lock-osx-64.txt rename to requirements/locks/py311-lock-osx-64.lock diff --git a/requirements/locks/py311-lock-win-64.txt b/requirements/locks/py311-lock-win-64.lock similarity index 100% rename from requirements/locks/py311-lock-win-64.txt rename to requirements/locks/py311-lock-win-64.lock diff --git a/requirements/locks/py312-lock-linux-64.txt b/requirements/locks/py312-lock-linux-64.lock similarity index 100% rename from requirements/locks/py312-lock-linux-64.txt rename to requirements/locks/py312-lock-linux-64.lock diff --git a/requirements/locks/py312-lock-osx-64.txt b/requirements/locks/py312-lock-osx-64.lock similarity index 100% rename from requirements/locks/py312-lock-osx-64.txt rename to requirements/locks/py312-lock-osx-64.lock diff --git a/requirements/locks/py312-lock-win-64.txt b/requirements/locks/py312-lock-win-64.lock similarity index 100% rename from requirements/locks/py312-lock-win-64.txt rename to requirements/locks/py312-lock-win-64.lock diff --git a/requirements/locks/py313-lock-linux-64.txt b/requirements/locks/py313-lock-linux-64.lock similarity index 100% rename from requirements/locks/py313-lock-linux-64.txt rename to requirements/locks/py313-lock-linux-64.lock diff --git a/requirements/locks/py313-lock-osx-64.txt b/requirements/locks/py313-lock-osx-64.lock similarity index 100% rename from requirements/locks/py313-lock-osx-64.txt rename to requirements/locks/py313-lock-osx-64.lock diff --git a/requirements/locks/py313-lock-win-64.txt b/requirements/locks/py313-lock-win-64.lock similarity index 100% rename from requirements/locks/py313-lock-win-64.txt rename to requirements/locks/py313-lock-win-64.lock diff --git a/tox.ini b/tox.ini index 12e39dae..29bcd19d 100644 --- a/tox.ini +++ b/tox.ini @@ -29,23 +29,23 @@ skip_install = commands = cp {env:YMLFILE} {env:TMPFILE} python -c 'from sys import version_info as v; fh = open("{env:TMPFILE}", "a"); fh.write(f"\n - python =\{v.major\}.\{v.minor\}\n")' - conda-lock --channel conda-forge --kind explicit --file {env:TMPFILE} --platform linux-64 --filename-template "{envname}-\{platform\}.txt" {posargs} + conda-lock --channel conda-forge --kind explicit --file {env:TMPFILE} --platform linux-64 --filename-template "{envname}-\{platform\}.lock" {posargs} [testenv:py{310,311,312,313}-{linux,osx,win}-test] conda_spec = - py310-linux: {toxinidir}{/}requirements{/}locks{/}py310-lock-linux-64.txt - py311-linux: {toxinidir}{/}requirements{/}locks{/}py311-lock-linux-64.txt - py312-linux: {toxinidir}{/}requirements{/}locks{/}py312-lock-linux-64.txt - py313-linux: {toxinidir}{/}requirements{/}locks{/}py313-lock-linux-64.txt - py310-osx: {toxinidir}{/}requirements{/}locks{/}py310-lock-osx-64.txt - py311-osx: {toxinidir}{/}requirements{/}locks{/}py311-lock-osx-64.txt - py312-osx: {toxinidir}{/}requirements{/}locks{/}py312-lock-osx-64.txt - py313-osx: {toxinidir}{/}requirements{/}locks{/}py313-lock-osx-64.txt - py310-win: {toxinidir}{/}requirements{/}locks{/}py310-lock-win-64.txt - py311-win: {toxinidir}{/}requirements{/}locks{/}py311-lock-win-64.txt - py312-win: {toxinidir}{/}requirements{/}locks{/}py312-lock-win-64.txt - py313-win: {toxinidir}{/}requirements{/}locks{/}py313-lock-win-64.txt + py310-linux: {toxinidir}{/}requirements{/}locks{/}py310-lock-linux-64.lock + py311-linux: {toxinidir}{/}requirements{/}locks{/}py311-lock-linux-64.lock + py312-linux: {toxinidir}{/}requirements{/}locks{/}py312-lock-linux-64.lock + py313-linux: {toxinidir}{/}requirements{/}locks{/}py313-lock-linux-64.lock + py310-osx: {toxinidir}{/}requirements{/}locks{/}py310-lock-osx-64.lock + py311-osx: {toxinidir}{/}requirements{/}locks{/}py311-lock-osx-64.lock + py312-osx: {toxinidir}{/}requirements{/}locks{/}py312-lock-osx-64.lock + py313-osx: {toxinidir}{/}requirements{/}locks{/}py313-lock-osx-64.lock + py310-win: {toxinidir}{/}requirements{/}locks{/}py310-lock-win-64.lock + py311-win: {toxinidir}{/}requirements{/}locks{/}py311-lock-win-64.lock + py312-win: {toxinidir}{/}requirements{/}locks{/}py312-lock-win-64.lock + py313-win: {toxinidir}{/}requirements{/}locks{/}py313-lock-win-64.lock description = Perform cf-units unit/integration tests. passenv =