From af1720b6c3305ed317bb15ff2735ee220f51ef36 Mon Sep 17 00:00:00 2001 From: Adam Moussa <166072409+amoussa1229@users.noreply.github.com> Date: Mon, 18 May 2026 15:11:57 -0400 Subject: [PATCH] Refactor workflows to thin wrappers calling org reusable workflows CI jobs now call ci-dotnet, ci-typescript-cdk, and ci-python-sam from the org repo. Deploy calls cd-cdk with post-deploy script for web build/S3/CloudFront. Mobile deploy calls cd-mobile-ios. Adds deploy concurrency groups to both deploy workflows. --- .github/workflows/ci.yaml | 104 ++++++++------------------- .github/workflows/deploy-mobile.yaml | 54 ++++---------- .github/workflows/deploy.yaml | 91 ++++------------------- scripts/post-deploy.sh | 19 +++++ 4 files changed, 72 insertions(+), 196 deletions(-) create mode 100755 scripts/post-deploy.sh diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index b7c4f16..83cb14b 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -10,91 +10,43 @@ permissions: jobs: dotnet: name: .NET Build & Test - runs-on: ubuntu-latest - defaults: - run: - working-directory: api - steps: - - uses: actions/checkout@v6 - - - uses: actions/setup-dotnet@v5 - with: - dotnet-version: '8.0.x' - - - run: dotnet restore ProposalSystem.sln - - run: dotnet build ProposalSystem.sln --no-restore --configuration Release - - run: dotnet test ProposalSystem.sln --no-build --configuration Release + uses: Sea-Haven-Industries/.github/.github/workflows/ci-dotnet.yaml@main + with: + working-directory: api + solution: ProposalSystem.sln web: name: Web Frontend Check - runs-on: ubuntu-latest - defaults: - run: - working-directory: web - steps: - - uses: actions/checkout@v6 - - - uses: actions/setup-node@v6 - with: - node-version: 24 - cache: npm - cache-dependency-path: web/package-lock.json - - - run: npm ci - - run: npx tsc --noEmit + uses: Sea-Haven-Industries/.github/.github/workflows/ci-typescript-cdk.yaml@main + with: + working-directory: web + cache-dependency-path: web/package-lock.json + run-cdk-synth: false + run-conventions-check: false python: name: Python Lint - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - - - uses: actions/setup-python@v5 - with: - python-version: '3.12' - - - run: pip install ruff - - run: ruff check lambdas/ - - run: ruff format --check lambdas/ + uses: Sea-Haven-Industries/.github/.github/workflows/ci-python-sam.yaml@main + with: + source-dirs: "lambdas/" + run-sam-validate: false + run-conventions-check: false mobile: name: Mobile Typecheck - runs-on: ubuntu-latest - defaults: - run: - working-directory: mobile - steps: - - uses: actions/checkout@v6 - - - uses: actions/setup-node@v6 - with: - node-version: 24 - cache: npm - cache-dependency-path: mobile/package-lock.json - - - run: npm ci - - run: npx tsc --noEmit + uses: Sea-Haven-Industries/.github/.github/workflows/ci-typescript-cdk.yaml@main + with: + working-directory: mobile + cache-dependency-path: mobile/package-lock.json + run-cdk-synth: false + run-conventions-check: false infra: name: CDK Synth - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - - - uses: actions/setup-dotnet@v4 - with: - dotnet-version: '8.0.x' - - - name: Publish .NET API (required for CDK asset path) - run: dotnet publish api/src/ProposalSystem.Api/ProposalSystem.Api.csproj --configuration Release --runtime linux-arm64 --self-contained - - - uses: actions/setup-node@v6 - with: - node-version: 24 - cache: npm - cache-dependency-path: infra/package-lock.json - - - run: npm ci - working-directory: infra - - run: npx cdk synth - working-directory: infra + uses: Sea-Haven-Industries/.github/.github/workflows/ci-typescript-cdk.yaml@main + with: + working-directory: infra + cache-dependency-path: infra/package-lock.json + dotnet-version: "8.0.x" + dotnet-publish-project: api/src/ProposalSystem.Api/ProposalSystem.Api.csproj + run-typecheck: false diff --git a/.github/workflows/deploy-mobile.yaml b/.github/workflows/deploy-mobile.yaml index 94fd1eb..8ad0f5a 100644 --- a/.github/workflows/deploy-mobile.yaml +++ b/.github/workflows/deploy-mobile.yaml @@ -8,48 +8,20 @@ name: Deploy Mobile (iOS) on: workflow_dispatch: -permissions: - id-token: write - contents: read +concurrency: + group: deploy-mobile + cancel-in-progress: false jobs: deploy-ios: name: Build & Upload to TestFlight - runs-on: macos-latest - defaults: - run: - working-directory: mobile - timeout-minutes: 45 - steps: - - uses: actions/checkout@v6 - - - uses: aws-actions/configure-aws-credentials@v6 - with: - role-to-assume: ${{ secrets.AWS_DEPLOY_ROLE_ARN }} - aws-region: us-east-1 - - - uses: actions/setup-node@v6 - with: - node-version: 24 - cache: npm - cache-dependency-path: mobile/package-lock.json - - - uses: ruby/setup-ruby@v1 - with: - ruby-version: "3.3" - bundler-cache: true - working-directory: mobile - - - name: Install JS dependencies - run: npm ci - - - name: Install CocoaPods - run: bundle exec pod install --project-directory=ios - - - name: Build and upload to TestFlight - run: bundle exec fastlane ios beta - env: - MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }} - ASC_KEY_ID: ${{ secrets.ASC_KEY_ID }} - ASC_ISSUER_ID: ${{ secrets.ASC_ISSUER_ID }} - ASC_KEY_CONTENT: ${{ secrets.ASC_KEY_CONTENT }} + uses: Sea-Haven-Industries/.github/.github/workflows/cd-mobile-ios.yaml@main + with: + working-directory: mobile + cache-dependency-path: mobile/package-lock.json + secrets: + deploy-role-arn: ${{ secrets.AWS_DEPLOY_ROLE_ARN }} + match-password: ${{ secrets.MATCH_PASSWORD }} + asc-key-id: ${{ secrets.ASC_KEY_ID }} + asc-issuer-id: ${{ secrets.ASC_ISSUER_ID }} + asc-key-content: ${{ secrets.ASC_KEY_CONTENT }} diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml index 2c9db0c..5f7f4ee 100644 --- a/.github/workflows/deploy.yaml +++ b/.github/workflows/deploy.yaml @@ -4,86 +4,19 @@ on: push: branches: [main] -permissions: - id-token: write - contents: read +concurrency: + group: deploy-backend + cancel-in-progress: false jobs: deploy: name: Deploy to AWS - runs-on: ubuntu-latest - environment: production - steps: - - uses: actions/checkout@v6 - - - uses: actions/setup-node@v6 - with: - node-version: 24 - cache: npm - cache-dependency-path: infra/package-lock.json - - - uses: actions/setup-dotnet@v5 - with: - dotnet-version: '8.0.x' - - - uses: actions/setup-python@v5 - with: - python-version: '3.12' - - - uses: aws-actions/configure-aws-credentials@v6 - with: - role-to-assume: ${{ secrets.AWS_DEPLOY_ROLE_ARN }} - aws-region: us-east-1 - - # Build .NET API - - name: Build API - working-directory: api - run: | - dotnet publish src/ProposalSystem.Api/ProposalSystem.Api.csproj \ - --configuration Release \ - --runtime linux-arm64 \ - --self-contained false \ - --output src/ProposalSystem.Api/bin/Release/net8.0/linux-arm64/publish - - # Install Python dependencies for Lambdas - - name: Install PDF Extract deps - working-directory: lambdas/pdf-extract - run: pip install -r requirements.txt -t . - - - name: Install PDF Generate deps - working-directory: lambdas/pdf-generate - run: pip install -r requirements.txt -t . - - - name: Install Library Ingest deps - working-directory: lambdas/library-ingest - run: pip install -r requirements.txt -t . - - # CDK Deploy - - name: CDK Deploy - working-directory: infra - run: | - npm ci - npx cdk deploy --all --require-approval never - - # CloudFront Invalidation (after frontend deploy) - - name: Build Web Frontend - working-directory: web - run: | - npm ci - npm run build - - - name: Deploy Web to S3 - run: | - BUCKET=$(aws cloudformation describe-stacks \ - --stack-name proposal-system-frontend \ - --query "Stacks[0].Outputs[?OutputKey=='SiteBucketName'].OutputValue" \ - --output text) - aws s3 sync web/dist "s3://$BUCKET" --delete - - - name: Invalidate CloudFront - run: | - DIST_ID=$(aws cloudformation describe-stacks \ - --stack-name proposal-system-frontend \ - --query "Stacks[0].Outputs[?OutputKey=='DistributionId'].OutputValue" \ - --output text) - aws cloudfront create-invalidation --distribution-id "$DIST_ID" --paths "/*" + uses: Sea-Haven-Industries/.github/.github/workflows/cd-cdk.yaml@main + with: + cdk-dir: infra + dotnet-version: "8.0.x" + dotnet-publish-project: api/src/ProposalSystem.Api/ProposalSystem.Api.csproj + python-version: "3.12" + post-deploy-script: scripts/post-deploy.sh + secrets: + deploy-role-arn: ${{ secrets.AWS_DEPLOY_ROLE_ARN }} diff --git a/scripts/post-deploy.sh b/scripts/post-deploy.sh new file mode 100755 index 0000000..42dc379 --- /dev/null +++ b/scripts/post-deploy.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +set -euo pipefail + +cd web +npm ci +npm run build +cd .. + +BUCKET=$(aws cloudformation describe-stacks \ + --stack-name proposal-system-frontend \ + --query "Stacks[0].Outputs[?OutputKey=='SiteBucketName'].OutputValue" \ + --output text) +aws s3 sync web/dist "s3://$BUCKET" --delete + +DIST_ID=$(aws cloudformation describe-stacks \ + --stack-name proposal-system-frontend \ + --query "Stacks[0].Outputs[?OutputKey=='DistributionId'].OutputValue" \ + --output text) +aws cloudfront create-invalidation --distribution-id "$DIST_ID" --paths "/*"