103 lines
		
	
	
	
		
			3.3 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			103 lines
		
	
	
	
		
			3.3 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
#!/usr/bin/env python3
 | 
						|
 | 
						|
# Zulip notification post-receive hook.
 | 
						|
#
 | 
						|
# The "post-receive" script is run after receive-pack has accepted a pack
 | 
						|
# and the repository has been updated.  It is passed arguments in through
 | 
						|
# stdin in the form
 | 
						|
#  <oldrev> <newrev> <refname>
 | 
						|
# For example:
 | 
						|
#  aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/main
 | 
						|
 | 
						|
import os
 | 
						|
import os.path
 | 
						|
import subprocess
 | 
						|
import sys
 | 
						|
 | 
						|
sys.path.insert(0, os.path.dirname(__file__))
 | 
						|
import zulip_git_config as config
 | 
						|
 | 
						|
VERSION = "0.9"
 | 
						|
 | 
						|
if config.ZULIP_API_PATH is not None:
 | 
						|
    sys.path.append(config.ZULIP_API_PATH)
 | 
						|
 | 
						|
import zulip
 | 
						|
 | 
						|
client = zulip.Client(
 | 
						|
    email=config.ZULIP_USER,
 | 
						|
    site=config.ZULIP_SITE,
 | 
						|
    api_key=config.ZULIP_API_KEY,
 | 
						|
    client="ZulipGit/" + VERSION,
 | 
						|
)
 | 
						|
 | 
						|
 | 
						|
def git_repository_name() -> str:
 | 
						|
    output = subprocess.check_output(["git", "rev-parse", "--is-bare-repository"])
 | 
						|
    if output.strip() == "true":
 | 
						|
        return os.path.basename(os.getcwd())[: -len(".git")]
 | 
						|
    else:
 | 
						|
        return os.path.basename(os.path.dirname(os.getcwd()))
 | 
						|
 | 
						|
 | 
						|
def git_commit_range(oldrev: str, newrev: str) -> str:
 | 
						|
    log_cmd = ["git", "log", "--reverse", "--pretty=%aE %H %s", f"{oldrev}..{newrev}"]
 | 
						|
    commits = ""
 | 
						|
    for ln in subprocess.check_output(log_cmd, universal_newlines=True).splitlines():
 | 
						|
        author_email, commit_id, subject = ln.split(None, 2)
 | 
						|
        if hasattr(config, "format_commit_message"):
 | 
						|
            commits += config.format_commit_message(author_email, subject, commit_id)
 | 
						|
        else:
 | 
						|
            commits += f"!avatar({author_email}) {subject}\n"
 | 
						|
    return commits
 | 
						|
 | 
						|
 | 
						|
def send_bot_message(oldrev: str, newrev: str, refname: str) -> None:
 | 
						|
    repo_name = git_repository_name()
 | 
						|
    branch = refname.replace("refs/heads/", "")
 | 
						|
    destination = config.commit_notice_destination(repo_name, branch, newrev)
 | 
						|
    if destination is None:
 | 
						|
        # Don't forward the notice anywhere
 | 
						|
        return
 | 
						|
 | 
						|
    new_head = newrev[:12]
 | 
						|
    old_head = oldrev[:12]
 | 
						|
 | 
						|
    if (
 | 
						|
        oldrev == "0000000000000000000000000000000000000000"
 | 
						|
        or newrev == "0000000000000000000000000000000000000000"
 | 
						|
    ):
 | 
						|
        # New branch pushed or old branch removed
 | 
						|
        added = ""
 | 
						|
        removed = ""
 | 
						|
    else:
 | 
						|
        added = git_commit_range(oldrev, newrev)
 | 
						|
        removed = git_commit_range(newrev, oldrev)
 | 
						|
 | 
						|
    if oldrev == "0000000000000000000000000000000000000000":
 | 
						|
        message = f"`{new_head}` was pushed to new branch `{branch}`"
 | 
						|
    elif newrev == "0000000000000000000000000000000000000000":
 | 
						|
        message = f"branch `{branch}` was removed (was `{old_head}`)"
 | 
						|
    elif removed:
 | 
						|
        message = f"`{new_head}` was pushed to `{branch}`, **REMOVING**:\n\n{removed}"
 | 
						|
        if added:
 | 
						|
            message += "\n**and adding**:\n\n" + added
 | 
						|
        message += "\n**A HISTORY REWRITE HAS OCCURRED!**"
 | 
						|
        message += "\n@everyone: Please check your local branches to deal with this."
 | 
						|
    elif added:
 | 
						|
        message = f"`{new_head}` was deployed to `{branch}` with:\n\n{added}"
 | 
						|
    else:
 | 
						|
        message = f"`{new_head}` was pushed to `{branch}`... but nothing changed?"
 | 
						|
 | 
						|
    message_data = {
 | 
						|
        "type": "stream",
 | 
						|
        "to": destination["stream"],
 | 
						|
        "subject": destination["subject"],
 | 
						|
        "content": message,
 | 
						|
    }
 | 
						|
    client.send_message(message_data)
 | 
						|
 | 
						|
 | 
						|
for ln in sys.stdin:
 | 
						|
    oldrev, newrev, refname = ln.strip().split()
 | 
						|
    send_bot_message(oldrev, newrev, refname)
 |