Githubアクションをブログ投稿を公開するには

21556 ワード

記事https://aralroca.com/blog/ghaction-devto
私は2017年に参加したときに書き始めました.
私は自分の個人を作成することを決めたいくつかの記事の後blog . しかし、私は常にdev . toに貢献し続けてきた.そういうわけで、私は私の個人的なブログに記事を掲示して、それから、彼らを率直にしてdev . toに共有します.私は、それが標準的な実行であると思います、そして、あなたの1人以上はそれをしています.
私の人生を少しより簡単にするために、私は最近、devに直接投稿するgithubアクションを作りました.

どのように新しい投稿を検出する


記事が新しくて、公開される必要があるかどうかわかっているために、あなたはマークダウンメタデータを使用することができます.私の場合、私は出版の日付をメタデータとして保存します(マスターにマージされても、別の日に公開したい場合).
その後、それがdevに投稿されると、Githubアクションで私は別のメタデータを作成するので、それが公開されてタグ付けされます.
なぜ?Githubアクションが実行されるためです.
  • 何かがマスターにプッシュされるたびに.

  • 毎日17時00分UTCで.
  • このように、すでに公表されたようにポストをマークして、我々が記事を16時にマスターすることを押すならば、我々は2回それを公表するのを避けます.
    発行するGHアクションダイアグラム

    アクションでギタブアクション


    name: Publishing post
    
    on:
      push:
        branches: [master]
      schedule:
        - cron: '0 17 */1 * *'
    
    jobs:
      build:
        runs-on: ubuntu-latest
    
        strategy:
          matrix:
            node-version: [14.x]
    
        steps:
          - uses: actions/checkout@v2
    
          - name: Publishing post
            uses: actions/setup-node@v1
            with:
              node-version: ${{ matrix.node-version }}
          - run: yarn install --pure-lockfile
          - run: DEV_TO=${{secrets.DEV_TO}} yarn run publish:post
          - run: |
              git config user.name aralroca
              git config user.email [email protected]
              git add -A
              git diff --quiet && git diff --staged --quiet || git commit -m "[bot] Published to dev.to"
              git push origin master
    
    何をするか
  • プログラムをマスターにプッシュし、毎日17時00分UTCでcronを使用して動作します.
  • 依存関係をインストールするyarn install --pure-lockfile
  • 環境変数を設定するDEV_TO 使用GitHub secrets . これはスクリプトに必要です.
  • 私たちのスクリプトを実行してdevに公開する
  • 変更があったときのみマスターをコミットしてプッシュします.
  • devに公開するスクリプト


    我々の中でpackage.json ファイルは、スクリプトがノードファイルを実行していることを示す必要があります.
    {
      "scripts": {
        "publish:post": "node ./publish/index.js"
      }
    }
    
    これはdev . toに記事を公開するスクリプトの内容です.
    async function deploy() {
      const post = getNewPost()
    
      if (!post) {
        console.log('No new post detected to publish.')
        process.exit()
      }
    
      await deployToDevTo(post)
    }
    
    console.log('Start publishing')
    deploy()
      .then(() => {
        console.log('Published!')
        process.exit()
      })
      .catch((e) => {
        console.log('ERROR publishing:', e)
        process.exit()
      })
    
    The getNewPost 関数は、dev . oに必要な形式で既にフォーマットされたポストを返す.null 新しい投稿がない場合
    const fs = require('fs')
    const path = require('path')
    const matter = require('gray-matter')
    
    const deployToDevTo = require('./dev-to')
    
    function getNewPost() {
      const today = new Date()
    
      return (
        fs
          .readdirSync('posts')
          .map((slug) => {
            const post = matter(fs.readFileSync(path.join('posts', slug)))
            return { ...post, slug }
          })
          .filter((p) => {
            const created = new Date(p.data.created)
    
            return (
              !p.data.published_devto &&
              created.getDate() === today.getDate() &&
              created.getMonth() === today.getMonth() &&
              created.getFullYear() === today.getFullYear()
            )
          })
          .map(({ slug, data, content }) => {
            const id = slug.replace('.md', '')
            const canonical = `https://aralroca.com/blog/${id}`
            const body = `***Original article: ${canonical}***\n${content}`
    
            return {
              body_markdown: body,
              canonical_url: canonical,
              created: data.created,
              description: data.description,
              main_image: data.cover_image,
              published: true,
              series: data.series,
              slug,
              tags: data.tags,
              title: data.title,
            }
          })[0] || null
      )
    }
    
    私はgray-matter マークダウンメタデータとその内容を取得するライブラリ.
    ここではdeployToDevTo スクリプトで使用する関数
    const fetch = require('isomorphic-unfetch')
    const path = require('path')
    const fs = require('fs')
    
    function createPost(article) {
      return fetch('https://dev.to/api/articles', {
        method: 'POST',
        headers: {
          'api-key': process.env.DEV_TO,
          'content-type': 'application/json',
        },
        body: JSON.stringify({ article }),
      })
        .then((r) => r.json())
        .then((res) => {
          console.log('dev.to -> OK', `https://dev.to/aralroca/${res.slug}`)
          return res.slug
        })
        .catch((e) => {
          console.log('dev.to -> KO', e)
        })
    }
    
    async function deployToDevTo(article) {
      const devToId = await createPost(article)
    
      if (!devToId) return
    
      const postPath = path.join('posts', article.slug)
      const post = fs.readFileSync(postPath).toString()
      let occurrences = 0
    
      // Write 'published_devto' metadata before the second occourrence of ---
      fs.writeFileSync(
        postPath,
        post.replace(/---/g, (m) => {
          occurrences += 1
          if (occurrences === 2) return `published_devto: true\n${m}`
          return m
        })
      )
    }
    
    私たちは、記事をアップロードして、我々のMarkdownpublished_devto: true メタデータ.このように、我々のGithubアクションは、マスターにアップロードする変更があることを検出します.

    結論


    この短い記事では、自動的に私たちの個人的なブログの新しい記事を投稿するgithubアクションを作成する方法を見てきました.私はあなたが役に立つと思います.