Implement recursive loginc on downloader.Manager

Signed-off-by: Miguel Elias dos Santos <migueleliasweb@gmail.com>
pull/11766/head
Miguel Elias dos Santos 3 years ago
parent 03911aeab7
commit 271e9231bc

6
.gitignore vendored

@ -10,3 +10,9 @@ bin/
vendor/ vendor/
# Ignores charts pulled for dependency build tests # Ignores charts pulled for dependency build tests
cmd/helm/testdata/testcharts/issue-7233/charts/* cmd/helm/testdata/testcharts/issue-7233/charts/*
cmd/helm/testdata/testcharts/chart-with-multi-level-deps/root/charts/*
cmd/helm/testdata/testcharts/chart-with-multi-level-deps/root/Chart.lock
cmd/helm/testdata/testcharts/chart-with-multi-level-deps/dep1/charts/*
cmd/helm/testdata/testcharts/chart-with-multi-level-deps/dep1/Chart.lock
cmd/helm/testdata/testcharts/chart-with-multi-level-deps/dep2/charts/*
cmd/helm/testdata/testcharts/chart-with-multi-level-deps/dep2/Chart.lock

@ -68,7 +68,7 @@ func newDependencyBuildCmd(cfg *action.Configuration, out io.Writer) *cobra.Comm
if client.Verify { if client.Verify {
man.Verify = downloader.VerifyIfPossible man.Verify = downloader.VerifyIfPossible
} }
err := man.Build() err := man.Build(client.BuildOrUpdateRecursive)
if e, ok := err.(downloader.ErrRepoNotFound); ok { if e, ok := err.(downloader.ErrRepoNotFound); ok {
return fmt.Errorf("%s. Please add the missing repos via 'helm repo add'", e.Error()) return fmt.Errorf("%s. Please add the missing repos via 'helm repo add'", e.Error())
} }
@ -80,6 +80,7 @@ func newDependencyBuildCmd(cfg *action.Configuration, out io.Writer) *cobra.Comm
f.BoolVar(&client.Verify, "verify", false, "verify the packages against signatures") f.BoolVar(&client.Verify, "verify", false, "verify the packages against signatures")
f.StringVar(&client.Keyring, "keyring", defaultKeyring(), "keyring containing public keys") f.StringVar(&client.Keyring, "keyring", defaultKeyring(), "keyring containing public keys")
f.BoolVar(&client.SkipRefresh, "skip-refresh", false, "do not refresh the local repository cache") f.BoolVar(&client.SkipRefresh, "skip-refresh", false, "do not refresh the local repository cache")
f.BoolVar(&client.BuildOrUpdateRecursive, "recursive", false, "build dependencies recursively")
return cmd return cmd
} }

@ -71,7 +71,7 @@ func newDependencyUpdateCmd(cfg *action.Configuration, out io.Writer) *cobra.Com
if client.Verify { if client.Verify {
man.Verify = downloader.VerifyAlways man.Verify = downloader.VerifyAlways
} }
return man.Update() return man.Update(client.BuildOrUpdateRecursive)
}, },
} }
@ -79,6 +79,7 @@ func newDependencyUpdateCmd(cfg *action.Configuration, out io.Writer) *cobra.Com
f.BoolVar(&client.Verify, "verify", false, "verify the packages against signatures") f.BoolVar(&client.Verify, "verify", false, "verify the packages against signatures")
f.StringVar(&client.Keyring, "keyring", defaultKeyring(), "keyring containing public keys") f.StringVar(&client.Keyring, "keyring", defaultKeyring(), "keyring containing public keys")
f.BoolVar(&client.SkipRefresh, "skip-refresh", false, "do not refresh the local repository cache") f.BoolVar(&client.SkipRefresh, "skip-refresh", false, "do not refresh the local repository cache")
f.BoolVar(&client.BuildOrUpdateRecursive, "recursive", false, "update dependencies recursively")
return cmd return cmd
} }

@ -18,9 +18,11 @@ package main
import ( import (
"bytes" "bytes"
"fmt"
"io" "io"
"os" "os"
"os/exec" "os/exec"
"path/filepath"
"runtime" "runtime"
"strings" "strings"
"testing" "testing"
@ -30,6 +32,7 @@ import (
"helm.sh/helm/v3/internal/test" "helm.sh/helm/v3/internal/test"
"helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/chart/loader"
"helm.sh/helm/v3/pkg/chartutil" "helm.sh/helm/v3/pkg/chartutil"
"helm.sh/helm/v3/pkg/cli" "helm.sh/helm/v3/pkg/cli"
kubefake "helm.sh/helm/v3/pkg/kube/fake" kubefake "helm.sh/helm/v3/pkg/kube/fake"
@ -58,6 +61,15 @@ func runTestCmd(t *testing.T, tests []cmdTestCase) {
t.Fatal(err) t.Fatal(err)
} }
} }
if tt.preCmd != nil {
t.Logf("running preCmd (attempt %d): %s", i+1, tt.cmd)
if err := tt.preCmd(t); err != nil {
t.Errorf("expected no error executing preCmd, got: '%v'", err)
t.FailNow()
}
}
t.Logf("running cmd (attempt %d): %s", i+1, tt.cmd) t.Logf("running cmd (attempt %d): %s", i+1, tt.cmd)
_, out, err := executeActionCommandC(storage, tt.cmd) _, out, err := executeActionCommandC(storage, tt.cmd)
if tt.wantError && err == nil { if tt.wantError && err == nil {
@ -220,3 +232,43 @@ func TestPluginExitCode(t *testing.T) {
} }
} }
} }
// resetChartDependencyState completely resets dependency state of a given chart
// by deleting `Chart.lock` and `charts/`.
//
// If `recursive` is set to true, it will recurse into all local dependency charts
// and do the same.
func resetChartDependencyState(chartPath string, recursive bool) error {
chartRequested, err := loader.Load(chartPath)
if err != nil {
return err
}
os.Remove(fmt.Sprintf("%s/Chart.lock", chartPath))
os.RemoveAll(fmt.Sprintf("%s/charts/", chartPath))
if recursive {
for _, chartDep := range chartRequested.Metadata.Dependencies {
if strings.HasPrefix(
chartDep.Repository,
"file://",
) {
fullDepPath, err := filepath.Abs(
fmt.Sprintf("%s/%s", chartPath, chartDep.Repository[7:]),
)
if err != nil {
return err
}
if err := resetChartDependencyState(fullDepPath, recursive); err != nil {
return err
}
}
}
}
return nil
}

@ -172,6 +172,7 @@ func addInstallFlags(cmd *cobra.Command, f *pflag.FlagSet, client *action.Instal
f.StringVar(&client.Description, "description", "", "add a custom description") f.StringVar(&client.Description, "description", "", "add a custom description")
f.BoolVar(&client.Devel, "devel", false, "use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored") f.BoolVar(&client.Devel, "devel", false, "use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored")
f.BoolVar(&client.DependencyUpdate, "dependency-update", false, "update dependencies if they are missing before installing the chart") f.BoolVar(&client.DependencyUpdate, "dependency-update", false, "update dependencies if they are missing before installing the chart")
f.BoolVar(&client.DependencyUpdateRecursive, "dependency-update-recursive", false, "update dependencies recursively if they are missing before installing the chart")
f.BoolVar(&client.DisableOpenAPIValidation, "disable-openapi-validation", false, "if set, the installation process will not validate rendered templates against the Kubernetes OpenAPI Schema") f.BoolVar(&client.DisableOpenAPIValidation, "disable-openapi-validation", false, "if set, the installation process will not validate rendered templates against the Kubernetes OpenAPI Schema")
f.BoolVar(&client.Atomic, "atomic", false, "if set, the installation process deletes the installation on failure. The --wait flag will be set automatically if --atomic is used") f.BoolVar(&client.Atomic, "atomic", false, "if set, the installation process deletes the installation on failure. The --wait flag will be set automatically if --atomic is used")
f.BoolVar(&client.SkipCRDs, "skip-crds", false, "if set, no CRDs will be installed. By default, CRDs are installed if not already present") f.BoolVar(&client.SkipCRDs, "skip-crds", false, "if set, no CRDs will be installed. By default, CRDs are installed if not already present")
@ -242,7 +243,7 @@ func runInstall(args []string, client *action.Install, valueOpts *values.Options
// https://github.com/helm/helm/issues/2209 // https://github.com/helm/helm/issues/2209
if err := action.CheckDependencies(chartRequested, req); err != nil { if err := action.CheckDependencies(chartRequested, req); err != nil {
err = errors.Wrap(err, "An error occurred while checking for chart dependencies. You may need to run `helm dependency build` to fetch missing dependencies") err = errors.Wrap(err, "An error occurred while checking for chart dependencies. You may need to run `helm dependency build` to fetch missing dependencies")
if client.DependencyUpdate { if client.DependencyUpdate || client.DependencyUpdateRecursive {
man := &downloader.Manager{ man := &downloader.Manager{
Out: out, Out: out,
ChartPath: cp, ChartPath: cp,
@ -253,7 +254,7 @@ func runInstall(args []string, client *action.Install, valueOpts *values.Options
RepositoryCache: settings.RepositoryCache, RepositoryCache: settings.RepositoryCache,
Debug: settings.Debug, Debug: settings.Debug,
} }
if err := man.Update(); err != nil { if err := man.Update(client.DependencyUpdateRecursive); err != nil {
return nil, err return nil, err
} }
// Reload the chart with the updated Chart.lock file. // Reload the chart with the updated Chart.lock file.

@ -153,6 +153,12 @@ func TestInstall(t *testing.T) {
cmd: "install --dependency-update updeps testdata/testcharts/chart-with-subchart-update", cmd: "install --dependency-update updeps testdata/testcharts/chart-with-subchart-update",
golden: "output/chart-with-subchart-update.txt", golden: "output/chart-with-subchart-update.txt",
}, },
// Install chart with update-dependency-recursive
{
name: "install chart with dependency update recursive",
cmd: "install --dependency-update-recursive recdeps testdata/testcharts/chart-with-multi-level-deps/root/",
golden: "output/install-dependency-update-recursive.txt",
},
// Install, chart with bad dependencies in Chart.yaml in /charts // Install, chart with bad dependencies in Chart.yaml in /charts
{ {
name: "install chart with bad dependencies in Chart.yaml", name: "install chart with bad dependencies in Chart.yaml",

@ -96,7 +96,7 @@ func newPackageCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
RepositoryCache: settings.RepositoryCache, RepositoryCache: settings.RepositoryCache,
} }
if err := downloadManager.Update(); err != nil { if err := downloadManager.Update(client.DependencyUpdateRecursive); err != nil {
return err return err
} }
} }
@ -119,6 +119,7 @@ func newPackageCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
f.StringVar(&client.AppVersion, "app-version", "", "set the appVersion on the chart to this version") f.StringVar(&client.AppVersion, "app-version", "", "set the appVersion on the chart to this version")
f.StringVarP(&client.Destination, "destination", "d", ".", "location to write the chart.") f.StringVarP(&client.Destination, "destination", "d", ".", "location to write the chart.")
f.BoolVarP(&client.DependencyUpdate, "dependency-update", "u", false, `update dependencies from "Chart.yaml" to dir "charts/" before packaging`) f.BoolVarP(&client.DependencyUpdate, "dependency-update", "u", false, `update dependencies from "Chart.yaml" to dir "charts/" before packaging`)
f.BoolVarP(&client.DependencyUpdateRecursive, "dependency-update-recursive", "r", false, `update dependencies recursively from from "Chart.yaml" and all of its subcharts before packaging`)
return cmd return cmd
} }

@ -131,6 +131,22 @@ func TestTemplateCmd(t *testing.T) {
cmd: fmt.Sprintf(`template '%s' --skip-tests`, chartPath), cmd: fmt.Sprintf(`template '%s' --skip-tests`, chartPath),
golden: "output/template-skip-tests.txt", golden: "output/template-skip-tests.txt",
}, },
{
name: "template with dependency update recursive",
preCmd: func(t *testing.T) error {
// We must reset the chart's dependency to actually
// exercise the ability to provision missing nested depencendies.
// If we don't do this, the chart will contain the `tgz` files from previous runs
// and the `--dependency-update-recursive` flag won't do much.
// Note the dependency files for the chart are ignored via .gitignore.
return resetChartDependencyState(
"testdata/testcharts/chart-with-multi-level-deps/root",
true,
)
},
cmd: fmt.Sprintf(`template '%s' --dependency-update-recursive`, "testdata/testcharts/chart-with-multi-level-deps/root"),
golden: "output/template-dependency-update-recursive.txt",
},
} }
runTestCmd(t, tests) runTestCmd(t, tests)
} }

@ -0,0 +1,6 @@
NAME: recdeps
LAST DEPLOYED: Fri Sep 2 22:04:05 1977
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None

@ -0,0 +1,22 @@
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "kube-sigs-external-dns" chart repository
Update Complete. ⎈Happy Helming!⎈
Saving 1 charts
Deleting outdated charts
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "kube-sigs-external-dns" chart repository
Update Complete. ⎈Happy Helming!⎈
Saving 1 charts
Deleting outdated charts
---
# Source: root/charts/dep1/templates/configmap1.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: dep1
---
# Source: root/templates/configmaproot.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: root

@ -0,0 +1,9 @@
apiVersion: v2
name: dep1
description: A Helm chart for Kubernetes
type: application
version: 0.1.0
dependencies:
- name: dep2
repository: file://../dep2
version: 0.1.0

@ -0,0 +1,4 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: dep1

@ -0,0 +1,24 @@
apiVersion: v2
name: dep2
description: A Helm chart for Kubernetes
# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.1.0
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "1.16.0"

@ -0,0 +1,4 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: dep2

@ -0,0 +1,9 @@
apiVersion: v2
name: root
description: A Helm chart for Kubernetes
type: application
version: 0.1.0
dependencies:
- name: dep1
repository: file://../dep1
version: 0.1.0

@ -0,0 +1,4 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: root

@ -125,7 +125,8 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
instClient.SubNotes = client.SubNotes instClient.SubNotes = client.SubNotes
instClient.Description = client.Description instClient.Description = client.Description
instClient.DependencyUpdate = client.DependencyUpdate instClient.DependencyUpdate = client.DependencyUpdate
instClient.EnableDNS = client.EnableDNS instClient.EnableDNS = client.EnableDNS
instClient.DependencyUpdateRecursive = client.DependencyUpdateRecursive
rel, err := runInstall(args, instClient, valueOpts, out) rel, err := runInstall(args, instClient, valueOpts, out)
if err != nil { if err != nil {
@ -172,7 +173,7 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
RepositoryCache: settings.RepositoryCache, RepositoryCache: settings.RepositoryCache,
Debug: settings.Debug, Debug: settings.Debug,
} }
if err := man.Update(); err != nil { if err := man.Update(client.DependencyUpdateRecursive); err != nil {
return err return err
} }
// Reload the chart with the updated Chart.lock file. // Reload the chart with the updated Chart.lock file.

@ -34,10 +34,11 @@ import (
// //
// It provides the implementation of 'helm dependency' and its respective subcommands. // It provides the implementation of 'helm dependency' and its respective subcommands.
type Dependency struct { type Dependency struct {
Verify bool Verify bool
Keyring string Keyring string
SkipRefresh bool SkipRefresh bool
ColumnWidth uint ColumnWidth uint
BuildOrUpdateRecursive bool
} }
// NewDependency creates a new Dependency object with the given configuration. // NewDependency creates a new Dependency object with the given configuration.

@ -69,28 +69,29 @@ type Install struct {
ChartPathOptions ChartPathOptions
ClientOnly bool ClientOnly bool
Force bool Force bool
CreateNamespace bool CreateNamespace bool
DryRun bool DryRun bool
DisableHooks bool DisableHooks bool
Replace bool Replace bool
Wait bool Wait bool
WaitForJobs bool WaitForJobs bool
Devel bool Devel bool
DependencyUpdate bool DependencyUpdate bool
Timeout time.Duration DependencyUpdateRecursive bool
Namespace string Timeout time.Duration
ReleaseName string Namespace string
GenerateName bool ReleaseName string
NameTemplate string GenerateName bool
Description string NameTemplate string
OutputDir string Description string
Atomic bool OutputDir string
SkipCRDs bool Atomic bool
SubNotes bool SkipCRDs bool
DisableOpenAPIValidation bool SubNotes bool
IncludeCRDs bool DisableOpenAPIValidation bool
IncludeCRDs bool
// KubeVersion allows specifying a custom kubernetes version to use and // KubeVersion allows specifying a custom kubernetes version to use and
// APIVersions allows a manual set of supported API Versions to be passed // APIVersions allows a manual set of supported API Versions to be passed
// (for things like templating). These are ignored if ClientOnly is false // (for things like templating). These are ignored if ClientOnly is false

@ -35,14 +35,15 @@ import (
// //
// It provides the implementation of 'helm package'. // It provides the implementation of 'helm package'.
type Package struct { type Package struct {
Sign bool Sign bool
Key string Key string
Keyring string Keyring string
PassphraseFile string PassphraseFile string
Version string Version string
AppVersion string AppVersion string
Destination string Destination string
DependencyUpdate bool DependencyUpdate bool
DependencyUpdateRecursive bool
RepositoryConfig string RepositoryConfig string
RepositoryCache string RepositoryCache string

@ -102,6 +102,8 @@ type Upgrade struct {
DisableOpenAPIValidation bool DisableOpenAPIValidation bool
// Get missing dependencies // Get missing dependencies
DependencyUpdate bool DependencyUpdate bool
// Get missing dependencies, recursively
DependencyUpdateRecursive bool
// Lock to control raceconditions when the process receives a SIGTERM // Lock to control raceconditions when the process receives a SIGTERM
Lock sync.Mutex Lock sync.Mutex
// Enable DNS lookups when rendering templates // Enable DNS lookups when rendering templates

@ -82,8 +82,8 @@ type Manager struct {
// If the lockfile is not present, this will run a Manager.Update() // If the lockfile is not present, this will run a Manager.Update()
// //
// If SkipUpdate is set, this will not update the repository. // If SkipUpdate is set, this will not update the repository.
func (m *Manager) Build() error { func (m *Manager) Build(recursive bool) error {
c, err := m.loadChartDir() c, err := m.loadChartDir(m.ChartPath)
if err != nil { if err != nil {
return err return err
} }
@ -92,7 +92,7 @@ func (m *Manager) Build() error {
// an update. // an update.
lock := c.Lock lock := c.Lock
if lock == nil { if lock == nil {
return m.Update() return m.Update(recursive)
} }
// Check that all of the repos we're dependent on actually exist. // Check that all of the repos we're dependent on actually exist.
@ -149,8 +149,30 @@ func (m *Manager) Build() error {
// It first reads the Chart.yaml file, and then attempts to // It first reads the Chart.yaml file, and then attempts to
// negotiate versions based on that. It will download the versions // negotiate versions based on that. It will download the versions
// from remote chart repositories unless SkipUpdate is true. // from remote chart repositories unless SkipUpdate is true.
func (m *Manager) Update() error { //
c, err := m.loadChartDir() // If `recursive` is set to true, it will iterate over all dependencies
// recursively and perform the update.
func (m *Manager) Update(recursive bool) error {
if recursive {
depChartPaths, err := m.locateDependencies(m.ChartPath, recursive)
if err != nil {
return err
}
for _, depChartPath := range depChartPaths {
if err := m.doUpdate(depChartPath); err != nil {
return err
}
}
}
// for last, update the root chart
return m.doUpdate(m.ChartPath)
}
func (m *Manager) doUpdate(chartPath string) error {
c, err := m.loadChartDir(chartPath)
if err != nil { if err != nil {
return err return err
} }
@ -218,13 +240,13 @@ func (m *Manager) Update() error {
return writeLock(m.ChartPath, lock, c.Metadata.APIVersion == chart.APIVersionV1) return writeLock(m.ChartPath, lock, c.Metadata.APIVersion == chart.APIVersionV1)
} }
func (m *Manager) loadChartDir() (*chart.Chart, error) { func (m *Manager) loadChartDir(chartPath string) (*chart.Chart, error) {
if fi, err := os.Stat(m.ChartPath); err != nil { if fi, err := os.Stat(chartPath); err != nil {
return nil, errors.Wrapf(err, "could not find %s", m.ChartPath) return nil, errors.Wrapf(err, "could not find %s", chartPath)
} else if !fi.IsDir() { } else if !fi.IsDir() {
return nil, errors.New("only unpacked charts can be updated") return nil, errors.New("only unpacked charts can be updated")
} }
return loader.LoadDir(m.ChartPath) return loader.LoadDir(chartPath)
} }
// resolve takes a list of dependencies and translates them into an exact version to download. // resolve takes a list of dependencies and translates them into an exact version to download.
@ -742,6 +764,63 @@ func (m *Manager) findChartURL(name, version, repoURL string, repos map[string]*
return url, username, password, false, false, "", "", "", err return url, username, password, false, false, "", "", "", err
} }
// LocateDependencies locates the dependencies for the given chart (optionally recursively)
//
// The returned list of Chart paths is ordered from "leaf to root" so we can issue updates in
// the right order when iterating over this list.
func (m *Manager) locateDependencies(baseChartPath string, resursive bool) ([]string, error) {
reversedDeps := []string{}
baseChart, err := m.loadChartDir(baseChartPath)
if err != nil {
return nil, err
}
for _, chartDependency := range baseChart.Metadata.Dependencies {
fullDepChartPath := chartDependency.Repository
isLocalChart := false
if strings.HasPrefix(
chartDependency.Repository,
"file://",
) {
isLocalChart = true
fullDepChartPath, err = filepath.Abs(
fmt.Sprintf(
"%s/%s",
baseChartPath, chartDependency.Repository[7:]), // removes "file://"
)
if err != nil {
return nil, err
}
}
reversedDeps = append(
[]string{fullDepChartPath},
reversedDeps...,
)
if resursive && isLocalChart {
subDeps, err := m.locateDependencies(fullDepChartPath, resursive)
if err != nil {
return nil, err
}
reversedDeps = append(
subDeps,
reversedDeps...,
)
}
}
return reversedDeps, nil
}
// findEntryByName finds an entry in the chart repository whose name matches the given name. // findEntryByName finds an entry in the chart repository whose name matches the given name.
// //
// It returns the ChartVersions for that entry. // It returns the ChartVersions for that entry.

@ -321,12 +321,12 @@ func TestUpdateBeforeBuild(t *testing.T) {
} }
// Update before Build. see issue: https://github.com/helm/helm/issues/7101 // Update before Build. see issue: https://github.com/helm/helm/issues/7101
err = m.Update() err = m.Update(false)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
err = m.Build() err = m.Build(false)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -396,7 +396,7 @@ func TestUpdateWithNoRepo(t *testing.T) {
} }
// Test the update // Test the update
err = m.Update() err = m.Update(false)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -461,13 +461,13 @@ func checkBuildWithOptionalFields(t *testing.T, chartName string, dep chart.Depe
} }
// First build will update dependencies and create Chart.lock file. // First build will update dependencies and create Chart.lock file.
err = m.Build() err = m.Build(false)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
// Second build should be passed. See PR #6655. // Second build should be passed. See PR #6655.
err = m.Build() err = m.Build(false)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

Loading…
Cancel
Save