Skip to content

fix: CustomException.msg missing #250

fix: CustomException.msg missing

fix: CustomException.msg missing #250

Workflow file for this run

name: Python CI
on:
push:
branches:
- "*"
tags:
- '[0-9]+.[0-9]+.[0-9]+'
paths:
- "src/**/*.py"
- "requirements.txt"
- ".dockerignore"
- "./.docker/Dockerfile"
- "docker-compose*.yml"
- ".github/workflows/python.yml"
pull_request:
types: [opened, synchronize]
branches:
- "*"
paths:
- "src/**/*.py"
- "tests/**/*.py"
- "requirements.txt"
- ".dockerignore"
- "./.docker/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:
info:
name: "Informations"
runs-on: ubuntu-latest
outputs:
project_version: ${{ steps.environment.outputs.project_version }}
environment: ${{ steps.environment.outputs.git_environment }}
docker_tag: ${{ steps.environment.outputs.docker_tag }}
commit_id: ${{ steps.environment.outputs.commit_id }}
last_release_ref: ${{ steps.last_release.result.last_release_ref }}
changelog: ${{ steps.changelog.outputs.changelog }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Define build variables
id: environment
uses: actions/github-script@v7
with:
script: |
const refType = '${{ github.ref_type }}';
const ref = context.ref;
const sha = context.sha;
const shortSha = sha.slice(0, 7);
let dockerTag;
let gitEnvironment;
let projectVersion;
if (refType === 'tag') {
dockerTag = 'latest';
gitEnvironment = 'production';
projectVersion = '${{ github.ref_name }}';
} else if (ref === 'refs/heads/main') {
dockerTag = 'pre-prod';
gitEnvironment = 'pre-production';
projectVersion = `${shortSha}`;
} else {
dockerTag = 'staging';
gitEnvironment = 'staging';
projectVersion = `${shortSha}`;
}
const reset = "\x1b[0m";
const textColor = "\x1b[36m"; // Cyan for static text
const varColor = "\x1b[35m"; // Magenta for variables
console.log(`${textColor}${projectVersion} in environment ${varColor}${gitEnvironment}${textColor} with tag ${varColor}${dockerTag}${reset}.`);
core.setOutput("docker_tag", dockerTag);
core.setOutput("git_environment", gitEnvironment);
core.setOutput("commit_id", shortSha);
core.setOutput("project_version", projectVersion);
- name: Get Github last release name
id: last_release
uses: actions/github-script@v7
with:
script: |
const latestRelease = await github.rest.repos.getLatestRelease({
owner: context.repo.owner,
repo: context.repo.repo,
});
const reset = "\x1b[0m";
const textColor = "\x1b[36m"; // Cyan for static text
const varColor = "\x1b[35m"; // Magenta for variables
console.log(`${textColor}The last release is ${varColor}${latestRelease.data.tag_name}${textColor}.${reset}`);
core.setOutput("last_release_ref", latestRelease.data.tag_name);
- name: Generate Changelog
id: changelog
uses: actions/github-script@v7
with:
script: |
const lastRelease = '${{ steps.last_release.outputs.last_release_ref }}';
const currentSha = context.sha;
const pulls = await github.rest.pulls.list({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'closed',
per_page: 100,
});
const mergedPulls = pulls.data.filter(pr =>
pr.merged_at &&
pr.merge_commit_sha >= lastRelease &&
pr.merge_commit_sha <= currentSha
);
let changes = "## What's Changed\n";
let contributorsNames = new Set();
mergedPulls.forEach(pr => {
changes += `* ${pr.title} ${pr.html_url}\n`;
contributorsNames.add(pr.user.login);
});
let contributors = `### Contributors
Thanks to @${Array.from(contributorsNames).join(', @')}.\n`;
const fullChangelog = `**Full Changelog**: https://github.com/${context.repo.owner}/${context.repo.repo}/compare/${lastRelease}...${currentSha}`;
const changelog = changes + '\n' + (contributorsNames.size ? contributors + '\n' : '') + fullChangelog;
const reset = "\x1b[0m";
const textColor = "\x1b[36m"; // Cyan for static text
const varColor = "\x1b[35m"; // Magenta for variables
console.log(`${textColor}Changelog:${reset}\n${changelog}`);
core.setOutput("changelog", changelog);
- name: Output Changelog
run: echo "${{ steps.changelog.outputs.changelog }}"
docker_image_build:
name: "Build"
needs: ["info"]
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
platform:
- linux/amd64
- linux/arm64
steps:
- name: Prepare
run: |
platform=${{ matrix.platform }}
echo "platform_pair=${platform//\//-}" >> $GITHUB_OUTPUT
id: prepare
- name: Checkout repository
uses: actions/checkout@v4
- 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:
file: ./.docker/Dockerfile
target: executable
context: .
platforms: ${{ matrix.platform }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
provenance: mode=max
build-args: |
PROJECT_VERSION=${{ needs.info.outputs.project_version }}
outputs: |
type=image,name=${{ env.REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true
- name: Export image digest
run: |
echo "Digest: ${{ steps.build.outputs.digest }}"
mkdir -p /tmp/digests
digest="${{ steps.build.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}"
- name: Upload image digest as artifact
uses: actions/upload-artifact@v4
with:
name: digests-${{ steps.prepare.outputs.platform_pair }}
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1
- name: Export image to tar
uses: docker/build-push-action@v6
with:
file: ./.docker/Dockerfile
target: executable
context: .
platforms: ${{ matrix.platform }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
provenance: mode=max
build-args: |
PROJECT_VERSION=${{ needs.info.outputs.project_version }}
outputs: |
type=oci,dest=./pyramid-oci.tar
- name: Upload image as artifact
uses: actions/upload-artifact@v4
with:
name: image-${{ steps.prepare.outputs.platform_pair }}
path: ./pyramid-oci.tar
if-no-files-found: error
retention-days: 1
security_scanner:
name: "Security scan"
needs: ["docker_image_build"]
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
platform:
- linux/amd64
- linux/arm64
steps:
- name: Prepare
run: |
platform=${{ matrix.platform }}
echo "platform_pair=${platform//\//-}" >> $GITHUB_OUTPUT
id: prepare
- name: Download tests image
uses: actions/download-artifact@v4
with:
name: image-${{ steps.prepare.outputs.platform_pair }}
- name: Untar OCI Image
run: |
mkdir -p ./pyramid-oci
tar -xvf ./pyramid-oci.tar -C ./pyramid-oci
- name: Run Trivy vulnerability scanner
uses: aquasecurity/[email protected]
with:
input: './pyramid-oci'
format: 'github'
output: 'dependency-results.sbom.json'
github-pat: '${{ secrets.GITHUB_TOKEN }}'
env:
TRIVY_DB_REPOSITORY: 'public.ecr.aws/aquasecurity/trivy-db:2'
TRIVY_JAVA_DB_REPOSITORY: 'public.ecr.aws/aquasecurity/trivy-java-db:1'
- name: Print Trivy result in humain format
uses: aquasecurity/[email protected]
with:
input: './pyramid-oci'
format: 'table'
exit-code: '1'
# ignore-unfixed: true
severity: 'UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL'
env:
TRIVY_DB_REPOSITORY: 'public.ecr.aws/aquasecurity/trivy-db:2'
TRIVY_JAVA_DB_REPOSITORY: 'public.ecr.aws/aquasecurity/trivy-java-db:1'
- name: Upload trivy report as a Github artifact
uses: actions/upload-artifact@v4
with:
name: trivy-sbom-${{ steps.prepare.outputs.platform_pair }}-report
path: '${{ github.workspace }}/dependency-results.sbom.json'
retention-days: 90
docker_image_test_build:
name: "Build Tests"
needs: ["info", "docker_image_build"]
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Docker image Build
id: build
uses: docker/build-push-action@v6
with:
file: ./.docker/Dockerfile
target: tests
context: .
tags: pyramid:tests
cache-from: type=gha
cache-to: type=gha,mode=max
build-args: |
PROJECT_VERSION=${{ needs.info.outputs.project_version }}-tests
push: false
outputs: type=docker
- name: Export tests image
run: docker save pyramid:tests -o "./pyramid-tests.tar"
- name: Upload tests image as artifact
uses: actions/upload-artifact@v4
with:
name: image-tests
path: ./pyramid-tests.tar
if-no-files-found: error
retention-days: 1
tests_in_docker:
name: "Tests"
needs: ["docker_image_test_build"]
runs-on: ubuntu-latest
steps:
- name: Download tests image
uses: actions/download-artifact@v4
with:
name: image-tests
- name: Load Docker image
run: docker load -i "./pyramid-tests.tar"
- name: Run unit tests
run: |
mkdir -p ./coverage && chmod 777 ./coverage
docker run --rm -v ./coverage:/app/coverage -e DEEZER__ARL=${{ secrets.CONFIG_DEEZER_ARL }} -e SPOTIFY__CLIENT_ID=${{ secrets.CONFIG_SPOTIFY_CLIENT_ID }} -e SPOTIFY__CLIENT_SECRET=${{ secrets.CONFIG_SPOTIFY_CLIENT_SECRET }} pyramid:tests
- name: Upload coverage reports to Codecov
uses: codecov/[email protected]
with:
token: ${{ secrets.CODECOV_TOKEN }}
slug: tristiisch/PyRamid
files: ./coverage/coverage1.xml
fail_ci_if_error: true
docker_image_push:
name: "Push"
runs-on: ubuntu-latest
needs: ["info", "docker_image_build", "tests_in_docker"]
steps:
- name: Download digests
uses: actions/download-artifact@v4
with:
path: /tmp/digests
pattern: digests-*
merge-multiple: true
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Docker meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY_IMAGE }}
tags: |
type=raw,value=${{ needs.info.outputs.docker_tag }}
type=raw,value=${{ needs.info.outputs.project_version }}
- 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"
runs-on: ubuntu-latest
needs: ["info", "docker_image_build", "tests_in_docker"]
steps:
- name: Download digests
uses: actions/download-artifact@v4
with:
path: /tmp/digests
pattern: digests-*
merge-multiple: true
- 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: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Docker meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY_IMAGE_PRIVATE }}
tags: |
type=raw,value=${{ needs.info.outputs.docker_tag }}
type=raw,value=${{ needs.info.outputs.project_version }}
- 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"
needs: ["info", "docker_image_push"]
runs-on: ubuntu-latest
environment: ${{ needs.info.outputs.environment }}
if: (github.ref_type == 'tag' && needs.info.outputs.docker_tag == 'latest') || (github.ref_type == 'branch' && needs.info.outputs.docker_tag != 'latest')
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Deploy ${{ needs.info.outputs.project_version }} to ${{ needs.info.outputs.environment }}
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: "Release"
needs: ["info", "docker_image_push"]
runs-on: ubuntu-latest
if: github.ref_type == 'tag' && github.event_name == 'push' && needs.info.outputs.docker_tag == 'latest'
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Update Release v${{ needs.info.outputs.project_version }}
run: |
set -eu
EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
cat <<$EOF > ./changelog.txt
The latest version of the Discord bot PyRamid#6882 has been successfully deployed.
To start using this updated version, please follow the instructions provided at [PyRamid Usage Guide](https://github.com/tristiisch/PyRamid/#usage).
${{ needs.info.outputs.changelog }}
## Docker
This 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.
### Images availables
* \`${{ env.REGISTRY_IMAGE }}:${{ needs.info.outputs.docker_tag }}\`
* \`${{ env.REGISTRY_IMAGE }}:${{ needs.info.outputs.project_version }}\`
$EOF
gh release edit "${{ github.ref_name }}" \
--title "Release v${{ needs.info.outputs.project_version }}" \
--draft=false \
--prerelease=false \
--notes-file "./changelog.txt"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}