All jobs

Fix Jira Bug Tickets With Pull Requests in a Spring Boot App

Yes. An agent reads the Jira bug, finds the Spring Boot service at fault, reproduces it with a JUnit test, fixes it and links the pull request on the ticket.

Run this on RushIn a Project that has your repository.

What the agent does

When a bug is filed, a Jira automation rule posts its 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, including the comments. In a system split into services the first question is which service owns the behaviour, and a ticket written from the UI ("the visit I added doesn't show on the pet") does not say; the agent answers it from the code.

In spring-petclinic/spring-petclinic-microservices the root pom.xml (parent spring-boot-starter-parent 4.0.1, java.version 17) builds eight modules: config, discovery and admin servers, the API gateway, a GenAI service, and the customers, vets and visits services. Owners and pets are in spring-petclinic-customers-service: OwnerResource under /owners and PetResource for /owners/{ownerId}/pets and owners/*/pets/{petId}. Visits are in spring-petclinic-visits-service, where VisitResource serves owners/*/pets/{petId}/visits and a batch read at pets/visits?petId=. The gateway's CustomersServiceClient and VisitsServiceClient combine the two for the UI, so a missing visit can be in the visits service, the gateway's merge, or the customers side.

The agent reads the endpoints the ticket touches closely, because the details are where bugs hide. PetResource.processUpdateForm takes PUT /owners/*/pets/{petId} but reads the pet id from the request body's id, not the path. Its private save sets the type only when findPetTypeById(typeId) finds one, so an unknown typeId leaves the old type in place with no error. Not-found cases throw ResourceNotFoundException, annotated @ResponseStatus(NOT_FOUND), while VisitResource.create saves a visit for any petId of at least 1 without asking the customers service whether the pet exists. The agent matches the ticket to one of these paths, or to another it finds, before changing code.

Then it writes a JUnit test that fails the way the ticket describes, in the module that owns the code. PetResourceTest and VisitResourceTest are @WebMvcTest slices with @ActiveProfiles("test") and the repositories as @MockitoBean, and each service has src/test/resources/application-test.yml, so the tests need neither the config server nor Eureka. It fixes the code, runs ./mvnw test for that module and then the whole build, opens a pull request with the ticket key in the title and branch, and comments on the ticket with the link.

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. Work out which service owns the behaviour: spring-petclinic-customers-service (OwnerResource, PetResource), spring-petclinic-visits-service (VisitResource), or the API gateway's CustomersServiceClient and VisitsServiceClient. Reproduce the bug with a failing JUnit test in that module, in the existing @WebMvcTest style with @ActiveProfiles(\"test\") and @MockitoBean repositories. Fix the code, run ./mvnw test -pl <module> and then ./mvnw test for the whole build until both pass. Open a pull request with the ticket key in its title and branch name, then comment on the ticket with the pull request link, the service that was at fault 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 that changes one service, and says which one in its first line. In PetClinic microservices that is usually a resource class under customers/web/ or visits/web/, or a client under the gateway's api/application/, plus a test method in the matching *ResourceTest.java or a new test beside it. The description explains why the bug lives in that service and not the others, shows the test that failed before the change and gives the ./mvnw test result.

The ticket gets one comment with the pull request link and the service name, which helps whoever triages the next bug of the same kind. On GitHub the pull request runs the repository's maven-build.yml, which builds every module with mvn -B package, so a fix in one service that breaks a contract the gateway depends on shows up in the gateway's tests. The transcript keeps every command and its output.

Before merging, a reviewer checks that the change does not alter the JSON shape another service or the UI reads (the gateway's DTOs such as PetDetails and VisitDetails mirror these responses), that a new 404 or 400 is handled by the gateway rather than becoming a 500 there, and that the new test fails on main. When 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 with trigger "Work item created", a condition on issue type Bug, and the action "Send web request" to your handler with {{issue.key}}, {{issue.summary}} and, if your project uses them, {{issue.components.name}}. The handler appends them to input, names your Atlassian connection in connections and sends one request per ticket; a component that already names the service saves the agent a step.

Give the API key a webhook URL and Rush POSTs run.completed or run.failed with the session_url when each 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?

Reproducing a bug in a multi-module Spring build means a JDK, the Maven wrapper resolving dependencies for eight modules, and knowing which module's tests to run. In a Rush sandbox the agent does that on its own machine; a developer's IDE, local Docker Compose stack and Maven cache stay as they were, and each ticket starts from a clean clone of main.

The proof is the test and where it lives: the transcript shows it failing in one module and the full build passing after the fix, the pull request's workflow builds every module again, and the Jira comment records which service owned the bug. Tickets that arrive together run in parallel, one sandbox each.

Frequently asked questions

Does it need the config server and Eureka running?

Not for the tests. Each service's application.yml imports the config server as optional:, and the test profile in application-test.yml is what the @WebMvcTest slices use. The agent only starts the whole system with Docker Compose if the bug cannot be shown in one service.

What if the bug spans two services?

The agent says so in the pull request and keeps the change in the service where the cause is, with a test there. If both sides need a change, it puts them in one pull request with a test in each module, because the build compiles and tests them together.

Can I send the Jira link in resources?

No. resources takes a GitHub repository or a Linear issue, and a Jira URL is 422 RESOURCE_UNSUPPORTED. Send the key in the prompt and name your Atlassian connection in connections.

Will it touch the GenAI service?

Only if the ticket is about it. spring-petclinic-genai-service is its own module, and the agent works in the module that owns the behaviour the ticket describes.