1. Purpose

To describe how to use giblish as a tool for creating a static web site backed by a git repo that is automatically generated each time a contributor push changes to the git repo.

This text covers the following deployment scenarios:

  1. Using a git hook together with a shell script.

  2. Using a git hook together with Jenkins.

They have been tested on Linux servers (Ubuntu). Most of the tools and scripts should work on a Windows server as well but might need some tweaking and it is not tested.

If you want to dive straight in and setup one of the scenarios below, jump to Section 4, otherwise read on for some examples and considerations.

2. Git hook and shell script

This requires the least number of external dependencies but is limited.

deploy with hooks
Figure 1. Deploy using git hook and shell script

The components needed on the server are:

A 'Main Repo'

The common (bare) git repo used by all content writers to push updates to. This repo shall be setup with a server-side hook (post-receive) that initiates the html generation and is triggered by each push to the repo.

A 'Staging Repo'

A mirror of the Main Repo that fulfils two functions:

  1. to provide a checked-out working tree with the source files (adoc files).

  2. to provide a script that uses giblish to generate html documents and publish those docs to a location where a web server can access them.

A Web Server

Apache, Nginx or other web server that provides clients with HTML pages located somewhere on the file system on the server (e.g under /var/www/…​ )

2.1. Pros & Cons

Pros
  • it has few dependencies on external tools, only git, giblish and a web server are needed for this to work.

  • giblish provides templates for the post-receive hook.

Cons
  • The hook and publish scripts provided with giblish runs synchronously at each push from a Doc Writer to the Main Repo. The time it takes to generate the HTML docs from the adoc source will thus be added to each push to the Main Repo.

  • You need to manually setup the Staging Repo on the server and this is a bit more 'hackish' than letting a build orchestrator tool implement a proper 'build' of your documents. You might for example end up with race conditions if two pushes to the Main Repo are done close in time.

3. Using a combination of Jenkins and git hook

This setup adds a Jenkins (or similar build orchestrator) installation so it is more tools to setup but offer more flexibility and performance. It is also more robust and thus more 'production friendly'.

If you are already doing some kind of development, chances are that you already have this kind of setup as a CI pipeline.

deploy with jenkins
Figure 2. Deploy using Jenkins

The components needed on the server are:

Main Repo

The common (bare) git repo used by all content writers to push updates to. This repo needs to be setup with a server-side hook (post-receive) that are executed by git after each push to the repository.

Jenkins instance

A running instance of Jenkins and one or more defined build jobs that use giblish to build the HTML documents.

Web Server

Apache, Nginx or other web server that provides clients with HTML pages located somewhere on the file system on the server (e.g under /var/www/…​ )

3.1. Pros & cons

Pros
  • Using Jenkins enables a lot of flexibility and scaleability. You can setup multiple Jenkins agents to increase performance, you can define many build jobs where each job builds either a particular branch from a particular git repo or many branches from one or many repos.

Cons
  • You need to be familiar with, and maintain, the Jenkins instance.

4. Setup instructions

Follow the instructions below to get one of the above setups running on your server.

4.1. Some preliminary notes

Setting up permissions and secure your setup from unwanted access is outside the scope of these instructions. You must understand and implement the proper authentication rules for your use case.

git server side hooks are used in the instructions below. For details on git hooks see this doc.

4.2. Initial setup

These steps are common to both deployment scenarios.

giblish setup
  1. Install ruby on the Server (a version no more than 18 months old)

  2. Install giblish on the Server. See e.g. [:docid:G-001]

git and git repo setup
  1. Install git on the Server.

  2. Setup the bare Main Repo on the Server by either.

    1. Copy a bare repo you already use to the Server file system.

    2. Initiate a new repo using git init --bare <your_repo_name> somewhere on the Server file system.

      If you start with an empty, bare, Main Repo on the Server, it is a good idea to directly clone it to your local machine, commit some content to the 'master' branch and push the result back to the Main Repo. An empty, bare repo does not even contain a 'master' branch from the start and this can lead to some edge cases that complicate things.

4.3. Scenario 1 - use a git hook and shell script

First, follow the steps described in Section 4.2. Then proceed with the steps below.

  1. Setup the Staging Repo on the Server by cloning the Main Repo to a suitable folder in the Server file system, ex:

    Example 1. Setup a staging repo in your home folder on the Server
    1
    2
    3
    4
    5
    
    # go to your home directory
    cd ~
    
    # clone the Main Repo, assuming it is located at /usr/local/main_repo.git
    git clone file:///usr/local/main_repo.git
    
  2. Make a copy of the post-receive.example template from the installed giblish gem.

    Example 2. Find the post-receive template in the giblish gem

    run the following to copy the post-receive template to your current directory:

    cp $(dirname $(gem which giblish))/../scripts/hooks/post-receive.example .
  3. Rename the copy to post-receive

  4. Tweak the configuration variables of the copy to suite your use case.

  5. Move your copy to the hooks directory of your Main Repo.

  6. Set the execute permission using chmod +x post-receive

That’s it. You can now push to your Main Repo and the post-receive hook will run giblish on the branches that you set it up to.

4.4. Setup the git hook and Jenkins scenario

First, follow the steps described in Section 4.2. Then proceed with the steps below.

4.4.1. Sequence for generating documents

The following image shows how the sequence from user commit to generated documents.

Render Documents
Figure 3. Sequence diagram for generating docs from adoc

Appendix A: Template scripts

The giblish post-receive template git hook
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#!/bin/bash
#
# this hook runs giblish on a document tree according to the 
# users settings.
# Typically used to publish html documents when a push to a matching
# branch is detected.

# the git refs that should trigger a doc generation at update
TRIGGERING_REFS_REGEX=$'main'

# the relative path to a subfolder in the repo where the docs are
REPO_DOC_SUBFOLDER="docs"

# the staging repo root (where the working tree exists)
STAGING_REPO="/usr/local/git_staging/rillbert_se_staging"

# The web-server top dir for the published documents
DST_DIR="/var/www/rillbert_se/html/public/docs"

# path to a top dir of the styling css and other resources
RESOURCE_DIR="scripts/resources"

# the name of the css file to use for styling, without the 'css' extension
LAYOUT_STYLE="giblish"

# "true" runs an 'rm -rf' of the destination dir before generating new htmls
CLEAR_DST="true"

echo "post-receive hook running..."

# read the input that git sends to this hook
read oldrev newrev ref

# remove the 'refs/heads/' prefix from the git ref
ref="${ref/refs\/heads\//}"

# filter out refs that are irrelevant for doc generation
if [[ ! "${ref}" =~ "${TRIGGERING_REFS_REGEX}" ]]; then
  echo "Ref '${ref}' received. Doing nothing: only refs matching the regex: /${TRIGGERING_REFS_REGEX}/ will trigger a doc generation."
  exit 0
fi

echo "Document generation triggered by an update to ${ref}."
echo ""

# use a subshell with the correct working dir for the actual doc generation
(
  cd "${STAGING_REPO}"

  # need to unset the GIT_DIR env set by the invoking hook for giblish to work correctly
  unset GIT_DIR

  if [[ "${CLEAR_DST}" -eq "true" ]]; then
    echo "Remove everything under ${DST_DIR}/"
    rm -rf ${DST_DIR}/*
  fi

  # Generate html docs
  echo "running giblish..."
  giblish -a xrefstyle=basic \
          --copy-asset-folders "_assets$" \
          -g "${TRIGGERING_REFS_REGEX}" \
          -r "${RESOURCE_DIR}" \
          -s "${LAYOUT_STYLE}" \
          "${REPO_DOC_SUBFOLDER}" "${DST_DIR}"
)

A.1. post-update hook

Below is an example of a post-update hook that triggers Jenkins jobs after a push to a git repo. This hook should be installed on the server side git repository to trigger Jenkins builds

Example of a git hook triggering Jenkins builds
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/bin/sh
#
# This hook script kicks-in after git has completed
# a push, it will thus never be able to abort a push.
#
# This hook will:
# - ping Jenkins to trigger any builds related to the
#   git push

# let the user perfoming a git push know that we actually do something
echo "Start post-update"

# Hit Jenkins to initiate a Jenkins poll for which jobs that shall be started as
# consequence of a push to a specific git repo. The generic format for this is:
# curl <jenkins_url>/git/notifyCommit?url=<git repo url>
#
# If jenkins is accessible on http://jenkins.example.com:8080 and
# you want to initiate a poll for jobs associated with the giblish repository on
# github located at https://github.com/rillbert/giblish.git
# you would use the following:
curl http://jenkins.example.com:8080/git/notifyCommit?url=https://github.com/rillbert/giblish.git

# Tell user we're done
echo "Finished post-update"