archlinuxcn / lilac

Lilac is the build bot for archlinuxcn
GNU General Public License v3.0
113 stars 39 forks source link

[WIP] adding lilac3 #168

Closed petronny closed 1 year ago

petronny commented 3 years ago

145 #149 #159

lilac 3

首先 lilac 3 就是我想的分拆后的下一代 lilac 。 所有代码执行寄托于 github actions ,这样所有运行的 log 都是透明的。邮件系统可以大幅度简化。 同时 github actions 可以写死很多变量,配置也可以大幅度简化。

主要模块包括:

合并是还没打算合并的。。。可以等其他的模块都搞定了的。现在就是来征求一下意见。。。

seeker

seeker 是 lilac 3 第一个模块,内容即从 lilac.yaml 中收集 nvchecker 信息,生成 nvchecker.toml 。 最后执行 nvchecker 得到 newver.json 并传输至 artifacts 。

配置

配置 secrets.REPOSITORY 即可运行。

执行预览

seekerhttps://github.com/petronny/lilac/runs/1558298622?check_suite_focus=true log 可以帮助大家了解报错情况,不用再发邮件了。

附注

lilydjwg commented 3 years ago

首先,我不希望 lilac 重依赖 GitHub。目前 lilac 本体对 GitHub 的依赖是非常少的,只有 issue 处理部分的依赖会比较大。

关于邮件和日志。邮件是一个又方便又通用的通知方式。GitHub Actions 怎么把报错准确地送达到相关的维护者呢?

有日志看自然是好的,但是我们不应该让维护者时不时地检查日志,或者把相关的信息埋在很深的日志中。GitHub Actions 的日志的阅读体验实在不敢恭维,要点+等加载好些次才能看到,而且内容区域过小。而服务器上的日志,就跟普通日志一样,虽然没有分节,但是可以随意 grep,使用传统 UNIX 工具处理。

目前我的想法是这样的:

至于你希望的在别处执行 nvchecker,只需要写一个 wrapper 脚本,让真正的 nvchecker 在别的地方执行,完了之后把结果再回传回来就好了呀。

petronny commented 3 years ago

关于邮件和日志。邮件是一个又方便又通用的通知方式。GitHub Actions 怎么把报错准确地送达到相关的维护者呢?

我的计划是 poster 模块每天一次根据数据库中的包状态,发送对应的 log 的链接的汇总邮件给维护者。 发个邮件 GitHub Actions 还是做得到的。

GitHub Actions 的日志的阅读体验实在不敢恭维,要点+等加载好些次才能看到,而且内容区域过小。而服务器上的日志,就跟普通日志一样,虽然没有分节,但是可以随意 grep,使用传统 UNIX 工具处理。

日志可以通过 artifacts 链接的形式写进邮件里,可以下载然后本地 grep 。 甚至按原来的方式发送日志也是可以的。

我不希望 lilac 重依赖 GitHub。目前 lilac 本体对 GitHub 的依赖是非常少的,只有 issue 处理部分的依赖会比较大。

嗯。。。理论上说 GitHub Actions 可以不是必须的。可以分拆成 seeker.sh scheduler.sh ,然后本地 cron 执行。 不过 GitHub Actions workflow 正好是之前我想做的一些事的一个契机,包括

等等。总之我按 GitHub Actions 的情况先做着吧。。。 上面很多需求 arch4edu 还挺急用的。。。比如公共 log 访问、多层目录、分拆 single_main 、汇总邮件

lilydjwg commented 3 years ago

日志可以通过 artifacts 链接的形式写进邮件里,可以下载然后本地 grep 。

grep 最近一些日子的所有日志可不容易。

现在的确有邮件数量过多的问题,比如现在 numba 不支持 python3.9 导致的依赖问题让我每天收到一大串的邮件。

你可以过滤掉不想看的邮件呀。

lilac 一直没有开自动 rebuild 那些之前 fail 的包也是因为邮件数量问题。

不是。是因为 lilac 没法分辨暂时性错误和永久错误,所以假定所有错误都是永久错误,放一放也不会变好。

有链接的话,对于不想加入 group 的 AUR 包维护者,他们可以根据这些 log 来自行修改 PKGBUILD 。

现在也是有日志链接的呀。

国际上说,我猜 GitHub 的网络也应该比 build 机所在的网络国际链路更好吧。

不一定。实际上我在 Travis-CI 观察到许多我正常网络环境没法复现的奇怪问题。GitHub Actions 的网是好,可是它的使用量也大,甚至可能因为某些用户的滥用而导致 IP 地址被封禁。

arch4edu 没有公网 IP 服务器,所以比较需要这个功能。。。

你可以把日志传到另一地方来展示。

关于汇总邮件,就像你说的,需要一个数据库。还需要用户配置「使用偏好」的功能。然后你还需要个界面。想过,但是懒得做……

lilac.yaml 也需要一个类似 single_main 的东西。

你可以放个 lilac.py 文件里写上 single_main。不过确实不那么方便。我平时是用不上这个的。用得最多的是 import lilac; lilac.pre_build()

并行打包,去掉通过编辑 pkgver 来trigger rebuild 的机制等等

那你要怎么 trigger rebuild 呢?

上面很多需求 arch4edu 还挺急用的。。。比如公共 log 访问、多层目录、分拆 single_main 、汇总邮件

这些没一个是依赖 GitHub Actions 的。

如果是两层目录的话,其实要实现很容易。single_main 那个东西,独立写个脚本也是可以的。

我希望 nvchecker 运行在其他机器上这些奇怪需求也更容易实现。。。

取决于你如何访问其他机器,可能可以很容易地实现。

lilac.yaml 中的 pre_build 中直接写 shell 命令

可以加一个配置项。

实际上你的需求挺多的……一个个解决吧。不要觉得换 GitHub Actions 就万事大吉了。

petronny commented 3 years ago

grep 最近一些日子的所有日志可不容易。

为什么会有这个需求呢。。。

那你要怎么 trigger rebuild 呢?

写一个 API 直接去数据库标记状态为过期就行了,接下来交给 scheduler 。 GitHub Actions 也可以提供手动触发的前端按钮。 微信截图_20201217015508

实际上你的需求挺多的……一个个解决吧。不要觉得换 GitHub Actions 就万事大吉了。

嗯。。。我是想先按 GitHub Actions 做着,先踩坑,保证模块独立的基础上实现功能,之后再把 GitHub Actions 去掉。 去的时候把各种写死的东西改成配置。

总之目前先用我熟悉的 django orm 先把数据库加上了。。。

lilydjwg commented 3 years ago

On Wed, Dec 16, 2020 at 08:23:23AM -0800, Jingbei Li wrote:

grep 最近一些日子的所有日志可不容易。

为什么会有这个需求呢。。。

在一个包的近期打包日志里找东西,或者在一个批次里找某个相同的报错。

那你要怎么 trigger rebuild 呢?

写一个 API 直接去数据库标记状态为过期就行了,接下来交给 scheduler 。

好麻烦,还要写一份用户认证的功能,然后还对外不可见。直接写到 git 仓库里 能省不少事呀。

-- Best regards, lilydjwg

petronny commented 3 years ago

好麻烦,还要写一份用户认证的功能,然后还对外不可见。

GitHub Actions 可以提供手动触发的前端按钮。(见上)

petronny commented 3 years ago

GitHub Actions 可以提供手动触发的前端按钮

这个现在也加上了。目前唯一问题是 GitHub Actions 到我在阿里云杭州的数据库有点慢。。。写入 2 条/秒 。

petronny commented 3 years ago

初步实现了一下 scheduler 的规划部分,感觉这块可能是问题最大的。。。求 review ...

petronny commented 3 years ago

你虽然在写 Python,但是看着很 shell……

...因为我没认为这些会相互 import ... 就没那么写。。。

就是除了数据库没认为别的是库,都是独立程序。

petronny commented 3 years ago

使用 enum 而不是字符串

状态集还没想好。。。先字符串扔着了

lilydjwg commented 3 years ago

On Sun, Dec 20, 2020 at 03:34:12AM -0800, Jingbei Li wrote:

你虽然在写 Python,但是看着很 shell……

...因为我没认为这些会相互 import ... 就没那么写。。。

那么写很方便的。即使用的时候不需要 import,测试的时候 import 也不错。另 外局部变量比全局变量快很多。

-- Best regards, lilydjwg

lilydjwg commented 3 years ago

On Sun, Dec 20, 2020 at 03:49:52AM -0800, Jingbei Li wrote:

@petronny commented on this pull request.

+for i in repository.rglob('lilac.yaml'):

  • try:
  • pkgbase = str(i.parent)[len(str(repository))+1:]
  • with open(i) as f:
  • lilac = yaml.safe_load(f)
  • for j, update_on in enumerate(lilac['update_on']):
  • if 'alias' in update_on.keys():
  • config[f'{pkgbase}:{j}'] = aliases[update_on['alias']]
  • else:
  • for key, value in update_on.items():
  • if value is None:
  • update_on[key] = i.parent.name
  • config[f'{pkgbase}:{j}'] = update_on
  • logger.debug(f'Loaded {i}.')
  • except:
  • logger.error(f'Failed to load {i}.')

这个是方便 i18n 的原因么

是因为一些日志处理工具会按消息来合并,比如 sentry。另外,如果你格式化出 来的消息里包含 % 字符的话也会出问题。

-- Best regards, lilydjwg

lilydjwg commented 3 years ago

On Sun, Dec 20, 2020 at 03:45:08AM -0800, Jingbei Li wrote:

@petronny commented on this pull request.

+from tornado.log import enable_pretty_logging +from tornado.options import options + +options.logging = 'debug' +logger = logging.getLogger() +enable_pretty_logging(options=options, logger=logger) + +repository = Path(sys.argv[1]) + +with open(Path(file).parent / 'aliases.yaml') as f:

  • aliases = yaml.safe_load(f)
  • +config = {} +config['config'] = {} +config['config']['oldver'] = '/dev/null' +config['config']['newver'] = 'newver.json'

这块我不清楚对齐标准。

我的 vim 说是这样的:

config = {
        '__config__': ...
        }

就是最后这个 '}' 的对齐标准是什么,内部怎么对齐。

我每次为了避免思考这个问题都按现在的写法写的。。。。

和对应的 { 的最左边对齐,跟某个 C 风格一样。也有人是和上一行第一个非空白 字符对齐的。PEP 8 说都行。但我喜欢前者,因为方便找对应的括号在哪里,尤其 是嵌套的时候。

-- Best regards, lilydjwg

petronny commented 3 years ago
from optparse import Values

class Options(Values):

    def __repr__(self):
        return super().__str__()

    def __getattr__(self, attr):
        setattr(self, attr, Options())
        return getattr(self, attr)

config = Options()
config.__config__.oldver = '/dev/null'
config.__config__.newver = 'newver.json'

这样如何?

lilydjwg commented 3 years ago

On Sun, Dec 20, 2020 at 04:37:51AM -0800, Jingbei Li wrote:

from optparse import Values

class Options(Values):

    def __repr__(self):
        return super().__str__()

    def __getattr__(self, attr):
        setattr(self, attr, Options())
        return getattr(self, attr)

config = Options()
config.__config__.oldver = '/dev/null'
config.__config__.newver = 'newver.json'

这样如何?

你干嘛要用过时包里的东西。不如去看看 dataclass 或者 attr 能不能这么搞。 不过不建议为了省一点 shift 去弄这个。

-- Best regards, lilydjwg

petronny commented 3 years ago
class Options(dict):

    def __getitem__(self, key):
        if not key in self.keys():
            self.__setitem__(key, Options())
        return super().__getitem__(key)

    def __getattr__(self, attr):
        if not attr in self.keys():
            self[attr] = Options()
        return self[attr]

    def __setattr__(self, attr, value):
        self[attr] = value

    def __delattr__(self, attr):
        del self[attr]

optparse 的确多余了。。。

不过不建议为了省一点 shift 去弄这个。

我觉得用的还挺多的😂 好几个 config 都能这么写了

petronny commented 3 years ago

感觉美观多了,尤其这里

config.GitHubActions.max_parallel = 20
config.x86_64.max_parallel = 1
config.arm.max_parallel = 1
petronny commented 3 years ago

呃,好像也没有尤其。。。不过就这样吧😂

petronny commented 3 years ago

if __name__ == '__main__': 都加上了,虽然基本没什么用。。。因为原来的代码按设计都是 main

petronny commented 1 year ago

情况紧急,我把之前的这些就先实现在了 https://github.com/arch4edu/cactus 再加上免费的 GitHub Actions runners 和其他免费资源总算把 arch4edu 救活了。

不过 cactus 现在跟 GitHub Actions 集成比较深,估计应该是合并不回来了,这个 PR 就关了吧