From 250b38689a035a57f467303c3fa3cd6c2cb0758b Mon Sep 17 00:00:00 2001 From: borislavr Date: Wed, 2 Jul 2025 10:32:35 +0300 Subject: [PATCH 1/7] feat: added possibility to search image versions by regexp --- actions/helm-charts-release/action.yaml | 2 ++ .../image-versions-replace.py | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/actions/helm-charts-release/action.yaml b/actions/helm-charts-release/action.yaml index aa6a5eb6..8fd3b5d9 100644 --- a/actions/helm-charts-release/action.yaml +++ b/actions/helm-charts-release/action.yaml @@ -70,6 +70,8 @@ runs: - name: "Update chart and images versions" id: update-versions run: | + sudo apt-get update + sudo apt-get install -y skopeo sudo chmod +x "${GITHUB_ACTION_PATH}/image-versions-replace.py" ${GITHUB_ACTION_PATH}/image-versions-replace.py \ --config-file ${{ inputs.config-file }} \ diff --git a/actions/helm-charts-release/image-versions-replace.py b/actions/helm-charts-release/image-versions-replace.py index fd6e957f..f587580d 100644 --- a/actions/helm-charts-release/image-versions-replace.py +++ b/actions/helm-charts-release/image-versions-replace.py @@ -4,6 +4,7 @@ import json import os import re +import subprocess import yaml def replace_env_variables(input_string): @@ -17,6 +18,20 @@ def replacer(match): return pattern.sub(replacer, input_string) +def replace_tag_regexp(image_str, tag_re): + # Try to find the requested tag for given image_str + if tag_re.startswith("#"): + try: + os.system(f"skopeo login -u $GITHUB_ACTOR -p GITHUB_TOKEN ghcr.io") + result_tag = subprocess.run(f"skopeo list-tags docker://{image_str} | jq -r '.Tags[] | select(test(\"^{tag_re[1:]}\"))' | sort -V | tail -n 1", shell=True, text=True, check=True, capture_output=True).stdout + return(result_tag) + #os.system(f"skopeo list-tags docker://{image_str} | jq -r '.Tags[] | select(test("^{tag_re[1:]}"))' | sort -V | tail -n 1") + except Exception as e: + print(f"Error: {e}") + + else: + return tag_re + def create_summary(images_versions): # Create a summary of the images versions summary = "## Image Versions Updated\n" @@ -47,6 +62,7 @@ def set_image_versions(config_file, release, chart_version, method): search_str = image.split(':')[0] if method == 'parse': image_ver = replace_env_variables(image.split(':')[1].replace('${release}', release)) + image_ver = replace_tag_regexp(search_str, image_ver) print(f"Updating {search_str} version to {image_ver}") os.system(f"sed -i 's|{search_str}:[a-zA-Z0-9._-]*|{search_str}:{image_ver}|' {values_file}") # Add to dictionary for action output From 45438846eb1785c0b1b97f51fa177693ef2f7f0d Mon Sep 17 00:00:00 2001 From: borislavr Date: Wed, 2 Jul 2025 10:47:08 +0300 Subject: [PATCH 2/7] fix: ensure trailing whitespace is removed from result tag in replace_tag_regexp function --- actions/helm-charts-release/image-versions-replace.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/actions/helm-charts-release/image-versions-replace.py b/actions/helm-charts-release/image-versions-replace.py index f587580d..07bc7b32 100644 --- a/actions/helm-charts-release/image-versions-replace.py +++ b/actions/helm-charts-release/image-versions-replace.py @@ -22,8 +22,8 @@ def replace_tag_regexp(image_str, tag_re): # Try to find the requested tag for given image_str if tag_re.startswith("#"): try: - os.system(f"skopeo login -u $GITHUB_ACTOR -p GITHUB_TOKEN ghcr.io") - result_tag = subprocess.run(f"skopeo list-tags docker://{image_str} | jq -r '.Tags[] | select(test(\"^{tag_re[1:]}\"))' | sort -V | tail -n 1", shell=True, text=True, check=True, capture_output=True).stdout + os.system(f"skopeo login -u $GITHUB_ACTOR -p $GITHUB_TOKEN ghcr.io") + result_tag = subprocess.run(f"skopeo list-tags docker://{image_str} | jq -r '.Tags[] | select(test(\"^{tag_re[1:]}\"))' | sort -V | tail -n 1", shell=True, text=True, check=True, capture_output=True).stdout.rstrip() return(result_tag) #os.system(f"skopeo list-tags docker://{image_str} | jq -r '.Tags[] | select(test("^{tag_re[1:]}"))' | sort -V | tail -n 1") except Exception as e: From 25ab53905e353ff5a9848c43540c1c7214177e24 Mon Sep 17 00:00:00 2001 From: borislavr Date: Wed, 2 Jul 2025 10:55:19 +0300 Subject: [PATCH 3/7] feat: add GITHUB_TOKEN and GITHUB_ACTOR to environment variables for improved authentication --- actions/helm-charts-release/action.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/actions/helm-charts-release/action.yaml b/actions/helm-charts-release/action.yaml index 8fd3b5d9..9a4c7202 100644 --- a/actions/helm-charts-release/action.yaml +++ b/actions/helm-charts-release/action.yaml @@ -80,6 +80,9 @@ runs: --version-replace-method ${{ inputs.version-replace-method }} shell: bash working-directory: ${{ inputs.working-directory }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_ACTOR: ${{ github.actor }} - name: "Summary" run: | From 4c374a10504650ef250cf4ea73f075a3b1b2b1ac Mon Sep 17 00:00:00 2001 From: borislavr Date: Wed, 2 Jul 2025 11:10:17 +0300 Subject: [PATCH 4/7] fix: remove unnecessary environment variables from helm charts release action --- actions/helm-charts-release/action.yaml | 3 --- 1 file changed, 3 deletions(-) diff --git a/actions/helm-charts-release/action.yaml b/actions/helm-charts-release/action.yaml index 9a4c7202..8fd3b5d9 100644 --- a/actions/helm-charts-release/action.yaml +++ b/actions/helm-charts-release/action.yaml @@ -80,9 +80,6 @@ runs: --version-replace-method ${{ inputs.version-replace-method }} shell: bash working-directory: ${{ inputs.working-directory }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - GITHUB_ACTOR: ${{ github.actor }} - name: "Summary" run: | From 9bd9d37d741b542c249769e356ad5e6d967ed992 Mon Sep 17 00:00:00 2001 From: borislavr Date: Wed, 2 Jul 2025 14:00:47 +0300 Subject: [PATCH 5/7] feat: enhance README and config examples for version replacement and environment variables --- actions/helm-charts-release/README.md | 18 +++++++++++++++++- .../helm-charts-release-config.yaml | 8 +++----- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/actions/helm-charts-release/README.md b/actions/helm-charts-release/README.md index 0f3473e3..01e429f1 100644 --- a/actions/helm-charts-release/README.md +++ b/actions/helm-charts-release/README.md @@ -30,12 +30,25 @@ Whether to create a release branch. Defaults to `true`. If set to `false`, then The method to replace the version in `values.yaml`. Can be `replace` or `parse`. Defaults to `parse`. If set to `replace` the action will just replace the versions of docker images with `release-version` value. If set to `parse` the action read provided `config-file` and substitute any environment variables provided in the version part. For example if you have some 3-rd party image in `values.yaml` file and want to manage it's version, you can add repository level variable and use it in the config file: `some-thirg-party-image:${THIRD_PARTY_VERSION}`. +Also if you want the action to find the latest version of some image (supplimentary service for instance), you can set it to something like `#4.*.*`. In that case the action will find the latest 4th version of an image. The regex of a version must start with `#` symbol. ### `working-directory` **Optional** The working directory for the action. Defaults to `.`. Used in specific cases, in testing CI workflows mostly. +## Environment + +### `GITHUB_TOKEN` + +**Required** +The GitHub token to authenticate in `ghcr.io` registry. + +### `GITHUB_ACTOR` + +**Required** +The GitHub login to authenticate in `ghcr.io` registry. + ## Outputs ### `images-versions` @@ -73,6 +86,10 @@ jobs: create-release-branch: 'true' version-replace-method: 'parse' working-directory: './charts' + env: + ${{ insert }}: ${{ vars }} # This will insert all repository variables into env context + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_ACTOR: ${{ github.actor }} ``` ## How It Works @@ -93,4 +110,3 @@ jobs: - `image`: List of image keys to update in `values.yaml`. > Example: [helm-charts-release-config.yaml](./helm-charts-release-config.yaml). -Ensure that the Python environment is set up to run the `yaml` module for processing the configuration file. diff --git a/actions/helm-charts-release/helm-charts-release-config.yaml b/actions/helm-charts-release/helm-charts-release-config.yaml index 9669ee01..2af08127 100644 --- a/actions/helm-charts-release/helm-charts-release-config.yaml +++ b/actions/helm-charts-release/helm-charts-release-config.yaml @@ -10,8 +10,6 @@ charts: chart_file: charts/helm/module1/Chart.yaml values_file: charts/helm/module1/values.yaml image: - - ghcr.io/netcracker/module1:${release} - - ghcr.io/netcracker/module1-service1:${release} - - ghcr.io/netcracker/module1-service2:${release} - - ghcr.io/netcracker/module1-service3:${release} - - ghcr.io/netcracker/module1-service4:${release} + - ghcr.io/netcracker/module1:${release} # This will replace the image version with the release version + - ghcr.io/netcracker/module1-service1:${release}-${THIRD_PARTY_VERSION} # This will replace the image version with the release version and append the THIRD_PARTY_VERSION variable + - ghcr.io/netcracker/module1-service2:#5.*.* # This will select the latest tag matching the regexp From e903c9d363554ef8115aedaa935d07acdff349b8 Mon Sep 17 00:00:00 2001 From: borislavr Date: Thu, 3 Jul 2025 11:12:22 +0300 Subject: [PATCH 6/7] feat: added support for `#latest` label --- actions/helm-charts-release/image-versions-replace.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/actions/helm-charts-release/image-versions-replace.py b/actions/helm-charts-release/image-versions-replace.py index 07bc7b32..64ea7827 100644 --- a/actions/helm-charts-release/image-versions-replace.py +++ b/actions/helm-charts-release/image-versions-replace.py @@ -23,9 +23,11 @@ def replace_tag_regexp(image_str, tag_re): if tag_re.startswith("#"): try: os.system(f"skopeo login -u $GITHUB_ACTOR -p $GITHUB_TOKEN ghcr.io") - result_tag = subprocess.run(f"skopeo list-tags docker://{image_str} | jq -r '.Tags[] | select(test(\"^{tag_re[1:]}\"))' | sort -V | tail -n 1", shell=True, text=True, check=True, capture_output=True).stdout.rstrip() + if tag_re[1:] == 'latest': + result_tag = subprocess.run(f"skopeo list-tags docker://{image_str} | jq -r '.Tags[]' | grep -e \"^[0-9]*\.[0-9]*\.[0-9]*\" | sort -V | tail -n 1", shell=True, text=True, check=True, capture_output=True).stdout.rstrip() + else: + result_tag = subprocess.run(f"skopeo list-tags docker://{image_str} | jq -r '.Tags[] | select(test(\"^{tag_re[1:]}\"))' | sort -V | tail -n 1", shell=True, text=True, check=True, capture_output=True).stdout.rstrip() return(result_tag) - #os.system(f"skopeo list-tags docker://{image_str} | jq -r '.Tags[] | select(test("^{tag_re[1:]}"))' | sort -V | tail -n 1") except Exception as e: print(f"Error: {e}") From 25d1955465b848e596b004fd73059a3add8626ce Mon Sep 17 00:00:00 2001 From: borislavr Date: Thu, 3 Jul 2025 11:26:11 +0300 Subject: [PATCH 7/7] docs: improved helm-charts-release action README.md --- actions/helm-charts-release/README.md | 8 ++++++-- .../helm-charts-release/helm-charts-release-config.yaml | 3 ++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/actions/helm-charts-release/README.md b/actions/helm-charts-release/README.md index 01e429f1..2263fc5e 100644 --- a/actions/helm-charts-release/README.md +++ b/actions/helm-charts-release/README.md @@ -29,8 +29,12 @@ Whether to create a release branch. Defaults to `true`. If set to `false`, then **Optional** The method to replace the version in `values.yaml`. Can be `replace` or `parse`. Defaults to `parse`. -If set to `replace` the action will just replace the versions of docker images with `release-version` value. If set to `parse` the action read provided `config-file` and substitute any environment variables provided in the version part. For example if you have some 3-rd party image in `values.yaml` file and want to manage it's version, you can add repository level variable and use it in the config file: `some-thirg-party-image:${THIRD_PARTY_VERSION}`. -Also if you want the action to find the latest version of some image (supplimentary service for instance), you can set it to something like `#4.*.*`. In that case the action will find the latest 4th version of an image. The regex of a version must start with `#` symbol. +If set to `replace` the action will just replace the versions of docker images with `release-version` value. +If set to `parse` the action read provided `config-file` and substitute any environment variables provided in the version part. +For example if you have some 3-rd party image in `values.yaml` file and want to manage it's version, you can add repository level variable and use it in the config file: `some-thirg-party-image:${THIRD_PARTY_VERSION}`. +Also if you want the action to find the latest version of some image (supplimentary service for instance), you can set it to something like `#4.*.*` or `#latest`. +In that case the action will find the latest tag of an image which satisfy the regular expression. The regular expression of a tag must start with `#` symbol and follow the `jq` syntax. +**Special word `#latest` will result the latest SemVer tag of the image, not the one which marked with `latest` tag.** ### `working-directory` diff --git a/actions/helm-charts-release/helm-charts-release-config.yaml b/actions/helm-charts-release/helm-charts-release-config.yaml index 2af08127..1fd091f5 100644 --- a/actions/helm-charts-release/helm-charts-release-config.yaml +++ b/actions/helm-charts-release/helm-charts-release-config.yaml @@ -12,4 +12,5 @@ charts: image: - ghcr.io/netcracker/module1:${release} # This will replace the image version with the release version - ghcr.io/netcracker/module1-service1:${release}-${THIRD_PARTY_VERSION} # This will replace the image version with the release version and append the THIRD_PARTY_VERSION variable - - ghcr.io/netcracker/module1-service2:#5.*.* # This will select the latest tag matching the regexp + - ghcr.io/netcracker/module1-service2:#5.*.* # This will select the latest tag matching the jq regular expression + - ghcr.io/netcracker/module1-service2:#latest # This will select the latest SemVer tag