A self-hosted webhook processing system that replaces Jira Automation's 3 core rules with a 1:1 alternative.
- Rule-01: Change Jira issue status from 'To Do' → 'In Progress' when branch is created
- Rule-02: Change Jira issue status to 'In Review' when PR is created
- Rule-03: Change Jira issue status to 'Done' when PR is merged
- Discord Notifications: Real-time notifications for each automation result
The following statuses must exist in your Jira project with appropriate transition paths:
| Status Name | Used By | Transition Path |
|---|---|---|
| To Do | Rule-01 | Initial status |
| In Progress | Rule-01 | To Do → In Progress |
| In Review | Rule-02 | In Progress → In Review |
| Done | Rule-03 | Any status → Done |
git clone <repository-url>
cd free-jira-github-integration
npm installCopy .env.example to create .env file and configure values:
cp .env.example .env# Server Configuration
PORT=3000
# GitHub Webhook Configuration
GITHUB_WEBHOOK_SECRET=your-github-webhook-secret-here
# Jira Configuration
JIRA_BASE_URL=https://your-domain.atlassian.net
JIRA_EMAIL=[email protected]
JIRA_API_TOKEN=your-jira-api-token-here
JIRA_PROJECT_KEY=PROJ
# Jira Status Names (customize according to your workflow)
JIRA_STATUS_TODO=To Do
JIRA_STATUS_IN_PROGRESS=In Progress
JIRA_STATUS_IN_REVIEW=In Review
JIRA_STATUS_DONE=Done
# Logging
LOG_LEVEL=info
# Discord Notifications (Optional)
DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/your-webhook-url-
Navigate to Atlassian Account Settings
- 🌐 URL: https://id.atlassian.com/manage-profile/security/api-tokens
⚠️ Note: NOThttps://admin.atlassian.com/!
-
Create API Token
- Click "Create API token" button
- Enter token name (e.g., "GitHub Integration")
- Copy the generated token (shown only once)
-
Set Environment Variable
- Set the copied token to
JIRA_API_TOKEN
- Set the copied token to
When the API token is correctly configured, you'll see logs like this:
POST https://your-worker.workers.dev/api/webhook/github - Ok
(log) Received create event
(log) Processing branch creation event
(log) Found Jira key: MAT-388
(log) Current status: To Do
(log) Successfully transitioned MAT-388 to In Progress
(log) Rule-01: MAT-388 transitioned from To Do to In Progress
If you see errors like this, the API token is incorrectly configured:
Rule-01 failed for MAT-388: Failed to get issue status: Issue MAT-388 not found
Solution:
- Delete existing token and create a new one
- Ensure no leading/trailing spaces when copying token
- Verify the account has access to the Jira project
Test the connection after setup:
curl -u "[email protected]:your-api-token" \
-X GET \
-H "Content-Type: application/json" \
"https://your-domain.atlassian.net/rest/api/3/myself"Success returns account information in JSON format.
GitHub webhooks enable SSL verification by default, but it can be disabled when needed.
- HTTPS endpoint + SSL verification enabled
- Highest security level
- Requires domain with SSL certificate
- HTTP endpoint available (when SSL verification disabled)
- Local development:
http://localhost:3000can be used directly - Lower security but convenient for development
# Option 1: HTTP + SSL verification disabled (simple)
# Use http://localhost:3000 directly
# Check "Disable SSL verification" in GitHub webhook settings
# Option 2: HTTPS tunnel (secure)
npx ngrok http 3000 # or
npx cloudflared tunnel --url http://localhost:3000- GitHub Repository → Settings → Webhooks → Add webhook
- Payload URL:
- Production:
https://your-domain.com/api/webhook/github - Local Development:
http://localhost:3000/api/webhook/github
- Production:
- Content type:
application/json - Secret: Same value as
GITHUB_WEBHOOK_SECRETin.env - SSL verification:
- Production: Keep checked (default)
- Local Development: Check "Disable SSL verification"
- Events: Select
Branch or tag creation,Pull requests,Pushes
npm run devnpm startEndpoint to receive webhooks from GitHub.
Headers:
Content-Type:application/jsonX-GitHub-Event: GitHub event typeX-Hub-Signature-256: HMAC-SHA256 signature
Health check endpoint to verify server status.
(${projectKey}-\d+)- Case-insensitive: Both
MAT-123andmat-123match - Result converted to uppercase: Finally unified as
MAT-123format
✅ Working formats:
feature/MAT-123-add-login
bugfix/mat-456-fix-navigation (case-insensitive)
MAT-789
hotfix/MAT-999-urgent-fix
feat/MAT-123/hello-world
release/v1.0-MAT-111-final-changes
❌ Non-working formats:
feature/PROJ-123 (different project key)
feature/MAT (no issue number)
feature/add-login (no Jira key)
- 1st Priority: Try extracting from PR title
- 2nd Priority: Try extracting from branch name (fallback)
Branch Creation:
git checkout -b "feat/MAT-123/implement-auth"
# → Changes MAT-123 issue from 'To Do' → 'In Progress'PR Creation:
PR Title: "MAT-456: Add user authentication"
Branch Name: "feature/auth-system"
# → Extracts MAT-456 from PR title and changes to 'In Review'
-
Branch Creation (
createevent)- Changes to 'In Progress' only if current status is 'To Do'
-
PR Creation (
pull_request-opened)- Always changes to 'In Review' without conditions
-
PR Merge (
pull_request-closed+merged: true)- Changes to 'Done' only if current status is not 'Done'
All rules are idempotent, so multiple executions of the same request are safe:
- Skips work if already in target status
- Maintains data consistency even with GitHub webhook retries
The system can send real-time notifications to Discord for each automation result.
-
Create Discord Webhook:
- Open Discord server → Text channel → Settings → Integrations → Webhooks
- Click "New Webhook" → Copy webhook URL
- Set the URL to
DISCORD_WEBHOOK_URLenvironment variable
-
Notification Types:
- ✅ Success: When automation rules execute successfully
- ❌ Failure: When automation rules fail with error details
- ⏭️ Skipped: When rules are skipped (e.g., already in target status)
- 🔇 Ignored: No notifications sent for ignored events (no Jira key found)
-
Example Notifications:
Success Notification:
✅ Sync Success 📋 Issue: MAT-462 🔄 Action: In Progress → In ReviewFailure Notification:
❌ Sync Failed 📋 Issue: MAT-456 🔄 Action: Jira status transition ⚠️ Error: Issue not found
Discord notifications are optional. If DISCORD_WEBHOOK_URL is not set, the system will:
- Log a warning message once
- Continue normal operation without notifications
- Still log all activities to console
When all rules work correctly, you'll see logs like this:
POST https://your-worker.workers.dev/api/webhook/github - Ok
(log) Received create event
(log) Processing branch creation event
(log) Found Jira key: MAT-388
(log) Current status: To Do
(log) Successfully transitioned MAT-388 to In Progress
(log) Rule-01: MAT-388 transitioned from To Do to In Progress
POST https://your-worker.workers.dev/api/webhook/github - Ok
(log) Received push event
(log) Ignoring event: push
POST https://your-worker.workers.dev/api/webhook/github - Ok
(log) Received pull_request event
(log) Processing PR opened event
(log) Found Jira key: MAT-388
(log) Successfully transitioned MAT-388 to In Review
(log) Rule-02: MAT-388 transitioned to In Review
POST https://your-worker.workers.dev/api/webhook/github - Ok
(log) Received push event
(log) Ignoring event: push
POST https://your-worker.workers.dev/api/webhook/github - Ok
(log) Received pull_request event
(log) Processing PR merged event
(log) Found Jira key: MAT-388
(log) Current status: In Review
(log) Successfully transitioned MAT-388 to Done
(log) Rule-03: MAT-388 transitioned from In Review to Done
- All processes are logged to console
- Detailed error messages on failures
- Success/failure tracking for each rule
- Skip operations due to idempotency are also logged
Consider the following for production environments:
- HTTPS Required: GitHub webhooks only support HTTPS endpoints
- Process Management: Use PM2 etc. for zero-downtime service operation
- Log Management: Integrate with appropriate log collection systems
- Monitoring: Set up server status and webhook processing failure alerts
Free and convenient serverless deployment option
# Install wrangler (already included in package.json)
npm install
# Login to Cloudflare account
npx wrangler loginIf you haven't created a Worker yet, please agree to create one when setting up your first environment variable.
In Cloudflare Workers, environment variables must be set as secrets:
# Set required environment variables as secrets
npx wrangler secret put GITHUB_WEBHOOK_SECRET
npx wrangler secret put JIRA_BASE_URL
npx wrangler secret put JIRA_EMAIL
npx wrangler secret put JIRA_API_TOKEN
npx wrangler secret put JIRA_PROJECT_KEY
# Optional environment variables (can be omitted if using defaults)
npx wrangler secret put JIRA_STATUS_TODO
npx wrangler secret put JIRA_STATUS_IN_PROGRESS
npx wrangler secret put JIRA_STATUS_IN_REVIEW
npx wrangler secret put JIRA_STATUS_DONE
# Discord notifications (optional)
npx wrangler secret put DISCORD_WEBHOOK_URL# Production deployment
npm run deploy:worker
# Or use wrangler directly
npx wrangler deploy# Test Workers environment locally
npm run dev:worker
# View real-time logs
npm run worker:tailSet the Workers URL provided after deployment to GitHub Webhook:
- URL:
https://your-worker.your-subdomain.workers.dev/api/webhook/github
- Free: Up to 100,000 requests per month
- Global Deployment: Runs on edge servers worldwide
- Auto-scaling: Automatically scales with traffic
- Zero Server Management: No infrastructure management needed
- Fast Cold Start: Quick serverless function startup
- Invalid signature: GitHub webhook secret is incorrect
- Issue not found: Jira issue key doesn't exist
- No transition available: Transition to target status not possible in Jira workflow
- HTTP 404: Not Found: Jira API token expired or insufficient permissions
If you encounter errors like:
Rule-02 failed for MAT-462: Failed to transition issue: Failed to get transitions: HTTP 404: Not Found
Possible Causes:
- Expired API Token: Jira API tokens may have expired
Set log level to 'debug' for more detailed information:
LOG_LEVEL=debugMIT