diff --git a/packages/app-shell/rollup.config.js b/packages/app-shell/rollup.config.js
index 254f320bc3c53b0e03268f40805a51b1d130fd80..71997a34cbf3f2e209b6b5ec9ef0c7dfa3dbf4e4 100644
--- a/packages/app-shell/rollup.config.js
+++ b/packages/app-shell/rollup.config.js
@@ -6,71 +6,55 @@ import serve from 'rollup-plugin-serve';
 import consts from 'rollup-plugin-consts';
 import del from 'rollup-plugin-delete';
 import json from '@rollup/plugin-json';
+import {getBuildInfo, getPackagePath} from '../../rollup.utils.js';
 
 const build = (typeof process.env.BUILD !== 'undefined') ? process.env.BUILD : 'local';
 console.log("build: " + build);
 
-function getBuildInfo() {
-    const child_process = require('child_process');
-    const url = require('url');
-
-    let remote = child_process.execSync('git config --get remote.origin.url').toString().trim();
-    let commit = child_process.execSync('git rev-parse --short HEAD').toString().trim();
-
-    let parsed = url.parse(remote);
-    let newPath = parsed.path.slice(0, parsed.path.lastIndexOf('.'));
-    let newUrl = parsed.protocol + '//' + parsed.host + newPath + '/commit/' + commit;
-
+export default (async () => {
     return {
-        info: commit,
-        url: newUrl,
-        time: new Date().toISOString(),
-        env: build
+        input: (build !='test') ? ['src/dbp-app-shell.js', 'src/dbp-activity-example.js'] : glob.sync('test/**/*.js'),
+        output: {
+            dir: 'dist',
+            entryFileNames: '[name].js',
+            chunkFileNames: 'shared/[name].[hash].[format].js',
+            format: 'esm',
+            sourcemap: true
+          },
+        onwarn: function (warning, warn) {
+            // ignore chai warnings
+            if (warning.code === 'CIRCULAR_DEPENDENCY') {
+              return;
+            }
+            // keycloak bundled code uses eval
+            if (warning.code === 'EVAL') {
+                return;
+            }
+            warn(warning);
+        },
+        plugins: [
+            del({
+                targets: 'dist/*'
+              }),
+            consts({
+                environment: build,
+                buildinfo: getBuildInfo(build),
+            }),
+            resolve(),
+            commonjs(),
+            json(),
+            copy({
+                targets: [
+                    {src: 'assets/silent-check-sso.html', dest:'dist'},
+                    {src: 'assets/index.html', dest: 'dist'},
+                    {src: 'assets/*.json', dest: 'dist'},
+                    {src: await getPackagePath('dbp-common', 'assets/icons/*.svg'), dest: 'dist/local/dbp-common/icons'},
+                ],
+            }),
+            (process.env.ROLLUP_WATCH === 'true') ? serve({
+                contentBase: 'dist',
+                historyApiFallback: '/index.html',
+                host: '127.0.0.1', port: 8002}) : false
+        ]
     }
-}
-
-export default {
-    input: (build !='test') ? ['src/dbp-app-shell.js', 'src/dbp-activity-example.js'] : glob.sync('test/**/*.js'),
-    output: {
-        dir: 'dist',
-        entryFileNames: '[name].js',
-        chunkFileNames: 'shared/[name].[hash].[format].js',
-        format: 'esm',
-        sourcemap: true
-      },
-    onwarn: function (warning, warn) {
-        // ignore chai warnings
-        if (warning.code === 'CIRCULAR_DEPENDENCY') {
-          return;
-        }
-        // keycloak bundled code uses eval
-        if (warning.code === 'EVAL') {
-            return;
-        }
-        warn(warning);
-    },
-    plugins: [
-        del({
-            targets: 'dist/*'
-          }),
-        consts({
-            environment: build,
-            buildinfo: getBuildInfo(),
-        }),
-        resolve(),
-        commonjs(),
-        json(),
-        copy({
-            targets: [
-                {src: 'assets/silent-check-sso.html', dest:'dist'},
-                {src: 'assets/index.html', dest: 'dist'},
-                {src: 'assets/*.json', dest: 'dist'},
-                {src: 'node_modules/dbp-common/assets/icons/*.svg', dest: 'dist/local/dbp-common/icons'},
-            ],
-        }),
-        (process.env.ROLLUP_WATCH === 'true') ? serve({
-            contentBase: 'dist',
-            historyApiFallback: '/index.html',
-            host: '127.0.0.1', port: 8002}) : false
-    ]
-};
+})();
\ No newline at end of file
diff --git a/packages/auth/rollup.config.js b/packages/auth/rollup.config.js
index b199dd8ea8dba8fd719466bbb01ba6509ffc8543..cbad57d18261074304f80a4c502a5cc4bbb99422 100644
--- a/packages/auth/rollup.config.js
+++ b/packages/auth/rollup.config.js
@@ -7,51 +7,53 @@ import json from '@rollup/plugin-json';
 import serve from 'rollup-plugin-serve';
 import consts from 'rollup-plugin-consts';
 import del from 'rollup-plugin-delete';
+import {getPackagePath} from '../../rollup.utils.js';
 
 const pkg = require('./package.json');
 const build = (typeof process.env.BUILD !== 'undefined') ? process.env.BUILD : 'local';
 console.log("build: " + build);
 
-
-export default {
-    input: (build != 'test') ? ['src/dbp-auth.js', 'src/dbp-auth-demo.js'] : glob.sync('test/**/*.js'),
-    output: {
-        dir: 'dist',
-        entryFileNames: '[name].js',
-        chunkFileNames: 'shared/[name].[hash].[format].js',
-        format: 'esm',
-        sourcemap: true
-    },
-    onwarn: function (warning, warn) {
-        // keycloak bundled code uses eval
-        if (warning.code === 'EVAL') {
-            return;
-        }
-        // ignore chai warnings
-        if (warning.code === 'CIRCULAR_DEPENDENCY') {
-            return;
-        }
-        warn(warning);
-    },
-    plugins: [
-        del({
-            targets: 'dist/*'
-        }),
-        consts({
-            environment: build,
-        }),
-        resolve(),
-        commonjs(),
-        json(),
-        (build !== 'local' && build !== 'test') ? terser() : false,
-        copy({
-            targets: [
-                {src: 'assets/index.html', dest:'dist'},
-                {src: 'assets/silent-check-sso.html', dest: 'dist/local/' + pkg.name},
-                {src: 'assets/favicon.ico', dest:'dist'},
-                {src: 'node_modules/dbp-common/assets/icons/*.svg', dest: 'dist/local/dbp-common/icons'},
-            ]
-        }),
-        (process.env.ROLLUP_WATCH === 'true') ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) : false
-    ]
-};
+export default (async () => {
+    return {
+        input: (build != 'test') ? ['src/dbp-auth.js', 'src/dbp-auth-demo.js'] : glob.sync('test/**/*.js'),
+        output: {
+            dir: 'dist',
+            entryFileNames: '[name].js',
+            chunkFileNames: 'shared/[name].[hash].[format].js',
+            format: 'esm',
+            sourcemap: true
+        },
+        onwarn: function (warning, warn) {
+            // keycloak bundled code uses eval
+            if (warning.code === 'EVAL') {
+                return;
+            }
+            // ignore chai warnings
+            if (warning.code === 'CIRCULAR_DEPENDENCY') {
+                return;
+            }
+            warn(warning);
+        },
+        plugins: [
+            del({
+                targets: 'dist/*'
+            }),
+            consts({
+                environment: build,
+            }),
+            resolve(),
+            commonjs(),
+            json(),
+            (build !== 'local' && build !== 'test') ? terser() : false,
+            copy({
+                targets: [
+                    {src: 'assets/index.html', dest:'dist'},
+                    {src: 'assets/silent-check-sso.html', dest: 'dist/local/' + pkg.name},
+                    {src: 'assets/favicon.ico', dest:'dist'},
+                    {src: await getPackagePath('dbp-common', 'assets/icons/*.svg'), dest: 'dist/local/dbp-common/icons'},
+                ]
+            }),
+            (process.env.ROLLUP_WATCH === 'true') ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) : false
+        ]
+    };
+})();
\ No newline at end of file
diff --git a/packages/data-table-view/rollup.config.js b/packages/data-table-view/rollup.config.js
index eb2ff3e0a02a9e1a888823d26fbccfb58cba9087..17209b0752cd901bed1f9b40902c7ea6b2f42d4d 100644
--- a/packages/data-table-view/rollup.config.js
+++ b/packages/data-table-view/rollup.config.js
@@ -8,70 +8,72 @@ import serve from 'rollup-plugin-serve';
 import urlPlugin from "@rollup/plugin-url";
 import consts from 'rollup-plugin-consts';
 import del from 'rollup-plugin-delete';
+import {getPackagePath} from '../../rollup.utils.js';
 
 const pkg = require('./package.json');
 const build = (typeof process.env.BUILD !== 'undefined') ? process.env.BUILD : 'local';
 console.log("build: " + build);
 
-export default {
-    input: (build != 'test') ? ['src/dbp-data-table-view.js', 'src/dbp-data-table-view-demo.js'] : glob.sync('test/**/*.js'),
-    output: {
-        dir: 'dist',
-        entryFileNames: '[name].js',
-        chunkFileNames: 'shared/[name].[hash].[format].js',
-        format: 'esm',
-        sourcemap: true
-    },
-    onwarn: function (warning, warn) {
-        // ignore "suggestions" warning re "use strict"
-        if (warning.code === 'MODULE_LEVEL_DIRECTIVE') {
-            return;
-        }
-        // ignore chai warnings
-        if (warning.code === 'CIRCULAR_DEPENDENCY') {
-            return;
-        }
-        // keycloak bundled code uses eval
-        if (warning.code === 'EVAL') {
-            return;
-        }
-        warn(warning);
-    },
-    watch: {
-        chokidar: true,
-    },
-    plugins: [
-        del({
-            targets: 'dist/*'
-        }),
-        consts({
-            environment: build,
-        }),
-        resolve(),
-        commonjs(),
-        json(),
-        urlPlugin({
-            limit: 0,
-            emitFiles: true,
-            fileName: 'shared/[name].[hash][extname]'
-          }),
-        (build !== 'local' && build !== 'test') ? terser() : false,
-        copy({
-            targets: [
-                {src: 'assets/index.html', dest: 'dist'}, //rename: pkg.name + '.html'},
-                {src: 'assets/*.css', dest: 'dist/local/' + pkg.name},
-                {src: 'assets/*.ico', dest: 'dist/local/' + pkg.name},
-                {src: 'node_modules/dbp-common/dbp-spinner.js', dest: 'dist/local/' + pkg.name, rename: 'spinner.js'},
-                {src: 'node_modules/dbp-common/assets/icons/*.svg', dest: 'dist/local/dbp-common/icons'},
-                {src: 'assets/nomodule.js', dest: 'dist/local/' + pkg.name},
+export default (async () => {
+    return {
+        input: (build != 'test') ? ['src/dbp-data-table-view.js', 'src/dbp-data-table-view-demo.js'] : glob.sync('test/**/*.js'),
+        output: {
+            dir: 'dist',
+            entryFileNames: '[name].js',
+            chunkFileNames: 'shared/[name].[hash].[format].js',
+            format: 'esm',
+            sourcemap: true
+        },
+        onwarn: function (warning, warn) {
+            // ignore "suggestions" warning re "use strict"
+            if (warning.code === 'MODULE_LEVEL_DIRECTIVE') {
+                return;
+            }
+            // ignore chai warnings
+            if (warning.code === 'CIRCULAR_DEPENDENCY') {
+                return;
+            }
+            // keycloak bundled code uses eval
+            if (warning.code === 'EVAL') {
+                return;
+            }
+            warn(warning);
+        },
+        watch: {
+            chokidar: true,
+        },
+        plugins: [
+            del({
+                targets: 'dist/*'
+            }),
+            consts({
+                environment: build,
+            }),
+            resolve(),
+            commonjs(),
+            json(),
+            urlPlugin({
+                limit: 0,
+                emitFiles: true,
+                fileName: 'shared/[name].[hash][extname]'
+            }),
+            (build !== 'local' && build !== 'test') ? terser() : false,
+            copy({
+                targets: [
+                    {src: 'assets/index.html', dest: 'dist'},
+                    {src: 'assets/*.css', dest: 'dist/local/' + pkg.name},
+                    {src: 'assets/*.ico', dest: 'dist/local/' + pkg.name},
+                    {src: 'assets/nomodule.js', dest: 'dist/local/' + pkg.name},
 
-                {src: '../../node_modules/datatables.net-dt/css', dest: 'dist/local/dbp-data-table-view'},
-                {src: '../../node_modules/datatables.net-dt/images', dest: 'dist/local/dbp-data-table-view'},
-                {src: '../../node_modules/datatables.net-responsive-dt/css', dest: 'dist/local/dbp-data-table-view'},
-                {src: '../../node_modules/datatables.net-buttons-dt/css', dest: 'dist/local/dbp-data-table-view'},
-            ],
-        }),
+                    {src: await getPackagePath('dbp-common', 'assets/icons/*.svg'), dest: 'dist/local/dbp-common/icons'},
+                    {src: await getPackagePath('datatables.net-dt', 'css'), dest: 'dist/local/dbp-data-table-view'},
+                    {src: await getPackagePath('datatables.net-dt', 'images'), dest: 'dist/local/dbp-data-table-view'},
+                    {src: await getPackagePath('datatables.net-responsive-dt', 'css'), dest: 'dist/local/dbp-data-table-view'},
+                    {src: await getPackagePath('datatables.net-buttons-dt', 'css'), dest: 'dist/local/dbp-data-table-view'},
+                ],
+            }),
 
-        (process.env.ROLLUP_WATCH === 'true') ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8003}) : false
-    ]
-};
+            (process.env.ROLLUP_WATCH === 'true') ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8003}) : false
+        ]
+    };
+})();
\ No newline at end of file
diff --git a/packages/file-handling/rollup.config.js b/packages/file-handling/rollup.config.js
index be1a1676b22083e4ef1c7f7d6607142ad4bcc36f..3c597be182733aedd8571ba82b1de1005f963bca 100644
--- a/packages/file-handling/rollup.config.js
+++ b/packages/file-handling/rollup.config.js
@@ -7,6 +7,7 @@ import json from '@rollup/plugin-json';
 import serve from 'rollup-plugin-serve';
 import consts from 'rollup-plugin-consts';
 import del from 'rollup-plugin-delete';
+import {getPackagePath} from '../../rollup.utils.js';
 
 const build = (typeof process.env.BUILD !== 'undefined') ? process.env.BUILD : 'local';
 console.log("build: " + build);
@@ -14,36 +15,38 @@ console.log("build: " + build);
 let nextcloudBaseURL = 'https://cloud.tugraz.at';
 let nextcloudFileURL = nextcloudBaseURL + '/apps/files/?dir=';
 
-export default {
-    input: (build !== 'test') ? ['src/demo.js', 'src/dbp-file-source.js'] : glob.sync('test/**/*.js'),
-    output: {
-        dir: 'dist',
-        entryFileNames: '[name].js',
-        chunkFileNames: 'shared/[name].[hash].[format].js',
-        format: 'esm',
-        sourcemap: true
-    },
-    plugins: [
-        del({
-            targets: 'dist/*'
-        }),
-        consts({
-            environment: build,
-            nextcloudBaseURL: nextcloudBaseURL,
-            nextcloudFileURL: nextcloudFileURL,
-        }),
-        resolve(),
-        commonjs(),
-        json(),
-        (build !== 'local' && build !== 'test') ? terser() : false,
-        copy({
-            targets: [
-                {src: 'assets/index.html', dest: 'dist'},
-                {src: 'assets/favicon.ico', dest: 'dist'},
-                {src: '../../node_modules/material-design-icons-svg/paths/*.json', dest: 'dist/local/dbp-common/icons'},
-                {src: '../../node_modules/tabulator-tables/dist/css', dest: 'dist/local/dbp-file-source/tabulator-tables'},
-            ],
-        }),
-        (process.env.ROLLUP_WATCH === 'true') ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) : false
-    ]
-};
+export default (async () => {
+    return {
+        input: (build !== 'test') ? ['src/demo.js', 'src/dbp-file-source.js'] : glob.sync('test/**/*.js'),
+        output: {
+            dir: 'dist',
+            entryFileNames: '[name].js',
+            chunkFileNames: 'shared/[name].[hash].[format].js',
+            format: 'esm',
+            sourcemap: true
+        },
+        plugins: [
+            del({
+                targets: 'dist/*'
+            }),
+            consts({
+                environment: build,
+                nextcloudBaseURL: nextcloudBaseURL,
+                nextcloudFileURL: nextcloudFileURL,
+            }),
+            resolve(),
+            commonjs(),
+            json(),
+            (build !== 'local' && build !== 'test') ? terser() : false,
+            copy({
+                targets: [
+                    {src: 'assets/index.html', dest: 'dist'},
+                    {src: 'assets/favicon.ico', dest: 'dist'},
+                    {src: await getPackagePath('dbp-common', 'assets/icons/*.svg'), dest: 'dist/local/dbp-common/icons'},
+                    {src: await getPackagePath('tabulator-tables', 'dist/css'), dest: 'dist/local/dbp-file-source/tabulator-tables'},
+                ],
+            }),
+            (process.env.ROLLUP_WATCH === 'true') ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) : false
+        ]
+    };
+})();
\ No newline at end of file
diff --git a/packages/knowledge-base-web-page-element-view/rollup.config.js b/packages/knowledge-base-web-page-element-view/rollup.config.js
index 331a360a2123ba550db828f86c6ae1cdbd5fd329..f8e63062172b0d2d0f69c1deb7ea9e7b9521d647 100644
--- a/packages/knowledge-base-web-page-element-view/rollup.config.js
+++ b/packages/knowledge-base-web-page-element-view/rollup.config.js
@@ -8,49 +8,52 @@ import serve from 'rollup-plugin-serve';
 import url from "@rollup/plugin-url";
 import consts from 'rollup-plugin-consts';
 import del from 'rollup-plugin-delete';
+import {getPackagePath} from '../../rollup.utils.js';
 
 const build = (typeof process.env.BUILD !== 'undefined') ? process.env.BUILD : 'local';
 console.log("build: " + build);
 
-export default {
-    input: (build != 'test') ? ['src/dbp-knowledge-base-web-page-element-view.js', 'src/dbp-knowledge-base-web-page-element-view-demo.js'] : glob.sync('test/**/*.js'),
-    output: {
-        dir: 'dist',
-        entryFileNames: '[name].js',
-        chunkFileNames: 'shared/[name].[hash].[format].js',
-        format: 'esm',
-        sourcemap: true
-    },
-    onwarn: function (warning, warn) {
-        // keycloak bundled code uses eval
-        if (warning.code === 'EVAL') {
-          return;
-        }
-        warn(warning);
-    },
-    plugins: [
-        del({
-            targets: 'dist/*'
-        }),
-        consts({
-            environment: build,
-        }),
-        resolve(),
-        commonjs(),
-        json(),
-        url({
-            limit: 0,
-            emitFiles: true,
-            fileName: 'shared/[name].[hash][extname]'
-        }),
-        (build !== 'local' && build !== 'test') ? terser() : false,
-        copy({
-            targets: [
-                {src: 'assets/index.html', dest: 'dist'},
-                {src: 'assets/favicon.ico', dest: 'dist'},
-                {src: 'node_modules/dbp-common/assets/icons/*.svg', dest: 'dist/local/dbp-common/icons'},
-            ],
-        }),
-        (process.env.ROLLUP_WATCH === 'true') ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) : false
-    ]
-};
+export default (async () => {
+    return {
+        input: (build != 'test') ? ['src/dbp-knowledge-base-web-page-element-view.js', 'src/dbp-knowledge-base-web-page-element-view-demo.js'] : glob.sync('test/**/*.js'),
+        output: {
+            dir: 'dist',
+            entryFileNames: '[name].js',
+            chunkFileNames: 'shared/[name].[hash].[format].js',
+            format: 'esm',
+            sourcemap: true
+        },
+        onwarn: function (warning, warn) {
+            // keycloak bundled code uses eval
+            if (warning.code === 'EVAL') {
+            return;
+            }
+            warn(warning);
+        },
+        plugins: [
+            del({
+                targets: 'dist/*'
+            }),
+            consts({
+                environment: build,
+            }),
+            resolve(),
+            commonjs(),
+            json(),
+            url({
+                limit: 0,
+                emitFiles: true,
+                fileName: 'shared/[name].[hash][extname]'
+            }),
+            (build !== 'local' && build !== 'test') ? terser() : false,
+            copy({
+                targets: [
+                    {src: 'assets/index.html', dest: 'dist'},
+                    {src: 'assets/favicon.ico', dest: 'dist'},
+                    {src: await getPackagePath('dbp-common', 'assets/icons/*.svg'), dest: 'dist/local/dbp-common/icons'},
+                ],
+            }),
+            (process.env.ROLLUP_WATCH === 'true') ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) : false
+        ]
+    };
+})();
\ No newline at end of file
diff --git a/packages/person-profile/rollup.config.js b/packages/person-profile/rollup.config.js
index 0de66fdbbdc2cedf2518589b760f50a2c5fa3c12..685196d6d09684d6971a07d270df77fc1cc79125 100644
--- a/packages/person-profile/rollup.config.js
+++ b/packages/person-profile/rollup.config.js
@@ -9,51 +9,54 @@ import serve from 'rollup-plugin-serve';
 import url from "@rollup/plugin-url"
 import consts from 'rollup-plugin-consts';
 import del from 'rollup-plugin-delete';
+import {getPackagePath} from '../../rollup.utils.js';
 
 const build = (typeof process.env.BUILD !== 'undefined') ? process.env.BUILD : 'local';
 console.log("build: " + build);
 
-export default {
-    input: (build != 'test') ? ['src/dbp-person-profile.js', 'src/dbp-person-profile-demo.js'] : glob.sync('test/**/*.js'),
-    output: {
-        dir: 'dist',
-        entryFileNames: '[name].js',
-        chunkFileNames: 'shared/[name].[hash].[format].js',
-        format: 'esm',
-        sourcemap: true
-    },
-    onwarn: function (warning, warn) {
-        // keycloak bundled code uses eval
-        if (warning.code === 'EVAL') {
-          return;
-        }
-        warn(warning);
-    },
-    plugins: [
-        del({
-            targets: 'dist/*'
-        }),
-        consts({
-            environment: build,
-        }),
-        resolve(),
-        commonjs(),
-        url({
-            limit: 0,
-            include: [
-                "../../**/node_modules/select2/**/*.css",
-            ],
-            emitFiles: true,
-            fileName: 'shared/[name].[hash][extname]'
-        }),
-        json(),
-        (build !== 'local' && build !== 'test') ? terser() : false,
-        copy({
-            targets: [
-                {src: 'assets/index.html', dest: 'dist'},
-                {src: 'node_modules/dbp-common/assets/icons/*.svg', dest: 'dist/local/dbp-common/icons'},
-            ],
-        }),
-        (process.env.ROLLUP_WATCH === 'true') ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) : false
-    ]
-};
+export default (async () => {
+    return {
+        input: (build != 'test') ? ['src/dbp-person-profile.js', 'src/dbp-person-profile-demo.js'] : glob.sync('test/**/*.js'),
+        output: {
+            dir: 'dist',
+            entryFileNames: '[name].js',
+            chunkFileNames: 'shared/[name].[hash].[format].js',
+            format: 'esm',
+            sourcemap: true
+        },
+        onwarn: function (warning, warn) {
+            // keycloak bundled code uses eval
+            if (warning.code === 'EVAL') {
+            return;
+            }
+            warn(warning);
+        },
+        plugins: [
+            del({
+                targets: 'dist/*'
+            }),
+            consts({
+                environment: build,
+            }),
+            resolve(),
+            commonjs(),
+            url({
+                limit: 0,
+                include: [
+                    await getPackagePath('select2', '**/*.css'),
+                ],
+                emitFiles: true,
+                fileName: 'shared/[name].[hash][extname]'
+            }),
+            json(),
+            (build !== 'local' && build !== 'test') ? terser() : false,
+            copy({
+                targets: [
+                    {src: 'assets/index.html', dest: 'dist'},
+                    {src: await getPackagePath('dbp-common', 'assets/icons/*.svg'), dest: 'dist/local/dbp-common/icons'},
+                ],
+            }),
+            (process.env.ROLLUP_WATCH === 'true') ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) : false
+        ]
+    };
+})();
\ No newline at end of file
diff --git a/packages/person-select/rollup.config.js b/packages/person-select/rollup.config.js
index cf08aa6f9d58138ecc6703d6fc46054c7b374d58..5a72c687d25035329e8733e782f3a8f13bef960d 100644
--- a/packages/person-select/rollup.config.js
+++ b/packages/person-select/rollup.config.js
@@ -8,51 +8,54 @@ import serve from 'rollup-plugin-serve';
 import url from "@rollup/plugin-url"
 import consts from 'rollup-plugin-consts';
 import del from 'rollup-plugin-delete';
+import {getPackagePath} from '../../rollup.utils.js';
 
 const build = (typeof process.env.BUILD !== 'undefined') ? process.env.BUILD : 'local';
 console.log("build: " + build);
 
-export default {
-    input: (build != 'test') ? ['src/dbp-person-select.js', 'src/dbp-person-select-demo.js'] : glob.sync('test/**/*.js'),
-    output: {
-        dir: 'dist',
-        entryFileNames: '[name].js',
-        chunkFileNames: 'shared/[name].[hash].[format].js',
-        format: 'esm',
-        sourcemap: true
-    },
-    onwarn: function (warning, warn) {
-        // keycloak bundled code uses eval
-        if (warning.code === 'EVAL') {
-            return;
-        }
-        warn(warning);
-    },
-    plugins: [
-        del({
-            targets: 'dist/*'
-        }),
-        consts({
-            environment: build,
-        }),
-        resolve(),
-        commonjs(),
-        url({
-            limit: 0,
-            include: [
-                "../../**/node_modules/select2/**/*.css",
-            ],
-            emitFiles: true,
-            fileName: 'shared/[name].[hash][extname]'
-        }),
-        json(),
-        (build !== 'local' && build !== 'test') ? terser() : false,
-        copy({
-            targets: [
-                {src: 'assets/index.html', dest: 'dist'},
-                {src: 'node_modules/dbp-common/assets/icons/*.svg', dest: 'dist/local/dbp-common/icons'},
-            ],
-        }),
-        (process.env.ROLLUP_WATCH === 'true') ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) : false
-    ]
-};
+export default (async () => {
+    return {
+        input: (build != 'test') ? ['src/dbp-person-select.js', 'src/dbp-person-select-demo.js'] : glob.sync('test/**/*.js'),
+        output: {
+            dir: 'dist',
+            entryFileNames: '[name].js',
+            chunkFileNames: 'shared/[name].[hash].[format].js',
+            format: 'esm',
+            sourcemap: true
+        },
+        onwarn: function (warning, warn) {
+            // keycloak bundled code uses eval
+            if (warning.code === 'EVAL') {
+                return;
+            }
+            warn(warning);
+        },
+        plugins: [
+            del({
+                targets: 'dist/*'
+            }),
+            consts({
+                environment: build,
+            }),
+            resolve(),
+            commonjs(),
+            url({
+                limit: 0,
+                include: [
+                    await getPackagePath('select2', '**/*.css'),
+                ],
+                emitFiles: true,
+                fileName: 'shared/[name].[hash][extname]'
+            }),
+            json(),
+            (build !== 'local' && build !== 'test') ? terser() : false,
+            copy({
+                targets: [
+                    {src: 'assets/index.html', dest: 'dist'},
+                    {src: await getPackagePath('dbp-common', 'assets/icons/*.svg'), dest: 'dist/local/dbp-common/icons'},
+                ],
+            }),
+            (process.env.ROLLUP_WATCH === 'true') ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) : false
+        ]
+    };
+})();
\ No newline at end of file
diff --git a/rollup.utils.js b/rollup.utils.js
new file mode 100644
index 0000000000000000000000000000000000000000..634b82d1898c8521001712ad7cede796651de7bf
--- /dev/null
+++ b/rollup.utils.js
@@ -0,0 +1,28 @@
+import path from 'path';
+import url from 'url';
+import child_process from 'child_process';
+import resolve from '@rollup/plugin-node-resolve';
+
+export function getBuildInfo(build) {
+    let remote = child_process.execSync('git config --get remote.origin.url').toString().trim();
+    let commit = child_process.execSync('git rev-parse --short HEAD').toString().trim();
+
+    let parsed = url.parse(remote);
+    let newPath = parsed.path.slice(0, parsed.path.lastIndexOf('.'));
+    let newUrl = parsed.protocol + '//' + parsed.host + newPath + '/commit/' + commit;
+
+    return {
+        info: commit,
+        url: newUrl,
+        time: new Date().toISOString(),
+        env: build
+    }
+}
+
+export async function getPackagePath(packageName, assetPath) {
+    const r = resolve();
+    const id = (await r.resolveId(packageName)).id;
+    const packageInfo = r.getPackageInfoForId(id);
+    const fullAssetPath = path.join(packageInfo.root, assetPath);
+    return path.relative(process.cwd(), fullAssetPath);
+}
\ No newline at end of file