|
| 1 | +name: Build Helm Releases |
| 2 | +on: |
| 3 | + workflow_call: |
| 4 | + inputs: |
| 5 | + charts: |
| 6 | + description: The list of charts filtered to be built. |
| 7 | + required: true |
| 8 | + type: string |
| 9 | + images: |
| 10 | + description: The list of built images. |
| 11 | + required: true |
| 12 | + type: string |
| 13 | + image_tag: |
| 14 | + description: The tag of the built images. |
| 15 | + required: true |
| 16 | + type: string |
| 17 | + chart_filters_path: |
| 18 | + description: Path to chart filters YAML file. |
| 19 | + required: false |
| 20 | + default: .github/chart-filters.yml |
| 21 | + type: string |
| 22 | + outputs: |
| 23 | + helmreleases: |
| 24 | + description: The dict with the helm releases to be deployed for each cluster. |
| 25 | + value: ${{ jobs.build-helmreleases.outputs.helmreleases }} |
| 26 | + updated_prod_cluster_names: |
| 27 | + description: The list of updated production cluster names. |
| 28 | + value: ${{ jobs.build-helmreleases.outputs.updated_prod_cluster_names }} |
| 29 | + staging_helmreleases: |
| 30 | + description: List of staging helm releases that shoul be waited for. |
| 31 | + value: ${{ jobs.build-helmreleases.outputs.staging_helmreleases }} |
| 32 | + built_charts: |
| 33 | + description: Dict of built charts including the chart name and version. |
| 34 | + value: ${{ jobs.build-helmreleases.outputs.built_charts }} |
| 35 | + |
| 36 | +jobs: |
| 37 | + build-helmreleases: |
| 38 | + runs-on: |
| 39 | + group: infra1-runners-arc |
| 40 | + labels: runners-small |
| 41 | + outputs: |
| 42 | + helmreleases: ${{ steps.build-helmreleases.outputs.helmreleases }} |
| 43 | + built_charts: ${{ steps.get-built-charts.outputs.built_charts }} |
| 44 | + staging_helmreleases: ${{ steps.extract-staging-helmreleases.outputs.staging_helmreleases }} |
| 45 | + updated_prod_cluster_names: ${{ steps.extract-updated-prod-names.outputs.updated_prod_names }} |
| 46 | + steps: |
| 47 | + - name: Checkout repository |
| 48 | + uses: actions/checkout@v5 |
| 49 | + |
| 50 | + - name: Get built charts |
| 51 | + id: get-built-charts |
| 52 | + run: | |
| 53 | + charts=$(echo '${{ inputs.charts }}' | jq -r '.[]') |
| 54 | + result='{}' |
| 55 | + for chart in $charts; do |
| 56 | + chart_file="k8s/charts/$chart/Chart.yaml" |
| 57 | + version=$(yq e '.version' "$chart_file") |
| 58 | + chart_obj=$(jq -n --arg name "$chart" --arg version "$version" '{name: $name, version: $version}') |
| 59 | + result=$(echo "$result" | jq --arg n "$chart" --argjson obj "$chart_obj" '. + {($n): $obj}') |
| 60 | + done |
| 61 | + echo "Built charts: $result" |
| 62 | + echo "built_charts=$(echo "$result" | jq -c)" >> $GITHUB_OUTPUT |
| 63 | +
|
| 64 | + - name: Prepare charts |
| 65 | + id: prepare-charts |
| 66 | + run: | |
| 67 | + built_charts='${{ steps.get-built-charts.outputs.built_charts }}' |
| 68 | + all_charts=$(yq e 'keys' "${{ inputs.chart_filters_path }}" -o=json | jq -c) |
| 69 | + prepared_charts='{}' |
| 70 | +
|
| 71 | + for name in $(echo "$all_charts" | jq -r '.[]'); do |
| 72 | + if echo "$built_charts" | jq -e --arg n "$name" 'has($n)' >/dev/null; then |
| 73 | + chart=$(echo "$built_charts" | jq -c --arg n "$name" '.[$n]') |
| 74 | + else |
| 75 | + chart_file="k8s/charts/$name/Chart.yaml" |
| 76 | + if [[ ! -f "$chart_file" ]]; then |
| 77 | + echo "Chart $name not found at $chart_file" |
| 78 | + exit 1 |
| 79 | + fi |
| 80 | +
|
| 81 | + version=$(grep '^version:' "$chart_file" | awk '{print $2}') |
| 82 | + chart=$(jq -n \ |
| 83 | + --arg name "$name" \ |
| 84 | + --arg version "$version" \ |
| 85 | + '{name: $name, version: $version}') |
| 86 | + fi |
| 87 | + prepared_charts=$(echo "$prepared_charts" | jq --arg n "$name" --argjson c "$chart" '. + {($n): $c}') |
| 88 | + done |
| 89 | +
|
| 90 | + echo "Prepared charts: $prepared_charts" |
| 91 | + echo "charts=$(echo "$prepared_charts" | jq -c)" >> $GITHUB_OUTPUT |
| 92 | +
|
| 93 | + - name: Checkout gitops-deployments |
| 94 | + uses: actions/checkout@v5 |
| 95 | + with: |
| 96 | + repository: gooddata/gitops-deployments |
| 97 | + token: ${{ secrets.TOKEN_GITHUB_YENKINS }} |
| 98 | + |
| 99 | + - name: Get cluster mapping |
| 100 | + id: cluster-mapping |
| 101 | + run: | |
| 102 | + cluster_mapping=$(yq -e '.clusterMapping' tools/auto_merge/config.yaml -o json) |
| 103 | + echo "Cluster mapping: $cluster_mapping" |
| 104 | + echo "cluster_mapping=$(echo "$cluster_mapping" | jq -c)" >> $GITHUB_OUTPUT |
| 105 | +
|
| 106 | + - name: Build HelmReleases |
| 107 | + id: build-helmreleases |
| 108 | + run: | |
| 109 | + charts='${{ steps.prepare-charts.outputs.charts }}' |
| 110 | + built_images='${{ inputs.images }}' |
| 111 | + tag=${{ inputs.image_tag }} |
| 112 | + cluster_mapping='${{ steps.cluster-mapping.outputs.cluster_mapping }}' |
| 113 | +
|
| 114 | + hrs_per_cluster='{}' |
| 115 | +
|
| 116 | + for cluster_id in $(echo "$cluster_mapping" | jq -r '.[]'); do |
| 117 | + helmreleases='[]' |
| 118 | + echo "Processing cluster $cluster_id" |
| 119 | + for entry in $(echo "$charts" | jq -c 'to_entries[]'); do |
| 120 | + chart_name=$(echo "$entry" | jq -r '.key') |
| 121 | + chart_definition=$(echo "$entry" | jq -c '.value') |
| 122 | +
|
| 123 | + file_path="${cluster_id}/${chart_name}.yaml" |
| 124 | + if [[ ! -f "$file_path" ]]; then |
| 125 | + echo "File $file_path not found, skipping..." |
| 126 | + continue |
| 127 | + fi |
| 128 | + echo "Processing chart $chart_name for cluster $cluster_id" |
| 129 | +
|
| 130 | + used_images=$(yq e '.. | .image? | select(.) | .name' "$file_path" | sort -u) |
| 131 | + filtered_images='[]' |
| 132 | + for img_name in $(echo "$built_images" | jq -r '.[]'); do |
| 133 | + if echo "$used_images" | grep -qx "$img_name"; then |
| 134 | + filtered_images=$(echo "$filtered_images" | jq --arg n "$img_name" --arg t "$tag" '. + [{name: $n, tag: $t}]') |
| 135 | + fi |
| 136 | + done |
| 137 | + echo "Filtered images for $chart_name: $filtered_images" |
| 138 | +
|
| 139 | + if [[ "$filtered_images" == "[]" ]]; then |
| 140 | + original_version=$(yq e '.spec.chart.spec.version' "$file_path") |
| 141 | + new_version=$(echo "$chart_definition" | jq -r '.version') |
| 142 | +
|
| 143 | + if [[ "$original_version" == "$new_version" ]]; then |
| 144 | + echo "There is nothing to update for chart $chart_name in cluster $cluster_id, skipping..." |
| 145 | + continue |
| 146 | + fi |
| 147 | + fi |
| 148 | +
|
| 149 | + chart_version="$(echo "$chart_definition" | jq -r '.version')" |
| 150 | + releasename=$(echo "$chart_definition" | jq -r '.name') |
| 151 | + wait_retries=$(yq e '.spec.values.waitRetries' "$file_path") |
| 152 | + namespace=$(yq e '.metadata.namespace' "$file_path") |
| 153 | +
|
| 154 | + helmrelease=$(jq -n \ |
| 155 | + --arg chart_version "$chart_version" \ |
| 156 | + --argjson images "$filtered_images" \ |
| 157 | + --arg releasename "$releasename" \ |
| 158 | + --argjson waitRetries "$wait_retries" \ |
| 159 | + --arg namespace "$namespace" \ |
| 160 | + '{chart_version: $chart_version, images: $images, releasename: $releasename, waitRetries: $waitRetries, namespace: $namespace}') |
| 161 | +
|
| 162 | + helmreleases=$(echo "$helmreleases" | jq --argjson hr "$helmrelease" '. + [ $hr ]') |
| 163 | + done |
| 164 | + hrs_per_cluster=$(echo "$hrs_per_cluster" | jq --arg cluster_id "$cluster_id" --argjson list "$helmreleases" '. + {($cluster_id): $list}') |
| 165 | + done |
| 166 | +
|
| 167 | + echo "Final hrs_per_cluster: $hrs_per_cluster" |
| 168 | + echo "helmreleases=$(echo "$hrs_per_cluster" | jq -c)" >> $GITHUB_OUTPUT |
| 169 | +
|
| 170 | + - name: Extract staging helmreleases |
| 171 | + id: extract-staging-helmreleases |
| 172 | + run: | |
| 173 | + hrs_per_cluster='${{ steps.build-helmreleases.outputs.helmreleases }}' |
| 174 | + staging_hrs=$(echo "$hrs_per_cluster" | jq -c '."62" // []') |
| 175 | + echo "staging_helmreleases=$(echo "$staging_hrs" | jq -c)" >> $GITHUB_OUTPUT |
| 176 | +
|
| 177 | + - name: Extract updated production cluster names |
| 178 | + id: extract-updated-prod-names |
| 179 | + run: | |
| 180 | + hrs_per_cluster='${{ steps.build-helmreleases.outputs.helmreleases }}' |
| 181 | + cluster_mapping='${{ steps.cluster-mapping.outputs.cluster_mapping }}' |
| 182 | + updated_prod_ids=$(echo "$hrs_per_cluster" | jq 'del(.["62"], .["ucluster"]) | [to_entries | map(select(.value | length > 0) | .key)] | .[]') |
| 183 | + updated_prod_names=$(echo "$cluster_mapping" | jq -r --argjson ids "$updated_prod_ids" ' |
| 184 | + to_entries |
| 185 | + | map(select((.value | tostring) as $v | $ids[] == $v)) |
| 186 | + | map(.key) |
| 187 | + ') |
| 188 | + echo "Updated production clusters: $updated_prod_names" |
| 189 | + echo "updated_prod_names=$(echo "$updated_prod_names" | jq -c)" >> $GITHUB_OUTPUT |
0 commit comments