blob: b0d69ef90466db187f08e4c08842bab0e4f73a3c [file] [log] [blame]
Philip Zeyliger9e3c8672025-05-27 17:09:14 +00001#!/usr/bin/env python3
2import json
3import os
4import subprocess
5import sys
6import urllib.request
7from datetime import datetime, timezone
8
9def validate_environment():
10 """Validate required environment variables."""
Philip Zeyliger9e3c8672025-05-27 17:09:14 +000011 if not os.environ.get('GITHUB_SHA'):
12 print("Error: GITHUB_SHA environment variable is required")
13 sys.exit(1)
14
15 if not os.environ.get('GITHUB_REPOSITORY'):
16 print("Error: GITHUB_REPOSITORY environment variable is required")
17 sys.exit(1)
18
19 if not os.environ.get('DISCORD_WEBHOOK_FOR_COMMITS'):
20 print("Error: DISCORD_WEBHOOK_FOR_COMMITS environment variable is required")
21 sys.exit(1)
22
23def get_commit_info():
24 """Extract commit information using git commands."""
25 try:
26 # Get commit message (subject line)
27 commit_message = subprocess.check_output(
28 ['git', 'log', '-1', '--pretty=format:%s'],
29 text=True, stderr=subprocess.DEVNULL
30 ).strip()
31
32 # Get commit author
33 commit_author = subprocess.check_output(
34 ['git', 'log', '-1', '--pretty=format:%an'],
35 text=True, stderr=subprocess.DEVNULL
36 ).strip()
37
38 return commit_message, commit_author
39 except subprocess.CalledProcessError as e:
40 print(f"Failed to get commit information: {e}")
41 sys.exit(1)
42
43def main():
44 # Validate we're running in the correct environment
45 validate_environment()
46
47 # Check for test mode
48 if os.environ.get('DISCORD_TEST_MODE') == '1':
49 print("Running in test mode - will not send actual webhook")
50
51 # Get commit information from git
52 commit_message, commit_author = get_commit_info()
53
54 # Get remaining info from environment
55 github_sha = os.environ.get('GITHUB_SHA')
56 commit_sha = github_sha[:8]
57 commit_url = f"https://github.com/{os.environ.get('GITHUB_REPOSITORY')}/commit/{github_sha}"
58
59 # Create timestamp
60 timestamp = datetime.now(timezone.utc).strftime('%Y-%m-%dT%H:%M:%S.%fZ')[:-3] + 'Z'
61
62 # Create Discord webhook payload
63 payload = {
64 "embeds": [
65 {
66 "title": "New commit to main",
67 "description": f"**{commit_message}**",
68 "color": 5814783,
69 "fields": [
70 {
71 "name": "Author",
72 "value": commit_author,
73 "inline": True
74 },
75 {
76 "name": "Commit",
77 "value": f"[{commit_sha}]({commit_url})",
78 "inline": True
79 },
80 {
81 "name": "Repository",
82 "value": os.environ.get('GITHUB_REPOSITORY'),
83 "inline": True
84 }
85 ],
86 "timestamp": timestamp
87 }
88 ]
89 }
90
91 # Convert to JSON
92 json_payload = json.dumps(payload)
93
94 # Test mode - just print the payload
95 if os.environ.get('DISCORD_TEST_MODE') == '1':
96 print("Generated Discord payload:")
97 print(json.dumps(payload, indent=2))
98 print("✓ Test mode: payload generated successfully")
99 return
100
101 # Send to Discord webhook
102 webhook_url = os.environ.get('DISCORD_WEBHOOK_FOR_COMMITS')
103
104 req = urllib.request.Request(
105 webhook_url,
106 data=json_payload.encode('utf-8'),
107 headers={'Content-Type': 'application/json'}
108 )
109
110 try:
111 with urllib.request.urlopen(req) as response:
112 if response.status == 204:
113 print("Discord notification sent successfully")
114 else:
115 print(f"Discord webhook returned status: {response.status}")
116 sys.exit(1)
117 except urllib.error.HTTPError as e:
118 print(f"Discord webhook HTTP error: {e.code} - {e.reason}")
119 try:
120 error_body = e.read().decode('utf-8')
121 print(f"Error details: {error_body}")
122 if e.code == 403 and 'error code: 1010' in error_body:
123 print("Error 1010: Webhook not found - the Discord webhook URL may be invalid or expired")
124 except:
125 pass
126 sys.exit(1)
127 except Exception as e:
128 print(f"Failed to send Discord notification: {e}")
129 sys.exit(1)
130
131if __name__ == "__main__":
132 main()