suite-py 1.41.9__tar.gz → 1.42.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 (54) hide show
  1. {suite_py-1.41.9 → suite_py-1.42.0}/PKG-INFO +4 -4
  2. {suite_py-1.41.9 → suite_py-1.42.0}/pyproject.toml +4 -4
  3. {suite_py-1.41.9 → suite_py-1.42.0}/suite_py/__version__.py +1 -1
  4. {suite_py-1.41.9 → suite_py-1.42.0}/suite_py/cli.py +36 -210
  5. {suite_py-1.41.9 → suite_py-1.42.0}/suite_py/commands/check.py +0 -18
  6. {suite_py-1.41.9 → suite_py-1.42.0}/suite_py/commands/merge_pr.py +1 -12
  7. {suite_py-1.41.9 → suite_py-1.42.0}/suite_py/commands/open_pr.py +1 -6
  8. suite_py-1.41.9/suite_py/commands/deploy.py → suite_py-1.42.0/suite_py/commands/release.py +41 -45
  9. {suite_py-1.41.9 → suite_py-1.42.0}/suite_py/lib/config.py +0 -1
  10. {suite_py-1.41.9 → suite_py-1.42.0}/suite_py/lib/handler/captainhook_handler.py +0 -7
  11. {suite_py-1.41.9 → suite_py-1.42.0}/suite_py/lib/handler/okta_handler.py +8 -4
  12. {suite_py-1.41.9 → suite_py-1.42.0}/suite_py/lib/metrics.py +1 -1
  13. {suite_py-1.41.9 → suite_py-1.42.0}/suite_py/lib/oauth.py +7 -3
  14. {suite_py-1.41.9 → suite_py-1.42.0}/suite_py/lib/tokens.py +3 -7
  15. suite_py-1.41.9/suite_py/commands/aggregator.py +0 -159
  16. suite_py-1.41.9/suite_py/commands/batch_job.py +0 -215
  17. suite_py-1.41.9/suite_py/commands/docker.py +0 -91
  18. suite_py-1.41.9/suite_py/commands/generator.py +0 -238
  19. suite_py-1.41.9/suite_py/commands/id.py +0 -60
  20. suite_py-1.41.9/suite_py/commands/ip.py +0 -68
  21. suite_py-1.41.9/suite_py/commands/release.py +0 -449
  22. suite_py-1.41.9/suite_py/commands/secret.py +0 -204
  23. suite_py-1.41.9/suite_py/lib/handler/drone_handler.py +0 -252
  24. suite_py-1.41.9/suite_py/lib/handler/vault_handler.py +0 -28
  25. {suite_py-1.41.9 → suite_py-1.42.0}/LICENSE-APACHE +0 -0
  26. {suite_py-1.41.9 → suite_py-1.42.0}/LICENSE-MIT +0 -0
  27. {suite_py-1.41.9 → suite_py-1.42.0}/suite_py/__init__.py +0 -0
  28. {suite_py-1.41.9 → suite_py-1.42.0}/suite_py/commands/__init__.py +0 -0
  29. {suite_py-1.41.9 → suite_py-1.42.0}/suite_py/commands/ask_review.py +0 -0
  30. {suite_py-1.41.9 → suite_py-1.42.0}/suite_py/commands/bump.py +0 -0
  31. {suite_py-1.41.9 → suite_py-1.42.0}/suite_py/commands/common.py +0 -0
  32. {suite_py-1.41.9 → suite_py-1.42.0}/suite_py/commands/context.py +0 -0
  33. {suite_py-1.41.9 → suite_py-1.42.0}/suite_py/commands/create_branch.py +0 -0
  34. {suite_py-1.41.9 → suite_py-1.42.0}/suite_py/commands/login.py +0 -0
  35. {suite_py-1.41.9 → suite_py-1.42.0}/suite_py/commands/project_lock.py +0 -0
  36. {suite_py-1.41.9 → suite_py-1.42.0}/suite_py/commands/set_token.py +0 -0
  37. {suite_py-1.41.9 → suite_py-1.42.0}/suite_py/commands/status.py +0 -0
  38. {suite_py-1.41.9 → suite_py-1.42.0}/suite_py/lib/__init__.py +0 -0
  39. {suite_py-1.41.9 → suite_py-1.42.0}/suite_py/lib/handler/__init__.py +0 -0
  40. {suite_py-1.41.9 → suite_py-1.42.0}/suite_py/lib/handler/aws_handler.py +0 -0
  41. {suite_py-1.41.9 → suite_py-1.42.0}/suite_py/lib/handler/changelog_handler.py +0 -0
  42. {suite_py-1.41.9 → suite_py-1.42.0}/suite_py/lib/handler/frequent_reviewers_handler.py +0 -0
  43. {suite_py-1.41.9 → suite_py-1.42.0}/suite_py/lib/handler/git_handler.py +0 -0
  44. {suite_py-1.41.9 → suite_py-1.42.0}/suite_py/lib/handler/github_handler.py +0 -0
  45. {suite_py-1.41.9 → suite_py-1.42.0}/suite_py/lib/handler/metrics_handler.py +0 -0
  46. {suite_py-1.41.9 → suite_py-1.42.0}/suite_py/lib/handler/prompt_utils.py +0 -0
  47. {suite_py-1.41.9 → suite_py-1.42.0}/suite_py/lib/handler/version_handler.py +0 -0
  48. {suite_py-1.41.9 → suite_py-1.42.0}/suite_py/lib/handler/youtrack_handler.py +0 -0
  49. {suite_py-1.41.9 → suite_py-1.42.0}/suite_py/lib/logger.py +0 -0
  50. {suite_py-1.41.9 → suite_py-1.42.0}/suite_py/lib/requests/__init__.py +0 -0
  51. {suite_py-1.41.9 → suite_py-1.42.0}/suite_py/lib/requests/auth.py +0 -0
  52. {suite_py-1.41.9 → suite_py-1.42.0}/suite_py/lib/requests/session.py +0 -0
  53. {suite_py-1.41.9 → suite_py-1.42.0}/suite_py/lib/symbol.py +0 -0
  54. {suite_py-1.41.9 → suite_py-1.42.0}/suite_py/templates/login.html +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: suite-py
3
- Version: 1.41.9
3
+ Version: 1.42.0
4
4
  Summary:
5
5
  Author: larrywax, EugenioLaghi, michelangelomo
6
6
  Author-email: devops@prima.it
@@ -13,7 +13,7 @@ Classifier: Programming Language :: Python :: 3.11
13
13
  Classifier: Programming Language :: Python :: 3.12
14
14
  Requires-Dist: Click (>=7.0)
15
15
  Requires-Dist: InquirerPy (>=0.2.0)
16
- Requires-Dist: Jinja2 (>=2.11,<3.0.0)
16
+ Requires-Dist: Jinja2 (>=3.1.4,<4.0.0)
17
17
  Requires-Dist: PyGithub (>=1.57)
18
18
  Requires-Dist: PyYaml (>=5.4)
19
19
  Requires-Dist: autoupgrade-prima (>=0.6)
@@ -21,12 +21,12 @@ Requires-Dist: black (>=22.6,<25.0)
21
21
  Requires-Dist: boto3 (>=1.17.84)
22
22
  Requires-Dist: cement (>=3.0)
23
23
  Requires-Dist: colorama (>=0.4.3)
24
- Requires-Dist: cryptography (==42.0.7)
24
+ Requires-Dist: cryptography (==43.0.0)
25
25
  Requires-Dist: halo (>=0.0.28)
26
26
  Requires-Dist: inquirer (==3.1.4)
27
27
  Requires-Dist: itsdangerous (==2.2.0)
28
28
  Requires-Dist: keyring (>=23.9.1,<26.0.0)
29
- Requires-Dist: kubernetes (==29.0.0)
29
+ Requires-Dist: kubernetes (==30.1.0)
30
30
  Requires-Dist: logzero (==1.7.0)
31
31
  Requires-Dist: markupsafe (==2.0.1)
32
32
  Requires-Dist: pptree (==3.1)
@@ -2,12 +2,12 @@
2
2
  authors = ["larrywax, EugenioLaghi, michelangelomo <devops@prima.it>"]
3
3
  description = ""
4
4
  name = "suite-py"
5
- version = "1.41.9"
5
+ version = "1.42.0"
6
6
 
7
7
  [tool.poetry.dependencies]
8
8
  Click = ">=7.0"
9
9
  InquirerPy = ">=0.2.0"
10
- Jinja2 = ">=2.11,<3.0.0"
10
+ Jinja2 = ">=3.1.4,<4.0.0"
11
11
  PyGithub = ">=1.57"
12
12
  PyYaml = ">=5.4"
13
13
  autoupgrade-prima = ">=0.6"
@@ -19,7 +19,7 @@ halo = ">=0.0.28"
19
19
  inquirer = "==3.1.4"
20
20
  itsdangerous = "==2.2.0"
21
21
  keyring = ">=23.9.1,<26.0.0"
22
- kubernetes = "==29.0.0"
22
+ kubernetes = "==30.1.0"
23
23
  logzero = "==1.7.0"
24
24
  markupsafe = "==2.0.1"
25
25
  pptree = "==3.1"
@@ -34,7 +34,7 @@ rich = "==13.7.1"
34
34
  semver = "^2.13.0"
35
35
  termcolor = ">=1.1.0"
36
36
  truststore = {version = ">=0.7,<0.10", python = ">=3.10"}
37
- cryptography = "42.0.7"
37
+ cryptography = "43.0.0"
38
38
 
39
39
  [tool.poetry.dev-dependencies]
40
40
 
@@ -1,2 +1,2 @@
1
1
  # -*- encoding: utf-8 -*-
2
- __version__ = "1.41.9"
2
+ __version__ = "1.42.0"
@@ -4,12 +4,38 @@
4
4
  # for performance reasons, so turn off the lint warning
5
5
  # pylint: disable=import-outside-toplevel
6
6
 
7
- import os
7
+ # We need to inject truststore code before we do any libraries
8
+ # that might end up creating an ssl.SSlContext object
9
+ # pylint: disable=wrong-import-position
10
+
8
11
  import sys
12
+
13
+
14
+ def maybe_inject_truststore() -> None:
15
+ """
16
+ Injects the truststore package into the system ssl store, to fix verficiation certificate issues when using warp.
17
+ """
18
+ if sys.version_info >= (3, 10):
19
+ import truststore
20
+
21
+ truststore.inject_into_ssl()
22
+ else:
23
+ # pylint: disable-next=reimported
24
+ from suite_py.lib import logger
25
+
26
+ logger.warning(
27
+ "Your python version is older than 3.10 and doesn't support the truststore package. You might experience issues with certificate verification when connected to the warp VPN.\nPlease update to python 3.10 or newer"
28
+ )
29
+
30
+
31
+ # Needs to be done before any other imports
32
+ maybe_inject_truststore()
33
+
34
+ import os
9
35
  from functools import wraps
36
+ from importlib.metadata import PackageNotFoundError, version
10
37
  from typing import Optional
11
38
 
12
- from importlib.metadata import version, PackageNotFoundError
13
39
  import click
14
40
  import requests
15
41
  from autoupgrade import Package
@@ -25,22 +51,10 @@ from suite_py.lib.handler.captainhook_handler import CaptainHook
25
51
  from suite_py.lib.handler.okta_handler import Okta
26
52
  from suite_py.lib.tokens import Tokens
27
53
 
28
- ALLOW_NO_GIT_SUBCOMMAND = ["login", "aggregator"]
29
- ALLOW_NO_HOME_SUBCOMMAND = ["login", "aggregator"]
54
+ # pylint: enable=wrong-import-position
30
55
 
31
-
32
- def maybe_inject_truststore() -> None:
33
- """
34
- Injects the truststore package into the system ssl store, to fix verficiation certificate issues when using warp.
35
- """
36
- if sys.version_info >= (3, 10):
37
- import truststore
38
-
39
- truststore.inject_into_ssl()
40
- else:
41
- logger.warning(
42
- "Your python version is older than 3.10 and doesn't support the truststore package. You might experience issues with certificate verification when connected to the warp VPN.\nPlease update to python 3.10 or newer"
43
- )
56
+ ALLOW_NO_GIT_SUBCOMMAND = ["check", "set-token", "login"]
57
+ ALLOW_NO_HOME_SUBCOMMAND = ["check", "set-token", "login"]
44
58
 
45
59
 
46
60
  def fetch_latest_version() -> Optional[str]:
@@ -132,12 +146,12 @@ def main(ctx, project, timeout, verbose):
132
146
  if ctx.invoked_subcommand not in ALLOW_NO_GIT_SUBCOMMAND and not git.is_repo(
133
147
  project
134
148
  ):
135
- raise Exception(f"the folder {project} is not a git repo")
149
+ raise ClickException(f"the folder {project} is not a git repo")
136
150
 
137
151
  if ctx.invoked_subcommand not in ALLOW_NO_HOME_SUBCOMMAND and not os.path.basename(
138
152
  project
139
153
  ) in os.listdir(config.user["projects_home"]):
140
- raise Exception(
154
+ raise ClickException(
141
155
  f"the folder {project} is not in {config.user['projects_home']}"
142
156
  )
143
157
 
@@ -243,8 +257,8 @@ def cli_unlock_project(obj, environment):
243
257
  @click.pass_obj
244
258
  @catch_exceptions
245
259
  def cli_open_pr(obj):
246
- from suite_py.commands.open_pr import OpenPR
247
260
  from suite_py.commands.ask_review import AskReview
261
+ from suite_py.commands.open_pr import OpenPR
248
262
 
249
263
  ask_review = obj.call(AskReview)
250
264
  obj.call(OpenPR, ask_review=ask_review).run()
@@ -278,67 +292,12 @@ def release():
278
292
  @release.command(
279
293
  "create", help="Create a github release (and deploy it if GHA are used)"
280
294
  )
281
- @click.option(
282
- "--deploy",
283
- is_flag=True,
284
- help="Trigger deploy with Drone CI after release creation (Github Actions based microservices will be automatically deployed on production)",
285
- )
286
- @click.pass_obj
287
- @catch_exceptions
288
- def cli_release_create(obj, deploy):
289
- from suite_py.commands.release import Release
290
-
291
- obj.call(Release, action="create", flags={"deploy": deploy}).run()
292
-
293
-
294
- @release.command("deploy", help="Deploy a github release with Drone CI")
295
295
  @click.pass_obj
296
296
  @catch_exceptions
297
- def cli_release_deploy(obj):
297
+ def cli_release_create(obj):
298
298
  from suite_py.commands.release import Release
299
299
 
300
- obj.call(Release, action="deploy").run()
301
-
302
-
303
- @release.command("rollback", help="Rollback a deployment")
304
- @click.pass_obj
305
- @catch_exceptions
306
- def cli_release_rollback(obj):
307
- from suite_py.commands.release import Release
308
-
309
- obj.call(Release, "rollback").run()
310
-
311
-
312
- @main.command("deploy", help="Deploy master branch in production")
313
- @click.pass_obj
314
- @catch_exceptions
315
- def cli_deploy(obj):
316
- from suite_py.commands.deploy import Deploy
317
-
318
- obj.call(Deploy).run()
319
-
320
-
321
- @main.group("docker", help="Manage docker images")
322
- def docker():
323
- pass
324
-
325
-
326
- @docker.command("release", help="Release new docker image")
327
- @click.pass_obj
328
- @catch_exceptions
329
- def cli_docker_release(obj):
330
- from suite_py.commands.docker import Docker
331
-
332
- obj.call(Docker, action="release").run()
333
-
334
-
335
- @docker.command("versions", help="List all available versions of specific image")
336
- @click.pass_obj
337
- @catch_exceptions
338
- def cli_docker_versions(obj):
339
- from suite_py.commands.docker import Docker
340
-
341
- obj.call(Docker, action="versions").run()
300
+ obj.call(Release, action="create").run()
342
301
 
343
302
 
344
303
  @main.command("status", help="Current status of a project")
@@ -359,75 +318,6 @@ def cli_check(obj):
359
318
  obj.call(Check).run()
360
319
 
361
320
 
362
- @main.command("id", help="Get the ID of the hosts where the task is running")
363
- @click.argument("environment", type=click.Choice(("staging", "production")))
364
- @click.pass_obj
365
- @catch_exceptions
366
- def cli_id(obj, environment):
367
- from suite_py.commands.id import ID
368
-
369
- obj.call(ID, environment=environment).run()
370
-
371
-
372
- @main.command("ip", help="Get the IP addresses of the hosts where the task is running")
373
- @click.argument("environment", type=click.Choice(("staging", "production")))
374
- @click.pass_obj
375
- @catch_exceptions
376
- def cli_ip(obj, environment):
377
- from suite_py.commands.ip import IP
378
-
379
- obj.call(IP, environment=environment).run()
380
-
381
-
382
- @main.command("generator", help="Generate different files from templates")
383
- @click.pass_obj
384
- @catch_exceptions
385
- def cli_generator(obj):
386
- from suite_py.commands.generator import Generator
387
-
388
- obj.call(Generator).run()
389
-
390
-
391
- @main.group(
392
- "aggregator",
393
- help="Manage CNAMEs of aggregators in QA envs",
394
- invoke_without_command=True,
395
- )
396
- @click.option(
397
- "-l", "--list", "show_list", help="deprecated", required=False, count=True
398
- )
399
- @click.option("-c", "--change", "change", help="deprecated", required=False, count=True)
400
- @click.pass_context
401
- def aggregator(ctx, show_list, change):
402
- if show_list == 1 or change == 1:
403
- logger.error(
404
- "suite-py aggregator [-c|-l] has been hard-deprecated. Use suite-py aggregator [list|change] instead."
405
- )
406
- sys.exit(0)
407
-
408
- if ctx.invoked_subcommand is None:
409
- logger.error("Missing command. Try suite-py aggregator --help for help.")
410
- sys.exit(0)
411
-
412
-
413
- @aggregator.command("list", help="List all aggregators with the current record")
414
- @click.pass_obj
415
- @catch_exceptions
416
- def cli_aggregator_list(obj):
417
- from suite_py.commands.aggregator import Aggregator
418
-
419
- obj.call(Aggregator, action="list").run()
420
-
421
-
422
- @aggregator.command("change", help="Change aggregator record")
423
- @click.pass_obj
424
- @catch_exceptions
425
- def cli_aggregator_change(obj):
426
- from suite_py.commands.aggregator import Aggregator
427
-
428
- obj.call(Aggregator, action="list").run()
429
-
430
-
431
321
  @main.command("login", help="manage login against Auth0")
432
322
  @click.pass_obj
433
323
  @catch_exceptions
@@ -437,70 +327,6 @@ def login(obj):
437
327
  obj.call(Login).run()
438
328
 
439
329
 
440
- @main.group(
441
- "secret", help="Manage secrets grants in multiple countries (aws-vault needed)"
442
- )
443
- def secret():
444
- pass
445
-
446
-
447
- @secret.command("create", help="Create a new secret")
448
- @click.option("-b", "--base-profile", "base_profile", required=False)
449
- @click.option("-f", "--secret-file", "secret_file", required=False)
450
- @click.pass_obj
451
- @catch_exceptions
452
- def cli_secret_create(obj, base_profile, secret_file):
453
- from suite_py.commands.secret import Secret
454
-
455
- obj.call(
456
- Secret, action="create", base_profile=base_profile, secret_file=secret_file
457
- ).run()
458
-
459
-
460
- @secret.command("grant", help="Grant permissions to an existing secret")
461
- @click.option("-b", "--base-profile", "base_profile", required=False)
462
- @click.option("-f", "--secret-file", "secret_file", required=False)
463
- @click.pass_obj
464
- @catch_exceptions
465
- def cli_secret_grant(obj, base_profile, secret_file):
466
- from suite_py.commands.secret import Secret
467
-
468
- obj.call(
469
- Secret, action="grant", base_profile=base_profile, secret_file=secret_file
470
- ).run()
471
-
472
-
473
- @main.command("batch-job", help="Run batch job on kube")
474
- @click.argument("environment", type=click.Choice(("staging", "production")))
475
- @click.option(
476
- "-c",
477
- "--cpu",
478
- "cpu_request",
479
- required=True,
480
- type=str,
481
- help="Millicpu format. E.g: 1000m (=1CPU)",
482
- )
483
- @click.option(
484
- "-m",
485
- "--memory",
486
- "memory_request",
487
- required=True,
488
- type=str,
489
- help="Mebibytes or gibibyte format. E.g: 256Mi or 1Gi",
490
- )
491
- @click.pass_obj
492
- @catch_exceptions
493
- def cli_run_batch_job(obj, environment, cpu_request, memory_request):
494
- from suite_py.commands.batch_job import BatchJob
495
-
496
- obj.call(
497
- BatchJob,
498
- environment=environment,
499
- cpu_request=cpu_request,
500
- memory_request=memory_request,
501
- ).run()
502
-
503
-
504
330
  @main.command("set-token", help="Create or update a service token")
505
331
  @click.pass_obj
506
332
  @catch_exceptions
@@ -2,7 +2,6 @@
2
2
 
3
3
  from suite_py.lib import logger, metrics
4
4
  from suite_py.lib.handler import prompt_utils
5
- from suite_py.lib.handler.drone_handler import DroneHandler
6
5
  from suite_py.lib.handler.github_handler import GithubHandler
7
6
  from suite_py.lib.handler.youtrack_handler import YoutrackHandler
8
7
  from suite_py.lib.symbol import CHECKMARK, CROSSMARK
@@ -16,11 +15,9 @@ class Check:
16
15
  self._youtrack = YoutrackHandler(config, tokens)
17
16
  self._github = GithubHandler(tokens)
18
17
  self._captainhook = captainhook
19
- self._drone = DroneHandler(config, tokens)
20
18
 
21
19
  self._checks = [
22
20
  ("Github", self._check_github),
23
- ("Drone", self._check_drone),
24
21
  ("Youtrack", self._check_youtrack),
25
22
  ("CaptainHook", self._check_captainhook),
26
23
  ("AWS", self._check_aws),
@@ -52,21 +49,6 @@ class Check:
52
49
  self._invalid_or_missing_tokens.append("github")
53
50
  return "missing_token"
54
51
 
55
- def _check_drone(self):
56
- if self._tokens.drone:
57
- try:
58
- drone_user = self._drone.get_user()
59
- if "message" in drone_user and drone_user["message"] == "Unauthorized":
60
- self._invalid_or_missing_tokens.append("drone")
61
- return "invalid_token"
62
- return "ok"
63
- except Exception:
64
- logger.debug("Error connecting to drone", exc_info=True)
65
- return "unreachable"
66
- else:
67
- self._invalid_or_missing_tokens.append("drone")
68
- return "missing_token"
69
-
70
52
  def _check_youtrack(self):
71
53
  if self._tokens.youtrack:
72
54
  try:
@@ -7,7 +7,6 @@ from suite_py.lib import logger, metrics
7
7
  from suite_py.lib.handler import git_handler as git
8
8
  from suite_py.lib.handler import prompt_utils
9
9
  from suite_py.lib.handler.captainhook_handler import CaptainHook
10
- from suite_py.lib.handler.drone_handler import DroneHandler
11
10
  from suite_py.lib.handler.git_handler import GitHandler
12
11
  from suite_py.lib.handler.github_handler import GithubHandler
13
12
  from suite_py.lib.handler.youtrack_handler import YoutrackHandler
@@ -22,7 +21,6 @@ class MergePR:
22
21
  self._captainhook = captainhook
23
22
  self._git = GitHandler(project, config)
24
23
  self._github = GithubHandler(tokens)
25
- self._drone = DroneHandler(config, tokens, repo=project)
26
24
 
27
25
  @metrics.command("merge-pr")
28
26
  def run(self):
@@ -56,13 +54,6 @@ class MergePR:
56
54
 
57
55
  logger.info("Pull request merged on master!")
58
56
 
59
- if self._drone.parse_yaml():
60
- drone_build_number = self._drone.get_pr_build_number(merge_status.sha)
61
- drone_build_url = self._drone.get_build_url(drone_build_number)
62
-
63
- if drone_build_url:
64
- logger.info(f"You can follow the build status at {drone_build_url}")
65
-
66
57
  self._git.fetch()
67
58
  if self._git.remote_branch_exists(branch_name):
68
59
  self._git.delete_remote_branch(branch_name)
@@ -84,9 +75,7 @@ class MergePR:
84
75
  logger.warning(
85
76
  "There is no YouTrack issue in the branch name or the selected issue does not exist."
86
77
  )
87
- logger.warning(
88
- "No card updated on YouTrack and no QA turned off automatically"
89
- )
78
+ logger.warning("No card updated on YouTrack")
90
79
 
91
80
  logger.info("All done!")
92
81
  sys.exit()
@@ -15,7 +15,6 @@ class OpenPR:
15
15
  self._ask_review = ask_review
16
16
  self._project = project
17
17
  self._config = config
18
- self._tokens = tokens
19
18
  self._youtrack = YoutrackHandler(config, tokens)
20
19
  self._git = GitHandler(project, config)
21
20
  self._branch_name = self._git.current_branch_name()
@@ -25,11 +24,7 @@ class OpenPR:
25
24
  def run(self):
26
25
  if not self._git.remote_branch_exists(self._branch_name):
27
26
  logger.warning(f"No branch named {self._branch_name} found on GitHub")
28
- if prompt_utils.ask_confirm(
29
- "Do you want to commit all the files and push them?"
30
- ):
31
- self._git.add()
32
- self._git.commit("Initial commit")
27
+ if prompt_utils.ask_confirm("Do you want to push your commits to github?"):
33
28
  self._git.push(self._branch_name)
34
29
  else:
35
30
  logger.error("Please, run 'git push' manually")
@@ -3,52 +3,58 @@ import re
3
3
  import sys
4
4
 
5
5
  from suite_py.commands import common
6
- from suite_py.commands.release import _parse_available_countries
7
6
  from suite_py.lib import logger, metrics
8
7
  from suite_py.lib.handler import git_handler as git
9
8
  from suite_py.lib.handler import prompt_utils
10
9
  from suite_py.lib.handler.changelog_handler import ChangelogHandler
11
- from suite_py.lib.handler.drone_handler import DroneHandler
12
10
  from suite_py.lib.handler.git_handler import GitHandler
13
11
  from suite_py.lib.handler.github_handler import GithubHandler
14
12
  from suite_py.lib.handler.version_handler import DEFAULT_VERSION, VersionHandler
15
13
  from suite_py.lib.handler.youtrack_handler import YoutrackHandler
16
14
 
17
15
 
18
- class Deploy:
16
+ class Release:
19
17
  # pylint: disable=too-many-instance-attributes
20
- def __init__(self, project, captainhook, config, tokens):
18
+ def __init__(self, action, project, captainhook, config, tokens):
19
+ self._action = action
21
20
  self._project = project
22
21
  self._config = config
22
+ self._tokens = tokens
23
+ self._changelog_handler = ChangelogHandler()
23
24
  self._youtrack = YoutrackHandler(config, tokens)
24
25
  self._captainhook = captainhook
25
- self._changelog_handler = ChangelogHandler()
26
26
  self._github = GithubHandler(tokens)
27
27
  self._repo = self._github.get_repo(project)
28
28
  self._git = GitHandler(project, config)
29
- self._drone = DroneHandler(config, tokens, repo=project)
30
- self._countries = _parse_available_countries(self._drone)
31
29
  self._version = VersionHandler(self._repo, self._git, self._github)
32
30
 
33
- @metrics.command("deploy")
31
+ @metrics.command("release")
34
32
  def run(self):
35
33
  self._stop_if_prod_locked()
36
-
37
34
  self._git.fetch()
38
35
 
39
- if len(self._countries) > 0:
36
+ if self._action == "create":
37
+ self._create()
38
+
39
+ def _stop_if_prod_locked(self):
40
+ request = self._captainhook.status(self._project, "production")
41
+ if request.status_code != 200:
42
+ logger.error("Unable to determine lock status on master.")
43
+ sys.exit(-1)
44
+
45
+ request_object = request.json()
46
+ if request_object["locked"]:
40
47
  logger.error(
41
- "Deploy command cannot be used on this project. Try to run `suite-py release` instead."
48
+ f"The project is locked in production by {request_object['by']}. Unable to continue."
42
49
  )
43
- sys.exit(1)
50
+ sys.exit(-1)
44
51
 
45
- current_version = self._version.get_latest_version()
52
+ def _create(self):
53
+ latest = self._version.get_latest_version()
46
54
 
47
- if current_version != "":
48
- logger.info(f"The current release is {current_version}")
49
- commits = self._github.get_commits_since_release(
50
- self._repo, current_version
51
- )
55
+ if latest != "":
56
+ logger.info(f"The current release is {latest}")
57
+ commits = self._github.get_commits_since_release(self._repo, latest)
52
58
 
53
59
  _check_migrations_deploy(commits)
54
60
 
@@ -65,10 +71,10 @@ class Deploy:
65
71
  logger.info(f"\nCommits list:\n{message}\n")
66
72
 
67
73
  if not prompt_utils.ask_confirm("Do you want to continue?"):
68
- sys.exit()
74
+ return
69
75
 
70
76
  new_version = self._version.select_new_version(
71
- current_version, allow_prerelease=True, allow_custom_version=True
77
+ latest, allow_prerelease=True
72
78
  )
73
79
 
74
80
  else:
@@ -100,20 +106,6 @@ class Deploy:
100
106
  message = common.ask_for_release_description(message)
101
107
 
102
108
  self._create_release(new_version, message)
103
- self._manage_youtrack_card(commits, new_version)
104
-
105
- def _stop_if_prod_locked(self):
106
- request = self._captainhook.status(self._project, "production")
107
- if request.status_code != 200:
108
- logger.error("Unable to determine lock status on master.")
109
- sys.exit(-1)
110
-
111
- request_object = request.json()
112
- if request_object["locked"]:
113
- logger.error(
114
- f"The project is locked in production by {request_object['by']}. Unable to continue."
115
- )
116
- sys.exit(-1)
117
109
 
118
110
  def _create_release(self, new_version, message):
119
111
  new_release = self._repo.create_git_release(
@@ -124,17 +116,12 @@ class Deploy:
124
116
  if new_release:
125
117
  logger.info(f"The release has been created! Link: {new_release.html_url}")
126
118
 
127
- build_number = self._drone.get_build_number_from_tag(new_version)
128
- if build_number:
129
- drone_url = self._drone.get_build_url(build_number)
130
- logger.info(
131
- f"You can follow the deployment in production here: {drone_url}"
132
- )
133
-
134
- def _manage_youtrack_card(self, commits, new_version):
119
+ def _manage_youtrack_card(self, version, countries):
135
120
  release_state = self._config.youtrack["release_state"]
136
121
 
137
- issue_ids = self._youtrack.get_issue_ids(commits)
122
+ release_body = self._repo.get_release(version).body
123
+
124
+ issue_ids = self._youtrack.get_ids_from_release_body(release_body)
138
125
 
139
126
  if len(issue_ids) > 0:
140
127
  update_youtrack_state = prompt_utils.ask_confirm(
@@ -146,7 +133,7 @@ class Deploy:
146
133
  try:
147
134
  self._youtrack.comment(
148
135
  issue_id,
149
- f"Deploy in production of {self._project} done with the release {new_version}",
136
+ f"Deploy in production of {self._project} in countries {countries} done with the release {version}",
150
137
  )
151
138
  if update_youtrack_state:
152
139
  self._youtrack.update_state(issue_id, release_state)
@@ -167,7 +154,7 @@ class Deploy:
167
154
 
168
155
  def _get_repos_status_from_issue(self, issue_id):
169
156
  regex_pr = r"^PR .* -> https:\/\/github\.com\/primait\/(.*)\/pull\/([0-9]*)$"
170
- regex_deploy = r"^Deploy in production of (.*) done with the release"
157
+ regex_deploy = r"^Deploy in production of (.*) in countries"
171
158
  comments = self._youtrack.get_comments(issue_id)
172
159
  repos_status = {}
173
160
 
@@ -188,6 +175,15 @@ class Deploy:
188
175
  pass
189
176
  return repos_status
190
177
 
178
+ def _tags_drifted(self, versions):
179
+ for country, version in versions.items():
180
+ for c, v in versions.items():
181
+ if country == c:
182
+ continue
183
+ if version is None or v is None or version.compare(v) != 0:
184
+ return True
185
+ return False
186
+
191
187
 
192
188
  def _check_migrations_deploy(commits):
193
189
  if not commits:
@@ -40,7 +40,6 @@ class Config:
40
40
  conf["user"].setdefault("captainhook_timeout", 30)
41
41
  conf["user"].setdefault("captainhook_url", "https://captainhook.prima.it")
42
42
  conf["user"].setdefault("use_commits_in_pr_body", False)
43
- conf["user"].setdefault("delete_qa_after_merge", True)
44
43
  conf["user"].setdefault("frequent_reviewers_max_number", 5)
45
44
 
46
45
  conf["youtrack"].setdefault("add_reviewers_tags", True)
@@ -52,13 +52,6 @@ class CaptainHook:
52
52
  def get_users_list(self):
53
53
  return self.send_get_request("/users/all")
54
54
 
55
- def aggregators(self):
56
- return self.send_get_request("/cloudflare/aggregators/available")
57
-
58
- def change_aggregator(self, aggregator, qa_address):
59
- data = {"aggregator": aggregator, "qa_address": qa_address}
60
- return self.send_put_request("/cloudflare/aggregators", data)
61
-
62
55
  def send_metrics(self, metrics):
63
56
  self.send_post_request("/suite_py/metrics/", json=metrics).raise_for_status()
64
57