Skip to content

feat: Jenkins Base Integration#3015

Open
alabro-bm wants to merge 17 commits intosuperplanehq:mainfrom
alabro-bm:feature/superplane-2112-jenkins-base
Open

feat: Jenkins Base Integration#3015
alabro-bm wants to merge 17 commits intosuperplanehq:mainfrom
alabro-bm:feature/superplane-2112-jenkins-base

Conversation

@alabro-bm
Copy link
Contributor

@alabro-bm alabro-bm commented Feb 10, 2026

The basic integration for jenkins with two component:

  • Trigger Build
  • On Build Finished

Its important that the Notification Plugin has to be installed in jenkins to work with webhooks. Otherwise the pooling solution works as fallback.

Screenshot 2026-02-16 at 17 11 24 Screenshot 2026-02-16 at 15 54 57 Screenshot 2026-02-16 at 17 02 15 Screenshot 2026-02-16 at 17 01 48

Local testing note: The app runs inside Docker and blocks requests to private IP ranges by default
(BLOCKED_PRIVATE_IP_RANGES). To test with a local Jenkins instance, you need to either:

  • Set BLOCKED_PRIVATE_IP_RANGES=240.0.0.0/4 in .env to disable the private IP block
  • Connect the Jenkins container to the same Docker network and use the container hostname
  • Use ngrok to expose Jenkins on a public URL

This is a dev-only concern -- in production, Jenkins will have a public/routable URL.

Signed-off-by: alabro-bm <atanas.labroski@brightmarbles.io>
Signed-off-by: alabro-bm <atanas.labroski@brightmarbles.io>
@alabro-bm alabro-bm changed the title feat: Jenkins base integration feat: Jenkins Base Integration Feb 10, 2026
@alabro-bm alabro-bm marked this pull request as ready for review February 10, 2026 17:48
Signed-off-by: alabro-bm <atanas.labroski@brightmarbles.io>
@shiroyasha shiroyasha added the pr:stage-2/3 Needs to pass functional review label Feb 10, 2026
@shiroyasha shiroyasha self-assigned this Feb 10, 2026
@shiroyasha
Copy link
Collaborator

@alabro-bm does Jenkins supports setting up a webhook, either manually, or via an API?

Signed-off-by: alabro-bm <atanas.labroski@brightmarbles.io>
@alabro-bm
Copy link
Contributor Author

@alabro-bm does Jenkins supports setting up a webhook, either manually, or via an API?

yes it does, that is my next step and Im already on it

…2112-jenkins-base

Signed-off-by: alabro-bm <atanas.labroski@brightmarbles.io>

# Conflicts:
#	web_src/src/pages/workflowv2/mappers/index.ts
Signed-off-by: alabro-bm <atanas.labroski@brightmarbles.io>
Signed-off-by: alabro-bm <atanas.labroski@brightmarbles.io>
Signed-off-by: alabro-bm <atanas.labroski@brightmarbles.io>
@shiroyasha shiroyasha added pr:stage-3/3 Ready for full, in-depth, review and removed pr:stage-2/3 Needs to pass functional review labels Feb 12, 2026
return err
}

if err := ctx.ExecutionState.SetKV(buildJobKey, spec.Job); err != nil {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Webhook matches by non-unique job name, misrouting concurrent builds

High Severity

The execution KV stores the job name (spec.Job) via SetKV(buildJobKey, spec.Job), but the job name is not unique per execution. When the webhook handler calls FindExecutionByKV(buildJobKey, payload.Name), concurrent builds of the same job would share the same KV value, causing the webhook to match and complete the wrong execution with incorrect build results. Every other integration in the codebase (CircleCI, GitHub, Cursor) uses a unique per-execution ID for this purpose.

Additional Locations (1)

Fix in Cursor Fix in Web

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a known limitation. Jenkins doesn't provide a unique build ID at trigger time — the build number is only available after the build starts. We've documented this in the code. For the common case (one build at a time per job), the matching works correctly. We can improve this in the future by using the build number from the first webhook notification (STARTED phase) to refine the KV match.

Signed-off-by: alabro-bm <atanas.labroski@brightmarbles.io>
Signed-off-by: alabro-bm <atanas.labroski@brightmarbles.io>
…ed steps

Signed-off-by: alabro-bm <atanas.labroski@brightmarbles.io>
"url": payload.Build.FullURL,
"result": payload.Build.Status,
},
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Webhook path omits duration from build output

Low Severity

The HandleWebhook method emits build results without a duration field (lines 334–338), while the poll method includes duration (line 442). The documented example output and the ExampleOutput JSON both include duration, and the frontend mapper in trigger_build.tsx references build.duration to display it. This means the output schema is inconsistent depending on whether the result arrived via webhook or polling fallback, and the duration detail will silently be absent when webhooks are used.

Additional Locations (1)

Fix in Cursor Fix in Web

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Jenkins Notification Plugin payload doesn't include build duration — it's only available from the Jenkins Build API, which is what the polling fallback uses. This is a limitation of the plugin, not a bug in our code. The frontend gracefully handles the missing field (renders nothing if undefined).


// ListJobs returns all jobs from the Jenkins instance, flattening folder structures.
func (c *Client) ListJobs() ([]Job, error) {
requestURL := c.apiURL("/api/json?tree=jobs[name,fullName,url,color,_class,jobs[name,fullName,url,color,_class]]")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ListJobs query depth mismatches recursive flattening logic

Low Severity

The Jenkins tree query in ListJobs only fetches two levels of nesting, but flattenJobs recurses arbitrarily deep. A folder at level 2 whose children weren't fetched will have an empty Jobs slice and be incorrectly treated as a selectable leaf job by flattenJobs. Meanwhile, actual jobs at depth 3+ are silently invisible in the resource picker. This affects users with nested Jenkins folder structures.

Additional Locations (1)

Fix in Cursor Fix in Web

Signed-off-by: alabro-bm <atanas.labroski@brightmarbles.io>
Signed-off-by: alabro-bm <atanas.labroski@brightmarbles.io>
Signed-off-by: alabro-bm <atanas.labroski@brightmarbles.io>
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

Signed-off-by: alabro-bm <atanas.labroski@brightmarbles.io>
@shiroyasha
Copy link
Collaborator

Jenkins has the same UX problem as Jira and Linear. We need a solution for this until we move on. Assigning @AleksandarCole and @ropsii.

@shiroyasha shiroyasha added pr:stage-2/3 Needs to pass functional review and removed pr:stage-3/3 Ready for full, in-depth, review labels Feb 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

mkd pr:stage-2/3 Needs to pass functional review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants