La mise en production d'un site Github Page par d'un workflow automatisé est un sujet bien documenté. Il s'agit généralement de compiler les sources présentes sur une branche du dépôt puis de copier le résultat sur une autre branche du même dépôt. Or un prérequis de Github Page est d'être hébergé en public.
Je vais détailler ici une solution alternative permettant de séparer les sources du build. Cette architecture présente deux principaux avantages :
Nous allons avoir besoin de deux dépôts Github et d'un environnement de développement front (NodeJs, Git, SSH...). Nous hébergerons le code source sur un dépôt privé qui exécutera un workflow automatisé Github Actions afin de copier une version compilée du site sur un dépôt public défini comme Github Page. Voici une représentation simplifiée des éléments mis en œuvre.
Un compte personnel Github peut comporter une Github Page principale et des Github Pages secondaires qui y seront rattachées. Le dépôt de la Github Page principale doit être nommé suivant le pattern username.github.io.
Dépot | Page |
---|---|
username.github.io.git | username.github.io |
projectOne.git | username.github.io/projectOne |
projectTwo.git | username.github.io/projectTwo |
Nous devons donc créer un dépôt respectant cette contrainte en prenant soin de le définir comme public. Une première configuration peut être effectuée de suite en nous rendant dans l'onglet Settings du dépôt nouvellement créé, puis dans la section Pages. Selectionnez y la branche principale comme source de la Github Page.
Créons maintenant un second dépôt pour accueillir les sources. Par soucis de clarté, il me semble pertinent d'utiliser le pattern précédent en y ajoutant un suffixe : username.github.io.sources.
Ce dépôt peut être défini comme privé puisque c'est le but de cette article.
L'authentification entre les deux dépôts est effectuée par clés SSH stockés dans les configurations de de Github. Je ne m'attarde pas sur ce sujet car la procédure pour en générer est clairement expliquée dans la documentation de Github.
Une fois obtenu nous allons les enregistrer la clé privée comme Secret du dépôt de sources. Les valeurs secrètes de Github sont des variables d'environnement protégées. Vous pouvez utiliser leurs références mais leurs valeurs restent secrète. Rendez-vous donc dans l'onglet Settings du dépôt puis Secrets.
La clé publique est utilisée sur le dépôt accueillant le build du site. Allez dans ses Settings puis cette fois dans Deploy Keys afin d'enregistrer votre clé. Attention, il est nécessaire de cocher la case Allow write access afin d'autoriser la copie des fichiers compilés dans ce dépôt.
Nous devons maintenant automatiser le workflow par un script définissant les actions à effectuer. Les Github Actions nous permettent cela très facilement. Ouvrez l'onglet Actions du dépôt de sources puis créez un nouveau workflow vierge.
1name: Build and Deploy
2
3on:
4 push:
5 branches:
6 - main
7
8jobs:
9 deploy:
10 runs-on: ubuntu-latest
11 steps:
12 - uses: actions/checkout@v2
13
14 - uses: actions/setup-node@v2.1.2
15 with:
16 node-version: '14.x'
17
18 - name: Get yarn cache directory path
19 id: yarn-cache-dir-path
20 run: echo "::set-output name=dir::$(yarn cache dir)"
21
22 - uses: actions/cache@v2
23 id: yarn-cache
24 with:
25 path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
26 key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
27 restore-keys: |
28 ${{ runner.os }}-yarn-
29
30 - run: yarn install --frozen-lockfile
31 - run: yarn run build
32
33 - uses: peaceiris/actions-gh-pages@v3
34 with:
35 deploy_key: ${{ secrets.DEPLOY_KEY }}
36 publish_dir: ./public
37 external_repository: AurelienDud/AurelienDud.github.io
38 publish_branch: main
La clé on définit les événements déclenchant le script. Il peut s'agir d'un cron ou changement sur dépôt. Soyez prudent si vous êtes tenté de définir un déclenchement basé sur un cron car les comptes Free de Github sont limités à 2000 minutes de fonctionnement par mois sur les dépôts privés. Le plus classique pour un site est de déployer lorsque des modifications sont poussées sur la branche principale.
1on: 2 push: 3 branches: 4 - main
Voici au passage un rappel sur les bonnes pratiques de branches git. Les développements doivent s'effectuer sur des branches dédiées. Lorsqu'une release est souhaitée une nouvelle branche doit être créée afin d'accueillir les fusions. Ainsi la branche principale n'est pas impactée en cas de fusion problématique.
Nous définissons ensuite un environnement serveur.
1runs-on: ubuntu-latest
Puis les steps des actions à exécuter sous forme de liste. Le mot clé uses permet d'indiquer que nous souhaitons utiliser des scripts réutilisables. Comprendre par là une librairie Github Actions.
Nous commençons par récupérer les dernières modifications sur le dépôt.
1- uses: actions/checkout@v2
Avant d'initialiser NodeJs à la version souhaitée.
1- uses: actions/setup-node@v2.1.2 2 with: 3 node-version: '14.x'
et d'activer le cache tel que défini dans la documentation dédiée.
1- name: Get yarn cache directory path 2 id: yarn-cache-dir-path 3 run: echo "::set-output name=dir::$(yarn cache dir)" 4 5- uses: actions/cache@v2 6 id: yarn-cache 7 with: 8 path: ${{ steps.yarn-cache-dir-path.outputs.dir }} 9 key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} 10 restore-keys: | 11 ${{ runner.os }}-yarn-
Ensuite nous exécutons les commandes d'installation et de compilation contenu dans le package.json du projet que nous créerons plus tard. Un coup d'œil dans la documentation de GatsbyJs nous confirme qu'elles seront très classiques.
1- run: yarn install --frozen-lockfile
2- run: yarn run build
Le première commande installe les dépendances en respectant les versions mentionnées dans le fichier yarn.lock (la commande npm ci doit-être utilisé en cas d'utilisation de NPM). Cela va garantir l'usage de versions testées en développement et donc prévenir des problèmes d'incompatibilité.
Puis la seconde commande exécute la compilation des sources.
Le site est généré alors mais ses fichiers se trouvent sur une machine virtuelle de Github.
Pour déployer ces sources sur le dépôt dédié j'utilise une action développée par un confrère developpeur. Il suffit d'indiquer la référence de la clé SSH (deploy_key), le répertoire dans lequel a été généré le build (publish_dir), puis les informations de destination (external_repository, publish_branch).
1- uses: peaceiris/actions-gh-pages@v3
2 with:
3 deploy_key: ${{ secrets.DEPLOY_KEY }}
4 publish_dir: ./public
5 external_repository: AurelienDud/AurelienDud.github.io
6 publish_branch: main
Voilà, l'infrastructure du projet est prête ! C'est à maintenant à vous de jouer pour développer un beau projet. A la prochaine.