sum-cli 3.0.0__tar.gz → 3.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. sum_cli-3.1.0/PKG-INFO +230 -0
  2. sum_cli-3.1.0/README.md +202 -0
  3. {sum_cli-3.0.0 → sum_cli-3.1.0}/pyproject.toml +1 -1
  4. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/cli.py +3 -3
  5. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/commands/__init__.py +2 -2
  6. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/commands/init.py +97 -15
  7. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/commands/promote.py +29 -10
  8. sum_cli-3.1.0/sum/commands/setup.py +143 -0
  9. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/setup/git_ops.py +69 -50
  10. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/setup/orchestrator.py +2 -2
  11. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/setup/scaffold.py +9 -12
  12. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/setup/site_orchestrator.py +29 -4
  13. sum_cli-3.1.0/sum/site_config.py +129 -0
  14. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/system_config.py +0 -37
  15. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/utils/environment.py +2 -2
  16. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/utils/validation.py +2 -2
  17. sum_cli-3.1.0/sum_cli.egg-info/PKG-INFO +230 -0
  18. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum_cli.egg-info/SOURCES.txt +4 -3
  19. {sum_cli-3.0.0 → sum_cli-3.1.0}/tests/test_cli_entrypoint.py +2 -2
  20. {sum_cli-3.0.0 → sum_cli-3.1.0}/tests/test_command_config_errors.py +117 -0
  21. sum_cli-3.1.0/tests/test_git_ops.py +179 -0
  22. {sum_cli-3.0.0 → sum_cli-3.1.0}/tests/test_init.py +72 -27
  23. sum_cli-3.1.0/tests/test_setup.py +218 -0
  24. sum_cli-3.1.0/tests/test_site_config.py +345 -0
  25. {sum_cli-3.0.0 → sum_cli-3.1.0}/tests/test_system_config.py +8 -27
  26. sum_cli-3.0.0/PKG-INFO +0 -127
  27. sum_cli-3.0.0/README.md +0 -99
  28. sum_cli-3.0.0/sum/commands/run.py +0 -96
  29. sum_cli-3.0.0/sum/docs/USER_GUIDE.md +0 -663
  30. sum_cli-3.0.0/sum_cli.egg-info/PKG-INFO +0 -127
  31. sum_cli-3.0.0/tests/test_git_ops.py +0 -219
  32. sum_cli-3.0.0/tests/test_run.py +0 -91
  33. {sum_cli-3.0.0 → sum_cli-3.1.0}/LICENSE +0 -0
  34. {sum_cli-3.0.0 → sum_cli-3.1.0}/MANIFEST.in +0 -0
  35. {sum_cli-3.0.0 → sum_cli-3.1.0}/setup.cfg +0 -0
  36. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/__init__.py +0 -0
  37. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/boilerplate/.env.example +0 -0
  38. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/boilerplate/.gitea/workflows/ci.yml +0 -0
  39. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/boilerplate/.gitea/workflows/deploy-production.yml +0 -0
  40. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/boilerplate/.gitea/workflows/deploy-staging.yml +0 -0
  41. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/boilerplate/.github/workflows/ci.yml +0 -0
  42. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/boilerplate/.github/workflows/deploy-production.yml +0 -0
  43. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/boilerplate/.github/workflows/deploy-staging.yml +0 -0
  44. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/boilerplate/.gitignore +0 -0
  45. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/boilerplate/README.md +0 -0
  46. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/boilerplate/manage.py +0 -0
  47. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/boilerplate/project_name/__init__.py +0 -0
  48. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/boilerplate/project_name/home/__init__.py +0 -0
  49. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/boilerplate/project_name/home/apps.py +0 -0
  50. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/boilerplate/project_name/home/management/__init__.py +0 -0
  51. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/boilerplate/project_name/home/management/commands/__init__.py +0 -0
  52. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/boilerplate/project_name/home/management/commands/populate_demo_content.py +0 -0
  53. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/boilerplate/project_name/home/management/commands/seed.py +0 -0
  54. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/boilerplate/project_name/home/management/commands/seed_showroom.py +0 -0
  55. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/boilerplate/project_name/home/migrations/__init__.py +0 -0
  56. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/boilerplate/project_name/home/models.py +0 -0
  57. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/boilerplate/project_name/settings/__init__.py +0 -0
  58. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/boilerplate/project_name/settings/base.py +0 -0
  59. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/boilerplate/project_name/settings/local.py +0 -0
  60. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/boilerplate/project_name/settings/production.py +0 -0
  61. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/boilerplate/project_name/urls.py +0 -0
  62. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/boilerplate/project_name/wsgi.py +0 -0
  63. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/boilerplate/pytest.ini +0 -0
  64. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/boilerplate/requirements.txt +0 -0
  65. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/boilerplate/static/client/.gitkeep +0 -0
  66. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/boilerplate/templates/overrides/.gitkeep +0 -0
  67. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/boilerplate/tests/__init__.py +0 -0
  68. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/boilerplate/tests/test_health.py +0 -0
  69. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/commands/backup.py +0 -0
  70. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/commands/check.py +0 -0
  71. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/commands/themes.py +0 -0
  72. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/commands/update.py +0 -0
  73. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/config.py +0 -0
  74. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/exceptions.py +0 -0
  75. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/setup/__init__.py +0 -0
  76. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/setup/auth.py +0 -0
  77. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/setup/database.py +0 -0
  78. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/setup/deps.py +0 -0
  79. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/setup/infrastructure.py +0 -0
  80. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/setup/remote_themes.py +0 -0
  81. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/setup/seed.py +0 -0
  82. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/setup/venv.py +0 -0
  83. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/themes_registry.py +0 -0
  84. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/utils/__init__.py +0 -0
  85. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/utils/django.py +0 -0
  86. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/utils/output.py +0 -0
  87. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/utils/project.py +0 -0
  88. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum/utils/prompts.py +0 -0
  89. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum_cli.egg-info/dependency_links.txt +0 -0
  90. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum_cli.egg-info/entry_points.txt +0 -0
  91. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum_cli.egg-info/requires.txt +0 -0
  92. {sum_cli-3.0.0 → sum_cli-3.1.0}/sum_cli.egg-info/top_level.txt +0 -0
  93. {sum_cli-3.0.0 → sum_cli-3.1.0}/tests/test_auth.py +0 -0
  94. {sum_cli-3.0.0 → sum_cli-3.1.0}/tests/test_check.py +0 -0
  95. {sum_cli-3.0.0 → sum_cli-3.1.0}/tests/test_cli_init_and_check.py +0 -0
  96. {sum_cli-3.0.0 → sum_cli-3.1.0}/tests/test_cli_safety.py +0 -0
  97. {sum_cli-3.0.0 → sum_cli-3.1.0}/tests/test_config.py +0 -0
  98. {sum_cli-3.0.0 → sum_cli-3.1.0}/tests/test_database.py +0 -0
  99. {sum_cli-3.0.0 → sum_cli-3.1.0}/tests/test_deps.py +0 -0
  100. {sum_cli-3.0.0 → sum_cli-3.1.0}/tests/test_django.py +0 -0
  101. {sum_cli-3.0.0 → sum_cli-3.1.0}/tests/test_e2e_production.py +0 -0
  102. {sum_cli-3.0.0 → sum_cli-3.1.0}/tests/test_environment.py +0 -0
  103. {sum_cli-3.0.0 → sum_cli-3.1.0}/tests/test_exceptions.py +0 -0
  104. {sum_cli-3.0.0 → sum_cli-3.1.0}/tests/test_orchestrator.py +0 -0
  105. {sum_cli-3.0.0 → sum_cli-3.1.0}/tests/test_orchestrator_seed_site.py +0 -0
  106. {sum_cli-3.0.0 → sum_cli-3.1.0}/tests/test_output.py +0 -0
  107. {sum_cli-3.0.0 → sum_cli-3.1.0}/tests/test_prompts.py +0 -0
  108. {sum_cli-3.0.0 → sum_cli-3.1.0}/tests/test_remote_themes.py +0 -0
  109. {sum_cli-3.0.0 → sum_cli-3.1.0}/tests/test_scaffold.py +0 -0
  110. {sum_cli-3.0.0 → sum_cli-3.1.0}/tests/test_seed.py +0 -0
  111. {sum_cli-3.0.0 → sum_cli-3.1.0}/tests/test_theme_init.py +0 -0
  112. {sum_cli-3.0.0 → sum_cli-3.1.0}/tests/test_themes_command.py +0 -0
  113. {sum_cli-3.0.0 → sum_cli-3.1.0}/tests/test_validation.py +0 -0
  114. {sum_cli-3.0.0 → sum_cli-3.1.0}/tests/test_venv.py +0 -0
sum_cli-3.1.0/PKG-INFO ADDED
@@ -0,0 +1,230 @@
1
+ Metadata-Version: 2.4
2
+ Name: sum-cli
3
+ Version: 3.1.0
4
+ Summary: SUM Platform CLI: single control plane for site lifecycle management
5
+ Author: Mark Ashton
6
+ License-Expression: BSD-3-Clause
7
+ Project-URL: Homepage, https://github.com/markashton480/sum-platform
8
+ Project-URL: Repository, https://github.com/markashton480/sum-platform
9
+ Project-URL: Issues, https://github.com/markashton480/sum-platform/issues
10
+ Project-URL: Documentation, https://github.com/markashton480/sum-platform/tree/main/docs/dev/cli.md
11
+ Keywords: sum,cli,django,wagtail
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3 :: Only
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: Software Development :: Build Tools
19
+ Classifier: Topic :: Software Development :: Code Generators
20
+ Requires-Python: >=3.12
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: click>=8.1.7
24
+ Requires-Dist: pyyaml>=6.0
25
+ Provides-Extra: gitea
26
+ Requires-Dist: httpx>=0.27.0; extra == "gitea"
27
+ Dynamic: license-file
28
+
29
+ # SUM CLI (v3.1)
30
+
31
+ [![PyPI](https://img.shields.io/pypi/v/sum-cli.svg)](https://pypi.org/project/sum-cli/)
32
+
33
+ The SUM CLI is the single control plane for deploying and managing SUM Platform client sites on staging and production servers.
34
+
35
+ ## Install
36
+
37
+ ```bash
38
+ pip install sum-cli
39
+ sum-platform --version
40
+ ```
41
+
42
+ ### With Gitea Support
43
+
44
+ If using Gitea instead of GitHub for repository hosting:
45
+
46
+ ```bash
47
+ pip install sum-cli[gitea]
48
+ ```
49
+
50
+ ## Initial Setup
51
+
52
+ Before using the CLI, configure your infrastructure settings:
53
+
54
+ ```bash
55
+ sudo sum-platform setup
56
+ ```
57
+
58
+ This interactive command creates `/etc/sum/config.yml` with your staging/production server settings.
59
+
60
+ ## Commands
61
+
62
+ | Command | Description | Requires Sudo |
63
+ |---------|-------------|---------------|
64
+ | `setup` | Configure infrastructure settings | Yes |
65
+ | `init` | Create new site at `/srv/sum/<name>/` | Yes |
66
+ | `update` | Pull updates, migrate, restart | No (staging) |
67
+ | `backup` | Database and media backup | No |
68
+ | `promote` | Deploy staging site to production | No |
69
+ | `check` | Validate project setup | No |
70
+ | `themes` | List available themes | No |
71
+
72
+ ## Creating Sites
73
+
74
+ ### With GitHub
75
+
76
+ ```bash
77
+ sudo sum-platform init acme --git-provider github --git-org acme-corp
78
+ ```
79
+
80
+ ### With Gitea
81
+
82
+ ```bash
83
+ sudo sum-platform init acme --git-provider gitea --git-org clients \
84
+ --gitea-url https://gitea.agency.com
85
+ ```
86
+
87
+ ### With Gitea (Custom SSH Port)
88
+
89
+ ```bash
90
+ sudo sum-platform init acme --git-provider gitea --git-org clients \
91
+ --gitea-url https://gitea.agency.com --gitea-ssh-port 2222
92
+ ```
93
+
94
+ ### Without Git
95
+
96
+ ```bash
97
+ sudo sum-platform init acme --no-git
98
+ ```
99
+
100
+ ### Additional Init Options
101
+
102
+ ```bash
103
+ sudo sum-platform init acme --git-provider github --git-org acme-corp \
104
+ --theme theme_a \
105
+ --profile sage-stone \
106
+ --content-path /path/to/custom/content
107
+ ```
108
+
109
+ ## Managing Sites
110
+
111
+ ```bash
112
+ # Update a deployed site (pull, migrate, restart)
113
+ sum-platform update acme
114
+
115
+ # Backup database and media
116
+ sum-platform backup acme --include-media
117
+
118
+ # Promote staging to production
119
+ sum-platform promote acme --domain acme.example.com
120
+
121
+ # Validate project setup
122
+ sum-platform check acme
123
+
124
+ # List available themes
125
+ sum-platform themes
126
+ ```
127
+
128
+ ## Configuration
129
+
130
+ ### Global Config (`/etc/sum/config.yml`)
131
+
132
+ Infrastructure settings only. Created via `sum-platform setup`.
133
+
134
+ ```yaml
135
+ agency:
136
+ name: Your Agency Name
137
+
138
+ staging:
139
+ server: staging.example.com
140
+ domain_pattern: "{slug}.staging.example.com"
141
+ base_dir: /srv/sum
142
+
143
+ production:
144
+ server: prod.example.com
145
+ ssh_host: 10.0.0.1
146
+ base_dir: /srv/sum
147
+
148
+ templates:
149
+ dir: /opt/your-ops/infra
150
+ systemd: systemd/sum-site-gunicorn.service.template
151
+ caddy: caddy/Caddyfile.template
152
+
153
+ defaults:
154
+ theme: theme_a
155
+ seed_profile: starter
156
+ deploy_user: deploy
157
+ postgres_port: 5432
158
+ ```
159
+
160
+ ### Site Config (`/srv/sum/<site>/.sum/config.yml`)
161
+
162
+ Per-site configuration. Auto-created when you run `init`.
163
+
164
+ **GitHub site:**
165
+ ```yaml
166
+ site:
167
+ slug: acme
168
+ theme: theme_a
169
+ created: 2026-02-03T14:30:00Z
170
+
171
+ git:
172
+ provider: github
173
+ org: acme-corp
174
+ ```
175
+
176
+ **Gitea site:**
177
+ ```yaml
178
+ site:
179
+ slug: acme
180
+ theme: theme_a
181
+ created: 2026-02-03T14:30:00Z
182
+
183
+ git:
184
+ provider: gitea
185
+ org: clients
186
+ url: https://gitea.agency.com
187
+ ssh_port: 2222
188
+ token_env: GITEA_TOKEN
189
+ ```
190
+
191
+ **No-git site:**
192
+ ```yaml
193
+ site:
194
+ slug: acme
195
+ theme: theme_a
196
+ created: 2026-02-03T14:30:00Z
197
+
198
+ git: null
199
+ ```
200
+
201
+ ## Git Provider Setup
202
+
203
+ ### GitHub
204
+
205
+ Requires the GitHub CLI (`gh`) to be installed and authenticated:
206
+
207
+ ```bash
208
+ gh auth login
209
+ ```
210
+
211
+ ### Gitea
212
+
213
+ Set the API token environment variable:
214
+
215
+ ```bash
216
+ export GITEA_TOKEN=your-token-here
217
+ ```
218
+
219
+ Or use a custom environment variable name:
220
+
221
+ ```bash
222
+ sudo sum-platform init acme --git-provider gitea --git-org clients \
223
+ --gitea-url https://gitea.agency.com --gitea-token-env MY_GITEA_TOKEN
224
+ ```
225
+
226
+ ## Development Install (monorepo)
227
+
228
+ ```bash
229
+ pip install -e ./cli
230
+ ```
@@ -0,0 +1,202 @@
1
+ # SUM CLI (v3.1)
2
+
3
+ [![PyPI](https://img.shields.io/pypi/v/sum-cli.svg)](https://pypi.org/project/sum-cli/)
4
+
5
+ The SUM CLI is the single control plane for deploying and managing SUM Platform client sites on staging and production servers.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ pip install sum-cli
11
+ sum-platform --version
12
+ ```
13
+
14
+ ### With Gitea Support
15
+
16
+ If using Gitea instead of GitHub for repository hosting:
17
+
18
+ ```bash
19
+ pip install sum-cli[gitea]
20
+ ```
21
+
22
+ ## Initial Setup
23
+
24
+ Before using the CLI, configure your infrastructure settings:
25
+
26
+ ```bash
27
+ sudo sum-platform setup
28
+ ```
29
+
30
+ This interactive command creates `/etc/sum/config.yml` with your staging/production server settings.
31
+
32
+ ## Commands
33
+
34
+ | Command | Description | Requires Sudo |
35
+ |---------|-------------|---------------|
36
+ | `setup` | Configure infrastructure settings | Yes |
37
+ | `init` | Create new site at `/srv/sum/<name>/` | Yes |
38
+ | `update` | Pull updates, migrate, restart | No (staging) |
39
+ | `backup` | Database and media backup | No |
40
+ | `promote` | Deploy staging site to production | No |
41
+ | `check` | Validate project setup | No |
42
+ | `themes` | List available themes | No |
43
+
44
+ ## Creating Sites
45
+
46
+ ### With GitHub
47
+
48
+ ```bash
49
+ sudo sum-platform init acme --git-provider github --git-org acme-corp
50
+ ```
51
+
52
+ ### With Gitea
53
+
54
+ ```bash
55
+ sudo sum-platform init acme --git-provider gitea --git-org clients \
56
+ --gitea-url https://gitea.agency.com
57
+ ```
58
+
59
+ ### With Gitea (Custom SSH Port)
60
+
61
+ ```bash
62
+ sudo sum-platform init acme --git-provider gitea --git-org clients \
63
+ --gitea-url https://gitea.agency.com --gitea-ssh-port 2222
64
+ ```
65
+
66
+ ### Without Git
67
+
68
+ ```bash
69
+ sudo sum-platform init acme --no-git
70
+ ```
71
+
72
+ ### Additional Init Options
73
+
74
+ ```bash
75
+ sudo sum-platform init acme --git-provider github --git-org acme-corp \
76
+ --theme theme_a \
77
+ --profile sage-stone \
78
+ --content-path /path/to/custom/content
79
+ ```
80
+
81
+ ## Managing Sites
82
+
83
+ ```bash
84
+ # Update a deployed site (pull, migrate, restart)
85
+ sum-platform update acme
86
+
87
+ # Backup database and media
88
+ sum-platform backup acme --include-media
89
+
90
+ # Promote staging to production
91
+ sum-platform promote acme --domain acme.example.com
92
+
93
+ # Validate project setup
94
+ sum-platform check acme
95
+
96
+ # List available themes
97
+ sum-platform themes
98
+ ```
99
+
100
+ ## Configuration
101
+
102
+ ### Global Config (`/etc/sum/config.yml`)
103
+
104
+ Infrastructure settings only. Created via `sum-platform setup`.
105
+
106
+ ```yaml
107
+ agency:
108
+ name: Your Agency Name
109
+
110
+ staging:
111
+ server: staging.example.com
112
+ domain_pattern: "{slug}.staging.example.com"
113
+ base_dir: /srv/sum
114
+
115
+ production:
116
+ server: prod.example.com
117
+ ssh_host: 10.0.0.1
118
+ base_dir: /srv/sum
119
+
120
+ templates:
121
+ dir: /opt/your-ops/infra
122
+ systemd: systemd/sum-site-gunicorn.service.template
123
+ caddy: caddy/Caddyfile.template
124
+
125
+ defaults:
126
+ theme: theme_a
127
+ seed_profile: starter
128
+ deploy_user: deploy
129
+ postgres_port: 5432
130
+ ```
131
+
132
+ ### Site Config (`/srv/sum/<site>/.sum/config.yml`)
133
+
134
+ Per-site configuration. Auto-created when you run `init`.
135
+
136
+ **GitHub site:**
137
+ ```yaml
138
+ site:
139
+ slug: acme
140
+ theme: theme_a
141
+ created: 2026-02-03T14:30:00Z
142
+
143
+ git:
144
+ provider: github
145
+ org: acme-corp
146
+ ```
147
+
148
+ **Gitea site:**
149
+ ```yaml
150
+ site:
151
+ slug: acme
152
+ theme: theme_a
153
+ created: 2026-02-03T14:30:00Z
154
+
155
+ git:
156
+ provider: gitea
157
+ org: clients
158
+ url: https://gitea.agency.com
159
+ ssh_port: 2222
160
+ token_env: GITEA_TOKEN
161
+ ```
162
+
163
+ **No-git site:**
164
+ ```yaml
165
+ site:
166
+ slug: acme
167
+ theme: theme_a
168
+ created: 2026-02-03T14:30:00Z
169
+
170
+ git: null
171
+ ```
172
+
173
+ ## Git Provider Setup
174
+
175
+ ### GitHub
176
+
177
+ Requires the GitHub CLI (`gh`) to be installed and authenticated:
178
+
179
+ ```bash
180
+ gh auth login
181
+ ```
182
+
183
+ ### Gitea
184
+
185
+ Set the API token environment variable:
186
+
187
+ ```bash
188
+ export GITEA_TOKEN=your-token-here
189
+ ```
190
+
191
+ Or use a custom environment variable name:
192
+
193
+ ```bash
194
+ sudo sum-platform init acme --git-provider gitea --git-org clients \
195
+ --gitea-url https://gitea.agency.com --gitea-token-env MY_GITEA_TOKEN
196
+ ```
197
+
198
+ ## Development Install (monorepo)
199
+
200
+ ```bash
201
+ pip install -e ./cli
202
+ ```
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "sum-cli"
7
- version = "3.0.0"
7
+ version = "3.1.0"
8
8
  description = "SUM Platform CLI: single control plane for site lifecycle management"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
@@ -9,7 +9,7 @@ from sum.commands.backup import backup
9
9
  from sum.commands.check import check
10
10
  from sum.commands.init import init
11
11
  from sum.commands.promote import promote
12
- from sum.commands.run import run
12
+ from sum.commands.setup import setup
13
13
  from sum.commands.themes import themes
14
14
  from sum.commands.update import update
15
15
 
@@ -26,14 +26,14 @@ def _get_version() -> str:
26
26
  version=_get_version(), prog_name="sum-platform", message="%(prog)s %(version)s"
27
27
  )
28
28
  def cli() -> None:
29
- """SUM Platform CLI (v2)."""
29
+ """SUM Platform CLI - Deploy and manage client sites."""
30
30
 
31
31
 
32
32
  cli.add_command(backup)
33
33
  cli.add_command(check)
34
34
  cli.add_command(init)
35
35
  cli.add_command(promote)
36
- cli.add_command(run)
36
+ cli.add_command(setup)
37
37
  cli.add_command(themes)
38
38
  cli.add_command(update)
39
39
 
@@ -4,7 +4,7 @@ from __future__ import annotations
4
4
 
5
5
  from sum.commands.check import check
6
6
  from sum.commands.init import init
7
- from sum.commands.run import run
7
+ from sum.commands.setup import setup
8
8
  from sum.commands.themes import themes
9
9
 
10
- __all__ = ["check", "init", "run", "themes"]
10
+ __all__ = ["check", "init", "setup", "themes"]
@@ -7,7 +7,7 @@ Creates a working site on staging at /srv/sum/<name>/ with:
7
7
  - External venv
8
8
  - Systemd service
9
9
  - Caddy configuration
10
- - Git repository (optional)
10
+ - Git repository (optional, specify provider with --git-provider)
11
11
  """
12
12
 
13
13
  from __future__ import annotations
@@ -17,6 +17,7 @@ from types import ModuleType
17
17
  from sum.exceptions import SetupError
18
18
  from sum.setup.infrastructure import check_infrastructure
19
19
  from sum.setup.site_orchestrator import SiteOrchestrator, SiteSetupConfig
20
+ from sum.site_config import GitConfig
20
21
  from sum.system_config import ConfigurationError, get_system_config
21
22
  from sum.utils.output import OutputFormatter
22
23
  from sum.utils.project import validate_project_name
@@ -37,6 +38,11 @@ def run_init(
37
38
  profile: str = "starter",
38
39
  content_path: str | None = None,
39
40
  no_git: bool = False,
41
+ git_provider: str | None = None,
42
+ git_org: str | None = None,
43
+ gitea_url: str | None = None,
44
+ gitea_ssh_port: int = 22,
45
+ gitea_token_env: str = "GITEA_TOKEN",
40
46
  skip_systemd: bool = False,
41
47
  skip_caddy: bool = False,
42
48
  superuser_username: str = "admin",
@@ -51,7 +57,12 @@ def run_init(
51
57
  theme: Theme slug to use.
52
58
  profile: Content profile name to seed.
53
59
  content_path: Optional path to custom content directory.
54
- no_git: Skip GitHub repository creation.
60
+ no_git: Skip git repository creation.
61
+ git_provider: Git provider ("github" or "gitea").
62
+ git_org: Git organization/namespace.
63
+ gitea_url: Gitea instance URL (required if git_provider=gitea).
64
+ gitea_ssh_port: SSH port for Gitea.
65
+ gitea_token_env: Env var name for Gitea API token.
55
66
  skip_systemd: Skip systemd service installation.
56
67
  skip_caddy: Skip Caddy configuration.
57
68
  superuser_username: Username for Django superuser.
@@ -96,11 +107,32 @@ def run_init(
96
107
  OutputFormatter.error(f"Site already exists at {site_dir}")
97
108
  return 1
98
109
 
99
- # Warn about GitHub if gh CLI not available and --no-git not set
100
- if not no_git and not infra.has_gh_cli:
101
- OutputFormatter.warning(
102
- "GitHub CLI (gh) not available. Repository creation will be skipped.\n"
103
- "To enable: install gh CLI and run 'gh auth login'"
110
+ # Build git config from flags
111
+ git_config: GitConfig | None = None
112
+ if not no_git:
113
+ # Validate required git flags
114
+ if not git_provider:
115
+ OutputFormatter.error(
116
+ "Git provider required. Use --git-provider github or --git-provider gitea.\n"
117
+ "Or use --no-git to skip git setup."
118
+ )
119
+ return 1
120
+ if not git_org:
121
+ OutputFormatter.error(
122
+ "Git organization required. Use --git-org <org>.\n"
123
+ "Or use --no-git to skip git setup."
124
+ )
125
+ return 1
126
+ if git_provider == "gitea" and not gitea_url:
127
+ OutputFormatter.error("Gitea URL required. Use --gitea-url <url>.")
128
+ return 1
129
+
130
+ git_config = GitConfig(
131
+ provider=git_provider,
132
+ org=git_org,
133
+ url=gitea_url,
134
+ ssh_port=gitea_ssh_port,
135
+ token_env=gitea_token_env,
104
136
  )
105
137
 
106
138
  # Build setup config
@@ -110,9 +142,9 @@ def run_init(
110
142
  seed_profile=profile,
111
143
  content_path=content_path,
112
144
  superuser_username=superuser_username,
113
- skip_git=no_git,
114
145
  skip_systemd=skip_systemd,
115
146
  skip_caddy=skip_caddy,
147
+ git_config=git_config,
116
148
  )
117
149
 
118
150
  # Run setup
@@ -153,6 +185,11 @@ def _init_command(
153
185
  profile: str,
154
186
  content_path: str | None,
155
187
  no_git: bool,
188
+ git_provider: str | None,
189
+ git_org: str | None,
190
+ gitea_url: str | None,
191
+ gitea_ssh_port: int,
192
+ gitea_token_env: str,
156
193
  skip_systemd: bool,
157
194
  skip_caddy: bool,
158
195
  superuser_username: str,
@@ -164,6 +201,11 @@ def _init_command(
164
201
  profile=profile,
165
202
  content_path=content_path,
166
203
  no_git=no_git,
204
+ git_provider=git_provider,
205
+ git_org=git_org,
206
+ gitea_url=gitea_url,
207
+ gitea_ssh_port=gitea_ssh_port,
208
+ gitea_token_env=gitea_token_env,
167
209
  skip_systemd=skip_systemd,
168
210
  skip_caddy=skip_caddy,
169
211
  superuser_username=superuser_username,
@@ -202,7 +244,36 @@ else:
202
244
  @click.option(
203
245
  "--no-git",
204
246
  is_flag=True,
205
- help="Skip GitHub repository creation (git init only).",
247
+ help="Skip git repository creation (local git init only).",
248
+ )
249
+ @click.option(
250
+ "--git-provider",
251
+ type=click.Choice(["github", "gitea"]),
252
+ default=None,
253
+ help="Git provider: github or gitea. Required unless --no-git.",
254
+ )
255
+ @click.option(
256
+ "--git-org",
257
+ default=None,
258
+ help="Git organization/namespace. Required unless --no-git.",
259
+ )
260
+ @click.option(
261
+ "--gitea-url",
262
+ default=None,
263
+ help="Gitea instance URL. Required if --git-provider=gitea.",
264
+ )
265
+ @click.option(
266
+ "--gitea-ssh-port",
267
+ type=int,
268
+ default=22,
269
+ show_default=True,
270
+ help="SSH port for Gitea.",
271
+ )
272
+ @click.option(
273
+ "--gitea-token-env",
274
+ default="GITEA_TOKEN",
275
+ show_default=True,
276
+ help="Environment variable for Gitea API token.",
206
277
  )
207
278
  @click.option(
208
279
  "--skip-systemd",
@@ -227,6 +298,11 @@ else:
227
298
  profile: str,
228
299
  content_path: str | None,
229
300
  no_git: bool,
301
+ git_provider: str | None,
302
+ git_org: str | None,
303
+ gitea_url: str | None,
304
+ gitea_ssh_port: int,
305
+ gitea_token_env: str,
230
306
  skip_systemd: bool,
231
307
  skip_caddy: bool,
232
308
  superuser_username: str,
@@ -241,15 +317,16 @@ else:
241
317
  - External virtualenv
242
318
  - Systemd service
243
319
  - Caddy reverse proxy
244
- - GitHub repository (optional)
245
-
246
- The site will be accessible at https://<SITE_NAME>.lintel.site
320
+ - Git repository (optional, specify provider with --git-provider)
247
321
 
248
322
  \b
249
323
  Examples:
250
- sudo sum-platform init acme
251
- sudo sum-platform init acme --theme theme_b
252
- sudo sum-platform init acme --content-path /path/to/profiles/acme
324
+ sudo sum-platform init acme --no-git
325
+ sudo sum-platform init acme --git-provider github --git-org acme-corp
326
+ sudo sum-platform init acme --git-provider gitea --git-org clients \\
327
+ --gitea-url https://git.agency.com
328
+ sudo sum-platform init acme --git-provider gitea --git-org clients \\
329
+ --gitea-url https://git.agency.com --gitea-ssh-port 2222
253
330
  """
254
331
  _init_command(
255
332
  site_name,
@@ -257,6 +334,11 @@ else:
257
334
  profile=profile,
258
335
  content_path=content_path,
259
336
  no_git=no_git,
337
+ git_provider=git_provider,
338
+ git_org=git_org,
339
+ gitea_url=gitea_url,
340
+ gitea_ssh_port=gitea_ssh_port,
341
+ gitea_token_env=gitea_token_env,
260
342
  skip_systemd=skip_systemd,
261
343
  skip_caddy=skip_caddy,
262
344
  superuser_username=superuser_username,