π Git Blog μλν νλλ²
π λΈλ‘κ·Έλ₯Ό μ μ¨μΌ νλμ§?!
κ°λ°μλ κΈ°μ λΈλ‘κ·Έλ₯Ό ν΅ν΄ μμ μ κ²½νμ 곡μ νκ³ , λ€λ₯Έ κ°λ°μλ€κ³Ό μ§μμ 곡μ νλ©° μ±μ₯ν μ μμ΅λλ€.
λν, λΈλ‘κ·Έλ₯Ό μ΄μν¨μΌλ‘μ¨ μμ μ νλ‘μ νΈλ ν¬νΈν΄λ¦¬μ€λ₯Ό λ³΄λ€ μ½κ² 곡μ νκ³ , κ°μΈ λΈλλ©μλ λμμ΄ λ©λλ€.
μμ§νκ² κ΄κ³ λ‘ μΌλ§λ₯Ό λ² μ μλμ§ νλ² μ¬μ¬ν΄μ μμνμ΅λλ€. γ γ γ β¦
κ°λ°μ λν΄ μ΄μ§μ΄λΌλ μκ³ κ³μλ©΄ μΆμ² ν©λλ€!
π¨ μ€λΉλ¬Όμ΄ 무μμ΄ νμνμ§?!
μλνλ Git Blogλ₯Ό μ΄μνκΈ° μν΄ νμν μ€λΉλ¬Όμ λ€μκ³Ό κ°μ΅λλ€.
- Git κ³μ λ° λΈλ‘κ·Έ νΈμ€ν νλ«νΌ (e.g. GitHub, GitLab, Bitbucket, Gitea λ±)
- μ μ μ¬μ΄νΈ μμ±κΈ° (e.g. Jekyll, Hugo, Pelican λ±)
- λ§ν¬λ€μ΄ μλν° (e.g. Typora, Visual Studio Code λ±)
- μλν μ€ν¬λ¦½νΈ (e.g. GitHub Actions, Travis CI λ±)
μ κ° μΈμ λ μν€ν
μ²λ GitHub Actionsλ₯Ό μ¬μ©νμ¬ Jekyll κΈ°λ°μ μ μ λΈλ‘κ·Έλ₯Ό μλννλ λ°©λ²μ
λλ€.
1. Github blog λ₯Ό μ¬μ©νλ€. (API μ¬μ© ν μ μλ€λ©΄ μ΄λ€ λΈλ‘κ·Έμ¬λ μκ΄μμ΅λλ€.)
2. μ€μΌμ₯΄λ¬λ₯Ό λ릴 μ μλ νκ²½μ΄ μμ΄μΌλλ€. (μλμΌλ‘ μ£Όμ μ λν΄ ChatGpt νν
μ¨λ¬λΌκ³ ν κ±°κ±°λ μ.)
3. κ°λ¨νκ² μ€ν μν¬ νμΌμ΄ μμ΄μΌλ©λλ€. (Python, Node ...)
κ°λ¨νκ² μ 리νλ©΄ μν€ν
μ²λ μλμ κ°μ΅λλ€.
1. Python μ μ΄μ©ν΄μ ChatGpt μ°λ ν μ£Όμ λ₯Ό DB λλ κ΅¬κΈ μνΈλ‘ λͺ¨μ λλλ€.
2. Github action μ€μΌμ₯΄λ¬λ₯Ό μ¬μ©νμ¬ λκ°μ μ‘μ λ§λ λ€.
a. μ£Όμ μμ± λ° κ²ΉμΉμ§ μκ² κ΄λ¦¬ νλ Job
b. μ£Όμ μ λν΄ μ»¨ν
μΈ λ₯Ό λ§λλ Job
3. μ€μΌμ₯΄λ¬κ° μ μμ μΌλ‘ λ ν Github > commit & deploy μ§ν μν¨λ€. (CI/CD ꡬμΆ)
ps.λμ€μ κ·Έλ¦Ό μΆκ° μμ μ
λλ€.
π§ λΈλ‘κ·Έ κΈμ μλν νλλ°©λ² !?
λΈλ‘κ·Έλ₯Ό μλννλ λ°©λ²μ ν¬κ² λ κ°μ§λ‘ λλ μ μμ΅λλ€.
첫째λ μ μ μ¬μ΄νΈ μμ±κΈ°μ Git νΈμ€ν νλ«νΌμ μ¬μ©νμ¬ λΈλ‘κ·Έλ₯Ό λ§λ λ€, Git Actionκ³Ό κ°μ CI/CD λꡬλ₯Ό μ΄μ©νμ¬ μ»¨ν μΈ λ₯Ό μλμΌλ‘ μμ±νκ³ , λΉλ λ° λ°°ν¬νλ λ°©λ²μ λλ€. μ΄ λ°©λ²μ λΈλ‘κ·Έμ κ΅¬μ‘°κ° μ μ μ΄κΈ° λλ¬Έμ μμ±λ 컨ν μΈ κ° λ§μ§ μλ€λ©΄ μ’ λ μ½κ² μλνν μ μμ΅λλ€.
λμ§Έλ λμ μΈ λΈλ‘κ·Έλ₯Ό λ§λ€μ΄ μλ²λ₯Ό ν΅ν΄ μλννλ λ°©λ²μ λλ€. μ΄ λ°©λ²μ λΈλ‘κ·Έκ° λμ μΈ νΉμ±μ λκΈ° λλ¬Έμ 컨ν μΈ λ₯Ό μμ±νκ³ λ°°ν¬νλ κ³Όμ μ΄ λ 볡μ‘ν΄μ§ μ μμ΅λλ€. κ·Έλ¬λ μ΄ λ°©λ²μ μ¬μ©νλ©΄ λΈλ‘κ·Έμ μ’ λ λ§μ κΈ°λ₯μ μΆκ°ν μ μμΌλ©°, λΈλ‘κ·Έ μ΄μμ μμ΄μ λμ± μ μ°μ±μ΄ μμ΅λλ€.
μ΄λ€ λ°©λ²μ μ ννλλΌλ λΈλ‘κ·Έλ₯Ό μλννλ κ²μ κ°λ°μλ‘μμ μλμ λμ΄λλ° ν° λμμ΄ λ©λλ€. 컨ν μΈ λ₯Ό μμ±νκ³ , λ°°ν¬νλ κ³Όμ μ μλνν¨μΌλ‘μ¨ κ°λ°μλ μ’ λ λ§μ μκ°μ κ°λ°μ μ§μ€ν μ μμΌλ©°, λΈλ‘κ·Έ μ΄μμ λν λΆλ΄μ μ€μΌ μ μμ΅λλ€.
μ λ λλ²μ§Έ λ°©λ²μΌλ‘ μ§νν μμ μ λλ€.
Git blog λ§λλλ²
- λΈλ‘κ·Έ μ μ₯μ μμ± λ° Jekyll ν λ§ μ μ©
- GitHub, GitLab, Bitbucket λ±μ Git νΈμ€ν νλ«νΌμμ μλ‘μ΄ μ μ₯μλ₯Ό μμ±νκ³ , Jekyll κΈ°λ°μ μ μ λΈλ‘κ·Έ ν λ§λ₯Ό μ μ©ν©λλ€.
- μ κ²½μ°λ μ€μ½λ©λ Blog ν νλ¦Ώμ κ°κ³ μμ μ¬μ©νμ΅λλ€.
μλν μ€ν¬λ¦½νΈ μμ±
- GitHub Actionsμ μ¬μ©νμ¬ λΈλ‘κ·Έλ₯Ό μλμΌλ‘ λΉλνκ³ λ°°ν¬νλ μλν μ€ν¬λ¦½νΈλ₯Ό μμ±ν©λλ€.
Github action μ μ μ€λΉ μμ ν΄λΉνλ Github Reposittory > setting > security > action
- MY_EMAIL, MY_NAME, MY_TOKEN, OPENAI_API_KEY μΆκ°ν΄μ£ΌμΈμ.
μ΄ μ€ν¬λ¦½νΈλ λΈλ‘κ·Έ μ μ₯μμ .github/workflows λλ ν 리μ μμ±λ©λλ€.
-
μλλ yaml μμμ λλ€.
name: Auto Publish Blog Posts by μ(Son/μλ―ΌκΈ°) on: schedule: - cron: '0 0 * * *' jobs: generate-blog-post: runs-on: ubuntu-latest steps: - name: Checkout Repository uses: actions/checkout@v2 - name: Set up Python uses: actions/setup-python@v2 with: python-version: 3.x - name: Cache Python packages uses: actions/cache@v2 with: path: ~/.cache/pip key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} restore-keys: | ${{ runner.os }}-pip- - name: Install Required Python Packages run: | python -m pip install --upgrade pip pip install gitpython pip install -r requirements.txt - name: Generate Blog Post env: OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} run: python generate_blog_post.py - name: Commit Changes env: MY_EMAIL: ${{ secrets.MY_EMAIL }} MY_NAME: ${{ secrets.MY_NAME }} MY_TOKEN : ${{ secrets.MY_TOKEN }} run: | git config --local user.email $MY_EMAIL git config --local user.name $MY_NAME git remote set-url origin https://$MY_NAME:$MY_TOKEN@github.com/smk692/smk692.github.io.git git add . git commit -m "Add a new blog post" git push deploy: needs: generate-blog-post runs-on: ubuntu-latest steps: - name: Checkout Repository uses: actions/checkout@v2 - uses: actions/setup-node@v3 with: node-version: v14.17.4 - name: Cache node modules uses: actions/cache@v2 with: path: ~/.npm key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }} restore-keys: | ${{ runner.os }}-npm- - name: Npm install run: npm install - name: Update blog env: MY_EMAIL: ${{ secrets.MY_EMAIL }} MY_NAME: ${{ secrets.MY_NAME }} MY_TOKEN : ${{ secrets.MY_TOKEN }} run: | git config --local user.email $MY_EMAIL git config --local user.name $MY_NAME git remote set-url origin https://$MY_NAME:$MY_TOKEN@github.com/smk692/smk692.github.io.git npm run deploy
-
GitHub Actionsμ μ¬μ©νμ¬ λΈλ‘κ·Έ 컨ν μΈ μ λ°μ΄νΈνλ νμ΄μ¬ μ½λμ λλ€. (generate_blog_post.py)
# ...import λΆλΆ μλ΅ def generate_contents(topic): openai.api_key = os.getenv("OPENAI_API_KEY") prompt_contents = f''' {topic} λν΄μ μμΈνκ² μ μ΄μ€ ''' contents = connection_chatgpt(prompt_contents) contents = '\n'.join(contents.strip().split('\n')[3:]) return contents def connection_chatgpt(prompt): response = openai.Completion.create( model="text-davinci-003", prompt=prompt, temperature=1, max_tokens=3800, top_p=1, frequency_penalty=0.0, presence_penalty=0.6, ) contents = "" for choice in response.choices: contents += choice.text return contents def create_blog_post(topic, tags, categories, contents): # ν΄λκ° μμΌλ©΄ μμ± if not os.path.exists(directory_path): os.makedirs(directory_path) # λΈλ‘κ·Έ ν¬μ€νΈμ μ¬μ©λ λ©νλ°μ΄ν° metadata = [ "---", "layout: post", f"title: \"{topic}\"", f"date: '{now.strftime('%Y-%m-%d %H:%M:%S')}'", f"author: μ(Son/μλ―ΌκΈ°)", f"tags: {tags}", f"categories: {categories}", "---" ] # λΈλ‘κ·Έ ν¬μ€νΈ νμΌ μμ± with open(file_name, "w") as f: f.write("\n".join(metadata)) f.write("\n") f.write(contents) print(f"λΈλ‘κ·Έ ν¬μ€νΈ νμΌμ΄ μμ±λμμ΅λλ€: {file_name}") if __name__ == "__main__": topic = "λΈλ‘κ·Έ μλν!" tags = "gitblog" categories = "μλν" contents = generate_contents(topic) pprint.pprint(contents) create_blog_post(topic, tags, categories, contents)
β μμ±λ κ²°κ³Όμ λν μ€ν¬λ¦°μ·!
-
Github action κΈ μμ± λ κ²°κ³Ό
-
Github action κΈ λ°°ν¬ λ κ²°κ³Ό
-
Github blog μ λ°μ΄νΈ λ κ²°κ³Ό
μκ°
μ΄μμΌλ‘ λΈλ‘κ·Έ μλνμ λν΄ μμ보μμ΅λλ€.
μλνλ₯Ό ν΅ν΄ κ°λ°μλ λΈλ‘κ·Έ μ΄μμ λ³΄λ€ ν¨μ¨μ μΌλ‘ ν μ μκ³ , λ λ§μ μκ°μ κ°λ°μ μ§μ€ν μ μμ΅λλ€.
λ§μ κ°λ°μλΆλ€μ΄ μ΄ κΈμ λ³΄κ³ μμ λ§μ μλνλ λΈλ‘κ·Έλ₯Ό μ΄μνμκΈΈ λ°λλλ€!
ps. κ°λ¨νκ² μ§ κ±°λΌ νμνλ©΄ κ°κ³ κ°μλ©΄ λ©λλ€. (λμ λκΈ νλλ§ μ μ΄μ£ΌμΈμ.)
λ°λ° μ 무쑰건 μκ°νκ² λ§μ΅λλ€.