Skip to content

Commit 13ae3d8

Browse files
authored
GOATS-724: Add --ci flag for installing GOATS. (#323)
* GOATS-724: Add --ci flag for installing GOATS. * Add towncrier entry.
1 parent 4b8ec02 commit 13ae3d8

3 files changed

Lines changed: 50 additions & 6 deletions

File tree

docs/changes/323.new.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Added `--ci` flag to allow installing GOATS bypassing the user prompts for a CI pipeline.

src/goats_cli/cli.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,16 @@ def cli(ctx):
7878
),
7979
callback=validate_addrport,
8080
)
81+
@click.option(
82+
"--ci", is_flag=True, help="Run install in non-interactive CI mode (no prompts)."
83+
)
8184
def install(
8285
project_name: str,
8386
directory: Path,
8487
overwrite: bool,
8588
media_dir: Path | None,
8689
redis_addrport: str,
90+
ci: bool,
8791
) -> None:
8892
"""Installs GOATS with a specified or default name in a specified or
8993
default directory and configures Redis server.
@@ -101,6 +105,8 @@ def install(
101105
The path to save media files.
102106
redis_addrport : `str`
103107
The host and port Redis is served on.
108+
ci : `bool`
109+
Run install in non-interactive CI mode (no prompts).
104110
105111
Raises
106112
------
@@ -159,6 +165,9 @@ def install(
159165
)
160166
goats_setup_command.extend(["--media-dir", f"{resolved_media_dir}"])
161167

168+
if ci:
169+
goats_setup_command.append("--ci")
170+
162171
subprocess.run(goats_setup_command, check=True)
163172

164173
# Migrate the webpage.

src/goats_setup/management/commands/goats_setup.py

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""Django command to install GOATS."""
22

3+
import os
34
import re
45
import sys
56
from pathlib import Path
@@ -14,7 +15,7 @@
1415
from packaging import version
1516
from tom_setup.management.commands.tom_setup import Command as TOMCommand
1617

17-
PYTHON_VERSION: str = "3.10"
18+
PYTHON_VERSION: str = "3.12"
1819
REDIS_HOST: str = "localhost"
1920
REDIS_PORT: int = 6379
2021
REDIS_ADDRPORT: str = f"{REDIS_HOST}:{REDIS_PORT}"
@@ -29,8 +30,12 @@ class Command(TOMCommand):
2930

3031
help = "🐐 GOATS setup wizard."
3132

32-
def welcome_banner(self) -> None:
33+
def welcome_banner(self, ci: bool = False) -> None:
3334
"""Displays a welcome banner."""
35+
if ci:
36+
self.stdout.write("🐐 Running GOATS for CI, skipping prompts.")
37+
return
38+
3439
welcome_text = (
3540
"🐐 Welcome to the GOATS setup wizard. This will assist you with your "
3641
"new GOATS project.\n"
@@ -82,6 +87,13 @@ def add_arguments(self, parser):
8287
"Providing only a port number (e.g., '6379') binds to localhost."
8388
),
8489
)
90+
# Argument to be used for CI.
91+
parser.add_argument(
92+
"--ci",
93+
action="store_true",
94+
default=False,
95+
help="Run install in non-interactive CI mode (no prompts).",
96+
)
8597

8698
def check_python(self) -> None:
8799
"""Checks the Python version, exits if not compatible."""
@@ -137,10 +149,11 @@ def generate_secret_key(self) -> None:
137149

138150
def handle(self, *args, **options) -> None:
139151
"""Handles the setup process."""
152+
ci = options.get("ci", False)
140153
self.context["CREATE_DATE"] = timezone.now()
141154
self.context["PROJECT_NAME"] = settings.BASE_DIR.name
142155
self.context["HINTS_ENABLED"] = False
143-
self.welcome_banner()
156+
self.welcome_banner(ci=ci)
144157
self.stdout.write(self.style.MIGRATE_HEADING("Initial setup:"))
145158
self.check_python()
146159
self.setup_redis(redis_addrport=options.get("redis_addrport"))
@@ -153,7 +166,7 @@ def handle(self, *args, **options) -> None:
153166
self.generate_file("urls")
154167
self.generate_file("asgi")
155168
self.run_migrations()
156-
self.create_pi()
169+
self.create_pi(ci=ci)
157170
self.create_public_group()
158171
self.complete()
159172

@@ -214,14 +227,35 @@ def get_target_type(self) -> None:
214227
"""Gets the target type for the project."""
215228
self.context["TARGET_TYPE"] = "SIDEREAL"
216229

217-
def create_pi(self) -> None:
230+
def create_pi(self, ci: bool = False) -> None:
218231
"""Creates a Principal Investigator (PI) superuser."""
219232
self.stdout.write(
220233
self.style.MIGRATE_HEADING(
221234
"Principal Investigator (PI) and public user creation:",
222235
)
223236
)
224-
call_command("createsuperuser", verbosity=0)
237+
if ci:
238+
password = os.environ.get("DJANGO_SUPERUSER_PASSWORD")
239+
if not password:
240+
self.stdout.write(
241+
self.style.WARNING(
242+
"🐐 DJANGO_SUPERUSER_PASSWORD is not set; the superuser will "
243+
"not be able to log in until a password is manually set."
244+
)
245+
)
246+
247+
call_command(
248+
"createsuperuser",
249+
verbosity=0,
250+
username="goats",
251+
email="goats@goats.com",
252+
interactive=False,
253+
)
254+
else:
255+
call_command(
256+
"createsuperuser",
257+
verbosity=0,
258+
)
225259
self.status(" PI Superuser created... ")
226260
self.ok()
227261

0 commit comments

Comments
 (0)