Skip to content

Commit 1ecd65a

Browse files
authored
Add CI workflow to build a Docker ctr img to serve the docs (#15)
* Add CI workflow to build Docker ctr img with offline copy of the docs * Don't try to run the deploy CI workflow from PRs * Fix incorrect CI step context * Fix incorrect file path for Dockerfile * Try to copy photos in a separate ctr img layer * Try to resolve complaint about `--exclude` flag in `Dockerfile` * Troubleshoot previous commit * Continue troubleshooting... * Continue troubleshooting... * Fix ctr img push conditions, and built site artifact upload * Allow overriding the base URL via env var * Override the base URL when building the site for the ctr img * Don't set base URL, because it breaks many hard-coded links * Revert change in previous commit * Fix some broken links in the homepage and footer * Change base URL path for Docker container * Try setting the appropriate base URL in `Caddyfile`, too * Stop uploading built site as archive, since it's not usable as such * Try to cache Docusaurus builds * Fix syntax error in previous commit * Try again to change base URL path in the Caddyfile
1 parent d3268ec commit 1ecd65a

8 files changed

Lines changed: 232 additions & 17 deletions

File tree

.github/dependabot.yml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# To get started with Dependabot version updates, you'll need to specify which
2+
# package ecosystems to update and where the package manifests are located.
3+
# Please see the documentation for all configuration options:
4+
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
5+
6+
version: 2
7+
updates:
8+
# Maintain dependencies for GitHub Actions
9+
- package-ecosystem: "github-actions"
10+
directory: "/"
11+
schedule:
12+
interval: "monthly"
13+
commit-message:
14+
prefix: build(ci)
15+
groups:
16+
ci:
17+
patterns:
18+
- '*'
19+
20+
# Maintain dependencies for npm
21+
- package-ecosystem: "npm"
22+
directory: "/"
23+
schedule:
24+
interval: "monthly"
25+
commit-message:
26+
prefix: build(pip)
27+
groups:
28+
pip:
29+
patterns:
30+
- '*'
31+
32+
# Maintain dependencies for docker
33+
- package-ecosystem: "docker"
34+
directory: "/"
35+
schedule:
36+
interval: "monthly"
37+
commit-message:
38+
prefix: build(docker)
39+
groups:
40+
docker:
41+
patterns:
42+
- '*'

.github/workflows/build-docker.yml

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
name: build-docker
2+
3+
on:
4+
push:
5+
branches:
6+
- 'master'
7+
- 'main'
8+
tags:
9+
- 'v*'
10+
pull_request:
11+
merge_group:
12+
workflow_dispatch:
13+
inputs:
14+
git-ref:
15+
description: 'Git ref (optional)'
16+
required: false
17+
18+
env:
19+
IMAGE_REGISTRY: ghcr.io/${{ github.repository_owner }}
20+
IMAGE_NAME: 'project-docs'
21+
MAIN_BRANCH: 'master' # pushing to the main branch will update the "edge" tag on the image
22+
BETA_BRANCH: 'beta' # pushing to this branch will update the "beta" tag on the image
23+
STABLE_BRANCH: 'stable' # pushing to this branch will update the "stable" tag on the image
24+
TAG_PREFIX: 'v' # pushing tags with this prefix will add a version tag to the image and update the "latest" tag on the image
25+
# Because openUC2/openuc2.github.io is a fork of an upstream repo, we can't suppress attempts to push
26+
# container images for forks of the openUC2/openuc2.github.io repo. That's is probably acceptable for how
27+
# we develop this project (i.e. with PRs from branches on the openUC2/openuc2.github.io repo, rather than
28+
# PRs from user-created forks of openUC2/openuc2.github.io).
29+
PUSH_IMAGE: ${{ github.event_name == 'pull_request' || github.event_name == 'push' || github.event_name == 'push tag' }}
30+
# TODO(ethanjli): Restore the following line once this repo is detached from its fork upstream
31+
# PUSH_IMAGE: ${{ (github.event_name == 'pull_request' && !github.event.pull_request.head.repo.fork) || github.event_name == 'push' || github.event_name == 'push tag' }}
32+
33+
jobs:
34+
build:
35+
runs-on: ubuntu-latest
36+
permissions:
37+
contents: read
38+
packages: write
39+
strategy:
40+
fail-fast: false
41+
matrix:
42+
variant:
43+
- default
44+
steps:
45+
- uses: actions/checkout@v4
46+
with:
47+
# Only fetch files we actually need:
48+
fetch-depth: 0
49+
filter: 'blob:none'
50+
51+
# Build documentation website
52+
- name: Install poetry
53+
run: pipx install poetry==2.1.3
54+
55+
- name: Set up Node
56+
uses: actions/setup-node@v2
57+
with:
58+
node-version: "19" # FIXME: this is very old and out-of-date. Bump the version!
59+
60+
- name: Cache ~/.npm
61+
uses: actions/cache@v4
62+
with:
63+
path: ~/.npm
64+
key: ${{ runner.os }}-node-${{ matrix.variant }}-${{ hashFiles('**/package-lock.json') }}
65+
restore-keys: ${{ runner.os }}-node
66+
67+
- name: Install build dependencies
68+
run: |
69+
npm install
70+
71+
- name: Cache Docusaurus build
72+
uses: docuactions/cache@v1
73+
74+
- name: Make documentation ${{ matrix.variant }}
75+
if: matrix.variant != 'default'
76+
working-directory: documentation
77+
run: npm run make-${{ matrix.variant }}
78+
79+
- name: Build documentation
80+
env:
81+
# Container image should be built with `/openUC2` as the base URL instead of `/`, as the
82+
# self-contained root of the site. We use `/openUC2/` instead of `/docs/` as the root so
83+
# that we don't have pages in `/docs/docs/`, but instead we have them in `/openUC2/docs/`.
84+
BASE_URL: '/openUC2/'
85+
run: |
86+
npm run build
87+
88+
# Work around a bug where capital letters in the GitHub username (e.g. "PlanktoScope") make it
89+
# impossible to push to GHCR. See https://github.com/macbre/push-to-ghcr/issues/12
90+
- name: Lowercase image registry and owner
91+
id: image_registry_case
92+
uses: ASzc/change-string-case-action@v6
93+
with:
94+
string: ${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAME }}
95+
96+
- name: Set documentation variant suffix
97+
run: |
98+
if [[ '${{ matrix.variant }}' != 'default' ]]; then
99+
echo 'VARIANT_SUFFIX=-${{ matrix.variant}}' >> $GITHUB_ENV
100+
fi
101+
102+
# Build and publish Docker container image
103+
- name: Get Docker metadata
104+
id: meta
105+
uses: docker/metadata-action@v5
106+
env:
107+
DOCKER_METADATA_PR_HEAD_SHA: true
108+
IS_MAIN_BRANCH: ${{ github.ref == format('refs/heads/{0}', env.MAIN_BRANCH) }}
109+
IS_BETA_BRANCH: ${{ github.ref == format('refs/heads/{0}', env.BETA_BRANCH) }}
110+
IS_STABLE_BRANCH: ${{ github.ref == format('refs/heads/{0}', env.STABLE_BRANCH) }}
111+
with:
112+
images: ${{ steps.image_registry_case.outputs.lowercase }}
113+
flavor: |
114+
suffix=${{ env.VARIANT_SUFFIX }}
115+
tags: |
116+
type=match,pattern=${{ env.TAG_PREFIX }}(.*),group=1 # this implicitly updates latest
117+
type=raw,value=stable,enable=${{ env.IS_STABLE_BRANCH }},priority=702
118+
type=raw,value=beta,enable=${{ env.IS_BETA_BRANCH }},priority=701
119+
type=edge,branch=${{ env.MAIN_BRANCH }}
120+
type=ref,event=pr
121+
type=sha,priority=100
122+
123+
- name: Set up QEMU
124+
uses: docker/setup-qemu-action@v3
125+
126+
- name: Set up Docker Buildx
127+
uses: docker/setup-buildx-action@v3
128+
129+
- name: Log in to GitHub Container Registry
130+
if: env.PUSH_IMAGE == 'true'
131+
uses: docker/login-action@v3
132+
with:
133+
registry: ghcr.io
134+
username: ${{ github.repository_owner }}
135+
password: ${{ secrets.GITHUB_TOKEN }}
136+
137+
- name: Build and push
138+
uses: docker/build-push-action@v6
139+
with:
140+
context: .
141+
pull: true
142+
platforms: linux/amd64,linux/arm64
143+
tags: ${{ steps.meta.outputs.tags }}
144+
labels: ${{ steps.meta.outputs.labels }}
145+
push: ${{ env.PUSH_IMAGE }}
Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
1-
2-
name: deploy-docusaurus
1+
name: deploy
32

43
on:
54
push:
6-
pull_request:
5+
branches:
6+
- 'master'
7+
- 'main'
78
workflow_dispatch:
89

9-
10-
1110
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
1211
jobs:
1312
deploy:
@@ -18,17 +17,24 @@ jobs:
1817
steps:
1918
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
2019
- name: Check out repo
21-
uses: actions/checkout@v2
20+
uses: actions/checkout@v4
21+
with:
22+
# Only fetch files we actually need:
23+
fetch-depth: 0
24+
filter: 'blob:none'
25+
2226
# Node is required for npm
2327
- name: Set up Node
2428
uses: actions/setup-node@v2
2529
with:
26-
node-version: "19"
30+
node-version: "19" # FIXME: this is very old and out-of-date. Bump the version!
31+
2732
# Install and build Docusaurus website
2833
- name: Build Docusaurus website
2934
run: |
3035
npm install
3136
npm run build
37+
3238
- name: Deploy 🚀
3339
uses: JamesIves/github-pages-deploy-action@releases/v3
3440
with:

Caddyfile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
auto_https off
3+
}
4+
5+
:80 {
6+
handle_path /openUC2/* {
7+
root * /srv
8+
file_server
9+
}
10+
}

Dockerfile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# syntax=docker/dockerfile:1.19
2+
# Note: the above syntax parser directive is only needed so that we can use the COPY directive with
3+
# the `--exclude` option.
4+
5+
FROM caddy:2.10.2
6+
7+
COPY build/assets/images /srv/assets/images
8+
COPY --exclude=build/assets/images build /srv
9+
10+
COPY Caddyfile /etc/caddy/Caddyfile

docusaurus.config.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@ const darkCodeTheme = require('prism-react-renderer/themes/dracula');
66
const math = require('remark-math');
77
const katex = require('rehype-katex');
88

9+
const baseURL = process.env.BASE_URL || '/'
10+
911
/** @type {import('@docusaurus/types').Config} */
1012
const config = {
1113
title: 'openUC2 Documentation',
1214
tagline: 'Seeing is believing. But better with the docs!',
13-
url: 'https://docs.youseetoo.org',
14-
baseUrl: '/',
15+
url: 'https://openuc2.github.io/',
16+
baseUrl: baseURL,
1517
onBrokenLinks: 'warn',
1618
onBrokenMarkdownLinks: 'warn',
1719
favicon: 'img/favicon.ico',
@@ -134,7 +136,7 @@ const config = {
134136
items: [
135137
{
136138
label: 'Tutorial',
137-
to: '/docs/intro',
139+
to: `${baseURL}docs/intro`,
138140
},
139141
],
140142
},
@@ -156,7 +158,7 @@ const config = {
156158
items: [
157159
{
158160
label: 'Blog',
159-
to: '/blog',
161+
to: 'https://openuc2.com/blog',
160162
},
161163
{
162164
label: 'GitHub',

src/components/HomepageFeatures/index.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ type FeatureItem = {
1313
const FEATURES: FeatureItem[] = [
1414
{
1515
title: 'Optics Basics',
16-
to: '/docs/Toolboxes',
16+
to: 'docs/Toolboxes',
1717
image: require('@site/static/img/Application_Discovery_Kit_Base.png').default,
1818
description: 'Explorer & Discovery boxes to master fundamentals.',
1919
},
@@ -31,26 +31,26 @@ const FEATURES: FeatureItem[] = [
3131
},
3232
{
3333
title: 'Fluorescence & Lightsheet',
34-
to: '/docs/Toolboxes/LightsheetBox/Light_sheet_Fluoresence_microscope',
34+
to: 'docs/Toolboxes/LightsheetBox/Light_sheet_Fluoresence_microscope',
3535
image: require('@site/static/img/ZebraFish-1-1536x864.gif').default,
3636

3737
description: 'LED, laser & light-sheet fluorescence tutorials.',
3838
},
3939
{
4040
title: 'Interferometry & Polarization',
41-
to: '/docs/Toolboxes/QuantumBox/MichelsonInterferometer/MichelsonInterferometer',
41+
to: 'docs/Toolboxes/QuantumBox/MichelsonInterferometer/MichelsonInterferometer',
4242
image: require('@site/static/img/429833192-806c55e3-47cf-45a0-b216-883e5747821a.jpg').default,
4343
description: 'Michelson, Mach-Zehnder, Newton’s rings, stress birefringence.',
4444
},
4545
{
4646
title: 'ImSwitch and Firmware',
47-
to: '/docs/ImSwitch/Quickstart',
47+
to: 'docs/ImSwitch/Quickstart',
4848
image: require('@site/static/img/FRAME6.png').default,
4949
description: 'Everything that drives your microscopy hardware.',
5050
},
5151
{
5252
title: 'Seeed Studio x openUC2',
53-
to: '/docs/Toolboxes/SeeedMicroscope/04_1_seeedmicroscope',
53+
to: 'docs/Toolboxes/SeeedMicroscope/04_1_seeedmicroscope',
5454
image: require('@site/static/img/Application_SEEEDxOpenUC2_v2.png').default,
5555
description: 'The standalone microscope for the IoT.',
5656
},

src/pages/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ function HomepageHeader() {
1717
<div className={styles.buttons}>
1818
<Link
1919
className="button button--secondary button--lg"
20-
to="/docs/intro">
20+
to="docs/intro">
2121
🔬🎲 Visit the openUC2 Tutorials 🔬🎲
2222
</Link>
2323
</div>

0 commit comments

Comments
 (0)