Architecture
TaskForge API runs on the following Azure infrastructure:Azure App Service
Linux plan, Python 3.11 runtime. Gunicorn serves the Flask app with 4 workers.
Azure SQL Database
Managed SQL Server instance. Schema initialized via
scripts/init_db_azure.sql.GitHub Actions
Two workflows: deployment pipeline and code quality analysis run on every push.
https://task-forge-gbd6h8gtg8hchve9.chilecentral-01.azurewebsites.net
Prerequisites
- An active Azure subscription
- The Azure CLI installed and authenticated
- A GitHub repository containing the TaskForge API source code
Deployment procedure
Create Azure SQL Database
Create a new Azure SQL Server and database using the Azure portal or CLI:Then run
scripts/init_db_azure.sql against the new database in Azure Data Studio or SQL Server Management Studio to initialize the schema (tables, roles, indexes).Configure the startup command
Set the startup command so Azure App Service uses the included The startup script initializes the database and launches Gunicorn:
startup.sh script:startup.sh
Set environment variables on App Service
Configure application settings in Azure App Service. These are exposed as environment variables at runtime:
Add GitHub secrets
The deployment workflow authenticates to Azure using OIDC (no stored credentials). Add these secrets to your GitHub repository under Settings → Secrets and variables → Actions:
The trailing
| Secret | Description |
|---|---|
AZUREAPPSERVICE_CLIENTID_* | Azure AD application (client) ID for the federated identity |
AZUREAPPSERVICE_TENANTID_* | Azure AD tenant ID |
AZUREAPPSERVICE_SUBSCRIPTIONID_* | Azure subscription ID |
SONAR_TOKEN | SonarCloud project token for the code quality workflow |
* in the secret names is a hash suffix generated by Azure when you set up deployment center — use the exact names shown in the portal.CI/CD pipeline
Two separate GitHub Actions workflows run on each push:main_task-forge.yml — Build, test, and deploy
Triggered on push tomain or master.
| Job | What it does |
|---|---|
build | Sets up Python 3.11, installs dependencies, creates release.zip (excludes .env, tests/, htmlcov/), uploads artifact |
test | Runs pytest --cov=app --cov-fail-under=70 — the pipeline fails if coverage drops below 70% |
deploy | Downloads the build artifact, authenticates to Azure via OIDC, deploys to the Production slot of the task-forge App Service |
code-quality.yml — SonarCloud and accessibility
Triggered on push and pull requests tomain, master, and develop.
| Job | What it does |
|---|---|
sonarcloud | Runs pytest with coverage, then uploads results to SonarCloud for bug, vulnerability, code smell, and duplication analysis |
accessibility | Starts the Flask dev server, runs AXE-core accessibility tests against the Swagger UI via Playwright/Chromium, uploads an HTML report |
The code quality workflow does not block deployment. It runs in parallel and its results are visible in the SonarCloud dashboard and as GitHub Actions artifacts.
Gunicorn configuration
Gunicorn is configured instartup.sh with the following settings:
| Option | Value | Notes |
|---|---|---|
--bind | 0.0.0.0:8000 | Azure App Service routes traffic to port 8000 on Linux |
--workers | 4 | Pre-fork worker processes |
--timeout | 120 | Worker timeout in seconds |
--access-logfile | /home/site/wwwroot/logs/access.log | Persistent log storage |
--error-logfile | /home/site/wwwroot/logs/error.log | Persistent log storage |