Terraform AWS #110
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build, deploy and test | |
| on: | |
| push: | |
| branches: | |
| - main | |
| - qa | |
| pull_request: | |
| defaults: | |
| run: | |
| shell: bash | |
| env: | |
| TZ: "/usr/share/zoneinfo/America/Los_Angeles" | |
| CI_BRANCH: ${{ github.head_ref || github.ref_name }} | |
| BASE_BRANCH: ${{ github.base_ref }} | |
| jobs: | |
| build_dev: | |
| name: Build for development | |
| runs-on: ubuntu-latest | |
| container: | |
| image: ghcr.io/uceap/devcontainer-drupal:main | |
| if: github.head_ref != 'qa' && github.head_ref != 'main' | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ github.head_ref || github.ref_name }} | |
| fetch-depth: 0 | |
| - name: Prep for build | |
| run: composer -n dev-initialize-local | |
| - name: Build project for development | |
| run: composer -n install | |
| - name: Upload dev build artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| path: . | |
| name: dev-build | |
| include-hidden-files: true | |
| retention-days: 1 | |
| build_for_pantheon: | |
| name: Build for Pantheon | |
| runs-on: ubuntu-latest | |
| container: | |
| image: ghcr.io/uceap/devcontainer-drupal:main | |
| if: github.head_ref != 'qa' && github.head_ref != 'main' | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ github.head_ref || github.ref_name }} | |
| - name: Build project for deployment | |
| run: composer -n install --no-dev --optimize-autoloader | |
| - name: Remove files that should not be deployed | |
| run: | | |
| sed -n '/# *:.*cut.*:/,$p' .gitignore > ../deploy.gitignore | |
| git config --global --add safe.directory $GITHUB_WORKSPACE | |
| git ls-files -X ../deploy.gitignore -oi | xargs rm -rf | |
| find . -name .git -exec rm -rf {} + | |
| cp ../deploy.gitignore .gitignore | |
| - name: Upload deployment build artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| path: . | |
| name: deployment-build | |
| include-hidden-files: true | |
| retention-days: 1 | |
| build_for_aws: | |
| name: Build for AWS | |
| runs-on: ubuntu-latest | |
| if: github.ref_name == 'main' | |
| permissions: | |
| contents: read | |
| id-token: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Configure AWS credentials | |
| uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
| aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
| aws-region: ${{ vars.AWS_REGION }} | |
| - name: Log in to Amazon ECR | |
| uses: aws-actions/amazon-ecr-login@v2 | |
| with: | |
| mask-password: 'true' | |
| - name: Build and push container image to ECR | |
| uses: docker/build-push-action@v6 | |
| with: | |
| push: true | |
| tags: | | |
| ${{ vars.ECR_REPOSITORY_URL }}:${{ github.sha }} | |
| ${{ vars.ECR_REPOSITORY_URL }}:latest | |
| file: ./Dockerfile | |
| build-args: | | |
| MYSQL_HOST=${{ vars.AWS_MYSQL_HOST }} | |
| MYSQL_TCP_PORT=${{ vars.AWS_MYSQL_TCP_PORT }} | |
| MYSQL_USER=${{ vars.AWS_MYSQL_USER }} | |
| MYSQL_PASSWORD=${{ secrets.AWS_MYSQL_PASSWORD }} | |
| MYSQL_DATABASE=${{ vars.AWS_MYSQL_DATABASE }} | |
| REDIS_HOST=${{ vars.AWS_REDIS_HOST }} | |
| REDIS_AUTH=${{ secrets.AWS_REDIS_AUTH }} | |
| HASH_SALT=${{ secrets.AWS_HASH_SALT }} | |
| lint: | |
| name: Check lint | |
| needs: [build_dev] | |
| runs-on: ubuntu-latest | |
| container: | |
| image: ghcr.io/uceap/devcontainer-drupal:main | |
| steps: | |
| - name: Download build artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: dev-build | |
| # TODO think about using tar for our artifacts: https://github.com/actions/upload-artifact?tab=readme-ov-file#permission-loss | |
| - name: Fix file modes | |
| run: chmod +x ./vendor/bin/* | |
| - name: PHP lint project custom modules | |
| run: composer -n lint | |
| coding_standards: | |
| name: Coding standards | |
| needs: [build_dev] | |
| runs-on: ubuntu-latest | |
| container: | |
| image: ghcr.io/uceap/devcontainer-drupal:main | |
| steps: | |
| - name: Download build artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: dev-build | |
| - name: Fix file modes | |
| run: chmod +x ./vendor/bin/* | |
| - name: Fix dubious ownership error | |
| run: git config --global --add safe.directory $GITHUB_WORKSPACE | |
| - name: Check PHP coding standards for project custom modules and theme | |
| run: | | |
| if [ -n "$BASE_BRANCH" ]; then | |
| if ! git diff --quiet --diff-filter=d origin/$BASE_BRANCH... -- '*.php' '*.module' '*.inc' '*.install' '*.test' '*.profile' '*.theme' '*.info'; then | |
| composer -n code-sniff-feature | |
| else | |
| echo "No changes to relevant files." | |
| fi | |
| else | |
| composer -n code-sniff | |
| fi | |
| static_analysis: | |
| name: Static analysis | |
| needs: [build_dev] | |
| runs-on: ubuntu-latest | |
| container: | |
| image: ghcr.io/uceap/devcontainer-drupal:main | |
| steps: | |
| - name: Download build artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: dev-build | |
| - name: Fix file modes | |
| run: chmod +x ./vendor/bin/* | |
| - name: Fix dubious ownership error | |
| run: git config --global --add safe.directory $GITHUB_WORKSPACE | |
| - name: Run static analysis on custom modules and theme | |
| run: | | |
| if [ -n "$BASE_BRANCH" ]; then | |
| if ! git diff --quiet --diff-filter=d origin/$BASE_BRANCH... -- '*.php' '*.module' '*.inc' '*.install' '*.test' '*.profile' '*.theme' '*.info'; then | |
| composer -n static-analysis-feature | |
| else | |
| echo "No changes to relevant files." | |
| fi | |
| else | |
| composer -n static-analysis | |
| fi | |
| unit_test: | |
| name: Unit tests | |
| needs: [build_dev] | |
| runs-on: ubuntu-latest | |
| container: | |
| image: ghcr.io/uceap/devcontainer-drupal:main | |
| steps: | |
| - name: Download build artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: dev-build | |
| - name: Fix file modes | |
| run: chmod +x ./vendor/bin/* | |
| - name: Run unit tests | |
| run: composer -n unit-test | |
| prepare_pantheon: | |
| name: Prepare Pantheon | |
| runs-on: ubuntu-latest | |
| container: | |
| image: ghcr.io/uceap/devcontainer-drupal:main | |
| outputs: | |
| terminus_env: ${{ steps.determine_pantheon_env.outputs.terminus_env }} | |
| if: github.head_ref != 'qa' && github.head_ref != 'main' && github.actor != 'dependabot[bot]' | |
| steps: | |
| - name: Determine Pantheon environment | |
| id: determine_pantheon_env | |
| env: | |
| PR_NUMBER: ${{ github.event.pull_request.number }} | |
| run: | | |
| if [ -z "$PR_NUMBER" ]; then | |
| case "$CI_BRANCH" in | |
| main) export TERMINUS_ENV=dev ;; | |
| qa) export TERMINUS_ENV=qa ;; | |
| *) exit 1 ;; # we should never get here | |
| esac | |
| else | |
| export TERMINUS_ENV=pr-$PR_NUMBER | |
| fi | |
| echo TERMINUS_ENV=$TERMINUS_ENV >> $GITHUB_ENV | |
| echo terminus_env=$TERMINUS_ENV >> $GITHUB_OUTPUT | |
| - name: Load secrets | |
| uses: 1password/load-secrets-action@v2 | |
| with: | |
| export-env: true | |
| env: | |
| OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }} | |
| TERMINUS_TOKEN: op://secrets-example/pantheon-terminus/credential | |
| - name: Create Pantheon environment | |
| env: | |
| TERMINUS_SITE: ${{ vars.TERMINUS_SITE }} | |
| run: | | |
| terminus -n auth:login --machine-token="$TERMINUS_TOKEN" | |
| set +e | |
| terminus -n env:info --quiet; PANTHEON_SITE_EXISTS=$((!$?)) | |
| set -e | |
| if [ $PANTHEON_SITE_EXISTS -eq 0 ]; then | |
| terminus multidev:create $TERMINUS_SITE.dev $TERMINUS_ENV | |
| fi | |
| deploy_to_pantheon: | |
| name: Deploy to Pantheon | |
| needs: [build_for_pantheon, prepare_pantheon] | |
| runs-on: ubuntu-latest | |
| container: | |
| image: ghcr.io/uceap/devcontainer-drupal:main | |
| steps: | |
| - name: Download build artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: deployment-build | |
| - name: Fix file modes | |
| run: find vendor/bin -type f | xargs chmod +x | |
| - name: Load secrets | |
| uses: 1password/load-secrets-action@v2 | |
| with: | |
| export-env: true | |
| env: | |
| OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }} | |
| TERMINUS_TOKEN: op://secrets-example/pantheon-terminus/credential | |
| SSH_PRIVATE_KEY: op://secrets-example/pantheon-ssh/private key | |
| - name: deploy to Pantheon | |
| env: | |
| TERMINUS_SITE: ${{ vars.TERMINUS_SITE }} | |
| TERMINUS_ENV: ${{ needs.prepare_pantheon.outputs.terminus_env }} | |
| run: | | |
| echo "$SSH_PRIVATE_KEY" > ../private.key | |
| chmod 600 ../private.key | |
| eval `ssh-agent -s` | |
| ssh-add ../private.key | |
| if [ $TERMINUS_ENV == "dev" ]; then | |
| uceap deploy-to-dev | |
| else | |
| uceap deploy-to-multidev | |
| fi | |
| deploy_to_aws: | |
| name: Deploy to AWS | |
| if: github.ref_name == 'main' | |
| runs-on: ubuntu-latest | |
| needs: [build_for_aws] | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Configure AWS credentials | |
| uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
| aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
| aws-region: ${{ vars.AWS_REGION }} | |
| - name: Update ECS service with new image | |
| run: | | |
| # Get the current task definition | |
| TASK_DEF=$(aws ecs describe-task-definition \ | |
| --task-definition ${{ vars.AWS_ECS_TASK_DEFINITION }} \ | |
| --region ${{ vars.AWS_REGION }} \ | |
| --query 'taskDefinition' --output json) | |
| # Update the image in the task definition | |
| NEW_TASK_DEF=$(echo "$TASK_DEF" | jq \ | |
| --arg IMAGE "${{ vars.ECR_REPOSITORY_URL }}:${{ github.sha }}" \ | |
| '.containerDefinitions[0].image = $IMAGE | | |
| del(.taskDefinitionArn, .revision, .status, .requiresAttributes, .compatibilities, .registeredAt, .registeredBy)') | |
| # Register the new task definition | |
| NEW_TASK_DEF_ARN=$(aws ecs register-task-definition \ | |
| --region ${{ vars.AWS_REGION }} \ | |
| --cli-input-json "$(echo "$NEW_TASK_DEF" | jq -c .)" \ | |
| --query 'taskDefinition.taskDefinitionArn' \ | |
| --output text) | |
| # Update the ECS service to use the new task definition | |
| aws ecs update-service \ | |
| --cluster ${{ vars.AWS_ECS_CLUSTER }} \ | |
| --service ${{ vars.AWS_ECS_SERVICE }} \ | |
| --task-definition "$NEW_TASK_DEF_ARN" \ | |
| --region ${{ vars.AWS_REGION }} \ | |
| --force-new-deployment | |
| e2e_test: | |
| name: Feature tests | |
| needs: [deploy_to_pantheon] | |
| runs-on: ubuntu-latest | |
| if: ${{ github.actor != 'dependabot[bot]' && github.ref_name != 'main' }} | |
| steps: | |
| - name: Run Cypress | |
| run: echo "This is where the Cypress tests would run." |