|
| 1 | +name: production-heartbeat |
| 2 | +on: |
| 3 | + workflow_dispatch: # As per documentation, the colon is necessary even though no config is required. |
| 4 | + schedule: |
| 5 | + # Cron syntax is "minute[0-59] hour[0-23] date[1-31] month[1-12] day[0-6]". '*' is 'any value', and multiple values |
| 6 | + # can be specified with comma-separated lists. All times are UTC. |
| 7 | + # So this expression means "run at 45 minutes past 1, 5, and 9 AM/PM UTC". The hours were chosen so that |
| 8 | + # the jobs run only close to business hours of Central Time. |
| 9 | + # Days were chosen to run only from Monday through Friday. |
| 10 | + - cron: '45 13,17,21 * * 1,2,3,4,5' |
| 11 | +jobs: |
| 12 | + production-heartbeat: |
| 13 | + strategy: |
| 14 | + fail-fast: false |
| 15 | + matrix: |
| 16 | + os: [{vm: ubuntu-latest}, {vm: windows-2019}, {vm: macos-latest}] |
| 17 | + node: ['lts/*'] |
| 18 | + runs-on: ${{ matrix.os.vm }} |
| 19 | + timeout-minutes: 60 |
| 20 | + steps: |
| 21 | + # 1 Install VS Code and Extension on Ubuntu |
| 22 | + - name: Install VS Code on Ubuntu |
| 23 | + if: runner.os == 'Linux' |
| 24 | + run: | |
| 25 | + sudo apt update |
| 26 | + sudo apt install wget gpg -y |
| 27 | + wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > packages.microsoft.gpg |
| 28 | + sudo install -o root -g root -m 644 packages.microsoft.gpg /usr/share/keyrings/ |
| 29 | + sudo sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/vscode stable main" > /etc/apt/sources.list.d/vscode.list' |
| 30 | + sudo apt update |
| 31 | + sudo apt install code -y |
| 32 | +
|
| 33 | + - name: Install Salesforce Code Analyzer Extension on Ubuntu |
| 34 | + if: runner.os == 'Linux' |
| 35 | + run: | |
| 36 | + code --install-extension salesforce.sfdx-code-analyzer-vscode |
| 37 | +
|
| 38 | + - name: Verify Extension Installation on Ubuntu |
| 39 | + if: runner.os == 'Linux' |
| 40 | + run: | |
| 41 | + if code --list-extensions | grep -q 'salesforce.sfdx-code-analyzer-vscode'; then |
| 42 | + echo "Extension installed successfully" |
| 43 | + else |
| 44 | + echo "::error Extension installation failed" && exit 1 |
| 45 | + fi |
| 46 | +
|
| 47 | + # 2 Install VS Code and Extension on Windows |
| 48 | + # We use chocolatey to install vscode since it gives a reliable path for the location of code.exe |
| 49 | + # We have also seen Windows to be flaky, so adding addition echo statements. |
| 50 | + - name: Install VS Code on Windows |
| 51 | + if: runner.os == 'Windows' |
| 52 | + run: | |
| 53 | + Write-Host "Installing Chocolatey..." |
| 54 | + Set-ExecutionPolicy Bypass -Scope Process -Force; |
| 55 | + [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; |
| 56 | + iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1')) |
| 57 | + Write-Host "Installing Visual Studio Code using Chocolatey..." |
| 58 | + choco install vscode -y |
| 59 | +
|
| 60 | + - name: Install Salesforce Code Analyzer Extension on Windows |
| 61 | + if: runner.os == 'Windows' |
| 62 | + run: | |
| 63 | + echo "Installing Code Analyzer Extension..." |
| 64 | + "/c/Program Files/Microsoft VS Code/bin/code" --install-extension salesforce.sfdx-code-analyzer-vscode |
| 65 | + echo "Installing Code Analyzer Complete" |
| 66 | + |
| 67 | + echo "Waiting for 10 seconds..." |
| 68 | + sleep 10 |
| 69 | + |
| 70 | + echo "Listing installed extensions..." |
| 71 | + "/c/Program Files/Microsoft VS Code/bin/code" --list-extensions |
| 72 | + shell: bash |
| 73 | + |
| 74 | + - name: Verify Extension on Windows |
| 75 | + if: runner.os == 'Windows' |
| 76 | + run: | |
| 77 | + echo "Waiting for 10 seconds..." |
| 78 | + sleep 10 |
| 79 | +
|
| 80 | + echo "Listing installed extensions..." |
| 81 | + extensions=$("/c/Program Files/Microsoft VS Code/bin/code" --list-extensions) |
| 82 | +
|
| 83 | + echo "$extensions" |
| 84 | +
|
| 85 | + if echo "$extensions" | grep -q 'salesforce.sfdx-code-analyzer-vscode'; then |
| 86 | + echo "Extension 'salesforce.sfdx-code-analyzer-vscode' is installed successfully" |
| 87 | + else |
| 88 | + echo "::error Extension 'salesforce.sfdx-code-analyzer-vscode' is NOT installed" |
| 89 | + exit 1 |
| 90 | + fi |
| 91 | + shell: bash |
| 92 | + |
| 93 | + # 3 Install VS Code and Extension on macOS |
| 94 | + - name: Install VS Code on macOS |
| 95 | + if: runner.os == 'macOS' |
| 96 | + run: | |
| 97 | + brew install --cask visual-studio-code |
| 98 | +
|
| 99 | + - name: Install Salesforce Code Analyzer Extension on macOS |
| 100 | + if: runner.os == 'macOS' |
| 101 | + run: | |
| 102 | + code --install-extension salesforce.sfdx-code-analyzer-vscode |
| 103 | +
|
| 104 | + - name: Verify Extension Installation on macOS |
| 105 | + if: runner.os == 'macOS' |
| 106 | + run: | |
| 107 | + if code --list-extensions | grep -q 'salesforce.sfdx-code-analyzer-vscode'; then |
| 108 | + echo "Extension installed successfully" |
| 109 | + else |
| 110 | + echo "::error Extension installation failed" && exit 1 |
| 111 | + fi |
| 112 | +
|
| 113 | + # === Report any problems === |
| 114 | + - name: Report problems |
| 115 | + # There are problems if any step failed or was skipped. |
| 116 | + # Note that the `join()` call omits null values, so if any steps were skipped, they won't have a corresponding |
| 117 | + # value in the string. |
| 118 | + if: ${{ failure() || cancelled() }} |
| 119 | + shell: bash |
| 120 | + env: |
| 121 | + # If we're here because steps failed or were skipped, then that's a critical problem. Otherwise it's a normal one. |
| 122 | + # We can't use the `failure()` or `cancelled()` convenience methods outside of the `if` condition, hence the |
| 123 | + # `contains()` calls. |
| 124 | + IS_CRITICAL: ${{ contains(join(steps.*.outcome), 'failure') || contains(join(steps.*.outcome), 'skipped') }} |
| 125 | + # A link to this run, so the PagerDuty assignee can quickly get here. |
| 126 | + RUN_LINK: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} |
| 127 | + |
| 128 | + run: | |
| 129 | +
|
| 130 | + if [[ ${{ env.IS_CRITICAL }} == true ]]; then |
| 131 | + ALERT_SEV="critical" |
| 132 | + ALERT_SUMMARY="Production heartbeat script failed on ${{ runner.os }}" |
| 133 | + else |
| 134 | + # Leaving the else part here to help with running end-to-end sanity test with real alerts being created. |
| 135 | + ALERT_SEV="info" |
| 136 | + ALERT_SUMMARY="Production heartbeat script succeeded with retries on ${{ runner.os }}" |
| 137 | + fi |
| 138 | + # Define a helper function to create our POST request's data, to sidestep issues with nested quotations. |
| 139 | + generate_post_data() { |
| 140 | + # This is known as a HereDoc, and it lets us declare multi-line input ending when the specified limit string, |
| 141 | + # in this case EOF, is encountered. |
| 142 | + cat <<EOF |
| 143 | + {"payload": { |
| 144 | + "summary": "${ALERT_SUMMARY}", |
| 145 | + "source": "Github Actions", |
| 146 | + "severity": "${ALERT_SEV}" |
| 147 | + }, |
| 148 | + "links": [{ |
| 149 | + "href": "${{ env.RUN_LINK }}", |
| 150 | + "text": "Link to action execution" |
| 151 | + }], |
| 152 | + "event_action": "trigger", |
| 153 | + "dedup_key": "GH-HB-${{ matrix.os.vm }}-${{ matrix.node }}", |
| 154 | + "routing_key": "${{ secrets.PAGERDUTY_HEARTBEAT_KEY }}" |
| 155 | + } |
| 156 | + EOF |
| 157 | + } |
| 158 | + # Make our POST request |
| 159 | + curl --request POST --data "$(generate_post_data)" https://events.pagerduty.com/v2/enqueue |
0 commit comments