production-heartbeat #118
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: production-heartbeat | |
on: | |
workflow_dispatch: # As per documentation, the colon is necessary even though no config is required. | |
schedule: | |
# Cron syntax is "minute[0-59] hour[0-23] date[1-31] month[1-12] day[0-6]". '*' is 'any value', and multiple values | |
# can be specified with comma-separated lists. All times are UTC. | |
# So this expression means "run at 45 minutes past 1, 5, and 9 AM/PM UTC". The hours were chosen so that | |
# the jobs run only close to business hours of Central Time. | |
# Days were chosen to run only from Monday through Friday. | |
- cron: '45 13,17,21 * * 1,2,3,4,5' | |
jobs: | |
production-heartbeat: | |
strategy: | |
fail-fast: false | |
matrix: | |
os: [{vm: ubuntu-latest}, {vm: windows-2019}, {vm: macos-latest}] | |
node: ['lts/*'] | |
runs-on: ${{ matrix.os.vm }} | |
timeout-minutes: 60 | |
steps: | |
# 1 Install VS Code and Extension on Ubuntu | |
- name: Install VS Code on Ubuntu | |
if: runner.os == 'Linux' | |
run: | | |
sudo apt update | |
sudo apt install wget gpg -y | |
wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > packages.microsoft.gpg | |
sudo install -o root -g root -m 644 packages.microsoft.gpg /usr/share/keyrings/ | |
sudo sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/vscode stable main" > /etc/apt/sources.list.d/vscode.list' | |
sudo apt update | |
sudo apt install code -y | |
- name: Install Salesforce Code Analyzer Extension on Ubuntu | |
if: runner.os == 'Linux' | |
run: | | |
code --install-extension salesforce.sfdx-code-analyzer-vscode | |
- name: Verify Extension Installation on Ubuntu | |
if: runner.os == 'Linux' | |
run: | | |
if code --list-extensions | grep -q 'salesforce.sfdx-code-analyzer-vscode'; then | |
echo "Extension installed successfully" | |
else | |
echo "::error Extension installation failed" && exit 1 | |
fi | |
# 2 Install VS Code and Extension on Windows | |
# We use chocolatey to install vscode since it gives a reliable path for the location of code.exe | |
# We have also seen Windows to be flaky, so adding addition echo statements. | |
- name: Install VS Code on Windows | |
if: runner.os == 'Windows' | |
run: | | |
Write-Host "Installing Chocolatey..." | |
Set-ExecutionPolicy Bypass -Scope Process -Force; | |
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; | |
iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1')) | |
Write-Host "Installing Visual Studio Code using Chocolatey..." | |
choco install vscode -y | |
- name: Install Salesforce Code Analyzer Extension on Windows | |
if: runner.os == 'Windows' | |
run: | | |
echo "Installing Code Analyzer Extension..." | |
"/c/Program Files/Microsoft VS Code/bin/code" --install-extension salesforce.sfdx-code-analyzer-vscode | |
echo "Installing Code Analyzer Complete" | |
echo "Waiting for 10 seconds..." | |
sleep 10 | |
echo "Listing installed extensions..." | |
"/c/Program Files/Microsoft VS Code/bin/code" --list-extensions | |
shell: bash | |
- name: Verify Extension on Windows | |
if: runner.os == 'Windows' | |
run: | | |
echo "Waiting for 10 seconds..." | |
sleep 10 | |
echo "Listing installed extensions..." | |
extensions=$("/c/Program Files/Microsoft VS Code/bin/code" --list-extensions) | |
echo "$extensions" | |
if echo "$extensions" | grep -q 'salesforce.sfdx-code-analyzer-vscode'; then | |
echo "Extension 'salesforce.sfdx-code-analyzer-vscode' is installed successfully" | |
else | |
echo "::error Extension 'salesforce.sfdx-code-analyzer-vscode' is NOT installed" | |
exit 1 | |
fi | |
shell: bash | |
# 3 Install VS Code and Extension on macOS | |
- name: Install VS Code on macOS | |
if: runner.os == 'macOS' | |
run: | | |
brew install --cask visual-studio-code | |
- name: Install Salesforce Code Analyzer Extension on macOS | |
if: runner.os == 'macOS' | |
run: | | |
code --install-extension salesforce.sfdx-code-analyzer-vscode | |
- name: Verify Extension Installation on macOS | |
if: runner.os == 'macOS' | |
run: | | |
if code --list-extensions | grep -q 'salesforce.sfdx-code-analyzer-vscode'; then | |
echo "Extension installed successfully" | |
else | |
echo "::error Extension installation failed" && exit 1 | |
fi | |
# === Report any problems === | |
- name: Report problems | |
# There are problems if any step failed or was skipped. | |
# Note that the `join()` call omits null values, so if any steps were skipped, they won't have a corresponding | |
# value in the string. | |
if: ${{ failure() || cancelled() }} | |
shell: bash | |
env: | |
# If we're here because steps failed or were skipped, then that's a critical problem. Otherwise it's a normal one. | |
# We can't use the `failure()` or `cancelled()` convenience methods outside of the `if` condition, hence the | |
# `contains()` calls. | |
IS_CRITICAL: ${{ contains(join(steps.*.outcome), 'failure') || contains(join(steps.*.outcome), 'skipped') }} | |
# A link to this run, so the PagerDuty assignee can quickly get here. | |
RUN_LINK: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} | |
run: | | |
if [[ ${{ env.IS_CRITICAL }} == true ]]; then | |
ALERT_SEV="critical" | |
ALERT_SUMMARY="Production heartbeat script failed on ${{ runner.os }}" | |
else | |
# Leaving the else part here to help with running end-to-end sanity test with real alerts being created. | |
ALERT_SEV="info" | |
ALERT_SUMMARY="Production heartbeat script succeeded with retries on ${{ runner.os }}" | |
fi | |
# Define a helper function to create our POST request's data, to sidestep issues with nested quotations. | |
generate_post_data() { | |
# This is known as a HereDoc, and it lets us declare multi-line input ending when the specified limit string, | |
# in this case EOF, is encountered. | |
cat <<EOF | |
{"payload": { | |
"summary": "${ALERT_SUMMARY}", | |
"source": "Github Actions", | |
"severity": "${ALERT_SEV}" | |
}, | |
"links": [{ | |
"href": "${{ env.RUN_LINK }}", | |
"text": "Link to action execution" | |
}], | |
"event_action": "trigger", | |
"dedup_key": "GH-HB-${{ matrix.os.vm }}-${{ matrix.node }}", | |
"routing_key": "${{ secrets.PAGERDUTY_HEARTBEAT_KEY }}" | |
} | |
EOF | |
} | |
# Make our POST request | |
curl --request POST --data "$(generate_post_data)" https://events.pagerduty.com/v2/enqueue |