11# This workflow builds and deploys documentation for the project.
22#
3- # Steps overview:
4- # Job 1: build-docs
5- # - Builds documentation (including running Jupyter notebooks to generate output cells).
6- # - Uploads the built site as a Pages artifact.
7- # Job 2: deploy-dev
8- # - Deploys the built site to GitHub Pages for development (pushes to develop/master).
9- # Job 3: deploy-prod
10- # - Deploys the built site to gh-pages branch for production (release tags starting with v*).
11- # - This triggers deployment to a custom domain via webhook.
3+ # Overview:
4+ # - Converts tutorial Python scripts to Jupyter notebooks and executes them.
5+ # - Builds the documentation site using MkDocs with the Material theme.
6+ # - Uploads the built site as an artifact for local inspection.
7+ # - Deploys versioned documentation to the gh-pages branch using Mike:
8+ # - For release tags (v*): deploys to a versioned folder (e.g., /0.9.1/) and updates /latest/.
9+ # - For branches: deploys to /dev/.
1210#
13- # The action summary page will contain links to the built artifact for downloading
14- # and inspecting, as well as links to both the development and production versions of
15- # the deployed documentation site.
11+ # The action summary page will contain a link to the built artifact for downloading
12+ # and inspecting, as well as a link to the deployed documentation site.
1613
1714name : Docs build and deployment
1815
3027 # Allows you to run this workflow manually from the Actions tab
3128 workflow_dispatch :
3229
33- # Allow only one concurrent workflow, skipping runs queued between the run
34- # in-progress and latest queued. And cancel in-progress runs.
30+ # Allow only one concurrent deployment to gh-pages at a time.
31+ # All docs workflows share the same concurrency group to prevent race conditions
32+ # when multiple branches/tags trigger simultaneous deployments.
3533concurrency :
36- group :
37- ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
38- cancel-in-progress : true
34+ group : docs-gh-pages-deploy
35+ cancel-in-progress : false
3936
4037# Set the environment variables to be used in all jobs defined in this workflow
4138env :
5350 NOTEBOOKS_DIR : tutorials
5451
5552jobs :
56- # Job 1: Build the static files for the documentation site
53+ # Single job that builds and deploys documentation.
54+ # Uses macOS runner for consistent Plotly chart rendering.
5755 build-deploy-docs :
5856 strategy :
5957 matrix :
60- os : [macos-14] # Use macOS to switch to dark mode for Plotly charts
58+ os : [macos-14]
6159
6260 runs-on : ${{ matrix.os }}
6361
6462 permissions :
65- contents : write # required for pushing to gh-pages branch
63+ contents : write # Required for pushing to the gh-pages branch
6664
6765 steps :
6866 # Setting DOCS_VERSION to be used in mkdocs.yml, and then in the
@@ -87,10 +85,20 @@ jobs:
8785 echo "DOCS_VERSION=${DOCS_VERSION}" >> "$GITHUB_ENV"
8886 echo "DEPLOYMENT_URL=https://easyscience.github.io/${{ github.event.repository.name }}/${DOCS_VERSION}" >> "$GITHUB_ENV"
8987
88+ # Create GitHub App token for pushing to gh-pages as easyscience[bot].
89+ - name : Create GitHub App installation token
90+ id : app-token
91+ uses : actions/create-github-app-token@v2
92+ with :
93+ app-id : ${{ vars.EASYSCIENCE_APP_ID }}
94+ private-key : ${{ secrets.EASYSCIENCE_APP_KEY }}
95+
96+ # Check out the repository source code.
97+ # Note: The gh-pages branch is fetched separately later for mike deployment.
9098 - name : Check-out repository
9199 uses : actions/checkout@v5
92100 with :
93- fetch-depth : 0 # full history with tags; needed for mike to push/deploy docs
101+ token : ${{ steps.app-token.outputs.token }}
94102
95103 # Activate dark mode to create documentation with Plotly charts in dark mode
96104 # Need a better solution to automatically switch the chart colour theme based on the mkdocs material switcher
@@ -103,6 +111,8 @@ jobs:
103111 # dark-mode on
104112 # dark-mode status
105113
114+ # Set up the pixi package manager and install dependencies from pixi.toml.
115+ # Uses frozen lockfile to ensure reproducible builds.
106116 - name : Set up pixi
107117 uses : prefix-dev/setup-pixi@v0.9.0
108118 with :
@@ -113,37 +123,43 @@ jobs:
113123 cache : false
114124 post-cleanup : false
115125
126+ # Install additional development dependencies (e.g., pre-commit hooks, dev tools).
116127 - name : Install and setup development dependencies
117128 shell : bash
118129 run : pixi run dev
119130
131+ # Clone shared documentation assets and branding resources from external repositories.
132+ # These contain common MkDocs configuration, templates, stylesheets, and images.
120133 - name : Clone easyscience/assets-docs and easyscience/assets-branding
121134 run : |
122135 cd ..
123136 git clone https://github.com/easyscience/assets-docs.git
124137 git clone https://github.com/easyscience/assets-branding.git
125138
139+ # Copy assets from the cloned repositories into the docs/ directory.
140+ # This includes stylesheets, images, templates, and other shared resources.
126141 - name : Add files from cloned repositories
127142 run : pixi run docs-assets
128143
129- # Convert python scripts in the notebooks directory to Jupyter notebooks
130- # Strip output from the notebooks
131- # Prepare the notebooks for documentation (add colab cell, etc.)
132- # Run the notebooks to generate the output cells using multiple cores
133- # The notebooks are then used to build the documentation site
144+ # Convert Python scripts in the tutorials/ directory to Jupyter notebooks.
145+ # This step also strips any existing output from the notebooks and prepares
146+ # them for documentation.
134147 - name : Convert tutorial scripts to notebooks
135148 run : pixi run notebook-prepare
136149
137- # The following step is needed to avoid the following message during the build:
138- # "Matplotlib is building the font cache; this may take a moment"
150+ # Pre-import the main package to trigger Matplotlib font cache building.
151+ # This avoids "Matplotlib is building the font cache" messages during notebook execution.
139152 - name : Pre-build site step
140153 run : pixi run python -c "import easydiffraction"
141154
142- # Run the notebooks to generate the output cells using multiple cores
155+ # Execute all Jupyter notebooks to generate output cells (plots, tables, etc.).
156+ # Uses multiple cores for parallel execution to speed up the process.
143157 - name : Run notebooks
144158 # if: false # Temporarily disabled to speed up the docs build
145159 run : pixi run notebook-exec
146160
161+ # Move the executed notebooks to docs/tutorials/ directory
162+ # so they can be included in the documentation site.
147163 - name : Move notebooks to docs/tutorials
148164 run : pixi run docs-notebooks
149165
@@ -170,17 +186,24 @@ jobs:
170186 if-no-files-found : ' error'
171187 compression-level : 0
172188
173- # Publish versioned docs with Mike (dev on branches, prod on tags)
174- # Configure git for pushing to gh-pages branch
189+ # Configure git user for mike to commit and push to gh-pages branch.
175190 - name : Configure git for pushing
176191 run : |
177- git config user.name "github-actions[bot]"
178- git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
192+ git config user.name "easyscience[bot]"
193+ git config user.email "${{ vars.EASYSCIENCE_APP_ID }}+easyscience[bot]@users.noreply.github.com"
194+
195+ # Fetch the gh-pages branch to ensure mike has the latest remote state.
196+ # This is required because the checkout step only fetches the source branch,
197+ # not the gh-pages branch that mike needs to update.
198+ - name : Fetch gh-pages branch
199+ run : |
200+ git fetch origin gh-pages:gh-pages 2>/dev/null || true
179201
180- # Publish versioned docs with Mike. The tagged release docs go to
181- # the versioned prefix, e.g. /v1.2.3/, and also to /latest/.
182- # All other branches go to /dev/.
183- # "${RELEASE_VERSION#v}" for v0.8.3.post1 -> 0.8.3.post1
202+ # Deploy versioned documentation using mike (MkDocs plugin for versioning).
203+ # - For release tags (v*): deploys to versioned folder (e.g., /0.9.1/) and aliases to /latest/.
204+ # - For branches: deploys to /dev/.
205+ # The "${RELEASE_VERSION#v}" syntax strips the 'v' prefix (v0.9.1 -> 0.9.1).
206+ # Also sets 'latest' as the default version for the version selector.
184207 - name : Rebuild and deploy docs with mike
185208 run : |
186209 if [[ "${IS_RELEASE_TAG}" == "true" ]]; then
0 commit comments