Skip to main content

Monday GitHub Integration - Implementation Guide

This guide is for developers implementing or maintaining the Monday-GitHub integration. For user-facing documentation, see Monday GitHub Integration.

Architecture

System Overview

Components

  1. Local Git Hook (Optional)

    • File: .github/hooks/commit-msg
    • Validates commit messages contain Monday links
    • Installed manually by running .github/hooks/install.sh
    • Allows bypass with [skip-monday] tag or --no-verify flag
  2. GitHub Webhook

    • Triggers on push events to any branch
    • Sends payload to pivot-kpi API endpoint
    • Configured via Terraform in pivot-devops
  3. pivot-kpi API Endpoint (/api/webhooks/github)

    • Receives and processes webhook payloads
    • Verifies webhook signature (security)
    • Extracts Monday task IDs from commit messages
  4. Monday.com API Client

    • Posts updates to Monday tasks
    • Includes duplicate detection logic
    • Formats commit info for Monday

Setup Guide for New Repositories

Step 1: Add Git Hooks to Repository

Create .github/hooks/commit-msg:

#!/bin/bash
# Monday.com Link Validation - Local Git Hook
# Validates that commit messages contain a Monday.com task link
#
# Installation: Run ./.github/hooks/install.sh
#
# Bypass:
# - Use [skip-monday] in commit message
# - Use git commit --no-verify to skip all hooks

COMMIT_MSG_FILE=$1
COMMIT_MSG=$(cat "$COMMIT_MSG_FILE")

# Check if commit message contains Monday.com link or [skip-monday] tag
if echo "$COMMIT_MSG" | grep -qE '(monday\.com/boards/[0-9]+(/views/[0-9]+)?/pulses/[0-9]+|\[skip-monday\])'; then
# Valid commit - has Monday link or skip tag
exit 0
else
# Invalid commit - missing Monday link
echo ""
echo "❌ COMMIT REJECTED: Missing Monday.com task link"
echo ""
echo "Every commit must include a Monday.com task URL like:"
echo " https://pivotapp.monday.com/boards/XXX/pulses/YYY"
echo ""
echo "To bypass this check (for testing/CICD), add [skip-monday] to your commit message."
echo "To skip this hook entirely, use: git commit --no-verify"
echo ""
exit 1
fi

Create .github/hooks/install.sh:

#!/bin/bash
# Install Monday.com validation git hook
# Run this once after cloning the repository

HOOK_SOURCE=".github/hooks/commit-msg"
HOOK_DEST=".git/hooks/commit-msg"

if [ ! -f "$HOOK_SOURCE" ]; then
echo "❌ Error: $HOOK_SOURCE not found"
echo "Make sure you're running this from the repository root"
exit 1
fi

# Copy hook to git hooks directory
cp "$HOOK_SOURCE" "$HOOK_DEST"
chmod +x "$HOOK_DEST"

echo "✅ Git hook installed successfully!"
echo ""
echo "The commit-msg hook will now validate that all commits include a Monday.com task link."
echo ""
echo "Usage:"
echo " - Normal commit: git commit -m \"Your message"
echo ""
echo " https://pivotapp.monday.com/boards/XXX/pulses/YYY\""
echo " - Skip validation: git commit -m \"Your message [skip-monday]\""
echo " - Skip all hooks: git commit --no-verify -m \"Your message\""
echo ""

Make executable and commit:

chmod +x .github/hooks/commit-msg .github/hooks/install.sh
git add .github/hooks/
git commit -m "Add Monday.com validation git hooks

https://pivotapp.monday.com/boards/XXX/pulses/YYY"
git push

Step 2: Configure Webhook via Terraform

In /home/chipdev/pivot-meta/pivot-devops/github/webhook-[your-repo].tf:

# GitHub Webhook for [your-repo]
# Sends push events to the KPI dashboard for Monday.com integration

resource "github_repository_webhook" "your_repo_monday_integration" {
repository = "your-repo-name"

configuration {
url = "https://kpi.pivotdev.ca/api/webhooks/github"
content_type = "json"
secret = "c6ef29d6bd781b265c6fe59445bd05ee9b047deaadb9e934361c8aaeef2980bc"
insecure_ssl = false
}

events = ["push", "pull_request"]
active = true
}

Apply with:

cd /home/chipdev/pivot-meta/pivot-devops/github
terraform apply

Step 3: Test the Integration

Push a commit with a Monday link:

git commit -m "Test Monday integration

https://pivotapp.monday.com/boards/4176868787/pulses/18382176781"
git push origin main

Check:

  1. Monday task for notification
  2. GitHub webhook deliveries (Settings → Webhooks)

Monday.com URL Pattern

The system detects Monday task references in commit messages using this regex:

/monday\.com\/boards\/\d+(?:\/views\/\d+)?\/pulses\/(\d+)/

Matches:

  • https://pivotapp.monday.com/boards/123/pulses/456
  • https://pivotapp.monday.com/boards/123/views/789/pulses/456

Duplicate Detection

Problem

When a PR is merged, the same commit can appear multiple times in the target branch, which would create duplicate notifications.

Solution

Before posting a notification, check if an identical update already exists in the Monday task:

  1. Fetch existing updates for the task via Monday API
  2. Compare the new notification text with existing updates
  3. Only post if no exact match exists

Edge Cases

  • Different commits, same PR: Allow duplicates (different commit messages)
  • Same commit, different tasks: Allow duplicates (different Monday tasks)
  • Same commit, same task: Prevent duplicate

Pull Request Tracking

In addition to commit tracking, the system now supports full pull request lifecycle management with Monday.com integration.

PR Workflow

Commit Tracking Flow

Key Points:

  • Only commits pushed to main or master branches trigger Monday updates
  • Feature branch commits are tracked via PR notifications instead
  • Commits are accumulated into a single Monday update that gets replaced when new commits arrive
  • Each commit update shows: commit SHA (short), message, author, and link to GitHub

PR Requirements

All Pull Requests MUST include a Monday.com task link in the PR body:

https://pivotapp.monday.com/boards/BOARD_ID/pulses/TASK_ID

or

https://pivot584586.monday.com/boards/BOARD_ID/pulses/TASK_ID

The Monday link MUST be in the PR description body, NOT in individual commit messages.

PR Events Handled

  1. PR Opened (pull_request.opened)

    • Extracts Monday task IDs from PR body
    • Posts notification to each linked Monday task
    • Notification includes: PR number, title, author, link
  2. PR Merged (pull_request.closed with merged: true)

    • Extracts Monday task IDs from PR body
    • Updates BOTH status columns on the Monday task
    • Posts merge notification
  3. PR Closed (not merged) (pull_request.closed with merged: false)

    • No action taken
  4. Other PR events (edited, reopened, synchronize)

    • No action taken (avoids spam)

Status Column Updates

When a PR is merged, the system automatically updates TWO status columns on the linked Monday task(s):

Column IDColumn NameNew Value
status9StatusDeployed to non-production
dup__of_status__1Deployment StatusDeployed to non-production

Implementation Details:

  • Requires board_id parameter (fetched via getTaskDetails())
  • Uses Monday GraphQL mutation change_column_value
  • Value format: JSON.stringify({ label: "Deployed to non-production" })

Preview URL Integration

For repositories with Firebase Hosting preview deployments (like pivot), the preview URL is automatically posted to Monday.

Preview URL Format: https://pivot-dev-59310--pr-{number}-{hash}.web.app

Implementation Details:

  1. Firebase Workflow (.github/workflows/firebase-hosting-pull-request.yml):

    • Deploy to preview channel captures details_url output
    • Workflow calls pivot-kpi endpoint with preview URL and PR details
  2. pivot-kpi Endpoint (/api/webhooks/monday-preview):

    • Receives preview URL, PR number, repository, and PR body
    • Extracts Monday task IDs from PR body
    • Checks for duplicate preview URLs (prevents reposting)
    • Posts clickable HTML link to Monday task
  3. Notification Format:

    🌐 Preview Deployment

    PR #123 - pivotteam/pivot

    🔗 Preview URL: <a href="URL" target="_blank">URL</a>

Duplicate Prevention: The system checks existing Monday updates for the same preview URL before posting, preventing duplicates if the workflow reruns.

Monday Updates Summary

For each PR, you'll see up to 4 separate Monday updates:

  1. PR Opened - When PR is created (one time)
  2. Commits - Consolidated list of commits on main branch (updated as new commits pushed)
  3. Preview URL - Link to preview deployment (posted once, if available)
  4. PR Merged - Merge notification + status column updates (one time)

Important: Each update is separate and distinct to maintain clarity in Monday task history.

API Endpoints

GitHub Webhook Receiver

Endpoint: POST /api/webhooks/github

Location: /home/chipdev/pivot-meta/pivot-kpi/app/api/webhooks/github/route.ts

Authentication: GitHub webhook secret (HMAC SHA-256)

Payload (GitHub push event):

{
"ref": "refs/heads/branch-name",
"commits": [
{
"id": "abc123...",
"message": "Fix bug\n\nhttps://pivotapp.monday.com/boards/123/pulses/456",
"url": "https://github.com/org/repo/commit/abc123",
"author": {
"name": "Developer Name",
"email": "dev@example.com"
}
}
],
"repository": {
"name": "repo-name",
"full_name": "org/repo-name"
}
}

Response:

{
"success": true,
"repository": "pivotteam/pivot",
"branch": "main",
"commits_processed": 2,
"notifications": {
"posted": 2,
"duplicates_skipped": 0,
"errors": 0
},
"results": [
{
"taskId": "456",
"commit": "abc123",
"status": "posted"
}
]
}

Monday.com API Integration

Authentication

Use Monday.com API token (personal or app token).

Environment Variable: MONDAY_API_TOKEN

Token Location:

  • GitHub: Organization secret MONDAY_API_TOKEN
  • pivot-kpi: Environment variable or GitHub Actions secret

API Endpoints Used

  1. Get Task Updates

    • Endpoint: https://api.monday.com/v2
    • Query: query { items(ids: [TASK_ID]) { updates { body } } }
    • Purpose: Check for duplicates
  2. Create Update

    • Endpoint: https://api.monday.com/v2
    • Mutation: mutation { create_update(item_id: TASK_ID, body: "text") { id } }
    • Purpose: Post notification

Notification Format

🔧 GitHub Commit

Repository: org/repo-name
Branch: feature-branch
Commit: abc123

Message: Fix authentication bug

👤 Author: Developer Name
🔗 View Commit: https://github.com/org/repo/commit/abc123

Implementation Checklist

Core Infrastructure (One-time - COMPLETED)

  • Create Monday.com API token
  • Create organization-level MONDAY_API_TOKEN secret
  • Implement GitHub webhook receiver at /api/webhooks/github
  • Implement Monday.com client wrapper
  • Implement duplicate detection logic
  • Add webhook signature verification
  • Deploy to production (kpi.pivotdev.ca)

Adding to New Repository

  • Create .github/hooks/commit-msg hook file
  • Create .github/hooks/install.sh installer script
  • Make hook files executable (chmod +x)
  • Commit hook files to repository
  • Add webhook configuration in Terraform (webhook-*.tf)
  • Run terraform apply
  • Test: Push commit with Monday link
  • Verify: Check Monday task for notification
  • Verify: Check GitHub webhook deliveries
  • Document: Update repository README with hook installation instructions
  • Inform: Tell team to run ./.github/hooks/install.sh after cloning

Current Status

Commit Tracking + PR Tracking:

  • pivot (main web app - webhook + hooks + PR tracking + preview URLs)
  • pivot-kpi (KPI dashboard - webhook + hooks + PR tracking)
  • pivot-mobile (React Native app - webhook + hooks + PR tracking)
  • pivot-jobs (pending)

Features Implemented:

  • Commit notifications to Monday (main branch only)
  • PR opened notifications
  • PR merged notifications with status updates
  • Automatic status column updates (Status + Deployment Status)
  • Preview URL posting with clickable links
  • Comprehensive unit tests with CI/CD integration

Troubleshooting

Webhook not posting to Monday

  1. Check webhook delivery in GitHub:

    • Go to repository Settings → Webhooks
    • Click on webhook URL
    • Check recent deliveries for errors
  2. Verify webhook secret matches:

    • Terraform: Check webhook-*.tf files
    • pivot-kpi: Check WEBHOOK_SECRET environment variable
  3. Check pivot-kpi logs (webhook receiver):

    cd /home/chipdev/pivot-meta/pivot-kpi
    npm run dev # Check console for webhook events
  4. Test webhook manually:

    # Get recent delivery payload from GitHub
    # Resend using curl or Postman

Webhook secret mismatch

All webhooks use the same secret:

c6ef29d6bd781b265c6fe59445bd05ee9b047deaadb9e934361c8aaeef2980bc

This must match the WEBHOOK_SECRET environment variable in pivot-kpi.

Security Considerations

  1. Webhook Secret Verification

    • Always verify GitHub webhook signature
    • Use constant-time comparison
    • Reject invalid signatures immediately
  2. API Token Storage

    • Store in environment variables
    • Never commit to git
    • Rotate periodically
  3. Input Validation

    • Sanitize commit messages before posting
    • Validate Monday task IDs (numeric only)
    • Prevent injection attacks

Monitoring

Metrics to Track

  • Total webhooks received
  • Notifications posted successfully
  • Duplicates skipped
  • Errors by type
  • Processing time
  • Monday API rate limit usage

Logs to Capture

{
timestamp: "2025-01-18T12:00:00Z",
event: "webhook_received",
repository: "pivotteam/pivot",
branch: "main",
commits: 3,
notifications: {
posted: 2,
duplicates_skipped: 1,
errors: 0
}
}

Rate Limits

Monday.com API

  • Rate limit: 60 requests per minute per token
  • Recommended: Add exponential backoff and retry logic
  • Monitor: Check response headers for rate limit status

GitHub Webhooks

  • Timeout: 10 seconds
  • Retry: GitHub retries failed webhooks
  • Recommended: Respond quickly (200 OK), process async if needed

File Locations

Git Hooks (in each repository)

  • .github/hooks/commit-msg - Validation hook
  • .github/hooks/install.sh - Installation script

Terraform (pivot-devops repository)

  • github/webhook-kpi.tf - pivot-kpi webhook
  • github/webhook-pivot.tf - pivot webhook
  • github/webhook-mobile.tf - Pivotmobile webhook

API Implementation (pivot-kpi repository)

  • app/api/webhooks/github/route.ts - Webhook receiver (handles both push and pull_request events)
  • app/api/webhooks/monday-preview/route.ts - Preview URL posting endpoint
  • lib/github/webhooks.ts - GitHub utilities and type definitions
  • lib/github/pr-handlers.ts - Pull request event handlers
  • lib/monday/client.ts - Monday.com API client (includes status update functions)
  • tests/unit/ - Comprehensive unit tests for all pure functions
  • tests/unit/monday-preview-endpoint.test.ts - Preview URL endpoint tests

Future Enhancements

  1. Bidirectional Sync

    • Monday task updates → GitHub PR comments
    • Status sync (task complete → close PR)
  2. Rich Notifications

    • Include diff summary
    • Link to CI/CD status
    • Show changed files
  3. Analytics Dashboard

    • Commits per Monday task
    • Developer activity
    • Task completion velocity
  4. Automated Hook Installation

    • Explore git config options (init.templateDir)
    • Consider package.json postinstall script
    • Document for team leads