{
    "componentChunkName": "component---src-templates-doc-tsx",
    "path": "/docs/3.9.x/en/development/plugins/plugin-development/",
    "result": {"data":{"navigation":{"nodes":[{"section":"Getting started","entries":[{"frontmatter":{"title":"Installation","subtitle":"Installation of scm-manager","partiallyActive":true},"fields":{"slug":"/docs/3.9.x/en/installation/"}},{"frontmatter":{"title":"First Startup","subtitle":"Administration User Creation","partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/first-startup/"}},{"frontmatter":{"title":"Migrate from v1 to v3","subtitle":"How to use the Migration-Wizard","partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/migrate-scm-manager-from-v1/"}},{"frontmatter":{"title":"Migrate from v2 to v3","subtitle":"Changes in the configuration","partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/migrate-scm-manager-from-v2/"}},{"frontmatter":{"title":"Import existing repositories","subtitle":"How to import existing repositories into SCM-Manager","partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/import/"}},{"frontmatter":{"title":"Frequently Asked Questions","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/faq/"}},{"frontmatter":{"title":"Known Issues","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/known-issues/"}}]},{"section":"User-oriented","entries":[{"frontmatter":{"title":"Repository","subtitle":null,"partiallyActive":true},"fields":{"slug":"/docs/3.9.x/en/user/repo/"}},{"frontmatter":{"title":"User","subtitle":null,"partiallyActive":true},"fields":{"slug":"/docs/3.9.x/en/user/user/"}},{"frontmatter":{"title":"Groups","subtitle":null,"partiallyActive":true},"fields":{"slug":"/docs/3.9.x/en/user/group/"}},{"frontmatter":{"title":"Administration","subtitle":null,"partiallyActive":true},"fields":{"slug":"/docs/3.9.x/en/user/admin/"}},{"frontmatter":{"title":"Profile","subtitle":null,"partiallyActive":true},"fields":{"slug":"/docs/3.9.x/en/user/profile/"}},{"frontmatter":{"title":"Notifications","subtitle":null,"partiallyActive":true},"fields":{"slug":"/docs/3.9.x/en/user/notification/"}},{"frontmatter":{"title":"CLI Client","subtitle":null,"partiallyActive":true},"fields":{"slug":"/docs/3.9.x/en/user/cli/"}},{"frontmatter":{"title":"Shortcuts","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/user/shortcuts/"}}]},{"section":"Administration","entries":[{"frontmatter":{"title":"Base Directory","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/administration/basedirectory/"}},{"frontmatter":{"title":"Logging","subtitle":"Configuration and locations of SCM-Manager logging","partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/administration/logging/"}},{"frontmatter":{"title":"SCM-Server Configuration","subtitle":"Various configuration options for the SCM-Server","partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/administration/scm-server/"}},{"frontmatter":{"title":"Reverse Proxy","subtitle":"How to use SCM-Manager with common reverse proxies","partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/administration/reverse-proxies/"}},{"frontmatter":{"title":"Caching for Working Directories","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/administration/workdir_caching/"}}]},{"section":"Development","entries":[{"frontmatter":{"title":"Intellij IDEA Configuration","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/intellij-idea-configuration/"}},{"frontmatter":{"title":"Building SCM-Manager from Source","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/build-from-source/"}},{"frontmatter":{"title":"Architecture overview","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/architecture-overview/"}},{"frontmatter":{"title":"Common pitfall occurred while developing the SCM V2","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/ui-common-pitfall/"}},{"frontmatter":{"title":"Permission Concept","subtitle":"Fine-grained permission for SCM-Manager v2","partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/permission-concept/"}},{"frontmatter":{"title":"Decision Table","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/decision-table/"}},{"frontmatter":{"title":"Error Handling","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/error-handling/"}},{"frontmatter":{"title":"Styleguide","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/styleguide/"}},{"frontmatter":{"title":"Testing Guide","subtitle":"Howto write tests for SCM-Manager","partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/testing-guide/"}},{"frontmatter":{"title":"Integration Tests","subtitle":"How to run integration tests","partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/integration-tests/"}},{"frontmatter":{"title":"UI-Extensions","subtitle":"How to extend the SCM-Manager UI with plugins","partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/ui-extensions/"}},{"frontmatter":{"title":"I18n","subtitle":"Howto do internationalization","partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/i18n/"}},{"frontmatter":{"title":"Building Forms","subtitle":"Howto build forms for SCM-Manager","partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/building-forms/"}},{"frontmatter":{"title":"Javadoc","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/javadoc/"}},{"frontmatter":{"title":"CLI Guidelines","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/cli-guideline/"}},{"frontmatter":{"title":"Definition of Done","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/definition-of-done/"}},{"frontmatter":{"title":"DOD for UI development","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/ui-dod/"}}]},{"section":"Plugin Development","entries":[{"frontmatter":{"title":"Create a plugin","subtitle":"Create a new SCM-Manager plugin","partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/plugins/create/"}},{"frontmatter":{"title":"Migrate a v1 plugin","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/plugins/migrate-plugin-from-v1/"}},{"frontmatter":{"title":"Extension Points","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/plugins/extension-points/"}},{"frontmatter":{"title":"i18n for Plugins","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/plugins/i18n-for-plugins/"}},{"frontmatter":{"title":"Plugin Descriptor","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/plugins/plugin-descriptor/"}},{"frontmatter":{"title":"SCM-Manager v2 Plugin Development","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/plugins/plugin-development/"}},{"frontmatter":{"title":"Publish","subtitle":"Publish your Plugin","partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/plugins/publish/"}}]}]},"versions":{"group":[{"fieldValue":"1.0.x"},{"fieldValue":"1.x"},{"fieldValue":"2.0.x"},{"fieldValue":"2.1.x"},{"fieldValue":"2.10.x"},{"fieldValue":"2.11.x"},{"fieldValue":"2.12.x"},{"fieldValue":"2.13.x"},{"fieldValue":"2.14.x"},{"fieldValue":"2.15.x"},{"fieldValue":"2.16.x"},{"fieldValue":"2.17.x"},{"fieldValue":"2.18.x"},{"fieldValue":"2.19.x"},{"fieldValue":"2.2.x"},{"fieldValue":"2.20.x"},{"fieldValue":"2.21.x"},{"fieldValue":"2.22.x"},{"fieldValue":"2.23.x"},{"fieldValue":"2.24.x"},{"fieldValue":"2.25.x"},{"fieldValue":"2.26.x"},{"fieldValue":"2.27.x"},{"fieldValue":"2.28.x"},{"fieldValue":"2.29.x"},{"fieldValue":"2.3.x"},{"fieldValue":"2.30.x"},{"fieldValue":"2.31.x"},{"fieldValue":"2.32.x"},{"fieldValue":"2.33.x"},{"fieldValue":"2.34.x"},{"fieldValue":"2.35.x"},{"fieldValue":"2.36.x"},{"fieldValue":"2.37.x"},{"fieldValue":"2.38.x"},{"fieldValue":"2.39.x"},{"fieldValue":"2.4.x"},{"fieldValue":"2.40.x"},{"fieldValue":"2.41.x"},{"fieldValue":"2.42.x"},{"fieldValue":"2.43.x"},{"fieldValue":"2.44.x"},{"fieldValue":"2.45.x"},{"fieldValue":"2.46.x"},{"fieldValue":"2.47.x"},{"fieldValue":"2.48.x"},{"fieldValue":"2.5.x"},{"fieldValue":"2.6.x"},{"fieldValue":"2.7.x"},{"fieldValue":"2.8.x"},{"fieldValue":"2.9.x"},{"fieldValue":"3.0.x"},{"fieldValue":"3.1.x"},{"fieldValue":"3.10.x"},{"fieldValue":"3.11.x"},{"fieldValue":"3.2.x"},{"fieldValue":"3.3.x"},{"fieldValue":"3.4.x"},{"fieldValue":"3.5.x"},{"fieldValue":"3.6.x"},{"fieldValue":"3.7.x"},{"fieldValue":"3.8.x"},{"fieldValue":"3.9.x"}]},"languages":{"group":[{"fieldValue":"de"},{"fieldValue":"en"}]},"markdownRemark":{"html":"<h2 id=\"build-and-testing\" style=\"position:relative;\"><a href=\"#build-and-testing\" aria-label=\"build and testing permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Build and testing</h2>\n<p>The plugin can be compiled and packaged with the normal maven lifecycle:</p>\n<ul>\n<li>clean - <code class=\"language-text\">mvn clean</code> - removes the target directory, can be combined with other phases</li>\n<li>compile - <code class=\"language-text\">mvn compile</code> - compiles Java code and creates the ui bundle</li>\n<li>test - <code class=\"language-text\">mvn test</code> - executes test for Java and JavaScript</li>\n<li>install - <code class=\"language-text\">mvn install</code> - installs the plugin (smp and jar) in the local maven repository</li>\n<li>package - <code class=\"language-text\">mvn package</code> - creates the final plugin bundle (smp package) in the target folder</li>\n<li>deploy - <code class=\"language-text\">mvn deploy</code> - deploys the plugin (smp and jar) to the configured remote repository</li>\n</ul>\n<p>For the development and testing the <code class=\"language-text\">serve</code> lifecycle of the plugin can be used:</p>\n<ul>\n<li>run - <code class=\"language-text\">mvn run</code> - starts scm-manager with the plugin pre installed.</li>\n</ul>\n<p>If the plugin was started with <code class=\"language-text\">mvn run</code>, the default browser of the os should be automatically opened.\nIf the browser does not start automatically, start it manually and go to <a href=\"http://localhost:8081/scm\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">http://localhost:8081/scm</a>.</p>\n<p>In this mode each change to web files (src/main/js or src/main/webapp), should trigger a reload of the browser with the made changes.\nIf you compile a class (e.g.: with your IDE from src/main/java to target/classes),\nthe SCM-Manager context will restart automatically. So you can see your changes without restarting the server.</p>\n<h2 id=\"directory--file-structure\" style=\"position:relative;\"><a href=\"#directory--file-structure\" aria-label=\"directory  file structure permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Directory &#x26; File structure</h2>\n<p>A quick look at the files and directories you'll see in a SCM-Manager project.</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">.\n├── node_modules/\n├── src/\n|   ├── main/\n|   |   ├── java/\n|   |   ├── js/\n|   |   └── resources/\n|   ├── test/\n|   |   ├── java/\n|   |   └── resources/\n|   └── target/\n├── .editorconfig\n├── .gitignore\n├── CHANGELOG.md\n├── LICENSE\n├── package.json\n├── pom.xml\n├── README.md\n├── tsconfig.json\n└── yarn.lock</code></pre></div>\n<ol>\n<li>\n<p><strong><code class=\"language-text\">node_modules/</code></strong>: This directory contains all of the modules of code that your project depends on (npm packages) are automatically installed.</p>\n</li>\n<li>\n<p><strong><code class=\"language-text\">src/</code></strong>: This directory will contain all of the code related to what you see or not. <code class=\"language-text\">src</code> is a convention for “source code”.</p>\n<ol>\n<li><strong><code class=\"language-text\">main/</code></strong>\n<ol>\n<li><strong><code class=\"language-text\">java/</code></strong>: This directory contain the Java code.</li>\n<li><strong><code class=\"language-text\">js/</code></strong>: This directory contains the TypeScript code for the web ui, inclusive unit tests: suffixed with <code class=\"language-text\">.test.ts</code> or <code class=\"language-text\">.test.tsx</code></li>\n<li><strong><code class=\"language-text\">resources/</code></strong>: This directory contains the the classpath resources.</li>\n</ol>\n</li>\n<li><strong><code class=\"language-text\">test/</code></strong>\n<ol>\n<li><strong><code class=\"language-text\">java/</code></strong>: This directory contains the Java unit tests.</li>\n<li><strong><code class=\"language-text\">resources/</code></strong>: This directory contains classpath resources for unit tests.</li>\n</ol>\n</li>\n<li><strong><code class=\"language-text\">target/</code></strong>: This is the build directory.</li>\n</ol>\n</li>\n<li>\n<p><strong><code class=\"language-text\">.editorconfig</code></strong>: This is a configuration file for your editor using <a href=\"https://editorconfig.org/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">EditorConfig</a>. The file specifies a style that IDEs use for code.</p>\n</li>\n<li>\n<p><strong><code class=\"language-text\">.gitignore</code></strong>: This file tells git which files it should not track / not maintain a version history for.</p>\n</li>\n<li>\n<p><strong><code class=\"language-text\">CHANGELOG.md</code></strong>: All notable changes to this project will be documented in this file.</p>\n</li>\n<li>\n<p><strong><code class=\"language-text\">LICENSE</code></strong>: This project is licensed under AGPL-3.0-only.</p>\n</li>\n<li>\n<p><strong><code class=\"language-text\">package.json</code></strong>: Here you can find the dependency/build configuration and dependencies for the frontend.</p>\n</li>\n<li>\n<p><strong><code class=\"language-text\">pom.xml</code></strong>: Maven configuration, which also includes things like metadata.</p>\n</li>\n<li>\n<p><strong><code class=\"language-text\">README.md</code></strong>: This file, containing useful reference information about the project.</p>\n</li>\n<li>\n<p><strong><code class=\"language-text\">tsconfig.json</code></strong> This is the typescript configuration file.</p>\n</li>\n<li>\n<p><strong><code class=\"language-text\">yarn.lock</code></strong>: This is the ui dependency configuration.</p>\n</li>\n</ol>\n<h2 id=\"ui-extensions\" style=\"position:relative;\"><a href=\"#ui-extensions\" aria-label=\"ui extensions permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>UI Extensions</h2>\n<p>Plugins are able to extend or modify the ui of SCM-Manager.\nIn order to extend the ui the plugin requires a <code class=\"language-text\">package.json</code> in the project root e.g:</p>\n<div class=\"gatsby-highlight\" data-language=\"json\"><pre class=\"language-json\"><code class=\"language-json\"><span class=\"token punctuation\">{</span>\n  <span class=\"token property\">\"name\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"@scm-manager/scm-readme-plugin\"</span><span class=\"token punctuation\">,</span>\n  <span class=\"token property\">\"main\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"src/main/js/index.tsx\"</span><span class=\"token punctuation\">,</span>\n  <span class=\"token property\">\"scripts\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token property\">\"build\"</span> <span class=\"token operator\">:</span> <span class=\"token string\">\"ui-scripts plugin\"</span><span class=\"token punctuation\">,</span>\n    <span class=\"token property\">\"watch\"</span> <span class=\"token operator\">:</span> <span class=\"token string\">\"ui-scripts plugin-watch\"</span><span class=\"token punctuation\">,</span>\n    <span class=\"token property\">\"test\"</span> <span class=\"token operator\">:</span> <span class=\"token string\">\"jest\"</span><span class=\"token punctuation\">,</span>\n    <span class=\"token property\">\"postinstall\"</span> <span class=\"token operator\">:</span> <span class=\"token string\">\"ui-plugins postinstall\"</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n  <span class=\"token property\">\"dependencies\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token property\">\"@scm-manager/ui-plugins\"</span> <span class=\"token operator\">:</span> <span class=\"token string\">\"2.0.0\"</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n</code></pre></div>\n<p>The <code class=\"language-text\">main</code> field of the <code class=\"language-text\">package.json</code> describes the main entry point of the plugin.\nThe file specified at <code class=\"language-text\">main</code> should use the <code class=\"language-text\">binder</code> from the <a href=\"../../ui-extensions\">@scm-manager/ui-extensions</a> in oder to bind its extensions.</p>\n<p>If the plugins gets build (<code class=\"language-text\">mvn package</code> or <code class=\"language-text\">mvn install</code>), the <a href=\"https://github.com/sdorra/buildfrontend-maven-plugin\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">buildfrontend-maven-plugin</a>, will call the <code class=\"language-text\">build</code> script of <code class=\"language-text\">package.json</code>.\nThe build script triggers the <code class=\"language-text\">plugin</code> command of <code class=\"language-text\">@scm-manager/ui-scripts</code>.\nThe <code class=\"language-text\">ui-scripts</code> will do the following steps:</p>\n<ul>\n<li>traverses the import statements of the script specified at <code class=\"language-text\">main</code></li>\n<li>transpiles TypeScript to es5</li>\n<li>creates a single bundle</li>\n<li>stores the bundle in the final smp package</li>\n</ul>\n<p>At runtime the plugins are loaded by PluginLoader. The PluginLoader is a React component, which does the following steps:</p>\n<ul>\n<li>fetches plugin metadata (name and registered bundles) from the rest service</li>\n<li>fetches each bundle of every plugin</li>\n<li>executes each bundle</li>\n<li>starts the rest of the application</li>\n</ul>\n<h2 id=\"static-web-resources\" style=\"position:relative;\"><a href=\"#static-web-resources\" aria-label=\"static web resources permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Static web resources</h2>\n<p>A plugin can also store static files in the <code class=\"language-text\">src/main/webapp</code> directory.\nAll files of the webapp directory can be resolved relative to the root of the application e.g. the file\n<code class=\"language-text\">src/main/webapp/images/logo.jpg</code> of a plugin can be resolved at <code class=\"language-text\">http://localhost:8081/scm/images/logo.jpg</code>\nassuming SCM-Manager is running at <code class=\"language-text\">http://localhost:8081/scm</code>.</p>","description":"Build and testing The plugin can be compiled and packaged with the normal maven lifecycle: clean -  - removes the target directory, can be combined with other…","tableOfContents":"<ul>\n<li><a href=\"#build-and-testing\">Build and testing</a></li>\n<li><a href=\"#directory--file-structure\">Directory &#x26; File structure</a></li>\n<li><a href=\"#ui-extensions\">UI Extensions</a></li>\n<li><a href=\"#static-web-resources\">Static web resources</a></li>\n</ul>","frontmatter":{"title":"SCM-Manager v2 Plugin Development","subtitle":null,"displayToc":null,"description":null,"keywords":null,"image":null}}},"pageContext":{"slug":"/docs/3.9.x/en/development/plugins/plugin-development/","version":"3.9.x","latestVersion":"3.11.x","latestPageVersion":"3.11.x","language":"en","relativePath":"/development/plugins/plugin-development/","canonicalPath":"/docs/latest/en/development/plugins/plugin-development/","latestRootPath":"/docs/3.11.x/en/"}},
    "staticQueryHashes": ["1973669194","2742214048","2956773653","2957019495","698804963"]}