ai-cr 3.0.0__py3-none-any.whl → 3.1.1__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: ai-cr
3
- Version: 3.0.0
3
+ Version: 3.1.1
4
4
  Summary: AI code review tool that works with any language model provider. It detects issues in GitHub pull requests or local changes—instantly, reliably, and without vendor lock-in.
5
5
  License: MIT
6
6
  Keywords: static code analysis,code review,code quality,ai,coding,assistant,llm,github,automation,devops,developer tools,github actions,workflows,git
@@ -1,21 +1,22 @@
1
1
  gito/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  gito/__main__.py,sha256=MSmt_5Xg84uHqzTN38JwgseJK8rsJn_11A8WD99VtEo,61
3
- gito/bootstrap.py,sha256=9MCV80dMs8QFaB0tmuSlrpPbnRu2ACPHAWKnOSQV-xI,3168
4
- gito/cli.py,sha256=H6LpoUfw-R4BdJcG4WGcktaIlq2C1kgKWIZ7IEwFljI,6808
3
+ gito/bootstrap.py,sha256=m8g7e4sacTe7SsRKmDms1_L2ESF8TAas1lMaH3hvrl8,3218
4
+ gito/cli.py,sha256=D0XZ7H1Xo6Q7dOL0rC6mJVNQuD7C8MAw1E01jnZXbSw,7072
5
5
  gito/cli_base.py,sha256=h0CvkfOaIYGArqNuKyAuDcJDx-hOB7H7uyfJV3afINg,2390
6
6
  gito/commands/__init__.py,sha256=B2uUQsLMEsHfNT1N3lWYm38WSuQIHFmjiGs2tdBuDBA,55
7
7
  gito/commands/deploy.py,sha256=PbNcw7Ccau2Bncpi121YDRz9gg9xvkrviytrAEFfpmw,3749
8
8
  gito/commands/fix.py,sha256=C4imdS776yl7g-KmH9Wu2PqeN4WNJh8NvSeV3pV-63g,5304
9
9
  gito/commands/gh_post_review_comment.py,sha256=xrCauuifrUEufBjx43sw5FMtWP9seHiGYzwAq5SFnvQ,3795
10
- gito/commands/gh_react_to_comment.py,sha256=3R0Ke-Met06epooImI6ZC2TuLQ2Qpv276OWMSelVcNY,6395
10
+ gito/commands/gh_react_to_comment.py,sha256=QAc5cZOu9GfPtbEOWH6dQYhsgFSSWFWzzZ1RPNzHxFA,7090
11
11
  gito/commands/linear_comment.py,sha256=8kCudz0cogWm8LsgLRWN-BybDq13zEqwV456JB3_7xo,1411
12
12
  gito/commands/repl.py,sha256=jJCRO-O7r_fFXZrk9f1_oAcYPOAwPi3cGI3bMoRyer8,549
13
+ gito/commands/version.py,sha256=u3khraY95jpIoIo-ndBxXYIEvSy_uyCmiHicAXk-V28,188
13
14
  gito/config.toml,sha256=kd2fbztnr2LGaNE2BE81yt1Ed0PTF5xe_8WtTgDxxkw,18417
14
- gito/constants.py,sha256=_G40SAMfuYjYsBzEVUIxKT8Vo0dAWIQqCWWxdaBAltY,766
15
+ gito/constants.py,sha256=1ElhE4RH0EPEq3xlhwyYRUcgr38X8wXduos0gV9yPy8,819
15
16
  gito/context.py,sha256=OBfcQOREsNx8WHANsplNrnrKYrXz1PyZyne11lSfZjw,446
16
- gito/core.py,sha256=Huz0WnnuuojwFWKD_zPLIjB6wzcoGw3r7a4zzDiQLBI,14484
17
- gito/env.py,sha256=HWNQb2q1mzyTg6w1FmDIxUheNSuoIUEsIEPiC1SYaYY,61
18
- gito/gh_api.py,sha256=FbJ7w6dtuAFUVbZNyNHn8RRDGBvJyQlrIX82m46cTac,2958
17
+ gito/core.py,sha256=YgPuVCZsoSgvskbjHmkB9Bj4cQtnxUfoBjcunSoGRJc,16289
18
+ gito/env.py,sha256=TVNxqrnLefqfZt5sSg495p8UenSgHaMgTImK1rRMIlY,146
19
+ gito/gh_api.py,sha256=2yDikXr9BM2tndYpCo-weJxjoCAlEtuPh-QBinlnHtg,4052
19
20
  gito/issue_trackers.py,sha256=XYspyaIuf0ANQSvDUea5_oOdo9tQvpZZsapI5S9g78U,1551
20
21
  gito/pipeline.py,sha256=H6eiyDHUg_p3jxNVhSnyB7EVVNbMIZkA35WMymgPnh0,2610
21
22
  gito/pipeline_steps/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -23,14 +24,16 @@ gito/pipeline_steps/jira.py,sha256=NjFgpGFAkT5PSXi6jQ9Yr8CY9M8sa3_rMb7RFhdpoNg,1
23
24
  gito/pipeline_steps/linear.py,sha256=6UDc8nGKGpwHruPq8VItE2QBWshWxaTapoMhu_qjN_g,2445
24
25
  gito/project_config.py,sha256=jOPVMgN01_krELlNXzZlrZOKmXZP-RLDS7iOgVSUyic,3182
25
26
  gito/report_struct.py,sha256=96gDYnw0MXhOZrrGaNOTyWstqpjjS7_cuWufd0XJzR4,4320
26
- gito/tpl/github_workflows/components/env-vars.j2,sha256=ouZY4vpKUkAAM5qUxA3BKAh9BpJMfwsrn8qqahhrh7U,356
27
+ gito/tpl/github_workflows/components/env-vars.j2,sha256=ypmf938h5PA38mXTZnP1eI4Un3AIhhmnl6wXg2X4kqI,406
27
28
  gito/tpl/github_workflows/components/installs.j2,sha256=j5wl0yVEIrXZDpAgzqBwmhXQA9End3xFspPxr2ZzHR0,693
28
- gito/tpl/github_workflows/gito-code-review.yml.j2,sha256=PcxXMTblWX2ANK-8bkxFPI3H-xby5Do_yaufhxGzw0Y,1159
29
- gito/tpl/github_workflows/gito-react-to-comments.yml.j2,sha256=zVNkJRgje75AejXAePZugruDu3pOuDaPcujrDfth8K4,2165
30
- gito/tpl/release_notes.j2,sha256=20QtQwdZYcFEjmfYxTysenY-njTPl2nmHpv9077WFdg,849
29
+ gito/tpl/github_workflows/gito-code-review.yml.j2,sha256=rciiX_HzygwVFTp0nUxzsLYQTRcJlR-wnft7-6gM_6Q,963
30
+ gito/tpl/github_workflows/gito-react-to-comments.yml.j2,sha256=EpBXgFwF7jMU-Zty0usx6q2lj31Ocd_OMoTPYRg7kr0,2129
31
+ gito/tpl/questions/changes_summary.j2,sha256=N80OQoo9UKii0CWLuck5bOwbijul5RefvCqHJljenmE,2213
32
+ gito/tpl/questions/release_notes.j2,sha256=20QtQwdZYcFEjmfYxTysenY-njTPl2nmHpv9077WFdg,849
33
+ gito/tpl/questions/testing_guide.j2,sha256=AVnl7MoFrRxrH2A83PgV-l7VxqPE6XNRh7VksjE50as,832
31
34
  gito/utils.py,sha256=OSBn7IeWKjoLJoGOcdgQcJHBA69UiHUChtaYMInUeko,6852
32
- ai_cr-3.0.0.dist-info/LICENSE,sha256=VbdF_GbbDK24JvdTfnsxa2M6jmhsxmRSFeHCx-lICGE,1075
33
- ai_cr-3.0.0.dist-info/METADATA,sha256=HzNuuuJhSDq9LwSRuzx0QUOHQRhC7-p3KX6XmAoYH_c,7989
34
- ai_cr-3.0.0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
35
- ai_cr-3.0.0.dist-info/entry_points.txt,sha256=Ua1DxkhJJ8TZuLgnH-IlWCkrre_0S0dq_GtYRaYupWk,38
36
- ai_cr-3.0.0.dist-info/RECORD,,
35
+ ai_cr-3.1.1.dist-info/LICENSE,sha256=VbdF_GbbDK24JvdTfnsxa2M6jmhsxmRSFeHCx-lICGE,1075
36
+ ai_cr-3.1.1.dist-info/METADATA,sha256=PZrnP1catEWRFiD5cjUTjCBYfydpPeLZkqFZeFQfQ-k,7989
37
+ ai_cr-3.1.1.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
38
+ ai_cr-3.1.1.dist-info/entry_points.txt,sha256=Ua1DxkhJJ8TZuLgnH-IlWCkrre_0S0dq_GtYRaYupWk,38
39
+ ai_cr-3.1.1.dist-info/RECORD,,
gito/bootstrap.py CHANGED
@@ -41,7 +41,10 @@ def bootstrap(verbosity: int = 1):
41
41
  Env.verbosity = verbosity
42
42
  Env.logging_level = log_levels_by_verbosity.get(verbosity, logging.INFO)
43
43
  setup_logging(Env.logging_level)
44
- logging.info("Bootstrapping... "+mc.ui.gray(f"[verbosity={verbosity}]"))
44
+ logging.info(
45
+ f"Bootstrapping Gito v{Env.gito_version}... "
46
+ + mc.ui.gray(f"[verbosity={verbosity}]")
47
+ )
45
48
 
46
49
  # cp1251 is used on Windows when redirecting output
47
50
  if sys.stdout.encoding and sys.stdout.encoding.lower() != "utf-8":
gito/cli.py CHANGED
@@ -26,7 +26,7 @@ from .utils import no_subcommand, extract_gh_owner_repo, remove_html_comments
26
26
  from .gh_api import resolve_gh_token
27
27
 
28
28
  # Import fix command to register it
29
- from .commands import fix, gh_react_to_comment, repl, deploy # noqa
29
+ from .commands import fix, gh_react_to_comment, repl, deploy, version # noqa
30
30
  from .commands.gh_post_review_comment import post_github_cr_comment
31
31
  from .commands.linear_comment import linear_comment
32
32
 
@@ -92,6 +92,7 @@ def cmd_review(
92
92
  out: str = arg_out()
93
93
  ):
94
94
  _what, _against = args_to_target(refs, what, against)
95
+ pr = pr or os.getenv("PR_NUMBER_FROM_WORKFLOW_DISPATCH")
95
96
  with get_repo_context(url, _what) as (repo, out_folder):
96
97
  asyncio.run(review(
97
98
  repo=repo,
@@ -100,6 +101,7 @@ def cmd_review(
100
101
  filters=filters,
101
102
  use_merge_base=merge_base,
102
103
  out_folder=out or out_folder,
104
+ pr=pr,
103
105
  ))
104
106
  if post_comment:
105
107
  try:
@@ -134,8 +136,13 @@ def cmd_answer(
134
136
  default=None,
135
137
  show_default=False
136
138
  ),
139
+ pr: int = typer.Option(
140
+ default=None,
141
+ help="GitHub Pull Request number"
142
+ ),
137
143
  ):
138
144
  _what, _against = args_to_target(refs, what, against)
145
+ pr = pr or os.getenv("PR_NUMBER_FROM_WORKFLOW_DISPATCH")
139
146
  if str(question).startswith("tpl:"):
140
147
  prompt_file = str(question)[4:]
141
148
  question = ""
@@ -149,6 +156,7 @@ def cmd_answer(
149
156
  use_merge_base=merge_base,
150
157
  prompt_file=prompt_file,
151
158
  use_pipeline=use_pipeline,
159
+ pr=pr,
152
160
  )
153
161
  if post_to == 'linear':
154
162
  logging.info("Posting answer to Linear...")
@@ -25,6 +25,30 @@ from ..utils import extract_gh_owner_repo
25
25
  from .fix import fix
26
26
 
27
27
 
28
+ def cleanup_comment_addressed_to_gito(text):
29
+ if not text:
30
+ return text
31
+ patterns = [
32
+ r'^\s*gito\b',
33
+ r'^\s*ai\b',
34
+ r'^\s*bot\b',
35
+ r'^\s*@gito\b',
36
+ r'^\s*@ai\b',
37
+ r'^\s*@bot\b'
38
+ ]
39
+ result = text
40
+ # Remove each pattern from the beginning
41
+ for pattern in patterns:
42
+ result = re.sub(pattern, '', result, flags=re.IGNORECASE)
43
+
44
+ # Remove leading comma and spaces that may be left after prefix removal
45
+ result = re.sub(r'^\s*,\s*', '', result)
46
+
47
+ # Clean up extra whitespace
48
+ result = re.sub(r'\s+', ' ', result).strip()
49
+ return result
50
+
51
+
28
52
  @app.command(hidden=True)
29
53
  def react_to_comment(
30
54
  comment_id: int = typer.Argument(),
@@ -99,7 +123,8 @@ def react_to_comment(
99
123
  )
100
124
  else:
101
125
  if cfg.answer_github_comments:
102
- response = answer(comment.body, repo=repo)
126
+ question = cleanup_comment_addressed_to_gito(comment.body)
127
+ response = answer(question, repo=repo, pr=pr)
103
128
  post_gh_comment(
104
129
  gh_repository=f"{owner}/{repo_name}",
105
130
  pr_or_issue_number=pr,
@@ -0,0 +1,8 @@
1
+ from ..cli_base import app
2
+ from ..env import Env
3
+
4
+
5
+ @app.command(name='version', help='Show the version of gito.bot')
6
+ def version():
7
+ print(Env.gito_version)
8
+ return Env.gito_version
gito/constants.py CHANGED
@@ -1,4 +1,5 @@
1
1
  from pathlib import Path
2
+ from .env import Env
2
3
 
3
4
  PROJECT_GITO_FOLDER = ".gito"
4
5
  PROJECT_CONFIG_FILE_NAME = "config.toml"
@@ -9,5 +10,5 @@ JSON_REPORT_FILE_NAME = "code-review-report.json"
9
10
  GITHUB_MD_REPORT_FILE_NAME = "code-review-report.md"
10
11
  EXECUTABLE = "gito"
11
12
  TEXT_ICON_URL = 'https://raw.githubusercontent.com/Nayjest/Gito/main/press-kit/logo/gito-bot-1_64top.png' # noqa: E501
12
- HTML_TEXT_ICON = f'<a href="https://github.com/Nayjest/Gito"><img src="{TEXT_ICON_URL}" align="left" width=64 height=50 /></a>' # noqa: E501
13
+ HTML_TEXT_ICON = f'<a href="https://github.com/Nayjest/Gito"><img src="{TEXT_ICON_URL}" align="left" width=64 height=50 title="Gito v{Env.gito_version}"/></a>' # noqa: E501
13
14
  HTML_CR_COMMENT_MARKER = '<!-- GITO_COMMENT:CODE_REVIEW_REPORT -->'
gito/core.py CHANGED
@@ -1,11 +1,12 @@
1
+ import os
1
2
  import fnmatch
2
3
  import logging
3
- from os import PathLike
4
4
  from typing import Iterable
5
5
  from pathlib import Path
6
6
  from functools import partial
7
7
 
8
8
  import microcore as mc
9
+ from gito.gh_api import gh_api
9
10
  from microcore import ui
10
11
  from git import Repo, Commit
11
12
  from git.exc import GitCommandError
@@ -66,16 +67,57 @@ def commit_in_branch(repo: Repo, commit: Commit, target_branch: str) -> bool:
66
67
  return False
67
68
 
68
69
 
70
+ def get_base_branch(repo: Repo, pr: int | str = None):
71
+ if os.getenv('GITHUB_ACTIONS'):
72
+
73
+ # triggered from PR
74
+ if base_ref := os.getenv('GITHUB_BASE_REF'):
75
+ logging.info(f"Using GITHUB_BASE_REF:{base_ref} as base branch")
76
+ return f'origin/{base_ref}'
77
+ logging.info("GITHUB_BASE_REF is not available...")
78
+ if pr:
79
+ api = gh_api(repo=repo)
80
+ pr_obj = api.pulls.get(pr)
81
+ logging.info(
82
+ f"Using 'origin/{pr_obj.base.ref}' as base branch "
83
+ f"(received via GH API for PR#{pr})"
84
+ )
85
+ return f'origin/{pr_obj.base.ref}'
86
+
87
+ try:
88
+ logging.info(
89
+ "Trying to resolve base branch from repo.remotes.origin.refs.HEAD.reference.name..."
90
+ )
91
+ # 'origin/main', 'origin/master', etc
92
+ # Stopped working in github actions since 07/2025
93
+ return repo.remotes.origin.refs.HEAD.reference.name
94
+ except AttributeError:
95
+ try:
96
+ logging.info(
97
+ "Checking if repo has 'main' or 'master' branchs to use as --against branch..."
98
+ )
99
+ remote_refs = repo.remotes.origin.refs
100
+ for branch_name in ['main', 'master']:
101
+ if hasattr(remote_refs, branch_name):
102
+ return f'origin/{branch_name}'
103
+ except Exception:
104
+ pass
105
+
106
+ logging.error("Could not determine default branch from remote refs.")
107
+ raise ValueError("No default branch found in the repository.")
108
+
109
+
69
110
  def get_diff(
70
111
  repo: Repo = None,
71
112
  what: str = None,
72
113
  against: str = None,
73
114
  use_merge_base: bool = True,
115
+ pr: str | int = None
74
116
  ) -> PatchSet | list[PatchedFile]:
75
117
  repo = repo or Repo(".")
76
118
  if not against:
77
119
  # 'origin/main', 'origin/master', etc
78
- against = repo.remotes.origin.refs.HEAD.reference.name
120
+ against = get_base_branch(repo, pr=pr)
79
121
  if review_subject_is_index(what):
80
122
  what = None # working copy
81
123
  if use_merge_base:
@@ -175,7 +217,7 @@ def get_diff(
175
217
  )
176
218
  if file_path == DEV_NULL:
177
219
  continue
178
- if is_binary_file(repo, file_path.lstrip("b/")):
220
+ if is_binary_file(repo, file_path.removeprefix("b/")):
179
221
  logging.info(f"Skipping binary file: {patched_file.path}")
180
222
  continue
181
223
  non_binary_diff.append(patched_file)
@@ -230,6 +272,7 @@ def make_cr_summary(ctx: Context, **kwargs) -> str:
230
272
  diff=mc.tokenizing.fit_to_token_size(ctx.diff, ctx.config.max_code_tokens)[0],
231
273
  issues=ctx.report.issues,
232
274
  pipeline_out=ctx.pipeline_out,
275
+ env=Env,
233
276
  **ctx.config.prompt_vars,
234
277
  **kwargs,
235
278
  ).to_llm()
@@ -250,11 +293,12 @@ def _prepare(
250
293
  against: str = None,
251
294
  filters: str | list[str] = "",
252
295
  use_merge_base: bool = True,
296
+ pr: str | int = None,
253
297
  ):
254
298
  repo = repo or Repo(".")
255
299
  cfg = ProjectConfig.load_for_repo(repo)
256
300
  diff = get_diff(
257
- repo=repo, what=what, against=against, use_merge_base=use_merge_base
301
+ repo=repo, what=what, against=against, use_merge_base=use_merge_base, pr=pr,
258
302
  )
259
303
  diff = filter_diff(diff, filters)
260
304
  if not diff:
@@ -317,11 +361,17 @@ async def review(
317
361
  against: str = None,
318
362
  filters: str | list[str] = "",
319
363
  use_merge_base: bool = True,
320
- out_folder: str | PathLike | None = None,
364
+ out_folder: str | os.PathLike | None = None,
365
+ pr: str | int = None
321
366
  ):
322
367
  try:
323
368
  repo, cfg, diff, lines = _prepare(
324
- repo=repo, what=what, against=against, filters=filters, use_merge_base=use_merge_base
369
+ repo=repo,
370
+ what=what,
371
+ against=against,
372
+ filters=filters,
373
+ use_merge_base=use_merge_base,
374
+ pr=pr,
325
375
  )
326
376
  except NoChangesInContextError:
327
377
  logging.error("No changes to review")
@@ -377,10 +427,16 @@ def answer(
377
427
  use_merge_base: bool = True,
378
428
  use_pipeline: bool = True,
379
429
  prompt_file: str = None,
430
+ pr: str | int = None,
380
431
  ) -> str | None:
381
432
  try:
382
433
  repo, config, diff, lines = _prepare(
383
- repo=repo, what=what, against=against, filters=filters, use_merge_base=use_merge_base
434
+ repo=repo,
435
+ what=what,
436
+ against=against,
437
+ filters=filters,
438
+ use_merge_base=use_merge_base,
439
+ pr=pr
384
440
  )
385
441
  except NoChangesInContextError:
386
442
  logging.error("No changes to review")
gito/env.py CHANGED
@@ -1,3 +1,7 @@
1
+ from importlib.metadata import version
2
+
3
+
1
4
  class Env:
2
5
  logging_level: int = 1
3
6
  verbosity: int = 1
7
+ gito_version: str = version("gito.bot")
gito/gh_api.py CHANGED
@@ -2,7 +2,38 @@ import os
2
2
  import logging
3
3
 
4
4
  import requests
5
+ import git
5
6
  from fastcore.basics import AttrDict # objects returned by ghapi
7
+ from ghapi.core import GhApi
8
+
9
+ from .project_config import ProjectConfig
10
+ from .utils import extract_gh_owner_repo
11
+
12
+
13
+ def gh_api(
14
+ repo: git.Repo = None, # used to resolve owner/repo
15
+ config: ProjectConfig | None = None, # used to resolve owner/repo
16
+ token: str | None = None
17
+ ) -> GhApi:
18
+ if repo:
19
+ # resolve owner/repo from repo.remotes.origin.url
20
+ owner, repo_name = extract_gh_owner_repo(repo)
21
+ else:
22
+ if not config:
23
+ config = ProjectConfig.load()
24
+ # resolve owner/repo from github env vars (github actions)
25
+ gh_env = config.prompt_vars.get("github_env", {})
26
+ gh_repo = gh_env.get("github_repo")
27
+ if not gh_repo:
28
+ raise ValueError("GitHub repository not specified and not found in project config.")
29
+ parts = gh_repo.split('/')
30
+ if len(parts) != 2:
31
+ raise ValueError(f"Invalid GitHub repository format: {gh_repo}. Expected 'owner/repo'.")
32
+ owner, repo_name = parts
33
+
34
+ token = resolve_gh_token(token)
35
+ api = GhApi(owner, repo_name, token=token)
36
+ return api
6
37
 
7
38
 
8
39
  def resolve_gh_token(token_or_none: str | None = None) -> str | None:
@@ -7,4 +7,5 @@
7
7
  JIRA_URL: ${{ secrets.JIRA_URL }}
8
8
  JIRA_USER: ${{ secrets.JIRA_USER }}
9
9
  LINEAR_API_KEY: ${{ secrets.LINEAR_API_KEY }}
10
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
10
11
  {%- endraw %}
@@ -22,8 +22,8 @@ jobs:
22
22
  {%- include("github_workflows/components/env-vars.j2") %}
23
23
  PR_NUMBER_FROM_WORKFLOW_DISPATCH: {% raw %}${{ github.event.inputs.pr_number }}{% endraw %}
24
24
  run: |{% raw %}
25
- gito --verbose review ${{ github.event_name == 'pull_request' && github.event.pull_request.base.ref && format(' --against="origin/{0}"', github.event.pull_request.base.ref) || '' }}
26
- gito github-comment --token ${{ secrets.GITHUB_TOKEN }}{% endraw %}
25
+ gito --verbose review
26
+ gito github-comment{% endraw %}
27
27
 
28
28
  - uses: actions/upload-artifact@v4
29
29
  with:
@@ -67,4 +67,4 @@ jobs:
67
67
  # Otherwise, use LLM_API_TYPE: none
68
68
  {%- include("github_workflows/components/env-vars.j2") %}
69
69
  run: |
70
- {% raw %}gito react-to-comment ${{ github.event.comment.id }} --token ${{ secrets.GITHUB_TOKEN }}{%- endraw %}
70
+ {% raw %}gito react-to-comment ${{ github.event.comment.id }}{%- endraw %}
@@ -0,0 +1,55 @@
1
+ {{ self_id }}
2
+ ----TASK----
3
+
4
+ ## Subtask 1:
5
+ Write a codebase changes summary clearly describing and explaining it for the engineering managers.
6
+ - It is intended to be posted into bug tracker for estimating work done in the pull request.
7
+ - Summary should be in a form of compact changelist where each change is described by one sentence.
8
+ - Caption should be: ## PR Summary: <3-10 words>
9
+ - Each change summary BP list item should start from effort estimation icon:
10
+ - - ◆◇◇ (up to 2 hours)
11
+ - - ◆◆◇ (half day)
12
+ - - ◆◆◆ (1-2 days and more)
13
+
14
+ Also include this estimation legend below as "Pure Codebase Work Estimation Legend".
15
+
16
+
17
+ ## Subtask 1 (Issue alignment sentence)
18
+ Include one sentence about how the code changes address the requirements of the associated issue listed below.
19
+ - Use ✅ or ⚠️ to indicate whether the implementation fully satisfies the issue requirements.
20
+ - Put this sentence immediately below the PR Summary title
21
+ Examples:
22
+
23
+ If the implementation fully delivers the requested functionality:
24
+ ```
25
+ ✅ Implementation Satisfies [<ISSUE_KEY>](<ISSUE_URL>).
26
+ ```
27
+ If there are concerns about how thoroughly the code covers the requirements and technical description from the associated issue:
28
+ ```
29
+ ⚠️ <Describe specific gap or concern>.
30
+ ⚠️ <Describe additional limitation or missing feature>.
31
+ ```
32
+
33
+ ## Subtask 3:
34
+ Write release notes for public documentation.
35
+ - Caption should be: ## Release Notes Proposal
36
+ Summarize the following changes, focusing on what is new, improved, or fixed for the end user.
37
+ Do not include internal or technical details.
38
+ Structure release notes using clear sections: Added, Changed, Fixed.
39
+ Avoid internal technical jargon or developer-specific details.
40
+
41
+ ----RELATED CODEBASE CHANGES----
42
+ {% for part in diff %}{{ part }}\n{% endfor %}
43
+
44
+ ----FULL FILE CONTENT AFTER APPLYING CHANGES----
45
+ {% for file, file_lines in all_file_lines.items() %}
46
+ --FILE: {{ file }}--
47
+ {{ file_lines }}
48
+ {% endfor %}
49
+
50
+ {%- if pipeline_out.associated_issue and pipeline_out.associated_issue.title %}
51
+ ----ASSOCIATED ISSUE----
52
+ # {{ pipeline_out.associated_issue.title }}
53
+ {{ pipeline_out.associated_issue.description }}
54
+ URL: {{ pipeline_out.associated_issue.url }}
55
+ {%- endif -%}{{ '\n' }}
@@ -0,0 +1,23 @@
1
+ {{ self_id }}
2
+ ----TASK----
3
+ Create a concise comment for QA specialists that explains how to test the code-base changes.
4
+ Include:
5
+ - User journeys that could be disrupted by failures
6
+ - Relevant security scenarios and edge cases
7
+ - Potential risk areas introduced by the changes, with suggestions for focused testing to mitigate them
8
+
9
+ ----RELATED CODEBASE CHANGES----
10
+ {% for part in diff %}{{ part }}\n{% endfor %}
11
+
12
+ ----FULL FILE CONTENT AFTER APPLYING CHANGES----
13
+ {% for file, file_lines in all_file_lines.items() %}
14
+ --FILE: {{ file }}--
15
+ {{ file_lines }}
16
+ {% endfor %}
17
+
18
+ {%- if pipeline_out.associated_issue and pipeline_out.associated_issue.title %}
19
+ ----ASSOCIATED ISSUE----
20
+ # {{ pipeline_out.associated_issue.title }}
21
+ {{ pipeline_out.associated_issue.description }}
22
+ URL: {{ pipeline_out.associated_issue.url }}
23
+ {%- endif -%}{{ '\n' }}
File without changes
File without changes