|
1 | 1 | import subprocess |
2 | 2 | import os |
| 3 | +import platform |
3 | 4 | from dotenv import load_dotenv |
4 | 5 |
|
5 | 6 | class CloudDeployer: |
@@ -116,20 +117,66 @@ def run_commands(self): |
116 | 117 | self.create_api_file() |
117 | 118 | self.create_dockerfile() |
118 | 119 | """Runs a sequence of shell commands for deployment, continues on error.""" |
| 120 | + |
| 121 | + # Get project ID upfront for Windows compatibility |
| 122 | + try: |
| 123 | + result = subprocess.run(['gcloud', 'config', 'get-value', 'project'], |
| 124 | + capture_output=True, text=True, check=True) |
| 125 | + project_id = result.stdout.strip() |
| 126 | + except subprocess.CalledProcessError: |
| 127 | + print("ERROR: Failed to get GCP project ID. Ensure gcloud is configured.") |
| 128 | + return |
| 129 | + |
| 130 | + # Get environment variables |
| 131 | + openai_model = os.environ.get('OPENAI_MODEL_NAME', 'gpt-4o') |
| 132 | + openai_key = os.environ.get('OPENAI_API_KEY', 'Enter your API key') |
| 133 | + openai_base = os.environ.get('OPENAI_API_BASE', 'https://api.openai.com/v1') |
| 134 | + |
| 135 | + # Build commands with actual values |
119 | 136 | commands = [ |
120 | | - "yes | gcloud auth configure-docker us-central1-docker.pkg.dev", |
121 | | - "gcloud artifacts repositories create praisonai-repository --repository-format=docker --location=us-central1", |
122 | | - "docker build --platform linux/amd64 -t gcr.io/$(gcloud config get-value project)/praisonai-app:latest .", |
123 | | - "docker tag gcr.io/$(gcloud config get-value project)/praisonai-app:latest us-central1-docker.pkg.dev/$(gcloud config get-value project)/praisonai-repository/praisonai-app:latest", |
124 | | - "docker push us-central1-docker.pkg.dev/$(gcloud config get-value project)/praisonai-repository/praisonai-app:latest", |
125 | | - "gcloud run deploy praisonai-service --image us-central1-docker.pkg.dev/$(gcloud config get-value project)/praisonai-repository/praisonai-app:latest --platform managed --region us-central1 --allow-unauthenticated --set-env-vars OPENAI_MODEL_NAME=${OPENAI_MODEL_NAME},OPENAI_API_KEY=${OPENAI_API_KEY},OPENAI_API_BASE=${OPENAI_API_BASE}" |
| 137 | + ['gcloud', 'auth', 'configure-docker', 'us-central1-docker.pkg.dev'], |
| 138 | + ['gcloud', 'artifacts', 'repositories', 'create', 'praisonai-repository', |
| 139 | + '--repository-format=docker', '--location=us-central1'], |
| 140 | + ['docker', 'build', '--platform', 'linux/amd64', '-t', |
| 141 | + f'gcr.io/{project_id}/praisonai-app:latest', '.'], |
| 142 | + ['docker', 'tag', f'gcr.io/{project_id}/praisonai-app:latest', |
| 143 | + f'us-central1-docker.pkg.dev/{project_id}/praisonai-repository/praisonai-app:latest'], |
| 144 | + ['docker', 'push', |
| 145 | + f'us-central1-docker.pkg.dev/{project_id}/praisonai-repository/praisonai-app:latest'], |
| 146 | + ['gcloud', 'run', 'deploy', 'praisonai-service', |
| 147 | + '--image', f'us-central1-docker.pkg.dev/{project_id}/praisonai-repository/praisonai-app:latest', |
| 148 | + '--platform', 'managed', '--region', 'us-central1', '--allow-unauthenticated', |
| 149 | + '--set-env-vars', f'OPENAI_MODEL_NAME={openai_model},OPENAI_API_KEY={openai_key},OPENAI_API_BASE={openai_base}'] |
126 | 150 | ] |
127 | | - |
128 | | - for cmd in commands: |
| 151 | + |
| 152 | + # Run commands with appropriate handling for each platform |
| 153 | + for i, cmd in enumerate(commands): |
129 | 154 | try: |
130 | | - subprocess.run(cmd, shell=True, check=True) |
| 155 | + if i == 0: # First command (gcloud auth configure-docker) |
| 156 | + if platform.system() != 'Windows': |
| 157 | + # On Unix, pipe 'yes' to auto-confirm |
| 158 | + proc = subprocess.Popen(cmd, stdin=subprocess.PIPE) |
| 159 | + proc.communicate(input=b'Y\n') |
| 160 | + if proc.returncode != 0: |
| 161 | + raise subprocess.CalledProcessError(proc.returncode, cmd) |
| 162 | + else: |
| 163 | + # On Windows, try with --quiet flag to avoid prompts |
| 164 | + cmd_with_quiet = cmd + ['--quiet'] |
| 165 | + try: |
| 166 | + subprocess.run(cmd_with_quiet, check=True) |
| 167 | + except subprocess.CalledProcessError: |
| 168 | + # If --quiet fails, try without it |
| 169 | + print("Note: You may need to manually confirm the authentication prompt") |
| 170 | + subprocess.run(cmd, check=True) |
| 171 | + else: |
| 172 | + # Run other commands normally |
| 173 | + subprocess.run(cmd, check=True) |
131 | 174 | except subprocess.CalledProcessError as e: |
132 | | - print(f"ERROR: Command '{e.cmd}' failed with exit status {e.returncode}") |
| 175 | + print(f"ERROR: Command failed with exit status {e.returncode}") |
| 176 | + # Commands 2 (build) and 4 (push) and 5 (deploy) are critical |
| 177 | + if i in [2, 4, 5]: |
| 178 | + print("Critical command failed. Aborting deployment.") |
| 179 | + return |
133 | 180 | print(f"Continuing with the next command...") |
134 | 181 |
|
135 | 182 | # Usage |
|
0 commit comments