GitLab Pages Theme Submodules

Introduction

At the end of the GitLab Pages Setup post, I described an issue I encountered with GitLab CI generating the static site. The issue is caused by Hexo themes being linked as Git submodules - which means the default theme configuration is used. At the time, I only had a single idea - but was not sure whether or not it would work. Since then I have had a few more ideas about possible solutions and this post will describe them.

Overwrite Default Theme Configuration

The most straightforward approach was to add the modified configuration file to the repository. Using the GitLab build configuration, the configuration file could be copied to the themes folder overwriting the default theme configuration.

The only benefit of this approach is its simplicity. Adding the file is trivial and the modified GitLab build configuration would look something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
image: node:10.15.3

variables:
GIT_SUBMODULE_STRATEGY: recursive

cache:
paths:
- node_modules/

before_script:
- npm install hexo-cli -g
- test -e package.json && npm install
- mv themes/_config.yml themes/icarus/_config.yml
- hexo generate

pages:
script:
- hexo generate
artifacts:
paths:
- public
only:
- master

In case it isn’t clear because it’s only a line, the change is:

1
- mv themes/_config.yml themes/icarus/_config.yml

This approach has a few problems though. The first inconvenience is if the theme allows the configuration of branding images or avatars that utilize a path in the theme structure these files must also be copied or moved into the theme after the submodule has been initialized. This could probably be overcome by mirroring the structure of the theme and modifying the command to move a folder into the theme during the build process. Changing themes requires updating the theme config file, the GitLab build configuration file, and adding the theme as a submodule reference. Most troubling however is that if the submodule is updated, there is no way to detect conflicts or updates that may break the theme except at runtime. Overall, this does not seem like a good approach anymore.

Include Theme Contents

The second option could be to include the theme contents directly instead of referencing them as a submodule. Doing so would eliminate the first two issues described with the previous method above. However, it still suffers from the final issue, although slightly different. Updates now are a completely manual process, which will likely entail overwriting the files - potentially leaving orphaned files. Additionally, it also adds bloat to the Hexo content repository which probably is not necessary. Overall, this solution is better than the previous one but still is less than ideal.

Fork and Update

The final idea I had is to fork the theme being used. Updates can be made to this new repository that is specific to the Hexo instance. Updates can be applied by merging the original master repository into this forked copy. If the update changes something unexpected, a conflict will occur that the user will have to resolve to finish the merge. The Hexo content repository would then have the Git submodule reference the forked copy. Another great part about this is that the submodule can be edited directly and changes committed for it from the parent module.

Summary

I think the final solution eliminates most of the major risks associated with the other options and is what I will be using. I can even make my forked repository private and have the GitLab runner still able to access it thanks to GitLab’s CI build permissions. The only differences are that my submodule name will need to be the project name and the URL will need to be changed from an absolute URL to a relative URL:

1
2
3
[submodule "hexo-theme-icarus"]
path = themes/icarus
url=../hexo-theme-icarus.git

The other solutions should work fine but they seemed wrong for one reason or another. Choose whichever option has risks that you can live with.