-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #25 from mozilla-it/add-render-and-diff-helm
feat: add render and diff helm action
- Loading branch information
Showing
2 changed files
with
208 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# Render and diff helm charts | ||
|
||
This action is used to render helm charts on the base and ref branches of a pull request, create a diff between charts that have been modified and then post the diff as a comment on the pull request. | ||
|
||
## Inputs | ||
|
||
### `chart_path` | ||
|
||
The path filter for helm charts in the repository. Default `'**/k8s/**/**'` | ||
|
||
### Example usage | ||
``` | ||
name: render-and-diff-charts | ||
on: | ||
pull_request: | ||
paths: | ||
- '**/k8s/**/**' | ||
jobs: | ||
run_helm_chart_diff: | ||
permissions: | ||
contents: read | ||
pull-requests: write | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Render and diff modified helm charts | ||
uses: mozilla-it/deploy-actions/[email protected] | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,179 @@ | ||
# This Source Code Form is subject to the terms of the Mozilla Public | ||
# License, v. 2.0. If a copy of the MPL was not distributed with this | ||
# file, You can obtain one at https://mozilla.org/MPL/2.0/. | ||
|
||
name: Matrix render and diff helm charts | ||
description: Renders BASE and REF helm charts then posts the diff of the rendered charts as a comment on the pull request | ||
|
||
|
||
on: | ||
workflow_call: | ||
inputs: | ||
chart_path: | ||
description: Path filter for helm charts | ||
required: false | ||
type: string | ||
default: '**/k8s/**' | ||
|
||
env: | ||
CHART_PATH: ${{ inputs.chart_path }} | ||
|
||
jobs: | ||
get_changed_helm_charts: | ||
runs-on: ubuntu-latest | ||
outputs: | ||
matrix_charts: ${{ steps.find_changed_charts.outputs.matrix_changed_charts }} | ||
charts: ${{ steps.find_changed_charts.outputs.changed_charts }} | ||
steps: | ||
- name: checkout repository | ||
uses: actions/checkout@v4 | ||
with: | ||
fetch-depth: '100' | ||
|
||
- name: find changed helm charts | ||
id: find_changed_charts | ||
run: | | ||
git fetch origin ${{ github.base_ref }}:${{ github.base_ref }} | ||
echo matrix_changed_charts=$(git diff --name-only ${{ github.base_ref }}...HEAD -- '**/k8s/**/*.yaml' '**/k8s/**/*.yml' '**/k8s/**/*.tpl' '**/k8s/**/*.tmpl' | cut -d'/' -f1,2,3 | uniq | jq -R 'split("\n")' | jq -s 'flatten(1)') >> $GITHUB_OUTPUT | ||
echo changed_charts=$(git diff --name-only ${{ github.base_ref }}...HEAD -- '**/k8s/**/*.yaml' '**/k8s/**/*.yml' '**/k8s/**/*.tpl' '**/k8s/**/*.tmpl' | cut -d'/' -f1,2,3 | uniq) >> $GITHUB_OUTPUT | ||
render_head_ref_charts: | ||
runs-on: ubuntu-latest | ||
needs: get_changed_helm_charts | ||
strategy: | ||
matrix: | ||
chart: ${{ fromJSON(needs.get_changed_helm_charts.outputs.matrix_charts) }} | ||
steps: | ||
- name: checkout repository | ||
uses: actions/checkout@v4 | ||
|
||
- name: setup helm | ||
uses: azure/[email protected] | ||
|
||
- name: render ${{ matrix.chart }} from head ref | ||
id: render_head | ||
run: | | ||
mkdir -p shared/head-charts | ||
git fetch origin ${{ github.head_ref }} | ||
git checkout ${{ github.head_ref }} -- | ||
if [ -d "${{ matrix.chart }}" ]; then | ||
helm dependency build "${{ matrix.chart }}" | ||
values_files="${{ matrix.chart }}"/values-* | ||
for values_file in $(basename -a $values_files); do | ||
helm template "${{ matrix.chart }}" -f "${{ matrix.chart }}/values.yaml" -f "${{ matrix.chart }}/${values_file}" --output-dir "shared/head-charts/${{ matrix.chart }}/${values_file}" | ||
done | ||
fi | ||
echo sanitized_name=$(echo "${{ matrix.chart }}" | sed 's/\//-/g') >> $GITHUB_OUTPUT | ||
- name: upload artifact | ||
uses: actions/upload-artifact@v4 | ||
with: | ||
name: "shared-head-${{ steps.render_head.outputs.sanitized_name }}" | ||
path: "shared" | ||
|
||
render_base_ref_charts: | ||
runs-on: ubuntu-latest | ||
needs: get_changed_helm_charts | ||
strategy: | ||
matrix: | ||
chart: ${{ fromJSON(needs.get_changed_helm_charts.outputs.matrix_charts) }} | ||
steps: | ||
- name: checkout repository | ||
uses: actions/checkout@v4 | ||
|
||
- name: setup helm | ||
uses: azure/[email protected] | ||
|
||
- name: render ${{ matrix.chart }} from base ref | ||
id: render_base | ||
run: | | ||
mkdir -p shared/base-charts | ||
git fetch origin ${{ github.base_ref }} | ||
git checkout ${{ github.base_ref }} -- | ||
if [ -d "${{ matrix.chart }}" ]; then | ||
helm dependency build "${{ matrix.chart }}" | ||
values_files="${{ matrix.chart }}"/values-* | ||
for values_file in $(basename -a $values_files); do | ||
helm template "${{ matrix.chart }}" -f "${{ matrix.chart }}/values.yaml" -f "${{ matrix.chart }}/${values_file}" --output-dir "shared/base-charts/${{ matrix.chart }}/${values_file}" | ||
done | ||
fi | ||
echo sanitized_name=$(echo "${{ matrix.chart }}" | sed 's/\//-/g') >> $GITHUB_OUTPUT | ||
- name: upload artifact | ||
uses: actions/upload-artifact@v4 | ||
with: | ||
name: "shared-base-${{ steps.render_base.outputs.sanitized_name }}" | ||
path: "shared" | ||
|
||
diff_helm_charts: | ||
runs-on: ubuntu-latest | ||
needs: | ||
- get_changed_helm_charts | ||
- render_base_ref_charts | ||
- render_head_ref_charts | ||
steps: | ||
- name: setup helm | ||
uses: azure/[email protected] | ||
|
||
- name: download artifacts | ||
uses: actions/download-artifact@v4 | ||
with: | ||
pattern: shared-* | ||
merge-multiple: true | ||
path: "shared" | ||
|
||
- name: diff helm charts | ||
id: diff_helm_charts | ||
run: | | ||
for chart in ${{ needs.get_changed_helm_charts.outputs.charts }}; do | ||
chart_diff_output=$(diff -r "shared/base-charts/${chart}" "shared/head-charts/${chart}" || true) | ||
if [ -n "$chart_diff_output" ]; then | ||
echo -e "Changes found in chart: ${chart}\n$(diff -ru shared/base-charts/${chart} shared/head-charts/${chart})\n" >> diff.log | ||
fi | ||
done | ||
- name: post diff as comment on pull request | ||
if: needs.get_changed_helm_charts.outputs.charts != '' | ||
uses: actions/github-script@v7 | ||
with: | ||
script: | | ||
const fs = require('fs'); | ||
const comment_char_limit = 65536; // GitHub comment character limit | ||
const diff = fs.readFileSync('diff.log', 'utf8'); | ||
function splitComment(comment, maxSize, sepEnd, sepStart, comStart) { | ||
// Adapted from Atlantis SplitComment function | ||
// https://github.com/runatlantis/atlantis/blob/main/server/events/vcs/common/common.go#L18 | ||
if (comment.length <= (comment_char_limit - comStart.length)) { | ||
return [comStart + diff] | ||
} | ||
maxWithSep = comment_char_limit - sepEnd.length - sepStart.length; | ||
var comments = []; | ||
var numComments = Math.ceil(comment.length / maxWithSep); | ||
for (var i = 0; i < numComments; i++) { | ||
var upTo = Math.min(comment.length, (i + 1) * maxWithSep); | ||
var portion = comment.slice(i * maxWithSep, upTo); | ||
if (i < numComments - 1) { | ||
portion += sepEnd; | ||
} | ||
if (i > 0) { | ||
portion = sepStart + portion | ||
} else { | ||
portion = comStart + portion | ||
} | ||
comments.push(portion); | ||
} | ||
return comments; | ||
} | ||
var sepEnd = "\n```\n</details>" + "\n<br>\n\n**Warning**: Output length greater than max comment size. Continued in next comment."; | ||
var sepStart = "Continued from previous comment.\n<details><summary>Show Output</summary>\n\n" + "```diff\n"; | ||
var comStart = "Changes found in Helm charts.\n<details><summary>Show Output</summary>\n\n" + "```diff\n"; | ||
comments = splitComment(diff, comment_char_limit, sepEnd, sepStart, comStart); | ||
for (const comment of comments) { | ||
await github.rest.issues.createComment({ | ||
issue_number: context.issue.number, | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
body: comment | ||
}) | ||
} |