A calm GitHub Actions workflow that gently reviews Dependabot pull requests and provides clear summaries to help you merge confidently.
gon stays quiet, helpful, and unobtrusive.
# .github/workflows/gon.ymlname: Gonon:
pull_request:
types: [opened, synchronize, reopened]issue_comment:
types: [created, edited]workflow_dispatch:
inputs:
pr_number:
description: 'PR number to analyze'required: falsetype: stringjobs:
analyze-dependabot-pr:
uses: libnudget/gon/.github/workflows/gon.yml@mainpermissions:
pull-requests: writecontents: read# .github/workflows/gon.ymlname: gonon:
pull_request:
types: [opened, synchronize, reopened]issue_comment:
types: [created, edited]jobs:
analyze-dependabot-pr:
runs-on: ubuntu-latestpermissions:
pull-requests: writecontents: readsteps:
- name: Determine if should runid: should-runrun: | if [ "${{ github.actor }}" = "dependabot[bot]" ]; then echo "RUN=true" >> $GITHUB_OUTPUT echo "PR_NUMBER=${{ github.event.pull_request.number }}" >> $GITHUB_OUTPUT echo "TRIGGER_USER=dependabot[bot]" >> $GITHUB_OUTPUT else echo "RUN=false" >> $GITHUB_OUTPUT fi - name: Get changed filesif: steps.should-run.outputs.RUN == 'true'id: changed-filesrun: | PR_NUM="${{ steps.should-run.outputs.PR_NUMBER }}" PR_DATA=$(curl -s -H "Authorization: token ${{ github.token }}" \ -H "Accept: application/vnd.github.v3+json" \ "https://api.github.com/repos/${{ github.repository }}/pulls/$PR_NUM") echo "PR_TITLE=$(echo "$PR_DATA" | jq -r '.title')" >> $GITHUB_OUTPUT FILES_JSON=$(curl -s -H "Authorization: token ${{ github.token }}" \ -H "Accept: application/vnd.github.v3+json" \ "https://api.github.com/repos/${{ github.repository }}/pulls/$PR_NUM/files?per_page=100") FILES=$(echo "$FILES_JSON" | jq -r '.[].filename') DEP_PATTERNS="requirements|setup.py|pyproject.toml|Pipfile|package.json|yarn.lock|pnpm-lock.yaml|Cargo.toml|go.mod|go.sum|composer.json|pom.xml|\\.csproj$|Gemfile" DEP_FILES="" for file in $FILES; do if echo "$file" | grep -qiE "$DEP_PATTERNS"; then DEP_FILES="$DEP_FILES $file" fi done echo "CHANGED_FILES=$DEP_FILES" >> $GITHUB_OUTPUT - name: Analyze changesif: steps.should-run.outputs.RUN == 'true'id: analysisrun: | PR_TITLE="${{ steps.changed-files.outputs.PR_TITLE }}" if [ -z "${{ steps.changed-files.outputs.CHANGED_FILES }}" ]; then echo "impact=low" >> $GITHUB_OUTPUT echo "status=No dependency files were modified." >> $GITHUB_OUTPUT exit 0 fi echo "impact=medium" >> $GITHUB_OUTPUT if echo "$PR_TITLE" | grep -qi "security"; then echo "status=Security-related update. Review calmly before merging." >> $GITHUB_OUTPUT elif echo "$PR_TITLE" | grep -qiE "(major|breaking)"; then echo "impact=high" >> $GITHUB_OUTPUT echo "status=Major update detected. Testing is recommended." >> $GITHUB_OUTPUT elif echo "$PR_TITLE" | grep -qiE "(minor|patch|chore|deps|fix)"; then echo "impact=low" >> $GITHUB_OUTPUT echo "status=Minor update. Usually safe to merge." >> $GITHUB_OUTPUT else echo "status=Review the dependency changes before merging." >> $GITHUB_OUTPUT fi - name: Post summary commentif: steps.should-run.outputs.RUN == 'true'uses: actions/github-script@v7with:
script: | const impact = '${{ steps.analysis.outputs.impact }}'; const status = '${{ steps.analysis.outputs.status }}'; const files = '${{ steps.changed-files.outputs.CHANGED_FILES }}'; const pr = Number('${{ steps.should-run.outputs.PR_NUMBER }}'); const user = '${{ steps.should-run.outputs.TRIGGER_USER }}'; const symbol = impact === 'high' ? '⚠️' : impact === 'medium' ? '◻️' : '✓'; const body = `Hi @${user},\n\n` + `I took a calm look at this Dependabot pull request.\n\n` + `## gon ${symbol}\n\n` + `${status}\n\n` + `**Changed files:** ${files || 'None'}\n\n` + `---\n` + `_Reviewed quietly by gon_`; const comments = await github.rest.issues.listComments({ owner: context.repo.owner, repo: context.repo.repo, issue_number: pr, }); const existing = comments.data.find(c => c.user.type === 'Bot' && c.body.includes('_Reviewed quietly by gon_') ); if (existing) { await github.rest.issues.updateComment({ owner: context.repo.owner, repo: context.repo.repo, comment_id: existing.id, body, }); } else { await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: pr, body, }); } - name: Skipif: steps.should-run.outputs.RUN != 'true'run: echo "gon stayed quiet."- Automatic triggering: Runs on Dependabot PRs automatically
- Comment triggers: Use
/analyze,/run analysis, or/check pron any PR - Manual trigger: Use
workflow_dispatchto analyze any PR by number - Impact assessment: Categorizes updates as low, medium, or high impact
- Smart detection: Identifies security, major, and minor updates from PR titles
- Non-intrusive: Stays quiet when not triggered, no noise from other PRs
| Event | Behavior |
|---|---|
| Dependabot PR opened/synced | Automatically analyzes |
/analyze comment | Analyzes the PR |
workflow_dispatch | Manually trigger with PR number |
| Level | Symbol | When |
|---|---|---|
| Low | ✓ | Minor, patch, chore, deps, fix updates |
| Medium | ◻️ | Regular dependency updates |
| High | Major/breaking updates, security fixes |
To review or adjust the workflow, simply edit the file locally:
.github/workflows/gon.ymlNo local server, build step, or additional tooling is required.
gon is an Open Source project licensed under the MIT License.
Contributions are welcome. Please open an issue to discuss changes before submitting a pull request.
Automation should assist quietly.
gon exists to reduce noise and provide calm guidance without blocking, enforcing, or interrupting existing workflows.