feat(backend): remove SQLAlchemy and replace with async psycopg db dr… #1329
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
# Workflow for build and auto-deploy of branches | |
name: 🔧 Build and Deploy | |
on: | |
# Push includes PR merge | |
push: | |
branches: | |
- main | |
- staging | |
- development | |
paths: | |
# Workflow is triggered only if src changes | |
- src/** | |
# Allow manual trigger | |
workflow_dispatch: | |
jobs: | |
backend-test: | |
uses: hotosm/gh-workflows/.github/workflows/[email protected] | |
with: | |
image_name: ghcr.io/${{ github.repository }}/backend | |
build_context: src/backend | |
pre_command: docker compose up -d proxy && docker compose exec api /app-entrypoint.sh | |
compose_service: api | |
compose_command: pytest | |
tag_override: ci-${{ github.ref_name }} | |
coverage: true | |
secrets: inherit | |
frontend-unit-test: | |
uses: hotosm/gh-workflows/.github/workflows/[email protected] | |
with: | |
working_dir: src/frontend | |
frontend-e2e-test: | |
uses: hotosm/gh-workflows/.github/workflows/[email protected] | |
with: | |
playwright: true | |
cache_image: false | |
compose_file: docker-compose.yml -f contrib/playwright/docker-compose.yml | |
compose_service: ui-test | |
cache_extra_imgs: | | |
"docker.io/postgis/postgis:${{ vars.POSTGIS_TAG }}" | |
"docker.io/minio/minio:${{ vars.MINIO_TAG }}" | |
"mcr.microsoft.com/playwright:${{ vars.PLAYWRIGHT_TAG }}" | |
secrets: inherit | |
backend-build: | |
uses: hotosm/gh-workflows/.github/workflows/[email protected] | |
needs: [backend-test] | |
with: | |
context: src/backend | |
build_target: prod | |
image_name: ghcr.io/${{ github.repository }}/backend | |
frontend-build: | |
uses: hotosm/gh-workflows/.github/workflows/[email protected] | |
needs: [frontend-unit-test, frontend-e2e-test] | |
with: | |
context: src/frontend | |
dockerfile: prod.dockerfile | |
build_target: prod | |
image_name: ghcr.io/${{ github.repository }}/frontend | |
smoke-test-backend: | |
runs-on: ubuntu-latest | |
needs: [backend-build] | |
environment: | |
name: ${{ github.ref_name }} | |
steps: | |
- name: Checkout repository | |
uses: actions/checkout@v4 | |
- name: Vars and Secrets to Env | |
env: | |
GIT_BRANCH: ${{ github.ref_name }} | |
TAG_OVERRIDE: ${{ needs.backend-build.outputs.image_tag }} | |
VARS_CONTEXT: ${{ toJson(vars) }} | |
SECRETS_CONTEXT: ${{ toJson(secrets) }} | |
run: | | |
# Random delimiter string for security | |
delim=$(dd if=/dev/urandom bs=15 count=1 status=none | base64) | |
# Parse JSON with multiline strings, using delimiter (Github specific) | |
to_envs() { jq -r "to_entries[] | \"\(.key)<<$delim\n\(.value)\n$delim\n\""; } | |
# Set all vars | |
echo "GIT_BRANCH=${GIT_BRANCH}" >> $GITHUB_ENV | |
echo "TAG_OVERRIDE=${TAG_OVERRIDE}" >> $GITHUB_ENV | |
echo "${VARS_CONTEXT}" | to_envs >> $GITHUB_ENV | |
echo "${SECRETS_CONTEXT}" | to_envs >> $GITHUB_ENV | |
- name: Create .env file | |
run: | | |
# Get a8m/envsubst (required for default vals syntax ${VAR:-default}) | |
echo "Downloading envsubst" | |
curl -L https://github.com/a8m/envsubst/releases/download/v1.2.0/envsubst-`uname -s`-`uname -m` -o envsubst | |
chmod +x envsubst | |
echo "Substituting variables from .env.example --> .env" | |
./envsubst < .env.example > .env | |
echo "GIT_BRANCH=${GIT_BRANCH}" >> .env | |
echo "TAG_OVERRIDE=${TAG_OVERRIDE}" >> .env | |
- name: Backend smoke test | |
env: | |
# Hardcode replicas=1 for test | |
API_REPLICAS: 1 | |
run: | | |
# Migrate db first, so api works | |
docker compose up migrations --exit-code-from migrations | |
# Run without migrations (avoid exit code 0) | |
# Also run within if block to capture logs if failure | |
if docker compose up --detach \ | |
--no-deps --wait --wait-timeout 60 \ | |
central-db central s3 api | |
then | |
docker compose logs api | |
else | |
echo "Application not healthy after 1m0s. Exiting." | |
docker compose logs api | |
exit 1 | |
fi | |
smoke-test-frontend: | |
runs-on: ubuntu-latest | |
needs: [frontend-build] | |
environment: | |
name: ${{ github.ref_name }} | |
steps: | |
- name: Checkout repository | |
uses: actions/checkout@v4 | |
- name: Create .env file | |
run: | | |
# Get a8m/envsubst (required for default vals syntax ${VAR:-default}) | |
echo "Downloading envsubst" | |
curl -L https://github.com/a8m/envsubst/releases/download/v1.2.0/envsubst-`uname -s`-`uname -m` -o envsubst | |
chmod +x envsubst | |
echo "Substituting variables from .env.example --> .env" | |
./envsubst < .env.example > .env | |
- name: Frontend smoke test | |
run: | | |
if docker compose up --detach \ | |
--no-deps --wait --wait-timeout 30 \ | |
ui | |
then | |
docker compose logs ui | |
echo "Sleeping 5 seconds to wait for dev server" | |
sleep 5 | |
curl --fail http://localhost:7051 || exit 1 | |
else | |
echo "Application not healthy after 30s. Exiting." | |
docker compose logs ui | |
exit 1 | |
fi | |
deploy-containers: | |
needs: | |
- smoke-test-backend | |
- smoke-test-frontend | |
uses: hotosm/gh-workflows/.github/workflows/[email protected] | |
with: | |
environment: ${{ github.ref_name }} | |
docker_compose_file: "docker-compose.${{ github.ref_name }}.yml" | |
secrets: inherit |