Skip to content

Keep 'ci/dependency-updates' up-to-date with 'main' #723

Keep 'ci/dependency-updates' up-to-date with 'main'

Keep 'ci/dependency-updates' up-to-date with 'main' #723

Workflow file for this run

name: CI - Tests
on:
pull_request:
push:
branches:
- 'main'
- 'push-action/**' # Allow pushing to protected branches (using CasperWA/push-protected)
jobs:
basic-tests:
name: External
uses: SINTEF/ci-cd/.github/workflows/ci_tests.yml@v2.8.3
with:
# General setup
install_extras: "[dev]"
# pre-commit
run_pre-commit: false
# pylint & safety
python_version_pylint_safety: "3.10"
run_pylint: false
run_safety: true
# ID: 70612
# Package: Jinja2
# Has been disputed by the maintainer and multiple third parties.
# For more information see: https://github.com/advisories/GHSA-f6pv-j8mr-w6rr
safety_options: |
--ignore=70612
# Build dist
python_version_package: "3.10"
build_libs: flit
build_cmd: flit build
# Build documentation
run_build_docs: false
docker:
name: Docker
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
docker_target: ["development", "production"]
env:
# "Regular" entities service configuration values
ENTITIES_SERVICE_MONGO_URI: mongodb://localhost:27017
ENTITIES_SERVICE_X509_CERTIFICATE_FILE: docker_security/test-client.pem
ENTITIES_SERVICE_CA_FILE: docker_security/test-ca.pem
# These are used in the Dockerfile as well as in pytest
ENTITIES_SERVICE_HOST: localhost
ENTITIES_SERVICE_PORT: 7000
steps:
- name: Checkout ${{ github.repository }}
uses: actions/checkout@v4
- name: Setup Python 3.10
uses: actions/setup-python@v5
with:
python-version: "3.10"
- name: Run MongoDB
run: |
# Create folder for certificates
mkdir -p docker_security
# Generate certificates
cd docker_security && ${{ github.workspace }}/.github/docker_init/setup_mongo_security.sh
cd ${{ github.workspace }}
# Pull mongo:8 image and run it
docker pull mongo:8
docker run --rm -d \
--name "mongo" \
--network "host" \
--volume "${{ github.workspace }}/.github/docker_init/create_x509_user.js:/docker-entrypoint-initdb.d/0_create_x509_user.js" \
--volume "${{ github.workspace }}/docker_security:/mongo_tls" \
mongo:8 \
--tlsMode allowTLS --tlsCertificateKeyFile /mongo_tls/test-server1.pem --tlsCAFile /mongo_tls/test-ca.pem
# Health check
tmp_file=.dockerPs
while ! docker exec mongo mongosh --eval "db.runCommand('ping').ok" mongodb://root:root@localhost:27017/?authSource=admin --quiet ; do
docker ps -a > $tmp_file
grep -E "^.*mongo .* Exited .*$" $tmp_file && exited=yes && break
sleep 3
done
rm -f $tmp_file
# Write logs
docker logs mongo
if [ -n "$exited" ]; then
exit 1
fi
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build Docker image
uses: docker/build-push-action@v6
with:
context: .
target: ${{ matrix.docker_target }}
load: true
tags: entities-service
cache-from: type=gha
cache-to: type=gha,mode=max
provenance: false
build-args: |
CI=1
- name: Install test dependencies
run: |
python -m pip install -U pip
pip install -U setuptools wheel
pip install -U -e .[testing]
- name: Run Docker container
run: |
# Create logging directory and file
mkdir -p logs
touch -a logs/entities_service.log
# Run the service in the background
docker run -d \
--env ENTITIES_SERVICE_MONGO_URI \
--env ENTITIES_SERVICE_X509_CERTIFICATE_FILE \
--env ENTITIES_SERVICE_CA_FILE \
--name "entities-service" \
--network "host" \
--volume "${PWD}:/app" \
--user "$(id -u):$(id -g)" \
--init \
--entrypoint "gunicorn" \
entities-service \
--bind="0.0.0.0:${ENTITIES_SERVICE_PORT}" --workers=1 --worker-class="uvicorn.workers.UvicornWorker" --log-level="debug" --pythonpath=".github/utils" run_with_coverage:APP
# Install requirements for health check
sudo apt-get update && sudo apt-get install -y --no-install-recommends -fqqy curl
# Health check
tmp_file=.dockerPs
while ! curl -sf http://localhost:${ENTITIES_SERVICE_PORT}/openapi.json >> /dev/null ; do
docker ps -a > $tmp_file
grep -E "^.*entities-service .* Exited .*$" $tmp_file && exited=yes && break
sleep 1
done
rm -f $tmp_file
# Write logs
docker logs entities-service
if [ -n "$exited" ]; then
exit 1
fi
- name: Run tests
run: |
{
pytest -vv --live-backend --cov-report= --color=yes
} || {
echo "Failed! Here's the Docker logs for the service:" &&
docker logs entities-service &&
echo -e "\nAnd the service log:" &&
cat logs/entities_service.log &&
exit 1
}
- name: Collect coverage
run: |
# We can stop the service via a SIGINT signal.
# Since we map the current directory to /app in the container, the coverage file will be
# available in the current working directory.
docker kill --signal=SIGTERM entities-service
# Wait for the coverage file to be written and the service to stop
sleep 10
# Combine the coverage data from pytest and the service
{
mv .coverage .coverage.pytest &&
coverage combine --data-file=.coverage.final --rcfile=pyproject.toml .coverage.pytest .coverage.docker &&
coverage xml --data-file=.coverage.final --rcfile=pyproject.toml -o coverage.xml &&
coverage report --data-file=.coverage.final --rcfile=pyproject.toml --show-missing --skip-covered --skip-empty
} || {
echo "Failed to collect coverage data." &&
echo "Here's the Docker logs for the service:" &&
docker logs entities-service &&
echo -e "\nAnd the service log:" &&
cat logs/entities_service.log &&
exit 1
}
- name: Upload coverage
if: github.repository_owner == 'SINTEF'
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: coverage.xml
fail_ci_if_error: true
env_vars: OS,PYTHON
flags: docker
env:
OS: ubuntu-latest
PYTHON: '3.10'
- name: Clean up Docker
if: always()
run: |
docker stop entities-service ||:
docker rm entities-service ||:
docker stop mongo ||:
docker rm mongo ||:
pytest:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python_version: ["3.10", "3.11", "3.12"]
steps:
- name: Checkout ${{ github.repository }}
uses: actions/checkout@v4
- name: Setup Python ${{ matrix.python_version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python_version }}
- name: Install test dependencies
run: |
python -m pip install -U pip
pip install -U setuptools wheel flit
pip install -U -e .[testing]
- name: Run pytest
run: pytest -vv --cov-report=xml --color=yes
- name: Upload coverage
if: github.repository_owner == 'SINTEF'
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: true
env_vars: OS,PYTHON
flags: local
env:
OS: ubuntu-latest
PYTHON: ${{ matrix.python_version }}
pre-commit-hooks:
name: Run custom pre-commit hooks
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11", "3.12"]
os: ["ubuntu-latest", "windows-latest"]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install Python dependencies
run: |
python -m pip install -U pip
pip install -U setuptools wheel
pip install pre-commit
- name: Update pre-commit config file with Python version
run: sed -i "s/SET_PYTHON_VERSION/python${{ matrix.python-version }}/g" .github/utils/.pre-commit-config_testing.yaml
# Note, shell defaults to bash in ubuntu and pwsh in windows
- name: Run validate-entities
run: python .github/utils/run_pre-commit_hooks.py default
- name: Run invalid-entities
run: python .github/utils/run_pre-commit_hooks.py invalid-entities
- name: Run mixed-validity
run: python .github/utils/run_pre-commit_hooks.py mixed-validity
- name: Run quiet
run: python .github/utils/run_pre-commit_hooks.py quiet
- name: Run quiet-mixed-validity
run: python .github/utils/run_pre-commit_hooks.py quiet-mixed-validity
- name: Run fail-fast
run: python .github/utils/run_pre-commit_hooks.py fail-fast
- name: Run validate-entities (cmd)
if: runner.os == 'Windows'
run: python .github/utils/run_pre-commit_hooks.py default
shell: cmd
- name: Run invalid-entities (cmd)
if: runner.os == 'Windows'
run: python .github/utils/run_pre-commit_hooks.py invalid-entities
shell: cmd
- name: Run mixed-validity (cmd)
if: runner.os == 'Windows'
run: python .github/utils/run_pre-commit_hooks.py mixed-validity
shell: cmd
- name: Run quiet (cmd)
if: runner.os == 'Windows'
run: python .github/utils/run_pre-commit_hooks.py quiet
shell: cmd
- name: Run quiet-mixed-validity (cmd)
if: runner.os == 'Windows'
run: python .github/utils/run_pre-commit_hooks.py quiet-mixed-validity
shell: cmd
- name: Run fail-fast (cmd)
if: runner.os == 'Windows'
run: python .github/utils/run_pre-commit_hooks.py fail-fast
shell: cmd
build-cli-docs:
name: Build CLI docs
runs-on: ubuntu-latest
steps:
- name: Checkout ${{ github.repository }}
uses: actions/checkout@v4
- name: Setup Python 3.10
uses: actions/setup-python@v5
with:
python-version: "3.10"
- name: Install dependencies
run: |
python -m pip install -U pip
pip install -U setuptools wheel
pip install -U -e .[cli]
- name: Typer version
run: typer --version
- name: Build CLI docs
run: |
# Build the CLI documentation
# Run it twice, since the first run may create a doc only for the `config` sub-typer app.
typer entities_service.cli.main utils docs --output /tmp/CLI.md > /dev/null
typer entities_service.cli.main utils docs --output /tmp/CLI.md > /dev/null
diff --suppress-common-lines /tmp/CLI.md docs/CLI.md 2>&1 > /tmp/CLI_diff.md && ERROR_CODE=0 || ERROR_CODE=$?
ERROR_CODE=$?
if [ ${ERROR_CODE} -eq 2 ]; then
echo "diff encountered an error."
exit 2
elif [ ${ERROR_CODE} -eq 1 ]; then
echo "CLI documentation has changed. Please update the documentation."
echo "Diff:"
cat /tmp/CLI_diff.md
exit 1
elif [ ${ERROR_CODE} -eq 0 ]; then
echo "CLI documentation is up-to-date."
else
echo "Unknown error."
exit 3
fi