🕵️ Velog
에 글을 작성하면 GitHub
에 업로드가 되게 하고 싶었다.
📂 폴더 구조
📁 프로젝트 루트 ├── 📁 .github │ └── 📁 workflows │ └── python-workflow.yml # GitHub Actions 워크플로우 정의 파일 ├── 📁 scripts │ └── my_script.py # 실행할 Python 스크립트 파일 └── README.md
echo "# velog" >> README.md
git init
git add README.md
git commit -m "first commit"
git branch -M main
git remote add origin https://github.com/NuyHesHUB/velog.git
git push -u origin main
해당 로컬 디렉토리에서 입력하여 .github/workflows 폴더를 생성한다.
# terminal
mkdir -p .github/workflows
.github/workflows 폴더 생성 후 update_velog.yml
파일 생성하고 yml 설정코드를 작성한다.
GitHub Actions
는 빌드, 테스트 및 배포 파이프라인을 자동화할 수 있는 CI/CD(연속 통합 및 지속적인 업데이트) 플랫폼입니다. 리포지토리에 대한 모든 끌어오기 요청을 빌드 및 테스트하거나 병합된 끌어오기 요청을 프로덕션에 배포하는 워크플로를 만들 수 있습니다.
GitHub Actions은(는) 단순한 DevOps 수준을 넘어 리포지토리에서 다른 이벤트가 발생할 때 워크플로를 실행할 수 있도록 합니다. 예를 들어 누군가가 리포지토리에서 새 이슈를 만들 때마다 워크플로를 실행하여 적절한 레이블을 자동으로 추가할 수 있습니다.
GitHub에서 워크플로를 실행할 Linux, Windows, macOS 가상 머신을 제공하거나, 사용자 고유의 데이터 센터 또는 클라우드 인프라에서 자체 호스트형 실행기를 호스트할 수 있습니다.
자동화된 워크플로우
.github/workflows
디렉토리 아래에 작성된 YAML
파일로 정의됩니다.이벤트 기반 실행
Github Actions
는 다양한 이벤트를 트리거로 실행됩니다. 예 ) main
브랜치에 코드가 푸시되면 자동으로 테스트를 실행 등멀티 플랫폼 지원
Linux
, macOS
, Windows
환경에서 작업을 실행할 수 있습니다.직접 작성 가능한 커스텀 작업
시크릿 및 환경 변수 관리
다양한 마켓플레이스
코드
name: Update Velog
on:
push:
branches:
- master
schedule:
- cron: '0 0 * * *'
jobs:
update_velog:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Push changes
run: |
git config --global user.name 'github-actions[bot]'
git config --global user.email 'github-actions[bot]@user.noreply.github.com'
git push https://${{ secrets.GH_PAT }}@github.com/🟢깃허브ID🟢/velog.git
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: Install dependencies
run: |
pip install feedparser gitpython
- name: Run script
run: python scripts/update_velog.py
git push https://${{ secrets.GH_PAT }}@github.com/🟢깃허브ID🟢/velog.git
에서
변수 sercrets.GH_PAT 은 잠시 PAT 생성한는 NAME과 동일하게 한다.
벨로그
RSS 피드를 파싱하여 새로운 글을 로컬 깃 저장소에 마크다운 파일로 저장하고, 이를 커밋 및 푸시하는 스크립트다.
velog-posts
폴더 경로를 설정하고, 폴더가 없으면 생성한다.코드
import feedparser
import git
import os
# 벨로그 RSS 피드 URL
rss_url = 'https://api.velog.io/rss/@nuyhes'
# 깃허브 레포지토리 경로
repo_path = '.'
# 'velog-posts' 폴더 경로
posts_dir = os.path.join(repo_path, 'velog-posts')
# 'velog-posts' 폴더가 없으면 생성
if not os.path.exists(posts_dir):
os.makedirs(posts_dir)
# 레포지토리 로드
repo = git.Repo(repo_path)
# RSS 피드 파싱
feed = feedparser.parse(rss_url)
# 각 글을 파일로 저장하고 커밋
for entry in feed.entries:
# 파일 이름에서 유효하지 않은 문자 제거 또는 대체
file_name = entry.title
file_name = file_name.replace('/', '-') # 슬래시는 하위 폴더로 인식되므로 대시로 대체
file_name = file_name.replace('\\', '') # 역슬래시는 파일 이름에 사용할 수 없으므로 제거
file_name += '.md' # 마크다운 파일 확장자 추가
file_path = os.path.join(posts_dir, file_name) # 파일 경로
if not os.path.exists(file_path):
with open(file_path, 'w', encoding='utf-8') as file:
file.write(entry.discription) # 글 내용을 파일에 쓰기
repo.git.add(file_path) # 깃에 파일 추가
repo.git.commit('-m', f'Add post: {entry.title}') # 커밋
# 푸시
repo.git.push()
1️⃣ Github 계정
2️⃣ Settings
3️⃣ Developer Settings
4️⃣ Personal access tokens
5️⃣ Tokens(classic)
6️⃣ Generate New Token 버튼 클릭
1️⃣ Note에 토큰 이름을 적는다
2️⃣ repo 체크 , workflow 체크
3️⃣ Generate Token 버튼 클릭
4️⃣ 토큰 값 복사 (토큰 값은 메모해둔다)
velog 레포지토리 이동
1️⃣ Settings
2️⃣ Security 목록 > Secret and variables > Actions
3️⃣ Secrets 탭 > Repository secrets > New repository secret 버튼 클릭
4️⃣ Name 이름 작성 (yml 변수에 넣은 이름) GH_PAT_이름
/ Secret 란 토큰 값 입력
레포지토리 외부 권한 부여
1️⃣ 해당 레포지토리 > Settings
2️⃣ Actions > General
3️⃣ Actions permissions > 첫번째 Allow all actions and reusable workflows 체크
4️⃣ Approval for running fork pull request workflows from contributors > 세번째 Require approval for all external contributors 체크
5️⃣ Workflow permissions > 첫번째 Read and write permissions 체크
6️⃣ Allow GitHub Actions to create and approve pull requests 활성화
Actions 확인
1️⃣ 해당 레포지토리 > Actions > jobs
2️⃣ Run script 부분에서 에러가 발생했다.
에러 로그
Run python scripts/update_velog.py
[7](https://github.com/NuyHesHUB/velog/actions/runs/12578392936/job/35057054076#step:6:8)Traceback (most recent call last):
[8](https://github.com/NuyHesHUB/velog/actions/runs/12578392936/job/35057054076#step:6:9) File "/opt/hostedtoolcache/Python/3.12.8/x64/lib/python3.12/site-packages/feedparser/util.py", line 156, in __getattr__
[9](https://github.com/NuyHesHUB/velog/actions/runs/12578392936/job/35057054076#step:6:10) return self.__getitem__(key)
[10](https://github.com/NuyHesHUB/velog/actions/runs/12578392936/job/35057054076#step:6:11) ^^^^^^^^^^^^^^^^^^^^^
[11](https://github.com/NuyHesHUB/velog/actions/runs/12578392936/job/35057054076#step:6:12) File "/opt/hostedtoolcache/Python/3.12.8/x64/lib/python3.12/site-packages/feedparser/util.py", line 113, in __getitem__
[12](https://github.com/NuyHesHUB/velog/actions/runs/12578392936/job/35057054076#step:6:13) return dict.__getitem__(self, key)
[13](https://github.com/NuyHesHUB/velog/actions/runs/12578392936/job/35057054076#step:6:14) ^^^^^^^^^^^^^^^^^^^^^^^^^^^
[14](https://github.com/NuyHesHUB/velog/actions/runs/12578392936/job/35057054076#step:6:15)KeyError: 'discription'
[15](https://github.com/NuyHesHUB/velog/actions/runs/12578392936/job/35057054076#step:6:16)
[16](https://github.com/NuyHesHUB/velog/actions/runs/12578392936/job/35057054076#step:6:17)During handling of the above exception, another exception occurred:
[17](https://github.com/NuyHesHUB/velog/actions/runs/12578392936/job/35057054076#step:6:18)
[18](https://github.com/NuyHesHUB/velog/actions/runs/12578392936/job/35057054076#step:6:19)Traceback (most recent call last):
[19](https://github.com/NuyHesHUB/velog/actions/runs/12578392936/job/35057054076#step:6:20) File "/home/runner/work/velog/velog/scripts/update_velog.py", line 35, in <module>
[20](https://github.com/NuyHesHUB/velog/actions/runs/12578392936/job/35057054076#step:6:21) file.write(entry.discription) # 글 내용을 파일에 쓰기
[21](https://github.com/NuyHesHUB/velog/actions/runs/12578392936/job/35057054076#step:6:22) ^^^^^^^^^^^^^^^^^
[22](https://github.com/NuyHesHUB/velog/actions/runs/12578392936/job/35057054076#step:6:23) File "/opt/hostedtoolcache/Python/3.12.8/x64/lib/python3.12/site-packages/feedparser/util.py", line 158, in __getattr__
[23](https://github.com/NuyHesHUB/velog/actions/runs/12578392936/job/35057054076#step:6:24) raise AttributeError("object has no attribute '%s'" % key)
[24](https://github.com/NuyHesHUB/velog/actions/runs/12578392936/job/35057054076#step:6:25)AttributeError: object has no attribute 'discription'
[25](https://github.com/NuyHesHUB/velog/actions/runs/12578392936/job/35057054076#step:6:26)Error: Process completed with exit code 1.
📄update_velog.py
if not os.path.exists(file_path):
with open(file_path, 'w', encoding='utf-8') as file:
🔴file.write(entry.description) # 글 내용을 파일에 쓰기
repo.git.add(file_path) # 깃에 파일 추가
repo.git.commit('-m', f'Add post: {entry.title}') # 커밋
🔴부분 : entry.discription
오타가 있었다. entry.description
로 수정
참고