Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FE] 모노레포 환경 설정에 따른 workflow 변경 #535

Closed
wants to merge 1 commit into from

Conversation

Todari
Copy link
Contributor

@Todari Todari commented Aug 29, 2024

issue

구현 사항

1. lerna를 이용한 CI 수정

client/package.json의 스크립트는 아래와 같습니다.

// client/packag.json
...
"scripts": {
    "start": "npx lerna run build:watch --scope=haengdong-design --parallel & npx lerna run dev --scope=haengdong-client --parallel",
    "build": "npx lerna run build",
    "lint": "npx lerna run lint",
    "test": "npx lerna run test --scope=haengdong-client",
    "e2e": "npx lerna run cypress-run --scope=haengdong-client",
    "storybook": "npx lerna run storybook --scope=haengdong-design",
    "ci:versionup:patch": "npx lerna version patch --no-push --no-git-tag-version --yes && npm run commit-version",
    "ci:versionup:minor": "npx lerna version minor --no-push --no-git-tag-version --yes && npm run commit-version",
    "ci:versionup:major": "npx lerna version major --no-push --no-git-tag-version --yes && npm run commit-version",
    "commit-version": "git add . && git commit -m \"chore(release): v`node -p 'require(\"./lerna.json\").version'`\"",
    "release": "npx lerna publish from-package",
    "ci:release": "npx lerna publish from-package --yes",
    "graph": "npx nx graph"
  },
  ...

npx lerna run ~~ 명령어를 실행시키면 packages 내부의 모든 패키지에서 npm run ~~ 을 실행시킵니다. npx lerna run lint를 예로 들면 client에서도, design에서도 모두 npm run lint를 실행시킵니다. --scope=package-name을 사용하면 범위를 지정할 수 있습니다.

lerna를 이용하여 /client 경로에서도 내부의 haengdong-client, haengdong-design의 테스트 및 빌드를 한번에 진행할 수 있습니다.
따라서, workflow도 clientdesign 모두 일괄적으로 테스트 할 수 있도록 변경하였습니다.

name: Client Pull Request

on:
  pull_request:
    types: [opened, synchronize]
    branches: [main, fe-dev]
    paths:
      - 'client/**'

jobs:
  test:
    runs-on: ubuntu-latest

    defaults:
      run:
        shell: bash
        working-directory: ./client

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20.15.1'

      - name: Install dependencies
        run: npm install

      - name: Run build
        run: npm run build

      - name: Run lint
        run: npm run lint

      - name: Run test
        run: npm run test

      - name: Cypress test
        run: npm run e2e

2. lerna를 이용한 디자인시스템 릴리즈 PR 생성 CI

fe-dev branch에 버전을 신경쓰지 않고 계속 merge한 뒤 main 브랜치로 release할 때, 해당 workflow를 실행하면 release에 대한 pr이 생성됩니다.

이는 main에 merge되어야 적용되므로 별도로 main으로 향하는 PR을 만들겠습니다.

name: Design System Pull Request

on:
  workflow_dispatch:
    inputs:
      semver:
        description: 'New Version(semver)'
        required: true
        default: 'patch'
        type: choice
        options:
          - patch
          - minor
          - major

permissions:
  contents: write # 체크아웃과 commit을 위해 필요합니다.
  pull-requests: write  # PR 생성을 위해 필요합니다.

jobs:

  chromatic:
    name: Run Chromatic
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20.15.1'

      - name: Cache dependencies
        id: cache
        uses: actions/cache@v3
        with:
          path: '**/node_modules'
          key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ runner.os }}-npm-

      - name: Install dependencies
        if: steps.cache.outputs.cache-hit != 'true'
        run: |
          cd client
          npm install

      - name: Run Chromatic
        uses: chromaui/action@latest
        id: publish_chromatic
        with:
          workingDir: client/packages/haengdong-design
          projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}

      - name: Comment on PR
        uses: thollander/actions-comment-pull-request@v2
        with:
          message: '🚀 **storybook**: ${{ steps.publish_chromatic.outputs.storybookUrl }}'

  create-release-pr:
    name: Create Release PR
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: ./client
    steps:
      - name: checkout
        uses: actions/checkout@v3
      - name: Update Version
       
        # git의 정보를 불러오고, ci:versionup 스크립트를 통해 npx lerna version 을 실행합니다. 처음 workflow를 실행 할 때 선택한 SEMVER(patch, minor, major)가 적용됩니다.
        run: |
          git config --global user.email "${GIT_AUTHOR_EMAIL}"
          git config --global user.name "${GIT_AUTHOR_NAME}"
          npm run ci:versionup:${SEMVER} --yes
        env:
          SEMVER: ${{ github.event.inputs.semver }}
          GIT_AUTHOR_NAME: ${{ github.actor }}
          GIT_AUTHOR_EMAIL: ${{ github.actor }}@users.noreply.github.com

		# lerna.json을 통해서 현재 버전을 확인합니다.
      - name: Set PACKAGE_VERSION
        run: echo "PACKAGE_VERSION=$(cat lerna.json | jq -r .version)" >> $GITHUB_ENV
        
        # github release note를 작성합니다. 위에서 알아낸 package version을 이용합니다.
      - name: Set GitHub Release Note
        id: release_note
        uses: actions/github-script@v6
        with:
          script: |
            const result = await exec.getExecOutput(`gh api "/repos/{owner}/{repo}/releases/generate-notes" -f tag_name="v${process.env.PACKAGE_VERSION}" --jq .body`, [], {
              ignoreReturnCode: true,
            })
            core.setOutput('stdout', result.stdout)
        env:
          PACKAGE_VERSION: ${{ env.PACKAGE_VERSION }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - name: Create Pull Request
        id: cpr
        uses: peter-evans/create-pull-request@v4
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          commit-message: "chore(release): v${{ env.PACKAGE_VERSION }}"
          committer: GitHub <[email protected]>
          author: ${{ github.actor }} <${{ github.actor }}@users.noreply.github.com>
          assignees: ${{ github.actor }}
          signoff: false
          branch: release/${{ env.PACKAGE_VERSION }}
          branch-suffix: timestamp
          delete-branch: true
          title: 'v${{ env.PACKAGE_VERSION }}'
          body: |
            ${{ steps.release_note.outputs.stdout }}
            '🚀 **storybook**: ${{ steps.publish_chromatic.outputs.storybookUrl }}'
          labels: "Type: Release"
      - name: Check Pull Request
        run: |
          echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}"
          echo "Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}"

image

위 workflow를 이용해 release PR을 만들었습니다. 해당 PR을 확인하고, main에 merge하게 된다면 아래와 같은 workflow가 작동합니다.

name: Design System Release

on:
  pull_request:
    branches:
      - main
    types: [ closed ]
  workflow_dispatch: # 강제로도 릴리즈 할 수 있도록 diapatch 존재

jobs:
  check:
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: ./client
    permissions:
      contents: read
    if: github.event.pull_request.merged == true || github.event_name == 'workflow_dispatch'
    outputs:
      EXISTS_TAG: ${{ steps.tag_check.outputs.EXISTS_TAG }}
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Set PACKAGE_VERSION
        run: echo "PACKAGE_VERSION=$(cat lerna.json | jq -r .version)" >> $GITHUB_ENV

		# 현재 브랜치에 version Tag가 존재하는지 확인합니다.
      - name: Tag Check
        id: tag_check
        run: |
          GET_API_URL="https://api.github.com/repos/${GITHUB_REPOSITORY}/git/ref/tags/${TAG_NAME}"
          http_status_code=$(curl -LI $GET_API_URL -o /dev/null -w '%{http_code}\n' -s \
            -H "Authorization: token ${GITHUB_TOKEN}")
          if [ "$http_status_code" -ne "404" ] ; then
            echo "EXISTS_TAG=true" >> $GITHUB_OUTPUT
          else
            echo "EXISTS_TAG=false" >> $GITHUB_OUTPUT
          fi
        env:
          TAG_NAME: v${{ env.PACKAGE_VERSION }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

  release:
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: ./client
    needs: check
	# 위에서 확인한 태그가 없는 경우에만 실행합니다.
    if: always() && (needs.check.outputs.EXISTS_TAG == 'false')
    permissions:
      contents: write
      issues: write
      pull-requests: write
      packages: write
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Setup Node
        uses: actions/setup-node@v3
        with:
          node-version: '20.15.1'
          registry-url: 'https://registry.npmjs.org'
      - name: Git Identity
        run: |
          git config --global user.name 'github-actions[bot]'
          git config --global user.email 'github-actions[bot]@users.noreply.github.com'
          git remote set-url origin https://x-access-token:${GITHUB_TOKEN}@github.com/$GITHUB_REPOSITORY
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

		# lerna.json을 통해서 package version을 확인합니다.
      - name: Set PACKAGE_VERSION
        run: echo "PACKAGE_VERSION=$(cat lerna.json | jq -r .version)" >> $GITHUB_ENV
      - name: Install
        run: npm install
      - name: Publish
		# ci:release 스크립트로 npx lerna publish를 실행시킵니다.
        run: npm run ci:release
        env:
        # 배포를 위한 npm token을 활용합니다.
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
		# 버전 변경을 담은 github tag를 설정합니다.
      - name: Create Git Tag
        uses: pkgdeps/git-tag-action@v2
        with:
          version: ${{ env.PACKAGE_VERSION }}
          github_token: ${{ secrets.GITHUB_TOKEN }}
          github_repo: ${{ github.repository }}
          git_commit_sha: ${{ github.sha }}
          git_tag_prefix: "v"
        # github release를 생성합니다.
      - name: Create Release
        id: create_release
        uses: softprops/action-gh-release@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tag_name: v${{ env.PACKAGE_VERSION }}
          # Copy Pull Request's tile and body to Release Note
          name: ${{ github.event.pull_request.title }}
          body: ${{ github.event.pull_request.body }}
          draft: false
          prerelease: false
          generate_release_notes: ${{ !github.event.pull_request.body }}
      - uses: actions/github-script@v6
        if: github.event_name != 'workflow_dispatch'
        with:
          github-token: ${{secrets.GITHUB_TOKEN}}
          script: |
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: '🎉 Release https://github.com/${{ github.repository }}/releases/tag/v${{ env.PACKAGE_VERSION }}'
            })

@Todari Todari added this to the lev4 milestone Aug 29, 2024
@Todari Todari self-assigned this Aug 29, 2024
@Todari Todari linked an issue Aug 29, 2024 that may be closed by this pull request
1 task
Copy link

Test Results

 23 files   23 suites   3s ⏱️
120 tests 120 ✅ 0 💤 0 ❌
122 runs  122 ✅ 0 💤 0 ❌

Results for commit 78db03e.

Copy link
Contributor

@jinhokim98 jinhokim98 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생했어요~~~ 덕분에 행동 디자인을 편하게 배포할 수 있을 것 같아요. (돌려봐야하겠지만)
방학 중에 고생 많았어요 :)

Comment on lines +7 to +14
description: 'New Version(semver)'
required: true
default: 'patch'
type: choice
options:
- patch
- minor
- major
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

client release로 행동디자인과는 다른 부분인 것 같은데 시멘틱 버저닝을 관리하기 위해서 patch, minor, major를 추가한 것일까요?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

두가지를 한번에 client 라고 묶어놨어요. 두개가 모두 같은 버전으로 반영될거에요~

GIT_AUTHOR_NAME: ${{ github.actor }}
GIT_AUTHOR_EMAIL: ${{ github.actor }}@users.noreply.github.com
- name: Set PACKAGE_VERSION
run: echo "PACKAGE_VERSION=$(cat lerna.json | jq -r .version)" >> $GITHUB_ENV
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 깃헙 env는 개인마다 따로 가지고 있어야하나요?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아뇽 여기선 workflow dispatch를 한 사람의 정보가 자동으로 들어갑니다~!

uses: actions/github-script@v6
with:
script: |
const result = await exec.getExecOutput(`gh api "/repos/{owner}/{repo}/releases/generate-notes" -f tag_name="v${process.env.PACKAGE_VERSION}" --jq .body`, [], {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기도 PACKAGE_VERSION이 있는데 어떤 값을 넣어두면 되는지 공유부탁드려요~

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

값을 넣는게 아니라, 위의 STEP에서 lerna.json 을 통해 가져온 값이 process.env로 저장되는 것입니다~

      - name: Set PACKAGE_VERSION
        run: echo "PACKAGE_VERSION=$(cat lerna.json | jq -r .version)" >> $GITHUB_ENV
``

Comment on lines +54 to +66
- name: Checkout
uses: actions/checkout@v3
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: '20.15.1'
registry-url: 'https://registry.npmjs.org'
- name: Git Identity
run: |
git config --global user.name 'github-actions[bot]'
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
git remote set-url origin https://x-access-token:${GITHUB_TOKEN}@github.com/$GITHUB_REPOSITORY
env:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 코드로 인해서 행동 디자인이 자동 배포 되는걸까요?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분을 말씀하시는 거라면, 이 부분은 단지 github 정보를 넣어주는 프로세스입니다!

# === `echo "${ registry-url }/:_authToken=${ NODE_AUTH_TOKEN }" > .npmrc`
# NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} # [EXAMPLE]
# for publishing packages to npm
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기는 github repo에 시크릿으로 설정해주신거죠?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

맞습니다~!

@Todari
Copy link
Contributor Author

Todari commented Sep 6, 2024

모노레포 적용 재 논의가 필요하여 close 합니다

@Todari Todari closed this Sep 6, 2024
@Todari Todari modified the milestones: lev4, v2.0.0 Sep 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: ✅ Done
Development

Successfully merging this pull request may close these issues.

[FE] 모노레포 환경 설정에 따른 workflow 변경
2 participants