Skip to content

Commit

Permalink
update prompt
Browse files Browse the repository at this point in the history
  • Loading branch information
bemijonathan committed Apr 27, 2024
1 parent 8be690c commit 883e673
Show file tree
Hide file tree
Showing 14 changed files with 265 additions and 256 deletions.
36 changes: 18 additions & 18 deletions src/__tests__/run.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as github from '@actions/github'
import {
getJiraTicket,
getChanges,
SummariseChanges,
SummarizeChanges,
postSummary
} from '../steps'
import * as core from '@actions/core'
Expand All @@ -22,26 +22,26 @@ describe('run', () => {
const acsummaries = 'Summary'

const githubContext = mockdata
// getJiraTicket.mockResolvedValue(jiraIssues)
// getChanges.mockResolvedValue(changes)
// SummariseChanges.summarizeGitChanges.mockResolvedValue(gitSummary)
// SummariseChanges.summariseJiraTickets.mockResolvedValue(jiraSummary)
// SummariseChanges.checkedCodeReviewAgainstCriteria.mockResolvedValue(acsummaries)
// postComment.mockResolvedValue()
getJiraTicket.mockResolvedValue(jiraIssues)
getChanges.mockResolvedValue(changes)
SummariseChanges.summarizeGitChanges.mockResolvedValue(gitSummary)
SummariseChanges.summariseJiraTickets.mockResolvedValue(jiraSummary)
SummariseChanges.checkedCodeReviewAgainstCriteria.mockResolvedValue(acsummaries)
postComment.mockResolvedValue()

// await run()
await run()

// expect(getJiraTicket).toHaveBeenCalledWith({
// title: githubContext.payload.pull_request.title,
// branchName: githubContext.payload.pull_request.head.ref,
// body: githubContext.payload.pull_request.body
// })
expect(getJiraTicket).toHaveBeenCalledWith({
title: githubContext.payload.pull_request.title,
branchName: githubContext.payload.pull_request.head.ref,
body: githubContext.payload.pull_request.body
})

// expect(getChanges).toHaveBeenCalledWith(githubContext.payload.pull_request.number)
// expect(SummariseChanges.summarizeGitChanges).toHaveBeenCalledWith(changes)
// expect(SummariseChanges.summariseJiraTickets).toHaveBeenCalledWith(jiraIssues)
// expect(SummariseChanges.checkedCodeReviewAgainstCriteria).toHaveBeenCalledWith(gitSummary, jiraSummary)
// expect(postComment).toHaveBeenCalledWith(githubContext.payload.pull_request.number, gitSummary)
expect(getChanges).toHaveBeenCalledWith(githubContext.payload.pull_request.number)
expect(SummariseChanges.summarizeGitChanges).toHaveBeenCalledWith(changes)
expect(SummariseChanges.summariseJiraTickets).toHaveBeenCalledWith(jiraIssues)
expect(SummariseChanges.checkedCodeReviewAgainstCriteria).toHaveBeenCalledWith(gitSummary, jiraSummary)
expect(postComment).toHaveBeenCalledWith(githubContext.payload.pull_request.number, gitSummary)
})

it('should handle errors', async () => {
Expand Down
50 changes: 50 additions & 0 deletions src/ai.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import {
prompt,
jiraPrompt,
acSummariesPrompt,
compareOldSummaryTemplate
} from './prompts.js'
import core from '@actions/core'
import OpenAI from 'openai'
import { Logger } from './utils.js'


export class Ai {
constructor() {
const openAiKey = core.getInput('openAIKey') || process.env.OPENAI_API_KEY
if (!openAiKey) {
throw new Error('OpenAI key is required')
}
this.model = new OpenAI({
apiKey: openAiKey
})
}
configuration = {
model: 'gpt-3.5-turbo'
}
model: OpenAI
basePromptTemplate = prompt
jiraPromptTemplate = jiraPrompt
acSummariesPromptTemplate = acSummariesPrompt
compareOldSummaryTemplate(oldSummary: string, newSummary: string): string {
return compareOldSummaryTemplate(oldSummary, newSummary)
}
execute = async (prompt: string) => {
try {
const response = await this.model.chat.completions.create({
messages: [
{
role: 'user',
content: prompt
}
],
...this.configuration
})
Logger.log('ai response', { response })
return response.choices[0].message.content
} catch (e) {
Logger.error('error summarizing changes', e)
return null
}
}
}
49 changes: 49 additions & 0 deletions src/clients/github.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import * as core from '@actions/core'
import * as github from '@actions/github'
import { Logger } from '../utils'
import { Ai } from '../ai'
import { GitHub } from '@actions/github/lib/utils'

export class GithubClient {
octokit: InstanceType<typeof GitHub>
repo: { owner: string; repo: string }
constructor() {
const { octokit, repo } = this.getGithubContext()
this.octokit = octokit
this.repo = repo
}

getGithubContext = () => {
const githubToken =
core.getInput('gitHubToken') || process.env.GITHUB_ACCESS_TOKEN || ''
const octokit = github.getOctokit(githubToken)
const repo = github.context.repo
return { octokit, repo, githubToken }
}


async getComments(pullRequestNumber: number) {
try {
const response = await this.octokit.rest.issues.listComments({
...this.repo,
issue_number: pullRequestNumber
})
return response.data
} catch (error) {
Logger.error('error getting comments', JSON.stringify(error))
return []
}
}

async postComment(comment: string, pullRequestNumber: number) {
try {
await this.octokit.rest.pulls.update({
...this.repo,
pull_number: pullRequestNumber,
body: comment
})
} catch (error) {
Logger.error('error posting comment', JSON.stringify(error))
}
}
}
2 changes: 2 additions & 0 deletions src/clients/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './jira.js'
export * from './github.js'
52 changes: 52 additions & 0 deletions src/clients/jira.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { WebhookPayload } from '@actions/github/lib/interfaces'
import { Version2Client } from 'jira.js'
import { Issue } from 'jira.js/out/agile/models'
import * as core from '@actions/core'

import { Logger } from '../utils'

export class JiraClient {
client: Version2Client
constructor() {
this.client = this.initializeJiraClient()
}
initializeJiraClient = () => {
const host = core.getInput('jiraHost') || process.env.JIRA_HOST || ''
return new Version2Client({
host,
authentication: {
basic: {
email: core.getInput('jiraEmail') || process.env.JIRA_EMAIL || '',
apiToken: core.getInput('jiraApiKey') || process.env.JIRA_API_KEY || ''
}
}
})
}
getJiraTicket = async ({
title,
branchName,
body
}: {
title?: string
branchName: string
body?: string
}): Promise<Issue[]> => {
const ticketRegex = /([A-Z]+-[0-9]+)/g
const allTickets = (`${body} ${branchName} ${title}` || '').match(ticketRegex)
if (!allTickets?.length) return []
const ticket = [...new Set(allTickets)]
const issues = await Promise.all(
ticket.map(async t => {
try {
const issue = await this.client.issues.getIssue({
issueIdOrKey: t
})
return issue.fields.description
} catch (e) {
Logger.error(`Error while fetching ${t} from JIRA`)
}
})
)
return issues.filter(e => e) as unknown as Issue[]
}
}
77 changes: 40 additions & 37 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,81 +1,84 @@
import * as core from '@actions/core'
import * as github from '@actions/github'
import core from '@actions/core'
import github from '@actions/github'
import {
SummariseChanges,
SummarizeChanges,
getChanges,
postSummary,
getJiraTicket,
Ai,
postComment
CommentHandler
} from './steps'
import dotenv from 'dotenv'
dotenv.config({ path: __dirname + '/.env' })
dotenv.config()

import { Logger } from './utils.js'
import { Logger, Templates } from './utils.js'
import { mockdata } from './mockdata'
import { Ai } from './ai'
import { GithubClient, JiraClient } from './clients'

// instantiate clients
const jiraClient = new JiraClient()
const githubClient = new GithubClient()
const commentsHandler = new CommentHandler(
githubClient
)
const ai = new Ai()

export async function run(): Promise<void> {
try {
// const githubContext = mockdata
const githubContext = github.context
const githubContext = process.env.NODE_ENV === 'local' ? mockdata : github.context
const pullRequestNumber = githubContext.payload.pull_request?.number
if (!pullRequestNumber) {
Logger.warn('Could not get pull request number from context, exiting')
return
}
const jiraIssues = await getJiraTicket({

const jiraIssues = await jiraClient.getJiraTicket({
title: githubContext.payload.pull_request?.title,
branchName: githubContext.payload.pull_request?.head.ref,
body: `${githubContext.payload.pull_request?.body} ${githubContext.payload.pull_request?.head.ref}}`
})

if (!jiraIssues.length) {
Logger.warn('Could not get jira ticket, exiting')
await postComment(
`
**⚠️ Warning:**
No jira ticket found.
`,
await commentsHandler.postComment(
Templates.warning(
'No jira ticket found in this pull request, exiting.'
),
pullRequestNumber
)
return
}

const changes = await getChanges(pullRequestNumber)
if (!changes) {
Logger.warn('Could not get changes, exiting')
await postComment(
`
**⚠️ Warning:**
No git changes found in this pull request.
`,
await commentsHandler.postComment(
Templates.warning('No git changes found in this pull request.'),
pullRequestNumber
)

return
}

const ai = new Ai()
const gitSummary = await SummariseChanges.summarizeGitChanges(changes, ai)
const jiraSummary = await SummariseChanges.summariseJiraTickets(
jiraIssues,
ai
)
const [gitSummary, jiraSummary] = await Promise.all([
SummarizeChanges.summarizeGitChanges(changes, ai),
SummarizeChanges.summarizeJiraTickets(jiraIssues, ai)
])

if (!jiraSummary || !gitSummary) {
Logger.warn('Summary is empty, exiting')
await postComment(
`
**⚠️ Warning:**
No jira ticket found.
`,
Logger.warn('No jira ticket found or Summary is empty, exiting')
await commentsHandler.postComment(
Templates.warning('No matching jira ticket found.'),
pullRequestNumber
)
return
}
const acSummaries = await SummariseChanges.checkedCodeReviewAgainstCriteria(

const acSummaries = await SummarizeChanges.checkedCodeReviewAgainstCriteria(
gitSummary,
jiraSummary,
ai
)
await postSummary(pullRequestNumber, acSummaries ?? '', ai)

await commentsHandler.postSummary(pullRequestNumber, acSummaries ?? '', ai)

} catch (error) {
core.setFailed((error as Error)?.message as string)
}
Expand Down
32 changes: 32 additions & 0 deletions src/steps/comments-handler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import * as core from '@actions/core'
import * as github from '@actions/github'
import { Logger } from '../utils'
import { Ai } from '../ai'
import { GitHub } from '@actions/github/lib/utils'
import { GithubClient } from '../clients'

export class CommentHandler {
constructor(private readonly repoClient: GithubClient) { }
SIGNATURE = 'Added by woot! 🚂'
async postSummary(
pullRequestNumber: number,
summary: string,
ai: Ai
) {
Logger.log('posted comment', github.context)
const comments = await this.repoClient.getComments(pullRequestNumber)
const existingComment = comments.find(
comment => comment.body?.includes(this.SIGNATURE)
)
let comment = `${summary} \n ${this.SIGNATURE}`
if (existingComment?.body) {
Logger.log('found existing comment, updating')
comment = `${await ai.compareOldSummaryTemplate(existingComment.body, summary)} \n ${this.SIGNATURE}`
}
await this.postComment(comment, pullRequestNumber)
}

postComment = async (comment: string, pullRequestNumber: number) => {
return this.repoClient.postComment(comment, pullRequestNumber)
}
}
2 changes: 1 addition & 1 deletion src/steps/get-changes.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as core from '@actions/core'
import * as github from '@actions/github'
import { Logger } from '../utils'
// import { mockdata } from '../mockdata'


export async function getChanges(
pullRequestNumber: number
Expand Down
3 changes: 1 addition & 2 deletions src/steps/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
export * from './get-changes.js'
export * from './post-comment.js'
export * from './comments-handler.js'
export * from './summarize-changes.js'
export * from './jira.js'
Loading

0 comments on commit 883e673

Please sign in to comment.