suite-py 1.41.9__py3-none-any.whl → 1.42.0__py3-none-any.whl

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.
@@ -2,15 +2,11 @@
2
2
  import re
3
3
  import sys
4
4
 
5
- import semver
6
- from halo import Halo
7
-
8
5
  from suite_py.commands import common
9
6
  from suite_py.lib import logger, metrics
10
7
  from suite_py.lib.handler import git_handler as git
11
8
  from suite_py.lib.handler import prompt_utils
12
9
  from suite_py.lib.handler.changelog_handler import ChangelogHandler
13
- from suite_py.lib.handler.drone_handler import DroneHandler
14
10
  from suite_py.lib.handler.git_handler import GitHandler
15
11
  from suite_py.lib.handler.github_handler import GithubHandler
16
12
  from suite_py.lib.handler.version_handler import DEFAULT_VERSION, VersionHandler
@@ -19,10 +15,9 @@ from suite_py.lib.handler.youtrack_handler import YoutrackHandler
19
15
 
20
16
  class Release:
21
17
  # pylint: disable=too-many-instance-attributes
22
- def __init__(self, action, project, captainhook, config, tokens, flags=None):
18
+ def __init__(self, action, project, captainhook, config, tokens):
23
19
  self._action = action
24
20
  self._project = project
25
- self._flags = flags
26
21
  self._config = config
27
22
  self._tokens = tokens
28
23
  self._changelog_handler = ChangelogHandler()
@@ -31,7 +26,6 @@ class Release:
31
26
  self._github = GithubHandler(tokens)
32
27
  self._repo = self._github.get_repo(project)
33
28
  self._git = GitHandler(project, config)
34
- self._drone = DroneHandler(config, tokens, repo=project)
35
29
  self._version = VersionHandler(self._repo, self._git, self._github)
36
30
 
37
31
  @metrics.command("release")
@@ -39,23 +33,8 @@ class Release:
39
33
  self._stop_if_prod_locked()
40
34
  self._git.fetch()
41
35
 
42
- if self._flags:
43
- if self._flags.get("deploy", False):
44
-
45
- countries = _parse_available_countries(self._drone)
46
-
47
- if len(countries) == 0:
48
- logger.error(
49
- "Can't determine which countries can be deployed. Try to run `suite-py deploy` instead."
50
- )
51
- sys.exit(1)
52
-
53
36
  if self._action == "create":
54
37
  self._create()
55
- elif self._action == "deploy":
56
- self._deploy()
57
- else:
58
- self._rollback()
59
38
 
60
39
  def _stop_if_prod_locked(self):
61
40
  request = self._captainhook.status(self._project, "production")
@@ -70,13 +49,6 @@ class Release:
70
49
  )
71
50
  sys.exit(-1)
72
51
 
73
- def _get_release(self, tag):
74
- with Halo(text="Loading...", spinner="dots", color="magenta"):
75
- latest_release = self._github.get_latest_release_if_exists(self._repo)
76
- if latest_release and latest_release.title == tag:
77
- return latest_release
78
- return None
79
-
80
52
  def _create(self):
81
53
  latest = self._version.get_latest_version()
82
54
 
@@ -99,7 +71,7 @@ class Release:
99
71
  logger.info(f"\nCommits list:\n{message}\n")
100
72
 
101
73
  if not prompt_utils.ask_confirm("Do you want to continue?"):
102
- sys.exit()
74
+ return
103
75
 
104
76
  new_version = self._version.select_new_version(
105
77
  latest, allow_prerelease=True
@@ -135,128 +107,6 @@ class Release:
135
107
 
136
108
  self._create_release(new_version, message)
137
109
 
138
- if "deploy" in self._flags and self._flags["deploy"]:
139
- self._deploy(new_version)
140
-
141
- def _deploy(self, version=""):
142
- countries = _parse_available_countries(self._drone)
143
- if len(countries) > 1:
144
- while True:
145
- countries = prompt_utils.ask_multiple_choices(
146
- "Which countries do you want to deploy to?",
147
- countries,
148
- )
149
- if countries:
150
- break
151
- logger.warning(
152
- "You didn't select any country, press SPACEBAR to select countries to deploy to, then press ENTER to confirm!"
153
- )
154
-
155
- versions = {}
156
-
157
- for country in countries:
158
- versions[country] = {}
159
- versions[country] = self._get_current_version(country)
160
-
161
- if self._tags_drifted(versions):
162
- logger.warning(
163
- "NOTE: one or more countries runs older tags or tag hasn't been found."
164
- )
165
-
166
- if not version:
167
- releases = self._extract_releases(versions)
168
- if len(releases) == 0:
169
- logger.error(f"No new release found for project {self._project}!")
170
- sys.exit(0)
171
-
172
- version = prompt_utils.ask_choices(
173
- "Which version do you want to deploy?",
174
- [{"name": f"{r.title}", "value": r.title} for r in releases],
175
- )
176
-
177
- if not prompt_utils.ask_confirm(
178
- f"You're about to deploy {self._project} release {version} in {countries}, do you confirm?",
179
- default=False,
180
- ):
181
- sys.exit(0)
182
-
183
- self._start_deploy(version, countries)
184
- self._manage_youtrack_card(version, countries)
185
-
186
- def _rollback(self):
187
- countries = _parse_available_countries(self._drone)
188
- country = prompt_utils.ask_choices(
189
- "Which country do you want to rollback?",
190
- countries,
191
- )
192
-
193
- if not country:
194
- logger.error("You must select at least one country!")
195
- self._rollback()
196
- return
197
-
198
- current = self._get_current_version(country)
199
- releases = self._get_releases_before(current)
200
- if not releases:
201
- logger.error(f"No previous releases found for project {self._project}!")
202
- sys.exit(-1)
203
- version = prompt_utils.ask_choices(
204
- "Which version do you want to roll back to?",
205
- [{"name": f"{r.tag_name}", "value": r.tag_name} for r in releases],
206
- )
207
-
208
- if not prompt_utils.ask_confirm(
209
- f"You're about to roll back {self._project} to version {version} in {country}, do you confirm?",
210
- default=False,
211
- ):
212
- sys.exit(0)
213
-
214
- self._start_deploy(version, [country], rollback=True)
215
-
216
- def _get_current_version(self, country):
217
- try:
218
- logger.info("Retrieving latest version, this may take some time...")
219
- # get latest 10 tags
220
- tags = self._github.get_tags(self._project)
221
- # exclude tags that don't match semver notation
222
- semver_tags = [t for t in tags if semver.VersionInfo.isvalid(t.name)][0:9]
223
-
224
- builds = []
225
- for tag in semver_tags:
226
- for b in self._drone.get_builds_from_tag(tag.name):
227
- if (
228
- b["event"] == "promote"
229
- and b["status"] == "success"
230
- and b["deploy_to"] == f"deploy-{country}-production"
231
- and "params" in b
232
- and "DRONE_TAG" in b["params"]
233
- ):
234
- builds.append(b)
235
-
236
- if not builds:
237
- raise Exception(
238
- "Perhaps there were not any successful builds for latest 10 tags?"
239
- )
240
-
241
- # get latest build using build number as key
242
- current_build = max(builds, key=lambda x: x["number"])
243
-
244
- if not current_build:
245
- logger.error(
246
- f"Unable to determine current version for country {country}"
247
- )
248
- sys.exit(255)
249
-
250
- v = semver.VersionInfo.parse(current_build["params"]["DRONE_TAG"])
251
- logger.info(f"Current version for country {country}: {v}")
252
-
253
- return v
254
- except Exception as e:
255
- logger.error(
256
- f"An error has occurred retrieving current version during rollback. {e}\nPlease ask #team-platform-operations for help."
257
- )
258
- sys.exit(255)
259
-
260
110
  def _create_release(self, new_version, message):
261
111
  new_release = self._repo.create_git_release(
262
112
  new_version,
@@ -266,49 +116,6 @@ class Release:
266
116
  if new_release:
267
117
  logger.info(f"The release has been created! Link: {new_release.html_url}")
268
118
 
269
- if self._drone.parse_yaml():
270
- build_number = self._drone.get_build_number_from_tag(new_version)
271
- if build_number:
272
- drone_url = self._drone.get_build_url(build_number)
273
- logger.info(f"You can follow the build status here: {drone_url}")
274
-
275
- def _start_deploy(self, version, countries, rollback=False):
276
- for country in countries:
277
- if rollback:
278
- promotion = self._drone.promote_production(
279
- version,
280
- f"deploy-{country}-production",
281
- f"DRONE_TAG={version}&ROLLBACK=true",
282
- )
283
- else:
284
- promotion = self._drone.promote_production(
285
- version,
286
- f"deploy-{country}-production",
287
- f"DRONE_TAG={version}",
288
- )
289
-
290
- if "number" not in promotion:
291
- logger.warning(f"Unable to promote drone build. Response: {promotion}")
292
- return
293
-
294
- logger.info("Drone build started successfully!")
295
- logger.info(
296
- f"You can follow the build status here: {self._drone.get_build_url(promotion['number'])}"
297
- )
298
-
299
- if rollback:
300
- self._post_rollback()
301
-
302
- def _get_releases_since(self, threshold):
303
- releases = self._repo.get_releases().get_page(0)
304
-
305
- return [rel for rel in releases if threshold.compare(rel.tag_name) == -1][0:4]
306
-
307
- def _get_releases_before(self, threshold):
308
- releases = self._repo.get_releases().get_page(0)
309
-
310
- return [rel for rel in releases if threshold.compare(rel.tag_name) == 1][0:4]
311
-
312
119
  def _manage_youtrack_card(self, version, countries):
313
120
  release_state = self._config.youtrack["release_state"]
314
121
 
@@ -368,16 +175,6 @@ class Release:
368
175
  pass
369
176
  return repos_status
370
177
 
371
- def _post_rollback(self):
372
- logger.warning("--- !!!! ---")
373
- logger.warning("Remember to revert git commit(s) if needed!")
374
-
375
- if prompt_utils.ask_confirm(
376
- "Do you want to lock production?",
377
- default=True,
378
- ):
379
- self._captainhook.lock_project(self._project, "production")
380
-
381
178
  def _tags_drifted(self, versions):
382
179
  for country, version in versions.items():
383
180
  for c, v in versions.items():
@@ -387,31 +184,6 @@ class Release:
387
184
  return True
388
185
  return False
389
186
 
390
- def _extract_releases(self, versions):
391
- r = []
392
- for _, version in versions.items():
393
- releases = None
394
- if version:
395
- releases = self._get_releases_since(version)
396
- else:
397
- releases = self._get_releases_since(
398
- semver.VersionInfo.parse("0.1.0")
399
- ) # default
400
-
401
- if releases:
402
- # check if releases already exist in the list, if not: append
403
- if not self._is_release_duplicated(r, releases):
404
- r = r + releases
405
-
406
- return r
407
-
408
- def _is_release_duplicated(self, current, releases):
409
- for c in current:
410
- for rel in releases:
411
- if c.title == rel.title:
412
- return True
413
- return False
414
-
415
187
 
416
188
  def _check_migrations_deploy(commits):
417
189
  if not commits:
@@ -429,21 +201,3 @@ def _check_migrations_deploy(commits):
429
201
  "Are you sure you want to continue?", default=False
430
202
  ):
431
203
  sys.exit()
432
-
433
-
434
- def _parse_available_countries(drone):
435
- pipelines = drone.parse_yaml()
436
-
437
- if pipelines is None:
438
- logger.error("The file .drone.yml was not found. Unable to continue.")
439
- sys.exit(1)
440
-
441
- countries = []
442
- REGEX = re.compile(r"deploy-([a-z]+)-.*")
443
- for pipeline in pipelines:
444
- if "name" in pipeline:
445
- c = REGEX.findall(pipeline["name"])
446
- if len(c) > 0 and c[0] is not None and c[0] not in countries:
447
- countries.append(c[0])
448
-
449
- return countries
suite_py/lib/config.py CHANGED
@@ -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
 
@@ -8,6 +8,10 @@ from suite_py.lib.tokens import Tokens
8
8
  _SCOPE = "openid offline_access"
9
9
 
10
10
 
11
+ class OktaError(Exception):
12
+ pass
13
+
14
+
11
15
  class Okta:
12
16
  def __init__(self, config: Config, tokens: Tokens) -> None:
13
17
  self._config = config
@@ -34,8 +38,8 @@ class Okta:
34
38
 
35
39
  refresh_token = self._get_refresh_token()
36
40
  if not isinstance(refresh_token, str):
37
- raise Exception(
38
- "Invalid okta refresh token. Try logging in with `suite_py login`"
41
+ raise OktaError(
42
+ "Invalid okta refresh token. Try logging in with `suite-py login`"
39
43
  )
40
44
  res = oauth.do_refresh_token(
41
45
  self._config.okta["client_id"],
@@ -48,9 +52,9 @@ class Okta:
48
52
 
49
53
  def _update_tokens(self, tokens: oauth.OAuthTokenResponse) -> str:
50
54
  if not tokens.id_token:
51
- raise Exception("Okta didn't return a new id_token. This shouldn't happen.")
55
+ raise OktaError("Okta didn't return a new id_token. This shouldn't happen.")
52
56
  if not tokens.refresh_token:
53
- raise Exception(
57
+ raise OktaError(
54
58
  "Okta didn't return a new refresh_token. This shouldn't happen."
55
59
  )
56
60
 
suite_py/lib/metrics.py CHANGED
@@ -12,7 +12,7 @@ def _metrics() -> Metrics:
12
12
  if _metrics_handler:
13
13
  return _metrics_handler
14
14
 
15
- raise Exception(
15
+ raise RuntimeError(
16
16
  "command_executed called before logger.setup(). This is a bug, please report it"
17
17
  )
18
18
 
suite_py/lib/oauth.py CHANGED
@@ -23,6 +23,10 @@ class OAuthTokenResponse:
23
23
  expires_in: float
24
24
 
25
25
 
26
+ class OAuthError(Exception):
27
+ pass
28
+
29
+
26
30
  def retrieve_token(base_url, params) -> OAuthTokenResponse:
27
31
  url = f"{base_url}/token"
28
32
  headers = {
@@ -34,7 +38,7 @@ def retrieve_token(base_url, params) -> OAuthTokenResponse:
34
38
  logger.debug(data)
35
39
 
36
40
  if error := data.get("error_description", None):
37
- raise Exception(f"OAuth error: {error}")
41
+ raise OAuthError(f"OAuth error: {error}")
38
42
 
39
43
  return OAuthTokenResponse(
40
44
  access_token=data["access_token"],
@@ -125,12 +129,12 @@ def authorization_code_flow(
125
129
  server.handle_request()
126
130
 
127
131
  if state != server.received_state:
128
- raise Exception(
132
+ raise OAuthError(
129
133
  "Error: session replay or similar attack in progress. Please log out of all connections."
130
134
  )
131
135
 
132
136
  if server.error_message:
133
- raise Exception(server.error_message)
137
+ raise OAuthError(server.error_message)
134
138
 
135
139
  # Step4: Request tokens: Exchange your authorization_code and code_verifier for tokens.
136
140
  body = {
suite_py/lib/tokens.py CHANGED
@@ -10,7 +10,7 @@ from InquirerPy import prompt
10
10
 
11
11
  from suite_py.lib import logger
12
12
 
13
- TOKENS = ["github", "youtrack", "drone"]
13
+ TOKENS = ["github", "youtrack"]
14
14
 
15
15
 
16
16
  def platform_has_chmod():
@@ -32,7 +32,7 @@ def should_use_keyring():
32
32
  pass
33
33
 
34
34
  if not test_success:
35
- raise Exception("Loaded keyring didn't match the saved test keyring")
35
+ raise RuntimeError("Loaded keyring didn't match the saved test keyring")
36
36
 
37
37
  return True
38
38
  except Exception as error:
@@ -139,7 +139,7 @@ class Tokens:
139
139
  if os.path.exists(self._file_name):
140
140
  try:
141
141
  if not platform_has_chmod():
142
- raise Exception("chmod is not supported on this OS")
142
+ raise RuntimeError("chmod is not supported on this OS")
143
143
 
144
144
  os.chmod(self._file_name, 0o600)
145
145
  except Exception as error:
@@ -162,9 +162,5 @@ class Tokens:
162
162
  def youtrack(self):
163
163
  return self._tokens["youtrack"]
164
164
 
165
- @property
166
- def drone(self):
167
- return self._tokens["drone"]
168
-
169
165
  def okta(self):
170
166
  return self._tokens.get("okta", {})
@@ -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)
@@ -1,54 +1,44 @@
1
1
  suite_py/__init__.py,sha256=REmi3D0X2G1ZWnYpKs8Ffm3NIj-Hw6dMuvz2b9NW344,142
2
- suite_py/__version__.py,sha256=9Lm2m6l1n6KrpsW6I8NMfl6nA0nBNZrACrlL10iipLg,49
3
- suite_py/cli.py,sha256=TUxsNK35_-KalEBi0Jj_Vui5OG0qIPSAnfHYBGSXBPs,14805
2
+ suite_py/__version__.py,sha256=hJTDtNLTlQS_WH_-iShJEn0PsoEs1NeHPvMJIjNqFfs,49
3
+ suite_py/cli.py,sha256=nQmnOXTLoO12vyH_6d41bd7h8xElRusT_tLGNtYt-Tg,9953
4
4
  suite_py/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- suite_py/commands/aggregator.py,sha256=_xyyX7MOMZzDEvzj2AI03OF3sut5PpSIyuRjUiCp5aI,5747
6
5
  suite_py/commands/ask_review.py,sha256=yN__Ac-fiZBPShjRDhyCCQZGfVlQE16KozoJk4UtiNw,3788
7
- suite_py/commands/batch_job.py,sha256=flTSxmNaUv1VcL91Lv-BwEjFpEyF8APTNysQE_2jPYE,7474
8
6
  suite_py/commands/bump.py,sha256=oFZU1hPfD11ujFC5G7wFyQOf2alY3xp2SO1h1ldjf3s,5406
9
- suite_py/commands/check.py,sha256=0e2NsPi3cqvCwtNYzhR1UroT59bCojLlGo69vv3FiOA,4074
7
+ suite_py/commands/check.py,sha256=jCX59g6DgTA55yD_75mgcqJ5zCjRwl_eIRGDeUFjUWY,3316
10
8
  suite_py/commands/common.py,sha256=aWCEvO3hqdheuMUmZcHuc9EGZPQTk7VkzkHJk283MxQ,566
11
9
  suite_py/commands/context.py,sha256=6dssSqoABPb9gLmL3Y7W2iAGxrY_oma665X8zrSkNNQ,1079
12
10
  suite_py/commands/create_branch.py,sha256=cDpeDsQk1AK70GkWz-hTduaEeU65x1wck1b-5nKIMew,4424
13
- suite_py/commands/deploy.py,sha256=kadgbVKUMtE_X4b8oWaQ1ufS4Qy9b2WuutPDXnjm4t4,8088
14
- suite_py/commands/docker.py,sha256=POz_VXOXEQaFZCafkH-grgB2_HZFrckAc0CpB9IgOiU,2932
15
- suite_py/commands/generator.py,sha256=-wQFRS0UNc-EvuYvnj3gk6DHTVSsg9lA-NMU2kQewb8,8510
16
- suite_py/commands/id.py,sha256=qMQMSH_bGDInarYaGOpX2lEGf1tyHBeAV5GQiNr5Kiw,1998
17
- suite_py/commands/ip.py,sha256=pbyVuee_cN507qUYSBv5gWcvKLYolOeuU_w_P7P7nVc,2396
18
11
  suite_py/commands/login.py,sha256=A59e1HsbN7Ocv2L_2H0Eb7MZK7AzLkLb72QxBthnIqU,258
19
- suite_py/commands/merge_pr.py,sha256=gUpoDx3q23X6gF9PLXCZnIL9DfRw_3D0LlqBlGVt7rA,5676
20
- suite_py/commands/open_pr.py,sha256=U7MVl-JFKu1mdfxC_UvxUHtPLEln0g4kKl-SvP-6zd8,7159
12
+ suite_py/commands/merge_pr.py,sha256=fXIE8mT9MjvvpqE-uVdXGBVFGhn0eQzcBxNr-N8SyAY,5171
13
+ suite_py/commands/open_pr.py,sha256=e6IT6f8L_HKsOEtrGHZQ2HWrFwmvIgXGNCK_TU0WE9k,7009
21
14
  suite_py/commands/project_lock.py,sha256=b7OkGysue_Sl13VIT7B5CTBppCvrB_Q6iC0IJRBSHp8,1909
22
- suite_py/commands/release.py,sha256=clKgmsNgR9DdgBkYjXI3NqVaw8_mCe2TZHegby3ESn4,16634
23
- suite_py/commands/secret.py,sha256=Us7wvsqAPJhe1nUSHOmzO1RSyZriKAGKwi2YEhPNIA4,7976
15
+ suite_py/commands/release.py,sha256=WOBaBGXU5bkxUV12CRGUVHBJChCt1Yo2ySA5HhCDjEY,7723
24
16
  suite_py/commands/set_token.py,sha256=fehIqKjKhE-BJGFhgkPTo3Ntr0MvpgLd6EC5yjKuRs8,1508
25
17
  suite_py/commands/status.py,sha256=0JUK53_d1-U3WNS742JD2QTiGmCGZONo3jJx8WR7q70,1122
26
18
  suite_py/lib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
- suite_py/lib/config.py,sha256=4uKXAav8E-VXlXGPnkYQ_fZYyi6058S0FM2JmyV8L2k,3970
19
+ suite_py/lib/config.py,sha256=52YV0K0GK1WRbeM70IDXkpG8oZD1Zvxipn1b-XekwNA,3907
28
20
  suite_py/lib/handler/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
21
  suite_py/lib/handler/aws_handler.py,sha256=dRvRDicikfRbuFtCLPbevaX-yC-fO4LwXFdyqLPJ8OI,8815
30
- suite_py/lib/handler/captainhook_handler.py,sha256=xZ9NueGfh14L46S8AWSCZAGJdOFUCa2cFbbguq5SVv8,3281
22
+ suite_py/lib/handler/captainhook_handler.py,sha256=sp1dxZXO1QJaq304JhtkTrQjn8Z4971e2uFTM7Dh5wg,2983
31
23
  suite_py/lib/handler/changelog_handler.py,sha256=-ppnRl3smBA_ys8tPqXmytS4eyntlwfawC2fiXFcwlw,4818
32
- suite_py/lib/handler/drone_handler.py,sha256=rmtzu30OQyG3vRPlbZKsQhHN9zbguPtXO0RpDjYOTPA,8967
33
24
  suite_py/lib/handler/frequent_reviewers_handler.py,sha256=EIJX5FEMWzrxuXS9A17hu1vfxgJSOHSBX_ahCEZ2FVA,2185
34
25
  suite_py/lib/handler/git_handler.py,sha256=boxhl9lQz6fjEJ10ib1KrDW-geCVjhA_6nKwv2ll01g,11333
35
26
  suite_py/lib/handler/github_handler.py,sha256=AnFL54yOZ5GDIU91wQat4s-d1WTcmg_B_5M7-Rop3wA,2900
36
27
  suite_py/lib/handler/metrics_handler.py,sha256=-Tp62pFIiYsBkDga0nQG3lWU-gxH68wEjIIIJeU1jHk,3159
37
- suite_py/lib/handler/okta_handler.py,sha256=3GEnJxbLXlu2zjFWniYwG0m1mFKJGfske1t-uUUdpZU,2545
28
+ suite_py/lib/handler/okta_handler.py,sha256=QOt7fhCy-1Pw_tQ0Psfuy2fXP-gbxvJ1zVNmrGvwRXw,2584
38
29
  suite_py/lib/handler/prompt_utils.py,sha256=vgk1O7h-iYEAZv1sXtMh8xIgH1djI398rzxRIgZWZcg,2474
39
- suite_py/lib/handler/vault_handler.py,sha256=r4osw7qwz3ZFmLg2U1oFPdtRFcXzDXiaWBZC01cYK_w,871
40
30
  suite_py/lib/handler/version_handler.py,sha256=DXTx4yCAbFVC6CdMqPJ-LiN5YM-dT2zklG8POyKTP5A,6774
41
31
  suite_py/lib/handler/youtrack_handler.py,sha256=eTGBBXjlN_ay1cawtnZ2IG6l78dDyKdMN1x6PxcvtA0,7499
42
32
  suite_py/lib/logger.py,sha256=q_qRtpg0Eh7r5tB-Rwz87dnWBwP-a2dIvggkiQikH8M,782
43
- suite_py/lib/metrics.py,sha256=hGGrWg_c3uTz4xhpb7POGZh_xhIAYU3drRo-KgwpBvM,1626
44
- suite_py/lib/oauth.py,sha256=Y_I8a9wDKOVQ75xJH5ECDRH4xrJHSPVPUvVVM2fTQdA,5014
33
+ suite_py/lib/metrics.py,sha256=CqAIwPIRm0AJR4qmCTj1rw-NCwdSL4Huj2eKhLxgLgU,1629
34
+ suite_py/lib/oauth.py,sha256=NOX96coz_pb10C4pZ2Sk33beJQTTi_N-LXPUjDYuRKM,5057
45
35
  suite_py/lib/requests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
46
36
  suite_py/lib/requests/auth.py,sha256=wN_WtGFmDUWRFilWzOmUaRBvP2n3EPpPMqex9Zjddko,228
47
37
  suite_py/lib/requests/session.py,sha256=P32H3cWnCWunu91WIj2iDM5U3HzaBglg60VN_C9JBL4,267
48
38
  suite_py/lib/symbol.py,sha256=z3QYBuNIwD3qQ3zF-cLOomIr_-C3bO_u5UIDAHMiyTo,60
49
- suite_py/lib/tokens.py,sha256=kK4vatd5iKEFaue0BZwK1f66YOh9zLdLzP41ZOhjMCU,5534
39
+ suite_py/lib/tokens.py,sha256=4DbsHDFLIxs40t3mRw_ZyhmejZQ0Bht7iAL8dTCTQd4,5458
50
40
  suite_py/templates/login.html,sha256=fJLls2SB84oZTSrxTdA5q1PqfvIHcCD4fhVWfyco7Ig,861
51
- suite_py-1.41.9.dist-info/METADATA,sha256=Ya0nVIVuYCPW5DMYjRIi5Gj8Ok1CwzrSWMkQYTE6kMQ,1532
52
- suite_py-1.41.9.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
53
- suite_py-1.41.9.dist-info/entry_points.txt,sha256=dVKLC-9Infy-dHJT_MkK6LcDjOgBCJ8lfPkURJhBjxE,46
54
- suite_py-1.41.9.dist-info/RECORD,,
41
+ suite_py-1.42.0.dist-info/METADATA,sha256=BBTBS6aVgG6_2F3a-Rjoi0RPduumq5AN0wpn0RH3gdk,1533
42
+ suite_py-1.42.0.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
43
+ suite_py-1.42.0.dist-info/entry_points.txt,sha256=dVKLC-9Infy-dHJT_MkK6LcDjOgBCJ8lfPkURJhBjxE,46
44
+ suite_py-1.42.0.dist-info/RECORD,,