Créer un blog grâce à Hugo

| Tags: blog hugo tech circleci | Catégories: Tuto | Auteur: Jérémy

Hugo est un générateur de site statique comme Jekyll (développé en Ruby). C’est-à-dire qu’il n’a pas besoin de base de données ou autre pour fonctionner.

Les pages sont donc générées lors de la création ou à la modification d’un contenu. L’avantage, est qu’il fonctionne sans dépendances. Pas comme Ruby, Python ou PHP.

Avant-propos

Site utilisant Hugo

Hugo est assez répandu et utilisé pour sa mise en place rapide, sa rapidité d’exécution et sa souplesse. Entre autres il y a comme site :

  • Github Pages
  • Amazon S3
  • Azure
  • Let’s Encrypt

Avantages

L’un des avantages c’est sa rapidité pour le build de vos pages (< 1ms). L’autre c’est qu’il est multi-platforme et possède un système de live reload. C’est-à-dire que lors de la modification d’un contenu, il va détecter ce qui est modifié et rebuilder instantanément le contenu, même pour ceux qui auraient déjà la page en cours de lecture.

Création du blog

Installation

L’installation est très simple et rapide. La documentation est disponible à cette adresse : https://gohugo.io/getting-started/quick-start/. Les thèmes ou plugins s’installent via les submodules de git.

Pour cet exemple nous allons utiliser le thème bleak.

1hugo new site blog
2cd blog
3git init
4git submodule add https://github.com/Zenithar/hugo-theme-bleak.git themes/bleak
5echo 'theme = "bleak"' >> config.toml
6cp themes/bleak/archetypes/default.md archetypes/default.md
7hugo server

Lors du lancement de notre serveur via la commande hugo server, il est possible de lui passer comme paramètre -D ou --buildDrafts. Cela permet de lui dire d’inclure les contenus qui sont marqués comme brouillon ou draft dans la compilation automatique.

Création d’un article

Pour créer un article, rien de bien compliqué :

1hugo new posts/my-first-content.md
2nano content/posts/my-first-content.md

Déploiement

Avoir un blog c’est bien mais l’héberger c’est encore mieux. Nous allons pour cela faire en sorte d’avoir un repository (public ou private) qui contiendra nos sources et un repository qui contiendra le blog compilé. L’avantage de stocker cela sur un repository Github est la possibilité de bénéficier gratuitement d’un hébergement et d’un nom de domaine (github_user.github.io).

Nous allons donc créer deux repositories, l’un nommé par exemple blog-go-src et l’autre github_user.github.iogithub_user correspond à votre nom d’utilisateur Github.

CircleCI

Pour déployer notre blog nous allons utiliser l’offre gratuite de CircleCI. CircleCI est un outil d’intégration continue qui permet de gérer divers jobs en fonction de plusieurs paramètres.

Vous allez par exemple pouvoir exécuter du code à la création d’un pull request (tests unitaires) et au merge de cette pull request faire en sorte de pousser votre code sur vos différents envionnements. C’est ce que nous allons justement faire mais sans la partie tests unitaires.

Nous allons d’abord commencer par nous créer un compte et dans la partie de gauche, cliquer sur Add projects et ajouter notre repository principal en cliquant sur Set Up Project. Une fois créé la CI va s’exécuter et bien sûr comme nous n’avons rien paramétré elle va être rouge et marquer build error.

Pour paramétrer CircleCI il faut créer un dossier .circleci à la racine de votre projet et créer un fichier config.yml. Et dans ce fichier vous allez mettre ceci :

 1version: 2.1
 2
 3commands:
 4    checkout-alpine:
 5        description: Install alpine requirements for checkout
 6        steps:
 7            - run:
 8                  name: "Install alpine requirements for checkout"
 9                  command: apk add git openssh-client curl make
10            - checkout
11            - run:
12                  name: "Init submodules"
13                  command: |
14                      git submodule init;
15                      git submodule update;
16
17    hugo-install:
18        description: Install Hugo for compile blog
19        steps:
20            - run:
21                  name: "Download Hugo"
22                  command: |
23                      if [ ! -f /usr/local/bin/hugo ];then
24                          curl -L https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_linux-64bit.tar.gz | tar -xz;
25                          mv hugo /usr/local/bin/hugo;
26                      fi
27
28    restore-hugo-install-cache:
29        description: "Restore Hugo install"
30        steps:
31            - restore_cache:
32                key: hugo-install-v${HUGO_VERSION}
33
34    store-hugo-install-cache:
35        description: "Store Hugo install in CircleCI cache"
36        steps:
37            - checkout-alpine
38            - restore-hugo-install-cache
39            - hugo-install
40            - save_cache:
41                  key: hugo-install-v0.1
42                  paths:
43                      - /usr/local/bin
44            - persist_to_workspace:
45                  root: /
46                  paths:
47                      - usr/local/bin
48
49    hugo-compile:
50        description: Compile & deploy blog
51        steps:
52            - add_ssh_keys:
53                  fingerprints:
54                      - "YOUR_FINGER_PRINT"
55            - run:
56                  name: "Compile & deploy blog"
57                  command: ./deploy.sh
58
59executors:
60    hugo:
61        docker:
62            - image: alpine:latest
63        working_directory: ~/repository
64
65jobs:
66    hugo:
67        executor: hugo
68        steps:
69            - store-hugo-install-cache
70            - hugo-compile
71
72workflows:
73    version: 2.1
74    Compile & deploy:
75        jobs:
76            - hugo:
77                  filters:
78                      branches:
79                          only: master

La syntaxe est assez simple à comprendre vous allez voir :

  • commands: correspond à un lot de commandes bash ou natives à CircleCI pouvant être exécutées dans un job. Dans ces commandes, il y a notamment une commande permettant de stocker et récupérer le binaire hugo. Cela permet de gagner du temps dans la CI et ainsi ne pas être obligé de télécharger à chaque pull request le nouveau binaire
  • executors: correspond à un lot d’images docker qui vont être utilisées dans vos jobs
  • jobs: correspond aux tâches qui vont être exécutées dans vos workflows avec en paramètre les executors et les commands associées
  • workflows: Comment votre CI doit fonctionner. C’est notamment ici que vous allez pouvoir lancer en parallèle vos tests unitaires et si ceux-ci ont bien fonctionné lancer votre déploiement

Dans la partie workflows vous constaterez que nous avons un filtre qui n’est que la branche master. Il permet de faire en sorte que CircleCI ne lance le job que si le code va sur la branche master.

Comme je l’ai dit plus haut nous allons devoir pousser notre code sur un autre repository. Le souci c’est que CircleCI n’a pas les accès pour le faire. Nous allons donc devoir créer une clé SSH et l’utiliser dans CircleCI.

1ssh-keygen -m PEM -t rsa -C "your_email@example.com"

Une fois cette clé créée, vous allez devoir l’ajouter à votre projet en allant dans les paramètres de votre projet puis dans SSH Permissions. Quand celle-ci sera créée, vous aurez une fingerprint que vous renseignerez dans la commande où vous avez le git push. Dans notre cas ça sera dans la commande hugo-compile.

Script de déploiement

Afin de ne pas voir une commande trop longue à écrire dans le fichier de configuration CircleCI, il est préférable d’externaliser cela dans un script bash.

 1#!/bin/sh
 2
 3# If a command fails then the deploy stops
 4set -e
 5
 6printf "\033[0;32mDeploying updates to GitHub...\033[0m\n"
 7
 8git config --global user.email "github_email"
 9git config --global user.name "github_user"
10
11# Add destination repository
12git submodule add -b master -f git@github.com:github_user/github_repository public
13
14# Build the project.
15hugo -t bleak
16
17# Go To Public folder
18cd public
19
20# Add changes to git.
21git add .
22
23# Commit changes.
24msg="rebuilding site $(date)"
25if [ -n "$*" ]; then
26	msg="$*"
27fi
28git commit -m "$msg"
29
30# Push source and build repos.
31git push origin master

Votre blog peut maintenant se compiler tout seul à chaque merge d’un article.