-
-
Save jnunemaker/7e4b909bce0bb8796d342bed06bd4c3e to your computer and use it in GitHub Desktop.
| #!/bin/sh | |
| #/ Usage: bin/conductor-setup | |
| #/ | |
| #/ Setup files that are not tracked in git for Conductor workspaces. | |
| #/ This is run automatically when a new workspace is created. | |
| set -e | |
| cd $(dirname "$0")/.. | |
| # Symlink .env from the root repo so all workspaces share the same config. | |
| # Set up your .env once at $CONDUCTOR_ROOT_PATH/.env and all workspaces use it. | |
| if [ -n "$CONDUCTOR_ROOT_PATH" ]; then | |
| if [ -f "$CONDUCTOR_ROOT_PATH/.env" ]; then | |
| echo "Symlinking .env from $CONDUCTOR_ROOT_PATH/.env..." | |
| ln -sf "$CONDUCTOR_ROOT_PATH/.env" .env | |
| else | |
| echo "Warning: $CONDUCTOR_ROOT_PATH/.env not found." | |
| echo "Create it from .env.example: cp .env.example $CONDUCTOR_ROOT_PATH/.env" | |
| fi | |
| # Copy database.yml and credential keys from repo root | |
| if [ -f "$CONDUCTOR_ROOT_PATH/config/database.yml" ]; then | |
| echo "Copying database.yml from repo root..." | |
| cp "$CONDUCTOR_ROOT_PATH/config/database.yml" config/database.yml | |
| fi | |
| if [ -f "$CONDUCTOR_ROOT_PATH/config/credentials/development.key" ]; then | |
| echo "Copying development.key from repo root..." | |
| cp "$CONDUCTOR_ROOT_PATH/config/credentials/development.key" config/credentials/development.key | |
| fi | |
| if [ -f "$CONDUCTOR_ROOT_PATH/config/credentials/test.key" ]; then | |
| echo "Copying test.key from repo root..." | |
| cp "$CONDUCTOR_ROOT_PATH/config/credentials/test.key" config/credentials/test.key | |
| fi | |
| # Symlink storage directory for Active Storage | |
| if [ -d "$CONDUCTOR_ROOT_PATH/storage" ]; then | |
| echo "Symlinking storage from $CONDUCTOR_ROOT_PATH/storage..." | |
| ln -sf "$CONDUCTOR_ROOT_PATH/storage" storage | |
| else | |
| echo "Creating storage directory at $CONDUCTOR_ROOT_PATH/storage..." | |
| mkdir -p "$CONDUCTOR_ROOT_PATH/storage" | |
| ln -sf "$CONDUCTOR_ROOT_PATH/storage" storage | |
| fi | |
| # Symlink ngrok.yml from repo root if it exists | |
| if [ -f "$CONDUCTOR_ROOT_PATH/ngrok.yml" ]; then | |
| echo "Symlinking ngrok.yml from $CONDUCTOR_ROOT_PATH/ngrok.yml..." | |
| ln -sf "$CONDUCTOR_ROOT_PATH/ngrok.yml" ngrok.yml | |
| fi | |
| # Symlink .bundle for private gem credentials | |
| if [ -d "$CONDUCTOR_ROOT_PATH/.bundle" ]; then | |
| if [ -e .bundle ] && [ ! -L .bundle ]; then | |
| echo "Error: .bundle exists and is not a symlink. Remove it manually first." | |
| exit 1 | |
| fi | |
| echo "Symlinking .bundle from $CONDUCTOR_ROOT_PATH/.bundle..." | |
| ln -sf "$CONDUCTOR_ROOT_PATH/.bundle" .bundle | |
| fi | |
| else | |
| # Fallback for running outside Conductor | |
| if [ ! -f .env ]; then | |
| echo "Creating .env from .env.example..." | |
| cp .env.example .env | |
| else | |
| echo ".env already exists, skipping..." | |
| fi | |
| fi | |
| # Run full setup (dependencies, database, fixtures) | |
| script/bootstrap | |
| echo "Conductor setup complete!" |
| { | |
| "scripts": { | |
| "setup": "bin/conductor-setup", | |
| "server": "script/server" | |
| } | |
| } |
| canonical_host = ENV["CANONICAL_HOST"] | |
| CANONICAL_HOST = if canonical_host | |
| canonical_host | |
| elsif Rails.env.development? | |
| "localhost:#{ENV.fetch("PORT", 3000)}" | |
| elsif Rails.env.test? | |
| "www.example.com" | |
| else | |
| "#{ENV["HEROKU_APP_NAME"]}.herokuapp.com" | |
| end | |
| scheme = Rails.configuration.force_ssl ? "https" : "http" | |
| APP_URL = "#{scheme}://#{CANONICAL_HOST}" | |
| Rails.application.routes.default_url_options[:host] = CANONICAL_HOST | |
| Rails.application.config.action_mailer.default_url_options = { host: CANONICAL_HOST } | |
| Rails.application.config.asset_host = CANONICAL_HOST | |
| if canonical_host | |
| Rails.application.middleware.use Rack::CanonicalHost, canonical_host | |
| end |
| workers_count = Integer(ENV['WEB_CONCURRENCY'] || 1) | |
| max_threads_count = Integer(ENV['RAILS_MAX_THREADS'] || 2) | |
| min_threads_count = Integer(ENV['RAILS_MIN_THREADS'] || max_threads_count) | |
| threads min_threads_count, max_threads_count | |
| port ENV['PORT'] || 3000 | |
| environment ENV['RACK_ENV'] || ENV['RAILS_ENV'] || 'development' | |
| # FIXME(ezekg) https://www.heroku.com/blog/pumas-routers-keepalives-ohmy/ | |
| enable_keep_alives false | |
| if workers_count > 1 | |
| preload_app! | |
| workers workers_count | |
| before_fork do | |
| if defined?(::ActiveRecord) && defined?(::ActiveRecord::Base) | |
| ApplicationRecord.connection_pool.disconnect! | |
| end | |
| end | |
| on_worker_boot do | |
| if defined?(::ActiveRecord) && defined?(::ActiveRecord::Base) | |
| ApplicationRecord.establish_connection | |
| end | |
| end | |
| end | |
| if ENV['RACK_ENV'] == 'development' || ENV['RAILS_ENV'] == 'development' || (ENV['RACK_ENV'].nil? && ENV['RAILS_ENV'].nil?) | |
| on_booted do | |
| port = ENV['PORT'] || 3000 | |
| url = "http://localhost:#{port}" | |
| puts | |
| puts " ✅ App running at #{url}" | |
| puts | |
| end | |
| end | |
| # Allow puma to be restarted by `rails restart` command. | |
| plugin :tmp_restart |
| #!/bin/sh | |
| #/ Usage: server | |
| #/ | |
| #/ Run all the processes necessary to for the app. | |
| set -e | |
| cd $(dirname "$0")/.. | |
| [ "$1" = "--help" -o "$1" = "-h" -o "$1" = "help" ] && { | |
| grep '^#/' <"$0"| cut -c4- | |
| exit 0 | |
| } | |
| # Use CONDUCTOR_PORT if set, otherwise PORT, defaulting to 3000 | |
| # Set Vite port to PORT + 36 (e.g., 3000 -> 3036) | |
| export PORT=${CONDUCTOR_PORT:-${PORT:-3000}} | |
| export VITE_RUBY_PORT=$((PORT + 36)) | |
| # sqs_worker turned off because we set active job to inline for shoryuken jobs | |
| # worker turned off because we set good job to inline for all other jobs | |
| bundle exec foreman start -p ${PORT} -f Procfile.dev |
| import { defineConfig } from 'vite' | |
| import ViteRails from 'vite-plugin-rails' | |
| import vue from '@vitejs/plugin-vue' | |
| // Default Vite port to PORT + 36 (e.g., Rails on 4000 -> Vite on 4036) | |
| const basePort = parseInt(process.env.PORT || '4000', 10) | |
| const vitePort = parseInt(process.env.VITE_PORT || String(basePort + 36), 10) | |
| export default defineConfig({ | |
| server: { | |
| port: vitePort, | |
| strictPort: true, | |
| }, | |
| plugins: [ | |
| ViteRails(), | |
| vue() | |
| ] | |
| }) |
@jeremysmithco I have .tool-versions either symlinked or checked into git depending on the project and mise/asdf pick it up.
@jnunemaker Ahh, gotcha! The universe seems to be telling me to switch to mise today.
Is the cd $(dirname "$0")/.. there for mise's Hook on cd?
I’m using asdf. Maybe? I just had Claude make it and it’s worked so I didn’t over analyze. Haha
😄 Ok, fair enough! I'm going to switch to mise and see if that solves the issue.
For posterity, I finally got things working and I'm 90% sure the issue was that Conductor is using zsh for Setup and Run scripts, which I hadn’t configured for version management (though for Terminal, it seems to use your default shell, which for me is Bash).
Thanks for sharing @jnunemaker !
It would be nice to be able to choose the shell used to run commands, since I ran into same issue as @jeremysmithco (tho fish+mise). I've submitted it as feedback to the Conductor team.
EDIT: Just providing my own binscript with a fish shebang seems like it will do for now.
@adam12 Ahh, thanks for the info! Glad it wasn't just me. :) Should've thought to submit feedback myself, but glad you did! 👍
@jnunemaker Hey, thanks for this! 🙏
How does your setup know which version of Ruby to run? I use chruby (configured within
.bashrc), but since thesetupandrunscripts aren't run from interactive shells, it doesn't load the proper version and defaults to system Ruby for me.