본문 바로가기
T.I.L(Today I learned)/Git

티스토리 블로그 게시하면 깃허브 커밋되도록 하는 방법

by Amy97 2023. 1. 13.
728x90

'티스토리 블로그에 게시물을 작성하면 자동으로 깃허브에 커밋이 되는 방법은 없을까?'

구글링 해보니 많은 이들이 같은 생각을 했고, 해결책을 찾아 적용하고 있었다.

진작 검색해 볼 걸 그랬다.

 

깃허브 프로필로 사용되는 README 파일에 블로그 최신글이 업데이트 되도록 설정하면 된다. 

티스토리 블로그에 게시물을 업로드하면 >  README 파일 내 블로그 최신글 목록이 업데이트되고 > 깃허브에 커밋 기록이 남는다.

깃허브 프로필도 꾸미고, 1일1커밋에 일조하고, 1석2조! 

 

자... 이제 설정하는 방법을 알아보자.

키워드: python, feedparser, rss, github action

https://pypi.org/project/feedparser/

 

feedparser

Universal feed parser, handles RSS 0.9x, RSS 1.0, RSS 2.0, CDF, Atom 0.3, and Atom 1.0 feeds

pypi.org

python 라이브러리 feedparser 대한 내용은 공식 문서 참고!

 

1. Repository에 Python 파일 추가하기

import feedparser

URL = "https://amylim.tistory.com/rss" # 티스토리 블로그 주소 + /rss
RSS_FEED = feedparser.parse(URL)
MAX_POST = 5 # 최신글 목록 게시글 수 

markdown_txt = """
## :page_facing_up: Latest Blog Posts 
"""
# readme 파일 내 markdown 문법으로 작성하는 부분 

blog_post = ""

for idx, feed in enumerate(RSS_FEED['entries']):
    if idx > MAX_POST:
        break
    else:
        feed_date = feed['published_parsed']
        blog_post += f"[{feed['title']}]({feed['link']}) <br/>\n"
# rss에서 블로그 게시글 제목, 주소 크롤링

readme_result = f"{markdown_txt}{blog_post}"
           
f = open("README.md", mode="w", encoding="utf-8")
f.write(readme_result)
f.close()

 

라고 추가하면 

위와 같은 결과를 도출할 수 있다.

 

필자는 README 파일 배치를 감안해 코드를 수정했다. 

import feedparser

URL = "https://amylim.tistory.com/rss" # 티스토리 블로그 주소 + /rss
RSS_FEED = feedparser.parse(URL)
MAX_POST = 5 # 최신글 목록 게시글 수 

blog_post = ""

for idx, feed in enumerate(RSS_FEED['entries']):
    if idx > MAX_POST:
        break
    else:
        feed_date = feed['published_parsed']
        blog_post += f"[{feed['title']}]({feed['link']}) <br/>\n"
# rss에서 블로그 게시글 제목, 주소 크롤링
        
readme_top = """
![header](https://capsule-render.vercel.app/api?type=waving&color=auto&height=200&section=header&text=Amy%20Lim&fontSize=90&animation=twinkling)
## :computer: Skills
### BackEnd
<img src="https://img.shields.io/badge/Java-007396?style=for-the-badge&logo=Java&logoColor=white"> <img src="https://img.shields.io/badge/Spring-6DB33F?style=for-the-badge&logo=Spring&logoColor=white"> <img src="https://img.shields.io/badge/Spring Boot-6DB33F?style=for-the-badge&logo=SpringBoot&logoColor=white"> <img src="https://img.shields.io/badge/JPA-59666C?style=for-the-badge&logo=Hibernate&logoColor=white"> <img src="https://img.shields.io/badge/Gradle-02303A?style=for-the-badge&logo=Gradle&logoColor=white"> <img src="https://img.shields.io/badge/Apache Maven-C71A36?style=for-the-badge&logo=Apache Maven&logoColor=white"> <img src="https://img.shields.io/badge/Oracle-F80000?style=for-the-badge&logo=Oracle&logoColor=white"> 
### FrontEnd
<img src="https://img.shields.io/badge/javascript-F7DF1E?style=for-the-badge&logo=javascript&logoColor=black"> <img src="https://img.shields.io/badge/html-E34F26?style=for-the-badge&logo=html5&logoColor=white"> <img src="https://img.shields.io/badge/css-1572B6?style=for-the-badge&logo=css3&logoColor=white"> <img src="https://img.shields.io/badge/bootstrap-7952B3?style=for-the-badge&logo=bootstrap&logoColor=white"> <img src="https://img.shields.io/badge/Thymeleaf-005F0F?style=for-the-badge&logo=Thymeleaf&logoColor=white">
## :medal_sports: Certificate
- 정보처리기사 Engineer Information Processing (2022.11)
## :page_facing_up: Latest Blog Posts 
"""
# readme 파일 상단 부분

readme_bottom = """
## :bar_chart: Stats
<div align="center">
  
|                                                       Solved.ac                                                        |                                                             Languages                                                              |
| :--------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------: |
| [![Solved.ac profile](http://mazassumnida.wtf/api/v2/generate_badge?boj=amylim32897)](https://solved.ac/amylim32897) | [![Top Langs](https://github-readme-stats-git-masterrstaa-rickstaa.vercel.app/api/top-langs/?username=amylim328&layout=compact&theme=dark)](https://github.com/anuraghazra/github-readme-stats)
| ![Amy's GitHub stats](https://github-readme-stats-git-masterrstaa-rickstaa.vercel.app/api?username=amylim328&show_icons=true&theme=dark) |
| :-----------------------------------------------------------------------------------------------------------------------: |
  
</div> 
"""
# readme 파일 하단 부분

readme_result = f"{readme_top}{blog_post}{readme_bottom}"
           
f = open("README.md", mode="w", encoding="utf-8")
f.write(readme_result)
f.close()

 

2. Github Action workflow 설정 파일 추가하기

Actions > New workflow > Python application > Configure 선택하면 

이렇게 yml 파일이 생성되는데 작성된 내용을 삭제하고

# This workflow will install Python dependencies, run tests and lint with a single version of Python
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions

name: Latest Blog Posts

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]
  schedule:
      - cron: "0 * * * *" # 매 시각 정각마다 작동 https://crontab.guru 크론식은 해당 사이트 참고
  workflow_dispatch: # Run workflow manually (without waiting for the cron to be called), through the Github Actions Workflow page directly    

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v3
    - name: Set up Python 3.10
      uses: actions/setup-python@v3
      with:
        python-version: "3.10"
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install feedparser
    - name: Run Update Python Script
      run: |
        python main.py
    - name: Update Latest Blog Posts
      run: | 
        git pull 
        git add .
        git diff
        git config --local user.email "amylim32897@gmail.com" // 깃허브 메일 주소
        git config --local user.name "Amy Lim" // 깃허브 이름
        git commit -m "update latest blog posts"
        git push

위의 내용으로 수정해서 Commit 하면 된다.

크론식으로 작동 주기 변경 가능 https://crontab.guru

깃허브 메일, 이름 본인 계정으로 작성하도록 주의!

 

결과

https://github.com/AmyLim328/AmyLim328

 

ERROR

1.  Github Action 예약 작업 실행되지 않음

다음 날 일어나서 확인해 보니 Github Action이 제시간에 실행되지 않았다. 애꿎은 cron식만 이리저리 수정해 보다가 해결되지 않아 GitHub action cron not working 구글링 해보니 유명한 에러였다.

Github Actions의 예약 작업 기능은 제대로 작동하지 않는다고 한다.

당초 설정한 예약 시간에 비해 10~20분 정도의 딜레이가 발생하거나 심한 경우 1~3시간의 딜레이가 발생하고, 최악의 경우 예약이 아예 실행되지 않는다고 한다.

https://github.com/orgs/community/discussions/27130

 

No assurance on scheduled jobs? · Discussion #27130 · community

This is a re-post, as I just realized I started the thread in the wrong forum. (And, don’t see any functionality to move it.) Is there no assurance on execution of scheduled jobs? I mean if they ar...

github.com

그래서 yml 파일에

workflow_dispatch:

이 부분을 꼭 추가해 줘야 한다 !!!!!

위의 코드를 추가하면 사진과 같이 수동으로  workflow run 시킬 수 있는 버튼이 발생한다.

제대로 작동되지 않으면 저 버튼 눌러주면 됨......

 

2. 갑자기 Stat card 생상되지 않음

엎친 데 덮친 격 Stat card가 제대로 뜨지 않는 에러 발생함

이때까지 아무런 문제없었는데 갑자기 무슨 일....?

에러는 원래 한꺼번에 몰려오는 것인가....

https://github.com/anuraghazra/github-readme-stats/issues/2382

 

Cannot read properties of undefined (reading 'user') · Issue #2382 · anuraghazra/github-readme-stats

Describe the bug Cannot read properties of undefined (reading 'user') Expected behaviour I hope that stats cards will be shown Screenshots / Live demo link Additional context No response

github.com

도무지 영문을 몰라서 해당 repository에 가서 issue 등록했다.

알고 보니 같은 시간에 여러 명의 유저의 동일한 에러를 경험하고 있었다.

깃허브 자체 에러인가.. 하여튼 집단 지성 덕분 다음 날 바로 에러 해결법을 찾았다.

 

다행히 지금은 Github Action 예약 작업도 정상적으로 실행되고 모든 에러가 해결된 상태이다. 

X라고 뜨는 것도 에러인 줄 알고 이러 저리 검색하며 원인을 찾았는데 티스토리 블로그에 새 게시물이 없으므로 README 내 업데이트할 내용이 없어서 저렇게 뜨는 거였음.... ^^

728x90

댓글