Total Pageviews

Showing posts with label github. Show all posts
Showing posts with label github. Show all posts

Wednesday, 30 April 2025

GitHub的维基百科上线

 

Cognition AI 公司推出了一款产品:DeepWiki ,既然叫 Wiki 大家就明白了,就像是维基百科一样,只不过 DeepWiki 是给 GitHub 搭建的百科全书。

它的作用就是主要用于帮助开发者快速了解 GitHub 仓库内容,为 GitHub 仓库提供自动生成类似 Wikipedia 的交互式文档和交互式分析功能。

一般来讲,GitHub 仓库的 README 文件是有开发者自己写的,很多开发者写的可能简略或难以理解,尤其是对于大型或复杂的项目,不能只通过 README 文件就能完全讲清楚。

那对于学习者来讲,看简略的 README 可能学习起来门槛就比较高,不能足够让大家了解。

DeepWiki 则通过 AI技术去自动分析 GitHub 仓库上的代码,自动给大家生成一份详细的文档,我看了看,确实写的非常详细,还带有各种图表。

DeepWiki 是由 Cognition AI 公司推出,提这个公司大家如果不了解的话,但是,提到 Devin 大家可能就有印象了,没错, Devin 这个 AI 程序员就是 Cognition AI 公司研发的。

DeepWiki 包括以下功能:

  • 自动文档:解释代码结构、函数和依赖关系。
  • 交互式图表:如类层次结构和依赖图,帮助可视化代码。
  • AI 聊天助手:基于 Devin 技术,回答关于仓库的具体问题。
  • 深度查询:支持发现 bug、优化建议等复杂分析。
图片

据说,DeepWiki 已经分析了超过 400 亿行代码,涵盖了 30,000 多个仓库,耗费了 30 万美元的计算资源,能力很强大。所以,一经推出,业界称它为“一个免费的 GitHub 仓库百科全书”。

如果使用呢?方法很简单,都不需要注册就可以使用,而且提供了非常方便的转换方式,这进一步降低了使用门槛。

方法就是:对于任何公开的 GitHub 仓库,用户只需将 URL 中的 "github.com" 替换为 "deepwiki.com",即可立即帮你转换成交互式文档

举个例子,比如,我刚才在 GitHub 热榜上看到一个比较火的开源项目:

https://github.com/ocrmypdf/OCRmyPDF

这个开源项目的功能是为扫描的 PDF 文件添加 OCR 文本层,允许其进行搜索。

我这里将链接当中的 "github" 替换为 "deepwiki" ,链接就变成了:

https://deepwiki.com/ocrmypdf/OCRmyPDF

我们直接访问这个链接,就可以看到 OCRmyPDF 这个项目的详细文档了

图片

大家可以看看,关于 OCRmyPDF 这个开源项目的文档非常全面,侧边栏有概述介绍、核心架构、高级功能、部署选项等等各种功能介绍。

甚至会帮你生成各种架构图和流程图来帮助你理解这个开源项目的核心代码以及功能。

图片

更甚者,还支持代码问答:

图像

对于不同的地方可以直接问 AI ,有深度研究功能。

我感觉 DeepWiki 的诞生,对于开发者和学习者都非常有帮助。

对于开发者开源项目,以后不用自己写文档了,将代码上传到 GitHub 之后,直接让 DeepWiki 帮你生成文档之后,复制到 README 文件中就行了

对于开源项目的学习者呢?看不懂开源代码的可以用 DeepWiki 来帮你生成文档,详细跟 DeepWiki 交流咨询就解决了

大家可以去试一试。

这个创意非常赞,既解决了程序员不爱写文档的痛点,也降低了开源项目的学习门槛。

from https://mp.weixin.qq.com/s/snkm35BaahYuIn4l6t1LNQ

Sunday, 13 April 2025

GitHub的开源库里,可能会有恶意程序

 

卡巴斯基全球研究与分析团队(GReAT)在一项被卡巴斯基称为GitVenom的行动中发现数百个开源存储库包含针对游戏玩家和加密货币投资者的恶意程序。受感染的项目包括用于与 Instagram 帐户交互的自动化工具、能够远程管理比特币钱包的 Telegram 机器人以及用于玩 Valorant 游戏的破解工具。所有这些所谓的项目功能都是假的,该活动背后的网络犯罪分子窃取了个人和银行数据,并从剪贴板中劫持了加密钱包地址。由于恶意活动,网络犯罪分子能够窃取 5 个比特币(调查时约为 485,000 美元)。卡巴斯基在全球范围内检测到了受感染存储库的使用情况,其中大多数发生在巴西、土耳其和俄罗斯。

虽然这些项目是用多种编程语言(Python、JavaScript、C、C++ 和 C#)编写的,但存储在受感染项目中的恶意负载具有相同的目标:从攻击者控制的 GitHub 存储库下载其他恶意组件并执行它们。这些组件包括一个窃取程序,它收集密码、银行账户信息、保存的凭据、加密货币钱包数据和浏览历史记录,将其打包到 .7z 存档中,并通过 Telegram 将其上传到攻击者

安全报告原文:https://www.kaspersky.com/about/press-releases/kaspersky-exposes-hidden-malware-on-github-stealing-personal-data-and-485000-in-bitcoin

Monday, 17 March 2025

generate-albums


项目模板

https://github.com/jkjoy/generate-albums

设置

在自己仓库的Settings中找到

TOKEN为你的 Github token

REPO为你想要生成相册的仓库名称 如username/repo

上传规则

相册内容上传到 photos 这个目录下

photos 根目录下的照片默认标题为分享生活

新建文件夹, 该文件夹名称为此目录下所有图片的标题

  • 照片同名txt中的文本为描述说明 最高优先级
    1.jpg 1.txt 则使用1.txt中的文本为描述说明

  • 目录下描述.txt为此目录下所有图片的描述说明 第二优先级

  • 如果两者都没有则使用照片文件名为描述说明

其他部分

可以根据需求修改 template目录下对应模板的index.html文件 中的布局和内容.

每次修改仓库会自动触发Action 生成HTML到目标仓库,目标仓库可以使用Github Pages,也可以部署在Vercel,这里就不多做说明

演示

https://photo.memos.top/

-----------------------------------

自动化生成相册Automatically generate photo albums.

photos-jkjkjoy.vercel.app/ 

 

自动化生成相册

具体功能

把源仓库作为私有仓库,存放照片

脚本会自动抹除照片含有exif的信息(如果有).

在目标仓库生成缩略图和原图(已处理).

点击缩略图会打开展示原图.

免责

模板来自于网络

可以自行修改模板

使用方法

Tip

使用方法

  1. 点击Use this template创建一个新的仓库

action中设置secret

TOKEN为你的github token

REPO为你想要生成相册的仓库名称 如username/repo

  1. template目录下为模板文件,可自行调整 标题 等
  1. photos为图片文件夹,照片上传到此文件夹中,会自动生成相册

photos 根目录下的照片默认标题为分享生活

新建文件夹,文件夹名称为标题

照片同名txt中的文本为描述说明 最高优先级

1.jpg 1.txt 则使用1.txt中的文本为描述说明

目录下描述.txt为此目录下所有图片的描述说明 第二优先级

如果两者都没有则使用照片文件名为描述说明.

from https://github.com/jkjoy/generate-albums

 

Friday, 28 February 2025

搭建基于github issue的静态博客程序egi


  首先 fork 此项目https://github.com/eyasliu/eyasliu.github.io,我fork 后的项目地址是https://github.com/briteming/egi ,然后访问https://github.com/briteming/egi/settings,勾选issues. 新建一些issues.

   编辑config.js文件- https://github.com/briteming/egi/blob/master/config.js,把user和repo的值分别改为你的github用户名和仓库名。

然后访问app.netlify.com ( 需先登录),导入项目https://github.com/briteming/egi.

 在来到如下页面https://app.netlify.com/start/repos/briteming%2Fegi时,

在 Site name栏,填写一个你所选择的二级域名,我选择的是egi-brite ,


 Base directory栏的值,填   ./ (意思就是项目的根目录)

 Build command栏的值,填 npm run build

 Publish directory栏的值,填  ./ (因为项目的根目录下有index.html, 所以 Publish directory其实就是项目的根目录)

然后点击页面底部的 deploy按钮。等待部署完成,部署完成后,app.netlify.com网站给我的网址是https://egi-brite.netlify.app

演示网站: https://egi-brite.netlify.app/

项目地址:https://github.com/eyasliu/eyasliu.github.io

https://github.com/briteming/egi

---------------------------------------------

 首先 fork 此项目https://github.com/eyasliu/eyasliu.github.io,我fork 后的项目地址是https://github.com/ymbrite/egi

然后访问https://github.com/ymbrite/egi/settings,勾选issues. 新建一些issues.

   编辑config.js文件- https://github.com/ymbrite/egi/blob/master/config.js,把user和repo的值分别改为你的github用户名和仓库名。

然后访问vercel.com/new ( 需先登录),导入项目https://github.com/ymbrite/egi.

部署完成后,vercel.com/new网站给我的网址是https://egi-blond.vercel.app/

演示网站:https://egi-blond.vercel.app/

项目地址:https://github.com/eyasliu/eyasliu.github.io

https://github.com/ymbrite/egi




Tuesday, 25 February 2025

搭建基于github issues的静态博客程序jgi

 

首先fork此项目https://github.com/jrdeng/jrdeng.github.io,我fork后的项目地址是

https://github.com/briteming/jgi/ ,然后在此处https://github.com/briteming/jgi/settings,勾选issues. 

 然后访问 https://github.com/briteming/jgi/settings/pages,在“Build and deployment”处,source的值

选择deploy from a branch;  Branch的值选择"master , /docs",然后点击右边的save.

然后在此https://github.com/briteming/jgi/blob/master/.github/workflows/main.yml#L33

把author的值改为briteming(你的github 用户名)。在此 https://github.com/briteming/jgi/blob/master/hugo-template/config.toml#L1 ,把baseurl的值改为了https://briteming.github.io/jgi

 然后,访问https://github.com/briteming/jgi/issues/new,创建一些issues, 

访问https://github.com/briteming/jgi/actions/workflows/main.yml

发现已自动触发了workflow,我的博客网站https://briteming.github.io/jgi/ 就更新了。

项目地址: https://github.com/jrdeng/jrdeng.github.io

 https://github.com/jrdeng/jrdeng.github.io/issues/26

 https://github.com/briteming/jgi/

 演示网站:https://briteming.github.io/jgi/

Monday, 24 February 2025

搭建基于github issues的静态博客程序plain(更新版)

首先fork此项目https://github.com/wallleap/plain/,我fork后的项目地址是

https://github.com/briteming/plain/ ,然后在此处https://github.com/briteming/plain/settings,勾选issues. 然后访问https://github.com/briteming/plain/issues/new,新建issue.

然后,(以下步骤我是在windows上进行的。)

git clone https://github.com/briteming/plain plain-by-briteming

cd  plain-by-briteming

pnpm install

cp .env.sample .env

nano .env 

cat .env

显示:

# [必须配置] TOKEN,不配置获取不到文章,格式必须正确
V_GITHUB_TOKEN="你的
GITHUB TOKEN的值。GitHub Token 中间任意地方用英文逗号+空格断开"
V_USERNAME="briteming"
V_REPOSITORY="plain"

# [!必须配置] 博客信息
V_TITLE="blog of brite" # 博客标题,例如 V_TITLE="wallleap"
V_DESCRIPTION="
主要分享前端知识" # 博客描述,例如 V_DESCRIPTION="主要分享前端知识"
V_KEYWORDS="
前端, web, 博客" # 博客关键词,例如 V_KEYWORDS="前端, web, 博客"
V_LOGO="./logo.svg"

pnpm build

(此步会遇到错误。解决办法:

nano src/utils/index.ts

timerId = setTimeout(() => { 改为:

timerId = window.setTimeout(() => {

pnpm build即可成功,并会生成静态网站的根目录dist) 

cd dist

python3 -m http.server 2345

浏览器里访问127.0.0.1:2345即可看到静态网站的效果。


(里面的帖子,比如https://pl-luckypoems-projects.vercel.app/post/11,如果我直接访问它,是无法访问的,这不正常。https://stellular-creponne-e802ce.netlify.app/post/11 也是一样。一定要先访问首页,再点击首页里的posts链接,然后点击标题:"古代中国最早的情诗,只有四个字-候人兮猗", 才能打开帖子https://stellular-creponne-e802ce.netlify.app/post/11

解决办法:先在项目的根目录里,新建vercel.json 文件,内容如下:

{
  "rewrites": [{ "source": "/:path*", "destination": "/index.html" }]
}
然后再次上传静态网站的根目录dist的内容到vercel空间,这次就正常了。)
上传静态网站的根目录dist的内容到app.netlify.com 空间,也有同样的问题,解决办法:
先在dist目录里,新建_redirects文件,内容为
/*   /index.html   200
然后再次上传静态网站的根目录dist的内容到netlify空间,这次就正常了,
参考: https://github.com/wallleap/plain/issues/2#issuecomment-2662211832里面的2张图。
 https://github.com/wallleap/plain/issues/2#issuecomment-2662311687
 按所说的示意图重新部署,
这次ok了:https://plain-wl.netlify.app/posts 
另外, 导入项目https://github.com/ymbrite/plain/ 到vercel.com/new而得到的网址:
https://plain-oui4.vercel.app/posts 
演示网站:https://plain-wl.netlify.app/posts 
https://plain-oui4.vercel.app/posts 
项目地址:https://github.com/wallleap/plain/
https://github.com/wallleap/plain/issues/2 
https://github.com/briteming/plain/ 
 https://github.com/ymbrite/plain/

Saturday, 22 February 2025

尝试在 GitHub Issues 上写文章并自动同步至博客

 

在创作内容过程中,总会遇到需要在其他设备中继续的情况。由于我使用无后端的 Hexo 框架生成博客页面,自然无法仅仅在其他设备中打开个网页就回到上次结束的状态。尽管我曾经也有记录将网站源码同步至 GitHub 仓库并自动化更新网站的操作(参见'初探无后端静态博客自动化部署方案'- https://blog.ichr.me/post/automated-deployment-of-serverless-static-blog/),但万一设备上没有 Git 怎么办、万一是在手机上怎么办?

这时,我们不妨把目光投向 GitHub Issues,这个初衷是用于用户与开发者交流的工具,却不经意间成为非常好用的 Markdown 编辑器——基础语法支持、渲染预览、图片拖拽上传……对!甚至连图床都免了,完全可以只关注内容,无需在乎其它。更何况 GitHub Issues 还有完善的 API 支持,确实可以试试在 GitHub Issues 上写作,然后借助 GitHub Actions 更新至网站。

网站源码托管在 GitHub Repository、使用 GitHub Issues 编写文章、借助 GitHub Actions 自动更新、网站部署至 GitHub Pages……用到的工具全是 GitHub 的,不得不说这方面 GitHub 还是太会了。不可不谓之「完全围绕 GitHub 进行内容创作与分发」了。

准备工作

匿名账户调用 GitHub Issues API 是有较为严格的限制的,而且若仓库为私有仓库,匿名账户也是访问不到的。为此,我们最好给予一个 Personal Access Token 以获得必要权限。

登录你的 GitHub 账户,在「Settings => Developer Settings => Personal access token」处新建一个 Token,点击「Generate new token」。

勾选第一条,授予「repo」下的所有权限。注意保管好这个 Token,它只会出现一次。

同时由于此方法使用 GitHub Actions 同步更新至网站,所以最好你已经实现借助 GitHub Actions 自动化部署网站。如果还没有好的实践,不妨参考下我之前写的文章「初探无后端静态博客自动化部署方案」,本文就不再过多探讨关于自动部署方面的内容了。

能从 GitHub API 中获得哪些信息

在正式开始操作前,不妨来看看,我们究竟能从 GitHub REST API 中获取到哪些关于 GitHub Issues 的信息。

对这个路由发起 GET 请求,注意将用户、仓库名换成自己的。

https://api.github.com/repos/username/reponame/issues

还记得刚刚生成的 token 吗?这里可以通过在请求的 header 中加入以下内容来认证。

Authorization: `token your_token_blablalba`

此时就会获取到一个由每个 Issue 信息键值对组成的数组,我们关注某一个 Issue 信息:

  • number/node_id:由于其他参数有可能变动,由此可以确定 issue 唯一性
  • title:由此可以获得文章标题
  • body:由此可以获得文章内容
  • created_at:由此可以获得文章创建日期
  • updated_at:由此可以获得文章最后更新日期
  • labels:由此可以获得文章标签
  • milestone:由此可以获得文章分类

最后两个,使用 labels 存储标签和使用 milestone 存储分类是我自作主张决定的,你也可以有别的想法。但前面几个应该是没有什么异议的,我们可以根据这些信息来生成文章页面。

创建 Issue 同时新建文章

由于 Hexo 每个页面都会使用 Front-matter 来存储关于这个页面的一些信息,但是在 GitHub Issues 中没有找到方便存储键值对的功能。所以这里只好退一步,当监听到开启新的 Issue 时,在 source/_posts 文件夹下新建一个 .md 文件仅用于存放 Front-matter。使用 GitHub Actions 就能很好地监听 Issues 事件。

on: 
  issues:
    types: [opened]

由于我不是很熟悉命令行编辑,所以采用了 Node.js 处理。

let content = '';
(content += '---\r\n'), (content += '<!-- titlePlaceHolder -->\r\n'), (content += '<!-- datePlaceHolder -->\r\n'), (content += '<!-- updatedPlaceHolder -->\r\n'), (content += '<!-- tagsPlaceHolder -->\r\n'), (content += '<!-- categoriesPlaceHolder -->\r\n');
if (data.front_matters) {
    data.front_matters.forEach((item) => {
        content += `${item}\r\n`;
    });
}
content += '---\r\n\r\n';

fs.writeFileSync(join(dirname(__dirname) + `/source/_posts/${id}.md`), content);

在标题、日期、标签、分类等可以从 GitHub Issues 中很方便获取的参数,只创建一个展位符留给后续更新部署的时候替换。至于其他无法方便获取的参数,只好修改对应 .md 文件来实现了。

我是使用 Issue number 作为文件名并以此确定 Issue 与文件的对应关系,你也可以使用别的方式。但注意最好是创建之后不会修改的参数来确定对应关系。

最后,完整的代码如下。注意你是无法明文存储 Token 的,上传的时候 GitHub 会帮你抹掉,更何况从安全的角度而言,将 Token 存至 GitHub Secret 也是更明智的选择。

# .github/workflows/new_post.yml

name: Create New Post

on: 
  issues:
    types: [opened]

jobs:
  build:
    runs-on: ubuntu-20.04

    strategy:
      matrix:
        node-version: [12.x]

    steps:
      - name: Checkout Source
        uses: actions/checkout@v2

      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v1
        with:
          node-version: ${{ matrix.node-version }}

      - name: Install Dependencies
        run: npm i

      - name: Generate Post File
        run: node -e "require('./src/new_post').generate_files(${{ github.event.issue.number }})"
          
      - name: Commit Changes
        run: |
          git config user.name "username"
          git config user.email "your_email@example.com"
          git add ./source/_posts
          git commit -m "New Post #${{ github.event.issue.number }}"

      - name: Push Changes
        uses: ad-m/github-push-action@master
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          branch: ${{ github.ref }}
// src/new_post.js

'use strict';

const fs = require('fs');
const fetch = require('node-fetch');
const { join, dirname } = require('path');

const GITHUB_TOKEN = process.env.GITHUB_TOKEN;
const data = {
    repo: "username/reponame",
    front_matter: [], // 默认添加的 Front-matter
}

function generate_files(id) {
    if (!fs.existsSync(join(dirname(__dirname) + `/source/_posts/${id}.md`))) {
        let content = '';
        (content += '---\r\n'), (content += '<!-- titlePlaceHolder -->\r\n'), (content += '<!-- datePlaceHolder -->\r\n'), (content += '<!-- updatedPlaceHolder -->\r\n'), (content += '<!-- tagsPlaceHolder -->\r\n'), (content += '<!-- categoriesPlaceHolder -->\r\n');
        if (data.front_matter) {
            data.front_matter.forEach((item) => {
                content += `${item}\r\n`;
            });
        }
        content += '---\r\n\r\n';

        fs.writeFileSync(join(dirname(__dirname) + `/source/_posts/${id}.md`), content);

    }
}

module.exports = {
    generate_files: generate_files,
};

部署更新至网站

首先要明确一个问题——根据什么信号触发部署更新至网站?

原来的每次 push 部署更新肯定是行不通的了。一来现在文章根本就不在仓库中,而是在 Issues 里,更新并不会有在仓库中修改并推送;二来新建 Issue 创建的占位 .md 文件也会被算入更新中,然而此时往往还没有编辑好文章。
监听 Issue 更新也不太好,这样每次 Issue 更新都会被部署。然而有时我们只是想打草稿,还没想着发布。或者有时候文章还没写完,但是突然有事情不能继续写了,此时只是想保存当前状态,也不想发布。

我采用的是一种比较笨的方法——手动触发部署更新。

on: workflow_dispatch

这样在 GitHub Actions 页面就会有一个手动触发的按钮:


 


每次触发会根据从 GitHub API 获取的信息修改本地占位文件并重新生成网页部署至云端。我使用了 Fetch API 在 Node.js 中发送 HTTP 请求,fetch() 可以理解为 XMLHttpRequest 的升级版,使用 Promise 而非回调函数使其在编写上更为优雅。

fetch(postEntry.url, {
    method: 'GET',
    headers: {
        Authorization: `token your_tokekn_blablabla`,
    },
})
    .then((response) => {
        return response.json();
    })
    .then((post) => {
        let title = post.title,
            date = post.created_at.replace(/[TZ]/g, ' '),
            updated = post.updated_at.replace(/[TZ]/g, ' '),
            categories = post.milestone;
        let tags = [];
        post.labels.forEach((tag) => {
            tags.push(tag.name);
        });

        let content = fs.readFileSync(join(dirname(__dirname) + `/source/_posts/${post.number}.md`), 'utf-8');
        (title && (content = content.replace('<!-- titlePlaceHolder -->', `title: ${title}`))) || (content = content.replace('<!-- titlePlaceHolder -->', ''));
        (date && (content = content.replace('<!-- datePlaceHolder -->', `date: ${date}`))) || (content = content.replace('<!-- datePlaceHolder -->', ''));
        (updated && (content = content.replace('<!-- updatedPlaceHolder -->', `updated: ${updated}`))) || (content = content.replace('<!-- updatedPlaceHolder -->', ''));
        (tags && (content = content.replace('<!-- tagsPlaceHolder -->', `tags: ["${tags.join('", "')}"]`))) || (content = content.replace('<!-- tagsPlaceHolder -->', ''));
        (categories && (content = content.replace('<!-- categoriesPlaceHolder -->', `categories: ["${categories}"]`))) || (content = content.replace('<!-- categoriesPlaceHolder -->', ''));
        content += `\r\n\r\n${post.body}`;
    
    	fs.writeFileSync(join(dirname(__dirname) + `/source/_posts/${post.number}.md`), content);
    });

看到最后那一串长长的东西了吗?就是在根据从 GitHub API 中获取到的信息更新占位符,如果对应信息不存在(如没有设置 labels)则清除占位符。只不过这里我压行了,陋习陋习……

到这里,如果文章少的话是不会遇到什么问题的。但要是文章比较多,可能会发现旧文章都不见了。这是因为 GitHub API 会自动分页,默认 30 条 Issue 每页,可以手动上调至不超过 100 条每页。要处理分页也不难,每次请求返回中的 Link header 会包含分页信息,跑个递归就好了。

function main(page = 1) {
    fetch(`https://api.github.com/repos/username/reponame/issues?page=${page}&per_page=100`, {
        method: 'GET',
        headers: {
            Authorization: `token your_token_blablabla`,
        },
    })
        .then((response) => {
            if (response.headers.get('Link') && /rel\=\"next\"/gi.test(response.headers.get('Link'))) {
                main(page + 1);
            }
            return response.json();
        })
        .then((list) => {
            list.forEach((postEntry) => {
                // ...
            });
        });
}

最后,完整的代码如下。

// src/main.js

'use strict';

const fs = require('fs');
const fetch = require('node-fetch');
const { join, dirname } = require('path');
const { generate_files } = require('./new_post');

const GITHUB_TOKEN = process.env.GITHUB_TOKEN;
const data = {
    repo: "username/reponame",
    
}

function main(page = 1) {
    fetch(`https://api.github.com/repos/${data.repo}/issues?page=${page}&per_page=100`, {
        method: 'GET',
        headers: {
            Authorization: `token ${GITHUB_TOKEN}`,
        },
    })
        .then((response) => {
            if (response.headers.get('Link') && /rel\=\"next\"/gi.test(response.headers.get('Link'))) {
                main(page + 1);
            }
            return response.json();
        })
        .then((list) => {
            list.forEach((postEntry) => {
                fetch(postEntry.url, {
                    method: 'GET',
                    headers: {
                        Authorization: `token ${GITHUB_TOKEN}`,
                    },
                })
                    .then((response) => {
                        return response.json();
                    })
                    .then((post) => {
                        let title = post.title,
                            date = post.created_at.replace(/[TZ]/g, ' '),
                            updated = post.updated_at.replace(/[TZ]/g, ' '),
                            categories = post.milestone;
                        let tags = [];
                        post.labels.forEach((tag) => {
                            tags.push(tag.name);
                        });

                        if (!fs.existsSync(join(dirname(__dirname) + `/source/_posts/${post.number}.md`))) {
                            generate_files(post.number);
                        }
                        let content = fs.readFileSync(join(dirname(__dirname) + `/source/_posts/${post.number}.md`), 'utf-8');
                        (title && (content = content.replace('<!-- titlePlaceHolder -->', `title: ${title}`))) || (content = content.replace('<!-- titlePlaceHolder -->', ''));
                        (date && (content = content.replace('<!-- datePlaceHolder -->', `date: ${date}`))) || (content = content.replace('<!-- datePlaceHolder -->', ''));
                        (updated && (content = content.replace('<!-- updatedPlaceHolder -->', `updated: ${updated}`))) || (content = content.replace('<!-- updatedPlaceHolder -->', ''));
                        (tags && (content = content.replace('<!-- tagsPlaceHolder -->', `tags: ["${tags.join('", "')}"]`))) || (content = content.replace('<!-- tagsPlaceHolder -->', ''));
                        (categories && (content = content.replace('<!-- categoriesPlaceHolder -->', `categories: ["${categories}"]`))) || (content = content.replace('<!-- categoriesPlaceHolder -->', ''));
                        content += `\r\n\r\n${post.body}`;

                        fs.writeFileSync(join(dirname(__dirname) + `/source/_posts/${post.number}.md`), content);
                    })
                    .catch((e) => {
                        console.log(e);
                    });
            });
        })
        .catch((e) => {
            console.log(e);
        });
}

module.exports = {
    main: main,
};
# ,github/workflows/deploy.yml

name: Build WebSite

on: workflow_dispatch

jobs:
  build:
    runs-on: ubuntu-20.04

    strategy:
      matrix:
        node-version: [12.x]

    steps:
      - name: Checkout Source
        uses: actions/checkout@v2

      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v1
        with:
          node-version: ${{ matrix.node-version }}

      - name: Install Dependencies
        run: npm i

      - name: Process Post
        run: node -e "require('./src/main').main()"
        env:
          GITHUB_TOKEN: ${{ secrets.token }}

      - name: Build WebSite
        run: npx hexo g

      - name: Deploy to GitHub Pages
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_branch: gh-pages
          publish_dir: ./public
          force_orphan: true
          cname: your.domain.com

其实主要是将 Process Post 部分加入 hexo g 之前即可。如果你以前有配置过 GitHub Actions 自动化部署,其它部分基本不用修改。

from https://blog.ichr.me/post/blog-with-github-issues/

Friday, 14 February 2025

搭建基于github issue的静态博客程序wib

  首先 fork 此项目https://github.com/wschenk/issue-blog,我fork 后的项目地址是https://github.com/briteming/wib ,然后访问https://github.com/briteming/wib/settings,勾选issues. 新建一些issues.

然后,访问https://github.com/briteming/wib/settings/pages。在Build and deployment处,source的值选择github actions. 在项目https://github.com/briteming/wib 页面的左上角的 main 处,创建gh-pages分支。稍等2分钟,即可打开https://briteming.github.io/wib/

编辑 _config.yml文件- https://github.com/briteming/wib/blob/main/_config.yml ,把第6行的baseurl的值改为 /wib

创建新 issue(标题必须为英文或其他基于26个字母的西方语言) 后,就会自动触发"Issue to Post" action (马上访问https://github.com/briteming/wib/actions/workflows/issue_to_post.yml,即可看到。),待"Issue to Post" action完成(即 issue的标题的前面出现)后,就会自动触发Build and Deploy(马上访问https://github.com/briteming/wib/actions/workflows/deploy_to_pages.yml,即可看到),待"deploy" action完成(即 deploy的前面出现)后,帖子就发表成功了。

演示网站:https://briteming.github.io/wib/

项目地址: https://github.com/wschenk/issue-blog

 https://github.com/briteming/wib

 虽然静态博客程序wib也是基于github actions,但生成的博客中的帖子还是按创建issue 的时间顺序排列的,难得!不像ib(https://briteming.blogspot.com/2025/02/github-issueib.html),

nb(https://briteming.blogspot.com/2025/02/github-issuenb.html)和静态博客程序 Issue_Blog 那样所生成的博客中的帖子是乱排列的。

------------------------------------------------------------------------------------------------

Building a blog using github issues

what else can we do with github actions

I wanted to see if I could write blog posts using github issues, and have them be published on the web. You can!

Create a jekyll site


  cd $(mktemp -d)
  bundle init
  bundle add jekyll
  bundle exec jekyll new issue-blog
  cursor issue-blog

Then inside


  bundle add jekyll-compose
  bundle
  jekyll s

Create the repo


  git init
  git add .
  git commit -m "initial commit"
  gh repo create wschenk/issue-blog --public
  gh repo edit -d "Playground to make posts and comments from github issues"
  git remote add origin https://github.com/wschenk/issue-blog
  git push origin main

Add the secret


  gh auth token | gh secret set AUTH_TOKEN

Issue to Post workflow

When you open or edit and issue, we check out the repo, and then create a file in the _posts directory can fill in the information

Once that's done, we trigger a deploy action using peter-evans/repository-dispatch to trigger the second build action.


  name: Issue to Post

  on:
    workflow_dispatch:
    issues:
      types:
        - opened
        - edited

  permissions: write-all

  jobs:
    create_post:
      runs-on: ubuntu-latest
      steps:
        - name: Checkout repository
          uses: actions/checkout@v2
        - name: Create post file
          run: |
            POST_FILENAME="_posts/$(date +%Y-%m-%d)-$(echo -n ${{github.event.issue.title}} | tr '[A-Z]' '[a-z]' | tr -c 'a-z' '-' ).md"
            echo "POST_FILENAME: ${POST_FILENAME}"
            echo --- > ${POST_FILENAME}
            echo title: "${{github.event.issue.title}}" >> ${POST_FILENAME}
            echo layout: post >> ${POST_FILENAME}
            echo date: $(date +"%Y-%m-%d %H:%M %z") >> ${POST_FILENAME}
            echo --- >> ${POST_FILENAME}
            echo >> ${POST_FILENAME}
            echo "${{github.event.issue.body}}" >> ${POST_FILENAME}
        - name: Commit and push changes
          run: |
            git config --global user.email "readme-bot@example.com"
            git config --global user.name "README-bot"
            git add .
            git commit -m "Create post for issue #${{ github.event.issue.number }}"
            git push
          env:
            GITHUB_TOKEN: ${{ secrets.AUTH_TOKEN }}
        - name: Trigger deploy action
          uses: peter-evans/repository-dispatch@v3
          with:
            event-type: deploy

Deploy to pages

Here we check out the code and deploy it to github pages. We replace the baseurl with the base_path that we get from configure-pages, so its smart enough to know if you have it on a custom domain or as a subdirectory.


  name: "Build and Deploy"
  on:
    repository_dispatch:
      types: [deploy]
    push:
      branches:
        - main
        - master
      paths-ignore:
        - .gitignore
        - README.md
        - LICENSE
        - .github/

    # Allows you to run this workflow manually from the Actions tab
    workflow_dispatch:

  permissions:
    contents: read
    pages: write
    id-token: write

  # Allow one concurrent deployment
  concurrency:
    group: "pages"
    cancel-in-progress: true

  jobs:
    build:
      runs-on: ubuntu-latest

      steps:
        - name: Checkout
          uses: actions/checkout@v4

          - name: Setup Pages
          id: pages
          uses: actions/configure-pages@v4

        - name: Setup Ruby
          uses: ruby/setup-ruby@v1
          with:
            ruby-version: 3.3
            bundler-cache: true
        - name: Replace baseurl
          run: |
            sed -i 's|baseurl: ""|baseurl: "${{ steps.pages.outputs.base_path }}"|' _config.yml
        - name: Build site
          run: bundle exec jekyll b -d "_site${{ steps.pages.outputs.base_path }}"
          env:
            JEKYLL_ENV: "production"

        - name: Upload site artifact
          uses: actions/upload-pages-artifact@v3
          with:
            path: "_site${{ steps.pages.outputs.base_path }}"

    deploy:
      environment:
        name: github-pages
        url: ${{ steps.deployment.outputs.page_url }}
      runs-on: ubuntu-latest
      needs: build
      steps:
        - name: Deploy to GitHub Pages
          id: deployment
          uses: actions/deploy-pages@v4

Check it out

You can see it in action:

from https://willschenk.com/howto/2024/building_a_blog_using_github_issues/

 

 

 

使用 Zola 和 GitHub actions 构建博客

 使用 Zola 和 GitHub Pages 构建博客是一个高效且简洁的方式。Zola 是一个静态网站生成器,而 GitHub Pages 是一个免费的静态网站托管服务。以下是详细的步骤,帮助你从零开始构建并部署你的博客。
1. 安装 Zola

首先,你需要在本地安装 Zola。根据你的操作系统,选择以下命令之一:

    macOS (Homebrew):

    brew install zola

Linux:

curl -sSL https://get.zola.dev | bash -s

Windows (Scoop):

scoop install zola

安装完成后,运行以下命令检查是否安装成功:

zola --version

2. 创建一个新的 Zola 项目

使用 Zola 初始化一个新的博客项目:

zola init my-blog

这会创建一个名为 my-blog 的目录,并生成一个基本的 Zola 项目结构。

进入项目目录:

cd my-blog

3. 添加主题

Zola 支持主题,你可以从 Zola 主题库( https://www.getzola.org/themes/)中选择一个喜欢的主题。以下是一个添加主题的示例:

    将主题添加为 Git 子模块。例如,使用 even 主题:

    git init
    git submodule add https://github.com/getzola/even.git themes/even

在 config.toml 中启用主题:

theme = "even"

根据主题的文档,配置 config.toml 文件。例如,设置博客标题、描述等:

title = "My Awesome Blog"
description = "Welcome to my blog!"

4. 创建博客内容

Zola 使用 Markdown 文件来生成博客内容。你可以在 content 目录中创建博客文章。

    创建博客文章:

    zola new content/blog/my-first-post.md

编辑生成的 Markdown 文件(content/blog/my-first-post.md):

+++
title = "My First Post"
date = 2023-10-01
+++

This is my first blog post using Zola!

5. 本地预览

在本地启动 Zola 服务器,预览你的博客:

zola serve

打开浏览器,访问 http://127.0.0.1:1111,即可查看你的博客。
6. 部署到 GitHub Pages

GitHub Pages 是一个免费的静态网站托管服务。以下是部署步骤:
6.1 创建 GitHub 仓库

    在 GitHub 上创建一个新的仓库,命名为 username.github.io(将 username 替换为你的 GitHub 用户名)。
    将本地项目与远程仓库关联:

    git remote add origin https://github.com/username/username.github.io.git

6.2 配置 GitHub Actions

    在项目根目录下创建 .github/workflows/deploy.yml 文件,内容如下:

    name: Deploy to GitHub Pages

    on:
      push:
        branches:
          - main

    jobs:
      deploy:
        runs-on: ubuntu-latest
        steps:
          - name: Checkout
            uses: actions/checkout@v2
            with:
              submodules: true

          - name: Setup Zola
            uses: shalzz/zola-deploy-action@v0.14.1

          - name: Deploy
            uses: peaceiris/actions-gh-pages@v3
            with:
              github_token: ${{ secrets.GITHUB_TOKEN }}
              publish_dir: ./public

提交并推送代码到 GitHub:

git add .
git commit -m "Initial commit"
git push -u origin main

6.3 启用 GitHub Pages

    进入 GitHub 仓库的 Settings 页面。
    找到 Pages 选项,将 Source 设置为 gh-pages 分支。
    稍等片刻,GitHub Pages 会自动构建并发布你的博客。

7. 访问你的博客

完成上述步骤后,你的博客将通过以下 URL 访问:

https://username.github.io

8. 后续维护

    添加新文章:在 content 目录中创建新的 Markdown 文件,然后推送更改到 GitHub。
    更新主题:如果主题有更新,可以通过以下命令更新子模块:

    git submodule update --remote --merge

    自定义博客:根据需要修改 config.toml 或主题文件。

总结

通过 Zola 和 GitHub Pages,你可以快速构建一个静态博客,并免费托管在 GitHub 上。整个过程简单高效,适合个人博客、文档站点等场景。

 如果你有任何问题,可以参考 Zola 官方文档GitHub Pages 文档

----------------------

related post: https://briteming.blogspot.com/2020/03/rust-zola.html

Thursday, 13 February 2025

Hexo Deploy Action

 Deploy a Hexo project to github pages.

This GitHub action will handle the building and deploying process of hexo project.

Getting Started

You can view an example of this below.

name: Build and Deploy
on: [push]
jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout
      uses: actions/checkout@master

    - name: Build and Deploy
      uses: solybum/hexo-deploy@master
      env:
        PERSONAL_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        PUBLISH_REPOSITORY: solybum/solybum.github.io # The repository the action should deploy to.
        BRANCH: master  # The branch the action should deploy to.
        PUBLISH_DIR: ./public # The folder the action should deploy.

if you want to make the workflow only triggers on push events to specific branches, you can like this:

on:
  push:	
    branches:	
      - master

Configuration

The env portion of the workflow must be configured before the action will work. You can add these in the env section found in the examples above. Any secrets must be referenced using the bracket syntax and stored in the GitHub repositories Settings/Secrets menu. You can learn more about setting environment variables with GitHub actions here.

Below you'll find a description of what each option does.

Key Value Information Type Required
PERSONAL_TOKEN Depending on the repository permissions you may need to provide the action with a GitHub Personal Access Token in order to deploy. You can learn more about how to generate one here. This should be stored as a secret. secrets Yes
PUBLISH_REPOSITORY The repository the action should deploy to. for example solybum/solybum.github.io env Yes
BRANCH The branch the action should deploy to. for example master env Yes
PUBLISH_DIR The folder the action should deploy. for example ./public env Yes

from  https://github.com/jinzhu/hexo-deploy

Wednesday, 12 February 2025

搭建基于github issue的静态博客程序ib

 首先 fork 此项目https://github.com/imfing/issues-blog,我fork 后的项目地址是https://github.com/briteming/ib ,然后访问https://github.com/briteming/ib/settings,勾选issues. 新建一些issues, 并关闭这些issues(之所以要关闭它们,是因为下面要说的github actions所要求的。)

然后访问https://github.com/briteming/ib/actions,以启用actions.

 然后,编辑go.mod文件- https://github.com/briteming/ib/blob/main/go.mod,把用户名和项目名改为你的用户名和项目名。编辑config.toml文件-https://github.com/briteming/ib/blob/main/config/_default/config.toml ,修改baseURL的值,我的值为https://briteming.github.io/ib 。

启用github pages:

访问https://github.com/briteming/ib/settings/pages,如图设置:


 稍等2分钟,即可访问https://briteming.github.io/ib。如果没有看见gh-pages选项,则访问

https://github.com/briteming/ib页面的左上角的main处,创建分支gh-pages.

新建一些issues, 并关闭这些issues后, GitHub Actions should automatically start to build and publish your website. 

演示网站: https://briteming.github.io/ib

https://briteming.github.io/ib/posts/

项目地址: https://github.com/imfing/issues-blog

https://github.com/imfing/issues-blog/issues/11 

https://github.com/briteming/ib

教程:https://imfing.github.io/issues-blog/posts/quick-start/ 

此静态博客程序跟静态博客程序 Issue_Blog (静态博客程序 Issue_Blog一样,发表的帖子并未按提交issue的时间顺序排列。 这是这种使用github actions的静态博客程序的通病。

 类似的程序:

搭建基于github issue的静态博客程序nb 

https://briteming.blogspot.com/2024/12/github-issue-issueblog.html

这2款程序在 settings/pages那里,设置build and deployment的方式时,source的值选择的都是

github actions,  而现在这个 静态博客程序ib,settings/pages那里,设置build and deployment的方式时,source的值选择的却是deploy from a branch, 这有点奇怪。