Skip to content

⚙️ [기능추가][배포][인증] 인증서 생성 및 https 프록시 설정 필요 #9

⚙️ [기능추가][배포][인증] 인증서 생성 및 https 프록시 설정 필요

⚙️ [기능추가][배포][인증] 인증서 생성 및 https 프록시 설정 필요 #9

# ===================================================================
# 자동 QA 이슈 생성 워크플로우
# ===================================================================
#
# 이 워크플로우는 GitHub 이슈/PR 댓글에서 @suh-lab 멘션을 감지하여
# QA(시험요청) 이슈를 자동으로 생성합니다.
#
# 작동 방식:
# 1. 이슈 또는 PR 댓글에서 "@suh-lab" + "create" + "qa" 감지 (순서 무관)
# 2. 댓글에 👀 리액션 추가 (확인 표시)
# 3. 원본 이슈/PR 제목 또는 브랜치명에서 이슈 번호 추출
# 4. 제목에서 불필요한 이모지 및 키워드 제거
# 5. "🔍 [시험요청]" 접두사를 붙여 QA 이슈 생성
# 6. 시험 템플릿이 적용된 본문 자동 생성
# 7. 원본 이슈/PR에 QA 이슈 링크 댓글 작성
#
# 지원 기능:
# - 이슈와 PR 모두 지원
# - PR 브랜치명에서 이슈 번호 자동 추출
# - 명령어 순서 무관 (@suh-lab create qa, @suh-lab qa create 모두 가능)
# - 이모지 자동 제거 (🚀, 🔥, ⌛ 등)
# - 이슈 타입 키워드 제거 ([버그], [디자인], [기능요청] 등)
# - 카테고리 및 내용 자동 추출
# - QA 템플릿 자동 적용
# - 담당자 자동 할당
# - 확인 리액션 (👀) 자동 추가
#
# 사용 예시:
# 원본 이슈: "🚀 [기능개발][로그인] 소셜 로그인 추가"
# QA 이슈: "🔍 [시험요청][로그인] 소셜 로그인 추가"
#
# 트리거 방법:
# 이슈/PR 댓글에 "@suh-lab create qa" 또는 "@suh-lab qa create" 입력
#
# ===================================================================
name: PROJECT-CREATE-QA-ISSUE
on:
issue_comment:
types: [created]
# ===================================================================
# 설정 변수
# ===================================================================
env:
# QA 이슈 기본 담당자 설정
# - 'default': 댓글 작성자가 담당자로 지정됨
# - GitHub ID (예: 'Cassiiopeia'): 해당 사용자가 담당자로 지정됨
DEFAULT_QA_ASSIGNEE: 'default'
jobs:
create-qa:
# @suh-lab과 create, qa 키워드가 모두 포함되어 있으면 실행 (순서 무관)
if: |
contains(github.event.comment.body, '@suh-lab') &&
contains(github.event.comment.body, 'create') &&
contains(github.event.comment.body, 'qa')
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
contents: read
steps:
- name: 댓글에 👀 리액션 추가
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const commentId = context.payload.comment.id;
await github.rest.reactions.createForIssueComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: commentId,
content: 'eyes'
});
console.log('👀 댓글에 확인 리액션 추가 완료');
- name: QA 이슈 생성
uses: actions/github-script@v7
env:
DEFAULT_QA_ASSIGNEE: ${{ env.DEFAULT_QA_ASSIGNEE }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const issue = context.payload.issue;
const commenter = context.payload.comment.user.login;
// 담당자 결정: 'default'면 댓글 작성자, 그 외에는 지정된 GitHub ID
const defaultAssignee = process.env.DEFAULT_QA_ASSIGNEE || 'default';
const assignee = (defaultAssignee === 'default') ? commenter : defaultAssignee;
console.log(`👤 담당자 설정: ${assignee} (설정값: ${defaultAssignee})`);
const issueOrPrNumber = issue.number;
const isPullRequest = !!issue.pull_request;
console.log(`📌 타입: ${isPullRequest ? 'Pull Request' : 'Issue'}`);
console.log(`📌 번호: #${issueOrPrNumber}`);
let originalIssueNumber = issueOrPrNumber;
let title = issue.title;
// PR인 경우 브랜치명에서 이슈 번호 추출
if (isPullRequest) {
const { data: pr } = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: issueOrPrNumber
});
const branchName = pr.head.ref;
console.log(`🌿 브랜치명: ${branchName}`);
// 브랜치명에서 #31 형태의 이슈 번호 추출
const issueMatch = branchName.match(/#(\d+)/);
if (issueMatch) {
originalIssueNumber = parseInt(issueMatch[1]);
console.log(`🔍 추출된 이슈 번호: #${originalIssueNumber}`);
// 원본 이슈 정보 가져오기
try {
const { data: originalIssue } = await github.rest.issues.get({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: originalIssueNumber
});
title = originalIssue.title;
console.log(`📋 원본 이슈 제목: ${title}`);
} catch (error) {
console.log(`⚠️ 이슈 #${originalIssueNumber}를 찾을 수 없어 PR 제목 사용`);
}
}
}
console.log('📝 원본 제목:', title);
// 1. 이모지 제거
title = title.replace(/[\u{1F300}-\u{1F9FF}]/gu, '')
.replace(/[\u{2600}-\u{26FF}]/gu, '')
.replace(/[\u{2700}-\u{27BF}]/gu, '');
// 2. 특정 키워드 앞부분까지 제거
const keywordPattern = /^.*?\[(버그|디자인|기능요청|기능추가|기능개선)\]/;
title = title.replace(keywordPattern, '');
// 3. 공백 정리
title = title.replace(/^\s+/, '').trim();
console.log('✨ 정제된 제목:', title);
// 4. QA 이슈 제목 생성
const qaTitle = `🔍 [시험요청]${title}`;
console.log('🎯 QA 이슈 제목:', qaTitle);
// QA 이슈 본문 생성
const qaBody = `🔗 ISSUE 정보
---
- #${originalIssueNumber}
${isPullRequest ? `- PR: #${issueOrPrNumber}` : ''}
🔗 PR 정보
---
${isPullRequest ? `- #${issueOrPrNumber}` : '<!-- PR 번호나 URL을 작성해주세요 -->'}
🧩 시험 대상
---
${title.replace(/^\[.*?\]\s*/, '')}에 대한 기능 시험
📋 테스트 시나리오
---
1. 기본 기능 동작 확인
2. 엣지 케이스 테스트
3. UI/UX 확인
4. 에러 처리 확인
⚙️ 테스트 환경
---
- **프로젝트 Version**:
- **OS**:
- **브라우저**:
- **기기**:
🙋‍♂️ 담당자
---
- **시험담당**: 이름
- **요청자**: @${issue.user.login}
---
*🤖 이 이슈는 @suh-lab 봇에 의해 자동 생성되었습니다.*`;
try {
// QA 이슈 생성
const { data: qaIssue } = await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: qaTitle,
body: qaBody,
labels: ['작업 전'],
assignees: [assignee]
});
console.log(`✅ QA 이슈 생성 완료: #${qaIssue.number}`);
// 원본 이슈/PR에 댓글
const commentBody = isPullRequest
? [
'✅ **시험(QA) 요청 이슈가 생성되었습니다!**',
'',
'📋 **시험(QA) 요청**',
`- #${qaIssue.number}`,
'',
'🔗 **이슈정보**',
`- #${originalIssueNumber}`,
'',
'시험 완료 후 결과를 QA 이슈에 기록해주세요.'
].join('\n')
: [
'✅ **시험(QA) 요청 이슈가 생성되었습니다!**',
'',
'📋 **시험(QA) 요청**',
`- #${qaIssue.number}`,
'',
'시험 완료 후 결과를 QA 이슈에 기록해주세요.'
].join('\n');
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueOrPrNumber,
body: commentBody
});
console.log('💬 원본에 댓글 작성 완료');
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
console.log('🎉 QA 이슈 생성 프로세스 완료!');
console.log(` • ${isPullRequest ? 'PR' : 'Issue'}: #${issueOrPrNumber}`);
console.log(` • 원본 Issue: #${originalIssueNumber}`);
console.log(` • QA Issue: #${qaIssue.number}`);
console.log(` • 담당자: @${assignee}`);
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
} catch (error) {
console.error('❌ 에러 발생:', error);
// 에러 발생 시 댓글
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueOrPrNumber,
body: `❌ QA 이슈 생성 중 오류가 발생했습니다.\n\n\`\`\`\n${error.message}\n\`\`\``
});
}