diff --git a/.github/scripts/notion-sync.js b/.github/scripts/notion-sync.js new file mode 100644 index 0000000..341d198 --- /dev/null +++ b/.github/scripts/notion-sync.js @@ -0,0 +1,108 @@ +// GitHub Action에서 'env:'로 전달해 준 변수들을 가져옵니다. +const { NOTION_API_KEY, NOTION_DATABASE_ID, TASK_ID_NUM, PR_URL, PR_ACTION, PR_IS_MERGED } = process.env; + +// --- 노션 DB 속성 이름 (하드코딩) --- +const ID_PROPERTY_NAME = 'ID'; +const STATUS_PROPERTY_NAME = '상태'; +const STATUS_IN_PROGRESS = '진행 중'; +const STATUS_DONE = '완료'; +// ------------------------------------ + +// 메인 로직을 비동기 함수로 실행 +async function main() { + if (!TASK_ID_NUM) { + console.log('Task ID number is not provided. Skipping.'); + return; + } + + const { Client } = require('@notionhq/client'); + const notion = new Client({ auth: NOTION_API_KEY }); + + const taskIdNum = parseInt(TASK_ID_NUM, 10); + const taskIdString = `KIO-${taskIdNum}`; + const isMerged = PR_IS_MERGED === 'true'; // 문자열 'true'를 boolean으로 변환 + + let newStatus = null; + let commentText = null; + + // 1. 이벤트에 따라 상태와 코멘트 결정 + if (PR_ACTION === 'opened') { + newStatus = STATUS_IN_PROGRESS; + commentText = `🚀 PR이 생성되었습니다: ${PR_URL}`; + } else if (PR_ACTION === 'reopened') { + newStatus = STATUS_IN_PROGRESS; + } else if (PR_ACTION === 'closed' && isMerged) { + newStatus = STATUS_DONE; + commentText = '✅ PR이 머지되었습니다'; + } else { + console.log(`Skipping: PR action '${PR_ACTION}', merged status '${isMerged}'.`); + return; + } + + // 2. KIO-ID (숫자)로 노션 페이지 검색 + let pageId = null; + try { + const response = await notion.databases.query({ + database_id: NOTION_DATABASE_ID, + filter: { + property: ID_PROPERTY_NAME, + unique_id: { + equals: taskIdNum, + }, + }, + }); + + if (response.results.length === 0) { + console.log(`[Error] No Notion page found with ID: ${taskIdString}`); + return; + } + pageId = response.results[0].id; + console.log(`Found Notion page: ${pageId}`); + } catch (error) { + console.error('Error finding Notion page:', error.body || error.message); + return; + } + + // 3. 노션 페이지 상태 업데이트 (Status 타입) + try { + await notion.pages.update({ + page_id: pageId, + properties: { + [STATUS_PROPERTY_NAME]: { + status: { + name: newStatus, + }, + }, + }, + }); + console.log(`Updated status to '${newStatus}' for page ${pageId}`); + } catch (error) { + console.error('Error updating Notion page status:', error.body || error.message); + // 상태 업데이트에 실패해도 코멘트는 시도 + } + + // 4. 노션 페이지에 코멘트 추가 (링크 포함) + try { + if (!commentText) { + return; + } + + await notion.comments.create({ + parent: { page_id: pageId }, + rich_text: [ + { + text: { + content: commentText, + link: { url: PR_URL }, + }, + }, + ], + }); + console.log(`Added comment to page ${pageId}`); + } catch (error) { + console.error('Error adding comment to Notion page:', error.body || error.message); + } +} + +// 스크립트 실행 +main(); diff --git a/.github/scripts/package.json b/.github/scripts/package.json new file mode 100644 index 0000000..f44946f --- /dev/null +++ b/.github/scripts/package.json @@ -0,0 +1,8 @@ +{ + "name": "notion-sync-script", + "version": "1.0.0", + "private": true, + "dependencies": { + "@notionhq/client": "^2.2.14" + } +} \ No newline at end of file diff --git a/.github/workflows/notion-sync.yml b/.github/workflows/notion-sync.yml new file mode 100644 index 0000000..d251590 --- /dev/null +++ b/.github/workflows/notion-sync.yml @@ -0,0 +1,48 @@ +name: Update Notion Task Status from PR + +on: + pull_request: + types: [opened, reopened, closed] + +jobs: + update_notion: + runs-on: ubuntu-latest + if: "contains(github.head_ref, 'KIO-')" + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Get Task ID Number from Branch Name + id: get_id + run: | + BRANCH_NAME="${{ github.head_ref }}" + REGEX="KIO-([0-9]+)" + if [[ $BRANCH_NAME =~ $REGEX ]]; then + echo "task_id_num=${BASH_REMATCH[1]}" >> $GITHUB_OUTPUT + else + echo "No KIO-[number] ID found in branch name." + fi + + - name: Set up Node.js + if: steps.get_id.outputs.task_id_num + uses: actions/setup-node@v4 + with: + node-version: '18' + + - name: Install Script Dependencies + if: steps.get_id.outputs.task_id_num + run: npm install + working-directory: .github/scripts + + - name: Run Notion Sync Script + if: steps.get_id.outputs.task_id_num + run: node notion-sync.js + working-directory: .github/scripts + env: + NOTION_API_KEY: ${{ secrets.NOTION_API_KEY }} + NOTION_DATABASE_ID: ${{ secrets.NOTION_DATABASE_ID }} + TASK_ID_NUM: ${{ steps.get_id.outputs.task_id_num }} + PR_URL: ${{ github.event.pull_request.html_url }} + PR_ACTION: ${{ github.event.action }} + PR_IS_MERGED: ${{ github.event.pull_request.merged }} \ No newline at end of file