{"id":20611734,"url":"https://github.com/ivaivalous/jenxt","last_synced_at":"2026-05-10T05:42:54.442Z","repository":{"id":88869347,"uuid":"108629203","full_name":"ivaivalous/jenxt","owner":"ivaivalous","description":"Power up your build automation, running trusted Groovy scripts en masse on your Jenkins servers","archived":false,"fork":false,"pushed_at":"2019-03-04T13:40:12.000Z","size":60,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-17T03:33:09.136Z","etag":null,"topics":["devops","groovy","jenkins"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ivaivalous.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-10-28T07:31:43.000Z","updated_at":"2023-07-17T10:33:15.000Z","dependencies_parsed_at":"2023-03-16T00:00:55.968Z","dependency_job_id":null,"html_url":"https://github.com/ivaivalous/jenxt","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivaivalous%2Fjenxt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivaivalous%2Fjenxt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivaivalous%2Fjenxt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivaivalous%2Fjenxt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ivaivalous","download_url":"https://codeload.github.com/ivaivalous/jenxt/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242259944,"owners_count":20098429,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["devops","groovy","jenkins"],"created_at":"2024-11-16T10:21:49.918Z","updated_at":"2026-05-10T05:42:54.400Z","avatar_url":"https://github.com/ivaivalous.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Jenxt\nJenkins API Extender—Extend the Jenkins API with custom Groovy scripts you can run en masse on your Jenkins servers.\n\n# What is Jenxt\n\nJenxt acts as a web server, written in Go, that lets you easily extend the Jenkins API through Groovy scripts. In a nutshell, it executes Groovy against Jenkins' script console, which gives you full control over Jenkins to make your automation tasks easier.\n\nNormally, it is dangerous to let users run arbitrary scripts as they might take actions that are malicious. With Jenxt, the content of the script is abstracted away from the user and they can't view or modify it. They can only execute it, passing in parameters, and retrieving a response. User requests to Jenxt can be validated.\n\n# How to setup\n\nInstallation is meant to be as easy as possible.\n\n```\ngo get ivo.qa/jenxt\ncd ivo.qa/jenxt\ngo build\n./jenxt\n```\n\nOr download a released executable. The choice of Go as a development language is exactly to make running Jenxt as easy as possible. No frameworks needed, or advanced setup.\n\n```\njenxt\njenxt.json\nscripts\n```\n\n`jenxt` is the main executable. It starts the server and listens for incoming requests.\n`jenxt.json` is the file where you configure the system. `scripts` contains all your user scripts.\n\nTo use Jenxt, simply create Groovy scripts and place them in the scripts directory. Scripts are normal Groovy Jenkins would understand, with some special annotations to register them with the Jenxt server. You'll learn about this later.\n\nTo start using Jenxt, first edit `jenxt.json`:\n\n```\n{\n    \"server\": {\n        \"port\": 8899\n    },\n    \"remotes\": [{\n        \"name\": \"Jenkins Production Server\",\n        \"url\": \"https://ci.example.com\",\n        \"username\": \"user123\",\n        \"password\": \"My Password\",\n        \"labels\": [\"default\"]\n    }, {\n        \"name\": \"Jenkins Server in Paris\",\n        \"url\": \"https://ci2.example.com\",\n        \"username\": \"user\",\n        \"password\": \"PASSWORD\",\n        \"labels\": [\"default\", \"Europe\"]\n    }]\n}\n```\n\nUnder server \u003e port, you can change the port where the server is started. Use `remotes` to specify a list of remote Jenkins servers you would like to manage. The `remotes` array consists of server descriptions.\n\n`name` is a descriptive name for the server, like \"Jenkins Production Server\". This name will be returned in responses so you know how each server responded to your request. In `url` you specify the full address of your Jenkins server. `username` and `password` are the credentials of a user who has the permission to run Groovy scripts.\n\nTo avert the risk of committing your passwords to version control by mistake, you can separate passwords from the rest of the configuration. Simply remove the passwords from the configuration file so that it looks like this:\n\n```\n...\n{\n    \"name\": \"Jenkins Server in Paris\",\n    \"url\": \"https://ci2.example.com\",\n    \"username\": \"user\",\n    \"labels\": [\"default\", \"Europe\"]\n}\n...\n```\n\nAnd then create a new JSON file with a name of your choice, with the following structure:\n\n```\n{\n    \"remotes\": [{\n        \"name\": \"Jenkins Server in Paris\",\n        \"password\": \"YouR Pa$$w0RD\"\n    }]\n}\n```\n\nThe configuration and secrets file can be stored anywhere on the file system your program can access, and you can give it the location by running it with two arguments:\n\n```\n./jenxt \u003cpath to jenxt.json\u003e \u003cpath to secrets.json\u003e\n```\n\nThe last component of the config file is the `labels` list that allows you to group your servers. You can use this to enable executing scripts only for the groups you'd like. If you want to store a server but never execute any scripts on it, you can just not set any labels for it.\n\n# Creating scripts\n\nGroovy scripts you create go in the `scripts` directory. The repository contains some scripts for example purposes that you can safely delete. To enable a script, you just have to place it in the folder. Please only put Groovy scripts in there as Jentx will try to register any file it finds in the directory.\n\nYou can add, change or remove scripts without restarting Jenxt. Checks for changes are run every ten seconds. This should allow you to just run the server somewhere and sync it though your version control system.\n\nA script looks like this:\n\n```\n/*\n\u003cjenxt\u003e\n{\n    \"expose\": \"epoch-time\"\n}\n\u003c/jenxt\u003e\n*/\n\nreturn new Date().getTime()\n```\n\nWrapped in `\u003cjenxt\u003e...\u003c/jenxt\u003e` is the so-called meta of the script. It instructs Jenxt how to run the script. Inside is a simple JSON object that may currently contain the following settings:\n\n - `expose` - this is the endpoint one needs to access so they can run the script. In the above example, an HTTP request to `http://127.0.0.1:8899/epoch-time` will run the given script against the configured Jenkins instances that have the \"default\" label. To execute against instances labelled \"XYZ\", add a `label` parameter to the request, like in `http://127.0.0.1:8899/epoch-time?label=XYZ`.\n  - `jsonResponse` - Set this to false or omit to get Jenkins' response as a string. Set it to true to return a JSON. *Note*: if jsonResponse is `true` and the response can't be converted to a JSON (for example, when it is a normal string), the response will be returned as `null`.\n\n**Note**: In next releases, additional configuration will be added for parameters, request validation, etc.\n\n# Responses\n\nRunning the script from the above example against two machines yields a response similar to this one.\n\n```\n{\n   \"results\":[\n      {\n         \"server\":\"Jenkins Production Server\",\n         \"response\":\"1509269708370\"\n      },\n      {\n         \"server\":\"Jenkins Server in Paris\",\n         \"response\":\"1509269708721\"\n      }\n   ]\n}\n```\n\nIf there was an error in executing the script, it will be restured in the `response` field, too. Additionally, there will be an `error` fiels with the value of `true`. Like:\n\n```\n{\n  \"results\": [{\n    \"server\": \"Jenkins Server in Pune\",\n    \"response\": \"Authentication failed\",\n    \"error\": true\n  }]\n}\n```\n\nAnd if we have the below, more complex script, giving us the SCM configuration for all jobs that have one,\n\n```\n/*\n\u003cjenxt\u003e\n{\n    \"expose\": \"scm-triggers\",\n    \"jsonResponse\": true\n}\n\u003c/jenxt\u003e\n*/\n\nimport groovy.json.*\n\ndef result = [:]\n\nJenkins.instance.getAllItems().each { it -\u003e\n  if (!(it instanceof jenkins.triggers.SCMTriggerItem)) {\n    return\n  }\n\n  def itTrigger = (jenkins.triggers.SCMTriggerItem)it\n  def triggers = itTrigger.getSCMTrigger()\n\n  triggers.each { t-\u003e\n    def builder = new JsonBuilder()\n    result[it.name] = builder {\n      spec \"${t.getSpec()}\"\n      ignorePostCommitHooks \"${t.isIgnorePostCommitHooks()}\"\n    }\n  }\n}\n\nreturn new JsonBuilder(result).toPrettyString()\n```\n\nThe result would resamble this:\n\n```\n{\n   \"results\":[\n      {\n         \"server\":\"Jenkins Production Server\",\n         \"response\":{\n            \"Build Project A\":{\n               \"ignorePostCommitHooks\":\"false\",\n               \"spec\":\"@hourly\"\n            },\n            \"ivodb.deploy\":{\n               \"ignorePostCommitHooks\":\"false\",\n               \"spec\":\"H 15 * * *\"\n            }\n         }\n      }\n   ]\n}\n```\n\n# Roadmap\n\n - Unit tests :) :)\n - Parameters in requests\n - Request parameters and body validation\n - DONE - Automatic pick up of configuration and script changes\n - Authentication of requests to Jenxt\n - Password encryption\n - CI\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fivaivalous%2Fjenxt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fivaivalous%2Fjenxt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fivaivalous%2Fjenxt/lists"}