| import gradio as gr |
| from datetime import datetime, timedelta |
| import google.generativeai as genai |
| from github import Github, GithubException |
| import docx |
| import re |
| import tempfile |
|
|
| def generate_release_notes(github_repo, github_token, gemini_api_key, start_date, end_date): |
| try: |
| g = Github(github_token) |
| |
| repo = g.get_repo(github_repo) |
| |
| start_date = datetime.strptime(start_date, "%Y-%m-%d") |
| end_date = datetime.strptime(end_date, "%Y-%m-%d") |
| commits = list(repo.get_commits(since=start_date, until=end_date)) |
| |
| commit_messages = [commit.commit.message for commit in commits] |
| commit_text = "\n".join(commit_messages) |
| |
| if not commit_text: |
| return "No commits found in the specified date range.", None, None |
| |
| genai.configure(api_key=gemini_api_key) |
| model = genai.GenerativeModel('gemini-2.5-pro-preview-03-25') |
| |
| prompt = f"""Based on the following commit messages, generate comprehensive release notes: |
| |
| {commit_text} |
| |
| Please organize the release notes into sections such as: |
| 1. New Features |
| 2. Bug Fixes |
| 3. Improvements |
| 4. Breaking Changes (if any) |
| |
| Provide a concise summary for each item. Do not include any links, but keep issue numbers if present. |
| |
| Important formatting instructions: |
| - Use proper Markdown syntax |
| - Use # for main headers and ## for subheaders |
| - Use - for list items |
| - Keep the text structure simple and easy to read |
| - Be sure to briefly explain the why and benefits of the change for average users that are non-technical |
| """ |
|
|
| response = model.generate_content(prompt) |
| release_notes = response.text |
| |
| doc = docx.Document() |
| doc.add_heading('Release Notes', 0) |
| |
| current_list_style = None |
| for line in release_notes.split('\n'): |
| line = line.strip() |
| if line.startswith('# '): |
| doc.add_heading(line[2:], level=1) |
| current_list_style = None |
| elif line.startswith('## '): |
| doc.add_heading(line[3:], level=2) |
| current_list_style = None |
| elif line.startswith('- '): |
| if current_list_style is None: |
| current_list_style = doc.add_paragraph().style |
| current_list_style.name = 'List Bullet' |
| current_list_style.font.size = docx.shared.Pt(11) |
| doc.add_paragraph(line[2:], style=current_list_style) |
| elif line: |
| doc.add_paragraph(line) |
| |
| with tempfile.NamedTemporaryFile(delete=False, suffix='.docx') as temp_docx: |
| doc.save(temp_docx.name) |
| docx_path = temp_docx.name |
|
|
| with tempfile.NamedTemporaryFile(delete=False, suffix='.md', mode='w', encoding='utf-8') as temp_md: |
| temp_md.write(release_notes) |
| md_path = temp_md.name |
| |
| return release_notes, docx_path, md_path |
| |
| except GithubException as e: |
| if e.status == 401: |
| return "Error: Invalid GitHub token or insufficient permissions.", None, None |
| elif e.status == 404: |
| return f"Error: Repository not found. Please check the GitHub repository name. Attempted to access: {github_repo}", None, None |
| else: |
| return f"GitHub API error: {str(e)}", None, None |
| except Exception as e: |
| return f"An error occurred: {str(e)}", None, None |
|
|
| default_end_date = datetime.now() |
| default_start_date = default_end_date - timedelta(days=30) |
|
|
| iface = gr.Interface( |
| fn=generate_release_notes, |
| inputs=[ |
| gr.Textbox(label="GitHub Repository Name", placeholder="MicroHealthLLC/maiko-assistant"), |
| gr.Textbox(label="GitHub Personal Access Token", type="password"), |
| gr.Textbox(label="Gemini API Key", type="password"), |
| gr.Textbox( |
| label="Start Date", |
| placeholder="YYYY-MM-DD", |
| value=default_start_date.strftime("%Y-%m-%d"), |
| ), |
| gr.Textbox( |
| label="End Date", |
| placeholder="YYYY-MM-DD", |
| value=default_end_date.strftime("%Y-%m-%d"), |
| ) |
| ], |
| outputs=[ |
| gr.Textbox(label="Generated Release Notes"), |
| gr.File(label="Download Release Notes (DOCX)"), |
| gr.File(label="Download Release Notes (Markdown)") |
| ], |
| title="Automated Release Notes Generator", |
| description="Generate release notes based on GitHub commits using Gemini AI. Enter start and end dates (YYYY-MM-DD) to define the time range for commits.", |
| allow_flagging="never", |
| theme="default", |
| analytics_enabled=False, |
| ) |
|
|
| iface.launch() |