GitHub 저장소에서 dev.to 블로그를 관리합니다.

소개



서로 도와주는 엔지니어 커뮤니티인 Zenn에서 일본어로 블로그를 합니다. Zenn을 사용하면 GitHub 리포지토리에서 블로그를 관리하고 내가 가장 좋아하는 편집기에서 기사를 작성할 수 있습니다. 또한 CI/CD를 사용하여 내 블로그에 자동으로 게시되는 기사를 기본 분기로 병합합니다.
dev.to도 같은 방식으로 블로그를 만들고 싶고, 이 글을 참고하여 dev.to 블로그를 GitHub 리포지토리에서 관리하고 자동으로 게시/업데이트한다는 사실을 깨달았습니다.

DEV API으로 GitHub Actions CI/CD를 구현합니다. 위의 글을 바탕으로 저의 dev.to 블로그 관리 방법을 소개합니다.

구축 방법


1. 템플릿 복사



기사 작성자의 저장소로 이동합니다. https://github.com/Yuhta28/dev-to-blog-template 템플릿을 복사합니다.

2. DEV 커뮤니티 API 키 생성



DEV 커뮤니티 API 키로 이동하여 생성하십시오.

3. API 키를 GitHub Actions로 설정



템플릿에서 복사한 GitHub 리포지토리로 이동하여 API Key를 Actions secrets로 설정합니다.

4. GitHub Actions 워크플로 구축



참조 문서에서 prettier을 사용하여 마크다운 및 코드 스니펫의 형식을 지정합니다. 그 외에 textlintreviewdog을 사용하여 텍스트 리뷰를 구현합니다.

name: Build and Deploy

on:
  push:
    branches: [main]
  pull_request:

jobs:
  build:
    name: Build
    if: github.event_name == 'pull_request'
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Repo
        uses: actions/checkout@master

      - name: Install reviewdog
        uses: reviewdog/action-setup@v1
        with:
          reviewdog_version: latest

      - name: Install Dependencies
        uses: bahmutov/npm-install@v1

        #Make sure that cache is retrieved even if steps fail
      - name: cache-node-modules
        uses: pat-s/always-upload-cache@v3
        env:
          cache-name: cache-node-modules
        with:
          path: ~/.npm
          key: node-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            node-

      - name: Install textlint
        run: 'npm install --save-dev textlint textlint-rule-common-misspellings textlint-rule-spellchecker'

      - name: Run textlint
        run: npx textlint -f checkstyle "blog-posts/**/*.md" >> .textlint.log

      - name: Run reviewdog
        if: failure()
        env:
          REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          cat .textlint.log
          cat .textlint.log | reviewdog -f=checkstyle -name="textlint" -reporter="github-pr-review"

      - name: Run Prettier
        run: yarn run prettier:check

      - name: Run Embedme
        run: yarn run embedme:check

  deploy:
    name: Deploy
    if: github.ref == 'refs/heads/main' && github.event_name == 'push'
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Repo
        uses: actions/checkout@master

      - name: Install Dependencies
        uses: bahmutov/npm-install@v1

      - name: Deploy to dev.to
        run: DEV_TO_GIT_TOKEN=${{ secrets.DEV_TO_GIT_TOKEN }} yarn run dev-to-git


5. dev.to와 GitHub 연결


repository.url에서 속성package.json을 정의하고 GitHub 리포지토리 URL로 설정합니다.

  "name": "dev.to",
  "repository": {
    "type": "git",
    "url": "https://github.com/Yuhta28/dev-to-blog.git"
  }


6. 새 기사 작성



DEV API를 사용하기 위해 새 문서에 대한 템플릿을 만듭니다. go run create-post.go
package main

import (
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
    "os"
    "strings"
)

func main() {
    DEVAPIKEY := os.Getenv("DEVAPIKEY") //Set your dev.to API key in your environment variables
    client := &http.Client{}
    var data = strings.NewReader(`{"article":{"title":"Template","body_markdown":"Body","published":false,"tags":["tag1", "tag2"]}}`)
    req, err := http.NewRequest("POST", "https://dev.to/api/articles", data)
    if err != nil {
        log.Fatal(err)
    }
    req.Header.Set("Content-Type", "application/json")
    req.Header.Set("api-key", DEVAPIKEY)
    resp, err := client.Do(req)
    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()
    bodyText, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("%s\n", bodyText)
}


아쉽게도 템플릿은 GitHub 리포지토리에 연결할 수 없으므로 문서 ID를 가져와서 dev-to-git.json에 설정해야 GitHub 리포지토리에 연결할 수 있습니다.

7. 기사 ID 설정



DEV API를 사용하려면 기사 ID도 얻으십시오. go run get-blog-id.go
package main

import (
    "encoding/json"
    "fmt"
    "log"
    "net/http"
    "os"

    "github.com/itchyny/gojq"
)

func curl() interface{} {
    DEVAPIKEY := os.Getenv("DEVAPIKEY") //Set your dev.to API key in your environment variables
    client := &http.Client{}
    req, err := http.NewRequest("GET", "https://dev.to/api/articles/me/unpublished", nil)
    if err != nil {
        log.Fatal(err)
    }
    req.Header.Set("api-key", DEVAPIKEY)
    resp, err := client.Do(req)
    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()
    var data interface{}
    err = json.NewDecoder(resp.Body).Decode(&data)
    if err != nil {
        log.Fatal(err)
    }
    return data
}

func main() {
    // Parse JSON
    query, err := gojq.Parse(".[].id")
    if err != nil {
        log.Fatalln(err)
    }
    input := curl()
    iter := query.Run(input) // or query.RunWithContext
    for {
        v, ok := iter.Next()
        if !ok {
            break
        }
        if err, ok := v.(error); ok {
            log.Fatalln(err)
        }
        fmt.Printf("%1.0f\n", v)
    }
}


8. 새 기사의 템플릿 만들기



새 문서의 템플릿을 만듭니다. go run make-template.go
package main

import (
    "fmt"
    "os"
)

func main() {

    var blog string

    print("Enter the name of the new article: ")
    fmt.Scan(&blog)

    // Create blog directory and article file
    if err := os.MkdirAll("blog-posts/"+blog, 0777); err != nil {
        fmt.Println(err)
    }
    file_article, err := os.Create("blog-posts/" + blog + "/" + blog + ".md")
    if err != nil {
        fmt.Println(err)
    }
    defer file_article.Close()

    // Add blog metadata in article file
    file_article.WriteString("---\ntitle: Title \npublished: false\ndescription: description\ntags: tag1, tag2\n---\n")

    // Create code directory
    if err := os.MkdirAll("blog-posts/"+blog+"/code", 0777); err != nil {
        fmt.Println(err)
    }
    file_code, err := os.Create("blog-posts/" + blog + "/code/.gitkeep")
    if err != nil {
        fmt.Println(err)
    }
    defer file_code.Close()

    // Create assets directory
    if err := os.MkdirAll("blog-posts/"+blog+"/assets", 0777); err != nil {
        fmt.Println(err)
    }
    file_assets, err := os.Create("blog-posts/" + blog + "/assets/.gitkeep")
    if err != nil {
        fmt.Println(err)
    }
    defer file_assets.Close()
}


9. 문서 ID를 템플릿과 연결



템플릿이 있는 문서 ID를 dev-to-git.json에 연결합니다.

[
  {
    "id": 773216,
    "relativePathToArticle": "./blog-posts/cw-oss-cloudwatch/i-use-cw-which-is-oss-to-tail-aws-cloudwatch-logs-2e9g.md"
  },
  {
    "id": 1056501,
    "relativePathToArticle": "./blog-posts/repography-make-readme-rich/repography-makes-github-repository-beautiful-3dn3.md"
  }
]


10. 기사 배포



GitHub 리포지토리에서 내 dev.to 블로그를 관리하면 완성입니다. 그런 다음 메인 브랜치에 푸시 브랜치와 풀 리퀘스트를 하고 GitHub Actions CI/CD를 실행합니다.



결론



GitHub 저장소에서 dev.to 블로그를 관리했습니다. 버전 관리가 쉬워지고 내가 가장 좋아하는 편집기(Visual Studio 코드)를 사용하여 기사를 작성할 수 있습니다. 게다가 linter 도구는 내가 글을 쓸 때 부주의한 실수를 줄이는 데 도움이 됩니다. 자, dev.to에서 글을 작성할 때 이 방법을 시도해 봅시다.

원래의



https://zenn.dev/yuta28/articles/dev-github-vscode

참조

좋은 웹페이지 즐겨찾기