1
1
#! /bin/bash
2
2
3
- # CLI output colors
3
+ # Colors for output
4
4
RED=' \033[0;31m'
5
5
YELLOW=' \033[1;33m'
6
- NC=' \033[0m' # No Color
6
+ NC=' \033[0m'
7
7
8
8
errors=()
9
9
warnings=()
10
10
11
- # Check if Terraform is installed
12
- if ! command -v terraform > /dev/null 2>&1 ; then
13
- echo -e " ${RED} Error:${NC} Terraform is not installed or not in PATH"
14
- exit 1
15
- fi
16
-
17
11
check_readme_format () {
18
12
local readme_path=" $1 "
19
13
@@ -22,30 +16,60 @@ check_readme_format() {
22
16
return 1
23
17
fi
24
18
25
- # Check for valid YAML front matter
26
- if ! awk ' /^---/{f=1; next} /^---$/{if(f){exit 0}} END{exit 1}' " $readme_path " ; then
27
- errors+=(" README.md at $readme_path does not have a valid YAML front matter block (start and end with '---')" )
19
+ # 1. Check that the first line is exactly ---
20
+ local first_line
21
+ first_line=$( head -n 1 " $readme_path " )
22
+ if [[ " $first_line " != " ---" ]]; then
23
+ errors+=(" Missing starting '---' in README.md at $readme_path " )
28
24
return 1
29
25
fi
30
26
31
- # Extract YAML block
32
- local yaml_header
33
- yaml_header=$( awk ' /^---/{f=1; next} /^---$/{f=0} f' " $readme_path " )
34
-
35
- # Check for required fields
36
- if ! grep -q " name:" <<< " $yaml_header" ; then
37
- errors+=(" Missing 'name' in YAML header of README.md at $readme_path " )
27
+ # 2. Find end of YAML block
28
+ local end_line
29
+ end_line=$( awk ' NR>1 && /^---$/ { print NR; exit }' " $readme_path " )
30
+ if [[ -z " $end_line " ]]; then
31
+ errors+=(" Missing closing '---' in README.md at $readme_path " )
32
+ return 1
38
33
fi
39
- if ! grep -q " supportedPlatforms:" <<< " $yaml_header" ; then
40
- errors+=(" Missing 'supportedPlatforms' in YAML header of README.md at $readme_path " )
34
+
35
+ # 3. Extract YAML block
36
+ local yaml
37
+ yaml=$( head -n " $(( end_line - 1 )) " " $readme_path " | tail -n +2)
38
+
39
+ # 4. Check for required fields and that they are not empty
40
+
41
+ # name
42
+ if ! grep -q " ^name:" <<< " $yaml" ; then
43
+ errors+=(" Missing 'name:' field in YAML header of README.md at $readme_path " )
44
+ elif [[ -z $( grep " ^name:" <<< " $yaml" | cut -d' :' -f2 | xargs) ]]; then
45
+ errors+=(" Field 'name:' is empty in README.md at $readme_path " )
41
46
fi
42
- if ! grep -q " description:" <<< " $yaml_header" ; then
43
- errors+=(" Missing 'description' in YAML header of README.md at $readme_path " )
47
+
48
+ # supportedPlatforms
49
+ if ! grep -q " ^supportedPlatforms:" <<< " $yaml" ; then
50
+ errors+=(" Missing 'supportedPlatforms:' field in YAML header of README.md at $readme_path " )
51
+ else
52
+ local platforms_count
53
+ platforms_count=$( awk ' /^supportedPlatforms:/ {found=1; next} /^ *[^- ]/ {found=0} found && /^ *-/{count++} END{print count+0}' <<< " $yaml" )
54
+ if [[ " $platforms_count " -eq 0 ]]; then
55
+ errors+=(" Field 'supportedPlatforms:' is empty in README.md at $readme_path " )
56
+ fi
44
57
fi
45
58
46
- return 0
59
+ # description
60
+ if ! grep -q " ^description:" <<< " $yaml" ; then
61
+ errors+=(" Missing 'description:' field in YAML header of README.md at $readme_path " )
62
+ else
63
+ local desc_start desc_content
64
+ desc_start=$( awk ' /^description:/ {print NR; exit}' <<< " $yaml" )
65
+ desc_content=$( echo " $yaml " | tail -n +" $(( desc_start + 1 )) " | awk ' NF {print; exit}' )
66
+ if [[ -z " $desc_content " ]]; then
67
+ errors+=(" Field 'description:' is empty in README.md at $readme_path " )
68
+ fi
69
+ fi
47
70
}
48
71
72
+
49
73
check_png_naming () {
50
74
local png_path=" $1 "
51
75
local png_name
@@ -59,33 +83,44 @@ check_png_naming() {
59
83
check_terraform_files () {
60
84
local buildingblock_path=" $1 "
61
85
62
- # Check if any .tf files exist
63
- if ! find " $buildingblock_path " -maxdepth 1 -name ' *.tf' | grep -q . ; then
86
+ # Check for at least one .tf file (excluding .terraform subfolder)
87
+ if ! find " $buildingblock_path " -maxdepth 1 -type f - name ' *.tf' | grep -q . ; then
64
88
errors+=(" No Terraform (.tf) files found in $buildingblock_path " )
65
89
return 1
66
90
fi
67
91
68
- # Optional: Check for recommended files
69
- local required_tf_files =(" main.tf" " variables.tf" " outputs.tf" " provider.tf" " versions.tf" )
70
- for tf_file in " ${required_tf_files [@]} " ; do
92
+ # Optional recommended file check
93
+ local recommended_tf_files =(" main.tf" " variables.tf" " outputs.tf" , " provider.tf" " versions.tf" )
94
+ for tf_file in " ${recommended_tf_files [@]} " ; do
71
95
if [[ ! -f " $buildingblock_path /$tf_file " ]]; then
72
96
warnings+=(" Recommended file '$tf_file ' is missing in $buildingblock_path " )
73
97
fi
74
98
done
75
99
76
- # Validate Terraform configuration
100
+ # Run terraform init + validate with visible output
77
101
pushd " $buildingblock_path " > /dev/null || return 1
102
+ rm -rf .terraform/ > /dev/null 2>&1
78
103
79
- if ! terraform init -backend=false -input=false > /dev/null 2>&1 ; then
104
+ echo " 🔄 Running terraform init in $buildingblock_path "
105
+ if ! terraform init -backend=false -input=false; then
106
+ echo -e " ❌ ${RED} Terraform init failed in $buildingblock_path ${NC} "
80
107
errors+=(" Terraform init failed in $buildingblock_path " )
81
- elif ! terraform validate > /dev/null 2>&1 ; then
108
+ popd > /dev/null
109
+ return 1
110
+ fi
111
+
112
+ echo " 🔄 Running terraform validate in $buildingblock_path "
113
+ if terraform validate; then
114
+ echo -e " ✅ ${buildingblock_path} validated successfully"
115
+ else
116
+ echo -e " ❌ ${RED} Terraform validate failed in $buildingblock_path ${NC} "
82
117
errors+=(" Terraform validate failed in $buildingblock_path " )
83
118
fi
84
119
85
- popd > /dev/null || return 1
120
+ popd > /dev/null
86
121
}
87
122
88
- # Ensure the script is run from repo root
123
+ # Ensure script is run from repo root
89
124
cd " $( dirname " $0 " ) /.." || exit 1
90
125
modules_path=" modules"
91
126
96
131
97
132
modules_glob=" $modules_path /*/*/buildingblock"
98
133
99
- # Check all README.md files
100
- find $modules_glob -name ' README.md' -print0 | while IFS= read -r -d ' ' readme_file ; do
134
+ # Check README.md files only directly inside each buildingblock
135
+ for readme_file in $( find $modules_glob -maxdepth 1 - name ' README.md' ) ; do
101
136
check_readme_format " $readme_file "
102
137
done
103
138
104
- # Check all PNG files
105
- find $modules_glob -name ' *.png' -print0 | while IFS= read -r -d ' ' png_file ; do
139
+ # Check PNG files only directly inside each buildingblock
140
+ for png_file in $( find $modules_glob -maxdepth 1 - name ' *.png' ) ; do
106
141
check_png_naming " $png_file "
107
142
done
108
143
109
- # Check all Terraform buildingblock directories
110
- find $modules_glob -type d -name ' buildingblock' -print0 | while IFS= read -r -d ' ' buildingblock_dir ; do
144
+ Check each buildingblock directory
145
+ for buildingblock_dir in $( find $modules_glob -type d -name ' buildingblock' ) ; do
111
146
check_terraform_files " $buildingblock_dir "
112
147
done
113
148
114
- # Print results
149
+ # Output summary
115
150
echo " "
116
151
echo " Number of errors: ${# errors[@]} "
117
152
echo " Number of warnings: ${# warnings[@]} "
118
153
echo " "
119
154
120
155
if [[ ${# errors[@]} -gt 0 ]]; then
121
- echo -e " ${RED} Errors found :${NC} "
122
- for error in " ${errors[@]} " ; do
123
- echo -e " - $error "
156
+ echo -e " ${RED} Errors:${NC} "
157
+ for e in " ${errors[@]} " ; do
158
+ echo " - $e "
124
159
done
125
- echo " "
126
160
exit 1
127
161
elif [[ ${# warnings[@]} -gt 0 ]]; then
128
- echo -e " ${YELLOW} Warnings found :${NC} "
129
- for warning in " ${warnings[@]} " ; do
130
- echo -e " - $warning "
162
+ echo -e " ${YELLOW} Warnings:${NC} "
163
+ for w in " ${warnings[@]} " ; do
164
+ echo " - $w "
131
165
done
132
- echo " "
133
166
exit 0
134
167
else
135
168
echo " ✅ All checks passed successfully."
136
169
exit 0
137
170
fi
171
+
172
+ if [[ -n " $GITHUB_STEP_SUMMARY " ]]; then
173
+ {
174
+ echo " ## 🧪 Module Validation Summary"
175
+ echo " "
176
+ echo " **Errors:** ${# errors[@]} "
177
+ for e in " ${errors[@]} " ; do echo " - ❌ $e " ; done
178
+ echo " "
179
+ echo " **Warnings:** ${# warnings[@]} "
180
+ for w in " ${warnings[@]} " ; do echo " - ⚠️ $w " ; done
181
+ if [[ ${# errors[@]} -eq 0 && ${# warnings[@]} -eq 0 ]]; then
182
+ echo " - ✅ All checks passed successfully."
183
+ fi
184
+ }
185
+ fi
0 commit comments