Skip to content

CI\CD

CI\CD #461

Workflow file for this run

name: CI\CD
on:
push:
branches:
- main
tags:
- '*'
pull_request:
workflow_dispatch:
# Update docker hub retention policy
schedule:
- cron: "21 7 8 * *"
env:
PIP_NO_CACHE_DIR: "off"
POETRY_VIRTUALENVS_IN_PROJECT: "true"
POETRY_NO_INTERACTION: "1"
DOCKER_BUILDKIT: "1"
COMPOSE_DOCKER_CLI_BUILD: "1"
PROJECT_NAME: "picodi"
REGISTRY: "docker.io"
REGISTRY_USERNAME: "yakimka"
REGISTRY_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
CACHE_REGISTRY: "ghcr.io"
CACHE_REGISTRY_USERNAME: "yakimka"
CACHE_REGISTRY_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DOCKER_COMPOSE_SERVICE_NAME: "devtools"
MAIN_PY_VERSION: "3.11"
POETRY_DOCKER_IMAGE: "yakimka/poetry:1.8.2-py3.11-slim"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions: read-all
jobs:
check-code:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
strategy:
matrix:
python-version: ['3.10', '3.11', '3.12', '3.13']
steps:
- uses: actions/checkout@v4
- run: echo "DEV_IMAGE_FULL_NAME=$(echo ${CACHE_REGISTRY}/${CACHE_REGISTRY_USERNAME}/${PROJECT_NAME})" >> $GITHUB_ENV
- run: echo "DEV_VERSION=`(cat Dockerfile-dev; cat .github/workflows/workflow-ci.yml)|sha1sum |cut -c 1-8`" >> $GITHUB_ENV
- run: echo "DEV_IMAGE=${DEV_IMAGE_FULL_NAME}:dev-${{ matrix.python-version }}-${DEV_VERSION}" >> $GITHUB_ENV
- run: echo "VERSION=$(echo ${GITHUB_REF:10})" >> $GITHUB_ENV
- run: echo "SHORT_VERSION=$(echo ${VERSION%.*})" >> $GITHUB_ENV
- name: Prepare Docker
run: |
docker login "$CACHE_REGISTRY" -u "$CACHE_REGISTRY_USERNAME" --password="${CACHE_REGISTRY_TOKEN}"
docker buildx create --use --driver=docker-container
docker --version && docker compose --version
- name: Load cached venv and cache
id: cached-venv-and-cache
uses: actions/cache@v4
with:
path: |
.venv
.cache
key: py${{ matrix.python-version }}-${{ hashFiles('./poetry.lock') }}
- name: Build docker dev image
run: |
docker pull ${DEV_IMAGE} || (
PYTHON_VERSION=${{ matrix.python-version }} docker compose build ${DOCKER_COMPOSE_SERVICE_NAME} ;
docker tag ${PROJECT_NAME}:dev ${DEV_IMAGE} ;
docker push ${DEV_IMAGE}
)
docker tag ${DEV_IMAGE} ${PROJECT_NAME}:dev
- name: Run checks
run: docker compose run -e CI=1 --user=$(id -u) --rm devtools ./ci.sh
- name: Upload coverage reports to Codecov
uses: codecov/[email protected]
with:
file: ./coverage.xml
token: ${{ secrets.CODECOV_TOKEN }}
slug: yakimka/picodi
- uses: actions/upload-artifact@v4
with:
name: built-package-py${{ matrix.python-version }}
path: dist/
- uses: actions/upload-artifact@v4
with:
name: benchmark-results${{ matrix.python-version }}
include-hidden-files: true
path: .benchmarks/*/*.json
pypy-test:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
strategy:
matrix:
pypy-version: ['3.10']
steps:
- uses: actions/checkout@v4
- name: Prepare Docker
run: |
docker login "$CACHE_REGISTRY" -u "$CACHE_REGISTRY_USERNAME" --password="${CACHE_REGISTRY_TOKEN}"
docker buildx create --use --driver=docker-container
docker --version && docker compose --version
- name: Load cached venv
id: cached-venv
uses: actions/cache@v4
with:
path: |
.venv
key: pypy${{ matrix.pypy-version }}-${{ hashFiles('./poetry.lock') }}
- name: Pull docker image
run: |
docker pull pypy:${{ matrix.pypy-version }}-slim
docker tag pypy:${{ matrix.pypy-version }}-slim pypy-image
- name: Run checks
run: >
docker run -e VIRTUAL_ENV=/opt/code/.venv --rm -v $(pwd):/opt/code -w /opt/code
pypy-image bash -c "
if [ ! -d .venv ]; then
python -m venv .venv;
fi
&& .venv/bin/pip install poetry
&& .venv/bin/poetry install
&& .venv/bin/pip install --no-deps -e .
&& .venv/bin/pytest
"
free-threading-test:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
strategy:
matrix:
image-name: ['quay.io/pypa/manylinux_2_28_x86_64']
steps:
- uses: actions/checkout@v4
- name: Prepare Docker
run: |
docker login "$CACHE_REGISTRY" -u "$CACHE_REGISTRY_USERNAME" --password="${CACHE_REGISTRY_TOKEN}"
docker buildx create --use --driver=docker-container
docker --version && docker compose --version
- name: Load cached venv
id: cached-venv
uses: actions/cache@v4
with:
path: |
.venv
key: free-threading${{ matrix.image-name }}-${{ hashFiles('./poetry.lock') }}
- name: Pull docker image
run: |
docker pull ${{ matrix.image-name }}
docker tag ${{ matrix.image-name }} free-threading-image
- name: Run checks
run: >
docker run -e VIRTUAL_ENV=/opt/code/.venv --rm -v $(pwd):/opt/code -w /opt/code
free-threading-image bash -c "
if [ ! -d .venv ]; then
python3.13t -m venv .venv;
fi
&& .venv/bin/pip install pytest pytest-asyncio pytest-cov pytest-randomly pytest-race pytest-repeat pytest-benchmark
&& .venv/bin/pip install --no-deps -e .
&& .venv/bin/python -VV
&& .venv/bin/pytest --ignore=tests/test_integrations
"
release-package:
runs-on: ubuntu-latest
needs: [check-code, pypy-test, free-threading-test]
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
name: built-package-py${{ env.MAIN_PY_VERSION }}
path: dist/
- name: Prepare Docker
run: |
docker login "$REGISTRY" -u "$REGISTRY_USERNAME" --password="${REGISTRY_TOKEN}" || true
- name: Pull and spin dev container
run: |
docker run -v $(pwd):/code -w /code --rm -d --name=poetry ${POETRY_DOCKER_IMAGE} sleep infinity
- run: echo "PROJECT_VERSION=$(docker exec poetry poetry version --short)" >> $GITHUB_ENV
- name: Login to PyPI
env:
PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
run: |
echo "Login"
docker exec poetry poetry config pypi-token.pypi $PYPI_TOKEN || true
- name: Check if tag version matches project version
if: startsWith(github.ref, 'refs/tags/')
run: |
TAG=${GITHUB_REF:10}
echo $TAG
echo $PROJECT_VERSION
if [[ "$TAG" != "$PROJECT_VERSION" ]]; then exit 1; fi
- name: Build and publish (dry-run)
if: github.actor != 'dependabot[bot]'
run: docker exec poetry poetry publish --dry-run
- name: Build and publish
if: startsWith(github.ref, 'refs/tags/')
run: docker exec poetry poetry publish