From fc52952914747dc937c805baa211a251a795b847 Mon Sep 17 00:00:00 2001 From: "Rafael G. Martins" Date: Thu, 17 Nov 2016 23:18:40 +0100 Subject: 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. --- man/blogc-git-receiver.1.ronn | 10 +++++ src/blogc-git-receiver/pre-receive.c | 50 ++++++++++++++++++++++-- tests/blogc-git-receiver/check_pre_receive.sh.in | 16 ++++++++ 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 +#include #include #include #include @@ -15,6 +16,7 @@ #include #include #include +#include #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" -- cgit v1.2.3-18-g5258