2022 오픈소스 컨트리뷰션 아카데미 "NHN Toast Power Platform Connector" 프로젝트에 참여하면서 Challengers 기간 동안 배운 내용을 기록하였습니다.
github-actions-from-scratch를 추가로 공부하면서 기록하였습니다.
Github actions를 추가로 공부하면서 기록하였습니다.
DevOps 방법론에서 나온 말임!!
코드 작성, test, 빌드, 사용자에게 배포, 버그를 고치는 모든 과정에서는 cycle이 존재한다!(버그 고치려면 코드 작성 다시 해야 하니까!) -> 그러나 이런 과정은 자주 발생한다.
❗ 코드, 빌드, test 부분을 자동화(workflow Automation)해서 cycle이 좀 더 짧은 주기를 갖게 하는 것! ❗
코드, 빌드, 테스트, 배포 과정이 있는데 이때 배포가 개발환경에 배포되는 것일 수도 있고, 운영 환경에 배포되는 것일 수도 있다. 보통 개발환경에서 먼저 배포가 이루어진 다음에 운영환경에 배포한다.
코드, 테스트, 빌드, 배포, 버그 이렇게 Full cycle을 도는 것에 있어서 무엇인가 이 주기의 생명주기를 짧게 하는 것이 CI / CD이다!
pr을 날렸을 때 자동으로 뭘 체크하거나 이슈 생성 했을 때,, 코멘트 남겼을 때 뭐가 되는 경우가 있음!
흠 깃헙 액션 사전 지식 배워야 할 듯..
Github action을 이해하기 위해 꼭 알아야 하는 용어로 먼저 Workflows와 action이 있다.
workflows는 조금 더 큰 개념이라면 Actions는 작은 개념이다. 예를 들어 비유를 하자면 Workflow는 스탠드, 나무, 다이닝 세트라면 Actions는 전구, 잎, 포크 인 것! 즉 actions는 workflows에 속하는 개념이다.
이때 컴포넌트에는 네 개의 단계가 있다. Workflow -> Job -> Step -> Action로 점점 작아진다.
VsCode extension에서 위의 두 extensions을 설치하면 된다!
name : 'My First GitHub Actions Workflow'
on: push
# on은 깃허브 액션이 작동하게 하는 trigger 같은 것
jobs:
fist-job:
name: 'first Job'
runs-on : 'ubuntu-latest'
# ['windows-latest', 'ubuntu-latest','macos-latest'] # 어떤 운영체제에서 실행시킬 것인지 설정!! 이건 3개의 OS에서 동시에 실행 가능!
steps:
- name: 'Say Hello World on step 1'
shell: bash
run: |
echo "Hello World from Step 1"
- name: 'Say Lorem Ipsum on step 2'
shell: pwsh
run: |
echo "Lorem Ipsum on step 2"
# on에 대해 어떤 일을 하게 하는지 정의
# 각각의 job은 독립적인 서버(머신)라고 생각!! 그래서 서로 관여 못하고 데이터를 받을 수 없음
# 기본적으로 job 하나당 서버 하나!
해당 코드를 깃허브에 push 해보자!
깃허브 Actions에 보면 First Job이 잘 실행된 것을 볼 수 있다.
name : 'My First GitHub Actions Workflow'
on: push
# on은 깃허브 액션이 작동하게 하는 trigger 같은 것
env:
WORKFLOW_LEVEL: 'This value comes fom the workflow level'
jobs:
fist-job:
name: 'first Job'
runs-on : 'ubuntu-latest'
env:
JOB_LEVEL_1: 'This value comes fom the job level 1'
steps:
- name: 'Say Hello World on step 1'
shell: bash
env:
STEP_LEVEL_1: 'This value comes fom the step 1'
run: |
echo "Hello World from Step 1"
echo "workflow level : $WORKFLOW_LEVEL"
echo "job level 1 : $JOB_LEVEL_1"
echo "job level 2 : $JOB_LEVEL_2"
echo "step level 1 : $STEP_LEVEL_1"
echo "step level 2 : $STEP_LEVEL_2"
# step1에서 $로 접근
- name: 'Say Lorem Ipsum on step 2'
shell: pwsh
env:
STEP_LEVEL_2: 'This value comes fom the step 2'
run: |
echo "Lorem Ipsum on step 2"
echo "workflow level: $env:WORKFLOW_LEVEL"
echo "job level 1 : $env:JOB_LEVEL_1"
echo "job level 2 : $env:JOB_LEVEL_2"
echo "step level 1 : $env:STEP_LEVEL_1"
echo "step level 2 : $env:STEP_LEVEL_2"
# step2에서 환경 변수로 접근, 이때 STEP 간에 변수 공유가 되는지 확인
#power shell은 변수 가져오는 방식이 다르다!(bash랑 다름 주의)
#job이 다른 경우에도 변수간에 접근이 가능한지 확인해보기 위해
second-job:
name: 'second Job'
runs-on : 'ubuntu-latest'
env:
JOB_LEVEL_2: 'This value comes fom the job level 2'
steps:
- name: 'Say Hello World on step 1'
shell: bash
env:
STEP_LEVEL_1: 'This value comes fom the step 1'
run: |
echo "Hello World from Step 1"
echo "workflow level: $WORKFLOW_LEVEL"
echo "job level 1 : $JOB_LEVEL_1"
echo "job level 2 : $JOB_LEVEL_2"
echo "step level 1 : $STEP_LEVEL_1"
echo "step level 2 : $STEP_LEVEL_2"
- name: 'Say Lorem Ipsum on step 2'
shell: pwsh
env:
STEP_LEVEL_2: 'This value comes fom the step 2'
run: |
echo "Lorem Ipsum on step 2"
echo "workflow level: $env:WORKFLOW_LEVEL"
echo "job level 1 : $env:JOB_LEVEL_1"
echo "job level 2 : $env:JOB_LEVEL_2"
echo "step level 1 : $env:STEP_LEVEL_1"
echo "step level 2 : $env:STEP_LEVEL_2"
위의 결과는 Fist Job의 결과인데 STEP 1에서는 Second Job의 값과 STEP2의 값이 안 나온다. 또한 STEP 2에서는 Second Job의 값과 STEP1의 값이 안 나온다.
위의 결과는 Second Job의 결과인데 STEP 1에서는 First Job의 값과 STEP2의 값이 안 나온다. 또한 STEP 2에서는 First Job의 값과 STEP1의 값이 안 나온다.
즉 어느 레벨에서 환경변수 값을 놓을 것이냐에 따라, 참조 가능한 위치가 달라진다. 그래서 scope를 잘 해둬야 한다.
name : 'My First GitHub Actions Workflow'
on: push
# on은 깃허브 액션이 작동하게 하는 trigger 같은 것
env:
WORKFLOW_LEVEL: 'This value comes fom the workflow level'
jobs:
fist-job:
name: 'first Job'
runs-on : 'ubuntu-latest'
# ['windows-latest', 'ubuntu-latest','macos-latest'] # 어떤 운영체제에서 실행시킬 것인지 설정!! ㅣ건 3개의 OSd에서 동시에 실행 가능!
steps:
- name: 'Set environment variable 1'
shell: bash
run: |
echo "STEP_1 ='This value comes from the step 1'" >> $GITHUB_ENV
# GITHUB_ENV에 "STEP1~"을 저장해라!
- name: 'Set environment variable 2'
shell: pwsh
run : |
echo "STEP_2 ='This value comes from the step 2'" | Out-File -FilePath $env:GITHUB_ENV -Encoing utf-8 -Append
- name : 'Get environment variables'
shell: bash
run: |
echo "WORKFLOW: ${{ env.WORKFLOW_LEVEL }}"
echo "STEP 1: ${{ env.STEP_1 }}"
echo "STEP 2: ${{ env.STEP_2 }}"
이렇게 깃허브 환경변수에 값을 runtime 중에 추가해줄 수도 있다! 이때 주의할 점은 var_name = 'expession' 이렇게 변수명과 변수값과 '=' 사이에 공백이 있으면 값이 할당이 안 될 수도 있다. 꼭 붙여주자.
name : 'My First GitHub Actions Workflow'
on: push
env:
WORKFLOW_LEVEL: 'This value comes fom the workflow level'
jobs:
fist-job:
name: 'first Job'
runs-on : 'ubuntu-latest'
steps:
- name: 'Set output value 1'
id: step1
shell: bash
run: |
STEP_1='This value comes from the step 1'
echo "::add-mask::$STEP_1"
echo "::set-output name=value1::$STEP_1"
# bash에서 변수 값을 할당할 때 그냥 변수명='값'만 써줘도 된다.
- name: 'Set output value 2'
id: step2
shell: pwsh
run : |
$STEP_2='This value comes from the step 2'
# pwsh에서 변수 값을 할당하려면 $를 써줘야 한다.
echo "::set-output name=value2::$STEP_2"
- name : 'Get values'
shell: bash
run: |
echo "STEP 1: ${{ steps.step1.outputs.value1 }}"
echo "STEP 2: ${{ steps.step2.outputs.value2 }}"
# STEP1 output은 마스크 처리 됨.
먼저 STEP1이라는 변수에 값을 할당해준다. 그 다음에 output 변수 이름을 value1 이라 하고 STEP1을 할당해준다. 이때 set-ouput은 다른 step에서 참조해줄 수 있게 한다.
위의 사진처럼 add-mask하면 민감 정보를 ***으로 표시하게 한다.
Settings에 들어가서 Secrets을 선택하고 New repository secret을 선택해보장
이런식으로 값을 입력해주었다!
name : 'My First GitHub Actions Workflow'
on: push
env:
WORKFLOW_LEVEL: 'This value comes fom the workflow level'
jobs:
fist-job:
name: 'first Job'
runs-on : 'ubuntu-latest'
steps:
- name: 'Set output value 1'
id: step1
shell: bash
run: |
STEP_1='This value comes from the step 1'
echo "::add-mask::$STEP_1"
echo "::set-output name=value1::$STEP_1"
- name: 'Set output value 2'
id: step2
shell: pwsh
run : |
$STEP_2='This value comes from the step 2'
echo "::set-output name=value2::$STEP_2"
- name : 'Get values'
shell: pwsh
run: |
echo "STEP 1: ${{ steps.step1.outputs.value1 }}"
echo "STEP 2: ${{ steps.step2.outputs.value2 }}"
echo "SECRET 1: ${{ secrets.SECRET_1 }}"
if ("${{ secrets.SECRET_1 }}" -eq "Hello World") { # SECRET_1은 Hello임
echo "TRUE"
} else {
echo "FALSE"
}
이렇게 Secret은 자동으로 *** 표시가 된다는 것을 알 수 있고 기댓값 FALSE도 잘 나왔다.
name : 'My First GitHub Actions Workflow'
on: push
env:
WORKFLOW_LEVEL: 'This value comes fom the workflow level'
jobs:
fist-job:
name: 'first Job'
strategy:
matrix:
os: ['windows-latest', 'ubuntu-latest','macos-latest']
runs-on : ${{ matrix.os }}
# 즉 first job이 각 os에서 총 3번 돈다!
steps:
- name: 'Say Hello on ${{ matrix.os }}'
shell: bash
run: |
echo "Hello from ${{ matrix.os }}"
strategy, matrix, runs-on keyword를 통해 각 os에서 setp이 실행될 수 있도록 한다.
name : 'My First GitHub Actions Workflow'
on: push
env:
WORKFLOW_LEVEL: 'This value comes fom the workflow level'
jobs:
fist-job:
name: 'first Job'
strategy:
matrix:
os: ['windows-latest', 'ubuntu-latest','macos-latest']
nodejs : ['14.x', '16.x']
runs-on : ${{ matrix.os }}
# 즉 first job이 각 os에서 3번 돈다!
steps:
- name: 'Setup node.js version'
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.nodejs }}
- name: 'Check node.js version on ${{ matrix.os }}'
shell: bash
run: |
echo "nodejs version: $(node --version)"
## 즉 총 6번 돈다 os버전 * nodejs 버전 == 6
matrix의 os와 nodejs에 각각 접근한다.
name : 'My First GitHub Actions Workflow'
on: push
env:
WORKFLOW_LEVEL: 'This value comes fom the workflow level'
jobs:
fist-job:
name: 'first Job'
if: github.event_name == 'pull_request'
strategy:
matrix:
os: ['windows-latest', 'ubuntu-latest','macos-latest']
nodejs : ['14.x', '16.x']
runs-on : ${{ matrix.os }}
steps:
- name: 'Setup node.js version'
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.nodejs }}
- name: 'Run only on Windows'
if: matrix.os == 'windows-latest'
shell: bash
run: |
echo "Windows Only"
- name: 'Run not on Windows'
if: matrix.os != 'windows-latest'
shell: bash
run: |
echo "Not Windows"
- name: 'Check node.js version on ${{ matrix.os }}'
shell: bash
run: |
echo "nodejs version: $(node --version)"
즉 pull request라는 trigger가 발생해야만 job이 실행되므로
아예 실행이 안 된다.
name : 'My First GitHub Actions Workflow'
on: push
# on은 깃허브 액션이 작동하게 하는 trigger 같은 것
env:
WORKFLOW_LEVEL: 'This value comes fom the workflow level'
jobs:
fist-job:
name: 'first Job'
strategy:
matrix:
os: ['windows-latest', 'ubuntu-latest','macos-latest']
nodejs : ['14.x', '16.x']
runs-on : ${{ matrix.os }}
# 즉 first job이 각 os에서 3번 돈다!
steps:
- name: 'Setup node.js version'
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.nodejs }}
- name: 'Run only on Windows'
if: matrix.os == 'windows-latest'
shell: bash
run: |
echo "Windows Only"
- name: 'Run not on Windows'
if: matrix.os != 'windows-latest'
shell: bash
run: |
echo "Not Windows"
- name: 'Check node.js version on ${{ matrix.os }}'
shell: bash
run: |
echo "nodejs version: $(node --version)"
즉 os가 Window인 경우와 아닌 경우로 조건을 나누어 각각 처리를 다르게 해주었는데 ubuntu는 window가 아니니 Run only on Winodw라는 step은 실행되지 못한 것을 확인할 수 있다.
작업 순서가 정해진 경우! needs를 쓰면 된다.
name : 'My First GitHub Actions Workflow'
on: push
env:
WORKFLOW_LEVEL: 'This value comes fom the workflow level'
jobs:
build-job:
name: 'build Job'
runs-on : ubuntu-latest
steps:
- name: 'Say Hello'
shell: bash
run: |
echo "Hello World"
deploy-to-dev-job:
name: 'Deployment Job to DEV'
needs:
- build-job
# build-job이 실행된 후에 실행해줘!
runs-on: ubuntu-latest
steps:
- name: 'Say DEV'
shell: bash
run: |
echo "DEVELOPERS"
deploy-to-prod-job:
name: 'Deployment Job to PROD'
needs:
- build-job
# build-job이 실행된 후에 실행해줘!
runs-on: ubuntu-latest
steps:
- name: 'Say PROD'
shell: bash
run: |
echo "PRODUCTION"
# 반드시 작업 순서가 정해진 채로 실행되어야 하는 경우
즉 build가 끝나야 다른 task가 실행되는 것을 확인할 수 있습니다. 이때 task 2개는 어떤 task가 먼저 실행해도 상관없다.
name: 'My First GitHub Actions Workflow'
on: push
jobs:
build-job:
name: 'Build Job'
runs-on: ubuntu-latest
steps:
- name: 'Say Hello'
shell: bash
run: |
echo "Hello World"
deploy-to-dev-job:
name: 'Deployment Job to DEV'
runs-on: ubuntu-latest
steps:
- name: 'Say DEV'
shell: bash
run: |
echo "DEVELOPERS"
deploy-to-prod-job:
name: 'Deployment Job to PROD'
needs:
- build-job
- deploy-to-dev-job
# build랑 deploy 끝나면 실행
runs-on: ubuntu-latest
steps:
- name: 'Say PROD'
shell: bash
run: |
echo "PRODUCTION"
이 경우는 먼저 두 task를 실행한 후에 다음 task가 실행되어야 한다. 이때 두 task의 실행 순서는 상관없다.