# .gitea/workflows/deploy.yml name: Build and Deploy Backend run-name: ${{ gitea.actor }} deploying backend on Gitea Actions 🚀 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/**' - '.gitea/workflows/deploy.yml' - 'backend/docker-compose.deploy.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@v5 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 if: gitea.event_name == 'push' || gitea.event_name == 'workflow_dispatch' || gitea.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: ${{ secrets.DOCKER_REGISTRY_USERNAME }} # Uses the username stored in secrets 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/${{ secrets.DOCKER_REGISTRY_USERNAME }}/maia:${{ gitea.sha }} ghcr.io/${{ secrets.DOCKER_REGISTRY_USERNAME }}/maia:latest # Pull latest base image updates when building (good for scheduled runs) pull: true # ------------------------------------------------------------------ # Deploy to mara # ------------------------------------------------------------------ - name: Deploy Locally run: | #!/bin/bash -ex # Define path to compose file WITHIN the checked-out workspace COMPOSE_FILE="${{ gitea.workspace }}/backend/docker-compose.deploy.yml" PROJECT_NAME="maia" echo "--- Start Deploy Locally (using compose file from repo) ---" echo "Workspace root: ${{ gitea.workspace }}" echo "Using compose file: ${COMPOSE_FILE}" # Verify compose file exists if [ ! -f "${COMPOSE_FILE}" ]; then echo "ERROR: Compose file not found at ${COMPOSE_FILE}" ls -la "${{ gitea.workspace }}/backend/" # List contents for debugging exit 1 fi # Pull the specific image version built in this workflow echo "Pulling image ${{ gitea.sha }}..." docker pull ghcr.io/${{ secrets.DOCKER_REGISTRY_USERNAME }}/maia:${{ gitea.sha }} echo "Pull complete." # Pull other images defined in compose using the specific file # Ensures base images like redis/db are up-to-date if specified in compose echo "Pulling other compose services..." docker compose -p "${PROJECT_NAME}" -f "${COMPOSE_FILE}" pull redis db echo "Other service pull complete." # Update the image tag IN THE CHECKED-OUT COMPOSE FILE # This change only exists within the job's workspace, it doesn't modify the repo source echo "Running sed on ${COMPOSE_FILE}..." sed -i 's|image: ghcr.io/${{ secrets.DOCKER_REGISTRY_USERNAME }}/maia:.*|image: ghcr.io/${{ secrets.DOCKER_REGISTRY_USERNAME }}/maia:${{ gitea.sha }}|g' "${COMPOSE_FILE}" echo "sed complete. Showing updated line:" grep "image: ghcr.io/${{ secrets.DOCKER_REGISTRY_USERNAME }}/maia" "${COMPOSE_FILE}" || echo "Image line not found after sed!" # Restart the services using the updated compose file from the workspace # Docker compose interacts with the HOST daemon via the mounted socket echo "Bringing compose stack down and up with new image..." docker compose -p "${PROJECT_NAME}" -f "${COMPOSE_FILE}" up -d --force-recreate --remove-orphans echo "Docker compose up command finished." echo "--- Local deployment complete! ---"