{
-
- public FormValidation doCheckName(@QueryParameter String value, @QueryParameter boolean useFrench)
- throws IOException, ServletException {
- if (value.length() == 0)
- return FormValidation.error(Messages.HelloWorldBuilder_DescriptorImpl_errors_missingName());
- if (value.length() < 4)
- return FormValidation.warning(Messages.HelloWorldBuilder_DescriptorImpl_warnings_tooShort());
- if (!useFrench && value.matches(".*[éáàç].*")) {
- return FormValidation.warning(Messages.HelloWorldBuilder_DescriptorImpl_warnings_reallyFrench());
- }
- return FormValidation.ok();
- }
-
- @Override
- public boolean isApplicable(Class extends AbstractProject> aClass) {
- return true;
- }
-
- @Override
- public String getDisplayName() {
- return Messages.HelloWorldBuilder_DescriptorImpl_DisplayName();
- }
- }
-}
diff --git a/src/main/resources/index.jelly b/src/main/resources/index.jelly
index 35f37a7..41fb7af 100644
--- a/src/main/resources/index.jelly
+++ b/src/main/resources/index.jelly
@@ -1,4 +1,7 @@
- TODO
-
+ ${%plugin.description}
+
+ ${%plugin.configuration}
+
+
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/config.jelly b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/config.jelly
new file mode 100644
index 0000000..d7c5ac6
--- /dev/null
+++ b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/config.jelly
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/config.properties b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/config.properties
new file mode 100644
index 0000000..e7f8c46
--- /dev/null
+++ b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/config.properties
@@ -0,0 +1,11 @@
+# English translations for CtrlplaneGlobalConfiguration
+config.apiUrl.title=API URL
+config.apiUrl.description=The URL of the Ctrlplane API (e.g., https://app.ctrlplane.dev)
+config.apiKey.title=API Key
+config.apiKey.description=The API key for authenticating with Ctrlplane
+config.agentId.title=Agent ID
+config.agentId.description=The unique identifier for this agent in Ctrlplane
+config.agentWorkspaceId.title=Agent Workspace ID
+config.agentWorkspaceId.description=The workspace ID for this agent in Ctrlplane
+config.pollingIntervalSeconds.title=Polling Interval (seconds)
+config.pollingIntervalSeconds.description=How often to check Ctrlplane for new jobs (minimum 10 seconds)
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/config_de.properties b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/config_de.properties
new file mode 100644
index 0000000..5032505
--- /dev/null
+++ b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/config_de.properties
@@ -0,0 +1,11 @@
+# German translations for CtrlplaneGlobalConfiguration
+config.apiUrl.title=API-URL
+config.apiUrl.description=Die Ctrlplane API-URL (z.B. https://app.ctrlplane.dev)
+config.apiKey.title=API-Schlüssel
+config.apiKey.description=Der API-Schlüssel zur Authentifizierung bei Ctrlplane
+config.agentId.title=Agent-ID
+config.agentId.description=Die eindeutige Kennung für diesen Agent in Ctrlplane
+config.agentWorkspaceId.title=Arbeitsbereich-ID
+config.agentWorkspaceId.description=Die Arbeitsbereich-ID für diesen Agent in Ctrlplane
+config.pollingIntervalSeconds.title=Abfrageintervall (Sekunden)
+config.pollingIntervalSeconds.description=Häufigkeit der Überprüfung auf neue Aufgaben in Ctrlplane (mindestens 10 Sekunden)
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/config_es.properties b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/config_es.properties
new file mode 100644
index 0000000..f552eab
--- /dev/null
+++ b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/config_es.properties
@@ -0,0 +1,11 @@
+# Spanish translations for CtrlplaneGlobalConfiguration
+config.apiUrl.title=URL de API
+config.apiUrl.description=La URL de la API de Ctrlplane (ej. https://app.ctrlplane.dev)
+config.apiKey.title=Clave de API
+config.apiKey.description=La clave de API para autenticarse con Ctrlplane
+config.agentId.title=ID de Agente
+config.agentId.description=El identificador único para este agente en Ctrlplane
+config.agentWorkspaceId.title=ID de Espacio de Trabajo
+config.agentWorkspaceId.description=El ID del espacio de trabajo para este agente en Ctrlplane
+config.pollingIntervalSeconds.title=Intervalo de Sondeo (segundos)
+config.pollingIntervalSeconds.description=Frecuencia de comprobación de nuevas tareas en Ctrlplane (mínimo 10 segundos)
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/config_fr.properties b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/config_fr.properties
new file mode 100644
index 0000000..86f7080
--- /dev/null
+++ b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/config_fr.properties
@@ -0,0 +1,11 @@
+# French translations for CtrlplaneGlobalConfiguration
+config.apiUrl.title=URL de l'API
+config.apiUrl.description=L'URL de l'API Ctrlplane (ex. https://app.ctrlplane.dev)
+config.apiKey.title=Clé API
+config.apiKey.description=La clé API pour s'authentifier auprès de Ctrlplane
+config.agentId.title=ID de l'Agent
+config.agentId.description=L'identifiant unique pour cet agent dans Ctrlplane
+config.agentWorkspaceId.title=ID de l'Espace de Travail
+config.agentWorkspaceId.description=L'ID de l'espace de travail pour cet agent dans Ctrlplane
+config.pollingIntervalSeconds.title=Intervalle de Polling (secondes)
+config.pollingIntervalSeconds.description=Fréquence de vérification des nouvelles tâches dans Ctrlplane (minimum 10 secondes)
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/config_it.properties b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/config_it.properties
new file mode 100644
index 0000000..7330b72
--- /dev/null
+++ b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/config_it.properties
@@ -0,0 +1,11 @@
+# Italian translations for CtrlplaneGlobalConfiguration
+config.apiUrl.title=URL API
+config.apiUrl.description=L'URL API di Ctrlplane (es. https://app.ctrlplane.dev)
+config.apiKey.title=Chiave API
+config.apiKey.description=La chiave API per autenticarsi con Ctrlplane
+config.agentId.title=ID Agente
+config.agentId.description=L'identificatore unico per questo agente in Ctrlplane
+config.agentWorkspaceId.title=ID Area di Lavoro
+config.agentWorkspaceId.description=L'ID dell'area di lavoro per questo agente in Ctrlplane
+config.pollingIntervalSeconds.title=Intervallo di Polling (secondi)
+config.pollingIntervalSeconds.description=Frequenza di verifica di nuove attività in Ctrlplane (minimo 10 secondi)
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/config_pt_BR.properties b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/config_pt_BR.properties
new file mode 100644
index 0000000..0fcd9cd
--- /dev/null
+++ b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/config_pt_BR.properties
@@ -0,0 +1,11 @@
+# Portuguese (Brazil) translations for CtrlplaneGlobalConfiguration
+config.apiUrl.title=URL da API
+config.apiUrl.description=A URL da API Ctrlplane (ex. https://app.ctrlplane.dev)
+config.apiKey.title=Chave API
+config.apiKey.description=A chave de API para autenticação com Ctrlplane
+config.agentId.title=ID do Agente
+config.agentId.description=O identificador único para este agente no Ctrlplane
+config.agentWorkspaceId.title=ID do Espaço de Trabalho
+config.agentWorkspaceId.description=O ID do espaço de trabalho para este agente no Ctrlplane
+config.pollingIntervalSeconds.title=Intervalo de Verificação (segundos)
+config.pollingIntervalSeconds.description=Frequência de verificação de novas tarefas no Ctrlplane (mínimo 10 segundos)
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/config_sv.properties b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/config_sv.properties
new file mode 100644
index 0000000..ad5a938
--- /dev/null
+++ b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/config_sv.properties
@@ -0,0 +1,11 @@
+# Swedish translations for CtrlplaneGlobalConfiguration
+config.apiUrl.title=API URL
+config.apiUrl.description=URL:en till Ctrlplane API (t.ex. https://app.ctrlplane.dev)
+config.apiKey.title=API-nyckel
+config.apiKey.description=API-nyckeln för autentisering mot Ctrlplane
+config.agentId.title=Agent-ID
+config.agentId.description=Den unika identifieraren för denna agent i Ctrlplane
+config.agentWorkspaceId.title=Arbetsområdes-ID
+config.agentWorkspaceId.description=Arbetsområdets ID för denna agent i Ctrlplane
+config.pollingIntervalSeconds.title=Pollningsintervall (sekunder)
+config.pollingIntervalSeconds.description=Hur ofta Ctrlplane kontrolleras för nya jobb (minimum 10 sekunder)
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/config_tr.properties b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/config_tr.properties
new file mode 100644
index 0000000..b140293
--- /dev/null
+++ b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/config_tr.properties
@@ -0,0 +1,11 @@
+# Turkish translations for CtrlplaneGlobalConfiguration
+config.apiUrl.title=API URL
+config.apiUrl.description=Ctrlplane API URL'si (örn. https://app.ctrlplane.dev)
+config.apiKey.title=API Anahtarı
+config.apiKey.description=Ctrlplane ile kimlik doğrulama için API anahtarı
+config.agentId.title=Ajan ID
+config.agentId.description=Bu ajanın Ctrlplane'deki benzersiz tanımlayıcısı
+config.agentWorkspaceId.title=Ajan Çalışma Alanı ID
+config.agentWorkspaceId.description=Bu ajanın Ctrlplane'deki çalışma alanı ID'si
+config.pollingIntervalSeconds.title=Yoklama Aralığı (saniye)
+config.pollingIntervalSeconds.description=Yeni işler için Ctrlplane'i kontrol etme sıklığı (minimum 10 saniye)
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/config_zh_CN.properties b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/config_zh_CN.properties
new file mode 100644
index 0000000..256c412
--- /dev/null
+++ b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/config_zh_CN.properties
@@ -0,0 +1,11 @@
+# Simplified Chinese translations for CtrlplaneGlobalConfiguration
+config.apiUrl.title=API 地址
+config.apiUrl.description=Ctrlplane API 的地址(例如:https://app.ctrlplane.dev)
+config.apiKey.title=API 密钥
+config.apiKey.description=用于 Ctrlplane 身份验证的 API 密钥
+config.agentId.title=代理 ID
+config.agentId.description=此代理在 Ctrlplane 中的唯一标识符
+config.agentWorkspaceId.title=代理工作区 ID
+config.agentWorkspaceId.description=此代理在 Ctrlplane 中的工作区 ID
+config.pollingIntervalSeconds.title=轮询间隔(秒)
+config.pollingIntervalSeconds.description=检查 Ctrlplane 新任务的频率(最小 10 秒)
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiKey.html b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiKey.html
new file mode 100644
index 0000000..c177213
--- /dev/null
+++ b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiKey.html
@@ -0,0 +1,4 @@
+
+
Enter your Ctrlplane API key here. This key is used to authenticate your Jenkins instance with Ctrlplane.
+
You can obtain this key from your Ctrlplane account settings page.
+
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiKey_de.html b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiKey_de.html
new file mode 100644
index 0000000..43ba75b
--- /dev/null
+++ b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiKey_de.html
@@ -0,0 +1,4 @@
+
+
Geben Sie hier Ihren Ctrlplane API-Schlüssel ein. Dieser Schlüssel wird verwendet, um Ihre Jenkins-Instanz bei Ctrlplane zu authentifizieren.
+
Sie können diesen Schlüssel auf Ihrer Ctrlplane-Kontoeinstellungsseite erhalten.
+
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiKey_es.html b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiKey_es.html
new file mode 100644
index 0000000..578595d
--- /dev/null
+++ b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiKey_es.html
@@ -0,0 +1,4 @@
+
+
Introduzca su clave de API de Ctrlplane aquí. Esta clave se utiliza para autenticar su instancia de Jenkins con Ctrlplane.
+
Puede obtener esta clave en la página de configuración de su cuenta de Ctrlplane.
+
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiKey_fr.html b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiKey_fr.html
new file mode 100644
index 0000000..a13814b
--- /dev/null
+++ b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiKey_fr.html
@@ -0,0 +1,4 @@
+
+
Entrez votre clé API Ctrlplane ici. Cette clé est utilisée pour authentifier votre instance Jenkins avec Ctrlplane.
+
Vous pouvez obtenir cette clé depuis la page des paramètres de votre compte Ctrlplane.
+
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiKey_it.html b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiKey_it.html
new file mode 100644
index 0000000..ba19d2e
--- /dev/null
+++ b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiKey_it.html
@@ -0,0 +1,4 @@
+
+
Inserisci qui la tua chiave API Ctrlplane. Questa chiave viene utilizzata per autenticare la tua istanza Jenkins con Ctrlplane.
+
Puoi ottenere questa chiave dalla pagina delle impostazioni del tuo account Ctrlplane.
+
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiKey_pt_BR.html b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiKey_pt_BR.html
new file mode 100644
index 0000000..8106de9
--- /dev/null
+++ b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiKey_pt_BR.html
@@ -0,0 +1,4 @@
+
+
Digite sua chave de API Ctrlplane aqui. Esta chave é usada para autenticar sua instância Jenkins com Ctrlplane.
+
Você pode obter esta chave na página de configurações da sua conta Ctrlplane.
+
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiKey_sv.html b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiKey_sv.html
new file mode 100644
index 0000000..747bc23
--- /dev/null
+++ b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiKey_sv.html
@@ -0,0 +1,4 @@
+
+
Ange din Ctrlplane API-nyckel här. Denna nyckel används för att autentisera din Jenkins-instans med Ctrlplane.
+
Du kan få denna nyckel från din Ctrlplane-kontoinställningssida.
+
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiKey_tr.html b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiKey_tr.html
new file mode 100644
index 0000000..7fbd853
--- /dev/null
+++ b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiKey_tr.html
@@ -0,0 +1,4 @@
+
+
Ctrlplane API anahtarınızı buraya girin. Bu anahtar, Jenkins örneğinizi Ctrlplane ile doğrulamak için kullanılır.
+
Bu anahtarı Ctrlplane hesap ayarları sayfanızdan alabilirsiniz.
+
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiKey_zh_CN.html b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiKey_zh_CN.html
new file mode 100644
index 0000000..7c4b346
--- /dev/null
+++ b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiKey_zh_CN.html
@@ -0,0 +1,4 @@
+
+
在此输入您的 Ctrlplane API 密钥。此密钥用于向 Ctrlplane 验证您的 Jenkins 实例。
+
您可以从 Ctrlplane 账户设置页面获取此密钥。
+
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiUrl.html b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiUrl.html
new file mode 100644
index 0000000..73600d5
--- /dev/null
+++ b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiUrl.html
@@ -0,0 +1,3 @@
+
+ The URL of the Ctrlplane API. If left blank, the default URL (https://app.ctrlplane.dev) will be used.
+
diff --git a/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiUrl_de.html b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiUrl_de.html
new file mode 100644
index 0000000..5c7e82c
--- /dev/null
+++ b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiUrl_de.html
@@ -0,0 +1,3 @@
+
+ Die URL der Ctrlplane API. Wenn leer gelassen, wird die Standard-URL (https://app.ctrlplane.dev) verwendet.
+
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiUrl_es.html b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiUrl_es.html
new file mode 100644
index 0000000..299439a
--- /dev/null
+++ b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiUrl_es.html
@@ -0,0 +1,3 @@
+
+ La URL de la API de Ctrlplane. Si se deja en blanco, se utilizará la URL predeterminada (https://app.ctrlplane.dev).
+
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiUrl_fr.html b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiUrl_fr.html
new file mode 100644
index 0000000..40e3fef
--- /dev/null
+++ b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiUrl_fr.html
@@ -0,0 +1,3 @@
+
+ L'URL de l'API Ctrlplane. Si laissé vide, l'URL par défaut (https://app.ctrlplane.dev) sera utilisée.
+
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiUrl_it.html b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiUrl_it.html
new file mode 100644
index 0000000..6f0e28d
--- /dev/null
+++ b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiUrl_it.html
@@ -0,0 +1,3 @@
+
+ L'URL dell'API Ctrlplane. Se lasciato vuoto, verrà utilizzato l'URL predefinito (https://app.ctrlplane.dev).
+
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiUrl_pt_BR.html b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiUrl_pt_BR.html
new file mode 100644
index 0000000..8ad3606
--- /dev/null
+++ b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiUrl_pt_BR.html
@@ -0,0 +1,3 @@
+
+ A URL da API Ctrlplane. Se deixado em branco, a URL padrão (https://app.ctrlplane.dev) será usada.
+
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiUrl_sv.html b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiUrl_sv.html
new file mode 100644
index 0000000..14fd44b
--- /dev/null
+++ b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiUrl_sv.html
@@ -0,0 +1,3 @@
+
+ URL:en till Ctrlplane API. Om den lämnas tom kommer standard-URL:en (https://app.ctrlplane.dev) att användas.
+
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiUrl_tr.html b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiUrl_tr.html
new file mode 100644
index 0000000..999f49d
--- /dev/null
+++ b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiUrl_tr.html
@@ -0,0 +1,3 @@
+
+ Ctrlplane API URL'si. Boş bırakılırsa, varsayılan URL (https://app.ctrlplane.dev) kullanılacaktır.
+
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiUrl_zh_CN.html b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiUrl_zh_CN.html
new file mode 100644
index 0000000..096bdfa
--- /dev/null
+++ b/src/main/resources/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfiguration/help-apiUrl_zh_CN.html
@@ -0,0 +1,3 @@
+
+ Ctrlplane API 的地址。如果留空,将使用默认地址(https://app.ctrlplane.dev)。
+
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/ctrlplane/Messages.properties b/src/main/resources/io/jenkins/plugins/ctrlplane/Messages.properties
new file mode 100644
index 0000000..c5f3fdb
--- /dev/null
+++ b/src/main/resources/io/jenkins/plugins/ctrlplane/Messages.properties
@@ -0,0 +1,2 @@
+plugin.description=This plugin integrates Jenkins with Ctrlplane for triggering and monitoring jobs.
+plugin.configuration=Configuration for this plugin is managed globally. Go to Manage Jenkins > System and find the Ctrlplane Agent Plugin section.
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/ctrlplane/Messages_de.properties b/src/main/resources/io/jenkins/plugins/ctrlplane/Messages_de.properties
new file mode 100644
index 0000000..4f53782
--- /dev/null
+++ b/src/main/resources/io/jenkins/plugins/ctrlplane/Messages_de.properties
@@ -0,0 +1,2 @@
+plugin.description=Dieses Plugin integriert Jenkins mit Ctrlplane zum Auslösen und Überwachen von Jobs.
+plugin.configuration=Die Konfiguration für dieses Plugin wird global verwaltet. Gehen Sie zu Jenkins verwalten > System und finden Sie den Abschnitt Ctrlplane Agent Plugin.
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/ctrlplane/Messages_es.properties b/src/main/resources/io/jenkins/plugins/ctrlplane/Messages_es.properties
new file mode 100644
index 0000000..ec513c6
--- /dev/null
+++ b/src/main/resources/io/jenkins/plugins/ctrlplane/Messages_es.properties
@@ -0,0 +1,2 @@
+plugin.description=Este plugin integra Jenkins con Ctrlplane para activar y monitorear trabajos.
+plugin.configuration=La configuración de este plugin se gestiona globalmente. Vaya a Administrar Jenkins > Sistema y busque la sección Plugin de Agente Ctrlplane.
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/ctrlplane/Messages_fr.properties b/src/main/resources/io/jenkins/plugins/ctrlplane/Messages_fr.properties
new file mode 100644
index 0000000..bd2c6fe
--- /dev/null
+++ b/src/main/resources/io/jenkins/plugins/ctrlplane/Messages_fr.properties
@@ -0,0 +1,2 @@
+plugin.description=Ce plugin intègre Jenkins avec Ctrlplane pour déclencher et surveiller les tâches.
+plugin.configuration=La configuration de ce plugin est gérée globalement. Allez dans Administrer Jenkins > Système et trouvez la section Plugin Agent Ctrlplane.
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/ctrlplane/Messages_it.properties b/src/main/resources/io/jenkins/plugins/ctrlplane/Messages_it.properties
new file mode 100644
index 0000000..a0f401f
--- /dev/null
+++ b/src/main/resources/io/jenkins/plugins/ctrlplane/Messages_it.properties
@@ -0,0 +1,2 @@
+plugin.description=Questo plugin integra Jenkins con Ctrlplane per l'attivazione e il monitoraggio dei lavori.
+plugin.configuration=La configurazione di questo plugin è gestita globalmente. Vai su Gestisci Jenkins > Sistema e trova la sezione Plugin Agente Ctrlplane.
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/ctrlplane/Messages_pt_BR.properties b/src/main/resources/io/jenkins/plugins/ctrlplane/Messages_pt_BR.properties
new file mode 100644
index 0000000..e42621d
--- /dev/null
+++ b/src/main/resources/io/jenkins/plugins/ctrlplane/Messages_pt_BR.properties
@@ -0,0 +1,2 @@
+plugin.description=Este plugin integra o Jenkins com o Ctrlplane para disparar e monitorar tarefas.
+plugin.configuration=A configuração deste plugin é gerenciada globalmente. Vá para Gerenciar Jenkins > Sistema e encontre a seção Plugin do Agente Ctrlplane.
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/ctrlplane/Messages_sv.properties b/src/main/resources/io/jenkins/plugins/ctrlplane/Messages_sv.properties
new file mode 100644
index 0000000..fade712
--- /dev/null
+++ b/src/main/resources/io/jenkins/plugins/ctrlplane/Messages_sv.properties
@@ -0,0 +1,2 @@
+plugin.description=Detta plugin integrerar Jenkins med Ctrlplane för att utlösa och övervaka jobb.
+plugin.configuration=Konfigurationen för detta plugin hanteras globalt. Gå till Hantera Jenkins > System och hitta avsnittet Ctrlplane Agent Plugin.
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/ctrlplane/Messages_tr.properties b/src/main/resources/io/jenkins/plugins/ctrlplane/Messages_tr.properties
new file mode 100644
index 0000000..672567f
--- /dev/null
+++ b/src/main/resources/io/jenkins/plugins/ctrlplane/Messages_tr.properties
@@ -0,0 +1,2 @@
+plugin.description=Bu eklenti, işleri tetiklemek ve izlemek için Jenkins'i Ctrlplane ile entegre eder.
+plugin.configuration=Bu eklenti için yapılandırma genel olarak yönetilir. Jenkins'i Yönet > Sistem'e gidin ve Ctrlplane Ajan Eklentisi bölümünü bulun.
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/ctrlplane/Messages_zh_CN.properties b/src/main/resources/io/jenkins/plugins/ctrlplane/Messages_zh_CN.properties
new file mode 100644
index 0000000..7465e22
--- /dev/null
+++ b/src/main/resources/io/jenkins/plugins/ctrlplane/Messages_zh_CN.properties
@@ -0,0 +1,2 @@
+plugin.description=此插件将 Jenkins 与 Ctrlplane 集成,用于触发和监控作业。
+plugin.configuration=此插件的配置在全局管理。转到 管理 Jenkins > 系统 并找到 Ctrlplane 代理插件 部分。
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/config.jelly b/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/config.jelly
deleted file mode 100644
index e97fba0..0000000
--- a/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/config.jelly
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/config.properties b/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/config.properties
deleted file mode 100644
index 7ebd98b..0000000
--- a/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/config.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-Name=Name
-French=French
-FrenchDescr=Check if we should say hello in French
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/config_de.properties b/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/config_de.properties
deleted file mode 100644
index abaf008..0000000
--- a/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/config_de.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-Name=Name
-French=Franz\u00F6sisch
-FrenchDescr=Markieren f\u00FCr Begr\u00FC\u00DFung auf franz\u00F6sisch
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/config_es.properties b/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/config_es.properties
deleted file mode 100644
index d3306b6..0000000
--- a/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/config_es.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-Name=Nombre
-French=Franc\u00E9s
-FrenchDescr=Compruebe si debemos decir hola en franc\u00E9s
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/config_fr.properties b/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/config_fr.properties
deleted file mode 100644
index 393218b..0000000
--- a/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/config_fr.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-Name=Nom
-French=Fran\u00e7ais
-FrenchDescr=V\u00e9rifie qu'on dit bien hello en fran\u00e7ais
diff --git a/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/config_it.properties b/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/config_it.properties
deleted file mode 100644
index 94fdb64..0000000
--- a/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/config_it.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-Name=Nome
-French=Francese
-FrenchDescr=Mostra il messagio in francese
diff --git a/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/config_pt_BR.properties b/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/config_pt_BR.properties
deleted file mode 100644
index c1aa4da..0000000
--- a/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/config_pt_BR.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-Name=Nome
-French=Franc\u00EAs
-FrenchDescr=Marque se devemos falar ol\u00E1 em franc\u00EAs
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/config_sv.properties b/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/config_sv.properties
deleted file mode 100644
index bbab3b3..0000000
--- a/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/config_sv.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-Name=Namn
-French=Franska
-FrenchDescr=S\u00E4tt om vi ska s\u00E4ga hej p\u00E5 Franska
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/config_tr.properties b/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/config_tr.properties
deleted file mode 100644
index 9651121..0000000
--- a/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/config_tr.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-Name=\u0130sim
-French=Frans\u0131zca
-FrenchDescr=Frans\u0131zca olarak merhaba demeliyim diye sor
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/config_zh_CN.properties b/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/config_zh_CN.properties
deleted file mode 100644
index ea63c18..0000000
--- a/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/config_zh_CN.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-Name=\u540d\u5b57
-French=\u6cd5\u8bed
-FrenchDescr=\u68c0\u67e5\u6211\u4eec\u662f\u5426\u5e94\u8be5\u7528\u6cd5\u8bed\u6253\u4e2a\u62db\u547c
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/help-name.html b/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/help-name.html
deleted file mode 100644
index e712210..0000000
--- a/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/help-name.html
+++ /dev/null
@@ -1,3 +0,0 @@
-
- Your name.
-
diff --git a/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/help-name_de.html b/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/help-name_de.html
deleted file mode 100644
index 3521ace..0000000
--- a/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/help-name_de.html
+++ /dev/null
@@ -1,3 +0,0 @@
-
- Geben Sie Ihren Namen ein.
-
diff --git a/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/help-useFrench.html b/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/help-useFrench.html
deleted file mode 100644
index b4eadd6..0000000
--- a/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/help-useFrench.html
+++ /dev/null
@@ -1,3 +0,0 @@
-
- Use French?
-
diff --git a/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/help-useFrench_de.html b/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/help-useFrench_de.html
deleted file mode 100644
index 96b2698..0000000
--- a/src/main/resources/io/jenkins/plugins/sample/HelloWorldBuilder/help-useFrench_de.html
+++ /dev/null
@@ -1,3 +0,0 @@
-
- Ob die Begrüßung auf französisch angegeben werden soll.
-
diff --git a/src/main/resources/io/jenkins/plugins/sample/Messages.properties b/src/main/resources/io/jenkins/plugins/sample/Messages.properties
deleted file mode 100644
index eb02a09..0000000
--- a/src/main/resources/io/jenkins/plugins/sample/Messages.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-HelloWorldBuilder.DescriptorImpl.errors.missingName=Please set a name
-HelloWorldBuilder.DescriptorImpl.warnings.tooShort=Isn't the name too short?
-HelloWorldBuilder.DescriptorImpl.warnings.reallyFrench=Are you actually French?
-
-HelloWorldBuilder.DescriptorImpl.DisplayName=Say hello world
\ No newline at end of file
diff --git a/src/main/resources/io/jenkins/plugins/sample/Messages_de.properties b/src/main/resources/io/jenkins/plugins/sample/Messages_de.properties
deleted file mode 100644
index 4b85c2d..0000000
--- a/src/main/resources/io/jenkins/plugins/sample/Messages_de.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-HelloWorldBuilder.DescriptorImpl.errors.missingName=Bitte geben Sie einen Namen an
-HelloWorldBuilder.DescriptorImpl.warnings.tooShort=Der Name ist zu kurz.
-HelloWorldBuilder.DescriptorImpl.warnings.reallyFrench=Sind Sie wirklich französisch?
-
-HelloWorldBuilder.DescriptorImpl.DisplayName="Hallo Welt" sagen
diff --git a/src/test/java/io/jenkins/plugins/ctrlplane/CtrlplaneConfigChangeTest.java b/src/test/java/io/jenkins/plugins/ctrlplane/CtrlplaneConfigChangeTest.java
new file mode 100644
index 0000000..2205689
--- /dev/null
+++ b/src/test/java/io/jenkins/plugins/ctrlplane/CtrlplaneConfigChangeTest.java
@@ -0,0 +1,183 @@
+package io.jenkins.plugins.ctrlplane;
+
+import static org.junit.Assert.*;
+
+import io.jenkins.plugins.ctrlplane.api.JobAgent;
+import java.util.Objects;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Tests that configuration changes are properly detected and handled.
+ */
+@RunWith(JUnit4.class)
+public class CtrlplaneConfigChangeTest {
+
+ /**
+ * Test configuration class that mirrors CtrlplaneConfig
+ */
+ private static class TestConfig {
+ public String apiUrl;
+ public String apiKey;
+ public String agentName;
+ public String agentWorkspaceId;
+ public int pollingIntervalSeconds;
+ }
+
+ private TestableCtrlplaneJobPoller jobPoller;
+
+ /**
+ * Extends CtrlplaneJobPoller to access protected methods and
+ * track JobAgent recreations.
+ */
+ private static class TestableCtrlplaneJobPoller extends CtrlplaneJobPoller {
+ public int jobAgentCreationCount = 0;
+ public String lastApiUrl;
+ public String lastApiKey;
+ public String lastAgentName;
+ public String lastWorkspaceId;
+ public int lastPollingIntervalSeconds;
+ private JobAgent testJobAgent;
+
+ @Override
+ protected JobAgent createJobAgent(
+ String apiUrl, String apiKey, String agentName, String agentWorkspaceId, int pollingIntervalSeconds) {
+ jobAgentCreationCount++;
+ lastApiUrl = apiUrl;
+ lastApiKey = apiKey;
+ lastAgentName = agentName;
+ lastWorkspaceId = agentWorkspaceId;
+ lastPollingIntervalSeconds = pollingIntervalSeconds;
+
+ JobAgent agent = new JobAgent(apiUrl, apiKey, agentName, agentWorkspaceId);
+ testJobAgent = agent;
+ return agent;
+ }
+
+ /**
+ * Simplified test version that doesn't need to access internal CtrlplaneConfig
+ */
+ public boolean initializeAndRegisterAgent(TestConfig config) {
+ if (config.apiUrl == null || config.apiUrl.isBlank() || config.apiKey == null || config.apiKey.isBlank()) {
+ return false;
+ }
+
+ String agentName = config.agentName;
+ if (agentName == null || agentName.isBlank()) {
+ agentName = CtrlplaneGlobalConfiguration.DEFAULT_AGENT_ID;
+ }
+
+ if (testJobAgent == null
+ || !config.apiUrl.equals(lastApiUrl)
+ || !config.apiKey.equals(lastApiKey)
+ || !agentName.equals(lastAgentName)
+ || !Objects.equals(config.agentWorkspaceId, lastWorkspaceId)
+ || config.pollingIntervalSeconds != lastPollingIntervalSeconds) {
+
+ JobAgent newAgent = createJobAgent(
+ config.apiUrl,
+ config.apiKey,
+ agentName,
+ config.agentWorkspaceId,
+ config.pollingIntervalSeconds);
+
+ try {
+ java.lang.reflect.Field field = CtrlplaneJobPoller.class.getDeclaredField("jobAgent");
+ field.setAccessible(true);
+ field.set(this, newAgent);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ return true;
+ }
+ }
+
+ @Before
+ public void setUp() {
+ jobPoller = new TestableCtrlplaneJobPoller();
+ }
+
+ @Test
+ public void testInitialAgentSetup() {
+ // Create test configuration
+ TestConfig config = new TestConfig();
+ config.apiUrl = "https://api.example.com";
+ config.apiKey = "test-key";
+ config.agentName = "test-agent";
+ config.agentWorkspaceId = "test-workspace";
+ config.pollingIntervalSeconds = 120;
+
+ // Initialize agent
+ boolean result = jobPoller.initializeAndRegisterAgent(config);
+
+ // Verify
+ assertTrue("Agent initialization should succeed", result);
+ assertEquals("Agent should be created once", 1, jobPoller.jobAgentCreationCount);
+ assertEquals("API URL should match", "https://api.example.com", jobPoller.lastApiUrl);
+ assertEquals("API key should match", "test-key", jobPoller.lastApiKey);
+ assertEquals("Agent name should match", "test-agent", jobPoller.lastAgentName);
+ assertEquals("Workspace ID should match", "test-workspace", jobPoller.lastWorkspaceId);
+ assertEquals("Polling interval should match", 120, jobPoller.lastPollingIntervalSeconds);
+ }
+
+ @Test
+ public void testAgentReInitializationOnConfigChange() {
+ // First initialization
+ TestConfig config = new TestConfig();
+ config.apiUrl = "https://api.example.com";
+ config.apiKey = "test-key";
+ config.agentName = "test-agent";
+ config.agentWorkspaceId = "test-workspace";
+ config.pollingIntervalSeconds = 120;
+
+ jobPoller.initializeAndRegisterAgent(config);
+ assertEquals("Agent should be created once", 1, jobPoller.jobAgentCreationCount);
+
+ // Same config - should not recreate
+ jobPoller.initializeAndRegisterAgent(config);
+ assertEquals("Agent should not be recreated for same config", 1, jobPoller.jobAgentCreationCount);
+
+ // Change API URL - should recreate
+ config.apiUrl = "https://new-api.example.com";
+ jobPoller.initializeAndRegisterAgent(config);
+ assertEquals("Agent should be recreated when API URL changes", 2, jobPoller.jobAgentCreationCount);
+ assertEquals("New API URL should be used", "https://new-api.example.com", jobPoller.lastApiUrl);
+
+ // Change API key - should recreate
+ config.apiKey = "new-test-key";
+ jobPoller.initializeAndRegisterAgent(config);
+ assertEquals("Agent should be recreated when API key changes", 3, jobPoller.jobAgentCreationCount);
+ assertEquals("New API key should be used", "new-test-key", jobPoller.lastApiKey);
+
+ // Change polling interval - should recreate
+ config.pollingIntervalSeconds = 180;
+ jobPoller.initializeAndRegisterAgent(config);
+ assertEquals("Agent should be recreated when polling interval changes", 4, jobPoller.jobAgentCreationCount);
+ assertEquals("New polling interval should be used", 180, jobPoller.lastPollingIntervalSeconds);
+ }
+
+ @Test
+ public void testDefaultAgentNameUsedWhenBlank() {
+ TestConfig config = new TestConfig();
+ config.apiUrl = "https://api.example.com";
+ config.apiKey = "test-key";
+ config.agentName = ""; // Blank agent name
+ config.agentWorkspaceId = "test-workspace";
+ config.pollingIntervalSeconds = 120;
+
+ jobPoller.initializeAndRegisterAgent(config);
+
+ // Should use default agent name
+ assertFalse(
+ "Agent name should not be blank", jobPoller.lastAgentName == null || jobPoller.lastAgentName.isEmpty());
+ assertEquals(
+ "Default agent name should be used",
+ CtrlplaneGlobalConfiguration.DEFAULT_AGENT_ID,
+ jobPoller.lastAgentName);
+ }
+}
diff --git a/src/test/java/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfigurationTest.java b/src/test/java/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfigurationTest.java
new file mode 100644
index 0000000..971008b
--- /dev/null
+++ b/src/test/java/io/jenkins/plugins/ctrlplane/CtrlplaneGlobalConfigurationTest.java
@@ -0,0 +1,113 @@
+package io.jenkins.plugins.ctrlplane;
+
+import static org.junit.Assert.*;
+
+import org.htmlunit.html.HtmlForm;
+import org.htmlunit.html.HtmlNumberInput;
+import org.htmlunit.html.HtmlTextInput;
+import org.junit.Rule;
+import org.junit.Test;
+import org.jvnet.hudson.test.JenkinsSessionRule;
+
+public class CtrlplaneGlobalConfigurationTest {
+
+ @Rule
+ public JenkinsSessionRule sessions = new JenkinsSessionRule();
+
+ /**
+ * Tries to exercise enough code paths to catch common mistakes:
+ *
+ * - missing {@code load}
+ *
- missing {@code save}
+ *
- misnamed or absent getter/setter
+ *
- misnamed {@code textbox}
+ *
- misnamed {@code number}
+ *
+ */
+ @Test
+ public void uiAndStorage() throws Throwable {
+ sessions.then(r -> {
+ assertEquals(
+ "default API URL is set initially",
+ CtrlplaneGlobalConfiguration.DEFAULT_API_URL,
+ CtrlplaneGlobalConfiguration.get().getApiUrl());
+ assertNull(
+ "API key not set initially",
+ CtrlplaneGlobalConfiguration.get().getApiKey());
+ assertEquals(
+ "Default Agent ID is set initially",
+ CtrlplaneGlobalConfiguration.DEFAULT_AGENT_ID,
+ CtrlplaneGlobalConfiguration.get().getAgentId());
+ assertNull(
+ "Agent Workspace ID not set initially",
+ CtrlplaneGlobalConfiguration.get().getAgentWorkspaceId());
+ assertEquals(
+ "Default Polling Interval is set initially",
+ CtrlplaneGlobalConfiguration.DEFAULT_POLLING_INTERVAL_SECONDS,
+ CtrlplaneGlobalConfiguration.get().getPollingIntervalSeconds());
+
+ HtmlForm config = r.createWebClient().goTo("configure").getFormByName("config");
+
+ HtmlTextInput apiUrlBox = config.getInputByName("_.apiUrl");
+ apiUrlBox.setText("https://api.example.com");
+
+ HtmlTextInput apiKeyBox = config.getInputByName("_.apiKey");
+ apiKeyBox.setText("test-api-key");
+
+ HtmlTextInput agentIdBox = config.getInputByName("_.agentId");
+ agentIdBox.setText("test-agent");
+
+ HtmlTextInput agentWorkspaceIdBox = config.getInputByName("_.agentWorkspaceId");
+ agentWorkspaceIdBox.setText("test-workspace");
+
+ HtmlNumberInput pollingIntervalBox = config.getInputByName("_.pollingIntervalSeconds");
+ pollingIntervalBox.setText("30");
+
+ r.submit(config);
+
+ assertEquals(
+ "API URL was updated",
+ "https://api.example.com",
+ CtrlplaneGlobalConfiguration.get().getApiUrl());
+ assertEquals(
+ "API key was updated",
+ "test-api-key",
+ CtrlplaneGlobalConfiguration.get().getApiKey());
+ assertEquals(
+ "Agent ID was updated",
+ "test-agent",
+ CtrlplaneGlobalConfiguration.get().getAgentId());
+ assertEquals(
+ "Agent Workspace ID was updated",
+ "test-workspace",
+ CtrlplaneGlobalConfiguration.get().getAgentWorkspaceId());
+ assertEquals(
+ "Polling Interval was updated",
+ 30,
+ CtrlplaneGlobalConfiguration.get().getPollingIntervalSeconds());
+ });
+
+ sessions.then(r -> {
+ assertEquals(
+ "API URL still there after restart",
+ "https://api.example.com",
+ CtrlplaneGlobalConfiguration.get().getApiUrl());
+ assertEquals(
+ "API key still there after restart",
+ "test-api-key",
+ CtrlplaneGlobalConfiguration.get().getApiKey());
+ assertEquals(
+ "Agent ID still there after restart",
+ "test-agent",
+ CtrlplaneGlobalConfiguration.get().getAgentId());
+ assertEquals(
+ "Agent Workspace ID still there after restart",
+ "test-workspace",
+ CtrlplaneGlobalConfiguration.get().getAgentWorkspaceId());
+ assertEquals(
+ "Polling Interval still there after restart",
+ 30,
+ CtrlplaneGlobalConfiguration.get().getPollingIntervalSeconds());
+ });
+ }
+}
diff --git a/src/test/java/io/jenkins/plugins/ctrlplane/CtrlplaneJobPollerMockTest.java b/src/test/java/io/jenkins/plugins/ctrlplane/CtrlplaneJobPollerMockTest.java
new file mode 100644
index 0000000..3b6665d
--- /dev/null
+++ b/src/test/java/io/jenkins/plugins/ctrlplane/CtrlplaneJobPollerMockTest.java
@@ -0,0 +1,159 @@
+package io.jenkins.plugins.ctrlplane;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+import io.jenkins.plugins.ctrlplane.CtrlplaneJobPoller.JobInfo;
+import io.jenkins.plugins.ctrlplane.api.JobAgent;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.jvnet.hudson.test.JenkinsRule;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+public class CtrlplaneJobPollerMockTest {
+
+ @Rule
+ public JenkinsRule j = new JenkinsRule();
+
+ @Mock
+ private JobAgent jobAgent;
+
+ // Simple subclass that exposes protected methods for testing
+ private static class TestableCtrlplaneJobPoller extends CtrlplaneJobPoller {
+ private final JobAgent mockJobAgent;
+
+ public TestableCtrlplaneJobPoller(JobAgent mockJobAgent) {
+ this.mockJobAgent = mockJobAgent;
+ }
+
+ @Override
+ protected JobAgent createJobAgent(
+ String apiUrl, String apiKey, String agentName, String agentWorkspaceId, int pollingIntervalSeconds) {
+ return mockJobAgent;
+ }
+
+ public void updateJobStatusWithExternalId(JobInfo jobInfo, String status, String trigger, String externalId) {
+ Map details = new HashMap<>();
+ details.put("trigger", trigger);
+ details.put("externalId", externalId);
+ this.mockJobAgent.updateJobStatus(jobInfo.jobUUID, status, details);
+ }
+ }
+
+ private TestableCtrlplaneJobPoller jobPoller;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.openMocks(this);
+ jobPoller = new TestableCtrlplaneJobPoller(jobAgent);
+ }
+
+ @Test
+ public void testExtractJobNameFromUrl() {
+ // Test basic URL parsing
+ assertEquals("simple-job", jobPoller.extractJobNameFromUrl("http://jenkins-server/job/simple-job/"));
+ assertEquals(
+ "folder/subfolder/job",
+ jobPoller.extractJobNameFromUrl("http://jenkins-server/job/folder/job/subfolder/job/job/"));
+ assertNull(jobPoller.extractJobNameFromUrl("http://not-a-jenkins-url"));
+ }
+
+ @Test
+ public void testJobStatusUpdating() {
+ // Given
+ String jobId = "test-job-id";
+ UUID jobUUID = UUID.randomUUID();
+ String jobUrl = "http://jenkins-server/job/test-job/";
+ JobInfo jobInfo = new JobInfo(jobId, jobUUID, jobUrl);
+ String externalId = "123";
+
+ // When
+ Map expectedDetails = new HashMap<>();
+ expectedDetails.put("trigger", "Test");
+ expectedDetails.put("externalId", externalId);
+ when(jobAgent.updateJobStatus(eq(jobUUID), eq("in_progress"), eq(expectedDetails)))
+ .thenReturn(true);
+ jobPoller.updateJobStatusWithExternalId(jobInfo, "in_progress", "Test", externalId);
+
+ // Then
+ verify(jobAgent).updateJobStatus(eq(jobUUID), eq("in_progress"), eq(expectedDetails));
+ }
+
+ @Test
+ public void testExtractJobInfo() {
+ // Create test job data
+ Map jobConfig = new HashMap<>();
+ jobConfig.put("jobUrl", "http://jenkins-server/job/test-job/");
+
+ Map jobMap = new HashMap<>();
+ String jobId = UUID.randomUUID().toString();
+ jobMap.put("id", jobId);
+ jobMap.put("status", "pending");
+ jobMap.put("jobAgentConfig", jobConfig);
+
+ // Extract job info
+ JobInfo jobInfo = jobPoller.extractJobInfo(jobMap);
+
+ // Verify
+ assertNotNull("JobInfo should not be null", jobInfo);
+ assertEquals("Job ID should match", jobId, jobInfo.jobId);
+ assertEquals("Job URL should match", "http://jenkins-server/job/test-job/", jobInfo.jobUrl);
+ }
+
+ @Test
+ public void testExtractJobInfo_SkipNonPendingJobs() {
+ // Create test job data with non-pending status
+ Map jobConfig = new HashMap<>();
+ jobConfig.put("jobUrl", "http://jenkins-server/job/test-job/");
+
+ Map jobMap = new HashMap<>();
+ String jobId = UUID.randomUUID().toString();
+ jobMap.put("id", jobId);
+ jobMap.put("status", "in_progress"); // Non-pending status
+ jobMap.put("jobAgentConfig", jobConfig);
+
+ // Extract job info should return null for non-pending jobs
+ JobInfo jobInfo = jobPoller.extractJobInfo(jobMap);
+
+ // Verify
+ assertNull("JobInfo should be null for non-pending jobs", jobInfo);
+ }
+
+ @Test
+ public void testJobStatusUpdateWithExternalId() {
+ // Given
+ String jobId = "test-job-id";
+ UUID jobUUID = UUID.randomUUID();
+ String jobUrl = "http://jenkins-server/job/test-job/";
+ JobInfo jobInfo = new JobInfo(jobId, jobUUID, jobUrl);
+ String externalId = "123";
+
+ // Capture the arguments passed to updateJobStatus
+ @SuppressWarnings("unchecked")
+ ArgumentCaptor