itw-python-builder 0.1.22__tar.gz → 0.1.24__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.
- {itw_python_builder-0.1.22 → itw_python_builder-0.1.24}/PKG-INFO +1 -1
- {itw_python_builder-0.1.22 → itw_python_builder-0.1.24}/itw_python_builder/tasks.py +68 -0
- {itw_python_builder-0.1.22 → itw_python_builder-0.1.24}/itw_python_builder.egg-info/PKG-INFO +1 -1
- {itw_python_builder-0.1.22 → itw_python_builder-0.1.24}/pyproject.toml +1 -1
- {itw_python_builder-0.1.22 → itw_python_builder-0.1.24}/LICENSE +0 -0
- {itw_python_builder-0.1.22 → itw_python_builder-0.1.24}/README.md +0 -0
- {itw_python_builder-0.1.22 → itw_python_builder-0.1.24}/itw_python_builder/.pylintrc +0 -0
- {itw_python_builder-0.1.22 → itw_python_builder-0.1.24}/itw_python_builder/__init__.py +0 -0
- {itw_python_builder-0.1.22 → itw_python_builder-0.1.24}/itw_python_builder/cli.py +0 -0
- {itw_python_builder-0.1.22 → itw_python_builder-0.1.24}/itw_python_builder/version.py +0 -0
- {itw_python_builder-0.1.22 → itw_python_builder-0.1.24}/itw_python_builder.egg-info/SOURCES.txt +0 -0
- {itw_python_builder-0.1.22 → itw_python_builder-0.1.24}/itw_python_builder.egg-info/dependency_links.txt +0 -0
- {itw_python_builder-0.1.22 → itw_python_builder-0.1.24}/itw_python_builder.egg-info/entry_points.txt +0 -0
- {itw_python_builder-0.1.22 → itw_python_builder-0.1.24}/itw_python_builder.egg-info/requires.txt +0 -0
- {itw_python_builder-0.1.22 → itw_python_builder-0.1.24}/itw_python_builder.egg-info/top_level.txt +0 -0
- {itw_python_builder-0.1.22 → itw_python_builder-0.1.24}/setup.cfg +0 -0
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
from invoke import task, Context
|
|
2
2
|
from itw_python_builder.version import Version
|
|
3
|
+
import getpass
|
|
4
|
+
import io
|
|
3
5
|
import os
|
|
4
6
|
from datetime import datetime
|
|
5
7
|
from pathlib import Path
|
|
@@ -7,6 +9,42 @@ from pathlib import Path
|
|
|
7
9
|
PYLINTRC = Path(__file__).parent / ".pylintrc"
|
|
8
10
|
_venv_activated = False
|
|
9
11
|
|
|
12
|
+
def detect_project_type() -> str:
|
|
13
|
+
"""Detect whether the current directory is a 'frontend' or 'backend' project."""
|
|
14
|
+
cwd = os.getcwd()
|
|
15
|
+
has_package_json = os.path.isfile(os.path.join(cwd, 'package.json'))
|
|
16
|
+
has_manage_py = os.path.isfile(os.path.join(cwd, 'manage.py'))
|
|
17
|
+
|
|
18
|
+
if has_package_json and has_manage_py:
|
|
19
|
+
raise RuntimeError(
|
|
20
|
+
'Ambiguous project: both package.json and manage.py found in current directory.'
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
if has_package_json:
|
|
24
|
+
if not os.path.isdir(os.path.join(cwd, 'node_modules')):
|
|
25
|
+
raise RuntimeError(
|
|
26
|
+
'Found package.json but no node_modules/ directory.\n'
|
|
27
|
+
'Install dependencies with: npm install'
|
|
28
|
+
)
|
|
29
|
+
return 'frontend'
|
|
30
|
+
|
|
31
|
+
if has_manage_py:
|
|
32
|
+
has_venv = (
|
|
33
|
+
os.path.isdir(os.path.join(cwd, '.venv'))
|
|
34
|
+
or os.path.isdir(os.path.join(cwd, 'venv'))
|
|
35
|
+
)
|
|
36
|
+
if not has_venv:
|
|
37
|
+
raise RuntimeError(
|
|
38
|
+
'Found manage.py but no virtual environment (venv or .venv) in current directory.\n'
|
|
39
|
+
'Create one with: python -m venv .venv'
|
|
40
|
+
)
|
|
41
|
+
return 'backend'
|
|
42
|
+
|
|
43
|
+
raise RuntimeError(
|
|
44
|
+
'Could not detect project type: no package.json or manage.py in current directory.'
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
|
|
10
48
|
def detect_and_activate_venv():
|
|
11
49
|
"""Detect venv in current directory and prepend to PATH. Runs only once."""
|
|
12
50
|
global _venv_activated
|
|
@@ -92,6 +130,34 @@ def generate_image_path(ctx: Context, branch: str) -> str:
|
|
|
92
130
|
return container_registry_path
|
|
93
131
|
|
|
94
132
|
|
|
133
|
+
def get_gitlab_username(ctx: Context) -> str:
|
|
134
|
+
"""Resolve the GitLab username from git config user.email (local part before '@')."""
|
|
135
|
+
result = ctx.run('git config user.email', hide=True, warn=True)
|
|
136
|
+
email = result.stdout.strip() if result.ok else ''
|
|
137
|
+
if not email or '@' not in email:
|
|
138
|
+
raise RuntimeError(
|
|
139
|
+
'Could not determine GitLab username from git config user.email. '
|
|
140
|
+
'Set it with: git config --global user.email "you@email.com" '
|
|
141
|
+
'or pass --username=... explicitly.'
|
|
142
|
+
)
|
|
143
|
+
return email.split('@')[0]
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
@task
|
|
147
|
+
def login(ctx: Context, username=None):
|
|
148
|
+
"""Log in to the GitLab container registry."""
|
|
149
|
+
if not username:
|
|
150
|
+
username = get_gitlab_username(ctx)
|
|
151
|
+
print(f'Logging in to gitreg.it-works.io:443 as {username}')
|
|
152
|
+
token = getpass.getpass(f'Enter GitLab token (password) for {username}: ')
|
|
153
|
+
if not token:
|
|
154
|
+
raise RuntimeError('No token entered; aborting login.')
|
|
155
|
+
ctx.run(
|
|
156
|
+
f'podman login -u {username} --password-stdin gitreg.it-works.io:443 --tls-verify=false',
|
|
157
|
+
in_stream=io.StringIO(token)
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
|
|
95
161
|
def commit_version(ctx: Context, version: Version) -> None:
|
|
96
162
|
ctx.run(f'git add {Version.VERSION_FILE_NAME}')
|
|
97
163
|
ctx.run('git add CHANGELOG.md')
|
|
@@ -146,6 +212,7 @@ def taginit(ctx: Context) -> None:
|
|
|
146
212
|
def incrementrc(ctx: Context, skip_pipeline=False, pylintrc=None) -> None:
|
|
147
213
|
"""Increment release candidate version and deploy"""
|
|
148
214
|
check_branch(ctx)
|
|
215
|
+
login(ctx)
|
|
149
216
|
version = Version.read_from_file()
|
|
150
217
|
version.increment_release_candidate()
|
|
151
218
|
lint(ctx, pylintrc=pylintrc)
|
|
@@ -195,6 +262,7 @@ def incrementmajor(ctx: Context, skip_pipeline=False) -> None:
|
|
|
195
262
|
def release(ctx: Context, skip_pipeline=False) -> None:
|
|
196
263
|
"""Promote release candidate to stable release and deploy"""
|
|
197
264
|
_ = check_branch(ctx)
|
|
265
|
+
login(ctx)
|
|
198
266
|
version = Version.read_from_file()
|
|
199
267
|
version.reset_release_candidate(release=True)
|
|
200
268
|
tag_build_push(ctx, version, skip_pipeline)
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "itw_python_builder"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.24"
|
|
8
8
|
description = "Standardized Django deployment pipeline with Docker, testing, and SonarQube integration"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{itw_python_builder-0.1.22 → itw_python_builder-0.1.24}/itw_python_builder.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{itw_python_builder-0.1.22 → itw_python_builder-0.1.24}/itw_python_builder.egg-info/entry_points.txt
RENAMED
|
File without changes
|
{itw_python_builder-0.1.22 → itw_python_builder-0.1.24}/itw_python_builder.egg-info/requires.txt
RENAMED
|
File without changes
|
{itw_python_builder-0.1.22 → itw_python_builder-0.1.24}/itw_python_builder.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|