我如何提醒使用GitHub Action撰写博客文章
#javascript #写作 #github #githubactions

作为作家,我了解发布新内容的一致性的重要性。但是,有时候生活会阻碍生活,记住写一篇新博客文章可能会很具有挑战性。为了帮助我遵守共享时间表,我使用github动作创建了一个简单的提醒。在这篇文章中,我将分享我如何完成此工作流程。

什么是github动作?

github操作是一种强大的工具,可自动化工作流程。您可以使用它来构建,测试和部署代码。您也可以使用它执行多种其他任务,例如发送通知或调整提醒。

我如何创建一个写博客文章的提醒

要创建一个提醒来撰写博客文章的提醒,我正在使用GitHub special repository of README.md,并添加了一个名为.github/workflows/blog-posts.yml的文件。在此文件中,我定义了GitHub操作将执行的工作流程。这是文件的初始内容:

name: Blog Posts

on:
  schedule:
    - cron: '0 0 * * 0' # Run at 00:00 every Sunday
  workflow_dispatch:

jobs:
  update-posts:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Update post list
        run: |
          sleep 1m
          curl -LO https://blog.imam.dev/feed.xml
          node src/list-posts.js
          rm feed.xml
      - name: Commit changes
        run: |
          git config --local user.email "github-actions[bot]@users.noreply.github.com"
          git config --local user.name "github-actions[bot]"
          git add -A
          git diff-index --quiet HEAD || git commit -m "Update blog posts"
      - name: Pull changes
        run: git pull -r
      - name: Push changes
        uses: ad-m/github-push-action@0fafdd62b84042d49ec0cb92d9cac7f7ce4ec79e
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}

每个星期日的00:00触发此工作流程。然后,它运行一个脚本来更新博客文章列表。该脚本是用JavaScript编写的,并解析了我的博客的RSS feed。然后,它生成了博客文章的列表,并更新了readme.md文件。最后,它提交了变化,并将它们推到github。我正在使用ouuan的存储库作为此工作流的参考。

提醒来自哪里?它实际上在list-posts.js文件中。我在博客文章列表中添加了一个提醒。这是文件的内容:

const { readFileSync, writeFileSync } = require('fs')

/**
 * Convert XML string to JSON
 * @param {string} xmlString
 * @returns {object} json
 */
const xmlToJson = (xmlString) => {
  const regex = /<(\w+)([^>]*)>([\s\S]*?)<\/\1>/gm
  const matches = xmlString.matchAll(regex)
  const json = {}

  for (const match of matches) {
    const [, key, attributes, value] = match
    const subMatches = value.matchAll(regex)
    const subJson = {}

    for (const subMatch of subMatches) {
      const [, subKey, subAttributes, subValue] = subMatch

      if (subValue.match(regex)) {
        if (Array.isArray(subJson[subKey])) {
          subJson[subKey].push(
            xmlToJson(`<${subKey}${subAttributes}>${subValue}</${subKey}>`)[subKey]
          )
        } else if (subJson[subKey]) {
          subJson[subKey] = [
            subJson[subKey],
            xmlToJson(`<${subKey}${subAttributes}>${subValue}</${subKey}>`)[subKey],
          ]
        } else {
          subJson[subKey] = xmlToJson(`<${subKey}${subAttributes}>${subValue}</${subKey}>`)[subKey]
        }
      } else if (Array.isArray(subJson[subKey])) {
        subJson[subKey].push(subValue)
      } else if (subJson[subKey]) {
        subJson[subKey] = [subJson[subKey], subValue]
      } else {
        subJson[subKey] = subValue
      }
    }

    if (json[key]) {
      if (Array.isArray(json[key])) {
        json[key].push(subJson)
      } else {
        json[key] = [json[key], subJson]
      }
    } else {
      json[key] = subJson
    }
  }

  return json
}

/**
 * Sort JSON by pubDate
 * @param {object} json
 * @returns {object} sortedJson
 */
const sortJson = (json) => {
  json.sort((a, b) => new Date(b.pubDate) - new Date(a.pubDate))
  return json
}

// Read XML file and convert to JSON
const xmlString = readFileSync('feed.xml', 'utf8')
const feeds = sortJson(xmlToJson(xmlString).rss.channel.item)

// Create Markdown list of posts
const posts = feeds
  .slice(0, 5)
  .map(
    (item) =>
      `- ${new Date(item.pubDate).toISOString().split('T')[0]} [${item.title}](${
        item.link
      }?utm_source=GitHubProfile)`
  )

// Update README.md if posts have changed,
// Otherwise throw an error to remind me to write a blog post
const readme = readFileSync('README.md', 'utf8')
if (readme.includes(posts.join('\n'))) {
  throw new Error('No new blog posts')
} else {
  const updatedReadme = readFileSync('README.md', 'utf8').replace(
    /(?<=<!--START_SECTION:blog-posts-->\n)[\s\S]*(?=\n<!--END_SECTION:blog-posts-->)/,
    posts.join('\n')
  )
  writeFileSync('README.md', updatedReadme)

  console.log('Updated README.md')
}

脚本读取我博客的RSS feed,并生成博客文章列表。然后,它更新了带有博客文章列表的readme.md文件。如果没有新的博客文章,则会引发错误以提醒我写博客文章。

这只是一个错误,即在帖子仍然相同的情况下执行脚本时会丢下错误,而这不是将发送给我的电子邮件或更明显的提醒。因此,我决定为任何失败的工作流程启用通知。这是这样做的方法:

  1. 单击页面的右上角,然后选择设置
  2. 选择左侧栏上的通知
  3. 单击动作
  4. 选择仅发送失败工作流的通知

现在,执行脚本时,我将收到通知,并且没有新的博客文章。我还可以在GitHub网站上看到通知。

我探索的另一种方式

我告诉您的以前的工作流程是一个修改版本,因此我的readme.md始终是最新的。我还探索了另一种方法来提醒写博客文章。但是,这是一个纯粹的提醒。

为了创建一个写博客文章的提醒,我创建了一个新的github存储库,并添加了一个名为.github/workflows/remind.yml的文件。在此文件中,我定义了GitHub操作将执行的工作流程。这是文件的内容:

name: Reminder to write a blog post

on:
  schedule:
    - cron: '0 10 * * 1-5'

jobs:
  remind:
    runs-on: ubuntu-latest
    steps:
      - name: Send a reminder
        uses: dawidd6/action-send-mail@v3.1.0
        with:
          server_address: smtp.gmail.com
          server_port: 465
          username: ${{ secrets.EMAIL_USERNAME }}
          password: ${{ secrets.EMAIL_PASSWORD }}
          subject: 'Reminder to write a new blog post'
          body: "Don't forget to write a new blog post today!"
          to: my-email@example.com

此工作流程给我发送电子邮件提醒,每个工作日上午10:00,提醒我写一篇新的博客文章。我使用第三方动作Dawidd6/Action-Send-lail发送电子邮件。我提供了我的电子邮件凭据作为github秘密,因此在工作流文件中不可见。

结论

我探索了两种提醒写博客文章的方法。第一种方法是更新我的github配置文件的readme.md文件。第二种方法是发送电子邮件提醒。我目前正在使用第一种方式,因为它比第二种方式更可见。每次访问GitHub个人资料时,我都可以看到提醒。

创建提醒以使用GitHub Action撰写博客文章是一种简单有效的方法,可以跟踪您的博客时间表。有了这个工作流,您将永远不会忘记再次写一篇新帖子。如果您有兴趣创建提醒工作流程,请务必查看GitHub操作文档以了解更多信息。愉快的博客!