Skip to content

DD-add rspec subcommand and PR CI #4

DD-add rspec subcommand and PR CI

DD-add rspec subcommand and PR CI #4

Workflow file for this run

# .github/workflows/pr-dashboard.yml
#
# Generates a Grafana dashboard for observability signals in a PR
# and posts a link as a PR comment.
#
# Required secrets:
# GRAFANA_URL - Your Grafana instance URL (e.g., https://myorg.grafana.net)
# GRAFANA_TOKEN - Grafana Service Account token with Editor role
#
# Optional secrets:
# GRAFANA_FOLDER_ID - Folder ID to place dashboards in
name: PR Observability Dashboard
on:
pull_request:
types: [opened, synchronize, reopened]
paths:
- '**/*.rb'
- '!spec/**'
- '!test/**'
permissions:
contents: read
pull-requests: write
jobs:
generate-dashboard:
name: Generate Grafana Dashboard
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0 # Need full history for git diff
ref: ${{ github.event.pull_request.head.sha }} # Checkout the PR head
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.2'
bundler-cache: true
- name: Install diffdash from GitHub
run: |
git clone https://github.com/rossme/diffdash.git /tmp/diffdash
cd /tmp/diffdash
gem build diffdash.gemspec
gem install diffdash-*.gem
- name: Generate and upload dashboard
id: dashboard
env:
GRAFANA_URL: ${{ secrets.GRAFANA_URL }}
GRAFANA_TOKEN: ${{ secrets.GRAFANA_TOKEN }}
GRAFANA_FOLDER_ID: ${{ secrets.GRAFANA_FOLDER_ID }}
run: |
# Run diffdash and capture output
OUTPUT=$(diffdash --verbose 2>&1) || {
echo "::error::Diffdash failed"
echo "$OUTPUT"
exit 1
}
# Extract dashboard URL from output (it's printed to stderr)
DASHBOARD_URL=$(echo "$OUTPUT" | grep "Uploaded to:" | sed 's/.*Uploaded to: //')
if [ -n "$DASHBOARD_URL" ]; then
echo "dashboard_url=$DASHBOARD_URL" >> $GITHUB_OUTPUT
echo "dashboard_created=true" >> $GITHUB_OUTPUT
else
echo "dashboard_created=false" >> $GITHUB_OUTPUT
fi
# Also output the JSON for debugging
echo "$OUTPUT"
- name: Comment on PR with dashboard link
if: steps.dashboard.outputs.dashboard_created == 'true'
uses: actions/github-script@v7
with:
script: |
const dashboardUrl = '${{ steps.dashboard.outputs.dashboard_url }}';
const prNumber = context.issue.number;
// Check for existing comment to update
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
});
const botComment = comments.find(c =>
c.user.type === 'Bot' &&
c.body.includes('📊 Observability Dashboard')
);
const body = `## 📊 Observability Dashboard
A Grafana dashboard has been generated for the observability signals in this PR.
**[View Dashboard](${dashboardUrl})**
This dashboard includes panels for:
- Log events detected in changed files
- Metrics (counters, gauges, histograms)
- Signals from parent classes and included modules
---
<sub>Generated by [diffdash](https://github.com/rossme/diffdash) • Updates on each push</sub>`;
if (botComment) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body: body
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body: body
});
}
- name: Comment if no signals found
if: steps.dashboard.outputs.dashboard_created == 'false'
uses: actions/github-script@v7
with:
script: |
const prNumber = context.issue.number;
// Check for existing comment
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
});
const botComment = comments.find(c =>
c.user.type === 'Bot' &&
c.body.includes('📊 Observability Dashboard')
);
const body = `## 📊 Observability Dashboard
No observability signals were detected in the Ruby files changed in this PR.
Signals we look for:
- \`logger.info\`, \`Rails.logger.*\`, etc.
- \`StatsD.increment\`, \`Prometheus.counter\`, etc.
---
<sub>Generated by [diffdash](https://github.com/rossme/diffdash)</sub>`;
if (botComment) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body: body
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body: body
});
}