From c87a118ebdbbc655184af6c736fcb8a88bc2439d Mon Sep 17 00:00:00 2001 From: Naresh Kumar D Date: Fri, 10 Jul 2026 15:43:55 +0530 Subject: [PATCH 1/2] Deploy code feature Deploying the required code --- .github/workflows/trigger-deploy-on-merge.yml | 36 +++++++++++++++++++ api/core/config.py | 8 ++--- api/main.py | 4 ++- 3 files changed, 42 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/trigger-deploy-on-merge.yml diff --git a/.github/workflows/trigger-deploy-on-merge.yml b/.github/workflows/trigger-deploy-on-merge.yml new file mode 100644 index 0000000..82265c8 --- /dev/null +++ b/.github/workflows/trigger-deploy-on-merge.yml @@ -0,0 +1,36 @@ +name: Trigger Deployment on Pull Request Merge +on: + pull_request: + types: [closed] + branches: [ develop, staging, production] +permissions: + contents: read + actions: write +jobs: + on-merge: + if: github.event.pull_request.merged == true + runs-on: ubuntu-latest + outputs: + environment: ${{ steps.set-environment.outputs.environment }} + steps: + - name: Set Environment + id: set-environment + run: | + case "${{ github.base_ref }}" in + develop) echo "environment=develop" >> $GITHUB_OUTPUT ;; + staging) echo "environment=staging" >> $GITHUB_OUTPUT ;; + production) echo "environment=production" >> $GITHUB_OUTPUT ;; + testing) echo "environment=testing" >> $GITHUB_OUTPUT ;; + esac + deploy: + needs: on-merge + runs-on: ubuntu-latest + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + steps: + - name: Trigger Deployment Workflow + run: | + gh workflow run push-docker-image.yml \ + --repo ${{ github.repository }} \ + --ref ${{ github.base_ref }} \ + --field environment=${{ needs.on-merge.outputs.environment }} \ No newline at end of file diff --git a/api/core/config.py b/api/core/config.py index c4c6bde..643e586 100644 --- a/api/core/config.py +++ b/api/core/config.py @@ -10,11 +10,9 @@ class Settings(BaseSettings): PROJECT_NAME: str = "Workspaces API" - # JSON array of allowed CORS origins. For example: - # - # ["https://workspaces.example.com", "https://leaderboard.example.com"] - # - CORS_ORIGINS: list[str] = [] + # Comma separated list of origins, or "*" to allow all origins. Defaults to an empty list. + # Example: CORS_ORIGINS="https://workspaces.example.com,https://leaderboard.example.com" + CORS_ORIGINS: str = "" TASK_DATABASE_URL: str = ( "postgresql+asyncpg://user:pass@localhost:5432/tasking_manager" diff --git a/api/main.py b/api/main.py index d537b72..9123a4e 100644 --- a/api/main.py +++ b/api/main.py @@ -97,7 +97,9 @@ async def lifespan(_app: FastAPI): app.add_middleware( CORSMiddleware, - allow_origins=settings.CORS_ORIGINS, + allow_origins=[ + origin.strip() for origin in settings.CORS_ORIGINS.split(",") if origin.strip() + ], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], From 090c4bc747e98a1c378a6682effff4dbb4ea1cfc Mon Sep 17 00:00:00 2001 From: Naresh Kumar D Date: Fri, 10 Jul 2026 15:49:29 +0530 Subject: [PATCH 2/2] Update test_config.py Updated unit tests for CORS --- tests/unit/test_config.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/unit/test_config.py b/tests/unit/test_config.py index 3a06d3b..4a9ab45 100644 --- a/tests/unit/test_config.py +++ b/tests/unit/test_config.py @@ -14,7 +14,7 @@ def test_defaults_loaded_when_env_unset(): s = Settings(_env_file=None) # type: ignore[call-arg] # pydantic-settings init kwarg assert s.PROJECT_NAME == "Workspaces API" - assert s.CORS_ORIGINS == [] + assert s.CORS_ORIGINS == "" assert s.DEBUG is False assert s.SENTRY_DSN == "" assert s.WS_OSM_HOST == "http://osm-web" @@ -38,18 +38,18 @@ def test_env_vars_override_members(monkeypatch): def test_cors_origins_parsed_from_json_env(monkeypatch): - monkeypatch.setenv("CORS_ORIGINS", '["https://a.example", "https://b.example"]') + monkeypatch.setenv("CORS_ORIGINS", "https://a.example,https://b.example") s = Settings(_env_file=None) # type: ignore[call-arg] # pydantic-settings init kwarg - assert s.CORS_ORIGINS == ["https://a.example", "https://b.example"] + assert s.CORS_ORIGINS == "https://a.example,https://b.example" def test_value_types_and_formats(): s = Settings(_env_file=None) # type: ignore[call-arg] # pydantic-settings init kwarg assert isinstance(s.PROJECT_NAME, str) - assert isinstance(s.CORS_ORIGINS, list) + assert isinstance(s.CORS_ORIGINS, str) assert isinstance(s.DEBUG, bool) # empty-string default is preserved (not coerced to None): assert s.SENTRY_DSN == ""