The git hooks I use on my server to facilitate Continuous Deployment (CD) and assist with Continuous Integration (CI).

Name Last Update
.gitignore Loading commit data...
README.md Loading commit data...
git-hooks.sublime-project Loading commit data...
lax-develop Loading commit data...
lax-master Loading commit data...
package.json Loading commit data...
web-mirror Loading commit data...

Deploy Hooks

FKA: Git Hooks

Within this repository are the deploy hooks (written in JS) that I use on my server to facilitate Continuous Deployment (CD) and assist with Continuous Integration (CI). They are meant to be used with GitLab, but can be invoked manually via CLI if necessary. For example:

sudo -u git env CI_PROJECT_DIR='/home/xunnamius/repos/web-mirrored/xunn.io.git' WEBMIRROR_JSON_CONFIG='{"branches":{"master":{"web_public_dir":"public","ignore_hash_check":true}}}' WEBMIRROR_DEBUG_MODE=1 bash -c '/home/build-scripts/deploy/web-mirror'

NOTE that this deploy code expects anything named gulpfile.js (excact case) to be a Gulp run file and will attempt to run its "deploy" task i.e. "gulp deploy".


  • Rejoinder
  • Shelljs

Using with GitLab

  1. Create a .gitlab-ci.yml file in the root of your repository
  2. Inside the YAML file, set the proper configuration variables (below)
  3. Commit and profit (you may have to activate the deploy via the GitLab pipeline UI)

Example .gitlab-ci.yml File for Web Mirroring

    - /home/build-scripts/deploy/web-mirror
  stage: deploy
  environment: production
        "branches": {
          "master": {
            "log_path": "/where/the/posthook/will/log/stuff.log",
            "web_push_root": "/var/http/webserver/root",
            "web_public_dir": "public",
            "defer_dep_loading": true
    - master
    - triggers
    - deploy

For more details, see the .gitlab-ci.yml documentation.

JSON Configuration

What used to be postrec.json configuration should now be stored in WEBMIRROR_JSON_CONFIG. An explanation of valid values can be found below:

    "global": {
        /* Global settings are the same as the per-branch rules below, except they apply to ALL branches that do not specify their own version
         * of the rule(s). If a rule is specified here and again in one of the branch rulesets below, the branch rule wins every time.
         * In essence, these can be thought of as defaults. The only exception is `default_branch`

        "default_branch": "master" /* This is the name of the branch that the target git repository will be reset to */
    "branches": {   /* If empty, the hook will report that nothing was pushed and everything went okay */
        "master": { /* This specifies a set of rules that will be executed with respect to the `master` branch */
                    /* What follows are the default values for some of the rules; you can exclude all, some, or none of them */
            "log_path": "/where/the/posthook/will/log/stuff.log", /* Can also be a relative path. NULL will disable logging for this branch */
            "web_push_root": "/var/http/webserver/root",          /* The root location where the directory containing this repository's contents will live */
            "web_push_target": null,    /* The name of the directory containing this repository's contents or NULL if you want the hook to use the repo name */
            "web_public_dir": "public", /* The name of the directory that will be visible to the web and resides within the web_push_target directory */
            "truncate_log": true,       /* Should the log be cleared before each push? */
            "defer_dep_loading": false, /* Should we defer dependency loading (npm, etc) to the remotewatch script? */
            "clear_on_checkout": [],    /* An array of strings that will be passed directly to rm BEFORE every push. `web_push_target` is the cwd */
            "ch_rules": {               /* An array of strings that will be passed directly to chmod/chown AFTER every push. `web_push_target` is the cwd */
                "chmod": [],
                "chown": []
            "ignore_hash_check": false  /* Should we ignore the hash check and push to this branch even if no changes have occurred since last commit? */

        /* You can define sets of rules for other branches as well! */
        "examplebranch": {
            /* Same range of rules are possible as is in the `master` example above... */

/* Instead of specifying settings in a "branches" object, a simple array of branch names also works (settings are taken from global and superglobal) */
    "global": {},
    "branches": ["master", "topic"],
    "preshell": "echo 'hello world!'" /* You can also specify a "preshell" command outside of "global" and "branches" to have a shell command executed */

Notes and Warnings

Also note that there are gitlab-wide superglobal values defined as constants within some of the scripts that can be modified manually. For more in-depth descriptions of each of the possible configuration options, have a peek inside the source.

WARNING: chown comands can only be issued by root/sudo. For this reason, they are not used by default. Use them only if you know what you are doing. See web-mirror for a more detailed description of the functionality.

NOTE: if you don't use the default web visible directory name (i.e. public), you'll have to edit the value of web_public_dir!