---
title: A Jenkins shared library to execute commands with vcn, our CLI tool - Codenotary
description: MONITOR & MANAGE THE RISK EXPOSURE OF YOUR APPLICATIONS WITH TRUESBOM®
image: https://codenotary.com/hubfs/Imported_Blog_Media/Blog-Default-General-Feb-06-2023-03-57-07-0930-PM.jpg
---

**$ protect --distro linux --machines 25 --free**

[Start now](https://apps.codenotary.com/linux)

[![cn-logo-black-nobg](https://codenotary.com/hubfs/cn-logo-black-nobg.svg)](https://codenotary.com/)

- Product
  
  #### [![AgentMon Start](https://codenotary.com/hubfs/AgentMon%20Start.svg) **AgentMon Start** Organization-wide AI agent spend, security and device fleet TRY NOW →](https://apps.codenotary.com/agentmon-start)
  
  #### [![AgentMon for Enterprise](https://codenotary.com/hubfs/AgentMon%20for%20Enterprise.svg) **AgentMon** Currently monitors more \> 7 million agent interactions/day. TRY NOW →](https://codenotary.com/agentmon)
  
  #### [![AgentX](https://codenotary.com/hubfs/AgentX.svg) **AgentX** Agentic network control middleware. TRY NOW →](https://codenotary.com/agent-network-control)
  
  #### [![Autonomous Security](https://codenotary.com/hubfs/Autonomous%20Security.svg) **Autonomous Security** AI Agents keep your servers secure. TRY NOW →](https://codenotary.com/trust)
- Use Cases
  
  #### [**AI Agent Risk Monitoring** Continuous oversight of autonomous agents across every environment.](https://codenotary.com/use-cases#risk)
  
  #### [**Autonomous Security Operations** Self-healing defenses that detect, contain, and remediate threats.](https://codenotary.com/use-cases#agentops)
  
  #### [**AI Coding Governance & Performance Monitoring** AI-generated code reviewed, tracked, and held to quality standards.](https://codenotary.com/use-cases#performance)
  
  #### [**AI Tool Cost & Usage Optimization** Spend and consumption optimized across every AI service in use.](https://codenotary.com/use-cases#cost)
  
  #### [**AI Tool Security & Policy Enforcement** Approved AI usage enforced with guardrails and policy controls.](https://codenotary.com/use-cases#security#security)
  
  #### [**Shadow AI Governance** Unsanctioned AI tools discovered, surfaced, and brought under control.](https://codenotary.com/use-cases#shadowit)
- [Blog](https://codenotary.com/blog)
- [Press](https://codenotary.com/press)
- Resources
  
  #### [**Integrations** Connect with your favorite tools and platforms. LEARN MORE →](https://codenotary.com/integrations)
  
  #### [**Support** Get help from our dedicated support team. GET HELP →](https://support.codenotary.com)
  
  #### [**Success Stories** Read how customers achieve their goals. READ MORE →](https://codenotary.com/success)
  
  #### [**Learn** Access documentation and learning resources. EXPLORE →](https://codenotary.com/learn)

[Login](https://apps.codenotary.com/auth/login)

[All posts](https://codenotary.com/blog/all)

 Jul 20, 2022

# A Jenkins shared library to execute commands with vcn, our CLI tool

 By  [@marco](https://codenotary.com/blog/author/marco)  ·   1 minute read

#### Learn how to reuse code in continuous integration pipelines with our digital assets attestation tool

If you need to use the same piece of code in many different pipelines, a [Jenkins shared library](https://www.jenkins.io/doc/book/pipeline/shared-libraries/) is a good approach. After importing it, you will have access to its methods, which is a convenient way of avoiding repetition and improving scalability and maintainability.

Here at Codenotary we recently wrote a shared library with simple methods for some commands of our command line interface (CLI) tool, `vcn`, which we can then use on other pipelines in a very intuitive manner:

```
package lib

public class VCN implements Serializable {
    def context

    public VCN(def context) {
        this.context = context
    }

    def execute(String command, String... arguments) {
        arguments = arguments.join(" ")
        context.echo context.sh(returnStdout: true, script: "./vcn ${command} ${arguments}").trim()
    }

    def authenticate(String... arguments) {
        execute("authenticate", arguments)
    }

    def bom(String... arguments) {
        execute("bom", arguments)
    }

    def inspect(String... arguments) {
        execute("inspect", arguments)
    }

    def list(String... arguments) {
        execute("list", arguments)
    }

    def login(String... arguments) {
        execute("login", arguments)
    }

    def logout(String... arguments) {
        execute("logout", arguments)
    }

    def notarize(String... arguments) {
        execute("notarize", arguments)
    }

    def serve(String... arguments) {
        execute("serve", arguments)
    }

    def unsupport(String... arguments) {
        execute("unsupport", arguments)
    }

    def untrust(String... arguments) {
        execute("untrust", arguments)
    }
}
```

As you can see, the shared library exposes a class that models the `vcn` tool. When initialized, the class instance receives the Jenkins context, which allows it to execute the commands on the pipeline that called it. All methods representing the commands just receive any amount of String parameters and pass them, with the command name, to the execute method. The execute method then just joins the parameters received and calls `vcn` in a shell – with the command passed and the joined parameters.

This is an example Jenkins pipeline script that could make use of this shared library:

```
@Library('jenkins-libs@vcn') _

import lib.VCN

node('debian') {
    try {
	def vcn = new VCN(this)

	stage('Checkout vcn') {
	    checkout scm
	    }

	stage('Build vcn') {
	    sh "make"
	}

	stage("Login") {
	    String arguments = "--lc-host ${LC_HOST} --lc-skip-tls-verify --lc-port 443"
	    vcn.login(arguments)
	}

	stage("Notarize vcn") {
            String arguments = '"*.py"'
            vcn.notarize(arguments)
	}

	stage("Authenticate vcn") {
	    String arguments = 'vcn --output=""'
		vcn.authenticate(arguments)
	}

	} finally {
	    stage('Cleanup') {
	    step([$class: 'WsCleanup'])
	    deleteDir()
	}
    }
}
```

The pipeline would work like this:

![](https://static.hsstatic.net/BlogImporterAssetsUI/ex/missing-image.png)

This is just a simple example to show the power of a Jenkins shared library. It can be certainly improved and extended to accommodate more robust needs required by a production environment.

You can try it yourself by starting a [**Codenotary Trustcenter trial**](https://codenotary.com/products/trustcenter)

[![Share on twitter](https://4059529.fs1.hubspotusercontent-na1.net/hub/4059529/hubfs/01-marketplace/twitter-color.png?width=35&height=35&name=twitter-color.png)](https://twitter.com/intent/tweet?original_referer=https://codenotary.com/blog/a-jenkins-shared-library-to-execute-commands-with-vcn-our-cli-tool&utm_medium=social&utm_source=twitter&url=https://codenotary.com/blog/a-jenkins-shared-library-to-execute-commands-with-vcn-our-cli-tool&utm_medium=social&utm_source=twitter&source=tweetbutton&text=) [![Share on facebook](https://4059529.fs1.hubspotusercontent-na1.net/hub/4059529/hubfs/01-marketplace/facebook-color.png?width=35&height=35&name=facebook-color.png)](http://www.facebook.com/share.php?u=https://codenotary.com/blog/a-jenkins-shared-library-to-execute-commands-with-vcn-our-cli-tool&utm_medium=social&utm_source=facebook) [![Share on linkedin](https://4059529.fs1.hubspotusercontent-na1.net/hub/4059529/hubfs/01-marketplace/linkedin-color.png?width=35&height=35&name=linkedin-color.png)](http://www.linkedin.com/shareArticle?mini=true&url=https://codenotary.com/blog/a-jenkins-shared-library-to-execute-commands-with-vcn-our-cli-tool&utm_medium=social&utm_source=linkedin) [![Share on pinterest](https://4059529.fs1.hubspotusercontent-na1.net/hub/4059529/hubfs/pinterest.jpg?width=35&height=35&name=pinterest.jpg)](http://pinterest.com/pin/create/button/?url=https://codenotary.com/blog/a-jenkins-shared-library-to-execute-commands-with-vcn-our-cli-tool&utm_medium=social&utm_source=pinterest&media=)

```json
{
  "@context" : "https://schema.org",
  "@type" : "BlogPosting",
  "author" : {
    "@type" : "Person",
    "name" : "@marco",
    "url" : "https://codenotary.com/blog/author/marco"
  },
  "dateModified" : "2025-06-25T14:09:36.263Z",
  "datePublished" : "2022-07-20T17:16:12.000Z",
  "headline" : "A Jenkins shared library to execute commands with vcn, our CLI tool - Codenotary",
  "image" : [ "https://codenotary.com/hubfs/Imported_Blog_Media/Blog-Default-General-Feb-06-2023-03-57-07-0930-PM.jpg" ],
  "mainEntityOfPage" : {
    "@id" : "https://codenotary.com/blog/a-jenkins-shared-library-to-execute-commands-with-vcn-our-cli-tool",
    "@type" : "WebPage"
  },
  "publisher" : {
    "@type" : "Organization",
    "logo" : {
      "@type" : "ImageObject",
      "url" : "https://codenotary.com/hubfs/logo-light.svg"
    },
    "name" : "Codenotary, Inc."
  }
}
```

```json
{
  "@context" : "http://schema.org",
  "@type" : "Article",
  "author" : {
    "@type" : "Person",
    "name" : [ "@marco" ],
    "url" : "https://codenotary.com/blog/author/marco"
  },
  "datePublished" : "2022-07-20T17:16:12+0000",
  "description" : "MONITOR & MANAGE THE RISK EXPOSURE OF YOUR APPLICATIONS WITH TRUESBOM®",
  "headline" : "A Jenkins shared library to execute commands with vcn, our CLI tool",
  "image" : "https://cdn2.hubspot.net/hubfs/23873599/Imported_Blog_Media/Blog-Default-General-Feb-06-2023-03-57-07-0930-PM.jpg",
  "publisher" : {
    "@type" : "Organization",
    "logo" : {
      "@type" : "ImageObject",
      "url" : "https://cdn2.hubspot.net/hubfs/23873599/logo-light.svg"
    },
    "name" : ""
  },
  "url" : "https://codenotary.com/blog/a-jenkins-shared-library-to-execute-commands-with-vcn-our-cli-tool"
}
```