/images/avatar.png

Patrick Weizhi Xu

GitHub Pull Request 合并时在 Slack 上通知我

厌倦了刷新 GitHub 网页和等待同事的 PR 合并。 试着把这些事情从我脑子里赶走,集中精力做真正的工作。

步骤

只需要三步

  1. 通过 https://api.slack.com/messaging/webhooks 创建 Slack 应用程序。您需要的是在 Incoming Webhooks 下的 以 https://hooks.slack.com/services/ 开头的 Webhook URL,以便向其发送通知消息。
  2. 注意 GitHub API 的速率限制,并根据需要创建个人访问令牌或创建 GitHub 应用程序。
  3. 借助 ChatGPT 和一些修正,我们得到了以下脚本
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import requests
import argparse
import time
import re

# Could be none or personal access token https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api
GITHUB_TOKEN="<your_github_token>"
# On how to get webhooks token https://api.slack.com/messaging/webhooks
SLACK_WEBHOOK="https://hooks.slack.com/services/XXXXXXXXXXX/YYYYYYYYYY/ZZZZZZZZZZZZZZ"
WAIT_DURATION_SEC=600

def parse_args():
    parser = argparse.ArgumentParser(description='Check if a GitHub pull request was merged and send a Slack message.')
    parser.add_argument('pr_url', help='GitHub pull request URL.')
    return parser.parse_args()

def parse_pr_url(pr_url):
    """
    Parses the PR URL and returns the owner, repository, and PR number.

    Example URL: https://github.com/owner/repo/pull/123
    """
    pattern = r'https?://github\.com/(?P<owner>[^/]+)/(?P<repo>[^/]+)/pull/(?P<pr_number>\d+)'
    match = re.match(pattern, pr_url)
    if match:
        return match.group('owner'), match.group('repo'), int(match.group('pr_number'))
    else:
        raise ValueError('Invalid GitHub pull request URL.')

def check_if_pr_merged(owner, repo, pr_number, github_token=None):
    url = f'https://api.github.com/repos/{owner}/{repo}/pulls/{pr_number}'
    headers = {'Accept': 'application/vnd.github.v3+json'}
    if github_token:
        headers['Authorization'] = f'token {github_token}'
    response = requests.get(url, headers=headers)
    if response.status_code == 200:
        pr_data = response.json()
        return pr_data.get('merged', False)
    else:
        print(f'Error fetching PR data: {url} {response.status_code} {response.reason}')
        return False

def send_slack_message(slack_webhook_url, message):
    payload = {'text': message}
    response = requests.post(slack_webhook_url, json=payload)
    if response.status_code != 200:
        print(f'Error sending Slack message: {slack_webhook_url} {response.status_code} {response.reason}')

def main():
    args = parse_args()
    try:
        owner, repo, pr_number = parse_pr_url(args.pr_url)
    except ValueError as e:
        print(e)
        return

    print(f"Monitoring PR #{pr_number} in repository '{owner}/{repo}' for merge status.")

    while True:
        is_merged = check_if_pr_merged(owner, repo, pr_number, GITHUB_TOKEN)

        if is_merged:
            message = f'Pull request {args.pr_url} has been merged.'
            send_slack_message(SLACK_WEBHOOK, message)
            break
        else:
            time.sleep(WAIT_DURATION_SEC)

if __name__ == '__main__':
    main()

保存脚本并进行别名后,您可以使用

力扣周赛 156 + 其他题目

力扣挑战第二周。因为有事,所以参加了模拟比赛。

Weekly Contest 156

1207. Unique Number of Occurrences

https://leetcode.com/contest/weekly-contest-156/problems/unique-number-of-occurrences/

暴力。记下每个数出现的次数,遍历次数看有没有相同的。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
class Solution {
public:
    bool uniqueOccurrences(vector<int>& arr) {
        unordered_map<int, int> occ;
        unordered_map<int, bool> flag;
        
        for (int i = 0; i < arr.size(); ++i) {
            occ[arr[i]]++;
        }
        
        for (const auto x : occ) {
            if (flag.find(x.second) != flag.end()) {
                if (flag[x.second]) return false;
            } else {
                flag[x.second] = true;
            }
        }
        
        return true;
    }
};

1208. Get Equal Substrings Within Budget

https://leetcode.com/contest/weekly-contest-156/problems/get-equal-substrings-within-budget/

力扣周赛 155 + 其他题目

这是力扣第一周挑战,包括周赛 155 和其他一些题目。

Weekly Contest 155

https://leetcode.com/contest/weekly-contest-155

1200. Minimum Absolute Difference

https://leetcode.com/contest/weekly-contest-155/problems/minimum-absolute-difference/

暴力。先遍历找到最小绝对差,接着再遍历一遍输出差值是该值的整数对。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Solution {
public:
    vector<vector<int>> minimumAbsDifference(vector<int>& arr) {
        vector<vector<int>> ans;
        if (arr.size() == 1) return ans;
        sort(arr.begin(), arr.end());
        
        int mini = 0x3f3f3f3f;
        for (int i = 1; i < arr.size(); ++i) {
            mini = min(mini, abs(arr[i] - arr[i-1]));
        }
        
        for (int i = 1; i < arr.size(); ++i) {
            if (abs(arr[i]- arr[i-1]) == mini) {
                if (arr[i] < arr[i-1]) {
                    ans.push_back({arr[i], arr[i-1]});
                } else {
                    ans.push_back({arr[i-1], arr[i]});
                }
            }
        }
        return ans;
    }
};

1201. Ugly Number III

https://leetcode.com/contest/weekly-contest-155/problems/ugly-number-iii/

CLDictP: 命令行英文词典工具

CLDictP是一个用Perl,韦氏词典API写的命令行英文词典工具。

这是我第一个用Perl写的小项目。每次想用Quizlet做Flashcard(抽认卡?)来记单词的时候,因为想有的地方要加粗之类的,手动很麻烦。而且查单词的时候打开在线词典,太懒了,就想着写一个小工具吧。