Github 협업 설정(Github Issue + Jira 연동)

김 주현·2024년 1월 19일
8

내가 그동안 하던 협업은... 협업이 아니었다(!)

새로 사이드 프로젝트 팀에 들어갔다! 매번 기획 + 디자인 + 프론트를 혼자 맡고 백엔드는 지인이나 Open API만 써봐서 협업이 전체적으로 어떻게 진행되는지 항상 궁금했는데, 이번에 기회가 생긴 만큼 협업툴에 관한 걸 마스터해보겠다! 싶은 생각으로 덤벼들었다. 그런데 항상 깨지는 건 나

다행히 같은 FE팀에 여러 프로젝트를 해보신 분이 계셔서 많이 도움을 받았다. 좋은 사람! 배운 걸 기록하기 위해 적어보는 포스팅.


협업 툴

팀마다 방식이야 다르겠지만 이 팀에서는 Slack, Notion, Jira, Github를 기본으로 사용하고 있었고, 아마 다른 팀들도 이게 기본 환경이지 않을까 싶다. (비개발쪽은 Jandi도 많이 쓰는 듯?)

Slack

Slack은 워크스페이스 단위의 메신저앱이라고 해야하나, 카톡처럼 개인이 채팅방을 가지고 있는 게 아니고 한 개의 워크스페이스를 기준으로 여러 채팅방(채널)을 생성할 수 있다. 이렇게 워크스페이스 내에서 채널을 생성하며 업무에 대한 이야기를 나누다보니 확실히 특정 분야에 대해서만 모아서 볼 수도 있고, 내가 원하는 것만 볼 수도 있었다.

채널 이름 설정

내가 팀에 들어오기 전, Slack을 쓰고 있긴 했는데 협업을 위한 주채널이 아닌 것 같았다. 주로 카톡으로 의견을 나누고 있었다. 그 이유가 나는 채널의 목적이 분명하지 않아서인 것 같다는 생각이 들었다.

구분을 짓긴 했지만 잡담, 공지, 회의 정도로만 크게크게 나누어져 있다보니 이걸 이야기를 하고 싶을 때 어디에서 이야기를 꺼내지? 라는 생각에 결국 카톡으로 이야기하게 되는 흐름이라고 생각했다. (무엇보다, 의견을 공식적으로 개진할 곳이 없었다!)

여러 포스팅을 찾아보고 제일 괜찮은 것 같은 채널 구분을 도입해보았다.

채널 인덱싱

  • #0-이름 / 팀 전체가 필요한 채널
  • #1-이름 / 팀별 채널
  • #2-이름 / 협업 채널
  • #9-이름 / For bot

채널 분리 후 확실히 카톡 보다는 Slack에 대한 이용률이 높아졌고, 기능에 대한 협의도 서로서로 공유가 되고 있어 의논한 기능에 대해 서로 잘못 알고 있는 경우가 줄었다.

무엇보다도,, 다들 Slack을 써야겠다는 필요성을 느끼고 있어서! 단순 협업 도구가 아니라 소통의 창구 쓰일 수 있게 팀원들이 적극 이용해준 것도 큰 영향인 것 같다.

반응

사실 Slack에서 가장 좋았던 건 이 반응이다. 일을 할 땐 내가 말한 거에 대해 확인을 했는지 안 했는지에 대한 확인 대답이 필요하다고 생각하는 편인데, 이를 편하게 남길 수 있어서 좋았다. 확인했다고 굳이 말로 남길 필요없이 이모지 하나만 남기면 되는 게 넘 귀여워!


Notion

노션은 개인적으로도 잘 사용하고 있는 툴이었고, 몇 없는 협업을 해봤을 때도 노션이 짱이더라 싶었다. 그런데 여기에서 난 몰랐던 게.. Notion은 Teamspace로 만들면 만들 수 있는 블럭 수 제한이 걸려있더라! 여태 난 항상 내가 파고 공유를 한 거라 Teamspace가 있는지도 몰랐긴 했는데 그래서 무료 플랜으로 진행하려면 제한에 가까울 때마다 팀 페이지를 새로 만들어야 했다.. 꽤나 불편하더군.

그러다보니까 문서들이 파편화되어 필요한 문서가 어디에 있었는지 매번 확인해야 했었다. 이에 한번 물갈이 개편이 필요하다는 생각에 개발 진행 및 외부에 공유할 수 있는 문서들로만 이루어진 팀 페이지를 만들었다.

페이지 구성은 다음과 같이 잡았다.

페이지 구성

  1. DASSDA 서비스 소개
  2. DASSDA 팀원 소개
  3. DASSDA 개발 보드

개인적으로는 Ticket 형식으로 개발에 대한 현황도 보여주고 싶었는데, 작업에 관련해선 Jira를 쓰고 있기도 했고, 외부 사람들이 그걸 알 필요가 있나? 싶은 생각에 빼버렸다.

픽스된 형식은 아니지만 일단 진행해보며 필요한 게 있으면 넣기로 했다! 덕분에 이제 여러 팀 페이지를 돌며 문서를 찾지 않아도 됐다 ^___^


Jira

Jira는 작업 관리를 도와주는 툴이다. 이슈와 프로젝트 계획을 도와주는데, 가장 큰 특징이 바로 추적을 할 수 있다는 점! Notion도 투두리스트를 만들어서 작업을 진행할 수 있지만, 큰 단위로는 설정할 수 없어 전체적인 진행 상황을 알 수 없다.

그렇지만 요놈은 프로젝트에 대한 설계부터 시작해서 작업 진행 상황에 대한 추적이 가능해서 현재 프로젝트가 어디까지 진행이 됐는지 파악할 수 있다!

개인적으로 많이 들어보긴 했는데 협업할 상황이 없어서 못 쓰고 있던 상황이라, 이번에 아주 써보려고 작정해봤다. 하다보니 내 성향하고도 잘 맞는 툴이라 개인 용도로도 잘 쓰지 않을까 싶은... 생각

마음에 들었던 건 타임라인 별로 볼 수 있다는 점? 지금까지 작업에 대한 상황이라고 하면 칸반보드 정도밖에 없었는데, 이렇게 타임라인으로 볼 수 있으니까 프로젝트가 한 눈에 들어오는 느낌!


Github

Github는 워낙 많이 써봐서 배울 게 없다고 생각했었는데, 협업을 위해 써보니 배울 게 또 있더라... 역시 배움엔 끝이 없다😇

Issue와 Action에 대해서 좀 다룰 수 있게 됐고, PR의 방법도 여러가지가 있다는 것도 알게 됐다. 자세한 건 아래에서!


협업 환경 설정

본격적으로 협업을 위해서 Jira와 Github를 연동시켜보자! 그 전에 먼저 논의가 되어야 하는 게 있다.

기본적으로 연동이 되었을 때, Jira가 Github에 영향을 줄 수도 있고 Github가 Jira에 영향을 줄 수 있다. 그렇기 때문에 메인으로 가져갈 도구를 선택해야 한다. 우리 팀은 Github를 메인으로 가져가기로 했다. 아무래도 나중에 포폴이나 이력서를 생각하면 외부에서도 확인할 수 있는 게 좋을 것 같다는 생각으로!

조금 더 포장해서 말하면, Jira는 폐쇄적이고 내부의 규칙에 따라 달라질 수 있는 내용이 많고 무엇보다 '작업'을 기준으로 서비스를 운영하다보니 코드 리뷰와 이슈 논의에 대한 기능이 부족하다고 생각했다. 따라서 Github로 결정!

1. Jira에 Github Repo 연동

Jira와 Github Repo를 연동하면 Jira가 해당 레포를 자동으로 추적해준다(!) 넘 신기했다. 그래서 따로 뭐 자동화 옵션을 걸어줘야 하는 게 아니라 연동만 시켜주면 다음과 같이 추적할 수 있다.

다만 추적을 위해 Jira에서 생성한 Ticket Number를 기입해줘야 한다. Branch든 Commit이든 ~_~

Github for Jira

Jira Software에서 앱 > 더 많은 앱 살펴보기 > Github for Jira 검색해서 아래의 앱을 다운로드 하자. 요놈이 연동을 도와주는 녀석!

이후 요기에서 나온 대로 잘 진행해주면 연동 끝! 너무 잘 정리가 되어있어서 따로 정리하진 않겠다. 내가 겪었던 문제만 정리해보겠음!

Repo 추가가 안 돼요

  • 해당 Repo에 대한 권한을 확인해야 한다. 조직에 있는 레포를 연결하려고 보니 나는 조직 내에서 Owner가 아니라 Member여서 설치가 안 됐다. Owner로 권한을 부여받고 나니 설치가 잘 됐다.
  • 추가로, Member로서 Repo를 추가하려고 시도하면 설치 요청이 Owner에게 가고, Owner가 수락을 해줘야 설치가 된다. 이걸 모르고 n번 시도를 했더니 무수히 많은 설치 요청이 있었더랬다

Backfill이 뭐야요?


설치하고 나고 보면 Backfill status라는 녀석이 있던데, 간단히 말하자면 깃헙 백업이다. 자세한 건 아래의 설명을 참고!

  • GitHub for Jira를 통해 GitHub 조직을 연결하면 해당 조직의 기록을 Jira로 가져옵니다(백필이라고 함). When you connect a GitHub organization through GitHub for Jira, the history from that organization is imported to Jira (called backfilling).

  • 풀 리퀘스트, 배포, 빌드 및 커밋에 대한 6개월의 기록을 자동으로 백필하고 브랜치에 대한 모든 기록을 가져옵니다. We automatically backfill 6 months of history for pull requests, deployments, builds, and commits, and import all history for branches.

  • 조직이 연결되면 기록이 계속 동기화되므로 항상 최신 상태로 유지됩니다. Once the organization’s connected, its history continues to sync so it’s always up to date.

  • 기본 6개월 이상의 데이터를 가져오거나, 가져온 데이터에 문제가 있는 경우 현재 기록을 덮어쓰도록 선택할 수 있습니다. You can choose to import more than the default 6 months of data, or overwrite the current history if you’re having issues with the imported data.

2. Github Action 생성

그리고 우린 Issue를 생성할 때마다 Jira Issue도 같이 생성되게 하고 싶었다. 그래서 Github Action에 대해서 먼저 쓰윽 훑어봤는데 이거.. 꽤 물건이었다. 그냥 일종의 Batch 파일이더라. 근데 이제 할 수 있는 게 많은(ㅋㅋ)

Jira에 대한 Action도 역시 만들어져 있었고, Jira를 만든 Atlassian가 제공하는 Action도 많았다. 이걸 이용하면 대충 될 것 같아서~ 내가 원하는 기능에 대해 크게 순서를 잡아보았다.

Jira Issue 생성 Action

  1. Issue가 열리면(라고 표현하더라) Action 작동
  2. Jira Issue 생성
  3. 생성된 Issue의 Ticket Number로 Branch 생성(from develop)
  4. Issue 제목 앞에 생성된 Issue의 Ticket Number 기입

issue-form.yml

먼저 Issue Form을 활용한 이슈 템플릿이다.

issue-form.yml

name: 'SSDA Front 이슈 생성'
description: 'SSDA Front Repo에 이슈를 생성하며, 생성된 이슈는 Jira와 연동됩니다.'
labels: [order]
title: '이슈 이름을 작성해주세요'
body:
  - type: input
    id: parentKey
    attributes:
      label: '상위 작업 Ticket Number'
      description: '상위 작업의 Ticket Number를 기입해주세요'
      placeholder: 'DIAR-00'
    validations:
      required: true

  - type: input
    id: description
    attributes:
      label: '이슈 내용(Description)'
      description: '이슈에 대해서 간략히 설명해주세요'
    validations:
      required: true

  - type: textarea
    id: details
    attributes:
      label: '상세 내용(Details)'
      description: '이슈에 대해서 자세히 설명해주세요'
      value: |
        - About Details
    validations:
      required: true

  - type: textarea
    id: tasks
    attributes:
      label: '체크리스트(Tasks)'
      description: '해당 이슈에 대해 필요한 작업목록을 작성해주세요'
      value: |
        - [ ] Task1
        - [ ] Task2
    validations:
      required: true

  - type: textarea
    id: references
    attributes:
      label: '참조(References)'
      description: '해당 이슈과 관련된 레퍼런스를 참조해주세요'
      value: |
        - Reference1
    validations:
      required: false

Issue Form으로 작성하면 좀 더 깔끔한 화면이 나온다. Issue Form을 사용한 이유는 Action에서 필요한 파라미터를 제공하기 위해서 사용했다.

create-jira-issue.yml

다음은 완성된 Action 파일이다.

create-jira-issue.yml

name: Create Jira issue
on:
  issues:
    types:
      - opened
jobs:
  create-issue:
    name: Create Jira issue
    runs-on: ubuntu-latest
    steps:
      - name: Login
        uses: atlassian/gajira-login@v3
        env:
          JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }}
          JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }}
          JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }}

      - name: Checkout main code
        uses: actions/checkout@v4
        with:
          ref: main

      - name: Issue Parser
        uses: stefanbuck/github-issue-praser@v3
        id: issue-parser
        with:
          template-path: .github/ISSUE_TEMPLATE/issue_form.yml

      - name: Log Issue Parser
        run: |
          echo '${{ steps.issue-parser.outputs.jsonString }}'

      - name: Convert markdown to Jira Syntax
        uses: peter-evans/jira2md@v1
        id: md2jira
        with:
          input-text: |
            ### Github Issue Link
            - ${{ github.event.issue.html_url }}

            ${{ github.event.issue.body }}
          mode: md2jira

      - name: Create Issue
        id: create
        uses: atlassian/gajira-create@v3
        with:
          project: DIAR
          issuetype: Subtask
          summary: "${{ github.event.issue.title }}"
          description: "${{ steps.md2jira.outputs.output-text }}"
          fields: |
            {
              "parent": {
                "key": "${{ steps.issue-parser.outputs.issueparser_parentKey }}"
              }
            }

      - name: Log created issue
        run: echo "Jira Issue ${{ steps.issue-parser.outputs.parentKey }}/${{ steps.create.outputs.issue }} was created"

      - name: Checkout develop code
        uses: actions/checkout@v4
        with:
          ref: develop

      - name: Create branch with Ticket number
        run: |
          git checkout -b ${{ steps.create.outputs.issue }}
          git push origin ${{ steps.create.outputs.issue }}

      - name: Update issue title
        uses: actions-cool/issues-helper@v3
        with:
          actions: "update-issue"
          token: ${{ secrets.GITHUB_TOKEN }}
          title: "${{ steps.create.outputs.issue }} ${{ github.event.issue.title }}"

처음 만들어본 Action이었지만 yml 문법 자체는 간단해서 금방 만들었다. 근데 이게 불편한 게 디버깅을 하려면 계속 실행을 시켜줘야 해서 ;ㅅ; 무슨 방법이 있을 것 같은데 난 몰라서 일단 삽질^___^

create-jira-issue.yml 실행 순서 및 설명

Action 파일 내용의 순서는 다음과 같다.

1. Jira Login

- name: Login
  uses: atlassian/gajira-login@v3
  env:
    JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }}
    JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }}
    JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }}

Jira에서 제공하는 create-issue action을 사용하려면 Jira Login이 선행되어야 한다. 제공해야 하는 env는 사용하고 있는 Jira URL, Jira API Token, API Token을 만든 User의 email이다. (자세한 내용은 gajira-login repo로 들어가보면 된다!)

여기에서 주의할 게, Personal API Token이라 해당 API를 생성한 유저 계정으로 보고자가 올라간다.

이왕 만들 때 만드는 사람으로 올라가면 좋을 것 같아서 env에 api token과 user_email을 또 추가할까 싶었는데,, 알고보니 저 보고자 필드는 수정 가능해서 내비두기로 했다.

+) env는 Github Repo > Setting > Secrets and variables > Repository secrets에서 설정했다.

2. Checkout main branch

- name: Checkout main code
  uses: actions/checkout@v4
  with:
    ref: main

git의 checkout 느낌인 줄 알았는데, 여기에서는 특정 브랜치의 code를 가져오는 역할이다. 머.. 비슷하긴 하다. with의 ref로 특정 브랜치를 설정할 수 있고 생략시 기본값으로 main을 가져온다.

3. Issue Parser 실행(with issue form)

- name: Issue Parser
  uses: stefanbuck/github-issue-praser@v3
  id: issue-parser
  with:
    template-path: .github/ISSUE_TEMPLATE/issue_form.yml

Subtask를 만들려면 상위 이슈 Ticket Number를 알아야 했다. 그런데 기능에 따라 상위 이슈는 달라지니까 Issue에서 입력을 받으면 좋겠다는 생각이었다.

찾아보니 Issue Form이라는 게 있길래 이걸 쓰면 되겠다! 싶었는데, 이 녀석은 스키마만 정해주는 거지 읽어와서 쓸 순 없다는 사실을 알았을 때의 황당함이란...

Issue Parser는 Markdown 형식으로 표현된 Issue 내용을 가져오는 녀석이다. 다행히 이 녀석이 주어진 Issue Form을 이용해서 Issue Body를 파싱해준다.
요놈을

이렇게!

4. Issue Parser 로그

- name: Log Issue Parser
  run: |
    echo '${{ steps.issue-parser.outputs.jsonString }}'

디버깅용으로 로그를 남겨준다. jsonString를 불러오면 파싱한 데이터를 보여준다.

5. Convert Github Markdown to Jira Syntax

- name: Convert markdown to Jira Syntax
  uses: peter-evans/jira2md@v1
  id: md2jira
  with:
    input-text: |
      ### Github Issue Link
      - ${{ github.event.issue.html_url }}

      ${{ github.event.issue.body }}
    mode: md2jira

진짜 억까였던 게... Github Markdown 형식 그대로 Jira 이슈를 생성하면 이상하게 나온다. 이는 Jira Issue Description의 형식이 자체 양식이기 때문이다. (Ex. Github MD에서는 h3이 ### 이지만 Jira는 h3. 이더라)

그래서... 해당 형식으로 바꿔주는 action을 사용해야 한다. 이거 해결한다고 진짜 삽질을 ^___^*,,

6. Create Jira Issue(Subtask)

- name: Create Issue
  id: create
  uses: atlassian/gajira-create@v3
  with:
    project: DIAR
    issuetype: Subtask
    summary: "${{ github.event.issue.title }}"
    description: "${{ steps.md2jira.outputs.output-text }}"
    fields: |
      {
        "parent": {
          "key": "${{ steps.issue-parser.outputs.issueparser_parentKey }}"
        }
      }

gajira-create에서 제공하는 field대로 값을 주면 되는데, Subtask로 생성할 시에 fields 필드에 key를 가진 parent 필드를 제공해야한다. 해당 key는 아까 우리가 파싱한 issue-parser에서 가져오면 되는데, outputs.parentKey가 아닌 outputs.issueparser_parentKey 임을 주의하자.

그리고,, description에는 객체가 들어갈 수 없다. 아까 5번에서 언급했듯이 형식이 이상하게 나오길래, 직접 Jira에서 수정하면서 보내는 데이터를 확인해봤는데, 객체 형태로 한 블럭블럭으로 보내고 있었다. 진짜 이렇게 다 해야하나... 싶어서 일단 해봤는데 또 description은 객체가 불가능했다. 그래서 fields에 description을 담아서 보내봤더니 이상한 에러가 나오고....

아무튼! 포인트는 description은 자체 형식으로 변환해서 보내줘야 하고! Subtask는 Parent Key를 같이 보내줘야한다!

7. Create Jira Issue Log

- name: Log created issue
  run: echo "Jira Issue ${{ steps.issue-parser.outputs.parentKey }}/${{ steps.create.outputs.issue }} was created"

gajira-create는 생성에 성공하면 해당 Issue의 Ticket Number를 반환한다. 확인하기 위해 로그를 남겨준다.

8. Checkout develop branch

- name: Checkout develop code
  uses: actions/checkout@v4
  with:
    ref: develop

이제 Ticket Number로 Branch를 생성해야 하는데, 현재 checkout이 main으로 되어 있어서 이 상태로 만들면 main에서 바로 따오는 형태가 된다. 그래서 develop으로 checkout 해준다.

9. Create a ticket number branch

- name: Create branch with Ticket number
  run: |
    git checkout -b ${{ steps.create.outputs.issue }}
    git push origin ${{ steps.create.outputs.issue }}

branch 만드는 action을 계속 검색했는데 잘 없길래 뭐지.. 했는데 당연함. run으로 처리하면 됨.

10. Update Github Issue Title with ticket number prefix

- name: Update issue title
  uses: actions-cool/issues-helper@v3
  with:
    actions: "update-issue"
    token: ${{ secrets.GITHUB_TOKEN }}
    title: "${{ steps.create.outputs.issue }} ${{ github.event.issue.title }}"

마지막으로 이슈 추적이 용이하게 Github Issue의 제목 앞에 Ticket Number를 붙여준다. 이때 secrets.GITHUB_TOKEN은 Github에서 자동으로 생성하는 토큰이다.

여기까지 하면 원하는 목적 달성!

Github Action 권한 설정

...인 줄 알았지? 끝날 때까지 끝난 게 아니란다

오류 내용을 보니 Write에 대해 권한이 없다는 내용이었다. 설정을 해주려고 보니.. Write Permission을 설정해주는 곳이 닫혀있었다.

뭐야 내 Write 돌려줘요

그 이유는~ 조직 내에서 Action 권한이 달랐기 때문이다. (Repo의 Action 권한과 조직의 Action 권한이 다른 거였더라) 조직의 Action 권한에 Write를 주면~

정상적으로 Repop에서 Write Permission을 줄 수 있게 된다.

여기까지 하면 진짜 원하는 목적을 달성했다!


3. Husky 설정

프로젝트를 함께 개발할 때 제일 중요한 것: 코드 컨벤션커밋 컨벤션

이게 안 맞으면 코드 보기도 힘들고 커밋 내용도 맘대로라 일정한 형식을 만들어서 서로 맞춰줘야 한다. 이걸 위해서 따로 ESLint + Prettier도 설정하고, Commit Convention 규칙도 정했지만 아무래도 사람이다 보니 실수가 있을 수도 있다.

이럴 때 커밋을 보낼 때마다 자동으로 검사를 해주고 규칙에 맞게 도와주는 녀석이 바로 Husky이다.

검색해보다 귀여워서 ...

Husky를 알려면 먼저 Git Hook을 알아야 한다. Git Hook는 Git Repo에서 특정 이벤트가 발생하면 자동으로 스크립트를 실행시켜주는 기능이고, 이를 사용하기 더 편하게 만들어준 게 Husky이다! 편하기도 편한 거지만, 프로젝트에 husky를 설치해두고 설정해두면 팀원들에게도 자동으로 Git Hook이 설치가 됨으로써 간편하게 팀 컨벤션을 지킬 수 있게 된다.

Commit 할 때 앞에 Ticket Number 넣기

Jira에서 Commit 추적을 위해 Ticket Number를 기입해줘야 한다. 일일이 기입해줘도 되지만 넘 귀찮으므로, prepare-commit-msg를 사용해보자.

  • 기본 전제: Branch의 이름이 Ticket Number여야 합니다

husky 설치

pnpm add husky jira-prepare-commit-msg -D
pnpm husky install

jira-prepare-commit-msg는 husky를 위한 일종의 플러그인이라고 생각하면 된다. husky install을 하게 되면 Hooking을 위해 기본적으로 필요한 설정을 진행한다.

prepare-commit-msg

.husky/prepare-commit-msg

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

pnpm jira-prepare-commit-msg $1

.husky 폴더 안에 미리 지정된 이름인 prepare-commit-msg를 생성해주면 commit을 날리기 전에 메시지를 수정할 수 있다(메시지만!)

commit message 설정

package.json

{
  "jira-prepare-commit-msg": {
    "messagePattern": "[$J] $M",
    "allowEmptyCommitMessage": false,
    "ignoredBranchesPattern": "^(master|main|dev|develop|development|release)$"
  }
}

어떤 식으로 메시지를 구성할 건지는 package.json의 jira-prepare-commit-msg를 설정해주면 된다. messagePattern에서 $J는 Jira Ticket Number, $M은 Origin Commit Message이다. 또~ 모든 브랜치에서 작동하는 게 아니라 Ticket Number Branch에서만 작동하게 하고 싶으므로 일반적인 branch에서는 skip하도록 설정했다.

그러면~ 자동으로 feat: husky test[DIAR-92] feat: husky test가 된다.

Jira에서 한눈에 커밋 추적 가능!


4. 개발 환경 설정

각자의 코딩 스타일이 다르기 때문에 일정한 코드 형식과 퀄리티를 유지하기 위해서는 ESLint와 Prettier가 필요하다. 그렇지만서도 그렇게 막 빡세게 잡을 건 아니여서, 기본 Lint와 일반적인 Prettier Config만 잡고 갔다.

ESLint + Prettier

Prettier Config

{
  "singleQuote": true,
  "semi": true,
  "useTabs": false,
  "tabWidth": 2,
  "printWidth": 120,
  "bracketSpacing": true,
  "endOfLine": "auto"
}

ESLint Config

ESLint는 코드의 퀄리티를 위한 것인데, 여기 규칙에 Prettier를 넣어줄 수 있다. 이를 위해서는 여러가지 플러그인을 설치해줬어야 했는데, 결론적으론 plugin:prettier/recommended 요것만 해주면 된다.

module.exports = {
  root: true,
  env: { browser: true, es2020: true },
  extends: [
    'eslint:recommended',
    'plugin:@typescript-eslint/recommended',
    'plugin:react-hooks/recommended',
    'plugin:prettier/recommended',
  ],
  ignorePatterns: ['dist', '.eslintrc.cjs'],
  parser: '@typescript-eslint/parser',
  plugins: ['react-refresh'],
  rules: {
    'react-refresh/only-export-components': ['warn', { allowConstantExport: true }],
  },
};

이렇게하면~ 협업 설정 끝!


협업 진행 순서

혼자서 할 땐 손이 가는 대로 막했지만, 같이 하니까 순서가 생기더라. 나름대로 정리해본 순서다.

1. PM의 작업 할당

PM은 전체적인 프로젝트 진행을 관리하는 사람! 그래서 회의를 통해 결정된 사항을 작업으로 나누고 할당해준다. 세세하게까진 아니고, 화면/기능 단위로 에픽을 만들고 그 아래에 각 팀별로 작업을 할당하는 정도. MY일기장/기획, MY일기장/프론트, ... 이런 식으로.

2. 작업 목록 생성 및 분담 협의

그러면 이제 각자 팀별로 해당 기능에 대해 어떤 작업을 해야하는지 파악한다. 예를 들어 MY일기장에 들어가는 컴포넌트들이라든가, 기능이라든가, UI라든가 등등. 어떤 게 필요한지 먼저 이야기를 나눈 후 업무를 나눈다. 나눈 다음엔 각자 하위 이슈를 만들어 진행한다.

3. Github Issue 생성

Github Issue에 현재 들어갈 기능에 대해서 이슈를 만든다. 해당 기능에 대해서 또 어떤 걸 구현해야하는지 정도 적어주면 좋다. 물론, 이대로 지킬 필욘 없고 이정도이겠다~ 정도여도 된다. 포인트는 전체적인 그림이다.

4. Jira Task Status 변경

Github Action에 연결해두었기에 Task와 Branch가 생겼다. 그러면 이제 Jira로 가서 Task를 작업중으로 바꾼다.

5. 개발 진행

브랜치 땡겨와서 작업한다. 중간중간 커밋 많이하기! 나중에 스쿼시해도 되니까 한 꼭지가 끝나면 커밋하는 습관을 기르자. 기능 개발이 완료 되면 push하기 전에 develop에서 땡겨와 다른 작업자가 추가했을지도 모르는 코드를 가져오고, 티켓 브런치에 push한다.

6. PR 요청

그리고 develop에 PR요청을 한다. 리뷰어로 팀원을 선택하고 코드리뷰를 부탁한다. 확인하면 상대방이 머지하고, 아니면 required change를 선택! required를 받으면 로컬에서 다시 수정후 푸시한다. 그러면 해당 PR이 자동으로 업데이트 된다. 그러면 다시 리뷰를 요청하면 된다.


혼자서 진행했을 땐 의아했던 부분들이 확실히 정리가 됐다. Branch를 나눠서 개발을 한다거나, Ticket Number라는 걸 왜 사용하는 건지, Commit Convention을 왜 해야하는지 등등! 모든 건 혼자 하면 의미가 없고, 같이 하기 때문에 정하는 거다. 당연하게도!

profile
FE개발자 가보자고🥳

5개의 댓글

comment-user-thumbnail
2024년 5월 10일

좋은 글 감사합니다 :D
상세하게 작성해주셔서 많이 배우고 갑니다~

답글 달기
comment-user-thumbnail
2024년 5월 22일

이슈 생성하면 jira 에서 이슈생성되게 하고 싶었는데 자세한 글 넘넘 감사합니다!

답글 달기
comment-user-thumbnail
2024년 7월 9일

좋은 글 감사합니다! 덕분에 지라 이슈 자동 생성 성공했습니다 ㅎㅎ!

답글 달기
comment-user-thumbnail
2024년 7월 18일

안녕하세요 좋은글 정말 감사합니다! 글 읽으며 한가지 궁금한 점이 생겼는데 혹시 프로젝트 진행하며 지라와 깃헙에서 동시에 이슈 관리를 한 이유가 있을까요?

1개의 답글