From c680110477e04ceaee7fca0f72a410100464aeaa Mon Sep 17 00:00:00 2001 From: Ricardo Boss Date: Wed, 27 Jul 2022 19:11:27 +0200 Subject: [PATCH 01/34] Proof of concept runtime theming and api url setting --- .env.example | 5 ----- .gitignore | 1 + public/webapp-settings.example.json | 9 +++++++++ src/App.vue | 19 +++++++++++++++++++ src/WebappSettings.ts | 9 +++++++++ src/main.ts | 15 +-------------- src/plugins/vuetify.ts | 8 ++++---- src/shims-vuex.d.ts | 1 + 8 files changed, 44 insertions(+), 23 deletions(-) create mode 100644 public/webapp-settings.example.json create mode 100644 src/WebappSettings.ts diff --git a/.env.example b/.env.example index e15db32..e69de29 100644 --- a/.env.example +++ b/.env.example @@ -1,5 +0,0 @@ -VUE_APP_API_BASE=https://localhost:7262/api/ -VUE_APP_PRIMARY_COLOR='#8af' -VUE_APP_PRIMARY_FOREGROUND_COLOR='#000' -VUE_APP_NAME='My Wiki' -VUE_APP_USE_AUTH=false diff --git a/.gitignore b/.gitignore index 0058338..1f0836b 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ node_modules .env.local .env.*.local appsettings.local.json +public/webapp-settings.json # Log files npm-debug.log* diff --git a/public/webapp-settings.example.json b/public/webapp-settings.example.json new file mode 100644 index 0000000..943b296 --- /dev/null +++ b/public/webapp-settings.example.json @@ -0,0 +1,9 @@ +{ + "theme": { + "primary": "80,120,200", + "primary-foreground": "255,255,255" + }, + "api": { + "baseUrl": "https://localhost:7262/api/" + } +} \ No newline at end of file diff --git a/src/App.vue b/src/App.vue index 25029dc..627759e 100644 --- a/src/App.vue +++ b/src/App.vue @@ -127,6 +127,7 @@ import TrenzDocsLogo from "@/components/TrenzDocsLogo.vue"; import ApiClient from "@/api/ApiClient"; import {mapGetters} from "vuex"; import * as api from "@/api"; +import {WebappSettings} from "@/WebappSettings"; export default defineComponent({ name: 'App', @@ -139,6 +140,24 @@ export default defineComponent({ async beforeMount() { window.addEventListener('keydown', this.handleKeyDown) + ApiClient.setBaseUrl(window.location.origin) + const settings: WebappSettings = await ApiClient.getJson('webapp-settings.json') + + const baseUrl = settings.api.baseUrl; + if (typeof baseUrl === 'undefined') { + alert('Please add a webapp-settings.json file to the content root.') + + throw new Error('API base url is not set'); + } else { + ApiClient.setBaseUrl(baseUrl); + } + + let a = document.querySelectorAll('.v-theme--light'); + a.forEach(root => { + root.style.setProperty('--v-theme-primary', settings.theme.primary); + root.style.setProperty('--v-theme-on-primary', settings.theme["primary-foreground"]); + }) + await this.$store.dispatch('loadNavTree'); api.auth.state().then(result => { diff --git a/src/WebappSettings.ts b/src/WebappSettings.ts new file mode 100644 index 0000000..d59f246 --- /dev/null +++ b/src/WebappSettings.ts @@ -0,0 +1,9 @@ +export interface WebappSettings { + theme: { + primary: string; + 'primary-foreground': string; + } + api: { + baseUrl: string; + } +} diff --git a/src/main.ts b/src/main.ts index a6c1c27..0425091 100644 --- a/src/main.ts +++ b/src/main.ts @@ -3,20 +3,7 @@ import App from './App.vue' import router from './router' import store from './store' import vuetify from './plugins/vuetify' -import {loadFonts} from './plugins/webfontloader' -import ApiClient from "@/api/ApiClient"; - -if (process.env.VUE_APP_API_BASE) { - ApiClient.setBaseUrl(process.env.VUE_APP_API_BASE); -} else { - alert('Please set the VUE_APP_API_BASE environment variable (e.g. VUE_APP_API_BASE=https://localhost:7262/api)'); - - throw new Error('VUE_APP_API_BASE is not set'); -} - -if (process.env.VUE_APP_USE_AUTH && process.env.VUE_APP_USE_AUTH === 'true') { - ApiClient.useAuth = true; -} +import { loadFonts } from './plugins/webfontloader' loadFonts() diff --git a/src/plugins/vuetify.ts b/src/plugins/vuetify.ts index 5cae0b7..1fb01eb 100644 --- a/src/plugins/vuetify.ts +++ b/src/plugins/vuetify.ts @@ -19,15 +19,15 @@ export default createVuetify({ themes: { light: { colors: { - primary: process.env.VUE_APP_PRIMARY_COLOR ?? '#ddd', - 'on-primary': process.env.VUE_APP_PRIMARY_FOREGROUND_COLOR ?? '#000', + primary: '#ddd', + 'on-primary': '#000', } } as ThemeDefinition, dark: { dark: true, colors: { - primary: process.env.VUE_APP_PRIMARY_COLOR ?? '#222', - 'on-primary': process.env.VUE_APP_PRIMARY_FOREGROUND_COLOR ?? '#fff', + primary: '#222', + 'on-primary': '#fff', } } as ThemeDefinition, }, diff --git a/src/shims-vuex.d.ts b/src/shims-vuex.d.ts index 9eb7538..ae2168b 100644 --- a/src/shims-vuex.d.ts +++ b/src/shims-vuex.d.ts @@ -4,5 +4,6 @@ import {State} from "@/store/State"; declare module '@vue/runtime-core' { interface ComponentCustomProperties { $store: Store + $settings: WebappSettings } } From 4d755361370723973477bdea8768d8ba36195f81 Mon Sep 17 00:00:00 2001 From: Ricardo Boss Date: Fri, 19 Aug 2022 11:22:14 +0200 Subject: [PATCH 02/34] Added useAuth to webapp settings --- public/webapp-settings.example.json | 5 +++-- src/WebappSettings.ts | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/public/webapp-settings.example.json b/public/webapp-settings.example.json index 943b296..e96bb2e 100644 --- a/public/webapp-settings.example.json +++ b/public/webapp-settings.example.json @@ -5,5 +5,6 @@ }, "api": { "baseUrl": "https://localhost:7262/api/" - } -} \ No newline at end of file + }, + "useAuth": false +} diff --git a/src/WebappSettings.ts b/src/WebappSettings.ts index d59f246..e4b4483 100644 --- a/src/WebappSettings.ts +++ b/src/WebappSettings.ts @@ -6,4 +6,5 @@ export interface WebappSettings { api: { baseUrl: string; } + useAuth: boolean; } From 6a691004947dba013a1fa3b083685c805d2dbd7b Mon Sep 17 00:00:00 2001 From: Ricardo Boss Date: Fri, 19 Aug 2022 11:23:24 +0200 Subject: [PATCH 03/34] Implement useAuth from settings --- src/App.vue | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/App.vue b/src/App.vue index 627759e..5cb29aa 100644 --- a/src/App.vue +++ b/src/App.vue @@ -152,6 +152,10 @@ export default defineComponent({ ApiClient.setBaseUrl(baseUrl); } + if (settings.useAuth) { + ApiClient.useAuth = true; + } + let a = document.querySelectorAll('.v-theme--light'); a.forEach(root => { root.style.setProperty('--v-theme-primary', settings.theme.primary); From f55345462bd52e2601b1e8a17caaaa8ad5f5bda2 Mon Sep 17 00:00:00 2001 From: Ricardo Boss Date: Fri, 19 Aug 2022 11:39:33 +0200 Subject: [PATCH 04/34] Provide $settings via app --- src/App.vue | 38 ++++++++++++-------------------------- src/main.ts | 31 ++++++++++++++++++++++++++----- 2 files changed, 38 insertions(+), 31 deletions(-) diff --git a/src/App.vue b/src/App.vue index 5cb29aa..33daf85 100644 --- a/src/App.vue +++ b/src/App.vue @@ -124,14 +124,14 @@ import {defineComponent} from 'vue' import NavTreeNode from "@/components/NavTreeNode.vue"; import {VTextField} from "vuetify/components"; import TrenzDocsLogo from "@/components/TrenzDocsLogo.vue"; -import ApiClient from "@/api/ApiClient"; import {mapGetters} from "vuex"; import * as api from "@/api"; -import {WebappSettings} from "@/WebappSettings"; export default defineComponent({ name: 'App', + inject: ['$settings'], + components: { TrenzDocsLogo, NavTreeNode, @@ -140,28 +140,6 @@ export default defineComponent({ async beforeMount() { window.addEventListener('keydown', this.handleKeyDown) - ApiClient.setBaseUrl(window.location.origin) - const settings: WebappSettings = await ApiClient.getJson('webapp-settings.json') - - const baseUrl = settings.api.baseUrl; - if (typeof baseUrl === 'undefined') { - alert('Please add a webapp-settings.json file to the content root.') - - throw new Error('API base url is not set'); - } else { - ApiClient.setBaseUrl(baseUrl); - } - - if (settings.useAuth) { - ApiClient.useAuth = true; - } - - let a = document.querySelectorAll('.v-theme--light'); - a.forEach(root => { - root.style.setProperty('--v-theme-primary', settings.theme.primary); - root.style.setProperty('--v-theme-on-primary', settings.theme["primary-foreground"]); - }) - await this.$store.dispatch('loadNavTree'); api.auth.state().then(result => { @@ -170,6 +148,14 @@ export default defineComponent({ }); }, + mounted() { + let allThemed = document.querySelectorAll('.v-theme--light, .v-theme--dark'); + allThemed.forEach(el => { + el.style.setProperty('--v-theme-primary', this.$settings.theme.primary); + el.style.setProperty('--v-theme-on-primary', this.$settings.theme["primary-foreground"]); + }) + }, + unmounted() { window.removeEventListener('keydown', this.handleKeyDown) }, @@ -274,11 +260,11 @@ export default defineComponent({ }, loginUrl() { - return ApiClient.getBaseUrl() + "auth/transfer?returnUrl=" + encodeURI(window.location.origin + this.$route.fullPath); + return this.$settings.api.baseUrl + "auth/transfer?returnUrl=" + encodeURI(window.location.origin + this.$route.fullPath); }, logoutUrl() { - return ApiClient.getBaseUrl() + "auth/signout?returnUrl=" + encodeURI(window.location.origin + this.$route.fullPath); + return this.$settings.api.baseUrl + "auth/signout?returnUrl=" + encodeURI(window.location.origin + this.$route.fullPath); }, }, }) diff --git a/src/main.ts b/src/main.ts index 0425091..1649f02 100644 --- a/src/main.ts +++ b/src/main.ts @@ -4,11 +4,32 @@ import router from './router' import store from './store' import vuetify from './plugins/vuetify' import { loadFonts } from './plugins/webfontloader' +import ApiClient from "@/api/ApiClient"; +import {WebappSettings} from "@/WebappSettings"; loadFonts() -createApp(App) - .use(router) - .use(store) - .use(vuetify) - .mount('#app') +ApiClient.setBaseUrl(window.location.origin) +ApiClient.getJson('webapp-settings.json').then(settings => { + const appSettings: WebappSettings = settings; + + const baseUrl = appSettings.api.baseUrl; + if (typeof baseUrl === 'undefined') { + alert('Please add a webapp-settings.json file to the content root.') + + throw new Error('API base url is not set'); + } else { + ApiClient.setBaseUrl(baseUrl); + } + + if (appSettings.useAuth) { + ApiClient.useAuth = true; + } + + createApp(App) + .provide('$settings', appSettings) + .use(router) + .use(store) + .use(vuetify) + .mount('#app') +}) From c61ff632d6d1b8c54166c04615967eec2eac166e Mon Sep 17 00:00:00 2001 From: Ricardo Boss Date: Fri, 19 Aug 2022 11:54:44 +0200 Subject: [PATCH 05/34] Removed env vars from Dockerfile and bound local webapp-settings.json to final path in docker-compose --- .gitignore | 1 + Dockerfile | 3 --- docker-compose.yml | 4 ++-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 1f0836b..e3cbfce 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ node_modules .env.*.local appsettings.local.json public/webapp-settings.json +webapp-settings.local*.json # Log files npm-debug.log* diff --git a/Dockerfile b/Dockerfile index cf9721c..40a0857 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,9 +2,6 @@ FROM node:lts-alpine as build WORKDIR /app -ARG VUE_APP_API_BASE -ENV VUE_APP_API_BASE $VUE_APP_API_BASE - # add node binaries to path ENV PATH /app/node_modules/.bin:$PATH diff --git a/docker-compose.yml b/docker-compose.yml index ebc5bc8..05e400e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,13 +5,13 @@ services: build: context: . target: final - args: - - VUE_APP_API_BASE=http://localhost:5001/api/ ports: - "5000:80" restart: unless-stopped depends_on: - api + volumes: + - ./webapp-settings.local.json:/usr/share/nginx/html/webapp-settings.json api: image: ghcr.io/trenz-gmbh/trenz-docs-api:latest environment: From c6ae2c746789ff2254d6c6d043823b0acab77361 Mon Sep 17 00:00:00 2001 From: Ricardo Boss Date: Fri, 19 Aug 2022 12:01:57 +0200 Subject: [PATCH 06/34] Updated README with new example deployment process --- README.md | 73 +++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 60 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 4e28c23..49997fa 100644 --- a/README.md +++ b/README.md @@ -3,36 +3,73 @@ [![Node.js CI](https://github.com/trenz-gmbh/trenz-docs/actions/workflows/node.js.yml/badge.svg)](https://github.com/trenz-gmbh/trenz-docs/actions/workflows/node.js.yml) ## Project setup + ``` npm install ``` ### Compiles and hot-reloads for development + ``` npm run serve ``` ### Compiles and minifies for production + ``` npm run build ``` ### Lints and fixes files + ``` npm run lint ``` -### Customize configuration -See [Configuration Reference](https://cli.vuejs.org/config/). - ## Deployment To deploy a trenz-docs wiki, follow these steps: -1. clone this repository to the target server: - ```bash - git clone https://github.com/trenz-gmbh/trenz-docs my-wiki - cd my-wiki +1. create a `docker-compose.yml` or copy the one from this repository and replace the ports: + ```docker-compose.yml + version: '3.4' + + services: + frontend: + image: ghcr.io/trenz-gmbh/trenz-docs:latest + ports: + - ":80" + restart: unless-stopped + depends_on: + - api + volumes: + - ./webapp-settings.local.json:/usr/share/nginx/html/webapp-settings.json + api: + image: ghcr.io/trenz-gmbh/trenz-docs-api:latest + environment: + - ASPNETCORE_ENVIRONMENT=${ASPNETCORE_ENVIRONMENT:-Production} + - Meilisearch__Url=http://meilisearch:7700 + - Meilisearch__ApiKey=${MEILISEARCH_API_KEY:-masterKey} + ports: + - ":80" + restart: unless-stopped + depends_on: + - meilisearch + volumes: + - ./appsettings.local.json:/app/appsettings.local.json + meilisearch: + image: getmeili/meilisearch:latest + ports: + - "7700:7700" + environment: + - MEILI_MASTER_KEY=${MEILISEARCH_API_KEY:-masterKey} + - MEILI_NO_ANALYTICS=true + restart: unless-stopped + volumes: + - meili_data:/data + + volumes: + meili_data: ``` 2. add a `appsettings.local.json` file to specify which repositories to use as sources: @@ -50,11 +87,18 @@ To deploy a trenz-docs wiki, follow these steps: } ``` -3. optionally: add a `.env` (or `.env.local`) file: - ```env - VUE_APP_API_BASE=https://localhost:7262/api/ - VUE_APP_PRIMARY_COLOR='#8af' - VUE_APP_PRIMARY_FOREGROUND_COLOR='#000' +3. add a `webapp-settings.local.json` and add your customer-facing api endpoint: + ```json + { + "theme": { + "primary": "80,120,200", + "primary-foreground": "255,255,255" + }, + "api": { + "baseUrl": "https:///api/" + }, + "useAuth": false + } ``` 4. run: @@ -62,4 +106,7 @@ To deploy a trenz-docs wiki, follow these steps: docker-compose up -d ``` -5. access your new wiki at [localhost:5050](http://localhost:5050/) +5. access your new wiki at hosted locally: + ```bash + http://localhost: + ``` From da48061722f4f714b8f01d35fe8e2fe68552185c Mon Sep 17 00:00:00 2001 From: Ricardo Boss Date: Fri, 19 Aug 2022 12:03:39 +0200 Subject: [PATCH 07/34] Fix typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 49997fa..168c6a4 100644 --- a/README.md +++ b/README.md @@ -106,7 +106,7 @@ To deploy a trenz-docs wiki, follow these steps: docker-compose up -d ``` -5. access your new wiki at hosted locally: +5. access your new wiki hosted at: ```bash http://localhost: ``` From 5e9b9dae5eb52aa275f4aaa72da752e7a6cd830f Mon Sep 17 00:00:00 2001 From: Ricardo Boss Date: Tue, 18 Oct 2022 19:34:27 +0200 Subject: [PATCH 08/34] Moved webapp settings fetching to store --- src/main.ts | 22 ++-------------------- src/store/State.ts | 2 ++ src/store/index.ts | 28 ++++++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/src/main.ts b/src/main.ts index 1649f02..3aa396b 100644 --- a/src/main.ts +++ b/src/main.ts @@ -4,30 +4,12 @@ import router from './router' import store from './store' import vuetify from './plugins/vuetify' import { loadFonts } from './plugins/webfontloader' -import ApiClient from "@/api/ApiClient"; -import {WebappSettings} from "@/WebappSettings"; loadFonts() -ApiClient.setBaseUrl(window.location.origin) -ApiClient.getJson('webapp-settings.json').then(settings => { - const appSettings: WebappSettings = settings; - - const baseUrl = appSettings.api.baseUrl; - if (typeof baseUrl === 'undefined') { - alert('Please add a webapp-settings.json file to the content root.') - - throw new Error('API base url is not set'); - } else { - ApiClient.setBaseUrl(baseUrl); - } - - if (appSettings.useAuth) { - ApiClient.useAuth = true; - } - +store.dispatch('loadWebAppSettings').then(settings => { createApp(App) - .provide('$settings', appSettings) + .provide('$settings', settings) .use(router) .use(store) .use(vuetify) diff --git a/src/store/State.ts b/src/store/State.ts index 9580d08..8ae7c5c 100644 --- a/src/store/State.ts +++ b/src/store/State.ts @@ -2,8 +2,10 @@ import {IndexedFile} from "@/models/IndexedFile"; import {NavTree} from "@/models/NavTree"; import {SearchResult} from "@/models/SearchResult"; import IndexStats from "@/models/IndexStats"; +import {WebappSettings} from "@/WebappSettings"; export interface State { + settings: WebappSettings | null, navTree: NavTree; searchQuery: string; searchResults: Array; diff --git a/src/store/index.ts b/src/store/index.ts index 696b0f2..6f4bf26 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -7,6 +7,7 @@ import * as api from "@/api"; import ApiClient, {ApiError} from "@/api/ApiClient"; import IndexStats from "@/models/IndexStats"; import {NavNode} from "@/models/NavNode"; +import {WebappSettings} from "@/WebappSettings"; function replaceApiHost(content: string): string { return content.replaceAll("%API_HOST%", ApiClient.getBaseUrl()?.slice(0, -1) ?? "/api"); @@ -14,6 +15,7 @@ function replaceApiHost(content: string): string { export default createStore({ state: { + settings: null, navTree: {root: {}, containsUnauthorizedChildren: false}, searchQuery: '', searchResults: [], @@ -64,12 +66,38 @@ export default createStore({ setStats(state: State, stats: IndexStats | null) { state.stats = stats; }, + + setSettings(state: State, settings: WebappSettings | null) { + state.settings = settings; + } }, actions: { async loadNavTree({commit}) { commit('setNavTree', await api.documents.navTree()); }, + async loadWebAppSettings({commit}): Promise { + ApiClient.setBaseUrl(window.location.origin) + const settings: WebappSettings = await ApiClient.getJson('webapp-settings.json'); + + const baseUrl = settings.api.baseUrl; + if (typeof baseUrl === 'undefined') { + alert('Please add a webapp-settings.json file to the content root.') + + throw new Error('API base url is not set'); + } else { + ApiClient.setBaseUrl(baseUrl); + } + + if (settings.useAuth) { + ApiClient.useAuth = true; + } + + commit('setSettings', settings); + + return settings; + }, + async search({commit}, query: string) { // update stats async, don't wait for it api.search.stats().then(stats => commit('setStats', stats)); From bd343bd59293860abbfef0c5ddb6eaa6fe5427ff Mon Sep 17 00:00:00 2001 From: Ricardo Boss Date: Tue, 18 Oct 2022 19:34:45 +0200 Subject: [PATCH 09/34] Read title name from webapp-settings.json --- public/webapp-settings.example.json | 1 + src/WebappSettings.ts | 17 +++++++++-------- src/router/index.ts | 10 ++++++---- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/public/webapp-settings.example.json b/public/webapp-settings.example.json index e96bb2e..f6798f0 100644 --- a/public/webapp-settings.example.json +++ b/public/webapp-settings.example.json @@ -1,4 +1,5 @@ { + "name": "My Docs", "theme": { "primary": "80,120,200", "primary-foreground": "255,255,255" diff --git a/src/WebappSettings.ts b/src/WebappSettings.ts index e4b4483..a3a3c9c 100644 --- a/src/WebappSettings.ts +++ b/src/WebappSettings.ts @@ -1,10 +1,11 @@ export interface WebappSettings { - theme: { - primary: string; - 'primary-foreground': string; - } - api: { - baseUrl: string; - } - useAuth: boolean; + name: string; + theme: { + primary: string; + 'primary-foreground': string; + } + api: { + baseUrl: string; + } + useAuth: boolean; } diff --git a/src/router/index.ts b/src/router/index.ts index 8bb8e34..248c17f 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -1,6 +1,7 @@ import {createRouter, createWebHistory, RouteRecordRaw} from 'vue-router' import ContentView from "@/views/ContentView.vue"; import NotFoundView from "@/views/NotFoundView.vue"; +import store from "@/store"; const routes: Array = [ { @@ -35,17 +36,18 @@ const routes: Array = [ ] const router = createRouter({ - history: createWebHistory(process.env.BASE_URL), + history: createWebHistory(), routes, }) router.beforeEach((to, from, next) => { + const appName = store.state.settings?.name ?? 'Loading...' if (to.meta.title) { - document.title = to.meta.title + ' \u2022 ' + process.env.VUE_APP_NAME; + document.title = to.meta.title + ' \u2022 ' + appName; } else if (to.params.location) { - document.title = (to.params.location as string).split('/').pop() + ' \u2022 ' + process.env.VUE_APP_NAME; + document.title = (to.params.location as string).split('/').pop() + ' \u2022 ' + appName; } else { - document.title = process.env.VUE_APP_NAME; + document.title = appName; } if (Object.hasOwnProperty.call(to.query, 'error')) { From 4ce638ad7f2884dbaef5e74f978a669e96792252 Mon Sep 17 00:00:00 2001 From: Ricardo Boss Date: Tue, 18 Oct 2022 19:35:06 +0200 Subject: [PATCH 10/34] Removed unused ignore entry --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index e3cbfce..1f0836b 100644 --- a/.gitignore +++ b/.gitignore @@ -8,7 +8,6 @@ node_modules .env.*.local appsettings.local.json public/webapp-settings.json -webapp-settings.local*.json # Log files npm-debug.log* From cabf181cabcd8258ae0d81892e12a3f2d318625f Mon Sep 17 00:00:00 2001 From: Ricardo Boss Date: Tue, 18 Oct 2022 19:59:45 +0200 Subject: [PATCH 11/34] Add explaining comment to default color themes --- src/plugins/vuetify.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/vuetify.ts b/src/plugins/vuetify.ts index 1fb01eb..c080071 100644 --- a/src/plugins/vuetify.ts +++ b/src/plugins/vuetify.ts @@ -17,6 +17,8 @@ export default createVuetify({ theme: { defaultTheme: 'light', themes: { + // The primary and on-primary values get overridden by the values in public/webapp-settings.json at runtime. + // They may be visible until the settings got loaded and applied. light: { colors: { primary: '#ddd', From b2884b79d88a265e583a6032c17d2fc4fac9fab2 Mon Sep 17 00:00:00 2001 From: Ricardo Boss Date: Tue, 18 Oct 2022 20:00:22 +0200 Subject: [PATCH 12/34] Add name to example webapp-settings in README --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 168c6a4..ee71276 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,7 @@ To deploy a trenz-docs wiki, follow these steps: 3. add a `webapp-settings.local.json` and add your customer-facing api endpoint: ```json { + "name": "", "theme": { "primary": "80,120,200", "primary-foreground": "255,255,255" From 9d4f0438d39aafe0d2b77c8013af0d9371e97e72 Mon Sep 17 00:00:00 2001 From: Ricardo Boss Date: Wed, 19 Oct 2022 11:33:44 +0200 Subject: [PATCH 13/34] Add workflow for building docker images --- .github/workflows/docker-image.yml | 38 ++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 .github/workflows/docker-image.yml diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml new file mode 100644 index 0000000..cc3df25 --- /dev/null +++ b/.github/workflows/docker-image.yml @@ -0,0 +1,38 @@ +name: Docker Image CI + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + build: + name: Build Docker Image + + runs-on: ubuntu-latest + + permissions: + packages: write + + steps: + - uses: actions/checkout@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + - name: Login to GitHub Container Registry + uses: docker/login-action@v2 + if: github.event_name != 'pull_request' + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Build and push image + uses: docker/build-push-action@v3 + if: github.event_name != 'pull_request' + with: + context: . + platforms: linux/amd64 + push: true + tags: | + ghcr.io/${{ github.repository }}:latest + ghcr.io/${{ github.repository }}:${{ github.sha }} From fab5fc0ab1ec10a209a4882309bc80305188a3b8 Mon Sep 17 00:00:00 2001 From: Ricardo Boss Date: Wed, 19 Oct 2022 11:34:06 +0200 Subject: [PATCH 14/34] Use npm ci as proposed by npm --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 40a0857..1781c0f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,7 +7,7 @@ ENV PATH /app/node_modules/.bin:$PATH # install dependencies and build tools COPY package*.json ./ -RUN npm install --silent +RUN npm ci # build app COPY . . From 043a05e1036d77bf3e682a46dadf78e5b4c3d1e0 Mon Sep 17 00:00:00 2001 From: Ricardo Boss Date: Wed, 19 Oct 2022 11:34:21 +0200 Subject: [PATCH 15/34] Autoscale worker threads --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 1781c0f..6550ea5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -24,4 +24,4 @@ COPY nginx/nginx.conf /etc/nginx/conf.d # start nginx EXPOSE 80 -CMD ["nginx", "-g", "daemon off;"] +CMD ["nginx", "-g", "daemon off; worker_processes auto;"] From 9e8747cb81a6b52ba822b895f6ddbba59938cab3 Mon Sep 17 00:00:00 2001 From: Ricardo Boss Date: Wed, 19 Oct 2022 11:38:16 +0200 Subject: [PATCH 16/34] Actually build the docker image --- .github/workflows/docker-image.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index cc3df25..daeca5e 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -26,6 +26,9 @@ jobs: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - run: cp ./public/webapp-settings.example.json ./webapp-settings.local.json + - name: Test docker-compose.yml + run: timeout 10s docker-compose run --rm frontend - name: Build and push image uses: docker/build-push-action@v3 if: github.event_name != 'pull_request' From 9d59891b08b1c20baef97f07d46415cc6da34b79 Mon Sep 17 00:00:00 2001 From: Ricardo Boss Date: Wed, 19 Oct 2022 11:38:29 +0200 Subject: [PATCH 17/34] Ignore local config in docker --- .dockerignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.dockerignore b/.dockerignore index 1a10672..ea81ab9 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,4 +1,5 @@ node_modules/ .env.local +*.local.json Dockerfile* README.md From 3480d894d37c81003ed7a449a8d080da6379ca17 Mon Sep 17 00:00:00 2001 From: Ricardo Boss Date: Wed, 19 Oct 2022 11:39:23 +0200 Subject: [PATCH 18/34] Give docker-compose more time --- .github/workflows/docker-image.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index daeca5e..5e018d6 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -28,7 +28,7 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - run: cp ./public/webapp-settings.example.json ./webapp-settings.local.json - name: Test docker-compose.yml - run: timeout 10s docker-compose run --rm frontend + run: timeout 30s docker-compose run --rm frontend - name: Build and push image uses: docker/build-push-action@v3 if: github.event_name != 'pull_request' From 8df043a5e9d54d7791f34c4a8cd690d5cabd6d9d Mon Sep 17 00:00:00 2001 From: Ricardo Boss Date: Wed, 19 Oct 2022 11:41:28 +0200 Subject: [PATCH 19/34] Give docker-compose even more time --- .github/workflows/docker-image.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 5e018d6..1e90daf 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -28,7 +28,7 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - run: cp ./public/webapp-settings.example.json ./webapp-settings.local.json - name: Test docker-compose.yml - run: timeout 30s docker-compose run --rm frontend + run: timeout 120s docker-compose run --rm frontend - name: Build and push image uses: docker/build-push-action@v3 if: github.event_name != 'pull_request' From 2ae48a9cc7957aa09428d5cf096e477516d31c1e Mon Sep 17 00:00:00 2001 From: Ricardo Boss Date: Wed, 19 Oct 2022 11:45:33 +0200 Subject: [PATCH 20/34] Config is already set in image --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 6550ea5..1781c0f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -24,4 +24,4 @@ COPY nginx/nginx.conf /etc/nginx/conf.d # start nginx EXPOSE 80 -CMD ["nginx", "-g", "daemon off; worker_processes auto;"] +CMD ["nginx", "-g", "daemon off;"] From 2dbf5e5c540ecebfed359ee0363aaeece811807a Mon Sep 17 00:00:00 2001 From: Ricardo Boss Date: Wed, 19 Oct 2022 11:49:13 +0200 Subject: [PATCH 21/34] Ignore .github folder in docker --- .dockerignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.dockerignore b/.dockerignore index ea81ab9..b43901c 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,3 +1,4 @@ +.github/ node_modules/ .env.local *.local.json From a0150d9819ce919ac333563bb1b1978f38a6a23b Mon Sep 17 00:00:00 2001 From: Ricardo Boss Date: Wed, 19 Oct 2022 11:58:34 +0200 Subject: [PATCH 22/34] Ignore .git folder --- .dockerignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.dockerignore b/.dockerignore index b43901c..b3dba55 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,3 +1,4 @@ +**/.git .github/ node_modules/ .env.local From 35060aa3ddbf46446269fdb121ba687a991afa0a Mon Sep 17 00:00:00 2001 From: Ricardo Boss Date: Wed, 19 Oct 2022 12:12:34 +0200 Subject: [PATCH 23/34] Run script to test docker image --- .github/scripts/docker-image-test.sh | 38 ++++++++++++++++++++++++++++ .github/workflows/docker-image.yml | 4 +-- 2 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 .github/scripts/docker-image-test.sh diff --git a/.github/scripts/docker-image-test.sh b/.github/scripts/docker-image-test.sh new file mode 100644 index 0000000..c4cf0fc --- /dev/null +++ b/.github/scripts/docker-image-test.sh @@ -0,0 +1,38 @@ +#!/usr/scripts/env bash + +# exit on error +set -e + +# copy webapp settings +cp public/webapp-settings.example.json webapp-settings.local.json + +# start frontend server +container_id=$(docker-compose up -d) + +# test if the server is running and serves files +requested_settings=$(curl http://localhost:5000/webapp-settings.json) + +# compare served file with actual file (a 404 or 50x error - or a timeout - would fail here) +actual_settings=$(cat webapp-settings.local.json) +if [ "$actual_settings" != "$requested_settings" ]; then + echo "Could not verify server functionality. Received:" + exit 1 +else + echo "Received settings:" +fi + +echo "$requested_settings" + +# test if homepage gets served without errors +requested_homepage=$(curl http://localhost:5000/) + +echo "Received homepage:" +echo "$requested_homepage" + +echo "Server seems to respond correctly." + +# shutdown server +docker-compose stop "$container_id" + +# cleanup +rm webapp-settings.local.json diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 1e90daf..ee5ea21 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -26,9 +26,9 @@ jobs: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - run: cp ./public/webapp-settings.example.json ./webapp-settings.local.json - name: Test docker-compose.yml - run: timeout 120s docker-compose run --rm frontend + run: ./.github/scripts/docker-image-test.sh + shell: bash - name: Build and push image uses: docker/build-push-action@v3 if: github.event_name != 'pull_request' From 05241cc9c68ab0a4bf298141652d517ef1226d9d Mon Sep 17 00:00:00 2001 From: Ricardo Boss Date: Wed, 19 Oct 2022 12:14:26 +0200 Subject: [PATCH 24/34] Make file executable --- .github/workflows/docker-image.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index ee5ea21..ec8705b 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -27,7 +27,7 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Test docker-compose.yml - run: ./.github/scripts/docker-image-test.sh + run: chmod +x ./.github/scripts/docker-image-test.sh && ./.github/scripts/docker-image-test.sh shell: bash - name: Build and push image uses: docker/build-push-action@v3 From 6fc5c8c9b18f3cf435713dc0e902fdc1e4c7ded9 Mon Sep 17 00:00:00 2001 From: Ricardo Boss Date: Wed, 19 Oct 2022 12:16:14 +0200 Subject: [PATCH 25/34] Hard-code bash location --- .github/scripts/docker-image-test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/scripts/docker-image-test.sh b/.github/scripts/docker-image-test.sh index c4cf0fc..8b3b6e8 100644 --- a/.github/scripts/docker-image-test.sh +++ b/.github/scripts/docker-image-test.sh @@ -1,4 +1,4 @@ -#!/usr/scripts/env bash +#!/bin/bash # exit on error set -e From c4b7e160fe029ecba2668f6f3532b07f83fc7ec7 Mon Sep 17 00:00:00 2001 From: Ricardo Boss Date: Wed, 19 Oct 2022 12:19:53 +0200 Subject: [PATCH 26/34] Explicitly exit with 0 --- .github/scripts/docker-image-test.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/scripts/docker-image-test.sh b/.github/scripts/docker-image-test.sh index 8b3b6e8..b3daab4 100644 --- a/.github/scripts/docker-image-test.sh +++ b/.github/scripts/docker-image-test.sh @@ -36,3 +36,5 @@ docker-compose stop "$container_id" # cleanup rm webapp-settings.local.json + +exit 0 From 2273db27be7a8eaca369a0e6709c89b30b08fa53 Mon Sep 17 00:00:00 2001 From: Ricardo Boss Date: Wed, 19 Oct 2022 12:21:38 +0200 Subject: [PATCH 27/34] Echo settings if not equal --- .github/scripts/docker-image-test.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/scripts/docker-image-test.sh b/.github/scripts/docker-image-test.sh index b3daab4..799db83 100644 --- a/.github/scripts/docker-image-test.sh +++ b/.github/scripts/docker-image-test.sh @@ -16,11 +16,11 @@ requested_settings=$(curl http://localhost:5000/webapp-settings.json) actual_settings=$(cat webapp-settings.local.json) if [ "$actual_settings" != "$requested_settings" ]; then echo "Could not verify server functionality. Received:" + echo "$requested_settings" exit 1 -else - echo "Received settings:" fi +echo "Received settings:" echo "$requested_settings" # test if homepage gets served without errors From 89607bbdc680d8828c4bc15ba3042c632369ffe3 Mon Sep 17 00:00:00 2001 From: Ricardo Boss Date: Wed, 19 Oct 2022 12:30:57 +0200 Subject: [PATCH 28/34] Fix docker-compose calls --- .github/scripts/docker-image-test.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/scripts/docker-image-test.sh b/.github/scripts/docker-image-test.sh index 799db83..f915bdb 100644 --- a/.github/scripts/docker-image-test.sh +++ b/.github/scripts/docker-image-test.sh @@ -6,8 +6,8 @@ set -e # copy webapp settings cp public/webapp-settings.example.json webapp-settings.local.json -# start frontend server -container_id=$(docker-compose up -d) +# start server +docker-compose up -d # test if the server is running and serves files requested_settings=$(curl http://localhost:5000/webapp-settings.json) @@ -32,7 +32,7 @@ echo "$requested_homepage" echo "Server seems to respond correctly." # shutdown server -docker-compose stop "$container_id" +docker-compose down # cleanup rm webapp-settings.local.json From 929bcc3fa0ce309de1d99eabc0e1ef464ec5acde Mon Sep 17 00:00:00 2001 From: Ricardo Boss Date: Wed, 19 Oct 2022 12:33:31 +0200 Subject: [PATCH 29/34] Also check received homepage --- .github/scripts/docker-image-test.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/scripts/docker-image-test.sh b/.github/scripts/docker-image-test.sh index f915bdb..04f3273 100644 --- a/.github/scripts/docker-image-test.sh +++ b/.github/scripts/docker-image-test.sh @@ -15,7 +15,7 @@ requested_settings=$(curl http://localhost:5000/webapp-settings.json) # compare served file with actual file (a 404 or 50x error - or a timeout - would fail here) actual_settings=$(cat webapp-settings.local.json) if [ "$actual_settings" != "$requested_settings" ]; then - echo "Could not verify server functionality. Received:" + echo "Could not verify server functionality. Received settings:" echo "$requested_settings" exit 1 fi @@ -25,6 +25,12 @@ echo "$requested_settings" # test if homepage gets served without errors requested_homepage=$(curl http://localhost:5000/) +actual_homepage=$(cat public/index.html) +if [ "$actual_homepage" != "$requested_homepage" ]; then + echo "Could not verify server functionality. Received homepage:" + echo "$requested_settings" + exit 1 +fi echo "Received homepage:" echo "$requested_homepage" From fcc0f6121a81b0d6c06ff516465f0d59d4e4e394 Mon Sep 17 00:00:00 2001 From: Ricardo Boss Date: Wed, 19 Oct 2022 12:34:51 +0200 Subject: [PATCH 30/34] Use correct variable --- .github/scripts/docker-image-test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/scripts/docker-image-test.sh b/.github/scripts/docker-image-test.sh index 04f3273..21a33db 100644 --- a/.github/scripts/docker-image-test.sh +++ b/.github/scripts/docker-image-test.sh @@ -28,7 +28,7 @@ requested_homepage=$(curl http://localhost:5000/) actual_homepage=$(cat public/index.html) if [ "$actual_homepage" != "$requested_homepage" ]; then echo "Could not verify server functionality. Received homepage:" - echo "$requested_settings" + echo "$requested_homepage" exit 1 fi From e32c4b2dc720cc397b91dca52f9d6bdce3869594 Mon Sep 17 00:00:00 2001 From: Ricardo Boss Date: Wed, 19 Oct 2022 12:40:12 +0200 Subject: [PATCH 31/34] Can't check against index.html --- .github/scripts/docker-image-test.sh | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.github/scripts/docker-image-test.sh b/.github/scripts/docker-image-test.sh index 21a33db..2ac908e 100644 --- a/.github/scripts/docker-image-test.sh +++ b/.github/scripts/docker-image-test.sh @@ -25,13 +25,6 @@ echo "$requested_settings" # test if homepage gets served without errors requested_homepage=$(curl http://localhost:5000/) -actual_homepage=$(cat public/index.html) -if [ "$actual_homepage" != "$requested_homepage" ]; then - echo "Could not verify server functionality. Received homepage:" - echo "$requested_homepage" - exit 1 -fi - echo "Received homepage:" echo "$requested_homepage" From 367e8b3301377b2cb9bf4bd76219661cde27e7d5 Mon Sep 17 00:00:00 2001 From: Ricardo Boss Date: Wed, 19 Oct 2022 12:40:47 +0200 Subject: [PATCH 32/34] Check against built index.html --- .github/scripts/docker-image-test.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/scripts/docker-image-test.sh b/.github/scripts/docker-image-test.sh index 2ac908e..655ab94 100644 --- a/.github/scripts/docker-image-test.sh +++ b/.github/scripts/docker-image-test.sh @@ -25,6 +25,13 @@ echo "$requested_settings" # test if homepage gets served without errors requested_homepage=$(curl http://localhost:5000/) +actual_homepage=$(cat dist/index.html) +if [ "$actual_homepage" != "$requested_homepage" ]; then + echo "Could not verify server functionality. Received homepage:" + echo "$requested_homepage" + exit 1 +fi + echo "Received homepage:" echo "$requested_homepage" From 55e100be72de679d8495536221cb605a24c11bf2 Mon Sep 17 00:00:00 2001 From: Ricardo Boss Date: Wed, 19 Oct 2022 12:56:33 +0200 Subject: [PATCH 33/34] Don't copy example webapp settings to dist folder --- vue.config.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/vue.config.js b/vue.config.js index 998a143..f201651 100644 --- a/vue.config.js +++ b/vue.config.js @@ -31,4 +31,11 @@ module.exports = defineConfig({ allowedHosts: 'all', server: serverOpts, }, + + chainWebpack: config => { + config.plugin('copy').tap(options => { + options[0].patterns[0].globOptions.ignore.push('**/webapp-settings.example.json') + return options + }) + } }) From 6964fa25c5c14a392a61672fe81b9c046d88866d Mon Sep 17 00:00:00 2001 From: Ricardo Boss Date: Wed, 19 Oct 2022 13:03:32 +0200 Subject: [PATCH 34/34] Don't have access to built files... --- .github/scripts/docker-image-test.sh | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.github/scripts/docker-image-test.sh b/.github/scripts/docker-image-test.sh index 655ab94..2ac908e 100644 --- a/.github/scripts/docker-image-test.sh +++ b/.github/scripts/docker-image-test.sh @@ -25,13 +25,6 @@ echo "$requested_settings" # test if homepage gets served without errors requested_homepage=$(curl http://localhost:5000/) -actual_homepage=$(cat dist/index.html) -if [ "$actual_homepage" != "$requested_homepage" ]; then - echo "Could not verify server functionality. Received homepage:" - echo "$requested_homepage" - exit 1 -fi - echo "Received homepage:" echo "$requested_homepage"