Project

General

Profile

GithubRedmineRepoSync » History » Version 1

cryptogopher, 2022-11-02 17:04

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