Skip to content

Instantly share code, notes, and snippets.

@supernovel
Created August 11, 2022 07:36
Show Gist options
  • Save supernovel/0d23db57d0077b8e3d4bfaba17ab8db4 to your computer and use it in GitHub Desktop.
Save supernovel/0d23db57d0077b8e3d4bfaba17ab8db4 to your computer and use it in GitHub Desktop.
커밋에 있는 지라 이슈를 기반으로 변경 사항 내용을 만든다.
import "https://deno.land/x/dotenv@v3.2.0/load.ts";
import * as Line from "https://deno.land/x/line@v1.0.1/mod.ts";
import uniq from "https://esm.sh/lodash@4.17.21/uniq?no-dts";
import lodashGet from "https://esm.sh/lodash@4.17.21/get?no-dts";
import * as log from "https://deno.land/std/log/mod.ts";
import { render } from "https://deno.land/x/mustache_ts@v0.4.1.1/mustache.ts";
await log.setup({
handlers: {
stringFmt: new log.handlers.FileHandler("DEBUG", {
filename: "./changelog_builder_log.txt",
formatter: "[{levelName}] {msg}",
}),
},
loggers: {
default: {
level: "DEBUG",
handlers: ["stringFmt"],
},
},
});
const logger = log.getLogger();
const defaultOutputTemplate = `
{{#issues}}
- {{id}} {{summary}}
{{/issues}}
`;
// 지라 이슈 타입 정의
class JiraIssue {
id!: string;
summary!: string
// deno-lint-ignore ban-types
static fromJson(json: object): JiraIssue {
const issue = new JiraIssue();
issue.id = lodashGet(json, "key");
issue.summary = lodashGet(json, "fields.summary");
return issue;
}
}
// 커밋 로그 가져오기
const getCommitLogs = async (startCommitHash: string): Promise<string> => {
const process = Deno.run({
cmd: ["git", "--no-pager", "log", `${startCommitHash}..HEAD`],
stdout: "piped",
});
const stdout = new TextDecoder().decode(await process.output());
process.close();
return stdout;
}
// 커밋 로그로 부터 지라 이슈 넘버 가져오기
const getJiraIssueIdsFromCommitLogs = (commitLogs: string): string[] => {
const matchedIterator = commitLogs.matchAll(/[A-Za-z]+\-\d+/g);
const matchedList = [...matchedIterator].flat().map((item) => item.toUpperCase());
const uniqueIssueKey: string[] = uniq(matchedList);
return uniqueIssueKey.sort();
}
// 지라 이슈 정보 가져오기
const getJiraIssueFromServer = async (jiraIssueId: string, {
jiraApiUsername,
jiraApiToken
}: {
jiraApiUsername: string,
jiraApiToken: string
}): Promise<JiraIssue> => {
const jiraApiKey = btoa(`${jiraApiUsername}:${jiraApiToken}`);
const response = await fetch(`https://lucentblock.atlassian.net/rest/api/latest/issue/${jiraIssueId}`, {
headers: {
"Authorization": `Basic ${jiraApiKey}`
}
});
const body = await response.json();
return JiraIssue.fromJson(body);
}
// 메인 커멘드 정의
class MainCommand extends Line.MainCommand {
public signature = "changelog-builder";
public options = {
"-ch [value], --commit-hash [value]": "가져올 커밋 메세지의 시작점",
"--jira-api-username [value]": "지라 API 유저 이메일",
"--jira-api-token [value]": "지라 API 유저 토큰",
};
public async handle(): Promise<void> {
const startCommitHash = this.option("--commit-hash") || Deno.env.get("CB_COMMIT_HASH");
const jiraApiUsername = this.option("--jira-api-username") || Deno.env.get("CB_JIRA_API_USERNAME");
const jiraApiToken = this.option("--jira-api-token") || Deno.env.get("CB_JIRA_API_TOKEN");
if(startCommitHash == null) {
logger.error(`
가져올 커밋 시작점인 --commit-hash 를 설정해야 합니다.
`);
return;
}
if(jiraApiUsername == null) {
logger.error(`
--jira-api-username 또는 CB_JIRA_API_USERNAME 환경 변수 설정이 필요합니다.
보통 지라 계정 이메일로 설정 하시면 됩니다.
`);
return;
}
if(jiraApiToken == null) {
logger.error(`
--jira-api-token 또는 CB_JIRA_API_TOKEN 환경 변수 설정이 필요합니다.
아래 링크에서 발급받으시면 됩니다.
https://id.atlassian.com/manage-profile/security/api-tokens
`);
return;
}
const commitLogs = await getCommitLogs(startCommitHash as string);
const jiraIssueIds = await getJiraIssueIdsFromCommitLogs(commitLogs);
const result = await Promise.all(jiraIssueIds.map(async (jiraIssueId) => {
try{
return await getJiraIssueFromServer(jiraIssueId, {
jiraApiUsername: jiraApiUsername as string,
jiraApiToken: jiraApiToken as string,
});
}catch(error){
logger.error(`Request ${jiraIssueId} issue error. => ${error.message}`);
}
}));
const jiraIssueList = result.filter((item) => item != null) as JiraIssue[];
console.log(
render(
defaultOutputTemplate,
{
issues: jiraIssueList
},
),
);
}
}
// cli 설정 정의
const cli = new Line.CLI({
name: "Changelog builder CLI",
description: `
commit log를 기준으로 jira 이슈 키를 가져와 CHANGELOG.md 파일을 업데이트 합니다.
--jira-api-username, --jira-api-token 옵션을 통해 Jira API 인증 정보를 설정 해야합니다.
또는 environment 변수를 통해서도 API 인증 정보 설정이 가능합니다.
API 인증 정보 발급: https://id.atlassian.com/manage-profile/security/api-tokens
`,
version: "v1.0.0",
command: MainCommand,
});
cli.run();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment