Merge remote-tracking branch 'origin/dev' into dev-deploy #54
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: DEV - KodemyBackend deploy | |
on: | |
push: | |
branches: [ "dev-deploy" ] | |
paths-ignore: | |
- '.gitignore' | |
- 'docker-compose.deploy.yml' | |
- 'docker-compose.yml' | |
- 'README.md' | |
- 'config' | |
env: | |
WORKING_DIRECTORY: ${{ vars.WORKING_DIRECTORY }} | |
NETWORK_NAME: ${{ vars.NETWORK_NAME }} | |
DATASOURCE_CONTAINER: ${{ vars.DATASOURCE_CONTAINER }} | |
DATASOURCE_DB: ${{ vars.DATASOURCE_DB }} | |
RABBITMQ_HOST: ${{ vars.RABBITMQ_HOST }} | |
RABBITMQ_PORT: ${{ vars.RABBITMQ_PORT }} | |
ELASTICSEARCH_HOSTS: ${{ vars.RABBITMQ_PASSWORD }} | |
EUREKA_URL: ${{ vars.EUREKA_URL }} | |
FRONTEND_PUBLIC_HOST: ${{ vars.FRONTEND_PUBLIC_HOST }} | |
CORS_ALLOWED_ORIGINS: ${{ vars.CORS_ALLOWED_ORIGINS }} | |
GATEWAY_PUBLIC_HOST: ${{ vars.GATEWAY_PUBLIC_HOST }} | |
OAUTH_GITHUB_ID: ${{ vars.OAUTH_GITHUB_ID }} | |
REDIS_HOST: ${{ vars.REDIS_HOST }} | |
REDIS_PORT: ${{ vars.REDIS_PORT }} | |
DATASOURCE_USERNAME: ${{ secrets.DATASOURCE_USERNAME }} | |
DATASOURCE_PASSWORD: ${{ secrets.DATASOURCE_PASSWORD }} | |
RABBITMQ_USERNAME: ${{ secrets.RABBITMQ_USERNAME }} | |
RABBITMQ_PASSWORD: ${{ secrets.RABBITMQ_PASSWORD }} | |
ELASTICSEARCH_USERNAME: ${{ secrets.ELASTICSEARCH_USERNAME }} | |
ELASTICSEARCH_PASSWORD: ${{ secrets.ELASTICSEARCH_PASSWORD }} | |
OAUTH_GITHUB_KEY: ${{ secrets.OAUTH_GITHUB_KEY }} | |
JWT_KEY: ${{ secrets.JWT_KEY }} | |
jobs: | |
prepare: | |
name: Prepare | |
runs-on: self-hosted | |
environment: dev | |
steps: | |
- name: Check environments | |
run: | | |
REQUIRED_VARS=\ | |
( | |
"WORKING_DIRECTORY" | |
"NETWORK_NAME" | |
"DATASOURCE_CONTAINER" | |
"DATASOURCE_USERNAME" | |
"DATASOURCE_PASSWORD" | |
"DATASOURCE_DB" | |
"RABBITMQ_HOST" | |
"RABBITMQ_PORT" | |
"RABBITMQ_USERNAME" | |
"RABBITMQ_PASSWORD" | |
"RABBITMQ_PASSWORD" | |
"ELASTICSEARCH_USERNAME" | |
"ELASTICSEARCH_PASSWORD" | |
"EUREKA_URL" | |
"FRONTEND_PUBLIC_HOST" | |
"CORS_ALLOWED_ORIGINS" | |
"GATEWAY_PUBLIC_HOST" | |
"OAUTH_GITHUB_ID" | |
"OAUTH_GITHUB_KEY" | |
"JWT_KEY" | |
"REDIS_HOST" | |
"REDIS_PORT" | |
) | |
EXIT=0 | |
for VAR in "${REQUIRED_VARS[@]}"; do | |
[ -z "${!VAR}" ] && echo "Environment variable $VAR is missing." && EXIT=1 | |
done | |
exit $EXIT | |
update-branch: | |
name: Update branch | |
needs: [ prepare ] | |
runs-on: self-hosted | |
environment: dev | |
steps: | |
- name: Update ${{ github.ref_name }} | |
uses: appleboy/ssh-action@master | |
env: | |
BRANCH: ${{ github.ref_name }} | |
with: | |
host: ${{ secrets.REMOTE_HOST }} | |
username: ${{ secrets.REMOTE_USER }} | |
port: ${{ secrets.REMOTE_PORT }} | |
key: ${{ secrets.SSH_PRIVATE_KEY }} | |
envs: WORKING_DIRECTORY,BRANCH | |
script: | | |
cd $WORKING_DIRECTORY | |
git checkout $BRANCH || exit 1 | |
git pull origin $BRANCH || exit 1 | |
validate: | |
name: Validate services | |
runs-on: self-hosted | |
needs: [ update-branch ] | |
environment: dev | |
steps: | |
- name: Validate services | |
uses: appleboy/ssh-action@master | |
with: | |
host: ${{ secrets.REMOTE_HOST }} | |
username: ${{ secrets.REMOTE_USER }} | |
port: ${{ secrets.REMOTE_PORT }} | |
key: ${{ secrets.SSH_PRIVATE_KEY }} | |
envs: WORKING_DIRECTORY,NETWORK_NAME,DATASOURCE_CONTAINER,DATASOURCE_USERNAME,DATASOURCE_DB | |
script: | | |
echo "Validate network" | |
docker network inspect $NETWORK_NAME > /dev/null 2>&1 \ | |
|| { echo "Network $NETWORK_NAME is not available."; exit 1; } | |
echo "Validate database - container" | |
docker exec -t $DATASOURCE_CONTAINER pg_isready \ | |
|| { echo "PostgreSQL is not running."; exit 1; } | |
echo "Validate database - database" | |
docker exec -t $DATASOURCE_CONTAINER psql -lqt -U $DATASOURCE_USERNAME | grep -q $DATASOURCE_DB \ | |
|| { echo "Database $DATASOURCE_DB does not exist."; exit 1; } | |
echo "Validate database - schemas" | |
DATASOURCE_SCHEMAS=("kodemy-auth" "kodemy-backend" "kodemy-notification") | |
for SCHEMA in "${DATASOURCE_SCHEMAS[@]}" | |
do | |
docker exec -t $DATASOURCE_CONTAINER psql \ | |
-U $DATASOURCE_USERNAME \ | |
-d $DATASOURCE_DB \ | |
-tAc "SELECT 1 FROM information_schema.schemata WHERE schema_name = '$SCHEMA'" \ | |
| grep -q 1 || { echo "Schema $SCHEMA does not exist."; exit 1; } | |
done | |
build-and-deploy: | |
name: Build, Test, Deploy | |
runs-on: self-hosted | |
needs: [ validate ] | |
environment: dev | |
steps: | |
- name: Build, Test, Deploy | |
uses: appleboy/ssh-action@master | |
with: | |
host: ${{ secrets.REMOTE_HOST }} | |
username: ${{ secrets.REMOTE_USER }} | |
port: ${{ secrets.REMOTE_PORT }} | |
key: ${{ secrets.SSH_PRIVATE_KEY }} | |
envs: | | |
WORKING_DIRECTORY, | |
DATASOURCE_CONTAINER,DATASOURCE_USERNAME,DATASOURCE_PASSWORD,DATASOURCE_DB, | |
RABBITMQ_HOST,RABBITMQ_PORT,RABBITMQ_USERNAME,RABBITMQ_PASSWORD, | |
ELASTICSEARCH_HOSTS,ELASTICSEARCH_USERNAME,ELASTICSEARCH_PASSWORD, | |
EUREKA_URL, | |
FRONTEND_PUBLIC_HOST,CORS_ALLOWED_ORIGINS, | |
GATEWAY_PUBLIC_HOST, | |
OAUTH_GITHUB_ID,OAUTH_GITHUB_KEY, | |
JWT_KEY, | |
REDIS_HOST,REDIS_PORT | |
script: | | |
cd $WORKING_DIRECTORY/commons | |
./gradlew clean assemble | |
cd $WORKING_DIRECTORY/kodemy-api-gateway | |
./gradlew clean assemble -x test | |
cd $WORKING_DIRECTORY/kodemy-auth | |
./gradlew clean assemble | |
cd $WORKING_DIRECTORY/kodemy-backend | |
./gradlew clean assemble -x test | |
cd $WORKING_DIRECTORY/kodemy-notification | |
./gradlew clean assemble -x test | |
cd $WORKING_DIRECTORY/kodemy-search | |
./gradlew clean assemble -x test | |
cd $WORKING_DIRECTORY/kodemy-service-registry | |
./gradlew clean assemble -x test | |
export DATASOURCE_URL=jdbc:postgresql://$DATASOURCE_CONTAINER/$DATASOURCE_DB | |
cd $WORKING_DIRECTORY | |
docker compose -f docker-compose.app.yml -f docker-compose.app.expose.yml up --build -d | |
export BACKEND_CONTAINERS=$(docker-compose -f docker-compose.app.yml ps -q) | |
- name: Validate running | |
uses: appleboy/ssh-action@master | |
with: | |
host: ${{ secrets.REMOTE_HOST }} | |
username: ${{ secrets.REMOTE_USER }} | |
port: ${{ secrets.REMOTE_PORT }} | |
key: ${{ secrets.SSH_PRIVATE_KEY }} | |
envs: | | |
WORKING_DIRECTORY, | |
DATASOURCE_CONTAINER,DATASOURCE_USERNAME,DATASOURCE_PASSWORD,DATASOURCE_DB, | |
RABBITMQ_HOST,RABBITMQ_PORT,RABBITMQ_USERNAME,RABBITMQ_PASSWORD, | |
ELASTICSEARCH_HOSTS,ELASTICSEARCH_USERNAME,ELASTICSEARCH_PASSWORD, | |
EUREKA_URL, | |
FRONTEND_PUBLIC_HOST,CORS_ALLOWED_ORIGINS, | |
GATEWAY_PUBLIC_HOST, | |
OAUTH_GITHUB_ID,OAUTH_GITHUB_KEY, | |
JWT_KEY, | |
REDIS_HOST,REDIS_PORT | |
script: | | |
cd $WORKING_DIRECTORY | |
echo "Waiting 1 minute..." | |
sleep 1m | |
for container in $BACKEND_CONTAINERS; do | |
status=$(docker inspect --format='{{.State.Status}}' $container) | |
if [ "$status" != "running" ]; then | |
echo "$container not running" | |
docker compose -f docker-compose.app.yml -f docker-compose.app.expose.yml -f docker-compose.backup.yml up -d | |
exit 1 | |
fi | |
done | |
echo "All containers validated successfully." | |
docker commit kodemybackend-kodemy-service-registry-1 kodemy-service-registry:backup | |
docker commit kodemybackend-kodemy-api-gateway-1 kodemy-api-gateway:backup | |
docker commit kodemybackend-kodemy-auth-1 kodemy-auth:backup | |
docker commit kodemybackend-kodemy-backend-1 kodemy-backend:backup | |
docker commit kodemybackend-kodemy-notification-1 kodemy-notification:backup | |
docker commit kodemybackend-kodemy-search-1 kodemy-search:backup | |
- name: Cleanup | |
uses: appleboy/ssh-action@master | |
with: | |
host: ${{ secrets.REMOTE_HOST }} | |
username: ${{ secrets.REMOTE_USER }} | |
port: ${{ secrets.REMOTE_PORT }} | |
key: ${{ secrets.SSH_PRIVATE_KEY }} | |
script: | | |
docker system prune -f | |
create-tag: | |
name: Create tag | |
runs-on: self-hosted | |
environment: dev | |
needs: [ build-and-deploy ] | |
steps: | |
- name: Create tag | |
uses: appleboy/ssh-action@master | |
with: | |
host: ${{ secrets.REMOTE_HOST }} | |
username: ${{ secrets.REMOTE_USER }} | |
port: ${{ secrets.REMOTE_PORT }} | |
key: ${{ secrets.SSH_PRIVATE_KEY }} | |
envs: | | |
WORKING_DIRECTORY | |
script: | | |
cd $WORKING_DIRECTORY | |
git tag -l | xargs git tag -d | |
git fetch --tags | |
tags=$(git tag -l) | |
latest_tag=$(echo "$tags" | grep -E '^v?0\.[0-9]+\.[0-9]+(-.*)?$' | sort -V | tail -n 1) | |
if [ -n "$latest_tag" ]; then | |
if [[ "$latest_tag" == v* ]]; then | |
latest_tag="${latest_tag#v}" | |
fi | |
base_version=$(echo "$latest_tag" | sed 's/-.*//') | |
major=$(echo "$base_version" | cut -d'.' -f1) | |
minor=$(echo "$base_version" | cut -d'.' -f2) | |
patch=$(echo "$base_version" | cut -d'.' -f3) | |
new_patch=$((patch + 1)) | |
new_tag="v${major}.${minor}.${new_patch}-dev" | |
else | |
new_tag="0.0.1" | |
fi | |
echo "New tag: $new_tag" | |
git tag $new_tag | |
git push origin --tags |