diff --git a/docker/ci-runner/Dockerfile b/docker/ci-runner/Dockerfile index d016805c4a8c2392b3a373d05a672225b59b2f15..aa795837c670f9e26b3c9dea4e7010007b91a1c8 100644 --- a/docker/ci-runner/Dockerfile +++ b/docker/ci-runner/Dockerfile @@ -1,6 +1,8 @@ +# This dockerfile is used throughout steps of the CI/CD pipeline +# It contains dependencies to execute the template and run tests FROM python:3.13 RUN python -m pip install --upgrade pip -RUN python -m pip install --upgrade cibuildwheel==2.23.0 cookiecutter tox twine +RUN python -m pip install --upgrade cibuildwheel>=2.23.0 cookiecutter tox twine RUN curl -sSL https://get.docker.com/ | sh diff --git a/project.gitlab-ci.yml b/project.gitlab-ci.yml index 663b7b530b0b476902c3ffb0e18674d7bc16da2c..740497a5bdb6a0b706f980cba8867aa4f45d7ee9 100644 --- a/project.gitlab-ci.yml +++ b/project.gitlab-ci.yml @@ -78,13 +78,13 @@ package_docs: paths: - my_awesome_app/docs/build/* -#docker_build: -# needs: -# - pipeline: $PARENT_PIPELINE_ID -# job: build-template -# - package_files -# before_script: -# - cd my_awesome_app +docker_build: + needs: + - pipeline: $PARENT_PIPELINE_ID + job: build-template + - package_files + before_script: + - cd my_awesome_app run_integration_tests: needs: diff --git a/{{cookiecutter.project_slug}}/.gitlab-ci.yml b/{{cookiecutter.project_slug}}/.gitlab-ci.yml index a08ac42cee44750882e09355b11c49321f1f5673..d08a6214f35dec222333e4062815c637b6ff8b71 100644 --- a/{{cookiecutter.project_slug}}/.gitlab-ci.yml +++ b/{{cookiecutter.project_slug}}/.gitlab-ci.yml @@ -2,8 +2,6 @@ default: image: name: $CI_REGISTRY_IMAGE/ci-build-runner:$CI_COMMIT_REF_SLUG pull_policy: always - before_script: - - python --version # For debugging cache: paths: - .cache/pip @@ -22,14 +20,13 @@ stages: variables: PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip" - +# Job templates from Gitlab that scan for security issues or leaked secrets include: - template: Security/SAST.gitlab-ci.yml - template: Security/Dependency-Scanning.gitlab-ci.yml - template: Security/Secret-Detection.gitlab-ci.yml - -# Prepare image to run ci on +# Prepare image to run ci on, image will be used in most jobs trigger_prepare: stage: prepare trigger: @@ -48,16 +45,6 @@ sast: pmd-apex, sobelow, spotbugs stage: test -dependency_scanning: - # override default before_script, job won't have Python available - before_script: - - uname - -secret_detection: - # override default before_script, job won't have Python available - before_script: - - uname - # Basic setup for all Python versions for which we don't have a base image .run_unit_test_version_base: before_script: @@ -66,6 +53,7 @@ secret_detection: - python -m pip install --upgrade tox twine # Run all unit tests for Python versions except the base image +# The base image is used for the highest Python version run_unit_tests: extends: .run_unit_test_version_base stage: test @@ -90,6 +78,8 @@ run_unit_tests_coverage: paths: - htmlcov/* +# Binary packages will be build for many architectures +# using scikitbuild-core and cibuildwheel package_files: stage: package tags: @@ -102,6 +92,7 @@ package_files: - source scripts/setup-docker-host.sh - tox -e build-ci-linux +# Build the sphinx documentation package_docs: stage: package artifacts: @@ -111,6 +102,22 @@ package_docs: script: - tox -e docs +# Build a tiny docker image that contains the minimal dependencies to run this project +docker_build: + stage: images + image: docker:latest + needs: + - package_files + tags: + - dind + before_script: [] + script: + - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY + - docker build -f docker/{{cookiecutter.project_slug}}/Dockerfile . --build-arg BUILD_ENV=copy --tag $CI_REGISTRY_IMAGE/{{cookiecutter.project_slug}}:$CI_COMMIT_REF_SLUG + # enable this push line once you have configured docker registry cleanup policy + # - docker push $CI_REGISTRY_IMAGE/{{cookiecutter.project_slug}}:$CI_COMMIT_REF_SLUG + + run_integration_tests: stage: integration allow_failure: true @@ -187,6 +194,7 @@ publish_to_readthedocs: - echo "scp docs/* ???" - exit 1 +# automatically create a release on Gitlab for every tagged commit release_job: stage: publish image: registry.gitlab.com/gitlab-org/release-cli:latest diff --git a/{{cookiecutter.project_slug}}/.pre-commit-config.yaml b/{{cookiecutter.project_slug}}/.pre-commit-config.yaml index c6570e2e9f17962260b75e7e3b80f5ffde48c422..c7c1b720cfc8d8d631b4c7c2640aebd0499b3a08 100644 --- a/{{cookiecutter.project_slug}}/.pre-commit-config.yaml +++ b/{{cookiecutter.project_slug}}/.pre-commit-config.yaml @@ -1,4 +1,7 @@ -# https://pre-commit.com/ +# run several checks prior to creating a commit or pushing to a remote +# These can be skipped (but you shouldn't generally as the pipeline will fail) +# using `git push / commit --no-check` +# for more information see: https://pre-commit.com/ default_stages: [ pre-commit, pre-push ] default_language_version: python: python3 diff --git a/{{cookiecutter.project_slug}}/README.md b/{{cookiecutter.project_slug}}/README.md index 4e6e8c75c5bbc2a58e17e98bb27d8b7bf49143b0..f74c6e09970b07a4cbd88e8b588933e75269d617 100644 --- a/{{cookiecutter.project_slug}}/README.md +++ b/{{cookiecutter.project_slug}}/README.md @@ -38,5 +38,7 @@ To automatically apply most suggested linting changes execute: ```tox -e format``` +The configuration for linting and tox can be found in `pyproject.toml` + ## License This project is licensed under the Apache License Version 2.0 diff --git a/{{cookiecutter.project_slug}}/bin/install-hooks/pre-commit.sh b/{{cookiecutter.project_slug}}/bin/install-hooks/pre-commit.sh deleted file mode 100755 index 792a3aabef83dc4ebf0c94635ae1de0e7412c479..0000000000000000000000000000000000000000 --- a/{{cookiecutter.project_slug}}/bin/install-hooks/pre-commit.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/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}}/build-requirements.txt b/{{cookiecutter.project_slug}}/build-requirements.txt index d2d6bde8d4c933d8debe5d02272df5fe446e288e..502b5f30232469f7a5614b019b541d998546db1e 100644 --- a/{{cookiecutter.project_slug}}/build-requirements.txt +++ b/{{cookiecutter.project_slug}}/build-requirements.txt @@ -1,3 +1,3 @@ -cibuildwheel==2.23.0 # BSD +cibuildwheel>=2.23.0 # BSD tox >= 4.0 # ? build >= 0.8.0 # MIT diff --git a/{{cookiecutter.project_slug}}/docker/ci-runner/Dockerfile b/{{cookiecutter.project_slug}}/docker/ci-runner/Dockerfile index d61c39998b79b4975715276f7a179ca1eb68b549..4494c2bc3b3819ffa2b4b4b0faabe62d7f2eaa11 100644 --- a/{{cookiecutter.project_slug}}/docker/ci-runner/Dockerfile +++ b/{{cookiecutter.project_slug}}/docker/ci-runner/Dockerfile @@ -1,5 +1,7 @@ +# This dockerfile is used throughout steps of the CI/CD pipeline +# It contains dependencies to run tests FROM python:3.13 RUN python -m pip install --upgrade pip -RUN python -m pip install --upgrade cibuildwheel==2.23.0 tox twine +RUN python -m pip install --upgrade cibuildwheel>=2.23.0 tox twine 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 index d64db4971e9fa1cbf067936c7152fc02d4c4fbff..9e9cb238f3302d1d16207d9300a32575d9e96bc8 100644 --- a/{{cookiecutter.project_slug}}/docker/{{cookiecutter.project_slug}}/Dockerfile +++ b/{{cookiecutter.project_slug}}/docker/{{cookiecutter.project_slug}}/Dockerfile @@ -1,13 +1,18 @@ +# This dockerfile creates a minimal docker image that can run the project. +# It can copy the result of `tox -e build` from the host to the container +# or build from source inside the container. +# Set `docker build --build-arg BUILD_ENV=copy` to copy from the host, rebuild otherwise +# contrarily, to the ci image it does not contain any dependencies used for testing. ARG BUILD_ENV=no_copy # Build without copying from host inside docker FROM python:3.13 AS build_no_copy ADD ../../requirements.txt . COPY ../.. /work -RUN rm -r /work/dist | true +RUN rm -rf /work/dist RUN python -m pip install --user tox WORKDIR /work -RUN python -m tox -e build +RUN python -m tox -e build-local # Copy build package from host `dist` directory FROM python:3.13 AS build_copy diff --git a/{{cookiecutter.project_slug}}/docs/cleanup.py b/{{cookiecutter.project_slug}}/docs/cleanup.py index b2e219cbfe66e894109aefb3b8cf1cb34d6d40ea..c88889067f1dc736a881d565ee02460f8cd05148 100644 --- a/{{cookiecutter.project_slug}}/docs/cleanup.py +++ b/{{cookiecutter.project_slug}}/docs/cleanup.py @@ -5,6 +5,12 @@ """ Remove generated source documentation files except for index.rst + +If a source file is created, documentation is generated and the source file is later +removed. The documentation for this source file will persists. + +This file ensures generated source documentation files, which are automatically +generated from source, are removed between every build. """ import os diff --git a/{{cookiecutter.project_slug}}/setup.sh b/{{cookiecutter.project_slug}}/setup.sh index 3eb742940523b3955505298d84cb499eb4ae602f..b1a3a35ac02753f663a029cd320f7936aca93b9b 100755 --- a/{{cookiecutter.project_slug}}/setup.sh +++ b/{{cookiecutter.project_slug}}/setup.sh @@ -4,14 +4,16 @@ # SPDX-License-Identifier: Apache-2.0 # -# This file's directory is used to determine the station control directory -# location. We substitute BASH_SOURCE if it doesn't get set, this particularly -# happens when sourcing using the `docker` docker image due to its primitive -# shell. +# Substitute BASH_SOURCE if unset this is required for simple shells +# such as the one found in docker or alpine docker images. +# `#! /usr/bin/env bash` does not actually ensure the sourcing is executed +# using BASH if [ -z ${BASH_SOURCE} ]; then BASH_SOURCE=${(%):-%x} fi +# From BASH_SOURCE determine the absolute path, this is needed because $0 is +# unset when sourcing in some shells. ABSOLUTE_PATH=$(realpath $(dirname ${BASH_SOURCE})) # Create a virtual environment directory if it doesn't exist @@ -26,7 +28,7 @@ source "$VENV_DIR/bin/activate" python -m pip install pre-commit python -m pip install "tox>=4.21.0" -# Install git pre-commit pre-push hook -if [ ! -f "${ABSOLUTE_PATH}/.git/hooks/pre-push.legacy" ]; then - source "${ABSOLUTE_PATH}/bin/install-hooks/pre-commit.sh" +# Install git pre-commit pre-push hook if not already installed +if [ ! -f "${ABSOLUTE_PATH}/.git/hooks/pre-push" ]; then + pre-commit install --hook-type pre-push fi