Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow building lesson using GitLab Pages #521

Open
wants to merge 6 commits into
base: gh-pages
Choose a base branch
from

Conversation

unode
Copy link
Contributor

@unode unode commented Nov 22, 2020

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: carpentries/lesson-example#317

@unode
Copy link
Contributor Author

unode commented Nov 22, 2020

With regards to the maintenance aspect that @maxim-belkin mentioned in carpentries/lesson-example#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).

@maxim-belkin
Copy link
Contributor

maxim-belkin commented Nov 24, 2020

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.

@unode
Copy link
Contributor Author

unode commented Nov 25, 2020

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 unode force-pushed the patch-1 branch 2 times, most recently from 49ba964 to bb8e812 Compare May 15, 2021 21:09
Gemfile Outdated
group :jekyll_plugins do
gem 'github-pages'
# Allows accessing ENV variables in CI environments
gem 'jekyll-environment-variables'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this gem is necessary on GitLab only. If so, could you please make it depend on whether it's executed in GitLab? You can do so by appending if ENV["SOME_GITLAB_VAR"] to the end of the line.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies, only saw this comment after mine below.
Would it be ok to use the same approach to only load the first plugin if running in GitHub?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be precise, if ENV["GITHUB_ACTIONS"] which according to GitHub Actions environment variables is only set when GitHub Actions is running a workflow.

Copy link
Contributor Author

@unode unode May 15, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact, the jekyll-environment-variables plugin might be useful in GitHub Actions too if wanting to access any of the env variables mentioned in the previous comment.

This plugin is very small so its impact should be minimal.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies, only saw this comment after mine below.
Would it be ok to use the same approach to only load the first plugin if running in GitHub?

Hum.. this won't work. Making both plugins conditional causes jekyll to not be installed at all.

@unode
Copy link
Contributor Author

unode commented May 15, 2021

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
Copy link
Contributor Author

unode commented May 15, 2021

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. 😖

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. 😕

unode added a commit to unode/styles that referenced this pull request May 15, 2021
Allows inclusion of gems that will be relevant in
other CIs such as GitLab.

See pull request carpentries#521 for additional context
unode added a commit to unode/styles that referenced this pull request May 15, 2021
Allows inclusion of gems that will be relevant in
other CIs such as GitLab.

See pull request carpentries#521 for additional context
@unode
Copy link
Contributor Author

unode commented May 16, 2021

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.

In particular test that the github-pages plugin
isn't interfering with reading environment variables
@unode
Copy link
Contributor Author

unode commented May 16, 2021

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

@maxim-belkin
Copy link
Contributor

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.

@unode
Copy link
Contributor Author

unode commented May 17, 2021

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants