Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions .github/workflows/build-jekyll.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: Build and Deploy
on:
pull_request:
branches:
- gh-pages
- 2025-redesign # TODO: Remove before merge
- 2025-build-changes # TODO: Remove before merge
push:
branches:
- gh-pages
- 2025-redesign # TODO: Remove before merge
- 2025-build-changes # TODO: Remove before merge
workflow_dispatch:

# Prevent concurrent deploys
concurrency:
group: "pages"

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Setup ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.4'
bundler-cache: true
- name: Setup node
uses: bahmutov/npm-install@v1
- name: Setup pages
id: pages
uses: actions/configure-pages@v5
- name: Build Jekyll
run: bundle exec jekyll build --baseurl "${{ steps.pages.outputs.base_path }}" --profile
env:
JEKYLL_ENV: production
RUBYOPT: --yjit
- name: Upload
uses: actions/upload-pages-artifact@v4
deploy:
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
needs: build
permissions:
pages: write
id-token: write
# Only deploy on push, merge or manual
if: "github.event_name != 'pull_request'"
steps:
- name: Deploy
id: deployment
uses: actions/deploy-pages@v4
2 changes: 1 addition & 1 deletion .github/workflows/check-a11y-of-changed-content.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 2.3
ruby-version: 3.4

- name: Install gems
run: bundle config path vendor/bundle && bundle install
Expand Down
2 changes: 0 additions & 2 deletions .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ name: Lint Posts

on:
pull_request:
branches:
- 'gh-pages' # Runs when a PR targets the gh-pages branch

jobs:
lint-posts:
Expand Down
23 changes: 5 additions & 18 deletions .pa11yci.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,20 @@
/// This is a configuration file automatically picked up by pa11y-ci.

const relativeUrls = require('./pa11y-ci-urls');
const relativeUrls = require("./pa11y-ci-urls");

const chromiumBin = process.env.CHROMIUM_BIN;
if (!chromiumBin) {
throw new Error('CHROMIUM_BIN environment variable is not set');
}

const baseUrl = 'http://localhost:4000';
const baseUrl = "http://localhost:4000";

// Colour contrast is a known issue. If we ever fix the brand colours, this should be removed.
const colourContrastRuleIds = [
// HTML CodeSniffer rule IDs come from section 1.4.3 of:
// https://squizlabs.github.io/HTML_CodeSniffer/Standards/WCAG2/
'WCAG2AA.Principle1.Guideline1_4.1_4_3.G18.Fail', // normal text
'WCAG2AA.Principle1.Guideline1_4.1_4_3.G145.Fail', // large text
"WCAG2AA.Principle1.Guideline1_4.1_4_3.G18.Fail", // normal text
"WCAG2AA.Principle1.Guideline1_4.1_4_3.G145.Fail", // large text
];

module.exports = {
defaults: {
chromeLaunchConfig: {
executablePath: chromiumBin,
"args": ["--no-sandbox"],
},
ignore: [
...colourContrastRuleIds,
],
reporter: 'cli',
runners: ['htmlcs'],
ignore: [...colourContrastRuleIds],
},
urls: relativeUrls.map((url) => `${baseUrl}${url}`),
};
12 changes: 12 additions & 0 deletions .prettierrc.json5
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
plugins: ["@shopify/prettier-plugin-liquid"],
overrides: [
// Treat all html as liquid html
{
"files": "*.html",
"options": {
parser: "liquid-html"
}
}
]
}
49 changes: 42 additions & 7 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -1,12 +1,47 @@
source 'http://rubygems.org'
gem 'github-pages'
ruby '~> 3.3'

gem "jekyll", "~> 4"
group :jekyll_plugins do
# Deps from EOL github-pages gem minus themes
gem "jekyll-avatar"
gem "jekyll-commonmark"
gem "jekyll-default-layout"
gem "jekyll-feed"
gem "jekyll-gist"
gem "jekyll-github-metadata"
gem "jekyll-include-cache"
gem "jekyll-mentions"
gem "jekyll-optional-front-matter"
gem "jekyll-readme-index"
gem "jekyll-redirect-from"
gem "jekyll-relative-links"
gem "jekyll-remote-theme"
gem "jekyll-sass-converter"
gem "jekyll-seo-tag"
gem "jekyll-sitemap"
gem "jekyll-swiss"
gem "jekyll-titles-from-headings"
gem "jemoji"
gem "kramdown"
gem "kramdown-parser-gfm"
gem "liquid"
gem "mercenary"
gem "minima"
gem "nokogiri"
gem "rouge"
gem "terminal-table"
gem "webrick", "~> 1.7"

gem "tzinfo-data", "~> 1.2022"
gem 'jekyll-paginate'

gem "webrick", "~> 1.7"
gem "tzinfo-data", "~> 1.2022"

# Issue with ffi requiring a very recent rubygems version, not yet available
# in many current linux docker images, so this must be locked down for now.
# See https://github.com/ffi/ffi/issues/1103
gem "ffi", "< 1.17.0"
gem "html-minify", "1.0.0", path: "gems/html-minify-gem"
gem "hook-exec", "1.0.0", path: "gems/hook-exec-gem"

# Issue with ffi requiring a very recent rubygems version, not yet available
# in many current linux docker images, so this must be locked down for now.
# See https://github.com/ffi/ffi/issues/1103
gem "ffi", "< 1.17.0"
end
91 changes: 91 additions & 0 deletions README-DEV.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Blog Development
Useful things for working the blog itself (not blog posts).

## Setup
See [README.md](README.md).
It has everything needed to get the blog up and running.

## HTML
Base layouts must be in `_layouts` and components must be in `_includes`.
Within components, prefer passing variables in using `{%- include foo.html bar=baz -%}` rather than using the page
context.
This allows for includes to be cached using `{%- include_cached ... -%}` if they begin to consume too much build time.

A few custom filters are provided by the `custom-filters` plugin:
- `starts_with` - returns true if the given string starts with a given string
- `"https://example.com" | starts_with: "https"` resolves to `true`
- `"ftp://example.com" | starts_with: "https"` resolves to `false`
- `nil | starts_with: "https:"` resolves to `false`
- `ends_with` - returns true if the given string ends with a given string
- `"foo.html" | ends_with: "html"` resolves to `true`
- `"foo.scss" | ends_with: "html"` resolves to `false`
- `nil | ends_with: "html"` resolves to `false`

## Styles
Blog stylesheets must be in `scss/`, be a partial stylesheet (be prefixed with an `_`) and `@use`'d by either
`assets/style.scss` or a stylesheet already `@use`'d by `assets/style.scss`.

For example, the styles related to the author list are in `scss/_author-list.scss`, which is `@use`d by
`assets/style.scss`, but `scss/_colours.scss` isn't `@use`'d by `assets/style.scss`.
Rather `_colours` is `@use`d by other stylesheets such as `_author-list.scss`.

Avoid deprecated SCSS features like `@import` where possible.
If it cannot be avoided, include a comment with the reason why.
For example `_util.scss` uses `@import` because the foundations framework still requires it.

All stylesheets reachable from `assets/style.scss` are compiled and minified into `_site/assets/style.css` as part of
the build process, using Jekyll's builtin SCSS support.

## Scripts
Blog scripts should be in `scripts/` and preferably be TypeScript (type safety is king).
Where possible, try and import new scripts into `scripts/index.ts`.
If this isn't possible, add the new script to `rspack.config.ts`'s `entry.page` array.

The scripts are compiled, concatenated and minified using a custom build hook that triggers `rspack build`.

## Build Hook
To aid in development, arbitrary commands can be run at different Jekyll hooks by adding entries to `_config.yml`'s
`hook_exec` entry.

Each entry has the following structure:
```yaml
hook_exec:
owner:
event:
name:
cmd: string
env: optional map
priority: optional int
```
where:
- `owner` and `event` are from the list in the [Jekyll docs](https://jekyllrb.com/docs/plugins/hooks/#built-in-hook-owners-and-events)
with the `:` removed.
- `name` is a useful identifier for logging
- `cmd` is the command to run
- The value is treated as a [liquid template](https://shopify.github.io/liquid/)
- `env` is a map of environment variables
- Values in the map are treated as [liquid template](https://shopify.github.io/liquid/)
- `priority` is the priority of the hook with higher values being run first

Liquid templates have access to the following variables, depending on which hook they are running in:
- `site` - hooks with `:site` owner
- Same as the `site` object in normal templates
- `doc` - hooks with `:document` owner
- [Jekyll document](https://github.com/jekyll/jekyll/blob/master/lib/jekyll/document.rb)
- `page` - hooks with `:pages` owner
- Same as the `page` object in normal template
- `payload` - hooks with either the `:pre_render` or `:post_render` event
- a hash containing variables to be used during rendering (`:pre_render`) or their final values after rendering
(`:post_render`)
- `files` - hooks with `:clean` owner
- list of [files](https://ruby-doc.org/3.4.1/File.html) to be deleted

For example, the `:site` `:pre_render` hook has the `site` and `payload` variables.

These templates do not have access to [Jekyll specific filters and tags](https://jekyllrb.com/docs/liquid/).

If a command produces a file in `_site`, it must be added to `_config.yml`'s `keep_file` list to prevent Jekyll from
removing it as part of the build.

This is primarily used to invoke external build commands.
Anything more complicated should be implemented as a custom plugin, similar to the `html-minify` plugin.
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,11 +152,15 @@ The blog will then be available on [localhost][localhost].
If you are working on fixes or new features, and need to re-compile the scripts or SCSS, you can use these npm scripts:

```shell
npm ci
npm run scripts
npm run style
npm ci # Install deps
npm run prettier # Format non-post files
```

##### Useful Options for Jekyll
* `--livereload` - trigger a build on file change (excluding SCSS or JS) and refresh the browser once built
* `--incremental` - use the experimental incremental build mode which after the initial build, only builds changed files
* `RUBYOPT="--yjit"` - let ruby use its JIT (only macOS, Linux and BSD on x86-64 and arm64/aarch64 CPUs are supported)

### Running with Docker

Use a bash-compatible shell; Git bash on Windows should work fine.
Expand Down
75 changes: 51 additions & 24 deletions _config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,17 @@ collections:
title: Uploads
output: true
defaults:
- scope:
path: ''
type: posts
values:
summary: a quick summary of your post
author: the name of the authers account
layout: default_post
- scope:
path: ""
type: posts
values:
summary: a quick summary of your post
author: the name of the authors account
layout: default_post
repository: ScottLogic/blog
name: Scott Logic
description: This feed is brought to you by Scott Logic's team of technical authors
description:
This feed is brought to you by Scott Logic's team of technical authors
and bloggers, covering topics including HTML5, iOS, C#, process, UX and practically
anything else relating to software development.
canonical:
Expand All @@ -34,23 +35,49 @@ permalink: "/:year/:month/:day/:title.html"
safe: true
twitter_handle: Scott_Logic
plugins:
- jekyll-redirect-from
- jekyll-redirect-from
- jekyll-paginate
- jekyll-include-cache
kramdown:
input: kramdown
paginate: 20
excerpt_separator:
excerpt_separator: <!-- end_excerpt -->
exclude:
- CNAME
- Gemfile
- Gemfile.lock
- lintPosts.js
- scss
- node_modules
- package.json
- README.md
- ".spelling"
- scripts/jquery-1.9.1.js
- scripts/jquery.jscroll-2.2.4.js
- scripts/tweet.js
- scripts/search.js
- vendor
- ".idea"
- ".prettierrc.json5"
- ".spelling"
- CNAME
- Gemfile
- Gemfile.lock
- PULL_REQUEST_TEMPLATE
- README.md
- README-DEV.md
- gems
- generate_pa11y_ci_urls_from_git_diff.sh
- lintPosts.js
- node_modules
- package-lock.json
- package.json
- rspack.config.ts
- scripts
- scss
- send-blogs-to-deploy-endpoint.js
- tsconfig.json
- vendor
keep_files:
- "script.js"
sass:
style: compressed
sourcemap: development
sass_dir: scss
quiet_deps: true
load_paths:
- "node_modules/applause-button/dist/"
- "node_modules/cookieconsent/build/"
hook_exec:
site:
post_write:
bundle-js:
env:
BASE_URL: "{{ site.baseurl }}"
cmd: "./node_modules/.bin/rspack build"
Loading