如何使用
issue 的标题是你要执行的 docker pull
命令, 内容不需要写。
几分钟后,在这个 issue 下会收到一个包含下载链接的评论。
点击这个链接即可下载镜像到本地。
执行 docker load < xxx.tar.gz
即可加载镜像。
如何实现
issue 标题作为下载镜像的命令,Actions 获取到 issue 的标题后执行命令下载 Docker 镜像,然后上传到 Onedrive 网盘上。
上传工具使用 rclone,这样就可以避免自己写代码和 Onedrive API 交互。
直接 rclone copy
即可。
最后,使用 GitHub API 为 issue 发送一个评论,包含下载链接。
name: Docker Pull
on:
issues:
types: [opened] # 只有 issue 被打开时触发
jobs:
new-issue-job:
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v2
- name: Docker Pull
run: |
sudo -v; curl https://rclone.org/install.sh | sudo bash # 安装 rclone
rclone version
issue_title="$${{ github.event.issue.title }}" # 获取 issue 标题
issue_number="$${{ github.event.issue.number }}" # 获取 issue 编号
if [[ $ =~ ^docker\ pull\ (.+)$$ ]]; then # 正则匹配 issue 标题,应该以 docker pull 开头
echo "Issue title is valid."
$ # 执行 docker pull 命令
image_name="$${BASH_REMATCH[1]}" # 获取镜像名
save_image_name=$${image_name//[:\/]/_} # 替换镜像名中的 : 和 / 为 _ , 用于保存文件名
docker save $ | gzip > ./$.tar.gz # 保存镜像
rclone copy ./$.tar.gz E5:/DockerPull/$/ # 上传到 Onedrive
gh issue comment $${{ github.event.issue.number }} -b "Docker image has been pulled and uploaded to E5. Please download it from the following link: https://e5.1881997.xyz/DockerPull/$/$.tar.gz" # 为 issue 发送评论
else
echo "Issue title is invalid."
exit 1
fi
shell: bash
env:
RCLONE_CONFIG_PASS: $${{ secrets.RCLONE_CONFIG_PASS }} # rclone 配置文件的密码
GH_TOKEN: $${{ secrets.PAT }} # GitHub token, 用于发送评论。GitHub Actions 的默认 token 无法发送评论,需要自己生成一个有权限的 token
RCLONE_CONFIG: ./config/rclone.conf # rclone 配置文件路径
整体实现非常简单,只需要几行代码。
再简单解释一下这里面可能会令人疑惑的两个地方:
rclone copy
是如何上传到我的 Onedrive 的?
这里需要首先在本地配置好 rclone,然后将配置文件进行加密,上传到 GitHub 仓库中。
https://github.com/WANG-Guangxin/DockerPull/blob/master/config/rclone.conf
这里是我的 rclone 配置文件,里面包含了我 Onedrive 的配置信息。
RCLONE_CONFIG
环境变量用于指定 rclone 配置文件的路径。
RCLONE_CONFIG_PASS
环境变量用于指定 rclone 配置文件的密码。这个环境变量需要用 secrets 存储。
这两个环境变量在 Actions 的 yaml 中,当执行 rclone copy
时,会自动解密配置文件,然后上传。
- https://e5.1881997.xyz/DockerPull/.tar.gz 是如何生成的?
https://e5.1881997.xyz 其实是我搭建的一个网盘列表程序,我用的是 OneManager-php
我曾经在这篇文章 中介绍过这个程序。
至于后面的路径,就是 issue 编号和镜像名,这样就可以保证每个 issue 的镜像都是唯一的。
只要保证上传和下载的路径一致,就可以了。
可能的扩展
- 只有 star 了这个仓库的人才能使用
下面是一个可能的方案,但还未经测试。
- name: Check if user starred the repo
run: |
user="$${{ github.event.issue.user.login }}"
repo="$${{ github.repository }}"
starred=$$(curl -H 'Authorization: token $${{ secrets.GITHUB_TOKEN }}' https://api.github.com/user/starred/$ | grep -c "$")
if [ "$" -eq "0" ]; then
echo "User has not starred the repo, aborting."
exit 1
fi
- 删除过早的镜像
同样也是未经测试的代码。
issue_number="$${{ github.event.issue.number }}"
issue_number_minus_ten=$$((issue_number - 10))
if rclone lsf E5:/DockerPull/$/ > /dev/null 2>&1; then
rclone delete remote:path
else
echo "Path does not exist, skipping."
fi
最后
目前只有两个人使用过这个机器人,有一个人 fork 了这个仓库,但实际上仅仅 fork 这个仓库是无法使用的。
有兴趣的话可以参考这篇文章自己实现一个。
但实际上用我的就够了,希望使用的用户给个 star ⭐