๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ–ฅ๏ธ ๋ฐฑ์—”๋“œ/CICD

[CICD] ๊ธฐ์ดˆ ์‹œ๋‚˜๋ฆฌ์˜ค ๊นƒํ—™ ์•ก์…˜

by OR15A 2024. 3. 23.
๊นƒํ—™์•ก์…˜ ์ฝ”๋“œ ์˜ค๋ฅ˜ ๊ฒ€์‚ฌ ์‚ฌ์ดํŠธ
 

actionlint playground

Loading WebAssembly binary... Yay! No error was detected.

rhysd.github.io

 

 

๊ฐ•์˜ ์‹œ๋‚˜๋ฆฌ์˜ค 3
  • ํ˜„์žฌ ํ”„๋กœ์ ํŠธ์— ํˆฌ์žํ•  ์ˆ˜ ์žˆ๋Š” ์‹œ๊ฐ„์„ ๊ณ ๋ คํ•ด์„œ ์ผ๋‹จ ๊ฐ„๋‹จํ•œ CICD๋ฅผ ์ ์šฉํ•ด๋ณด๊ธฐ ์œ„ํ•ด ์‹œ๋‚˜๋ฆฌ์˜ค 3์„ ์„ ํƒํ•จ
  • ๊ฐ€์ •
    • ๊ฐœ๋ฐœํ™˜๊ฒฝ, QA, ์šด์˜ํ™˜๊ฒฝ์˜ CICD ๊ตฌ์„ฑ
  • branch
    • dev : ๊ฐœ๋ฐœํ™˜๊ฒฝ
    • master : ์šด์˜ํ™˜๊ฒฝ
  • QA
    • ํ…Œ์ŠคํŠธ๋ฅผ ํ†ตํ•ด ์†Œํ”„๋ฅด์›จ์–ด ๊ฒฐํ•จ ์‹๋ณ„ํ•˜๊ธฐ
    • ์ฝ”๋“œ์˜ ํ’ˆ์งˆ๊ณผ ๊ธฐ๋Šฅ์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€ ๊ฒ€์ฆํ•จ
  • ๋ฐฐํฌ์ˆœ์„œ
    • 1. ๊ฐœ๋ฐœ ํ™˜๊ฒฝ (dev branch)
    • 2. QA ํ™˜๊ฒฝ
    • 3. ์šด์˜ ํ™˜๊ฒฝ (master branch)
  • ๊ธฐ์กด ์š”๊ตฌ์‚ฌํ•ญ
    • ํŠน์ • path์— ๋Œ€ํ•ด์„œ๋งŒ ์‹คํ–‰
    • dev, master branch๋กœ PR์ด ์ƒ์„ฑ&๋™๊ธฐํ™” ๋  ๋•Œ ํ…Œ์ŠคํŠธ ์ž‘์—… ์‹คํ–‰ [CI]
    • PR์ด dev branch์— ๋จธ์ง€๋˜๋ฉด, ์ด๋ฏธ์ง€๋ฅผ ๋นŒ๋“œํ•˜๊ณ  ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์— ๋ฐฐํฌ [CD]  
    • ํ•„์š”ํ•œ ์‹œ์ ์— QA ํ™˜๊ฒฝ์— ๋ฐฐํฌ [CD] (Tag ์ด๋ฒคํŠธ๋กœ ๋ฐœ์ƒ)
    • QA ๋ฐฐํฌ Tag๋ฅผ ์ด๋ฆ„์œผ๋กœ ํ•˜๋Š” Release ๋ธŒ๋žœ์น˜ ์ƒ์„ฑ -> master๋กœ PR
    • PR์ด master branch์— ๋จธ์ง€๋˜๋ฉด, ์ด๋ฏธ์ง€๋ฅผ ๋นŒ๋“œํ•˜๊ณ  ์šด์˜ ํ™˜๊ฒฝ์— ๋ฐฐํฌ [CD]
    • ๋ฐฐํฌ ์„ฑ๊ณต ์—ฌ๋ถ€๋ฅผ ์Šฌ๋ž™์œผ๋กœ ์ „์†กํ•จ

  • Tag๋ฅผ ์ด์šฉํ•˜๋Š” ์ด์œ 
    • ํ•„์š”ํ•œ ์‹œ์ ์— ๋ฐฐํฌํ•˜๊ธฐ ์œ„ํ•ด์„œ
    • ๋กค๋ฐฑ์„ ๊ณ ๋ คํ•˜๊ธฐ ์œ„ํ•ด์„œ : ํƒœ๊ทธ๋Š” ํŠน์ • ์ปค๋ฐ‹์„ ๋ช…ํ™•ํ•˜๊ฒŒ ์ฐธ์กฐํ•จ

ํƒœ๊ทธ ์‚ฌ์šฉ = ๋ช…์‹œ์ ์ธ ๋ฐฐํฌ ํฌ์ธํŠธ

 

 

 

๊ฐ•์˜ ์‹œ๋‚˜๋ฆฌ์˜ค3 ์˜ˆ์‹œ
  • ๋‚ด ํ”„๋กœ์ ํŠธ์— ๋งž๊ฒŒ ์ˆ˜์ •ํ•ด์•ผํ•จ
name: cicd-3
on:
  push:
    paths:
    - 'my-app/**'
    tags:
    - 'v[0-9]+.[0-9]+.[0-9]+'
  pull_request:
    types: [opened, synchronize, closed]
    branches: [dev, master]
    paths:
    - 'my-app/**'

jobs:
  test:
    if: github.event.action == 'opened' || github.event.action == 'synchronize'
    runs-on: ubuntu-latest
    steps:
    - name: checkout the code
      uses: actions/checkout@v4
    - name: setup-node
      uses: actions/setup-node@v3
      with:
        node-version: 18
    - name: Cache Node.js modules
      uses: actions/cache@v3
      with:
        path: ~/.npm
        key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
        restore-keys: |
          ${{ runner.os }}-node-
    - name: Install dependencies
      run: |
        cd my-app
        npm ci
    - name: npm build
      run: |
        cd my-app
        npm run build

  set-environment:
    if: github.event.pull_request.merged == true || github.ref_type == 'tag'
    runs-on: ubuntu-latest
    outputs:
      environment: ${{ steps.set-env.outputs.environment }}
    steps:
    - name: set env
      id: set-env
      run: |
        if [[ ${{ github.ref_type }} == "tag" ]]; then
          echo "environment=qa" >> $GITHUB_OUTPUT 
          exit 0
        fi
        
        if [[ ${{ github.ref_type }} == "branch" ]]; then
          echo "environment=dev" >> $GITHUB_OUTPUT
          if [[ ${{ github.base_ref }} == "master" ]]; then
            echo "environment=prod" >> $GITHUB_OUTPUT 
          fi
        fi
    - name: check env
      run: echo ${{ steps.set-env.outputs.environment }}


  image-build:
    runs-on: ubuntu-latest
    needs: [set-environment]
    permissions:
      id-token: write
      contents: read
    strategy:
      matrix:
        environment: ["${{ needs.set-environment.outputs.environment }}"]
    environment: ${{ matrix.environment }}
    steps:
    - name: checkout the code
      uses: actions/checkout@v4
    - name: Configure AWS Credentials
      id: credentials
      uses: aws-actions/configure-aws-credentials@v4
      with:
        aws-region: ${{ vars.AWS_REGION }}
        role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }}
    - name: Login to Amazon ECR
      id: login-ecr
      uses: aws-actions/amazon-ecr-login@v2
      with:
        mask-password: 'true'
    - name: docker build & push
      run: |
        docker build -f Dockerfile --tag ${{ secrets.REGISTRY }}/${{ vars.REPOSITORY }}:${{ github.sha }} .
        docker push ${{ secrets.REGISTRY }}/${{ vars.REPOSITORY }}:${{ github.sha }}
  
  deploy:
    runs-on: ubuntu-latest
    needs: [ set-environment, image-build ]
    permissions:
      id-token: write
      contents: read
    strategy:
      matrix:
        environment: ["${{ needs.set-environment.outputs.environment }}"]
    environment: ${{ matrix.environment }}  
    steps:
    - name: checkout the code
      uses: actions/checkout@v4
    - name: Configure AWS Credentials
      id: credentials
      uses: aws-actions/configure-aws-credentials@v4
      with:
        aws-region: ${{ vars.AWS_REGION }}
        role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }}
    - name: setup kubectl
      uses: azure/setup-kubectl@v3
      with:
        version: latest
    - name: setup helm
      uses: azure/setup-helm@v3
      with:
        version: v3.11.1
    - name: access kubernetes
      run: |
        aws eks update-kubeconfig --name ${{ vars.CLUSTER_NAME }}
    - name: deploy
      id: status
      run: |
        helm upgrade --install my-app kubernetes/my-app --create-namespace --namespace my-app-${{ vars.SUFFIX }} \
        --set image.tag=${{ github.sha }} \
        --set image.repository=${{ secrets.REGISTRY }}/${{ vars.REPOSITORY }}
    - name: notify
      if: always()
      uses: slackapi/slack-github-action@v1.24.0
      with:
        payload: |
          {
            "text": "message",
            "blocks": [
              {
                "type": "section",
                "text": {
                  "type": "mrkdwn",
                  "text": "Environment : ${{ matrix.environment }}, Deploy Result : ${{ steps.status.outcome }}, Repository : ${{ github.repository }}."
                }
              }
            ]
          }
      env:
        SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
        SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK

  create-pr:
    if: needs.set-environment.outputs.environment == 'qa'
    runs-on: ubuntu-latest
    needs: [set-environment, deploy]
    steps:
    - name: checkout
      uses: actions/checkout@v4
    - name: gh auth login
      run: |
        echo ${{ secrets.PERSONAL_ACCESS_TOKEN }} | gh auth login --with-token
    - name: create branch
      run: |
        git checkout -b release/${{ github.ref_name }}
        git push origin release/${{ github.ref_name }}
    - name: create pr
      run: |
        gh pr create --base master --head release/${{ github.ref_name }} --title "release/${{ github.ref_name }} -> master" --body "release pr"

 

 

 

  • ์•„์ง ์ต์ˆ™ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋‚ด ํ”„๋กœ์ ํŠธ๋Š” 4๊ฐ€์ง€์˜ ์‹œ๋‚˜๋ฆฌ์˜ค ์ค‘, 3๋ฒˆ์งธ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ๋”ฐ๋ฅด๋Š” ๊ฒƒ์œผ๋กœ ์„ ํƒํ•˜์˜€๋‹ค.
  • ์ฒœ์ฒœํžˆ ๋„์ž…ํ•ด๋ด์•ผ๊ฒ ๋‹ค ใ…Žใ…Ž