diff --git a/.gitignore b/.gitignore
index 99dfdb903b77afb1955b90c9e1d60529975fef6c..6c78d4794fc8249bbe4c1c168c7fa26526e28077 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@
 *venv/
 *.egg-info/
 __pycache__/
+public*/
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 3614f61df63c6a1c9b7acc4a355c9a2056272342..fa3d137ee0db86674dc793d32ca0ccdc3a1f3925 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,21 +1,26 @@
 include:
   - '.gitlab/ci/static-analysis.yml'
   - '.gitlab/ci/docker.yml'
+  - '.gitlab/ci/doc.yml'
 
 variables:
-  STATIC_ANALYSIS_IMG_TAG: "3.12"
-
   PYTHON_IMG: python:3.12-slim
   STATIC_ANALYSIS_IMG: $CI_REGISTRY_IMAGE/python-static-analysis:$STATIC_ANALYSIS_IMG_TAG
   IMPL_MODULE_NAME: python_test_project
 
   DEV_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_BRANCH
 
+  # Specific to this repo
+  STATIC_ANALYSIS_IMG_TAG: "3.12"
+
+
 stages:
   - Pre-Build
   - Build
   - Static Analysis
-  - Push
+  - Documentation
+  - Docker image
+
 
 
 # ------------------------------ Build Linters docker images ------------------------------
diff --git a/.gitlab/ci/doc.yml b/.gitlab/ci/doc.yml
new file mode 100644
index 0000000000000000000000000000000000000000..ad8561ee28648c38e734009f516ee59cee0f0ae6
--- /dev/null
+++ b/.gitlab/ci/doc.yml
@@ -0,0 +1,22 @@
+.doc_base:
+  image: python:3.12-slim
+  stage: Documentation
+  before_script:
+    - pip install -r doc/doc_requirements.txt
+
+pages_test:
+  extends: .doc_base
+  except:
+    - main
+    - tags
+  script:
+    - mkdocs build --site-dir public_test
+
+pages:
+  extends: .doc_base
+  only: [main]
+  script:
+    - mkdocs build --site-dir public
+  artifacts:
+    paths:
+      - public
diff --git a/.gitlab/ci/docker.yml b/.gitlab/ci/docker.yml
index 5048075f9b8b603013ef7795026e77f0dd689d8a..fdfbab579235f54520d05ae598f0e549471c39c4 100644
--- a/.gitlab/ci/docker.yml
+++ b/.gitlab/ci/docker.yml
@@ -1,8 +1,9 @@
 variables:
+  IMAGE_PREFIX: $CI_REGISTRY_IMAGE
   DEV_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_BRANCH
-  PROD_IMAGE_PREFIX: $CI_REGISTRY_IMAGE
 
 .docker_build_base:
+  stage: Docker image
   image: docker:latest
   retry: 2 # Often crashes
   services:
@@ -15,7 +16,6 @@ variables:
     - echo $VERSION
 
 Build dev image:
-  stage: Build
   extends: .docker_build_base
   except: [main]
   script:
@@ -23,12 +23,11 @@ Build dev image:
     - docker push $DEV_IMAGE
 
 Ship:
-  stage: Push
   extends: .docker_build_base
   only: [main]
   script:
-    - docker build --build-arg IMG=$PYTHON_IMG --tag $PROD_IMAGE_PREFIX:latest .
-    - docker push $PROD_IMAGE_PREFIX:latest
+    - docker build --build-arg IMG=$PYTHON_IMG --tag $IMAGE_PREFIX:latest .
+    - docker push $IMAGE_PREFIX:latest
 
-    - docker tag $PROD_IMAGE_PREFIX:latest $PROD_IMAGE_PREFIX:$VERSION
-    - docker push $PROD_IMAGE_PREFIX:$VERSION
+    - docker tag $IMAGE_PREFIX:latest $IMAGE_PREFIX:$VERSION
+    - docker push $IMAGE_PREFIX:$VERSION
diff --git a/.gitlab/ci/pip.yml b/.gitlab/ci/pip.yml
new file mode 100644
index 0000000000000000000000000000000000000000..32cbb150bd2dfcbad3d2928d345e15650621ad0a
--- /dev/null
+++ b/.gitlab/ci/pip.yml
@@ -0,0 +1,12 @@
+Build pip package:
+  stage: Pip
+  only: [tags]
+  variables:
+    PRVTOKEN: "\"PRIVATE-TOKEN: ${CI_JOB_TOKEN}\""
+    PIP_PACKAGE_URL: "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/pypi"
+    TWINE_USERNAME: gitlab-ci-token 
+    TWINE_PASSWORD: ${CI_JOB_TOKEN} 
+  script:
+    - pip install build twine
+    - python -m build
+    - python -m twine upload --verbose --repository-url $PIP_PACKAGE_URL dist/*
diff --git a/doc/doc_requirements.txt b/doc/doc_requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..4f596924fbe5b08ec401e8a4d8425659104e247d
--- /dev/null
+++ b/doc/doc_requirements.txt
@@ -0,0 +1,7 @@
+mkdocstrings
+mkdocstrings[crystal,python]
+mkdocs-material
+mkdocs-gen-files
+mkdocs-section-index
+mkdocs-literate-nav
+mkdocs-mermaid2-plugin
diff --git a/doc/index.md b/doc/index.md
new file mode 100644
index 0000000000000000000000000000000000000000..b77812bcfff05c4c45955ed7fc862a3acf191e2b
--- /dev/null
+++ b/doc/index.md
@@ -0,0 +1,7 @@
+# Pycode quality
+
+This project contains python tools to improve quality of projects of Montpellier CDOS.
+
+## Contact
+
+Rémi Cresson at INRAE dot fr
diff --git a/mkdocs.yml b/mkdocs.yml
new file mode 100755
index 0000000000000000000000000000000000000000..2a1d4e3b2b50b6aa5b0d547f9ab9e207b816bb0b
--- /dev/null
+++ b/mkdocs.yml
@@ -0,0 +1,46 @@
+# mkdocs.yml
+theme:
+  name: "material"
+  features:
+    - content.code.annotate
+    - toc.follow
+    - navigation.instant
+    - content.code.copy
+
+plugins:
+- search
+- literate-nav:
+    nav_file: SUMMARY.md
+- section-index
+- mermaid2
+
+nav:
+- Home: index.md
+
+# Customization
+extra:
+  feature:
+    tabs: true
+
+markdown_extensions:
+  - attr_list
+  - admonition
+  - toc:
+      permalink: true
+      title: On this page
+      toc_depth: 1-3
+  - pymdownx.highlight:
+      anchor_linenums: true
+  - pymdownx.inlinehilite
+  - pymdownx.snippets
+  - pymdownx.details
+  - pymdownx.superfences
+  - pymdownx.emoji:
+      emoji_index: !!python/name:materialx.emoji.twemoji
+      emoji_generator: !!python/name:materialx.emoji.to_svg
+
+# rest of the navigation..
+site_name: Python code quality
+repo_url: https://forgemia.inra.fr/cdos-pub/pycode-quality/
+repo_name: pycode-quality
+docs_dir: doc/
diff --git a/python_test_project/__init__.py b/python_test_project/__init__.py
index b8bb207053db05c68543a2d19fbedf8dc24d672a..90d25093f9be252326a0f6bcd5e2b00730ce4a28 100644
--- a/python_test_project/__init__.py
+++ b/python_test_project/__init__.py
@@ -1,3 +1,3 @@
 """Python test project."""
 
-__version__ = "0.1.1"
+__version__ = "0.1.2"