-
Notifications
You must be signed in to change notification settings - Fork 3
/
action.yml
306 lines (274 loc) · 10.9 KB
/
action.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
name: "Code-Formatter"
description: "Format Ruby, Terraform, YAML/YML, Python, Markdown, JSON and html.md.erb files within a PR"
inputs:
ignore-files:
description: "Files to ignore"
required: false
default: ""
terraform-version:
description: "Version of Terraform to use for formatting"
required: false
default: "latest"
runs:
using: "composite"
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
repository: ${{ github.repository }}
- name: Check Branch exists and is not a fork.
id: branch-exists
run: |
git fetch origin
branch_name=${{ github.head_ref }}
echo "branch_name=$branch_name" >> $GITHUB_ENV
if [[ $( git rev-parse --verify origin/$branch_name ) ]]; then
echo "result=$((0))" >> ${GITHUB_OUTPUT}
else
echo "Warning: Cannot code-format a forked branch or cannot find the branch!"
echo $branch_name
echo "Finished: no Code Formatter changes."
echo "result=$((1))" >> ${GITHUB_OUTPUT}
fi
shell: bash
- name: Change branch and set up a ruby version file that may be needed
run: |
if [[ ${{ steps.branch-exists.outputs.result }} == 0 ]];
then
git switch ${{ github.head_ref }}
FILE0=.ruby-version
FILE1=.tool-versions
FILE3=Gemfile
FILE4=Gemfile.lock
if [ -f "$FILE0" ]; then
echo "$FILE0 exists."
elif [ -f "$FILE1" ]; then
echo "$FILE1 exists."
elif [ -f "$FILE3" ]; then
echo "$FILE3 exists."
if grep 'ruby "' $FILE3; then
echo "Found ruby version"
grep 'ruby "' $FILE3 | sed "s/[^0-9.]*//g" > .ruby-version
chmod 755 .ruby-version
else
if [ -f "$FILE4" ]; then
echo "$FILE4 exists."
if tail -5 $FILE4 | grep ruby; then
echo "Found ruby version"
tail -5 $FILE4 | grep ruby | sed "s/[^0-9.]*//g" > .ruby-version
chmod 755 .ruby-version
else
echo "Using ruby version 3.1.0"
echo '3.1.0' > .ruby-version
chmod 755 .ruby-version
fi
fi
fi
else
echo "Using ruby version 3.1.0"
echo '3.1.0' > .ruby-version
chmod 755 .ruby-version
fi
fi
shell: bash
- name: Create blank ruby version file
run: |
if [[ ${{ steps.branch-exists.outputs.result }} == 1 ]];
then
echo "Using ruby version 3.1.0"
echo '3.1.0' > .ruby-version
chmod 755 .ruby-version
fi
shell: bash
- uses: ruby/setup-ruby@v1
- name: Install dependencies
run: |
if [[ ${{ steps.branch-exists.outputs.result }} == 0 ]];
then
npm install --location=global prettier
pipx install autopep8
FILE2=Gemfile
if [ -f "$FILE2" ]; then
echo "$FILE2 already exists."
if grep -q standardrb "$FILE2"; then
echo "standardrb already exists."
else
bundle add standardrb
fi
if grep -q erb_lint "$FILE2"; then
echo "erb_lint already exists."
else
bundle add erb_lint
fi
else
bundle init
bundle add standardrb
bundle add erb_lint
fi
fi
shell: bash
- name: Setup Terraform
uses: hashicorp/[email protected] # v3.1.2
with:
terraform_version: "${{ inputs.terraform-version }}"
terraform_wrapper: false
- name: Get PR changed files via Git and code format files
run: |
if [[ ${{ steps.branch-exists.outputs.result }} == 0 ]];
then
git config user.name 'github-actions[bot]'
git config user.email 'github-actions[bot]@users.noreply.github.com'
git fetch origin $GITHUB_BASE_REF --depth=50
base_branch_sha=${{ github.event.pull_request.base.sha }}
git fetch origin ${{ github.head_ref }} --depth=50
head_branch_sha=${{ github.event.pull_request.head.sha }}
echo $base_branch_sha
echo $head_branch_sha
git diff-tree -r --no-commit-id --name-only --diff-filter=ACMRT $base_branch_sha $head_branch_sha > modified_files.txt
chmod 755 modified_files.txt
[ -n "$(tail -c1 modified_files.txt)" ] && echo >> modified_files.txt
modified_files=()
while IFS= read -r file
do
modified_files+=("$file")
done < modified_files.txt
ignore_files_string=${{ inputs.ignore-files }}
ignore_files_length=${#ignore_files_string}
if [ $ignore_files_length -gt 0 ]; then
ignore_files=()
IFS=,
for ignore_file in "${ignore_files_string[@]}";
do
ignore_files+=("$ignore_file")
done
for modified_file in "${modified_files[@]}";
do
file_name=$(basename $modified_file)
for ignore_file in ${ignore_files[@]};
do
if [[ $file_name == $ignore_file ]]; then
echo "Ignore file: $ignore_file"
modified_files=("${modified_files[@]/$ignore_file}")
fi
done
done
fi
for file in "${modified_files[@]}";
do
if [ ${#file} -gt 0 ]; then
echo "Checking file: $file"
if [[ $file == *".github"* ]]; then
echo "Cannot format .github/workflow files."
elif [[ $file == *".py"* ]]; then
~/.local/bin/autopep8 --in-place $file
elif [[ $file == *".rb"* ]]; then
bundle exec standardrb --fix $file
elif [[ $file == *".tf" ]] || [[ $file == *".tfvars" ]]; then
terraform fmt $file
elif [[ $file == *".html.md.erb" ]]; then
bundle exec erblint -a $file
elif [[ $file == *".yaml" || $file == *".yml" || $file == *".md" || $file == *".html.md" || $file == *".json" ]]; then
npx prettier --print-width=150 --write $file
fi
fi
done
fi
shell: bash
- name: Remove non needed files from new commit
run: |
if [[ ${{ steps.branch-exists.outputs.result }} == 0 ]];
then
rm -rf Gemfile
rm -rf Gemfile.lock
rm -rf package-lock.json
rm -rf package.json
rm -rf node_modules
rm -rf namespaces
rm -rf modified_files.txt
rm -rf .ruby-version
fi
shell: bash
- name: Commit new files or finish script
run: |
if [[ ${{ steps.branch-exists.outputs.result }} == 0 ]];
then
git ls-files --deleted -z | git update-index --assume-unchanged -z --stdin
if [ -n "$(git status --porcelain=1 --untracked-files=no)" ]; then
# Stage the changes
git add --ignore-removal .
# Get the amended file names and save them.
git diff --staged --name-only > changed_files.txt
echo "List files amended by formatter"
cat changed_files.txt
commit_oid=$(git rev-parse HEAD)
echo "commit_oid=$commit_oid" >> $GITHUB_ENV
# Initialize an empty JSON object for the additions
files_for_commit='{"additions": []}'
# Read the changed files from changed_files.txt
while IFS= read -r file; do
if [[ -f "$file" ]]; then
# Get the content for the file
file_content="$(cat "$file")"
# Base64 encode the contents of the file
base64_content=$(base64 -w 0 <<< "$file_content")
# Construct a JSON object for this file and append it to the additions array
files_for_commit=$(echo "$files_for_commit" | jq --arg path "$file" --arg content "$base64_content" \
'.additions += [{ "path": $path, "contents": $content }]')
fi
done < changed_files.txt
# Output the final JSON array
echo "$files_for_commit" > files_for_commit.json
# Error handling for `jq` output
echo "Check for valid json output"
if ! jq . files_for_commit.json; then
echo "Error reading files_for_commit.json"
exit 1
fi
# Get the Repo Owner and Name
repo_owner=$(echo $GITHUB_REPOSITORY | cut -d'/' -f1)
repo_name=$(echo $GITHUB_REPOSITORY | cut -d'/' -f2)
echo "The calling repo is $repo_owner/$repo_name"
commit_message="Commit changes made by code formatters"
# Prepare the mutation payload
mutation_payload=$(jq -n \
--arg branch_name "$branch_name" \
--arg commit_oid "$commit_oid" \
--arg repo_id "$repo_id" \
--arg commit_message "$commit_message" \
--arg repo_owner "$repo_owner" \
--arg repo_name "$repo_name" \
--argjson fileChanges "$(jq -c . < files_for_commit.json)" \
'{
query: "mutation($input: CreateCommitOnBranchInput!) { createCommitOnBranch(input: $input) { commit { oid } } }",
variables: {
input: {
branch: {
repositoryNameWithOwner: "\($repo_owner)/\($repo_name)",
branchName: $branch_name
},
message: {
headline: $commit_message
},
fileChanges: $fileChanges,
expectedHeadOid: $commit_oid
}
}
}')
echo "Mutation Payload: $mutation_payload"
# Send the mutation request to GitHub's GraphQL API and capture the response
RESPONSE=$(curl -X POST -H "Authorization: bearer $GITHUB_TOKEN" \
-H "Content-Type: application/json" \
-d "$mutation_payload" https://api.github.com/graphql)
# Parse the commit OID from the response
COMMIT_OID=$(echo "$RESPONSE" | jq -r ".data.createCommitOnBranch.commit.oid")
# Check if the commit was successfully created
if [ "$COMMIT_OID" != "null" ]; then
echo "Commit successfully created with OID: $COMMIT_OID"
else
echo "Error creating commit: $RESPONSE"
fi
echo "Finished: Code Formatter changes applied."
else
echo "Finished: no Code Formatter changes."
fi
fi
shell: bash