diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..badbc02 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +_site +.sass-cache diff --git a/404.html b/404.html new file mode 100644 index 0000000..bb6df78 --- /dev/null +++ b/404.html @@ -0,0 +1,15 @@ +--- +layout: site +title: Page not found +description: The requested page could not be found. +permalink: /404.html +--- + +
+

404

+

Page not found

+

+ If you expected this page to exist, please + file an issue. +

+
diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..5a22c9d --- /dev/null +++ b/Gemfile @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +git_source(:github) {|repo_name| "https://github.com/#{repo_name}" } + +# gem "rails" + +gem "github-pages", "= 232" +gem "nokogiri", "= 1.16.7" diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..807875c --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,288 @@ +GEM + remote: https://rubygems.org/ + specs: + activesupport (8.1.3) + base64 + bigdecimal + concurrent-ruby (~> 1.0, >= 1.3.1) + connection_pool (>= 2.2.5) + drb + i18n (>= 1.6, < 2) + json + logger (>= 1.4.2) + minitest (>= 5.1) + securerandom (>= 0.3) + tzinfo (~> 2.0, >= 2.0.5) + uri (>= 0.13.1) + addressable (2.9.0) + public_suffix (>= 2.0.2, < 8.0) + base64 (0.3.0) + bigdecimal (4.1.2) + coffee-script (2.4.1) + coffee-script-source + execjs + coffee-script-source (1.12.2) + colorator (1.1.0) + commonmarker (0.23.12) + concurrent-ruby (1.3.6) + connection_pool (3.0.2) + csv (3.3.5) + dnsruby (1.73.1) + base64 (>= 0.2) + logger (~> 1.6) + simpleidn (~> 0.2.1) + drb (2.2.3) + em-websocket (0.5.3) + eventmachine (>= 0.12.9) + http_parser.rb (~> 0) + ethon (0.18.0) + ffi (>= 1.15.0) + logger + eventmachine (1.2.7) + execjs (2.10.1) + faraday (2.14.2) + faraday-net_http (>= 2.0, < 3.5) + json + logger + faraday-net_http (3.4.4) + net-http (~> 0.5) + ffi (1.17.4) + forwardable-extended (2.6.0) + gemoji (4.1.0) + github-pages (232) + github-pages-health-check (= 1.18.2) + jekyll (= 3.10.0) + jekyll-avatar (= 0.8.0) + jekyll-coffeescript (= 1.2.2) + jekyll-commonmark-ghpages (= 0.5.1) + jekyll-default-layout (= 0.1.5) + jekyll-feed (= 0.17.0) + jekyll-gist (= 1.5.0) + jekyll-github-metadata (= 2.16.1) + jekyll-include-cache (= 0.2.1) + jekyll-mentions (= 1.6.0) + jekyll-optional-front-matter (= 0.3.2) + jekyll-paginate (= 1.1.0) + jekyll-readme-index (= 0.3.0) + jekyll-redirect-from (= 0.16.0) + jekyll-relative-links (= 0.6.1) + jekyll-remote-theme (= 0.4.3) + jekyll-sass-converter (= 1.5.2) + jekyll-seo-tag (= 2.8.0) + jekyll-sitemap (= 1.4.0) + jekyll-swiss (= 1.0.0) + jekyll-theme-architect (= 0.2.0) + jekyll-theme-cayman (= 0.2.0) + jekyll-theme-dinky (= 0.2.0) + jekyll-theme-hacker (= 0.2.0) + jekyll-theme-leap-day (= 0.2.0) + jekyll-theme-merlot (= 0.2.0) + jekyll-theme-midnight (= 0.2.0) + jekyll-theme-minimal (= 0.2.0) + jekyll-theme-modernist (= 0.2.0) + jekyll-theme-primer (= 0.6.0) + jekyll-theme-slate (= 0.2.0) + jekyll-theme-tactile (= 0.2.0) + jekyll-theme-time-machine (= 0.2.0) + jekyll-titles-from-headings (= 0.5.3) + jemoji (= 0.13.0) + kramdown (= 2.4.0) + kramdown-parser-gfm (= 1.1.0) + liquid (= 4.0.4) + mercenary (~> 0.3) + minima (= 2.5.1) + nokogiri (>= 1.16.2, < 2.0) + rouge (= 3.30.0) + terminal-table (~> 1.4) + webrick (~> 1.8) + github-pages-health-check (1.18.2) + addressable (~> 2.3) + dnsruby (~> 1.60) + octokit (>= 4, < 8) + public_suffix (>= 3.0, < 6.0) + typhoeus (~> 1.3) + html-pipeline (2.14.3) + activesupport (>= 2) + nokogiri (>= 1.4) + http_parser.rb (0.8.1) + i18n (1.14.8) + concurrent-ruby (~> 1.0) + jekyll (3.10.0) + addressable (~> 2.4) + colorator (~> 1.0) + csv (~> 3.0) + em-websocket (~> 0.5) + i18n (>= 0.7, < 2) + jekyll-sass-converter (~> 1.0) + jekyll-watch (~> 2.0) + kramdown (>= 1.17, < 3) + liquid (~> 4.0) + mercenary (~> 0.3.3) + pathutil (~> 0.9) + rouge (>= 1.7, < 4) + safe_yaml (~> 1.0) + webrick (>= 1.0) + jekyll-avatar (0.8.0) + jekyll (>= 3.0, < 5.0) + jekyll-coffeescript (1.2.2) + coffee-script (~> 2.2) + coffee-script-source (~> 1.12) + jekyll-commonmark (1.4.0) + commonmarker (~> 0.22) + jekyll-commonmark-ghpages (0.5.1) + commonmarker (>= 0.23.7, < 1.1.0) + jekyll (>= 3.9, < 4.0) + jekyll-commonmark (~> 1.4.0) + rouge (>= 2.0, < 5.0) + jekyll-default-layout (0.1.5) + jekyll (>= 3.0, < 5.0) + jekyll-feed (0.17.0) + jekyll (>= 3.7, < 5.0) + jekyll-gist (1.5.0) + octokit (~> 4.2) + jekyll-github-metadata (2.16.1) + jekyll (>= 3.4, < 5.0) + octokit (>= 4, < 7, != 4.4.0) + jekyll-include-cache (0.2.1) + jekyll (>= 3.7, < 5.0) + jekyll-mentions (1.6.0) + html-pipeline (~> 2.3) + jekyll (>= 3.7, < 5.0) + jekyll-optional-front-matter (0.3.2) + jekyll (>= 3.0, < 5.0) + jekyll-paginate (1.1.0) + jekyll-readme-index (0.3.0) + jekyll (>= 3.0, < 5.0) + jekyll-redirect-from (0.16.0) + jekyll (>= 3.3, < 5.0) + jekyll-relative-links (0.6.1) + jekyll (>= 3.3, < 5.0) + jekyll-remote-theme (0.4.3) + addressable (~> 2.0) + jekyll (>= 3.5, < 5.0) + jekyll-sass-converter (>= 1.0, <= 3.0.0, != 2.0.0) + rubyzip (>= 1.3.0, < 3.0) + jekyll-sass-converter (1.5.2) + sass (~> 3.4) + jekyll-seo-tag (2.8.0) + jekyll (>= 3.8, < 5.0) + jekyll-sitemap (1.4.0) + jekyll (>= 3.7, < 5.0) + jekyll-swiss (1.0.0) + jekyll-theme-architect (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-cayman (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-dinky (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-hacker (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-leap-day (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-merlot (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-midnight (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-minimal (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-modernist (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-primer (0.6.0) + jekyll (> 3.5, < 5.0) + jekyll-github-metadata (~> 2.9) + jekyll-seo-tag (~> 2.0) + jekyll-theme-slate (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-tactile (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-time-machine (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-titles-from-headings (0.5.3) + jekyll (>= 3.3, < 5.0) + jekyll-watch (2.2.1) + listen (~> 3.0) + jemoji (0.13.0) + gemoji (>= 3, < 5) + html-pipeline (~> 2.2) + jekyll (>= 3.0, < 5.0) + json (2.19.8) + kramdown (2.4.0) + rexml + kramdown-parser-gfm (1.1.0) + kramdown (~> 2.0) + liquid (4.0.4) + listen (3.10.0) + logger + rb-fsevent (~> 0.10, >= 0.10.3) + rb-inotify (~> 0.9, >= 0.9.10) + logger (1.7.0) + mercenary (0.3.6) + mini_portile2 (2.8.9) + minima (2.5.1) + jekyll (>= 3.5, < 5.0) + jekyll-feed (~> 0.9) + jekyll-seo-tag (~> 2.1) + minitest (6.0.6) + drb (~> 2.0) + prism (~> 1.5) + net-http (0.9.1) + uri (>= 0.11.1) + nokogiri (1.16.7) + mini_portile2 (~> 2.8.2) + racc (~> 1.4) + octokit (4.25.1) + faraday (>= 1, < 3) + sawyer (~> 0.9) + pathutil (0.16.2) + forwardable-extended (~> 2.6) + prism (1.9.0) + public_suffix (5.1.1) + racc (1.8.1) + rb-fsevent (0.11.2) + rb-inotify (0.11.1) + ffi (~> 1.0) + rexml (3.4.4) + rouge (3.30.0) + rubyzip (2.4.1) + safe_yaml (1.0.5) + sass (3.7.4) + sass-listen (~> 4.0.0) + sass-listen (4.0.0) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) + sawyer (0.9.3) + addressable (>= 2.3.5) + faraday (>= 0.17.3, < 3) + securerandom (0.4.1) + simpleidn (0.2.3) + terminal-table (1.8.0) + unicode-display_width (~> 1.1, >= 1.1.1) + typhoeus (1.6.0) + ethon (>= 0.18.0) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) + unicode-display_width (1.8.0) + uri (1.1.1) + webrick (1.9.2) + +PLATFORMS + ruby + +DEPENDENCIES + github-pages (= 232) + nokogiri (= 1.16.7) + +BUNDLED WITH + 2.5.23 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..8e64801 --- /dev/null +++ b/Makefile @@ -0,0 +1,7 @@ +.PHONY: build serve + +build: + ./scripts/pages-build + +serve: + ./scripts/pages-serve diff --git a/README.md b/README.md index 636e0d8..8031dbe 100644 --- a/README.md +++ b/README.md @@ -1 +1,22 @@ # Website for the CMRCS group + +## Local development + +The GitHub Actions workflow builds this site with the official Pages Jekyll +Docker action image. Use the same image locally to avoid host Ruby/Bundler +version mismatches: + +```sh +make build +make serve +``` + +This will rebuild the site, then serves `_site` at `http://localhost:4000`. + +Useful overrides: + +```sh +PAGES_PORT=5000 scripts/pages-serve +PAGES_DESTINATION=./_site-preview scripts/pages-build +PAGES_JEKYLL_IMAGE=ghcr.io/actions/jekyll-build-pages:v1.0.13 scripts/pages-build +``` diff --git a/_config.yml b/_config.yml new file mode 100644 index 0000000..8bef2b3 --- /dev/null +++ b/_config.yml @@ -0,0 +1,26 @@ +# Static configuration for the site +# +# Values in this file are meant to be constant and rarely edited. +# These parameters can be accessed in HTML via `{{ site.title }}` etc. +# Changes to this file are NOT automatically picked up by `jekyll serve`. + +# Site settings +title: CMRCS +description: > + Cardiovascular Magnetic Resonance Computational Simulations +footer: > + CMRCS ยท Cardiovascular MR Computational Simulations + +# Hosting settings +url: https://cmrcs.org + +# Build settings +markdown: kramdown +theme: minima + +exclude: + - Gemfile + - Gemfile.lock + - Makefile + - README.md + - scripts diff --git a/_layouts/home.html b/_layouts/home.html new file mode 100644 index 0000000..6d2796e --- /dev/null +++ b/_layouts/home.html @@ -0,0 +1,37 @@ +--- +layout: site +--- + +
+
+ Computational cardiac MRI simulation visualization with microstructure and random-walk diffusion overlays +
+

Computational cardiac imaging

+

Cardiovascular MR Computational Simulations

+

+ We develop computational models, image analysis methods, and simulation workflows for cardiovascular magnetic resonance research. +

+ +
+
+
+ +
+
+
+ Histology-informed models + Simulating realistic microstructures based on histology to understand the relationship between pathology and signal. +
+
+ Simulation frameworks + Building robust and fast numerical methods that can efficiently solve physics. +
+
+
+ +
+ {{ content }} +
diff --git a/_layouts/site.html b/_layouts/site.html new file mode 100644 index 0000000..330957a --- /dev/null +++ b/_layouts/site.html @@ -0,0 +1,30 @@ + + + + + + + {{ page.title }} | {{ site.title }} + + + + + +
+ {{ content }} +
+ + + + diff --git a/assets/css/site.css b/assets/css/site.css new file mode 100644 index 0000000..5fd445a --- /dev/null +++ b/assets/css/site.css @@ -0,0 +1,423 @@ +:root { + --ink: #17202a; + --muted: #5e6b78; + --line: #d9e1e8; + --paper: #f8fafb; + --panel: #ffffff; + --teal: #007d8a; + --red: #bd3f32; + --gold: #c39130; +} + +* { + box-sizing: border-box; +} + +body { + margin: 0; + background: var(--paper); + color: var(--ink); + font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; + line-height: 1.55; +} + +a { + color: inherit; +} + +.site-header { + border-bottom: 1px solid rgba(23, 32, 42, 0.12); + background: rgba(248, 250, 251, 0.92); +} + +.nav { + align-items: center; + display: flex; + gap: 24px; + justify-content: space-between; + margin: 0 auto; + max-width: 1180px; + min-height: 72px; + padding: 0 28px; +} + +.brand { + font-size: 0.92rem; + font-weight: 800; + letter-spacing: 0.14em; + text-decoration: none; +} + +.nav-links { + align-items: center; + display: flex; + gap: 22px; + color: var(--muted); + font-size: 0.94rem; + font-weight: 650; +} + +.nav-links a { + text-decoration: none; +} + +.nav-links a:hover { + color: var(--teal); +} + +main { + overflow: hidden; +} + +.hero { + background: var(--ink); + border-bottom: 1px solid var(--line); + color: #ffffff; +} + +.hero-inner { + display: flex; + margin: 0; + min-height: min(780px, calc(100vh - 72px)); + overflow: hidden; + padding: 0; + position: relative; +} + +.hero-inner::before { + background: linear-gradient(90deg, rgba(23, 32, 42, 0.92) 0%, rgba(23, 32, 42, 0.82) 28%, rgba(23, 32, 42, 0.34) 55%, rgba(23, 32, 42, 0) 78%); + content: ""; + inset: 0; + position: absolute; + z-index: 1; +} + +.hero-copy { + align-self: center; + margin: 0 auto; + max-width: 1180px; + padding: 86px 28px 64px; + position: relative; + width: 100%; + z-index: 2; +} + +.eyebrow { + color: #45c8d4; + font-size: 0.82rem; + font-weight: 800; + letter-spacing: 0.12em; + margin: 0 0 18px; + text-transform: uppercase; +} + +h1 { + font-size: clamp(3rem, 5.4vw, 4.9rem); + letter-spacing: 0; + line-height: 0.98; + margin: 0; + max-width: 680px; +} + +.lead { + color: rgba(255, 255, 255, 0.82); + font-size: clamp(1.1rem, 1.8vw, 1.36rem); + margin: 28px 0 0; + max-width: 640px; +} + +.actions { + display: flex; + flex-wrap: wrap; + gap: 14px; + margin-top: 34px; +} + +.button { + align-items: center; + border: 1px solid var(--ink); + display: inline-flex; + font-weight: 760; + min-height: 46px; + padding: 0 18px; + text-decoration: none; +} + +.button.primary { + background: #ffffff; + border-color: #ffffff; + color: var(--ink); +} + +.hero .button.secondary { + border-color: rgba(255, 255, 255, 0.78); + color: #ffffff; +} + +.button.secondary { + background: transparent; + color: var(--ink); +} + +.hero-image { + display: block; + height: 100%; + inset: 0; + object-fit: cover; + object-position: center right; + position: absolute; + width: 100%; +} + +.metrics { + background: var(--ink); + color: #ffffff; +} + +.metrics-grid { + display: grid; + gap: 1px; + grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); + margin: 0 auto; + max-width: 1180px; + padding: 0 28px; +} + +.metric { + border-left: 1px solid rgba(255, 255, 255, 0.14); + padding: 34px 28px; +} + +.metric:last-child { + border-right: 1px solid rgba(255, 255, 255, 0.14); +} + +.metric strong { + display: block; + font-size: 1.45rem; + line-height: 1.2; +} + +.metric span { + color: rgba(255, 255, 255, 0.72); + display: block; + margin-top: 8px; +} + +.section, +.page-wrap { + margin: 0 auto; + max-width: 1180px; + padding: 80px 28px; + scroll-margin-top: 24px; +} + +.page-wrap { + padding-top: 62px; +} + +.section-heading, +.page-heading { + display: grid; + gap: 24px; + grid-template-columns: minmax(220px, 0.7fr) minmax(0, 1fr); + margin-bottom: 38px; +} + +.page-heading { + border-bottom: 1px solid var(--line); + padding-bottom: 38px; +} + +h2, +.page-title { + font-size: clamp(2rem, 3.6vw, 3.3rem); + letter-spacing: 0; + line-height: 1.06; + margin: 0; +} + +.section-heading p, +.page-heading p { + color: var(--muted); + font-size: 1.08rem; + margin: 0; + max-width: 690px; +} + +.marker { + display: block; + height: 4px; + margin-bottom: 26px; + width: 54px; +} + +.marker.teal { + background: var(--teal); +} + +.marker.red { + background: var(--red); +} + +.marker.gold { + background: var(--gold); +} + +.prose { + max-width: 760px; +} + +.prose h2 { + font-size: clamp(1.65rem, 2.4vw, 2.3rem); + margin-top: 0; +} + +.prose p + p { + margin-top: 18px; +} + +footer { + border-top: 1px solid var(--line); + color: var(--muted); + font-size: 0.92rem; + padding: 24px 28px; + text-align: center; +} + +.not-found { + margin: 0 auto; + max-width: 620px; + min-height: 52vh; + padding: 90px 28px; + text-align: center; +} + +.not-found h1 { + font-size: clamp(4rem, 12vw, 7rem); + line-height: 1; + margin: 0 0 24px; +} + +.not-found p { + color: var(--muted); + margin: 10px 0 0; +} + +.not-found strong { + color: var(--ink); +} + +.not-found a { + color: var(--ink); + font-weight: 750; + text-decoration-color: rgba(0, 125, 138, 0.4); + text-decoration-thickness: 2px; + text-underline-offset: 3px; +} + +.not-found a:hover { + color: var(--teal); +} + +@media (max-width: 850px) { + .nav { + align-items: center; + flex-direction: row; + gap: 18px; + min-height: 0; + padding-bottom: 14px; + padding-top: 14px; + } + + .brand { + font-size: 0.82rem; + } + + .nav-links { + flex-wrap: wrap; + font-size: 0.92rem; + gap: 14px; + justify-content: flex-end; + } + + .hero-inner, + .section-heading, + .page-heading { + grid-template-columns: 1fr; + } + + .hero-inner { + min-height: 620px; + } + + h1 { + font-size: clamp(2.35rem, 8vw, 3.35rem); + } + + .lead { + font-size: 1rem; + margin-top: 18px; + } + + .actions { + gap: 10px; + margin-top: 22px; + } + + .button { + font-size: 0.95rem; + min-height: 42px; + padding: 0 14px; + } + + .hero-copy { + padding-bottom: 44px; + padding-top: 56px; + } + + .hero-inner::before { + background: linear-gradient(180deg, rgba(23, 32, 42, 0.92) 0%, rgba(23, 32, 42, 0.74) 58%, rgba(23, 32, 42, 0.22) 100%); + } + + .hero-image { + object-position: 63% center; + } + + .section, + .page-wrap { + padding-bottom: 58px; + padding-top: 58px; + } + + .section-heading { + margin-bottom: 28px; + } + + .metrics-grid { + grid-template-columns: 1fr; + } + + .metric, + .metric:last-child { + border-left: 0; + border-right: 0; + border-top: 1px solid rgba(255, 255, 255, 0.14); + } + +} + +@media (max-width: 560px) { + .nav { + align-items: flex-start; + flex-direction: column; + } + + .nav-links { + justify-content: flex-start; + } + + .button { + width: 100%; + } +} diff --git a/assets/images/cmr-simulation-hero.png b/assets/images/cmr-simulation-hero.png new file mode 100644 index 0000000..69e668b Binary files /dev/null and b/assets/images/cmr-simulation-hero.png differ diff --git a/index.md b/index.md new file mode 100644 index 0000000..90c86bd --- /dev/null +++ b/index.md @@ -0,0 +1,8 @@ +--- +title: Home +layout: home +--- + +## This is a heading + +This is a section. diff --git a/scripts/pages-build b/scripts/pages-build new file mode 100755 index 0000000..8f8b453 --- /dev/null +++ b/scripts/pages-build @@ -0,0 +1,59 @@ +#!/usr/bin/env bash +set -euo pipefail + +repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +image="${PAGES_JEKYLL_IMAGE:-ghcr.io/actions/jekyll-build-pages:v1.0.13}" +platform="${PAGES_DOCKER_PLATFORM:-linux/amd64}" +source_dir="${PAGES_SOURCE:-./}" +destination_dir="${PAGES_DESTINATION:-./_site}" +local_baseurl="${PAGES_LOCAL_BASEURL:-}" +build_revision="${PAGES_BUILD_REVISION:-$(git -C "${repo_root}" rev-parse HEAD 2>/dev/null || echo local)}" + +if ! command -v docker >/dev/null 2>&1; then + echo "docker is required to run the GitHub Pages build image." >&2 + exit 127 +fi + +rm -rf "${repo_root}/${destination_dir#./}" +config_path="${repo_root}/${source_dir#./}/_config.yml" +config_backup="$(mktemp)" + +if [ ! -f "${config_path}" ]; then + echo "Cannot find Jekyll config at ${config_path}" >&2 + exit 1 +fi + +cp "${config_path}" "${config_backup}" + +cleanup() { + cp "${config_backup}" "${config_path}" + rm -f "${config_backup}" +} + +trap cleanup EXIT + +{ + echo + printf 'baseurl: "%s"\n' "${local_baseurl}" +} >> "${config_path}" + +docker run --rm \ + --platform "${platform}" \ + --volume "${repo_root}:/github/workspace" \ + --workdir /github/workspace \ + --env GITHUB_WORKSPACE=/github/workspace \ + --env GITHUB_REPOSITORY="${GITHUB_REPOSITORY:-CMRCS/cmrcs.github.io}" \ + --env GITHUB_API_URL="${GITHUB_API_URL:-https://api.github.com}" \ + --env INPUT_SOURCE="${source_dir}" \ + --env INPUT_DESTINATION="${destination_dir}" \ + --env INPUT_FUTURE="${PAGES_FUTURE:-false}" \ + --env INPUT_BUILD_REVISION="${build_revision}" \ + --env INPUT_VERBOSE="${PAGES_VERBOSE:-true}" \ + --env INPUT_TOKEN="${GITHUB_TOKEN:-}" \ + --entrypoint bash \ + "${image}" \ + -lc ' + set -euo pipefail + + /entrypoint.sh + ' diff --git a/scripts/pages-serve b/scripts/pages-serve new file mode 100755 index 0000000..63c861f --- /dev/null +++ b/scripts/pages-serve @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +set -euo pipefail + +repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +image="${PAGES_JEKYLL_IMAGE:-ghcr.io/actions/jekyll-build-pages:v1.0.13}" +platform="${PAGES_DOCKER_PLATFORM:-linux/amd64}" +port="${PAGES_PORT:-4000}" +source_dir="${PAGES_SOURCE:-./}" +destination_dir="${PAGES_DESTINATION:-./_site}" +local_baseurl="${PAGES_LOCAL_BASEURL:-}" +build_revision="${PAGES_BUILD_REVISION:-$(git -C "${repo_root}" rev-parse HEAD 2>/dev/null || echo local)}" + +if ! command -v docker >/dev/null 2>&1; then + echo "docker is required to run the GitHub Pages build image." >&2 + exit 127 +fi + +rm -rf "${repo_root}/${destination_dir#./}" +config_path="${repo_root}/${source_dir#./}/_config.yml" +config_backup="$(mktemp)" + +if [ ! -f "${config_path}" ]; then + echo "Cannot find Jekyll config at ${config_path}" >&2 + exit 1 +fi + +cp "${config_path}" "${config_backup}" + +cleanup() { + cp "${config_backup}" "${config_path}" + rm -f "${config_backup}" +} + +trap cleanup EXIT + +{ + echo + printf 'baseurl: "%s"\n' "${local_baseurl}" +} >> "${config_path}" + +docker run --rm \ + --platform "${platform}" \ + --volume "${repo_root}:/github/workspace" \ + --workdir /github/workspace \ + --env GITHUB_WORKSPACE=/github/workspace \ + --env GITHUB_REPOSITORY="${GITHUB_REPOSITORY:-CMRCS/cmrcs.github.io}" \ + --env GITHUB_API_URL="${GITHUB_API_URL:-https://api.github.com}" \ + --env INPUT_SOURCE="${source_dir}" \ + --env INPUT_DESTINATION="${destination_dir}" \ + --env INPUT_FUTURE="${PAGES_FUTURE:-false}" \ + --env INPUT_BUILD_REVISION="${build_revision}" \ + --env INPUT_VERBOSE="${PAGES_VERBOSE:-true}" \ + --env INPUT_TOKEN="${GITHUB_TOKEN:-}" \ + --entrypoint bash \ + "${image}" \ + -lc ' + /entrypoint.sh + ' + +cleanup +trap - EXIT + +docker run --rm \ + --platform "${platform}" \ + --publish "${port}:${port}" \ + --volume "${repo_root}:/github/workspace" \ + --workdir /github/workspace \ + --entrypoint ruby \ + "${image}" \ + -run -e httpd "${destination_dir#./}" -p "${port}" -b 0.0.0.0