# .github/workflows/deploy.yml name: Build and Deploy Backend on: # Triggers the workflow on push events but only for the main branch push: branches: [ main ] paths: # Only run if backend code or Docker config changes - 'backend/**' - '.github/workflows/deploy.yml' - 'backend/docker-compose.yml' # Allows running of this workflow manually from the Actions tab workflow_dispatch: # Ensures the project will never be out of date by running a cron for this job # Currently set to every Sunday at 3 AM UTC schedule: - cron: '0 3 * * 0' jobs: # ======================================================================== # Job to run unit tests. # ======================================================================== test: name: Run Linters and Tests runs-on: ubuntu-latest steps: # Checks out the repo under $GITHUB_WORKSPACE - name: Checkout code uses: actions/checkout@v4 # Sets up Python 3.12 environment - name: Set up Python uses: actions/setup-python@v4 with: python-version: '3.12' # Cache pip dependencies for faster reruns - name: Cache pip dependencies uses: actions/cache@v3 with: path: ~/.cache/pip key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements*.txt') }} restore-keys: | ${{ runner.os }}-pip- - name: Install dependencies working-directory: ./backend run: | python -m pip install --upgrade pip pip install -r requirements.txt pip install -r requirements-dev.txt - name: Lint with Ruff working-directory: ./backend run: | ruff check . - name: Check formatting with Black working-directory: ./backend run: | black --check . - name: Run Pytest working-directory: ./backend run: | pytest # ======================================================================== # Job to build and deploy the Docker image to mara. # ======================================================================== build-and-deploy: name: Build and Deploy runs-on: ubuntu-latest needs: test # Ensure tests pass before deploying # Only run this job if triggered by a push to main or manual dispatch/schedule # This prevents it running for PRs (eventually) if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' steps: # Checks out the repo under $GITHUB_WORKSPACE - name: Checkout code uses: actions/checkout@v4 # ------------------------------------------------------------------ # Login to Container Registry (Using GHCR) # ------------------------------------------------------------------ - name: Log in to GitHub Container Registry uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.repository_owner }} # GitHub username password: ${{ secrets.DOCKER_REGISTRY_TOKEN }} # Uses the PAT stored in secrets # ------------------------------------------------------------------ # Set up Docker Buildx for advanced build features # ------------------------------------------------------------------ - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 # ------------------------------------------------------------------ # Build and Push Docker Image # ------------------------------------------------------------------ - name: Build and push Docker image uses: docker/build-push-action@v5 with: context: ./backend file: ./backend/Dockerfile # Explicit path to Dockerfile push: true # Push the image after building tags: | # Use SHA for version specific, latest for general ghcr.io/${{ github.repository_owner }}/maia:${{ github.sha }} ghcr.io/${{ github.repository_owner }}/maia:latest # Pull latest base image updates when building (good for scheduled runs) pull: true cache-from: type=gha # Github Actions cache cache-to: type=gha,mode=max # ------------------------------------------------------------------ # Deploy to mara via SSH # ------------------------------------------------------------------ - name: Deploy to Server uses: appleboy/ssh-action@v1.0.3 with: host: ${{ secrets.SSH_HOST }} port: ${{ secrets.SSH_PORT }} username: ${{ secrets.SSH_USER }} key: ${{ secrets.SSH_PRIVATE_KEY }} script: | set -e # Exit script on first error cd ${{ secrets.DEPLOY_PATH }} echo "Logged into server: $(pwd)" # Log into GHCR on mara echo "Logging into GHCR..." echo ${{ secrets.DOCKER_REGISTRY_TOKEN }} | docker login ghcr.io -u ${{ github.repository_owner }} --password-stdin echo "GHCR login completed." # Pull the specific image version built in this workflow # Using the Git SHA ensures we deploy exactly what was just built echo "Pulling image ${{ github.sha }}..." docker pull ghcr.io/${{ github.repository_owner }}/maia:${{ github.sha }} # Also pull latest for other services to keep up to date docker compose pull redis db # Uses sed to update the compose file with the new image tag sed -i 's|image: ghcr.io/${{ github.repository_owner }}/maia:.*|image: ghcr.io/${{ github.repository_owner }}/maia:${{ github.sha }}|g' docker-compose.yml echo "Updated docker-compose.yml image tag" # Restart the services using the new image(s) echo "Bringing compose stack down and up with new image..." docker compose up -d --force-recreate --remove-orphans api worker db redis echo "Deployment complete!"