Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# `tailwindcss-rails` Changelog

## main (unreleased)

### Improved

* Setting the `TAILWINDCSS_SKIP_BUILD` environment variable to a non-blank value skips attaching `tailwindcss:build` to `assets:precompile` (and test prepare). This is useful when the CSS is pre-built/committed, when caching CI or Docker layers, or for cross-architecture Docker builds. @cgmoore120


## v4.6.0 / 2026-06-17

### Fixed
Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ README](https://github.com/rails/tailwindcss-rails/tree/v3-stable?tab=readme-ov-
* [Configuration and commands](#configuration-and-commands)
* [Building for production](#building-for-production)
* [Building for testing](#building-for-testing)
* [Skipping the automatic build](#skipping-the-automatic-build)
* [Building unminified assets](#building-unminified-assets)
* [Live rebuild](#live-rebuild)
* [Using Tailwind plugins](#using-tailwind-plugins)
Expand Down Expand Up @@ -288,6 +289,10 @@ The `tailwindcss:build` is automatically attached to `assets:precompile`, so bef

The `tailwindcss:build` task is automatically attached to the `test:prepare` Rake task. This task runs before test commands. If you run `bin/rails test` in your CI environment, your Tailwind output will be generated before tests run.

### Skipping the automatic build

Setting the `TAILWINDCSS_SKIP_BUILD` environment variable to any non-blank value skips the automatic `tailwindcss:build` that is otherwise attached to `assets:precompile` (and to test prepare). This is useful when the CSS is already built and committed, when you want to cache the build across CI or Docker layers, or for cross-architecture Docker builds where the standalone CLI may not produce correct output. The default behavior is unchanged when the variable is unset or blank.

### Building unminified assets

If you want unminified assets, you can:
Expand Down
18 changes: 10 additions & 8 deletions lib/tasks/build.rake
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,14 @@ namespace :tailwindcss do
end
end

Rake::Task["assets:precompile"].enhance(["tailwindcss:build"])

if Rake::Task.task_defined?("test:prepare")
Rake::Task["test:prepare"].enhance(["tailwindcss:build"])
elsif Rake::Task.task_defined?("spec:prepare")
Rake::Task["spec:prepare"].enhance(["tailwindcss:build"])
elsif Rake::Task.task_defined?("db:test:prepare")
Rake::Task["db:test:prepare"].enhance(["tailwindcss:build"])
unless ENV["TAILWINDCSS_SKIP_BUILD"].present?
Rake::Task["assets:precompile"].enhance(["tailwindcss:build"])

if Rake::Task.task_defined?("test:prepare")
Rake::Task["test:prepare"].enhance(["tailwindcss:build"])
elsif Rake::Task.task_defined?("spec:prepare")
Rake::Task["spec:prepare"].enhance(["tailwindcss:build"])
elsif Rake::Task.task_defined?("db:test:prepare")
Rake::Task["db:test:prepare"].enhance(["tailwindcss:build"])
end
end
54 changes: 54 additions & 0 deletions test/lib/tasks/build_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
require "test_helper"

class BuildRakeTest < ActiveSupport::TestCase
BUILD_RAKE = File.expand_path("../../../../lib/tasks/build.rake", __FILE__)

# Rake tasks are global singletons, so we can't load build.rake into the test
# process and inspect prerequisites without polluting other tests (and we'd
# only ever see one value of the env var per process). Instead we shell out to
# a fresh Ruby process that stubs the tasks build.rake expects to already
# exist, loads build.rake, and prints the resulting prerequisites.
def prerequisites_for(env: {})
script = <<~RUBY
require "bundler/setup"
require "rake"
require "active_support/all"

Rake::Task.define_task("environment")
Rake::Task.define_task("assets:precompile")
Rake::Task.define_task("test:prepare")

load #{BUILD_RAKE.inspect}

puts Rake::Task["assets:precompile"].prerequisites.inspect
puts Rake::Task["test:prepare"].prerequisites.inspect
RUBY

output = IO.popen(env, [Gem.ruby, "-e", script], &:read)
assert $?.success?, "subprocess failed:\n#{output}"

assets_precompile, test_prepare = output.lines.map { |line| eval(line) } # rubocop:disable Security/Eval
{ "assets:precompile" => assets_precompile, "test:prepare" => test_prepare }
end

test "tailwindcss:build is attached to assets:precompile and test:prepare by default" do
prerequisites = prerequisites_for(env: {})

assert_includes prerequisites["assets:precompile"], "tailwindcss:build"
assert_includes prerequisites["test:prepare"], "tailwindcss:build"
end

test "TAILWINDCSS_SKIP_BUILD skips attaching tailwindcss:build" do
prerequisites = prerequisites_for(env: { "TAILWINDCSS_SKIP_BUILD" => "1" })

refute_includes prerequisites["assets:precompile"], "tailwindcss:build"
refute_includes prerequisites["test:prepare"], "tailwindcss:build"
end

test "a blank TAILWINDCSS_SKIP_BUILD does not skip the build" do
prerequisites = prerequisites_for(env: { "TAILWINDCSS_SKIP_BUILD" => "" })

assert_includes prerequisites["assets:precompile"], "tailwindcss:build"
assert_includes prerequisites["test:prepare"], "tailwindcss:build"
end
end
Loading