-
-
Notifications
You must be signed in to change notification settings - Fork 633
fix: use env-var-driven ports in Procfile templates to support multiple worktrees #2539
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
ihabadham
wants to merge
26
commits into
master
Choose a base branch
from
ihabadham/fix/worktree-port-config
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+545
−15
Open
Changes from 24 commits
Commits
Show all changes
26 commits
Select commit
Hold shift + click to select a range
3ebe213
fix: use ${PORT:-3000} in Procfile.dev template to avoid worktree por…
ihabadham 7ce155b
fix: use ${PORT:-N} in Procfile variant templates
ihabadham 5026b83
feat: add .env.example template for per-worktree port configuration
ihabadham e717cb8
feat: copy .env.example during generator install
ihabadham 85abb9c
test: assert env-var ports and .env.example in base generator output
ihabadham 60573e7
docs: document worktree port configuration with .env pattern
ihabadham f84641a
feat: add PortSelector for automatic free port detection
ihabadham bcc9a59
feat: wire PortSelector into ServerManager before process manager starts
ihabadham f98bd7e
docs: update worktree section — auto port detection is now zero-config
ihabadham 71c8bd3
test: fill coverage gaps in PortSelector and procfile_port
ihabadham ad62225
test(generator): assert Procfile.dev-prod-assets uses env-var-driven …
ihabadham fd4806f
docs(generator): clarify PORT default differs between Procfile variants
ihabadham d09b9d8
docs(process-managers): fix stale process names in Procfile.dev snippet
ihabadham 0bc50cd
docs(process-managers): warn direct foreman users about PORT injection
ihabadham 47d1844
fix(server_manager): configure ports before printing the access URL b…
ihabadham d67ace7
refactor(port_selector): remove unused WEBPACK_OFFSET and deduplicate…
ihabadham f4eca17
docs(process-managers): add language tag to fenced code block (MD040)
ihabadham ee004b6
fix(server_manager): rescue NoPortAvailable in configure_ports for cl…
ihabadham 5dd07fd
test(server_manager): restore ENV vars instead of deleting in port co…
ihabadham 446ce06
docs(port_selector): document TOCTOU limitation in port_available?
ihabadham 9ecb4be
fix(generator): add .env to .gitignore so port config is not accident…
ihabadham d120d53
test(server_manager): clear ENV before each example to prevent order-…
ihabadham f06b6ff
fix(port_selector): probe the unset side in single-ENV branches
ihabadham 3305a64
fix(server_manager): pass auto-detected port to print_server_info in …
ihabadham bfec470
fix: probe Rails and webpack ports independently in find_free_pair
ihabadham 5fe353a
fix(server_manager): use procfile_port in run_production_like banner
ihabadham File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
18 changes: 18 additions & 0 deletions
18
react_on_rails/lib/generators/react_on_rails/templates/base/base/.env.example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| # Development environment configuration | ||
| # Copy this file to .env to override default ports. | ||
| # | ||
| # This is especially useful when running multiple git worktrees simultaneously. | ||
| # Each worktree needs its own .env with different ports to avoid conflicts. | ||
| # | ||
| # Shakapacker reads SHAKAPACKER_DEV_SERVER_PORT on both the Ruby (proxy) and | ||
| # JS (webpack-dev-server) sides, so no shakapacker.yml changes are needed. | ||
| # | ||
| # Example for a second worktree: | ||
| # PORT=3001 | ||
| # SHAKAPACKER_DEV_SERVER_PORT=3036 | ||
|
|
||
| # Rails server port (default: 3000 for Procfile.dev / 3001 for Procfile.dev-prod-assets) | ||
| # PORT=3000 | ||
ihabadham marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| # Webpack dev server port (default: 3035, used by shakapacker) | ||
| # SHAKAPACKER_DEV_SERVER_PORT=3035 | ||
6 changes: 5 additions & 1 deletion
6
react_on_rails/lib/generators/react_on_rails/templates/base/base/Procfile.dev
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,9 @@ | ||
| # Procfile for development | ||
| # You can run these commands in separate shells | ||
| rails: bundle exec rails s -p 3000 | ||
| # | ||
| # To run multiple worktrees simultaneously, set different ports in each worktree's .env: | ||
| # PORT=3001 | ||
| # SHAKAPACKER_DEV_SERVER_PORT=3036 | ||
| rails: bundle exec rails s -p ${PORT:-3000} | ||
ihabadham marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| dev-server: bin/shakapacker-dev-server | ||
| server-bundle: SERVER_BUNDLE_ONLY=yes bin/shakapacker --watch | ||
ihabadham marked this conversation as resolved.
Show resolved
Hide resolved
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
react_on_rails/lib/generators/react_on_rails/templates/base/base/Procfile.dev-static-assets
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,2 @@ | ||
| web: bin/rails server -p 3000 | ||
| web: bin/rails server -p ${PORT:-3000} | ||
| js: bin/shakapacker --watch |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,93 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| require "socket" | ||
|
|
||
| module ReactOnRails | ||
| module Dev | ||
| class PortSelector | ||
| DEFAULT_RAILS_PORT = 3000 | ||
| DEFAULT_WEBPACK_PORT = 3035 | ||
| MAX_ATTEMPTS = 100 | ||
|
|
||
| class NoPortAvailable < StandardError; end | ||
|
|
||
| class << self | ||
| # Returns { rails: Integer, webpack: Integer }. | ||
ihabadham marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| # Respects existing ENV['PORT'] / ENV['SHAKAPACKER_DEV_SERVER_PORT']. | ||
| # Only probes when both are unset (i.e. user hasn't configured them). | ||
| def select_ports | ||
| rails_port = explicit_rails_port | ||
| webpack_port = explicit_webpack_port | ||
|
|
||
| # If both are explicitly set, trust the user completely | ||
| return { rails: rails_port, webpack: webpack_port } if rails_port && webpack_port | ||
|
|
||
| # If only one is set, anchor it and probe for a free port on the other side | ||
| if rails_port | ||
| return { rails: rails_port, | ||
| webpack: find_available_port(DEFAULT_WEBPACK_PORT, exclude: rails_port) } | ||
| end | ||
|
|
||
| if webpack_port | ||
| return { rails: find_available_port(DEFAULT_RAILS_PORT, exclude: webpack_port), | ||
| webpack: webpack_port } | ||
| end | ||
|
|
||
| # Neither set — auto-detect a free pair | ||
| find_free_pair | ||
| end | ||
|
|
||
| # Public so it can be stubbed in tests. | ||
| # NOTE: Inherent TOCTOU race — another process can claim the port between | ||
| # server.close and the caller binding to it. This is unavoidable with the | ||
| # probe-then-use pattern and acceptable for the worktree port-selection use case. | ||
| def port_available?(port, host = "127.0.0.1") | ||
| server = TCPServer.new(host, port) | ||
| server.close | ||
| true | ||
ihabadham marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| rescue Errno::EADDRINUSE, Errno::EACCES | ||
| false | ||
| end | ||
|
|
||
| private | ||
|
|
||
| def explicit_rails_port | ||
| ENV["PORT"]&.to_i&.then { |p| p.between?(1, 65_535) ? p : nil } | ||
ihabadham marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| end | ||
|
|
||
| def explicit_webpack_port | ||
| ENV["SHAKAPACKER_DEV_SERVER_PORT"]&.to_i&.then { |p| p.between?(1, 65_535) ? p : nil } | ||
| end | ||
|
|
||
| def find_available_port(start_port, exclude:) | ||
| MAX_ATTEMPTS.times do |i| | ||
| port = start_port + i | ||
| next if port == exclude | ||
|
|
||
| return port if port_available?(port) | ||
| end | ||
|
|
||
| raise NoPortAvailable, "No available port found starting at #{start_port}." | ||
| end | ||
|
|
||
| def find_free_pair | ||
ihabadham marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| MAX_ATTEMPTS.times do |i| | ||
| rails_port = DEFAULT_RAILS_PORT + i | ||
| webpack_port = DEFAULT_WEBPACK_PORT + i | ||
|
|
||
| next unless port_available?(rails_port) && port_available?(webpack_port) | ||
|
|
||
| puts "Default ports in use. Using Rails :#{rails_port}, webpack :#{webpack_port}" if i.positive? | ||
ihabadham marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| return { rails: rails_port, webpack: webpack_port } | ||
| end | ||
|
|
||
| raise NoPortAvailable, | ||
| "No available port pair found in range " \ | ||
| "#{DEFAULT_RAILS_PORT}--#{DEFAULT_RAILS_PORT + MAX_ATTEMPTS - 1}. " \ | ||
| "Run 'bin/dev kill' to free up ports." | ||
| end | ||
| end | ||
| end | ||
| end | ||
| end | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.