diff --git a/cookiecutter.json b/cookiecutter.json index 1f29d355f8fcd56ebb3f1c5a3de8b49d748e60f6..8165b9764968afc310e18f5850f8b960c9c95a88 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -1,6 +1,7 @@ { "project_name": "My Awesome App", "project_slug": "{{ cookiecutter.project_name.lower()|replace(' ', '_')|replace('-', '_')|replace('.', '_')|trim() }}", - "project_url": "https://git.astron.nl/{{cookiecutter.project_slug}}", + "project_package": "{{ cookiecutter.project_name.lower()|replace(' ', '-')|replace('_', '-')|replace('.', '-')|trim() }}", + "project_url": "https://git.astron.nl/{{ cookiecutter.project_slug }}", "description": "An example package for CI/CD working group" } diff --git a/docker/ci-runner/Dockerfile b/docker/ci-runner/Dockerfile index 8b9621755a0653909c67cf1eda3ff2bfba87063c..497b89a715157c619baadc189a896f79a0731172 100644 --- a/docker/ci-runner/Dockerfile +++ b/docker/ci-runner/Dockerfile @@ -1,5 +1,5 @@ -FROM python:3.11 +FROM python:3.12 RUN python -m pip install --upgrade pip -RUN pip install --upgrade cookiecutter tox twine cibuildwheel==2.13.1 cookiecutter +RUN python -m pip install --upgrade cookiecutter tox twine cibuildwheel==2.13.1 cookiecutter RUN curl -sSL https://get.docker.com/ | sh diff --git a/{{cookiecutter.project_slug}}/.dockerignore b/{{cookiecutter.project_slug}}/.dockerignore new file mode 100644 index 0000000000000000000000000000000000000000..141f90da2fac6459ee10150e4cd3e12aff08a48b --- /dev/null +++ b/{{cookiecutter.project_slug}}/.dockerignore @@ -0,0 +1,4 @@ +.tox +build +*.egg-info +.venv diff --git a/{{cookiecutter.project_slug}}/.gitignore b/{{cookiecutter.project_slug}}/.gitignore index 5513c1bf7cbca7a522e1ea44f306bda82a80975d..885470b5e93bf922433ae1741179f1c7ae07918a 100644 --- a/{{cookiecutter.project_slug}}/.gitignore +++ b/{{cookiecutter.project_slug}}/.gitignore @@ -1,13 +1,19 @@ dist/* *.egg-info *.pyc +.tox +.venv .coverage coverage.xml htmlcov/* +build +dist -# Tox -.tox +# Documentation +docs/source/source_documentation +!docs/source/source_documentation/index.rst +docs/build # setuptools-scm src/{{cookiecutter.project_slug}}/_version.py diff --git a/{{cookiecutter.project_slug}}/.gitlab-ci.yml b/{{cookiecutter.project_slug}}/.gitlab-ci.yml index 429482664900652365935d2c323b79eda4698a92..5071e25812340c37592101c92d1c91b5f7804088 100644 --- a/{{cookiecutter.project_slug}}/.gitlab-ci.yml +++ b/{{cookiecutter.project_slug}}/.gitlab-ci.yml @@ -14,6 +14,7 @@ stages: - lint - test - package + - images - integration - publish # publish instead of deploy @@ -35,22 +36,10 @@ trigger_prepare: strategy: depend include: .prepare.gitlab-ci.yml -run_black: +run_lint: stage: lint script: - - tox -e black - allow_failure: true - -run_flake8: - stage: lint - script: - - tox -e pep8 - allow_failure: true - -run_pylint: - stage: lint - script: - - tox -e pylint + - tox -e lint allow_failure: true sast: @@ -74,7 +63,7 @@ secret_detection: before_script: - python --version # For debugging - python -m pip install --upgrade pip - - pip install --upgrade tox twine + - python -m pip install --upgrade tox twine # Run all unit tests for Python versions except the base image run_unit_tests: @@ -156,8 +145,7 @@ publish_on_test_pypi: - package_files when: manual rules: - - if: $CI_COMMIT_TAG - allow_failure: true + - if: '$CI_COMMIT_TAG && $CI_COMMIT_REF_PROTECTED == "true"' script: - echo "run twine for test pypi" # - | @@ -175,8 +163,7 @@ publish_on_pypi: - package_files when: manual rules: - - if: $CI_COMMIT_TAG - allow_failure: true + - if: '$CI_COMMIT_TAG && $CI_COMMIT_REF_PROTECTED == "true"' script: - echo "run twine for pypi" # - | @@ -195,7 +182,7 @@ publish_to_readthedocs: - package_docs when: manual rules: - - if: $CI_COMMIT_TAG + - if: '$CI_COMMIT_TAG && $CI_COMMIT_REF_PROTECTED == "true"' script: - echo "scp docs/* ???" - exit 1 diff --git a/{{cookiecutter.project_slug}}/.pre-commit-config.yaml b/{{cookiecutter.project_slug}}/.pre-commit-config.yaml new file mode 100644 index 0000000000000000000000000000000000000000..ce46e6463265d2ad9704a24ae7f467cb7b50d8d9 --- /dev/null +++ b/{{cookiecutter.project_slug}}/.pre-commit-config.yaml @@ -0,0 +1,22 @@ +default_stages: [ pre-commit, pre-push ] +default_language_version: + python: python3 +exclude: '^docs/.*\.py$' + +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: end-of-file-fixer + - id: trailing-whitespace + - id: check-yaml + - id: check-toml + - id: detect-private-key + - repo: local + hooks: + - id: tox-lint + name: tox-lint (local) + entry: tox + language: python + types: [file, python] + args: ["-e", "lint", "--"] diff --git a/{{cookiecutter.project_slug}}/bin/install-hooks/pre-commit.sh b/{{cookiecutter.project_slug}}/bin/install-hooks/pre-commit.sh new file mode 100755 index 0000000000000000000000000000000000000000..792a3aabef83dc4ebf0c94635ae1de0e7412c479 --- /dev/null +++ b/{{cookiecutter.project_slug}}/bin/install-hooks/pre-commit.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +if [ ! -f "setup.sh" ]; then + echo "pre-commit.sh must be executed with repository root as working directory!" + exit 1 +fi + +pre-commit install --hook-type pre-push diff --git a/{{cookiecutter.project_slug}}/docker/ci-runner/Dockerfile b/{{cookiecutter.project_slug}}/docker/ci-runner/Dockerfile index 48d4586f1eb2c4755b370b9bb4c5fe079c97fed8..2deb674a75484e11700e7f97b21bd80fe558e3f9 100644 --- a/{{cookiecutter.project_slug}}/docker/ci-runner/Dockerfile +++ b/{{cookiecutter.project_slug}}/docker/ci-runner/Dockerfile @@ -1,5 +1,5 @@ FROM python:3.13 RUN python -m pip install --upgrade pip -RUN pip install --upgrade tox twine cibuildwheel==2.13.1 +RUN python -m pip install --upgrade tox twine cibuildwheel==2.13.1 RUN curl -sSL https://get.docker.com/ | sh diff --git a/{{cookiecutter.project_slug}}/docker/{{cookiecutter.project_slug}}/Dockerfile b/{{cookiecutter.project_slug}}/docker/{{cookiecutter.project_slug}}/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..1f7eb275020d13ed45cb7b0983949c12161ff953 --- /dev/null +++ b/{{cookiecutter.project_slug}}/docker/{{cookiecutter.project_slug}}/Dockerfile @@ -0,0 +1,18 @@ +ARG BUILD_ENV=no_copy + +FROM python:3.13 AS build_no_copy +ADD ../../requirements.txt . +COPY ../.. /work +RUN rm -r /work/dist | true +RUN python -m pip install --user tox +WORKDIR /work +RUN python -m tox -e build + +FROM python:3.13 AS build_copy +COPY dist /work/dist + +FROM build_${BUILD_ENV} AS build + +FROM python:3.13-slim +COPY --from=build /work/dist /dist +RUN python -m pip install /dist/*.whl diff --git a/{{cookiecutter.project_slug}}/docs/cleanup.py b/{{cookiecutter.project_slug}}/docs/cleanup.py new file mode 100644 index 0000000000000000000000000000000000000000..3a4508d859234544bea35b1008e3c8e4f73d7cc0 --- /dev/null +++ b/{{cookiecutter.project_slug}}/docs/cleanup.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python3 + +# Copyright (C) 2023 ASTRON (Netherlands Institute for Radio Astronomy) +# SPDX-License-Identifier: Apache-2.0 + +import os + +file_dir = os.path.dirname(os.path.realpath(__file__)) + +clean_dir = os.path.join(file_dir, "source", "source_documentation") +print(f"Cleaning.. {clean_dir}/*") + +if not os.path.exists(clean_dir): + exit() + +for file_name in os.listdir(clean_dir): + file = os.path.join(clean_dir, file_name) + + if file_name == "index.rst": + continue + + print(f"Removing.. {file}") + os.remove(file) diff --git a/{{cookiecutter.project_slug}}/docs/cleanup.sh b/{{cookiecutter.project_slug}}/docs/cleanup.sh deleted file mode 100644 index aac4cef22a134a44b69e99369755a58507b3794f..0000000000000000000000000000000000000000 --- a/{{cookiecutter.project_slug}}/docs/cleanup.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -FILE_DIR=$(dirname -- "$(readlink -f -- "${0}")") - -echo "Cleaning.. ${FILE_DIR}/source/source_documentation/*" - -for f in "${FILE_DIR}"/source/source_documentation/* -do - - case $f in - */index.rst) true;; - *) echo "Removing.. ${f}"; rm "${f}";; - esac -done diff --git a/{{cookiecutter.project_slug}}/pyproject.toml b/{{cookiecutter.project_slug}}/pyproject.toml index db601f122b76f82a3f3037ee7524cfb28c4a75ff..3eefe305c58c025c89fd8914fca262091cd11966 100644 --- a/{{cookiecutter.project_slug}}/pyproject.toml +++ b/{{cookiecutter.project_slug}}/pyproject.toml @@ -46,20 +46,19 @@ archs = ["x86_64", "i686"] [tool.cibuildwheel.windows] archs = ["AMD64", "x86"] -[tool.pylint] -ignore = "_version.py" -# This does nothing until the issue below is resolved: -# https://github.com/PyCQA/flake8/issues/234 -[tool.flake8] -max-line-length = 88 -extend-ignore = ["E203"] -exclude = ["_version.py"] +[tool.ruff] +exclude = [ + ".venv", + ".git", + ".tox", + "dist", + "docs", + "*lib/python*", + "*egg", + "_version.py" +] + +[tool.ruff.lint] +ignore = ["E203"] -[tool.black] -line-length = 88 -extend-exclude = ''' -( - _version.py -) -''' diff --git a/{{cookiecutter.project_slug}}/tests/requirements.txt b/{{cookiecutter.project_slug}}/tests/requirements.txt index 82f1ee820e4b57fd3e720ad74078688cd87c2ead..b507faf8c6cc09660c41c58caa26d318e94cfd4d 100644 --- a/{{cookiecutter.project_slug}}/tests/requirements.txt +++ b/{{cookiecutter.project_slug}}/tests/requirements.txt @@ -1,8 +1,2 @@ -autopep8 >= 1.7.0 # MIT -black >= 22.0.0 # MIT -build >= 0.8.0 # MIT -flake8 >= 5.0.0 # MIT -pyproject-flake8 >= 5.0.4 # Unlicense -pylint >= 2.15.0 # GPLv2 pytest >= 7.0.0 # MIT pytest-cov >= 3.0.0 # MIT diff --git a/{{cookiecutter.project_slug}}/tests/test_cool_module.py b/{{cookiecutter.project_slug}}/tests/test_cool_module.py index 19e5cd2bd0bff16fa00560bdb678f9345e4e79f4..2cacc8e76f00c2d40f10bf9ff2bd28f61ca6b59a 100644 --- a/{{cookiecutter.project_slug}}/tests/test_cool_module.py +++ b/{{cookiecutter.project_slug}}/tests/test_cool_module.py @@ -1,3 +1,6 @@ +# Copyright (C) 2025 ASTRON (Netherlands Institute for Radio Astronomy) +# SPDX-License-Identifier: Apache-2.0 + """Testing of the Cool Module""" from unittest import TestCase