Skip to content

production-heartbeat #91

production-heartbeat

production-heartbeat #91

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