commit f4ef7da9db487b5aa493a03ceadd6b4af1ba18e7 Author: James Pace Date: Tue Feb 14 20:50:09 2023 -0500 Init commit. diff --git a/j7s_branch_trigger/__init__.py b/j7s_branch_trigger/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/j7s_branch_trigger/j7s_branch_trigger.py b/j7s_branch_trigger/j7s_branch_trigger.py new file mode 100644 index 0000000..ebaaf22 --- /dev/null +++ b/j7s_branch_trigger/j7s_branch_trigger.py @@ -0,0 +1,109 @@ +#!/usr/bin/env python +import subprocess +import re +import json +import os +import requests +import time +import schedule +import logging + +''' +Input: +- concerned repos +- regex for concerned branch +- Time between queries in minutes. + +Deps: https://schedule.readthedocs.io/en/stable/ + +schedule.every.minutes(query_time).do(loop) + +def loop(): + Call git ls-remote + Parse output. + Use regex to only leave concerned repos. + Check concerned repos to what we saw last time. + If different: + ping service + Update what we last saw. +''' + +def main(): + logging.basicConfig(level=logging.DEBUG) + logging.debug('Starting up....') + (repo, url, data_file, pattern, loop_time) = get_config() + def job(): + loop(repo, pattern, url, data_file) + schedule.every(loop_time).minutes.do(job) + logging.debug('Starting loop.') + while True: + schedule.run_pending() + time.sleep(1) + +def git_ls(repo): + cmd = 'git ls-remote {repo}'.format(repo=repo) + output = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE) + if output.returncode != 0: + return None + branch_to_commit = {} + for line in output.stdout.splitlines(): + (commit, branch) = line.decode().split('\t') + branch_to_commit[branch] = commit + return branch_to_commit + +def find_concerned_branches(branch_to_commit, pattern): + github_pull_pattern = '^refs/pull/.*' + onedev_update_pattern = '^refs/update/.*' + relevant_branches = {} + for (branch, commit) in branch_to_commit.items(): + is_relevant_branch = re.fullmatch(pattern, branch) + is_github_pull_request = re.fullmatch(github_pull_pattern, branch) + is_onedev_pull_update = re.fullmatch(onedev_update_pattern, branch) + if is_relevant_branch and not is_github_pull_request and not is_onedev_pull_update: + relevant_branches[branch] = commit + return relevant_branches + +def load_last_time(file_name): + from_last_time = {} + try: + with open(file_name, 'r') as f: + from_last_time = json.load(f) + except IOError: + logging.debug("Can't find state last time.") + return from_last_time + +def save_this_time(file_name, this_time): + with open(file_name, 'w') as f: + json.dump(this_time, f) + +def compare_branches(last_time, this_time, url): + for branch in this_time.keys(): + my_hash = this_time[branch] + last_hash = last_time.get(branch, None) + if my_hash != last_hash: + logging.debug('Branch {} has new hash.'.format(branch)) + r = requests.post(url, json={"branch": branch}) + if r.status_code != 200: + logging.warning("Something went wrong on request.") + +def loop(repo, pattern, request_url, data_file): + logging.debug('Looking at {} for {}.'.format(repo, pattern)) + all_branches = git_ls(repo) + logging.debug('All branches: {}'.format(all_branches)) + concerned_branches = find_concerned_branches(all_branches, pattern) + logging.debug('Concerned branches for {}: {}'.format(pattern, concerned_branches)) + last_time = load_last_time(data_file) + compare_branches(last_time, concerned_branches, request_url) + save_this_time(data_file, concerned_branches) + +def get_config(): + repo = os.environ.get('J7S_REPO', None) + url = os.environ.get('J7S_URL', None) + if not url or not repo: + raise Exception('Missing J7S_REPO OR J7S_URL.') + data_file = os.environ.get('J7S_HISTORY_FILE', '/tmp/branch-history.json') + pattern = os.environ.get('J7S_PATTERN', '(^HEAD$|refs/heads/(master|main)$)') + loop_time = float(os.environ.get('J7S_LOOPTIME', 1.0)) + + return (repo, url, data_file, pattern, loop_time) + diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..0fafa1f --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,24 @@ +[build-system] +requires = ["setuptools"] +build-backend = "setuptools.build_meta" + +[project] +name = "j7s_branch_trigger" +authors = [ + {name = "James Pace", email = "jpace121@gmail.com"}, +] +description = "Multi-branch pipelines with curl." +readme = "README.md" +requires-python = ">=3.7" +license = {text = "Apache-2.0"} +classifiers = [ + "Programming Language :: Python :: 3", +] +dependencies = [ + "requests", + "schedule" +] +version = "0.1" + +[project.scripts] +j7s_branch_trigger = "j7s_branch_trigger.j7s_branch_trigger:main" \ No newline at end of file