-
Notifications
You must be signed in to change notification settings - Fork 53
225 lines (190 loc) · 9.63 KB
/
versionCheck.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
# - Github Version Control Checker
# - Watches changes on contracts in the following paths:
# - src
# - src/Facets/
# - src/Periphery/
# - will check all modified or new contracts in watched paths
# - will fail if a new contract was added to watched paths without contract version
# - will fail if an existing contract was modified but version was not updated
# - will update the PR title to contain all contract names and their new versions (watched paths only)
name: Version Check
on:
pull_request:
types: [opened, edited, synchronize]
jobs:
check-version:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0 ##### Fetch all history for all branches
- name: Get list of modified files by this PR
id: modified_files
run: |
BASE_REF="${{ github.event.pull_request.base.ref }}"
##### get all files modified by this PR
FILES=$(git diff --name-only origin/${BASE_REF} HEAD)
##### make sure that there are modified files
if [[ -z $FILES ]]; then
echo "No files found. This should not happen. Please check the code of the Github action"
exit 1
fi
##### Initialize empty variables
CONTRACTS=""
##### go through all file names and identify facet, periphery & diamond contracts (other contracts dont have versioning)
while IFS= read -r FILE; do
if echo "$FILE" | grep -E '^src/Facets/.*\.sol$'; then
##### facet found
CONTRACTS="${CONTRACTS}${FILE}"$'\n'
elif echo "$FILE" | grep -E '^src/Periphery/.*\.sol$'; then
##### periphery found
CONTRACTS="${CONTRACTS}${FILE}"$'\n'
elif echo "$FILE" | grep -E '^src/.*\.sol$'; then
##### diamond contract found
CONTRACTS="${CONTRACTS}${FILE}"$'\n'
fi
done <<< "$FILES"
##### if none found, exit here as there is nothing to do
if [[ -z "$CONTRACTS" ]]; then
echo -e "\033[32mNo version-controlled contracts found in files modified/added by this PR.\033[0m"
echo -e "\033[32mNo further checks are required.\033[0m"
# set action output to false
echo "CONTINUE=false" >> $GITHUB_ENV
exit 0
else
# set action output to true
echo "CONTINUE=true" >> $GITHUB_ENV
fi
##### Write filenames to temporary files (using variables here was causing issues due to the file names)
echo -e "$CONTRACTS" > modified_contracts.txt
- name: Verify version updates on modified contracts
id: verify_version_changes
if: env.CONTINUE == 'true'
run: |
##### Read tmp file into variable
CONTRACTS=$(cat modified_contracts.txt)
##### Initialize variables
MISSING_VERSION_TAG=()
MISSING_VERSION_UPDATE=()
UPDATED_CONTRACTS=()
echo "--------------------"
##### Process each file separately
while IFS= read -r FILE; do
echo "Now checking contract: $FILE"
VERSION_TAG=$(grep -E '^/// @custom:version' "$FILE" || true)
VERSION=$(echo "$VERSION_TAG" | sed -E 's/^\/\/\/ @custom:version ([0-9]+\.[0-9]+\.[0-9]+).*$/\1/' || true)
##### Extract the filename without extension
FILENAME=$(basename "$FILE" .sol)
##### Check if a version tag exists in the contract file
if [[ -z "$VERSION_TAG" ]]; then
echo -e "\033[31mFile does not contain a version tag\033[0m"
MISSING_VERSION_TAG+=("$FILE")
else
echo -e "\033[32mFile contains a custom:version tag\033[0m"
##### get all changes of the current file/contract
DIFF_OUTPUT=$(git diff origin/${{ github.event.pull_request.base.ref }} HEAD "$FILE")
##### Check if the version was updated in this PR (by checking if any of the git diff lines starts with '/// @custom:version')
if echo "$DIFF_OUTPUT" | grep -qE '^\+/// @custom:version'; then
echo -e "\033[32mFile version was updated in this PR to version $VERSION\033[0m"
##### extract the new version and save it together with the name of the contract in an array
NEW_VERSION=$(echo "$VERSION_TAG" | awk '{print $NF}')
TARGET_STRING="${FILENAME} v${NEW_VERSION}"
UPDATED_CONTRACTS+=("$TARGET_STRING")
else
##### add to files with missing version updates
echo -e "\033[31mFile's version was not updated in this PR\033[0m"
MISSING_VERSION_UPDATE+=("$FILE")
fi
fi
echo "--------------------"
done <<< "$CONTRACTS"
##### If any contract files are missing a version tag, this must be corrected before continuing
if [[ ${#MISSING_VERSION_TAG[@]} -ne 0 ]]; then
echo "--------------------"
echo ">>>>>>"
echo -e "\033[31mThe following files are missing a custom:version tag in their code:\033[0m"
echo "${MISSING_VERSION_TAG[*]}"
echo -e "\033[31mEvery version-controlled contract needs to have a custom:version tag in its code.\033[0m"
echo -e "\033[31mThis Github action cannot complete until these issues are solved.\033[0m"
exit 1
fi
##### if the version was not updated in any of the changed contracts, store the list of affected files in a tmp file
if [[ ${#MISSING_VERSION_UPDATE[@]} -ne 0 ]]; then
echo "--------------------"
echo ">>>>>>"
echo -e "\033[31mThe following contract(s) have been modified but their version tags were not updated:\033[0m"
echo "${MISSING_VERSION_UPDATE[*]}"
echo -e "\033[31mPlease make sure to update a contract's version whenever there are changes in the file.\033[0m"
echo -e "\033[31mThis Github action cannot complete until these issues are solved.\033[0m"
echo ""
exit 1
fi
##### store any contracts that were correctly updated in a tmp file so we can check the PR title after for each of those
if [[ ${#UPDATED_CONTRACTS[@]} -ne 0 ]]; then
##### create a string from the array with all contracts
UPDATED_CONTRACTS_STR=$(IFS=,; echo "${UPDATED_CONTRACTS[*]}")
echo "UPDATED_CONTRACTS=$UPDATED_CONTRACTS_STR" >> $GITHUB_ENV
echo -e "${UPDATED_CONTRACTS_STR[*]}" > updated_contracts.txt
else
echo -e "\033[32mDid not find any contracts for which version control is activated (only facets, periphery and diamonds).\033[0m"
echo -e "\033[32mNo further checks are required.\033[0m"
echo "CONTINUE=false" >> $GITHUB_ENV
exit 0
fi
- name: Compose updated PR title
if: env.CONTINUE == 'true'
env:
PR_TITLE: ${{github.event.pull_request.title}}
run: |
##### Read tmp files into variables
if [ -f updated_contracts.txt ]; then
UPDATED_CONTRACTS=$(cat updated_contracts.txt)
fi
echo "UPDATED CONTRACTS: $UPDATED_CONTRACTS"
##### Initialize PR title
PR_TITLE_UPDATED="$PR_TITLE ["
##### Go through the list of target strings (contract + newVersion)
IFS=',' read -ra UPDATED_ARRAY <<< "$UPDATED_CONTRACTS"
for TARGET_STRING in "${UPDATED_ARRAY[@]}"; do
##### if current PR title does not contain this contract's name....
if [[ ! "$PR_TITLE_UPDATED" =~ "$TARGET_STRING" ]]; then
##### ... then add it to the title
echo "adding '$TARGET_STRING' to title"
PR_TITLE_UPDATED="$PR_TITLE_UPDATED$TARGET_STRING, "
fi
done
##### Finalize the PR title
##### Check if the last two characters are ", " (= contracts were added to title)
if [[ "${PR_TITLE_UPDATED: -2}" == ", " ]]; then
##### Remove the last two characters and append a closing bracket
PR_TITLE_UPDATED="${PR_TITLE_UPDATED:0:-2}]"
##### Check if last character is '(' (= no contracts were added to title)
elif [[ "${PR_TITLE_UPDATED: -1}" == "[" ]]; then
##### Remove the last character (not needed)
PR_TITLE_UPDATED="${PR_TITLE_UPDATED:0:-1}"
else
echo "Error: Unexpected ending in PR_TITLE_UPDATED: '$PR_TITLE_UPDATED'"
exit 1
fi
##### if there are no changes in the title, no need to continue further
if [[ $PR_TITLE == $PR_TITLE_UPDATED ]]; then
echo "No PR title updates are required."
echo "This github action will end here."
exit 0
fi
##### save updated PR title in env variable
echo "PR_TITLE_UPDATED=$PR_TITLE_UPDATED" >> $GITHUB_ENV
- name: Update the PR title on GitHub
if: env.CONTINUE == 'true'
env:
GH_PAT: ${{ secrets.GIT_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_TITLE_UPDATED: ${{ env.PR_TITLE_UPDATED }}
run: |
##### unset the default git token (does not have sufficient rights to perform the update)
unset GITHUB_TOKEN
##### use the Personal Access Token to log into git CLI
echo $GH_PAT | gh auth login --with-token
##### update the PR title
gh pr edit ${{ github.event.pull_request.number }} --title "${{ env.PR_TITLE_UPDATED }}"