unbroken-dome / gradle-helm-plugin

A Gradle plugin for building, publishing and managing Helm charts.
MIT License
52 stars 55 forks source link

Support for publish-if-not-exists #86

Open andysworkshop opened 4 years ago

andysworkshop commented 4 years ago

Our artifactory instance implements write-once semantics for final chart versions and will throw an error if you try to publish the same version again. Sometimes we need to re-run a pipeline to resolve an error that came after the chart publication leaving us unable to get past the publication that worked first time.

Currently we work around with an ugly bit of curl in an onlyIf attached to the publish task. It would be great if this logic was encapsulated in the DSL.

tkrullmann commented 4 years ago

Good idea :-)

In your custom curl call, are you downloading the repo index and check if it contains the chart, or are you just making a HEAD request to the known location of the chart and check for 404?

andysworkshop commented 4 years ago

We're using the artifactory storage API to do a GET on the artifact's information descriptor:

https://[SERVER]/artifactory/api/storage/[REPO]/[FULL-PATH-TO-CHART].tgz

If it succeeds you get back 200 and a small json document describing the artifact. HEAD will also work but we use GET because it's useful to see the artifact descriptor in the gradle INFO level output so we know why the publish didn't happen and when the last publication was.

If the artifact does not exist then the response is 404:

curl: (22) The requested URL returned error: 404 Not Found
andysworkshop commented 4 years ago

The complication we have with the above check is that our artifactory is configured to permit overwrites for snapshots but block them for releases (immutable release policy). I haven't checked to see how that plays out for our projects that are using semver but for -SNAPSHOT style versions it definitely is allowing overwrites, which it must do if the chart version is to match the java artifact version.

Ideally this plugin wouldn't try to get involved with all that and just support publishIfNotExists as a closure returning true/false where we can provide the logic that looks at the version and decides if artifactory is going to allow overwrites or not.

tkrullmann commented 4 years ago

Well, this approach seems pretty specific to Artifactory... so probably each repository type would need its own strategy to do the check. As a default strategy, I suppose checking the index and/or doing a HEAD request to a well-known location should be supported by all repository types.

Some custom repositories may not have an index, so we can't rely on that, but always using a HEAD request may also be problematic because the chart .tgz URL is only by convention, the repo index should be the source of truth.

As for configuration in the DSL, I suppose there should be a property skipPublishIfExists on the HelmPublish task and the chart. Maybe also add this property on a per-repository and global scope for convenience.

As for special SNAPSHOT versions, I would like to keep this logic out of the plugin as it seems pretty tied to Artifactory and its Maven heritage. With a Boolean property this could be achieved pretty easily in the build script.

If we're downloading and parsing the repo index anyway, we could also use the digest from the repo index for up-to-date checking of the HelmPublish task. But this will probably be a separate enhancement :-)

wingsofovnia commented 4 years ago

This feature would be really nice to have. I think having skipPublishIfExists on the HelmPublish task would be a great first step.