diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 2743a25df..71af5a061 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -4,7 +4,7 @@ on: push: branches: - master - # - 55-implement-PRODUCTION_DB_CLEAN_ALLOW-for-staging-production-evironments # for testing while developing + # - 5059-epic-groups # for testing while developing jobs: ############################################################################## @@ -83,7 +83,7 @@ jobs: ########################################################################## - name: Backend | Build `branded` image run: | - docker build --target branded -t "${DOCKER_ORGANISATION}/backend-branded:latest" -t "${DOCKER_ORGANISATION}/backend-branded:${VERSION}" -t "${DOCKER_ORGANISATION}/backend-branded:${BUILD_VERSION}" -f docker/backend.Dockerfile --build-arg "APP_IMAGE_TAG_CODE=${OCELOT_DOCKER_VERSION_TAG}-code" --build-arg "APP_IMAGE_TAG_BASE=${OCELOT_DOCKER_VERSION_TAG}-base" . + docker build --target branded -t "${DOCKER_ORGANISATION}/backend-branded:latest" -t "${DOCKER_ORGANISATION}/backend-branded:${VERSION}" -t "${DOCKER_ORGANISATION}/backend-branded:${BUILD_VERSION}" -f docker/backend.Dockerfile --build-arg "APP_IMAGE=ocelotsocialnetwork/backend" --build-arg "APP_IMAGE_TAG_CODE=${OCELOT_DOCKER_VERSION_TAG}-code" --build-arg "APP_IMAGE_TAG_BASE=${OCELOT_DOCKER_VERSION_TAG}-base" . docker save "${DOCKER_ORGANISATION}/backend-branded" > /tmp/backend-branded.tar - name: Upload Artifact uses: actions/upload-artifact@v2 @@ -125,7 +125,7 @@ jobs: ########################################################################## - name: Webapp | Build `branded` image run: | - docker build --target branded -t "${DOCKER_ORGANISATION}/webapp-branded:latest" -t "${DOCKER_ORGANISATION}/webapp-branded:${VERSION}" -t "${DOCKER_ORGANISATION}/webapp-branded:${BUILD_VERSION}" -f docker/webapp.Dockerfile --build-arg "APP_IMAGE_TAG_CODE=${OCELOT_DOCKER_VERSION_TAG}-code" --build-arg "APP_IMAGE_TAG_BASE=${OCELOT_DOCKER_VERSION_TAG}-base" . + docker build --target branded -t "${DOCKER_ORGANISATION}/webapp-branded:latest" -t "${DOCKER_ORGANISATION}/webapp-branded:${VERSION}" -t "${DOCKER_ORGANISATION}/webapp-branded:${BUILD_VERSION}" -f docker/webapp.Dockerfile --build-arg "APP_IMAGE=ocelotsocialnetwork/webapp" --build-arg "APP_IMAGE_TAG_CODE=${OCELOT_DOCKER_VERSION_TAG}-code" --build-arg "APP_IMAGE_TAG_BASE=${OCELOT_DOCKER_VERSION_TAG}-base" . docker save "${DOCKER_ORGANISATION}/webapp-branded" > /tmp/webapp-branded.tar - name: Upload Artifact uses: actions/upload-artifact@v2 @@ -167,7 +167,7 @@ jobs: ########################################################################## - name: Maintenance | Build `branded` image run: | - docker build --target branded -t "${DOCKER_ORGANISATION}/maintenance-branded:latest" -t "${DOCKER_ORGANISATION}/maintenance-branded:${VERSION}" -t "${DOCKER_ORGANISATION}/maintenance-branded:${BUILD_VERSION}" -f docker/maintenance.Dockerfile --build-arg "APP_IMAGE_TAG_CODE=${OCELOT_DOCKER_VERSION_TAG}-code" --build-arg "APP_IMAGE_TAG_BASE=${OCELOT_DOCKER_VERSION_TAG}-base" . + docker build --target branded -t "${DOCKER_ORGANISATION}/maintenance-branded:latest" -t "${DOCKER_ORGANISATION}/maintenance-branded:${VERSION}" -t "${DOCKER_ORGANISATION}/maintenance-branded:${BUILD_VERSION}" -f docker/maintenance.Dockerfile --build-arg "APP_IMAGE=ocelotsocialnetwork/maintenance" --build-arg "APP_IMAGE_TAG_CODE=${OCELOT_DOCKER_VERSION_TAG}-code" --build-arg "APP_IMAGE_TAG_BASE=${OCELOT_DOCKER_VERSION_TAG}-base" . docker save "${DOCKER_ORGANISATION}/maintenance-branded" > /tmp/maintenance-branded.tar - name: Upload Artifact uses: actions/upload-artifact@v2 @@ -256,6 +256,78 @@ jobs: - name: Push Maintenance run: docker push --all-tags ${DOCKER_ORGANISATION}/maintenance-branded + ############################################################################## + # JOB: KUBERNETES DEPLOY ACTUAL/LATEST VERSION ###################################### + ############################################################################## + kubernetes_deploy: + # see example https://github.com/do-community/example-doctl-action + # see example https://github.com/do-community/example-doctl-action/blob/main/.github/workflows/workflow.yaml + name: Kubernetes deploy of latest version to stage.ocelot.social cluster at DigitalOcean + runs-on: ubuntu-latest + needs: [upload_to_dockerhub] + steps: + ########################################################################## + # CHECKOUT CODE ########################################################## + ########################################################################## + - name: Checkout code + uses: actions/checkout@v2 + ########################################################################## + # SET ENVS ############################################################### + ########################################################################## + - name: ENV - VERSION + run: echo "VERSION=$(node -p -e "require('./package.json').version")" >> $GITHUB_ENV + - name: ENV - BUILD_DATE + run: echo "BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_ENV + - name: ENV - OCELOT_DOCKER_VERSION_TAG + run: echo "OCELOT_DOCKER_VERSION_TAG=$(node -p -e "require('./package.json').ocelotDockerVersionTag")" >> $GITHUB_ENV + - name: ENV - DOCKER_ORGANISATION + run: echo "DOCKER_ORGANISATION=$(node -p -e "require('./package.json').dockerOrganisation")" >> $GITHUB_ENV + # this is based on the node Docker version tag "node:12.19.0-alpine3.10" and looks like "app-branded:1.0.2-3-ocelot.social1.0.2-79" + - name: ENV - BUILD_VERSION + run: echo "BUILD_VERSION=${VERSION}-${GITHUB_RUN_NUMBER}-ocelot.social${OCELOT_DOCKER_VERSION_TAG}" >> $GITHUB_ENV + ########################################################################## + # Install DigitalOceans doctl and set kubeconfig ######################### + ########################################################################## + - name: Install doctl + uses: digitalocean/action-doctl@v2 + with: + token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }} + - name: Save DigitalOcean kubeconfig with short-lived credentials + run: doctl kubernetes cluster kubeconfig save --expiry-seconds 600 cluster-stage-yunite-me + ########################################################################## + # Deploy new Docker images to DigitalOcean Kubernetes cluster ############ + ########################################################################## + - name: Deploy actual version '$BUILD_VERSION' to DigitalOcean Kubernetes + run: | + kubectl -n default set image deployment/ocelot-webapp container-ocelot-webapp=${DOCKER_ORGANISATION}/webapp-branded:${BUILD_VERSION} + kubectl -n default rollout restart deployment/ocelot-webapp + kubectl -n default set image deployment/ocelot-backend container-ocelot-backend=${DOCKER_ORGANISATION}/backend-branded:${BUILD_VERSION} + kubectl -n default rollout restart deployment/ocelot-backend + kubectl -n default set image deployment/ocelot-maintenance container-ocelot-maintenance=${DOCKER_ORGANISATION}/maintenance-branded:${BUILD_VERSION} + kubectl -n default rollout restart deployment/ocelot-maintenance + kubectl -n default set image deployment/ocelot-neo4j container-ocelot-neo4j=${DOCKER_ORGANISATION}/neo4j-community-branded:${BUILD_VERSION} + kubectl -n default rollout restart deployment/ocelot-neo4j + # because this step 'kubectl -n default rollout status deployment/* --timeout=600s' does not work as expected + # and we need the pods to be up again for cleaning and seeding the Neo4j database and the backend. + # !!! this is not a perfect solution !!! + # deployments are regularly up again after 3 minutes and 10 seconds + - name: Sleep for 4 minutes, means 240 seconds + run: sleep 240s + shell: bash + - name: Verify deployment and wait for the pods of each deployment to get ready for cleaning and seeding of the database + run: | + kubectl -n default rollout status deployment/ocelot-backend --timeout=600s + kubectl -n default rollout status deployment/ocelot-neo4j --timeout=600s + kubectl -n default rollout status deployment/ocelot-maintenance --timeout=600s + kubectl -n default rollout status deployment/ocelot-webapp --timeout=600s + - name: Run migrations for Neo4j database via backend for staging + run: | + kubectl -n default exec -it $(kubectl -n default get pods | grep ocelot-backend | awk '{ print $1 }') -- /bin/sh -c "yarn prod:migrate up" + - name: Reset and seed Neo4j database via backend for staging + # db cleaning and seeding is only possible in production if env 'PRODUCTION_DB_CLEAN_ALLOW=true' is set in deployment + run: | + kubectl -n default exec -it $(kubectl -n default get pods | grep ocelot-backend | awk '{ print $1 }') -- /bin/sh -c "node --experimental-repl-await dist/db/clean.js && node --experimental-repl-await dist/db/seed.js" + ############################################################################## # JOB: GITHUB TAG LATEST VERSION ############################################# ############################################################################## diff --git a/README.md b/README.md index 9b70d3a8c..28dcd80ef 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,8 @@ __Try out our deployed [development environment](https://stage.ocelot.social).__ Visit our staging networks: -- central staging network: [stage.ocelot.social](https://stage.ocelot.social). +- central staging network: [stage.ocelot.social](https://stage.ocelot.social) +- Yunite staging network: [stage.yunite.me](https://stage.yunite.me) Logins: diff --git a/TODO-next-update.md b/TODO-next-update.md index 4cf3c8d10..bdf632325 100644 --- a/TODO-next-update.md +++ b/TODO-next-update.md @@ -2,11 +2,21 @@ When you overtake this deploy and rebrand repo to your network you have to recognize the following changes and doings … +## This Latest Version >= 2.0.0 with 'ocelotDockerVersionTag' 2.0.0-250 + +### Main Code PR – feat: 🍰 Implement LOGO_HEADER_CLICK As Configuration #5525 + +- You have to set `LOGO_HEADER_CLICK` in `branding/constants/logos.js` originally in main code file `webapp/constants/logos.js` to your prevered value. + +### Main Code Issue – 🌟 [EPIC] Release v2.0.0 – Beta Test → Final #5547 + +- You have to set `SHOW_GROUP_BUTTON_IN_HEADER` in `branding/constants/groups.js` originally in main code file `webapp/constants/groups.js` to your prevered value. + ## This Latest Version >= 1.1.0 with 'ocelotDockerVersionTag' 1.1.0-205 -### Deployment/Rebranding PR – chore: 🍰 Release v1.1.0 - Implement Categories Again #63 +### Deployment/Rebranding PR – chore: 🍰 Release v1.1.0 - Implement Categories Again #63 -- You have to add the `CATEGORIES_ACTIVE` from the `deployment/kubernetes/values.template.yaml` to your `deployment/kubernetes/values.yaml` and set it to your prevered value. +- You have to add the `CATEGORIES_ACTIVE` from the `deployment/kubernetes/values.template.yaml` to your `deployment/kubernetes/values.yaml` and set it to your preferred value. - Make sure the correct categories are in your Neo4j database on the server. ## Version >= 1.0.9 with 'ocelotDockerVersionTag' 1.0.9-199 diff --git a/branding/constants/groups.js b/branding/constants/groups.js new file mode 100644 index 000000000..f54a3bc08 --- /dev/null +++ b/branding/constants/groups.js @@ -0,0 +1,5 @@ +// this file is duplicated in `backend/src/constants/group.js` and `webapp/constants/group.js` +export const NAME_LENGTH_MIN = 3 +export const NAME_LENGTH_MAX = 50 +export const DESCRIPTION_WITHOUT_HTML_LENGTH_MIN = 100 // with removed HTML tags +export const SHOW_GROUP_BUTTON_IN_HEADER = false diff --git a/branding/constants/headerMenu.js b/branding/constants/headerMenu.js index c95e79122..48f9fd29f 100644 --- a/branding/constants/headerMenu.js +++ b/branding/constants/headerMenu.js @@ -1,11 +1,19 @@ export default { MENU: [ { - name: 'Beiträge', - path: '/#', + nameIdent: 'yuniteRebranding.header.newsFeed', + path: '/', }, { - name: 'Über Yunite', + nameIdent: 'yuniteRebranding.header.myGroups', + path: '/my-groups', + }, + { + nameIdent: 'yuniteRebranding.header.topics', + url: 'https://yunite.org/themen/', + }, + { + nameIdent: 'yuniteRebranding.header.about', url: 'https://yunite.org', }, ], diff --git a/branding/constants/links.js b/branding/constants/links.js index 7e89159eb..aa9e3a129 100644 --- a/branding/constants/links.js +++ b/branding/constants/links.js @@ -17,7 +17,7 @@ const ORGANIZATION = defaultPageParamsPages.ORGANIZATION.overwrite({ }) const DONATE = defaultPageParamsPages.DONATE.overwrite({ // we use 'ocelot-social.herokuapp.com' at the moment, because redirections of 'ocelot.social' subpages are not working correctly - externalLink: 'https://yunite.org/brand-guidelines/', // if string is defined and not empty it's dominating + externalLink: 'https://yunite.org/spenden/', // if string is defined and not empty it's dominating internalPage: { // footerIdent: 'site.donate', // localized string identifier, if undefined default is used @@ -34,7 +34,7 @@ const IMPRINT = defaultPageParamsPages.IMPRINT.overwrite({ externalLink: 'https://yunite.org/impressum/', // if string is defined and not empty it's dominating internalPage: { - // footerIdent: 'site.imprint', // localized string identifier, if undefined default is used + footerIdent: 'yuniteRebranding.footer.imprint', // localized string identifier, if undefined default is used // headTitleIdent: 'site.imprint', // localized string identifier, if undefined default is used // headlineIdent: 'site.imprint', // localized string identifier, on null it's hidden, if undefined default is used hasContainer: true, @@ -73,7 +73,7 @@ const DATA_PRIVACY = defaultPageParamsPages.DATA_PRIVACY.overwrite({ externalLink: 'https://yunite.org/datenschutz/', // if string is defined and not empty it's dominating internalPage: { - // footerIdent: 'site.data-privacy', // localized string identifier, if undefined default is used + footerIdent: 'yuniteRebranding.footer.dataPrivacy', // localized string identifier, if undefined default is used // headTitleIdent: 'site.data-privacy', // localized string identifier, if undefined default is used // headlineIdent: 'site.data-privacy', // localized string identifier, on null it's hidden, if undefined default is used hasContainer: true, @@ -124,11 +124,11 @@ export default { SUPPORT, FOOTER_LINK_LIST: [ - ORGANIZATION, + // ORGANIZATION, // TERMS_AND_CONDITIONS, - CODE_OF_CONDUCT, + // CODE_OF_CONDUCT, DATA_PRIVACY, - FAQ, + // FAQ, // DONATE, // SUPPORT, IMPRINT, diff --git a/branding/constants/logos.js b/branding/constants/logos.js index 75ac91b30..a78a67218 100644 --- a/branding/constants/logos.js +++ b/branding/constants/logos.js @@ -3,6 +3,10 @@ export default { LOGO_HEADER_PATH: '/img/custom/logo-horizontal.svg', LOGO_HEADER_WIDTH: '47px', + LOGO_HEADER_CLICK: { + externalLink: 'https://yunite.org', + internalPath: null, + }, LOGO_SIGNUP_PATH: '/img/custom/logo-squared.svg', LOGO_WELCOME_PATH: '/img/custom/logo-squared.svg', LOGO_LOGOUT_PATH: '/img/custom/logo-squared.svg', diff --git a/branding/locales/de.json b/branding/locales/de.json new file mode 100644 index 000000000..c27e5af24 --- /dev/null +++ b/branding/locales/de.json @@ -0,0 +1,14 @@ +{ + "yuniteRebranding": { + "header": { + "about": "Über Yunite", + "myGroups": "Gruppen", + "newsFeed": "Beiträge", + "topics": "Themen" + }, + "footer": { + "dataPrivacy": "Datenschutz", + "imprint": "Impressum" + } + } +} diff --git a/branding/locales/en.json b/branding/locales/en.json new file mode 100644 index 000000000..93609ee38 --- /dev/null +++ b/branding/locales/en.json @@ -0,0 +1,14 @@ +{ + "yuniteRebranding": { + "header": { + "about": "About Yunite", + "myGroups": "Groups", + "newsFeed": "News Feed", + "topics": "Topics" + }, + "footer": { + "dataPrivacy": "Data privacy", + "imprint": "Imprint" + } + } +} diff --git a/deployment/kubernetes/.gitignore b/deployment/kubernetes/.gitignore index 092cda60e..3bcb187b9 100644 --- a/deployment/kubernetes/.gitignore +++ b/deployment/kubernetes/.gitignore @@ -1,4 +1,5 @@ /dns.values.yaml +/dns.values*-ME.yaml /nginx.values.yaml /values.yaml /values*-ME.yaml \ No newline at end of file diff --git a/docker/webapp.Dockerfile b/docker/webapp.Dockerfile index 81748e08f..ba7cbffb0 100644 --- a/docker/webapp.Dockerfile +++ b/docker/webapp.Dockerfile @@ -10,11 +10,18 @@ ARG APP_IMAGE_CODE=${APP_IMAGE}:${APP_IMAGE_TAG_CODE} FROM $APP_IMAGE_CODE as code # copy public constants into the Docker image to brand it +COPY tools/ tools/ COPY branding/static/ static/ COPY branding/constants/ constants/ -COPY branding/locales/ locales/ +COPY branding/locales/html/ locales/html/ +# COPY branding/locales/index.js locales/index.js +COPY branding/locales/*.json locales/tmp/ COPY branding/assets/styles/imports/ assets/styles/imports/ +RUN apk add --no-cache bash jq + +RUN tools/merge-locales.sh + ################################################################################## # BUILD ########################################################################## ################################################################################## diff --git a/package.json b/package.json index dfce46c3c..5f6fa8663 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "yunite.net", - "version": "1.1.1", - "ocelotDockerVersionTag": "1.1.1-228", + "version": "2.1.0", + "ocelotDockerVersionTag": "2.1.0-253", "dockerOrganisation": "tirokk", "description": "yunite.net Branded", "author": "yunite.net Community", diff --git a/tools/merge-locales.sh b/tools/merge-locales.sh new file mode 100755 index 000000000..21d263265 --- /dev/null +++ b/tools/merge-locales.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +for locale in `ls locales/*.json`; +do + file=$(basename $locale); + if [ -f locales/tmp/$file ]; then + jq -s '.[0] * .[1]' $locale locales/tmp/$file > locales/tmp/tmp.json; + mv locales/tmp/tmp.json $locale; + fi; +done; + +rm -r locales/tmp/