Skip to content

Commit d5826fe

Browse files
committed
feat(RELEASE-1988): use utils script in process-file-updates task
call utils script from process-file-updates task Signed-off-by: Elena German <elgerman@redhat.com> Assisted-by: Cursor
1 parent 17b958a commit d5826fe

15 files changed

Lines changed: 178 additions & 1149 deletions

.github/scripts/test_tekton_tasks.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ apply_python_command_mocks_merge() {
6565
# Do not use printf %q for Tekton placeholders: single-quoted %q output
6666
# prevents Tekton from rewriting $(params.*) inside spec.steps[].script.
6767
if [[ "$w" == *'$('* ]]; then
68-
printf ' "%s"\n' "$w"
68+
printf " '%s'\n" "$w"
6969
else
7070
printf ' %q\n' "$w"
7171
fi

tasks/internal/process-file-updates-task/process-file-updates-task.yaml

Lines changed: 29 additions & 246 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ spec:
7878
readOnly: true
7979
steps:
8080
- name: perform-updates
81-
image: quay.io/konflux-ci/release-service-utils@sha256:e852a62497c4537059bb1f4c3ddf5c1a813b2b22bd9f4bb826cffb36af7d5f65
81+
image: quay.io/konflux-ci/release-service-utils@sha256:b3afc716641dccca0574b6fa26b12c579ed227d0d58aa5c299f2818ad4d4dae3
8282
securityContext:
8383
runAsUser: 1001
8484
computeResources:
@@ -91,248 +91,31 @@ spec:
9191
- name: file-updates-secret-vol
9292
mountPath: "/mnt/file-updates-secret"
9393
env:
94-
- name: TEMP
95-
value: "$(params.tempDir)"
96-
script: |
97-
#!/usr/bin/env bash
98-
set -eo pipefail
99-
100-
GITLAB_HOST="$(cat /mnt/file-updates-secret/gitlab_host)"
101-
ACCESS_TOKEN="$(cat /mnt/file-updates-secret/gitlab_access_token)"
102-
GIT_AUTHOR_NAME="$(cat /mnt/file-updates-secret/git_author_name)"
103-
GIT_AUTHOR_EMAIL="$(cat /mnt/file-updates-secret/git_author_email)"
104-
105-
# export the variables used by the scripts in release-service-utils
106-
export GITLAB_HOST ACCESS_TOKEN GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL
107-
108-
echo -n "$(params.internalRequestPipelineRunName)" > "$(results.internalRequestPipelineRunName.path)"
109-
echo -n "$(context.taskRun.name)" > "$(results.internalRequestTaskRunName.path)"
110-
111-
# loading git and gitlab functions
112-
# shellcheck source=/dev/null
113-
. /home/utils/gitlab-functions
114-
# shellcheck source=/dev/null
115-
. /home/utils/git-functions
116-
117-
echo "Temp Dir: $TEMP"
118-
mkdir -p "$TEMP"
119-
120-
gitlab_init
121-
git_functions_init
122-
123-
# saves the params.paths json to a file
124-
updatePathsTmpfile="${TEMP}/updatePaths.json"
125-
cat > "${updatePathsTmpfile}" << JSON
126-
$(params.paths)
127-
JSON
128-
129-
UPSTREAM_REPO="$(params.upstream_repo)"
130-
REPO="$(params.repo)"
131-
REVISION="$(params.ref)"
132-
133-
echo -e "=== UPDATING ${REPO} ON BRANCH ${REVISION} ===\n"
134-
135-
cd "${TEMP}"
136-
git_clone_and_checkout --repository "${REPO}" --revision "${REVISION}"
137-
138-
# updating local branch with the upstream
139-
git_rebase -n "glab-base" -r "${UPSTREAM_REPO}" -v "${REVISION}"
140-
141-
replacementsUpdateError=
142-
# getting the files that have replacements
143-
cat "${updatePathsTmpfile}"
144-
PATHS_LENGTH="$(jq '. | length' "${updatePathsTmpfile}")"
145-
for (( PATH_INDEX=0; PATH_INDEX < PATHS_LENGTH; PATH_INDEX++ )); do
146-
# getting the replacements for the file
147-
echo "-- start updatePathsTmpfile --"
148-
cat "${updatePathsTmpfile}"
149-
echo "-- end updatePathsTmpfile --"
150-
targetFile="$(jq -cr ".[${PATH_INDEX}].path" "${updatePathsTmpfile}")"
151-
echo "targetFile: ${targetFile}"
152-
153-
seed=$(jq ".[${PATH_INDEX}].seed // \"\"" "${updatePathsTmpfile}")
154-
seed="${seed%\"}"
155-
seed="${seed#\"}"
156-
echo "${seed}"
157-
158-
if [ -n "${seed}" ] ; then
159-
echo "seed operation to perform"
160-
targetDir=$(dirname "${targetFile}")
161-
mkdir -p "${targetDir}"
162-
echo -e "${seed}" > "${targetFile}"
163-
echo "-- start targetFile --"
164-
cat "${targetFile}"
165-
echo "-- end targetFile --"
166-
git add "${targetFile}"
167-
git status
168-
fi
169-
170-
REPLACEMENTS_LENGTH="$(jq -cr ".[${PATH_INDEX}].replacements | length" "${updatePathsTmpfile}")"
171-
echo "Replacements to perform: ${REPLACEMENTS_LENGTH}"
172-
REPLACEMENTS_PERFORMED=
173-
if [ "${REPLACEMENTS_LENGTH}" -gt 0 ] ; then
174-
REPLACEMENTS_PERFORMED=0
175-
# we need to know how many empty newlines and `---` the file has before
176-
# the actual yaml data starts excluding comments
177-
blankLinesBeforeYaml="$(awk '/[[:alpha:]]+/{ if(! match($0, "^#")) { print NR-1; exit } }' "${targetFile}")"
178-
179-
# check if the targetFile is a valid yaml file
180-
if ! yq "${targetFile}" >/dev/null 2>&1; then
181-
echo "fileUpdates: the targetFile ${targetFile} is not a yaml file" | \
182-
tee "$(results.fileUpdatesInfo.path)"
183-
exit 1
184-
fi
185-
186-
keyNotFound=false
187-
for (( REPLACEMENT_INDEX=0; REPLACEMENT_INDEX < REPLACEMENTS_LENGTH; REPLACEMENT_INDEX++ )); do
188-
echo "REPLACEMENT: #${REPLACEMENT_INDEX}"
189-
key="$(jq -cr ".[${PATH_INDEX}].replacements[${REPLACEMENT_INDEX}].key" "${updatePathsTmpfile}")"
190-
replacement="$(jq -cr ".[${PATH_INDEX}].replacements[${REPLACEMENT_INDEX}].replacement" \
191-
"${updatePathsTmpfile}")"
192-
193-
# getting the key's position
194-
echo -en "Searching for key \`${key}\`: "
195-
yq "${key} | (line, .)" "${targetFile}" > "${TEMP}/found.txt"
196-
cat "${TEMP}/found.txt"
197-
foundAt=$(head -n 1 "${TEMP}/found.txt")
198-
if (( foundAt == 0 )); then
199-
echo "NOT FOUND"
200-
keyNotFound=true
201-
continue
202-
fi
203-
echo "FOUND"
204-
205-
sed -i '1d' "${TEMP}/found.txt"
206-
# getting the value size (in number of lines)
207-
valueSize=$(yq "${key}" "${targetFile}" | wc -l)
208-
startBlock=$(( foundAt + blankLinesBeforeYaml ))
209-
210-
# the replacement should be a sed expression using "|" as separator
211-
if [[ $(tr -dc "|" <<< "${replacement}" | wc -m ) != 3 ]]; then
212-
replacementsUpdateError="Replace expression should be in '|search|replace|' format"
213-
break
214-
fi
215-
216-
# run the replace
217-
echo "--start file--"
218-
cat "${targetFile}"
219-
echo "--end file--"
220-
sed -i "${startBlock},+${valueSize}s${replacement}" "${targetFile}"
221-
222-
# get the replace part of "|search|replace|"
223-
replaceStr=$(awk -F"|" '{print $3}' <<< "${replacement}")
224-
225-
# when the value is a text block we must make sure
226-
# only a single line was replaced and that the result
227-
# block has the same number of lines as before
228-
sed -ne "${startBlock},+${valueSize}p" "${targetFile}" > "${TEMP}/result.txt"
229-
diff -u "${TEMP}/found.txt" "${TEMP}/result.txt" > "${TEMP}/diff.txt" || true
230-
231-
replacedBlockLines=$(wc -l < "${TEMP}/result.txt")
232-
if [[ $replacedBlockLines != $(( valueSize +1 )) ]]; then
233-
replacementsUpdateError="Text block size differs from the original"
234-
break
235-
fi
236-
237-
# check if only a single line was replaced
238-
replacedCount=$(sed -ne "${startBlock},+${valueSize}p" "${targetFile}" | grep -c "${replaceStr}")
239-
if [[ $replacedCount != 1 ]]; then
240-
replacementsUpdateError="Too many lines replaced. Check if the replace expression isn't too greedy"
241-
break
242-
fi
243-
REPLACEMENTS_PERFORMED=$((REPLACEMENTS_PERFORMED + 1))
244-
done
245-
fi
246-
git add "${targetFile}"
247-
done
248-
249-
if [ -n "${replacementsUpdateError}" ]; then
250-
tempdiff=$(cat "${TEMP}/diff.txt")
251-
# we need to limit the size to due to the max result buffer
252-
diff=${tempdiff:1:3700} \
253-
error="${replacementsUpdateError}" \
254-
yq -o json --null-input '.str = strenv(diff), .error = strenv(error)' \
255-
| tee "$(results.fileUpdatesInfo.path)"
256-
echo -n "Failed" |tee "$(results.fileUpdatesState.path)"
257-
# it should exit 0 otherwise the task does not set the results
258-
# this way the InternalRequest can see what was wrong
259-
exit 0
260-
fi
261-
if [ "${REPLACEMENTS_PERFORMED}" == 0 ] ;then
262-
if [[ "$keyNotFound" == true ]]; then
263-
error="\"no replacements were performed\"" \
264-
yq -o json --null-input '.str = strenv(error), .error = strenv(error)' \
265-
| tee "$(results.fileUpdatesInfo.path)"
266-
echo -n "Failed" |tee "$(results.fileUpdatesState.path)"
267-
else
268-
echo "nothing needs change" \
269-
| tee -a "$(results.fileUpdatesInfo.path)"
270-
echo -n "Success" |tee "$(results.fileUpdatesState.path)"
271-
fi
272-
# it should exit 0 otherwise the task does not set the results
273-
# this way the InternalRequest can see what was wrong
274-
exit 0
275-
fi
276-
277-
echo -e "\n*** START LOCAL CHANGES ***\n"
278-
echo -e "\n*** Result from git diff --cached ***\n"
279-
# compare the differences between the staging area and the latest commit
280-
git diff --cached | tee "${TEMP}"/tempMRFile-cached.diff
281-
282-
echo -e "\n*** END LOCAL CHANGES ***\n"
283-
284-
if [[ ! -s "${TEMP}"/tempMRFile-cached.diff ]]; then
285-
# nothing needs to change, the MR is merged
286-
echo "nothing needs change" \
287-
| tee -a "$(results.fileUpdatesInfo.path)"
288-
echo -n "Success" |tee "$(results.fileUpdatesState.path)"
289-
exit 0
290-
fi
291-
292-
# Get all MRs by paginating through results
293-
page=1
294-
openMRList=""
295-
while true; do
296-
mrPage=$(glab mr list -R "${UPSTREAM_REPO}" --search "Konflux release" \
297-
--per-page 100 --page $page | grep "^!" || true)
298-
# add "$mrPage" == '' check for unit testing
299-
if [ -z "$mrPage" ] || [ "$mrPage" == '' ] ; then
300-
break
301-
fi
302-
openMRList="${openMRList}${mrPage}"$'\n'
303-
((page++))
304-
done
305-
306-
# Remove trailing newline
307-
openMRList=$(echo "$openMRList" | sed '/^$/d')
308-
309-
if [ -n "$openMRList" ]; then
310-
while IFS= read -r oneItem; do
311-
mrNum=$(echo "$oneItem" | cut -f1 | tr -d '!')
312-
git fetch origin merge-requests/"${mrNum}"/head:mr_"${mrNum}"
313-
314-
# compare if the cached content and the content in MR are the same
315-
git diff --cached mr_"${mrNum}" | tee "${TEMP}"/final.diff
316-
317-
if [[ ! -s "${TEMP}"/final.diff ]] ; then
318-
echo "There is an existing MR with the same updates in the repo"
319-
echo "{\"merge_request\":\"${UPSTREAM_REPO}/-/merge_requests/${mrNum}\"}" \
320-
| tee -a "$(results.fileUpdatesInfo.path)"
321-
echo -n "Success" | tee "$(results.fileUpdatesState.path)"
322-
exit 0
323-
fi
324-
done <<< "$openMRList"
325-
fi
326-
327-
WORKING_BRANCH=$(uuidgen |awk '{print substr($1, 1, 8)}')
328-
git_commit_and_push --branch "$WORKING_BRANCH" --message "fileUpdates changes"
329-
330-
echo "Creating Pull Request..."
331-
GITLAB_MR_MSG="[Konflux release] $(params.componentGroup): fileUpdates changes ${WORKING_BRANCH}"
332-
gitlab_create_mr --head "$WORKING_BRANCH" --target-branch "$REVISION" --title "${GITLAB_MR_MSG}" \
333-
--description "${GITLAB_MR_MSG}" --upstream-repo "${UPSTREAM_REPO}" | jq . \
334-
| tee -a "$(results.fileUpdatesInfo.path)"
335-
336-
echo -n "Success" |tee "$(results.fileUpdatesState.path)"
337-
338-
echo -e "=== FINISHED ===\n"
94+
- name: RESULT_FILE_UPDATES_INFO
95+
value: $(results.fileUpdatesInfo.path)
96+
- name: RESULT_FILE_UPDATES_STATE
97+
value: $(results.fileUpdatesState.path)
98+
- name: RESULT_INTERNAL_REQUEST_PIPELINE_RUN_NAME
99+
value: $(results.internalRequestPipelineRunName.path)
100+
- name: RESULT_INTERNAL_REQUEST_TASK_RUN_NAME
101+
value: $(results.internalRequestTaskRunName.path)
102+
command:
103+
- python3
104+
args:
105+
- /home/scripts/python/tasks/internal/process_file_updates.py
106+
- --upstream-repo
107+
- $(params.upstream_repo)
108+
- --repo
109+
- $(params.repo)
110+
- --ref
111+
- $(params.ref)
112+
- --paths
113+
- $(params.paths)
114+
- --component-group
115+
- $(params.componentGroup)
116+
- --internal-request-pipeline-run-name
117+
- $(params.internalRequestPipelineRunName)
118+
- --internal-request-task-run-name
119+
- $(context.taskRun.name)
120+
- --temp-dir
121+
- $(params.tempDir)

tasks/internal/process-file-updates-task/tests/mocks.sh

Lines changed: 0 additions & 68 deletions
This file was deleted.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
# Declarative mocks for Tekton tests of this task (Python entrypoint). Mock
3+
# binaries live under tests/mocks/ and are prepended to PATH at runtime.
4+
version: 1

0 commit comments

Comments
 (0)