All jobs

Fix Jira Bug Tickets With Pull Requests in a Django App

Yes. An agent reads the Jira bug, reproduces it with a Django TestCase, fixes the view or integration, opens a pull request and comments the link on the ticket.

Run this on RushIn a Project that has your repository.

What the agent does

A Jira automation rule sends the new bug's key and summary to a handler on your server, and the handler sends the request on this page. The agent clones the repository into its own cloud sandbox and reads the ticket through your Atlassian connection: the description, the reporter's environment and every comment. For a monitoring service the details that matter are usually in there, such as the exact ping URL, the HTTP method, the exit status in the path or which integration failed to deliver.

In a Django project like healthchecks/healthchecks, the ping API is a short list of routes in hc/api/urls.py: views.ping behind /ping/<uuid:code> with fail, start, log and <int:exitstatus> variants, and views.ping_by_slug for the same actions by project ping key and slug. ping in hc/api/views.py answers not found for an unknown check and invalid url format for an exit status above 255, and reads the client address from X-Forwarded-For before REMOTE_ADDR. Alert integrations live one per directory under hc/integrations/ (30 of them, from slack and webhook to telegram and opsgenie), each with a transport.py subclassing Transport or HttpTransport from hc/api/transports.py. The agent maps the ticket to one of these before it edits.

It reproduces the bug as a test next to the existing ones. The ping tests are in hc/api/tests/test_ping.py and test_ping_by_slug.py; each integration has its own tests/ folder with test_notify.py, which patches hc.api.transports.curl.request so no real request leaves the sandbox. Tests inherit BaseTestCase from hc/test.py, which sets up users, a project and API keys. The agent writes the failing case first, so the pull request can show it failing before the fix.

Then it fixes the code and runs python manage.py test, first for the one module and then for the whole suite. hc/settings.py uses SQLite unless the DB environment variable is postgres, mysql or mariadb, so the sandbox run is on SQLite. Once the suite passes it opens a pull request with the ticket key in the title and branch, and comments on the ticket with the pull request link and the cause in a sentence.

Start it with one API call

POST https://api.prix.dev/o/{org}/sessions with this body:

{
  "agent": "claude",
  "input": "A Jira bug ticket was created; its key and summary follow this prompt. Use the Atlassian connection to read the ticket, its description and all comments. Find the code in the ping API (hc/api/urls.py, ping and ping_by_slug in hc/api/views.py) or in the alert integration it names (hc/integrations/<name>/transport.py and hc/api/transports.py). Reproduce the bug with a failing Django TestCase that extends BaseTestCase from hc/test.py, in hc/api/tests/ or the integration's tests/ folder, patching hc.api.transports.curl.request as the existing notify tests do. Fix the code and run python manage.py test until it passes. Open a pull request with the ticket key in its title and branch name, then comment on the ticket with the pull request link and the cause in one sentence. If you cannot reproduce it, comment with what you tried and open no pull request.",
  "resources": [
    {
      "url": "https://github.com/your-org/your-app"
    }
  ]
}
  1. Get an API key. In the console, open Settings, then API keys, and create a key for your org. Send it in the Authorization header as a Bearer token.
  2. Send the request. POST the body in request.json to https://api.prix.dev/o/{org}/sessions, with your repository as the resources URL. The run starts in its own cloud sandbox.
  3. Read what came back. Follow the run on its live stream or wait for the run.completed webhook, then read the result and its trajectory.

What comes back

What comes back is a pull request named after the ticket. In healthchecks it typically changes one view in hc/api/views.py or one transport.py under hc/integrations/, and adds a test method to the matching test_ping.py, test_ping_by_slug.py or test_notify.py. The description restates the bug, names the file and function at fault, quotes the test that failed before the change, and gives the python manage.py test result.

The ticket gets one comment with the pull request link. The pull request's checks are your workflows: in healthchecks, tests.yml runs python manage.py test across SQLite, Postgres, MySQL and MariaDB and Python 3.12 to 3.15, and mypy.yml runs mypy --strict over hc. That matters here, because the sandbox run is on SQLite and a fix that touches a query has to pass on all four databases. The transcript keeps every command and its output.

Before merging, a reviewer checks that the new test fails on main, that a fix to one integration did not change the shared HttpTransport behaviour the others depend on, and that the type hints still satisfy mypy --strict. If the agent could not reproduce the bug, there is no pull request, and the ticket comment says what it tried.

Run it on every new Jira bug

Create a Jira automation rule: trigger "Work item created", condition issue type is Bug (narrow it with a component such as Ping API or Integrations if you like), action "Send web request" to your handler with {{issue.key}} and {{issue.summary}}. The handler appends them to input, names your Atlassian connection in connections, and sends one request per ticket.

With a webhook URL set on the API key, Rush POSTs run.completed or run.failed and the session_url when the agent's turn finishes. A key runs at most max_concurrent sessions at once (4 by default) and answers 429 past that.

The use case this job follows, with its automation and trigger: Fix a bug from an alert.

Why run it on Rush?

Fixing a Django bug well means running the suite, not reading code and guessing. In a Rush sandbox the agent installs requirements.txt (Django 6.1, pycurl and psycopg among them), creates the SQLite database the tests use and runs them on its own machine. Nothing installs on a developer's laptop, and each ticket starts from a clean clone instead of a branch someone was halfway through.

The proof travels with the result: the failing test and the passing run are in the transcript, the database matrix runs on the pull request, and the Jira comment points the reporter at it. A batch of tickets filed after a release each get their own sandbox and their own pull request, so one hard bug does not hold up the easy ones.

Frequently asked questions

Will the tests send real Slack or webhook notifications?

No. The integration tests patch hc.api.transports.curl.request, and the agent writes its test the same way. Nothing is delivered from the sandbox.

Does it test against Postgres or MySQL?

In the sandbox it runs on SQLite, the default in hc/settings.py. Put DB=postgres in the prompt if you want it to install Postgres and run the suite there too; otherwise the pull request's tests.yml matrix covers all four databases.

Can I put the Jira ticket URL in resources?

No. resources takes a GitHub repository or a Linear issue, and any other URL is 422 RESOURCE_UNSUPPORTED. Pass the ticket key in the prompt and name your Atlassian connection; the agent reads the ticket through it.

What if the bug is in a third-party service, not our code?

Then the test cannot fail for a reason in the repository. The prompt tells the agent to comment on the ticket with what it found, for example that the integration's API rejected the request, and to open no pull request.