Skip to content

Commit e400723

Browse files
spencerugbovepatel
andauthored
fix issues with the release docs workflow (#10315)
* fix issues with the release workflow and update tech specs json * add column count validation * update index.md text and remove unnecessary rows from tech-specs.json * add check to determine upgrade section title --------- Co-authored-by: Venktesh Patel <ve.patel@f5.com>
1 parent 57f43c8 commit e400723

6 files changed

Lines changed: 75 additions & 109 deletions

File tree

.github/scripts/pull-release-notes.py

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@
1111
# parse args
1212
parser = argparse.ArgumentParser()
1313
parser.add_argument("nic_version", help="NGINX Ingress Controller version")
14+
parser.add_argument("previous_version", help="Previous NGINX Ingress Controller version")
1415
parser.add_argument("helm_chart_version", help="NGINX Ingress Controller Helm chart version")
1516
parser.add_argument("k8s_versions", help="Kubernetes versions")
1617
parser.add_argument("release_date", help="Release date")
1718
args = parser.parse_args()
19+
OLD_VERSION = args.previous_version
1820
NIC_VERSION = args.nic_version
1921
HELM_CHART_VERSION = args.helm_chart_version
2022
K8S_VERSIONS = args.k8s_versions
@@ -103,9 +105,9 @@ def format_pr_groups(prs, title):
103105

104106
# Get release text
105107
def get_github_release(version, github_org, github_repo, token):
106-
if token == "":
108+
if not token:
107109
print("ERROR: GITHUB token variable cannot be empty")
108-
return None
110+
return None, None
109111
auth = Auth.Token(token)
110112
g = Github(auth=auth)
111113
repo = g.get_organization(github_org).get_repo(github_repo)
@@ -148,18 +150,28 @@ def get_pr_labels(repo, pr_number):
148150
# and format them accordingly
149151
categories = {}
150152
dependencies_title = ""
153+
go_dependencies = []
154+
docker_dependencies = []
151155
for title, changes in sections.items():
152-
if any(x in title for x in ["Other Changes", "Documentation", "Maintenance", "Tests"]):
156+
if any(x in title for x in ["Other Changes", "Documentation", "Maintenance", "Tests", "New Contributors"]):
153157
# These sections do not show up in the docs release notes
154158
continue
155159
parsed_changes = []
156-
go_dependencies = []
157-
docker_dependencies = []
158160
for line in changes:
159161
change = re.search(change_regex, line)
162+
if not change:
163+
print(f"WARNING: Skipping unrecognized line: {line}")
164+
continue
160165
change_title = change.group(1)
161166
pr_link = change.group(2)
162-
pr_number = re.search(pull_request_regex, pr_link).group(1)
167+
pr_links = re.findall(r"https://github\.com/\S+/pull/\d+", pr_link)
168+
if pr_links:
169+
pr_link = pr_links[-1]
170+
pr_match = re.search(pull_request_regex, pr_link)
171+
if not pr_match:
172+
print(f"WARNING: Could not extract PR number from: {pr_link}")
173+
continue
174+
pr_number = pr_match.group(1)
163175
pr = {"details": f"[{pr_number}]({pr_link})", "title": change_title.capitalize()}
164176
if "Dependencies" in title:
165177
# save section title for later use as lookup key to categories dict
@@ -216,6 +228,11 @@ def get_pr_labels(repo, pr_number):
216228
categories[dependencies_title].append(format_pr_groups(go_dependencies, "Bump Go dependencies"))
217229
categories[dependencies_title].reverse()
218230

231+
# Check if version is a patch release or a minor/major release
232+
old_version_parts = OLD_VERSION.split(".")
233+
new_version_parts = NIC_VERSION.split(".")
234+
is_upgrade = old_version_parts[0] != new_version_parts[0] or old_version_parts[1] != new_version_parts[1]
235+
219236
# Populates the data needed for rendering the template
220237
# The data will be passed to the Jinja2 template for rendering
221238
data = {
@@ -224,6 +241,7 @@ def get_pr_labels(repo, pr_number):
224241
"sections": categories,
225242
"HELM_CHART_VERSION": HELM_CHART_VERSION,
226243
"K8S_VERSIONS": K8S_VERSIONS,
244+
"upgrade_label": "Upgrade" if is_upgrade else "Update",
227245
}
228246

229247
# Render with Jinja2

.github/scripts/release-docs.sh

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ RELEASE_BRANCH_PREFIX=${RELEASE_BRANCH_PREFIX:-"nic-release-"}
1414
export GH_TOKEN=${GITHUB_TOKEN:-""}
1515

1616
usage() {
17-
echo "Usage: $0 <ic_version> <helm_chart_version> <operator_version> <k8s_versions> <nginx_version> <release_date> [<nap_waf_version>] [<nap_waf_release_version>]"
17+
echo "Usage: $0 <ic_version> <previous_version> <helm_chart_version> <operator_version> <k8s_versions> <nginx_version> <release_date> [<nap_waf_version>] [<nap_waf_release_version>]"
1818
exit 1
1919
}
2020

@@ -23,18 +23,23 @@ export GH_TOKEN=${GITHUB_TOKEN:-""}
2323

2424
DOCS_FOLDER=${TMPDIR}/documentation
2525
ic_version=$1
26-
helm_chart_version=$2
27-
operator_version=$3
28-
k8s_versions=$4
29-
nginx_version=$5
30-
release_date=$6
31-
NAP_WAF_VERSION=${7:-}
32-
NAP_WAF_RELEASE_VERSION=${8:-}
26+
previous_version=$2
27+
helm_chart_version=$3
28+
operator_version=$4
29+
k8s_versions=$5
30+
nginx_version=$6
31+
release_date=$7
32+
NAP_WAF_VERSION=${8:-}
33+
NAP_WAF_RELEASE_VERSION=${9:-}
3334

3435
if [ -z "${ic_version}" ]; then
3536
usage
3637
fi
3738

39+
if [ -z "${previous_version}" ]; then
40+
usage
41+
fi
42+
3843
if [ -z "${helm_chart_version}" ]; then
3944
usage
4045
fi
@@ -83,6 +88,7 @@ if [ "${DEBUG}" != "false" ]; then
8388
echo "DEBUG: GH_TOKEN: ****$(echo -n $GH_TOKEN | tail -c 4)"
8489
echo "DEBUG: DOCS_FOLDER: ${DOCS_FOLDER}"
8590
echo "DEBUG: ic_version: ${ic_version}"
91+
echo "DEBUG: previous_version: ${previous_version}"
8692
echo "DEBUG: helm_chart_version: ${helm_chart_version}"
8793
echo "DEBUG: operator_version: ${operator_version}"
8894
echo "DEBUG: k8s_versions: ${k8s_versions}"
@@ -93,7 +99,7 @@ if [ "${DEBUG}" != "false" ]; then
9399
fi
94100

95101
echo "INFO: Generating release notes from github draft release"
96-
release_notes_content=$("${ROOTDIR}"/.github/scripts/pull-release-notes.py "${ic_version}" "${helm_chart_version}" "${k8s_versions}" "${release_date}")
102+
release_notes_content=$("${ROOTDIR}"/.github/scripts/pull-release-notes.py "${ic_version}" "${previous_version}" "${helm_chart_version}" "${k8s_versions}" "${release_date}")
97103
if [ $? -ne 0 ]; then
98104
echo "ERROR: failed to fetch release notes from GitHub draft release for version ${ic_version}"
99105
exit 2
@@ -180,11 +186,11 @@ if [ "${DEBUG}" != "false" ] && [ -n "${current_year}" ]; then
180186
echo "DEBUG: Found year in header text: ${current_year}"
181187
fi
182188

183-
# Second: if that fails, look for year in release headings like "## 5.2.1"
189+
# Second: if that fails, look for year in release date entries
184190
if [ -z "${current_year}" ]; then
185-
current_year=$(grep -o "^## .*[0-9]\{4\}" "${index_file_path}" | grep -o "[0-9]\{4\}" | head -1)
191+
current_year=$(grep -oE "[0-9]{1,2} [A-Z][a-z]+ [0-9]{4}" "${index_file_path}" | grep -o "[0-9]\{4\}" | head -1)
186192
if [ "${DEBUG}" != "false" ] && [ -n "${current_year}" ]; then
187-
echo "DEBUG: Found year in release headings: ${current_year}"
193+
echo "DEBUG: Found year in release date entries: ${current_year}"
188194
fi
189195
fi
190196

@@ -329,6 +335,7 @@ if [ -n "${nginx_version}" ]; then
329335
# Run the consolidated tech specs update script (driven by tech-specs.json)
330336
python3 ${ROOTDIR}/.github/scripts/tech-specs-update.py \
331337
--json-file "${ROOTDIR}/.github/scripts/tech-specs.json" \
338+
--update-json \
332339
"${ic_version}" "${k8s_versions}" "${nginx_version}" "${DOCS_FOLDER}" \
333340
${NAP_WAF_VERSION:+"${NAP_WAF_VERSION}"}
334341

.github/scripts/release-notes.j2

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,12 @@
2828
{%- endif %}
2929
{%- endfor %}
3030

31-
### {{ '{{% icon download %}' }}{{ '}' }} Upgrade
31+
### {{ '{{% icon download %}' }}{{ '}' }} {{ upgrade_label }}
3232

33-
- For NGINX, use the {{ version }} images from our [DockerHub](https://hub.docker.com/r/nginx/nginx-ingress/tags?page=1&ordering=last_updated&name={{ version }}), [GitHub Container](https://github.com/nginx/kubernetes-ingress/pkgs/container/kubernetes-ingress), [Amazon ECR Public Gallery](https://gallery.ecr.aws/nginx/nginx-ingress) or [Quay.io](https://quay.io/repository/nginx/nginx-ingress).
34-
- For NGINX Plus, use the {{ version }} images from the F5 Container registry or build your own image using the {{ version }} source code.
33+
- For NGINX, use the {{ version }} images from [DockerHub](https://hub.docker.com/r/nginx/nginx-ingress/tags?page=1&ordering=last_updated&name={{ version }}), [GitHub Container](https://github.com/nginx/kubernetes-ingress/pkgs/container/kubernetes-ingress), [Amazon ECR Public Gallery](https://gallery.ecr.aws/nginx/nginx-ingress) or [Quay.io](https://quay.io/repository/nginx/nginx-ingress).
34+
- For NGINX Plus, use the {{ version }} images from the F5 Container registry or build your own image from the {{ version }} source code.
3535
- For Helm, use version {{ HELM_CHART_VERSION }} of the chart.
3636

3737
### {{ '{{% icon life-buoy %}' }}{{ '}' }} Supported platforms
3838

39-
We will provide technical support for NGINX Ingress Controller on any Kubernetes platform that is currently supported by its provider and that passes the Kubernetes conformance tests. This release was fully tested on the following Kubernetes versions: {{ K8S_VERSIONS }}.
39+
We provide technical support for NGINX Ingress Controller on any Kubernetes platform that is currently supported by its provider and that passes the Kubernetes conformance tests. This release was fully tested on the following Kubernetes versions: {{ K8S_VERSIONS }}.

.github/scripts/tech-specs-update.py

Lines changed: 14 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import json
2424
import re
2525
import sys
26-
from datetime import datetime
2726
from pathlib import Path
2827

2928
# ---------------------------------------------------------------------------
@@ -140,7 +139,7 @@ def update_nap_sc_row(sc_row, nap_waf_version):
140139
"""
141140
if nap_waf_version and "+" in nap_waf_version:
142141
new_prefix = nap_waf_version.split("+")[0]
143-
m = re.search(r"(\d+)\+", sc_row)
142+
m = re.search(r"(\d+(?:\.\d+)*)\+", sc_row)
144143
if m and m.group(1) != new_prefix:
145144
return sc_row.replace(m.group(1) + "+", new_prefix + "+", 1)
146145
return sc_row
@@ -171,56 +170,35 @@ def generate_compat_table_md(json_data, sc_row=None):
171170
used as-is to preserve original formatting. Otherwise a fresh shortcode
172171
row is generated from the JSON shortcode_row values.
173172
174-
Prunes rows past their End of Technical Support date, keeping the most
175-
recently expired row as a reference.
176173
"""
177174
sr = json_data["nic_k8s"]["shortcode_row"]
178175
rows = json_data["nic_k8s"]["rows"]
179176

177+
if sc_row is not None:
178+
col_count = len(sc_row.split("|")[1:-1])
179+
if col_count != 5:
180+
sc_row = None
181+
180182
header = (
181183
"| NIC version | Kubernetes versions tested "
182184
"| NIC Helm Chart version | NIC Operator version "
183-
"| NGINX / NGINX Plus version | End of Technical Support |"
185+
"| NGINX / NGINX Plus version |"
184186
)
185-
sep = "| --- | --- | --- | --- | --- | --- |"
187+
sep = "| --- | --- | --- | --- | --- |"
186188

187189
if sc_row is None:
188190
sc_row = (
189191
f"| {{{{< nic-version >}}}} | {sr['k8s_versions']} "
190192
f"| {{{{< nic-helm-version >}}}} | {{{{< nic-operator-version >}}}} "
191-
f"| {sr['nginx_version']} | - |"
193+
f"| {sr['nginx_version']} |"
192194
)
193195

194-
# EOTS pruning
195-
now = datetime.now()
196-
active_rows = []
197-
expired_rows = []
198-
for row in rows:
199-
eots = row.get("eots_date", "-")
200-
if eots and eots != "-":
201-
try:
202-
eots_date = datetime.strptime(eots, "%b %d, %Y")
203-
if now > eots_date:
204-
expired_rows.append((eots_date, row))
205-
continue
206-
except ValueError:
207-
# End of Technical Support value doesn't match expected date format — keep the row rather than pruning it.
208-
print(
209-
f"WARNING: Could not parse End of Technical Support date '{eots}' for NIC version '{row.get('nic_version', 'unknown')}', keeping row"
210-
)
211-
active_rows.append(row)
212-
213-
# Keep the most recently expired row as a migration reference
214-
if expired_rows:
215-
expired_rows.sort(key=lambda x: x[0], reverse=True)
216-
active_rows.append(expired_rows[0][1])
217-
218196
data_lines = []
219-
for row in active_rows:
197+
for row in rows:
220198
data_lines.append(
221199
f"| {row['nic_version']} | {row['k8s_versions']} "
222200
f"| {row['helm_version']} | {row['operator_version']} "
223-
f"| {row['nginx_version']} | {row['eots_date']} |"
201+
f"| {row['nginx_version']} |"
224202
)
225203

226204
return "\n".join([header, sep, sc_row] + data_lines)
@@ -303,14 +281,14 @@ def update_nginx_prose(md, nginx_new):
303281
if oss_match:
304282
current_oss = oss_match.group(1)
305283
if current_oss != new_oss:
306-
md = re.sub(r"\b" + re.escape(current_oss) + r"\b", new_oss, md)
284+
md = re.sub(r"\b" + re.escape(current_oss) + r"(?!\.?\d)", new_oss, md)
307285

308286
if new_plus:
309-
plus_match = re.search(r"NGINX Plus images include NGINX Plus (R\d+(?:\s+P\d+)?)", md)
287+
plus_match = re.search(r"NGINX Plus images include NGINX Plus (R\d+(?:\.\d+)*(?:\s+P\d+)?)", md)
310288
if plus_match:
311289
current_plus = plus_match.group(1)
312290
if current_plus != new_plus:
313-
md = re.sub(r"\b" + re.escape(current_plus) + r"\b", new_plus, md)
291+
md = re.sub(r"\b" + re.escape(current_plus) + r"(?!\.?\d)", new_plus, md)
314292

315293
return md
316294

@@ -340,7 +318,6 @@ def freeze_compat_row(json_data, current_nic, current_helm, current_operator):
340318
"helm_version": current_helm,
341319
"operator_version": current_operator,
342320
"nginx_version": sr["nginx_version"],
343-
"eots_date": "-",
344321
}
345322
json_data["nic_k8s"]["rows"].insert(0, frozen)
346323
print(f"INFO: Frozen compat row for {current_nic}")

0 commit comments

Comments
 (0)