Skip to content

Commit

Permalink
chore: added frontend proxy, added translation logic for weblate to i18n
Browse files Browse the repository at this point in the history
  • Loading branch information
web-mi committed Jan 23, 2024
1 parent 8c100d5 commit 1b4e5c4
Show file tree
Hide file tree
Showing 64 changed files with 10,279 additions and 4,143 deletions.
32 changes: 31 additions & 1 deletion .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,34 @@ CSRF_WHITELIST_HEADER_FOR_LOCAL_DEVELOPMENT=X-WHITELIST-HEADER
#AUDIO_FILE_INCOMING_NOTIFICATION=/assets/audio/incomingNotification.mp3

# Disable 2FA
REACT_APP_DISABLE_2FA_DUTY=0
REACT_APP_DISABLE_2FA_DUTY=0

### Weblate
# Weblate host
FRONTEND_WEBLATE_HOST=
# Path to api
FRONTEND_WEBLATE_PATH=/weblate/api
# Name of weblate project
FRONTEND_WEBLATE_PROJECT=
# Weblate api key - Attention! if provided it will be used for frontend requests and is visible to everyone
FRONTEND_WEBLATE_API_KEY=
# Min percentage - percentage which must be translated in one language until it gets visible in the frontend
FRONTEND_WEBLATE_MIN_PERCENT=
# Disable localStorage caching
FRONTEND_TRANSLATION_CACHE_DISABLE=
# Time until frontend cache gets invalidated in minutes
FRONTEND_TRANSLATION_CACHE_TIME=

### NodeJS
# Storage path - if set relative to project root translation files will be stored temporary until LOCALIZATION_CACHE_TIME expired
STORAGE_PATH=./.storage

# Localize cache time - in minutes - default 120 minutes
LOCALIZATION_CACHE_TIME=

# Weblate host for proxy
LOCALIZATION_WEBLATE_HOST=https://weblate.example.com/
# If weblate is provided under subdirectory
LOCALIZATION_WEBLATE_PATH=/weblate
# Weblate api key - must be provided to skip request limits
LOCALIZATION_WEBLATE_API_KEY=
11 changes: 3 additions & 8 deletions .github/workflows/dockerImage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,6 @@ jobs:
- text: View CI
url: "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
push_to_registry:
strategy:
matrix:
registry: ['docker.pkg.github.com', 'ghcr.io']
needs: [build]
name: Push Docker image to GitHub Packages
runs-on: ubuntu-latest
Expand All @@ -104,8 +101,7 @@ jobs:
raw=$(git branch -r --contains ${{ github.ref }})
branch=${raw##*/}
echo BRANCH_NAME=$(echo -n "${branch}") >> $GITHUB_ENV
echo "MATRIX_REGISTRY=$(echo "${{ matrix.registry }}" | awk '{print tolower($0)}')" >> $GITHUB_ENV
echo "DOCKER_REGISTRY=$(echo "${{ matrix.registry }}/${{ github.repository }}" | awk '{print tolower($0)}')" >> $GITHUB_ENV
echo "DOCKER_REGISTRY=$(echo "ghcr.io/${{ github.repository }}" | awk '{print tolower($0)}')" >> $GITHUB_ENV
echo "DOCKER_IMAGE=$(echo "${{ github.repository }}" | awk -F / '{print tolower($2)}')" >> $GITHUB_ENV
echo "REPO_NAME_WITHOUT_PREFIX"=$(echo "${{ github.repository }}" | sed "s/.*\///" | awk -F / '{print tolower($0)}') >> $GITHUB_ENV
echo CLEAN_REF=$(echo "${GITHUB_REF_NAME#refs/heads/}") >> $GITHUB_ENV
Expand Down Expand Up @@ -145,7 +141,6 @@ jobs:
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build_args: DOCKER_MATRIX=${{ env.MATRIX_REGISTRY }}
- name: Hint about the Docker Image Tag if successfull
if: ${{ success() }}
run: |
Expand All @@ -160,7 +155,7 @@ jobs:
echo "" >> $GITHUB_STEP_SUMMARY
echo "- It seems that something has gone wrong" >> $GITHUB_STEP_SUMMARY
- name: Microsoft Teams Fail Card
if: ${{ (env.FAIL_WEBHOOK_SECRET != null) && (env.FAIL_WEBHOOK_SECRET != '') && (matrix.registry == 'ghcr.io') && (failure() || cancelled()) }}
if: ${{ (env.FAIL_WEBHOOK_SECRET != null) && (env.FAIL_WEBHOOK_SECRET != '') && (failure() || cancelled()) }}
uses: toko-bifrost/[email protected]
with:
github-token: ${{ github.token }}
Expand All @@ -174,7 +169,7 @@ jobs:
- text: View CI
url: "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
- name: Microsoft Teams Image Card
if: ${{ (env.IMAGE_WEBHOOK_SECRET != null) && (env.IMAGE_WEBHOOK_SECRET != '') && (matrix.registry == 'ghcr.io') && success() }}
if: ${{ (env.IMAGE_WEBHOOK_SECRET != null) && (env.IMAGE_WEBHOOK_SECRET != '') && success() }}
uses: toko-bifrost/[email protected]
with:
github-token: ${{ github.token }}
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

# dependencies
/node_modules
/proxy/node_modules
/.pnp
.pnp.js

Expand All @@ -12,6 +13,7 @@

# production
/build
/dist

# misc
.DS_Store
Expand All @@ -22,6 +24,7 @@
.env.test.local
.env.production.local
.idea
.storage

# cypress
browserstack.json
Expand Down
50 changes: 46 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,46 @@
ARG DOCKER_MATRIX=ghcr.io
FROM $DOCKER_MATRIX/onlineberatung/onlineberatung-nginx/onlineberatung-nginx:dockerimage.v.005-main
COPY build /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
ARG NODE_VERSION=14.21.1
ARG PORT=80

FROM node:$NODE_VERSION as proxyBuild

USER node
WORKDIR /app
COPY proxy /app

ENV NODE_ENV=development
ENV PORT=$PORT

# Currently nothing to build inside
# RUN npm run install
# RUN npm run build
# RUN rm /app/node_modules

###
# Build is done on github so no need for docker build
#FROM node:$NODE_VERSION as frontendBuild
#
#USER node
#WORKDIR /app
#COPY . /app
#
#ENV NODE_ENV=development
#ENV PORT=$PORT
#
#RUN npm install --ignore-scripts
#RUN npm run build

# Prod build
FROM node:$NODE_VERSION

USER node
WORKDIR /app
EXPOSE $PORT
COPY --from=proxyBuild /app ./
COPY build /app/build

ENV NODE_ENV=production
ENV PORT=$PORT

RUN npm install --ignore-scripts

CMD ["npm", "run", "start"]
6 changes: 2 additions & 4 deletions config/env.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,12 @@ function getClientEnvironment(publicUrl) {
// and `sockPort` options in webpack-dev-server.
WDS_SOCKET_HOST: process.env.WDS_SOCKET_HOST,
WDS_SOCKET_PATH: process.env.WDS_SOCKET_PATH,
WDS_SOCKET_PORT: process.env.WDS_SOCKET_PORT,
// Whether or not react-refresh is enabled.
// It is defined here so it is available in the webpackHotDevClient.
FAST_REFRESH: process.env.FAST_REFRESH !== 'false'
WDS_SOCKET_PORT: process.env.WDS_SOCKET_PORT
}
);
// Stringify all values so we can feed into webpack DefinePlugin
const stringified = {
'process': {}, // This is the only line added to the previous method
'process.env': Object.keys(raw).reduce((env, key) => {
env[key] = JSON.stringify(raw[key]);
return env;
Expand Down
3 changes: 3 additions & 0 deletions config/paths.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ module.exports = {
appNodeModules: resolveApp('node_modules'),
appWebpackCache: resolveApp('node_modules/.cache'),
appTsBuildInfoFile: resolveApp('node_modules/.cache/tsconfig.tsbuildinfo'),
storagePath: process.env.STORAGE_PATH
? resolveApp(process.env.STORAGE_PATH)
: null,
swSrc: resolveModule(resolveApp, 'src/service-worker'),
publicUrlOrPath
};
Expand Down
129 changes: 29 additions & 100 deletions config/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ const InlineChunkHtmlPlugin = require('react-dev-utils/InlineChunkHtmlPlugin');
const TerserPlugin = require('terser-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const { WebpackManifestPlugin } = require('webpack-manifest-plugin');
const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
const WorkboxWebpackPlugin = require('workbox-webpack-plugin');
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
Expand Down Expand Up @@ -59,11 +58,6 @@ const imageInlineSizeLimit = parseInt(
// Check if TypeScript is setup
const useTypeScript = fs.existsSync(paths.appTsConfig);

// Check if Tailwind config exists
const useTailwind = fs.existsSync(
path.join(paths.appPath, 'tailwind.config.js')
);

// Get the path to the uncompiled service worker (if it exists).
const swSrc = paths.swSrc;

Expand Down Expand Up @@ -164,36 +158,22 @@ module.exports = function (webpackEnv) {
// https://github.com/facebook/create-react-app/issues/2677
ident: 'postcss',
config: false,
plugins: !useTailwind
? [
'postcss-flexbugs-fixes',
[
'postcss-preset-env',
{
autoprefixer: {
flexbox: 'no-2009'
},
stage: 3
}
],
// Adds PostCSS Normalize as the reset css with default options,
// so that it honors browserslist config in package.json
// which in turn let's users customize the target behavior as per their needs.
'postcss-normalize'
]
: [
'tailwindcss',
'postcss-flexbugs-fixes',
[
'postcss-preset-env',
{
autoprefixer: {
flexbox: 'no-2009'
},
stage: 3
}
]
]
plugins: [
'postcss-flexbugs-fixes',
[
'postcss-preset-env',
{
autoprefixer: {
flexbox: 'no-2009'
},
stage: 3
}
],
// Adds PostCSS Normalize as the reset css with default options,
// so that it honors browserslist config in package.json
// which in turn let's users customize the target behavior as per their needs.
'postcss-normalize'
]
},
sourceMap: isEnvProduction
? shouldUseSourceMap
Expand Down Expand Up @@ -657,46 +637,19 @@ module.exports = function (webpackEnv) {
chunks: ['app'],
filename: 'beratung-hilfe.html'
}),
new HtmlWebpackPlugin({
title: 'Beratung & Hilfe',
templateParameters: {
type: 'error',
errorType: '400'
},
template: getTemplate('pages/app.html'),
chunks: ['error'],
filename: 'error.400.html'
}),
new HtmlWebpackPlugin({
title: 'Error Page 401',
templateParameters: {
type: 'error',
errorType: '401'
},
template: getTemplate('pages/app.html'),
chunks: ['error'],
filename: 'error.401.html'
}),
new HtmlWebpackPlugin({
title: 'Error Page 404',
templateParameters: {
type: 'error',
errorType: '404'
},
template: getTemplate('pages/app.html'),
chunks: ['error'],
filename: 'error.404.html'
}),
new HtmlWebpackPlugin({
title: 'Error Page 500',
templateParameters: {
type: 'error',
errorType: '500'
},
template: getTemplate('pages/app.html'),
chunks: ['error'],
filename: 'error.500.html'
}),
...['400', '401', '404', '500'].map(
(errorType) =>
new HtmlWebpackPlugin({
title: `Error Page ${errorType}`,
templateParameters: {
type: 'error',
errorType: errorType
},
template: getTemplate('pages/app.html'),
chunks: ['error'],
filename: `error.${errorType}.html`
})
),
new CopyPlugin({
patterns: [
{ from: getTemplate('pages/under-construction.html') }
Expand Down Expand Up @@ -745,30 +698,6 @@ module.exports = function (webpackEnv) {
'static/css/[name].[contenthash:8].chunk.css',
ignoreOrder: true // Temporary fix of imported css files
}),
// Generate an asset manifest file with the following content:
// - "files" key: Mapping of all asset filenames to their corresponding
// output file so that tools can pick it up without having to parse
// `index.html`
// - "entrypoints" key: Array of files which are included in `index.html`,
// can be used to reconstruct the HTML if necessary
// new WebpackManifestPlugin({
// fileName: 'asset-manifest.json',
// publicPath: paths.publicUrlOrPath,
// generate: (seed, files, entrypoints) => {
// const manifestFiles = files.reduce((manifest, file) => {
// manifest[file.name] = file.path;
// return manifest;
// }, seed);
// const entrypointFiles = Object.values(entrypoints).filter(
// (fileName) => !fileName.endsWith('.map')
// );

// return {
// files: manifestFiles,
// entrypoints: entrypointFiles
// };
// }
// }),
// Moment.js is an extremely popular library that bundles large locale files
// by default due to how webpack interprets its code. This is a practical
// solution that requires the user to opt into importing specific locales.
Expand Down
Loading

0 comments on commit 1b4e5c4

Please sign in to comment.