使用 GitHub Actions 云编译 OpenWrt

请注意,本文编写于 143 天前,最后修改于 6 天前,其中某些信息可能已经过时。

前言

Github Actions 是 GitHub 推出的持续集成(Continuous integration,简称CI)服务,它提供了配置非常不错的虚拟服务器环境(E5 2vCPU/7G RAM),基于它可以进行构建、测试、打包、部署项目。对于公共仓库可免费无时间限制的使用(指累积时间),不过要使用它首先需要知道如何编写 workflow 文件。但这篇文章并不是教你如何枯燥的去编写 workflow 文件,而是教你如何去使用博主已经编写好的 OpenWrt 编译方案。

教程更新

  • 2020-03-30 新增上传固件到奶牛快传
  • 2020-02-01 新图文教程
  • 2019-12-10 新增 macOS 编译方案使用说明
  • 2019-12-06 添加 tmate 网页终端链接说明
  • 2019-12-05 优化基础使用教程,添加 @lietxia 大佬的图文教程链接
  • 2019-12-04 新增云menuconfig使用方法
  • 2019-12-03 新增并发编译使用方法
  • 2019-11-30 新增自定义源码编译使用方法
  • 2019-11-14 全网独家首发

方案特点

  • 免费
  • 一键快速编译
  • 定时自动编译
  • 客制化编译
  • 并发编译(可同时进行20+5个编译任务)
  • 无需搭建编译环境(在线make menuconfig生成配置文件)
  • 无需消耗自己的计算机与服务器的计算资源(性感E5在线编译)
  • 无需担心磁盘空间不足(近60G磁盘空间)
  • 无需使用清理文件(内核更新不怕 boom )
  • 编译速度快(编译时间1-2小时)
  • 编译成功率提升200%(万兆自由网络环境)
  • 全新环境(杜绝编译环境不干净导致编译失败)
本解决方案是一个开放平台,任何人都可以基于此打造自己专属的编译方案。

项目地址

https://github.com/P3TERX/Actions-OpenWrt

支持项目请随手点个star,让更多的人发现、使用并受益。

准备工作

  • 注册 GitHub 账号
  • 搭建编译环境,用于生成.config文件。(可选)
TIPS: 关于编译环境的搭建,推荐去看我之前写的相关文章,Windows 10 可以使用 WSL ,macOS、Linux 可以使用 Docker

基础使用

首先你必须要熟悉整个 OpenWrt 的编译过程,这会让你非常容易的理解如何使用 GitHub Actions 进行编译,即使你没有成功过。因为实际上本地编译近 90% 失败的原因是因为网络问题导致的,中国大陆特色,咱也不敢多说。而使用 GitHub Actions 编译成功率至少提升 200% ,为什么这样说呢?因为 Actions 服务器由 Microsoft Azure 提供,在自由的美利坚,拥有万兆带宽。

首次编译

  • 在自己搭建编译环境中使用 Lean's OpenWrt 源码生成.config文件。(或使用后面进阶玩法中的云menuconfig,直接 SSH 到 Actions 进行操作)
TIPS: 方案默认引用 Lean 的源码,因为他的 README 影响了我开始学习编译,也就有了这个项目,而且他的源码非常的优秀。有其它需求可自行修改 workflow 文件,方法后面的进阶使用中有说明。

  • 填写仓库名称,然后点击Create repository from template(从模版创建储存库)按钮。

  • 经过几秒钟的等待,页面会跳转到新建的仓库,内容和我的项目是相同的。然后点击Create new file(创建新文件)按钮。

  • 文件名填写为.config,把生成的.config 文件的内容复制粘贴到下面的文本框中。

  • 翻到页面最下方,点击Commit new file(提交新文件)按钮即可。后续编译工作会自动开始,你可以在 Actions 页面进行查看。

  • 在等待编译完成的过程中,你可以进入这个页面点击右上角的star,这是对博主最大的支持,而且还可以加快编译速度哦(雾
  • 最后经过一两个小时的等待,不出意外你就可以在 Actions 页面看到已经打包好的固件目录压缩包。

TIPS: 如需 ipk 文件可以在进阶使用章节找到方法。因为大多数人只需要固件,而且总是有萌新问固件在哪,所以现在默认只上传固件。

再次编译

默认情况下触发编译有两种方式:

  1. 发布 release
  2. 修改.config文件

他们分别对应以下使用场景:

  • 在编译配置没有修改的情况下,若源码有更新,那么在 releases 页面发布一个 release 将直接使用最新源码进行编译。
  • 如果你想修改配置,则生成船新的.config文件 push 到仓库来触发编译的工作流程。

其它触发方式你可以在后面的进阶使用中看到。

进阶使用

自定义环境变量与功能


点击查看

打开 workflow 文件(.github/workflows/build-openwrt.yml),你会看到有如下一些环境变量,可按照自己的需求对这些变量进行定义。

env:
  REPO_URL: https://github.com/coolsnowwolf/lede
  REPO_BRANCH: master
  CONFIG_FILE: .config
  DIY_SH: diy.sh
  SSH_ACTIONS: false
  UPLOAD_BIN_DIR: false
  UPLOAD_FIRMWARE: true
  UPLOAD_COWTRANSFER: false
  TZ: Asia/Shanghai
TIPS: 修改时需要注意:(冒号)后面有空格。
环境变量功能
REPO_URL源码仓库地址
REPO_BRANCH源码分支
CONFIG_FILE.config文件名
DIY_SHDIY 脚本文件名
SSH_ACTIONSSSH 连接 Actions 功能。默认false
UPLOAD_BIN_DIR上传 bin 目录。即包含所有 ipk 文件和固件的目录。默认false
UPLOAD_FIRMWARE上传固件目录。默认true
UPLOAD_COWTRANSFER上传固件到奶牛快传。默认false
TZ时区设置

DIY 脚本

仓库内有一个diy.sh文件,你可以把对源码修改的指令写到这个文件中,比如修改默认IP、主机名、主题、添加/删除软件包等操作。但不仅限于这些操作,发挥你强大的想象力,可做出更强大的功能。

TIPS: 脚本工作目录在源码目录,内附一个修改默认 IP 的例子供参考使用。

添加软件包

在 DIY 脚本中加入对指定软件包的远程仓库的克隆指令。就像下面这样:

git clone https://github.com/P3TERX/xxx package/xxx

这样做的好处是每一次编译都会拉取最新的源码。

TIPS: 生成.config文件时记得选中相应的软件。如果添加的软件包与 OpenWrt 中已有的软件包同名的情况,则需要把源码中的同名软件包删除,否则会优先编译 OpenWrt 中的软件包。这同样可以利用到的 DIY 脚本。

最后不要忘了添加更新 feeds 的命令

./scripts/feeds update -a 
./scripts/feeds install -a

Custom files(自定义文件)

俗称“files 大法”,在仓库根目录下新建files目录,把文件放入即可。

定时自动编译


点击查看

编辑 workflow 文件(.github/workflows/build-openwrt.yml)取消注释下面两行。

#  schedule:
#    - cron: 0 8 * * 5

例子是北京时间每周五下午4点钟开始编译(周末下班回家直接下载最新固件开始折腾)。如需自定义则按照 cron 格式修改即可,Actions 虚拟环境中的时区是 UTC ,注意按照自己所在地时区进行转换。

真·一键编译(点击 star 开始编译)

点击自己仓库页面上的 Star 开始编译,为了防止被滥用,这个功能默认没有开启。开启后如果被恶意点击轻则封号,严重可能会导致中美关系恶化、原子弹爆炸、第三次世界大战等后果。(大雾


点击查看

编辑 workflow 文件(.github/workflows/build-openwrt.yml)取消注释下面两行,后续点击自己仓库上的 star 即可开始编译。

#  watch:
#    types: [started]
TIPS: 字段started并不是“开始了”的意思,而是“已经点击 Star”。
吐槽: 官方并没有提供一个开始按钮,通过搜索找到过很多奇怪的一键触发方式,但都是通过 Webhook 来实现的。机智的我发现了可以通过点击 Star 来触发,这样就相当于把 Star 当成开始按钮。这个started有种一句双关的意思了。

有个小技巧可以防止恶意点击,在runs-on: ubuntu-latest下面加上if: github.event.repository.owner.id == github.event.sender.id。这样只有你自己点star才会触发编译。

jobs:
  build:
    runs-on: ubuntu-latest
    if: github.event.repository.owner.id == github.event.sender.id

自定义源码编译

此方案默认引用的是L大的源码,如果你觉得不好用或者有编译其它源码的需求可以进行替换,自由是本解决方案最大的特点。


点击查看

编辑 workflow 文件(.github/workflows/build-openwrt.yml),修改下面的相关环境变量字段。

        REPO_URL: https://github.com/coolsnowwolf/lede
        REPO_BRANCH: master

比如修改为 OpenWrt 官方源码19.07分支

        REPO_URL: https://github.com/openwrt/openwrt
        REPO_BRANCH: openwrt-19.07
TIPS: 注意冒号后面有空格

并发编译(同时编译多个固件)

多 repository 方案

通过 P3TERX/Actions-OpenWrt 项目创建多个仓库来编译不同架构机型的 OpenWrt 固件。

多 workflow 方案

基于 GitHub Actions 可同时运行多个工作流程的特性,最多可以同时进行至少20个编译任务。也可以单独选择其中一个进行编译,这充分的利用到了 GitHub Actions 为每个账户免费提供的20个 Ubuntu 虚拟服务器环境。此外你还可以额外再使用5个 macOS 虚拟服务器环境进行编译,开启方法在后面有说明。


点击查看

假设有三台路由器的固件需要编译,比如K2P、软路由、新路由3。

  • 生成它们的.config文件
  • 分别将它们重命名为k2p.configx64.configd2.config放入本地仓库根目录。
  • 复制多个 workflow 文件(.github/workflows/build-openwrt.yml)。为了更好的区分可以对它进行重命名,比如k2p.ymlx64.ymld2.yml。此外第一行name字段也可以进行相应的修改。
  • 然后分别用上面修改的文件名替换对应 workflow 文件中下面两个位置的.config,不同的机型同样可以使用不同的 DIY 脚本。
...
    paths:
      - '.config'
...
        CONFIG_FILE: '.config'
        DIY_SH: 'diy.sh'
...
  • 最后 push ,此时此就触发了3个并行的编译工作流程。

云 menuconfig(SSH 连接到 Actions)

通过 tmate 连接到 GitHub Actions 虚拟服务器环境,可直接进行make menuconfig操作生成编译配置,或者任意的客制化操作。也就是说,你不需要再自己搭建编译环境了。这可能改变之前所有使用 GitHub Actions 的编译 OpenWrt 方式。


点击查看

  • 编辑 workflow 文件(.github/workflows/build-openwrt.yml),修改SSH_ACTIONS环境变量的值为true
SSH_ACTIONS: true
  • 在触发工作流程后,在 Actions 页面等待执行到SSH connection to Actions步骤,会出现下面的信息。
To connect to this session copy-n-paste the following into a terminal or browser:

ssh Y26QeagDtsPXp2mT6me5cnMRd@nyc1.tmate.io

https://tmate.io/t/Y26QeagDtsPXp2mT6me5cnMRd
  • 复制 SSH 连接命令粘贴到终端内执行,或者复制链接在浏览器中打开使用网页终端。(网页终端可能会遇到黑屏的情况,按 Ctrl + C 即可)
  • cd openwrt && make menuconfig
  • 完成后按快捷键Ctrl+D或执行exit命令退出,后续编译工作将自动进行。
TIPS: 固件目录下有个config.seed文件,如果你需要再次编译可以使用它。
WARRING: 默认连接30分钟后会断开并终止编译工作流程,防止资源浪费与封号风险。如果你想解除这个限制,可以根据提示操作,导致的一切后果请自行承担。

macOS 编译方案


点击查看

GitHub Actions 的 macOS 虚拟机性能要高于 Ubuntu 虚拟机,所以使用它编译 OpenWrt 理论上速度会更快。博主经过几天时间的研究已经总结出了 macOS 下的 OpenWrt 编译环境的搭建方法,并编写出了适用于 macOS 虚拟环境的 OpenWrt 编译方案的 workflow 文件。

由于并不是每个开发者都会按照规范去写代码,所以使用 macOS 编译 OpenWrt 不可避免的会遇到非常多的问题,而且后续测试发现 macOS 虚拟机性能已大幅下降,故相关 workflow 文件已经移除。也不建议任何人使用 macOS 编译 OpenWrt 。

上传固件到奶牛快传

奶牛快传是中国大陆的一款临时文件传输分享服务网盘,特点是不限速。因国情所致,中国大陆地区 GitHub 访问速度缓慢,有些小伙伴可能无法正常下载固件,上传固件到奶牛快传是个非常好的选择。


点击查看

  • 编辑 workflow 文件(.github/workflows/build-openwrt.yml),将环境变量UPLOAD_COWTRANSFER的值修改为true
UPLOAD_COWTRANSFER: true

编译完成后你可以在Upload firmware to cowtransfer步骤的日志中找到奶牛快传的下载链接。

奶牛快传 提供网盘服务,CLI 上传工具来自 Mikubill/cowtransfer-uploader,特此感谢。

尾巴

希望大家不要滥用免费的开发资源,需要时再编译,让开发者来充分利用才能产生更多更好的软件,这样大家才能受益。最后感谢 Microsoft 为我们提供 GitHub Actions 这样强大的工具。


相关 TG 群组:GitHub Actions Group

相关 TG 频道:GitHub Actions Channel

本博客已开设 Telegram 频道,欢迎小伙伴们订阅关注。

添加新评论

已有 50 条评论

感谢大佬! 梯子质量不行, 本地编译无数次都是看到红字编译失败的时候真的有种想砸电脑的冲动! 现在编译玩机简直是一种享受.

dalao好,前几天照着教程使用云ssh方法成功编译,但是最近用这样的方法workfile无法展开正在运行的ssh connection to actions的步骤,导致无法查看tmate链接网址,请问如何解决呢?

网络问题,2分钟内没有显示可刷新页面。

demo demo 回复 @P3TERX
0 0

我用手机热点也还是不行,所有完成的步骤都能展开,正在执行的步骤就打不开

demo demo 回复 @demo
0 0

今天试了一下又可以了,迷

P大你好,我用你的脚本现在编译成功了。。每次都可以编译成功,但是实际应用的固件,只要重启后然后就提示
Bad Gateway The process did not produce any response ,路由器可以ssh进去。。。但是就是网页访问不行。。。现在实在解决不了。。还麻烦P大能帮忙解决看看什么问题。。麻烦了

P3TERX P3TERX 回复 @奴隶主
0 0

云编译只是辅助编译而已,固件问题只会跟选择的组件和源码有关,建议你重新编译和通过搜索去解决。

奴隶主 奴隶主 回复 @P3TERX
0 0

已经解决了。。。其实也算是L大的bug,虚拟机下,单网卡的情况是会出现这种情况的。。如果添加2快以上网卡就没问题。。或者主动指定wan口网卡也行。。。。这样单网卡也不会出现问题。。。谢谢P大的回复。。

辛苦辛苦,很好用,技术牛逼。

谢谢分享,学了不少东西,深刻体会到github action的玩法。

我参考你的脚本,定制了lean的脚本。感觉比较满意。非常感谢。

感谢大神提供的代码可以成功编译。但是现在有两个问题想咨询一下您,第一个DIY脚本我按照您的格式填写完成了,但是编译出来的固件里没有添加DIY脚本里的插件,不知道为什么。第二个问题是能最后编译成功的同时把固件部署到onedrive上或者是其他第三方云盘里。谢谢您拉!

  1. 生成编译配置时必须要选中
  2. 通过引用第三方 action 可实现。
Qiang丶 Qiang丶 回复 @P3TERX
0 0

好的,非常感谢。

p3前辈,您好!
多次力量咨询阅读你的文章,这里教人how更教人why,知道很多所以然。从您的网站受益匪浅。
最近有个问题一直困扰,就是github actions云编译的固件比较大,即使开着梯子,从Artifacts处下载只能单线程且无法断点续传。
看到有的actions可以将Artifacts自动上传至releases,可以方便下载,比如使用IDM。

自己最近参考别人的写法尝试了一下,但是最终试了几次,还是还是不成。似乎是这个“${{ secrets.repo_token }}”不对。因为非常小白,不知道正确的写法如何。
如果您能有空看看,不知道是否可以给些提示。

或者能写一个样本,在你的build-openwrt.yml之中,就更完美了,感谢!

上传 releases 之前有考虑过加,但实际用处并不大,搞复杂了反而不利于新人来学习。其实像你一样有能力肯学习的都会自己去尝试加这个功能。
这个的关键在于生成一个 token ,在设置中去添加,然后在 workflow 文件中正确的去引用,官方文档实际都有说明。

jon jon 回复 @P3TERX
0 0

好的,感谢!
阅读官网文档是关键 (☆ω☆)

yym yym 回复 @jon
0 0

正常action会自动生成一个token,但这token只有一个小时有效期,通常对于编译来说太短了。等到编译完上传token就失效了。所以需要自己申请一个个人token,在最后上传的action中用自己的个人token。

yym yym 回复 @jon
0 0

同理,如果用action自动创建release的话是不会触发action on release published,估计避免循环嵌套无限制的编译下去。所以要想用action自动创建release触发自动编译的action也需要用自己的个人token。

不好意思请教下,如何只编译想要的ipk,而不是整个固件?

P3TERX P3TERX 回复 @蓝精灵
0 0

如果只想要指定的 ipk 并不适用我这个方案,你需要自己写 workflow 文件。

蓝精灵 蓝精灵 回复 @P3TERX
0 1

谢谢,我最后偷懒开启了上传package目录,一次选中尽可能多的组件,让github去慢慢跑编译,反正不要钱 ٩(ˊᗜˋ*)و

你好,大神,我是在dockerhub找到你的docker版openwrt的,我的机器是nvidia的jetson nano,cpu是arm64 v8a构架,在docker里运行你的openwrt,其他功能都正常,但是ssr plus+和passwall都虽然提示正在运行,但是检测google的连通性却都是无法连通。

P3TERX P3TERX 回复 @蓝精灵
0 0

我没有做过 Docker 版的 OpenWrt ,你是不是弄错了?

蓝精灵 蓝精灵 回复 @P3TERX
0 0

咦,我是在这里找到的docker版的openwrt,https://hub.docker.com/r/buddyfly/openwrt-aarch64
,Source Repository写的是你的https://www.github.com/buddyfly/Actions-OpenWrt,我一路照过来的~

P3TERX P3TERX 回复 @蓝精灵
0 0

这个是别人 fork 了我的云编译代码的仓库,所以会有我的网站链接。

蓝精灵 蓝精灵 回复 @P3TERX
0 0

谢谢大神了,看你的文章也受益不浅~今后会一直关注的

如何将yml中的

        name: OpenWrt_firmware
        path: ${{ env.FIRMWARE }}

分解成bin/img固件而不是固件目录?因为GitHub没有梯子不好下载

首先你要知道路径和文件名,以 x64 平台为例子:openwrt/bin/targets/x86/64/openwrt-x86-64-combined-squashfs.img。最简单粗暴的方法就是直接填路径,骚操作就是用各种命令去获取路径。但这并不能解决实质性问题,有个好梯子才是最重要的。

未日 未日 回复 @P3TERX
0 0

我填的是 /home/runner/work/Actions-OpenWrt/Actions-OpenWrt/openwrt/bin/targets/x86/64
前面/home/runner/work/Actions-OpenWrt/Actions-OpenWrt/这一串要去掉吗?

可以去掉,可以保留,实际效果是一样的。

未日 未日 回复 @P3TERX
0 0

保留的话提示路径错误,原fork源

怕不是后面的路径弄错了。

大神你好,我能在你的教程下成功编译出自己的固件非常方便。通过SSH 连接到 Actions编译或者上传.config编译出现编译完成后压缩包里只有initramfs-kernel.bin文件,没有squashfs-sysupgrade.bin文件的情况不知是什么原因

make menuconfig要选择相应的格式,不过一般来说squashfs-sysupgrade.bin是默认选择的。

dxs1256 dxs1256 回复 @P3TERX
0 0

我SSH 连接到 Actions 编译基本就是默认的选择完路由器型号,IPV6和需要的软件别的没有动。最开始成功过,后来不知道怎么的就不行了

幾米 幾米 回复 @dxs1256
0 0

可能是编译的固件大小超出闪存最大值了,就没有sysupgrade固件生成,你可以尝试去掉部分插件。
就算硬路由,也有硬改的,openwrt里面有对应硬件默认闪存限制好像。也是可以变更的,方便给硬改后的设备编译固件。希望能帮到你。

你好,首先感谢您,让我们既方便又简单的编译属于自己的固件。
我现在已经编译完成,而且已经在软路由上用了三天了,目前遇到的一个问题就是:在我家内网,所有的域名访问家里的设备都不行,都不同。但是在外网的时候,域名就可以访问。这个问题我访问很多资料,目前一直无解。。
请问这是哪里的问题? ⌇●﹏●⌇

P3TERX P3TERX 回复 @beidahuang
1 0

我没遇到过,所以没办法给你提供解决方法,只能你自己慢慢研究了。

jarao jarao 回复 @beidahuang
1 0

那是lean固件的问题,nat环回有故障,据说是由于docker引起的,但是我自己把docker卸载了也一样

P3大神你好,我能在你的教程下成功编译出自己的固件,非常方便,但是我想拿到固件的.config文件留作并发编译用,请问有获取云编译后生成的.config文件的方法吗?
(我用的是SSH连接Actions定制的。)

固件目录下有个config.seed文件,下次编译可以用。

Warthog Warthog 回复 @P3TERX
0 0

谢谢指点,找到了 OωO (表情:开心 发不了)

可以发啊,还以为博客崩了

Warthog Warthog 回复 @P3TERX
0 0

忘说了,是颜文字里的开心,居然提示有日文不让发

蓝精灵 蓝精灵 回复 @Warthog
0 0

前方高能预警也说有日文不让发

感谢分享!大佬牛批 ∠( ᐛ 」∠)_

只是做了一点微小的工作

你好 我已用lean的源碼 下好make menuconfig 所生成的.config文件 是指config這個目錄通通上傳到倉庫嗎

P3TERX P3TERX 回复 @中國熊貓
0 0

.config文件 push 到仓库就行了。

中國熊貓 中國熊貓 回复 @P3TERX
0 0

好的 我找到了 是隱藏檔 謝謝