diff --git a/.github/workflows/cd-dev.yml b/.github/workflows/cd-dev.yml deleted file mode 100644 index e332a40..0000000 --- a/.github/workflows/cd-dev.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: Deploy Space2Stats API Staging - -on: - pull_request: - branches: - - main - -permissions: - id-token: write - contents: read - -jobs: - build: - environment: "Space2Stats API Dev" - runs-on: ubuntu-latest - - steps: - - name: Check out repository code - uses: actions/checkout@v2 - - - name: Install AWS CDK - run: npm install -g aws-cdk - - - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@v1 - with: - role-to-assume: arn:aws:iam::017820688988:role/Space2Stats-Deploy-Role - aws-region: ${{ vars.CDK_DEFAULT_REGION }} - - - name: Install CDK dependencies - working-directory: ./space2stats_api/cdk - run: | - pip install -r requirements-cdk.txt - - - name: Deploy CDK stack to staging - working-directory: ./space2stats_api/cdk - env: - STAGE: dev - PGHOST: ${{ secrets.PGHOST }} - PGPORT: ${{ secrets.PGPORT }} - PGDATABASE: ${{ secrets.PGDATABASE }} - PGUSER: ${{ secrets.PGUSER }} - PGPASSWORD: ${{ secrets.PGPASSWORD }} - PGTABLENAME: ${{ secrets.PGTABLENAME }} - CDK_CERTIFICATE_ARN: ${{ vars.CDK_CERTIFICATE_ARN }} - CDK_DEFAULT_ACCOUNT: ${{ vars.CDK_DEFAULT_ACCOUNT }} - CDK_DEFAULT_REGION: ${{ vars.CDK_DEFAULT_REGION }} - CDK_DOMAIN_NAME: ${{ vars.CDK_DOMAIN_NAME }} - run: cdk deploy --require-approval never \ No newline at end of file diff --git a/.github/workflows/cd-prod.yml b/.github/workflows/cd-prod.yml deleted file mode 100644 index 78d2c16..0000000 --- a/.github/workflows/cd-prod.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: Deploy Space2Stats API Prod - -on: - push: - branches: - - main - -permissions: - id-token: write - contents: read - -jobs: - build: - environment: "Space2Stats API Prod" - runs-on: ubuntu-latest - - steps: - - name: Check out repository code - uses: actions/checkout@v2 - - - name: Install AWS CDK - run: npm install -g aws-cdk - - - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@v1 - with: - role-to-assume: arn:aws:iam::017820688988:role/Space2Stats-Deploy-Role - aws-region: ${{ vars.CDK_DEFAULT_REGION }} - - - name: Install CDK dependencies - working-directory: ./space2stats_api/cdk - run: | - pip install -r requirements-cdk.txt - - - name: Deploy CDK stack - working-directory: ./space2stats_api/cdk - env: - STAGING: prod - PGHOST: ${{ secrets.PGHOST }} - PGPORT: ${{ secrets.PGPORT }} - PGDATABASE: ${{ secrets.PGDATABASE }} - PGUSER: ${{ secrets.PGUSER }} - PGPASSWORD: ${{ secrets.PGPASSWORD }} - PGTABLENAME: ${{ secrets.PGTABLENAME }} - CDK_CERTIFICATE_ARN: ${{ vars.CDK_CERTIFICATE_ARN }} - CDK_DEFAULT_ACCOUNT: ${{ vars.CDK_DEFAULT_ACCOUNT }} - CDK_DEFAULT_REGION: ${{ vars.CDK_DEFAULT_REGION }} - CDK_DOMAIN_NAME: ${{ vars.CDK_DOMAIN_NAME }} - run: cdk deploy --require-approval never \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0328da9..3be9e3a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,47 +1,82 @@ name: Run Tests -on: [push, pull_request] +on: + push: + pull_request: + types: + - opened + - synchronize + - reopened + - closed jobs: test: runs-on: ubuntu-latest steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: 3.11 - - - name: Install Poetry - run: | - python -m pip install --upgrade pip - python -m pip install poetry - - - name: Install dependencies - working-directory: ./space2stats_api/src - run: | - poetry install --with test - - - name: install lib postgres - uses: nyurik/action-setup-postgis@v2 - - - name: Run pre-commit - working-directory: ./space2stats_api/src - run: | - poetry run pre-commit run --all-files - - - name: Run tests - working-directory: ./space2stats_api/src - run: | - poetry run python -m pytest --benchmark-skip tests - env: - PGHOST: localhost - PGPORT: 5432 - PGDATABASE: mydatabase - PGUSER: myuser - PGPASSWORD: mypassword - PGTABLENAME: space2stats - S3_BUCKET_NAME: test-bucket \ No newline at end of file + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: 3.11 + + - name: Install Poetry + run: | + python -m pip install --upgrade pip + python -m pip install poetry + + - name: Install dependencies + working-directory: ./space2stats_api/src + run: | + poetry install --with test + + - name: install lib postgres + uses: nyurik/action-setup-postgis@v2 + + - name: Run pre-commit + working-directory: ./space2stats_api/src + run: | + poetry run pre-commit run --all-files + + - name: Run tests + working-directory: ./space2stats_api/src + run: | + poetry run python -m pytest --benchmark-skip tests + env: + PGHOST: localhost + PGPORT: 5432 + PGDATABASE: mydatabase + PGUSER: myuser + PGPASSWORD: mypassword + PGTABLENAME: space2stats + S3_BUCKET_NAME: test-bucket + + deploy-to-dev: + if: ${{ github.event_name == 'pull_request' }} + uses: "./.github/workflows/deploy.yml" + needs: test + with: + environment: Space2Stats API Dev + stage: pr-${{ github.event.pull_request.number }} + pr-number: ${{ github.event.pull_request.number }} + secrets: inherit + + deploy-to-production: + if: ${{ github.event_name == 'push' && github.ref_name == 'main' }} + uses: "./.github/workflows/deploy.yml" + needs: test + with: + environment: Space2Stats API Prod + stage: prod + secrets: inherit + + destroy-pr-preview: + if: ${{ github.event.action == 'closed' }} + uses: "./.github/workflows/deploy.yml" + with: + environment: Space2Stats API Dev + stage: pr-${{ github.event.pull_request.number }} + + secrets: inherit diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..4c6c9b2 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,85 @@ +name: Deploy + +on: + workflow_call: + inputs: + environment: + type: string + required: true + stage: + type: string + required: true + pr-number: + type: number + required: false + +permissions: + id-token: write + contents: read + pull-requests: write + +jobs: + build: + concurrency: ${{ inputs.environment }} + environment: ${{ inputs.environment }} + runs-on: ubuntu-latest + + steps: + - name: Check out repository code + uses: actions/checkout@v2 + + - name: Install AWS CDK + run: npm install -g aws-cdk + + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: arn:aws:iam::017820688988:role/Space2Stats-Deploy-Role + aws-region: ${{ vars.CDK_DEFAULT_REGION }} + + - name: Install CDK dependencies + working-directory: ./space2stats_api/cdk + run: | + pip install -r requirements-cdk.txt + + - name: Deploy CDK stack to staging + working-directory: ./space2stats_api/cdk + env: + STAGE: ${{ inputs.stage }} + PGHOST: ${{ secrets.PGHOST }} + PGPORT: ${{ secrets.PGPORT }} + PGDATABASE: ${{ secrets.PGDATABASE }} + PGUSER: ${{ secrets.PGUSER }} + PGPASSWORD: ${{ secrets.PGPASSWORD }} + PGTABLENAME: ${{ secrets.PGTABLENAME }} + CDK_CERTIFICATE_ARN: ${{ vars.CDK_CERTIFICATE_ARN }} + CDK_DEFAULT_ACCOUNT: ${{ vars.CDK_DEFAULT_ACCOUNT }} + CDK_DEFAULT_REGION: ${{ vars.CDK_DEFAULT_REGION }} + CDK_DOMAIN_NAME: ${{ vars.CDK_DOMAIN_NAME }} + run: cdk deploy --require-approval never --outputs-file outputs.json + + - name: Get API URL + id: get-api-url + working-directory: ./space2stats_api/cdk + run: | + echo "api-url=$(jq -r '."Space2Stats-${{ inputs.stage }}".ApiGatewayUrl' outputs.json)" >> $GITHUB_OUTPUT + + - name: Find Comment + uses: peter-evans/find-comment@v3 + id: find-comment + if: ${{ inputs.pr-number }} + with: + issue-number: ${{ inputs.pr-number }} + comment-author: "github-actions[bot]" + body-includes: "PR Deployment Details:" + + - name: Create or update comment with URL + uses: peter-evans/create-or-update-comment@v4 + if: ${{ inputs.pr-number }} + with: + issue-number: ${{ inputs.pr-number }} + comment-id: ${{ steps.find-comment.outputs.comment-id }} + body: | + PR Deployment Details: + 🚀 PR deployed to ${{ steps.get-api-url.outputs.api-url }} + edit-mode: replace diff --git a/.github/workflows/destroy.yml b/.github/workflows/destroy.yml new file mode 100644 index 0000000..d4b59bc --- /dev/null +++ b/.github/workflows/destroy.yml @@ -0,0 +1,78 @@ +name: Destroy Preview Environment + +on: + workflow_call: + inputs: + environment: + type: string + required: true + stage: + type: string + required: true + pr-number: + type: number + required: false + +permissions: + id-token: write + contents: read + pull-requests: write + +jobs: + build: + concurrency: ${{ inputs.environment }} + environment: ${{ inputs.environment }} + runs-on: ubuntu-latest + + steps: + - name: Check out repository code + uses: actions/checkout@v2 + + - name: Install AWS CDK + run: npm install -g aws-cdk + + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: arn:aws:iam::017820688988:role/Space2Stats-Deploy-Role + aws-region: ${{ vars.CDK_DEFAULT_REGION }} + + - name: Install CDK dependencies + working-directory: ./space2stats_api/cdk + run: | + pip install -r requirements-cdk.txt + + - name: Deploy CDK stack to staging + working-directory: ./space2stats_api/cdk + env: + STAGE: ${{ inputs.stage }} + PGHOST: ${{ secrets.PGHOST }} + PGPORT: ${{ secrets.PGPORT }} + PGDATABASE: ${{ secrets.PGDATABASE }} + PGUSER: ${{ secrets.PGUSER }} + PGPASSWORD: ${{ secrets.PGPASSWORD }} + PGTABLENAME: ${{ secrets.PGTABLENAME }} + CDK_CERTIFICATE_ARN: ${{ vars.CDK_CERTIFICATE_ARN }} + CDK_DEFAULT_ACCOUNT: ${{ vars.CDK_DEFAULT_ACCOUNT }} + CDK_DEFAULT_REGION: ${{ vars.CDK_DEFAULT_REGION }} + CDK_DOMAIN_NAME: ${{ vars.CDK_DOMAIN_NAME }} + run: cdk destroy --require-approval never + + - name: Find Comment + uses: peter-evans/find-comment@v3 + id: find-comment + if: ${{ inputs.pr-number }} + with: + issue-number: ${{ inputs.pr-number }} + comment-author: "github-actions[bot]" + body-includes: "PR Deployment Details:" + + - name: Create or update comment with URL + uses: peter-evans/create-or-update-comment@v4 + if: ${{ inputs.pr-number }} + with: + issue-number: ${{ inputs.pr-number }} + comment-id: ${{ steps.find-comment.outputs.comment-id }} + body: | + Removed PR Preview Environment. + edit-mode: append diff --git a/space2stats_api/cdk/aws_stack.py b/space2stats_api/cdk/aws_stack.py index b6b666d..66aaf2f 100644 --- a/space2stats_api/cdk/aws_stack.py +++ b/space2stats_api/cdk/aws_stack.py @@ -1,4 +1,4 @@ -from aws_cdk import Duration, Stack +from aws_cdk import CfnOutput, Duration, Stack from aws_cdk import aws_apigatewayv2 as apigatewayv2 from aws_cdk import aws_apigatewayv2_integrations as integrations from aws_cdk import aws_certificatemanager as acm @@ -48,13 +48,6 @@ def __init__( self, "Certificate", deployment_settings.CDK_CERTIFICATE_ARN ) - domain_name = apigatewayv2.DomainName( - self, - "DomainName", - domain_name=deployment_settings.CDK_DOMAIN_NAME, - certificate=certificate, - ) - http_api = apigatewayv2.HttpApi( self, "Space2StatsHttpApi", @@ -63,10 +56,24 @@ def __init__( ), ) - apigatewayv2.ApiMapping( + CfnOutput( self, - "ApiMapping", - api=http_api, - domain_name=domain_name, - stage=http_api.default_stage, + "ApiGatewayUrl", + key="ApiGatewayUrl", + value=http_api.url, ) + + if deployment_settings.CDK_DOMAIN_NAME: + domain_name = apigatewayv2.DomainName( + self, + "DomainName", + domain_name=deployment_settings.CDK_DOMAIN_NAME, + certificate=certificate, + ) + apigatewayv2.ApiMapping( + self, + "ApiMapping", + api=http_api, + domain_name=domain_name, + stage=http_api.default_stage, + ) diff --git a/space2stats_api/cdk/settings.py b/space2stats_api/cdk/settings.py index 9589b6d..83044aa 100644 --- a/space2stats_api/cdk/settings.py +++ b/space2stats_api/cdk/settings.py @@ -1,3 +1,5 @@ +from typing import Optional + from pydantic_settings import BaseSettings @@ -14,5 +16,5 @@ class DeploymentSettings(BaseSettings): CDK_DEFAULT_ACCOUNT: str CDK_DEFAULT_REGION: str CDK_CERTIFICATE_ARN: str - CDK_DOMAIN_NAME: str + CDK_DOMAIN_NAME: Optional[str] STAGE: str = "dev"