Last active
September 3, 2024 06:23
-
-
Save TranBaVinhSon/deb7ce52ec79e9666c67a8b12ed1985c to your computer and use it in GitHub Desktop.
Getting all releases from the past 7 days from each repository within an organization, categorizing them, and creating a release note for business stakeholders.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Octokit } from "@octokit/rest"; | |
import OpenAI from "openai"; | |
import "dotenv/config"; | |
const octokit = new Octokit({ auth: process.env.GH_TOKEN }); | |
const openai = new OpenAI({ | |
apiKey: process.env.OPENAI_API_KEY, | |
}); | |
interface Release { | |
name: string; | |
body: string; | |
repositoryName: string; | |
} | |
export async function getAllReleasesLastWeek( | |
org: string, | |
days = 7 | |
): Promise<Release[]> { | |
const repos = await octokit.paginate(octokit.repos.listForOrg, { org }); | |
const releases: Release[] = []; | |
const now = new Date(); | |
const cutoffDate = new Date(now.getTime() - days * 24 * 60 * 60 * 1000); | |
for (const repo of repos) { | |
console.log("repo", repo.name); | |
let page = 1; | |
let shouldContinue = true; | |
while (shouldContinue) { | |
const repoReleases = await octokit.rest.repos.listReleases({ | |
owner: org, | |
repo: repo.name, | |
per_page: 100, | |
page: page, | |
}); | |
if (repoReleases.data.length === 0) break; | |
for (const repoRelease of repoReleases.data) { | |
const releaseDate = new Date(repoRelease.created_at); | |
if (releaseDate >= cutoffDate) { | |
releases.push({ | |
name: repoRelease.name as string, | |
body: repoRelease.body as string, | |
repositoryName: repo.name, | |
}); | |
} else { | |
shouldContinue = false; | |
break; | |
} | |
console.log(`release ${repoRelease.name} at ${repoRelease.created_at}`); | |
// If we reach to the final page | |
if (repoReleases.data.length < 100) { | |
shouldContinue = false; | |
} | |
} | |
page += 1; | |
} | |
} | |
return releases; | |
} | |
export async function classifyReleaseNotes(releaseNotes: string) { | |
const response = await openai.chat.completions.create({ | |
model: "gpt-4o-2024-08-06", | |
messages: [ | |
{ | |
role: "user", | |
content: `Classify the following release notes into the following categories and re-write them for non-technical readers such as business members in a concise manner: | |
## Product Improvements | |
New features and improvements which has impact directly to customers | |
### New Features | |
### Enhancements | |
### Bug Fixes | |
## Engineering Improvements | |
New release and improvements that can’t be seen from customers such as CI/CD improvement, cutting infra cost…etc | |
### Infrastructure Updates | |
### Performance Improvements | |
### Known Issues | |
\n\n | |
Release note: \n ${releaseNotes}`, | |
}, | |
], | |
}); | |
console.log(JSON.stringify(response, null, 2)); | |
return response.choices[0].message.content; | |
} | |
async function generateReleaseNote() { | |
const org = "moneyforward-i"; | |
const releases = await getAllReleasesLastWeek(org); | |
let releaseNotes = ""; | |
for (const release of releases) { | |
releaseNotes += `## ${release.name}\n${release.body}\n\n`; | |
} | |
const classifiedNotes = await classifyReleaseNotes(releaseNotes); | |
const releaseNote = ` \n\n ${classifiedNotes}`; | |
console.log("releaseNote", releaseNote); | |
} | |
generateReleaseNote(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
To generate release note weekly, here is the GH action:
.github/workflows/release-note.yml