diff --git a/.github/workflows/build-push-ecr.yml b/.github/workflows/build-push-ecr.yml deleted file mode 100644 index c514981..0000000 --- a/.github/workflows/build-push-ecr.yml +++ /dev/null @@ -1,186 +0,0 @@ -name: Build and Push to ECR - -on: - workflow_dispatch: - -permissions: - id-token: write - contents: read - -jobs: - validate: - name: Validation & Security - if: github.ref == 'refs/heads/main' - runs-on: ubuntu-latest - steps: - - name: Checkout Source Code - uses: actions/checkout@v4 - - - name: Set up Node.js Environment - uses: actions/setup-node@v4 - with: - node-version: '24' - cache: 'npm' - - - name: Authenticate to AWS - uses: aws-actions/configure-aws-credentials@v4 - with: - role-to-assume: ${{ secrets.AWS_CI_ROLE_ARN }} - aws-region: ap-southeast-1 - - - name: Get SSM Parameters - Key Value Pairs - id: ssm-param - uses: Armadillidiid/ssm-get-parameters-action@v1 - with: - by-path: true - secret: /durianpy/cms/prod/ - with-decryption: true - mask-values: true - recursive: true - - - name: Install Project Dependencies - run: npm ci --legacy-peer-deps - - - name: Static Analysis (NPM Vulnerability Scan) - uses: aquasecurity/trivy-action@a9c7b0f06e461e9d4b4d1711f154ee024b8d7ab8 # v0.36.0 - with: - scan-type: 'fs' - scan-ref: '.' - format: 'table' - output: 'trivy-fs-report.txt' - severity: 'CRITICAL,HIGH' - - - name: Publish FS Scan to Summary - if: always() - run: | - echo "### 🛡️ Filesystem Security Scan" >> $GITHUB_STEP_SUMMARY - if [ -s trivy-fs-report.txt ]; then - echo "\`\`\`text" >> $GITHUB_STEP_SUMMARY - cat trivy-fs-report.txt >> $GITHUB_STEP_SUMMARY - echo "\`\`\`" >> $GITHUB_STEP_SUMMARY - else - echo "No high/critical vulnerabilities found." >> $GITHUB_STEP_SUMMARY - fi - - - name: Lint Codebase - run: npm run lint - - - name: Execute Integration Tests - env: - PAYLOAD_SECRET: ${{ steps.ssm-param.outputs.PAYLOAD_SECRET }} - DATABASE_URL: ${{ steps.ssm-param.outputs.DATABASE_URL }} - run: npm run test:int - - deploy: - name: Build & Production Deploy - needs: validate - runs-on: ubuntu-latest - steps: - - name: Checkout Source Code - uses: actions/checkout@v4 - - - name: Authenticate to AWS - uses: aws-actions/configure-aws-credentials@v4 - with: - role-to-assume: ${{ secrets.AWS_CI_ROLE_ARN }} - aws-region: ap-southeast-1 - - - name: Login to Amazon ECR - id: login-ecr - uses: aws-actions/amazon-ecr-login@v2 - - - name: Set up Node.js Environment - uses: actions/setup-node@v4 - with: - node-version: '24' - cache: 'npm' - - - name: Get SSM Parameters for Deployment - id: ssm-param - uses: Armadillidiid/ssm-get-parameters-action@v1 - with: - by-path: true - secret: /durianpy/cms/prod/ - with-decryption: true - mask-values: true - recursive: true - - - name: Install Dependencies and Build - env: - ENVIRONMENT: 'production' - PAYLOAD_SECRET: ${{ steps.ssm-param.outputs.PAYLOAD_SECRET }} - DATABASE_URL: ${{ steps.ssm-param.outputs.DATABASE_URL }} - NEXT_PUBLIC_SERVER_URL: ${{ steps.ssm-param.outputs.NEXT_PUBLIC_SERVER_URL }} - CLOUDFRONT_DISTRIBUTION_DOMAIN: ${{ steps.ssm-param.outputs.CLOUDFRONT_DISTRIBUTION_DOMAIN }} - run: | - npm ci --legacy-peer-deps - npm run build - - - name: Sync Static Assets to S3 - run: | - aws s3 sync .next/static s3://${{ steps.ssm-param.outputs.S3_BUCKET }}/artifacts/_next/static --delete - aws s3 sync public s3://${{ steps.ssm-param.outputs.S3_BUCKET }}/public --delete - - - name: Fetch Lambda Layer URL - id: layer-url - run: | - LAYER_URL=$(aws lambda get-layer-version-by-arn --arn arn:aws:lambda:ap-southeast-1:044395824272:layer:AWS-Parameters-and-Secrets-Lambda-Extension:61 --query 'Content.Location' --output text) - echo "url=$LAYER_URL" >> $GITHUB_OUTPUT - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Build Image - uses: docker/build-push-action@v6 - with: - context: . - file: docker/lambda/Dockerfile - load: true - tags: | - ${{ steps.login-ecr.outputs.registry }}/durianpy-cms-prod:${{ github.sha }} - secrets: | - payload_secret=${{ steps.ssm-param.outputs.PAYLOAD_SECRET }} - database_url=${{ steps.ssm-param.outputs.DATABASE_URL }} - cloudfront_domain=${{ steps.ssm-param.outputs.CLOUDFRONT_DISTRIBUTION_DOMAIN }} - s3_bucket=${{ steps.ssm-param.outputs.S3_BUCKET }} - next_public_server_url=${{ steps.ssm-param.outputs.NEXT_PUBLIC_SERVER_URL }} - build-args: | - LAYER_URL=${{ steps.layer-url.outputs.url }} - AWS_DEFAULT_REGION=ap-southeast-1 - ENVIRONMENT=production - - - name: Image Scan (Container Check) - uses: aquasecurity/trivy-action@a9c7b0f06e461e9d4b4d1711f154ee024b8d7ab8 # v0.36.0 - with: - image-ref: ${{ steps.login-ecr.outputs.registry }}/durianpy-cms-prod:${{ github.sha }} - format: 'table' - output: 'trivy-image-report.txt' - severity: 'CRITICAL,HIGH' - exit-code: '0' # Temporarily allow build to pass even if vulnerabilities are found, but report them. - - - name: Push Image - if: success() - run: | - docker push ${{ steps.login-ecr.outputs.registry }}/durianpy-cms-prod:${{ github.sha }} - - - name: Summarize Build and Scan - if: always() - run: | - echo "### 🚢 Deployment Summary" >> $GITHUB_STEP_SUMMARY - echo "Image: \`${{ steps.login-ecr.outputs.registry }}/durianpy-cms-prod:${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY - - echo "### 🛡️ Container Image Scan" >> $GITHUB_STEP_SUMMARY - if [ -s trivy-image-report.txt ]; then - echo "\`\`\`text" >> $GITHUB_STEP_SUMMARY - cat trivy-image-report.txt >> $GITHUB_STEP_SUMMARY - echo "\`\`\`" >> $GITHUB_STEP_SUMMARY - else - echo "No high/critical vulnerabilities found." >> $GITHUB_STEP_SUMMARY - fi - - - name: Deploy to AWS Lambda - if: success() - run: | - aws lambda update-function-code \ - --function-name durianpy-cms-prod \ - --image-uri ${{ steps.login-ecr.outputs.registry }}/durianpy-cms-prod:${{ github.sha }}