如何用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文件分享给大家:

yelvlab/lede openwrt-ci.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),如果文中哪里讲的不够清楚,请在评论区告诉我,我会尽快修改,直到能看明白为止。如果是比较大的疑惑,我也可以开新帖子,尽我所能解答一些问题,共同提高和学习。

如果文中有什么错误,也请各位神仙来指正小弟学习中的错误。

最后修改:2020 年 10 月 12 日
如果觉得我的文章对你有用,请随意赞赏