Skip to content

Commit 04f6f67

Browse files
2293 - Jenkins component added
1 parent 4d9e775 commit 04f6f67

File tree

15 files changed

+813
-0
lines changed

15 files changed

+813
-0
lines changed

server/apps/server-app/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ dependencies {
223223
implementation(project(":server:libs:modules:components:infobip"))
224224
implementation(project(":server:libs:modules:components:insightly"))
225225
implementation(project(":server:libs:modules:components:intercom"))
226+
implementation(project(":server:libs:modules:components:jenkins"))
226227
implementation(project(":server:libs:modules:components:jira"))
227228
implementation(project(":server:libs:modules:components:jotform"))
228229
implementation(project(":server:libs:modules:components:json-file"))

server/ee/apps/worker-app/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ dependencies {
163163
implementation(project(":server:libs:modules:components:infobip"))
164164
implementation(project(":server:libs:modules:components:insightly"))
165165
implementation(project(":server:libs:modules:components:intercom"))
166+
implementation(project(":server:libs:modules:components:jenkins"))
166167
implementation(project(":server:libs:modules:components:jira"))
167168
implementation(project(":server:libs:modules:components:jotform"))
168169
implementation(project(":server:libs:modules:components:json-file"))
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
version="1.0"
2+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright 2025 ByteChef
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.bytechef.component.jenkins;
18+
19+
import static com.bytechef.component.definition.ComponentDsl.component;
20+
import static com.bytechef.component.definition.ComponentDsl.tool;
21+
22+
import com.bytechef.component.ComponentHandler;
23+
import com.bytechef.component.definition.ComponentCategory;
24+
import com.bytechef.component.definition.ComponentDefinition;
25+
import com.bytechef.component.jenkins.action.JenkinsCreateJobAction;
26+
import com.bytechef.component.jenkins.connection.JenkinsConnection;
27+
import com.bytechef.component.jenkins.trigger.JenkinsNewJobStatusNotificationTrigger;
28+
import com.google.auto.service.AutoService;
29+
30+
/**
31+
* @author Nikolina Spehar
32+
*/
33+
@AutoService(ComponentHandler.class)
34+
public class JenkinsComponentHandler implements ComponentHandler {
35+
36+
private static final ComponentDefinition COMPONENT_DEFINITION = component("jenkins")
37+
.title("Jenkins")
38+
.description(
39+
"Jenkins is leading open source automation server, Jenkins provides hundreds of plugins to support " +
40+
"building, deploying and automating any project.")
41+
.icon("path:assets/jenkins.svg")
42+
.categories(ComponentCategory.DEVELOPER_TOOLS)
43+
.actions(JenkinsCreateJobAction.ACTION_DEFINITION)
44+
.clusterElements(tool(JenkinsCreateJobAction.ACTION_DEFINITION))
45+
.connection(JenkinsConnection.CONNECTION_DEFINITION)
46+
.triggers(JenkinsNewJobStatusNotificationTrigger.TRIGGER_DEFINITION);
47+
48+
@Override
49+
public ComponentDefinition getDefinition() {
50+
return COMPONENT_DEFINITION;
51+
}
52+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Copyright 2025 ByteChef
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.bytechef.component.jenkins.action;
18+
19+
import static com.bytechef.component.definition.ComponentDsl.action;
20+
import static com.bytechef.component.definition.ComponentDsl.string;
21+
import static com.bytechef.component.jenkins.constant.JenkinsConstants.CONFIG_XML;
22+
import static com.bytechef.component.jenkins.constant.JenkinsConstants.NAME;
23+
24+
import com.bytechef.component.definition.ComponentDsl.ModifiableActionDefinition;
25+
import com.bytechef.component.definition.Context;
26+
import com.bytechef.component.definition.Context.Http.Body;
27+
import com.bytechef.component.definition.Parameters;
28+
29+
/**
30+
* @author Nikolina Spehar
31+
*/
32+
public class JenkinsCreateJobAction {
33+
34+
public static final ModifiableActionDefinition ACTION_DEFINITION = action("createJob")
35+
.title("Create Job")
36+
.description("Creates a new job.")
37+
.properties(
38+
string(NAME)
39+
.label("Name")
40+
.description("Name of the job.")
41+
.required(true),
42+
string(CONFIG_XML)
43+
.label("Config XML")
44+
.description("Content of the config.xml file.")
45+
.required(true))
46+
.perform(JenkinsCreateJobAction::perform);
47+
48+
private JenkinsCreateJobAction() {
49+
}
50+
51+
public static Object perform(Parameters inputParameters, Parameters connectionParameters, Context context) {
52+
context.http(http -> http.post("/createItem"))
53+
.header("Content-Type", "application/xml")
54+
.queryParameter(NAME, inputParameters.getRequiredString(NAME))
55+
.body(Body.of(inputParameters.getRequiredString(CONFIG_XML), "application/xml"))
56+
.execute();
57+
58+
return null;
59+
}
60+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright 2025 ByteChef
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.bytechef.component.jenkins.connection;
18+
19+
import static com.bytechef.component.definition.Authorization.PASSWORD;
20+
import static com.bytechef.component.definition.Authorization.USERNAME;
21+
import static com.bytechef.component.definition.ComponentDsl.authorization;
22+
import static com.bytechef.component.definition.ComponentDsl.connection;
23+
import static com.bytechef.component.definition.ComponentDsl.string;
24+
import static com.bytechef.component.jenkins.constant.JenkinsConstants.BASE_URI;
25+
26+
import com.bytechef.component.definition.Authorization.AuthorizationType;
27+
import com.bytechef.component.definition.ComponentDsl.ModifiableConnectionDefinition;
28+
29+
/**
30+
* @author Nikolina Spehar
31+
*/
32+
public class JenkinsConnection {
33+
34+
public static final ModifiableConnectionDefinition CONNECTION_DEFINITION = connection()
35+
.baseUri((connectionParameters, context) -> connectionParameters.getRequiredString(BASE_URI))
36+
.authorizations(
37+
authorization(AuthorizationType.BASIC_AUTH)
38+
.properties(
39+
string(USERNAME)
40+
.label("Username")
41+
.description("Jenkins username.")
42+
.required(true),
43+
string(PASSWORD)
44+
.label("API Token")
45+
.description("Jenkins API token.")
46+
.required(true),
47+
string(BASE_URI)
48+
.label("Base URI")
49+
.description("Complete base URI of your jenkins server.")
50+
.required(true)));
51+
52+
private JenkinsConnection() {
53+
}
54+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Copyright 2025 ByteChef
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.bytechef.component.jenkins.constant;
18+
19+
/**
20+
* @author Nikolina Spehar
21+
*/
22+
public class JenkinsConstants {
23+
24+
public static final String BASE_URI = "baseUri";
25+
public static final String CONFIG_XML = "configXml";
26+
public static final String NAME = "name";
27+
28+
private JenkinsConstants() {
29+
}
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/*
2+
* Copyright 2025 ByteChef
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.bytechef.component.jenkins.trigger;
18+
19+
import static com.bytechef.component.definition.ComponentDsl.array;
20+
import static com.bytechef.component.definition.ComponentDsl.integer;
21+
import static com.bytechef.component.definition.ComponentDsl.number;
22+
import static com.bytechef.component.definition.ComponentDsl.object;
23+
import static com.bytechef.component.definition.ComponentDsl.outputSchema;
24+
import static com.bytechef.component.definition.ComponentDsl.string;
25+
import static com.bytechef.component.definition.ComponentDsl.trigger;
26+
27+
import com.bytechef.component.definition.ComponentDsl.ModifiableTriggerDefinition;
28+
import com.bytechef.component.definition.Parameters;
29+
import com.bytechef.component.definition.TriggerContext;
30+
import com.bytechef.component.definition.TriggerDefinition.HttpHeaders;
31+
import com.bytechef.component.definition.TriggerDefinition.HttpParameters;
32+
import com.bytechef.component.definition.TriggerDefinition.TriggerType;
33+
import com.bytechef.component.definition.TriggerDefinition.WebhookBody;
34+
import com.bytechef.component.definition.TriggerDefinition.WebhookEnableOutput;
35+
import com.bytechef.component.definition.TriggerDefinition.WebhookMethod;
36+
import com.bytechef.component.definition.TypeReference;
37+
import java.util.Map;
38+
39+
/**
40+
* @author Nikolina Spehar
41+
*/
42+
public class JenkinsNewJobStatusNotificationTrigger {
43+
44+
public static final ModifiableTriggerDefinition TRIGGER_DEFINITION = trigger("newJobStatusNotification")
45+
.title("New Job Status Notification")
46+
.description("Triggers when job statuses are changed.")
47+
.type(TriggerType.STATIC_WEBHOOK)
48+
.output(
49+
outputSchema(
50+
object()
51+
.properties(
52+
string("name")
53+
.description("Name of the Jenkins job."),
54+
string("display_name")
55+
.description("Display name of the Jenkins job."),
56+
string("url")
57+
.description("URL of the Jenkins job."),
58+
object("build")
59+
.description("Jenkins job build.")
60+
.properties(
61+
string("full_url")
62+
.description("Full URL of the Jenkins job."),
63+
integer("number")
64+
.description("Number of the Jenkins job."),
65+
integer("queue_id")
66+
.description("Queue ID of the Jenkins job."),
67+
number("timestamp")
68+
.description("Timestamp of the Jenkins job notification."),
69+
integer("duration")
70+
.description("Duration of the Jenkins job."),
71+
string("phase")
72+
.description("Phase of the Jenkins job."),
73+
string("url")
74+
.description("URL of Jenkins job build."),
75+
object("scm")
76+
.properties(
77+
array("changes")
78+
.description("Changes of the Jenkins build."),
79+
array("culprits")
80+
.description("Culprits of the Jenkins build changes.")),
81+
string("log")
82+
.description("Log for the Jenkins job build."),
83+
string("notes")
84+
.description("Additional notes of the Jenkins job build."),
85+
object("artifacts")
86+
.description("Artifacts of Jenkins job build.")))))
87+
.webhookRequest(JenkinsNewJobStatusNotificationTrigger::webhookRequest);
88+
89+
private JenkinsNewJobStatusNotificationTrigger() {
90+
}
91+
92+
protected static Map<String, Object> webhookRequest(
93+
Parameters inputParameters, Parameters connectionParameters, HttpHeaders headers, HttpParameters parameters,
94+
WebhookBody body, WebhookMethod method, WebhookEnableOutput output, TriggerContext context) {
95+
96+
return body.getContent(new TypeReference<>() {});
97+
}
98+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
## Connection Setup
2+
3+
### Create Jenkins API Token
4+
5+
1. Click on **Manage Jenkins** icon.
6+
2. Click on **Users**.
7+
3. Click this icon on the user you want to create the API token for.
8+
4. Click on **Security**.
9+
5. Click on **Add new token**.
10+
6. Enter name of the token and then click on **Generate**.
11+
7. Copy token, you will not be able to see the whole token again.
12+
8. Click on **Done**.
13+
14+
<div style={{ position: 'relative', height:0, width: '100%', overflow: 'hidden', zIndex: 99999, boxSizing: 'border-box', paddingBottom: 'calc(50.05219207% + 32px)'}}>
15+
<iframe src="https://www.guidejar.com/embed/152dd033-4f42-4501-88cc-e6a5a4a2d4e2?type=1&controls=on" width="100%" height="100%" style={{height:'100%', position:'absolute', inset:0}} allowfullscreen frameborder="0"></iframe>
16+
</div>
17+
18+
## Trigger Setup
19+
20+
### Enable Notification Plugin
21+
22+
1. Click this icon.
23+
2. Click on **Plugins**.
24+
3. Click on **Available plugins**.
25+
4. Search for **notification**.
26+
5. Click on **Notification** from **Tikal Knowledge**. [Notification plugin link](https://plugins.jenkins.io/notification/)
27+
6. Click here.
28+
7. Click on **Install**.
29+
8. Wait for everything to finish downloading.
30+
9. Click on **Go back to the top page**.
31+
32+
<div style={{ position: 'relative', height:0, width: '100%', overflow: 'hidden', zIndex: 99999, boxSizing: 'border-box', paddingBottom: 'calc(50.05219207% + 32px)'}}>
33+
<iframe src="https://www.guidejar.com/embed/ef274d47-9a11-4394-afde-2b93679f73b2?type=1&controls=on" width="100%" height="100%" style={{height:'100%', position:'absolute', inset:0}} allowfullscreen frameborder="0"></iframe>
34+
</div>
35+
36+
### Trigger URL Setup
37+
38+
1. Select Jenkins job to which you want to connect the trigger to.
39+
2. Click this **Configure**.
40+
3. Click on **Add Endpoint**.
41+
4. Paste Webhook URL. See [Deploy documentation](https://docs.bytechef.io/automation/deploy) on how to get Webhook URL.
42+
5. Click on **Save**.
43+
44+
<div style={{ position: 'relative', height:0, width: '100%', overflow: 'hidden', zIndex: 99999, boxSizing: 'border-box', paddingBottom: 'calc(50.05219207% + 32px)'}}>
45+
<iframe src="https://www.guidejar.com/embed/41f291bd-ac7c-4cec-af6b-c5922be20ac0?type=1&controls=on" width="100%" height="100%" style={{height:'100%', position:'absolute', inset:0}} allowfullscreen frameborder="0"></iframe>
46+
</div>

0 commit comments

Comments
 (0)