knative / operator

Combined operator for Knative.
Apache License 2.0
190 stars 100 forks source link

Publish helm chart with each release #1525

Closed acelinkio closed 11 months ago

acelinkio commented 1 year ago

Describe the bug Helm chart is not published into a helm repository.

Expected behavior Have a helm chart available with each release (or a known cadence).

Additional context https://github.com/knative/operator/pull/1447 added a helm chart https://github.com/knative/operator/pull/1501 modified behavior to generate helm chart

Would greatly appreciate if this chart was published somewhere so this operator could be deployed using gitops tools.

acelinkio commented 1 year ago

Not sure how to best contribute here. Some teams choose to publish the chart with the same versioning as the project, others split it out.

houshengbo commented 1 year ago

@acelinkio Are you interested in publishing helm charts? Feel free to contribute. Thx.

github-actions[bot] commented 1 year ago

This issue is stale because it has been open for 90 days with no activity. It will automatically close after 30 more days of inactivity. Reopen the issue with /reopen. Mark the issue as fresh by adding the comment /remove-lifecycle stale.

Qwiko commented 5 months ago

Is this something that is being worked on? I am very interested in deploying the Knative Operator with GitOps methods.

kromanow94 commented 3 months ago

Hey, my two cents here:

Resources:

/reopen

/remove-lifecycle stale

knative-prow[bot] commented 3 months ago

@kromanow94: You can't reopen an issue/PR unless you authored it or you are a collaborator.

In response to [this](https://github.com/knative/operator/issues/1525#issuecomment-2245523050): >Hey, my two cents here: >* This is a big pain point that the Helm Chart is not released anywhere. >* It would be possible to use ArgoCD with Helm Chart source as a git repository but the [config/charts/knative-operator/Chart.yaml](https://github.com/knative/operator/blob/4d616234ad3ea4aad42adcb78d82c6005f486543/config/charts/knative-operator/Chart.yaml#L3) uses hacky `{{ version }}` variable that is provided through the `./hack/generate-helm.sh` described [here](https://github.com/knative/operator/blob/main/docs/release.md#release-the-helm-chart) which makes this unusable. > > ```yaml > apiVersion: argoproj.io/v1alpha1 > kind: Application > metadata: > name: knative-operator > namespace: argocd > finalizers: > - resources-finalizer.argocd.argoproj.io > spec: > destination: > server: https://kubernetes.default.svc > namespace: knative-operator > project: default > sources: > - repoURL: https://github.com/knative/operator.git > targetRevision: knative-v1.11.12 > path: config/charts/knative-operator > ``` > > The above ArgoCD App example would basically download the repo and checkout a specific version and execute `helm template`, but the following error is blocking this: > ``` > Error: cannot load Chart.yaml: error converting YAML to JSON: yaml: invalid map key: map[interface {}]interface {}{"version":interface {}(nil)} > ``` > >* There are nice tools that helps in releasing the Helm Chart with GitHub Repository serving as a Helm Chart Repository. One example would be the [Chart Releaser](https://github.com/helm/chart-releaser). But, the Helm Chart Release process in `knative/opreator` is using the `./hack/generate-helm.sh` and hacky `{{ version }}` in the `Chart.yaml`. Without it, it would be fairly straightforward to automate the Helm Chart Release process. Another idea would be to define a custom GH Workflow that would automate this process. > >* Another way to have a GitHub Repository as a Helm Chart Repository relates to manual creation of the `index.yaml` file and host it behind GitHub Pages. TL;DR: > * Create branch (can be empty) for GitHub Pages to point as the source of what to host. > * Create some simple `index.html` file for GitHub Pages to have something to host on the webpage. > * Create simple `index.yaml` file that contains information about the Helm Charts and their URL to the archive > * example: https://helm.sh/docs/topics/chart_repository/#the-index-file > * Configure GitHub Pages in the GitHub Repository config. > >Resources: >* https://docs.github.com/en/pages/getting-started-with-github-pages/creating-a-github-pages-site >* https://helm.sh/docs/topics/chart_repository >* https://github.com/helm/chart-releaser > >/reopen > >/remove-lifecycle stale Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md). If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes-sigs/prow](https://github.com/kubernetes-sigs/prow/issues/new?title=Prow%20issue:) repository.
kromanow94 commented 3 months ago

Or, even easier: create index.yaml file with format specified as in https://helm.sh/docs/topics/chart_repository/#the-index-file and create helm chart repository in artifacthub.io pointing to this file in a format similar to

https://raw.githubusercontent.com/knative/operator/main/

The above URL assumes that in the main branch of this repository contains the index.yaml file.

Then the artifacthub.io scans periodically for changes in the file and serves as the helm repository based on the index.yaml file.

One could even add some logic to the ./hack/generate-helm.sh or create ./hack/update-helm-index.sh and just commit the changes when new package is available.

With this, no github pages are required and this is baseically a two-step approach. Create index.yaml file and point to it in artifacthub.io.

kromanow94 commented 3 months ago

This is an example python script that can automate creation if index.yaml file:

import yaml
import requests
import hashlib
from datetime import datetime

urls = [
    "https://github.com/knative/operator/releases/download/knative-v1.14.5/knative-operator-v1.14.5.tgz",
    "https://github.com/knative/operator/releases/download/knative-v1.14.4/knative-operator-v1.14.4.tgz"
]

index = {'apiVersion': 'v1', 'entries': {}}

for url in urls:
    name_version = url.split('/')[-1].replace('.tgz', '')
    name, version = name_version.rsplit('-', 1)
    response = requests.get(url)
    digest = hashlib.sha256(response.content).hexdigest()

    if name not in index['entries']:
        index['entries'][name] = []

    index['entries'][name].append({
        'apiVersion': 'v2',
        'name': name,
        'version': version,
        'urls': [url],
        'created': datetime.utcnow().isoformat() + 'Z',
        'digest': digest
    })

with open('index.yaml', 'w') as f:
    yaml.dump(index, f, sort_keys=False)