관리 메뉴

솜씨좋은장씨

[GitHub] github actions를 활용하여 push 할 때 마다 README.md 업데이트 하는 방법! ( feat. 코딩 1일 1문제! ) 본문

유용한 정보/Git | GitHub

[GitHub] github actions를 활용하여 push 할 때 마다 README.md 업데이트 하는 방법! ( feat. 코딩 1일 1문제! )

솜씨좋은장씨 2021. 10. 16. 08:27
728x90
반응형

2020년 2월 부터 현재까지 매일 하루에 최소 코딩 문제 1개씩은 꼭 풀자라는 취지로 시작한 코딩 1일 1문제!

 

GitHub - SOMJANG/CODINGTEST_PRACTICE: 1일 1문제 since 2020.02.07

1일 1문제 since 2020.02.07. Contribute to SOMJANG/CODINGTEST_PRACTICE development by creating an account on GitHub.

github.com

중간중간 빼먹은 날을 빼고 오늘로서 514일차를 맞이했습니다.

 

[GitHub] 내 블로그 최신글 깃헙 프로필에 자동으로 표시하는 방법! ( feat. Python / GitHub Actions )

티스토리 블로그 스킨을 알아보던 중 heLLO라는 스킨을 만든 분의 GitHub 프로필에서 최신 블로그 포스팅 글이 자동으로 업데이트가 되는 것을 보았습니다. 안 그래도 블로그 유입을 늘릴 방법을

somjang.tistory.com

최근에 github actions를 활용하여 일정 시간이 되면

깃헙 프로필에 자동으로 최신 글 목록을 업데이트하도록 했던 것을 응용하여

 

이번에는 push를 하거나 pull request를 했을 때 자동으로 README.md에 

내가 풀었던 문제의 총 개수

출처 별 문제의 개수를 업데이트 해보면 좋겠다 싶었습니다.

📃 자동으로 카운트를 해주는 코드 작성하기

먼저 utils 디렉토리를 만들고 해당 디렉토리에 count_problem_source.py 라는 파일을 하나 만들어주었습니다.

count_problem_source.py

from collections import Counter
from datetime import datetime
import os
import re


def count_problem_source_code():
    problem_solve_code_list = []

    directory_list = [directory for directory in os.listdir("./") if "DAY" in directory]

    for directory in directory_list:
        code_list = os.listdir(f"./{directory}")

        problem_solve_code_list += code_list

    name_list = [re.findall(r'\[[^)]*\]', code_name) for code_name in problem_solve_code_list]

    name_list = [name[0].replace("[", "").replace("]", "") for name in name_list if len(name) > 0]

    total_code_num = len(name_list)
    
    code_cnt_info = sorted(Counter(name_list).items(), key=lambda x: -x[1])

    return total_code_num, code_cnt_info


def make_count_info(total_code_num, code_cnt_info):
    count_info = f"#### 현재까지 풀어본 총 문제 수 : {total_code_num}개\n"

    for name in code_cnt_info:
        temp = f"- {name[0]} - {name[1]}개\n"
        count_info += temp

    return count_info


def make_read_me(count_info):
    return f"""## 코딩 1일 1문제! ( CODING TEST PRACTICE )
[![SOMJANG LOGO](/images/SOMJANG.png)](https://somjang.tistory.com/category/Programming/%EC%BD%94%EB%94%A9%201%EC%9D%BC%201%EB%AC%B8%EC%A0%9C)
## 하루에 한 문제 씩이라도 코딩문제를 풀어보자! 
### Since 2020.02.07 ~
#### 모든 문제는 Python3 로 해결하였습니다.
{count_info}
#### 아래의 페이지에서 제공하는 문제들로 구성되어 있습니다.
[![BaekJoon](/images/BaekJoon.png)](https://www.acmicpc.net/)
[![Programmers](/images/Programmers.png)](https://programmers.co.kr/)
[![Samsung_SW_Academy](/images/Samsung_SW_Academy.png)](https://swexpertacademy.com/main/main.do)
[![LeetCode](/images/LeetCode.png)](https://leetcode.com/)
[![HackerRank](/images/HackerRank.png)](https://www.hackerrank.com/)
<p align="center"><a href="http://www.jungol.co.kr/"><img src="/images/JUNGOL.png"></a></p>
<p align="center"><a href="https://codeup.kr/"><img src="/images/CodeUp.png"></a></p>"""


def update_readme_md():
    total_code_num, code_cnt_info = count_problem_source_code()

    count_info = make_count_info(total_code_num=total_code_num, code_cnt_info=code_cnt_info)

    readme = make_read_me(count_info=count_info)

    return readme


if __name__ == "__main__":
    readme = update_readme_md()
    with open("./README.md", 'w', encoding='utf-8') as f:
        f.write(readme)

이 코드는 제가 풀어서 올렸던 코드의 이름을 모두 가져와서

각 코드의 이름 속 출처를 정규식을 통해 추출한 뒤 이를 모두 모아 collections의 Counter를 활용하여  카운팅을 합니다.

카운팅 한 수를 내림차순하고 이를 readme 파일 중간에 끼워넣을 내용으로 만들어 끼워 넣습니다.

 

이 코드를 작성할 때 주의해야할 점은

파일의 목록을 가져오려고 하는 디렉토리의 경로나 README.md 파일을 다시 덮어쓰려고할때의 경로를

가장 최상위 디렉토리를 기준으로 진행된다는 것을 염두해두고 작성하는 것입니다.

이 문제로 여러 번 삽질을....하기도 했습니다.

🤩 github actions 세팅하기

그 다음으로 github Actions를 세팅 해주어야 합니다.

CODINGTEST_PRACTICE 레포지토리로 이동하여 Actions 메뉴를 클릭합니다.

여기서 Python application > Set up this workflow를 클릭합니다.

workflow 코드는 아래와 같이 작성합니다.

python-app.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: Python application

on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2
    - name: Set up Python 3.9
      uses: actions/setup-python@v2
      with:
        python-version: 3.9
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
    - name: Run Update Python Script 
      run: |
        python utils/count_problem_source.py
    - name: Run Update README.md File
      run: |
        git add .
        git diff
        git config --local user.email "jjdh11117@gmail.com"
        git config --local user.name "SOMJANG"
        git commit -m ":smiley: Update README.md file"
        git push

자세하게 살펴보면

on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

push나 pull_request 시 실행하도록 하는 부분

- name: Run Update Python Script 
  run: |
    python utils/count_problem_source.py

아까 내가 작성해둔 count_problem_source.py 코드를 실행하는 부분

- name: Run Update README.md File
  run: |
    git add .
    git diff
    git config --local user.email "email"
    git config --local user.name "name"
    git commit -m ":smiley: Update README.md file"
    git push

코드를 통해 수정된 README.md 파일을 반영하는 부분 입니다.

성공하면 위와 같이 초록색으로 표시됩니다.

README.md 파일을 확인해보면 원하는대로 문제의 각 출처별로 문제의 개수가 README.md에 업데이트 되어있는 것을

볼 수 있습니다.

 

※ 이제 앞으로 push를 하기전에 actions가 변경해둔 내용을 로컬에도 반영한 뒤에 push 해야하므로 pull을 받고 push를 해야합니다.

 

이 actions를 활용해서 앞으로 코드를 Push 했을 때 테스트를 자동으로 하거나 자동으로 배포를 하는 것도 해보려합니다.

앞으로도 1,000문제 5,000문제까지 열심히 풀어보려합니다.

 

읽어주셔서 감사합니다.

Comments