1+ name : Auto PR Title from Issue
2+
3+ on :
4+ pull_request :
5+ types : [opened, synchronize, reopened, edited]
6+
7+ permissions :
8+ issues : read
9+ pull-requests : write
10+
11+ jobs :
12+ set-pr-title :
13+ runs-on : ubuntu-latest
14+ steps :
15+ - name : Set PR title same as issue title + number
16+ uses : actions/github-script@v7
17+ with :
18+ github-token : ${{ secrets.GITHUB_TOKEN }}
19+ script : |
20+ const pr = context.payload.pull_request;
21+
22+ // 1) Dependabot 등 봇 PR은 패스
23+ const botLogins = new Set(['dependabot[bot]']);
24+ if (botLogins.has(pr.user.login)) {
25+ console.log('ℹ️ Bot PR detected, skipping');
26+ return;
27+ }
28+
29+ const branch = pr.head.ref; // ex) feat/be/123
30+ // 2) 우리 브랜치 컨벤션이 아니면 스킵(실수 방지)
31+ const branchOK = /^(feat|fix|refactor|docs|chore|test)\/(fe|be|infra)\/\d+$/.test(branch);
32+ if (!branchOK) {
33+ console.log(`ℹ️ Branch "${branch}" does not match our pattern; skipping`);
34+ return;
35+ }
36+
37+ // 3) 브랜치에서 이슈 번호 추출 (마지막 세그먼트 숫자)
38+ const m = branch.match(/(?:\/|^)(\d+)$/);
39+ if (!m) {
40+ console.log(`❌ Could not extract issue number from "${branch}"`);
41+ return;
42+ }
43+ const issueNumber = Number(m[1]);
44+
45+ // 4) 이슈 조회 (404면 스킵)
46+ let issue;
47+ try {
48+ issue = await github.rest.issues.get({
49+ owner: context.repo.owner,
50+ repo: context.repo.repo,
51+ issue_number: issueNumber
52+ });
53+ } catch (error) {
54+ if (error.status === 404) {
55+ console.log(`❌ Issue #${issueNumber} not found; skipping`);
56+ return;
57+ }
58+ throw error;
59+ }
60+
61+ const issueTitle = (issue.data.title || '').trim();
62+ if (!issueTitle) {
63+ console.log(`❌ Issue #${issueNumber} has empty title; skipping`);
64+ return;
65+ }
66+
67+ // 5) PR 제목 동기화: "<이슈제목> (#번호)"
68+ const desiredTitle = `${issueTitle} (#${issueNumber})`;
69+ if (desiredTitle !== pr.title) {
70+ await github.rest.pulls.update({
71+ owner: context.repo.owner,
72+ repo: context.repo.repo,
73+ pull_number: pr.number,
74+ title: desiredTitle
75+ });
76+ console.log(`✅ PR title updated → ${desiredTitle}`);
77+ } else {
78+ console.log('ℹ️ PR title already up-to-date');
79+ }
80+
81+ // 6) (옵션) PR 본문에 이슈 링크 없으면 추가
82+ const body = pr.body || '';
83+ if (!new RegExp(`\\(#${issueNumber}\\)`).test(body) && !new RegExp(`#${issueNumber}(\\b|$)`).test(body)) {
84+ const appended = `${body}\n\nLinked: #${issueNumber}`.trim();
85+ await github.rest.pulls.update({
86+ owner: context.repo.owner,
87+ repo: context.repo.repo,
88+ pull_number: pr.number,
89+ body: appended
90+ });
91+ console.log(`📝 Appended issue link to PR body`);
92+ }
0 commit comments