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

crypto gopher, 2018-10-31 16:13

1 1 crypto gopher
h1. HowTo keep Redmine in sync with Github without dedicated plugin (Apache CGI + Github Webhook)
2 1 crypto gopher
3 1 crypto gopher
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 1 crypto gopher
5 4 crypto gopher
h2. Clone Github repository
6 4 crypto gopher
7 4 crypto gopher
Clone repository and make sure it is accessible by webserver:
8 4 crypto gopher
<pre>
9 4 crypto gopher
mkdir /var/lib/redmine/repo
10 4 crypto gopher
chown apache /var/lib/redmine/repo
11 4 crypto gopher
su -u apache git -C /var/lib/redmine/repo clone https://github.com/username/repo_name.git
12 4 crypto gopher
</pre>
13 4 crypto gopher
14 4 crypto gopher
h2. Enable WS for repository management in Redmine
15 4 crypto gopher
16 4 crypto gopher
Go to @https://your.redmine.com/settings?tab=repositories@ and:
17 4 crypto gopher
* select: _Enable WS for repository management_
18 4 crypto gopher
* generate a repository management WS API key and save it for next step
19 4 crypto gopher
20 1 crypto gopher
h2. Prepare CGI script
21 1 crypto gopher
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 8 crypto gopher
24 1 crypto gopher
<pre>
25 1 crypto gopher
#!/bin/sh
26 8 crypto gopher
# Requires: jq
27 8 crypto gopher
28 8 crypto gopher
REPO_PATH='/var/lib/redmine/repo'
29 8 crypto gopher
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 8 crypto gopher
if [ -z "${REPO_NAME}" ]  || [ ! -d "${REPO_PATH}/${REPO_NAME}" ]; then
33 8 crypto gopher
  echo "Status: 400 Bad Request"
34 8 crypto gopher
  echo "Content-Type: text/plain; charset=utf-8"
35 8 crypto gopher
  echo
36 8 crypto gopher
  echo "project: unrecognized"
37 8 crypto gopher
  exit 0
38 8 crypto gopher
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 8 crypto gopher
/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 1 crypto gopher
47 1 crypto gopher
if [[ $result1 && $result2 ]]; then
48 1 crypto gopher
  echo "Status: 200 OK"
49 1 crypto gopher
else
50 1 crypto gopher
  echo "Status: 500 Internal Server Error"
51 1 crypto gopher
fi
52 1 crypto gopher
53 1 crypto gopher
echo "Content-Type: text/plain; charset=utf-8"
54 1 crypto gopher
echo
55 8 crypto gopher
echo "project: ${PROJECT_NAME}"
56 1 crypto gopher
57 1 crypto gopher
if [[ $result1 ]]; then
58 1 crypto gopher
  echo "git pull: ok"
59 1 crypto gopher
else
60 1 crypto gopher
  echo "git pull: failed"
61 1 crypto gopher
fi
62 1 crypto gopher
63 1 crypto gopher
if [[ $result2 ]]; then
64 1 crypto gopher
  echo "fetch changesets: ok"
65 1 crypto gopher
else
66 1 crypto gopher
  echo "fetch changesets: failed"
67 1 crypto gopher
fi
68 1 crypto gopher
</pre>
69 1 crypto gopher
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 4 crypto gopher
<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 1 crypto gopher
78 2 crypto gopher
h2. Configure Apache to run script whenever particular URL is requested
79 2 crypto gopher
80 2 crypto gopher
Inside @VirtualHost@ of your choice just add:
81 2 crypto gopher
<pre>
82 2 crypto gopher
  ...
83 2 crypto gopher
  # Github webhook for repository pull/update
84 2 crypto gopher
  ScriptAlias /update-repo.cgi /var/www/localhost/cgi-bin/update-repo.cgi
85 2 crypto gopher
  <Directory /var/www/localhost/cgi-bin/>
86 2 crypto gopher
    Options ExecCGI
87 2 crypto gopher
    AllowOverride None
88 2 crypto gopher
    Require all granted
89 2 crypto gopher
  </Directory>
90 2 crypto gopher
  ...
91 2 crypto gopher
</pre>
92 2 crypto gopher
93 2 crypto gopher
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:
94 2 crypto gopher
<pre>
95 2 crypto gopher
ProxyPass /update-repo.cgi !
96 2 crypto gopher
</pre>
97 2 crypto gopher
98 3 crypto gopher
h2. Configure Github Webhook
99 3 crypto gopher
100 3 crypto gopher
Go to your Github repository page, choose _Settings -> Webhooks -> Add webhook_. Then set:
101 3 crypto gopher
* Payload URL: @https://your.virtualhost.com/update-repo.cgi@
102 3 crypto gopher
* Which events would you like to trigger this webhook?: Just the push event.
103 3 crypto gopher
* Active: yes
104 3 crypto gopher
105 3 crypto gopher
Update webhook and you're done.