diff --git a/.gitignore b/.gitignore
index c6dee3f2dc3dd149c7dc5c29a9f43cd0d70194d2..88853310b51b65ab35d408fec89564f7c795c96f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,4 +4,5 @@
 .vscode
 venv
 .DS_Store
-.idea
\ No newline at end of file
+.idea
+dist
\ No newline at end of file
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index bb3d4a2c40db07b700d3cdffa9617cc7a172a8ca..00bc33d12a95893a10608627a895c8f4b6f14d91 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -18,16 +18,8 @@ test:
 upload:
   stage: deploy
   needs: ['test', ]
-  image: harbor.pasteur.fr/kube-system/helm-kubectl:3.4.0
+  image: python:3.11
   script:
-    - CHART_VERSION=$(helm show chart shiny-server | grep version | cut -d' ' -f2)
-    - CHART_NAME=$(helm show chart shiny-server | grep name | cut -d' ' -f2)
-    - |
-      if [ "helm" == "${CI_COMMIT_REF_SLUG}" ]; then
-        export CHANNEL="stable"
-      else
-        export CHANNEL="${CI_COMMIT_REF_SLUG}"
-      fi
-      echo $CHANNEL
-    - helm package shiny-server
-    - curl --request POST --user gitlab-ci-token:$CI_JOB_TOKEN --form "chart=@${CHART_NAME}-${CHART_VERSION}.tgz" "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/helm/api/${CHANNEL}/charts"
\ No newline at end of file
+    - pip install -r requirements-dev.txt
+    - python setup.py sdist
+    - python -m twine upload --verbose --repository-url ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/pypi dist/*
diff --git a/requirements-dev.txt b/requirements-dev.txt
new file mode 100644
index 0000000000000000000000000000000000000000..6cea7e69488a9cd83bed9968de348b1cd190e754
--- /dev/null
+++ b/requirements-dev.txt
@@ -0,0 +1,2 @@
+setuptools
+twine
\ No newline at end of file