Skip to content

Commit 567672e

Browse files
psobolewskiPhDTimMonkowillingc
authored
Default CI to slimfast and add comment control to run other builds. (#669)
# References and relevant issues Depends on #671 # Description In #646 new make targets were added for faster builds that skip certain parts of the process. In this PR I make them available on CI using a comment: `napari-bot make <target>` (add the `@` in front of napari-bot) Here's the breakdown: 1. circleci/config.yml : Here I add a parameter `make_target` to make the make target configurable on-run. Default is `slimfast` (no gallery, no outside stuff, no notebook execution) 2. build_docs.yml : I added this back, as a reusable workflow, so that there is a build-only workflow that can be run on PR push and triggered with different make_target. (The build-deploy job needs to use the full build for obvious reasons). I made it so that this build-only job also be manually triggered by dispatch. Whether triggered or by manual dispatch, this workflow accepts a make target, one of: html html-noplot docs slimfast slimgallery. The default is `slimfast`, so on (every) push/open of PR it will use `slimfast`, but can be triggered with the other options. Note: at present the triggered state is not saved, so push always used the default. 3. build_trigger.yml : This is the workflow that detects PR comment, checks make target vs a list, and triggers the CircleCI and build_docs builds with the make target from the comment. It also has a step to report back that the triggered build_docs workflow finished and provide a link to the run. 4. build_and_deploy.yml : I modified this to not run on PR push anymore, because it's a full build -- we do need full build for deployment and it's triggered by napari/napari as well. I also modified the PR template to give info on the CI builds, as well as the contributor guide where we talk about docs building on CI. Note: I don't think the new features will trigger in this PR, because it's from a branch. You should be able to see this in action and test it here in my fork, where this PR branch is the default branch: psobolewskiPhD#74 You can see builds triggered by comments from Juan and Carol: https://github.com/psobolewskiPhD/napari-docs/actions/workflows/build_trigger.yml Followups: - have the trigger add a reaction to the comment, so the user knows it triggered - have the trigger add a label to the PR and then use the label as default for subsequent runs (e.g. push ones) --------- Co-authored-by: Tim Monko <[email protected]> Co-authored-by: Carol Willing <[email protected]>
1 parent 83e1189 commit 567672e

File tree

6 files changed

+278
-10
lines changed

6 files changed

+278
-10
lines changed

.circleci/config.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ version: 2.1
1111
orbs:
1212
python: circleci/[email protected]
1313

14+
# parameterize the make target used for build, passed in from build_trigger.yml action
15+
parameters:
16+
make_target:
17+
type: string
18+
default: "slimfast"
19+
1420
jobs:
1521
build-docs:
1622
docker:
@@ -41,7 +47,7 @@ jobs:
4147
command: |
4248
. .venv/bin/activate
4349
cd docs
44-
xvfb-run --auto-servernum make html
50+
xvfb-run --auto-servernum make << pipeline.parameters.make_target >>
4551
environment:
4652
PIP_CONSTRAINT: ../napari/resources/constraints/constraints_py3.10_docs.txt
4753
- store_artifacts:

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,22 @@ change: "An image is worth a thousand words!" -->
1313
<!-- You can also see a preview of the documentation changes you are submitting by
1414
clicking on "Details" to the right of the "Check the rendered docs here!" check on your PR.-->
1515

16+
<!-- Previewing the Documentation Build
17+
When you submit this PR, jobs that preview the documentation will be kicked off.
18+
By default, they will use the `slimfast` build (`make` target), which is fast, because
19+
it doesn't build any content from outside the `docs` repository and doesn't run notebook cells.
20+
You can trigger other builds by commenting on the PR with:
21+
22+
@napari-bot make <target>
23+
24+
where <target> can be:
25+
html : a full build, just like the deployment to napari.org
26+
html-noplot : a full build, but without the gallery examples from `napari/napari`
27+
docs : only the content from `napari/docs`, with notebook code cells executed
28+
slimfast : the default, only the content from `napari/docs`, without code cell execution
29+
slimgallery : `slimfast`, but with the gallery examples from `napari/napari` built
30+
-->
31+
1632
<!-- Final Checklist
1733
- If images included: I have added [alt text](https://webaim.org/techniques/alttext/)
1834
If workflow, documentation build or deployment change:

.github/workflows/build_and_deploy.yml

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,14 @@
55
# https://github.com/napari/napari/blob/main/.github/workflows/deploy_docs.yml when a
66
# commit to `main` occurs in `napari/napari`
77

8-
name: Build & Deploy PR Docs
9-
8+
name: Full Build & Deploy of Docs
9+
# this does a full build of the docs for deployment
1010
on:
1111
push:
1212
branches:
1313
- main
1414
tags:
1515
- 'v*'
16-
pull_request:
17-
branches:
18-
- main
1916
workflow_dispatch:
2017
inputs:
2118
target_directory:

.github/workflows/build_docs.yml

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# As much as possible, this file should be kept in sync with
2+
# https://github.com/napari/docs/blob/main/.github/workflows/build_and_deploy_docs.yml
3+
name: Build PR Docs
4+
5+
on:
6+
pull_request:
7+
branches:
8+
- main
9+
workflow_dispatch:
10+
inputs:
11+
make_target:
12+
description: "Enter make target: html html-noplot docs slimfast slimgallery"
13+
type: string
14+
default: 'slimfast'
15+
workflow_call:
16+
inputs:
17+
make_target:
18+
description: "Enter make target: html html-noplot docs slimfast slimgallery"
19+
type: string
20+
default: 'slimfast'
21+
22+
concurrency:
23+
group: ${{ github.workflow }}-${{ github.ref }}
24+
cancel-in-progress: true
25+
26+
jobs:
27+
build-and-upload:
28+
name: Build & Upload Artifact
29+
runs-on: ubuntu-latest
30+
steps:
31+
- name: Clone docs repo
32+
uses: actions/checkout@v4
33+
with:
34+
# Check out to '/home/runner/work/docs/docs/docs'
35+
path: docs
36+
37+
- name: Clone main repo
38+
uses: actions/checkout@v4
39+
with:
40+
# Check out to '/home/runner/work/docs/docs/napari'
41+
path: napari
42+
repository: napari/napari
43+
# fetch history ensure napari version metadata is read properly
44+
fetch-depth: 0
45+
46+
- uses: actions/setup-python@v5
47+
with:
48+
python-version: "3.10"
49+
cache-dependency-path: |
50+
napari/pyproject.toml
51+
52+
- uses: tlambert03/setup-qt-libs@v1
53+
54+
- name: Install Dependencies
55+
run: |
56+
python -m pip install --upgrade pip
57+
python -m pip install "napari/[pyqt5, docs]"
58+
env:
59+
PIP_CONSTRAINT: ${{ github.workspace }}/napari/resources/constraints/constraints_py3.10_docs.txt
60+
61+
- name: Check napari can be imported
62+
run: |
63+
python -c 'import napari; print(napari.__version__)'
64+
python -c 'import napari.layers; print(napari.layers.__doc__)'
65+
66+
- name: Build Docs
67+
uses: aganders3/headless-gui@v2
68+
env:
69+
GOOGLE_CALENDAR_ID: ${{ secrets.GOOGLE_CALENDAR_ID }}
70+
GOOGLE_CALENDAR_API_KEY: ${{ secrets.GOOGLE_CALENDAR_API_KEY }}
71+
PIP_CONSTRAINT: ${{ github.workspace }}/napari/resources/constraints/constraints_py3.10_docs.txt
72+
with:
73+
run: make -C docs ${{ github.event_name == 'pull_request' && 'slimfast' || inputs.make_target }}
74+
# skipping setup stops the action from running the default (tiling) window manager
75+
# the window manager is not necessary for docs builds at this time and it was causing
76+
# problems with screenshots (https://github.com/napari/docs/issues/285)
77+
linux-setup: "echo 'skip setup'"
78+
linux-teardown: "echo 'skip teardown'"
79+
80+
- name: Upload artifact
81+
id: upload
82+
uses: actions/upload-artifact@v4
83+
with:
84+
name: docs
85+
path: docs/docs/_build/html
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
name: Trigger target build of docs
2+
3+
on:
4+
issue_comment:
5+
types: [created]
6+
workflow_dispatch:
7+
inputs:
8+
make_target:
9+
description: "Enter make target: html html-noplot docs slimfast slimgallery"
10+
type: string
11+
default: 'slimfast'
12+
13+
permissions:
14+
statuses: write
15+
actions: read
16+
contents: read
17+
18+
jobs:
19+
determine-target:
20+
runs-on: ubuntu-latest
21+
outputs:
22+
target: ${{ steps.determine-target.outputs.target }}
23+
if: |
24+
(github.event_name == 'issue_comment' &&
25+
github.event.issue.pull_request != '' &&
26+
contains(github.event.comment.body, '@napari-bot make')) ||
27+
github.event_name == 'workflow_dispatch'
28+
steps:
29+
- uses: actions/checkout@v4
30+
with:
31+
ref: ${{ github.event.pull_request.head.sha }}
32+
- name: Determine make target
33+
id: determine-target
34+
env:
35+
COMMENT_BODY: ${{ github.event.comment.body }}
36+
MAKE_TARGET_INPUT: ${{ github.event.inputs.make_target }}
37+
run: |
38+
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
39+
if [ -z "$MAKE_TARGET_INPUT" ]; then
40+
echo "::error::No make target provided in workflow dispatch input."
41+
exit 1
42+
fi
43+
echo "Using manual input target: $MAKE_TARGET_INPUT"
44+
echo "target=$MAKE_TARGET_INPUT" >> "$GITHUB_OUTPUT"
45+
else
46+
# Safely handle comment body through environment variable
47+
TARGET=$(echo "$COMMENT_BODY" | grep -oP '(?<=make\s)\w+' || echo "slimfast")
48+
ALLOWED_TARGETS="html html-noplot docs slimfast slimgallery"
49+
if ! grep -qw "$TARGET" <<< "$ALLOWED_TARGETS"; then
50+
echo "::error::Invalid target '$TARGET'. Allowed targets: $ALLOWED_TARGETS"
51+
exit 1
52+
fi
53+
echo "Using comment target: $TARGET"
54+
echo "target=$TARGET" >> "$GITHUB_OUTPUT"
55+
fi
56+
57+
trigger-circleci:
58+
needs: determine-target
59+
runs-on: ubuntu-latest
60+
env:
61+
BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
62+
MAKE_TARGET: ${{ needs.determine-target.outputs.target }}
63+
steps:
64+
- name: Trigger CircleCI Pipeline
65+
run: |
66+
# Validate branch name isn't empty
67+
if [ -z "$BRANCH_NAME" ]; then
68+
echo "::error::Branch name is empty"
69+
exit 1
70+
fi
71+
72+
curl -X POST \
73+
-H "Content-Type: application/json" \
74+
-H "Circle-Token: ${{ secrets.CIRCLECI_TOKEN }}" \
75+
-d '{
76+
"branch": "'"$BRANCH_NAME"'",
77+
"parameters": {
78+
"make_target": "'"$MAKE_TARGET"'"
79+
}
80+
}' \
81+
"https://circleci.com/api/v2/project/gh/psobolewskiPhD/napari-docs/pipeline"
82+
83+
trigger-artifact-build:
84+
needs: determine-target
85+
uses: ./.github/workflows/build_docs.yml
86+
with:
87+
make_target: ${{ needs.determine-target.outputs.target }}
88+
89+
report-status:
90+
needs: [determine-target, trigger-artifact-build]
91+
runs-on: ubuntu-latest
92+
steps:
93+
- name: Get Reusable Workflow Job URL
94+
id: get-job-url
95+
uses: actions/github-script@v7
96+
with:
97+
script: |
98+
const { data: runs } = await github.rest.actions.listWorkflowRuns({
99+
owner: context.repo.owner,
100+
repo: context.repo.repo,
101+
workflow_id: 'build_trigger.yml',
102+
head_sha: `${{ github.event.pull_request.head.sha }}`,
103+
per_page: 1
104+
});
105+
106+
if (!runs.workflow_runs?.length) {
107+
throw new Error('No workflow runs found');
108+
}
109+
110+
const runId = runs.workflow_runs[0].id;
111+
const { data: jobs } = await github.rest.actions.listJobsForWorkflowRun({
112+
owner: context.repo.owner,
113+
repo: context.repo.repo,
114+
run_id: runId
115+
});
116+
117+
const job = jobs.jobs.find(j => j.name === 'trigger-artifact-build / Build & Upload Artifact');
118+
if (!job) {
119+
throw new Error(`Job not found. Available jobs: ${jobs.jobs.map(j => j.name).join(', ')}`);
120+
}
121+
122+
core.setOutput('url', job.html_url);
123+
124+
- name: Update PR Check with Job URL
125+
uses: actions/github-script@v7
126+
env:
127+
SHA: ${{ github.event.pull_request.head.sha || github.sha }}
128+
STATE: ${{ needs.trigger-artifact-build.result || 'pending' }}
129+
TARGET_URL: ${{ steps.get-job-url.outputs.url }}
130+
with:
131+
script: |
132+
const targetUrl = String(process.env.TARGET_URL).trim();
133+
await github.rest.repos.createCommitStatus({
134+
owner: context.repo.owner,
135+
repo: context.repo.repo,
136+
sha: process.env.SHA,
137+
state: process.env.STATE,
138+
target_url: targetUrl,
139+
context: "Triggered Docs Artifact Build",
140+
description: "View artifact build logs"
141+
});

docs/developers/contributing/documentation/index.md

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,33 @@ or [editing an existing file](https://docs.github.com/en/repositories/working-wi
4343
on the [napari/docs](https://github.com/napari/docs) GitHub repository.
4444
It's best if you first [fork](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo) the [napari/docs](https://github.com/napari/docs) repository to your own GitHub account, create a [feature branch](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-and-deleting-branches-within-your-repository#creating-a-branch), upload/create/edit files through the GitHub web interface, and then [open a pull request from your fork](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork) back to [napari-docs](https://github.com/napari/docs).
4545

46-
You will also be able to [preview the documentation](doc_view_ci) as it would appear on [napari.org](https://napari.org/dev) by
47-
using the `Check the rendered docs here!` action at the bottom of your PR which will go to a preview site on [CircleCI](https://circleci.com/).
48-
A member of the maintenance
49-
team will help with updating the [napari.org](https://napari.org/dev) table of contents where necessary (by placing a reference to your new file in [docs/_toc.yml](update-toc)) and making sure your documentation has built correctly.
46+
When you submit your PR, CI will kick off several jobs, including generation of a preview of
47+
the documentation. By default, CI will use the `slimfast` build ("make target"), which
48+
doesn't build any content from outside the `docs` repository or run any `docs` notebook cells.
49+
This is great for seeing the copy and formatting. If you want to preview other elements,
50+
you can trigger more complete builds by commenting on the PR with:
51+
```
52+
@napari-bot make <target>
53+
```
54+
where `<target>` can be:
55+
- `html` : a full build, just like napari.org live
56+
- `html-noplot` : a full build, but without the gallery examples from `napari/napari`
57+
- `docs` : only the content from `napari/docs`, with notebook code cells executed
58+
- `slimfast` : the default, only the content from `napari/docs`, without code cell execution
59+
- `slimgallery` : `slimfast`, but also builds the gallery examples from `napari/napari`
60+
61+
For more information about these targets see the ["building locally"](build_docs_locally) section
62+
of the documentation, including the part on [specialized builds](#building-what-you-need).
63+
64+
Once the jobs complete you will also be able to [preview the documentation](doc_view_ci) by
65+
using the `Check the rendered docs here!` action at the bottom of your PR, which will go to a
66+
preview website on [CircleCI](https://circleci.com/). Alternatively, you can download a zip file
67+
of [the build artifact](#download-documentation-artifact) and open the html files directly in your browser. For a build triggered by a comment, use
68+
the "Triggered Docs Artifact Build" link.
69+
70+
If needed, a member of the maintenance team will help with updating the [napari.org](https://napari.org/dev)
71+
table of contents where necessary (by placing a reference to your new file in [docs/_toc.yml](update-toc))
72+
and making sure your documentation has built correctly.
5073

5174
(prerequisites)=
5275
## Prerequisites for a local setup to contribute to the napari documentation

0 commit comments

Comments
 (0)