使用travis ci构建Cache Brew

Ste*_*enG 16 macos homebrew travis-ci

我有一个Travis CI osx构建,其brew依赖关系必须从源代码构建.

我知道Travis有这个cache功能,但它没有任何关于如何缓存brew构建或输出的文档.

关于如何brew在travis中缓存包的任何想法?

iva*_*eev 15

这里有3个单独的,松散相关的问题:

  • 缓存下载的瓶子
  • 缓存本地制造的瓶子
  • 缓存自制程序元数据

您不一定需要全部三个,因此请遵循适合您需求的部分.


缓存下载的瓶子

  • 添加$HOME/Library/Caches/Homebrew到Travis的缓存(实际上,这条路径应该被检索,brew --cache但是你不能在这里调用它,是吗)

    cache:
      directories:
        - $HOME/Library/Caches/Homebrew
    
    Run Code Online (Sandbox Code Playgroud)
  • brew cleanupbefore_cache阶段运行- 否则,随着新软件包版本的发布,缓存将无限增长

    before_cache:
      - brew cleanup
    
    Run Code Online (Sandbox Code Playgroud)

缓存本地制造的瓶子

完整代码太长,无法在此列出,因此给出了算法.

这是上一节的补充.如果在没有它的情况下使用,请在安装步骤中将本地瓶子保存在Homebrew缓存之外的某个位置,并下面的启动步骤中以适当的名称将它们添加到缓存中.

  • 安装时:

    • brew deps递归方式 检查包的依赖关系
      • 如果一个瓶子的包装不适用于你的环境(没有(bottled)brew info <pkg>输出),包括建立与依赖--include-build
    • 对于每个包和依赖项,

      • 如果已经安装(brew list --versions <pkg>成功)和最新版本(缺席brew outdated),请跳过它
      • 如果一个瓶子可用,只需brew unlink它([keg-only]如果安装了旧版本)
      • 如果没有瓶子,

        • 按以下顺序构建和安装它:

          brew install --build-bottle <pkg>
          brew bottle --json <pkg>
          brew uninstall --ignore-dependencies <pkg>
          brew install <bottle>
          
          Run Code Online (Sandbox Code Playgroud)

          (似乎没有任何官方方式来获取生成的瓶子和JSON文件的名称.我从brew info输出中获取了瓶子名称,并从中推断出了JSON文件名.)

        • 将瓶子信息添加到包装的配方中

          brew bottle --merge --write <json file>
          
          Run Code Online (Sandbox Code Playgroud)
        • 将瓶子文件保存到Travis缓存中,并使用相应的名称 brew install

          • 只有在添加瓶子信息后才这样做 - 否则,您将获得源包的路径.
          • (Homebrew还为下载的文件制作了符号链接--force.你不需要这样做.)
        • 保存JSON文件以供以后使用.确保将其位置添加到Travis缓存中.
  • 在启动时:

    • 这样做brew install,如果你要
    • 浏览已保存的.json文件.对于每个瓶子,检查本地瓶子是否仍然合适(通过比较版本和重建数字;您可以解析此数据的输出brew bottlebrew --cache <pkg>此数据).
      • 删除缓存的瓶子和.json,如果没有
        • 由于此时您将无法获得瓶子的路径$HOME/Library/Caches/Homebrew,因此您需要单独保存它.截至本文撰写时,符号链接未保存在Travis的缓存中,因此我最终使用了保存路径的常规文件.
      • 如果是,请将瓶子信息重新添加到上面的公式中
        • 他们也不太可能在不破坏版本的情况下更改公式中的下载URL - 然后瓶子的预期缓存名称将会更改,因为其中的哈希值是下载URL的哈希值.为此,请brew update在添加信息后检查是否仍然指向您的瓶子.
  • brew info --json=v1 <pkg>:

    • 如果您在brew info --json=v1 <bottle>上一节中使用,请在运行之前将缓存中的本地构建的瓶文件保存在某处,因为brew --cache可能会删除此次不需要的文件.之后brew --cache <pkg>,恢复已删除的内容.

缓存自制程序元数据

如果你运行before_cache (并确保没有秘密变量brew cleanup或你的Travis项目设置 - cleanup仅在cleanuptty时打印许多状态消息) - 你会看到究竟构成一个Homebrew selfupdate操作的原因 - 因此你应该缓存什么:

  • 拉(实际上,brew update --verbose默认情况下)为几个实际.travis.yml存储库的路径:
    • brew - Homebrew本身
    • stdout - 安装水龙头
  • 通过点击和缓存并迁移过时的位.由于Travis缓存内容被添加到现有目录结构而不是替换它,第二次,可能会有由于作为更新的一部分而被删除的文件引起的奇怪操作和错误,但是在新VM中又存在.我亲眼目睹的:
    • 将始终尝试迁移rebasegit,创建副本/usr/local/Homebrew.如果缓存,此副本将在下次运行时导致"错误:文件存在".
    • 将始终尝试导入大量未提交的文件 /usr/local/Homebrew/Library/Taps/*/*

所以,行动将是:

  • 添加Taps/caskroom/homebrew-cask到Travis缓存

    • 添加/ usr/local/Cellar/ usr/local/opt被证明是个坏主意:首先,它们太大,导致缓存制作和上传时超时; 第二,这是不安全的'cuz Taps/homebrew/homebrew-cask脚本可能会影响系统的其他任意部分,因此每次都应该从(缓存)瓶子安装新的包版本,而不是缓存结果.无论如何,安装瓶子只需要几秒钟.
  • 之前Taps/homebrew/homebrew-cask/homebrew-cask:清理Homebrew代码库

    • Taps/homebrew/homebrew-versions如果/usr/local/Homebrew存在,删除目录
    • postinstallbrew update(Taps/caskroom/homebrew-cask获得Taps/homebrew/homebrew-cask结果)下查找所有回购并git在每个回收中去除Travis的剩余物
    • 使用剩余的东西清理Homebrew缓存/usr/local/Homebrew(如果与上一节一起使用,请参阅其他操作) - 否则,您将find -type d -name .git"迁移缓存条目..."阶段遇到大量错误.
  • dirname:

    • 使用git clean -fxd代替-它会自动解决任何可能发生的冲突与本地提交与瓶资讯
  • 重新添加本地瓶子时(如果与前一部分一起使用):

    • 如果瓶子信息已经存在,请不要将瓶子信息重新添加到配方中
    • 如果包装版本已更改且瓶子信息出现在配方中,请将其从配方和brew cleanup结果中删除.没有库存方法,因此您必须使用脚本解析和编辑公式文件,并从brew update表中删除相应的行.使用检索公式文件的路径brew update.
  • 安装时:

  • brew update --merge:

    • git commit如果存在则删除


小智 13

您可以将brew缓存目录添加到travis缓存中:

cache:
  directories:
    - $HOME/Library/Caches/Homebrew
Run Code Online (Sandbox Code Playgroud)

据我所知,travis不支持开箱即用的自制缓存.

  • 这将缓存自制软件资源(下载内容),而不是已完成的构建(二进制文件等)。仍然超级有帮助! (2认同)

Dan*_*ger 5

要缓存实际编译的依赖项,而不是缓存源 tarball 或缓存对象文件,将相应的包Cellaropt目录添加到缓存并使用适当的 before_install 检查似乎工作正常。

您还可以添加所有/usr/local/Cellar//usr/local/opt/,但这会添加所有已安装的自制程序包,而不仅仅是您需要的软件包。

依赖 openssl、libevent 和 check 的项目示例:

cache:
  directories:
    - /usr/local/Cellar/openssl
    - /usr/local/opt/openssl
    - /usr/local/Cellar/libevent
    - /usr/local/opt/libevent
    - /usr/local/Cellar/check
    - /usr/local/opt/check
before_install:
  - test -d /usr/local/opt/openssl/lib  || { rmdir /usr/local/opt/openssl; brew install openssl; }
  - test -d /usr/local/opt/libevent/lib || { rmdir /usr/local/opt/libevent; brew install libevent; }
  - test -d /usr/local/opt/check/lib    || { rmdir /usr/local/opt/check; brew install check; }
Run Code Online (Sandbox Code Playgroud)

rmdir是必需的,因为如果缓存目录不存在,TravisCI 会创建缓存目录,brew install如果是目录则失败/usr/local/opt/$package(与 Cellar 中特定安装版本的符号链接相反)。出于同样的原因,test测试子目录,而不是主包目录。

请注意,这种方法要求您自己的项目能够获取安装在/usr/local/opt.