Project

General

Profile

HowTo keep Redmine in sync with Github without dedicated plugin (Apache CGI + Github Webhook) » History » Version 10

crypto gopher, 2018-10-31 16:15

1 1 crypto gopher
h1. HowTo keep Redmine in sync with Github without dedicated plugin (Apache CGI + Github Webhook)
2
3
This is a solution in case you don't want to install additional plugins just to keep repository synchronised. It requires you to have Apache webserver with access to repository you are trying to sync. Apache has to support running CGI scripts.
4
5 4 crypto gopher
h2. Clone Github repository
6
7
Clone repository and make sure it is accessible by webserver:
8
<pre>
9
mkdir /var/lib/redmine/repo
10
chown apache /var/lib/redmine/repo
11
su -u apache git -C /var/lib/redmine/repo clone https://github.com/username/repo_name.git
12
</pre>
13
14
h2. Enable WS for repository management in Redmine
15
16
Go to @https://your.redmine.com/settings?tab=repositories@ and:
17
* select: _Enable WS for repository management_
18
* generate a repository management WS API key and save it for next step
19
20 1 crypto gopher
h2. Prepare CGI script
21
22 8 crypto gopher
Any script you run on your server will do. Below is an example of Bash script that pulls git repository and notifies Redmine to fetch changesets (substitute @<repository-api-key>@ with your own):
23
24 1 crypto gopher
<pre>
25
#!/bin/sh
26 8 crypto gopher
# Requires: jq
27
28
REPO_PATH='/var/lib/redmine/repo'
29
30 1 crypto gopher
# Empty stdin, Apache issue https://bz.apache.org/bugzilla/show_bug.cgi?id=44782
31 8 crypto gopher
REPO_NAME=$(cat <&0 | jq '.repository.name' | tr -cd 'A-Za-z0-9_-')
32
if [ -z "${REPO_NAME}" ]  || [ ! -d "${REPO_PATH}/${REPO_NAME}" ]; then
33
  echo "Status: 400 Bad Request"
34
  echo "Content-Type: text/plain; charset=utf-8"
35
  echo
36
  echo "project: unrecognized"
37
  exit 0
38
fi
39 1 crypto gopher
40 8 crypto gopher
/usr/bin/git -C "${REPO_PATH}/${REPO_NAME}" pull -n -q
41 4 crypto gopher
result1=$?
42 1 crypto gopher
43 8 crypto gopher
PROJECT_NAME=$(echo "${REPO_NAME}" | tr '_' '-')
44
/usr/bin/curl --max-time 60 -s "https://your.redmine.com/sys/fetch_changesets?id=${PROJECT_NAME}&key=<repository-api-key>" >/dev/null
45 1 crypto gopher
result2=$?
46
47
if [[ $result1 && $result2 ]]; then
48
  echo "Status: 200 OK"
49
else
50
  echo "Status: 500 Internal Server Error"
51
fi
52
53
echo "Content-Type: text/plain; charset=utf-8"
54
echo
55 8 crypto gopher
echo "project: ${PROJECT_NAME}"
56 1 crypto gopher
57
if [[ $result1 ]]; then
58
  echo "git pull: ok"
59
else
60
  echo "git pull: failed"
61
fi
62
63
if [[ $result2 ]]; then
64
  echo "fetch changesets: ok"
65
else
66
  echo "fetch changesets: failed"
67
fi
68
</pre>
69
70 8 crypto gopher
Let's say you save this script under: _/var/www/cgi-bin/update-repo.cgi_
71 1 crypto gopher
72 4 crypto gopher
You can test if script executes properly:
73
<pre>
74 8 crypto gopher
echo <copy-input-from-github-webhook-request> | sudo -u apache /var/www/cgi-bin/update-repo.cgi
75 7 crypto gopher
</pre>
76 8 crypto gopher
77 2 crypto gopher
h2. Configure Apache to run script whenever particular URL is requested
78
79
Inside @VirtualHost@ of your choice just add:
80
<pre>
81
  ...
82 1 crypto gopher
  # Github webhook for repository pull/update
83 9 crypto gopher
  ScriptAlias /update-repo.cgi /var/www/cgi-bin/update-repo.cgi
84
  <Directory /var/www/cgi-bin/>
85 2 crypto gopher
    Options ExecCGI
86
    AllowOverride None
87
    Require all granted
88
  </Directory>
89
  ...
90
</pre>
91
92
In case you use the same @VirtualHost@ to proxy requests to your Redmine @rails server@, you should exclude your special URL from being proxied with:
93
<pre>
94
ProxyPass /update-repo.cgi !
95
</pre>
96
97 3 crypto gopher
h2. Configure Github Webhook
98
99
Go to your Github repository page, choose _Settings -> Webhooks -> Add webhook_. Then set:
100
* Payload URL: @https://your.virtualhost.com/update-repo.cgi@
101 10 crypto gopher
* Content type: application/json
102 3 crypto gopher
* Which events would you like to trigger this webhook?: Just the push event.
103
* Active: yes
104
105
Update webhook and you're done.