Class: Clacky::DeployTools::CreateDatabaseService

Inherits:
Object
  • Object
show all
Defined in:
lib/clacky/default_skills/deploy/tools/create_database_service.rb

Overview

Create a PostgreSQL database service on Railway and wait for it to be ready.

This tool handles the known Railway CLI bug where ‘railway add` returns an error exit code when using project tokens, but actually succeeds in creating the service.

Strategy:

  1. Capture existing service IDs before creation

  2. Execute ‘railway add –database postgres` (ignore exit code)

  3. Poll for new service ID (max 15 seconds)

  4. Wait for DATABASE_URL to be available on the new service (max 2 minutes)

Examples:

result = CreateDatabaseService.execute(
  platform_token: "railway-token-here"
)
if result[:success]
  puts "Database created: #{result[:service_name]}"
  puts "DATABASE_URL: #{result[:database_url]}"
end

Constant Summary collapse

DETECTION_TIMEOUT =

Maximum time to wait for new service to appear after creation command

15
DETECTION_INTERVAL =

seconds

3
PROVISION_TIMEOUT =

Maximum time to wait for DATABASE_URL to be available

120
PROVISION_INTERVAL =

seconds (2 minutes)

5

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(platform_token) ⇒ CreateDatabaseService

Returns a new instance of CreateDatabaseService.



52
53
54
55
# File 'lib/clacky/default_skills/deploy/tools/create_database_service.rb', line 52

def initialize(platform_token)
  @platform_token = platform_token
  @env = { "RAILWAY_TOKEN" => platform_token }
end

Class Method Details

.execute(platform_token:) ⇒ Hash

Execute database creation

}

Parameters:

  • platform_token (String)

    RAILWAY_TOKEN for authentication

Returns:

  • (Hash)

    { success: Boolean, service_id: String (if success), service_name: String (if success), database_url: String (if success), error: String (if failed)



48
49
50
# File 'lib/clacky/default_skills/deploy/tools/create_database_service.rb', line 48

def self.execute(platform_token:)
  new(platform_token).execute
end

Instance Method Details

#executeObject



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/clacky/default_skills/deploy/tools/create_database_service.rb', line 57

def execute
  # Step 0: Check if database already exists
  existing_db = find_existing_database
  
  if existing_db
    puts "  ✅ Database already exists: #{existing_db[:name]}"
    
    # Return without DATABASE_URL - Railway automatically shares it across services
    return {
      success: true,
      service_id: existing_db[:id],
      service_name: existing_db[:name],
      database_url: nil,  # Don't fetch - Railway auto-injects
      status: "existing"
    }
  end
  
  # No database exists - create new one
  puts "  📦 Creating new PostgreSQL database..."
  
  # Step 1: Get existing service IDs
  existing_service_ids = fetch_service_ids
  
  unless existing_service_ids
    return { success: false, error: "Failed to fetch existing services" }
  end
  
  # Step 2: Execute create command (ignore exit code due to known bug)
  execute_create_command
  
  # Step 3: Detect new service
  new_service = detect_new_service(existing_service_ids)
  
  unless new_service
    return { success: false, error: "Database service not detected after #{DETECTION_TIMEOUT}s" }
  end
  
  # Step 4: Wait for DATABASE_URL
  database_url = wait_for_database_url(new_service[:name])
  
  unless database_url
    return {
      success: false,
      error: "DATABASE_URL not available after #{PROVISION_TIMEOUT}s for service #{new_service[:name]}"
    }
  end
  
  {
    success: true,
    service_id: new_service[:id],
    service_name: new_service[:name],
    database_url: database_url,
    status: "created"
  }
  
rescue => e
  {
    success: false,
    error: "Unexpected error: #{e.message}"
  }
end