diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 17c2784..334e4ab 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -101,6 +101,8 @@ jobs: - name: Run tests run: | pytest --verbose --color=yes --cov chartpress + env: + HELM2: ${{ matrix.helm2 }} # GitHub action reference: https://github.com/codecov/codecov-action - uses: codecov/codecov-action@v3 diff --git a/README.md b/README.md index c9639fb..96bf0c7 100644 --- a/README.md +++ b/README.md @@ -161,8 +161,12 @@ for each chart. Below is an example `chartpress.yaml` file. ```yaml charts: # list of charts by name - # each name should be a directory containing a helm chart + # each name should be the name of a Helm chart - name: binderhub + # Directory containing the chart, relative to chartpress.yaml. + # Can be omitted if the directory is the same as the chart name. + chartPath: helm-charts/binderhub + # the prefix to use for built images imagePrefix: jupyterhub/k8s- # tag to use when resetting the chart values diff --git a/chartpress.py b/chartpress.py index b80758e..cedd412 100644 --- a/chartpress.py +++ b/chartpress.py @@ -358,7 +358,7 @@ def _get_all_chart_paths(options): """ paths = [] paths.append("chartpress.yaml") - paths.append(options["name"]) + paths.append(options["chartPath"]) paths.extend(options.get("paths", [])) if "images" in options: for image_name, image_config in options["images"].items(): @@ -719,9 +719,9 @@ def build_images( return values_file_modifications -def _update_values_file_with_modifications(name, modifications): +def _update_values_file_with_modifications(chart_path, modifications): """ - Update /values.yaml file with a dictionary of modifications with its + Update /values.yaml file with a dictionary of modifications with its root level keys representing a path within the values.yaml file. Example of a modifications dictionary: @@ -737,7 +737,7 @@ def _update_values_file_with_modifications(name, modifications): } } """ - values_file = os.path.join(name, "values.yaml") + values_file = os.path.join(chart_path, "values.yaml") with open(values_file) as f: values = yaml.load(f) @@ -815,7 +815,7 @@ def _trim_version_suffix(version): def build_chart( - name, + chart_path, version=None, paths=None, long=False, @@ -840,7 +840,7 @@ def build_chart( - 0.9.0 """ # read Chart.yaml - chart_file = os.path.join(name, "Chart.yaml") + chart_file = os.path.join(chart_path, "Chart.yaml") with open(chart_file) as f: chart = yaml.load(f) @@ -873,6 +873,7 @@ def publish_pages( chart_repo_url, extra_message="", force=False, + chart_path=None, ): """ Update a Helm chart registry hosted in the gh-pages branch of a GitHub git @@ -904,6 +905,9 @@ def publish_pages( this, it is as we would have a --force-publish-chart by default. """ + if chart_path is None: + chart_path = chart_name + # clone/fetch the Helm chart repo and checkout its gh-pages branch, note the # use of cwd (current working directory) checkout_dir = f"{chart_name}-{chart_version}" @@ -953,7 +957,7 @@ def publish_pages( [ "helm", "package", - chart_name, + chart_path, "--dependency-update", "--destination", td + "/", @@ -1222,6 +1226,9 @@ def main(argv=None): forced_version = None base_version = None + if not chart.get("chartPath"): + chart["chartPath"] = chart["name"] + if args.tag: # tag specified, use that version forced_version = args.tag @@ -1240,7 +1247,7 @@ def main(argv=None): if not args.list_images: # update Chart.yaml with a version chart_version = build_chart( - chart["name"], + chart["chartPath"], paths=_get_all_chart_paths(chart), version=forced_version, base_version=base_version, @@ -1284,7 +1291,7 @@ def main(argv=None): # update values.yaml _update_values_file_with_modifications( - chart["name"], values_file_modifications + chart["chartPath"], values_file_modifications ) # publish chart @@ -1296,6 +1303,7 @@ def main(argv=None): chart_repo_url=chart["repo"]["published"], extra_message=args.extra_message, force=args.force_publish_chart, + chart_path=chart["chartPath"], ) diff --git a/tests/conftest.py b/tests/conftest.py index c8ca86a..398a587 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -135,7 +135,7 @@ def git_repo_backport_branch(git_repo_dev_tag): @pytest.fixture def git_repo_alternative(monkeypatch, git_repo): """ - This fixture modifies the default git_repo fixture to use another the + This fixture modifies the default git_repo fixture to use chartpress_alternative.yaml as chartpress.yaml. """ r = git_repo @@ -149,8 +149,8 @@ def git_repo_alternative(monkeypatch, git_repo): @pytest.fixture def git_repo_base_version(monkeypatch, git_repo): """ - This fixture modifies the default git_repo fixture to use another the - chartpress_alternative.yaml as chartpress.yaml. + This fixture modifies the default git_repo fixture to use + chartpress_base_version.yaml as chartpress.yaml. """ r = git_repo shutil.move("chartpress_base_version.yaml", "chartpress.yaml") diff --git a/tests/test_helm_chart/chartpress_alternative.yaml b/tests/test_helm_chart/chartpress_alternative.yaml index 217b7d1..6ad224a 100644 --- a/tests/test_helm_chart/chartpress_alternative.yaml +++ b/tests/test_helm_chart/chartpress_alternative.yaml @@ -1,7 +1,11 @@ charts: - - name: testchart + - name: alternative + chartPath: subdir/chart images: testimage: - imageName: testimage + imageName: alternativeimage contextPath: image valuesPath: image + repo: + git: "." + published: https://test.local diff --git a/tests/test_helm_chart/subdir/chart/Chart.yaml b/tests/test_helm_chart/subdir/chart/Chart.yaml new file mode 100644 index 0000000..e3a9723 --- /dev/null +++ b/tests/test_helm_chart/subdir/chart/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v1 +name: alternative +version: 0.0.1-set.by.chartpress diff --git a/tests/test_helm_chart/subdir/chart/templates/configmap.yaml b/tests/test_helm_chart/subdir/chart/templates/configmap.yaml new file mode 100644 index 0000000..1db01ca --- /dev/null +++ b/tests/test_helm_chart/subdir/chart/templates/configmap.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: ConfigMap +data: + test.json: | + { + "alternativeKey": "alternativeValue" + } diff --git a/tests/test_helm_chart/subdir/chart/values.yaml b/tests/test_helm_chart/subdir/chart/values.yaml new file mode 100644 index 0000000..57407b0 --- /dev/null +++ b/tests/test_helm_chart/subdir/chart/values.yaml @@ -0,0 +1,4 @@ +image: alternative/alternative:set-by-chartpress +list: + - "alternative/alternative:set-by-chartpress" + - image: "alternative/alternative:set-by-chartpress" diff --git a/tests/test_repo_interactions.py b/tests/test_repo_interactions.py index f9e0269..fa3d82a 100644 --- a/tests/test_repo_interactions.py +++ b/tests/test_repo_interactions.py @@ -452,11 +452,13 @@ def test_chartpress_run_bare_minimum(git_repo_bare_minimum, capfd): assert f"Updating testchart/Chart.yaml: version: {tag}" in out +@pytest.mark.skipif(os.environ.get("HELM2") == "helm2", reason="Skipping helm 2") def test_chartpress_run_alternative(git_repo_alternative, capfd): """ Ensures that chartpress will run with an alternative configuration. This allow us to test against more kinds of configurations than we could squeeze - into a single chartpress.yaml file. + into a single chartpress.yaml file, including: + - chart name != chart directory name """ r = git_repo_alternative sha = r.heads.main.commit.hexsha[:7] @@ -465,9 +467,13 @@ def test_chartpress_run_alternative(git_repo_alternative, capfd): tag = "v1.0.0" check_version(tag) - out = _capture_output(["--skip-build", "--tag", tag], capfd) - assert f"Updating testchart/Chart.yaml: version: {tag[1:]}" in out - assert f"Updating testchart/values.yaml: image: testimage:{tag}" in out + out = _capture_output(["--skip-build", "--tag", tag, "--publish-chart"], capfd) + assert f"Updating subdir/chart/Chart.yaml: version: {tag[1:]}" in out + assert f"Updating subdir/chart/values.yaml: image: alternativeimage:{tag}" in out + + gh_pages = r.heads["gh-pages"].commit.tree + expected_files = sorted(b.name for b in gh_pages.blobs) + assert expected_files == ["alternative-1.0.0.tgz", "index.yaml"] def _capture_output(args, capfd, expect_output=False):