--- title: Github Actions自动发布博客 abbrlink: 3debc8f2 categories: - 工具 tags: - Automatic cover: 'https://static.zahui.fan/images/202211011808880.png' date: 2021-07-27 23:54:56 --- > 偶然发现github actions可以执行一些命令,这下可以把我的crontab停掉了,也不用占用一台机器专门用来发布博客了,并且完全免费!! > 首先我的GitHub pages和博客原始文件是分为两个仓库的,在GitHub Pages仓库里添加了一个Actions用来钉钉发通知: ## GitHub仓库配置Secret 需要先将环境变量配置在 Settings --> Secrets and Variables --> Actions 里面 ![github Acrions 环境变量配置](https://static.zahui.fan/images/202304111133670.png) 配置后,可以在actions里面通过 `${{ secrets.dingtalk_secret }}` 调用到对应的数据 ## 针对Hexo博客的构建 ```yml name: Deploy GitHub Pages on: push: branches: - master jobs: deploy_github_pages: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 with: submodules: recursive fetch-depth: 0 - name: Use Node.js 16.x uses: actions/setup-node@v1 with: node-version: 16.x # 为了解决更新日期问题,从git读取提交时间,然后批量touch一下 - name: build_hexo run: | git ls-files -z | while read -d '' path; do touch -d "$(git log -1 --format="@%ct" "$path")" "$path"; done npm install npx hexo clean npx hexo g - name: Deploy 🚀 uses: JamesIves/github-pages-deploy-action@4.1.5 with: BRANCH: main # The branch the action should deploy to. FOLDER: public # The folder the action should deploy. ssh-key: ${{ secrets.DEPLOY_SSH_KEY }} repository-name: iuxt/iuxt.github.io ``` ## 针对于Hugo博客的构建 ```yml name: Deploy GitHub Pages on: push: branches: - master # master更新后执行 schedule: - cron: '0 0 * * *' # 每天0点自动执行 jobs: deploy_github_pages: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 with: submodules: recursive - name: Setup Hugo uses: peaceiris/actions-hugo@v2 with: hugo-version: '0.80.0' extended: true - name: Build run: | git config core.quotePath false hugo - name: Deploy 🚀 uses: JamesIves/github-pages-deploy-action@4.1.4 with: BRANCH: main # 你要发布到哪个分支(GitHub Pages的仓库分支,不是你hugo代码的分支) FOLDER: public # 发布的文件夹,默认就是public ssh-key: ${{ secrets.DEPLOY_SSH_KEY }} # 我发布到不同的仓库,需要用到私钥,私钥用GitHub Secret来管理,发布同仓库可以去掉这个配置 repository-name: iuxt/iuxt.github.io # 发布到同仓库的不同分支要去掉这个配置 - name: Use Node.js 10.x uses: actions/setup-node@v1 with: node-version: 10.x - name: algolia upload run: | npm install npm run algolia # 使用algolia的,可以同时推送到algolia env: ALGOLIA_APP_ID: ${{ secrets.ALGOLIA_APP_ID }} # 一样的,需要在GitHub Secret里面创建键值对。 ALGOLIA_INDEX_NAME: blog ALGOLIA_INDEX_FILE: public/index.json ALGOLIA_ADMIN_KEY: ${{ secrets.ALGOLIA_ADMIN_KEY }} ``` ## 推送到百度,加快收录 ```yml name: Baidu push on: push: branches: - master schedule: - cron: '0 0 * * *' # 使用crontab定时执行,0点实际执行时间是9点,可能是时区问题 jobs: baidu-push: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 # 拉取代码,并拉取git submodule with: submodules: recursive - name: Setup Hugo uses: peaceiris/actions-hugo@v2 # hugo环境,用的是别人写好的actions with: hugo-version: '0.80.0' extended: true - name: Build run: | git config core.quotePath false hugo # 使用hugo命令生成静态文件 - name: Install requests run: pip install requests - name: Push run: | python <).+?(?=)') result = pattern.findall(sitemap.read()) req = requests.post('http://data.zz.baidu.com/urls?site=https://zahui.fan&token=${{ secrets.BAIDU_PUSH_TOKEN }}', '\n'.join(result)) print(req.text) END ``` ## 发送钉钉通知 > 这个我配置在了静态文件所在的仓库,就是hexo构建完成推送到的仓库,每当仓库发生了更新, 就会推送一条通知到钉钉 ```yml name: dingtalk_notify on: push: # 在收到push的时候触发 branches: - main # 监控main分支 jobs: dingtalk_notify: runs-on: ubuntu-latest # 用ubuntu系统来执行 steps: - name: dingtalk_notify run: | python < 当使用 Travis CI or Github Actions 自动化部署时,发现部署成功后,所有文章的更新时间都变成了此次提交修改的时间,但有些文章在上一次提交后是没有发生过任何修改的。 这是因为 git 在推送更新时,并不记录保存文件的访问时间、修改时间等元信息,([原因在这里](https://archive.kernel.org/oldwiki/git.wiki.kernel.org/index.php/Git_FAQ.html?spm=a2c4e.10696291.0.0.671919a4OeAqE1#Why_isn.27t_Git_preserving_modification_time_on_files.3F))所以每次使用 git 把项目 clone 下来时,文件的时间都是克隆时的时间。又因为如果没有在 front-matter 中指定 updated,Hexo 会默认使用文件的最后修改时间作为文章的更新时间,所以会出现所有文章的更新时间都发生变化的情况。 总的来说,使用 git clone 下来的文件的时间都不是原来文件的时间,而自动化部署每次都需要 clone 源码才能进行后面的生成和部署操作,所以目前如果想正确显示更新时间。对于Github Actions可以使用命令在构建之前进行处理 ```yml jobs: deploy_gh_pages: steps: - name: Restore file modification time run: | git ls-files -z | while read -d '' path; do touch -d "$(git log -1 --format="@%ct" "$path")" "$path"; done ``` 如果git命令不好用, 也可以使用find命令 ```bash find source/_posts -name '*.md' | while read file; do touch -d "$(git log -1 --format="@%ct" "$file")" "$file"; done ``` 实际上,clone 下来的文件的时间还是克隆时的时间,然后通过上面的命令,它将 clone 下来的文件的时间改成了该文件最近一次变动的推送时间(也即文件最后一次修改的 push 时间)。 注:如果github actions中使用actions/checkout@v2,请设定它的参数fetch-depth: 0,因为0表示获取所有分支和标签的所有历史记录。默认值为1