如何用GitHub Actions云编译L大固件
前段时间摸索了一下Github Actions,发现用来云编译L大固件非常的不错。可以很好解决本地编译速度慢,还占用硬件资源的问题,不过想要定制自己想要的功能,还是建议在本地下载一份代码仓库。
准备工作:
- 固件代码仓库:L大Lede,需要fork到自己的账号下面。
- CI脚本:OpenWrt-CI,并非只有这个,还有别的,目前我用的是这个,并且也直接包含在了L大的代码仓库里面。
- 开启Actions:我用一个新号来截图:
先fork了仓库之后,点击上面Actions按钮
然后点击绿色的按钮,继续
修改脚本
克隆一份你fork的仓库到本地来,这样比较方便修改。克隆好之后,使用文本编辑器打开code repo/.github/workflows/openwrt-ci.yml
修改名称以及合适开始编译
主要有两个部分需要修改,我一点点来介绍,但是需要声明下,我并不会YAML,只是照葫芦画瓢来的,有问题请提出,一起学习。下面,我直接再代码片段里面直接写修改的内容,看到中文就是我后添加的。
#
# This is free software, lisence use MIT.
#
# Copyright (C) 2019 P3TERX <https://p3terx.com>
# Copyright (C) 2019 KFERMercer <KFER.Mercer@gmail.com>
#
# <https://github.com/KFERMercer/OpenWrt-CI>
#
name: OpenWrt-CI #这里是workflow的名称,怎么理解呢?就是你在actions里面看到的进程名称。可以自行修改,以便区分
on:
schedule:
- cron: 0 20 * * *
# 整个上面三行应该是开始workflow,但是我没太明白他的作用,猜测是每天晚上20点编译?不过我是修改为了直接进行编译(同步了修改之后,这里来自openwrt-ci脚本作者的仓库里面的示例),改动如下:
on:
push:
branches:
- master
# schedule:
# - cron: 0 20 * * *
# release:
# types: [published]
# 这里要说明下,如果采用和我一样的方法,那就删除原本代码里面的那三行,复制我的进去,直接复制四行也行。
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@master
with:
ref: master
这部分的修改主要也就两点,workflow的名称,和开启的条件。
自定义固件的修改
下面就到了核心部分,固件定制部分了,设计到的修改也比较多,我慢慢来介绍:
- 首先要找到生成配置文件的地方:
- name: Generate configuration file
也就是这一行。L大代码内的原生内容为:
- name: Generate configuration file
run: make defconfig
这不行啊,我要定制啊,怎么办呢,同样可以去opwnert-ci作者的仓库里找示例,并且复制这段内容进来,或者直接复制下面的代码片段来替换到原本的两行代码:
- name: Update feeds
run: |
./scripts/feeds update -a
./scripts/feeds install -a
- name: Generate configuration file
run: |
rm -f ./.config*
touch ./.config
#
# ========================固件定制部分========================
#
#
# 如果不对本区块做出任何编辑, 则生成默认配置固件.
#
# 以下为定制化固件选项和说明:
#
#
# 有些插件/选项是默认开启的, 如果想要关闭, 请参照以下示例进行编写:
#
# =========================================
# | # 取消编译VMware镜像: |
# | cat >> .config <<EOF |
# | # CONFIG_VMDK_IMAGES is not set |
# | EOF |
# =========================================
#
#
# 以下是一些提前准备好的一些插件选项.
# 直接取消注释相应代码块即可应用. 不要取消注释代码块上的汉字说明.
# 如果不需要代码块里的某一项配置, 只需要删除相应行.
#
# 如果需要其他插件, 请按照示例自行添加.
# 注意, 只需添加依赖链顶端的包. 如果你需要插件 A, 同时 A 依赖 B, 即只需要添加 A.
#
# 无论你想要对固件进行怎样的定制, 都需要且只需要修改 EOF 回环内的内容.
#
# 编译x64固件:
# cat >> .config <<EOF
# CONFIG_TARGET_x86=y
# CONFIG_TARGET_x86_64=y
# CONFIG_TARGET_x86_64_Generic=y
# EOF
# 固件压缩:
# cat >> .config <<EOF
# CONFIG_TARGET_IMAGES_GZIP=y
# EOF
# 编译UEFI固件:
# cat >> .config <<EOF
# CONFIG_EFI_IMAGES=y
# EOF
# IPv6支持:
# cat >> .config <<EOF
# CONFIG_PACKAGE_dnsmasq_full_dhcpv6=y
# CONFIG_PACKAGE_ipv6helper=y
# EOF
# 多文件系统支持:
# cat >> .config <<EOF
# CONFIG_PACKAGE_kmod-fs-nfs=y
# CONFIG_PACKAGE_kmod-fs-nfs-common=y
# CONFIG_PACKAGE_kmod-fs-nfs-v3=y
# CONFIG_PACKAGE_kmod-fs-nfs-v4=y
# CONFIG_PACKAGE_kmod-fs-ntfs=y
# CONFIG_PACKAGE_kmod-fs-squashfs=y
# EOF
# USB3.0支持:
# cat >> .config <<EOF
# CONFIG_PACKAGE_kmod-usb-ohci=y
# CONFIG_PACKAGE_kmod-usb-ohci-pci=y
# CONFIG_PACKAGE_kmod-usb2=y
# CONFIG_PACKAGE_kmod-usb2-pci=y
# CONFIG_PACKAGE_kmod-usb3=y
# EOF
# 常用LuCI插件选择:
# cat >> .config <<EOF
# CONFIG_PACKAGE_luci-app-adbyby-plus=y
# CONFIG_PACKAGE_luci-app-aria2=y
# CONFIG_PACKAGE_luci-app-baidupcs-web=y
# CONFIG_PACKAGE_luci-app-docker=y
# CONFIG_PACKAGE_luci-app-frpc=y
# CONFIG_PACKAGE_luci-app-kodexplorer=y
# CONFIG_PACKAGE_luci-app-minidlna=y
# CONFIG_PACKAGE_luci-app-openvpn=y
# CONFIG_PACKAGE_luci-app-openvpn-server=y
# CONFIG_PACKAGE_luci-app-qbittorrent=y
# CONFIG_PACKAGE_luci-app-ssr-plus_INCLUDE_Kcptun=y
# CONFIG_PACKAGE_luci-app-ssr-plus_INCLUDE_Shadowsocks=y
# CONFIG_PACKAGE_luci-app-ssr-plus_INCLUDE_ShadowsocksR_Server=y
# CONFIG_PACKAGE_luci-app-ssr-plus_INCLUDE_ShadowsocksR_Socks=y
# CONFIG_PACKAGE_luci-app-ssr-plus_INCLUDE_V2ray=y
# CONFIG_PACKAGE_luci-app-ttyd=y
# CONFIG_PACKAGE_luci-app-v2ray-server=y
# CONFIG_PACKAGE_luci-app-verysync=y
# CONFIG_PACKAGE_luci-app-webadmin=y
# CONFIG_PACKAGE_luci-app-wireguard=y
# CONFIG_PACKAGE_luci-app-wrtbwmon=y
# EOF
# LuCI主题:
# cat >> .config <<EOF
# CONFIG_PACKAGE_luci-theme-argon=y
# CONFIG_PACKAGE_luci-theme-netgear=y
# EOF
# 常用软件包:
# cat >> .config <<EOF
# CONFIG_PACKAGE_curl=y
# CONFIG_PACKAGE_htop=y
# CONFIG_PACKAGE_nano=y
# CONFIG_PACKAGE_screen=y
# CONFIG_PACKAGE_tree=y
# CONFIG_PACKAGE_vim-fuller=y
# CONFIG_PACKAGE_wget=y
# EOF
# 取消编译VMware镜像以及镜像填充 (不要删除被缩进的注释符号):
# cat >> .config <<EOF
# # CONFIG_TARGET_IMAGES_PAD is not set
# # CONFIG_VMDK_IMAGES is not set
# EOF
#
# ========================固件定制部分结束========================
#
sed -i 's/^[ \t]*//g' ./.config
make defconfig
这里面也介绍的比较详细了,各部分内容,如果需要,就把各行前面的注释删掉即可。这段有点长,下面我再贴上我自己用的自定义部分,同时,感谢【videoTalk】的插件名称列表,还有github上一些非常优秀的插件以及luci主题。
我把我自己编译用的yml文件分享给大家:
我简单介绍一下,添加了一些常用工具,没有添加多播,因为我这没法使用。同时,我也添加了两个来自GitHub的luci主题和KPR插件,但是这需要我们在前面先下载仓库,那么如何让actions自动下载呢?我们在自定义固件配置前面找到- name: Update feeds
,我们需要在前天再添加一个任务,内容如下,添加时候,无比确保缩进量一致。如果你添加了来自GitHub的其他插件或者主题,也请按照下面git clone的格式添加clone仓库的命令,同时在- name: Generate configuration file
任务里面响应位置激活。
- name: add plugin
run: |
cd package
mkdir openwrt-packages
cd openwrt-packages
git clone https://github.com/openwrt-develop/luci-theme-atmaterial.git
git clone https://github.com/tzxiaozhen88/luci-app-koolproxyR.git
git clone https://github.com/rosywrt/luci-theme-rosy.git
这一段代码的作用提前下载代码仓库里面没有的,插件以及主题,因为这是我在github上找的,为什么要下载呢?因为我在后续的自定义部分里面添加了相关的配置。
# 我在末尾加上了KPR
# 常用LuCI插件选择:
cat >> .config <<EOF
CONFIG_PACKAGE_luci-app-adbyby-plus=y
CONFIG_PACKAGE_luci-app-aria2=y
CONFIG_PACKAGE_luci-app-baidupcs-web=y
CONFIG_PACKAGE_luci-app-docker=y
CONFIG_PACKAGE_luci-app-frpc=y
CONFIG_PACKAGE_luci-app-kodexplorer=y
CONFIG_PACKAGE_luci-app-minidlna=y
CONFIG_PACKAGE_luci-app-openvpn=y
CONFIG_PACKAGE_luci-app-openvpn-server=y
CONFIG_PACKAGE_luci-app-qbittorrent=y
CONFIG_PACKAGE_luci-app-ssr-plus_INCLUDE_Kcptun=y
CONFIG_PACKAGE_luci-app-ssr-plus_INCLUDE_Shadowsocks=y
CONFIG_PACKAGE_luci-app-ssr-plus_INCLUDE_ShadowsocksR_Server=y
CONFIG_PACKAGE_luci-app-ssr-plus_INCLUDE_ShadowsocksR_Socks=y
CONFIG_PACKAGE_luci-app-ssr-plus_INCLUDE_V2ray=y
CONFIG_PACKAGE_luci-app-ttyd=y
CONFIG_PACKAGE_luci-app-v2ray-server=y
CONFIG_PACKAGE_luci-app-verysync=y
CONFIG_PACKAGE_luci-app-webadmin=y
CONFIG_PACKAGE_luci-app-wireguard=y
CONFIG_PACKAGE_luci-app-wrtbwmon=y
CONFIG_PACKAGE_luci-app-koolproxyR=y
EOF
# 我在末尾添加了两个主题,是我比较喜欢的
# LuCI主题:
cat >> .config <<EOF
CONFIG_PACKAGE_luci-theme-argon=y
CONFIG_PACKAGE_luci-theme-netgear=y
CONFIG_PACKAGE_luci-theme-rosy=y
CONFIG_PACKAGE_luci-theme-atmaterial=y
EOF
其他与openwrt-ci的脚本不同的地方可以对照videotalk的列表,或者直接github搜名称。就明白作用了。
修改完脚本文件,就同步回自己fork的仓库就可以了。
编译其他平台
这里再说一下,openwrt-ci的yml和我的yml都是编译的x86
平台,如果你需要编译其他平台,要么找到你以前编译时候的.config
文件,要么还是需要你搭建一个编译环境,不过并不执行实际编译操作,所以对硬盘以及硬件性能无要求,虚拟机就可以,我们只需要在make menuconfig
步骤处徘徊即可。下面详细介绍一下:
在我提供的yml里面关于平台配置的代码:
# 编译x64固件:
cat >> .config <<EOF
CONFIG_TARGET_x86=y
CONFIG_TARGET_x86_64=y
CONFIG_TARGET_x86_64_Generic=y
EOF
然后呢,我们需要去编译环境里面按照L大仓库里面在本地编译的操作流程来到make menuconfig
步骤,第一次运行,会打开一个menuconfig的ui交互界面,我们在平台选择里面选择X86平台,然后保存退出,这个时候,把.config
文件部分一下如.config_x86
,然后我们再一次执行上面的操作,再选择平台为你需要编译的平台,再退出,再备份,然后对比两个文件就好了,把差异修改在yml里面就可以了。
这个方法不仅仅适用于平台,也是用于其他插件的编译,这就是控制了变量的笨方法。
当然不能排除你连menuconfig
也不懂,那么你也可以提供你需要编译的平台在我的github仓库的issue里,我看到了会尽可能的帮助你。
固件名称
在整个yml的末尾,我们也可以自定义输出的固件压缩包的名称,这也是方便管理与分类,不过我比较懒,没有修改。。。
在文件的最后三行:
with:
name: OpenWrt firmware # 这里就是输出的压缩包名称,我并没有改,比较懒
path: ./bin/targets/
等待编译完成以及找到bug
在上一步我们修改完脚本并且同步回去之后,在actions里面就会开始编译了。可以点击仓库上方的Actions
按钮查看进度,一般需要将近3个小时就会完成,当然这个过程中,你也可以点进去查看进度。
进入到Actions页面可以看到我们自己命名的workflow,然后可以看到我们每次同步的编译结果,因为我之前同步过多次,所以会有很多,一般点击第一个就是最新的,如果OK前面会有绿色的勾,如果有问题会有红色的叉,我们也可以点进去查看详细错误log,以便修改。
如果没问题,点击最上面的workflow就可以进入到详细页面,这里面,我们可以看到输出文件OpenWrt firmware
(如果你也没有修改的话),我们点击就可以开始下载了。
但是如果workflow前面是叉叉怎么办呢?
我们依旧点击这个workflow,然后点击右边的build,可以查看详细的编译过程,也可以看到到底是哪里出了问题。
我这里面的问题是clone地址填写错误,那么就回到错误的地方修复再重新同步yml文件,在同步回GitHub的时候信息,最好标明操作理由,因为这将显示在你的workflow里面,也方便后面去区分。
结语
整个过程说复杂也很复杂,但是明白了其中的逻辑之后又很简单(小声说:除了不懂YAML),如果文中哪里讲的不够清楚,请在评论区告诉我,我会尽快修改,直到能看明白为止。如果是比较大的疑惑,我也可以开新帖子,尽我所能解答一些问题,共同提高和学习。
如果文中有什么错误,也请各位神仙来指正小弟学习中的错误。