Rails 本地 asset:precompile - 是否有自动检查更改的方法?

Rails local asset:precompile - is there an automated way to check for changes?

我 运行 遇到部署期间资产预编译的问题,所以我选择进行本地预编译并将生成的文件签入我的源代码树。我对这种方法没有任何问题, 除了 有时我忘记 运行 预编译任务并在没有预编译资产的情况下发布! :(

我想知道是否有人遇到过某种方法来检查是否发生了任何资产变化?理想情况下,我想 运行 在我的 CI 服务器上进行某种检查,如果有未提交的资产更改,则构建失败。

我有几个想法:

  1. 运行 RAILS_ENV=production bundle exec rake assets:precompile 在 CI 服务器上查看是否有任何输出。 (如果资产是最新的,该命令似乎不会输出任何内容。)但是,该命令的输出似乎以某种方式与其 运行 所在的环境相关联,因为在 运行ning 之后在本地命令,提交结果,然后在 CI 服务器上 运行ning 命令,命令仍然有输出!我想知道为什么这与环境有关,但我什至无法在 rails git 集线器回购中找到 rake assets:precompile 的来源。有谁知道它的来源在哪里?

  2. 以某种方式编写一个命令,可以查看 git 历史记录并确定自上次预编译以来我的 assets/ 文件夹中是否有任何资产发生变化。不太确定这将如何工作...

这让我困扰了不止几次,有时当同事提交资产更改时我没有捕捉到它 - 而且这似乎真的是计算机应该能够为人类捕捉到的东西。我想第三种比较合理的选择是让 CI 服务器简单地 运行 命令,并自动将生成的文件提交到源代码树,但我不喜欢我的 CI 服务器提交。

有什么想法吗?谢谢。

我正在经历同样的努力,但我还没能解决这个问题。第一步是使用 git 预提交挂钩来编译资产(只有在资产被修改时才会做一些事情)。

http://jimneath.org/2012/05/05/precompile-assets-using-a-git-hook.html

编辑:看起来 link 被炸了,这是存档版本:https://web.archive.org/web/20161022195654/http://jimneath.org/2012/05/05/precompile-assets-using-a-git-hook.html

我的答案是基于 Git,OP 的想法 2 的实现:我们可以根据 Git 的元数据告诉我们 assets/ 源更新,我们可以使构建失败吗比当前签到的assets-precompile/。根据结帐环境中的条件或对 Rails 构建的一些了解,可能会改进答案。

  1. git log -1 --format=%ct -- assets/ 将为您提供最新源代码提交的时间戳。
  2. git log -1 --format=%ct -- assets-precompile/ 将为您提供最近一次预编译签入的时间戳。

在构建早期添加一个条件来比较这两个数字,如果 1>=2,则任何发布构建都失败。实际上,您可能希望在那里构建一个宽限期,以防有人在您签出和 运行 预编译以及提交时滑入并提交。

或者,为了更加严格,您可以将 {{assets/}} 的提交哈希存储在一个文件中,如果它发生变化并且与上次预编译时的不同,再次失败发布构建,直到再次预编译并签入:

git log --format=%H -- assets/

... 并将其与您使用预提交更新的提交哈希进行比较。您也可以使用 %T 作为树哈希而不是提交哈希,这可能会简化分支。

您可以在 sprockets-rails. The reason why you're not seeing any changes locally may be due to fingerprinting, which is enabled by default in production and disabled in the other environments (as debugging with fingerprints can be a hassle). You can enable it using config.assets.digest as described in the assets guide

中找到 precompile 任务的源代码

如您所述,很容易忘记预编译步骤。一个优雅的自动化是从你的 repo 中删除已编译的资产,并添加一个 capistrano(或 CI)任务来为每个部署预编译资产。预编译最好发生在 CI 服务器上(而不是 运行 它发生在每个生产服务器上)。这种方法还减少了继续扫描已编译资产以进行更改的需要(您实际上不必关心)。

自动将任何内容提交到您的存储库是一个坏主意 - 除了无意的提交之外,您最终会弄乱您的提交历史。

这里有一个Bash脚本,如果(app|lib|vendor)/assets中的master有任何变化,可以作为本地预编译资产的基础。如果存在更改,资产将在本地预编译,您将 rsync 使用您的生产服务器。它基于这样的前提,即每次提交到生产分支时都会有一个部署。基于 Michael Trojanek 撰写的加速部署的文章 5 steps to cut your deploy time in half

它假定使用 rvm gemsets。

#!/bin/sh
cd /Users/my_user/Rails_Projects/myrailsapp
branch="master"
git checkout "$branch" &> /dev/null
curbranch=`git branch | grep \* | cut -d ' ' -f2`
if [ "$curbranch" == "$branch" ]; then
  echo "You are on the $curbranch branch"
  changes=`git diff --name-only HEAD~ HEAD | grep -E "(app|lib|vendor)/assets"`
  if [ -z "$changes" ]; then
    echo "No assets need to be precompiled"
  else
    echo "Here are files that have changes:  $changes"
    echo "Beginning precompile of Rails assets..."
    source /Users/my_user/.rvm/environments/ruby-2.4.1@Rails-4.2.8
    bundle exec rake assets:precompile RAILS_ENV=production
  fi
else
  echo "Unable to checkout "$branch" branch"
fi