github_action_obsidiain배포자동화
개요
obsidian의 파일을 commit 하면 자동으로 githubBlog에 올리려고 하였다. 문제는 jeklly를 github으로 선택했는데 posting 파일에 대한 파일명 양식이 따로 정해져 있다는 것이다. 글 쓸 때마다 그 양식을 지키기는 너무 귀찮아서 commit 시점에 자동으로 파일명을 바꿔서 그 위치에 저장하는 workflow를 작성하기로 했다.(아마 1년 내내바꿔도 해당 workflow만드는 시간보단 덜들듯 하다.)
github Action의 역할
github action의 역할은 명확하다. "트리거 발생 시 -> 이미 구조화된 이벤트 실행"이다.
내 코드
- 트리거 : master 브랜치에 push 할 때 동작
- 구조화된 이벤트(workflow) : 하나의 단일 job으로 구성 (하나의 job은 하나의 트랜잭션)
// .github/workflows/push-to-posts.yml
name: Copy and Rename Files on Push
# trigger master 브랜치에 push 할 때 해당 workflows를 실행
on:
push:
branches:
- master
# workflows 내부의 job들 각 job은 하나의 트랜잭션
jobs:
copy_files:
# 실행시키는 환경. 대규모 프로젝트면 프로젝트환경과 맞추기도 한다.
runs-on: ubuntu-latest
# job 내 프로젝트 하나의 steps는 하나의 트랜잭션안에 있어서 하나가 실패하면 전체 취소
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
fetch-depth: 0 # 전체 커밋 기록을 가져오기
# 디폴트가 현재 커밋이라 설정 안하면 HEAD^ 못가져옴.
# 한글 깨짐 수정
- name: Set Git config to handle Korean filenames
run: |
git config --global core.quotepath false
- name: Set UTF-8 locale
run: |
sudo update-locale LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8
# github action의 보안관련 설정
- name: Set safe directory for Git
run: |
git config --global --add safe.directory /github/workspace
# 유저 적용
- name: Set up Git
run: |
git config --global user.name 'rn0614'
git config --global user.email 'rn0614@naver.com'
# 파일 copy & 이름변경 로직
- name: Copy and Rename Files
run: |
# 플래그 변수 초기화
FILE_COPIED=false
# 오늘 날짜 형식 (YYYY-MM-DD)
TODAY=$(date +"%Y-%m-%d")
# 시작부분 로그
echo "변경파일 추출 시작"
# 변경된 파일 목록을 임시 파일에 저장
git diff --name-only HEAD^ HEAD 2>/dev/null > changed_files.txt
# 임시 파일에서 파일명 추출 및 처리
echo "추출된 파일 목록:"
cat changed_files.txt # 추출된 파일 목록을 출력하여 확인
# 임시 파일에서 파일명 추출 및 처리
while IFS= read -r FILE; do
if echo "$FILE" | grep -E '.*.md$'; then
if echo "$FILE" | grep -E '^_github_open/.*'; then
echo "파일이 조건에 맞습니다: $FILE" # 매칭된 파일 확인
FILENAME=$(basename "$FILE" .md) # 확장자 제거한 파일명
# 파일명에서 공백을 '_'로 대체
FILENAME_WITH_UNDERSCORES=$(echo "$FILENAME" | sed 's/ /_/g')
# 새로운 파일명 생성 (YYYY-MM-DD-파일명.md)
NEW_FILENAME="${TODAY}-${FILENAME_WITH_UNDERSCORES}.md"
# 이름 formatting 완료된 파일이름 리스트 출력
echo "COPIED_FILENAME : ${NEW_FILENAME}"
# _posts 폴더로 파일 이동 및 파일명 변경
cp "$FILE" "_posts/${NEW_FILENAME}"
# 파일 복사 발생 시 플래그 변경
FILE_COPIED=true
fi
fi
done < changed_files.txt
# 환경 변수 파일에 기록
echo "file_copied=$FILE_COPIED" >> $GITHUB_ENV
# 변경점 psuh
- name: Commit and Push Changes
run: |
# GitHub Actions 환경 변수 참조
echo "file_copied is: $file_copied"
# 파일이 복사된 경우에만 커밋 및 푸시
if [ "$file_copied" = "true" ]; then
git add _posts/*.md
git commit -m "Copy and rename files on push"
git push origin master
else
echo "No files were copied. Skipping commit."
fi
오류 해결기록
1. HEAD^ 를 못찾는 현상
# 에러
fatal: ambiguous argument 'HEAD^': unknown revision or path not in the working tree. Use '--' to separate paths from revisions, like this: 'git <command> [<revision>...] -- [<file>...]'
# 개선
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
fetch-depth: 0 # 전체 커밋 기록을 가져오기
# 디폴트가 현재 커밋이라 설정 안하면 HEAD^ 못가져옴.
2. 한글 깨짐 수정
# 한글 깨짐 수정
- name: Set Git config to handle Korean filenames
run: |
git config --global core.quotepath false
- name: Set UTF-8 locale
run: |
sudo update-locale LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8
3. 보안관련 설정
- name: Set safe directory for Git
run: |
git config --global --add safe.directory /github/workspace
4. 특정 위치에서 commit 된 md 파일 추출
# 변경된 파일 목록을 임시 파일에 저장
git diff --name-only HEAD^ HEAD 2>/dev/null > changed_files.txt
# 임시 파일에서 파일명 추출 및 처리
echo "추출된 파일 목록:"
cat changed_files.txt # 추출된 파일 목록을 출력하여 확인
# 임시 파일에서 파일명 추출 및 처리
while IFS= read -r FILE; do
if echo "$FILE" | grep -E '.*.md$'; then
if echo "$FILE" | grep -E '^_github_open/.*'; then
echo "파일이 조건에 맞습니다: $FILE" # 매칭된 파일 확인
FILENAME=$(basename "$FILE" .md) # 확장자 제거한 파일명
# 파일명에서 공백을 '_'로 대체
FILENAME_WITH_UNDERSCORES=$(echo "$FILENAME" | sed 's/ /_/g')
# 새로운 파일명 생성 (YYYY-MM-DD-파일명.md)
NEW_FILENAME="${TODAY}-${FILENAME_WITH_UNDERSCORES}.md"
# 이름 formatting 완료된 파일이름 리스트 출력
echo "COPIED_FILENAME : ${NEW_FILENAME}"
# _posts 폴더로 파일 이동 및 파일명 변경
cp "$FILE" "_posts/${NEW_FILENAME}"
# 파일 복사 발생 시 플래그 변경
FILE_COPIED=true
fi
fi
done < changed_files.txt
# 환경 변수 파일에 기록
echo "file_copied=$FILE_COPIED" >> $GITHUB_ENV