GitHub Actions 로컬 테스트 방법 (with act)
GitHub Actions를 사용하다 보면, 매번 Commit하고 Push하지 않고도 로컬 환경에서 워크플로우가 정상적으로 동작하는지 간단하게 확인하고 싶을 때가 있습니다. 이런 경우 act라는 도구를 활용하면 로컬에서 GitHub Actions 워크플로우를 직접 실행해볼 수 있습니다. 이번 글에서는 act를 사용하여 로컬 환경에서 GitHub Actions 워크플로우를 테스트하는 방법에 대해 소개하겠습니다.
단, act는 간단한 구조의 워크플로우 테스트에 적합하며, 복잡한 조건 분기나 다양한 OS 환경, self-hosted runner, 외부 서비스와의 연동 등 복잡한 구성에서는 한계가 있을 수 있습니다. 따라서 기본적인 기능 확인이나 단순 로직 테스트를 목적으로 사용할 것을 권장드립니다.
또한 act는 내부적으로 Docker 컨테이너를 이용하여 워크플로우를 실행하므로, 사전에 로컬 환경에 Docker가 설치되어 있어야 합니다. Docker가 실행 중이지 않거나 설치되어 있지 않다면, act를 제대로 사용할 수 없습니다.
act 설치히기
MacOS와 Ubuntu별로 설치하는 방법이 다릅니다. 참고로 필자는 Ubuntu에서 실습을 진행하였습니다.
# MacOS 환경에 act 설치하기
> brew install act
# Ubuntu 환경에 act 설치하기
> curl -s https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash
# 결과
nektos/act info checking GitHub for latest tag
nektos/act info found version: 0.2.79 for v0.2.79/Linux/x86_64
nektos/act info installed ./bin/act
# 실행 파일 옮기기
> sudo mv ./bin/act /usr/local/bin/
# 설치 확인
> act --version
act version 0.2.79
테스트를 위한 workflow 작성
.github/workflows/test-workflow.yaml
name: test-workflow
on:
schedule:
- cron: "* * * * *"
workflow_dispatch:
jobs:
job-one:
name: Job One
runs-on: ubuntu-latest
steps:
- name: Step 1 - Job One
run: |
echo "Job One - Step 1 시작"
sleep 5
echo "Job One - Step 1 완료"
- name: Step 2 - Job One
run: |
echo "Job One - Step 2 시작"
sleep 5
echo "Job One - Step 2 완료"
- name: Step 3 - Job One
run: |
echo "Job One - Step 3 시작"
sleep 5
echo "Job One - Step 3 완료"
job-two:
name: Job Two
runs-on: ubuntu-latest
steps:
- name: Step 1 - Job Two
run: |
echo "Job Two - Step 1 시작"
sleep 5
echo "Job Two - Step 1 완료"
- name: Step 2 - Job Two
run: |
echo "Job Two - Step 2 시작"
sleep 5
echo "Job Two - Step 2 완료"
- name: Step 3 - Job Two
run: |
echo "Job Two - Step 3 시작"
sleep 5
echo "Job Two - Step 3 완료"
act 명령어 수행
act의 간단한 사용법을 정리하였습니다. 더 자세한 사용법은 "act --help" 를 통해 확인하시기 바랍니다.
# act 사용법
act --help
# 수행 가능한 모든 잡 출력하기
act --list
act --list | grep test-workflow
# 특정 workflow만 동작하기
act --workflows .github/workflows/test-workflow.yaml workflow_dispatch
act 수행 결과
> act --workflows .github/workflows/test-workflow.yaml workflow_dispatch
INFO[0000] Using docker host 'unix:///var/run/docker.sock', and daemon socket 'unix:///var/run/docker.sock'
[list-service-quotas/Job Two] ⭐ Run Set up job
[list-service-quotas/Job Two] 🚀 Start image=catthehacker/ubuntu:act-latest
[list-service-quotas/Job One] ⭐ Run Set up job
[list-service-quotas/Job One] 🚀 Start image=catthehacker/ubuntu:act-latest
[list-service-quotas/Job Two] 🐳 docker pull image=catthehacker/ubuntu:act-latest platform= username= forcePull=true
[list-service-quotas/Job One] 🐳 docker pull image=catthehacker/ubuntu:act-latest platform= username= forcePull=true
[list-service-quotas/Job One] 🐳 docker create image=catthehacker/ubuntu:act-latest platform= entrypoint=["tail" "-f" "/dev/null"] cmd=[] network="host"
[list-service-quotas/Job Two] 🐳 docker create image=catthehacker/ubuntu:act-latest platform= entrypoint=["tail" "-f" "/dev/null"] cmd=[] network="host"
[list-service-quotas/Job One] 🐳 docker run image=catthehacker/ubuntu:act-latest platform= entrypoint=["tail" "-f" "/dev/null"] cmd=[] network="host"
[list-service-quotas/Job Two] 🐳 docker run image=catthehacker/ubuntu:act-latest platform= entrypoint=["tail" "-f" "/dev/null"] cmd=[] network="host"
[list-service-quotas/Job One] 🐳 docker exec cmd=[node --no-warnings -e console.log(process.execPath)] user= workdir=
[list-service-quotas/Job Two] 🐳 docker exec cmd=[node --no-warnings -e console.log(process.execPath)] user= workdir=
[list-service-quotas/Job One] ✅ Success - Set up job
[list-service-quotas/Job Two] ✅ Success - Set up job
[list-service-quotas/Job One] ⭐ Run Main Step 1 - Job One
[list-service-quotas/Job Two] ⭐ Run Main Step 1 - Job Two
[list-service-quotas/Job Two] 🐳 docker exec cmd=[bash -e /var/run/act/workflow/0] user= workdir=
[list-service-quotas/Job One] 🐳 docker exec cmd=[bash -e /var/run/act/workflow/0] user= workdir=
| Job Two - Step 1 시작
| Job One - Step 1 시작
| Job One - Step 1 완료
| Job Two - Step 1 완료
[list-service-quotas/Job One] ✅ Success - Main Step 1 - Job One [5.071931778s]
[list-service-quotas/Job Two] ✅ Success - Main Step 1 - Job Two [5.071958243s]
[list-service-quotas/Job One] ⭐ Run Main Step 2 - Job One
[list-service-quotas/Job Two] ⭐ Run Main Step 2 - Job Two
[list-service-quotas/Job One] 🐳 docker exec cmd=[bash -e /var/run/act/workflow/1] user= workdir=
[list-service-quotas/Job Two] 🐳 docker exec cmd=[bash -e /var/run/act/workflow/1] user= workdir=
| Job One - Step 2 시작
| Job Two - Step 2 시작
| Job One - Step 2 완료
[list-service-quotas/Job One] ✅ Success - Main Step 2 - Job One [5.064165725s]
| Job Two - Step 2 완료
[list-service-quotas/Job Two] ✅ Success - Main Step 2 - Job Two [5.072087191s]
[list-service-quotas/Job One] ⭐ Run Main Step 3 - Job One
[list-service-quotas/Job Two] ⭐ Run Main Step 3 - Job Two
[list-service-quotas/Job One] 🐳 docker exec cmd=[bash -e /var/run/act/workflow/2] user= workdir=
[list-service-quotas/Job Two] 🐳 docker exec cmd=[bash -e /var/run/act/workflow/2] user= workdir=
| Job One - Step 3 시작
| Job Two - Step 3 시작
| Job One - Step 3 완료
[list-service-quotas/Job One] ✅ Success - Main Step 3 - Job One [5.066814648s]
| Job Two - Step 3 완료
[list-service-quotas/Job Two] ✅ Success - Main Step 3 - Job Two [5.065791836s]
[list-service-quotas/Job One] ⭐ Run Complete job
[list-service-quotas/Job One] Cleaning up container for job Job One
[list-service-quotas/Job Two] ⭐ Run Complete job
[list-service-quotas/Job Two] Cleaning up container for job Job Two
[list-service-quotas/Job One] ✅ Success - Complete job
[list-service-quotas/Job One] 🏁 Job succeeded
[list-service-quotas/Job Two] ✅ Success - Complete job
[list-service-quotas/Job Two] 🏁 Job succeeded
컨테이너 확인
위에서 소개한 방법으로 act를 이용해 워크플로우를 실행하면, 각 job이 Docker 컨테이너로 실행되는 것을 확인할 수 있습니다. 예를 들어 두 개의 job이 정의된 워크플로우를 실행했다면, act는 각각의 job을 개별 Docker 컨테이너로 실행합니다.
실행 중인 컨테이너는 다음 명령어를 통해 확인할 수 있습니다:
watch “docker ps -a” 이 명령어를 입력하면 현재 실행 중이거나 종료된 Docker 컨테이너 목록이 출력되며, act가 실행한 job들이 컨테이너로 존재하는 것을 확인할 수 있습니다. 컨테이너 이름에는 보통 `act-` 접두사가 포함되어 있으므로 식별하기도 비교적 쉽습니다.

'git & github' 카테고리의 다른 글
| git hook을 이용한 commit 메시지에 자동으로 branch명 추가하기 (0) | 2025.05.22 |
|---|---|
| 주니어 개발자가 알면 좋은 git 명령어 정리 (1) | 2023.07.12 |
| git config (0) | 2023.07.11 |
| git commit template 설정하기 (0) | 2023.07.10 |