content-release #16956
This file contains 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: Content Release | |
on: | |
repository_dispatch: | |
types: [content-release] | |
workflow_dispatch: | |
concurrency: | |
group: content-release-prod | |
env: | |
CMS_NOTIFICATIONS_SLACK: CJT90C0UT # cms-notifications | |
VFS_PLATFORM_BUILDS_SLACK: C0MQ281DJ # vfs-platform-builds | |
BROKEN_LINKS_SLACK: C030F5WV2TF # content-broken-links | |
CONTENT_BUILD_CHANNEL_ID: C02VD909V08 #status-content-build | |
NODE_EXTRA_CA_CERTS: /etc/ssl/certs/ca-certificates.crt | |
BUILDTYPE: vagovprod | |
DEPLOY_BUCKET: content.www.va.gov | |
DRUPAL_ADDRESS: https://prod.cms.va.gov | |
INSTANCE_TYPE: m6i.4xlarge | |
MAXIMUM_HEAP: 8192 | |
# secrets.ACTIONS_RUNNER_DEBUG is set to 'true' when re-running a workflow with debug. | |
ACTIONS_RUNNER_DEBUG: ${{ secrets.ACTIONS_RUNNER_DEBUG }} | |
jobs: | |
validate-build-status: | |
name: Validate Build Status | |
runs-on: [self-hosted, asg] | |
outputs: | |
REF: ${{ steps.get-latest-release.outputs.target_commitish }} | |
TAG: ${{ steps.get-latest-release.outputs.tag_name }} | |
APPROX_WORKFLOW_START_TIME: ${{ steps.export-approx-workflow-start-time.outputs.APPROX_WORKFLOW_START_TIME }} | |
timeout-minutes: 15 | |
steps: | |
- name: Export approximate workflow start time | |
id: export-approx-workflow-start-time | |
run: echo APPROX_WORKFLOW_START_TIME=$(date +"%s") >> $GITHUB_OUTPUT | |
- name: Checkout | |
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 | |
- name: Wait for the CMS to be ready | |
uses: ./.github/workflows/wait-for-cms-ready | |
- name: Notify CMS - Starting | |
uses: ./.github/workflows/authenticated-cms-request | |
with: | |
aws_access_key_id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
aws_secret_access_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
url: ${{ env.DRUPAL_ADDRESS }}/api/content_release/starting | |
method: GET | |
- name: Install dependencies | |
uses: ./.github/workflows/install | |
with: | |
key: ${{ hashFiles('yarn.lock') }} | |
yarn_cache_folder: ~/.cache/yarn | |
path: | | |
~/.cache/yarn | |
node_modules | |
- name: Get latest release | |
id: get-latest-release | |
uses: ./.github/workflows/fetch-latest-release | |
- name: Validate build status | |
run: node ./script/github-actions/validate-build-status.js ${{ steps.get-latest-release.outputs.target_commitish }} | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
notify-start-slack: | |
name: Notify Start (Slack) | |
runs-on: [self-hosted, asg] | |
needs: validate-build-status | |
steps: | |
- name: Checkout | |
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 | |
- name: Notify Slack | |
uses: department-of-veterans-affairs/platform-release-tools-actions/slack-notify@8c496a4b0c9158d18edcd9be8722ed0f79e8c5b4 # main | |
continue-on-error: true | |
with: | |
payload: '{"attachments": [{"color": "#2EB67D","blocks": [{"type": "section","text": {"type": "mrkdwn","text": "Stand by, content release for content-build coming up (using ${{ needs.validate-build-status.outputs.TAG }}). <https://github.com/${{github.repository}}/actions/runs/${{github.run_id}}>"}}]}]}' | |
channel_id: ${{ env.CONTENT_BUILD_CHANNEL_ID }} | |
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
build: | |
name: Build | |
runs-on: [self-hosted, asg] | |
needs: | |
- validate-build-status | |
timeout-minutes: 75 | |
defaults: | |
run: | |
working-directory: content-build | |
outputs: | |
vagovprod_buildtime: ${{ env.vagovprod_buildtime }} | |
BUILD_START_TIME: ${{ steps.export-build-start-time.outputs.BUILD_START_TIME }} | |
BUILD_END_TIME: ${{ steps.export-build-end-time.outputs.BUILD_END_TIME }} | |
CONTENT_BUILD_START_TIME: ${{ steps.export-content-build-start-time.outputs.CONTENT_BUILD_START_TIME }} | |
CONTENT_BUILD_END_TIME: ${{ steps.export-content-build-end.outputs.CONTENT_BUILD_END_TIME }} | |
GQL_QUERY_DURATION: ${{ steps.export-gql-query-duration.outputs.GQL_QUERY_DURATION }} | |
GQL_PAGE_COUNT: ${{ steps.export-gql-page-count.outputs.GQL_PAGE_COUNT }} | |
ARCHIVE_END_TIME: ${{ steps.export-archive-end-time.outputs.ARCHIVE_END_TIME }} | |
BROKEN_LINK_COUNT: ${{ steps.get-broken-link-info.outputs.BROKEN_LINK_COUNT || 0 }} | |
env: | |
CHROMEDRIVER_FILEPATH: /usr/local/share/chrome_driver/chromedriver | |
steps: | |
- name: Export build start time | |
id: export-build-start-time | |
run: echo BUILD_START_TIME=$(date +"%s") >> $GITHUB_OUTPUT | |
working-directory: ${{ github.workspace }} | |
- name: Checkout vagov-content | |
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 | |
with: | |
repository: department-of-veterans-affairs/vagov-content | |
path: vagov-content | |
- name: Checkout content-build | |
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 | |
with: | |
path: content-build | |
ref: ${{ needs.validate-build-status.outputs.REF }} | |
- name: Get Node version | |
id: get-node-version | |
run: echo NODE_VERSION=$(cat .nvmrc) >> $GITHUB_OUTPUT | |
- name: Setup Node | |
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 | |
with: | |
node-version: ${{ steps.get-node-version.outputs.NODE_VERSION }} | |
- name: Setup Yarn | |
run: npm i -g [email protected] | |
- name: Cache dependencies | |
id: cache-dependencies | |
uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 | |
with: | |
path: | | |
.cache/yarn | |
**/node_modules | |
key: ${{ steps.get-node-version.outputs.NODE_VERSION }}-on-demand-runner-${{ hashFiles('**/yarn.lock') }} | |
restore-keys: ${{ steps.get-node-version.outputs.NODE_VERSION }}-on-demand-runner- | |
- name: Install dependencies | |
uses: nick-invision/retry@943e742917ac94714d2f408a0e8320f2d1fcafcd # v2.8.3 | |
with: | |
command: cd content-build && yarn install --frozen-lockfile --prefer-offline | |
max_attempts: 3 | |
timeout_minutes: 7 | |
env: | |
YARN_CACHE_FOLDER: .cache/yarn | |
- name: Wait for the CMS to be ready | |
uses: ./content-build/.github/workflows/wait-for-cms-ready | |
- name: Export content build start time | |
id: export-content-build-start-time | |
run: echo CONTENT_BUILD_START_TIME=$(date +"%s") >> $GITHUB_OUTPUT | |
working-directory: ${{ github.workspace }} | |
- name: Get buildtime | |
id: buildtime | |
run: | | |
BUILDTIME=$(date +%s) | |
echo buildtime=$BUILDTIME >> $GITHUB_OUTPUT | |
echo "${{ env.BUILDTYPE }}_buildtime=$BUILDTIME" >> $GITHUB_ENV | |
- name: Configure AWS Credentials | |
uses: aws-actions/configure-aws-credentials@e1e17a757e536f70e52b5a12b2e8d1d1c60e04ef # v2.0.0 | |
with: | |
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
aws-region: us-gov-west-1 | |
- name: set Drupal prod password | |
uses: department-of-veterans-affairs/action-inject-ssm-secrets@d8e6de3bde4dd728c9d732baef58b3c854b8c4bb # latest | |
with: | |
ssm_parameter: /cms/prod/drupal_api_users/content_build_api/password | |
env_variable_name: DRUPAL_PASSWORD | |
- name: set Drupal prod username | |
uses: department-of-veterans-affairs/action-inject-ssm-secrets@d8e6de3bde4dd728c9d732baef58b3c854b8c4bb # latest | |
with: | |
ssm_parameter: /cms/prod/drupal_api_users/content_build_api/username | |
env_variable_name: DRUPAL_USERNAME | |
- name: Notify CMS - In Progress | |
uses: ./content-build/.github/workflows/authenticated-cms-request | |
with: | |
aws_access_key_id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
aws_secret_access_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
url: ${{ env.DRUPAL_ADDRESS }}/api/content_release/inprogress | |
method: GET | |
- name: Get verbose level | |
if: ${{ env.ACTIONS_RUNNER_DEBUG == 'true' }} | |
run: echo "VERBOSE_BUILD= --verbose" >> $GITHUB_ENV | |
- name: Build | |
run: | | |
set -eo pipefail | |
NODE_OPTIONS=--max-old-space-size=${{ env.MAXIMUM_HEAP }} yarn build:content_release --buildtype=${{ env.BUILDTYPE }} --asset-source=local --drupal-address=${{ env.DRUPAL_ADDRESS }} --drupal-user=${{ env.DRUPAL_USERNAME }} --drupal-password="${{ env.DRUPAL_PASSWORD }}" --pull-drupal --drupal-max-parallel-requests=15 --no-drupal-proxy ${{env.VERBOSE_BUILD}} | tee build-output.txt | |
env: | |
NODE_ENV: production | |
DEBUG: ${{ secrets.ACTIONS_RUNNER_DEBUG }} | |
- name: Export content build end time | |
id: export-content-build-end | |
run: echo CONTENT_BUILD_END_TIME=$(date +"%s") >> $GITHUB_OUTPUT | |
working-directory: ${{ github.workspace }} | |
- name: Export gql query duration | |
id: export-gql-query-duration | |
run: echo GQL_QUERY_DURATION=$(cat build-output.txt | grep -oP 'queries in \d+s' | grep -oP '\d+') >> $GITHUB_OUTPUT | |
- name: Export gql page count | |
id: export-gql-page-count | |
run: echo GQL_PAGE_COUNT=$(cat build-output.txt | grep -oP 'with \d+ pages' | grep -oP '\d+') >> $GITHUB_OUTPUT | |
- name: Set vars for CMS-triggered runs | |
if: ${{ github.event_name == 'repository_dispatch' }} | |
run: | | |
echo "DEPLOY_ENV=prod" >> $GITHUB_ENV | |
echo "BUILD_TRIGGER=cms" >> $GITHUB_ENV | |
- name: Build JSON object for step metrics | |
run: | | |
cat build/${{env.BUILDTYPE}}/metalsmith-step-metrics.json | \ | |
jq '.series[].tags[0] = "env:${{env.DEPLOY_ENV}}"' | \ | |
jq '.series[].tags[1] = "build_number:${{github.run_number}}"' | \ | |
jq '.series[].tags[2] = "instance_type:${{env.INSTANCE_TYPE}}"' | \ | |
jq '.series[].tags[3] = "heap_size:${{env.MAXIMUM_HEAP}}"' | \ | |
jq '.series[].tags[4] = "trigger:${{env.BUILD_TRIGGER}}"' > metrics.json | |
- name: Get Datadog api key from Parameter Store | |
uses: department-of-veterans-affairs/action-inject-ssm-secrets@d8e6de3bde4dd728c9d732baef58b3c854b8c4bb # latest | |
with: | |
ssm_parameter: /dsva-vagov/content-build/GHA_CONTENT_BUILD_DATADOG_API_KEY | |
env_variable_name: GHA_CONTENT_BUILD_DATADOG_API_KEY | |
- name: Send metrics to Datadog | |
run: | | |
curl -X POST "https://api.ddog-gov.com/api/v1/series" \ | |
-H "Content-Type: text/json" \ | |
-H "DD-API-KEY: ${{ env.GHA_CONTENT_BUILD_DATADOG_API_KEY }}" \ | |
-d @- < metrics.json | |
- name: Check broken links | |
id: get-broken-link-info | |
run: node ./script/github-actions/check-broken-links-blocks.js ${{ env.BUILDTYPE }} | |
- name: Configure AWS credentials | |
uses: aws-actions/configure-aws-credentials@e1e17a757e536f70e52b5a12b2e8d1d1c60e04ef # v2.0.0 | |
if: ${{ steps.get-broken-link-info.outputs.UPLOAD_AND_NOTIFY == '1' && always() }} | |
with: | |
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
aws-region: us-gov-west-1 | |
- name: Get Slack app token | |
uses: department-of-veterans-affairs/action-inject-ssm-secrets@d8e6de3bde4dd728c9d732baef58b3c854b8c4bb # latest | |
if: ${{ steps.get-broken-link-info.outputs.UPLOAD_AND_NOTIFY == '1' && always() }} | |
with: | |
ssm_parameter: /devops/github_actions_slack_socket_token | |
env_variable_name: SLACK_APP_TOKEN | |
- name: Get Slack bot token | |
uses: department-of-veterans-affairs/action-inject-ssm-secrets@d8e6de3bde4dd728c9d732baef58b3c854b8c4bb # latest | |
if: ${{ steps.get-broken-link-info.outputs.UPLOAD_AND_NOTIFY == '1' && always() }} | |
with: | |
ssm_parameter: /devops/github_actions_slack_bot_user_token | |
env_variable_name: SLACK_BOT_TOKEN | |
- name: Get role from Parameter Store | |
uses: department-of-veterans-affairs/action-inject-ssm-secrets@d8e6de3bde4dd728c9d732baef58b3c854b8c4bb # latest | |
if: ${{ steps.get-broken-link-info.outputs.UPLOAD_AND_NOTIFY == '1' && always() }} | |
with: | |
ssm_parameter: /frontend-team/github-actions/parameters/AWS_FRONTEND_NONPROD_ROLE | |
env_variable_name: AWS_FRONTEND_NONPROD_ROLE | |
- name: Configure AWS Credentials | |
uses: aws-actions/configure-aws-credentials@e1e17a757e536f70e52b5a12b2e8d1d1c60e04ef # v2.0.0 | |
if: ${{ steps.get-broken-link-info.outputs.UPLOAD_AND_NOTIFY == '1' && always() }} | |
with: | |
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
aws-region: us-gov-west-1 | |
role-to-assume: ${{ env.AWS_FRONTEND_NONPROD_ROLE }} | |
role-duration-seconds: 900 | |
role-session-name: vsp-frontendteam-githubaction | |
- name: Upload broken links file | |
if: ${{ steps.get-broken-link-info.outputs.UPLOAD_AND_NOTIFY == '1' && always() }} | |
run: aws s3 cp ./logs/${{ env.BUILDTYPE }}-broken-links.json s3://vetsgov-website-builds-s3-upload/broken-link-reports/${{ env.BUILDTYPE }}-broken-links.json --acl public-read --region us-gov-west-1 | |
- name: Notify content broken links channel about broken links | |
uses: slackapi/slack-github-action@007b2c3c751a190b6f0f040e47ed024deaa72844 # v1.23.0 | |
id: notify-content-broken-links | |
if: ${{ steps.get-broken-link-info.outputs.UPLOAD_AND_NOTIFY == '1' && always() }} | |
continue-on-error: true | |
env: | |
SSL_CERT_DIR: /etc/ssl/certs | |
SLACK_BOT_TOKEN: ${{ env.SLACK_BOT_TOKEN }} | |
with: | |
payload: ${{ steps.get-broken-link-info.outputs.SLACK_BLOCKS }} | |
channel-id: ${{ env.BROKEN_LINKS_SLACK }} | |
- name: Generate build details | |
run: | | |
cat > build/${{ env.BUILDTYPE }}/BUILD.txt << EOF | |
BUILDTYPE=${{ env.BUILDTYPE }} | |
NODE_ENV=production | |
BRANCH_NAME=$(echo "${GITHUB_REF#refs/heads/}") | |
CHANGE_TARGET=null | |
RUN_ID=${{ github.run_id }} | |
RUN_NUMBER=${{ github.run_number }} | |
REF=${{ needs.validate-build-status.outputs.REF }} | |
TAG=${{ needs.validate-build-status.outputs.TAG }} | |
BUILDTIME=${{ steps.buildtime.outputs.buildtime }} | |
EOF | |
- name: Prearchive | |
run: node ./script/prearchive.js --buildtype=${{ env.BUILDTYPE }} | |
- name: Compress build | |
run: tar -C build/${{ env.BUILDTYPE }} -cf ${{ env.BUILDTYPE }}.tar.bz2 . | |
- name: Export build end time | |
id: export-build-end-time | |
run: echo BUILD_END_TIME=$(date +"%s") >> $GITHUB_OUTPUT | |
working-directory: ${{ github.workspace }} | |
# Archive build by uploading it to S3 | |
- name: Show build archive size | |
run: | | |
df -h | |
du -h ${{ env.BUILDTYPE }}.tar.bz2 | |
- name: Configure AWS credentials (1) | |
uses: aws-actions/configure-aws-credentials@e1e17a757e536f70e52b5a12b2e8d1d1c60e04ef # v2.0.0 | |
with: | |
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
aws-region: us-gov-west-1 | |
- name: Get role from Parameter Store | |
uses: department-of-veterans-affairs/action-inject-ssm-secrets@d8e6de3bde4dd728c9d732baef58b3c854b8c4bb # latest | |
with: | |
ssm_parameter: /frontend-team/github-actions/parameters/AWS_FRONTEND_NONPROD_ROLE | |
env_variable_name: AWS_FRONTEND_NONPROD_ROLE | |
- name: Configure AWS Credentials (2) | |
uses: aws-actions/configure-aws-credentials@e1e17a757e536f70e52b5a12b2e8d1d1c60e04ef # v2.0.0 | |
with: | |
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
aws-region: us-gov-west-1 | |
role-to-assume: ${{ env.AWS_FRONTEND_NONPROD_ROLE }} | |
role-duration-seconds: 900 | |
role-session-name: vsp-frontendteam-githubaction | |
- name: Upload build | |
run: aws s3 cp ${{ env.BUILDTYPE }}.tar.bz2 s3://vetsgov-website-builds-s3-upload/content-build/${{needs.validate-build-status.outputs.REF}}/${{ env.BUILDTYPE }}.tar.bz2 --acl public-read --region us-gov-west-1 --no-progress | |
- name: Delete build | |
run: rm ${{ env.BUILDTYPE }}.tar.bz2 | |
- name: Debug filesystem size | |
run: | | |
pwd | |
du -a . | sort -n -r | head -n 10 | |
du -a /home/runner/ | sort -n -r | head -n 10 | |
find /home/runner/ -type f -printf '%s %p\n' | sort -nr | head | |
- name: Export archive end time | |
id: export-archive-end-time | |
run: echo ARCHIVE_END_TIME=$(date +"%s") >> $GITHUB_OUTPUT | |
deploy: | |
name: Deploy | |
runs-on: [self-hosted, asg] | |
needs: | |
- validate-build-status | |
- build | |
outputs: | |
DEPLOY_END_TIME: ${{ steps.export-deploy-end-time.outputs.DEPLOY_END_TIME }} | |
timeout-minutes: 25 | |
steps: | |
- name: Debug filesystem size | |
run: | | |
pwd | |
du -a . | sort -n -r | head -n 10 | |
du -a /home/runner/ | sort -n -r | head -n 10 | |
find /home/runner/ -type f -printf '%s %p\n' | sort -nr | head | |
- name: Checkout | |
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 | |
- name: Configure AWS credentials (1) | |
uses: aws-actions/configure-aws-credentials@e1e17a757e536f70e52b5a12b2e8d1d1c60e04ef # v2.0.0 | |
with: | |
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
aws-region: us-gov-west-1 | |
- name: Get role from Parameter Store | |
uses: department-of-veterans-affairs/action-inject-ssm-secrets@d8e6de3bde4dd728c9d732baef58b3c854b8c4bb # latest | |
with: | |
ssm_parameter: /frontend-team/github-actions/parameters/AWS_FRONTEND_PROD_ROLE | |
env_variable_name: AWS_FRONTEND_PROD_ROLE | |
- name: Configure AWS Credentials (2) | |
uses: aws-actions/configure-aws-credentials@e1e17a757e536f70e52b5a12b2e8d1d1c60e04ef # v2.0.0 | |
with: | |
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
aws-region: us-gov-west-1 | |
role-to-assume: ${{ env.AWS_FRONTEND_PROD_ROLE }} | |
role-duration-seconds: 900 | |
role-session-name: vsp-frontendteam-githubaction | |
- name: Deploy | |
run: ./script/github-actions/deploy.sh -s $SRC -d $DEST -v | |
env: | |
SRC: s3://vetsgov-website-builds-s3-upload/content-build/${{needs.validate-build-status.outputs.REF}}/${{env.BUILDTYPE}}.tar.bz2 | |
DEST: s3://${{ env.DEPLOY_BUCKET }} | |
- name: Wait for the CMS to be ready | |
uses: ./.github/workflows/wait-for-cms-ready | |
- name: Notify CMS - Complete | |
uses: ./.github/workflows/authenticated-cms-request | |
with: | |
aws_access_key_id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
aws_secret_access_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
url: ${{ env.DRUPAL_ADDRESS }}/api/content_release/complete | |
method: GET | |
- name: CMS GovDelivery callback | |
uses: ./.github/workflows/authenticated-cms-request | |
with: | |
aws_access_key_id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
aws_secret_access_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
url: ${{ env.DRUPAL_ADDRESS }}/api/govdelivery_bulletins/queue?EndTime=${{ needs.build.outputs.vagovprod_buildtime }}&src=gha&runId=${{ github.run_id }}&runNumber=${{ github.run_number }} | |
method: GET | |
# A failure here should not prevent the workflow from continuing. | |
continue-on-error: true | |
- name: Export deploy end time | |
id: export-deploy-end-time | |
run: echo DEPLOY_END_TIME=$(date +"%s") >> $GITHUB_OUTPUT | |
notify-success: | |
name: Notify Success | |
runs-on: [self-hosted, asg] | |
needs: | |
- validate-build-status | |
- deploy | |
steps: | |
- name: Checkout | |
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 | |
- name: Wait for the CMS to be ready | |
uses: ./.github/workflows/wait-for-cms-ready | |
- name: Notify CMS - Ready | |
uses: ./.github/workflows/authenticated-cms-request | |
with: | |
aws_access_key_id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
aws_secret_access_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
url: ${{ env.DRUPAL_ADDRESS }}/api/content_release/ready | |
method: GET | |
notify-success-slack: | |
name: Notify Success (Slack) | |
runs-on: [self-hosted, asg] | |
needs: | |
- validate-build-status | |
- deploy | |
steps: | |
- name: Notify Slack | |
uses: department-of-veterans-affairs/platform-release-tools-actions/slack-notify@8c496a4b0c9158d18edcd9be8722ed0f79e8c5b4 # | |
continue-on-error: true | |
with: | |
payload: '{"attachments": [{"color": "#2EB67D","blocks": [{"type": "section","text": {"type": "mrkdwn","text": "content release using ${{ needs.validate-build-status.outputs.TAG }} is complete."}}]}]}' | |
channel_id: ${{ env.CONTENT_BUILD_CHANNEL_ID }} | |
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
notify-success-datadog: | |
name: Notify Success (Datadog) | |
runs-on: [self-hosted, asg] | |
needs: | |
- validate-build-status | |
- deploy | |
steps: | |
- name: Checkout | |
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 | |
- name: Configure AWS credentials | |
uses: aws-actions/configure-aws-credentials@e1e17a757e536f70e52b5a12b2e8d1d1c60e04ef # v2.0.0 | |
with: | |
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
aws-region: us-gov-west-1 | |
- name: Get Datadog token from Parameter Store | |
uses: department-of-veterans-affairs/action-inject-ssm-secrets@d8e6de3bde4dd728c9d732baef58b3c854b8c4bb # latest | |
with: | |
ssm_parameter: /dsva-vagov/content-build/GHA_CONTENT_BUILD_DATADOG_API_KEY | |
env_variable_name: GHA_CONTENT_BUILD_DATADOG_API_KEY | |
- name: Build JSON object | |
run: | | |
jq --null-input '{}' | \ | |
jq '.title = "VA.gov CMS content release was successful"' | \ | |
jq '.text = "VA.gov Content release ${{github.run_id}} completed at \(now|strftime("%Y-%m-%d %H:%M:%S"))! https://github.com/${{github.repository}}/actions/runs/${{github.run_id}}"' | \ | |
jq '.date_happened = now' | \ | |
jq '.aggregation_key = "content release ${{github.run_id}}"' | \ | |
jq '.tags[0] = "project:vagov"' | \ | |
jq '.tags[1] = "repo:content-build"' | \ | |
jq '.tags[2] = "workflow:content-release"' | \ | |
jq '.tags[3] = "env:${{env.DEPLOY_ENV}}"' | \ | |
jq '.tags[5] = "status:${{needs.deploy.result}}"' | \ | |
jq '.tags[6] = "trigger:${{env.BUILD_TRIGGER}}"' | \ | |
jq '.alert_type = "success"' > event.json | |
- name: Send event to Datadog | |
run: | | |
curl -X POST "https://api.ddog-gov.com/api/v1/events" \ | |
-H "Content-Type: text/json" \ | |
-H "DD-API-KEY: ${{ env.GHA_CONTENT_BUILD_DATADOG_API_KEY }}" \ | |
-d @- < event.json | |
notify-failure: | |
name: Notify Failure | |
runs-on: [self-hosted, asg] | |
if: | | |
(failure() && needs.deploy.result != 'success') | |
needs: deploy | |
steps: | |
- name: Checkout | |
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 | |
- name: Configure AWS Credentials | |
uses: aws-actions/configure-aws-credentials@e1e17a757e536f70e52b5a12b2e8d1d1c60e04ef # v2.0.0 | |
with: | |
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
aws-region: us-gov-west-1 | |
- name: Wait for the CMS to be ready | |
uses: ./.github/workflows/wait-for-cms-ready | |
- name: Notify CMS - Error | |
uses: ./.github/workflows/authenticated-cms-request | |
with: | |
aws_access_key_id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
aws_secret_access_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
url: ${{ env.DRUPAL_ADDRESS }}/api/content_release/error | |
method: GET | |
notify-failure-slack: | |
name: Notify Failure (Slack) | |
runs-on: [self-hosted, asg] | |
if: | | |
(failure() && needs.deploy.result != 'success') | |
needs: deploy | |
steps: | |
- name: Notify Slack | |
uses: department-of-veterans-affairs/platform-release-tools-actions/slack-notify@8c496a4b0c9158d18edcd9be8722ed0f79e8c5b4 | |
continue-on-error: true | |
with: | |
payload: > | |
{ | |
"attachments": [ | |
{ | |
"color": "#2EB67D", | |
"blocks": [ | |
{ | |
"type": "section", | |
"text": { | |
"type": "mrkdwn", | |
"text": ":bangbang: <!subteam^S010U41C30V|cms-helpdesk> Content release using ${{ needs.validate-build-status.outputs.TAG || 'an unknown version' }} has failed." | |
} | |
} | |
] | |
} | |
] | |
} | |
channel_id: ${{ env.CONTENT_BUILD_CHANNEL_ID }} | |
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
notify-failure-datadog: | |
name: Notify Failure (Datadog) | |
runs-on: [self-hosted, asg] | |
if: | | |
(failure() && needs.deploy.result != 'success') | |
needs: deploy | |
steps: | |
- name: Checkout | |
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 | |
- name: Configure AWS Credentials | |
uses: aws-actions/configure-aws-credentials@e1e17a757e536f70e52b5a12b2e8d1d1c60e04ef # v2.0.0 | |
with: | |
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
aws-region: us-gov-west-1 | |
- name: Get Datadog token from Parameter Store | |
uses: department-of-veterans-affairs/action-inject-ssm-secrets@d8e6de3bde4dd728c9d732baef58b3c854b8c4bb # latest | |
with: | |
ssm_parameter: /dsva-vagov/content-build/GHA_CONTENT_BUILD_DATADOG_API_KEY | |
env_variable_name: GHA_CONTENT_BUILD_DATADOG_API_KEY | |
- name: Build JSON object | |
run: | | |
jq --null-input '{}' | \ | |
jq '.title = "VA.gov CMS content release has failed"' | \ | |
jq '.text = "VA.gov Content release ${{github.run_id}} failed at \(now|strftime("%Y-%m-%d %H:%M:%S"))! https://github.com/${{github.repository}}/actions/runs/${{github.run_id}}"' | \ | |
jq '.date_happened = now' | \ | |
jq '.aggregation_key = "content release ${{github.run_id}}"' | \ | |
jq '.tags[0] = "project:vagov"' | \ | |
jq '.tags[1] = "repo:content-build"' | \ | |
jq '.tags[2] = "workflow:content-release"' | \ | |
jq '.tags[3] = "env:${{env.DEPLOY_ENV}}"' | \ | |
jq '.tags[5] = "status:${{needs.deploy.result}}"' | \ | |
jq '.tags[6] = "trigger:${{env.BUILD_TRIGGER}}"' | \ | |
jq '.alert_type = "error"' > event.json | |
- name: Send event to Datadog | |
run: | | |
curl -X POST "https://api.ddog-gov.com/api/v1/events" \ | |
-H "Content-Type: text/json" \ | |
-H "DD-API-KEY: ${{ env.GHA_CONTENT_BUILD_DATADOG_API_KEY }}" \ | |
-d @- < event.json | |
record-metrics: | |
name: Record metrics in Datadog | |
runs-on: [self-hosted, asg] | |
needs: | |
- build | |
- deploy | |
- validate-build-status | |
env: | |
METRIC_NAMESPACE: dsva_vagov.content_build | |
steps: | |
- name: Checkout | |
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 | |
- name: Get current timestamp | |
run: echo "NOW=$(date +"%s")" >> $GITHUB_ENV | |
- name: Set vars for CMS-triggered runs | |
if: ${{ github.event_name == 'repository_dispatch' }} | |
run: | | |
echo "DEPLOY_ENV=prod" >> $GITHUB_ENV | |
echo "BUILD_TRIGGER=cms" >> $GITHUB_ENV | |
- name: Calculate durations | |
run: | | |
echo "SETUP_DURATION=$(expr ${{needs.build.outputs.BUILD_START_TIME}} - ${{needs.validate-build-status.outputs.APPROX_WORKFLOW_START_TIME}})" >> $GITHUB_ENV | |
echo "BUILD_DURATION=$(expr ${{needs.build.outputs.BUILD_END_TIME}} - ${{needs.build.outputs.BUILD_START_TIME}})" >> $GITHUB_ENV | |
echo "CONTENT_BUILD_DURATION=$(expr ${{needs.build.outputs.CONTENT_BUILD_END_TIME}} - ${{needs.build.outputs.CONTENT_BUILD_START_TIME}})" >> $GITHUB_ENV | |
echo "ARCHIVE_DURATION=$(expr ${{needs.build.outputs.ARCHIVE_END_TIME}} - ${{needs.build.outputs.BUILD_END_TIME}})" >> $GITHUB_ENV | |
echo "DEPLOY_DURATION=$(expr ${{needs.deploy.outputs.DEPLOY_END_TIME}} - ${{needs.build.outputs.ARCHIVE_END_TIME}})" >> $GITHUB_ENV | |
echo "OVERALL_DURATION=$(expr ${{needs.deploy.outputs.DEPLOY_END_TIME}} - ${{needs.validate-build-status.outputs.APPROX_WORKFLOW_START_TIME}})" >> $GITHUB_ENV | |
- name: Build JSON object | |
run: | | |
jq --null-input '{}' | \ | |
jq '.series[0].metric = "${{env.METRIC_NAMESPACE}}.setup.duration"' | \ | |
jq '.series[0].points[0] = [${{env.NOW}}, ${{env.SETUP_DURATION}}]' | \ | |
jq '.series[1].metric = "${{env.METRIC_NAMESPACE}}.build.duration"' | \ | |
jq '.series[1].points[0] = [${{env.NOW}}, ${{env.BUILD_DURATION}}]' | \ | |
jq '.series[2].metric = "${{env.METRIC_NAMESPACE}}.build.gql.pages"' | \ | |
jq '.series[2].points[0] = [${{env.NOW}}, ${{needs.build.outputs.GQL_PAGE_COUNT}}]' | \ | |
jq '.series[3].metric = "${{env.METRIC_NAMESPACE}}.build.gql.duration"' | \ | |
jq '.series[3].points[0] = [${{env.NOW}}, ${{needs.build.outputs.GQL_QUERY_DURATION}}]' | \ | |
jq '.series[4].metric = "${{env.METRIC_NAMESPACE}}.build.content-build.duration"' | \ | |
jq '.series[4].points[0] = [${{env.NOW}}, ${{env.CONTENT_BUILD_DURATION}}]' | \ | |
jq '.series[5].metric = "${{env.METRIC_NAMESPACE}}.archive.duration"' | \ | |
jq '.series[5].points[0] = [${{env.NOW}}, ${{env.ARCHIVE_DURATION}}]' | \ | |
jq '.series[6].metric = "${{env.METRIC_NAMESPACE}}.deploy.duration"' | \ | |
jq '.series[6].points[0] = [${{env.NOW}}, ${{env.DEPLOY_DURATION}}]' | \ | |
jq '.series[7].metric = "${{env.METRIC_NAMESPACE}}.overall.duration"' | \ | |
jq '.series[7].points[0] = [${{env.NOW}}, ${{env.OVERALL_DURATION}}]' | \ | |
jq '.series[8].metric = "${{env.METRIC_NAMESPACE}}.build.broken-links.count"' | \ | |
jq '.series[8].points[0] = [${{env.NOW}}, ${{needs.build.outputs.BROKEN_LINK_COUNT}}]' | \ | |
jq '.series[].tags[0] = "env:${{env.DEPLOY_ENV}}"' | \ | |
jq '.series[].tags[1] = "build_number:${{github.run_number}}"' | \ | |
jq '.series[].tags[2] = "status:${{needs.deploy.result}}"' | \ | |
jq '.series[].tags[3] = "trigger:${{env.BUILD_TRIGGER}}"' > metrics.json | |
- name: Configure AWS credentials | |
uses: aws-actions/configure-aws-credentials@e1e17a757e536f70e52b5a12b2e8d1d1c60e04ef # v2.0.0 | |
with: | |
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
aws-region: us-gov-west-1 | |
- name: Get Datadog api key from Parameter Store | |
uses: department-of-veterans-affairs/action-inject-ssm-secrets@d8e6de3bde4dd728c9d732baef58b3c854b8c4bb # latest | |
with: | |
ssm_parameter: /dsva-vagov/content-build/GHA_CONTENT_BUILD_DATADOG_API_KEY | |
env_variable_name: GHA_CONTENT_BUILD_DATADOG_API_KEY | |
- name: Get Datadog app key from Parameter Store | |
uses: department-of-veterans-affairs/action-inject-ssm-secrets@d8e6de3bde4dd728c9d732baef58b3c854b8c4bb # latest | |
with: | |
ssm_parameter: /dsva-vagov/content-build/GHA_CONTENT_BUILD_DATADOG_APP_KEY | |
env_variable_name: GHA_CONTENT_BUILD_DATADOG_APP_KEY | |
- name: Send metrics to Datadog | |
run: | | |
curl -X POST "https://api.ddog-gov.com/api/v1/series" \ | |
-H "Content-Type: text/json" \ | |
-H "DD-API-KEY: ${{ env.GHA_CONTENT_BUILD_DATADOG_API_KEY }}" \ | |
-d @- < metrics.json |