blob: b73b5d2c7b42c17e4a672371ffdf4431d7ff3bcb [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)
Josh Bleecher Snyderfa306772025-05-28 09:37:04 -070014
Philip Zeyliger9e3c8672025-05-27 17:09:14 +000015 if not os.environ.get('GITHUB_REPOSITORY'):
16 print("Error: GITHUB_REPOSITORY environment variable is required")
17 sys.exit(1)
Josh Bleecher Snyderfa306772025-05-28 09:37:04 -070018
Philip Zeyliger9e3c8672025-05-27 17:09:14 +000019 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()
Josh Bleecher Snyderfa306772025-05-28 09:37:04 -070031
32 # Get commit body (description)
33 commit_body = subprocess.check_output(
34 ['git', 'log', '-1', '--pretty=format:%b'],
35 text=True, stderr=subprocess.DEVNULL
36 ).strip()
37
Philip Zeyliger9e3c8672025-05-27 17:09:14 +000038 # Get commit author
39 commit_author = subprocess.check_output(
40 ['git', 'log', '-1', '--pretty=format:%an'],
41 text=True, stderr=subprocess.DEVNULL
42 ).strip()
Josh Bleecher Snyderfa306772025-05-28 09:37:04 -070043
44 return commit_message, commit_body, commit_author
Philip Zeyliger9e3c8672025-05-27 17:09:14 +000045 except subprocess.CalledProcessError as e:
46 print(f"Failed to get commit information: {e}")
47 sys.exit(1)
48
49def main():
50 # Validate we're running in the correct environment
51 validate_environment()
Josh Bleecher Snyderfa306772025-05-28 09:37:04 -070052
Philip Zeyliger9e3c8672025-05-27 17:09:14 +000053 # Check for test mode
54 if os.environ.get('DISCORD_TEST_MODE') == '1':
55 print("Running in test mode - will not send actual webhook")
Josh Bleecher Snyderfa306772025-05-28 09:37:04 -070056
Philip Zeyliger9e3c8672025-05-27 17:09:14 +000057 # Get commit information from git
Josh Bleecher Snyderfa306772025-05-28 09:37:04 -070058 commit_message, commit_body, commit_author = get_commit_info()
59
Philip Zeyliger9e3c8672025-05-27 17:09:14 +000060 # Get remaining info from environment
61 github_sha = os.environ.get('GITHUB_SHA')
62 commit_sha = github_sha[:8]
63 commit_url = f"https://github.com/{os.environ.get('GITHUB_REPOSITORY')}/commit/{github_sha}"
Josh Bleecher Snyderfa306772025-05-28 09:37:04 -070064
Philip Zeyliger9e3c8672025-05-27 17:09:14 +000065 # Create timestamp
66 timestamp = datetime.now(timezone.utc).strftime('%Y-%m-%dT%H:%M:%S.%fZ')[:-3] + 'Z'
Josh Bleecher Snyderfa306772025-05-28 09:37:04 -070067
Philip Zeyliger9e3c8672025-05-27 17:09:14 +000068 # Create Discord webhook payload
69 payload = {
70 "embeds": [
71 {
Josh Bleecher Snyderfa306772025-05-28 09:37:04 -070072 "title": commit_message,
73 "description": commit_body,
Philip Zeyliger9e3c8672025-05-27 17:09:14 +000074 "color": 5814783,
75 "fields": [
76 {
77 "name": "Author",
78 "value": commit_author,
79 "inline": True
80 },
81 {
82 "name": "Commit",
83 "value": f"[{commit_sha}]({commit_url})",
84 "inline": True
85 },
Philip Zeyliger9e3c8672025-05-27 17:09:14 +000086 ],
87 "timestamp": timestamp
88 }
89 ]
90 }
Josh Bleecher Snyderfa306772025-05-28 09:37:04 -070091
Philip Zeyliger9e3c8672025-05-27 17:09:14 +000092 # Convert to JSON
93 json_payload = json.dumps(payload)
Josh Bleecher Snyderfa306772025-05-28 09:37:04 -070094
Philip Zeyliger9e3c8672025-05-27 17:09:14 +000095 # Test mode - just print the payload
96 if os.environ.get('DISCORD_TEST_MODE') == '1':
97 print("Generated Discord payload:")
98 print(json.dumps(payload, indent=2))
99 print("✓ Test mode: payload generated successfully")
100 return
Josh Bleecher Snyderfa306772025-05-28 09:37:04 -0700101
Philip Zeyliger9e3c8672025-05-27 17:09:14 +0000102 # Send to Discord webhook
103 webhook_url = os.environ.get('DISCORD_WEBHOOK_FOR_COMMITS')
Josh Bleecher Snyderfa306772025-05-28 09:37:04 -0700104
Philip Zeyliger9e3c8672025-05-27 17:09:14 +0000105 req = urllib.request.Request(
106 webhook_url,
107 data=json_payload.encode('utf-8'),
Philip Zeyligerf1787552025-05-28 02:44:39 +0000108 headers={
109 'Content-Type': 'application/json',
110 'User-Agent': 'sketch.dev developers'
111 }
Philip Zeyliger9e3c8672025-05-27 17:09:14 +0000112 )
Josh Bleecher Snyderfa306772025-05-28 09:37:04 -0700113
Philip Zeyliger9e3c8672025-05-27 17:09:14 +0000114 try:
115 with urllib.request.urlopen(req) as response:
116 if response.status == 204:
117 print("Discord notification sent successfully")
118 else:
119 print(f"Discord webhook returned status: {response.status}")
Philip Zeyligerf1787552025-05-28 02:44:39 +0000120 response_body = response.read().decode('utf-8')
121 print(f"Response body: {response_body}")
Philip Zeyliger9e3c8672025-05-27 17:09:14 +0000122 sys.exit(1)
123 except urllib.error.HTTPError as e:
124 print(f"Discord webhook HTTP error: {e.code} - {e.reason}")
125 try:
126 error_body = e.read().decode('utf-8')
127 print(f"Error details: {error_body}")
128 if e.code == 403 and 'error code: 1010' in error_body:
129 print("Error 1010: Webhook not found - the Discord webhook URL may be invalid or expired")
130 except:
131 pass
132 sys.exit(1)
133 except Exception as e:
134 print(f"Failed to send Discord notification: {e}")
135 sys.exit(1)
136
137if __name__ == "__main__":
138 main()