<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Parro Nexus – Local development</title>
    <link>/dev/local-dev/</link>
    <description>Recent content in Local development on Parro Nexus</description>
    <generator>Hugo -- gohugo.io</generator>
    
	  <atom:link href="/dev/local-dev/index.xml" rel="self" type="application/rss+xml" />
    
    
      
        
      
    
    
    <item>
      <title>Dev: Project setup</title>
      <link>/dev/local-dev/project-setup/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/dev/local-dev/project-setup/</guid>
      <description>
        
        
        &lt;h2 id=&#34;parro-nexus---repo&#34;&gt;Parro Nexus - Repo&lt;/h2&gt;
&lt;p&gt;The Parro Nexus repo (&lt;a href=&#34;https://github.com/topicusonderwijs/parro-nexus&#34;&gt;https://github.com/topicusonderwijs/parro-nexus&lt;/a&gt;) is a mono repo containing all services and libraries for Parro Nexus.
There are three more repositories for Parro Nexus:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/topicusonderwijs/parro-connect-schema&#34;&gt;https://github.com/topicusonderwijs/parro-connect-schema&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;/infra/json-schema/&#34;&gt;See JSON schema page&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/topicusonderwijs/parro-connect-charts&#34;&gt;https://github.com/topicusonderwijs/parro-connect-charts&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;/infra/helm-charts/&#34;&gt;See HELM charts page&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/topicusonderwijs/parro-connect-infra&#34;&gt;https://github.com/topicusonderwijs/parro-connect-infra&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;/infra/kubernetes/&#34;&gt;See kubernetes page&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;apps&#34;&gt;Apps&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;apps&lt;/code&gt; directory contains all Parro Nexus services. Each app is a &lt;a href=&#34;/dev/new-service/nestjs/&#34;&gt;NestJS&lt;/a&gt; service generated with the &lt;a href=&#34;#Code generation&#34;&gt;service generator&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;An app is a NodeJS app which uses the NestJS framework. The root directory of the app therefore contains the usual NodeJS files like the &lt;code&gt;package.json&lt;/code&gt; and &lt;code&gt;tsconfig.json&lt;/code&gt;.
It also contains a &lt;code&gt;Jenkinsfile&lt;/code&gt; so the app can be build by &lt;a href=&#34;/infra/jenkins/&#34;&gt;Jenkins&lt;/a&gt;, a &lt;code&gt;Dockerfile&lt;/code&gt; so a docker container can be created and some &amp;ldquo;dot&amp;rdquo; files for configuration of npm packages.&lt;/p&gt;
&lt;h3 id=&#34;environment-variable&#34;&gt;Environment variable&lt;/h3&gt;
&lt;p&gt;Everything which is configurable in an app must be put in environment variables. This makes it easy to config an application when it is running in a docker container on k8s.
To use these env vars on your local machine without setting them as actual env vars you can use the &lt;code&gt;.env.*&lt;/code&gt; files. Default each app has 2 files &lt;code&gt;.env.template&lt;/code&gt; and &lt;code&gt;.env.test&lt;/code&gt;.
The &lt;code&gt;.env.test&lt;/code&gt; is used for the tests and the &lt;code&gt;env.template&lt;/code&gt; is used as template to show which variables are available.&lt;/p&gt;
&lt;p&gt;For local development you will need to create a file &lt;code&gt;env.local.development&lt;/code&gt;, which is ignored by git. In this file you can setup your local values.
Since some values are secrets (i.e the database user/pass) it should never end up in the git repo. The easiest way to create a &lt;code&gt;env.local.development&lt;/code&gt; file is to copy the &lt;code&gt;env.template&lt;/code&gt; and fill it with the appropriate values.
When you add new configurable values to a service you MUST add these to the &lt;code&gt;env.template&lt;/code&gt; file.&lt;/p&gt;
&lt;p&gt;The values from these &lt;code&gt;.env.*&lt;/code&gt; files are read in the &lt;code&gt;configuration.ts&lt;/code&gt; file located in &lt;code&gt;src/config&lt;/code&gt;, using the &lt;code&gt;cross-env&lt;/code&gt; npm module.
In the &lt;code&gt;package.json&lt;/code&gt; you can see the lib used in the &lt;code&gt;start&lt;/code&gt; script: &lt;code&gt;&amp;quot;start&amp;quot;: &amp;quot;cross-env NODE_ENV=development nest start --watch&amp;quot;&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;source-code&#34;&gt;Source code&lt;/h3&gt;
&lt;p&gt;All source code for the app is located in the &lt;code&gt;src&lt;/code&gt; directory. The &lt;code&gt;src&lt;/code&gt; directory contains 2 typescript files and 4 subdirectories:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;main.module.ts&lt;/strong&gt;: this file is the entrypoint for NestJS&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;main.ts&lt;/strong&gt;: this file is the main typescript file which bootstraps the app&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;config&lt;/strong&gt;: for handling all the configuration of the app&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;listeners&lt;/strong&gt;: for implementing custom shutdown listeners, to create a gracefull shutdown for the app&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;modules&lt;/strong&gt;: this directory contains the NestJS modules (&lt;a href=&#34;https://docs.nestjs.com/modules&#34;&gt;https://docs.nestjs.com/modules&lt;/a&gt;) which make up the actual app&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;schema&lt;/strong&gt;: this directory contains the generated &lt;a href=&#34;/infra/json-schema/&#34;&gt;JSON schema model&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The actual app code is located in the &lt;code&gt;src/modules&lt;/code&gt;. This directory consists of multiple NestJS modules:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;app&lt;/strong&gt;: this module contains the actual app code&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;authorization&lt;/strong&gt;: this module contains the REST oauth authorization code, only used for services which are publicly available&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;health&lt;/strong&gt;: this module contains the readiness and liveness endpoints which are used by k8s to determine if the service is up (&lt;a href=&#34;https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/&#34;&gt;https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;telemetry&lt;/strong&gt;: this module contains all the setup for the metrics and tracing, which is used to monitor the app&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Normally when you create a new app or work on an existing app you only need to change the code in the &lt;code&gt;src/modules/app&lt;/code&gt; module. This module contains all the app specific code and can have different setups based on the service needs.&lt;/p&gt;
&lt;p&gt;All service use the NestJS framework, so when you are new to this start by reading the docs: &lt;a href=&#34;https://docs.nestjs.com/&#34;&gt;https://docs.nestjs.com/&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;code-generation&#34;&gt;Code generation&lt;/h2&gt;
&lt;p&gt;To create uniform services we use a &lt;a href=&#34;/dev/schematics/&#34;&gt;code generation tool&lt;/a&gt;. This tool makes is possible to generate a skeleton app or lib project.
This way we can generate all the boilerplate code in a uniform way, so you can start working on the app code right away.&lt;/p&gt;
&lt;p&gt;The generation tool is located in &lt;code&gt;code-gen/schematics&lt;/code&gt;. The &lt;code&gt;src&lt;/code&gt; dir contains the files which will be added when you create a new service or lib.
When you change the code in the &lt;code&gt;code-gen/schematics&lt;/code&gt; a &lt;a href=&#34;/infra/jenkins/&#34;&gt;Jenkins&lt;/a&gt; job will build the code and create a NPM module &lt;code&gt;@parro-connect/schematics&lt;/code&gt;. This module is used by the script &lt;code&gt;create_nestjs_service.sh&lt;/code&gt; in the &lt;code&gt;apps&lt;/code&gt; directory.
Since each build creates a new version you must update the version of the &lt;code&gt;package.json&lt;/code&gt; when you want to merge changes on the main branch, otherwise the &lt;a href=&#34;/infra/jenkins/&#34;&gt;Jenkins&lt;/a&gt; build will fail.
The easies way is to use the npm command &lt;code&gt;npm run version:for-release&lt;/code&gt;. This will bump the version and add an entry to the &lt;code&gt;CHANGELOG.md&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;code-gen&lt;/code&gt; also contains a git submodule for the  &lt;a href=&#34;/infra/json-schema/&#34;&gt;JSON schema model&lt;/a&gt; &lt;code&gt;code-gen/parro-connect-schema&lt;/code&gt;. This submodule makes it possible to generate the model classes in your project.
To do so run &lt;code&gt;yarn build&lt;/code&gt; from within the &lt;code&gt;code-gen/parro-connect-schema&lt;/code&gt; and follow the steps.&lt;/p&gt;
&lt;h2 id=&#34;docker&#34;&gt;Docker&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;docker&lt;/code&gt; directory contain docker-compose files for running all the services or the local &lt;a href=&#34;/dev/local-dev/nats/&#34;&gt;NATS server&lt;/a&gt;.
To start all the Parro Nexus services at once run the &lt;code&gt;start-compose.sh&lt;/code&gt; script. This will build and run the &lt;code&gt;Dockerfile-NestJsService-Local&lt;/code&gt; files located in all the app directories.
The &lt;code&gt;Dockerfile-NestJsService-Local&lt;/code&gt; is a special docker setup which will mount the complete &lt;code&gt;src&lt;/code&gt; dir in the container and runs the &lt;code&gt;yarn start:dev&lt;/code&gt; command.
This makes it possible to change code in the apps and it will be auto reloaded in the container.&lt;/p&gt;
&lt;h2 id=&#34;docs&#34;&gt;Docs&lt;/h2&gt;
&lt;p&gt;The docs directory contains all the markdown files which makes up this documentation you are now reading.&lt;br&gt;
The docs use the Hugo (&lt;a href=&#34;https://gohugo.io/&#34;&gt;https://gohugo.io/&lt;/a&gt;) static site generator with the docsy (&lt;a href=&#34;https://www.docsy.dev/&#34;&gt;https://www.docsy.dev/&lt;/a&gt;) theme.&lt;br&gt;
To start the docs on your local machine run the &lt;code&gt;start_docs.sh&lt;/code&gt; script. This will start a docker container with Hugo and starts a server you can reach on http://localhost:1313/&lt;/p&gt;
&lt;h2 id=&#34;libs&#34;&gt;Libs&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;libs&lt;/code&gt; directory contain all the Parro Nexus libraries. When you need to create a reusable library (a custom NPM module) you can use the script &lt;code&gt;create_lib.sh&lt;/code&gt;.
This will use the code generation from the &lt;code&gt;code-gen&lt;/code&gt; dir to set up a basic library skeleton project. All libraries are build using &lt;a href=&#34;/infra/jenkins/&#34;&gt;Jenkins&lt;/a&gt; and are published to the &lt;code&gt;@parro-connect&lt;/code&gt; scope (&lt;a href=&#34;https://docs.npmjs.com/cli/v8/using-npm/scope)&#34;&gt;https://docs.npmjs.com/cli/v8/using-npm/scope)&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;scripts&#34;&gt;Scripts&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;scripts&lt;/code&gt; directory contains bash scripts for common tasks.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Dev: NATS</title>
      <link>/dev/local-dev/nats/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/dev/local-dev/nats/</guid>
      <description>
        
        
        &lt;h2 id=&#34;nats&#34;&gt;NATS&lt;/h2&gt;
&lt;p&gt;Parro Nexus relies heavily on &lt;a href=&#34;/infra/nats/&#34;&gt;NATS&lt;/a&gt; for service 2 service communication.
When you work on a service locally you will at some point need a working NATS environment for testing or running multiple services.&lt;/p&gt;
&lt;p&gt;The Parro Nexus repo contains a NATS setup using docker which can (and should) be used when working on services.
This setup uses the NATS docker container and adds some authorization en stream setup.&lt;/p&gt;
&lt;h3 id=&#34;prerequisites&#34;&gt;Prerequisites&lt;/h3&gt;
&lt;p&gt;You need to have docker installed on your machine in order to work with NATS.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.docker.com/get-docker/&#34;&gt;https://docs.docker.com/get-docker/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;start-a-server&#34;&gt;Start a server&lt;/h3&gt;
&lt;p&gt;In the &lt;code&gt;scripts&lt;/code&gt; directory of the Parro Nexus repo you will find a &lt;code&gt;start_nats.sh&lt;/code&gt; script which will start a NATS docker container.
The script will use the NATS config file found in &lt;code&gt;docker/nats_conf.conf&lt;/code&gt;. This configuration file has a fixed authorization setup with a single Account (see &lt;a href=&#34;/infra/nats/#authentication&#34;&gt;Authentication chapter of NATS page&lt;/a&gt;).
The credential files which work with this setup are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;./nats-sys-user.creds - System user, for NATS maintenance&lt;/li&gt;
&lt;li&gt;./nats-test-user.creds - Actual user, for Parro Nexus services&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;code&gt;start_nats.sh&lt;/code&gt; script will also mount all config (&lt;code&gt;./scripts/nats-box-scripts/config&lt;/code&gt;), sample messages (&lt;code&gt;./scripts/nats-box-scripts/tools&lt;/code&gt;) and a setup (&lt;code&gt;./scripts/nats-box-scripts/setup&lt;/code&gt;) script to a &lt;code&gt;nats-box&lt;/code&gt; container.
The &lt;code&gt;nats-box&lt;/code&gt; container contains a NATS CLI which can be used to configurate and monitor the NATS server. When you run the &lt;code&gt;start_nats.sh&lt;/code&gt; script you will end up in a shell within this &lt;code&gt;nats-box&lt;/code&gt; container.
Add this point you can run the &lt;code&gt;setup&lt;/code&gt; command to run the &lt;code&gt;./scripts/nats-box-scripts/setup&lt;/code&gt; script. This will create all configuration required for Parro Nexus to run.&lt;/p&gt;
&lt;p&gt;To test services you can use one of the sample messages in &lt;code&gt;./scripts/nats-box-scripts/tools&lt;/code&gt;. These are all added to the &lt;code&gt;/usr/local/bin&lt;/code&gt; dir so you can just run them as commands:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;dlq&lt;/strong&gt; - Send a message to the &lt;code&gt;connect.v1.dlq.ingester&lt;/code&gt; subject&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;error&lt;/strong&gt; - Send a message to the &lt;code&gt;connect.v1.error&lt;/code&gt; subject&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;get_org&lt;/strong&gt; - Send a request to the &lt;code&gt;organisation.v1.get_organisation&lt;/code&gt; subject&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ingest&lt;/strong&gt; - Send a message to the &lt;code&gt;message.v1.ingest&lt;/code&gt; subject&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;invalid_msg&lt;/strong&gt; - Send an invalid message to the &lt;code&gt;message.v1.validate&lt;/code&gt; subject&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;prepared&lt;/strong&gt; - Send a message to the &lt;code&gt;message.v1.prepared&lt;/code&gt; subject&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;receipt&lt;/strong&gt; - Send a message to the &lt;code&gt;message.v1.receipt&lt;/code&gt; subject&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;valid_msg&lt;/strong&gt; - Send a message to the &lt;code&gt;message.v1.validate&lt;/code&gt; subject&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;stop-the-server&#34;&gt;Stop the server&lt;/h3&gt;
&lt;p&gt;To stop the server you can kill the running docker containers or run the &lt;code&gt;stop_nats.sh&lt;/code&gt; script in the &lt;code&gt;scripts&lt;/code&gt; directory.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Dev: Tests</title>
      <link>/dev/local-dev/tests/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/dev/local-dev/tests/</guid>
      <description>
        
        
        &lt;h2 id=&#34;tests&#34;&gt;Tests&lt;/h2&gt;
&lt;p&gt;All services and libraries have tests.
There are 2 type of tests implemented:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Unit tests&lt;/li&gt;
&lt;li&gt;End 2 End (e2e) tests&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These tests are written using the &lt;a href=&#34;https://jestjs.io/&#34;&gt;jest&lt;/a&gt; framework (since this is used by nestjs).&lt;/p&gt;
&lt;p&gt;The unit tests are located near the source in a &lt;code&gt;test&lt;/code&gt; directory, and all the files have the extension &lt;code&gt;.spec.ts&lt;/code&gt;
To run the test run the command &lt;code&gt;yarn test&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The e2e tests are all located in the &lt;code&gt;test&lt;/code&gt; directory in the root dir of an app, they have the extension &lt;code&gt;.e2e-spec.ts&lt;/code&gt;.
To run the e2e tests run &lt;code&gt;yarn test:e2e&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;yarn test:e2e&lt;/code&gt; test runs the command &lt;code&gt;jest --config ./test/jest-e2e.json&lt;/code&gt;.
This is important when you want to run the tests from your IDE, since the e2e tests require a config file.
When you run the tests from an IDE make sure is also uses this config file otherwise the tests won&amp;rsquo;t work.&lt;/p&gt;
&lt;h2 id=&#34;testcontainers&#34;&gt;Testcontainers&lt;/h2&gt;
&lt;p&gt;Most of the e2e tests make use of the &lt;a href=&#34;https://node.testcontainers.org/quickstart/&#34;&gt;testcontainers project&lt;/a&gt;.
The testcontainers are used to start all dependencies of an application (i.e. postgres or NATS).&lt;/p&gt;
&lt;p&gt;This way you can test the actual app without mocking all external dependencies.&lt;/p&gt;
&lt;h2 id=&#34;scripts&#34;&gt;Scripts&lt;/h2&gt;
&lt;p&gt;The package.json files for all apps contain multiple scripts to run tests:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;test: Run the unit tests&lt;/li&gt;
&lt;li&gt;test:watch: Run the unit test and watch for changes for hot reloading&lt;/li&gt;
&lt;li&gt;test:cov: Run the unit tests with code coverage&lt;/li&gt;
&lt;li&gt;test:debug: Run the tests, but wait for a debugger before starting&lt;/li&gt;
&lt;li&gt;test:e2e: Run the e2e tests&lt;/li&gt;
&lt;li&gt;test:e2e-cov: Run the e2e tests with code coverage&lt;/li&gt;
&lt;li&gt;test:full-cov: Run all the test (unit and e2e) and combine the code coverages (this is used by the build pipelines)&lt;/li&gt;
&lt;li&gt;test:cov-silent: Run the units tests with code coverage, but without output (only errors)&lt;/li&gt;
&lt;li&gt;test:e2e-cov-silent: Run the e2e tests with code coverage, but without output (only errors)&lt;/li&gt;
&lt;li&gt;test:full-cov-silent: Run all the test (unit and e2e) and combine the code coverages, but without output (only errors)&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Dev: Docs</title>
      <link>/dev/local-dev/docs/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/dev/local-dev/docs/</guid>
      <description>
        
        
        &lt;h2 id=&#34;docs&#34;&gt;Docs&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&#34;https://docs.parro-connect.topicusonderwijs.build&#34;&gt;docs site&lt;/a&gt; for Parro Nexus (the one you are looking at now) is maintained from within the Parro nexus repo.
This site renders markdown files using &lt;a href=&#34;https://gohugo.io/&#34;&gt;Hugo&lt;/a&gt; with the &lt;a href=&#34;https://www.docsy.dev/&#34;&gt;Docsy&lt;/a&gt; template.&lt;/p&gt;
&lt;p&gt;When you make changes to the markdown, or add new documentation it will auto update the site using a &lt;a href=&#34;https://jenkins2.topicusonderwijs.nl/view/Parro/job/geon/job/Microservices/job/docs/&#34;&gt;Jenkins job&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The &lt;a href=&#34;https://github.com/topicusonderwijs/parro-nexus/blob/jenkins-pipeline/Jenkinsfile-docs.groovy&#34;&gt;Jenkinsfile&lt;/a&gt; for this job contains the following steps:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Validate&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;dockerfile.validate {}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This will validate the Dockerfile locates in the docs dir &lt;code&gt;docs/Dockerfile&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Build the site&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Since hugo generates all the static html we need to run it against the source of this repository.
There is no default jenkins step for hugo so we run the commands inside a docker image from hugo.
Since jenkins will mount the current workspace dir inside the container this will have the same effect as running &lt;code&gt;hugo&lt;/code&gt; inside the docs directory&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;docker.image(&amp;#34;klakegg/hugo:ext&amp;#34;).inside(&amp;#34;--entrypoint=\&amp;#34;\&amp;#34;&amp;#34;) {
    sh(&amp;#34;&amp;#34;&amp;#34;
        git submodule update --init --recursive themes/docsy 
        hugo
    &amp;#34;&amp;#34;&amp;#34;)
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Build docker image&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;def img = dockerfile.build {
    stage = &amp;#34;Build image&amp;#34;
    name = &amp;#34;parro-connect/docs&amp;#34;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Build the docker container with the generated static html pages&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Publish the image&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;dockerfile.publish {
    stage = &amp;#34;Publish image&amp;#34;
    image = img
    distribute = false
    tags = [&amp;#34;${tag}&amp;#34;]
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Publish the image to the artifactory&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Deploy&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;stage(&amp;#34;Deploy&amp;#34;){
    if(branchName == &amp;#34;main&amp;#34;){
        build   job: &amp;#34;geon/Microservices/deploy_development&amp;#34;,
                wait: false,
                propagate: true,
                parameters: [
                    string(name: &amp;#39;service_name&amp;#39;, value: &amp;#34;docs&amp;#34;),
                    string(name: &amp;#39;new_version&amp;#39;, value: tag),
                ]
    }else{
        jenkinsHelper.markStageAsSkipped(&amp;#34;Deploy&amp;#34;)
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;All commits on the main branch should be published.
This is done by a separate job &lt;code&gt;geon/Microservices/deploy_development&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&#34;running-the-docs-local&#34;&gt;Running the docs local&lt;/h2&gt;
&lt;p&gt;There are 2 ways to run the docs local:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Install hugo&lt;/li&gt;
&lt;li&gt;Run it in a container&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For both options there is a script in the docs dir:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;start_docs.sh -&amp;gt; will start a docker container&lt;/li&gt;
&lt;li&gt;start_docs_local_hugo.sh -&amp;gt; will start hugo with the correct startup parameters&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Both scripts will start hugo in a watch mode which will show updates as you type.
The local site is served at http://localhost:1313&lt;/p&gt;

      </description>
    </item>
    
  </channel>
</rss>
