diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..0e70e5745 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,42 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + # Maintain dependencies for GitHub Actions + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "monthly" + commit-message: + prefix: build(ci) + groups: + ci: + patterns: + - '*' + + # Maintain dependencies for npm + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "monthly" + commit-message: + prefix: build(pip) + groups: + pip: + patterns: + - '*' + + # Maintain dependencies for docker + - package-ecosystem: "docker" + directory: "/" + schedule: + interval: "monthly" + commit-message: + prefix: build(docker) + groups: + docker: + patterns: + - '*' diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml new file mode 100644 index 000000000..8581ea8d6 --- /dev/null +++ b/.github/workflows/build-docker.yml @@ -0,0 +1,145 @@ +name: build-docker + +on: + push: + branches: + - 'master' + - 'main' + tags: + - 'v*' + pull_request: + merge_group: + workflow_dispatch: + inputs: + git-ref: + description: 'Git ref (optional)' + required: false + +env: + IMAGE_REGISTRY: ghcr.io/${{ github.repository_owner }} + IMAGE_NAME: 'project-docs' + MAIN_BRANCH: 'master' # pushing to the main branch will update the "edge" tag on the image + BETA_BRANCH: 'beta' # pushing to this branch will update the "beta" tag on the image + STABLE_BRANCH: 'stable' # pushing to this branch will update the "stable" tag on the image + TAG_PREFIX: 'v' # pushing tags with this prefix will add a version tag to the image and update the "latest" tag on the image + # Because openUC2/openuc2.github.io is a fork of an upstream repo, we can't suppress attempts to push + # container images for forks of the openUC2/openuc2.github.io repo. That's is probably acceptable for how + # we develop this project (i.e. with PRs from branches on the openUC2/openuc2.github.io repo, rather than + # PRs from user-created forks of openUC2/openuc2.github.io). + PUSH_IMAGE: ${{ github.event_name == 'pull_request' || github.event_name == 'push' || github.event_name == 'push tag' }} + # TODO(ethanjli): Restore the following line once this repo is detached from its fork upstream + # PUSH_IMAGE: ${{ (github.event_name == 'pull_request' && !github.event.pull_request.head.repo.fork) || github.event_name == 'push' || github.event_name == 'push tag' }} + +jobs: + build: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + strategy: + fail-fast: false + matrix: + variant: + - default + steps: + - uses: actions/checkout@v4 + with: + # Only fetch files we actually need: + fetch-depth: 0 + filter: 'blob:none' + + # Build documentation website + - name: Install poetry + run: pipx install poetry==2.1.3 + + - name: Set up Node + uses: actions/setup-node@v2 + with: + node-version: "19" # FIXME: this is very old and out-of-date. Bump the version! + + - name: Cache ~/.npm + uses: actions/cache@v4 + with: + path: ~/.npm + key: ${{ runner.os }}-node-${{ matrix.variant }}-${{ hashFiles('**/package-lock.json') }} + restore-keys: ${{ runner.os }}-node + + - name: Install build dependencies + run: | + npm install + + - name: Cache Docusaurus build + uses: docuactions/cache@v1 + + - name: Make documentation ${{ matrix.variant }} + if: matrix.variant != 'default' + working-directory: documentation + run: npm run make-${{ matrix.variant }} + + - name: Build documentation + env: + # Container image should be built with `/openUC2` as the base URL instead of `/`, as the + # self-contained root of the site. We use `/openUC2/` instead of `/docs/` as the root so + # that we don't have pages in `/docs/docs/`, but instead we have them in `/openUC2/docs/`. + BASE_URL: '/openUC2/' + run: | + npm run build + + # Work around a bug where capital letters in the GitHub username (e.g. "PlanktoScope") make it + # impossible to push to GHCR. See https://github.com/macbre/push-to-ghcr/issues/12 + - name: Lowercase image registry and owner + id: image_registry_case + uses: ASzc/change-string-case-action@v6 + with: + string: ${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAME }} + + - name: Set documentation variant suffix + run: | + if [[ '${{ matrix.variant }}' != 'default' ]]; then + echo 'VARIANT_SUFFIX=-${{ matrix.variant}}' >> $GITHUB_ENV + fi + + # Build and publish Docker container image + - name: Get Docker metadata + id: meta + uses: docker/metadata-action@v5 + env: + DOCKER_METADATA_PR_HEAD_SHA: true + IS_MAIN_BRANCH: ${{ github.ref == format('refs/heads/{0}', env.MAIN_BRANCH) }} + IS_BETA_BRANCH: ${{ github.ref == format('refs/heads/{0}', env.BETA_BRANCH) }} + IS_STABLE_BRANCH: ${{ github.ref == format('refs/heads/{0}', env.STABLE_BRANCH) }} + with: + images: ${{ steps.image_registry_case.outputs.lowercase }} + flavor: | + suffix=${{ env.VARIANT_SUFFIX }} + tags: | + type=match,pattern=${{ env.TAG_PREFIX }}(.*),group=1 # this implicitly updates latest + type=raw,value=stable,enable=${{ env.IS_STABLE_BRANCH }},priority=702 + type=raw,value=beta,enable=${{ env.IS_BETA_BRANCH }},priority=701 + type=edge,branch=${{ env.MAIN_BRANCH }} + type=ref,event=pr + type=sha,priority=100 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to GitHub Container Registry + if: env.PUSH_IMAGE == 'true' + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push + uses: docker/build-push-action@v6 + with: + context: . + pull: true + platforms: linux/amd64,linux/arm64 + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + push: ${{ env.PUSH_IMAGE }} diff --git a/.github/workflows/deploydocusaurus.yml b/.github/workflows/deploy-edge.yml similarity index 74% rename from .github/workflows/deploydocusaurus.yml rename to .github/workflows/deploy-edge.yml index a268b79d8..d2cff99b9 100644 --- a/.github/workflows/deploydocusaurus.yml +++ b/.github/workflows/deploy-edge.yml @@ -1,13 +1,12 @@ - -name: deploy-docusaurus +name: deploy on: push: - pull_request: + branches: + - 'master' + - 'main' workflow_dispatch: - - # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: deploy: @@ -18,17 +17,24 @@ jobs: steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - name: Check out repo - uses: actions/checkout@v2 + uses: actions/checkout@v4 + with: + # Only fetch files we actually need: + fetch-depth: 0 + filter: 'blob:none' + # Node is required for npm - name: Set up Node uses: actions/setup-node@v2 with: - node-version: "19" + node-version: "19" # FIXME: this is very old and out-of-date. Bump the version! + # Install and build Docusaurus website - name: Build Docusaurus website run: | npm install npm run build + - name: Deploy ๐Ÿš€ uses: JamesIves/github-pages-deploy-action@releases/v3 with: diff --git a/Caddyfile b/Caddyfile new file mode 100644 index 000000000..cc8557390 --- /dev/null +++ b/Caddyfile @@ -0,0 +1,10 @@ +{ + auto_https off +} + +:80 { + handle_path /openUC2/* { + root * /srv + file_server + } +} diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..ceef98652 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,10 @@ +# syntax=docker/dockerfile:1.19 +# Note: the above syntax parser directive is only needed so that we can use the COPY directive with +# the `--exclude` option. + +FROM caddy:2.10.2 + +COPY build/assets/images /srv/assets/images +COPY --exclude=build/assets/images build /srv + +COPY Caddyfile /etc/caddy/Caddyfile diff --git a/docusaurus.config.js b/docusaurus.config.js index 028a5e01a..e95a3a8da 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -6,12 +6,14 @@ const darkCodeTheme = require('prism-react-renderer/themes/dracula'); const math = require('remark-math'); const katex = require('rehype-katex'); +const baseURL = process.env.BASE_URL || '/' + /** @type {import('@docusaurus/types').Config} */ const config = { title: 'openUC2 Documentation', tagline: 'Seeing is believing. But better with the docs!', - url: 'https://docs.youseetoo.org', - baseUrl: '/', + url: 'https://openuc2.github.io/', + baseUrl: baseURL, onBrokenLinks: 'warn', onBrokenMarkdownLinks: 'warn', favicon: 'img/favicon.ico', @@ -134,7 +136,7 @@ const config = { items: [ { label: 'Tutorial', - to: '/docs/intro', + to: `${baseURL}docs/intro`, }, ], }, @@ -156,7 +158,7 @@ const config = { items: [ { label: 'Blog', - to: '/blog', + to: 'https://openuc2.com/blog', }, { label: 'GitHub', diff --git a/src/components/HomepageFeatures/index.tsx b/src/components/HomepageFeatures/index.tsx index 88c6d7831..ff6aa4e6b 100644 --- a/src/components/HomepageFeatures/index.tsx +++ b/src/components/HomepageFeatures/index.tsx @@ -13,7 +13,7 @@ type FeatureItem = { const FEATURES: FeatureItem[] = [ { title: 'Optics Basics', - to: '/docs/Toolboxes', + to: 'docs/Toolboxes', image: require('@site/static/img/Application_Discovery_Kit_Base.png').default, description: 'Explorer & Discovery boxes to master fundamentals.', }, @@ -31,26 +31,26 @@ const FEATURES: FeatureItem[] = [ }, { title: 'Fluorescence & Lightsheet', - to: '/docs/Toolboxes/LightsheetBox/Light_sheet_Fluoresence_microscope', + to: 'docs/Toolboxes/LightsheetBox/Light_sheet_Fluoresence_microscope', image: require('@site/static/img/ZebraFish-1-1536x864.gif').default, description: 'LED, laser & light-sheet fluorescence tutorials.', }, { title: 'Interferometry & Polarization', - to: '/docs/Toolboxes/QuantumBox/MichelsonInterferometer/MichelsonInterferometer', + to: 'docs/Toolboxes/QuantumBox/MichelsonInterferometer/MichelsonInterferometer', image: require('@site/static/img/429833192-806c55e3-47cf-45a0-b216-883e5747821a.jpg').default, description: 'Michelson, Mach-Zehnder, Newtonโ€™s rings, stress birefringence.', }, { title: 'ImSwitch and Firmware', - to: '/docs/ImSwitch/Quickstart', + to: 'docs/ImSwitch/Quickstart', image: require('@site/static/img/FRAME6.png').default, description: 'Everything that drives your microscopy hardware.', }, { title: 'Seeed Studio x openUC2', - to: '/docs/Toolboxes/SeeedMicroscope/04_1_seeedmicroscope', + to: 'docs/Toolboxes/SeeedMicroscope/04_1_seeedmicroscope', image: require('@site/static/img/Application_SEEEDxOpenUC2_v2.png').default, description: 'The standalone microscope for the IoT.', }, diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 24bf9cb1c..8bc0c6443 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -17,7 +17,7 @@ function HomepageHeader() {
+ to="docs/intro"> ๐Ÿ”ฌ๐ŸŽฒ Visit the openUC2 Tutorials ๐Ÿ”ฌ๐ŸŽฒ