diff --git a/.ci/publish-git-tag.sh b/.ci/publish-git-tag.sh
deleted file mode 100755
index 09ee35d3a69c13c980bbd51053342fbf8c4d6325..0000000000000000000000000000000000000000
--- a/.ci/publish-git-tag.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#! /usr/bin/env bash
-
-git tag `python setup.py --version`
-
-# push tag to GitLab thanks to our GITLAB_API_ACCESS_TOKEN
-# and predefined variables (see https://docs.gitlab.com/ee/ci/variables/predefined_variables.html)
-# TODO move from .gitlab-ci.yml into here :
-# git push --tags -o ci.skip "https://${CI_REGISTRY_USER}:${GITLAB_API_ACCESS_TOKEN}@${CI_REPOSITORY_URL#*@}"
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 49cb52df62387a3f98630d1546a806e589e42990..111597ee361294cdc2cff5b3f3492f8a84f1f012 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,8 +1,5 @@
 image: python:3.11
 
-variables:
-  PYPI_USERNAME: leximpact-bot
-
 stages:
   - install
   - test
@@ -63,7 +60,7 @@ check_version:
   needs: ["dependencies"]
   script:
     # Check for functional changes and version number
-    - .ci/is-version-number-acceptable.sh
+    - .gitlab/ci/is-version-number-acceptable.sh
   except:
     - master
 
@@ -72,16 +69,35 @@ build:
   script:
     - make build
 
-deploy:
+# create release in order to create tag 
+# release needed to bypass 'git tag' access rights configuration limited by annual token
+release-and-tag:
+  stage: deploy
+  needs: ["build"]
+  # use release-cli to get release name from variable
+  image: registry.gitlab.com/gitlab-org/release-cli:latest
+  rules:
+    - if: $CI_COMMIT_TAG
+      when: never  # avoid running the pipeline twice: do not run this job when a tag is created
+    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
+  before_script:
+    - apk update && apk upgrade && apk add bash
+    # override default before_script made for 'python' image and get version with shell only
+    # (pip is not installed in 'release-cli' default image)
+    - export TAG_NAME=`grep version setup.py | cut -d '=' -f2 | xargs | tr -d ','`
+  script:
+    - if ! .gitlab/ci/has-functional-changes.sh ; then exit 0 ; fi
+    - echo "Creating $TAG_NAME release (and tag)..."  # creates the tag when it doesn't exist
+    - release-cli create --name "$TAG_NAME" --description "$CI_JOB_STARTED_AT release" --tag-name "$TAG_NAME" --ref "$CI_COMMIT_SHA" --assets-link "{\"url\":\"https://$CI_REGISTRY_IMAGE/$TAG_NAME\",\"name\":\"Container Image \"}"
+
+deploy-wheel:
   stage: deploy
   needs: ["build"]
   script:
-   - if ! .ci/has-functional-changes.sh ; then exit 1 ; fi
-   - .ci/publish-git-tag.sh
-   - git push --tags -o ci.skip "https://${CI_REGISTRY_USER}:${GITLAB_API_ACCESS_TOKEN}@${CI_REPOSITORY_URL#*@}"
-   # Use PyPi token connected to leximpact-bot user on PyPi
-   - twine upload dist/* --username __token__ --password $PYPI_TOKEN
+    - if ! .gitlab/ci/has-functional-changes.sh ; then exit 0 ; fi
+    # publish the wheel knowing that artifacts from all previous stages are passed by default
+    # use leximpact-bot PyPi account and token defined in:
+    # See: https://git.leximpact.dev/admin/application_settings/ci_cd
+    - twine upload dist/* --username __token__ --password $PYPI_TOKEN
   only:
     - master
-  environment:
-    name: integration
diff --git a/.ci/has-functional-changes.sh b/.gitlab/ci/has-functional-changes.sh
similarity index 100%
rename from .ci/has-functional-changes.sh
rename to .gitlab/ci/has-functional-changes.sh
diff --git a/.ci/is-version-number-acceptable.sh b/.gitlab/ci/is-version-number-acceptable.sh
similarity index 100%
rename from .ci/is-version-number-acceptable.sh
rename to .gitlab/ci/is-version-number-acceptable.sh
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 28759a645c146fd7298e9e218830c439ac35287e..4a2e20fbdb4cbb7399381e562d3b8339c5978611 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,15 @@
 # Changelog
 
+### 3.0.2 [!35](https://git.leximpact.dev/leximpact/simulateur-dotations-communes/openfisca-france-dotations-locales/-/merge_requests/35)
+
+* Correction d'un crash technique.
+* Périodes concernées : non applicable.
+* Zones impactées : `.gitlab-ci.yml`
+* Détails :
+  * Corrige le déploiement sur PyPi assuré par le job `deploy` en CI
+  * En CI, renomme le job `deploy` en `deploy-wheel` et le précède d'un nouveau `release-and-tag` ne nécessitant plus de token annuel
+  * Déplace les scripts de CI de `.ci/` à `.gitlab/ci/`
+
 ### 3.0.1 [!34](https://git.leximpact.dev/leximpact/simulateur-dotations-communes/openfisca-france-dotations-locales/-/merge_requests/34)
 
 * Évolution du système socio-fiscal.
diff --git a/setup.py b/setup.py
index ba302323bec0dfc48a99ba92c1e59f5d88a3aab1..0cdcb3d9936561d291f894bb05b28f1c23d3e46e 100644
--- a/setup.py
+++ b/setup.py
@@ -4,7 +4,7 @@ from setuptools import setup, find_packages
 
 setup(
     name = "OpenFisca-France-Dotations-Locales",
-    version = "3.0.1",
+    version = "3.0.2",
     author = "LexImpact Team",
     author_email = "leximpact@an.fr",
     classifiers=[