├── tests
├── CNAME
├── .gitignore
├── index.markdown
├── 404.html
├── about.markdown
├── Gemfile
├── _posts
│ └── 2020-08-26-welcome-to-jekyll.markdown
├── Gemfile.lock
└── _config.yml
├── .github
├── dependabot.yml
└── workflows
│ ├── jekyll-test.yml
│ └── jekyll-deploy.yml
├── deployer
├── Dockerfile
└── entrypoint.rb
├── action.yml
└── README.md
/tests/CNAME:
--------------------------------------------------------------------------------
1 | test.example.org
2 |
--------------------------------------------------------------------------------
/tests/.gitignore:
--------------------------------------------------------------------------------
1 | _site
2 | .sass-cache
3 | .jekyll-cache
4 | .jekyll-metadata
5 | vendor
6 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: bundler
4 | directory: "/tests"
5 | schedule:
6 | interval: weekly
7 | open-pull-requests-limit: 10
8 |
--------------------------------------------------------------------------------
/tests/index.markdown:
--------------------------------------------------------------------------------
1 | ---
2 | # Feel free to add content and custom Front Matter to this file.
3 | # To modify the layout, see https://jekyllrb.com/docs/themes/#overriding-theme-defaults
4 |
5 | layout: home
6 | ---
7 |
--------------------------------------------------------------------------------
/deployer/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM ruby:2.6
2 | LABEL "com.github.actions.name"="Jekyll Deploy"
3 | LABEL "com.github.actions.description"="Builds and deploys a jekyll page to GitHub pages"
4 | LABEL "com.github.actions.icon"="chevrons-right"
5 | LABEL "com.github.actions.color"="gray-dark"
6 |
7 | RUN gem install bundler -v 2.1.4 \
8 | && apt update \
9 | && apt install -y git-restore-mtime \
10 | && apt clean \
11 | && rm -rf /var/lib/apt/lists/*
12 |
13 | ADD entrypoint.rb /entrypoint.rb
14 | ENTRYPOINT ["/entrypoint.rb"]
15 |
--------------------------------------------------------------------------------
/tests/404.html:
--------------------------------------------------------------------------------
1 | ---
2 | permalink: /404.html
3 | layout: default
4 | ---
5 |
6 |
19 |
20 |
21 |
404
22 |
23 |
Page not found :(
24 |
The requested page could not be found.
25 |
26 |
--------------------------------------------------------------------------------
/tests/about.markdown:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | title: About
4 | permalink: /about/
5 | ---
6 |
7 | This is the base Jekyll theme. You can find out more info about customizing your Jekyll theme, as well as basic Jekyll usage documentation at [jekyllrb.com](https://jekyllrb.com/)
8 |
9 | You can find the source code for Minima at GitHub:
10 | [jekyll][jekyll-organization] /
11 | [minima](https://github.com/jekyll/minima)
12 |
13 | You can find the source code for Jekyll at GitHub:
14 | [jekyll][jekyll-organization] /
15 | [jekyll](https://github.com/jekyll/jekyll)
16 |
17 |
18 | [jekyll-organization]: https://github.com/jekyll
19 |
--------------------------------------------------------------------------------
/.github/workflows/jekyll-test.yml:
--------------------------------------------------------------------------------
1 | name: Jekyll Test
2 |
3 | on: [ pull_request ]
4 |
5 | jobs:
6 | test:
7 | runs-on: ubuntu-latest
8 |
9 | steps:
10 | - uses: actions/checkout@v2
11 |
12 | - name: Cache gems
13 | uses: actions/cache@v1
14 | with:
15 | path: tests/vendor/gems
16 | key: ${{ runner.os }}-build-${{ hashFiles('**/Gemfile.lock') }}
17 | restore-keys: |
18 | ${{ runner.os }}-build-
19 | ${{ runner.os }}-
20 |
21 | - name: Test using current SHA
22 | uses: ./
23 | with:
24 | source-dir: tests
25 | build-only: true
26 | env:
27 | JEKYLL_ENV: production
28 |
29 | - name: Test deploy using current SHA
30 | uses: ./
31 | with:
32 | source-dir: tests
33 | target-branch: deploy
34 | env:
35 | JEKYLL_ENV: production
36 | GH_PAGES_TOKEN: ${{ secrets.GH_PAGES_TOKEN }}
37 |
--------------------------------------------------------------------------------
/.github/workflows/jekyll-deploy.yml:
--------------------------------------------------------------------------------
1 | name: Jekyll Deploy
2 |
3 | # Controls when the action will run. Triggers the workflow on push or pull request
4 | # events but only for the master branch
5 | on:
6 | push:
7 | branches:
8 | # deploy on updates on main
9 | - main
10 | schedule:
11 | # redeploy every morning to update unpublished pages
12 | - cron: "0 2 * * *"
13 |
14 | jobs:
15 | deploy:
16 | runs-on: ubuntu-latest
17 |
18 | steps:
19 | - uses: actions/checkout@v2
20 |
21 | - name: Cache gems
22 | uses: actions/cache@v1
23 | with:
24 | path: tests/vendor/gems
25 | key: ${{ runner.os }}-build-${{ hashFiles('**/Gemfile.lock') }}
26 | restore-keys: |
27 | ${{ runner.os }}-build-
28 | ${{ runner.os }}-
29 |
30 | - name: Build & Deploy to GitHub Pages
31 | uses: DavidS/jekyll-deploy@main
32 | with:
33 | source-dir: tests
34 | target-branch: deploy
35 | env:
36 | JEKYLL_ENV: production
37 | GH_PAGES_TOKEN: ${{ secrets.GH_PAGES_TOKEN }}
38 |
--------------------------------------------------------------------------------
/action.yml:
--------------------------------------------------------------------------------
1 | name: jekyll-deploy
2 | description: "Builds and deploys a jekyll page to GitHub pages"
3 | branding:
4 | icon: "chevrons-right"
5 | color: "gray-dark"
6 | runs:
7 | using: "docker"
8 | image: "deployer/Dockerfile"
9 | inputs:
10 | build-only:
11 | description: Set to "true" to only build, but not deploy. This is useful for PR testing.
12 | required: false
13 | default: "false"
14 | adjust-last-modified:
15 | description: By default this action clamps last-modified times to the date of the last commit modifying it. This reduces the amount of churn of updating timestamps in the rendered files. Set this to "false" to use the build time instead.
16 | required: false
17 | default: "true"
18 | source-dir:
19 | description: Specify a subdirectory containing the jekyll site, relative to the root of the repository. If this is not specified, the site is expected to be in the root of the repository.
20 | required: false
21 | default: .
22 | target-branch:
23 | description: Specify the branch to deploy the site to. By default, this is "gh-pages", GitHub's default branch for doc sites.
24 | required: false
25 | default: "gh-pages"
26 |
--------------------------------------------------------------------------------
/tests/Gemfile:
--------------------------------------------------------------------------------
1 | source "https://rubygems.org"
2 | # Hello! This is where you manage which Jekyll version is used to run.
3 | # When you want to use a different version, change it below, save the
4 | # file and run `bundle install`. Run Jekyll with `bundle exec`, like so:
5 | #
6 | # bundle exec jekyll serve
7 | #
8 | # This will help ensure the proper Jekyll version is running.
9 | # Happy Jekylling!
10 | gem "jekyll", "~> 4.2.0"
11 | # This is the default theme for new Jekyll sites. You may change this to anything you like.
12 | gem "minima", "~> 2.5"
13 | # If you want to use GitHub Pages, remove the "gem "jekyll"" above and
14 | # uncomment the line below. To upgrade, run `bundle update github-pages`.
15 | # gem "github-pages", group: :jekyll_plugins
16 | # If you have any plugins, put them here!
17 | group :jekyll_plugins do
18 | gem "jekyll-feed", "~> 0.15"
19 | end
20 |
21 | # Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem
22 | # and associated library.
23 | platforms :mingw, :x64_mingw, :mswin, :jruby do
24 | gem "tzinfo", "~> 1.2"
25 | gem "tzinfo-data"
26 | end
27 |
28 | # Performance-booster for watching directories on Windows
29 | gem "wdm", "~> 0.1.1", :platforms => [:mingw, :x64_mingw, :mswin]
30 |
31 |
--------------------------------------------------------------------------------
/tests/_posts/2020-08-26-welcome-to-jekyll.markdown:
--------------------------------------------------------------------------------
1 | ---
2 | layout: post
3 | title: "Welcome to Jekyll!"
4 | date: 2020-08-26 14:52:19 +0100
5 | categories: jekyll update
6 | ---
7 | You’ll find this post in your `_posts` directory. Go ahead and edit it and re-build the site to see your changes. You can rebuild the site in many different ways, but the most common way is to run `jekyll serve`, which launches a web server and auto-regenerates your site when a file is updated.
8 |
9 | Jekyll requires blog post files to be named according to the following format:
10 |
11 | `YEAR-MONTH-DAY-title.MARKUP`
12 |
13 | Where `YEAR` is a four-digit number, `MONTH` and `DAY` are both two-digit numbers, and `MARKUP` is the file extension representing the format used in the file. After that, include the necessary front matter. Take a look at the source for this post to get an idea about how it works.
14 |
15 | Jekyll also offers powerful support for code snippets:
16 |
17 | {% highlight ruby %}
18 | def print_hi(name)
19 | puts "Hi, #{name}"
20 | end
21 | print_hi('Tom')
22 | #=> prints 'Hi, Tom' to STDOUT.
23 | {% endhighlight %}
24 |
25 | Check out the [Jekyll docs][jekyll-docs] for more info on how to get the most out of Jekyll. File all bugs/feature requests at [Jekyll’s GitHub repo][jekyll-gh]. If you have questions, you can ask them on [Jekyll Talk][jekyll-talk].
26 |
27 | [jekyll-docs]: https://jekyllrb.com/docs/home
28 | [jekyll-gh]: https://github.com/jekyll/jekyll
29 | [jekyll-talk]: https://talk.jekyllrb.com/
30 |
--------------------------------------------------------------------------------
/tests/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: https://rubygems.org/
3 | specs:
4 | addressable (2.8.0)
5 | public_suffix (>= 2.0.2, < 5.0)
6 | colorator (1.1.0)
7 | concurrent-ruby (1.1.8)
8 | em-websocket (0.5.2)
9 | eventmachine (>= 0.12.9)
10 | http_parser.rb (~> 0.6.0)
11 | eventmachine (1.2.7)
12 | ffi (1.15.0)
13 | forwardable-extended (2.6.0)
14 | http_parser.rb (0.6.0)
15 | i18n (1.8.10)
16 | concurrent-ruby (~> 1.0)
17 | jekyll (4.2.0)
18 | addressable (~> 2.4)
19 | colorator (~> 1.0)
20 | em-websocket (~> 0.5)
21 | i18n (~> 1.0)
22 | jekyll-sass-converter (~> 2.0)
23 | jekyll-watch (~> 2.0)
24 | kramdown (~> 2.3)
25 | kramdown-parser-gfm (~> 1.0)
26 | liquid (~> 4.0)
27 | mercenary (~> 0.4.0)
28 | pathutil (~> 0.9)
29 | rouge (~> 3.0)
30 | safe_yaml (~> 1.0)
31 | terminal-table (~> 2.0)
32 | jekyll-feed (0.15.1)
33 | jekyll (>= 3.7, < 5.0)
34 | jekyll-sass-converter (2.1.0)
35 | sassc (> 2.0.1, < 3.0)
36 | jekyll-seo-tag (2.6.1)
37 | jekyll (>= 3.3, < 5.0)
38 | jekyll-watch (2.2.1)
39 | listen (~> 3.0)
40 | kramdown (2.3.1)
41 | rexml
42 | kramdown-parser-gfm (1.1.0)
43 | kramdown (~> 2.0)
44 | liquid (4.0.3)
45 | listen (3.5.1)
46 | rb-fsevent (~> 0.10, >= 0.10.3)
47 | rb-inotify (~> 0.9, >= 0.9.10)
48 | mercenary (0.4.0)
49 | minima (2.5.1)
50 | jekyll (>= 3.5, < 5.0)
51 | jekyll-feed (~> 0.9)
52 | jekyll-seo-tag (~> 2.1)
53 | pathutil (0.16.2)
54 | forwardable-extended (~> 2.6)
55 | public_suffix (4.0.6)
56 | rb-fsevent (0.10.4)
57 | rb-inotify (0.10.1)
58 | ffi (~> 1.0)
59 | rexml (3.2.5)
60 | rouge (3.26.0)
61 | safe_yaml (1.0.5)
62 | sassc (2.4.0)
63 | ffi (~> 1.9)
64 | terminal-table (2.0.0)
65 | unicode-display_width (~> 1.1, >= 1.1.1)
66 | unicode-display_width (1.7.0)
67 |
68 | PLATFORMS
69 | ruby
70 |
71 | DEPENDENCIES
72 | jekyll (~> 4.2.0)
73 | jekyll-feed (~> 0.15)
74 | minima (~> 2.5)
75 | tzinfo (~> 1.2)
76 | tzinfo-data
77 | wdm (~> 0.1.1)
78 |
79 | BUNDLED WITH
80 | 2.1.4
81 |
--------------------------------------------------------------------------------
/tests/_config.yml:
--------------------------------------------------------------------------------
1 | # Welcome to Jekyll!
2 | #
3 | # This config file is meant for settings that affect your whole blog, values
4 | # which you are expected to set up once and rarely edit after that. If you find
5 | # yourself editing this file very often, consider using Jekyll's data files
6 | # feature for the data you need to update frequently.
7 | #
8 | # For technical reasons, this file is *NOT* reloaded automatically when you use
9 | # 'bundle exec jekyll serve'. If you change this file, please restart the server process.
10 | #
11 | # If you need help with YAML syntax, here are some quick references for you:
12 | # https://learn-the-web.algonquindesign.ca/topics/markdown-yaml-cheat-sheet/#yaml
13 | # https://learnxinyminutes.com/docs/yaml/
14 | #
15 | # Site settings
16 | # These are used to personalize your new site. If you look in the HTML files,
17 | # you will see them accessed via {{ site.title }}, {{ site.email }}, and so on.
18 | # You can create any custom variable you would like, and they will be accessible
19 | # in the templates via {{ site.myvariable }}.
20 |
21 | title: Your awesome title
22 | email: your-email@example.com
23 | description: >- # this means to ignore newlines until "baseurl:"
24 | Write an awesome description for your new site here. You can edit this
25 | line in _config.yml. It will appear in your document head meta (for
26 | Google search results) and in your feed.xml site description.
27 | baseurl: "" # the subpath of your site, e.g. /blog
28 | url: "" # the base hostname & protocol for your site, e.g. http://example.com
29 | twitter_username: jekyllrb
30 | github_username: jekyll
31 |
32 | # Build settings
33 | theme: minima
34 | plugins:
35 | - jekyll-feed
36 |
37 | # Exclude from processing.
38 | # The following items will not be processed, by default.
39 | # Any item listed under the `exclude:` key here will be automatically added to
40 | # the internal "default list".
41 | #
42 | # Excluded items can be processed by explicitly listing the directories or
43 | # their entries' file path in the `include:` list.
44 | #
45 | # exclude:
46 | # - .sass-cache/
47 | # - .jekyll-cache/
48 | # - gemfiles/
49 | # - Gemfile
50 | # - Gemfile.lock
51 | # - node_modules/
52 | # - vendor/bundle/
53 | # - vendor/cache/
54 | # - vendor/gems/
55 | # - vendor/ruby/
56 |
--------------------------------------------------------------------------------
/deployer/entrypoint.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | require 'English'
5 | require 'fileutils'
6 |
7 | def system_or_fail(*cmd)
8 | puts "executing #{cmd.inspect}"
9 | if system(*cmd)
10 | puts "executed #{cmd.inspect} successfully"
11 | else
12 | puts "execution failed with '#{$CHILD_STATUS}'"
13 | exit $CHILD_STATUS.exitstatus
14 | end
15 | end
16 |
17 | basedir = Dir.pwd
18 |
19 | if ENV['INPUT_ADJUST-LAST-MODIFIED'] == "true"
20 | # help jekyll with stable last modified times to avoid churning timestamps
21 | puts "Adjusting mtime/last modified times"
22 | system_or_fail('git', 'restore-mtime', '--merge', ENV['INPUT_SOURCE-DIR'])
23 | else
24 | puts "Adjusting mtime/last modified times disabled in config"
25 | end
26 |
27 | Dir.chdir(ENV['INPUT_SOURCE-DIR'])
28 | sourcedir = Dir.pwd
29 |
30 | system_or_fail('bundle', 'config', 'set', 'path', 'vendor/gems')
31 | system_or_fail('bundle', 'config', 'set', 'deployment', 'true')
32 | system_or_fail('bundle', 'install', '--jobs=4', '--retry=3')
33 |
34 | if ENV['INPUT_BUILD-ONLY'] == "true"
35 | system_or_fail('bundle', 'exec', 'jekyll', 'build', '--future', '--verbose', '--trace')
36 | exit
37 | else
38 | system_or_fail('bundle', 'exec', 'jekyll', 'build', '--verbose', '--trace')
39 | end
40 |
41 | Dir.chdir('_site')
42 | File.open('.nojekyll', 'w') { |f| f.puts 'Skip Jekyll' }
43 |
44 | system_or_fail('git', 'init', '.')
45 | FileUtils.cp(File.join(basedir, '/.git/config'), '.git/config')
46 | system_or_fail('git', 'config', 'user.name', ENV['GITHUB_ACTOR'])
47 | system_or_fail('git', 'config', 'user.email', "#{ENV['GITHUB_ACTOR']}@users.noreply.github.com")
48 | system_or_fail('git', 'fetch', '--no-tags', '--no-recurse-submodules', 'origin', "+#{ENV['GITHUB_SHA']}:refs/remotes/origin/source")
49 | if %x(git ls-remote --heads origin) =~ %r{\trefs/heads/#{ENV['INPUT_TARGET-BRANCH']}\n}
50 | puts "Found target branch '#{ENV['INPUT_TARGET-BRANCH']}', using that as base"
51 | system_or_fail('git', 'fetch', '--no-tags', '--no-recurse-submodules', 'origin', "+#{ENV['INPUT_TARGET-BRANCH']}:refs/remotes/origin/#{ENV['INPUT_TARGET-BRANCH']}")
52 | system_or_fail('git', 'reset', '--soft', "origin/#{ENV['INPUT_TARGET-BRANCH']}")
53 | else
54 | puts "Didn't find target branch '#{ENV['INPUT_TARGET-BRANCH']}', using the source as a base"
55 | system_or_fail('git', 'reset', '--soft', "origin/source")
56 | end
57 |
58 | if File.exist?(File.join(sourcedir, 'CNAME')) && !File.exist?('CNAME')
59 | puts "Rendering github's CNAME file"
60 | FileUtils.cp(File.join(sourcedir, 'CNAME'), 'CNAME')
61 | end
62 |
63 | system_or_fail('git', 'add', '-A', '.')
64 | system_or_fail('git', 'commit', '-m', 'Update github pages')
65 | system_or_fail('git', 'merge', '-s', 'ours', 'origin/source')
66 | system_or_fail('git', 'push', 'origin', "HEAD:#{ENV['INPUT_TARGET-BRANCH']}")
67 |
68 | puts "triggering a github pages deploy"
69 |
70 | require 'net/http'
71 | result = Net::HTTP.post(
72 | URI("https://api.github.com/repos/#{ENV['GITHUB_REPOSITORY']}/pages/builds"),
73 | "",
74 | "Content-Type" => "application/json",
75 | "Authorization" => "token #{ENV['GH_PAGES_TOKEN']}",
76 | )
77 |
78 | puts result.body
79 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # jekyll-deploy
2 |
3 | Builds and deploys a jekyll page to GitHub pages.
4 |
5 | Features:
6 | * build and test modes
7 | * record the site's source commit using a merge commit
8 | * build from any subdirectory in your repository
9 | * specify a target branch
10 |
11 | ## Usage
12 |
13 | To deploy every update to the `main` branch and regenerate the site once a day:
14 |
15 | ```yaml
16 | name: Jekyll Deploy
17 |
18 | on:
19 | push:
20 | branches:
21 | # deploy on updates on main
22 | - main
23 | schedule:
24 | # redeploy every morning to update unpublished pages
25 | - cron: "0 2 * * *"
26 |
27 | jobs:
28 | deploy:
29 | runs-on: ubuntu-latest
30 |
31 | steps:
32 | - uses: actions/checkout@v2
33 |
34 | - name: Cache gems
35 | uses: actions/cache@v1
36 | with:
37 | path: vendor/gems
38 | key: ${{ runner.os }}-build-${{ hashFiles('**/Gemfile.lock') }}
39 | restore-keys: |
40 | ${{ runner.os }}-build-
41 | ${{ runner.os }}-
42 |
43 | - name: Build & Deploy to GitHub Pages
44 | uses: DavidS/jekyll-deploy@main
45 | env:
46 | JEKYLL_ENV: production
47 | GH_PAGES_TOKEN: ${{ secrets.GH_PAGES_TOKEN }}
48 | ```
49 |
50 | To check PRs, set `build-only: true`:
51 |
52 | ```yaml
53 | name: Jekyll Test
54 |
55 | on: [ pull_request ]
56 |
57 | jobs:
58 | test:
59 | runs-on: ubuntu-latest
60 |
61 | steps:
62 | - uses: actions/checkout@v2
63 |
64 | - name: Cache gems
65 | uses: actions/cache@v1
66 | with:
67 | path: vendor/gems
68 | key: ${{ runner.os }}-build-${{ hashFiles('**/Gemfile.lock') }}
69 | restore-keys: |
70 | ${{ runner.os }}-build-
71 | ${{ runner.os }}-
72 |
73 | - name: Test
74 | uses: DavidS/jekyll-deploy@
75 | with:
76 | build-only: true
77 | env:
78 | JEKYLL_ENV: production
79 | GH_PAGES_TOKEN: ${{ secrets.GH_PAGES_TOKEN }}
80 | ```
81 |
82 | The `GH_PAGES_TOKEN` needs the `public_repo` scope to be able to trigger deployments on a public repo or the full `repo` scope to deploy a private repository. Please note that this is circumventing GitHub's protection for infinitely recursive Actions invocations, so proceed with caution!
83 |
84 | ## Specifying a source directory
85 |
86 | If your site's source is not at the root of the repository, you can use the `source-dir` input to tell this action where the source can be found. For example, if your site is in a `docs/jekyll` subdirectory:
87 |
88 | ```yaml
89 | - name: Build & Deploy to custom branch
90 | uses: DavidS/jekyll-deploy@
91 | with:
92 | source-dir: docs/jekyll
93 | env:
94 | JEKYLL_ENV: production
95 | GH_PAGES_TOKEN: ${{ secrets.GH_PAGES_TOKEN }}
96 | ```
97 |
98 |
99 | ## Specifying a target branch
100 |
101 | By default, this action deploys the compiled output to `gh-pages`, GitHub's default. If you want to use a different branch, you can use the `target-branch` input to do so. For example, to deploy to `docs`:
102 |
103 | ```yaml
104 | - name: Build & Deploy to custom branch
105 | uses: DavidS/jekyll-deploy@main
106 | with:
107 | target-branch: docs
108 | env:
109 | JEKYLL_ENV: production
110 | GH_PAGES_TOKEN: ${{ secrets.GH_PAGES_TOKEN }}
111 | ```
112 |
--------------------------------------------------------------------------------