Skip to content

Revert "cicd: reorganize (#19)" (#22) #150

Revert "cicd: reorganize (#19)" (#22)

Revert "cicd: reorganize (#19)" (#22) #150

Workflow file for this run

name: Python CI
on:
push:
branches:
- "*"
paths:
- "src/**/*.py"
- "requirements.txt"
- ".dockerignore"
- "entrypoint.sh"
- "Dockerfile"
- "docker-compose*.yml"
- ".github/workflows/python.yml"
tags:
- 'v[0-9]+.[0-9]+.[0-9]+'
pull_request:
types: [opened, synchronize]
branches:
- "*"
paths:
- "src/**/*.py"
- "tests/**/*.py"
- "requirements.txt"
- ".dockerignore"
- "entrypoint.sh"
- "Dockerfile"
- "docker-compose*.yml"
- ".github/workflows/python.yml"
workflow_dispatch:
env:
MODULE_NAME: "pyramid"
SRC: "./src"
TEST_DIR: "./tests"
REGISTRY_IMAGE: ${{ vars.DOCKERHUB_USERNAME }}/${{ vars.DOCKERHUB_REPO_NAME }}
REGISTRY_IMAGE_PRIVATE: ${{ vars.DOCKER_REGISTRY_PRIVATE_URL }}/${{ github.actor }}/${{ github.event.repository.name }}
jobs:
compile:
name: "Compile Python 3.11"
runs-on: ubuntu-latest
outputs:
json: ${{ steps.version.outputs.json }}
version: ${{ steps.version.outputs.version }}
commit_id: ${{ steps.version.outputs.commit_id }}
branch: ${{ steps.version.outputs.branch }}
last_author: ${{ steps.version.outputs.last_author }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Python 3.11
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Cache dependencies
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
- ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
- ${{ runner.os }}-pip
- name: Install dependencies
run: |
pip install --upgrade pip
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: Test compilation
run: |
python -m compileall ${{ env.SRC }}
- name: Save version
run: |
FULL_JSON=$(python ${{ env.SRC }} --version)
echo "json=$(echo $FULL_JSON | jq -c)" >> $GITHUB_OUTPUT
echo "version=$(echo $FULL_JSON | jq -r '.version')" >> $GITHUB_OUTPUT
echo "commit_id=$(echo $FULL_JSON | jq -r '.git_info.commit_id')" >> $GITHUB_OUTPUT
echo "branch=$(echo $FULL_JSON | jq -r '.git_info.branch')" >> $GITHUB_OUTPUT
echo "last_author=$(echo $FULL_JSON | jq -r '.git_info.last_author')" >> $GITHUB_OUTPUT
echo "Output $GITHUB_OUTPUT"
cat $GITHUB_OUTPUT
id: version
unit_test:
name: "Unit tests"
needs: compile
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
clean: false
- name: Set up Python 3.11
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Cache dependencies
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-python_test-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
- ${{ runner.os }}-python_test-${{ hashFiles('**/requirements.txt') }}
- ${{ runner.os }}-python_test-${{ hashFiles('**/requirements.txt') }}
- ${{ runner.os }}-python
- name: Install dependencies
run: |
python -m pip install --upgrade pip
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: Install project for tests
run: |
pip install pytest-cov
pip install -e .
- name: Units tests
env:
DEEZER__ARL: ${{ secrets.CONFIG_DEEZER_ARL }}
SPOTIFY__CLIENT_ID: ${{ secrets.CONFIG_SPOTIFY_CLIENT_ID }}
SPOTIFY__CLIENT_SECRET: ${{ secrets.CONFIG_SPOTIFY_CLIENT_SECRET }}
run: |
pytest --cov=${{ env.MODULE_NAME }} ${{ env.TEST_DIR }}
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v4.5.0
with:
token: ${{ secrets.CODECOV_TOKEN }}
slug: tristiisch/PyRamid
unit_test_compatibility:
name: "Envs unit tests"
needs: unit_test
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version:
- "3.8"
- "3.9"
- "3.10"
- "3.12"
platform:
- linux/amd64
- linux/arm64/v8
continue-on-error: true
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Python 3.11
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Cache dependencies
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-python_test_${{ matrix.python-version }}_${{ matrix.platform }}-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
- ${{ runner.os }}-python_test_${{ matrix.python-version }}_${{ matrix.platform }}
- ${{ runner.os }}-python_test_${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: Install project for tests
run: |
pip install pytest-cov
pip install -e .
- name: Units tests
env:
DEEZER__ARL: ${{ secrets.CONFIG_DEEZER_ARL }}
SPOTIFY__CLIENT_ID: ${{ secrets.CONFIG_SPOTIFY_CLIENT_ID }}
SPOTIFY__CLIENT_SECRET: ${{ secrets.CONFIG_SPOTIFY_CLIENT_SECRET }}
run: |
pytest --cov=${{ env.MODULE_NAME }} ${{ env.TEST_DIR }}
version_compatibility:
name: "Envs compatibility"
needs: compile
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version:
- "3.8"
- "3.9"
- "3.10"
- "3.12"
platform:
- linux/amd64
- linux/arm64/v8
continue-on-error: true
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: Cache dependencies
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-python_${{ matrix.python-version }}_${{ matrix.platform }}-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
- ${{ runner.os }}-python_${{ matrix.python-version }}_${{ matrix.platform }}
- ${{ runner.os }}-python_${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: Test compilation
run: |
python -m compileall ${{ env.SRC }}
info:
name: "Build information"
needs: ["compile"]
runs-on: ubuntu-latest
outputs:
environment: ${{ steps.environment.outputs.environment }}
version_tag: ${{ steps.environment.outputs.tag }}
version_number: ${{ steps.environment.outputs.version }}
last_release_ref: ${{ steps.last_release.outputs.last_release_ref }}
commit_messages: ${{ steps.commit_messages.outputs.commit_messages }}
if: github.event_name == 'push'
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 100
- name: Get tags
run: git fetch --tags origin
- name: Get environnement names
id: environment
run: |
if [ ${{ github.event_name }} == 'create' && ${{ github.ref_type }} == 'tag' ]; then
echo "tag=latest" >> $GITHUB_OUTPUT
echo "environment=production" >> $GITHUB_OUTPUT
echo "version=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
elif [ ${{ github.ref }} = 'refs/heads/main' ]; then
echo "tag=pre-prod" >> $GITHUB_OUTPUT
echo "environment=pre-production" >> $GITHUB_OUTPUT
echo "version=${GITHUB_SHA::7}" >> $GITHUB_OUTPUT
else
echo "tag=dev" >> $GITHUB_OUTPUT
echo "environment=developement" >> $GITHUB_OUTPUT
echo "version=${GITHUB_SHA::7}" >> $GITHUB_OUTPUT
fi
echo "Output $GITHUB_OUTPUT"
cat $GITHUB_OUTPUT
- name: Get Github last release tag
id: last_release
run: |
RESPONSE=$(curl -s "https://api.github.com/repos/${{ github.repository }}/releases/latest")
if [[ $(echo "$RESPONSE" | jq -r .message) == "Not Found" ]]; then
LAST_RELEASE_REF=$(git rev-list --max-parents=0 HEAD)
else
LAST_RELEASE_REF=$(echo "$RESPONSE" | jq -r .tag_name)
fi
echo "last_release_ref=${LAST_RELEASE_REF}" >> $GITHUB_OUTPUT
echo "Output $GITHUB_OUTPUT"
cat $GITHUB_OUTPUT
- name: Get Github commit messages
id: commit_messages
run: |
COMMIT_MESSAGES=$(git log ${{ steps.last_release.outputs.last_release_ref }}..${{ github.sha }} --oneline --no-merges | sed 's/^/* /' | sed "s/\n/\\\\n/g")
EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
echo "commit_messages<<$EOF" >> $GITHUB_OUTPUT
echo "$COMMIT_MESSAGES" >> $GITHUB_OUTPUT
echo "$EOF" >> $GITHUB_OUTPUT
echo "Output $GITHUB_OUTPUT"
cat $GITHUB_OUTPUT
docker_image_build:
name: "Build Docker Images"
needs: ["compile", "info"]
runs-on: ubuntu-latest
if: github.event_name == 'push'
strategy:
fail-fast: false
matrix:
platform:
- linux/amd64
- linux/arm64
steps:
- name: Prepare
run: |
platform=${{ matrix.platform }}
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
- name: Checkout repository
uses: actions/checkout@v4
- name: Set git info
run: |
echo '${{ needs.compile.outputs.json }}' | jq -r '.git_info' > git_info.json
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY_IMAGE }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Docker image Build
id: build
uses: docker/build-push-action@v6
with:
context: .
target: executable
platforms: ${{ matrix.platform }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
provenance: mode=max
build-args: |
VERSION=${{ needs.info.outputs.version_number }}
GIT_COMMIT_ID=${{ needs.compile.outputs.commit_id }}
GIT_BRANCH=${{ needs.compile.outputs.branch }}
GIT_LAST_AUTHOR=${{ needs.compile.outputs.last_author }}
outputs: type=image,name=${{ env.REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true
- name: Export digest
run: |
mkdir -p /tmp/digests
digest="${{ steps.build.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}"
- name: Upload digest
uses: actions/upload-artifact@v4
with:
name: digests-${{ env.PLATFORM_PAIR }}
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1
docker_image_push:
name: "Push Docker Images"
runs-on: ubuntu-latest
needs: ["compile", "unit_test", "info", "docker_image_build"]
steps:
- name: Download digests
uses: actions/download-artifact@v4
with:
path: /tmp/digests
pattern: digests-*
merge-multiple: true
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Docker meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY_IMAGE }}
tags: |
type=raw,value=${{ needs.info.outputs.version_number }},enable=${{ needs.info.outputs.version_tag == 'latest' }}
type=raw,value=${{ needs.info.outputs.version_tag }}
- name: Create manifest list and push
working-directory: /tmp/digests
run: docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") $(printf '${{ env.REGISTRY_IMAGE }}@sha256:%s ' *)
docker_image_push_private:
name: "Push Privates Docker Images"
runs-on: ubuntu-latest
needs: ["compile", "unit_test", "info", "docker_image_build"]
steps:
- name: Download digests
uses: actions/download-artifact@v4
with:
path: /tmp/digests
pattern: digests-*
merge-multiple: true
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Github Container Registry
uses: docker/login-action@v3
with:
registry: ${{ vars.DOCKER_REGISTRY_PRIVATE_URL }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Docker meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY_IMAGE_PRIVATE }}
tags: |
type=ref,event=branch
type=raw,value=${{ needs.compile.outputs.version }}-${{ needs.compile.outputs.commit_id }}
- name: Create manifest list and push
working-directory: /tmp/digests
run: docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") $(printf '${{ env.REGISTRY_IMAGE }}@sha256:%s ' *)
docker_swarm_deploy:
name: "Deploy Docker Swarm"
needs: ["info", "docker_image_push"]
runs-on: ubuntu-latest
environment: ${{ needs.info.outputs.environment }}
if: (github.event_name == 'tag' && needs.info.outputs.version_tag == 'latest') || (github.event_name == 'push' && needs.info.outputs.version_tag != 'latest')
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Docker Swarm Update
uses: tristiisch/docker-stack-deployment@master
with:
deployment_mode: docker-swarm
remote_docker_host: ${{ secrets.MANAGER_HOST }}
remote_docker_username: ${{ secrets.MANAGER_TO_USER }}
ssh_private_key: ${{ secrets.MANAGER_TO_SSH_PRIVATE_KEY }}
ssh_public_key: ${{ secrets.MANAGER_SSH_PUBLIC_KEY }}
stack_file_path: ${{ vars.DOCKER_COMPOSE_FILENAME }}
stack_name: ${{ vars.DOCKER_STACK_NAME }}
secrets: ${{ vars.DOCKER_COMPOSE_SERVICE}} ${{ vars.DOCKER_STACK_NAME }} DISCORD__TOKEN ${{ secrets.CONFIG_DISCORD_TOKEN }} DEEZER__ARL ${{ secrets.CONFIG_DEEZER_ARL }} SPOTIFY__CLIENT_ID ${{ secrets.CONFIG_SPOTIFY_CLIENT_ID }} SPOTIFY__CLIENT_SECRET ${{ secrets.CONFIG_SPOTIFY_CLIENT_SECRET }}
release_publish:
name: "Publish release"
needs: ["compile", "info", "docker_image_push"]
runs-on: ubuntu-latest
if: github.event_name == 'tag' && needs.info.outputs.version_tag == 'latest'
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Update Release
run: |
gh release edit "${GITHUB_REF#refs/tags/}" \
--title "Release v${{ needs.compile.outputs.version }}" \
--notes "This has been deployed on the Discord bot `PyRamid#6882`.\nTo use the latest version the bot, please refer to the instructions outlined at https://github.com/tristiisch/PyRamid/#usage.\n\n## Changes\n${{ needs.info.outputs.commit_messages }}\n\n## Docker\nThis version is now accessible through various Docker images. Each image creation corresponds to a unique snapshot of this version, while updating the image corresponds to using an updated Docker image tag.\n\n### Images creation\n* ${{ env.REGISTRY_IMAGE_PRIVATE }}:${{ needs.compile.outputs.version }}-${{ needs.compile.outputs.commit_id }}\n\n### Images update\n* ${{ env.REGISTRY_IMAGE }}:${{ needs.info.outputs.version_tag }}\n* ${{ env.REGISTRY_IMAGE }}:${{ needs.compile.outputs.version }}"
# --draft false \
# --prerelease false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}