diff --git a/.gitignore b/.gitignore index 274cb4d..1a65936 100644 --- a/.gitignore +++ b/.gitignore @@ -101,6 +101,10 @@ dmypy.json # ruff .ruff_cache +# cruft +.cruft-pr-body +*.rej + # PyCharm .idea/ .idea_modules/ diff --git a/CHANGELOG.md b/CHANGELOG.md index a872dc5..3927c02 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,12 +10,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - add review assignment to mex-template itself +- add code of conduct file to mex-template itself +- add badges for open-code and cookiecutter ### Changes - improve prompt for project name - switch from poetry to pdm -- switch order of black and ruff linter, as ruff often complains about issues, that are automatically fixed by black +- switch order of black and ruff linter, as ruff often complains about issues, + that are automatically fixed by black +- add tests and ruff cache to dockerignore +- use `WORKFLOW_TOKEN` in cookiecutter job for consistency +- switch json linting to 4-spaces and utf-8 +- clean up and expand pdm scripts +- improve and simplify mex.bat and makefile +- update pdm, ruff and pre-commit ### Deprecated diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..66cfe10 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,74 @@ +# Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and +maintainers pledge to make participation in our project and our community a +harassment-free experience for everyone, regardless of age, body size, disability, +ethnicity, sex characteristics, gender identity and expression, level of experience, +education, socio-economic status, nationality, personal appearance, race, religion, +or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +- The use of sexualized language or imagery and unwelcome sexual attention or + advances +- Trolling, insulting/derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or electronic + address, without explicit permission +- Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project team members are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in response to +any instances of unacceptable behavior. + +Project team members have the right and responsibility to remove, edit, or reject +comments, commits, code, and other contributions that are not aligned to this +Code of Conduct, or to ban temporarily or permanently any contributor for other +behaviors that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies within all project spaces, and it also applies when an +individual is representing the project or its community in public spaces. Examples of +representing a project or community include using an official project e-mail address, +appearing as a project maintainer, or acting as an appointed representative at an online +or offline event. Representation of a project may be further defined and clarified by +the project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by +contacting the project team at mex@rki.de. All complaints will be reviewed and +investigated and will result in a response that is deemed necessary and appropriate to +the circumstances. The project team is obligated to maintain confidentiality with regard +to the reporter of an incident. Further details of specific enforcement policies may be +posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may +face temporary or permanent repercussions as determined by project, departmental +or organizational leadership roles. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see +https://www.contributor-covenant.org/faq diff --git a/README.md b/README.md index 83d5a41..3ecec79 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ Cookiecutter template for MEx python projects. +[![open-code](https://github.com/robert-koch-institut/mex-template/actions/workflows/open-code.yml/badge.svg)](https://gitlab.opencode.de/robert-koch-institut/mex/mex-template) + ## project The Metadata Exchange (MEx) project is committed to improve the retrieval of RKI diff --git a/mex-{{ cookiecutter.project_name }}/.dockerignore b/mex-{{ cookiecutter.project_name }}/.dockerignore index 5485f54..284f9da 100644 --- a/mex-{{ cookiecutter.project_name }}/.dockerignore +++ b/mex-{{ cookiecutter.project_name }}/.dockerignore @@ -35,6 +35,7 @@ pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports +tests/ htmlcov/ .tox/ .nox/ @@ -96,6 +97,9 @@ venv.bak/ .dmypy.json dmypy.json +# ruff +.ruff_cache + # PyCharm .idea/ .idea_modules/ diff --git a/mex-{{ cookiecutter.project_name }}/.github/workflows/cookiecutter.yml b/mex-{{ cookiecutter.project_name }}/.github/workflows/cookiecutter.yml index 1311329..d924423 100644 --- a/mex-{{ cookiecutter.project_name }}/.github/workflows/cookiecutter.yml +++ b/mex-{{ cookiecutter.project_name }}/.github/workflows/cookiecutter.yml @@ -63,7 +63,7 @@ jobs: - name: Update template env: - {% raw %}GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}{% endraw %} + {% raw %}GH_TOKEN: ${{ secrets.WORKFLOW_TOKEN }}{% endraw %} run: | {% raw -%} if cruft check; then diff --git a/mex-{{ cookiecutter.project_name }}/.github/workflows/cve-scan.yml b/mex-{{ cookiecutter.project_name }}/.github/workflows/cve-scan.yml index 7b93497..77e3e21 100644 --- a/mex-{{ cookiecutter.project_name }}/.github/workflows/cve-scan.yml +++ b/mex-{{ cookiecutter.project_name }}/.github/workflows/cve-scan.yml @@ -57,7 +57,7 @@ jobs: - name: Export dependencies run: | mkdir --parents pdm - pdm export -G :all -f requirements > pdm/requirements.txt + pdm export-all > pdm/requirements.txt - name: Run trivy uses: aquasecurity/trivy-action@master diff --git a/mex-{{ cookiecutter.project_name }}/.pre-commit-config.yaml b/mex-{{ cookiecutter.project_name }}/.pre-commit-config.yaml index 33727bf..8398fbe 100644 --- a/mex-{{ cookiecutter.project_name }}/.pre-commit-config.yaml +++ b/mex-{{ cookiecutter.project_name }}/.pre-commit-config.yaml @@ -7,7 +7,7 @@ repos: hooks: - id: black - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.3.3 + rev: v0.3.5 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] @@ -16,10 +16,11 @@ repos: hooks: - id: pretty-format-json name: json - args: [--autofix] + args: [--autofix, --indent=4, --no-ensure-ascii] exclude: .cruft.json - id: check-yaml name: yaml + exclude: templates\/[a-z_-]+.yaml - id: end-of-file-fixer name: eof - id: trailing-whitespace @@ -27,7 +28,7 @@ repos: - id: fix-byte-order-marker name: byte-order - repo: https://github.com/pdm-project/pdm - rev: 2.12.4 + rev: 2.13.2 hooks: - id: pdm-lock-check name: pdm @@ -35,7 +36,7 @@ repos: hooks: - id: mypy name: mypy - entry: pdm run dmypy run --timeout 7200 -- mex + entry: pdm mypy-daemon files: ^mex/ language: system pass_filenames: false diff --git a/mex-{{ cookiecutter.project_name }}/Makefile b/mex-{{ cookiecutter.project_name }}/Makefile index 48d875a..e632151 100644 --- a/mex-{{ cookiecutter.project_name }}/Makefile +++ b/mex-{{ cookiecutter.project_name }}/Makefile @@ -1,13 +1,14 @@ -.PHONY: all test setup hooks install linter pytest wheel container run start docs +.PHONY: all test setup hooks install linter pytest wheel image run start docs all: install test test: linter pytest LATEST = $(shell git describe --tags $(shell git rev-list --tags --max-count=1)) +PWD = $(shell pwd) setup: # install meta requirements system-wide @ echo installing requirements; \ - python -m pip --quiet --disable-pip-version-check install --force-reinstall -r requirements.txt; \ + pip --disable-pip-version-check install --force-reinstall -r requirements.txt; \ hooks: # install pre-commit hooks when not in CI @@ -18,24 +19,24 @@ hooks: install: setup hooks # install packages from lock file in local virtual environment @ echo installing package; \ - pdm sync --clean --group dev; \ + pdm install-all; \ linter: # run the linter hooks from pre-commit on all files @ echo linting all files; \ - pre-commit run --all-files; \ + pdm lint; \ pytest: # run the pytest test suite with all unit tests @ echo running unit tests; \ - pdm run pytest -m "not integration"; \ + pdm unit; \ wheel: # build the python package @ echo building wheel; \ - pdm build --no-sdist; \ + pdm wheel; \ -container: +image: # build the docker image @ echo building docker image mex-{{ cookiecutter.project_name }}:${LATEST}; \ export DOCKER_BUILDKIT=1; \ @@ -43,7 +44,7 @@ container: --tag rki/mex-{{ cookiecutter.project_name }}:${LATEST} \ --tag rki/mex-{{ cookiecutter.project_name }}:latest .; \ -run: container +run: image # run the service as a docker container @ echo running docker container mex-{{ cookiecutter.project_name }}:${LATEST}; \ docker run \ @@ -51,15 +52,14 @@ run: container --publish 8081:8081 \ rki/mex-{{ cookiecutter.project_name }}:${LATEST}; \ -start: container - # start the service using docker-compose - @ echo running docker-compose with mex-{{ cookiecutter.project_name }}:${LATEST}; \ +start: image + # start the service using docker compose + @ echo start mex-{{ cookiecutter.project_name }}:${LATEST} with compose; \ export DOCKER_BUILDKIT=1; \ export COMPOSE_DOCKER_CLI_BUILD=1; \ - docker-compose up; \ + docker compose up --remove-orphans; \ docs: # use sphinx to auto-generate html docs from code - @ echo generating api docs; \ - pdm run sphinx-apidoc -f -o docs/source mex; \ - pdm run sphinx-build -aE -b dirhtml docs docs/dist; \ + @ echo generating docs; \ + pdm doc; \ diff --git a/mex-{{ cookiecutter.project_name }}/README.md b/mex-{{ cookiecutter.project_name }}/README.md index 34c11ba..858ff17 100644 --- a/mex-{{ cookiecutter.project_name }}/README.md +++ b/mex-{{ cookiecutter.project_name }}/README.md @@ -2,10 +2,12 @@ {{ cookiecutter.short_summary }} -[![testing](https://github.com/robert-koch-institut/mex-{{ cookiecutter.project_name }}/actions/workflows/testing.yml/badge.svg)](https://github.com/robert-koch-institut/mex-{{ cookiecutter.project_name }}/actions/workflows/testing.yml) -[![linting](https://github.com/robert-koch-institut/mex-{{ cookiecutter.project_name }}/actions/workflows/linting.yml/badge.svg)](https://github.com/robert-koch-institut/mex-{{ cookiecutter.project_name }}/actions/workflows/linting.yml) +[![cookiecutter](https://github.com/robert-koch-institut/mex-{{ cookiecutter.project_name }}/actions/workflows/cookiecutter.yml/badge.svg)](https://github.com/robert-koch-institut/mex-template) [![cve-scan](https://github.com/robert-koch-institut/mex-{{ cookiecutter.project_name }}/actions/workflows/cve-scan.yml/badge.svg)](https://github.com/robert-koch-institut/mex-{{ cookiecutter.project_name }}/actions/workflows/cve-scan.yml) [![documentation](https://github.com/robert-koch-institut/mex-{{ cookiecutter.project_name }}/actions/workflows/documentation.yml/badge.svg)](https://robert-koch-institut.github.io/mex-{{ cookiecutter.project_name }}) +[![linting](https://github.com/robert-koch-institut/mex-{{ cookiecutter.project_name }}/actions/workflows/linting.yml/badge.svg)](https://github.com/robert-koch-institut/mex-{{ cookiecutter.project_name }}/actions/workflows/linting.yml) +[![open-code](https://github.com/robert-koch-institut/mex-{{ cookiecutter.project_name }}/actions/workflows/open-code.yml/badge.svg)](https://gitlab.opencode.de/robert-koch-institut/mex/mex-{{ cookiecutter.project_name }}) +[![testing](https://github.com/robert-koch-institut/mex-{{ cookiecutter.project_name }}/actions/workflows/testing.yml/badge.svg)](https://github.com/robert-koch-institut/mex-{{ cookiecutter.project_name }}/actions/workflows/testing.yml) ## project @@ -60,19 +62,16 @@ components of the MEx project are open-sourced under the same license as well. ### linting and testing -- on unix run `make test` -- on windows run `.\mex.bat test` -- or run manually - - linter checks via `pre-commit run --all-files` - - all tests via `pdm run pytest` - - just unit tests via `pdm run pytest -m "not integration"` +- run all linters with `pdm lint` +- run only unit tests with `pdm unit` +- run unit and integration tests with `pdm test` ### updating dependencies - update boilerplate files with `cruft update` - update global requirements in `requirements.txt` manually - update git hooks with `pre-commit autoupdate` -- update package dependencies using `pdm autoupdate` +- update package dependencies using `pdm update-all` - update github actions in `.github/workflows/*.yml` manually ### creating release @@ -84,9 +83,9 @@ components of the MEx project are open-sourced under the same license as well. ### container workflow -- build container with `make container` +- build image with `make image` - run directly using docker `make run` -- start with docker-compose `make start` +- start with docker compose `make start` ## commands diff --git a/mex-{{ cookiecutter.project_name }}/mex.bat b/mex-{{ cookiecutter.project_name }}/mex.bat index 2d8e8be..75a4075 100644 --- a/mex-{{ cookiecutter.project_name }}/mex.bat +++ b/mex-{{ cookiecutter.project_name }}/mex.bat @@ -11,7 +11,8 @@ exit /b 1 :install @REM install meta requirements system-wide -Python -m pip --quiet --disable-pip-version-check install --force-reinstall -r requirements.txt +echo installing requirements +pip --disable-pip-version-check install --force-reinstall -r requirements.txt if %errorlevel% neq 0 exit /b %errorlevel% @REM install pre-commit hooks when not in CI @@ -22,26 +23,24 @@ if "%CI%"=="" ( @REM install packages from lock file in local virtual environment echo installing package -pdm sync --clean --group dev +pdm install-all exit /b %errorlevel% :test @REM run the linter hooks from pre-commit on all files echo linting all files -pre-commit run --all-files +pdm lint if %errorlevel% neq 0 exit /b %errorlevel% @REM run the pytest test suite with unit and integration tests echo running all tests -pdm run pytest +pdm test exit /b %errorlevel% :docs @REM use sphinx to auto-generate html docs from code -echo generating api docs -pdm run sphinx-apidoc -f -o docs\source mex -if %errorlevel% neq 0 exit /b %errorlevel% -pdm run sphinx-build -aE -b dirhtml docs docs\dist +echo generating docs +pdm doc exit /b %errorlevel% diff --git a/mex-{{ cookiecutter.project_name }}/pyproject.toml b/mex-{{ cookiecutter.project_name }}/pyproject.toml index a402ce1..da0650f 100644 --- a/mex-{{ cookiecutter.project_name }}/pyproject.toml +++ b/mex-{{ cookiecutter.project_name }}/pyproject.toml @@ -6,17 +6,17 @@ authors = [{ name = "MEx Team", email = "mex@rki.de" }] readme = { file = "README.md", content-type = "text/markdown" } license = { file = "LICENSE" } urls = { Repository = "https://github.com/robert-koch-institut/mex-{{ cookiecutter.project_name }}" } -requires-python = ">=3.11" +requires-python = "<3.13,>=3.11" dependencies = [] optional-dependencies.dev = [ "black>=24.3.0", "ipdb>=0.13.13", "mypy>=1.9.0", - "pytest>=8.1.1", "pytest-cov>=4.1.0", "pytest-random-order>=1.1.1", "pytest-xdist>=3.5.0", - "ruff>=0.3.3", + "pytest>=8.1.1", + "ruff>=0.3.5", "sphinx>=7.2.6", ] @@ -25,7 +25,7 @@ optional-dependencies.dev = [ [tool.cruft] template = "https://github.com/robert-koch-institut/mex-template" -skip = ["tests/conftest.py", "mex/{{ cookiecutter.project_name }}/main.py"] +skip = ["CHANGELOG.md", "mex", "tests"] [tool.ipdb] context = 5 @@ -40,9 +40,20 @@ plugins = ["pydantic.mypy"] distribution = true [tool.pdm.scripts] -autoupdate = { cmd = "pdm update --group :all --update-eager --save-minimum" } +update-all = { cmd = "pdm update --group :all --update-eager --save-minimum" } +lock-all = { cmd = "pdm lock --group :all" } +install-all = { cmd = "pdm install --group :all" } +export-all = { cmd = "pdm export --all :all -f requirements" } +apidoc = { cmd = "pdm run sphinx-apidoc -f -o docs/source mex" } +sphinx = { cmd = "pdm run sphinx-build -aE -b dirhtml docs docs/dist" } +doc = { composite = ["apidoc", "sphinx"] } +wheel = { cmd = "pdm build --no-sdist" } +mypy-daemon = { cmd = "pdm run dmypy run --timeout 7200 -- mex" } lint = { cmd = "pre-commit run --all-files" } +unit = { cmd = "pdm run pytest -m 'not integration'" } test = { cmd = "pdm run pytest --numprocesses=auto --dist=worksteal" } +all = { composite = ["install-all", "lint", "test", "doc"] } + [tool.pydantic-mypy] warn_untyped_fields = true diff --git a/mex-{{ cookiecutter.project_name }}/requirements.txt b/mex-{{ cookiecutter.project_name }}/requirements.txt index 279088b..8295f45 100644 --- a/mex-{{ cookiecutter.project_name }}/requirements.txt +++ b/mex-{{ cookiecutter.project_name }}/requirements.txt @@ -1,4 +1,4 @@ cruft==2.15.0 -pdm==2.12.4 -pre-commit==3.6.2 +pdm==2.13.2 +pre-commit==3.7.0 wheel==0.43.0