🔧 Update docs build setup, add support for sponsors, add sponsor GOVCERT.LU (#720)
This commit is contained in:
parent
cc11619c67
commit
276bcf788c
10
.github/workflows/build-docs.yml
vendored
10
.github/workflows/build-docs.yml
vendored
@ -30,6 +30,8 @@ jobs:
|
|||||||
- pyproject.toml
|
- pyproject.toml
|
||||||
- mkdocs.yml
|
- mkdocs.yml
|
||||||
- mkdocs.insiders.yml
|
- mkdocs.insiders.yml
|
||||||
|
- ./github/workflows/build-docs.yml
|
||||||
|
- ./github/workflows/deploy-docs.yml
|
||||||
|
|
||||||
build-docs:
|
build-docs:
|
||||||
needs:
|
needs:
|
||||||
@ -69,12 +71,10 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
key: mkdocs-cards-${{ github.ref }}
|
key: mkdocs-cards-${{ github.ref }}
|
||||||
path: .cache
|
path: .cache
|
||||||
|
- name: Verify README
|
||||||
|
run: python ./scripts/docs.py verify-readme
|
||||||
- name: Build Docs
|
- name: Build Docs
|
||||||
if: github.event_name == 'pull_request' && github.secret_source != 'Actions'
|
run: python ./scripts/docs.py build
|
||||||
run: python -m poetry run mkdocs build
|
|
||||||
- name: Build Docs with Insiders
|
|
||||||
if: github.event_name != 'pull_request' || github.secret_source == 'Actions'
|
|
||||||
run: python -m poetry run mkdocs build --config-file mkdocs.insiders.yml
|
|
||||||
- uses: actions/upload-artifact@v3
|
- uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: docs-site
|
name: docs-site
|
||||||
|
10
README.md
10
README.md
@ -38,6 +38,14 @@ The key features are:
|
|||||||
* **Extensible**: You have all the power of SQLAlchemy and Pydantic underneath.
|
* **Extensible**: You have all the power of SQLAlchemy and Pydantic underneath.
|
||||||
* **Short**: Minimize code duplication. A single type annotation does a lot of work. No need to duplicate models in SQLAlchemy and Pydantic.
|
* **Short**: Minimize code duplication. A single type annotation does a lot of work. No need to duplicate models in SQLAlchemy and Pydantic.
|
||||||
|
|
||||||
|
## Sponsors
|
||||||
|
|
||||||
|
<!-- sponsors -->
|
||||||
|
|
||||||
|
<a href="https://www.govcert.lu" target="_blank" title="This project is being supported by GOVCERT.LU"><img src="https://sqlmodel.tiangolo.com/img/sponsors/govcert.png"></a>
|
||||||
|
|
||||||
|
<!-- /sponsors -->
|
||||||
|
|
||||||
## SQL Databases in FastAPI
|
## SQL Databases in FastAPI
|
||||||
|
|
||||||
<a href="https://fastapi.tiangolo.com" target="_blank"><img src="https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png" style="width: 20%;"></a>
|
<a href="https://fastapi.tiangolo.com" target="_blank"><img src="https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png" style="width: 20%;"></a>
|
||||||
@ -68,7 +76,7 @@ Successfully installed sqlmodel
|
|||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|
||||||
For an introduction to databases, SQL, and everything else, see the <a href="https://sqlmodel.tiangolo.com" target="_blank">SQLModel documentation</a>.
|
For an introduction to databases, SQL, and everything else, see the <a href="https://sqlmodel.tiangolo.com/databases/" target="_blank">SQLModel documentation</a>.
|
||||||
|
|
||||||
Here's a quick example. ✨
|
Here's a quick example. ✨
|
||||||
|
|
||||||
|
6
data/sponsors.yml
Normal file
6
data/sponsors.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
gold: []
|
||||||
|
silver:
|
||||||
|
- url: https://www.govcert.lu
|
||||||
|
title: This project is being supported by GOVCERT.LU
|
||||||
|
img: https://sqlmodel.tiangolo.com/img/sponsors/govcert.png
|
||||||
|
bronze: []
|
BIN
docs/img/sponsors/govcert.png
Normal file
BIN
docs/img/sponsors/govcert.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.8 KiB |
@ -1,3 +1,7 @@
|
|||||||
|
<style>
|
||||||
|
.md-content .md-typeset h1 { display: none; }
|
||||||
|
</style>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://sqlmodel.tiangolo.com"><img src="https://sqlmodel.tiangolo.com/img/logo-margin/logo-margin-vector.svg" alt="SQLModel"></a>
|
<a href="https://sqlmodel.tiangolo.com"><img src="https://sqlmodel.tiangolo.com/img/logo-margin/logo-margin-vector.svg" alt="SQLModel"></a>
|
||||||
</p>
|
</p>
|
||||||
@ -38,6 +42,21 @@ The key features are:
|
|||||||
* **Extensible**: You have all the power of SQLAlchemy and Pydantic underneath.
|
* **Extensible**: You have all the power of SQLAlchemy and Pydantic underneath.
|
||||||
* **Short**: Minimize code duplication. A single type annotation does a lot of work. No need to duplicate models in SQLAlchemy and Pydantic.
|
* **Short**: Minimize code duplication. A single type annotation does a lot of work. No need to duplicate models in SQLAlchemy and Pydantic.
|
||||||
|
|
||||||
|
## Sponsors
|
||||||
|
|
||||||
|
<!-- sponsors -->
|
||||||
|
|
||||||
|
{% if sponsors %}
|
||||||
|
{% for sponsor in sponsors.gold -%}
|
||||||
|
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
|
||||||
|
{% endfor -%}
|
||||||
|
{%- for sponsor in sponsors.silver -%}
|
||||||
|
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<!-- /sponsors -->
|
||||||
|
|
||||||
## SQL Databases in FastAPI
|
## SQL Databases in FastAPI
|
||||||
|
|
||||||
<a href="https://fastapi.tiangolo.com" target="_blank"><img src="https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png" style="width: 20%;"></a>
|
<a href="https://fastapi.tiangolo.com" target="_blank"><img src="https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png" style="width: 20%;"></a>
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
INHERIT: mkdocs.yml
|
|
||||||
plugins:
|
plugins:
|
||||||
- search
|
social:
|
||||||
- social
|
typeset:
|
||||||
|
6
mkdocs.maybe-insiders.yml
Normal file
6
mkdocs.maybe-insiders.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# Define this here and not in the main mkdocs.yml file because that one could be auto
|
||||||
|
# updated and written, and the script would remove the env var
|
||||||
|
INHERIT: !ENV [INSIDERS_FILE, './mkdocs.no-insiders.yml']
|
||||||
|
markdown_extensions:
|
||||||
|
pymdownx.highlight:
|
||||||
|
linenums: !ENV [LINENUMS, false]
|
0
mkdocs.no-insiders.yml
Normal file
0
mkdocs.no-insiders.yml
Normal file
28
mkdocs.yml
28
mkdocs.yml
@ -1,3 +1,4 @@
|
|||||||
|
INHERIT: ./mkdocs.maybe-insiders.yml
|
||||||
site_name: SQLModel
|
site_name: SQLModel
|
||||||
site_description: SQLModel, SQL databases in Python, designed for simplicity, compatibility, and robustness.
|
site_description: SQLModel, SQL databases in Python, designed for simplicity, compatibility, and robustness.
|
||||||
site_url: https://sqlmodel.tiangolo.com/
|
site_url: https://sqlmodel.tiangolo.com/
|
||||||
@ -36,6 +37,11 @@ theme:
|
|||||||
repo_name: tiangolo/sqlmodel
|
repo_name: tiangolo/sqlmodel
|
||||||
repo_url: https://github.com/tiangolo/sqlmodel
|
repo_url: https://github.com/tiangolo/sqlmodel
|
||||||
edit_uri: ''
|
edit_uri: ''
|
||||||
|
plugins:
|
||||||
|
search: null
|
||||||
|
markdownextradata:
|
||||||
|
data: ./data
|
||||||
|
|
||||||
nav:
|
nav:
|
||||||
- SQLModel: index.md
|
- SQLModel: index.md
|
||||||
- features.md
|
- features.md
|
||||||
@ -98,30 +104,28 @@ nav:
|
|||||||
- release-notes.md
|
- release-notes.md
|
||||||
|
|
||||||
markdown_extensions:
|
markdown_extensions:
|
||||||
- markdown.extensions.attr_list
|
markdown.extensions.attr_list:
|
||||||
- markdown.extensions.tables
|
markdown.extensions.tables:
|
||||||
- markdown.extensions.md_in_html
|
markdown.extensions.md_in_html:
|
||||||
- toc:
|
toc:
|
||||||
permalink: true
|
permalink: true
|
||||||
- pymdownx.superfences:
|
pymdownx.superfences:
|
||||||
custom_fences:
|
custom_fences:
|
||||||
- name: mermaid
|
- name: mermaid
|
||||||
class: mermaid
|
class: mermaid
|
||||||
format: !!python/name:pymdownx.superfences.fence_code_format ''
|
format: !!python/name:pymdownx.superfences.fence_code_format ''
|
||||||
- pymdownx.betterem
|
pymdownx.betterem:
|
||||||
- pymdownx.highlight:
|
pymdownx.blocks.details:
|
||||||
linenums: !ENV [LINENUMS, false]
|
pymdownx.blocks.admonition:
|
||||||
- pymdownx.blocks.details
|
|
||||||
- pymdownx.blocks.admonition:
|
|
||||||
types:
|
types:
|
||||||
- note
|
- note
|
||||||
- info
|
- info
|
||||||
- tip
|
- tip
|
||||||
- warning
|
- warning
|
||||||
- danger
|
- danger
|
||||||
- pymdownx.blocks.tab:
|
pymdownx.blocks.tab:
|
||||||
alternate_style: True
|
alternate_style: True
|
||||||
- mdx_include
|
mdx_include:
|
||||||
|
|
||||||
extra:
|
extra:
|
||||||
analytics:
|
analytics:
|
||||||
|
@ -50,6 +50,8 @@ fastapi = "^0.103.2"
|
|||||||
ruff = "^0.1.2"
|
ruff = "^0.1.2"
|
||||||
# For FastAPI tests
|
# For FastAPI tests
|
||||||
httpx = "0.24.1"
|
httpx = "0.24.1"
|
||||||
|
typer-cli = "^0.0.13"
|
||||||
|
mkdocs-markdownextradata-plugin = ">=0.1.7,<0.3.0"
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["poetry-core"]
|
requires = ["poetry-core"]
|
||||||
|
155
scripts/docs.py
Normal file
155
scripts/docs.py
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import subprocess
|
||||||
|
from functools import lru_cache
|
||||||
|
from http.server import HTTPServer, SimpleHTTPRequestHandler
|
||||||
|
from importlib import metadata
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import mkdocs.commands.build
|
||||||
|
import mkdocs.commands.serve
|
||||||
|
import mkdocs.config
|
||||||
|
import mkdocs.utils
|
||||||
|
import typer
|
||||||
|
from jinja2 import Template
|
||||||
|
|
||||||
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
|
||||||
|
mkdocs_name = "mkdocs.yml"
|
||||||
|
en_docs_path = Path("")
|
||||||
|
|
||||||
|
app = typer.Typer()
|
||||||
|
|
||||||
|
|
||||||
|
@lru_cache
|
||||||
|
def is_mkdocs_insiders() -> bool:
|
||||||
|
version = metadata.version("mkdocs-material")
|
||||||
|
return "insiders" in version
|
||||||
|
|
||||||
|
|
||||||
|
@app.callback()
|
||||||
|
def callback() -> None:
|
||||||
|
if is_mkdocs_insiders():
|
||||||
|
os.environ["INSIDERS_FILE"] = "./mkdocs.insiders.yml"
|
||||||
|
# For MacOS with insiders and Cairo
|
||||||
|
os.environ["DYLD_FALLBACK_LIBRARY_PATH"] = "/opt/homebrew/lib"
|
||||||
|
|
||||||
|
|
||||||
|
index_sponsors_template = """
|
||||||
|
{% if sponsors %}
|
||||||
|
{% for sponsor in sponsors.gold -%}
|
||||||
|
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}"></a>
|
||||||
|
{% endfor -%}
|
||||||
|
{%- for sponsor in sponsors.silver -%}
|
||||||
|
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}"></a>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def generate_readme_content() -> str:
|
||||||
|
en_index = en_docs_path / "docs" / "index.md"
|
||||||
|
content = en_index.read_text("utf-8")
|
||||||
|
match_pre = re.search(r"</style>\n\n", content)
|
||||||
|
match_start = re.search(r"<!-- sponsors -->", content)
|
||||||
|
match_end = re.search(r"<!-- /sponsors -->", content)
|
||||||
|
sponsors_data_path = en_docs_path / "data" / "sponsors.yml"
|
||||||
|
sponsors = mkdocs.utils.yaml_load(sponsors_data_path.read_text(encoding="utf-8"))
|
||||||
|
if not (match_start and match_end):
|
||||||
|
raise RuntimeError("Couldn't auto-generate sponsors section")
|
||||||
|
if not match_pre:
|
||||||
|
raise RuntimeError("Couldn't find pre section (<style>) in index.md")
|
||||||
|
frontmatter_end = match_pre.end()
|
||||||
|
pre_end = match_start.end()
|
||||||
|
post_start = match_end.start()
|
||||||
|
template = Template(index_sponsors_template)
|
||||||
|
message = template.render(sponsors=sponsors)
|
||||||
|
pre_content = content[frontmatter_end:pre_end]
|
||||||
|
post_content = content[post_start:]
|
||||||
|
new_content = pre_content + message + post_content
|
||||||
|
return new_content
|
||||||
|
|
||||||
|
|
||||||
|
@app.command()
|
||||||
|
def generate_readme() -> None:
|
||||||
|
"""
|
||||||
|
Generate README.md content from main index.md
|
||||||
|
"""
|
||||||
|
typer.echo("Generating README")
|
||||||
|
readme_path = Path("README.md")
|
||||||
|
new_content = generate_readme_content()
|
||||||
|
readme_path.write_text(new_content, encoding="utf-8")
|
||||||
|
|
||||||
|
|
||||||
|
@app.command()
|
||||||
|
def verify_readme() -> None:
|
||||||
|
"""
|
||||||
|
Verify README.md content from main index.md
|
||||||
|
"""
|
||||||
|
typer.echo("Verifying README")
|
||||||
|
readme_path = Path("README.md")
|
||||||
|
generated_content = generate_readme_content()
|
||||||
|
readme_content = readme_path.read_text("utf-8")
|
||||||
|
if generated_content != readme_content:
|
||||||
|
typer.secho(
|
||||||
|
"README.md outdated from the latest index.md", color=typer.colors.RED
|
||||||
|
)
|
||||||
|
raise typer.Abort()
|
||||||
|
typer.echo("Valid README ✅")
|
||||||
|
|
||||||
|
|
||||||
|
@app.command()
|
||||||
|
def live() -> None:
|
||||||
|
"""
|
||||||
|
Serve with livereload a docs site for a specific language.
|
||||||
|
|
||||||
|
This only shows the actual translated files, not the placeholders created with
|
||||||
|
build-all.
|
||||||
|
|
||||||
|
Takes an optional LANG argument with the name of the language to serve, by default
|
||||||
|
en.
|
||||||
|
"""
|
||||||
|
# Enable line numbers during local development to make it easier to highlight
|
||||||
|
os.environ["LINENUMS"] = "true"
|
||||||
|
mkdocs.commands.serve.serve(dev_addr="127.0.0.1:8008")
|
||||||
|
|
||||||
|
|
||||||
|
@app.command()
|
||||||
|
def build() -> None:
|
||||||
|
"""
|
||||||
|
Build the docs.
|
||||||
|
"""
|
||||||
|
insiders_env_file = os.environ.get("INSIDERS_FILE")
|
||||||
|
print(f"Insiders file {insiders_env_file}")
|
||||||
|
if is_mkdocs_insiders():
|
||||||
|
print("Using insiders")
|
||||||
|
print("Building docs")
|
||||||
|
subprocess.run(["mkdocs", "build"], check=True)
|
||||||
|
typer.secho("Successfully built docs", color=typer.colors.GREEN)
|
||||||
|
|
||||||
|
|
||||||
|
@app.command()
|
||||||
|
def serve() -> None:
|
||||||
|
"""
|
||||||
|
A quick server to preview a built site.
|
||||||
|
|
||||||
|
For development, prefer the command live (or just mkdocs serve).
|
||||||
|
|
||||||
|
This is here only to preview the documentation site.
|
||||||
|
|
||||||
|
Make sure you run the build command first.
|
||||||
|
"""
|
||||||
|
typer.echo("Warning: this is a very simple server.")
|
||||||
|
typer.echo("For development, use the command live instead.")
|
||||||
|
typer.echo("This is here only to preview the documentation site.")
|
||||||
|
typer.echo("Make sure you run the build command first.")
|
||||||
|
os.chdir("site")
|
||||||
|
server_address = ("", 8008)
|
||||||
|
server = HTTPServer(server_address, SimpleHTTPRequestHandler)
|
||||||
|
typer.echo("Serving at: http://127.0.0.1:8008")
|
||||||
|
server.serve_forever()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
app()
|
Loading…
x
Reference in New Issue
Block a user