Merge pull request #213 from Open-Finance-Lab/fingpt_backend_prod #44
This file contains hidden or 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: Backend CI and Deploy | |
| on: | |
| push: | |
| branches: | |
| - main | |
| workflow_dispatch: | |
| env: | |
| BACKEND_DIR: Main/backend | |
| PYTHON_VERSION: "3.12" | |
| REGISTRY: ghcr.io | |
| DROPLET_HOST: agenticfinsearch.org | |
| DROPLET_USER: deploy | |
| SYSTEMD_UNIT: fingpt-api | |
| RUN_TESTS: "false" # Toggle to "true" to re-enable backend tests | |
| jobs: | |
| build: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| packages: write | |
| outputs: | |
| image: ${{ steps.meta.outputs.image }} | |
| sha_tag: ${{ steps.meta.outputs.sha_tag }} | |
| main_tag: ${{ steps.meta.outputs.main_tag }} | |
| latest_tag: ${{ steps.meta.outputs.latest_tag }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Set up uv | |
| uses: astral-sh/setup-uv@v3 | |
| - name: Install Python ${{ env.PYTHON_VERSION }} | |
| run: uv python install ${{ env.PYTHON_VERSION }} | |
| - name: Sync backend dependencies | |
| working-directory: ${{ env.BACKEND_DIR }} | |
| run: uv sync --frozen --python ${{ env.PYTHON_VERSION }} | |
| - name: Run Django system checks | |
| working-directory: ${{ env.BACKEND_DIR }} | |
| run: uv run python manage.py check | |
| - name: Compute image tags | |
| id: meta | |
| run: | | |
| REPO_SLUG=$(echo "${{ github.repository }}" | tr '[:upper:]' '[:lower:]') | |
| IMAGE_ID="${{ env.REGISTRY }}/${REPO_SLUG}-backend" | |
| echo "image=$IMAGE_ID" >> "$GITHUB_OUTPUT" | |
| echo "sha_tag=${IMAGE_ID}:${{ github.sha }}" >> "$GITHUB_OUTPUT" | |
| echo "main_tag=${IMAGE_ID}:main" >> "$GITHUB_OUTPUT" | |
| echo "latest_tag=${IMAGE_ID}:latest" >> "$GITHUB_OUTPUT" | |
| - name: Log in to GHCR | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Build backend image | |
| run: | | |
| docker build \ | |
| --file ${{ env.BACKEND_DIR }}/Dockerfile \ | |
| --tag ${{ steps.meta.outputs.sha_tag }} \ | |
| --tag ${{ steps.meta.outputs.main_tag }} \ | |
| --tag ${{ steps.meta.outputs.latest_tag }} \ | |
| ${{ env.BACKEND_DIR }} | |
| - name: Push backend image | |
| run: | | |
| docker push ${{ steps.meta.outputs.sha_tag }} | |
| docker push ${{ steps.meta.outputs.main_tag }} | |
| docker push ${{ steps.meta.outputs.latest_tag }} | |
| test: | |
| runs-on: ubuntu-latest | |
| needs: build | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Tests temporarily disabled | |
| if: ${{ env.RUN_TESTS != 'true' }} | |
| run: echo "::warning::Backend test suite is currently skipped. Set RUN_TESTS to true when ready to re-enable it." | |
| - name: Set up uv | |
| if: ${{ env.RUN_TESTS == 'true' }} | |
| uses: astral-sh/setup-uv@v3 | |
| - name: Install Python ${{ env.PYTHON_VERSION }} | |
| if: ${{ env.RUN_TESTS == 'true' }} | |
| run: uv python install ${{ env.PYTHON_VERSION }} | |
| - name: Sync backend dependencies | |
| if: ${{ env.RUN_TESTS == 'true' }} | |
| working-directory: ${{ env.BACKEND_DIR }} | |
| run: uv sync --frozen --python ${{ env.PYTHON_VERSION }} | |
| - name: Run backend tests | |
| if: ${{ env.RUN_TESTS == 'true' }} | |
| working-directory: ${{ env.BACKEND_DIR }} | |
| run: uv run python manage.py test | |
| deploy: | |
| runs-on: ubuntu-latest | |
| needs: | |
| - build | |
| - test | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Determine deploy eligibility | |
| id: deploy-gate | |
| env: | |
| DEPLOY_SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }} | |
| GHCR_READ_TOKEN: ${{ secrets.GHCR_READ_TOKEN }} | |
| run: | | |
| set -euo pipefail | |
| if [[ -n "${DEPLOY_SSH_KEY:-}" && -n "${GHCR_READ_TOKEN:-}" ]]; then | |
| echo "enabled=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "enabled=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Deploy to Fedora droplet | |
| if: ${{ steps.deploy-gate.outputs.enabled == 'true' }} | |
| uses: appleboy/ssh-action@v0.1.10 | |
| env: | |
| REMOTE_IMAGE: ${{ needs.build.outputs.main_tag }} | |
| GHCR_USERNAME: ${{ github.repository_owner }} | |
| GHCR_TOKEN: ${{ secrets.GHCR_READ_TOKEN }} | |
| with: | |
| host: ${{ env.DROPLET_HOST }} | |
| username: ${{ env.DROPLET_USER }} | |
| key: ${{ secrets.DEPLOY_SSH_KEY }} | |
| port: 22 | |
| envs: REMOTE_IMAGE,GHCR_USERNAME,GHCR_TOKEN,SYSTEMD_UNIT | |
| script: | | |
| set -euo pipefail | |
| export XDG_RUNTIME_DIR=/run/user/$(id -u) | |
| podman login ${{ env.REGISTRY }} -u "$GHCR_USERNAME" -p "$GHCR_TOKEN" | |
| podman pull "$REMOTE_IMAGE" | |
| systemctl --user daemon-reload | |
| systemctl --user restart "$SYSTEMD_UNIT" | |
| podman image prune -f |