개발자로 후회없는 삶 살기
[문법] 다양한 깃헙 액션 기능을 알아보자 본문
서론
※ 아래 내용을 다룹니다.
- 깃헙 액션의 다양한 기능
본론
- 체크아웃
레포의 코드를 가져와서 사용할 수 있는 작업이다. 깃헙 액션 마켓플레이스에 등록된 액션으로, 레포의 코드에 테스트가 있다면 테스트를 하고 빌드 할 수 있다.
name: checkout-flow
on: workflow_dispatch
jobs:
no-checkout:
runs-on: ubuntu-latest
steps:
- name: cat readme fail
run: cat README.md
checkout:
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v4
- name: cat
run: cat README.md
수동 워크플로우를 만들어서 체크아웃을 하는 yml을 작성했다. 레포의 리드미를 읽는 cat 스탭 전에 uses로 체크아웃 액션을 사용하면 레포를 가져오고 리드미를 잘 읽는다.
no-ckeckout 잡은 레포를 가져오지 않았기 때문에 실패한다.
- 깃헙 액션 컨텍스트
깃헙 액션의 환경 정보를 의미한다. 현재 레포와 레포 주인의 닉네임 등이 해당한다.
-> 사용하는 이유
dev 브랜치에 푸시 됐을 때 워크플로우의 1번 잡만을 실행
master 브랜치에 push하면 2번 잡을 실행
위처럼 워크플로우를 보다 유연하게 사용할 수 있다.
name: context-workflow
on: workflow_dispatch
jobs:
context:
runs-on: ubuntu-latest
steps:
- name: show context
run: echo '${{ toJSON(github) }}'
github 컨텍스트 안에 어떤 프로포티를 가지고 있는 지 확인해보자. github 키워드에 환경 정보를 담고 있고 이를 확인하기 위해서 toJSON으로 문자열로 보는 yml을 작성했다.
github 키워드에 이처럼 다양한 정보를 가지고 있고, github.{obj} 형태로 사용할 수 있다.
- filter
이벤트가 특정 조건에 부합할 때만 워크플로우를 트리거할 수 있다. 브랜치, 패스, 태그에 적용할 수 있다. 필터는 이벤트에 조건을 거는 것이므로 on 절과 함께 사용한다.
-> 브랜치 필터
name: branch-filter
on:
push:
branches: ['dev']
jobs:
branch-f:
runs-on: ubuntu-latest
steps:
- name: echo
run: echo hello
브랜치 필터는 특정 브랜치에 푸시 할 때만 워크플로가 실행되도록 하는 필터이다. dev와 master 중에서 dev에 푸시될 때만 트리거 되는 워크플로우를 작성했다. 브랜치 필터는 푸시와 풀리퀘 이벤트에 동작할 수 있다.
-> path 필터
name: path-filter
on:
push:
paths:
- '.github/workflows/part1/*'
- '!.github/workflows/part1/push.yml'
jobs:
branch-f:
runs-on: ubuntu-latest
steps:
- name: echo
run: echo hello
path 필터는 위의 part1 폴더처럼 특정 경로의 파일이 수정될 때만, 이벤트를 발생시킬 수 있는 필터이다. 푸시와 풀리퀘에서 동작하며 ! 기호로 무시 대상을 정할 수 있다.
-> 태그 필터
name: tag-filter
on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+'
jobs:
branch-f:
runs-on: ubuntu-latest
steps:
- name: echo
run: echo hello
태그 필터는 위의 v1.0.0처럼 특정 포멧으로 태그가 푸시 될 때만 워크플로우를 트리거할 수 있다. 태그 필터는 푸시에서만 동작한다. 위 yml을 레포에 반영하소 git tag를 생성하면 워크플로우가 트리거된다.
- cache
자주 사용되는 데이터를 빠르게 불러올 수 있도록 저장하는 기능으로 깃헙 액션의 공식 액션이다. 워크플로우를 실행할 때 의존성 설치 시간을 단축시킬 수 있다.
-> yml 설명
name: cache
on:
push:
paths:
- "my-app/**"
jobs:
cache:
runs-on: ubuntu-latest
steps:
- name: checkout
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
cache 액션의 with에는 path, key, restore 인풋을 넣어야 한다.
path : 캐싱할 경로 (여기서는 node의 의존성이 저장되는 npm 경로 지정)
key : 캐시를 찾을 때 사용하는 키
os : 워크플로우가 실행되는 os를 의미하고 각 os별로 캐시를 분리하기 위함
node : 캐시의 범주를 나타내기 위한 임의의 문자열 (여기서는 node를 저장함을 의미)
hash : 노드 패키지를 해시한 값으로 패키지가 추가될 경우 새로운 키 값을 생성하기 위함 (os와 node는 고정이니 키 값 생성의 주된값)
restore : 캐시 복구를 위한 키 (생성된 캐시 중 [-node-] 이후에 값이 현재 키와 가장 가까운 키의 캐시를 가져옴)
위처럼 캐시 액션을 설정하면 같은 os에서 동일한 lock.json을 가진 워크플로우가 실행될 때 이전에 저장했던 캐시를 사용해서 의존성 설치를 빠르게 수행할 수 있다. (위 워크플로우에서 npm build를 할 때 동일 os, 동일 의존성이면 키가 값을 것이니 캐시에서 의존성을 가져와서 워크플로우를 실행하고 npm build를 하게 된다.)
이제 위 워크플로우를 실행해보면, 캐시가 없을 땐 찾을 수 없다는 메시지가 나오고
끝나면 캐시를 저장했다는 메세지가 보여야 한다.
동일 패키지 상태에서 다시 워크플로우를 트리거하면 캐시 히트가 발생하고 과거에 로드한 모듈을 빠르게 가져와 사용한다.
생성된 캐시는 액션의 Caches 탭에서 관리할 수 있다.
- 아티팩트
동일한 워크 플로우의 잡 간에 파일 단위로 데이터를 공유할 수 있도록 하는 기능이다. 깃헙의 공식 액션으로 업로드로 원하는 파일을 아티팩트로 만들고, 다운로드로 원하는 아티팩트를 파일로 다운로드할 수 있다.
-> 실습
name: artifact-flow
on: push
jobs:
upload-artifact:
runs-on: ubuntu-latest
steps:
- name: echo
run: echo hello-wo > hello.txt
- name: upload artifact
uses: actions/upload-artifact@v3
with:
name: artifact-test
path: ./hello.txt
download-artifcat:
runs-on: ubuntu-latest
needs: [upload-artifact]
steps:
- name: download artifact
uses: actions/download-artifact@v3
with:
name: artifact-test
path: ./
- name: echo
run: cat hello.txt
-> 업로드 아티팩트 액션
name : 업로드된 파일의 아티팩트 이름
path: 업로드할 파일 경로
-> 다운로드 아티팩트 액션
name : 다운로드 할 아티팩트 이름
path: 다운로드 할 아티팩트가 저장될 경로
위 워크플로우를 실행하면, 업로드가 완료됐다는 메시지가 나온다.
다운로드 역시 메시지로 알려준다.
- output
파일 단위의 공유는 아티팩트를 사용하면 된다. 단순한 데이터를 공유하기 위해선 output을 사용한다. 동일 잡의 스탭 간, 다른 잡 간에 데이터를 공유할 수 있다. 데이터는 K-V 형태로 저장되며, 저장된 데이터를 사용하기 위해선 K에 접근하면 된다. 따라서 키에 접근하기 위한 id가 필요하다.
echo “{key}={value}” >> $GITHUB_OUTPUT
명령어로 아웃풋을 저장할 수 있다.
-> 동일 잡의 스탭 간에 공유
name: output
on: push
jobs:
create-out:
runs-on: ubuntu-latest
steps:
- name: echo
id: check-o
run: echo "test=hello" >> $GITHUB_OUTPUT
- name: check output
run: echo ${{ steps.check-o.outputs.test }}
접근 방법 = steps.{스텝 고유 아이디}.outputs.{key}
아티팩트처럼 액션을 사용할 필요 없이 echo 형태로 사용가능하다.
-> 다른 잡 간에 데이터 공유
잡 간에 데이터를 공유하기 위해선 잡 레벨의 outputs 키워드가 필요하다. 잡 레벨에서도 K-V 형태로 아웃풋을 저장한다. 앞 선 잡의 데이터를 사용하기 위해선 needs 종속성이 필요하다.
name: output
on: push
jobs:
create-out:
runs-on: ubuntu-latest
outputs:
test: "hihi"
steps:
- name: echo
id: check-o
run: echo "test=hello" >> $GITHUB_OUTPUT
- name: check output
run: echo ${{ steps.check-o.outputs.test }}
get:
runs-on: ubuntu-latest
needs: [create-out]
steps:
- name: get out
run: echo ${{ needs.create-out.outputs.test }}
outputs: 잡 레벨 output 지정 키워드
test: 잡 레벨 output 키
"hihi" : 잡 레벨 output 벨류
get 잡의 run : needs.{앞 선 잡 이름}.outputs.{앞 선 잡의 잡 레벨 output의 키}
name: output
on: push
jobs:
create-out:
runs-on: ubuntu-latest
outputs:
test: ${{ steps.check-o.outputs.test }}
steps:
- name: echo
id: check-o
run: echo "test=hello" >> $GITHUB_OUTPUT
- name: check output
run: echo ${{ steps.check-o.outputs.test }}
get:
runs-on: ubuntu-latest
needs: [create-out]
steps:
- name: get out
run: echo ${{ needs.create-out.outputs.test }}
잡 레벨 아웃풋의 값으로 스탭 레벨 벨류를 사용할 수 있다.
- 환경변수
스텝이나 잡에서 사용가능한 변수로 K-V 형태를 가진다.
-> 구성 방법
1. env 키워드
env.level 키워드로 워크플로우 내에서 환경 변수를 만들 수 있다.
스탭 > 잡 > 워크플로우
3가지 레벨에서 env 키워드를 사용할 수 있으며, 우선순위는 스탭이 가장 높아서 위 워플로우에서 get-env-3 잡의 check env 스텝은 LEVEL step이 출력된다.
2. 미리 정의
워크플로우 밖에서 미리 환경변수를 지정하는 방법으로, 이미 트리거된 워크플로우에서 환경변수를 바꾸고 re-run을 하면 결과가 달라질 수 있다.
name: var
on: push
jobs:
get-var:
runs-on: ubuntu-latest
steps:
- name: get var
run: echo ${{ vars.level }}
vars 키워드로 워크플로우에서 환경변수를 사용할 수 있다.
- secret
민감 데이터를 안전하게 저장하는 기능으로 사용할 수 있다.
1) 깃헙 액션에 암호화되어 저장
2) echo 로그에서 마스킹되어 출력
3) 깃헙 액션에서만 사용할 수 있고 워크 실행중에만 접근 가능하다.
시크릿을 미리 지정하면, 환경변수와 다르게 K만 보이고 V는 안 보인다.
echo로 출력을 해보면 마스킹된다.
- enviroment
enviroment : dev
enviroment는 특정 환경 자체를 만들고 특정 환경에서만 사용 가능한 환경변수와 시크릿을 만들 수 있는 기능이다.
환경 변수와 시크릿은 enviroment, repo, org 레벨이 있는데
environment > repo > org
enviroment가 가장 높은 우선순위를 가지기 때문에 워크플로우 환경변수와 시크릿에 접근 시 enviroment가 우선순위를 가진다.
enviroment의 특정 환경이 없을 때, org 레벨과 repo 레벨에서 환경변수와 시크릿을 만들고 vars와 secrets 키워드로 접근하면 repo의 우선순위가 높아서 repo와 def가 출력된다.
enviroment를 생성하고 dev 환경에서 환경변수를 출력하면 dev가 출력되고 prod 환경으로 지정하면 prod가 출력된다.
-> org 레벨의 환경 변수와 시크릿
org 레벨의 환경변수는 org의 setting에서 만들 수 있고
동일하게 K-V 형태를 가진다.
-> enviroment
enviroment를 dev로 만들고 환경변수와 시크릿을 하나씩 만들고 난 후
name: var
on: push
jobs:
get-var:
runs-on: ubuntu-latest
environment: dev
steps:
- name: get var
run: |
echo ${{ secrets.key }}
echo ${{ vars.level }}
워크플로우에서 접근하면 enviroment가 가장 큰 우선순위를 가져서 dev와 ghi가 출력된다. enviroment를 사용하면 특정 환경에서만 사용 가능한 환경변수와 시크릿을 생성할 수 있다. enviroment와 워크플로우의 env.{}는 전혀 다른 것으로 env는 환경 변수를 만드는 방법인 env 방식과 미리 정의 방식 중 하나이고, enviroment는 환경변수를 정의하는 환경이다.
- matrix
변수 기반으로 여러 개의 잡을 실행하는 기능으로, 매트릭스를 사용해서 하나의 잡을 구성하면 여러 개의 잡이 실행되도록 할 수 있다.
매트릭스를 사용해서 변수로 윈도우, 리눅스, 맥os가 설정된 하나의 잡을 구성하고 러너에서 매트릭 변수를 사용하면 윈도우 러너, 리눅스 러너, 맥 os 러너에서 각각 잡이 실행된다. 또한 서로 다른 버전에서 동일한 테스트 구성을 만들 수 있다. 매트릭스를 사용해서 변수로 파이썬 3.7,8,9 버전까지 설정된 하나의 잡을 구성하면 각 버전 별로 테스트를 구성할 수 있다.
✅ 장점
매트릭스를 사용하지 않으면 3개의 잡을 만들어야 하는데, 매트릭스를 사용하면 한개의 잡에 매트릭스만 3개 요소로 만들면 된다. 1개의 잡이지만 3개의 잡이 실행된다.
매트리스의 변수로 os와 버전을 만들면 윈도우 버전 12, 14,16로 우분투 버전 12, 14,16로 총 6개의 잡이 실행된다.
- if 문
특정 조건이 충족될 때만 실행하도록 하여 작업의 흐름을 세밀하게 제어할 수 있다.
예를들어서 깃헙 컨텍스트의 event 이름이 push 일 때만 잡이나 스탭을 실행시킬 수 있다. 잡과 스탭 레벨에서 정의할 수 있고 각각 잡과 스탭의 실행 여부를 결정한다.
name: if-1
on:
push:
workflow_dispatch:
jobs:
job1:
runs-on: ubuntu-latest
if: github.event_name == 'push'
steps:
- name: get event name
run: echo ${{ github.event_name }}
job2:
runs-on: ubuntu-latest
if: github.event_name != 'push'
steps:
- name: get event name
run: echo ${{ github.event_name }}
위 yml은 푸시일 경우 잡1이 실행되고 푸시가 아닐 경우 잡2가 실행되는 조건이다. 수동 이벤트라면 잡 2만 실행된다.
job3:
runs-on: ubuntu-latest
steps:
- name: get event name
if: github.event_name == 'push'
run: echo PUSH
- name: get event name
if: github.event_name != 'push'
run: echo DISPATCH
스탭 레벨에서도 첫 번째 스탭만 실행하고 두 번째 스탭은 무시할 수 있다.
-> 필터와 비교
필터 : 워크플로우를 트리거하는 조건을 검 ex) dev 브랜치일 경우에만 워크플로우 트리거
if 문 : 이미 트리거 된 워크플로우에서 잡과 스탭에 조건을 검 ex) 푸시 이벤트 일 경우 첫 번째 잡만 실행 or 두 번째 잡의 세번째 스탭은 무시
-> 잡과 스텝을 강제 실행
if: always()를 통해서 잡1이 실패해도 그에 의존하는 잡2를 강제 실행할 수 있다.
name: if-2
on:
push:
jobs:
job1:
runs-on: ubuntu-latest
steps:
- name: get event name
run: exit 1
job2:
needs: [job1]
runs-on: ubuntu-latest
if: always()
steps:
- name: get event name
run: echo HIHI
잡 2의 경우 앞 선 의존되는 잡이 실패하여 스킵되는 데 이때 강제 실행하도록 할 수 있다. 스탭에서도 스탭1이 실패하면 스탭2는 스킵되는데 스탭 2를 강제 실행할 수 있다.
- 문자열 처리 함수
문자열 처리 조건이 참 일 때만 잡과 스탭을 실행할 수 있는 함수이다.
1) startsWith
2) endsWith
3) contains
깃헙 액션에서 배열은 , 기호로 나타내는데, 이때도 참이다.
name: string-function
on: push
jobs:
string-function:
runs-on: ubuntu-latest
steps:
- name: startswith
if: startsWith('github actions', 'git')
run: echo "git"
- name: startswith
if: startsWith('github actions', 'test')
run: echo "test"
- name: endswith
if: endsWith('github actions', 'ions')
run: echo "ions"
- name: endsWith
if: endsWith('github actions', 'test')
run: echo "test"
- name: contains
if: contains('github actions', 'act')
run: echo "contains act"
- name: contains
if: contains('github, actions', 'git')
run: echo "contains git"
YML은 위처럼 구성하면 된다.
'[Infra] > [GitHub Actions]' 카테고리의 다른 글
[문법] 다양한 이벤트 트리거를 알아보자 (0) | 2025.01.19 |
---|