Installing charts in parallel using go routines I use the following code which works and install helm chart (in the loop) in parallel,
it get a kubeconfig file (to access to k8s) create a helm client and install the charts from the defined location and waits (upgradeAction.Wait = true) that each chart installation will finished successfully.
At first I do it in sequence and now I added a wait.group to be able to reduce the installation time and install it in parallel, do I miss something? error handling etc?
    package main
    
    import (
        &quot;fmt&quot;
        &quot;os&quot;
        &quot;strings&quot;
        &quot;sync&quot;
    )
    
    func main() {
      log.Info(&quot;tools Installation&quot;)

    kcfgFilePath, err := kubeFile(cfg)
    defer os.Remove(kcfgFilePath)
    if err != nil {
        return err
    }
    settings := cli.New()
    actionConfig := new(action.Configuration)
    clientGetter := genericclioptions.NewConfigFlags(false)
    clientGetter.KubeConfig = &amp;kcfgFilePath
    // install all relevant components
    var wg sync.WaitGroup

    for _, chartInstallation := range charts {
        wg.Add(1)
         go installChart(&amp;wg,chartInstallation, releaseName, actionConfig, clientGetter, settings, log)
    }
    return nil
}

func installChart(wg *sync.WaitGroup,chartInstallation Installation, releaseName string, actionConfig *action.Configuration, clientGetter *genericclioptions.ConfigFlags, settings *cli.EnvSettings, log logr.Logger) (error, bool) {
    defer wg.Done()
    chart, err := loader.Load(chartInstallation.Path)
    if err != nil {
        return err, true
    }
    releaseName = releaseName + &quot;-&quot; + chartInstallation.Name
    if err := actionConfig.Init(clientGetter, settings.Namespace(), os.Getenv(&quot;HELM_DRIVER&quot;), func(format string, v ...interface{}) {
        r := fmt.Sprintf(format, v)
        log.Info(&quot;Helm Installation&quot;, &quot;deploy status&quot;, r)
    }); err != nil {
        return err, true
    }
    releasePresent := true
    status, err := action.NewStatus(actionConfig).Run(releaseName)
    if err != nil {
        //if errors.Is(err, driver.ErrReleaseNotFound) {
        if strings.Contains(err.Error(), driver.ErrReleaseNotFound.Error()) {
            releasePresent = false
        } else {
            return err, true
        }
    }

    if !releasePresent {
        // install chart
        installAction := action.NewInstall(actionConfig)
        installAction.CreateNamespace = true
        installAction.Namespace = chartInstallation.Namespace
        installAction.ReleaseName = releaseName
        
        installAction.Wait = true
        // install new
        _, err := installAction.Run(chart, nil)
        if err != nil {
            return err, true
        }
        log.Info(&quot;installed: &quot;, &quot;releaseName&quot;, releaseName)
    }

    if status != nil {
        if releasePresent &amp;&amp; status.Info.Status.String() == release.StatusFailed.String() { // upgrade if broken
            upgradeAction := action.NewUpgrade(actionConfig)
            upgradeAction.Atomic = false
            upgradeAction.CleanupOnFail = true
            upgradeAction.Wait = true
            upgradeAction.ReuseValues = false
            upgradeAction.Recreate = false
            _, err := upgradeAction.Run(releaseName, chart, nil)
            if err != nil {
                return err, true
            }
        }
    }
    return nil, false
}
The code is ignoring the return values from the go routine
The WorkGroup isn't used to block until completion

// 1. Perhaps you'd want to have a separate channel to communicate the errors.
var errCh := make(chan error, len(charts))
for _, chartInstallation := range charts {
    wg.Add(1)
    go func(errCh chan error){
       installed, err := installChart(&amp;wg,chartInstallation, releaseName, actionConfig, clientGetter, settings, log)
       if err != nil {
           errCh &lt;- err
       }
    }(errCh)
}
// 2. Wait for the wait group to complete
wg.Wait()
// 1. Collect the errors
for err := range errCh {
    fmt.Println(&quot;Error: &quot;, err)
}