This repository was archived by the owner on Mar 11, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpost-receive
More file actions
141 lines (119 loc) · 4.37 KB
/
post-receive
File metadata and controls
141 lines (119 loc) · 4.37 KB
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#!/usr/bin/env python
#
# Git Deploy
# Copyright (c) Ryan Kadwell <ryan@riaka.ca>
#
# For the full copyright and license information, please view the LICENSE
# file that was distributed with this source code.
#
# Simple post-receive hook to perform deploys based on tags in the commit
# messages for git repositories.
#
import subprocess
import fileinput
import re
import sys
import os
# Targets dict lists allowed deploy targets in a key=target value=path dictionary
#
# targets = {
# "live": "/var/www/path-to-live-repo",
# "beta": "/var/www/path-to-beta-repo"
# }
#
targets = {}
def git(args):
"""
Function for running git command through subprocess
"""
cmd = subprocess.Popen(['git'] + args, stdout = subprocess.PIPE)
output = cmd.stdout.read()
output = output.strip()
return output
def get_timestamp(commit_hash):
"""
Get the commit timestamp for a given commit
"""
result = git(["show", "--stat", "--format=%ct", commit_hash])
result_lines = result.split("\n")
# make sure that we got a valid response
if re.match(r'^[0-9]+$', result_lines[0]):
return result_lines[0]
else:
return 0
if not targets:
print('deploy: No targets are defined. Go to http://github.com/ryakad/git-deploy'
' for information on how to set up this script')
sys.exit(0)
print('deploy: reading pushed commit messages')
deploy_targets = {} # commit objects that need to be checked for deploy.
pattern = re.compile(r'#HASH#')
for line in fileinput.input():
parts = line.split(" ") # <old_value> SP <ne_value> SP <ref_name>
# if this commit is the first on a branch we take the log for it
if parts[0] == "0000000000000000000000000000000000000000":
# TODO: Can't deploy with the first push of a branch.
# Need to be able to get a log for this branch only or give more
# detailed information to the user.
continue
else:
commitlog = git(["log", "--pretty=#HASH#%H%n%B", parts[0] + '..' + parts[1]])
for line in commitlog.split("\n"):
# check if the line starts with #HASH# and if so add an entry to the
# commits array. If not we will want to append the string to the
# previous commit message
if pattern.match(line):
current_hash = re.sub(pattern, '', line)
deploy_targets[current_hash] = []
continue
deploy_targets[current_hash].append(line)
# We now have our targets and can look for which ones need to be deployed.
deploys = {}
invalid_targets = []
deploy_pattern = re.compile(r'\[deploy-([a-z]+)\]')
for commit in deploy_targets:
commit_message = "\n".join(deploy_targets[commit])
for target in re.findall(deploy_pattern, commit_message):
# Check that they have provided a valid target
if target in targets.keys():
if not target in deploys.keys():
deploys[target] = []
deploys[target].append(commit)
else:
invalid_targets.append(target)
# Notify users of what deploy targets we will be skipping before we start
if invalid_targets:
for target in invalid_targets:
print('deploy: skipping unknown target: "' + target + '"')
if not deploys:
print('deploy: nothing to deploy')
sys.exit(1)
root_repo = os.getcwd()
# Need to find the commit with the newest commit-date and then update to that
for target in deploys:
os.chdir(root_repo)
os.unsetenv('GIT_DIR')
newest = None
for commit_hash in deploys[target]:
if newest == None:
newest = commit_hash
continue
print("deploy: comparing commits " + newest + " with " + commit_hash)
previous_timestamp = get_timestamp(newest)
current_timestamp = get_timestamp(commit_hash)
if previous_timestamp > current_timestamp:
newest = newest
else:
newest = commit_hash
# deploy if it is newer than the last deploy
wants_deploy = get_timestamp(newest)
os.chdir(targets[target])
os.unsetenv('GIT_DIR')
currently_on = get_timestamp(git(["rev-parse", "HEAD"]))
if wants_deploy > currently_on:
print('deploy: Deploying ' + newest + ' to ' + target)
print(git(["reset", "--hard", "HEAD"]))
print(git(["pull", "--all"]))
print(git(["checkout", newest]))
else:
print("deploy: latest in repo is a newer version than " + newest + ". skipping.")