Skip to content

Instantly share code, notes, and snippets.

@SteveBronder
Created March 19, 2025 14:31
Show Gist options
  • Save SteveBronder/9da83f49f27100e266a202f811bb7e1f to your computer and use it in GitHub Desktop.
Save SteveBronder/9da83f49f27100e266a202f811bb7e1f to your computer and use it in GitHub Desktop.
import requests
import datetime
import csv
# Function to get the release date for a given tag (e.g., "3.4.0")
def get_release_date(tag="3.4.0"):
releases_url = "https://gitlab.com/api/v4/projects/libeigen%2Feigen/releases"
response = requests.get(releases_url)
if response.status_code == 200:
releases = response.json()
for release in releases:
if release.get("tag_name") == tag:
release_date = release.get("released_at")
if release_date:
# Remove the trailing 'Z' if present and convert to datetime
return datetime.datetime.fromisoformat(release_date.rstrip("Z"))
return None
# Function to fetch all merged merge requests from the repository using pagination
def fetch_merge_requests():
merge_requests = []
api_url = "https://gitlab.com/api/v4/projects/libeigen%2Feigen/merge_requests"
page = 1
per_page = 100
while True:
params = {
'state': 'merged',
'per_page': per_page,
'page': page,
'order_by': 'merged_at',
'sort': 'asc' # Sorting in ascending order so older MRs come first
}
response = requests.get(api_url, params=params)
if response.status_code != 200:
print("Error fetching merge requests:", response.status_code)
break
page_data = response.json()
if not page_data:
break # No more pages
merge_requests.extend(page_data)
page += 1
return merge_requests
def main():
release_tag = "3.4.0"
release_date = get_release_date(release_tag)
if release_date is None:
print(f"Could not determine release date for tag {release_tag}. Exiting.")
return
print(f"Release {release_tag} date: {release_date.isoformat()}")
mrs = fetch_merge_requests()
print(f"Total merged MRs: {len(mrs)}")
filtered_mrs = []
for mr in mrs:
merged_at_str = mr.get("merged_at")
if merged_at_str:
merged_at = datetime.datetime.fromisoformat(merged_at_str.rstrip("Z"))
# Only include merge requests merged after the release date
if merged_at > release_date:
# Extract key pieces of information; default to "NA" if missing.
mr_id = mr.get("iid", "NA")
link = mr.get("web_url", "NA")
title = mr.get("title", "NA")
description = mr.get("description", "NA")
if isinstance(description, str):
description = description.strip() or "NA"
author = mr.get("author", {}).get("name", "NA")
merged_date = merged_at_str or "NA"
labels = mr.get("labels", [])
labels_str = ", ".join(labels) if labels else "NA"
# Impacted Areas/Components is not directly available via the API, so we default to "NA"
impacted_areas = "NA"
filtered_mrs.append({
"mr_id_link": f"{mr_id} ({link})",
"title_subject": title,
"description_summary": description,
"author": author,
"merge_date": merged_date,
"category_labels": labels_str,
"impacted_areas_components": impacted_areas
})
# Write the collected data to a CSV file.
output_file = "eigen_release_notes.csv"
fieldnames = ["mr_id_link", "title_subject", "description_summary", "author", "merge_date", "category_labels", "impacted_areas_components"]
try:
with open(output_file, "w", newline='', encoding="utf-8") as csvfile:
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
for row in filtered_mrs:
writer.writerow(row)
print(f"Release notes saved to {output_file}")
except Exception as e:
print("Error writing CSV file:", e)
if __name__ == "__main__":
main()
import openai
import csv
import os
# Set your API key for the model provider
api_key = os.environ['OPENAI_API_KEY']
client = openai.OpenAI(api_key=api_key)
def summarize_merge_request(mr):
# Construct the instructions (prompt) for the summarization.
instructions = (
"You are a summarization assistant. Summarize the following merge request "
"for the Eigen C++ library. Focus on the key changes, improvements, and their impact. "
"If any field is marked as NA, do not include it in the summary.\n\n"
"The summary should be in the form and have the sections as follows:\n"
"## Title: \n"
"## Authors: \n"
"## Summary:\n"
"### Key Changes:\n"
"### Improvements:\n"
"### Impact:\n")
input = (f"Title: {mr.get('title_subject', 'NA')}\n"
f"Description: {mr.get('description_summary', 'NA')}\n"
f"Author: {mr.get('author', 'NA')}\n"
f"Merge Date: {mr.get('merge_date', 'NA')}\n"
f"Labels: {mr.get('category_labels', 'NA')}\n"
f"Impacted Areas: {mr.get('impacted_areas_components', 'NA')}\n\n")
# Use the new API call with the gpt-4o-mini model.
response = client.responses.create(
model="gpt-4o-mini",
instructions=instructions,
input=input # No additional input is needed.
)
summary = response.output_text.strip()
return summary
def main():
input_csv = "eigen_release_notes.csv"
output_csv = "eigen_release_notes_with_summary.csv"
# Read the merge request data from CSV
with open(input_csv, newline='', encoding='utf-8') as csvfile:
reader = csv.DictReader(csvfile)
mrs = list(reader)
# Process each merge request to get its summary
check_first = True
for mr in mrs:
if check_first:
import pdb; pdb.set_trace()
mr["summary"] = summarize_merge_request(mr)
print(f"Summary for MR {mr.get('mr_id_link', 'NA')}:\n{mr['summary']}\n")
# Write the updated data (with summaries) to a new CSV file
fieldnames = list(mrs[0].keys())
with open(output_csv, "w", newline='', encoding='utf-8') as csvfile:
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(mrs)
print(f"Summaries saved to {output_csv}")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment