styles icon indicating copy to clipboard operation
styles copied to clipboard

Allow building lesson using GitLab Pages

Open unode opened this issue 3 years ago • 9 comments

This commit adds a .gitlab-ci.yml file that allows building the lesson on GitLab and deploying to GitLab Pages.

GitLab is an alternative to GitHub that supports "on-premise" installation, making it a popular choice for many organizations.

Originally submitted at: https://github.com/carpentries/lesson-example/pull/317

unode avatar Nov 22 '20 22:11 unode

With regards to the maintenance aspect that @maxim-belkin mentioned in https://github.com/carpentries/lesson-example/pull/317, the contribution guidelines don't currently cover how to proceed beyond GitHub, so I'm not sure.

The path of least effort would be to rely on end users that are interested in using this feature. If it breaks we would expect contributions to correct it. We could also add a comment to the file with additional information or a link to relevant documentation.

Beyond this there are several, more elaborate, options:

  • This repository could be mirrored at gitlab.com. Once configured, synchronization is automatic and the GitLab CI is triggered for every new commit to this repository.
  • A GitHub action could be configured to run gitlab-runner which replicates all the steps that also happen in GitLab CI (with exception of serving the final HTML documents).

unode avatar Nov 22 '20 22:11 unode

I think expanding our CI capabilities is a good thing and it'd be great if we can make our template work with GitLab. But I foresee a few issues with the current approach:

  1. We need to set JEKYLL_ENV environment variable to production (the default one is development which works fine when building locally at the cost of some broken links).
  2. There might be some issues with building the website inside of a container. For example, if you have a look at _includes/gh_variables.html you'll see that we use site.github.* variables. These variables might work on GitLab outside of a container (we need to test this but I saw some lessons using these variables on GitLab) but I expect them to not work in a container.

So, all in all, I'm +1 for adding bits and pieces for GitLab CI but we need to make sure it works and implement a way to test it when needed.

maxim-belkin avatar Nov 24 '20 21:11 maxim-belkin

JEKYLL_ENV: "production" is now included.

For site.github the GitLab issue https://gitlab.com/gitlab-org/gitlab/-/issues/22806 might be relevant. The take home message there is that there isn't a compatibility feature yet. There are however workarounds, including providing a customized docker image or including the suggested jekyll plugin.

According to https://github.com/jekyll/github-metadata/blob/master/docs/site.github.md there's quite a bit of metadata in this variable.

unode avatar Nov 25 '20 01:11 unode

Trying to revive this PR but running into some obstacles:

  1. Added the plugin jekyll-environment-variables which allows accessing ENV variables through site.env (e.g. {{ site.env.HOME }}). This would allow accessing GitLab CI environment variables.

However, this plugin only seems to work if I disable github-pages in the Gemfile. When both plugins are enabled, they are listed among others in the output of make site or make serve but accessing {{ site.env.VAR }} returns nothing. I'm not familiar enough with Jekyll's plugin infrastructure to understand why this is happening.

Note that this was tested locally by using make serve and JEKYLL_ENV=production make serve not via GitHub Pages where, according to Jekyll's documentation, --safe is used causing all plugins to be disabled.

  1. Still related to the github-pages plugin, when building with JEKYLL_ENV=production, site.baseurl is set to /pages/<repo-group>/<repo-name>. I assume this is the expected URL for GitHub Pages but this is unlikely to work if building anywhere else. Disabling the github-pages plugin no longer leads to site.baseurl being set so it looks like the plugin is also responsible for this.

With this I'm not sure how to proceed. It looks like the only option is to conditionally enable the github-pages plugin but I don't know how to achieve this in the Gemfile.

Any suggestions on how to proceed?

For reference, at the time of testing the two plugins were versions:

github-pages - 214
jekyll-environment-variables - 1.0.1

unode avatar May 15 '21 22:05 unode

Looking into the github-pages plugin it seems the plugin itself implements a mechanism to disable any other plugins. This explains why I had to disable this plugin to get jekyll-environment-variables to work.

Unfortunately, without disabling it and explicitly listing all the plugins that are necessary, I don't see how to make it possible to build elsewhere. :confounded:

EDIT 1: Some light at the end of the tunnel, seems like it's possible to bypass the plugin whitelist by setting DISABLE_WHITELIST=true.

EDIT 2: Doesn't seem to work. No {{ site.env.VAR }} is available even when using JEKYLL_ENV=development DISABLE_WHITELIST=true. :confused:

unode avatar May 15 '21 22:05 unode

To summarize:

  1. JEKYLL_ENV=production cannot be used to build outside GitHub. The github-pages plugin implements GitHub Pages specific behavior that would break builds elsewhere.
  2. The github-pages plugin disables any other plugins. The provided workaround doesn't work with JEKYLL_ENV=production and doesn't seem to work with JEKYLL_ENV=development either but the reason for the latter is unclear.

I've pushed an alternative solution that makes the github-pages gem conditional to ENV["GITHUB_ACTIONS"] and is explicit about all other dependencies following the dependency list of github-pages.

The list is now quite verbose and not all plugins may be necessary but I didn't want to do arbitrary decisions here. The only commented out are dependencies that would be specific to GitHub.

unode avatar May 16 '21 00:05 unode

Testing is now included through a GitHub Actions workflow that runs gitlab-runner to simulate a GitLab CI build.

unode avatar May 16 '21 05:05 unode

Hi @unode,

I had a closer look at the way you (propose to) use jekyll-environment-variables gem and it should be required unconditionally.

github-pages gem should still be required unconditionally because it's used for building websites locally. But please see my note below for.


I can confirm that github-pages gem causes the pain points you talk about above - I was able to observe them in my local tests. I do think, however, there is some misunderstanding regarding the "whitelist" setting: github-pages plugin has a predefined list of plugins that it can enable (using the plugins list in _config.yml) and the DISABLE_WHITELIST option disallows them (https://github.com/github/pages-gem/blob/75fd58be0f294a6bf55a1990643838d5984a1f62/lib/github-pages/configuration.rb#L81) -- at least that's how I think it's supposed to work.

I apologize that I don't have time to dig into this further. My general advice is to try to avoid hardcoding a lot of gem versions into the Gemfile. In my local tests I was able to build websites requiring kramdown-parser-gfm gem only. For GH actions I'd recommend trying to use GitLab's Docker image itself, if possible. If I understand correctly, JEKYLL_ENV on GitLab's runners is set to development, so it probably can be treated as if the website is being built locally.

maxim-belkin avatar May 17 '21 20:05 maxim-belkin

@maxim-belkin thanks a lot for taking the time to review the PR and even more to test it.

I'm not familiar enough with Ruby and Jekyll so I didn't quite understand the DISABLE_WHITELIST feature. Looking at the code didn't help. My interpretation was entirely based on the info on their README that reads:

If you'd like to run a Jekyll plugin locally that's not whitelisted for use on GitHub Pages, you can do so by prefixing the jekyll build or jekyll serve command with DISABLE_WHITELIST=true. This will allow your site to use any plugin listed in your site's gems configuration flag. Please note, however, this option is only available when previewing your Jekyll site locally.

I understood that disabling the whitelist would make the github-pages plugin more permissive. In your phrasing above I read it in the opposite direction, that is, disabling the whitelist would disallow any whitelisted plugin, effectively making it more restrictive, not less. This would be consistent with my tests but would contrast the quoted text above.

I still think that DISABLE_WHITELIST, if working as described above, would be the preferred option, but I failed to achieve this so far.

Regarding GitLab Pages, I'm happy to strip other dependencies from the Gemfile and keep only kramdown-parser-gfm. I opted for including the others out of caution. I wasn't sure if any were relevant to other lessons.

Finally, in what concerns the GitHub Action workflow test. The current workflow uses gitlab-runner, the official binary used by GitLab to run their CI tasks. This process in turn uses the docker image specified in the .gitlab-ci.yml file, currently set to carpentries/lesson-docker, which I found somewhere to be the recommended environment to build the lesson.

In the Jekyll example in GitLab Pages docs they use a bare ruby:2.7 docker image on which jekyll is then installed. In this sense, there is no "GitLab Pages" docker image. Any docker image can be used. This also means that the process will use whichever JEKYLL_ENV mode we decide. This PR currently doesn't set this variable so I also understand it to be equivalent to development.

Still on which docker image to use, the Jekyll template repository provided by GitLab uses the ruby:latest docker image. In some other tests I've successfully used the official Jekyll docker image. All these are equally valid options and need only a decision from our side.

unode avatar May 17 '21 21:05 unode