Skip to content

Commit 8543be1

Browse files
committed
Create README.md
1 parent 3e78c50 commit 8543be1

File tree

1 file changed

+330
-0
lines changed

1 file changed

+330
-0
lines changed

README.md

Lines changed: 330 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,330 @@
1+
# Documentation Setup and Automation Guide
2+
3+
This guide explains how to set up and maintain documentation for your Python library in a dedicated `docs` branch with GitHub Pages. It also details how all the steps, once configured, are automated via a GitHub Actions workflow that updates and builds documentation upon new releases.
4+
5+
For example, for the repository **https://"https://github.com/ORGANIZATION/REPO/** the corresponding GitHub documentation page will be **https://"https://ORGANIZATION.github.io/REPO/**.
6+
7+
Key points:
8+
- **Dedicated `docs` branch**: The documentation is served from the `docs` folder on the `docs` branch, utilizing GitHub Pages (so that it's updated automatically in the GitHub page when this folder is changed through a push).
9+
- **Automated `.rst` File Generation**: A Python script (`generate_doc_markdown.py`) scans your codebase and generates the `.rst` files automatically.
10+
- **Sphinx & Extensions**: Use Sphinx, `sphinx-automodapi`, and `pydata-sphinx-theme` to build the docs.
11+
- **CI/CD with GitHub Actions**: Once set up, the provided GitHub Actions workflow automatically updates the documentation every time a new release of the repository is published.
12+
13+
Logical flow of documentation updates:
14+
1. **Initial Setup**: Configure `docs` branch, Sphinx, and dependencies.
15+
2. **Automated `.rst` Generation**: Use `generate_doc_markdown.py` to generate `.rst` files from code.
16+
3. **Building Locally (if needed)**: `make html` to verify documentation locally.
17+
4. **Release Trigger**: On publishing a new release, the GitHub Actions workflow:
18+
- Checks out `docs` branch and release code.
19+
- Generates `.rst` files.
20+
- Builds HTML docs.
21+
- Deploys the updated docs to `docs/latest` and `docs/<version>`.
22+
5. **Automatic Deployment**: Changes are committed back to `docs` branch and served on GitHub Pages.
23+
24+
## 1. Create the `docs` Branch on GitHub
25+
26+
- Create a `docs` branch in your repository.
27+
- Go to the repository’s **Settings**.
28+
- Under **Pages**, configure the site to be served from the `docs/` folder on the `docs` branch.
29+
30+
## 2. Clean the `docs` Branch
31+
32+
- In the `docs` branch, delete all files except for `.gitignore` (and of course `.git`).
33+
- The branch should now be nearly empty, ready for the documentation setup.
34+
35+
## 3. Configuring Sphinx
36+
37+
You need to perform the following steps checking out the `docs` branch of your repo.
38+
39+
**Install Dependencies:**
40+
41+
```bash
42+
pip install sphinx sphinx-automodapi pydata-sphinx-theme
43+
```
44+
45+
**Run `sphinx-quickstart`:**
46+
47+
```bash
48+
sphinx-quickstart
49+
```
50+
51+
If the command is not found:
52+
53+
```bash
54+
python -m sphinx.cmd.quickstart
55+
```
56+
57+
This generates:
58+
59+
- `conf.py` (Sphinx configuration file)
60+
- `Makefile`
61+
- `index.rst`
62+
- `make.bat`
63+
64+
**Edit `conf.py`:**
65+
66+
- Add your code to `sys.path` so Sphinx can locate it:
67+
68+
```python
69+
import sys
70+
sys.path.insert(0, "release-code")
71+
```
72+
73+
- Add code to get the release from enviroment variable:
74+
75+
```python
76+
import os
77+
78+
# get release from environment variable
79+
version = os.environ.get("VERSION", "")
80+
if not version:
81+
print("Error: VERSION environment variable not set.")
82+
sys.exit(1)
83+
```
84+
85+
- Edit/Add the version number to appear in the title:
86+
87+
```python
88+
release = version
89+
```
90+
91+
- Add required extensions:
92+
93+
```python
94+
extensions = ["sphinx_automodapi.automodapi", "sphinx.ext.githubpages"]
95+
numpydoc_show_class_members = False
96+
automodapi_inheritance_diagram = False
97+
```
98+
99+
- Set the theme and options (**change ORGANIZATION and REPO as needed**):
100+
101+
```python
102+
html_theme = "pydata_sphinx_theme"
103+
html_static_path = ["_static"]
104+
html_theme_options = {
105+
"switcher": {
106+
"json_url": "https://ORGANIZATION.github.io/REPO/latest/_static/switcher.json",
107+
"version_match": version,
108+
},
109+
"navbar_end": [
110+
"version-switcher",
111+
"navbar-icon-links",
112+
],
113+
}
114+
```
115+
116+
**Create/edit `index.rst`:**
117+
118+
Place an `index.rst` file at the root of the `docs` branch:
119+
120+
```rst
121+
.. yourproject documentation master file.
122+
123+
yourproject documentation
124+
=========================
125+
126+
.. toctree::
127+
:maxdepth: 2
128+
:caption: Contents:
129+
130+
src/Documentation
131+
```
132+
133+
## 4. Copy the File to Generate `.rst` Files with the Script
134+
135+
Copy the Python script `generate_doc_markdown.py` to automate the `.rst` creation into the root folder of the `docs`branch.
136+
137+
> This will automate the `.rst` creation. It:
138+
>
139+
> - Identifies top-level modules and packages in `release-code/<library_name>`.
140+
> - Generates `.rst` files for each module.
141+
> - Creates a `Documentation.rst` that acts as a table of contents.
142+
>
143+
> **Usage:**
144+
>
145+
> ```bash
146+
> python generate_doc_markdown.py <library_name> [--force] [--exclude=mod1,mod2,...] [--output-dir=src]
147+
> ```
148+
>
149+
> **Arguments:**
150+
>
151+
> - `<library_name>`: The name of your library (the folder under `release-code`).
152+
> - `--force` / `-f`: Overwrite existing `.rst` files if present.
153+
> - `--exclude` / `-e`: Exclude specific submodules from documentation.
154+
> - `--output-dir` / `-o`: Directory to write output files, default is `src`.
155+
>
156+
> **Example:**
157+
>
158+
> ```bash
159+
> python generate_doc_markdown.py deeplay --force --exclude=_internal --output-dir=src
160+
> ```
161+
>
162+
> This command creates the `src` folder (if needed), generates `.rst` files for each module, and updates `Documentation.rst` automatically.
163+
164+
## 5. Add the Version Switcher
165+
166+
Add the version switcher `switcher.json` to the folder `_static`of the `docs`branch.
167+
168+
```
169+
[]
170+
```
171+
172+
173+
> The version switcher allows users to navigate between different versions of your documentation directly from the site’s navigation bar. This is handled by the switcher.json file, stored in _static/switcher.json, which follows a structure like:
174+
>
175+
> ```
176+
> [
177+
> {
178+
> "name": "0.1.0",
179+
> "version": "0.1.0",
180+
> "url": "https://ORGANIZATION.github.io/REPO/0.1.0/"
181+
> }
182+
> ]
183+
> ```
184+
>
185+
> How it works:
186+
>
187+
> Each entry in switcher.json specifies a documentation version and the URL where it can be found.
188+
> The html_theme_options in conf.py references this file, enabling a dropdown menu to choose the version.
189+
> The GitHub Actions workflow updates switcher.json upon new releases by prepending the new version into this list. This ensures that the newly released version appears in the version switcher, and users can easily switch to it.
190+
191+
## 6. Add the Following Files
192+
193+
- **`doc_requirements.txt`**: Lists the dependencies (Sphinx, sphinx-automodapi, pydata-sphinx-theme, etc.) needed to build documentation.
194+
195+
- **`docs`** folder: Where documentation content and builds are hosted. This should include **index.html.** (to redirect to the `docs/latest` folder) and **.nojekyll** (to prevent GitHub Pages from ignoring _static and other files that begin with an underscore).
196+
197+
## 7. Ensure All Special Files Are Set Up in the `docs` Branch
198+
199+
Ensure that all these files have been correctly prepared:
200+
- **`docs`** folder: Where documentation content and builds are hosted. This should include **index.html.** (to redirect to the `docs/latest` folder) and **.nojekyll** (to prevent GitHub Pages from ignoring _static and other files that begin with an underscore).
201+
- **`index.rst`**: Root documentation file linking to `Documentation.rst`.
202+
- **`conf.py`**: Sphinx configuration file where you set up paths, extensions, and themes.
203+
- **`generate_doc_markdown.py`**: Automation script that eliminates the need for manual `.rst` creation.
204+
- **`doc_requirements.txt`**: Lists the dependencies (Sphinx, sphinx-automodapi, pydata-sphinx-theme, etc.) needed to build documentation.
205+
- **`Makefile`**: Provides convenient commands (`make html`) to build the docs locally.
206+
- **`_static/switcher.json`**: Used for version switching within the docs (managed by the workflow).
207+
- **`README.md`**: Copy this readme file as well into the `docs`branch.
208+
209+
## 8. Add Worflow for Automated Documentation on Release
210+
211+
Add the `docs.yml` to the `.github/workflows/docs.yml` folder of the branch of your project from which the release will be made.
212+
213+
In the code below, ensure that PYTHON_PACKAGE, ORGANIZATON and REPO are the correct ones. Other minor changes might be needed (e.g., Python version).
214+
215+
> This workflow:
216+
>
217+
> 1. Checks out the `docs` branch.
218+
> 2. Sets up Python and installs dependencies from `requirements.txt`.
219+
> 3. Checks out the release code (tag specified by the release event) into `release-code`.
220+
> 4. Runs the `generate_doc_markdown.py` script to generate/update `.rst` files.
221+
> 5. Builds the Sphinx documentation.
222+
> 6. Copies the built HTML files to `docs/latest` and `docs/{version}` directories.
223+
> 7. Commits and pushes these changes back to the `docs` branch, updating the live documentation on GitHub Pages.
224+
>
225+
> **Example Workflow (in `.github/workflows/docs.yml`):**
226+
>
227+
> ```yaml
228+
> name: Update Documentation
229+
>
230+
> on:
231+
> release:
232+
> types:
233+
> - published
234+
> workflow_dispatch:
235+
> inputs:
236+
> test_tag:
237+
> description: "Release tag to simulate"
238+
> required: true
239+
>
240+
> jobs:
241+
> update-docs:
242+
> name: Update Documentation
243+
> runs-on: ubuntu-latest
244+
>
245+
> steps:
246+
> # Step 1: Check out the docs branch
247+
> - name: Checkout docs branch
248+
> uses: actions/checkout@v3
249+
> with:
250+
> ref: docs
251+
>
252+
> # Step 2: Set up Python
253+
> - name: Set up Python
254+
> uses: actions/setup-python@v4
255+
> with:
256+
> python-version: "3.9"
257+
>
258+
> # Step 3: Install dependencies
259+
> - name: Install dependencies
260+
> run: |
261+
> python -m pip install --upgrade pip
262+
> pip install -r doc_requirements.txt
263+
>
264+
> # Step 4: Pull the release code into a separate directory
265+
> - name: Checkout release code
266+
> uses: actions/checkout@v3
267+
> with:
268+
> path: release-code
269+
> # Use the test tag from workflow_dispatch or the actual release tag
270+
> ref: ${{ github.event.inputs.test_tag || github.event.release.tag_name }}
271+
>
272+
> - name: Install the package
273+
> run: |
274+
> cd release-code
275+
> pip install -e .
276+
>
277+
> - name: Create the markdown files
278+
> run: |
279+
> python generate_doc_markdown.py PYTHON_PACKAGE --exclude=tests,test
280+
>
281+
> # Step 5: Set version variable
282+
> - name: Set version variable
283+
> run: |
284+
> VERSION=${{ github.event.inputs.test_tag || github.event.release.tag_name }}
285+
> echo "VERSION=$VERSION" >> $GITHUB_ENV
286+
>
287+
> # Step 6: Update switcher.json
288+
> - name: Update switcher.json
289+
> run: |
290+
> SWITCHER_FILE=_static/switcher.json
291+
> jq --arg version "$VERSION" \
292+
> '. |= [{"name": $version, "version": $version, "url": "https://ORGANIZATION.github.io/REPO/\($version)/"}] + .' \
293+
> $SWITCHER_FILE > temp.json && mv temp.json $SWITCHER_FILE
294+
>
295+
> # Step 7: Build documentation using Sphinx into html
296+
> - name: Build documentation
297+
> env:
298+
> SPHINX_APIDOC_DIR: release-code
299+
> run: make html
300+
>
301+
> # Step 8: Copy built HTML to `docs/latest` and `docs/{version}`
302+
> - name: Copy built HTML
303+
> run: |
304+
> mkdir -p docs/latest
305+
> mkdir -p docs/$VERSION
306+
> cp -r _build/html/* docs/latest/
307+
> cp -r _build/html/* docs/$VERSION/
308+
>
309+
> # Step 9: Clean up `release-code` directory
310+
> - name: Remove release-code directory
311+
> run: rm -rf release-code
312+
>
313+
> # Step 10: Commit and push changes
314+
> - name: Commit and push changes
315+
> run: |
316+
> git config user.name "github-actions[bot]"
317+
> git config user.email "github-actions[bot]@users.noreply.github.com"
318+
> git add docs/latest docs/$VERSION _static/switcher.json
319+
> git commit -m "Update docs for release $VERSION"
320+
> git push
321+
> ```
322+
323+
## 9. Enable Write Permissions for GitHub Actions
324+
325+
Ensure that GitHub Actions have write permissions to the repository following these steps:
326+
- Go to your repository on GitHub.
327+
- Navigate to Settings > Actions > General.
328+
- Scroll to the Workflow permissions section.
329+
- Select Read and write permissions.
330+
- Click Save.

0 commit comments

Comments
 (0)