one more time #1609
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: Build server | |
on: | |
push: | |
branches: [main, develop] | |
jobs: | |
prepare-env: | |
runs-on: ubuntu-latest | |
outputs: | |
env_tag: ${{ steps.set-tag.outputs.ENV_TAG }} | |
compose_file: ${{ steps.set-tag.outputs.COMPOSE_FILE }} | |
stack_name: ${{ steps.set-tag.outputs.STACK_NAME }} | |
steps: | |
- name: Set environment tag | |
id: set-tag | |
run: | | |
if [[ ${{ github.ref }} == 'refs/heads/main' ]]; then | |
echo "ENV_TAG=prod" >> $GITHUB_OUTPUT | |
echo "COMPOSE_FILE=docker-compose.prod.yml" >> $GITHUB_OUTPUT | |
echo "STACK_NAME=prod" >> $GITHUB_OUTPUT | |
else | |
echo "ENV_TAG=staging" >> $GITHUB_OUTPUT | |
echo "COMPOSE_FILE=docker-compose.staging.yml" >> $GITHUB_OUTPUT | |
echo "STACK_NAME=staging" >> $GITHUB_OUTPUT | |
fi | |
build-and-push-images: | |
needs: prepare-env | |
runs-on: ubuntu-latest | |
strategy: | |
matrix: | |
include: | |
- image: server | |
dockerfile: ./packages/server/src/Dockerfile | |
- image: stage-transcriptions | |
dockerfile: ./packages/server/workers/stage-transcriptions/Dockerfile | |
- image: session-transcriptions | |
dockerfile: ./packages/server/workers/session-transcriptions/Dockerfile | |
- image: clips | |
dockerfile: ./packages/server/workers/clips/Dockerfile | |
- image: reel-creator | |
dockerfile: ./packages/reel-creator/Dockerfile | |
steps: | |
- name: Checkout repository | |
uses: actions/checkout@v4 | |
- name: Set up Docker Buildx | |
uses: docker/setup-buildx-action@v2 | |
# Add caching for Docker layers | |
- name: Cache Docker layers | |
uses: actions/cache@v3 | |
with: | |
path: /tmp/.buildx-cache | |
key: ${{ runner.os }}-buildx-${{ matrix.image }}-${{ github.sha }} | |
restore-keys: | | |
${{ runner.os }}-buildx-${{ matrix.image }}- | |
${{ runner.os }}-buildx- | |
- name: Log in to the Container registry | |
uses: docker/login-action@v3 | |
with: | |
registry: https://ghcr.io | |
username: ${{ github.actor }} | |
password: ${{ secrets.TOKEN }} | |
- name: Build and push ${{ matrix.image }} | |
id: docker_build | |
uses: docker/build-push-action@v3 | |
with: | |
context: . | |
push: true | |
tags: | | |
ghcr.io/streamethorg/streameth-platform/${{ matrix.image }}:${{ needs.prepare-env.outputs.env_tag }} | |
ghcr.io/streamethorg/streameth-platform/${{ matrix.image }}:${{ needs.prepare-env.outputs.env_tag }}-${{ github.sha }} | |
file: ${{ matrix.dockerfile }} | |
cache-from: type=local,src=/tmp/.buildx-cache | |
cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max | |
# Temp fix for cache handling | |
- name: Move cache | |
run: | | |
rm -rf /tmp/.buildx-cache | |
mv /tmp/.buildx-cache-new /tmp/.buildx-cache | |
deploy: | |
needs: [prepare-env, build-and-push-images] | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout repository | |
uses: actions/checkout@v4 | |
# Setup SSH key | |
- name: Setup SSH key | |
run: | | |
mkdir -p ~/.ssh | |
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa | |
chmod 600 ~/.ssh/id_rsa | |
ssh-keyscan -H 145.223.118.217 >> ~/.ssh/known_hosts | |
# Setup Docker context from base64-encoded secret | |
- name: Setup Docker context | |
run: | | |
mkdir -p ~/.docker/contexts | |
if [[ ${{ github.ref }} == 'refs/heads/docker-prod' ]]; then | |
echo "${{ secrets.DOCKER_CONTEXT_PROD_B64 }}" | base64 -d > ~/.docker/contexts/streameth-prod.tar.gz | |
docker context import streameth-prod ~/.docker/contexts/streameth-prod.tar.gz | |
docker context use streameth-prod | |
else | |
echo "${{ secrets.DOCKER_CONTEXT_STAGING_B64 }}" | base64 -d > ~/.docker/contexts/streameth-staging.tar.gz | |
docker context import streameth-staging ~/.docker/contexts/streameth-staging.tar.gz | |
docker context use streameth-staging | |
fi | |
# Copy compose files to server | |
- name: Copy compose files | |
run: | | |
scp docker-compose.*.yml [email protected]:/home/streameth/streameth/ | |
# Log in to registry on deployment server | |
- name: Log in to registry on deployment server | |
run: | | |
echo "${{ secrets.TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin | |
# Update services based on environment | |
- name: Update services | |
run: | | |
STACK_NAME="${{ needs.prepare-env.outputs.stack_name }}" | |
SHA="${{ github.sha }}" | |
# Function to update a service and capture its exit status | |
update_service() { | |
local service=$1 | |
local temp_file=$(mktemp) | |
if docker service update \ | |
--with-registry-auth \ | |
--image ghcr.io/streamethorg/streameth-platform/$service:${{ needs.prepare-env.outputs.env_tag }}-$SHA \ | |
${STACK_NAME}_${service} > $temp_file 2>&1; then | |
echo "✅ Service ${STACK_NAME}_${service} updated successfully" | |
rm $temp_file | |
return 0 | |
else | |
echo "❌ Failed to update ${STACK_NAME}_${service}" | |
cat $temp_file | |
rm $temp_file | |
return 1 | |
fi | |
} | |
# Start all updates in parallel and capture PIDs | |
pids=() | |
for service in server stage-transcriptions session-transcriptions clips reel-creator; do | |
update_service $service & | |
pids+=($!) | |
done | |
# Wait for all updates and check for failures | |
failed=0 | |
for pid in ${pids[@]}; do | |
if ! wait $pid; then | |
failed=1 | |
fi | |
done | |
# Exit with failure if any update failed | |
exit $failed | |
# Deploy router if it doesn't exist (only needs to be done once) | |
- name: Deploy router if needed | |
if: github.ref == 'refs/heads/docker-prod' # Only check/deploy router on prod branch pushes | |
run: | | |
if ! docker stack ls | grep -q "router"; then | |
docker stack deploy -c /home/streameth/streameth/docker-compose.router.yml router | |
fi |