diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 80ad328f094433833f53a5512cfc85f93eb799a5..36dd190f15721ddd0dc5c8cbdf0eba75ab7902c9 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,4 +1,245 @@ -include: - - project: bob/citools - ref: master - file: /src/citools/data/python.yml +workflow: + rules: + - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' + - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH' + - if: $CI_COMMIT_TAG + +variables: + PYTHONUNBUFFERED: "1" + XDG_CACHE_HOME: "${CI_PROJECT_DIR}/cache" + CITOOLS: "git+https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.idiap.ch/bob/citools" + +default: + tags: + - bob + - docker + image: python:3.10 + +stages: + - qa + - test + - doc + - dist + - deploy + +quality: + stage: qa + before_script: + - python3 -m venv venv + - source venv/bin/activate + - pip install pre-commit + script: + - pre-commit run --all-files --show-diff-on-failure --verbose + needs: [] + cache: + key: pre-commit-cache + paths: + - ${XDG_CACHE_HOME}/pre-commit + - ${XDG_CACHE_HOME}/pip + rules: + - exists: + - .pre-commit-config.yaml + +tests: + stage: test + image: python:${PYTHON} + parallel: + matrix: + - PYTHON: ["3.9", "3.10"] + TAG: ["docker"] + tags: + - bob + - ${TAG} + needs: + - job: quality + optional: true + before_script: + # get pip-constraints.txt from distribution + - python3 -m venv _citools + - source _citools/bin/activate + - pip install "${CITOOLS}" + - citool pip-constraints "constraints.txt" + - deactivate + # normal test procedure + - python3 -m venv venv + - source venv/bin/activate + - pip install -c constraints.txt '.[test]' pytest-cov coverage + script: + - pytest -sv --cov-report "html:html/coverage" --cov-report "xml:coverage.xml" --junitxml "junit-coverage.xml" + coverage: '/(?:TOTAL|total|Total).*? (100(?:\.0+)?\%|[1-9]?\d(?:\.\d+)?\%)$/' + cache: + key: test-cache-${TAG}-${PYTHON} + paths: + - ${XDG_CACHE_HOME}/pip + artifacts: + paths: + - html + reports: + junit: junit-coverage.xml + coverage_report: + coverage_format: cobertura + path: coverage.xml + +documentation: + stage: doc + rules: + - exists: + - doc/conf.py + needs: + - job: quality + optional: true + cache: + key: doc-cache + paths: + - ${XDG_CACHE_HOME}/pip + before_script: + # get pip-constraints.txt from distribution + - python3 -m venv _citools + - source _citools/bin/activate + - pip install "${CITOOLS}" + - citool pip-constraints "constraints.txt" + - deactivate + # normal doc-building procedure + - python3 -m venv venv + - source venv/bin/activate + - pip install -c constraints.txt '.[doc]' sphinx + script: + - sphinx-build -aEW doc html/sphinx + - sphinx-build -aEb doctest doc html/doctest + artifacts: + paths: + - html + +python-package: + stage: dist + cache: + key: packaging-cache + paths: + - ${XDG_CACHE_HOME}/pip + needs: + - tests + before_script: + - python3 -m venv venv + - source venv/bin/activate + - pip install build twine + script: + - python -m build + - twine check dist/* + artifacts: + paths: + - dist + +conda-package: + stage: dist + # make sure we use the same image as conda-forge: + # https://github.com/conda-forge/conda-forge-pinning-feedstock/blob/main/recipe/conda_build_config.yaml + image: quay.io/condaforge/linux-anvil-cos7-x86_64 + variables: + CONDA_OVERRIDE_CUDA: "11.6" + needs: + - tests + rules: + - exists: + - conda/meta.yaml + before_script: + - pip install "${CITOOLS}" + - rm -f /home/conda/.condarc + - citool conda-config --group "${CI_PROJECT_NAMESPACE}" --visibility "${CI_PROJECT_VISIBILITY}" --tag "${CI_COMMIT_TAG}" /opt/conda/condarc + - mamba update -n base --all + - eval "$(/opt/conda/bin/conda shell.bash hook)" + - PACKAGE_NAME=$(python setup.py --name 2>/dev/null) + - PACKAGE_VERSION=$(python setup.py --version 2>/dev/null) + - export BOB_BUILD_NUMBER=$(citool next-build --group "${CI_PROJECT_NAMESPACE}" --visibility "${CI_PROJECT_VISIBILITY}" --tag "${CI_COMMIT_TAG}" --name "${PACKAGE_NAME}" --version "${PACKAGE_VERSION}" conda-package-matches.txt) + script: + - mkdir dist + - echo "-> ${PACKAGE_NAME}-${PACKAGE_VERSION} build-number is ${BOB_BUILD_NUMBER}" + - citool conda-constraints conda/conda_build_config.yaml conda/recipe_append.yaml + - conda info + - conda mambabuild --output-folder=$(pwd)/dist conda + artifacts: + paths: + - dist + - conda-package-matches.txt + +local-pypi: + stage: deploy + needs: + - python-package + cache: + key: pypi-cache + paths: + - ${XDG_CACHE_HOME}/pip + rules: + # conditions: + # - only on the main branch + # - public or private + # - for tags or not + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + variables: + TWINE_USERNAME: "gitlab-ci-token" + TWINE_PASSWORD: "${CI_JOB_TOKEN}" + before_script: + - python3 -m venv venv + - source venv/bin/activate + - pip install "${CITOOLS}" twine + - PACKAGE_NAME=$(python setup.py --name 2>/dev/null) + - PACKAGE_VERSION=$(python setup.py --version 2>/dev/null) + script: + # only accept to replace version if not a tag + - test -z "${CI_COMMIT_TAG}" && citool deregister --git-url "${CI_SERVER_URL}" --token "${PYPI_PACKAGE_REGISTRY_TOKEN}" --project "${CI_PROJECT_ID}" --name "${PACKAGE_NAME}" --version "${PACKAGE_VERSION}" + - twine upload --repository-url "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/pypi" dist/* + +pypi: + extends: local-pypi + needs: + # only uploads to official PyPI if local PyPI upload suceeded as well + - local-pypi + rules: + # conditions: + # - only on the main branch + # - only for public packages + # - only for tags in PEP-440 style + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_PROJECT_VISIBILITY == "public" && $CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+([abc]\d*)?$/ + variables: + TWINE_USERNAME: "${PYPIUSER}" + TWINE_PASSWORD: "${PYPIPASS}" + script: + - twine upload dist/* + +local-docs: + stage: deploy + needs: + - tests + - job: documentation + optional: true + rules: + - if: ($CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH) + cache: + key: deploy-docs-cache + paths: + - ${XDG_CACHE_HOME}/pip + before_script: + - python3 -m venv venv + - source venv/bin/activate + - pip install "${CITOOLS}" + script: + # uses DOCUSER/DOCPASS environment variables + - citool deploy-docs --package "${CI_PROJECT_PATH}" --visibility "${CI_PROJECT_VISIBILITY}" --branch "${CI_COMMIT_REF_NAME}" --tag "${CI_COMMIT_TAG}" html + +conda-deploy: + stage: deploy + needs: + - conda-package + rules: + - if: ($CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH) + cache: + key: deploy-conda-cache + paths: + - ${XDG_CACHE_HOME}/pip + before_script: + - python3 -m venv venv + - source venv/bin/activate + - pip install "${CITOOLS}" + script: + # uses DOCUSER/DOCPASS environment variables + - citool deploy-conda --visibility "${CI_PROJECT_VISIBILITY}" --tag "${CI_COMMIT_TAG}" dist/*/*.conda