Skip to content

Commit 27e3e36

Browse files
authored
fix: generate changelog script (#785)
1 parent 139bfaa commit 27e3e36

File tree

1 file changed

+116
-49
lines changed

1 file changed

+116
-49
lines changed

.github/workflows/scripts/generate-changelog.sh

Lines changed: 116 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -87,18 +87,28 @@ find . -type d -name '[!.]*' -exec test -e "{}/Chart.yaml" ';' -print | while re
8787
done
8888

8989
# Checkout out last release tag and extract repository name and tag in its all values.yaml files
90-
git stash
91-
git switch --detach $last_release_tag
92-
find . -type d -name '[!.]*' -exec test -e "{}/Chart.yaml" ';' -print | while read chart_dir; do
93-
base_chart_dir=$(echo $chart_dir | cut -d'/' -f2)
94-
if [[ ! " ${excluded_charts[@]} " =~ " ${base_chart_dir} " ]]; then
95-
helm show values "$chart_dir" | grep -E 'repository:|tag:' | awk '{print $1 $2}' >> "${dir}/tags/last-release-tags.log"
96-
fi
90+
# Extract CURRENT tags from the current working tree
91+
find . -type d -name '[!.]*' -exec test -e "{}/Chart.yaml" ';' -print | while read -r chart_dir; do
92+
base_chart_dir=$(echo "$chart_dir" | cut -d'/' -f2)
93+
if [[ ! " ${excluded_charts[*]} " =~ " ${base_chart_dir} " ]]; then
94+
helm show values "$chart_dir" | grep -E 'repository:|tag:' | awk '{print $1 $2}' >> "${dir}/tags/current-tags.log"
95+
fi
9796
done
9897

99-
# Checkout back to current branch
100-
git checkout $current_branch
101-
git stash pop
98+
# Extract LAST RELEASE tags using a temporary git worktree
99+
last_release_wt="${dir}/worktrees/last-release"
100+
mkdir -p "${dir}/worktrees"
101+
git worktree add -f "$last_release_wt" "$last_release_tag" >/dev/null
102+
103+
find "$last_release_wt" -type d -name '[!.]*' -exec test -e "{}/Chart.yaml" ';' -print | while read -r chart_dir; do
104+
rel="${chart_dir#${last_release_wt}/}"
105+
base_chart_dir=$(echo "$rel" | cut -d'/' -f1)
106+
if [[ ! " ${excluded_charts[*]} " =~ " ${base_chart_dir} " ]]; then
107+
helm show values "$chart_dir" | grep -E 'repository:|tag:' | awk '{print $1 $2}' >> "${dir}/tags/last-release-tags.log"
108+
fi
109+
done
110+
111+
git worktree remove -f "$last_release_wt" >/dev/null
102112

103113
# accept all stashed changes
104114
# git stash list | awk -F: '{print $1}' | xargs -n 1 git stash apply
@@ -108,50 +118,107 @@ git stash pop
108118
# The associative arrays are indexed by the repository name and the value is the tag
109119
# We then iterate through the associative arrays and generate the changelog for each repository that has changed
110120

111-
# Read last release tags into associative array 'last_release_tags'
112-
while IFS= read -r line
113-
do
114-
if [[ $line == *"repository:"* ]]
115-
then
116-
repository=$(echo $line | cut -d':' -f2 | cut -d' ' -f1)
117-
last_release_tags[$repository]=null
118-
fi
119-
120-
if [[ $line == *"tag:"* ]]
121-
then
122-
tag=$(echo $line | cut -d':' -f2)
123-
last_release_tags[$repository]=$tag
124-
fi
121+
# Trim leading/trailing whitespace (pure bash, no xargs)
122+
trim() {
123+
local s="$1"
124+
s="${s#"${s%%[![:space:]]*}"}" # leading
125+
s="${s%"${s##*[![:space:]]}"}" # trailing
126+
printf '%s' "$s"
127+
}
128+
############################################
129+
# Read last release tags into associative array 'last_release_tags'
130+
############################################
131+
while IFS= read -r line; do
132+
if [[ $line == repository:* ]]; then
133+
repository="$(trim "${line#repository:}")"
134+
last_release_tags["$repository"]=null
135+
136+
elif [[ $line == tag:* ]]; then
137+
tag="$(trim "${line#tag:}")"
138+
last_release_tags["$repository"]="$tag"
139+
fi
125140
done < "$dir/tags/last-release-tags.log"
126141

142+
############################################
127143
# Read current tags into associative array 'current_tags'
128-
while IFS= read -r line
129-
do
130-
if [[ $line == *"repository:"* ]]
131-
then
132-
repository=$(echo $line | cut -d':' -f2 | cut -d' ' -f1)
133-
current_tags[$repository]=null
134-
fi
135-
136-
if [[ $line == *"tag:"* ]]
137-
then
138-
tag=$(echo $line | cut -d':' -f2)
139-
current_tags[$repository]=$tag
140-
fi
144+
############################################
145+
while IFS= read -r line; do
146+
if [[ $line == repository:* ]]; then
147+
repository="$(trim "${line#repository:}")"
148+
current_tags["$repository"]=null
149+
150+
elif [[ $line == tag:* ]]; then
151+
tag="$(trim "${line#tag:}")"
152+
current_tags["$repository"]="$tag"
153+
fi
141154
done < "$dir/tags/current-tags.log"
142155

143-
# Generate changelog for each mojaloop repository that has changed using github api
144-
for repository in "${!last_release_tags[@]}"
145-
do
146-
if [[ $repository == mojaloop* && ${current_tags[$repository]} && ${last_release_tags[$repository]} != ${current_tags[$repository]} ]]
147-
then
148-
repository_short_name=$(echo $repository | cut -d'/' -f2)
149-
curl -s -L \
150-
-H "Accept: application/vnd.github+json" \
151-
-H "Authorization: Bearer $AUTO_RELEASE_TOKEN" \
152-
-H "X-GitHub-Api-Version: 2022-11-28" \
153-
https://api.github.com/repos/$repository/compare/${last_release_tags[$repository]}...${current_tags[$repository]} > $dir/changelogs/$repository_short_name.json
154-
fi
156+
echo "DEBUG: last_release_tags entries = ${#last_release_tags[@]}"
157+
echo "DEBUG: current_tags entries = ${#current_tags[@]}"
158+
159+
echo "DEBUG: sample last_release_tags:"
160+
for k in "${!last_release_tags[@]}"; do echo " $k => ${last_release_tags[$k]}"; break; done
161+
echo "DEBUG: sample current_tags:"
162+
for k in "${!current_tags[@]}"; do echo " $k => ${current_tags[$k]}"; break; done
163+
############################################
164+
# Generate changelog for repos that changed
165+
############################################
166+
167+
is_bad_ref() {
168+
local ref="$1"
169+
ref="$(trim "$ref")"
170+
171+
# empty / null
172+
[[ -z "$ref" || "$ref" == "null" ]] && return 0
173+
174+
# obvious templating or quoting artifacts
175+
[[ "$ref" == *"{{"* || "$ref" == *"}}"* || "$ref" == *"{"* || "$ref" == *"}"* ]] && return 0
176+
[[ "$ref" == *"\""* || "$ref" == *"'"* ]] && return 0
177+
178+
# whitespace inside ref is suspicious for URLs
179+
[[ "$ref" =~ [[:space:]] ]] && return 0
180+
181+
return 1
182+
}
183+
184+
for repository in "${!last_release_tags[@]}"; do
185+
last="${last_release_tags[$repository]}"
186+
curr="${current_tags[$repository]}"
187+
188+
echo "DEBUG repo=[$repository] last=[$last] curr=[$curr]"
189+
190+
# Only Mojaloop GitHub repos in owner/repo form
191+
if [[ "$repository" != mojaloop/* ]]; then
192+
continue
193+
fi
194+
195+
# Need both refs and must be different
196+
if is_bad_ref "$last" || is_bad_ref "$curr"; then
197+
echo "WARN: skipping $repository due to bad ref(s): last=[$last] curr=[$curr]" >&2
198+
continue
199+
fi
200+
201+
if [[ "$last" == "$curr" ]]; then
202+
continue
203+
fi
204+
205+
repository_short_name="$(echo "$repository" | cut -d'/' -f2)"
206+
out="$dir/changelogs/$repository_short_name.json"
207+
208+
url="https://api.github.com/repos/$repository/compare/${last}...${curr}"
209+
210+
# Do not let a single repo failure kill the whole script
211+
http_code="$(curl -sS -L -o "$out" -w "%{http_code}" \
212+
-H "Accept: application/vnd.github+json" \
213+
-H "Authorization: Bearer $AUTO_RELEASE_TOKEN" \
214+
-H "X-GitHub-Api-Version: 2022-11-28" \
215+
"$url" || true)"
216+
217+
if [[ "$http_code" != "200" ]]; then
218+
echo "WARN: compare failed for $repository ($http_code) url=$url" >&2
219+
rm -f "$out"
220+
continue
221+
fi
155222
done
156223

157224
echo "Changelog generated successfully."

0 commit comments

Comments
 (0)