diff --git a/.github/workflows/gcp_notifications_job.yml b/.github/workflows/gcp_notifications_job.yml new file mode 100644 index 000000000..6433b6312 --- /dev/null +++ b/.github/workflows/gcp_notifications_job.yml @@ -0,0 +1,85 @@ +name: Deploy Notifications Job to Cloud RUN + +on: + # push: + # branches: [ "main", "development" ] + # paths: + # - 'backend/modal/**' + workflow_dispatch: + inputs: + environment: + description: 'Select the environment to deploy to' + required: true + default: 'development' + type: string + branch: + description: 'Branch to deploy from' + required: true + default: 'main' + type: string + +env: + SERVICE: notifications-job + REGION: us-central1 + +jobs: + deploy: + environment: ${{ github.event.inputs.environment }} + permissions: + contents: 'read' + id-token: 'write' + + runs-on: ubuntu-latest + steps: + - name: Validate Environment Input + run: | + if [[ "${{ github.event.inputs.environment }}" != "development" && "${{ github.event.inputs.environment }}" != "prod" ]]; then + echo "Invalid environment: ${{ github.event.inputs.environment }}. Must be 'development' or 'prod'." + exit 1 + fi + + # To workaround "no space left on device" issue of GitHub-hosted runner + - name: Delete huge unnecessary tools folder + run: rm -rf /opt/hostedtoolcache + + - name: Checkout + uses: actions/checkout@v4 + with: + ref: ${{ github.event.inputs.branch }} + + - name: Google Auth + id: auth + uses: 'google-github-actions/auth@v2' + with: + credentials_json: ${{ secrets.GCP_CREDENTIALS }} + + - name: Login to GCR + run: gcloud auth configure-docker + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Google Service Account + run: echo "${{ secrets.GCP_SERVICE_ACCOUNT }}" | base64 -d > ./backend/google-credentials.json + + - name: Build and Push Docker image + uses: docker/build-push-action@v6 + with: + context: . + file: ./backend/modal/Dockerfile.notifications_job + push: true + tags: gcr.io/${{ vars.GCP_PROJECT_ID }}/${{ env.SERVICE }}:latest + cache-from: type=registry,ref=gcr.io/${{ vars.GCP_PROJECT_ID }}/${{ env.SERVICE }}:buildcache + cache-to: type=registry,ref=gcr.io/${{ vars.GCP_PROJECT_ID }}/${{ env.SERVICE }}:buildcache,mode=max + + - name: Deploy to Cloud Run + id: deploy + uses: google-github-actions/deploy-cloudrun@v2 + with: + job: ${{ env.SERVICE }} + region: ${{ env.REGION }} + image: gcr.io/${{ vars.GCP_PROJECT_ID }}/${{ env.SERVICE }} + + # If required, use the Cloud Run url output in later steps + - name: Show Output + run: echo ${{ steps.deploy.outputs.url }} diff --git a/backend/modal/Dockerfile.notifications_job b/backend/modal/Dockerfile.notifications_job new file mode 100644 index 000000000..d22b30375 --- /dev/null +++ b/backend/modal/Dockerfile.notifications_job @@ -0,0 +1,20 @@ +FROM python:3.11 AS builder + +ENV PATH="/opt/venv/bin:$PATH" +RUN python -m venv /opt/venv + +COPY backend/requirements.txt /tmp/requirements.txt +RUN pip install --no-cache-dir --upgrade -r /tmp/requirements.txt + +FROM python:3.11-slim + +WORKDIR /app +ENV PATH="/opt/venv/bin:$PATH" + +RUN apt-get update && apt-get -y install ffmpeg curl unzip && rm -rf /var/lib/apt/lists/* + +COPY --from=builder /opt/venv /opt/venv +COPY backend/ . +COPY backend/modal/ . + +CMD ["python", "job.py"] diff --git a/backend/modal/job.py b/backend/modal/job.py new file mode 100644 index 000000000..7f3ffa8fb --- /dev/null +++ b/backend/modal/job.py @@ -0,0 +1,17 @@ +import json +import os + +import firebase_admin +import asyncio + +from utils.other.notifications import start_cron_job + +if os.environ.get('SERVICE_ACCOUNT_JSON'): + service_account_info = json.loads(os.environ["SERVICE_ACCOUNT_JSON"]) + credentials = firebase_admin.credentials.Certificate(service_account_info) + firebase_admin.initialize_app(credentials) +else: + firebase_admin.initialize_app() + +print('Starting cron job...') +asyncio.run(start_cron_job())