feat: 提交 commit 时检查关联 linear issue TUN-24
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
2ce344821f
commit
47248968fc
66
app.py
66
app.py
@ -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)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user