blob: ca465674da0954eda8283425485ad93a82e363aa [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'),
Philip Zeyligerf1787552025-05-28 02:44:39 +0000107 headers={
108 'Content-Type': 'application/json',
109 'User-Agent': 'sketch.dev developers'
110 }
Philip Zeyliger9e3c8672025-05-27 17:09:14 +0000111 )
112
113 try:
114 with urllib.request.urlopen(req) as response:
115 if response.status == 204:
116 print("Discord notification sent successfully")
117 else:
118 print(f"Discord webhook returned status: {response.status}")
Philip Zeyligerf1787552025-05-28 02:44:39 +0000119 response_body = response.read().decode('utf-8')
120 print(f"Response body: {response_body}")
Philip Zeyliger9e3c8672025-05-27 17:09:14 +0000121 sys.exit(1)
122 except urllib.error.HTTPError as e:
123 print(f"Discord webhook HTTP error: {e.code} - {e.reason}")
124 try:
125 error_body = e.read().decode('utf-8')
126 print(f"Error details: {error_body}")
127 if e.code == 403 and 'error code: 1010' in error_body:
128 print("Error 1010: Webhook not found - the Discord webhook URL may be invalid or expired")
129 except:
130 pass
131 sys.exit(1)
132 except Exception as e:
133 print(f"Failed to send Discord notification: {e}")
134 sys.exit(1)
135
136if __name__ == "__main__":
137 main()