Skip to content

Commit ea7f372

Browse files
committed
add logic to link releases with breaking changes
1 parent a821678 commit ea7f372

File tree

2 files changed

+141
-2
lines changed

2 files changed

+141
-2
lines changed

.github/workflows/nightly-build.yml

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,14 @@ jobs:
4141
python-version: '3.11'
4242

4343
- name: Install Python dependencies
44-
run: pip install requests
44+
run: pip install requests packaging
45+
46+
- name: Generate breaking changes summary
47+
id: breaking_changes
48+
run: |
49+
echo "BREAKING_CHANGES<<EOF" >> $GITHUB_OUTPUT
50+
python3 scripts/find_breaking_changes.py
51+
echo "EOF" >> $GITHUB_OUTPUT
4552
4653
- name: Update dependencies
4754
run: python3 scripts/update_dependencies.py
@@ -60,11 +67,25 @@ jobs:
6067
git commit -m "chore: update OpenTelemetry dependencies to latest versions"
6168
git push origin "$BRANCH_NAME"
6269
70+
- name: Create or update PR
71+
if: steps.check_changes.outputs.has_changes == 'true'
72+
run: |
73+
PR_BODY="Automated update of OpenTelemetry dependencies to their latest available versions.
74+
75+
**Upstream releases with breaking changes:**
76+
${{ steps.breaking_changes.outputs.BREAKING_CHANGES }}"
77+
78+
if gh pr view "$BRANCH_NAME" --json state --jq '.state' 2>/dev/null | grep -q "OPEN"; then
79+
echo "Open PR already exists, updating description..."
80+
gh pr edit "$BRANCH_NAME" --body "$PR_BODY"
81+
else
82+
echo "Creating new PR..."
6383
gh pr create \
6484
--title "Nightly dependency update: OpenTelemetry packages to latest versions" \
65-
--body "Automated update of OpenTelemetry dependencies to their latest available versions." \
85+
--body "$PR_BODY" \
6686
--base main \
6787
--head "$BRANCH_NAME"
6888
fi
89+
fi
6990
env:
7091
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

scripts/find_breaking_changes.py

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
#!/usr/bin/env python3
2+
3+
import re
4+
import requests
5+
import sys
6+
from packaging import version
7+
8+
9+
def get_current_versions():
10+
"""Get current versions from build.gradle.kts."""
11+
try:
12+
with open("dependencyManagement/build.gradle.kts", "r", encoding="utf-8") as file:
13+
content = file.read()
14+
15+
# Extract otelVersion
16+
otel_version_match = re.search(r'val otelVersion = "([^"]*)"', content)
17+
current_instrumentation_version = otel_version_match.group(1) if otel_version_match else None
18+
19+
return current_instrumentation_version
20+
21+
except (OSError, IOError) as error:
22+
print(f"Error reading current versions: {error}")
23+
return None
24+
25+
26+
def get_releases_with_breaking_changes(repo, current_version, new_version):
27+
"""Get releases between current and new version that mention breaking changes."""
28+
try:
29+
response = requests.get(f"https://api.github.com/repos/open-telemetry/{repo}/releases", timeout=30)
30+
response.raise_for_status()
31+
releases = response.json()
32+
33+
breaking_releases = []
34+
35+
for release in releases:
36+
try:
37+
tag_name = release["tag_name"]
38+
release_version = tag_name.lstrip("v")
39+
40+
# Check if this release is between current and new version
41+
if (
42+
version.parse(current_version)
43+
< version.parse(release_version)
44+
<= version.parse(new_version)
45+
):
46+
47+
# Check if release notes have breaking changes as headers
48+
body = release.get("body", "")
49+
breaking_header_pattern = r'^#+.*breaking changes'
50+
if re.search(breaking_header_pattern, body, re.IGNORECASE | re.MULTILINE):
51+
breaking_releases.append(
52+
{
53+
"version": release_version,
54+
"name": release["name"],
55+
"url": release["html_url"],
56+
"body": release.get("body", ""),
57+
}
58+
)
59+
except (ValueError, KeyError):
60+
# Skip releases with invalid version formats or missing data
61+
continue
62+
63+
return breaking_releases
64+
65+
except requests.RequestException as request_error:
66+
print(f"Warning: Could not get releases for {repo}: {request_error}")
67+
return []
68+
69+
70+
def main():
71+
current_instrumentation_version = get_current_versions()
72+
73+
if not current_instrumentation_version:
74+
print("Could not determine current versions")
75+
sys.exit(1)
76+
77+
# Get new versions from the update script
78+
sys.path.append('scripts')
79+
from update_dependencies import get_latest_instrumentation_version, get_latest_contrib_version
80+
81+
new_instrumentation_version = get_latest_instrumentation_version()
82+
new_contrib_version = get_latest_contrib_version()
83+
84+
if not new_instrumentation_version:
85+
print("Could not determine new versions")
86+
sys.exit(1)
87+
88+
print("Checking for breaking changes:")
89+
print(f"Instrumentation: {current_instrumentation_version}{new_instrumentation_version}")
90+
if new_contrib_version:
91+
print(f"Contrib: → {new_contrib_version}")
92+
93+
# Check instrumentation repo for breaking changes
94+
instrumentation_breaking = get_releases_with_breaking_changes(
95+
"opentelemetry-java-instrumentation", current_instrumentation_version, new_instrumentation_version
96+
)
97+
98+
# Generate breaking changes summary
99+
breaking_changes_summary = []
100+
101+
if instrumentation_breaking:
102+
breaking_changes_summary.append("**Breaking changes found in opentelemetry-java-instrumentation:**")
103+
for release in instrumentation_breaking:
104+
breaking_changes_summary.append(f"- [{release['name']}]({release['url']})")
105+
106+
# Always add contrib release link (no breaking changes detection needed)
107+
if new_contrib_version:
108+
breaking_changes_summary.append("**Check contrib releases:**")
109+
breaking_changes_summary.append("- [opentelemetry-java-contrib releases](https://github.com/open-telemetry/opentelemetry-java-contrib/releases)")
110+
111+
if breaking_changes_summary:
112+
print("\n" + "\n".join(breaking_changes_summary))
113+
else:
114+
print("\nNo breaking changes detected")
115+
116+
117+
if __name__ == "__main__":
118+
main()

0 commit comments

Comments
 (0)