feat: 提交 commit 时检查关联 linear issue TUN-24
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Ching 2024-03-21 14:59:30 +08:00
parent 2ce344821f
commit 47248968fc

66
app.py
View File

@ -1,7 +1,10 @@
from flask import Flask, request, jsonify
import apprise
import os import os
import re
import apprise
from flask import Flask, request, jsonify
from loguru import logger from loguru import logger
import requests
import sentry_sdk import sentry_sdk
@ -9,6 +12,8 @@ DISCORD_WEBHOOK_URL = os.environ.get('DISCORD_WEBHOOK_URL')
DISCORD_WEBHOOK_ID = DISCORD_WEBHOOK_URL.split('/')[-2] DISCORD_WEBHOOK_ID = DISCORD_WEBHOOK_URL.split('/')[-2]
DISCORD_WEBHOOK_TOKEN = DISCORD_WEBHOOK_URL.split('/')[-1] DISCORD_WEBHOOK_TOKEN = DISCORD_WEBHOOK_URL.split('/')[-1]
SENTRY_DSN = os.environ.get('SENTRY_DSN') SENTRY_DSN = os.environ.get('SENTRY_DSN')
LINEAR_API_URL = 'https://api.linear.app/graphql'
LINEAR_API_KEY = os.environ.get('LINEAR_API_KEY')
sentry_sdk.init( sentry_sdk.init(
dsn=SENTRY_DSN, dsn=SENTRY_DSN,
@ -54,5 +59,62 @@ def linear_issue():
return jsonify({'message': 'Ok'}), 200 return jsonify({'message': 'Ok'}), 200
@app.route('/gitea/push', methods=['POST'])
def gitea_push():
""" https://docs.gitea.io/en-us/webhooks/
"""
data = request.json
logger.info('Received gitea push webhook: %s' % data)
if request.headers.get('X-Gitea-Event') != 'push':
logger.error('Invalid event type: %s' % request.headers.get('X-Gitea-Event'))
return jsonify({'message': 'Invalid event type'}), 400
# check if it's a Linear issue
# linear issue id is like 'TUN-21'
headers = {'Authorization': LINEAR_API_KEY}
state_query = {'query': '{workflowStates(includeArchived:false) { edges { node { id name type } }}}'}
state_resp = requests.post(LINEAR_API_URL, json=state_query, headers=headers)
if state_resp.status_code != 200:
logger.error('Failed to get workflow states: %s' % state_resp.text)
return jsonify({'message': 'Failed to get workflow states'}), 500
states = state_resp.json().get('data').get('workflowStates').get('edges')
completed_state = None
for state in states:
if state['node']['type'] == 'completed':
completed_state = state['node']['id']
break
if not completed_state:
logger.error('Failed to get completed state')
return jsonify({'message': 'Failed to get completed state'}), 500
# check if the commit message contains a linear issue id
# if yes, update the issue state to completed
for commit in data['commits']:
issue = re.search(r'TUN-\d+', commit['message'])
if issue:
issue_id = issue.group()
data_ = {'query': '{ issue(id: "%s") { title state { name }}}' % issue_id}
resp = requests.post(LINEAR_API_URL, json=data_, headers=headers)
if resp.status_code != 200:
logger.error('Failed to get issue: %s' % resp.text)
return jsonify({'message': 'Failed to get issue'}), 500
issue_data = resp.json().get('data')
if not issue_data:
logger.error('Issue not found: %s' % issue_id)
return jsonify({'message': 'Issue not found'}), 400
issue_data = issue_data['issue']
if issue_data['state']['type'] == 'completed':
return jsonify({'message': 'Issue already completed'}), 200
update_data = {'query': 'mutation { issueUpdate(input: { stateId: "%s" } id: "%s") { success } }' % (completed_state, issue_id)}
update_resp = requests.post(LINEAR_API_URL, json=update_data, headers=headers)
if update_resp.status_code != 200:
logger.error('Failed to update issue: %s' % update_resp.text)
return jsonify({'message': 'Failed to update issue'}), 500
if not update_resp.json().get('data', {}).get('issueUpdate', {}).get('success'):
logger.error('Failed to update issue: %s' % update_resp.text)
return jsonify({'message': 'Failed to update issue'}), 500
return jsonify({'message': 'Ok'}), 200
if __name__ == "__main__": if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000) app.run(host="0.0.0.0", port=5000)