├── .editorconfig
├── .github
└── workflows
│ └── jekyll.yml
├── .gitignore
├── Gemfile
├── LICENSE
├── Makefile
├── README.md
├── docs
├── README.md
├── deploy.md
├── development.md
├── installation.md
└── usage.md
└── sample_site
├── _config.yml
├── about.md
├── index.md
├── resources.md
├── time-ago.md
└── tutorial.md
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 2
6 |
7 | [*.{md,html}]
8 | indent_size = 4
9 |
10 | [Makefile]
11 | indent_style = tab
12 | indent_size = 4
13 |
--------------------------------------------------------------------------------
/.github/workflows/jekyll.yml:
--------------------------------------------------------------------------------
1 | name: GH Pages CI
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 | paths-ignore:
8 | - "docs/**"
9 |
10 | jobs:
11 | build-deploy:
12 | runs-on: ubuntu-latest
13 |
14 | steps:
15 | - name: Checkout repo
16 | uses: actions/checkout@v2
17 |
18 | - name: Get cached gems
19 | uses: actions/cache@v2
20 | with:
21 | path: vendor/bundle
22 | key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
23 | restore-keys: |
24 | ${{ runner.os }}-gems-
25 |
26 | - name: Build and deploy
27 | uses: helaili/jekyll-action@v2
28 | with:
29 | token: ${{ secrets.GITHUB_TOKEN }}
30 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ### Install
2 |
3 | .bundle/
4 | vendor/
5 |
6 | ### Build
7 |
8 | .jekyll-cache/
9 | .jekyll-metadata
10 | build/
11 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source "https://rubygems.org"
2 |
3 | gem "jekyll", "~> 4.2"
4 | gem "webrick", "~> 1.7"
5 |
6 | gem "minima", "~> 2.5"
7 |
8 | group :jekyll_plugins do
9 | gem "jekyll-timeago", "~> 0.13.1"
10 | end
11 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 - 2022 MichaelCurrin
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | default: install
2 |
3 | h help:
4 | @grep '^[a-z]' Makefile
5 |
6 | install:
7 | bundle config set --local path vendor/bundle
8 | bundle install
9 |
10 | s serve:
11 | cd sample_site && \
12 | bundle exec jekyll serve --destination ../build/ --trace --livereload
13 |
14 | .PHONY: build
15 | build:
16 | cd sample_site && \
17 | JEKYLL_ENV=production bundle exec jekyll build -d ../build --trace
18 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Jekyll Actions Quickstart
2 | > Deploy a Jekyll 4 site to GH Pages using the "Jekyll Actions" action
3 |
4 | [](https://github.com/MichaelCurrin/jekyll-actions-quickstart/actions?query=workflow:"GH+Pages+CI")
5 | [](https://github.com/MichaelCurrin/jekyll-actions-quickstart/tags/)
6 | [](#license)
7 |
8 | [](https://pages.github.com/)
9 | [](https://github.com/features/actions)
10 |
11 | [](https://jekyllrb.com)
12 | [](https://github.com/marketplace/actions/jekyll-actions)
13 |
14 |
15 | ## Purpose
16 |
17 | A live demo and introduction around deploying Jekyll 4 to GitHub Pages - using a GitHub Actions workflow and the [Jekyll Actions](https://github.com/marketplace/actions/jekyll-actions) action. If you prefer a more generic, flexible, and reusable flow, see my related quickstart repo - [jekyll-gh-actions-quickstart](https://github.com/MichaelCurrin/jekyll-gh-actions-quickstart). That uses a Ruby action to install Ruby and gems, builds using a shell command, and then deploys using an action that handles GitHub Pages.
18 |
19 | GitHub Pages already supports building a plain HTML or Jekyll site. No workflow configuration needed for that. So, the reason for GitHub Actions here to build a Jekyll site is that it gives us more control over the environment and build steps. Like the ability to choose Jekyll 4 instead of Jekyll 3, using custom gems, and adding in shell, Python, or NPM commands before the Jekyll build command.
20 |
21 | If you are new to GH Actions, see links and code snippets in my [Workflow Builder](https://michaelcurrin.github.io/workflow-builder/) project.
22 |
23 |
24 | ## How can I use Jekyll 4 with GitHub Actions?
25 |
26 | Follow one of the approaches below to learn how it works and set up your own site and workflow.
27 |
28 | ### Tutorial
29 |
30 | This project was developed as part of writing a step-by-step guide for the Jekyll site's documentation.
31 |
32 | Here is the link:
33 |
34 | - [Jekyll CI GitHub Actions tutorial](https://jekyllrb.com/docs/continuous-integration/github-actions/)
35 |
36 | ### Demo
37 |
38 | See this project's live demo hosted on GitHub Pages:
39 |
40 |
41 |
42 | [](https://michaelcurrin.github.io/jekyll-actions-quickstart/)
43 |
44 |
45 |
46 | ### Create from template
47 |
48 | Create your own repo like this one using the button below. Then continue following the setup and run instructions on this page.
49 |
50 |
51 |
52 | [](https://github.com/MichaelCurrin/jekyll-actions-quickstart/generate)
53 |
54 |
55 |
56 | ### Comparing approaches
57 |
58 | There are many ways to deploy a Jekyll site on GH Pages. I cover some in my [Code Cookbook](https://michaelcurrin.github.io/code-cookbook/recipes/ci-cd/github-actions/workflows/jekyll/).
59 |
60 | Those approaches have different levels of complexity:
61 |
62 | - You use an all-one Jekyll + GH Pages action, like the one in this project and tutorial.
63 | - Or use a separate action for Jekyll and then another for GH Pages for more modularity (you can swap out one action easily and you can reuse the GH PAges deploy action for other projects like for React).
64 | - Or you can avoid pre-made actions and write all the low-level code yourself (not recommended.
65 |
66 | The approaches have varying levels of security.
67 |
68 | - Some flows use the GitHub-generated `GITHUB_TOKEN`. This only has access to one repo during workflow a run, is never seen by a human and so is _very_ secure.
69 | - Other flows expect a user-generated Personal Access Token. This has access to update _all_ of your public repos and requires you to generate and store it. It might get abused by a vulnerable or malicious Action. It is _less_ secure.
70 |
71 |
72 | ## Documentation
73 | > How to install and run locally and deploy on GH Pages
74 |
75 |
76 |
77 | [](/docs/)
78 |
79 |
80 |
81 |
82 | ## License
83 |
84 | - Released under [MIT](/LICENSE) by [@MichaelCurrin](https://github.com/MichaelCurrin).
85 | - Feel free to modify and reuse this project. You are required to include the license when using this code. Copy `LICENSE` to `LICENSE-source` and then modify `LICENSE` with your own name.
86 | - Please link back to this repo.
87 |
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | # Jekyll Actions Quickstart docs
2 |
3 | - [Installation](installation.md)
4 | - [Usage](usage.md)
5 | - [Deploy](deploy.md)
6 | - [Development](development.md)
7 |
--------------------------------------------------------------------------------
/docs/deploy.md:
--------------------------------------------------------------------------------
1 | # Deploy
2 | > How to deploy this project as a remote site using GH Pages and GH Actions
3 |
4 |
5 | ## Run a local production build
6 |
7 | If you want to use `make`:
8 |
9 | ```sh
10 | $ make build
11 | ```
12 |
13 | Or
14 |
15 | ```sh
16 | $ cd sample_site
17 | $ JEKYLL_ENV=production bundle exec jekyll build -d ../build --trace
18 | ```
19 |
20 | Then view the output in `build` at your project root.
21 |
22 |
23 | ## Set up this project as a GitHub Pages site
24 |
25 | The part which makes this project run on GitHub Actions is the workflow file - see [jekyll.yml](/.github/workflows/jekyll.yml). You do _not_ need to modify that file. Except perhaps to change the branch to `main`.
26 |
27 | 1. Add this repo to your GitHub repos using the template or fork button. You only need `master` branch. The `gh-pages` branch will get built from scratch later.
28 | 1. Save a file or push a commit.
29 | 1. Go to the _Actions_ tab of your repo to see the workflow running.
30 | - On success, it will generate the site, commit to `gh-pages` branch and make the content available GH Pages.
31 | - On the _very first_ run, you'll see a success, but not actually have the site live. So then you need to go into the _Settings_ of your repo and turn GitHub Pages **off** and then on again (for `gh-pages` branch). This has been my experience on multiple projects.
32 | 1. Check the _Environment_ section to see the status and your GH Pages URL.
33 |
34 | Your GH Pages site is live on GH Pages. It now rebuilds and deploys on a commit or push - using custom gems.
35 |
36 | Update the badge in your `README.md` to point to your workflow - this makes it easy to see the passing/failing status of your workflow.
37 |
38 | Note that the workflow has been configured to deploy using one branch - the default one. If you had the workflow run against other branches too, then you would accidentally deploy to your site any time your pushed work-in-progress code to a branch.
39 |
40 |
41 | ## How GH Pages and GH Actions work together
42 |
43 | Here we use GitHub Actions as a CI/CD flow to just _build_ the site. It does not actually _serve_ anything.
44 |
45 | The GitHub Pages deploy runs here, as if you were not using GH Actions at all. The difference is that normally GH Pages points to source content on `master` or `main` branch and no second branch is needed. Here we build to `gh-pages` directory and GH Pages then serves that. There are no Jekyll configs or markdown files on `gh-pages` - just compiled HTML files and other assets. The Action we use also adds an empty `.nojekyll` file to the `gh-pages` branch for us, to explicitly tell GH Pages to serve the content with doing a build.
46 |
--------------------------------------------------------------------------------
/docs/development.md:
--------------------------------------------------------------------------------
1 | # Development
2 |
3 |
4 | ## Note on locking gems
5 |
6 | For this simple demo project with few dependencies, leaving out the `Gemfile.lock` file altogether is reasonable.
7 |
8 | Note that `Gemfile.lock` must remain as file **ignored** by `git` to avoid build errors. This because an install locally with `bundle` will put `bundler` as a line in `Gemfile.lock`, while `bundler` use will cause an error on the remote build as its not available (at least in the container used by the chosen GitHub Action here.
9 |
10 | Alternatively, keep the file either build will a global (user-level) Jekyll. Or keep building a `Gemfile.lock` remember to manually remove the `bundler` reference.
11 |
12 |
13 | ## Excluding
14 |
15 | The `Makefile`, `LICENSE` and `README.md` files in the root do not have to be excluded, as this site is setup to build from a _subdirectory_. Otherwise they would have to be added to the ignore list.
16 |
17 | The `Gemfile` and `Gemfile.lock` are _always_ ignored by Jekyll 4.
18 |
--------------------------------------------------------------------------------
/docs/installation.md:
--------------------------------------------------------------------------------
1 | # Installation
2 |
3 |
4 | ## Requirements
5 |
6 | - [Ruby](https://www.ruby-lang.org/)
7 | - [Bundler](https://bundler.io)
8 |
9 | For convenience, this project used [GNU Make](https://www.gnu.org/software/make/), which is standard on Linux and macOS. If you do not have it on Windows, you can skip `make` commands and use the more verbose commands supplied in the docs of this project.
10 |
11 |
12 | ## Install system dependencies
13 |
14 | Install [Ruby](https://www.ruby-lang.org/en/documentation/installation/#package-management-systems).
15 |
16 | Install Bundler as gem for your user.
17 |
18 | ```sh
19 | $ gem install bundler --user-install
20 | ```
21 |
22 | Some people prefer to _omit_ the `--user-install` flag, but, then you need access to install to a shared `/usr/lib/ruby` directory, which could require use of `sudo` to run the `gem` command. In that case, rather change permissions on `/usr/lib/ruby` directory to be writable by all users, so you never have to run `sudo gem ...`.
23 |
24 |
25 | ## Clone
26 |
27 | Clone the repo or your repo copied from the template.
28 |
29 | ```sh
30 | $ git clone git@github.com:MichaelCurrin/jekyll-actions-quickstart.git
31 | $ cd jekyll-actions-quickstart
32 | ```
33 |
34 |
35 | ## Install project packages
36 |
37 | If you want to use `make`:
38 |
39 | ```sh
40 | $ make install
41 | ```
42 |
43 | Or configure Bundler in your project.
44 |
45 | ```sh
46 | $ bundle config set --local path vendor/bundle
47 | ```
48 |
49 | Then install project dependencies using Bundler. This will include Jekyll 4.
50 |
51 | ```sh
52 | $ bundle install
53 | ```
54 |
--------------------------------------------------------------------------------
/docs/usage.md:
--------------------------------------------------------------------------------
1 | # Usage
2 |
3 | Start a development server using the project-scoped Jekyll (ignoring any globally-installed Jekyll gem).
4 |
5 |
6 | If you want to use `make`:
7 |
8 | ```sh
9 | $ make serve
10 | ```
11 |
12 | Or
13 |
14 | ```sh
15 | $ cd sample_site
16 | $ bundle exec jekyll serve --destination ../build/ --trace --livereload
17 | ```
18 |
--------------------------------------------------------------------------------
/sample_site/_config.yml:
--------------------------------------------------------------------------------
1 | ## Site metadata ##
2 |
3 | title: Jekyll Actions Guide
4 | description: How to setup GH Pages + GH Actions for use with Jekyll 4
5 |
6 | ### Built settings ###
7 |
8 | url: "https://michaelcurrin.github.io"
9 | baseurl: "/jekyll-actions-quickstart"
10 |
11 | github_username: MichaelCurrin
12 |
13 | theme: minima
14 |
--------------------------------------------------------------------------------
/sample_site/about.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: About Actions
3 | layout: page
4 | ---
5 |
6 | ## Comparison
7 |
8 | GitHub's Actions functionality as a build and deploy pipeline for a Jekyll site gives more control than a standard _GitHub Pages_ deploy.
9 |
10 | Here are the main differences between GitHub Pages when using Actions or not.
11 |
12 | - Jekyll version
13 | - The GitHub Pages environment limits us to using Jekyll `3.9`.
14 | - Actions let you use a version in your Gemfile, such as Jekyll `4.2`.
15 | - Plugins
16 | - GitHub Pages limits you to a set of supported [gem versions](https://pages.github.com/versions/), so you cannot use plugins or versions outside of this. You can only specify whether a config is used by using `plugins` field in the config.
17 | - Actions lets you choose any plugin - whether your own or someone else's.
18 | - Themes
19 | - GitHub Pages normally limits you to these [Themes](https://pages.github.com/themes/) at certain versions. Though, GitHub Pages does also let you use the `remote_theme` parameter through the supported [benbalter/jekyll-remote-theme](https://github.com/benbalter/jekyll-remote-theme) plugin.
20 | - Actions lets you choose any theme - whether your own or by someone else.
21 | - Workflow
22 | - GitHub Pages gives you limited output and error messages when running a build and check that everything built okay.
23 | - With Actions, you specify a workflow file, do a build in a container and see verbose logged steps and errors. You can combine multiple actions or how secrets are used as environment variables. And you can add extra steps like calling an API at build time using a Ruby plugin. You can even compile a ReactJS site and use other non-Jekyll options if you find the right Action on the Marketplace.
24 | - Build destination
25 | - GitHub Pages builds to a `_site` or similar build location which you never get to see directly. You can mirror it by building locally of course.
26 | - Using Actions, you can build to a different branch like `gh-pages`. You can even output to your content another repo. When using GH Pages alone, you just needed one branch like `master` or `main`, without worrying about a `gh-pages` branch.
27 |
28 |
29 | ## Notes
30 |
31 | Even if a plugin or themes written for Jekyll 3 installs and runs without error in Jekyll 4, you may still run into issues. For example, you may have to overwrite a theme _layout_ or _includes_ file in your project, so that you can control the URLs better.
32 |
33 | See the [Upgrading from 3x to 4x](https://jekyllrb.com/docs/upgrading/3-to-4/) guide to see what changes there are.
34 |
35 | See also issue [#651](https://github.com/github/pages-gem/issues/651) on the Pages Gem repo, which deals with adding Jekyll 4 support to GitHub Pages. This is complex to implement, so don't expect it soon.
36 |
--------------------------------------------------------------------------------
/sample_site/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: home
3 | ---
4 |
5 | > {{ site.description }}
6 |
7 | [](https://github.com/MichaelCurrin/jekyll-actions-quickstart)
8 | [](https://github.com/MichaelCurrin/jekyll-actions-quickstart)
9 | [](https://github.com/MichaelCurrin/jekyll-actions-quickstart)
10 |
11 | [](https://jekyllrb.com)
12 | [](https://github.com/marketplace/actions/jekyll-actions)
13 |
14 |
15 | ## Purpose
16 |
17 | This project has the following purposes:
18 |
19 | ### Information
20 |
21 | - [About Actions]({% link about.md %}) page - this describes how you can use a custom CI flow with GitHub Actions to serve on GitHub Pages.
22 | - [Tutorial]({% link tutorial.md %}) page - instructions and resources to add Actions to your Jekyll site.
23 |
24 | ### Template
25 |
26 | - Get a copy of this repo in your GH user - click this: [](https://github.com/MichaelCurrin/jekyll-actions-quickstart/generate)
27 |
28 | ### Live demo
29 |
30 | - This site shows the result of a static site built with Jekyll Actions, using Jekyll 4 and a custom plugin.
31 | - See the custom plugin in action on the [Time ago]({% link time-ago.md %}) page.
32 | - See this site's [repo](https://github.com/MichaelCurrin/jekyll-actions-quickstart) to see how this project is setup. Note the GH workflows section and the `sample_site` directory which is found _automatically_ because of the config file.
33 |
--------------------------------------------------------------------------------
/sample_site/resources.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Resources
3 | layout: page
4 | ---
5 |
6 | > Some recommended links related to GitHub Actions and Jekyll.
7 |
8 |
9 | ## GitHub Actions docs
10 |
11 | - [Actions](https://github.com/features/actions) listed under GitHub features.
12 | - [Actions](https://help.github.com/en/actions) under GitHub help.
13 |
14 |
15 | ## Actions
16 |
17 | Some available actions for your workflow.
18 |
19 | Also try a [Jekyll](https://github.com/marketplace?type=actions&query=jekyll) search in the GitHub Marketplace.
20 |
21 |
22 | ### Jekyll + GitHub Pages actions
23 |
24 | Links are for the GH Actions Marketplace
25 |
26 | - [Jekyll Actions](https://github.com/marketplace/actions/jekyll-actions) - used by this project. It is a docker-based action.
27 | - [Jekyll Action TS](https://github.com/marketplace/actions/jekyll-action-ts) - a fork of the above but with TypeScript and without Docker, so it is lighter.
28 | - [Jekyll Deploy GH Pages](https://github.com/marketplace/actions/jekyll-deploy-gh-pages)
29 |
30 |
31 |
32 | ### Starter workflows
33 |
34 | If you create a new action through the Actions tab, you'll see this Jekyll action there. You might have to click the _more..._ button.
35 |
36 | That action references [jekyll.yml](https://github.com/actions/starter-workflows/blob/master/ci/jekyll.yml) in the [actions/starter-workflows](https://github.com/actions/starter-workflows) repo.
37 |
38 | That unfortunately does't provide any info though on what you do after a successful build in terms of publishing and viewing results.
39 |
40 | This Action was not used for this site and is not covered in more detail.
41 |
--------------------------------------------------------------------------------
/sample_site/time-ago.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Time ago
3 | layout: page
4 | ---
5 |
6 | > Demo of the [jekyll-timeago](https://rubygems.org/gems/jekyll-timeago) gem. This is not in the GitHub Pages supported list but used here through GH Actions.
7 |
8 | {% assign date = '2016-03-23T10:20:00Z' %}
9 |
10 | - Original value
11 | - `{{ date }}`
12 | - Time ago filter
13 | - `{{ date | timeago }}`
14 | - Time ago filter with YYYY-MM-DD format set using `'2020-1-1'`
15 | - `{{ date | timeago: '2020-1-1' }}`
16 |
--------------------------------------------------------------------------------
/sample_site/tutorial.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Tutorial
3 | layout: page
4 | ---
5 |
6 | > Where to find Jekyll actions on GitHub and how to set one up.
7 |
8 |
9 | ## Tutorial on Jekyll docs
10 |
11 | To learn how to setup a Jekyll / GitHub Actions / GitHub Pages integration, see the [GitHub Actions](https://jekyllrb.com/docs/continuous-integration/github-actions/) guide on the Jekyll docs site.
12 |
13 | This project was actually developed as part of the processing of writing that step-by-step guide and there is a link at the end of the doc back to this repo.
14 |
15 |
16 | ## Extra details
17 |
18 | Some details not mentioned in that guide but which I still want to share.
19 |
20 | - Links
21 | - See [helaili/jekyll-action](https://github.com/helaili/jekyll-action) repo which by [helaili](https://github.com/helaili), a staff member at GitHub. The instructions there cover optional input values.
22 | - [entrypoint.sh](https://github.com/helaili/jekyll-action/blob/master/entrypoint.sh)
23 | - This covers the shell commands which are run in the build, including use of `jekyll` and `git`. This is useful to see what would happen on the remote environment, for example file and directory references for inputs and outputs. Also it shows how `bundle` is actually used in the container.
24 | - Subdirectory usage
25 | - The action mentioned above will build from any directory which contains a config file. This is usually the root but can be a subdirectory, such as is the case for this repo.
26 | - Dotenv file
27 | - If you need to set values in the environment locally, you could do this with an ignored `.env` file at the root. You'll have to to load that into the shell. Some plugins will read from a `.env` file though. In this case the only environment variable needed is one needed to actually run the action and build to `gh-pages` branch, so this project has no `.env` file.
28 |
--------------------------------------------------------------------------------