diff --git a/actions/helm-charts-release/README.md b/actions/helm-charts-release/README.md index 0f3473e3..2263fc5e 100644 --- a/actions/helm-charts-release/README.md +++ b/actions/helm-charts-release/README.md @@ -29,13 +29,30 @@ 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}`. +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` **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 +90,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 +114,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/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/helm-charts-release-config.yaml b/actions/helm-charts-release/helm-charts-release-config.yaml index 9669ee01..1fd091f5 100644 --- a/actions/helm-charts-release/helm-charts-release-config.yaml +++ b/actions/helm-charts-release/helm-charts-release-config.yaml @@ -10,8 +10,7 @@ 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 jq regular expression + - ghcr.io/netcracker/module1-service2:#latest # This will select the latest SemVer tag diff --git a/actions/helm-charts-release/image-versions-replace.py b/actions/helm-charts-release/image-versions-replace.py index fd6e957f..64ea7827 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,22 @@ 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") + 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) + 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 +64,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