{"id":14984644,"url":"https://github.com/jenkinsci/zdevops-plugin","last_synced_at":"2025-10-19T11:31:54.486Z","repository":{"id":66296042,"uuid":"561912191","full_name":"jenkinsci/zdevops-plugin","owner":"jenkinsci","description":"Zowe z/OS DevOps Jenkins plugin - mainframes automation plugin, working through z/OSMF REST API and using Zowe Kotlin SDK.","archived":false,"fork":false,"pushed_at":"2024-11-08T08:47:47.000Z","size":513,"stargazers_count":6,"open_issues_count":1,"forks_count":6,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-01-29T14:38:53.206Z","etag":null,"topics":["deployment","devops","jcl","jenkins","jenkins-ci","jenkins-plugin","kotlin","misc","orchestration","zos","zos-development","zosmf","zowe","zowe-sdk","zowe-zdevops"],"latest_commit_sha":null,"homepage":"https://plugins.jenkins.io/zdevops/","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"epl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jenkinsci.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","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":"2022-11-04T19:26:40.000Z","updated_at":"2024-11-07T23:02:41.000Z","dependencies_parsed_at":null,"dependency_job_id":"52c49375-dc90-48a2-97ee-2b1ef7f61f05","html_url":"https://github.com/jenkinsci/zdevops-plugin","commit_stats":{"total_commits":30,"total_committers":5,"mean_commits":6.0,"dds":"0.23333333333333328","last_synced_commit":"51b7eba6500a36970b17c8e28a5420a6208773b9"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jenkinsci%2Fzdevops-plugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jenkinsci%2Fzdevops-plugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jenkinsci%2Fzdevops-plugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jenkinsci%2Fzdevops-plugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jenkinsci","download_url":"https://codeload.github.com/jenkinsci/zdevops-plugin/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":237117165,"owners_count":19258364,"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":["deployment","devops","jcl","jenkins","jenkins-ci","jenkins-plugin","kotlin","misc","orchestration","zos","zos-development","zosmf","zowe","zowe-sdk","zowe-zdevops"],"created_at":"2024-09-24T14:09:27.430Z","updated_at":"2025-10-19T11:31:54.480Z","avatar_url":"https://github.com/jenkinsci.png","language":"Kotlin","readme":"# Zowe® zDevOps Jenkins® plugin\n\n## About the plugin\nThe Zowe zDevOps Jenkins plugin is an open-source, secure, and reliable agent-less plugin for Jenkins that makes it possible to perform most of the actual tasks on the mainframe, managing it with a modern native mainframe zOSMF REST API and the capabilities of available zOSMF SDKs. [Zowe](https://www.zowe.org/) is a project hosted by the [Open Mainframe Project](https://www.openmainframeproject.org/), a [Linux Foundation](https://www.linuxfoundation.org/) project.\n\n## Main features\n- Secure and modern connection of Jenkins to the mainframes through the use of zOSMF REST API.\n- The functionality is based on the Kotlin SDK methods, such as JCL jobs submission, download, allocate, write to the dataset, etc., with a log collected upon completion.\n- Multiple connections to various mainframes — z/OS Connections List where you can save all the necessary systems and credentials (all data is safely stored under the protection of Jenkins Credentials manager).\n- Agent-less solution.\n- z/OSMF connection validation.\n- Convenient user interface panels for working with the mainframe\n- Fast execution and functional extensibility.\n\n## Before use - Plugin configuration\nAfter successfully installing the plugin, you need to configure it for further work - this will require a minimum of actions.\n1. Move to 'Manage Jenkins' -\u003e 'Configure System / System' -\u003e scroll to the very bottom of the list of installed plugins and find the panel with the name - \u003cb\u003e'z/OS Connection List'\u003c/b\u003e\n2. This setting allows you to add all necessary z/OS systems and configure access to them.\n   It is necessary to set the connection name (it is also the ID for declarative methods in the code). For the example: ```z/os-connection-name```\n3. The URL address and port of the required mainframe to connect via z/OSMF. Example: ```https://\u003cip-addres\u003e:\u003cport number\u003e```\n4. Add credentials (Mainframe User ID + Password) under which you can connect to the system.\n\nYou can save as many connections as you like, the system will keep the corresponding user IDs/passwords.\n\n## Declarative methods brief list\n```groovy\nstage (\"stage-name\") {\n    steps {\n        // ...\n        zosmf(\"z/os-connection-name\") {\n            submitJob \"//'EXAMPLE.DATASET(MEMBER)'\"\n            submitJobSync \"//'EXAMPLE.DATASET(MEMBER)'\"\n            downloadDS \"EXAMPLE.DATASET(MEMBER)\"\n            downloadDS dsn:\"EXAMPLE.DATASET(MEMBER)\", vol:\"VOL001\"\n            allocateDS dsn:\"EXAMPLE.DATASET\", alcUnit:\"TRK\", dsOrg:\"PS\", primary:1, secondary:1, recFm:\"FB\", failOnExist:\"False\"\n            writeFileToDS dsn:\"EXAMPLE.DATASET\", file:\"workspaceFile\"\n            writeFileToDS dsn:\"EXAMPLE.DATASET\", file:\"D:\\\\files\\\\localFile\"\n            writeToDS dsn:\"EXAMPLE.DATASET\", text:\"Write this string to dataset\"\n            writeFileToMember dsn:\"EXAMPLE.DATASET\", member:\"MEMBER\", file:\"workspaceFile\"\n            writeFileToMember dsn:\"EXAMPLE.DATASET\", member:\"MEMBER\", file:\"D:\\\\files\\\\localFile\"\n            writeToMember dsn:\"EXAMPLE.DATASET\", member:\"MEMBER\", text:\"Write this string to member\"\n\n            writeToFile destFile: \"u/USER/myfile\", text: \"Write this string to file\"\n            writeFileToFile destFile: \"u/USER/myfile\", sourceFile: \"myfile.txt\"\n            writeFileToFile destFile: \"u/USER/myfile\", sourceFile: \"myfile.txt\", binary: \"true\"\n\n            deleteDataset dsn:\"EXAMPLE.DATASET\", failOnNotExist:\"False\"\n            deleteDataset dsn:\"EXAMPLE.DATASET\", member:\"MEMBER\", failOnNotExist:\"True\"\n            deleteDatasetsByMask mask:\"EXAMPLE.DATASET.*\", failOnNotExist:\"False\"\n        }\n        // ...\n    }\n}\n```\n\n## Declarative Methods Detail Description\n\n### allocateDS - Represents an action for allocating a dataset in a declarative style\n```groovy\nzosmf (\"z/os-connection-name\") {\n    allocateDS(\n        // Mandatory Parameters below:\n        dsn: \"EXAMPLE.DATASET\",\n        dsOrg: \"PS\",\n        primary: 1,\n        secondary: 1,\n        recFm: \"FB\",\n        failOnExist:\"False\",\n        // Optional Parameters below:\n        volser:\"YOURVOL\",\n        unit:\"SYSDA\",\n        alcUnit:\"TRK\",\n        dirBlk:\"5\",\n        blkSize:\"800\",\n        lrecl:\"80\",\n        storClass:\"STORAGECLASS\",\n        mgntClass:\"MGMTCLASS\",\n        dataClass:\"DATACLASS\",\n        avgBlk:\"10\",\n        dsnType:\"LIBRARY\",\n        dsModel:\"MODEL.DATASET.NAME\"\n    )\n}\n```\n**Mandatory Parameters:**\n* ```dsn:\"EXAMPLE.DATASET\"``` - The name of the dataset to be allocated\n* ```dsOrg:\"PS\"``` - The dataset organization (could be only PO, POE, PS, VS)\n* ```primary:\"1\"``` - The primary allocation size in cylinders or tracks\n* ```secondary:\"1\"``` - The secondary allocation size in cylinders or tracks\n* ```recFm:\"FB\"``` - The record format (could be only F, FB, V, VB, U, VSAM, VA)\n* ```failOnExist:\"False\"``` - If the dataset already exists and the option is enabled, execution will halt. (Boolean parameter, is set to 'False' by default)\n\n**Optional parms:**\n* ```volser:\"YOURVOL\"``` - Volume serial number where the dataset will be allocated.\n* ```unit:\"SYSDA\"``` - Specifies the type of storage device. SYSDA is a common direct access storage device.\n* ```alcUnit:\"TRK\"``` - Allocation units (CYL for cylinders, TRK for tracks).\n* ```dirBlk:\"5\"``` - Directory block records.\n* ```blkSize:\"800\"``` - BLKSIZE=800: Block size of 800 bytes.\n* ```lrecl:\"80\"``` - Logical record length.\n* ```storClass:\"STORAGECLASS\"``` - Storage class for SMS-managed datasets.\n* ```mgntClass:\"MGMTCLASS\"``` - Management class for SMS-managed datasets.\n* ```dataClass:\"DATACLASS\"``` - Data class for SMS-managed datasets.\n* ```avgBlk:\"10\"``` - Average block length.\n* ```dsnType:\"LIBRARY\"``` - Specifies the type of dataset, LIBRARY for a PDS or PDSE.\n* ```dsModel:\"MODEL.DATASET.NAME\"``` - Data set model is a predefined set of attributes that can be used to allocate new data sets with the same characteristics (\"LIKE\" parameter).\n\n\n### deleteDataset - Represents an action for deleting datasets and members in a declarative style\n```groovy\nzosmf (\"z/os-connection-name\") {\n    deleteDataset dsn: \"EXAMPLE.DATASET\", member:\"MEMBER\", failOnNotExist:\"False\"\n}\n```\n**Mandatory Parameters:**\n* ```dsn:\"EXAMPLE.DATASET\"``` - Sequential or library dataset name for deletion\n* ```member:\"MEMBER\"``` - Dataset member name for deletion\n* ```failOnNotExist:\"False\"``` - If the dataset has been deleted and the option is enabled, execution will halt. (Boolean parameter, is set to 'False' by default)\n\n**Expected behavior under various deletion scenarios:**\n\n* To delete a member from the library, the dsn and member parameters must be specified:\n    ```\n    deleteDataset dsn:\"EXAMPLE.DATASET\", member:\"MEMBER\", failOnNotExist:\"False\"\n    ```\n\n* You cannot delete a VSAM dataset this way. Otherwise, you will get output similar to:\n    ```\n    Deleting dataset EXAMPLE.VSAM.DATASET with connection \u003cip-address\u003e:10443 \n    ISRZ002 Deallocation failed - Deallocation failed for data set 'EXAMPLE.VSAM.DATASET'\n    ```\n\n* What do you get if a dataset does not exist?\n\n    ```\n    Deleting dataset EXAMPLE.DS.DOES.NOT.EXIST with connection \u003cip-address\u003e:10443\n    ISRZ002 Data set not cataloged - 'EXAMPLE.DS.DOES.NOT.EXIST' was not found in catalog.\n    ```\n\n* What do you get if a dataset is busy by a user or a program?\n\n    ```\n    Deleting dataset EXAMPLE.DS.ISUSED.BY.USER with connection \u003cip-address\u003e:10443\n    ISRZ002 Data set in use - Data set 'EXAMPLE.DS.ISUSED.BY.USER' in use by another user, try later or enter HELP for a list of jobs and users allocated to 'EXAMPLE.DS.ISUSED.BY.USER'.\n    ```\n\n## Use case example\nHere you can find an example of a minimal declarative Jenkins pipeline for execution, testing and further modification for your personal needs.\nPipeline can be used either directly inside the ```Pipeline``` code block in the Jenkins server, or in a ```Jenkinsfile``` stored in Git\nThis pipeline example uses all currently available methods and functionality of the Zowe zDevOps plugin.\n\n**Steps to Execute the Pipeline:**\n1. Add a zosmf connection in settings (\u003cb\u003e'Manage Jenkins' -\u003e 'Configure System / System' -\u003e z/OS Connection List\u003c/b\u003e). Enter a connection name, zosmf url, username and password.\n2. Create a new Jenkins item -\u003e ```Pipeline``` and open its configuration.\n3. In the ```Pipeline``` section, paste the code from the example below and replace all the necessary variables with your data\n4. Done, enjoy the minimal ready-made pipeline template!\n\n```groovy\npipeline {\n    agent any\n\n    environment {\n        // Define environment variables\n        GIT_REPOSITORY_URL = 'https://github.com/your-username/your-repo.git'  // Replace with your GitHub URL\n        GIT_BRANCH = 'main'                                     // Replace with your GitHub branch name\n        GIT_USER_CREDENTIAL_ID = 'jenkins-cred-key'             // Replace with your Jenkins GitHub credential ID\n        ZOS_CONN_ID = 'z/os-connection-name'                    // Replace with your z/OS Connection ID from zDevOps plugin settings\n        HLQ = 'HLQ'                                             // Replace with your z/OS high-level qualifier (HLQ)\n        PS_DATASET_1 = \"${HLQ}.NEW.TEST1\"                       // OPTIONAL: Replace with the dataset names you need\n        PS_DATASET_2 = \"${HLQ}.NEW.TEST2\"                       // OPTIONAL\n        PO_DATASET = \"${HLQ}.NEW.TEST3\"                         // OPTIONAL\n        PO_MEMBER = \"NEWMEM\"                                    // OPTIONAL\n        JCL_JOB_TEMPLATE = \"jcl_job_example\"                    // Replace with the name of your file that contains the JCL job code\n        JIRA_URL = 'https://your-jira-instance.atlassian.net'   // Replace with your Jira URL\n        JIRA_USER = 'your-jira-email@example.com'               // Replace with your Jira user email\n        JIRA_API_TOKEN = 'your-jira-api-token'                  // Replace with your Jira API token\n        JIRA_ISSUE_KEY = 'PROJECT-123'                          // Replace with your Jira issue key\n    }\n\n    stages {\n        stage('Checkout') {\n            steps {\n                // Checkout the source code from Git\n                checkout scmGit(\n                        branches: [[name: \"${GIT_BRANCH}\"]],\n                        userRemoteConfigs: [[credentialsId:  \"${GIT_USER_CREDENTIAL_ID}\",\n                                             url: \"${GIT_REPOSITORY_URL}\"]])\n            }\n        }\n\n        stage('Allocate DSs') {\n            steps {\n                zosmf(\"${ZOS_CONN_ID}\") {\n                    allocateDS dsn:\"${PS_DATASET_1}\", dsOrg:\"PS\", primary:1, secondary:1, recFm:\"FB\", failOnExist:\"False\"\n                    allocateDS dsn:\"${PS_DATASET_2}\", dsOrg:\"PS\", primary:1, secondary:1, recFm:\"FB\", alcUnit:\"TRK\", failOnExist:\"False\"\n                    allocateDS dsn:\"${PO_DATASET}(${PO_MEMBER})\", dsOrg:\"PO\", primary:1, secondary:1, recFm:\"FB\", failOnExist:\"False\"\n                }\n            }\n        }\n\n        stage('Add JCL content') {\n            steps {\n                script {\n                    // Read the content of the JCL job into a variable\n                    env.JCL_CONTENT = readFile(\"${JCL_JOB_TEMPLATE}\").trim()\n                    // Print the content of the file (for debugging purposes)\n                    echo \"JCL job content:\\n${env.JCL_CONTENT}\"\n                }\n                zosmf(\"${ZOS_CONN_ID}\") {\n                    writeFileToDS dsn:\"${PS_DATASET_2}\", file:\"${JCL_JOB_TEMPLATE}\"\n                    writeFileToMember dsn:\"${PO_DATASET}\", member:\"${PO_MEMBER}\", file:\"${JCL_JOB_TEMPLATE}\"\n                    writeToDS dsn:\"${PS_DATASET_1}\", text:\"${env.JCL_CONTENT}\"\n                }\n            }\n        }\n\n        stage('Add USS content') {\n            steps {\n                zosmf(\"${ZOS_CONN_ID}\") {\n                    writeToFile destFile: \"u/${HLQ}/test_file1\", text: \"${env.JCL_CONTENT}\"\n                    writeFileToFile destFile: \"u/${HLQ}/test_file2\", sourceFile: \"${JCL_JOB_TEMPLATE}\", binary: \"true\"\n                }\n            }\n        }\n\n        stage('Submit JCL jobs') {\n            steps {\n                zosmf(\"${ZOS_CONN_ID}\") {\n                    submitJob \"//'${PS_DATASET_1}'\"\n                    submitJobSync \"//'${PO_DATASET}(NEWMEM)'\"\n                }\n            }\n        }\n\n        stage('Download datasets') {\n            steps {\n                zosmf(\"${ZOS_CONN_ID}\") {\n                    downloadDS \"${PS_DATASET_1}\"\n                    downloadDS dsn:\"${PS_DATASET_2}\"\n                }\n            }\n        }\n\n        stage('Clean up') {\n            steps {\n                zosmf(\"${ZOS_CONN_ID}\") {\n                    deleteDataset dsn:\"${PS_DATASET_1}\", failOnNotExist:\"False\"\n                    deleteDatasetsByMask mask:\"${HLQ}.NEW.*\", failOnNotExist:\"True\"\n                }\n            }\n        }\n    }\n\n    post {\n        always {\n            script {\n                def jiraStatus = currentBuild.currentResult == 'SUCCESS' ? 'Build Successful' : 'Build Failed'\n                def jiraComment = \"\"\"\n                {\n                    \"body\": \"Jenkins build ${jiraStatus} for Job ${env.JOB_NAME} - Build #${env.BUILD_NUMBER}.\n                    [View the build here|${env.BUILD_URL}]\"\n                }\n                \"\"\"\n\n                httpRequest acceptType: 'APPLICATION_JSON',\n                        contentType: 'APPLICATION_JSON',\n                        httpMode: 'POST',\n                        requestBody: jiraComment,\n                        url: \"${JIRA_URL}/rest/api/2/issue/${JIRA_ISSUE_KEY}/comment\",\n                        authentication: 'jira-credentials-id'\n            }\n        }\n\n        success {\n            // Notify success (example: send email)\n            mail to: '${JIRA_USER}',\n                    subject: \"SUCCESS: Build ${env.BUILD_NUMBER}\",\n                    body: \"The build ${env.BUILD_NUMBER} was successful.\"\n        }\n\n        failure {\n            // Notify failure (example: send email)\n            mail to: '${JIRA_USER}',\n                    subject: \"FAILURE: Build ${env.BUILD_NUMBER}\",\n                    body: \"The build ${env.BUILD_NUMBER} failed. Please check the Jenkins logs for more details.\"\n        }\n    }\n}\n```\n\n## Manual plugin installation by the .hpi executable file\nThe plugin are packaged as self-contained \u003cb\u003e.hpi\u003c/b\u003e files, which have all the necessary code, images, and other resources which the plugin needs to operate successfully.\n\n### \u003cb\u003eAlready packaged and tested installation .hpi file can be downloaded from a link from a nearby GitHub repository:\u003c/b\u003e\n### \u003cb\u003e[Zowe zDevOps plugin installation .hpi file](https://github.com/IBA-mainframe-dev/Global-Repository-for-Mainframe-Developers/blob/master/Jenkins%20zOS%20DevOps%20plugin%20installable%20hpi/zos-devops.hpi)\u003c/b\u003e\n\nAssuming a \u003cb\u003e.hpi\u003c/b\u003e file has been downloaded, a logged-in Jenkins administrator may upload the file from within the web UI:\n1. Navigate to the \u003cb\u003eManage Jenkins \u003e Plugins\u003c/b\u003e page in the web UI.\n2. Click on the \u003cb\u003eAdvanced\u003c/b\u003e tab.\n3. Choose the \u003cb\u003e.hpi\u003c/b\u003e file from your system or enter a URL to the archive file under the \u003cb\u003eDeploy Plugin\u003c/b\u003e section.\n4. \u003cb\u003eDeploy\u003c/b\u003e the plugin file.\n\n## Manual Jenkins plugin installation (Installation via source code build and .hpi file upload)\n1. Download the Zowe zDevOps Jenkins plugin source code from its [official Jenkins GitHub repository](https://github.com/jenkinsci/zdevops-plugin)\n2. It is necessary to build the project with the help of the Maven Build Tool\n3. To generate the ```target``` dir with generated-sources - you have to run the Maven command: ```mvn localizer:generate```\n4. Next, you need to generate an installation file: .hpi or .jpi file (both are installation files for the Jenkins plugin). This can be done by executing Maven command ```mvn install``` or by ```mvn hpi:hpi```.\n5. After building the .hpi/.jpi file, it should appear in a \u003cb\u003e\u003cPlugin-project-name\u003e/build/libs/\u003chpi_file_name\u003e.hpi\u003c/b\u003e directory\n6. Next you need to login into the Jenkins, move to the \u003cb\u003e'Manage Jenkins' -\u003e 'Plugins' -\u003e 'Advanced settings (tab)' -\u003e 'Deploy Plugin'\u003c/b\u003e (You can select a plugin file from your local system or provide a URL to install a plugin from outside the central plugin repository) \u003cb\u003e-\u003e Specify the path to the generated .hpi/.jpi file\u003c/b\u003e (or by dragging the file from Intellij IDEA project to the file upload field in the Jenkins).\n7. Click \u003cb\u003e'Deploy'\u003c/b\u003e, reboot Jenkins after installation. The Plugin is ready to go!\n\n## How to run Jenkins plugin in Debug mode in a local Jenkins sandbox\n\nFor debugging purposes run following Maven command from plugin project directory:\n\n```./mvnw hpi:run```\n\nOr by ```mvnDebug hpi:run``` - this will copy all the dependencies down (rather than in your jenkins install) and run it in place.\n\nBy default, the debugging instance is then available at [http://localhost:8080/jenkins](http://localhost:8080/jenkins) in your browser.\n\nIn order to launch Jenkins on a different port than 8080 use this system property:\n\n```./mvnw hpi:run -Djetty.port=8090```\n\nChanging the default context path can be achieved by setting this system property:\n\n```./mvnw hpi:run -Dhpi.prefix=/debug```\n\n## How to run unit-tests with JaCoCo report\n\n```./mvnw clean verify```\n\nThe results are available under `target/site/jacoco/index.html`","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjenkinsci%2Fzdevops-plugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjenkinsci%2Fzdevops-plugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjenkinsci%2Fzdevops-plugin/lists"}