{"id":643,"date":"2022-12-14T15:33:11","date_gmt":"2022-12-14T15:33:11","guid":{"rendered":"https:\/\/www.aviator.co\/blog\/?p=643"},"modified":"2025-09-25T13:08:45","modified_gmt":"2025-09-25T13:08:45","slug":"how-to-onboard-an-existing-helm-application-in-argocd","status":"publish","type":"post","link":"https:\/\/www.aviator.co\/blog\/how-to-onboard-an-existing-helm-application-in-argocd\/","title":{"rendered":"How to onboard an existing Helm application in ArgoCD"},"content":{"rendered":"\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img fetchpriority=\"high\" decoding=\"async\" width=\"1024\" height=\"576\" src=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2023\/01\/helmargocd-1024x576.jpeg\" alt=\"\" class=\"wp-image-713\" style=\"width:512px;height:288px\" srcset=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2023\/01\/helmargocd-1024x576.jpeg 1024w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2023\/01\/helmargocd-300x169.jpeg 300w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2023\/01\/helmargocd-768x432.jpeg 768w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2023\/01\/helmargocd-1536x864.jpeg 1536w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2023\/01\/helmargocd.jpeg 1920w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>GitOps is the recommended way of implementing continuous deployment for cloud-native applications. It helps an organization by minimizing manual mistakes while deploying an application, as Git will be the single source of truth. Hence, changes can be easily tracked across teams.<\/p>\n\n\n\n<p>This article aims to help engineers who\u2019d like to adopt GitOps culture in their company via ArgoCD on the applications that are already <a href=\"https:\/\/www.aviator.co\/blog\/choosing-canary-vs-rollout-deployments-in-kubernetes\/\" target=\"_blank\" rel=\"noopener\" title=\"deployed and running in the Kubernetes\">deployed and running in the Kubernetes<\/a> clusters.<\/p>\n\n\n\n<p>Since GitOps is relatively new, one might have questions regarding how to onboard existing apps to ArgoCD without redeploying their microservices. Let&#8217;s see how to solve that.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"1940\" height=\"500\" src=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/04\/aviator-mergequeue-blog-service-page-cta-photo-min-1.png\" alt=\"Mergequeue CTA\" class=\"wp-image-4920\" srcset=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/04\/aviator-mergequeue-blog-service-page-cta-photo-min-1.png 1940w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/04\/aviator-mergequeue-blog-service-page-cta-photo-min-1-300x77.png 300w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/04\/aviator-mergequeue-blog-service-page-cta-photo-min-1-1024x264.png 1024w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/04\/aviator-mergequeue-blog-service-page-cta-photo-min-1-768x198.png 768w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/04\/aviator-mergequeue-blog-service-page-cta-photo-min-1-1536x396.png 1536w\" sizes=\"(max-width: 1940px) 100vw, 1940px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Prerequisites<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Kubernetes cluster<\/li>\n\n\n\n<li>Helm v3<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Application via Helm repository<\/h2>\n\n\n\n<p>In ArgoCD, you can install Helm-based apps in two ways. One of them is installing apps directly via a remote Helm repository. This can be Gitlab\u2019s Helm repository, self-hosted options like Chartmusem, or GitHub Pages.<\/p>\n\n\n\n<p>Let\u2019s install app <code>nginx-ingress<\/code> using helm repository. This step tries to simulate an app already running in your cluster deployed via helm install command before you onboard it via ArgoCD.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#add the helm repo\nhelm repo add ingress-nginx https:\/\/kubernetes.github.io\/ingress-nginx\n\n#install the helm chart\nhelm install ingress-nginx ingress-nginx\/ingress-nginx --version 4.4.0 --set controller.service.type=ClusterIP\n\n#kubectl get pod\nNAME                                        READY   STATUS    RESTARTS   AGE\ningress-nginx-controller-6f7bd4bcfb-dp57x   1\/1     Running   0          3m50s<\/code><\/pre>\n\n\n\n<p>Once the pods are running, let\u2019s install ArgoCD to our cluster.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#add the helm repo\nhelm repo add argo https:\/\/argoproj.github.io\/argo-helm\n\n#install the helm chart\nhelm install argocd argo\/argo-cd --set-string configs.params.\"server\\.disable\\.auth\"=true --version 5.12.0 --create-namespace -n argocd<\/code><\/pre>\n\n\n\n<p>Validate that ArgoCD pods are running and are in READY state.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl get pod -n argocd\n\nNAME                                                READY   STATUS    RESTARTS   AGE\nargocd-application-controller-0                     1\/1     Running   0          14m\nargocd-applicationset-controller-6cb8549cd9-ms2tr   1\/1     Running   0          14m\nargocd-dex-server-77b996879b-j2zd8                  1\/1     Running   0          14m\nargocd-notifications-controller-6456d4b685-kb6hn    1\/1     Running   0          14m\nargocd-redis-cdf4df6bc-xg7v6                        1\/1     Running   0          14m\nargocd-repo-server-8b9dd576b-xfv8s                  1\/1     Running   0          14m\nargocd-server-b9f6c4ccd-7vdjz                       1\/1     Running   0          14m<\/code><\/pre>\n\n\n\n<p>Now that ArgoCD is running, let\u2019s create the ArgoCD Application manifest for our app.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cat &lt;&lt;EOF &gt;&gt; nginx-ingress.yaml\napiVersion: argoproj.io\/v1alpha1\nkind: Application\nmetadata:\n  name: ingress-nginx\n  namespace: argocd\nspec:\n  project: default\n  destination:\n    namespace: default  #update namespace name if you wish\n    name: in-cluster   #update cluster name if its different\n  source:\n    repoURL: https:\/\/kubernetes.github.io\/ingress-nginx\n    targetRevision: \"4.4.0\"\n    chart: ingress-nginx\n    helm:\n      values: |\n        controller:\n          service:\n            type: ClusterIP    \nEOF<\/code><\/pre>\n\n\n\n<p>Few points to note in the above manifest :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>If you\u2019re completely new to ArgoCD and aren\u2019t aware of the structure of an application manifest, I suggest you read about ArgoCD Application <a href=\"https:\/\/argo-cd.readthedocs.io\/en\/stable\/operator-manual\/declarative-setup\/#applications\">here<\/a>.<\/li>\n\n\n\n<li>Any helm custom values you wish to override on the default helm values need to be added in the <strong>helm values<\/strong> section.<\/li>\n\n\n\n<li>In the future, whenever you need to upgrade the app\/chart version, you can just update the <code>targetRevision<\/code> which is the git tag of the helm chart release and ArgoCD will pull that chart and apply the changes. This can be done either by editing this file or by updating the tag via ArgoCD UI.<\/li>\n\n\n\n<li><code>[**metadata.name**](&lt;http:\/\/metadata.name&gt;)<\/code> should exactly match the helm release name. Else this will be considered a new release.<\/li>\n<\/ul>\n\n\n\n<p>The main idea here is that the helm value config specified via ArgoCD should <strong>exactly match<\/strong> the config (values file) specified at the time of helm install or upgrade.<\/p>\n\n\n\n<p>For example, during helm install, if the service type was <code>ClusterIP<\/code>, ArgoCD app manifest should also have that config. If you don\u2019t specify that, ArgoCD will override with default chart values which will cause downtime.<\/p>\n\n\n\n<p>This mainly needs to be taken care of for dependent third-party charts for example MongoDB, Redis etc.<\/p>\n\n\n\n<p>Ok. Let\u2019s apply the manifest we created using the command.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl apply -f nginx-ingress.yaml\n\n#application.argoproj.io\/my-ingress-nginx created<\/code><\/pre>\n\n\n\n<p>To access Argo UI, lets port-forward the argocd-server service and open in your browser : https:\/\/localhost:8080<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl port-forward service\/argocd-server 8080:8080 -n argocd<\/code><\/pre>\n\n\n\n<p>Now, if you go to the nginx-ingress app, its status is OutOfSync.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/12\/helm1a.png\"><img decoding=\"async\" width=\"1024\" height=\"544\" src=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/12\/helm1-1024x544.png\" alt=\"\" class=\"wp-image-646\" srcset=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/12\/helm1-1024x544.png 1024w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/12\/helm1-300x159.png 300w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/12\/helm1-768x408.png 768w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/12\/helm1-1536x816.png 1536w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/12\/helm1.png 2000w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Let&#8217;s see what change is not synced by clicking on the App Diff. That will show you what is the desired change and what\u2019s applied right now.<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/12\/helm2a.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"414\" src=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/12\/helm2-1024x414.png\" alt=\"\" class=\"wp-image-647\" srcset=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/12\/helm2-1024x414.png 1024w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/12\/helm2-300x121.png 300w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/12\/helm2-768x311.png 768w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/12\/helm2-1536x621.png 1536w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/12\/helm2.png 2000w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">In our specific application, for almost all Kubernetes resources, an annotation is needed which is from the ArgoCD side. That\u2019s how ArgoCD keeps track of the resources it needs to track. You can read more about this annotation from the doc <a href=\"https:\/\/argo-cd.readthedocs.io\/en\/stable\/faq\/#why-is-my-app-out-of-sync-even-after-syncing\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a>.<\/figcaption><\/figure>\n\n\n\n<p>Let\u2019s <code>sync<\/code> the app which will apply that ArgoCD annotation on all resources.<\/p>\n\n\n\n<p>After the sync, as you can see no resources got removed or recreated.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/12\/helm3a.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"542\" src=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/12\/helm3-1024x542.png\" alt=\"\" class=\"wp-image-648\" srcset=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/12\/helm3-1024x542.png 1024w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/12\/helm3-300x159.png 300w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/12\/helm3-768x406.png 768w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/12\/helm3-1536x813.png 1536w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/12\/helm3.png 2000w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl get all -l app.kubernetes.io\/name=ingress-nginx\n\nNAME                                            READY   STATUS    RESTARTS   AGE\npod\/ingress-nginx-controller-6f7bd4bcfb-dp57x   1\/1     Running   0          21m\n\nNAME                                         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE\nservice\/ingress-nginx-controller             ClusterIP   10.96.156.40   &lt;none&gt;        80\/TCP,443\/TCP   21m\nservice\/ingress-nginx-controller-admission   ClusterIP   10.96.118.65   &lt;none&gt;        443\/TCP          21m\n\nNAME                                       READY   UP-TO-DATE   AVAILABLE   AGE\ndeployment.apps\/ingress-nginx-controller   1\/1     1            1           21m\n\nNAME                                                  DESIRED   CURRENT   READY   AGE\nreplicaset.apps\/ingress-nginx-controller-6f7bd4bcfb   1         1         1       21m<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Applications via Git Repository<\/h2>\n\n\n\n<p>If your helm chart is not hosted in a helm repository and stored in GitHub or any other SCM tools like GitLab or BitBucket, migration of that helm app can also be done easily.<\/p>\n\n\n\n<p>Fork the sample app repository : <a href=\"https:\/\/github.com\/stefanprodan\/podinfo\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/github.com\/stefanprodan\/podinfo<\/a><\/p>\n\n\n\n<p>Clone the repository and update replicacount in values.yaml from 1 to 3.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#clone your fork\ngit clone https:\/\/github.com\/&lt;user-name&gt;\/podinfo.git &amp;&amp; cd podinfo\/charts\/podinfo\n\n#update  replcaCount to 3\nsed -i -e '\/replicaCount\/ s\/: .*\/: 3\/' values.yaml<\/code><\/pre>\n\n\n\n<p>Push this change to your GitHub repository.<\/p>\n\n\n\n<p>Deploy the helm chart via helm.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>helm install podinfo-git . -f values.yaml -n default<\/code><\/pre>\n\n\n\n<p>Create an ArgoCD Application manifest that will point to your repository and the path inside the repository where the helm chart is stored.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\ncat &lt;&lt;EOF &gt;&gt; podinfo-app-git.yaml\napiVersion: argoproj.io\/v1alpha1\nkind: Application\nmetadata:\n  name: podinfo-git\n  namespace: argocd\nspec:\n  project: default  \n  destination:\n    namespace: default  #update namespace name if you wish\n    name: in-cluster   #update cluster name if its different\n  source:\n    repoURL: 'https:\/\/github.com\/tanmay-bhat\/podinfo'  #replace with your username\n    path: charts\/podinfo\n    targetRevision: HEAD\n    helm:\n      valueFiles:\n        - values.yaml       #any custom value file you want to apply.\nEOF<\/code><\/pre>\n\n\n\n<p>ArgoCD automatically detects that in the path you specified, the application has to be onboarded as a Helm chart not via Kubernetes Manifest files. It understands that type by scanning <code>Chart.yaml <\/code>in the path you specified to detect the Kind of Application. In my case <code>chart.yaml<\/code> is inside <code>charts\/podinfo<\/code> of the repository. You can read more about automated tool detection <a href=\"https:\/\/argo-cd.readthedocs.io\/en\/stable\/user-guide\/tool_detection\/\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a>.<\/p>\n\n\n\n<p>Apply the manifest you created into <code>argocd<\/code> namespace.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl apply -f podinfo-app-git.yaml -n argocd               \n\n#application.argoproj.io\/podinfo configured<\/code><\/pre>\n\n\n\n<p>Just like the previous migration, this app also will be out of sync with annotation change update. <code>Sync<\/code> the application after reviewing the <code>App Diff<\/code>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/12\/helm4a.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"414\" src=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/12\/helm4-1024x414.png\" alt=\"\" class=\"wp-image-649\" srcset=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/12\/helm4-1024x414.png 1024w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/12\/helm4-300x121.png 300w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/12\/helm4-768x310.png 768w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/12\/helm4-1536x621.png 1536w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/12\/helm4.png 2000w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>As you can see from the above snapshot, the pods &amp; other resources are not recreated.<\/p>\n\n\n\n<p>If you take a look at the <code>App Details<\/code> of this over the UI, we can see that it synced the configs to our GitHub repository.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/12\/helm5a.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"482\" src=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/12\/helm5-1024x482.png\" alt=\"\" class=\"wp-image-650\" srcset=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/12\/helm5-1024x482.png 1024w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/12\/helm5-300x141.png 300w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/12\/helm5-768x361.png 768w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/12\/helm5-1536x723.png 1536w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/12\/helm5.png 2000w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Gotchas<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>I haven&#8217;t added the auto sync option in ArgoCD application definition, since it&#8217;s always best to see what\u2019s the app diff, review and then sync.<\/li>\n\n\n\n<li>Certain application like Grafana has <code>checksum\/secret<\/code> in their template definitions.\n<ul class=\"wp-block-list\">\n<li>While migrating to ArgoCD, its own annotation needs to be applied as seen above.<\/li>\n\n\n\n<li>Once that annotation is applied to the secret, its checksum changes and that checksum will get <a href=\"https:\/\/github.com\/grafana\/helm-charts\/blob\/d35d39815a4d4373c3d9de7898d858f783e1786e\/charts\/grafana\/templates\/deployment.yaml#L40\">updated in the deployment<\/a>.<\/li>\n\n\n\n<li>So for application config like those, the pod will get recreated.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">References<\/h3>\n\n\n\n<p><a href=\"https:\/\/argo-cd.readthedocs.io\/en\/stable\/faq\/#why-is-my-app-out-of-sync-even-after-syncing\">https:\/\/argo-cd.readthedocs.io\/en\/stable\/faq\/#why-is-my-app-out-of-sync-even-after-syncing<\/a><\/p>\n\n\n\n<p><a href=\"https:\/\/argo-cd.readthedocs.io\/en\/stable\/getting_started\/\">https:\/\/argo-cd.readthedocs.io\/en\/stable\/getting_started\/<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><a href=\"https:\/\/www.aviator.co\/\" target=\"_blank\" rel=\"noreferrer noopener\">Aviator<\/a>: Automate your cumbersome merge processes<\/h2>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/www.aviator.co\/\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"727\" src=\"https:\/\/blog.aviator.co\/wp-content\/uploads\/2022\/08\/blog-cta-1024x727.png\" alt=\"\" class=\"wp-image-57\" srcset=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/08\/blog-cta-1024x727.png 1024w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/08\/blog-cta-300x213.png 300w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/08\/blog-cta-768x545.png 768w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/08\/blog-cta-1536x1090.png 1536w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/08\/blog-cta-2048x1454.png 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>Aviator automates tedious developer workflows by managing git Pull Requests (PRs) and continuous integration test (CI) runs to help your team avoid broken builds, streamline cumbersome merge processes, manage cross-PR dependencies, and handle flaky tests while maintaining their security compliance.<\/p>\n\n\n\n<p>There are 4 key components to Aviator:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>MergeQueue<\/strong>&nbsp;\u2013 an automated queue that manages the merging workflow for your GitHub repository to help protect important branches from broken builds. The Aviator bot uses GitHub Labels to identify Pull Requests (PRs) that are ready to be merged, validates CI checks, processes semantic conflicts, and merges the PRs automatically.<\/li>\n\n\n\n<li><strong>ChangeSets<\/strong>&nbsp;\u2013 workflows to synchronize validating and merging multiple PRs within the same repository or multiple repositories. Useful when your team often sees groups of related PRs that need to be merged together, or otherwise treated as a single broader unit of change.<\/li>\n\n\n\n<li><strong>FlakyBot<\/strong>&nbsp;\u2013 a tool to automatically detect, take action on, and process results from flaky tests in your CI infrastructure.<\/li>\n\n\n\n<li><strong>Stacked PRs CLI<\/strong>&nbsp;\u2013 a command line tool that helps developers manage cross-PR dependencies. This tool also automates syncing and merging of stacked PRs. Useful when your team wants to promote a culture of smaller, incremental PRs instead of large changes, or when your workflows involve keeping multiple, dependent PRs in sync.<\/li>\n<\/ol>\n\n\n\n<p><a href=\"https:\/\/www.aviator.co\/\" target=\"_blank\" rel=\"noopener\" title=\"\">Try it for free.<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>A step-by-step tutorial on how to use Helm  in ArgoCD<\/p>\n","protected":false},"author":11,"featured_media":713,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[302],"tags":[20,19,21],"class_list":["post-643","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tooling-integrations"],"blocksy_meta":{"styles_descriptor":{"styles":{"desktop":"","tablet":"","mobile":""},"google_fonts":[],"version":6}},"acf":[],"aioseo_notices":[],"jetpack_featured_media_url":"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2023\/01\/helmargocd.jpeg","post_mailing_queue_ids":[],"_links":{"self":[{"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/posts\/643","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/users\/11"}],"replies":[{"embeddable":true,"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/comments?post=643"}],"version-history":[{"count":20,"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/posts\/643\/revisions"}],"predecessor-version":[{"id":4927,"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/posts\/643\/revisions\/4927"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/media\/713"}],"wp:attachment":[{"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/media?parent=643"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/categories?post=643"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/tags?post=643"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}