1분기 개발팀 이니셔티브 중 하나인 형상 관리 표준화 및 전파
작업! 주요 내용은
이다.
깃 전략 및 깃허브 워크플로우 전략 등이
해당 이니셔티브를 진행하게 되었다.
그 중 Web Workflow 표준화 작업을 담당하게 되어 작업 히스토리와 결과 산출물을 기록해본다
name: (서비스명) deploy-prod
on:
push:
branches:
- main # 배포 브랜치
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup Environment
uses: pnpm/action-setup@v3
with:
version: 8
- name: Install Dependencies
uses: actions/setup-node@v3
with:
node-version: '18.x' # node-version-file: '.nvmrc'
- name: Build
run: |
pnpm i
pnpm build
# 슬랙 알림
slack_notifications:
runs-on: ubuntu-latest
# 배포 결과 슬랙 알림
steps:
- name: Notify Deployment Failure
if: ${{ failure() }}
uses: slackapi/slack-github-action@v1.23.0
with:
payload: |
{
"attachments": [
{
"title": "❌ 배포 실패했습니다 🥲",
"author_name": "${{github.actor}} 님의 배포 에러 😱",
"color": "danger",
"fields": [
{
"title": "Branch",
"value": "${{github.ref}}",
"short": true
},
{
"title": "Event",
"value": "${{github.event_name}}",
"short": true
},
{
"title": "Actions URL",
"value": "<${{github.server_url}}/${{github.repository}}/commit/${{github.sha}}/checks|${{github.workflow}}>",
"short": true
},
{
"title": "Commit",
"value": "<${{github.server_url}}/${{github.repository}}/commit/${{github.sha}}|Commit Link>",
"short": true
},
{
"title": "Message",
"value": "${{github.event.head_commit.message}}",
"short": false
}
]
}
]
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
- name: Notify Deployment Success
uses: slackapi/slack-github-action@v1.23.0
with:
payload: |
{
"attachments": [
{
"title": "✅ 배포 완료되었습니다! 👍",
"author_name": "${{github.actor}} 님! 성공적으로 배포되었습니다.🎉",
"color": "adff2f",
"fields": [
{
"title": "Branch",
"value": "${{github.ref}}",
"short": true
},
{
"title": "Event",
"value": "${{github.event_name}}",
"short": true
},
{
"title": "Actions URL",
"value": "<${{github.server_url}}/${{github.repository}}/commit/${{github.sha}}/checks|${{github.workflow}}>",
"short": true
},
{
"title": "Commit",
"value": "<${{github.server_url}}/${{github.repository}}/commit/${{github.sha}}|Commit Link>",
"short": true
},
{
"title": "Message",
"value": "${{github.event.head_commit.message}}",
"short": false
}
]
}
]
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
# 배포 후 릴리즈 태그 생성
release:
needs: deploy # deploy 성공하면 실행해라
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
# package.json에서 버전 정보 추출
- name: Get Package.json Info
id: info
uses: jaywcjlove/github-action-package@main
- run: echo "version - ${{ steps.info.outputs.version }}"
- name: Get Latest Release Tag
uses: actions-ecosystem/action-get-latest-tag@v1
id: get-latest-tag
with:
semver_only: true
- name: Create Release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ steps.info.outputs.version }}
release_name: ${{ steps.info.outputs.version }}
body: |
${{ github.event.head_commit.message }}
**Full Changelog**: https://github.com/${{ github.repository }}/compare/${{ steps.get-latest-tag.outputs.tag }}...${{ steps.info.outputs.version }}
# release, hotfix 배포 후 개발 배포도 동시에 되게끔 develop 브랜치에 머지
back-merge-to-develop:
needs: deploy # deploy 성공하면 실행해라
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Merge main → develop
uses: devmasx/merge-branch@master
with:
type: now
from_branch: main
target_branch: develop # 개발 배포 브랜치
github_token: ${{ secrets.GITHUB_TOKEN }}
# Github Flow 전략에선 release 브랜치가 불필요한 경우가 많다.
# 따라서 아예 분기하지 않는 경우가 일반적이다.
# ...
# develop 브랜치에 머지
back-merge-to-develop:
needs: deploy # deploy 성공하면 실행해라
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Merge main → develop
uses: devmasx/merge-branch@master
with:
type: now
from_branch: main # merge 시작할 브랜치
target_branch: develop # 개발 배포 브랜치
github_token: ${{ secrets.GITHUB_TOKEN }}
# hotfix PR merge 후 배포 브랜치 merge 후 배포
# Github Flow 전략에선 hotfix를 사소한 기능 변화로 바라본다.
# 마찬가지로 아예 분기하지 않는 경우가 많다.
# ...
# develop 브랜치에 머지
back-merge-to-develop:
needs: deploy # deploy 성공하면 실행해라
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Merge main → develop
uses: devmasx/merge-branch@master
with:
type: now
from_branch: main # merge 시작할 브랜치
target_branch: develop # 개발 배포 브랜치
github_token: ${{ secrets.GITHUB_TOKEN }}
# 모든 PR 체크
name: Check PR
on: [pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup Environment
uses: pnpm/action-setup@v3
with:
version: 8
- name: Install Dependencies
uses: actions/setup-node@v3
with:
node-version: '18.x' # node-version-file: '.nvmrc'
- name: Check Lint
run: |
pnpm i
pnpm lint
env:
CI: true
# 테스트 코드 실행 결과 보여주기
- name: Run Tests and Create Comment
uses: actions/github-script@v6
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const script = require('./test-result-commit.js')
console.log(script({github, context}))
# 결과 슬랙 알림
- name: Notify PR🎁 Check Failure
if: ${{ failure() }}
uses: slackapi/slack-github-action@v1.23.0
with:
payload: |
{
"attachments": [
{
"title": "❌ ${{ github.event.pull_request.title }} << 다시 확인해주세요! 🥲",
"author_name": "${{github.actor}} 님의 PR 에러 발생 😱",
"color": "danger",
"fields": [
{
"title": "Title",
"value": "${{ github.event.pull_request.title }}",
"short": true
},
{
"title": "Actions URL",
"value": "<${{github.server_url}}/${{github.repository}}/commit/${{github.sha}}/checks|${{github.workflow}}>",
"short": true
},
{
"title": "Commit",
"value": "<${{github.server_url}}/${{github.repository}}/commit/${{github.sha}}|Commit Link>",
"short": true
},
{
"title": "Message",
"value": "${{github.event.pull_request.html_url}}",
"short": false
}
]
}
]
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
- name: Notify PR🎁 Check Success
uses: slackapi/slack-github-action@v1.23.0
with:
payload: |
{
"attachments": [
{
"title": "PR🎁: ${{ github.event.pull_request.title }}",
"author_name": "${{github.actor}} 님의 PR🎉",
"color": "adff2f",
"fields": [
{
"title": "Commit",
"value": "<${{github.server_url}}/${{github.repository}}/commit/${{github.sha}}|Commit Link>",
"short": true
},
{
"title": "Message",
"value": "${{github.event.pull_request.html_url }}",
"short": false
}
]
}
]
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
💡 테스트 코드가 통과해야 merge 가능하도록 Github repository 설정하기
Repository Settings
→ Branches
→ Add rule
을 선택
Branch name pattern
을 설정하고 Require status checks to pass before merging
설정을 통해 merge를 위해 통과해야할 Action들을 선택할 수 있다
release/1.0.0
생성# 브랜치로 태그 생성
name: Release Tag
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: 버전 정보 추출
run: echo "##[set-output name=version;]$(echo '${{ github.event.head_commit.message }}' | egrep -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}')"
id: extract_version_name
- name: Release 생성
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ steps.extract_version_name.outputs.version }}
release_name: ${{ steps.extract_version_name.outputs.version }}
# package.json의 version 정보로 태그 생성
name: Create Release Tag
on:
push:
branches:
- main
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
# package.json에서 버전 정보 추출
- name: package.json info
id: info
uses: jaywcjlove/github-action-package@main
- run: echo "version - ${{ steps.info.outputs.version }}"
- name: Get latest release tag
uses: actions-ecosystem/action-get-latest-tag@v1
id: get-latest-tag
with:
semver_only: true
- name: Create Release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ steps.info.outputs.version }}
release_name: ${{ steps.info.outputs.version }}
body: |
${{ github.event.head_commit.message }}
**Full Changelog**: https://github.com/${{ github.repository }}/compare/${{ steps.get-latest-tag.outputs.tag }}...${{ steps.info.outputs.version }}
PR 시 공통: Style, UnitTest (각 단계마다 범위가 강화되는)
# 모든 PR lint 체크
name: Check PR
on: [pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
# pnpm 아닌 경우 제거
- name: Setup pnpm
uses: pnpm/action-setup@v3
with:
version: 8
- name: Node.js Setting
uses: actions/setup-node@v3
with:
node-version: '18.x'
- name: Check
run: |
pnpm i
pnpm lint
env:
CI: true
테스트 결과도 확인해야 하고
# 테스트 코드 실행
- name: Run tests
run: |
pnpm test
- name: Publish Unit Test Results
uses: EnricoMi/publish-unit-test-result-action@v1
if: ${{ always() }} # 테스트가 실패하여도 Report를 보기 위해 `always`로 설정
with:
files: build/test-results/**/*.xml
- name: 테스트 커버리지 결과 PR에 코멘트 추가하기
if: always()
uses: ArtiomTr/jest-coverage-report-action@v2
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
back-merge-to-develop:
needs: build # deploy 성공하면 실행해라
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Merge main → develop
uses: devmasx/merge-branch@master
with:
type: now
from_branch: main
target_branch: develop # TODO: 브랜치 전략 확인 후 수정
github_token: ${{ secrets.GITHUB_TOKEN }}
# package.json의 version 정보로 태그 생성
name: Create Release Tag
on:
workflow_run:
workflows: ['deploy'] # deploy workflow 후 실행
branches: [main]
types: [completed]
jobs:
release:
if: ${{ github.event.workflow_run.conclusion == 'success' }} # 성공했을 때
runs-on: ubuntu-latest
#...
back-merge-to-develop:
needs: build # deploy 성공하면 실행해라
runs-on: ubuntu-latest