aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael G. Martins <rafael@rafaelmartins.eng.br>2016-11-17 23:18:40 +0100
committerRafael G. Martins <rafael@rafaelmartins.eng.br>2016-11-17 23:18:40 +0100
commitfc52952914747dc937c805baa211a251a795b847 (patch)
treea32459b3bc63106dc049710b0b60878f253a7767
parent984fa87451c9dd3ef2d9ec7976af97ce88bac6d7 (diff)
downloadblogc-fc52952914747dc937c805baa211a251a795b847.tar.gz
blogc-fc52952914747dc937c805baa211a251a795b847.tar.bz2
blogc-fc52952914747dc937c805baa211a251a795b847.zip
git-receiver: allow users to re-run the last successful build
running the pre-receive hook manually on the server will re-run the last successful build.
-rw-r--r--man/blogc-git-receiver.1.ronn10
-rw-r--r--src/blogc-git-receiver/pre-receive.c50
-rwxr-xr-xtests/blogc-git-receiver/check_pre_receive.sh.in16
3 files changed, 73 insertions, 3 deletions
diff --git a/man/blogc-git-receiver.1.ronn b/man/blogc-git-receiver.1.ronn
index ab54490..1fd6188 100644
--- a/man/blogc-git-receiver.1.ronn
+++ b/man/blogc-git-receiver.1.ronn
@@ -45,6 +45,16 @@ This will deploy the example to the server, creating a symlink to the built cont
in `/home/blogc/repos/blogs/blogc-example.git/htdocs`. This symlink should be used
as the document root for the web server virtual host.
+### Rebuild last successful build
+
+If for some reason you want to rebuild the last successful build of a given website,
+you can run its `pre-receive` hook manually in the server:
+
+ # su -s /bin/sh - blogc
+ $ ./repos/blogs/blogc-example.git/hooks/pre-receive
+
+This should re-run the last build as if it was pushed to git.
+
### Setup with SELinux enabled (Fedora)
Supposing the usage of nginx as webserver, running as the `nginx` user:
diff --git a/src/blogc-git-receiver/pre-receive.c b/src/blogc-git-receiver/pre-receive.c
index 5d2ead8..99e15dd 100644
--- a/src/blogc-git-receiver/pre-receive.c
+++ b/src/blogc-git-receiver/pre-receive.c
@@ -7,6 +7,7 @@
*/
#include <stdio.h>
+#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -15,6 +16,7 @@
#include <sys/wait.h>
#include <dirent.h>
#include <time.h>
+#include <libgen.h>
#include "../common/utils.h"
#include "../common/stdin.h"
#include "pre-receive-parser.h"
@@ -92,10 +94,45 @@ bgr_pre_receive_hook(int argc, char *argv[])
{
int rv = 0;
char buffer[4096];
+ char *master = NULL;
- char *input = bc_stdin_read();
- char *master = bgr_pre_receive_parse(input);
- free(input);
+ if (isatty(STDIN_FILENO)) {
+ char *hooks_dir = dirname(argv[0]); // this was validated by main()
+ char *real_hooks_dir = realpath(hooks_dir, NULL);
+ if (real_hooks_dir == NULL) {
+ fprintf(stderr, "error: failed to guess repository root.\n");
+ return 1;
+ }
+ char *repo_dir = dirname(real_hooks_dir);
+ char *htdocs_sym = bc_strdup_printf("%s/htdocs", repo_dir);
+ free(real_hooks_dir);
+ if (0 != access(htdocs_sym, F_OK)) {
+ fprintf(stderr, "error: no previous build found. nothing to "
+ "rebuild.\n");
+ return 1;
+ }
+ char *build_dir = realpath(htdocs_sym, NULL);
+ free(htdocs_sym);
+ if (build_dir == NULL) {
+ fprintf(stderr, "error: failed to get the hash of last built "
+ "commit.\n");
+ return 1;
+ }
+ char **pieces = bc_str_split(basename(build_dir), '-', 2);
+ free(build_dir);
+ if (bc_strv_length(pieces) != 2) {
+ fprintf(stderr, "error: failed to parse the hash of last built "
+ "commit.\n");
+ return 1;
+ }
+ master = bc_strdup(pieces[0]);
+ bc_strv_free(pieces);
+ }
+ else {
+ char *input = bc_stdin_read();
+ master = bgr_pre_receive_parse(input);
+ free(input);
+ }
if (master == NULL) {
fprintf(stderr, "warning: no reference to master branch found. "
@@ -168,6 +205,13 @@ bgr_pre_receive_hook(int argc, char *argv[])
unsigned long epoch = time(NULL);
output_dir = bc_strdup_printf("%s/builds/%s-%lu", home, master, epoch);
+
+ if (0 == access(output_dir, F_OK)) {
+ char *tmp = output_dir;
+ output_dir = bc_strdup_printf("%s-", tmp);
+ free(tmp);
+ }
+
char *gmake_cmd = bc_strdup_printf(
"%s -j%d OUTPUT_DIR=\"%s\" BLOGC_GIT_RECEIVER=1", make_impl,
cpu_count(), output_dir);
diff --git a/tests/blogc-git-receiver/check_pre_receive.sh.in b/tests/blogc-git-receiver/check_pre_receive.sh.in
index 10fd4d9..b9aec45 100755
--- a/tests/blogc-git-receiver/check_pre_receive.sh.in
+++ b/tests/blogc-git-receiver/check_pre_receive.sh.in
@@ -143,4 +143,20 @@ grep "echo lol" "${TEMP}/output.txt" &> /dev/null
[[ "${DEST}" != "$(readlink htdocs)" ]]
[[ ! -e "${DEST}" ]]
+DEST="$(readlink htdocs)"
+HOME="${TEMP}" ${TESTS_ENVIRONMENT} ./hooks/pre-receive 2>&1 | tee "${TEMP}/output.txt"
+
+[[ -h htdocs ]]
+[[ "$(cat htdocs/foo.txt)" == "lol" ]]
+[[ "${DEST}" != "$(readlink htdocs)" ]]
+[[ ! -e "${DEST}" ]]
+
+DEST="$(readlink htdocs)"
+HOME="${TEMP}" ${TESTS_ENVIRONMENT} ./hooks/pre-receive 2>&1 | tee "${TEMP}/output.txt"
+
+[[ -h htdocs ]]
+[[ "$(cat htdocs/foo.txt)" == "lol" ]]
+[[ "${DEST}" != "$(readlink htdocs)" ]]
+[[ ! -e "${DEST}" ]]
+
rm "${TEMP}/output.txt"