Skip to content

Commit 10f4172

Browse files
Shell Format Workflow (#2400)
1 parent d781c75 commit 10f4172

File tree

1 file changed

+243
-0
lines changed

1 file changed

+243
-0
lines changed

.github/workflows/script_format.yml

Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
1+
name: Script Format Check
2+
permissions:
3+
pull-requests: write
4+
on:
5+
pull_request_target:
6+
branches:
7+
- main
8+
paths:
9+
- 'install/*.sh'
10+
- 'ct/*.sh'
11+
12+
jobs:
13+
run-install-script:
14+
runs-on: pvenode
15+
steps:
16+
- name: Checkout PR branch (supports forks)
17+
uses: actions/checkout@v4
18+
with:
19+
ref: ${{ github.event.pull_request.head.ref }}
20+
repository: ${{ github.event.pull_request.head.repo.full_name }}
21+
fetch-depth: 0
22+
23+
- name: Add Git safe directory
24+
run: |
25+
git config --global --add safe.directory /__w/ProxmoxVE/ProxmoxVE
26+
27+
- name: Set up GH_TOKEN
28+
env:
29+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
30+
run: |
31+
echo "GH_TOKEN=${GH_TOKEN}" >> $GITHUB_ENV
32+
33+
- name: Get Changed Files
34+
run: |
35+
CHANGED_FILES=$(gh pr diff ${{ github.event.pull_request.number }} --repo ${{ github.repository }} --name-only)
36+
CHANGED_FILES=$(echo "$CHANGED_FILES" | tr '\n' ' ')
37+
echo "Changed files: $CHANGED_FILES"
38+
echo "SCRIPT=$CHANGED_FILES" >> $GITHUB_ENV
39+
env:
40+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
41+
42+
- name: Check scripts
43+
id: run-install
44+
continue-on-error: true
45+
run: |
46+
for FILE in ${{ env.SCRIPT }}; do
47+
STRIPPED_NAME=$(basename "$FILE" | sed 's/-install//' | sed 's/\.sh$//')
48+
echo "Running Test for: $STRIPPED_NAME"
49+
FILE_STRIPPED="${FILE##*/}"
50+
LOG_FILE="result_$FILE_STRIPPED.log"
51+
52+
if [[ $FILE =~ ^ct/.*\.sh$ ]]; then
53+
54+
FIRST_LINE=$(sed -n '1p' "$FILE")
55+
[[ "$FIRST_LINE" != "#!/usr/bin/env bash" ]] && echo "Line 1 was $FIRST_LINE | Should be: #!/usr/bin/env bash" >> "$LOG_FILE"
56+
SECOND_LINE=$(sed -n '2p' "$FILE")
57+
[[ "$SECOND_LINE" != "source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)" ]] &&
58+
echo "Line 2 was $SECOND_LINE | Should be: source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)" >> "$LOG_FILE"
59+
THIRD_LINE=$(sed -n '3p' "$FILE")
60+
if ! [[ "$THIRD_LINE" =~ ^#\ Copyright\ \(c\)\ [0-9]{4}-[0-9]{4}\ community-scripts\ ORG$ || "$THIRD_LINE" =~ ^Copyright\ \(c\)\ [0-9]{4}-[0-9]{4}\ tteck$ ]]; then
61+
echo "Line 3 was $THIRD_LINE | Should be: # Copyright (c) 2021-2025 community-scripts ORG" >> "$LOG_FILE"
62+
fi
63+
64+
EXPECTED_AUTHOR="# Author:"
65+
EXPECTED_LICENSE="# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE"
66+
EXPECTED_SOURCE="# Source:"
67+
EXPECTED_EMPTY=""
68+
69+
for i in {4..7}; do
70+
LINE=$(sed -n "${i}p" "$FILE")
71+
72+
case $i in
73+
4)
74+
[[ $LINE == $EXPECTED_AUTHOR* ]] || printf "Line %d was: '%s' | Should start with: '%s'\n" "$i" "$LINE" "$EXPECTED_AUTHOR" >> $LOG_FILE
75+
;;
76+
5)
77+
[[ "$LINE" == "$EXPECTED_LICENSE" ]] || printf "Line %d was: '%s' | Should be: '%s'\n" "$i" "$LINE" "$EXPECTED_LICENSE" >> $LOG_FILE
78+
;;
79+
6)
80+
[[ $LINE == $EXPECTED_SOURCE* ]] || printf "Line %d was: '%s' | Should start with: '%s'\n" "$i" "$LINE" "$EXPECTED_SOURCE" >> $LOG_FILE
81+
;;
82+
7)
83+
[[ -z $LINE ]] || printf "Line %d was: '%s' | Should be empty\n" "$i" "$LINE" >> $LOG_FILE
84+
;;
85+
esac
86+
done
87+
88+
89+
EXPECTED_PREFIXES=(
90+
"APP="
91+
"var_tags="
92+
"var_cpu=" # Must be a number
93+
"var_ram=" # Must be a number
94+
"var_disk=" # Must be a number
95+
"var_os=" # Must be debian, alpine, or ubuntu
96+
"var_version="
97+
"var_unprivileged=" # Must be 0 or 1
98+
)
99+
100+
101+
for i in {8..15}; do
102+
LINE=$(sed -n "${i}p" "$FILE")
103+
INDEX=$((i - 8))
104+
105+
case $INDEX in
106+
2|3|4) # var_cpu, var_ram, var_disk (must be numbers)
107+
if [[ "$LINE" =~ ^${EXPECTED_PREFIXES[$INDEX]}([0-9]+)$ ]]; then
108+
continue # Valid
109+
else
110+
echo "Line $i was '$LINE' | Should be: '${EXPECTED_PREFIXES[$INDEX]}<NUMBER>'" >> "$LOG_FILE"
111+
fi
112+
;;
113+
5) # var_os (must be debian, alpine, or ubuntu)
114+
if [[ "$LINE" =~ ^var_os=(debian|alpine|ubuntu)$ ]]; then
115+
continue # Valid
116+
else
117+
echo "Line $i was '$LINE' | Should be: 'var_os=[debian|alpine|ubuntu]'" >> "$LOG_FILE"
118+
fi
119+
;;
120+
7) # var_unprivileged (must be 0 or 1)
121+
if [[ "$LINE" =~ ^var_unprivileged=[01]$ ]]; then
122+
continue # Valid
123+
else
124+
echo "Line $i was '$LINE' | Should be: 'var_unprivileged=[0|1]'" >> "$LOG_FILE"
125+
fi
126+
;;
127+
*) # Other lines (must start with expected prefix)
128+
if [[ "$LINE" == ${EXPECTED_PREFIXES[$INDEX]}* ]]; then
129+
continue # Valid
130+
else
131+
echo "Line $i was '$LINE' | Should start with '${EXPECTED_PREFIXES[$INDEX]}'" >> "$LOG_FILE"
132+
fi
133+
;;
134+
esac
135+
done
136+
137+
for i in {16..20}; do
138+
LINE=$(sed -n "${i}p" "$FILE")
139+
EXPECTED=(
140+
"header_info \"$APP\""
141+
"variables"
142+
"color"
143+
"catch_errors"
144+
"function update_script() {"
145+
)
146+
[[ "$LINE" != "${EXPECTED[$((i-16))]}" ]] && echo "Line $i was $LINE | Should be: ${EXPECTED[$((i-16))]}" >> "$LOG_FILE"
147+
done
148+
cat "$LOG_FILE"
149+
elif [[ $FILE =~ ^install/.*-install\.sh$ ]]; then
150+
151+
FIRST_LINE=$(sed -n '1p' "$FILE")
152+
[[ "$FIRST_LINE" != "#!/usr/bin/env bash" ]] && echo "Line 1 was $FIRST_LINE | Should be: #!/usr/bin/env bash" >> "$LOG_FILE"
153+
154+
SECOND_LINE=$(sed -n '2p' "$FILE")
155+
[[ -n "$SECOND_LINE" ]] && echo "Line 2 should be empty" >> "$LOG_FILE"
156+
157+
THIRD_LINE=$(sed -n '3p' "$FILE")
158+
if ! [[ "$THIRD_LINE" =~ ^#\ Copyright\ \(c\)\ [0-9]{4}-[0-9]{4}\ community-scripts\ ORG$ || "$THIRD_LINE" =~ ^Copyright\ \(c\)\ [0-9]{4}-[0-9]{4}\ tteck$ ]]; then
159+
echo "Line 3 was $THIRD_LINE | Should be: # Copyright (c) 2021-2025 community-scripts ORG" >> "$LOG_FILE"
160+
fi
161+
162+
EXPECTED_AUTHOR="# Author:"
163+
EXPECTED_LICENSE="# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE"
164+
EXPECTED_SOURCE="# Source:"
165+
EXPECTED_EMPTY=""
166+
167+
for i in {4..7}; do
168+
LINE=$(sed -n "${i}p" "$FILE")
169+
170+
case $i in
171+
4)
172+
[[ $LINE == $EXPECTED_AUTHOR* ]] || printf "Line %d was: '%s' | Should start with: '%s'\n" "$i" "$LINE" "$EXPECTED_AUTHOR" >> $LOG_FILE
173+
;;
174+
5)
175+
[[ "$LINE" == "$EXPECTED_LICENSE" ]] || printf "Line %d was: '%s' | Should be: '%s'\n" "$i" "$LINE" "$EXPECTED_LICENSE" >> $LOG_FILE
176+
;;
177+
6)
178+
[[ $LINE == $EXPECTED_SOURCE* ]] || printf "Line %d was: '%s' | Should start with: '%s'\n" "$i" "$LINE" "$EXPECTED_SOURCE" >> $LOG_FILE
179+
;;
180+
7)
181+
[[ -z $LINE ]] || printf "Line %d was: '%s' | Should be empty\n" "$i" "$LINE" >> $LOG_FILE
182+
;;
183+
esac
184+
done
185+
186+
[[ "$(sed -n '8p' "$FILE")" != 'source /dev/stdin <<< "$FUNCTIONS_FILE_PATH"' ]] && echo 'Line 8 should be: source /dev/stdin <<< "$FUNCTIONS_FILE_PATH"' >> "$LOG_FILE"
187+
188+
for i in {9..14}; do
189+
LINE=$(sed -n "${i}p" "$FILE")
190+
EXPECTED=(
191+
"color"
192+
"verb_ip6"
193+
"catch_errors"
194+
"setting_up_container"
195+
"network_check"
196+
"update_os"
197+
)
198+
[[ "$LINE" != "${EXPECTED[$((i-9))]}" ]] && echo "Line $i was $LINE | Should be: ${EXPECTED[$((i-9))]}" >> "$LOG_FILE"
199+
done
200+
201+
[[ -n "$(sed -n '15p' "$FILE")" ]] && echo "Line 15 should be empty" >> "$LOG_FILE"
202+
[[ "$(sed -n '16p' "$FILE")" != 'msg_info "Installing Dependencies"' ]] && echo 'Line 16 should be: msg_info "Installing Dependencies"' >> "$LOG_FILE"
203+
204+
LAST_3_LINES=$(tail -n 3 "$FILE")
205+
[[ "$LAST_3_LINES" != *"$STD apt-get -y autoremove"* ]] && echo 'Third to last line should be: $STD apt-get -y autoremove' >> "$LOG_FILE"
206+
[[ "$LAST_3_LINES" != *"$STD apt-get -y autoclean"* ]] && echo 'Second to last line should be: $STD apt-get -y clean' >> "$LOG_FILE"
207+
[[ "$LAST_3_LINES" != *'msg_ok "Cleaned"'* ]] && echo 'Last line should be: msg_ok "Cleaned"' >> "$LOG_FILE"
208+
cat "$LOG_FILE"
209+
fi
210+
211+
done
212+
213+
214+
- name: Post error comments
215+
run: |
216+
ERROR="false"
217+
for FILE in ${{ env.SCRIPT }}; do
218+
FILE_STRIPPED="${FILE##*/}"
219+
LOG_FILE="result_$FILE_STRIPPED.log"
220+
echo $LOG_FILE
221+
if [[ ! -f $LOG_FILE ]]; then
222+
continue
223+
fi
224+
ERROR_MSG=$(cat $LOG_FILE)
225+
226+
if [ -n "$ERROR_MSG" ]; then
227+
echo "Posting error message for $FILE"
228+
echo ${ERROR_MSG}
229+
gh pr comment ${{ github.event.pull_request.number }} \
230+
--repo ${{ github.repository }} \
231+
--body ":warning: The script _**$FILE**_ has the following formatting errors: <br> <div><strong>${ERROR_MSG}</strong></div>"
232+
233+
234+
ERROR="true"
235+
fi
236+
done
237+
echo "ERROR=$ERROR" >> $GITHUB_ENV
238+
env:
239+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
240+
241+
- name: Fail if error
242+
if: ${{ env.ERROR == 'true' }}
243+
run: exit 1

0 commit comments

Comments
 (0)