在 ArchGuard 2023 Roadmap 里,我们计划设计一个轻量级的任务引擎。在阅读了 Gradle 源码的 Task 设计之后,我们决定改用 GitHub Action 的方式:基于 Yaml 编排任务。在设计 Runner 时,设想的场景是::
在这篇文章里,我们将详细介绍:
其它的总是,问题 Kotlin 构建出来的体积,在 ArchGuard Scanner 我们通常构建了统一的依赖来解决。
PS:如果你也是参考(复制/粘贴)代码的话,记得注意一下开源软件的 License 问题。
起先,由于过去只熟悉 Gradle 源码及其 Task 机制,便想围绕 Gradle Task 设计,但是 Gradle 的机制过于复杂。于是,过了一段时间后,想起了类似于 GitHub Action 会是一种更简单的机制,而且 GitHub Action 也是开源的。
GitHub Action 是一个自动化工作流程,它由多个步骤和操作组成,主要由 Yaml 写成,可以在 GitHub 上触发和运行。而其 Runner 是 GitHub Actions 运行的环境,它负责从 GitHub 仓库下载工作流程、安装和配置需要的软件和工具、运行工作流程中的命令和操作,并将结果报告给 GitHub。
最重要的是 GitHub Action Runner 包含了一个开源版本,于是,我们设计(复制)了其 yaml 配置:
jobs:
steps:
- name: "Source Code with Linter"
uses: archguard/scanner@v2
with:
type: "source_code"
language: kotlin
features: [ "datamap" ]
output: [ "json", "arrow" ]
rules: [ "webapi", "test", "sql" ]
path: "."
要达到非常接近 GitHub Action 的设计,就需要去看源码,学习(抄) C# 代码可不是一件容易的事,还好我们有 IDE。其基本的几个 JobService 是:
考虑到我们当前并没有执行环境、进程等,只需要好好写 ActionRunner 即可,即解析上面 Yaml 中的 steps 里的 Action 字段。根据不同的 action 来执行,并将上面的 with
字段转换成对应的参数,因此上面的配置在执行时会变成:
java -jar plugins/scanner-v2 --output json --output arrow --features datamap --path . --language kotlin --rules webapi --rules test --rules sql --type source_code
如此一来,我们就有了更多的想象空间,可以自定义分析任务,并与架构实现更好的解耦:
- uses: linter/architecture@v1
- uses: linter/database@v1
- used: metric/oo@v1
- used: metric/complexity@v1
# for translation custom rules
- used: factor/sonarqube@v1
详细代码见:https://github.com/archguard/codedb-poc
我们参考了 NPM Registry、Maven Central 等制品仓库的思想,构建了基本的 Runner registry。它包含了以下的功能:
在 ArchGuard Runner 中,Registry 的运行机制如下:
于是乎,我们需要在 archguard.yml
中引入新的配置:
env:
registry:
url: https://registry.archguard.org/
local: true
server:
url: http://localhost:8084
将
@Serializable
data class ActionRegistry(
val name: String,
val description: String,
val version: String,
val author: String,
val time: Time,
val versions: Map<String, Version>,
val homepage: String,
val repository: Repository,
val license: String,
val readme: String
)
其中,versions
字段是一个 Map 类型,键是版本号,值是 Version
对象,Repository
表示代码仓库信息。每个 Version
对象包含了该版本的元数据信息,包括制品类型、制品下载 URL、制品 SHA256 校验和(还未实现)等。
现在的 Registry 是一个放在 GitHub Pages 的 JSON 文件,相当于是一个 fake server。尽管,我们可能并不需要一个真正的服务器,但是需要一个能生成 JSON 文件的机制。而为了根据制品生成 JSON,我们需要在制品构建和发布的过程中将制品的信息写入一个描述文件中,然后将该描述文件打包成制品一起发布。该描述文件应该包含制品的元数据,例如名称、版本、作者、发布时间、许可证等信息,以及制品所需的运行时环境和依赖项的描述。也因此 ChatGPT 建议我们可以考虑:
如果你也有兴趣,欢迎一起来设计 registr
由于先前的 ArchGuard Clone 逻辑比较简单,并且缺少 SshKey 等的支持,所以我们决定参考(复制)GitHub Action 编写一个新的。GitHub 的 Checkout Action 的主要处理逻辑可以概括为以下几个步骤:
每一步都是封装 Git 的命令完成的,诸如于 checkout 是:
git -c protocol.version=2 fetch --prune --progress --no-recurse-submodules origin +refs/heads/*:refs/remotes/origin/* +refs/tags/*:refs/tags/*
在这些参数里包含了非常多的 Git 使用细节,可惜我用的是 GitHub Copilot 来转换 TypeScript 代码为 Kotlin 的,所以并没有展开详细的研究。
然后,将构建的 jar 上传到 registry,并编写一个 Json,就实现了完成的 Runner DEMO。
如果你喜欢编写和优化软件构建流程,那么你一定会喜欢 ArchGuard Runner!它是一个全新的构建工具,旨在为开发人员提供更快、更可靠的软件构建和部署体验。现在,我们正在寻找有志于贡献自己力量的人加入我们的设计团队,一起开发这个充满活力的项目。
作为 ArchGuard Runner 的设计者之一,你将参与构建这个新工具的核心部分,包括运行器、插件、配置等等。你将与来自不同背景的开发人员、测试人员和其他设计师合作,共同探索新技术、解决问题并改进我们的软件开发流程。你还将有机会与各种软件开发团队和项目合作,了解他们的需求并提供解决方案。
围观我的Github Idea墙, 也许,你会遇到心仪的项目