CI\CD #264
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: CI\CD | |
on: | |
push: | |
branches: | |
- main | |
tags: | |
- '*' | |
pull_request: | |
workflow_dispatch: | |
# Update docker hub retention policy | |
schedule: | |
- cron: "21 7 8 * *" | |
env: | |
DOCKER_USERNAME: "yakim" | |
PROJECT_NAME: "difflume" | |
DOCKER_COMPOSE_SERVICE_NAME: "app" | |
MAIN_PY_VERSION: "3.11" | |
PIP_NO_CACHE_DIR: "off" | |
POETRY_VIRTUALENVS_IN_PROJECT: "true" | |
POETRY_NO_INTERACTION: "1" | |
REGISTRY: "" | |
DOCKER_BUILDKIT: "1" | |
COMPOSE_DOCKER_CLI_BUILD: "1" | |
concurrency: | |
group: ${{ github.workflow }}-${{ github.ref }} | |
cancel-in-progress: true | |
permissions: read-all | |
jobs: | |
check-code: | |
runs-on: ubuntu-latest | |
strategy: | |
matrix: | |
python-version: ['3.10', '3.11', '3.12'] | |
steps: | |
- uses: actions/checkout@v4 | |
- run: echo "IMAGE_FULL_NAME=$(echo ${DOCKER_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=${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 | |
env: | |
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} | |
run: | | |
docker login "$REGISTRY" -u "$DOCKER_USERNAME" --password="${DOCKERHUB_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 | |
- uses: actions/upload-artifact@v3 | |
if: failure() | |
with: | |
name: snapshot-report-py${{ matrix.python-version }} | |
path: snapshot_report.html | |
- name: Upload coverage to Codecov | |
uses: codecov/codecov-action@v3 | |
with: | |
file: ./coverage.xml | |
# token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos | |
- uses: actions/upload-artifact@v3 | |
with: | |
name: built-package-py${{ matrix.python-version }} | |
path: dist/ | |
release-package: | |
runs-on: ubuntu-latest | |
needs: [ check-code ] | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: actions/download-artifact@v3 | |
with: | |
name: built-package-py${{ env.MAIN_PY_VERSION }} | |
path: dist/ | |
- run: echo "IMAGE_FULL_NAME=$(echo ${DOCKER_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=${IMAGE_FULL_NAME}:dev-${MAIN_PY_VERSION}-${DEV_VERSION}" >> $GITHUB_ENV | |
- name: Prepare Docker | |
env: | |
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} | |
run: | | |
docker login "$REGISTRY" -u "$DOCKER_USERNAME" --password="${DOCKERHUB_TOKEN}" | |
docker buildx create --use --driver=docker-container | |
docker --version && docker compose --version | |
- name: Pull and spin dev container | |
run: | | |
docker pull ${DEV_IMAGE} | |
docker tag ${DEV_IMAGE} ${PROJECT_NAME}:dev | |
docker compose run --rm -d devtools sleep infinity | |
- run: echo "PROJECT_VERSION=$(docker compose exec devtools poetry version --short)" >> $GITHUB_ENV | |
- name: Login to PyPI | |
env: | |
PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} | |
run: | | |
echo "Login" | |
docker compose exec devtools 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 compose exec devtools poetry publish --dry-run | |
- name: Build and publish | |
if: startsWith(github.ref, 'refs/tags/') | |
run: docker compose exec devtools poetry publish | |
release-image: | |
runs-on: ubuntu-latest | |
needs: [ check-code ] | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: actions/download-artifact@v3 | |
with: | |
name: built-package-py${{ env.MAIN_PY_VERSION }} | |
path: dist/ | |
- run: echo "IMAGE_FULL_NAME=$(echo ${DOCKER_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=${IMAGE_FULL_NAME}:dev-${MAIN_PY_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 | |
env: | |
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} | |
run: | | |
docker login "$REGISTRY" -u "$DOCKER_USERNAME" --password="${DOCKERHUB_TOKEN}" | |
docker buildx create --use --driver=docker-container | |
docker --version && docker compose --version | |
- name: Pull and spin dev container | |
run: | | |
docker pull ${DEV_IMAGE} | |
docker tag ${DEV_IMAGE} ${PROJECT_NAME}:dev | |
docker compose run --rm -d devtools sleep infinity | |
- run: echo "PROJECT_VERSION=$(docker compose exec devtools poetry version --short)" >> $GITHUB_ENV | |
# https://docs.docker.com/build/cache/backends/gha/ | |
- name: Expose GitHub Runtime | |
uses: crazy-max/ghaction-github-runtime@v3 | |
- name: Create tag string | |
run: echo "TAG_ARGS=-t ${IMAGE_FULL_NAME}:latest" >> $GITHUB_ENV | |
- name: Add version from git tag | |
if: startsWith(github.ref, 'refs/tags/') | |
run: | | |
echo "TAG_ARGS=${TAGS} -t ${IMAGE_FULL_NAME}:${VERSION} -t ${IMAGE_FULL_NAME}:${SHORT_VERSION}" >> $GITHUB_ENV | |
- name: Set push flag | |
if: startsWith(github.ref, 'refs/tags/') || github.ref == 'refs/heads/main' | |
run: echo "PUSH_FLAG=--push" >> $GITHUB_ENV | |
- name: Build image | |
run: > | |
docker buildx build ${PUSH_FLAG:-} | |
--build-arg WHEEL=${PROJECT_NAME}-${PROJECT_VERSION}-py3-none-any.whl | |
--cache-to type=gha,mode=max --cache-from type=gha | |
--platform=linux/arm64,linux/amd64 | |
${TAG_ARGS} . |