|
| 1 | +# Reusable workflow for deploying Browser Agent to a single NR1 environment |
| 2 | +# Handles: RC asset deployment, promotion, change tracking, and notifications |
| 3 | + |
| 4 | +name: Deploy to Environment |
| 5 | + |
| 6 | +on: |
| 7 | + workflow_call: |
| 8 | + inputs: |
| 9 | + # Environment configuration |
| 10 | + environment: |
| 11 | + description: 'GitHub environment name for protection rules (e.g., nr1-dev, nr1-staging)' |
| 12 | + required: true |
| 13 | + type: string |
| 14 | + bucket_dir: |
| 15 | + description: 'S3 bucket directory for this environment (e.g., dev/, staging/, prod/)' |
| 16 | + required: true |
| 17 | + type: string |
| 18 | + nr_environment: |
| 19 | + description: 'NR environment name used by internal-promotion action (e.g., dev, staging, prod)' |
| 20 | + required: true |
| 21 | + type: string |
| 22 | + cdn_service: |
| 23 | + description: 'Fastly CDN service name' |
| 24 | + required: false |
| 25 | + type: string |
| 26 | + default: js-agent.newrelic.com |
| 27 | + |
| 28 | + # Runner configuration |
| 29 | + runner: |
| 30 | + description: 'GitHub runner to use (ubuntu-latest or Browser-Agent-Assigned-IP-Linux)' |
| 31 | + required: false |
| 32 | + type: string |
| 33 | + default: ubuntu-latest |
| 34 | + |
| 35 | + # Deployment mode |
| 36 | + is_rc_mode: |
| 37 | + description: 'Whether to build fresh RC assets (true) or use existing version (false)' |
| 38 | + required: true |
| 39 | + type: string |
| 40 | + script_url: |
| 41 | + description: 'Script URL for existing version mode (ignored in RC mode)' |
| 42 | + required: false |
| 43 | + type: string |
| 44 | + version_label: |
| 45 | + description: 'Version label for existing version mode (ignored in RC mode)' |
| 46 | + required: false |
| 47 | + type: string |
| 48 | + |
| 49 | + # Special features |
| 50 | + determine_branch_name: |
| 51 | + description: 'Whether to determine branch name for version suffix (only dev needs this)' |
| 52 | + required: false |
| 53 | + type: boolean |
| 54 | + default: false |
| 55 | + include_nrdb_upload: |
| 56 | + description: 'Whether to upload copy-paste loader to NRDB (only staging needs this)' |
| 57 | + required: false |
| 58 | + type: boolean |
| 59 | + default: false |
| 60 | + include_notification: |
| 61 | + description: 'Whether to send Slack notification (dev does not notify)' |
| 62 | + required: false |
| 63 | + type: boolean |
| 64 | + default: true |
| 65 | + |
| 66 | + # Change tracking metadata |
| 67 | + region_name: |
| 68 | + description: 'Region name for change tracking (e.g., Dev, Staging, EU, JP, US)' |
| 69 | + required: true |
| 70 | + type: string |
| 71 | + change_tracking_type: |
| 72 | + description: 'Change tracking type (Basic or Rolling)' |
| 73 | + required: false |
| 74 | + type: string |
| 75 | + default: Basic |
| 76 | + |
| 77 | + outputs: |
| 78 | + version_label: |
| 79 | + description: 'Version label of the deployed agent' |
| 80 | + value: ${{ jobs.deploy.outputs.version_label }} |
| 81 | + |
| 82 | + # All secrets are inherited from the calling workflow |
| 83 | + |
| 84 | +jobs: |
| 85 | + deploy: |
| 86 | + runs-on: ${{ inputs.runner }} |
| 87 | + environment: ${{ inputs.environment }} |
| 88 | + timeout-minutes: 30 |
| 89 | + outputs: |
| 90 | + version_label: ${{ steps.set-version.outputs.version_label }} |
| 91 | + steps: |
| 92 | + - uses: actions/checkout@v4 |
| 93 | + |
| 94 | + - uses: actions/setup-node@v4 |
| 95 | + with: |
| 96 | + node-version: 22.11.0 |
| 97 | + |
| 98 | + # Derive env_id from environment name (strip 'nr1-' prefix) |
| 99 | + # Used for selecting environment-specific secrets |
| 100 | + - name: Set environment ID |
| 101 | + id: env-id |
| 102 | + run: | |
| 103 | + ENV_ID="${{ inputs.environment }}" |
| 104 | + ENV_ID="${ENV_ID#nr1-}" # Strip nr1- prefix |
| 105 | + echo "value=${ENV_ID}" >> $GITHUB_OUTPUT |
| 106 | + echo "🏷️ Environment ID: ${ENV_ID}" |
| 107 | + |
| 108 | + # Determine branch name for version suffix (only dev needs this) |
| 109 | + - name: Determine branch name for version |
| 110 | + if: inputs.determine_branch_name |
| 111 | + id: branch-name |
| 112 | + run: | |
| 113 | + if [[ "${{ github.event_name }}" == "pull_request" ]]; then |
| 114 | + BRANCH="${{ github.head_ref }}" |
| 115 | + else |
| 116 | + BRANCH="${{ github.ref_name }}" |
| 117 | + fi |
| 118 | + |
| 119 | + # Clean branch name for version suffix (lowercase, replace special chars with hyphens) |
| 120 | + CLEAN_BRANCH=$(echo "$BRANCH" | sed 's/[^a-zA-Z0-9-]/-/g' | tr '[:upper:]' '[:lower:]') |
| 121 | + echo "branch_name=${CLEAN_BRANCH}" >> $GITHUB_OUTPUT |
| 122 | + echo "🏷️ Using branch-specific version suffix: ${CLEAN_BRANCH}" |
| 123 | + |
| 124 | + # Build and deploy RC assets |
| 125 | + - name: Deploy RC assets |
| 126 | + if: inputs.is_rc_mode == 'true' |
| 127 | + id: deploy-rc |
| 128 | + uses: ./.github/actions/deploy-rc-assets |
| 129 | + with: |
| 130 | + environment: ${{ inputs.nr_environment }} |
| 131 | + bucket_dir: ${{ inputs.bucket_dir }} |
| 132 | + cdn_service: ${{ inputs.cdn_service }} |
| 133 | + branch_name: ${{ inputs.determine_branch_name && steps.branch-name.outputs.branch_name || '' }} |
| 134 | + aws_access_key_id: ${{ secrets.AWS_ACCESS_KEY_ID }} |
| 135 | + aws_secret_access_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} |
| 136 | + aws_role: ${{ secsteps.env-id.outputs.value == 'dev' && secrets.INTERNAL_DEV_APPLICATION_ID || steps.env-id.outputs.value == 'staging' && secrets.INTERNAL_STAGING_APPLICATION_ID || steps.env-id.outputs.value == 'eu-prod' && secrets.INTERNAL_EU_PRODUCTION_APPLICATION_ID || steps.env-id.outputs.value |
| 137 | + aws_bucket_name: ${{ secrets.AWS_BUCKET }} |
| 138 | + fastly_key: ${{ secrets.FASTLY_PURGE_KEY }} |
| 139 | + |
| 140 | + # Promote agent to environment |
| 141 | + - name: Promote agent to ${{ inputs.region_name }} |
| 142 | + uses: ./.github/actions/internal-promotion |
| 143 | + with: |
| 144 | + nr_environment: ${{ inputs.nr_environment }} |
| 145 | + nrba_released_script_url: ${{ inputs.is_rc_mode == 'true' && steps.deploy-rc.outputs.script_url || inputs.script_url }} |
| 146 | + nrba_app_id: ${{ inputs.env_id == 'dev' && secrets.INTERNAL_DEV_APPLICATION_ID || inputs.env_id == 'staging' && secrets.INTERNAL_STAGING_APPLICATION_ID || inputs.env_id == 'eu-prod' && secrets.INTERNAL_EU_PRODUCTION_APPLICATION_ID || inputs.env_id == 'jp-prod' && secrets.INTERNAL_JP_PRODUCTION_APPLICATION_ID || secrets.INTERNAL_PRODUCTION_APPLICATION_ID }} |
| 147 | + nrba_license_key: ${{ secrets.INTERNAL_LICENSE_KEY }} |
| 148 | + aws_access_key_id: ${{ secrets.AWS_ACCESS_KEY_ID }} |
| 149 | + aws_secret_access_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} |
| 150 | + aws_role: ${{ secrets.AWS_ROLE_ARN }} |
| 151 | + aws_bucket_name: ${{ secrets.AWS_BUCKET }} |
| 152 | + fastly_key: ${{ secrets.FASTLY_PURGE_KEY }} |
| 153 | + |
| 154 | + # Build versioned loaders for NRDB copy+paste (staging only) |
| 155 | + - name: Build versioned loaders for NRDB copy+paste |
| 156 | + if: inputs.include_nrdb_upload && inputs.is_rc_mode == 'true' |
| 157 | + run: | |
| 158 | + echo "🔨 Building prod loaders with versioned filenames for NRDB upload" |
| 159 | + npm run cdn:webpack -- --env mode=prod |
| 160 | + |
| 161 | + # Update copy-paste loader in NRDB (staging only) |
| 162 | + - name: Update copy-paste loader in NRDB |
| 163 | + if: inputs.include_nrdb_upload && inputs.is_rc_mode == 'true' |
| 164 | + continue-on-error: true |
| 165 | + env: |
| 166 | + STAGE_API_KEY: ${{ secrets.NR_API_KEY_STAGING }} |
| 167 | + run: | |
| 168 | + LOADER_VERSION=$(jq -r '.version' package.json) |
| 169 | + npm --prefix .github/actions install |
| 170 | + node .github/actions/nr-upload/index.js \ |
| 171 | + --environment=stage \ |
| 172 | + --loader-version=$LOADER_VERSION \ |
| 173 | + --stage-api-key=$STAGE_API_KEY \ |
| 174 | + --local-dir=./build |
| 175 | + node .github/actions/nr-verify/index.js \ |
| 176 | + --loader-version=$LOADER_VERSION |
| 177 | + |
| 178 | + # Set version label output |
| 179 | + - name: Set version label |
| 180 | + id: set-version |
| 181 | + run: | |
| 182 | + if [[ "${{ inputs.is_rc_mode }}" == "true" ]]; then |
| 183 | + VERSION="${{ steps.deploy-rc.outputs.version_label }}" |
| 184 | + else |
| 185 | + VERSION="${{ inputs.version_label }}" |
| 186 | + fi |
| 187 | + echo "version_label=${VERSION}" >> $GITHUB_OUTPUT |
| 188 | +
|
| 189 | + # Create change tracking event |
| 190 | + change-tracking: |
| 191 | + needs: [deploy] |
| 192 | + runs-on: Browser-Agent-Assigned-IP-Linux |
| 193 | + environment: change-tracking |
| 194 | + timeout-minutes: 5 |
| 195 | + steps: |
| 196 | + - uses: actions/checkout@v4 |
| 197 | + - name: Create ${{ inputs.region_name }} change tracking event |
| 198 | + uses: ./.github/actions/change-tracking |
| 199 | + with: |
| 200 | + accountId: '1067061' |
| 201 | + entityGuid: ${{ steps.env-id.outputs.value == 'dev' && secrets.NR_ENTITY_GUID_NR1_DEV || steps.env-id.outputs.value == 'staging' && secrets.NR_ENTITY_GUID_NR1_STAGING || steps.env-id.outputs.value == 'eu-prod' && secrets.NR_ENTITY_GUID_NR1_EU_PROD || steps.env-id.outputs.value == 'jp-prod' && secrets.NR_ENTITY_GUID_NR1_JP_PROD || secrets.NR_ENTITY_GUID_NR1_US_PROD }} |
| 202 | + apiKey: ${{ secrets.NR_CHANGE_TRACKING_API_KEY_NR1 }} |
| 203 | + region: ${{ inputs.region_name }} |
| 204 | + version: ${{ needs.deploy.outputs.version_label }} |
| 205 | + type: ${{ inputs.change_tracking_type }} |
| 206 | + description: '${{ inputs.region_name }} promoted to ${{ needs.deploy.outputs.version_label }}' |
| 207 | + shortDescription: '${{ inputs.region_name }}: ${{ needs.deploy.outputs.version_label }}' |
| 208 | + deepLink: 'https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}' |
| 209 | + commit: ${{ github.sha }} |
| 210 | + user: ${{ github.actor }} |
| 211 | + groupId: '${{ github.run_id }}-${{ github.sha }}' |
| 212 | + |
| 213 | + # Send Slack notification |
| 214 | + notify: |
| 215 | + if: inputs.include_notification |
| 216 | + needs: [deploy] |
| 217 | + runs-on: ubuntu-latest |
| 218 | + timeout-minutes: 5 |
| 219 | + steps: |
| 220 | + - uses: actions/checkout@v4 |
| 221 | + - name: Send Slack notification |
| 222 | + uses: ./.github/actions/slack-notification |
| 223 | + with: |
| 224 | + notifications_channel_url: ${{ secrets.SLACK_BROWSER_AGENT_NOTIFICATIONS_WEBHOOK_URL }} |
| 225 | + dem_platform_ops_channel_url: ${{ secrets.SLACK_DEM_PLATFORM_OPS_WEBHOOK_URL }} |
| 226 | + message: ":rocket: New Browser Agent version promoted to \\`${{ inputs.region_name }}\\` environment. See <https://github.com/newrelic/newrelic-browser-agent/actions/runs/${{ github.run_id }}|workflow run>." |
| 227 | + |
| 228 | + message: ":rocket: New Browser Agent version promoted to \\`${{ inputs.region_name }}\\` environment. See <https://github.com/newrelic/newrelic-browser-agent/actions/runs/${{ github.run_id }}|workflow run>." |
0 commit comments