7777echo " INFO: Generating release notes from github draft release"
7878release_notes_content=$( ${ROOTDIR} /.github/scripts/pull-release-notes.py ${ic_version} ${helm_chart_version} ${k8s_versions} " ${release_date} " )
7979if [ $? -ne 0 ]; then
80- echo " ERROR: failed processing release notes"
80+ echo " ERROR: failed to fetch release notes from GitHub draft release for version ${ic_version} "
8181 exit 2
8282fi
8383
@@ -86,6 +86,9 @@ if [ -z "${release_notes_content}" ]; then
8686 exit 2
8787fi
8888
89+ # Fix HTML entity encoding issues that happen when converting github draft to .md
90+ release_notes_content=$( echo " ${release_notes_content} " | sed ' s/&/\&/g' | sed ' s/</</g' | sed ' s/>/>/g' | sed ' s/"/"/g' | sed ' s/"/"/g' )
91+
8992if [ " ${DEBUG} " != " false" ]; then
9093 echo " DEBUG: Release notes content:"
9194 echo " ${release_notes_content} "
@@ -113,10 +116,10 @@ if [ "${DEBUG}" != "false" ]; then
113116 echo " DEBUG: Cloned doc repo to ${DOCS_FOLDER} and changed directory"
114117fi
115118
116- # generate branch name
119+ # Generate branch name using major.minor version (e.g., nic-release-5.2)
117120branch=${RELEASE_BRANCH_PREFIX}${ic_version% .* }
118121if [ " ${DEBUG} " != " false" ]; then
119- echo " DEBUG: Generating branch ${branch} "
122+ echo " DEBUG: Generated branch name: ${branch} (from version ${ic_version} ) "
120123fi
121124
122125echo " INFO: Checking out branch ${branch} in the documentation repository"
@@ -125,29 +128,173 @@ remote_branch=$(git ls-remote --heads origin ${branch} 2> /dev/null)
125128if [ -n " ${remote_branch} " ]; then
126129 git checkout ${branch}
127130 if [ " ${DEBUG} " != " false" ]; then
128- echo " DEBUG: Checked out branch ${branch} "
131+ echo " DEBUG: Checked out existing branch ${branch} "
129132 fi
130133else
131134 git checkout -b ${branch}
132135 if [ " ${DEBUG} " != " false" ]; then
133- echo " DEBUG: Created branch ${branch} "
136+ echo " DEBUG: Created new branch ${branch} "
134137 fi
135138fi
136139
137- echo " INFO: Adding release notes content to release.md in the documentation repository"
138- file_path=${DOCS_FOLDER} /content/nic/releases.md
140+ # Extract year from release date
141+ release_year=$( date -j -f " %d %b %Y" " ${release_date} " " +%Y" 2> /dev/null || date -d " ${release_date} " " +%Y" 2> /dev/null)
142+
143+ if [ -z " ${release_year} " ]; then
144+ echo " ERROR: failed to parse release year from date: ${release_date} "
145+ exit 2
146+ fi
147+
148+ # Determine what year the current _index.md represents
149+ index_file_path=${DOCS_FOLDER} /content/nic/changelog/_index.md
150+
139151if [ " ${DEBUG} " != " false" ]; then
140- echo " DEBUG: Processing ${file_path} "
141- fi
142- file_name=$( basename " ${file_path} " )
143- mv " ${file_path} " " ${TMPDIR} /${file_name} "
144- head -n 8 " ${TMPDIR} /${file_name} " > " ${TMPDIR} /header"
145- tail -n +9 " ${TMPDIR} /${file_name} " > " ${TMPDIR} /body"
146- echo " ${release_notes_content} " > " ${TMPDIR} /release_notes"
147- cat " ${TMPDIR} /header" " ${TMPDIR} /release_notes" " ${TMPDIR} /body" > " ${file_path} "
152+ echo " DEBUG: Attempting to detect current changelog year from ${index_file_path} "
153+ fi
154+
155+ # First: look for "releases in 2025" in the header
156+ current_year=$( grep " releases in" " ${index_file_path} " | grep -o " [0-9]\{4\}" | head -1)
157+ if [ " ${DEBUG} " != " false" ] && [ -n " ${current_year} " ]; then
158+ echo " DEBUG: Found year in header text: ${current_year} "
159+ fi
160+
161+ # Second: if that fails, look for year in release headings like "## 5.2.1"
162+ if [ -z " ${current_year} " ]; then
163+ current_year=$( grep -o " ^## .*[0-9]\{4\}" " ${index_file_path} " | grep -o " [0-9]\{4\}" | head -1)
164+ if [ " ${DEBUG} " != " false" ] && [ -n " ${current_year} " ]; then
165+ echo " DEBUG: Found year in release headings: ${current_year} "
166+ fi
167+ fi
168+
169+ # Third: if both fail, assume it's the previous year as a safe fallback
170+ if [ -z " ${current_year} " ]; then
171+ current_year=$(( release_year - 1 ))
172+ if [ " ${DEBUG} " != " false" ]; then
173+ echo " DEBUG: No year found in changelog, using fallback: ${current_year} "
174+ fi
175+ fi
176+
177+ if [ " ${DEBUG} " != " false" ]; then
178+ echo " DEBUG: Current index year: ${current_year} , Release year: ${release_year} "
179+ fi
180+
181+ # Compare release year vs current index year
182+ # If different years: archive current year's releases and create new index
183+ # If same year: just add to existing index
184+ if [ " ${release_year} " != " ${current_year} " ]; then
185+ # New year - archive current year and start fresh
186+ echo " INFO: New year detected (${release_year} ). Archiving ${current_year} and creating new index."
187+
188+ # Create archive file with Hugo frontmatter for the current year's releases
189+ archive_file=${DOCS_FOLDER} /content/nic/changelog/${current_year} .md
190+ cp " ${index_file_path} " " ${TMPDIR} /temp_index.md"
191+
192+ # Update weights in existing archive files (bump each by 100 to make room for new archive at 100)
193+ if [ " ${DEBUG} " != " false" ]; then
194+ echo " DEBUG: Updating weights in existing archive files"
195+ fi
196+ for existing_archive in ${DOCS_FOLDER} /content/nic/changelog/[0-9][0-9][0-9][0-9].md; do
197+ if [ -f " ${existing_archive} " ]; then
198+ # Extract current weight and add 100
199+ current_weight=$( grep " ^weight:" " ${existing_archive} " | sed ' s/^weight:[[:space:]]*//' )
200+ new_weight=$(( current_weight + 100 ))
201+ sed -i.bak " s/^weight: *${current_weight} /weight: ${new_weight} /" " ${existing_archive} "
202+ rm -f " ${existing_archive} .bak"
203+ if [ " ${DEBUG} " != " false" ]; then
204+ echo " DEBUG: Updated $( basename " ${existing_archive} " ) weight from ${current_weight} to ${new_weight} "
205+ fi
206+ fi
207+ done
208+
209+ # Create archive with frontmatter
210+ cat > " ${archive_file} " << EOF
211+ ---
212+ title: "${current_year} archive"
213+ # Weights are assigned in increments of 100: determines sorting order
214+ weight: 100
215+ # Creates a table of contents and sidebar, useful for large documents
216+ toc: true
217+ # Types have a 1:1 relationship with Hugo archetypes, so you shouldn't need to change this
218+ nd-content-type: reference
219+ nd-product: INGRESS
220+ ---
221+
222+ EOF
223+
224+ # Find where releases start (first "## " heading) and copy everything after that
225+ # This skips the frontmatter and intro text, keeping only actual release entries
226+ release_start=$( grep -n " ^## " " ${TMPDIR} /temp_index.md" | head -1 | cut -d: -f1)
227+ if [ " ${DEBUG} " != " false" ]; then
228+ echo " DEBUG: Release content starts at line: ${release_start:- ' not found' } "
229+ fi
230+ [ -n " ${release_start} " ] && tail -n +${release_start} " ${TMPDIR} /temp_index.md" >> " ${archive_file} "
231+
232+ # Create new index for new year
233+ echo " INFO: Creating new _index.md for year ${release_year} "
234+
235+ # Extract header content (everything before the newest release) and update year references
236+ if [ " ${DEBUG} " != " false" ]; then
237+ echo " DEBUG: Extracting header and updating year references from ${current_year} to ${release_year} "
238+ fi
239+
240+ if [ -n " ${release_start} " ]; then
241+ # Extract everything before the newest release heading
242+ head -n $(( release_start - 1 )) " ${TMPDIR} /temp_index.md"
243+ else
244+ # No releases found, extract most of the file (excluding footer)
245+ head -n $(( $(wc - l < "${TMPDIR} / temp_index.md") - 3 )) " ${TMPDIR} /temp_index.md"
246+ fi | sed " s/${current_year} /${release_year} /g" | awk -v archived_year=" ${current_year} " '
247+ # Add the archived year to the "previous years" link list
248+ /For older releases, check the changelogs for previous years:/ {
249+ # Insert the archived year at the beginning
250+ sub(/For older releases, check the changelogs for previous years: /, "For older releases, check the changelogs for previous years: [" archived_year "]({{< ref \"/nic/changelog/" archived_year ".md\" >}}), ")
251+ }
252+ { print }
253+ ' > " ${TMPDIR} /new_header.md"
254+
255+ # Assemble new index file: header + new release notes
256+ if [ " ${DEBUG} " != " false" ]; then
257+ echo " DEBUG: Assembling new _index.md with header and new release notes"
258+ fi
259+ cat " ${TMPDIR} /new_header.md" > " ${index_file_path} "
260+ echo " " >> " ${index_file_path} "
261+ echo " ${release_notes_content} " >> " ${index_file_path} "
262+
263+ else
264+ # Same year - add to existing changelog
265+ echo " INFO: Adding release notes to existing changelog/_index.md for year ${release_year} "
266+
267+ # Find where to insert new release notes in existing changelog
268+ # Look for first release heading ("## ") or fallback to after compatibility matrix
269+ cp " ${index_file_path} " " ${TMPDIR} /temp_index.md"
270+ insert_line=$( grep -n " ^## " " ${TMPDIR} /temp_index.md" | head -1 | cut -d: -f1)
271+
272+ if [ -z " ${insert_line} " ]; then
273+ # No existing releases found, insert after the compatibility matrix
274+ if [ " ${DEBUG} " != " false" ]; then
275+ echo " DEBUG: No existing releases found, looking for {{< /details >}} tag"
276+ fi
277+ insert_line=$( grep -n " {{< /details >}}" " ${TMPDIR} /temp_index.md" | tail -1 | cut -d: -f1)
278+ [ -n " ${insert_line} " ] && insert_line=$(( insert_line + 2 )) || insert_line=8
279+ fi
280+
281+ if [ " ${DEBUG} " != " false" ]; then
282+ echo " DEBUG: Will insert new release at line ${insert_line} "
283+ fi
284+
285+ # Reconstruct the file: header + new release + existing releases
286+ # This inserts the new release at the top of the releases section
287+ head -n $(( insert_line - 1 )) " ${TMPDIR} /temp_index.md" > " ${TMPDIR} /final_index.md"
288+ echo " " >> " ${TMPDIR} /final_index.md"
289+ echo " ${release_notes_content} " >> " ${TMPDIR} /final_index.md"
290+ echo " " >> " ${TMPDIR} /final_index.md"
291+ tail -n +${insert_line} " ${TMPDIR} /temp_index.md" >> " ${TMPDIR} /final_index.md"
292+
293+ mv " ${TMPDIR} /final_index.md" " ${index_file_path} "
294+ fi
295+
148296if [ $? -ne 0 ]; then
149- echo " ERROR: failed processing ${file_path} "
150- mv " ${TMPDIR} /${file_name} " " ${file_path} "
297+ echo " ERROR: failed processing changelog files"
151298 exit 2
152299fi
153300
@@ -158,20 +305,21 @@ if [ $? -ne 0 ]; then
158305 exit 2
159306fi
160307
161- echo " INFO: Committing changes to the documentation repository "
308+ echo " INFO: Staging changes for commit "
162309git add -A
163310if [ $? -ne 0 ]; then
164311 echo " ERROR: failed adding files to git"
165312 exit 2
166313fi
167314
168- git commit -m " Update release notes for ${ic_version} "
169- if [ $? -ne 0 ]; then
170- echo " ERROR: failed committing changes to the docs repo"
171- exit 2
172- fi
173-
174315if [ " ${DRY_RUN} " == " false" ]; then
316+ echo " INFO: Committing changes to the documentation repository"
317+ git commit -m " Update release notes for ${ic_version} "
318+ if [ $? -ne 0 ]; then
319+ echo " ERROR: failed committing changes to the docs repo"
320+ exit 2
321+ fi
322+
175323 echo " INFO: Pushing changes to the documentation repository"
176324 git push origin ${branch}
177325 if [ $? -ne 0 ]; then
@@ -181,7 +329,9 @@ if [ "${DRY_RUN}" == "false" ]; then
181329 echo " INFO: Creating pull request for the documentation repository"
182330 gh pr create --title " Update release notes for ${ic_version} " --body " Update release notes for ${ic_version} " --head ${branch} --draft
183331else
184- echo " INFO: DRY_RUN: Skipping push and pull request creation"
332+ echo " INFO: DRY_RUN: Showing what would be committed:"
333+ git status --porcelain
334+ echo " INFO: DRY_RUN: Skipping commit, push and pull request creation"
185335fi
186336
187337if [ " ${DEBUG} " != " false" ]; then
@@ -191,7 +341,9 @@ cd - > /dev/null 2>&1
191341
192342if [ " ${TIDY} " == " true" ]; then
193343 echo " INFO: Clean up"
194- rm -rf " ${TMPDIR} /header" " ${TMPDIR} /body" " ${TMPDIR} /release_notes" " ${DOCS_FOLDER} "
344+ rm -rf " ${TMPDIR} /temp_index.md" " ${TMPDIR} /final_index.md" " ${TMPDIR} /current_index.md" " ${TMPDIR} /new_header.md" " ${DOCS_FOLDER} "
345+ else
346+ echo " INFO: Skipping tidy (docs folder: ${DOCS_FOLDER} )"
195347fi
196348
197349exit 0
0 commit comments