diff --git a/.github/workflows/container-deploy.yml b/.github/workflows/container-deploy.yml
index 5ce642b1..2576052e 100644
--- a/.github/workflows/container-deploy.yml
+++ b/.github/workflows/container-deploy.yml
@@ -63,6 +63,19 @@ jobs:
intervalSeconds: 10
timeoutSeconds: 600 # 10m
+ - name: Do something if build isn't launch
+ if: steps.wait-build-service-image.outputs.conclusion == 'does not exist'
+ run: echo job does not exist && true
+
+ - name: Do something if build fail
+ if: steps.wait-build-service-image.outputs.conclusion == 'failure'
+ run: echo fail && false # fail if build fail
+
+ - name: Do something if build timeout
+ if: steps.wait-build-service-image.outputs.conclusion == 'timed_out'
+ run: echo Timeout && false # fail if build time out
+
+
- name: Wait for search front image container build workflow
uses: tomchv/wait-my-workflow@v1.1.0
id: wait-build-front-image
@@ -74,17 +87,18 @@ jobs:
timeoutSeconds: 600 # 10m
- name: Do something if build isn't launch
- if: steps.wait-build.outputs.conclusion == 'does not exist'
+ if: steps.wait-build-front-image.outputs.conclusion == 'does not exist'
run: echo job does not exist && true
- name: Do something if build fail
- if: steps.wait-build.outputs.conclusion == 'failure'
+ if: steps.wait-build-front-image.outputs.conclusion == 'failure'
run: echo fail && false # fail if build fail
- name: Do something if build timeout
- if: steps.wait-build.outputs.conclusion == 'timed_out'
+ if: steps.wait-build-front-image.outputs.conclusion == 'timed_out'
run: echo Timeout && false # fail if build time out
+
- name: Checkout git repository
uses: appleboy/ssh-action@master
with:
diff --git a/.github/workflows/generate-doc.yml b/.github/workflows/generate-doc.yml
new file mode 100644
index 00000000..6ff31892
--- /dev/null
+++ b/.github/workflows/generate-doc.yml
@@ -0,0 +1,40 @@
+name: 📖 Documentation
+
+on:
+ pull_request:
+ # on pull request we just want to build
+ push:
+ # on merge to main, build and publish
+ # FIXME: remove ci-generate-docs before merging !
+ branches: [ "main" ]
+
+jobs:
+ documentation:
+ name: Documentation
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout sources
+ uses: actions/checkout@v4
+
+ - name: ensure we have a config file
+ run: |
+ echo "" > .envrc
+ echo CONFIG_PATH=data/config/openfoodfacts.yml >> .envrc
+ echo USER_IID=$(id -u) >>.envrc
+ echo USER_GID=$(id -g) >>.envrc
+
+ # generating project documentation
+ - name: Build documentation with MkDocs
+ run: |
+ ./scripts/generate_doc.sh
+
+ - name: Deploy documentation to GitHub Pages
+ uses: JamesIves/github-pages-deploy-action@v4.6.1
+ # we only deploy on push to main
+ if: |
+ github.event_name == 'push' && github.event.ref == 'refs/heads/main'
+ with:
+ token: ${{ secrets.GITHUB_TOKEN }}
+ branch: "gh-pages"
+ folder: gh_pages
diff --git a/.gitignore b/.gitignore
index 8dab0a74..245a3504 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,8 @@
# Project-specific
data/taxonomies
data/**/*.jsonl
+products*.jsonl.gz
+data/searchalicious-openapi.yml
# Byte-compiled / optimized / DLL files
__pycache__/
@@ -12,7 +14,6 @@ __pycache__/
# Distribution / packaging
.Python
-build/
develop-eggs/
dist/
downloads/
@@ -97,7 +98,10 @@ venv.bak/
# mkdocs documentation
-/site
+/gh_pages
+
+# github pages
+gh_pages/
# mypy
.mypy_cache/
@@ -121,4 +125,4 @@ dmypy.json
/frontend/test/
/frontend/public/dist/
/frontend/src/localization/generated/
-/frontend/public/generated/
\ No newline at end of file
+/frontend/public/generated/
diff --git a/Makefile b/Makefile
index ba39ea89..3d832ee2 100644
--- a/Makefile
+++ b/Makefile
@@ -156,6 +156,14 @@ build-translations:
@echo "🔎 Building translations …"
${DOCKER_COMPOSE} run --rm search_nodejs npm run translations:build
+generate-openapi: _ensure_network
+ @echo "🔎 Generating OpenAPI spec …"
+ ${DOCKER_COMPOSE} run --rm api python3 -m app export-openapi /opt/search/data/searchalicious-openapi.yml
+
+generate-custom-elements: _ensure_network
+ @echo "🔎 Generating custome-elements.json …"
+ ${DOCKER_COMPOSE} run --rm search_nodejs npm run analyze
+
#-------#
# Tests #
#-------#
diff --git a/app/cli/main.py b/app/cli/main.py
index b1642c06..a32ebe92 100644
--- a/app/cli/main.py
+++ b/app/cli/main.py
@@ -176,5 +176,33 @@ def run_update_daemon(
run_update_daemon(global_config)
+@cli.command()
+def export_openapi(
+ target_path: Path = typer.Argument(
+ exists=None,
+ file_okay=True,
+ dir_okay=False,
+ help="Path of target_path the YAML data file",
+ )
+):
+ import json
+
+ import yaml
+
+ from app.api import app as app_api
+
+ openapi = app_api.openapi()
+ version = openapi.get("openapi", "unknown version")
+
+ print(f"writing openapi spec v{version}")
+ with open(target_path, "w") as f:
+ if str(target_path).endswith(".json"):
+ json.dump(openapi, f, indent=2)
+ else:
+ yaml.dump(openapi, f, sort_keys=False)
+
+ print(f"spec written to {target_path}")
+
+
def main() -> None:
cli()
diff --git a/docs/.pages b/docs/.pages
index e6e673ec..e9bec3e2 100644
--- a/docs/.pages
+++ b/docs/.pages
@@ -1,3 +1,3 @@
nav:
- README.md
- - "Install": install.md
\ No newline at end of file
+ - users
diff --git a/docs/devs/index.md b/docs/devs/index.md
new file mode 100644
index 00000000..e69de29b
diff --git a/docs/reports/.pages b/docs/reports/.pages
new file mode 100644
index 00000000..a4a6dca8
--- /dev/null
+++ b/docs/reports/.pages
@@ -0,0 +1,2 @@
+# hide this directory from Mkdocs navigation
+hide: true
diff --git a/docs/users/.pages b/docs/users/.pages
new file mode 100644
index 00000000..a5b1dd76
--- /dev/null
+++ b/docs/users/.pages
@@ -0,0 +1,6 @@
+nav:
+ - tutorial.md
+ - ... | how-*.md
+ - ... | explain-*.md
+ - ... | ref-*.md
+ - ...
\ No newline at end of file
diff --git a/docs/users/index.md b/docs/users/index.md
new file mode 100644
index 00000000..e69de29b
diff --git a/docs/users/ref-openapi.md b/docs/users/ref-openapi.md
new file mode 100644
index 00000000..d2108c76
--- /dev/null
+++ b/docs/users/ref-openapi.md
@@ -0,0 +1,3 @@
+# Reference for Search-a-licious API
+
+**IMPORTANT:** do not edit this file, it is replaced by OpenAPI documentation (using redocly at documentation generation time).
\ No newline at end of file
diff --git a/docs/users/ref-web-components.md b/docs/users/ref-web-components.md
new file mode 100644
index 00000000..52de2df2
--- /dev/null
+++ b/docs/users/ref-web-components.md
@@ -0,0 +1,89 @@
+# Reference for Search-a-licious Web Components
+
+This page documents [web Components](https://developer.mozilla.org/en-US/docs/Web/API/Web_components)
+provided by Search-a-licious
+to quickly build your interfaces.
+
+## Main components
+
+### searchalicious-bar
+
+
+
+### searchalicious-results
+
+
+### searchalicious-pages
+
+
+
+### searchalicious-facets
+
+
+
+### searchalicious-chart
+
+
+
+### searchalicious-sort
+
+
+
+### searchalicious-sort-field
+
+
+
+### searchalicious-sort-script
+
+
+
+### searchalicious-button
+
+
+
+### searchalicious-count
+
+
+
+
+## Internal components
+
+### searchalicious-facet-terms
+
+
+
+### searchalicious-suggestion-entry
+
+
+
+### searchalicious-checkbox
+
+
+
+### searchalicious-radio
+
+
+
+### searchalicious-toggle
+
+
+
+### searchalicious-secondary-button
+
+
+
+### searchalicious-button-transparent
+
+
+
+### searchalicious-icon-cross
+
+
+
+### searchalicious-suggestion-entry
+
+
+
+
+
+
diff --git a/frontend/README.md b/frontend/README.md
index df977590..8e7e8dbe 100644
--- a/frontend/README.md
+++ b/frontend/README.md
@@ -62,7 +62,7 @@ This enables supporting multiple searches in the same page
* **searchalicious-facet-terms** renders the facet for terms (list of entries, with number of docs).
* it must be in a `searchalicious-facets`
* the user can select facets to filter the search
-* **searchalicious-checkbox** is a component that displays a list of suggestions
+* **searchalicious-suggestion-entry** is a component that displays a list of suggestions
* it must be in a `searchalicious-facet`
* it will influence the search adding terms to the search
* **searchalicious-checkbox** is a simple checkbox
@@ -101,6 +101,11 @@ Events always contains the search name, so we could have more than one search on
We tend to factor code when it make sense using mixins,
for example as there are lots of component that needs the search results, there is a mixin than contains the logic to register to such events (see `search-results-ctl.ts`).
+## Writing documentation
+
+We render the reference on web components using [`api-viewer`](https://api-viewer.open-wc.org/docs) web component.
+
+Please comply with JSDoc and [document every property / slots](https://api-viewer.open-wc.org/docs/guide/writing-jsdoc/) etc. on each web components.
## Tools
diff --git a/mkdocs.yml b/mkdocs.yml
new file mode 100644
index 00000000..8de756cf
--- /dev/null
+++ b/mkdocs.yml
@@ -0,0 +1,40 @@
+# Settings for mkdocs
+
+# Where to find documentation
+docs_dir: docs
+
+# Link to Github on every page
+repo_url: https://github.com/openfoodfacts/search-a-licious
+edit_uri: blob/main/docs/
+# add canonical url
+site_url: https://openfoodfacts.github.io/search-a-licious
+
+site_name: Search-a-licious documentation
+site_dir: gh_pages
+
+# Note see https://hub.docker.com/r/minidocks/mkdocs
+# for available extensions
+theme:
+ name: material
+
+markdown_extensions:
+ - footnotes
+ # support tables
+ - tables
+ # this one allow to have two space indentation counts as nested list, as in github/vscode
+ - mdx_truly_sane_lists
+ # this one allow to start a list without first adding a blank line, as in github/vscode
+ - mdx_breakless_lists
+ - pymdownx.highlight
+ - pymdownx.superfences
+ - toc:
+ # add permalink after titles
+ permalink: "#"
+plugins:
+ # thanks to this plugin, the .pages files will customize navigation entries
+ - awesome-pages
+ - search
+ - exclude:
+ glob:
+ - reports/
+ - "*_TODO.md"
\ No newline at end of file
diff --git a/scripts/Dockerfile.mkdocs b/scripts/Dockerfile.mkdocs
new file mode 100644
index 00000000..a3a71ca6
--- /dev/null
+++ b/scripts/Dockerfile.mkdocs
@@ -0,0 +1,11 @@
+FROM minidocks/mkdocs
+
+ARG USER_UID=1000
+ARG USER_GID=1000
+USER root
+# change user uid / gid by replacing "user"
+RUN deluser user && addgroup -g $USER_GID user && adduser -u $USER_UID -G user -D user
+# give right uid / gid to "user"
+RUN mkdir -p /app && chown user:user /app
+# install some package we need
+RUN pip3 install mdx_truly_sane_lists mdx-breakless-lists
diff --git a/scripts/build_mkdocs.sh b/scripts/build_mkdocs.sh
new file mode 100755
index 00000000..f6690fbf
--- /dev/null
+++ b/scripts/build_mkdocs.sh
@@ -0,0 +1,15 @@
+#!/usr/bin/env bash
+set -e
+# Renders markdown doc in docs to html in gh_pages
+
+# get group id to use it in the docker
+GID=$(id -g)
+
+# create image
+docker build --build-arg "USER_UID=$UID" --build-arg "USER_GID=$GID" --tag 'mkdocs-builder' -f scripts/Dockerfile.mkdocs .
+
+# we use minidocks way of choosing UID / GID
+docker run --rm \
+ -e USER_ID=$UID -e GROUP_ID=$GID \
+ -v $(pwd):/app -w /app \
+ mkdocs-builder build
diff --git a/scripts/generate_doc.sh b/scripts/generate_doc.sh
new file mode 100755
index 00000000..f23ab619
--- /dev/null
+++ b/scripts/generate_doc.sh
@@ -0,0 +1,32 @@
+#!/usr/bin/env bash
+
+# generating documentation
+
+# fail on errors
+set -e
+
+mkdir -p gh_pages
+
+# script to generate documentation
+echo "Build documentation with MkDocs"
+scripts/build_mkdocs.sh
+
+# TODO: generating python and documentation with sphinx
+
+echo "Generate OpenAPI documentation"
+make generate-openapi
+
+echo "Generate openapi html with redocly"
+docker run --rm \
+ -v $(pwd)/data:/data -v $(pwd)/gh_pages/:/output \
+ ghcr.io/redocly/redoc/cli:latest \
+ build -o /output/users/ref-openapi/index.html searchalicious-openapi.yml
+sudo chown $UID -R gh_pages/users/ref-openapi
+
+echo "Generate webcomponents documentation"
+make generate-custom-elements
+mkdir -p gh_pages/users/ref-web-components/dist
+cp frontend/public/dist/custom-elements.json gh_pages/users/ref-web-components/dist/custom-elements.json
+sudo chown $UID -R gh_pages/users/ref-web-components
+
+echo "To see your doc locally, run: python3 -m http.server -d gh_pages 8001"
\ No newline at end of file