diff --git a/README.md b/README.md
index 3addf3537284bd0ba83bf050fc9efa7a4e95631f..9b837fa74a4fc16686fb6ccd493ac7bd4bb8d9de 100644
--- a/README.md
+++ b/README.md
@@ -155,6 +155,36 @@ Each deployment job produces _output variables_ that are propagated to downstrea
 
 Those variables may be freely used in downstream jobs (for instance to run acceptance tests against the latest deployed environment).
 
+### Working with repositories & OCI-based registries
+
+The Helm template supports indifferently the use of [chart repositories](https://helm.sh/docs/topics/chart_repository/) and [OCI-based registries](https://helm.sh/docs/topics/registries/) (requires Helm 3 or above).
+
+Those can be used both for pulling and/or pushing charts.
+
+#### Configuring pull repositories
+
+The pulling repositories/registries can be configured with the `$HELM_REPOS`.
+The value is expected as a (whitespace-separated) list of `repo_name@repo_url` (defaults to `stable@https://charts.helm.sh/stable bitnami@https://charts.bitnami.com/bitnami`).
+
+:warning: When using OCI-based registries, simply prefix the url with `oci://`.
+
+The Helm template also supports user/password authentication for each, simply by defining `HELM_REPO_<NAME>_USER` and `HELM_REPO_<NAME>_PASSWORD` (as project or group secret variables).
+
+:warning: The `<NAME>` part is the `repo_name` transformed in [SCREAMING_SNAKE_CASE](https://en.wikipedia.org/wiki/Snake_case) (uppercase words separated by underscores).
+
+Example: declare the GitLab chart repository from another GitLab project
+
+```yml
+variables:
+  HELM_REPOS: "stable@https://charts.helm.sh/stable bitnami@https://charts.bitnami.com/bitnami other-proj@${CI_API_V4_URL}/projects/1234/packages/helm/release"
+  HELM_REPO_OTHER_PROJ_USER: "gitlab-token"
+  # HELM_REPO_OTHER_PROJ_PASSWORD set as a project secret variables
+```
+
+#### Configuring the push repository
+
+All configuration parameters are extensively documented in the [`helm-publish` job](#helm-publish-job) chapter.
+
 ## Configuration reference
 
 ### Secrets management
@@ -188,7 +218,7 @@ The Helm template uses some global configuration used throughout all jobs.
 | `HELM_DEPLOY_ARGS`    | The Helm [command with options](https://helm.sh/docs/helm/helm_upgrade/) to deploy the application (_without dynamic arguments such as release name and chart_) | `upgrade --install --atomic --timeout 120s` |
 | `HELM_DELETE_ARGS`    | The Helm [command with options](https://helm.sh/docs/helm/helm_uninstall/) to cleanup the application (_without dynamic arguments such as release name_) | `uninstall` |
 | `HELM_DEPLOY_CHART`   | The Helm [chart](https://helm.sh/docs/topics/charts/) to deploy. _Only required if you want to deploy an **external** chart._  | _none_ |
-| `HELM_REPOS`          | The Helm [chart repositories](https://helm.sh/docs/topics/chart_repository/) to use (formatted as `repo_name_1@:repo_url_1 repo_name_2@:repo_url_2 ...`) | `stable@https://charts.helm.sh/stable bitnami@https://charts.bitnami.com/bitnami` |
+| `HELM_REPOS`          | The Helm [chart repositories](https://helm.sh/docs/topics/chart_repository/) to use (formatted as `repo_name_1@repo_url_1 repo_name_2@repo_url_2 ...`) | `stable@https://charts.helm.sh/stable bitnami@https://charts.bitnami.com/bitnami` |
 | `HELM_BASE_APP_NAME`  | Base application name                  | `$CI_PROJECT_NAME` ([see GitLab doc](https://docs.gitlab.com/ee/ci/variables/predefined_variables.html)) |
 | `HELM_ENVIRONMENT_URL`    | Default environments url _(only define for static environment URLs declaration)_<br/>_supports late variable expansion (ex: `https://%{environment_name}.helm.acme.com`)_ | _none_ |
 
@@ -196,13 +226,13 @@ The Helm template uses some global configuration used throughout all jobs.
 
 Review environments are dynamic and ephemeral environments to deploy your _ongoing developments_ (a.k.a. _feature_ or _topic_ branches).
 
-They are **enabled by default** and can be disabled by setting the `HELM_REVIEW_DISABLED` variable (see below).
+They are **disabled by default** and can be enabled by setting the `HELM_REVIEW_ENABLED` variable (see below).
 
 Here are variables supported to configure review environments:
 
 | Name                     | description                            | default value     |
 | ------------------------ | -------------------------------------- | ----------------- |
-| `HELM_REVIEW_DISABLED`   | Set to `true` to disable `review` env            | _none_ (enabled) |
+| `HELM_REVIEW_ENABLED`    | Set to `true` to enable `review` env   | _none_ (enabled) |
 | `HELM_REVIEW_APP_NAME`   | Application name for `review` env      | `"${HELM_BASE_APP_NAME}-${CI_ENVIRONMENT_SLUG}"` (ex: `myproject-review-fix-bug-12`) |
 | `HELM_REVIEW_ENVIRONMENT_URL`| The review environments url _(only define for static environment URLs declaration and if different from default)_ | `$HELM_ENVIRONMENT_URL` |
 | `HELM_REVIEW_NAMESPACE`  | The Kubernetes namespace to use for `review` env _(only define to override default)_ | `$KUBE_NAMESPACE` |
@@ -213,13 +243,13 @@ Here are variables supported to configure review environments:
 
 The integration environment is the environment associated to your integration branch (`develop` by default).
 
-It is **enabled by default** and can be disabled by setting the `HELM_INTEG_DISABLED` variable (see below).
+It is **disabled by default** and can be enabled by setting the `HELM_INTEG_ENABLED` variable (see below).
 
 Here are variables supported to configure the integration environment:
 
 | Name                     | description                            | default value     |
 | ------------------------ | -------------------------------------- | ----------------- |
-| `HELM_INTEG_DISABLED`    | Set to `true` to disable `integration` env       | _none_ (enabled) |
+| `HELM_INTEG_ENABLED`     | Set to `true` to enable `integration` env | _none_ (enabled) |
 | `HELM_INTEG_APP_NAME`    | Application name for `integration` env | `$HELM_BASE_APP_NAME-integration` |
 | `HELM_INTEG_ENVIRONMENT_URL`| The integration environment url _(only define for static environment URLs declaration and if different from default)_ | `$HELM_ENVIRONMENT_URL` |
 | `HELM_INTEG_NAMESPACE`   | The Kubernetes namespace to use for `integration` env _(only define to override default)_ | `$KUBE_NAMESPACE` |
@@ -230,13 +260,13 @@ Here are variables supported to configure the integration environment:
 
 The staging environment is an iso-prod environment meant for testing and validation purpose associated to your production branch (`master` by default).
 
-It is **enabled by default** and can be disabled by setting the `HELM_STAGING_DISABLED` variable (see below).
+It is **disabled by default** and can be enabled by setting the `HELM_STAGING_ENABLED` variable (see below).
 
 Here are variables supported to configure the staging environment:
 
 | Name                     | description                            | default value     |
 | ------------------------ | -------------------------------------- | ----------------- |
-| `HELM_STAGING_DISABLED`  | Set to `true` to disable `staging` env           | _none_ (enabled) |
+| `HELM_STAGING_ENABLED`   | Set to `true` to enable `staging` env  | _none_ (enabled) |
 | `HELM_STAGING_APP_NAME`  | Application name for `staging` env     | `$HELM_BASE_APP_NAME-staging` |
 | `HELM_STAGING_ENVIRONMENT_URL`| The staging environment url _(only define for static environment URLs declaration and if different from default)_ | `$HELM_ENVIRONMENT_URL` |
 | `HELM_STAGING_NAMESPACE` | The Kubernetes namespace to use for `staging` env _(only define to override default)_ | `$KUBE_NAMESPACE` |
@@ -247,13 +277,13 @@ Here are variables supported to configure the staging environment:
 
 The production environment is the final deployment environment associated with your production branch (`master` by default).
 
-It is **enabled by default** and can be disabled by setting the `HELM_PROD_DISABLED` variable (see below).
+It is **disabled by default** and can be enabled by setting the `HELM_PROD_ENABLED` variable (see below).
 
 Here are variables supported to configure the production environment:
 
 | Name                     | description                            | default value     |
 | ------------------------ | -------------------------------------- | ----------------- |
-| `HELM_PROD_DISABLED`     | Set to `true` to disable `production` env        | _none_ (enabled)  |
+| `HELM_PROD_ENABLED`      | Set to `true` to enable `production` env | _none_ (enabled)  |
 | `HELM_PROD_APP_NAME`     | Application name for `production` env  | `$HELM_BASE_APP_NAME` |
 | `HELM_PROD_ENVIRONMENT_URL`| The production environment url _(only define for static environment URLs declaration and if different from default)_ | `$HELM_ENVIRONMENT_URL` |
 | `HELM_PROD_NAMESPACE`    | The Kubernetes namespace to use for `production` env _(only define to override default)_ | `$KUBE_NAMESPACE` |
@@ -292,55 +322,87 @@ This job runs [Kube-Score](https://kube-score.com/) on the resources to be creat
 | `HELM_KUBE_SCORE_IMAGE`   | The Docker image used to run [Kube-Score](https://kube-score.com/)   | `zegl/kube-score:latest-helm3` |
 | `HELM_KUBE_SCORE_ARGS`   | Arguments used by the helm-score job   | _none_ |
 
-### Charts publishing
+### `helm-package` job
 
-The template builds a chart package that may be pushed as two distinct packages, depending on a certain _workflow_:
+This job [packages](https://helm.sh/docs/helm/helm_package/) the Helm chart. It uses the following variables:
 
-1. **snapshot**: the chart is first packaged and then pushed to some registry as
-  the **snapshot** image. It can be seen as the raw result of the build, but still **untested and unreliable**.
-2. **release**: once the snapshot chart has been thoroughly tested (both by `package-test` stage jobs and/or `acceptance`
-  stage jobs after being deployed to some server), then the chart is pushed one more time as the **release** chart.
-  This second push can be seen as the **promotion** of the snapshot chart being now **tested and reliable**.
-
-Common variables for `helm-package` and `helm-pusblish`:
+| Name                                | description                                   | default value                     |
+| ----------------------------------- | --------------------------------------------- | --------------------------------- |
+| `HELM_PACKAGE_ARGS`                 | The Helm [command with options](https://helm.sh/docs/helm/helm_package/) to perform the packaging (_without dynamic arguments such as the chart path_)   | `package --dependency-update` |
+| `HELM_PUBLISH_SNAPSHOT_ENABLED`     | Set to `true` to enable publishing the snapshot (untested) chart during the packaging step | _none_ (disabled) |
+| `HELM_SEMREL_RELEASE_DISABLED`      | Set to `true` to disable usage of `semantic-release` release info for helm package (see next chapter) | _none_ (enabled) |
 
-| Name                              | description                                  | default value           |
-| --------------------------------- | -------------------------------------------- | ----------------------- |
-| `HELM_REPO_PUBLISH_METHOD`        | HTTP method to use to push the package       | `POST`                  |
-| :lock: `HELM_REPO_USER`           | Helm registry username                       | `$CI_REGISTRY_USER`     |
-| :lock: `HELM_REPO_PASSWORD`       | Helm registry password                       | `$CI_REGISTRY_PASSWORD` |
+#### `semantic-release` integration
 
-#### `helm-package` job
+If you activate the [`semantic-release-info` job from the `semantic-release` template](https://gitlab.com/to-be-continuous/semantic-release/#semantic-release-info-job), the `helm-package` job will automatically use the generated next version info for the chart version (`--version`).
 
-This job [packages your chart into an archive](https://helm.sh/docs/helm/helm_package/), optionaly push it to a snapshot repository and uses the following variables:
+If no next version info is determined by `semantic-release`, the package will be created, but without versioning info.
 
-| Name                                  | description                              | default value     |
-| ------------------------------------- | ---------------------------------------- | ----------------- |
-| `HELM_PACKAGE_ARGS`                   | The Helm [command with options](https://helm.sh/docs/helm/helm_package/) to perform the packaging (_without dynamic arguments such as the chart path_)   | `package --dependency-update` |
-| `HELM_SEMREL_RELEASE_DISABLED`        | Set to `true` to disable usage of `semantic-release` release info for helm package (see next chapter) | _none_ (enabled) |
-| `HELM_PUBLISH_SNAPSHOT_URL`           | The URL of the Helm repository to publish your Helm package as a snapshot | _gitlab repository on snapshot channel_ `${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/helm/api/snapshot/charts` |
-| `HELM_REPO_SNAPSHOT_PUBLISH_METHOD`   | HTTP method to use to push the package        | `$HELM_REPO_PUBLISH_METHOD`       |
-| `HELM_REPO_SNAPSHOT_USER`             | Snapshot repository username | `$HELM_REPO_USER` |
-| :lock: `HELM_REPO_SNAPSHOT_PASSWORD`  | Snapshot repository password | `$HELM_REPO_PASSWORD` |
+Note: You can disable the `semantic-release` integration described herebefore the `HELM_SEMREL_RELEASE_DISABLED` variable.
 
-#### `semantic-release` integration
+#### Chart version management
 
-If you activate the [`semantic-release-info` job from the `semantic-release` template](https://gitlab.com/to-be-continuous/semantic-release/#semantic-release-info-job), the `helm-publish` job will automatically use the generated next version info for both application version (`--app-version`) and chart version (`--version`).
+Depending on the branch and the step in the CI/CD pipeline, the chart will be packaged with a different version.
 
-If no next version info is generated by `semantic-release`, the package will be created, but without versioning info.
+The general version format will be `<x.y.z>-<label>`:
 
-Note: You can disable the `semantic-release` integration described herebefore the `HELM_SEMREL_RELEASE_DISABLED` variable.
+* `<x.y.z>`: 
+    * if [semantic-release integration](#semantic-release-integration) is enabled: uses the version determined by `semantic-release`, 
+    * otherwise uses the version from the chart file
+* `<label>`:
+    * on the production branch (`main` or `master` by default), no trailing label is used
+    * on any other branch, `$CI_COMMIT_REF_SLUG` is used as trailing label<br/>
+    _(ex: `review-feature-12` on branch `review/feature-12`)_
+    * :warning: when `HELM_PUBLISH_SNAPSHOT_ENABLED` is enabled, the chart is additionally packaged (and published) with a label suffixed with `snapshot`<br/>
+    _(ex: `snapshot` on production branch and `review-feature-12-snapshot` on branch `review/feature-12`)_
 
-#### `helm-publish` job
+### `helm-publish` job
 
-This job push helm package to a release repository and uses the following variables:
+This job publishes the packaged chart to a [chart repository](https://helm.sh/docs/topics/chart_repository/) or [OCI-based registry](https://helm.sh/docs/topics/registries/). It uses the following variables:
 
 | Name                                | description                                   | default value                     |
 | ----------------------------------- | --------------------------------------------- | --------------------------------- |
-| `HELM_PUBLISH_URL`                  | The URL of the Helm repository to publish your Helm package | _gitlab repository on release channel_ `${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/helm/api/release/charts`  |
-| `HELM_REPO_RELEASE_PUBLISH_METHOD`  | HTTP method to use to push the package        | `$HELM_REPO_PUBLISH_METHOD`       |
-| `HELM_REPO_RELEASE_USER`            | Release repository username (for PUT request auth)  | `$HELM_REPO_USER`                 |
-| :lock: `HELM_REPO_RELEASE_PASSWORD` | Release repository password (for PUT request auth)  | `$HELM_REPO_PASSWORD`             |
+| `HELM_PUBLISH_METHOD`               | Method to use to publish the packaged chart (one of `auto`, `push`, `post`, `put`, `custom`, `disabled`) | `auto`                  |
+| :lock: `HELM_PUBLISH_USER`          | Helm registry username                       | `$CI_REGISTRY_USER`     |
+| :lock: `HELM_PUBLISH_PASSWORD`      | Helm registry password                       | `$CI_REGISTRY_PASSWORD` |
+| `HELM_PUBLISH_URL`                  | The URL of the Helm repository to publish your Helm package.<br/>Supports both [chart repository](https://helm.sh/docs/topics/chart_repository/) or [OCI-based registry](https://helm.sh/docs/topics/registries/) (url must be prefixed with `oci://`) | `oci://$CI_REGISTRY/$CI_PROJECT_PATH/charts` ([GitLab's container registry](https://docs.gitlab.com/ee/user/packages/container_registry/)) |
+| `HELM_PUBLISH_ON`                   | Defines on which branch(es) the publish job shall be enabled (`prod` to enable on production branch only, `protected` to enable on protected references and `all` to enable on all Git references) | `prod`                  |
+| `HELM_CM_PUSH_PLUGIN_VERSION`       | cm-push plugin version to install (only when using `push` method with a regular chart [repository](https://helm.sh/docs/topics/chart_repository/)) | _none_ (latest) |
+
+
+#### Supported publish methods
+
+The Helm publish supports several methods, configurable with the `$HELM_PUBLISH_URL` variable:
+
+| Value           | description                                   |
+| --------------- | --------------------------------------------- |
+|`auto` (default) | tries to auto-detect the most appropriate method | 
+|`disabled`       | disables the `helm-publish` job |
+|`push`           | if publishing to an [OCI-based registry](https://helm.sh/docs/topics/registries/), publishes with [helm push](https://helm.sh/docs/helm/helm_push/) command; else uses the [cm-push plugin](https://github.com/chartmuseum/helm-push) | 
+|`post`           | publishes the package using http `POST` method (compatible with [GitLab packages repository](https://docs.gitlab.com/ee/user/packages/helm_repository/)) | 
+|`put`            | publishes the package using http `PUT` method | 
+|`custom`         | forces the use of a [custom publish script](#custom-publish-script) | 
+
+> :information_source: The default configuration will use [GitLab's container registry](https://docs.gitlab.com/ee/user/packages/container_registry/) to publish your charts
+>
+> If you wish to use [GitLab's Helm package repository](https://docs.gitlab.com/ee/user/packages/helm_repository/) instead, simply override:
+>
+> ```yaml
+> variables:
+>   # use channel 'release' (can be changed)
+>   HELM_PUBLISH_URL: "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/helm/release"
+> ```
+>
+> and leave default `$HELM_PUBLISH_USER`/`$HELM_PUBLISH_PASSWORD` values.
+
+#### Custom publish script
+
+If supported methods don't fit your needs, you may provide a `helm-publish.sh` script (with execution permissions) in your `$HELM_SCRIPTS_DIR` directory to implement the required publish method.
+
+This script may use the following variables:
+
+* `$helm_package`: the packaged chart to publish,
+* `$HELM_PUBLISH_USER`, `$HELM_PUBLISH_PASSWORD` and `$HELM_PUBLISH_URL` (see above).
 
 ### `helm-test` job
 
@@ -349,7 +411,7 @@ You are welcome to nest your test suite under a `tests/` directory like `$HELM_C
 
 It is **disabled by default** and can be enabled by setting the ``HELM_TEST_ENABLED`` variable (see below).
 
-It  uses the following variables:
+It uses the following variables:
 
 | Name                  | description                              | default value     |
 | --------------------- | ---------------------------------------- | ----------------- |
diff --git a/kicker.json b/kicker.json
index 445a4b25649d569fe56376da4e5a06fa67216d88..57d366bb79f7fad09aab4c5dbc19b5d2ef74aea0 100644
--- a/kicker.json
+++ b/kicker.json
@@ -29,7 +29,7 @@
     },
     {
       "name": "HELM_REPOS",
-      "description": "The Helm [chart repositories](https://helm.sh/docs/topics/chart_repository/) to use (formatted as `repo_name_1@:repo_url_1 repo_name_2@:repo_url_2 ...`)",
+      "description": "The Helm [chart repositories](https://helm.sh/docs/topics/chart_repository/) to use (formatted as `repo_name_1@repo_url_1 repo_name_2@repo_url_2 ...`)",
       "default": "stable@https://charts.helm.sh/stable bitnami@https://charts.bitnami.com/bitnami"
     },
     {
@@ -82,24 +82,6 @@
       "description": "The name of the Helm [value](https://helm.sh/docs/chart_best_practices/values/) containing the _environment hostname_ (extracted from the environment URL)",
       "default": "hostname",
       "advanced": true
-    },
-    {
-      "name": "HELM_REPO_USER",
-      "description": "Helm repository username",
-      "default": "$CI_REGISTRY_USER",
-      "advanced": true
-    },
-    {
-      "name": "HELM_REPO_PASSWORD",
-      "description": "Helm repository password",
-      "default": "$CI_REGISTRY_PASSWORD",
-      "advanced": true
-    },
-    {
-      "name": "HELM_REPO_PUBLISH_METHOD",
-      "description": "HTTP method to use to push the package",
-      "default": "POST",
-      "advanced": true
     }
   ],
   "features": [
@@ -186,71 +168,59 @@
           "advanced": true
         },
         {
-          "name": "HELM_SEMREL_RELEASE_DISABLED",
-          "description": "Disable semantic-release integration",
+          "name": "HELM_PUBLISH_SNAPSHOT_ENABLED",
+          "description": "Set to `true` to enable publishing the snapshot (untested) chart during the packaging step",
           "type": "boolean",
           "advanced": true
         },
         {
-          "name": "HELM_PUBLISH_SNAPSHOT_URL",
-          "description": "The URL of the Helm repository to publish your Helm package as a snapshot",
-          "default": "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/helm/api/snapshot/charts",
-          "advanced": true
-        },
-        {
-          "name": "HELM_REPO_SNAPSHOT_USER",
-          "description": "Snapshot repository username",
-          "default": "$HELM_REPO_USER",
-          "secret": true,
-          "advanced": true
-        },
-        {
-          "name": "HELM_REPO_SNAPSHOT_PASSWORD",
-          "description": "Snapshot repository password",
-          "default": "$HELM_REPO_PASSWORD",
-          "secret": true,
-          "advanced": true
-        },
-        {
-          "name": "HELM_REPO_SNAPSHOT_PUBLISH_METHOD",
-          "description": "HTTP method to use to push the snapshot package",
-          "default": "$HELM_REPO_PUBLISH_METHOD",
+          "name": "HELM_SEMREL_RELEASE_DISABLED",
+          "description": "Disable semantic-release integration",
+          "type": "boolean",
           "advanced": true
         }
-        
-        
-        
       ]
     },
     {
       "id": "publish",
       "name": "Publish your chart",
-      "description": "Publish your Helm chart",
+      "description": "Publishes the chart to a [Helm repository](https://helm.sh/docs/topics/chart_repository/) or [OCI-based registry](https://helm.sh/docs/topics/registries/)",
       "variables": [
         {
           "name": "HELM_PUBLISH_URL",
           "description": "The URL of the Helm repository to publish your Helm package",
-          "default": "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/helm/api/release/charts",
-          "advanced": true
+          "default": "oci://$CI_REGISTRY/$CI_PROJECT_PATH/charts"
         },
         {
-          "name": "HELM_REPO_RELEASE_USER",
-          "description": "Release repository username",
-          "default": "$HELM_REPO_USER",
-          "secret": true,
+          "name": "HELM_PUBLISH_METHOD",
+          "description": "HTTP method to use to push the package",
+          "default": "auto",
+          "type": "enum",
+          "values": ["auto", "push", "post", "put", "custom", "disabled"],
           "advanced": true
         },
         {
-          "name": "HELM_REPO_RELEASE_PASSWORD",
-          "description": "Release repository password",
-          "default": "$HELM_REPO_PASSWORD",
-          "secret": true,
-          "advanced": true
+          "name": "HELM_PUBLISH_USER",
+          "description": "Helm repository username",
+          "default": "$CI_REGISTRY_USER",
+          "secret": true
+        },
+        {
+          "name": "HELM_PUBLISH_PASSWORD",
+          "description": "Helm repository password",
+          "default": "$CI_REGISTRY_PASSWORD",
+          "secret": true
+        },
+        {
+          "name": "HELM_PUBLISH_ON",
+          "description": "Defines on which branch(es) the publish job shall be enabled",
+          "default": "prod",
+          "type": "enum",
+          "values": ["prod", "protected", "all"]
         },
         {
-          "name": "HELM_REPO_RELEASE_PUBLISH_METHOD",
-          "description": "HTTP method to use to push the release package",
-          "default": "$HELM_REPO_PUBLISH_METHOD",
+          "name": "HELM_CM_PUSH_PLUGIN_VERSION",
+          "description": "cm-push plugin version to install (only when using `push` method with a regular chart [repository](https://helm.sh/docs/topics/chart_repository/)",
           "advanced": true
         }
       ]
@@ -259,7 +229,7 @@
       "id": "review",
       "name": "Review",
       "description": "Dynamic review environments for your topic branches (see GitLab [Review Apps](https://docs.gitlab.com/ee/ci/review_apps/))",
-      "disable_with": "HELM_REVIEW_DISABLED",
+      "enable_with": "HELM_REVIEW_ENABLED",
       "variables": [
         {
           "name": "HELM_REVIEW_APP_NAME",
@@ -296,7 +266,7 @@
       "id": "integration",
       "name": "Integration",
       "description": "A continuous-integration environment associated to your integration branch (`develop` by default)",
-      "disable_with": "HELM_INTEG_DISABLED",
+      "enable_with": "HELM_INTEG_ENABLED",
       "variables": [
         {
           "name": "HELM_INTEG_APP_NAME",
@@ -333,7 +303,7 @@
       "id": "staging",
       "name": "Staging",
       "description": "An iso-prod environment meant for testing and validation purpose on your production branch (`master` by default)",
-      "disable_with": "HELM_STAGING_DISABLED",
+      "enable_with": "HELM_STAGING_ENABLED",
       "variables": [
         {
           "name": "HELM_STAGING_APP_NAME",
@@ -370,7 +340,7 @@
       "id": "prod",
       "name": "Production",
       "description": "The production environment",
-      "disable_with": "HELM_PROD_DISABLED",
+      "enable_with": "HELM_PROD_ENABLED",
       "variables": [
         {
           "name": "AUTODEPLOY_TO_PROD",
diff --git a/templates/gitlab-ci-helm.yml b/templates/gitlab-ci-helm.yml
index 484c2008e9bd3c882cd94b12d241a0841ed24547..76d7583773a6333d00cc323404e3b3c8c06a9ad3 100644
--- a/templates/gitlab-ci-helm.yml
+++ b/templates/gitlab-ci-helm.yml
@@ -58,9 +58,12 @@ variables:
   HELM_CHART_DIR: "."
   HELM_SCRIPTS_DIR: "."
   HELM_PACKAGE_ARGS: "package --dependency-update"
-  HELM_PUBLISH_URL: "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/helm/api/release/charts"
-  HELM_PUBLISH_SNAPSHOT_URL: "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/helm/api/snapshot/charts"
-  HELM_REPO_PUBLISH_METHOD: "POST"
+  # to GitLab's container registry (OCI-compliant)
+  HELM_PUBLISH_URL: "oci://$CI_REGISTRY/$CI_PROJECT_PATH/charts"
+  # to GitLab's packages repository
+  # HELM_PUBLISH_URL: "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/helm/release"
+  # HELM_PUBLISH_URL: "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/helm/release"
+  HELM_PUBLISH_METHOD: "auto"
 
   HELM_REPOS: "stable@https://charts.helm.sh/stable bitnami@https://charts.bitnami.com/bitnami"
 
@@ -73,17 +76,14 @@ variables:
 
 #  HELM_COMMON_VALUES: "values-common.yml"
 
-#  HELM_REVIEW_DISABLED: "true"
 #  HELM_REVIEW_VALUES: "values-review.yml"
 #  HELM_REVIEW_NAMESPACE: ""
 #  HELM_REVIEW_KUBE_CONFIG: ""
 
-#  HELM_INTEG_DISABLED: "true"
 #  HELM_INTEG_VALUES: "values-review.yml"
 #  HELM_INTEG_NAMESPACE: ""
 #  HELM_INTEG_KUBE_CONFIG: ""
 
-#  HELM_STAGING_DISABLED: "true"
 #  HELM_STAGING_VALUES: "values-staging.yml"
 #  HELM_STAGING_NAMESPACE: ""
 #  HELM_STAGING_KUBE_CONFIG: ""
@@ -107,6 +107,7 @@ variables:
 
   HELM_BASE_APP_NAME: "$CI_PROJECT_NAME"
   HELM_REVIEW_ENVIRONMENT_SCHEME: "https"
+  HELM_PUBLISH_ON: "prod"
 
   # default production ref name (pattern)
   PROD_REF: '/^(master|main)$/'
@@ -322,12 +323,6 @@ stages:
     done
   }
 
-  function get_helm_config_opt() {
-    echo -n "--registry-config $CI_PROJECT_DIR/.config/helm/registry.json "
-    echo -n "--repository-cache $CI_PROJECT_DIR/.cache/helm/repository "
-    echo -n "--repository-config $CI_PROJECT_DIR/.config/helm/repositories.yaml "
-  }
-
   function setup_kubeconfig() {
     if [ -n "$1" ]; then
       export KUBECONFIG="$CI_PROJECT_DIR/.kubeconfig"
@@ -344,23 +339,44 @@ stages:
     # Use cacheable folders
     mkdir -p "$CI_PROJECT_DIR/.config/helm/"
     mkdir -p "$CI_PROJECT_DIR/.cache/helm/repository/"
-    ln -s "$CI_PROJECT_DIR/.cache" ~/.cache
-    ln -s "$CI_PROJECT_DIR/.config" ~/.config
-
-    helm_opts=$(get_helm_config_opt)
 
     # Install helm repositories
     for repo in $HELM_REPOS
     do
       repo_name=$(echo "$repo" | cut -d@ -f 1)
       repo_url=$(echo "$repo" | cut -d@ -f 2)
-      log_info "--- add repository \\e[32m${repo_name}\\e[0m: \\e[33;1m${repo_url}\\e[0m"
-      # shellcheck disable=SC2086
-      helm $helm_opts repo add "$repo_name" "$repo_url"
+      repo_name_ssc=$(echo "$repo_name" | tr '[:lower:]' '[:upper:]' | tr '[:punct:]' '_')
+      repo_user=$(eval echo "\$HELM_REPO_${repo_name_ssc}_USER")
+      repo_password=$(eval echo "\$HELM_REPO_${repo_name_ssc}_PASSWORD")
+
+      if [[ "$repo_url" =~ oci://.* ]]
+      then
+        if [[ "$repo_user" ]] && [[ "$repo_password" ]]
+        then
+          registry_host=$(echo "$repo_url" | awk -F[/:] '{print $4}')
+          log_info "--- login to OCI-registry \\e[32m${repo_name}\\e[0m: \\e[33;1m${registry_host}\\e[0m"
+          export HELM_EXPERIMENTAL_OCI=1
+          # shellcheck disable=SC2086
+          echo "$repo_password" | helm ${TRACE+--debug} registry login "$registry_host" --username "$repo_user" --password-stdin
+        else
+          log_warn "--- OCI-registry \\e[32m${repo_name}\\e[0m (\\e[33;1m${repo_url}\\e[0m) defined, but no credentials found (\$HELM_REPO_${repo_name_ssc}_USER/\$HELM_REPO_${repo_name_ssc}_PASSWORD)"
+        fi
+      else
+        if [[ "$repo_user" ]] && [[ "$repo_password" ]]
+        then
+          log_info "--- add repository \\e[32m${repo_name}\\e[0m: \\e[33;1m${repo_url}\\e[0m (with user/password auth)"
+          # shellcheck disable=SC2086
+          echo "$repo_password" | helm ${TRACE+--debug} repo add "$repo_name" "$repo_url" --username "$repo_user" --password-stdin
+        else
+          log_info "--- add repository \\e[32m${repo_name}\\e[0m: \\e[33;1m${repo_url}\\e[0m (unauthenticated)"
+          # shellcheck disable=SC2086
+          helm ${TRACE+--debug} repo add "$repo_name" "$repo_url"
+        fi
+      fi
     done
 
     # shellcheck disable=SC2086
-    helm $helm_opts repo update
+    helm ${TRACE+--debug} repo update
   }
 
   function awkenvsubst() {
@@ -386,10 +402,6 @@ stages:
     values_files=$4
     environment_url=$5
 
-    # backwards compatibility
-    export env=$environment_type
-    export appname=$environment_name
-
     # variables expansion in $environment_url
     environment_url=$(echo "$environment_url" | awkenvsubst)
     export environment_url
@@ -416,12 +428,10 @@ stages:
       log_info "--- \\e[32mpre-deploy hook\\e[0m (\\e[33;1m${prescript}\\e[0m) not found: skip"
     fi
 
-    helm_opts=$(get_helm_config_opt)
+    helm_opts=${TRACE+--debug}
     
     helm_opts="$helm_opts --set ${HELM_ENV_VALUE_NAME}=$environment_type"
     helm_opts="$helm_opts --set ${HELM_HOSTNAME_VALUE_NAME}=$hostname"
-    # backward compatibility
-    helm_opts="$helm_opts --set env=$environment_type"
 
     if [ -n "$HELM_COMMON_VALUES" ]; then
       log_info "--- using \\e[32mcommon values\\e[0m file: \\e[33;1m${HELM_COMMON_VALUES}\\e[0m"
@@ -445,17 +455,16 @@ stages:
       helm_opts="$helm_opts --namespace $namespace"
     fi
 
-    package=$(ls -1 ./helm_packages/*.tgz 2>/dev/null || echo "")
-    package=${package:-$HELM_DEPLOY_CHART}
-    if [ -z "${package}" ]; then
+    chart=${HELM_DEPLOY_CHART:-$HELM_CHART_DIR}
+    if [ -z "${chart}" ]; then
       log_error "No Chart to deploy! Please use \\e[32m\$HELM_DEPLOY_CHART\\e[0m to deploy a chart from a repository"
       log_error "Or check the provided variables to package your own chart!"
       exit 1
     fi
-    log_info "--- using \\e[32mpackage\\e[0m: \\e[33;1m${package}\\e[0m"
+    log_info "--- using \\e[32mchart\\e[0m: \\e[33;1m${chart}\\e[0m"
 
     # shellcheck disable=SC2086
-    helm ${TRACE+--debug} $helm_opts $HELM_DEPLOY_ARGS $environment_name $package
+    helm $helm_opts $HELM_DEPLOY_ARGS $environment_name $chart
 
     # maybe execute post deploy script
     postscript="$HELM_SCRIPTS_DIR/helm-post-deploy.sh"
@@ -484,10 +493,6 @@ stages:
     export environment_name=$2
     namespace=$3
 
-    # backwards compatibility
-    export env=$environment_type
-    export appname=$environment_name
-
     log_info "--- \\e[32mdelete"
     log_info "--- \$namespace: \\e[33;1m${namespace}\\e[0m"
     log_info "--- \$environment_type: \\e[33;1m${environment_type}\\e[0m"
@@ -502,7 +507,7 @@ stages:
       log_info "--- \\e[32mpre-delete hook\\e[0m (\\e[33;1m${prescript}\\e[0m) not found: skip"
     fi
 
-    helm_opts=$(get_helm_config_opt)
+    helm_opts=${TRACE+--debug}
 
     if [ -f "$CI_PROJECT_DIR/.kubeconfig" ]; then
       log_info "--- using \\e[32mkubeconfig\\e[0m: \\e[33;1m$CI_PROJECT_DIR/.kubeconfig\\e[0m"
@@ -515,7 +520,7 @@ stages:
     fi
 
     # shellcheck disable=SC2086
-    helm ${TRACE+--debug} $helm_opts $HELM_DELETE_ARGS $environment_name
+    helm $helm_opts $HELM_DELETE_ARGS $environment_name
 
     # maybe execute post delete script
     postscript="$HELM_SCRIPTS_DIR/helm-post-delete.sh"
@@ -538,7 +543,7 @@ stages:
     log_info "--- \$environment_name: \\e[33;1m${environment_name}\\e[0m"
     log_info "--- \$environment_type: \\e[33;1m${environment_type}\\e[0m"
 
-    helm_opts=$(get_helm_config_opt)
+    helm_opts=${TRACE+--debug}
 
     if [ -f "$CI_PROJECT_DIR/.kubeconfig" ]; then
       log_info "--- using \\e[32mkubeconfig\\e[0m: \\e[33;1m$CI_PROJECT_DIR/.kubeconfig\\e[0m"
@@ -551,17 +556,130 @@ stages:
     fi
 
     # shellcheck disable=SC2086
-    helm ${TRACE+--debug} $helm_opts $HELM_TEST_ARGS $environment_name
+    helm $helm_opts $HELM_TEST_ARGS $environment_name
   }
 
-  function maybe_install_curl() {
-    if ! command -v curl > /dev/null
+  function helm_package() {
+    # determine chart version to publish (semantic-release integration)
+    if [[ "${SEMREL_INFO_ON}" && "${DOCKER_SEMREL_RELEASE_DISABLED}" != "true" ]]
     then
-      log_info "--- installing curl (required to publish Helm charts)..."
-      apk add --no-cache curl
+      if [[ -z "${SEMREL_INFO_NEXT_VERSION}" ]]
+      then
+        log_warn "[semantic-release] no new version to release: skip"
+        exit 0
+      else
+        log_info "[semantic-release] use computed next version: \\e[33;1m${SEMREL_INFO_NEXT_VERSION}\\e[0m"
+        base_version="${SEMREL_INFO_NEXT_VERSION}"
+      fi
+    else
+      base_version=$(awk -F':' '/^version:/ {print $2}' "$HELM_CHART_DIR/Chart.yaml")
+      base_version=${base_version// /}
+    fi
+
+    # also determine version label
+    prod_ref_expr=${PROD_REF#/}
+    prod_ref_expr=${prod_ref_expr%/}
+    if [[ "$CI_COMMIT_REF_NAME" =~ $prod_ref_expr ]]
+    then
+      version_label=""
+    else
+      version_label="-$CI_COMMIT_REF_SLUG"
+    fi
+
+    add_helm_repositories
+
+    # helm package
+    log_info "packaging chart with version: \\e[33;1m${base_version}${version_label}\\e[0m"
+    # shellcheck disable=SC2086
+    helm ${TRACE+--debug} $HELM_PACKAGE_ARGS --version ${base_version}${version_label} $HELM_CHART_DIR --destination helm_packages
+
+    if [[ "$HELM_PUBLISH_SNAPSHOT_ENABLED" == "true" ]]
+    then
+      log_info "snapshot enabled: also package and publish chart with version: \\e[33;1m${base_version}${version_label}-snapshot\\e[0m"
+      mkdir -p /tmp/helm_snapshot
+      # shellcheck disable=SC2086
+      helm ${TRACE+--debug} $HELM_PACKAGE_ARGS --version ${base_version}${version_label}-snapshot $HELM_CHART_DIR --destination /tmp/helm_snapshot
+      snapshot_package=$(ls -1 /tmp/helm_snapshot/*.tgz 2>/dev/null || echo "")
+      helm_publish "$snapshot_package"
     fi
   }
 
+  function helm_publish() {
+    helm_package=${1:-$(ls -1 ./helm_packages/*.tgz 2>/dev/null || echo "")}
+    if [[ -z "$helm_package" ]]; then
+      log_error "No package found to deploy"
+      exit 1
+    fi
+    helm_package_name=$(basename "$helm_package")
+    log_info "--- Publishing Helm package ${helm_package_name} to: ${HELM_PUBLISH_URL}..."
+
+    # method to lowercase
+    HELM_PUBLISH_METHOD=$(echo "$HELM_PUBLISH_METHOD" | tr '[:upper:]' '[:lower:]')
+
+    # auto-detect method
+    if [[ "$HELM_PUBLISH_METHOD" == "auto" ]]
+    then
+        log_info "--- trying to auto detect publish method..."
+        pubscript="$HELM_SCRIPTS_DIR/helm-publish.sh"
+        if [[ -f "$pubscript" ]]
+        then
+          log_info "--- ... custom publish script (\\e[33;1m${postscript}\\e[0m) found: will use"
+          HELM_PUBLISH_METHOD=custom
+        elif [[ "$HELM_PUBLISH_URL" =~ oci://.* ]]
+        then
+          log_info "--- ... publish url looks like an OCI registry: will use helm push"
+          HELM_PUBLISH_METHOD=push
+        else
+          log_info "--- ... publish url looks like a Chart repository: will use push method (uses cm-push plugin)"
+          log_info "--- ... if auto-selected method is not suited, override with \$HELM_PUBLISH_METHOD or provide a custom publish script"
+          HELM_PUBLISH_METHOD=push
+        fi
+    fi
+
+    username="${HELM_PUBLISH_USER:-$CI_REGISTRY_USER}"
+    password="${HELM_PUBLISH_PASSWORD:-$CI_REGISTRY_PASSWORD}"
+    case "$HELM_PUBLISH_METHOD" in
+    push)
+      if [[ "$HELM_PUBLISH_URL" =~ oci://.* ]]
+      then
+        registry_host=$(echo "$HELM_PUBLISH_URL" | awk -F[/:] '{print $4}')
+        # shellcheck disable=SC2086
+        echo "$password" | helm ${TRACE+--debug} registry login "$registry_host" --username "$username" --password-stdin
+        # enable OCI support prior to v3.8.0
+        export HELM_EXPERIMENTAL_OCI=1
+        # shellcheck disable=SC2086
+        helm ${TRACE+--debug} push "$helm_package" "$HELM_PUBLISH_URL"
+      else
+        log_info "Installing cm-push plugin (version ${HELM_CM_PUSH_PLUGIN_VERSION:-latest})..."
+        # shellcheck disable=SC2086
+        helm ${TRACE+--debug} plugin install ${HELM_CM_PUSH_PLUGIN_VERSION:+--version "$HELM_CM_PUSH_PLUGIN_VERSION"} https://github.com/chartmuseum/helm-push || true
+        # shellcheck disable=SC2086
+        helm ${TRACE+--debug} cm-push --username "$username" --password "$password" "$helm_package" "$HELM_PUBLISH_URL"
+      fi
+      ;;
+    post)
+      if ! command -v curl > /dev/null
+      then
+        log_info "--- installing curl (required to publish Helm charts)..."
+        apk add --no-cache curl
+      fi
+      curl --fail --request POST --form "chart=@$helm_package" --user "$username:$password" "$HELM_PUBLISH_URL"
+      ;;
+    put)
+      wget -v --method=PUT --user="$username" --password="$password" --body-file="$helm_package" "$HELM_PUBLISH_URL/$helm_package_name" -O -
+      ;;
+    custom)
+      pubscript="$HELM_SCRIPTS_DIR/helm-publish.sh"
+      log_info "--- run custom publish script (\\e[33;1m${pubscript}\\e[0m)"
+      exec_hook "$pubscript"
+      ;;
+    *)
+      log_error "Unsupported publish method: $HELM_PUBLISH_METHOD"
+      exit 1
+      ;;
+    esac
+  }
+
   unscope_variables
   eval_all_secrets
 
@@ -576,6 +694,9 @@ stages:
   services:
     - name: "$TBC_TRACKING_IMAGE"
       command: ["--service", "helm", "3.3.2" ]
+  variables:
+    HELM_CACHE_HOME: $CI_PROJECT_DIR/.cache/helm
+    HELM_CONFIG_HOME: $CI_PROJECT_DIR/.config/helm
   before_script:
     - *helm-scripts
     - install_ca_certs "${CUSTOM_CA_CERTS:-$DEFAULT_CA_CERTS}"
@@ -779,34 +900,12 @@ helm-package:
     - install_ca_certs "${CUSTOM_CA_CERTS:-$DEFAULT_CA_CERTS}"
     - add_helm_repositories
   script:
-    - |
-      if [[ "$SEMREL_INFO_ON" ]] && [[ "$SEMREL_INFO_NEXT_VERSION" ]] && [[ "$HELM_SEMREL_RELEASE_DISABLED" != "true" ]]
-      then
-        log_info "semantic-release info is activated, using computed next version for release: \\e[1;94m${SEMREL_INFO_NEXT_VERSION}\\e[0m"
-        helm_version_opts="--app-version ${SEMREL_INFO_NEXT_VERSION} --version ${SEMREL_INFO_NEXT_VERSION}"
-      fi
-    - helm $HELM_PACKAGE_ARGS ${TRACE+--debug} $helm_version_opts $HELM_CHART_DIR --destination helm_packages
-    - |
-      package=$(ls -1 ./helm_packages/*.tgz 2>/dev/null || echo "")
-      if [ -n "$HELM_PUBLISH_SNAPSHOT_URL" ] && [ -n "${package}" ]
-      then
-        package_file=$(basename ${package})
-        log_info "publishing helm chart ${package_file} to snapshot url: ${HELM_PUBLISH_SNAPSHOT_URL}"
-        username="${HELM_REPO_SNAPSHOT_USER:-${HELM_REPO_USER:-$CI_REGISTRY_USER}}"
-        password="${HELM_REPO_SNAPSHOT_PASSWORD:-${HELM_REPO_PASSWORD:-$CI_REGISTRY_PASSWORD}}"
-        method="${HELM_REPO_SNAPSHOT_PUBLISH_METHOD:-$HELM_REPO_PUBLISH_METHOD}"
-        if [[ "$method" == "POST" ]]
-        then
-          maybe_install_curl
-          curl --fail --request POST --form "chart=@${package}" --user "$username:$password" $HELM_PUBLISH_SNAPSHOT_URL
-        else
-          wget -v --method=PUT --user="$username" --password="$password" --body-file="${package}" "$HELM_PUBLISH_SNAPSHOT_URL/${package_file}" -O -
-        fi
-      fi
+    - helm_package
   rules:
     - exists:
         - "**/Chart.yaml"
   artifacts:
+    name: "$CI_JOB_NAME artifacts from $CI_PROJECT_NAME on $CI_COMMIT_REF_SLUG"
     expire_in: 1 week
     paths:
       - helm_packages/
@@ -818,35 +917,21 @@ helm-publish:
   extends: .helm-base
   stage: publish
   script:
-    - |
-      package=$(ls -1 ./helm_packages/*.tgz 2>/dev/null || echo "")
-      if [ -n "$HELM_PUBLISH_URL" ] && [ -n "${package}" ]
-      then
-        package_file=$(basename ${package})
-        log_info "publishing helm chart ${package_file} to release url: ${HELM_PUBLISH_URL}"
-        username="${HELM_REPO_RELEASE_USER:-${HELM_REPO_USER:-$CI_REGISTRY_USER}}"
-        password="${HELM_REPO_RELEASE_PASSWORD:-${HELM_REPO_PASSWORD:-$CI_REGISTRY_PASSWORD}}"
-        method="${HELM_REPO_RELEASE_PUBLISH_METHOD:-$HELM_REPO_PUBLISH_METHOD}"
-        if [[ "$method" == "POST" ]]
-        then
-          maybe_install_curl
-          curl --fail --request POST --form "chart=@${package}" --user "$username:$password" $HELM_PUBLISH_URL
-        else
-          wget -v --method=PUT --user="$username" --password="$password" --body-file="${package}" "$HELM_PUBLISH_URL/${package_file}" -O -
-        fi
-      else
-        log_error "No Chart to deploy! url is: $HELM_PUBLISH_URL, and package found is: ${package}"
-      fi
+    - helm_publish
   rules:
-    - if: $HELM_PUBLISH_URL == null || $CI_COMMIT_REF_NAME !~ $PROD_REF
+    - if: '$HELM_PUBLISH_URL == null || $HELM_PUBLISH_URL == "" || $HELM_PUBLISH_METHOD == "disabled"'
+      when: never
+    - if: '$HELM_PUBLISH_ON == "prod" && $CI_COMMIT_REF_NAME !~ $PROD_REF'
+      when: never
+    - if: '$HELM_PUBLISH_ON == "protected" && $CI_COMMIT_REF_PROTECTED != "true"'
       when: never
     - if: '$AUTODEPLOY_TO_PROD == "true"'
+      exists:
+        - "**/Chart.yaml"
     # else: manual + blocking
-    - if: $CI_COMMIT_REF_NAME # this 'if' is useless but only prevents GitLab warning :(
-      when: manual
-    # /!\ variables can't be used in rules:exists
     - exists:
         - "**/Chart.yaml"
+      when: manual
 
 # Deploy job prototype
 # Can be extended to define a concrete environment
@@ -928,7 +1013,7 @@ helm-publish:
 # Stage: review
 # ==================================================
 # deploy to review env (only for feature branches)
-# enabled by default, disable this job by setting $HELM_REVIEW_DISABLED
+# disabled by default, enable this job by setting $HELM_REVIEW_ENABLED
 helm-review:
   extends: .helm-deploy
   variables:
@@ -944,8 +1029,8 @@ helm-review:
     on_stop: helm-cleanup-review
   resource_group: review/$CI_COMMIT_REF_NAME
   rules:
-    # exclude tags and on $HELM_REVIEW_DISABLED set
-    - if: '$HELM_REVIEW_DISABLED == "true" || $CI_COMMIT_TAG'
+    # exclude tags and on $HELM_REVIEW_ENABLED not set
+    - if: '$HELM_REVIEW_ENABLED != "true" || $CI_COMMIT_TAG'
       when: never
     # only on non-production, non-integration branches
     - if: '$CI_COMMIT_REF_NAME !~ $PROD_REF && $CI_COMMIT_REF_NAME !~ $INTEG_REF'
@@ -963,8 +1048,8 @@ helm-cleanup-review:
     action: stop
   resource_group: review/$CI_COMMIT_REF_NAME
   rules:
-    # exclude tags and on $HELM_REVIEW_DISABLED set
-    - if: '$HELM_REVIEW_DISABLED == "true" || $CI_COMMIT_TAG'
+    # exclude tags and on $HELM_REVIEW_ENABLED not set
+    - if: '$HELM_REVIEW_ENABLED != "true" || $CI_COMMIT_TAG'
       when: never
     # only on non-production, non-integration branches
     - if: '$CI_COMMIT_REF_NAME !~ $PROD_REF && $CI_COMMIT_REF_NAME !~ $INTEG_REF'
@@ -972,7 +1057,7 @@ helm-cleanup-review:
       allow_failure: true
 
 # test to review env (only for feature branches)
-# enabled by default, disable this job by setting $HELM_REVIEW_DISABLED
+# disabled by default, enable this job by setting $HELM_REVIEW_ENABLED
 helm-test-review:
   extends: .helm-test
   variables:
@@ -984,7 +1069,7 @@ helm-test-review:
       when: never
     - if: '$HELM_TEST_ENABLED != "true"'
       when: never
-    - if: '$HELM_REVIEW_DISABLED == "true"'
+    - if: '$HELM_REVIEW_ENABLED != "true"'
       when: never
     # exclude on production or integration branch(es)
     - if: '$CI_COMMIT_REF_NAME =~ $PROD_REF || $CI_COMMIT_REF_NAME =~ $INTEG_REF'
@@ -996,7 +1081,7 @@ helm-test-review:
 # Stage: integration
 # ==================================================
 # deploy to integration env (only for integration branches)
-# enabled by default, disable this job by setting $HELM_INTEG_DISABLED
+# disabled by default, enable this job by setting $HELM_INTEG_ENABLED
 helm-integration:
   extends: .helm-deploy
   variables:
@@ -1011,8 +1096,8 @@ helm-integration:
     on_stop: helm-cleanup-integration
   resource_group: integration
   rules:
-    # exclude merge requests and on $HELM_INTEG_DISABLED set
-    - if: '$HELM_INTEG_DISABLED == "true"'
+    # exclude on $HELM_INTEG_ENABLED not set
+    - if: '$HELM_INTEG_ENABLED != "true"'
       when: never
     # only on integration branch(es)
     - if: '$CI_COMMIT_REF_NAME =~ $INTEG_REF'
@@ -1030,8 +1115,8 @@ helm-cleanup-integration:
     action: stop
   resource_group: integration
   rules:
-    # exclude merge requests and on $HELM_INTEG_DISABLED set
-    - if: '$HELM_INTEG_DISABLED == "true"'
+    # exclude on $HELM_INTEG_ENABLED not set
+    - if: '$HELM_INTEG_ENABLED != "true"'
       when: never
     # only on integration branch(es)
     - if: '$CI_COMMIT_REF_NAME =~ $INTEG_REF'
@@ -1039,7 +1124,7 @@ helm-cleanup-integration:
       allow_failure: true
 
 # test to integration env (only for integration branches)
-# enabled by default, disable this job by setting $HELM_INTEG_DISABLED
+# disabled by default, enable this job by setting $HELM_INTEG_ENABLED
 helm-test-integration:
   extends: .helm-test
   variables:
@@ -1052,7 +1137,7 @@ helm-test-integration:
       when: never
     - if: '$HELM_TEST_ENABLED != "true"'
       when: never
-    - if: '$HELM_INTEG_DISABLED == "true"'
+    - if: '$HELM_INTEG_ENABLED != "true"'
       when: never
     # exclude on non-integration branch
     - if: '$CI_COMMIT_REF_NAME !~ $INTEG_REF'
@@ -1077,8 +1162,8 @@ helm-staging:
     on_stop: helm-cleanup-staging
   resource_group: staging
   rules:
-    # exclude merge requests and on $HELM_STAGING_DISABLED set
-    - if: '$HELM_STAGING_DISABLED == "true"'
+    # exclude on $HELM_STAGING_ENABLED not set
+    - if: '$HELM_STAGING_ENABLED != "true"'
       when: never
     # only on production branch(es)
     - if: '$CI_COMMIT_REF_NAME =~ $PROD_REF'
@@ -1096,8 +1181,8 @@ helm-cleanup-staging:
     action: stop
   resource_group: staging
   rules:
-    # exclude merge requests and on $HELM_STAGING_DISABLED set
-    - if: '$HELM_STAGING_DISABLED == "true"'
+    # exclude on $HELM_STAGING_ENABLED not set
+    - if: '$HELM_STAGING_ENABLED != "true"'
       when: never
     # only on production branch(es)
     - if: '$CI_COMMIT_REF_NAME =~ $PROD_REF'
@@ -1116,7 +1201,7 @@ helm-test-staging:
       when: never
     - if: '$HELM_TEST_ENABLED != "true"'
       when: never
-    - if: '$HELM_STAGING_DISABLED == "true"'
+    - if: '$HELM_STAGING_ENABLED != "true"'
       when: never
     # exclude on non-production branch
     - if: '$CI_COMMIT_REF_NAME !~ $PROD_REF'
@@ -1145,8 +1230,8 @@ helm-production:
     # exclude non-production branches
     - if: '$CI_COMMIT_REF_NAME !~ $PROD_REF'
       when: never
-    # exclude if $HELM_PROD_DISABLED set
-    - if: '$HELM_PROD_DISABLED == "true"'
+    # exclude if $HELM_PROD_ENABLED not set
+    - if: '$HELM_PROD_ENABLED != "true"'
       when: never
     # if $AUTODEPLOY_TO_PROD: auto
     - if: '$AUTODEPLOY_TO_PROD == "true"'