Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .github/aicodingflow-tests/test_prepare_issue_spec_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

import argparse
import json
import subprocess
import sys
import tempfile
import unittest
from pathlib import Path
Expand All @@ -18,6 +20,24 @@


class PrepareIssueSpecContextTest(unittest.TestCase):
def test_issue_event_runs_without_installed_markdown_parser(self) -> None:
script_dir = Path(__file__).resolve().parents[1] / "scripts"
subprocess.run(
[
sys.executable, "-S", "-c",
"import argparse, sys; "
"sys.path.insert(0, sys.argv[1]); "
"from prepare_issue_spec_context import should_run; "
"args = argparse.Namespace(event_path='', event_name='workflow_dispatch', force=False, agent_login='codex'); "
"issue = {'labels': [{'name': 'ready-to-spec'}], 'assignees': [{'login': 'codex'}]}; "
"assert should_run(args, issue)[0] is True",
str(script_dir),
],
check=True,
capture_output=True,
text=True,
)

def test_spec_paths_use_issue_directory_and_spec_branch(self) -> None:
self.assertEqual(
prepare_issue_spec_context.spec_paths(32),
Expand Down
19 changes: 19 additions & 0 deletions .github/aicodingflow-tests/test_resolve_pr_event.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from __future__ import annotations

import json
import subprocess
import sys
import tempfile
import unittest
from pathlib import Path
Expand Down Expand Up @@ -95,6 +97,23 @@ def test_pull_request_event_reuses_existing_payload(self) -> None:
event,
)

def test_pull_request_event_runs_without_installed_markdown_parser(self) -> None:
with tempfile.TemporaryDirectory() as directory:
event_path = Path(directory) / "event.json"
output_path = Path(directory) / "resolved.json"
event_path.write_text(json.dumps({"pull_request": pr_payload()}), encoding="utf-8")
subprocess.run(
[
sys.executable, "-S", str(Path(__file__).resolve().parents[1] / "scripts/resolve_pr_event.py"),
"--repo", "owner/repo", "--event-name", "pull_request_target",
"--event-path", str(event_path), "--output", str(output_path),
],
check=True,
capture_output=True,
text=True,
)
self.assertTrue(output_path.is_file())

def test_pull_request_target_event_reuses_existing_payload(self) -> None:
with tempfile.TemporaryDirectory() as directory:
event_path = Path(directory) / "event.json"
Expand Down
16 changes: 16 additions & 0 deletions .github/aicodingflow-tests/test_review_workflow_dispatch.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ def test_pr_comment_jobs_install_markdown_parser_before_context(self) -> None:
for job in ("preflight", "respond"):
with self.subTest(job=job):
job_steps = steps(data, job)
setup = next(step for step in job_steps if step.get("name") == "set-up-python-for-markdown-parser")
install = next(step for step in job_steps if step.get("name") == "install-markdown-parser")
self.assertEqual(setup["uses"], "actions/setup-python@v6")
self.assertLess(job_steps.index(setup), job_steps.index(install))
self.assertIn("-r .github/scripts/requirements-spec-context.txt", install["run"])
context_index = next(i for i, step in enumerate(job_steps) if step.get("name") == "prepare-pr-comment-context")
self.assertLess(job_steps.index(install), context_index)
Expand All @@ -40,7 +43,12 @@ def test_pr_review_jobs_install_markdown_parser_before_resolving_event(self) ->
for job in ("preflight", "review"):
with self.subTest(job=job):
job_steps = steps(data, job)
setup = next(step for step in job_steps if step.get("name") == "set-up-python-for-markdown-parser")
install = next(step for step in job_steps if step.get("name") == "install-markdown-parser")
self.assertEqual(setup["uses"], "actions/setup-python@v6")
self.assertEqual(setup["if"], "github.event_name == 'issue_comment'")
self.assertEqual(install["if"], "github.event_name == 'issue_comment'")
self.assertLess(job_steps.index(setup), job_steps.index(install))
self.assertIn("-r .github/scripts/requirements-spec-context.txt", install["run"])
resolve_index = next(i for i, step in enumerate(job_steps) if step.get("name") == "resolve-pull-request")
self.assertLess(job_steps.index(install), resolve_index)
Expand Down Expand Up @@ -356,13 +364,21 @@ def test_create_spec_workflow_dispatches_review_after_pr_creation(self) -> None:

create_steps = steps(data, "create-spec")
parser_install = next(step for step in create_steps if step.get("name") == "install-markdown-parser")
parser_setup = next(step for step in create_steps if step.get("name") == "set-up-python-for-markdown-parser")
self.assertEqual(parser_setup["uses"], "actions/setup-python@v6")
self.assertEqual(parser_setup["if"], "github.event_name == 'issue_comment'")
self.assertEqual(parser_install["if"], "github.event_name == 'issue_comment'")
self.assertLess(create_steps.index(parser_setup), create_steps.index(parser_install))
self.assertIn("-r .github/scripts/requirements-spec-context.txt", parser_install["run"])
self.assertLess(
create_steps.index(parser_install),
next(index for index, step in enumerate(create_steps) if step.get("name") == "prepare-issue-context"),
)
ci_data = workflow(".github/workflows/ci.yml")
ci_install = next(step for step in steps(ci_data, "test") if step.get("name") == "install-python-test-dependencies")
ci_setup = next(step for step in steps(ci_data, "test") if step.get("name") == "set-up-python")
self.assertEqual(ci_setup["uses"], "actions/setup-python@v6")
self.assertLess(steps(ci_data, "test").index(ci_setup), steps(ci_data, "test").index(ci_install))
self.assertIn("-r .github/scripts/requirements-spec-context.txt", ci_install["run"])
handoff = next(step for step in create_steps if step.get("name") == "prepare-workflow-handoff-directory")
prepare = next(step for step in create_steps if step.get("name") == "prepare-issue-context")
Expand Down
4 changes: 2 additions & 2 deletions .github/scripts/prepare_issue_spec_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
from pathlib import Path
from typing import Any

from markdown_it import MarkdownIt

from artifact_contracts import load_json, write_github_output, write_json
from context_snapshot import flatten_pages, format_issue_comments, remove_triggering_comment
from github_api import fetch_default_branch, run_gh_json
Expand Down Expand Up @@ -127,6 +125,8 @@ def mask(match: re.Match[str]) -> str:
def comment_mentions_login(comment: str, login: str) -> bool:
if not login:
return False

from markdown_it import MarkdownIt
pattern = re.compile(rf"(?<![A-Za-z0-9-])@{re.escape(login)}(?![A-Za-z0-9-])")
quote_depth = 0
html = _VisibleHtml()
Expand Down
4 changes: 2 additions & 2 deletions .github/scripts/resolve_pr_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
from pathlib import Path
from typing import Any

from markdown_it import MarkdownIt

from artifact_contracts import write_github_output


Expand All @@ -37,6 +35,8 @@ def comment_has_agent_command(
if not isinstance(body, str) or not body.strip() or not agent_login.strip():
return False

from markdown_it import MarkdownIt

normalized_command = command.strip()
if not normalized_command.startswith("/"):
normalized_command = f"/{normalized_command}"
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ jobs:
with:
fetch-depth: 1

- name: set-up-python
uses: actions/setup-python@v6
with:
python-version: '3.12'

- name: install-python-test-dependencies
run: |
python3 -m venv "$RUNNER_TEMP/aicodingflow-venv"
Expand Down
7 changes: 7 additions & 0 deletions .github/workflows/create-spec-from-issue.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,14 @@ jobs:
fetch-depth: 0
ref: ${{ github.event.repository.default_branch }}

- name: set-up-python-for-markdown-parser
if: github.event_name == 'issue_comment'
uses: actions/setup-python@v6
with:
python-version: '3.12'

- name: install-markdown-parser
if: github.event_name == 'issue_comment'
run: |
python3 -m venv "$RUNNER_TEMP/aicodingflow-spec-venv"
"$RUNNER_TEMP/aicodingflow-spec-venv/bin/python" -m pip install \
Expand Down
10 changes: 10 additions & 0 deletions .github/workflows/respond-to-pr-comment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ jobs:
ref: ${{ github.event.repository.default_branch }}
persist-credentials: false

- name: set-up-python-for-markdown-parser
uses: actions/setup-python@v6
with:
python-version: '3.12'

- name: install-markdown-parser
run: |
python3 -m venv "$RUNNER_TEMP/aicodingflow-pr-comment-venv"
Expand Down Expand Up @@ -126,6 +131,11 @@ jobs:
ref: ${{ github.event.repository.default_branch }}
persist-credentials: false

- name: set-up-python-for-markdown-parser
uses: actions/setup-python@v6
with:
python-version: '3.12'

- name: install-markdown-parser
run: |
python3 -m venv "$RUNNER_TEMP/aicodingflow-pr-comment-venv"
Expand Down
14 changes: 14 additions & 0 deletions .github/workflows/review-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,14 @@ jobs:
with:
fetch-depth: 1

- name: set-up-python-for-markdown-parser
if: github.event_name == 'issue_comment'
uses: actions/setup-python@v6
with:
python-version: '3.12'

- name: install-markdown-parser
if: github.event_name == 'issue_comment'
run: |
python3 -m venv "$RUNNER_TEMP/aicodingflow-review-venv"
"$RUNNER_TEMP/aicodingflow-review-venv/bin/python" -m pip install \
Expand Down Expand Up @@ -120,7 +127,14 @@ jobs:
with:
fetch-depth: 1

- name: set-up-python-for-markdown-parser
if: github.event_name == 'issue_comment'
uses: actions/setup-python@v6
with:
python-version: '3.12'

- name: install-markdown-parser
if: github.event_name == 'issue_comment'
run: |
python3 -m venv "$RUNNER_TEMP/aicodingflow-review-venv"
"$RUNNER_TEMP/aicodingflow-review-venv/bin/python" -m pip install \
Expand Down
Loading