1+ name : " Generate values.schema.json"
2+
3+ on :
4+ push :
5+ branches :
6+ - main
7+ paths :
8+ - ' charts/**/values.yaml'
9+ pull_request :
10+ paths :
11+ - ' charts/**/values.yaml'
12+ workflow_dispatch :
13+ inputs :
14+ charts :
15+ description : ' Specific charts to generate schema for (comma-separated, e.g., "nginx,redis"). Leave empty for all charts.'
16+ required : false
17+ type : string
18+ force_regenerate :
19+ description : ' Force regeneration even if values.yaml has not changed'
20+ required : false
21+ type : boolean
22+ default : false
23+
24+ concurrency :
25+ group : ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref }}
26+ cancel-in-progress : true
27+
28+ jobs :
29+ generate-schema :
30+ runs-on : ubuntu-latest
31+ timeout-minutes : 15
32+ # Skip if the commit was made by github-actions bot to prevent infinite loops
33+ if : github.actor != 'github-actions[bot]'
34+ permissions :
35+ contents : write
36+ pull-requests : write
37+ steps :
38+ - name : Checkout code
39+ uses : actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
40+ with :
41+ fetch-depth : 0
42+ token : ${{ secrets.GITHUB_TOKEN }}
43+
44+ - name : Set up Python
45+ uses : actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
46+ with :
47+ python-version : ' 3.11'
48+
49+ - name : Set up Helm
50+ uses : azure/setup-helm@1a275c3b69536ee54be43f2070a358922e12c8d4 # v4.3.1
51+ with :
52+ version : ' v3.19.2'
53+
54+ - name : Install helm-schema plugin
55+ run : |
56+ set -e
57+ # Check if plugin is already installed
58+ if helm plugin list | grep -q "schema"; then
59+ echo "Plugin already installed"
60+ helm plugin list | grep "schema"
61+ else
62+ echo "Installing helm-values-schema-json plugin..."
63+ helm plugin install https://github.com/losisin/helm-values-schema-json.git --version v1.9.2
64+ fi
65+
66+ # Verify plugin installation
67+ echo "Verifying plugin installation..."
68+ helm plugin list
69+ if ! helm plugin list | grep -q "schema"; then
70+ echo "ERROR: Plugin installation failed"
71+ exit 1
72+ fi
73+
74+ echo "Plugin installed successfully"
75+
76+ - name : Determine charts to process
77+ id : determine-charts
78+ run : |
79+ set -e
80+
81+ # Function to get all charts except 'common'
82+ get_all_charts() {
83+ find charts -mindepth 1 -maxdepth 1 -type d ! -name 'common' -exec basename {} \; | sort
84+ }
85+
86+ # For workflow_dispatch with specific charts
87+ if [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ -n "${{ github.event.inputs.charts }}" ]; then
88+ echo "Manual trigger with specific charts: ${{ github.event.inputs.charts }}"
89+ CHARTS="${{ github.event.inputs.charts }}"
90+ echo "charts=$CHARTS" >> $GITHUB_OUTPUT
91+ echo "mode=manual-specific" >> $GITHUB_OUTPUT
92+
93+ # For workflow_dispatch with force regenerate all
94+ elif [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ "${{ github.event.inputs.force_regenerate }}" = "true" ]; then
95+ echo "Manual trigger: force regenerate all charts"
96+ CHARTS=$(get_all_charts | tr '\n' ',' | sed 's/,$//')
97+ echo "charts=$CHARTS" >> $GITHUB_OUTPUT
98+ echo "mode=manual-all" >> $GITHUB_OUTPUT
99+
100+ # For push/PR events - detect changed charts
101+ else
102+ echo "Detecting changed charts from git diff"
103+
104+ if [ "${{ github.event_name }}" = "pull_request" ]; then
105+ BASE_REF="${{ github.event.pull_request.base.sha }}"
106+ else
107+ BASE_REF="${{ github.event.before }}"
108+ fi
109+
110+ # Get changed values.yaml files
111+ CHANGED_FILES=$(git diff --name-only "$BASE_REF" HEAD -- 'charts/**/values.yaml' || echo "")
112+
113+ if [ -z "$CHANGED_FILES" ]; then
114+ echo "No values.yaml files changed"
115+ echo "charts=" >> $GITHUB_OUTPUT
116+ echo "mode=none" >> $GITHUB_OUTPUT
117+ else
118+ echo "Changed values.yaml files:"
119+ echo "$CHANGED_FILES"
120+
121+ # Extract chart names from changed files
122+ CHARTS=$(echo "$CHANGED_FILES" | grep -o 'charts/[^/]*' | cut -d/ -f2 | sort -u | grep -v '^common$' | tr '\n' ',' | sed 's/,$//')
123+
124+ if [ -z "$CHARTS" ]; then
125+ echo "Only common chart changed, skipping schema generation"
126+ echo "charts=" >> $GITHUB_OUTPUT
127+ echo "mode=none" >> $GITHUB_OUTPUT
128+ else
129+ echo "Charts to process: $CHARTS"
130+ echo "charts=$CHARTS" >> $GITHUB_OUTPUT
131+ echo "mode=auto" >> $GITHUB_OUTPUT
132+ fi
133+ fi
134+ fi
135+
136+ - name : Generate schema for charts
137+ if : steps.determine-charts.outputs.charts != ''
138+ run : |
139+ set -e
140+
141+ CHARTS="${{ steps.determine-charts.outputs.charts }}"
142+ IFS=',' read -ra CHART_ARRAY <<< "$CHARTS"
143+
144+ echo "Generating schemas for: ${CHART_ARRAY[*]}"
145+
146+ SUCCESS_COUNT=0
147+ FAIL_COUNT=0
148+ FAILED_CHARTS=""
149+
150+ for chart in "${CHART_ARRAY[@]}"; do
151+ chart=$(echo "$chart" | xargs) # trim whitespace
152+
153+ if [ -z "$chart" ]; then
154+ continue
155+ fi
156+
157+ echo "Processing chart: $chart"
158+ CHART_DIR="charts/$chart"
159+
160+ if [ ! -d "$CHART_DIR" ]; then
161+ echo "Warning: Chart directory not found: $CHART_DIR"
162+ FAIL_COUNT=$((FAIL_COUNT + 1))
163+ FAILED_CHARTS="$FAILED_CHARTS $chart"
164+ continue
165+ fi
166+
167+ if [ ! -f "$CHART_DIR/values.yaml" ]; then
168+ echo "Warning: values.yaml not found in $CHART_DIR"
169+ FAIL_COUNT=$((FAIL_COUNT + 1))
170+ FAILED_CHARTS="$FAILED_CHARTS $chart"
171+ continue
172+ fi
173+
174+ echo "Generating schema for $chart..."
175+ if helm schema -input "$CHART_DIR/values.yaml" -output "$CHART_DIR/values.schema.json" -draft 7; then
176+ echo "Successfully generated schema for $chart"
177+ SUCCESS_COUNT=$((SUCCESS_COUNT + 1))
178+ else
179+ echo "Failed to generate schema for $chart"
180+ FAIL_COUNT=$((FAIL_COUNT + 1))
181+ FAILED_CHARTS="$FAILED_CHARTS $chart"
182+ fi
183+ done
184+
185+ echo ""
186+ echo "Summary:"
187+ echo " Success: $SUCCESS_COUNT"
188+ echo " Failed: $FAIL_COUNT"
189+
190+ if [ $FAIL_COUNT -gt 0 ]; then
191+ echo " Failed charts:$FAILED_CHARTS"
192+ fi
193+
194+ echo "success_count=$SUCCESS_COUNT" >> $GITHUB_ENV
195+ echo "fail_count=$FAIL_COUNT" >> $GITHUB_ENV
196+
197+ - name : Check for schema changes
198+ if : steps.determine-charts.outputs.charts != ''
199+ id : check-changes
200+ run : |
201+ if git status --porcelain | grep -q 'values.schema.json'; then
202+ echo "has_changes=true" >> $GITHUB_OUTPUT
203+ echo "Schema files have been updated"
204+ git status --porcelain | grep 'values.schema.json'
205+ else
206+ echo "has_changes=false" >> $GITHUB_OUTPUT
207+ echo "No schema changes detected"
208+ fi
209+
210+ - name : Debug commit conditions
211+ if : steps.determine-charts.outputs.charts != ''
212+ run : |
213+ echo "Debug information for commit step:"
214+ echo " github.event_name: ${{ github.event_name }}"
215+ echo " github.ref: ${{ github.ref }}"
216+ echo " has_changes: ${{ steps.check-changes.outputs.has_changes }}"
217+ echo " Should commit to main: ${{ (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && github.ref == 'refs/heads/main' && steps.check-changes.outputs.has_changes == 'true' }}"
218+
219+ - name : Create PR for schema updates (push to main)
220+ if : |
221+ (github.event_name == 'push' || github.event_name == 'workflow_dispatch') &&
222+ github.ref == 'refs/heads/main' &&
223+ steps.check-changes.outputs.has_changes == 'true'
224+ env :
225+ GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
226+ run : |
227+ git config user.name 'github-actions[bot]'
228+ git config user.email 'github-actions[bot]@users.noreply.github.com'
229+
230+ # Create a new branch for the schema updates
231+ BRANCH_NAME="auto/schema-update-$(date +%s)"
232+ git checkout -b "$BRANCH_NAME"
233+
234+ git add charts/*/values.schema.json
235+
236+ git commit -m "chore: auto-generate values.schema.json for updated charts" \
237+ -m "Automatically generated JSON schemas for Helm values files." \
238+ -m "" \
239+ -m "Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>"
240+
241+ # Push the branch
242+ git push origin "$BRANCH_NAME"
243+
244+ # Create a pull request
245+ gh pr create \
246+ --title "chore: auto-generate values.schema.json" \
247+ --body "This PR contains automatically generated JSON schemas for Helm values files.
248+
249+ ## Changes
250+ - Auto-generated \`values.schema.json\` files for charts with updated \`values.yaml\`
251+
252+ ## Notes
253+ - This PR was automatically created by the schema generation workflow
254+ - Please review and merge if the changes look correct
255+ - The workflow will not run again on this bot's commits to prevent loops
256+
257+ ---
258+ 🤖 Generated by [generate-schema workflow](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})" \
259+ --base main \
260+ --head "$BRANCH_NAME"
261+
262+ - name : Commit schema updates to PR branch
263+ if : |
264+ github.event_name == 'pull_request' &&
265+ steps.check-changes.outputs.has_changes == 'true'
266+ run : |
267+ git config user.name 'github-actions[bot]'
268+ git config user.email 'github-actions[bot]@users.noreply.github.com'
269+
270+ git add charts/*/values.schema.json
271+
272+ git commit -m "chore: auto-generate values.schema.json" \
273+ -m "Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>" || echo "No changes to commit"
274+
275+ # Push to PR branch
276+ git push origin HEAD:${{ github.head_ref }}
277+
278+ - name : Commit schema updates to current branch (workflow_dispatch on non-main)
279+ if : |
280+ github.event_name == 'workflow_dispatch' &&
281+ github.ref != 'refs/heads/main' &&
282+ steps.check-changes.outputs.has_changes == 'true'
283+ run : |
284+ git config user.name 'github-actions[bot]'
285+ git config user.email 'github-actions[bot]@users.noreply.github.com'
286+
287+ git add charts/*/values.schema.json
288+
289+ git commit -m "chore: auto-generate values.schema.json" \
290+ -m "Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>"
291+
292+ # Push to current branch
293+ git push origin HEAD:${{ github.ref }}
294+
295+ - name : Generate job summary
296+ if : steps.determine-charts.outputs.charts != ''
297+ run : |
298+ echo "## 📋 Schema Generation Summary" >> $GITHUB_STEP_SUMMARY
299+ echo "" >> $GITHUB_STEP_SUMMARY
300+
301+ if [ "${{ steps.determine-charts.outputs.mode }}" = "none" ]; then
302+ echo "No charts required schema generation." >> $GITHUB_STEP_SUMMARY
303+ else
304+ echo "**Mode:** ${{ steps.determine-charts.outputs.mode }}" >> $GITHUB_STEP_SUMMARY
305+ echo "**Charts processed:** ${{ steps.determine-charts.outputs.charts }}" >> $GITHUB_STEP_SUMMARY
306+ echo "" >> $GITHUB_STEP_SUMMARY
307+ echo "**Results:**" >> $GITHUB_STEP_SUMMARY
308+ echo "- ✅ Success: ${success_count}" >> $GITHUB_STEP_SUMMARY
309+ echo "- ❌ Failed: ${fail_count}" >> $GITHUB_STEP_SUMMARY
310+ echo "" >> $GITHUB_STEP_SUMMARY
311+
312+ if [ "${{ steps.check-changes.outputs.has_changes }}" = "true" ]; then
313+ echo "**Status:** Schema files updated and committed" >> $GITHUB_STEP_SUMMARY
314+ else
315+ echo "**Status:** No schema changes detected" >> $GITHUB_STEP_SUMMARY
316+ fi
317+ fi
0 commit comments