This blog post documents the setup of deploying Hugo with Travis CI to the GitHub Pages.


Create Basic Site

Here I want to create a site named demo:

$ hugo new site demo

Generated directory structure by Hugo:

└── demo
    ├── archetypes
    ├── config.toml
    ├── content
    ├── data
    ├── layouts
    ├── static
    └── themes

Since I decide to combine the modified AllinOne and hugo-resume theme, I need to clone the two theme first:

$ cd demo/themes
$ git clone AllinOne
$ git clone resume
$ cd ..

Then, the configuration file config.toml should be modified. Here’s my example:

baseURL                    = ""
builddrafts                = false
languageCode               = "zh-Hans"
canonifyurls               = true
contentdir                 = "content"
layoutdir                  = "layouts"
publishdir                 = "public"
enableEmoji                = true
hasCJKLanguage             = true
summaryLength              = 200
Paginate                   = 5

#theme                      = "AllinOne"
theme                      = ["AllinOne", "resume"]

home = [ "HTML", "RSS", "JSON" ]
section = [ "HTML", "RSS"]
taxonomy = [ "HTML", "RSS"]

baseName = "index"
mediaType = "text/html"
isHTML = true

title                      = "Dreambooker"

pygmentsuseclasses         = true
disablePathToLower         = true 

sci-tech                 = ":year/:month/:day/:slug/"
essay                     = ":year/:month/:day/:slug/"

  tag                      = "tags"
  series                   = "series"
  category                 = "categories"

    name                   = "Sci-Tech"
    weight                 = 1
    identifier             = "sci-tech"
    url                    = "sci-tech/"

    name                   = "Essay"
    weight                 = 3
    identifier             = "essay"
    url                    = "essay/"

    name                   = "About"
    weight                 = 9
    identifier             = "about"
    url                    = "about/"

  faviconfile              = "img/logo.jpg"
  avatar                   = "img/me.jpg"             # path to image in static dir e.g img/avatar.png (do not use in the same time as gravatar)
  author                   = "Xin Zhang"
  description              = ["Life is a dream,", "Dream is a life."]           # appears in the site header when set to a non-empty string
  welcome_head             = "Hello, Dreambooker!"
  welcome_word             = "~ Chase your dream ~"

  latestpostscount         = 5                             # how many posts to display on the home page
  bloggroupby              = 'month'
  dateform                 = "Jan 2, 2006"
  dateformfull             = "2006-01-02  Monday  15:04:05"
  noshowreadtime           = false

  # slides
  slidesDirPath            = "static/img/header-slides"    # path to image in local dir (for hugo)
  slidesDirPathURL         = "img/header-slides"    # path to image in static dir (for static pages)

  # highlighting 
  highlightjs              = true

  # links
  email                    = ""
  github                   = "//"
  twitter                  = "//"
  instagram                = "//"
  include_rss              = true                         # include RSS <link> tag in <head> and show RSS icon

  # analytics
  # googleAnalytics          = "UA-90057853-1"

  # counter
  busuanzi                 = true

  firstName = "Xin"
  lastName = "Zhang"
  address = "Nanjing, CN"
  phone = "+86 15895938361"
  contactNote = "Mr."
  profileImage = "img/portrait.jpg"
  favicon = "images/favicon.ico"

  showSkills = true
  showProjects = false
  showOpenSource = true
  showPublications = true
  showExperience = false
  showEducation = true
  showQr = true

  username = "zxdawn2"
  repository = ""
  branch = "source"
  notifications = true

    name = "GitHub"
    link = ""

    name = "Twitter"
    link = ""

    name = "Youtube"
    link = ""

    name = "Instagram"
    link = ""

    name = "Facebook"
    link = ""

Then, put your image files under /static/img folder.

Create about, essay, sci-tech directories under /content and add contents.

To check the effect, just run hugo server and open http://localhost:1313/ in browser.

Create repository

Starting from here there are two possible ways:

  1. to use one repository for sources (hugo repository) and publishing (generated HTML)
  2. to use two repositories: one for sources and another for publishing

I prefer the first option which needs only one repository and create the empty <user/org name> repository without README file. I create a new account named zxdawn2 for this purpose. So, the corresponding repository name should be


Two branches will be created: master and code.

  • master branch will be used for hosting of generated HTML
  • code branch will be used as the sources of my page

Here’re all steps to set these branches:

Branch source

# Initialized empty Git repository
$ git init

# Create new branch named source
$ git checkout -b source

# Exclude the `public` directory which is deployed to `master` branch
$ echo '/public/' >> .gitignore

# Add themes correctly
$ git rm --cached themes/AlliOne
$ git rm --cached themes/resume
$ git commit -m "remove submodule"
$ git add themes/AllinOne/
$ git add themes/resume/
$ git commit -m "added codebase"

# Commit all source codes to `source` branch
$ git add .
$ git commit -m "Hugo generator source code"
$ git remote add origin
$ git push -u origin source

Branch master

# Generate codes of website
$ hugo

# Copy contents to temporary directory
$ HUGO_TEMP_DIR=$(mktemp -d)
$ cp -R public/* "$HUGO_TEMP_DIR"

# Create `master` branch
$ git checkout --orphan master

# Remove unnecessary contents
$ rm .git/index
$ git clean -fdx
$ echo '/themes/' >> .gitignore

# Copy files of website
$ cp -R "$HUGO_TEMP_DIR"/. .

# Commits
$ git add .
$ git commit -m 'initial website content'
$ git push -u origin master

$ [[ -d "$HUGO_TEMP_DIR" ]] && rm -rf "$HUGO_TEMP_DIR"

It’s time to check whether the website works in browser:

If you got 404 error, you need to initialize the README file of master branch.

Travis CI

There’re two possible ways:

  1. To use Github token;
  2. To use HTTPS for custom domains

I prefer the second method which is simpler and easier.

Add variable to Travis

Now that we need to set a private variable name GITHUB_AUTH_SECRET on Travis:

(update the placeholders with your data)




Switch to source branch, write the script below into file .travis.yml:

  - wget -O /tmp/hugo.deb
  - sudo dpkg -i /tmp/hugo.deb

  - hugo

  - provider: script
    script: chmod +x ./ && ./
    skip_cleanup: true
      branch: source # or master if you are using the two-repository approach

Create corresponding


set -e

echo $GITHUB_AUTH_SECRET > ~/.git-credentials && chmod 0600 ~/.git-credentials
git config --global credential.helper store
git config --global "<USERNAME>"
git config --global "<USERNAME>"
git config --global push.default simple

rm -rf deployment
git clone -b master<GITHUB HTTPS PATH TO YOUR PUBLISHING REPO> deployment
rsync -av --delete --exclude ".git" public/ deployment
cd deployment
git add -A
# we need the || true, as sometimes you do not have any content changes
# and git woundn't commit and you don't want to break the CI because of that
git commit -m "rebuilding site on `date`, commit ${TRAVIS_COMMIT} and job ${TRAVIS_JOB_NUMBER}" || true
git push

cd ..
rm -rf deployment

Push both of them to the source branch of remote repository.

$ git add .
$ git commit -m "add travis"
$ git push


Method 1

Add staticman.yml under root directory and add @staticmanlab to the collaborator on github:


Access the link below to accept the invitation:

You will see OK! on that page.

Method 2 (recommend)

Please check this tutorial about setting up your own staticman instance.

Then, you can add notifications using Mailgun.

Version control

1.1Add the part of setting up own staticman2019-08-28
1.2Add more references2020-02-23


  1. Using Hugo and Travis CI To Deploy Blog To Github Pages Automatically
  2. Hugo on GitHub Pages with Travis CI
  3. Hugo + Staticman
  4. Threaded comments for Hugo with Staticman v3
  5. Running Staticman on Hugo Blog With Nested Comments
  6. Staticman Comment Notifications Setup Using Mailgun
  7. Staticman: Adding comments to my Jekyll site

Say something

Thank you

Your comment has been submitted and will be published once it has been approved.


Your comment has not been submitted. Please go back and try again. Thank You!

If this error persists, please open an issue by clicking here.

Comments (6)

Xin Zhang
Wednesday, Aug 28, 2019

Test own notification

Xin Zhang
Sunday, Feb 23, 2020

Test markdown

Xin Zhang
Sunday, Feb 23, 2020

test subscription

Xin Zhang
In reply to Xin Zhang
Sunday, Feb 23, 2020

DM you

Xin Zhang
Sunday, Feb 23, 2020

new subscription

Xin Zhang
In reply to Xin Zhang
Sunday, Feb 23, 2020

DM again