itw-python-builder 0.1.46__tar.gz → 0.1.48__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 (22) hide show
  1. {itw_python_builder-0.1.46 → itw_python_builder-0.1.48}/PKG-INFO +1 -1
  2. {itw_python_builder-0.1.46 → itw_python_builder-0.1.48}/itw_python_builder/tasks.py +31 -30
  3. {itw_python_builder-0.1.46 → itw_python_builder-0.1.48}/itw_python_builder/utils.py +7 -2
  4. {itw_python_builder-0.1.46 → itw_python_builder-0.1.48}/itw_python_builder.egg-info/PKG-INFO +1 -1
  5. {itw_python_builder-0.1.46 → itw_python_builder-0.1.48}/pyproject.toml +3 -3
  6. {itw_python_builder-0.1.46 → itw_python_builder-0.1.48}/LICENSE +0 -0
  7. {itw_python_builder-0.1.46 → itw_python_builder-0.1.48}/README.md +0 -0
  8. {itw_python_builder-0.1.46 → itw_python_builder-0.1.48}/itw_python_builder/.pylintrc +0 -0
  9. {itw_python_builder-0.1.46 → itw_python_builder-0.1.48}/itw_python_builder/__init__.py +0 -0
  10. {itw_python_builder-0.1.46 → itw_python_builder-0.1.48}/itw_python_builder/cli.py +0 -0
  11. {itw_python_builder-0.1.46 → itw_python_builder-0.1.48}/itw_python_builder/notify.py +0 -0
  12. {itw_python_builder-0.1.46 → itw_python_builder-0.1.48}/itw_python_builder/ssr_tasks.py +0 -0
  13. {itw_python_builder-0.1.46 → itw_python_builder-0.1.48}/itw_python_builder/templates/new_version_email.html +0 -0
  14. {itw_python_builder-0.1.46 → itw_python_builder-0.1.48}/itw_python_builder/templates/server.sitemap.snippet.ts +0 -0
  15. {itw_python_builder-0.1.46 → itw_python_builder-0.1.48}/itw_python_builder/templates/sitemap.routes.ts +0 -0
  16. {itw_python_builder-0.1.46 → itw_python_builder-0.1.48}/itw_python_builder/version.py +0 -0
  17. {itw_python_builder-0.1.46 → itw_python_builder-0.1.48}/itw_python_builder.egg-info/SOURCES.txt +0 -0
  18. {itw_python_builder-0.1.46 → itw_python_builder-0.1.48}/itw_python_builder.egg-info/dependency_links.txt +0 -0
  19. {itw_python_builder-0.1.46 → itw_python_builder-0.1.48}/itw_python_builder.egg-info/entry_points.txt +0 -0
  20. {itw_python_builder-0.1.46 → itw_python_builder-0.1.48}/itw_python_builder.egg-info/requires.txt +0 -0
  21. {itw_python_builder-0.1.46 → itw_python_builder-0.1.48}/itw_python_builder.egg-info/top_level.txt +0 -0
  22. {itw_python_builder-0.1.46 → itw_python_builder-0.1.48}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: itw_python_builder
3
- Version: 0.1.46
3
+ Version: 0.1.48
4
4
  Summary: Standardized Django deployment pipeline with Docker, testing, and SonarQube integration
5
5
  Author-email: IT-Works <contact@it-works.io>
6
6
  License: MIT
@@ -1,7 +1,11 @@
1
- from invoke import task, Context
2
- from itw_python_builder.version import Version
1
+ import getpass
2
+ import io
3
+ import shutil
4
+ import tempfile
5
+ from datetime import datetime
6
+
7
+ from itw_python_builder.ssr_tasks import * # noqa: F401,F403 — exposes ssr-init
3
8
  from itw_python_builder.utils import (
4
- detect_project_type,
5
9
  detect_and_activate_venv,
6
10
  load_env,
7
11
  get_current_branch,
@@ -11,9 +15,7 @@ from itw_python_builder.utils import (
11
15
  generate_image_path,
12
16
  get_gitlab_username,
13
17
  _parse_gitlab_remote,
14
- is_ssr_project,
15
18
  install_sigint_guard,
16
- abort_if_interrupted,
17
19
  step,
18
20
  safe_remove,
19
21
  ensure_gitignored,
@@ -24,13 +26,7 @@ from itw_python_builder.utils import (
24
26
  TOKEN_CACHE_PATH,
25
27
  maybe_override_release_version,
26
28
  )
27
- from itw_python_builder.ssr_tasks import * # noqa: F401,F403 — exposes ssr-init
28
-
29
- import getpass
30
- import io
31
- import os
32
- from datetime import datetime
33
- from pathlib import Path
29
+ from itw_python_builder.version import Version
34
30
 
35
31
  PYLINTRC = Path(__file__).parent / ".pylintrc"
36
32
 
@@ -177,24 +173,29 @@ _CHANGELOG_TARGETS = {
177
173
 
178
174
 
179
175
  def _sync_changelog_to_branch(ctx: Context, source: str, target: str) -> None:
180
- """Apply CHANGELOG.md from source onto target, commit, push, then return to source."""
181
- print(f'[itw] Propagating CHANGELOG.md to {target}...')
182
- checkout = ctx.run(f'git checkout {target}', warn=True, hide=True)
183
- if not checkout.ok:
184
- fetch = ctx.run(f'git fetch origin {target}:{target}', warn=True, hide=True)
185
- if not fetch.ok:
186
- raise RuntimeError(f'branch {target!r} not found locally or on origin')
187
- ctx.run(f'git checkout {target}')
188
- ctx.run(f'git pull --rebase origin {target}', warn=True)
189
- ctx.run(f'git checkout {source} -- CHANGELOG.md')
190
- diff = ctx.run('git diff --cached --quiet CHANGELOG.md', warn=True, hide=True)
191
- if diff.ok:
192
- print(f'[itw] CHANGELOG.md already up to date on {target} — nothing to commit.')
193
- else:
194
- ctx.run(f'git commit -m "changelog sync from {source}"')
195
- ctx.run(f'git push origin {target}')
196
- print(f'[itw] CHANGELOG.md pushed to {target}.')
197
- ctx.run(f'git checkout {source}')
176
+ """Sync CHANGELOG.md onto target branch using a temporary git worktree."""
177
+ print(f'[itw] Propagating CHANGELOG.md to {target} via temporary worktree...')
178
+
179
+ temp_dir = tempfile.mkdtemp()
180
+ try:
181
+ ctx.run(f'git worktree add {temp_dir} {target}')
182
+ pull = ctx.run(f'git -C {temp_dir} pull --rebase origin {target}', warn=True)
183
+ if not pull.ok:
184
+ ctx.run(f'git -C {temp_dir} rebase --abort', warn=True)
185
+ raise RuntimeError(f"Failed to pull latest changes for target branch '{target}'")
186
+ shutil.copy2('CHANGELOG.md', os.path.join(temp_dir, 'CHANGELOG.md'))
187
+ diff = ctx.run(f'git -C {temp_dir} diff --quiet CHANGELOG.md', warn=True, hide=True)
188
+ if diff.ok:
189
+ print(f'[itw] CHANGELOG.md already up to date on {target}.')
190
+ else:
191
+ ctx.run(f'git -C {temp_dir} add CHANGELOG.md')
192
+ ctx.run(f'git -C {temp_dir} commit -m "changelog sync from {source}"')
193
+ ctx.run(f'git -C {temp_dir} push origin {target}')
194
+ print(f'[itw] CHANGELOG.md successfully pushed to {target}.')
195
+
196
+ finally:
197
+ ctx.run(f'git worktree remove --force {temp_dir}', warn=True)
198
+ shutil.rmtree(temp_dir, ignore_errors=True)
198
199
 
199
200
 
200
201
  def propagate_changelog(ctx: Context) -> None:
@@ -1,4 +1,3 @@
1
- import getpass
2
1
  import io
3
2
  import json
4
3
  import os
@@ -178,9 +177,10 @@ def check_branch(ctx: Context) -> bool:
178
177
 
179
178
  def get_latest_tag(ctx: Context) -> Version:
180
179
  """Read latest tag for current branch — release tags on master, RC tags elsewhere."""
180
+ ctx.run('git fetch origin --tags', warn=True, hide=True)
181
181
  branch = get_current_branch(ctx)
182
182
  pattern = 'v.*-release' if is_branch_production(branch) else 'v.*-rc*'
183
- result = ctx.run(f'git tag --list "{pattern}" --sort=-v:refname', hide=True)
183
+ result = ctx.run(f'git tag --list "{pattern}" --merged HEAD --sort=-v:refname', hide=True)
184
184
  tags = [line.strip() for line in result.stdout.splitlines() if line.strip()]
185
185
  if not tags:
186
186
  raise RuntimeError(
@@ -381,6 +381,9 @@ def maybe_override_release_version(default: Version, timeout: float = 5.0) -> Ve
381
381
  old = termios.tcgetattr(fd)
382
382
  try:
383
383
  tty.setcbreak(fd)
384
+ cb = termios.tcgetattr(fd)
385
+ cb[3] = cb[3] & ~termios.ECHO
386
+ termios.tcsetattr(fd, termios.TCSADRAIN, cb)
384
387
  ready, _, _ = select.select([sys.stdin], [], [], timeout)
385
388
  if not ready:
386
389
  print(f'[itw] No input within {int(timeout)}s — using default {default}.')
@@ -393,6 +396,8 @@ def maybe_override_release_version(default: Version, timeout: float = 5.0) -> Ve
393
396
  print(f'[itw] Empty input — using default {default}.')
394
397
  return default
395
398
 
399
+ sys.stdout.write(first)
400
+ sys.stdout.flush()
396
401
  rest = sys.stdin.readline().rstrip('\r\n')
397
402
  raw = (first + rest).strip()
398
403
  if not raw:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: itw_python_builder
3
- Version: 0.1.46
3
+ Version: 0.1.48
4
4
  Summary: Standardized Django deployment pipeline with Docker, testing, and SonarQube integration
5
5
  Author-email: IT-Works <contact@it-works.io>
6
6
  License: MIT
@@ -4,13 +4,13 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "itw_python_builder"
7
- version = "0.1.46"
7
+ version = "0.1.48"
8
8
  description = "Standardized Django deployment pipeline with Docker, testing, and SonarQube integration"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
11
- license = {text = "MIT"}
11
+ license = { text = "MIT" }
12
12
  authors = [
13
- {name = "IT-Works", email = "contact@it-works.io"}
13
+ { name = "IT-Works", email = "contact@it-works.io" }
14
14
  ]
15
15
  keywords = ["django", "deployment", "docker", "ci-cd", "sonarqube"]
16
16
  classifiers = [