发布于 2026-01-06 0 阅读
0

静态自述文件重新生成 git-auto-commit 行动 DEV 的全球展示与讲述挑战赛,由 Mux 呈现:展示你的项目!

静态自述文件重新生成

git-auto-commit 操作

由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!

原文链接:https://aralroca.com/blog/static-readme-regeneration

GitHub 最近推出了一项“隐藏”功能,可以在个人资料页面上显示 Markdown 模板。你可能已经听说过这项功能了。你只需要创建一个以你的用户名命名的仓库,并README.md在其中创建该文件即可。

提到 GitHub 上的 Markdown 模板,我们通常会想到静态内容。然而,在本文中,我想更进一步。我将告诉你如何添加会不时更新的内容;无论是你最新的推文、最新的 YouTube 视频还是最新的博客文章。

我的GH个人资料

我的 GitHub README 个人资料位于aralroca仓库下

我们将涵盖以下内容:

关于静态自述文件再生(SRR)

所谓“静态 README 重生成”,是指 README 文件README.md由我们的脚本生成,然后我们通过一个机器人(由我们编程)定期更新其内容README.md。这种方式的妙处在于,机器人只有在 README 文件README.md真正发生更改时才会提交到代码仓库。这样一来,README 的内容就不能完全静态,它可以每天、每小时甚至每分钟都发生变化。

为了实现这一点,我们将使用带有 cron 任务的 GitHub Action:

GitHub README配置文件的静态重生图

关于使用 GitHub Actions 进行静态重生成的示意图

执行

我以我的个人资料为例。它始终显示我博客的最新五篇文章,并且每天都会更新(如有必要)。这样我就能安心了,因为我知道当我上传新文章时,README.md我的个人资料会自动更新。

README.tpl

我们来创建一个README.md.tpl文件,这种.tpl格式用于模板文件。这个文件将包含所有静态内容README.md。我们将在这里编写 Markdown 代码,就像我们在README.md文件中编写代码一样。

主要区别在于,我们会使用一些插值符号来添加需要动态变化的内容。这样,我们的脚本就能用动态内容替换它们。

README.md.tpl 图
关于从.md.tpl到插值的图表.md

用于生成 README.md 文件的脚本

脚本必须:

  • 读取文件README.tpl.md
  • 从https://aralroca.com/rss.xml获取所有帖子
  • 排序方式pub_date+ 筛选条件 5.
  • README.md文件中的插值替换README.tpl.md为 5 篇文章,格式为 Markdown 字符串。



实施步骤

这可以用任何语言实现;JavaScript、Rust、Python、Go、C……在这种情况下,我选择了Rust,主要是因为我没有使用经验,所以我借此机会学习了一点(如果您是 Rust 专家,并且看到了可以改进的地方,请随时在仓库中创建一个问题)

> main.rs

mod create_readme;

use create_readme::create_readme;

fn main() {
    match create_readme() {
        Ok(_v) => println!("README.md file generated correctly"),
        Err(e) => println!("Opps! there was an error: {:?}", e),
    }
}
Enter fullscreen mode Exit fullscreen mode

> 创建自述文件

extern crate chrono;
extern crate rss;

use chrono::DateTime;
use rss::Channel;
use std::cmp::Ordering;
use std::fs;

struct FeedItem {
    title: String,
    link: String,
    pub_date: String,
}

pub fn create_readme() -> std::io::Result<()> {
    let tpl =
        fs::read_to_string("README.md.tpl")
        .expect("Something went wrong reading the README.tpl file");

    let last_articles = get_latest_articles();

    return fs::write(
        "README.md",
        tpl.replace("%{{latest_articles}}%", &last_articles),
    );
}

fn get_latest_articles() -> String {
    let mut posts: Vec<FeedItem> = get_blog_rss();

    // Sort articles by pub_date
    posts.sort_by(|a, b| {
        let date_a = DateTime::parse_from_rfc2822(&a.pub_date).unwrap();
        let date_b = DateTime::parse_from_rfc2822(&b.pub_date).unwrap();

        if date_b < date_a {
            Ordering::Less
        } else if date_b > date_a {
            Ordering::Greater
        } else {
            Ordering::Equal
        }
    });

    // Filter las 5 articles + format each one as markdown list string
    return posts[..5].iter().fold("".to_string(), |acc, item| {
        format!("{} \n* [{}]({})", acc, item.title, item.link)
    });
}

// Fetch all articles of my blog on rss.xml
fn get_blog_rss() -> Vec<FeedItem> {
    let items = Channel::from_url("https://aralroca.com/rss.xml")
        .unwrap()
        .items()
        .iter()
        .map(|item| FeedItem {
            title: item.title().unwrap().to_string(),
            link: item.link().unwrap().to_string(),
            pub_date: item.pub_date().unwrap().to_string(),
        })
        .collect();

    items
}
Enter fullscreen mode Exit fullscreen mode

GitHub Action 配合 cron 任务

一旦我们有了构建脚本README.md,我们只需要使用 GitHub Action 生成 cron 任务即可。

要创建 Action,我建议先将脚本上传到 master 分支,然后点击 GitHub 的“Actions”选项卡进行创建。这样,GitHub 就能检测到脚本语言(本例中为 Rust)并创建一个默认的 YAML 文件。

GitHub Actions 选项卡

我们将替换默认 YAML 文件中的一些内容,以便:

  • 安排一个定时任务
  • 运行脚本cargo run而不是cargo build && cargo test
  • 提交重新生成的 README 文件(仅当其有更改时)

> .github/workflows/rust.yml

name: Rust

on:

  # Schedule a cron
  schedule:
    - cron: "0 0 */1 * *" # each day at 00:00 UTC

env:
  CARGO_TERM_COLOR: always

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2
    - name: Build

    # Replace "cargo build" to "cargo run" to run the script
      run: cargo run

    # Commit the regenerated README only when it change 
    # (git diff --quiet && git diff --staged --quiet )
    - run: |
        git config user.name aralroca
        git config user.email aral-rg@hotmail.com
        git add README.md
        git diff --quiet && git diff --staged --quiet || git commit -m "[gh-action] Update README"
        git push origin master
Enter fullscreen mode Exit fullscreen mode

结论

总之,虽然大多数仓库中的 README 文件始终是静态的,但得益于 GitHub Actions 和 GitHub 的这项新功能,我们可以构建自己的README.md仓库,使其始终包含最新的更新(发布、PR、推文、帖子……)。

参考

文章来源:https://dev.to/aralroca/static-readme-regenesis-4pf2