Skip to content

Rollback Production Deployment #20

Rollback Production Deployment

Rollback Production Deployment #20

Workflow file for this run

name: Rollback Production Deployment
on:
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.sha }}
cancel-in-progress: true
permissions:
id-token: write # allows the JWT to be requested from GitHub's OIDC provider
contents: read # This is required for actions/checkout
env:
NODE_OPTIONS: "--no-warnings"
CACHE_CONTROL_NO_STORE: "\"no-store\""
CACHE_CONTROL_MAX_AGE: "\"max-age=3600\""
LEGACY_DIR_NAME: "legacy"
MODERN_DIR_NAME: "modern"
INTEGRATIONS_DIR_NAME: "js-integrations"
PLUGINS_DIR_NAME: "plugins"
LATEST_VERSION_DIR_NAME: "v3"
LEGACY_SDK_LATEST_VERSION_DIR_NAME: "v1.1"
jobs:
validate-actor:
# Only allow to be deployed from tags and main branch
if: startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main'
uses: ./.github/workflows/validate-actor.yml
with:
team_names: 'js-sdk,integrations'
secrets:
PAT: ${{ secrets.PAT }}
rollback:
needs: validate-actor
name: Rollback production deployment
runs-on: [self-hosted, Linux, X64]
steps:
- name: Install AWS CLI
uses: unfor19/install-aws-cli-action@master
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::${{ secrets.AWS_PROD_ACCOUNT_ID }}:role/${{ secrets.AWS_PROD_S3_SYNC_ROLE }}
aws-region: us-east-1
- name: Checkout source code
uses: actions/checkout@v4
with:
ref: ${{ github.sha }}
- name: Get rollback sdk versions
run: |
rollback_version=$(jq -r .version packages/analytics-js/package.json)
echo "ROLLBACK_VERSION_VALUE=$rollback_version" >> $GITHUB_ENV
echo "SDK rollback version: $rollback_version"
legacy_sdk_rollback_version=$(jq -r .version packages/analytics-v1.1/package.json)
echo "LEGACY_SDK_ROLLBACK_VERSION_VALUE=$legacy_sdk_rollback_version" >> $GITHUB_ENV
echo "Legacy SDK rollback version: $legacy_sdk_rollback_version"
echo "DATE=$(date)" >> $GITHUB_ENV
- name: Copy the core SDK artifacts from the previous version to the latest version directory
run: |
s3_path_prefix="s3://${{ secrets.AWS_PROD_S3_BUCKET_NAME }}"
# Copy from S3 bucket versioned directory to the same S3 bucket in the latest version directory
# excluding the plugins and js-integrations directories
# as the core SDK automatically refers to the plugins and js-integrations files from the versioned directory
aws s3 cp $s3_path_prefix/${{ env.ROLLBACK_VERSION_VALUE }}/${{ env.LEGACY_DIR_NAME }}/ $s3_path_prefix/${{ env.LATEST_VERSION_DIR_NAME }}/${{ env.LEGACY_DIR_NAME }}/ --recursive --exclude "${{ env.INTEGRATIONS_DIR_NAME }}/*" --exclude "${{ env.INTEGRATIONS_DIR_NAME }}/**" --cache-control ${{ env.CACHE_CONTROL_NO_STORE }}
aws s3 cp $s3_path_prefix/${{ env.ROLLBACK_VERSION_VALUE }}/${{ env.MODERN_DIR_NAME }}/ $s3_path_prefix/${{ env.LATEST_VERSION_DIR_NAME }}/${{ env.MODERN_DIR_NAME }}/ --recursive --exclude "${{ env.PLUGINS_DIR_NAME }}/*" --exclude "${{ env.PLUGINS_DIR_NAME }}/**" --exclude "${{ env.INTEGRATIONS_DIR_NAME }}/*" --exclude "${{ env.INTEGRATIONS_DIR_NAME }}/**" --cache-control ${{ env.CACHE_CONTROL_NO_STORE }}
- name: Invalidate CloudFront cache for the latest version directory
run: |
invalidation_id=$(AWS_MAX_ATTEMPTS=10 aws cloudfront create-invalidation --distribution-id ${{ secrets.AWS_PROD_CF_DISTRIBUTION_ID }} --paths "/${{ env.LATEST_VERSION_DIR_NAME }}*" --query "Invalidation.Id" --output text)
aws cloudfront wait invalidation-completed --distribution-id ${{ secrets.AWS_PROD_CF_DISTRIBUTION_ID }} --id "$invalidation_id"
# Repeat the above steps for the legacy SDK artifacts
- name: Copy the legacy SDK artifacts from the previous version to the latest version directory
run: |
s3_path_prefix="s3://${{ secrets.AWS_PROD_S3_BUCKET_NAME }}"
# Copy from S3 bucket versioned directory to the same S3 bucket in the latest version directory
aws s3 cp $s3_path_prefix/${{ env.LEGACY_SDK_ROLLBACK_VERSION_VALUE }}/ $s3_path_prefix/${{ env.LEGACY_SDK_LATEST_VERSION_DIR_NAME }}/ --recursive --cache-control ${{ env.CACHE_CONTROL_NO_STORE }}
- name: Invalidate CloudFront cache for the latest version directory (legacy SDK artifacts)
run: |
invalidation_id=$(AWS_MAX_ATTEMPTS=10 aws cloudfront create-invalidation --distribution-id ${{ secrets.AWS_PROD_CF_DISTRIBUTION_ID }} --paths "/${{ env.LEGACY_SDK_LATEST_VERSION_DIR_NAME }}*" --query "Invalidation.Id" --output text)
aws cloudfront wait invalidation-completed --distribution-id ${{ secrets.AWS_PROD_CF_DISTRIBUTION_ID }} --id "$invalidation_id"
- name: Send message to Slack channel
id: slack
continue-on-error: true
uses: slackapi/[email protected]
env:
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
PROJECT_NAME: 'JS SDK Browser Package - Rollback - Production'
CDN_URL: ${{ format('https://cdn.rudderlabs.com/{0}/modern/rsa.min.js', env.LATEST_VERSION_DIR_NAME) }}
RELEASES_URL: 'https://github.com/rudderlabs/rudder-sdk-js/releases/tag/@rudderstack/analytics-js@'
LINK_TEXT: ${{ format('v{0}', env.ROLLBACK_VERSION_VALUE) }}
with:
channel-id: ${{ secrets.SLACK_RELEASE_CHANNEL_ID }}
payload: |
{
"text": "*New Release: ${{ env.PROJECT_NAME }} - <${{ env.CDN_URL }}|${{ env.LINK_TEXT }}>*\n${{ env.DATE }}\nCC: <!subteam^S0555JBV36D> <!subteam^S03SW7DM8P3> <!subteam^S03SHJ20350>",
"blocks": [
{
"type": "header",
"text": {
"type": "plain_text",
"text": "New release: ${{ env.PROJECT_NAME }}"
}
},
{
"type": "divider"
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*<${{ env.CDN_URL }}|${{ env.LINK_TEXT }}>*\n${{ env.DATE }}\nCC: <!subteam^S0555JBV36D> <!subteam^S03SW7DM8P3> <!subteam^S03SHJ20350>"
},
"accessory": {
"type": "image",
"image_url": "https://cdn.jsdelivr.net/npm/programming-languages-logos/src/javascript/javascript.png",
"alt_text": "JavaScript Icon"
}
}
${{ format(',{{"type": "context", "elements": [{{"type": "mrkdwn", "text": "For more details, check the full release notes <{0}{1}|here>."}}]}}', env.RELEASES_URL, env.ROLLBACK_VERSION_VALUE) || '' }}
]
}