Skip to content

Commit 472eb12

Browse files
committed
controllers: set generation as version metadata
By providing the Generation of the object that is getting reconciled as version metadata to the builder if any custom values files are defined, the Artifact revision changes if the specification does, ensuring consumers of the Artifact are able to react to changes in values (and perform a release). Signed-off-by: Hidde Beydals <hello@hidde.co>
1 parent c202ad5 commit 472eb12

File tree

1 file changed

+33
-19
lines changed

1 file changed

+33
-19
lines changed

controllers/helmchart_controller.go

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"net/url"
2424
"os"
2525
"path/filepath"
26+
"strconv"
2627
"strings"
2728
"time"
2829

@@ -332,24 +333,29 @@ func (r *HelmChartReconciler) fromHelmRepository(ctx context.Context, repo sourc
332333
}
333334

334335
// Build the chart
335-
cBuilder := chart.NewRemoteBuilder(chartRepo)
336+
cb := chart.NewRemoteBuilder(chartRepo)
336337
ref := chart.RemoteReference{Name: c.Spec.Chart, Version: c.Spec.Version}
337338
opts := chart.BuildOptions{
338339
ValuesFiles: c.GetValuesFiles(),
339340
CachedChart: cachedChart,
340341
Force: force,
341342
}
342-
build, err := cBuilder.Build(ctx, ref, filepath.Join(workDir, "chart.tgz"), opts)
343+
// Set the VersionMetadata to the object's Generation if ValuesFiles is defined
344+
// This ensures changes can be noticed by the Artifact consumer
345+
if len(opts.GetValuesFiles()) > 0 {
346+
opts.VersionMetadata = strconv.FormatInt(c.Generation, 10)
347+
}
348+
b, err := cb.Build(ctx, ref, filepath.Join(workDir, "chart.tgz"), opts)
343349
if err != nil {
344350
return sourcev1.HelmChartNotReady(c, sourcev1.ChartPullFailedReason, err.Error()), err
345351
}
346352

347-
newArtifact := r.Storage.NewArtifactFor(c.Kind, c.GetObjectMeta(), build.Version,
348-
fmt.Sprintf("%s-%s.tgz", build.Name, build.Version))
353+
newArtifact := r.Storage.NewArtifactFor(c.Kind, c.GetObjectMeta(), b.Version,
354+
fmt.Sprintf("%s-%s.tgz", b.Name, b.Version))
349355

350356
// If the path of the returned build equals the cache path,
351357
// there are no changes to the chart
352-
if build.Path == cachedChart {
358+
if b.Path == cachedChart {
353359
// Ensure hostname is updated
354360
if c.GetArtifact().URL != newArtifact.URL {
355361
r.Storage.SetArtifactURL(c.GetArtifact())
@@ -374,18 +380,18 @@ func (r *HelmChartReconciler) fromHelmRepository(ctx context.Context, repo sourc
374380
defer unlock()
375381

376382
// Copy the packaged chart to the artifact path
377-
if err = r.Storage.CopyFromPath(&newArtifact, build.Path); err != nil {
383+
if err = r.Storage.CopyFromPath(&newArtifact, b.Path); err != nil {
378384
err = fmt.Errorf("failed to write chart package to storage: %w", err)
379385
return sourcev1.HelmChartNotReady(c, sourcev1.StorageOperationFailedReason, err.Error()), err
380386
}
381387

382388
// Update symlink
383-
cUrl, err := r.Storage.Symlink(newArtifact, fmt.Sprintf("%s-latest.tgz", build.Name))
389+
cUrl, err := r.Storage.Symlink(newArtifact, fmt.Sprintf("%s-latest.tgz", b.Name))
384390
if err != nil {
385391
err = fmt.Errorf("storage error: %w", err)
386392
return sourcev1.HelmChartNotReady(c, sourcev1.StorageOperationFailedReason, err.Error()), err
387393
}
388-
return sourcev1.HelmChartReady(c, newArtifact, cUrl, sourcev1.ChartPullSucceededReason, build.Summary()), nil
394+
return sourcev1.HelmChartReady(c, newArtifact, cUrl, sourcev1.ChartPullSucceededReason, b.Summary()), nil
389395
}
390396

391397
func (r *HelmChartReconciler) fromTarballArtifact(ctx context.Context, source sourcev1.Artifact, c sourcev1.HelmChart,
@@ -430,35 +436,43 @@ func (r *HelmChartReconciler) fromTarballArtifact(ctx context.Context, source so
430436
defer dm.Clear()
431437

432438
// Configure builder options, including any previously cached chart
433-
buildsOpts := chart.BuildOptions{
439+
opts := chart.BuildOptions{
434440
ValuesFiles: c.GetValuesFiles(),
435441
Force: force,
436442
}
437443
if artifact := c.Status.Artifact; artifact != nil {
438-
buildsOpts.CachedChart = artifact.Path
444+
opts.CachedChart = artifact.Path
439445
}
440446

441447
// Add revision metadata to chart build
442448
if c.Spec.ReconcileStrategy == sourcev1.ReconcileStrategyRevision {
443449
// Isolate the commit SHA from GitRepository type artifacts by removing the branch/ prefix.
444450
splitRev := strings.Split(source.Revision, "/")
445-
buildsOpts.VersionMetadata = splitRev[len(splitRev)-1]
451+
opts.VersionMetadata = splitRev[len(splitRev)-1]
452+
}
453+
// Set the VersionMetadata to the object's Generation if ValuesFiles is defined
454+
// This ensures changes can be noticed by the Artifact consumer
455+
if len(opts.GetValuesFiles()) > 0 {
456+
if opts.VersionMetadata != "" {
457+
opts.VersionMetadata += "."
458+
}
459+
opts.VersionMetadata += strconv.FormatInt(c.Generation, 10)
446460
}
447461

448462
// Build chart
449-
chartBuilder := chart.NewLocalBuilder(dm)
450-
result, err := chartBuilder.Build(ctx, chart.LocalReference{WorkDir: sourceDir, Path: chartPath}, filepath.Join(workDir, "chart.tgz"), buildsOpts)
463+
cb := chart.NewLocalBuilder(dm)
464+
b, err := cb.Build(ctx, chart.LocalReference{WorkDir: sourceDir, Path: chartPath}, filepath.Join(workDir, "chart.tgz"), opts)
451465
if err != nil {
452466
return sourcev1.HelmChartNotReady(c, reasonForBuildError(err), err.Error()), err
453467
}
454468

455-
newArtifact := r.Storage.NewArtifactFor(c.Kind, c.GetObjectMeta(), result.Version,
456-
fmt.Sprintf("%s-%s.tgz", result.Name, result.Version))
469+
newArtifact := r.Storage.NewArtifactFor(c.Kind, c.GetObjectMeta(), b.Version,
470+
fmt.Sprintf("%s-%s.tgz", b.Name, b.Version))
457471

458472
// If the path of the returned build equals the cache path,
459473
// there are no changes to the chart
460474
if apimeta.IsStatusConditionTrue(c.Status.Conditions, meta.ReadyCondition) &&
461-
result.Path == buildsOpts.CachedChart {
475+
b.Path == opts.CachedChart {
462476
// Ensure hostname is updated
463477
if c.GetArtifact().URL != newArtifact.URL {
464478
r.Storage.SetArtifactURL(c.GetArtifact())
@@ -483,19 +497,19 @@ func (r *HelmChartReconciler) fromTarballArtifact(ctx context.Context, source so
483497
defer unlock()
484498

485499
// Copy the packaged chart to the artifact path
486-
if err = r.Storage.CopyFromPath(&newArtifact, result.Path); err != nil {
500+
if err = r.Storage.CopyFromPath(&newArtifact, b.Path); err != nil {
487501
err = fmt.Errorf("failed to write chart package to storage: %w", err)
488502
return sourcev1.HelmChartNotReady(c, sourcev1.StorageOperationFailedReason, err.Error()), err
489503
}
490504

491505
// Update symlink
492-
cUrl, err := r.Storage.Symlink(newArtifact, fmt.Sprintf("%s-latest.tgz", result.Name))
506+
cUrl, err := r.Storage.Symlink(newArtifact, fmt.Sprintf("%s-latest.tgz", b.Name))
493507
if err != nil {
494508
err = fmt.Errorf("storage error: %w", err)
495509
return sourcev1.HelmChartNotReady(c, sourcev1.StorageOperationFailedReason, err.Error()), err
496510
}
497511

498-
return sourcev1.HelmChartReady(c, newArtifact, cUrl, reasonForBuildSuccess(result), result.Summary()), nil
512+
return sourcev1.HelmChartReady(c, newArtifact, cUrl, reasonForBuildSuccess(b), b.Summary()), nil
499513
}
500514

501515
// namespacedChartRepositoryCallback returns a chart.GetChartRepositoryCallback

0 commit comments

Comments
 (0)