Loading .gitlab-ci.pre-commit-run.bash 0 → 100644 +58 −0 Original line number Diff line number Diff line # Find a suitable commit for determining changed files # # # Copyright 2022 Dom Sekotill <dom.sekotill@kodo.org.uk> # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. pre_commit_run() ( set -eu declare -a PRE_COMMIT_ARGS find_lca() { local repo=$CI_REPOSITORY_URL local current_branch=$1 other_branch=$2 # See https://stackoverflow.com/questions/63878612/git-fatal-error-in-object-unshallow-sha-1 # and https://stackoverflow.com/questions/4698759/converting-git-repository-to-shallow/53245223#53245223 # for background on what `git repack -d` is doing here. git repack -qd git fetch -q $repo --shallow-exclude=$other_branch $current_branch git fetch -q $repo --deepen=1 $current_branch FROM_REF=$(git rev-parse -q --revs-only --verify shallow) || unset FROM_REF } fetch_ref() { git fetch -q $CI_REPOSITORY_URL --depth=1 $1 FROM_REF=$1 } if [[ -v CI_COMMIT_BEFORE_SHA ]] && [[ ! $CI_COMMIT_BEFORE_SHA =~ ^0{40}$ ]]; then fetch_ref $CI_COMMIT_BEFORE_SHA elif [[ -v CI_MERGE_REQUEST_TARGET_BRANCH_NAME ]]; then find_lca $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME $CI_MERGE_REQUEST_TARGET_BRANCH_NAME elif [[ $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH ]]; then find_lca $CI_COMMIT_BRANCH $CI_DEFAULT_BRANCH fi if [[ -v FROM_REF ]]; then PRE_COMMIT_ARGS=( --from-ref=$FROM_REF --to-ref=$CI_COMMIT_SHA ) else PRE_COMMIT_ARGS=( --all-files ) fi pre-commit run "$@" "${PRE_COMMIT_ARGS[@]}" ) .gitlab-ci.yml +89 −46 Original line number Diff line number Diff line # Optional project CI variables to set: # # SAFETY_API_KEY: # Set to your API key for accessing up-to-date package security information stages: - test - build - test - publish image: python:3.9 workflow: rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" - if: $CI_OPEN_MERGE_REQUESTS when: never - when: always .python: image: python:3.9 variables: PIP_CACHE_DIR: $CI_PROJECT_DIR/cache/pkg PRE_COMMIT_HOME: $CI_PROJECT_DIR/cache/pre-commit .cached: PIP_NO_COMPILE: "true" PIP_NO_CLEAN: "true" cache: key: $CI_JOB_IMAGE paths: [cache] before_script: - pip install "pip>=21.3" Build Package: stage: build extends: [.python] script: - pip install build - python -m build artifacts: paths: [dist] Pin: # Pin dependencies in requirements.txt for reproducing pipeline results stage: test extends: [.python] needs: [] script: - pip install --prefer-binary -e . - pip freeze --exclude-editable | tee requirements.txt artifacts: paths: [requirements.txt] Dependency Check: stage: test image: pyupio/safety:latest needs: [Pin] allow_failure: true script: - safety check -r requirements.txt Code Checks: stage: test extends: [.cached] image: docker.kodo.org.uk/ci-images/pre-commit:2.15.0-1 needs: [] variables: HOOK_STAGE: commit FROM_REF: $CI_DEFAULT_BRANCH PRE_COMMIT_HOME: $CI_PROJECT_DIR/cache/pre-commit cache: key: $CI_JOB_IMAGE paths: [cache] rules: - if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH variables: FROM_REF: $CI_COMMIT_BEFORE_SHA - if: $CI_PIPELINE_SOURCE == "push" - if: $CI_PIPELINE_SOURCE == "merge_request_event" variables: HOOK_STAGE: merge-commit script: - git fetch $CI_REPOSITORY_URL $FROM_REF:FROM_REF -f - pre-commit run --hook-stage=$HOOK_STAGE --from-ref=FROM_REF --to-ref=HEAD - source .gitlab-ci.pre-commit-run.bash - pre_commit_run --hook-stage=commit - pre_commit_run --hook-stage=push Commit Graph Check: extends: ["Code Checks"] variables: HOOK_STAGE: push rules: - if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH variables: FROM_REF: $CI_COMMIT_BEFORE_SHA - if: $CI_PIPELINE_SOURCE == "merge_request_event" Unit Tests: stage: test extends: [.python] needs: [Pin] script: - pip install -r requirements.txt -e .[tests] nose - coverage run -m nose tests --verbose --with-xunit --xunit-file=results/xunit.xml after_script: - coverage report - coverage json - coverage xml - coverage html coverage: '/^TOTAL .* (\d{1,3}\.\d{2})%$/' artifacts: paths: [results] reports: cobertura: results/coverage.xml junit: results/xunit.xml Check Tag: stage: test extends: [.cached] extends: [.python] needs: ["Build Package"] rules: - if: $CI_COMMIT_TAG =~ /^v[0-9]/ script: - pip install tomli packaging - pip install packaging pkginfo - | python <<-END import tomli from glob import glob from packaging.version import Version from pkginfo import Wheel with open("pyproject.toml", "rb") as f: proj = tomli.load(f) assert Version("$CI_COMMIT_TAG") == Version(proj["tool"]["poetry"]["version"]) wheel_path = glob("dist/*.whl")[0] wheel = Wheel(wheel_path) assert Version("$CI_COMMIT_TAG") == Version(wheel.version) END Build Package: stage: build extends: [.cached] script: - pip install build - python -m build artifacts: paths: [dist] Upload Package: stage: publish extends: [.cached] needs: ["Build Package"] rules: - if: $CI_COMMIT_TAG =~ /^v[0-9]/ script: Loading Loading
.gitlab-ci.pre-commit-run.bash 0 → 100644 +58 −0 Original line number Diff line number Diff line # Find a suitable commit for determining changed files # # # Copyright 2022 Dom Sekotill <dom.sekotill@kodo.org.uk> # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. pre_commit_run() ( set -eu declare -a PRE_COMMIT_ARGS find_lca() { local repo=$CI_REPOSITORY_URL local current_branch=$1 other_branch=$2 # See https://stackoverflow.com/questions/63878612/git-fatal-error-in-object-unshallow-sha-1 # and https://stackoverflow.com/questions/4698759/converting-git-repository-to-shallow/53245223#53245223 # for background on what `git repack -d` is doing here. git repack -qd git fetch -q $repo --shallow-exclude=$other_branch $current_branch git fetch -q $repo --deepen=1 $current_branch FROM_REF=$(git rev-parse -q --revs-only --verify shallow) || unset FROM_REF } fetch_ref() { git fetch -q $CI_REPOSITORY_URL --depth=1 $1 FROM_REF=$1 } if [[ -v CI_COMMIT_BEFORE_SHA ]] && [[ ! $CI_COMMIT_BEFORE_SHA =~ ^0{40}$ ]]; then fetch_ref $CI_COMMIT_BEFORE_SHA elif [[ -v CI_MERGE_REQUEST_TARGET_BRANCH_NAME ]]; then find_lca $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME $CI_MERGE_REQUEST_TARGET_BRANCH_NAME elif [[ $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH ]]; then find_lca $CI_COMMIT_BRANCH $CI_DEFAULT_BRANCH fi if [[ -v FROM_REF ]]; then PRE_COMMIT_ARGS=( --from-ref=$FROM_REF --to-ref=$CI_COMMIT_SHA ) else PRE_COMMIT_ARGS=( --all-files ) fi pre-commit run "$@" "${PRE_COMMIT_ARGS[@]}" )
.gitlab-ci.yml +89 −46 Original line number Diff line number Diff line # Optional project CI variables to set: # # SAFETY_API_KEY: # Set to your API key for accessing up-to-date package security information stages: - test - build - test - publish image: python:3.9 workflow: rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" - if: $CI_OPEN_MERGE_REQUESTS when: never - when: always .python: image: python:3.9 variables: PIP_CACHE_DIR: $CI_PROJECT_DIR/cache/pkg PRE_COMMIT_HOME: $CI_PROJECT_DIR/cache/pre-commit .cached: PIP_NO_COMPILE: "true" PIP_NO_CLEAN: "true" cache: key: $CI_JOB_IMAGE paths: [cache] before_script: - pip install "pip>=21.3" Build Package: stage: build extends: [.python] script: - pip install build - python -m build artifacts: paths: [dist] Pin: # Pin dependencies in requirements.txt for reproducing pipeline results stage: test extends: [.python] needs: [] script: - pip install --prefer-binary -e . - pip freeze --exclude-editable | tee requirements.txt artifacts: paths: [requirements.txt] Dependency Check: stage: test image: pyupio/safety:latest needs: [Pin] allow_failure: true script: - safety check -r requirements.txt Code Checks: stage: test extends: [.cached] image: docker.kodo.org.uk/ci-images/pre-commit:2.15.0-1 needs: [] variables: HOOK_STAGE: commit FROM_REF: $CI_DEFAULT_BRANCH PRE_COMMIT_HOME: $CI_PROJECT_DIR/cache/pre-commit cache: key: $CI_JOB_IMAGE paths: [cache] rules: - if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH variables: FROM_REF: $CI_COMMIT_BEFORE_SHA - if: $CI_PIPELINE_SOURCE == "push" - if: $CI_PIPELINE_SOURCE == "merge_request_event" variables: HOOK_STAGE: merge-commit script: - git fetch $CI_REPOSITORY_URL $FROM_REF:FROM_REF -f - pre-commit run --hook-stage=$HOOK_STAGE --from-ref=FROM_REF --to-ref=HEAD - source .gitlab-ci.pre-commit-run.bash - pre_commit_run --hook-stage=commit - pre_commit_run --hook-stage=push Commit Graph Check: extends: ["Code Checks"] variables: HOOK_STAGE: push rules: - if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH variables: FROM_REF: $CI_COMMIT_BEFORE_SHA - if: $CI_PIPELINE_SOURCE == "merge_request_event" Unit Tests: stage: test extends: [.python] needs: [Pin] script: - pip install -r requirements.txt -e .[tests] nose - coverage run -m nose tests --verbose --with-xunit --xunit-file=results/xunit.xml after_script: - coverage report - coverage json - coverage xml - coverage html coverage: '/^TOTAL .* (\d{1,3}\.\d{2})%$/' artifacts: paths: [results] reports: cobertura: results/coverage.xml junit: results/xunit.xml Check Tag: stage: test extends: [.cached] extends: [.python] needs: ["Build Package"] rules: - if: $CI_COMMIT_TAG =~ /^v[0-9]/ script: - pip install tomli packaging - pip install packaging pkginfo - | python <<-END import tomli from glob import glob from packaging.version import Version from pkginfo import Wheel with open("pyproject.toml", "rb") as f: proj = tomli.load(f) assert Version("$CI_COMMIT_TAG") == Version(proj["tool"]["poetry"]["version"]) wheel_path = glob("dist/*.whl")[0] wheel = Wheel(wheel_path) assert Version("$CI_COMMIT_TAG") == Version(wheel.version) END Build Package: stage: build extends: [.cached] script: - pip install build - python -m build artifacts: paths: [dist] Upload Package: stage: publish extends: [.cached] needs: ["Build Package"] rules: - if: $CI_COMMIT_TAG =~ /^v[0-9]/ script: Loading