diff --git a/.travis.yml b/.travis.yml index c266b5f0a..b5727bef6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,10 +15,11 @@ before_install: - cp cypress.env.template.json cypress.env.json install: - - docker-compose -f docker-compose.yml -f docker-compose.travis.yml up --build -d - # avoid "Database constraints have changed after this transaction started" + - docker-compose -f docker-compose.yml build --parallel + - docker-compose -f docker-compose.yml -f docker-compose.build-and-test.yml build # just tagging, just be quite fast + - docker-compose -f docker-compose.yml -f docker-compose.build-and-test.yml up -d - wait-on http://localhost:7474 - - docker-compose exec neo4j db_setup + - docker-compose -f docker-compose.yml -f docker-compose.build-and-test.yml exec neo4j db_setup script: - export CYPRESS_RETRIES=1 @@ -38,6 +39,9 @@ script: - docker-compose exec webapp yarn run test --ci --verbose=false --coverage - docker-compose exec -d backend yarn run test:before:seeder # Fullstack + - docker-compose down + - docker-compose -f docker-compose.yml up -d + - wait-on http://localhost:7474 - yarn run cypress:run # Coverage - yarn run codecov diff --git a/backend/Dockerfile b/backend/Dockerfile index 75f5a762f..dc2e6da87 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -2,6 +2,7 @@ FROM node:12.10.0-alpine as base LABEL Description="Backend of the Social Network Human-Connection.org" Vendor="Human Connection gGmbH" Version="0.0.1" Maintainer="Human Connection gGmbH (developer@human-connection.org)" EXPOSE 4000 +CMD ["yarn", "run", "start"] ARG BUILD_COMMIT ENV BUILD_COMMIT=$BUILD_COMMIT ARG WORKDIR=/nitro-backend @@ -12,17 +13,15 @@ RUN apk --no-cache add git COPY package.json yarn.lock ./ COPY .env.template .env -CMD ["yarn", "run", "start"] -FROM base as builder +FROM base as build-and-test RUN yarn install --production=false --frozen-lockfile --non-interactive COPY . . -RUN cp .env.template .env RUN NODE_ENV=production yarn run build # reduce image size with a multistage build FROM base as production ENV NODE_ENV=production -COPY --from=builder /nitro-backend/dist ./dist +COPY --from=build-and-test /nitro-backend/dist ./dist COPY ./public/img/ ./public/img/ -RUN yarn install --frozen-lockfile --non-interactive +RUN yarn install --production=true --frozen-lockfile --non-interactive --no-cache diff --git a/cypress.env.template.json b/cypress.env.template.json index f5916bb89..8eda47154 100644 --- a/cypress.env.template.json +++ b/cypress.env.template.json @@ -1,6 +1,6 @@ { - "SEED_SERVER_HOST": "http://localhost:4001", + "BACKEND_HOST": "http://localhost:4000", "NEO4J_URI": "bolt://localhost:7687", "NEO4J_USERNAME": "neo4j", "NEO4J_PASSWORD": "letmein" -} \ No newline at end of file +} diff --git a/cypress/support/commands.js b/cypress/support/commands.js index 630b52935..51ba950a6 100644 --- a/cypress/support/commands.js +++ b/cypress/support/commands.js @@ -16,12 +16,24 @@ import "cypress-file-upload"; import helpers from "./helpers"; import users from "../fixtures/users.json"; +import { GraphQLClient, request } from 'graphql-request' +import { gql } from '../../backend/src/jest/helpers' +const backendHost = Cypress.env('BACKEND_HOST') const switchLang = name => { cy.get(".locale-menu").click(); cy.contains(".locale-menu-popover a", name).click(); }; +const authenticatedHeaders = async (variables) => { + const mutation = gql` + mutation($email: String!, $password: String!) { + login(email: $email, password: $password) + } + ` + const response = await request(backendHost, mutation, variables) + return { authorization: `Bearer ${response.login}` } +} Cypress.Commands.add("switchLanguage", (name, force) => { const { code } = helpers.getLangByName(name); @@ -82,6 +94,26 @@ Cypress.Commands.add("createCategories", (id, slug) => { icon: "medkit" }); }); + + +Cypress.Commands.add( + 'authenticateAs', + async ({email, password}) => { + const headers = await authenticatedHeaders({ email, password }) + console.log(headers) + return new GraphQLClient(backendHost, { headers }) + } +) + +Cypress.Commands.add( + 'mutate', + { prevSubject: true }, + async (graphQLClient, mutation, variables) => { + await graphQLClient.request(mutation, variables) + return graphQLClient + } +) + // // // -- This is a child command -- diff --git a/cypress/support/factories.js b/cypress/support/factories.js index 20a4d4c77..da67debd5 100644 --- a/cypress/support/factories.js +++ b/cypress/support/factories.js @@ -3,17 +3,18 @@ import { getDriver, neode as getNeode } from '../../backend/src/bootstrap/neo4j' import setupNeode from '../../backend/src/bootstrap/neode' import neode from 'neode' +const backendHost = Cypress.env('SEED_SERVER_HOST') const neo4jConfigs = { uri: Cypress.env('NEO4J_URI'), username: Cypress.env('NEO4J_USERNAME'), password: Cypress.env('NEO4J_PASSWORD') } const neo4jDriver = getDriver(neo4jConfigs) -const factory = Factory({ seedServerHost, neo4jDriver, neodeInstance: setupNeode(neo4jConfigs)}) -const seedServerHost = Cypress.env('SEED_SERVER_HOST') +const factoryOptions = { seedServerHost: backendHost, neo4jDriver, neodeInstance: setupNeode(neo4jConfigs)} +const factory = Factory(factoryOptions) beforeEach(async () => { - await factory.cleanDatabase({ seedServerHost, neo4jDriver }) + await factory.cleanDatabase() }) Cypress.Commands.add('neode', () => { @@ -35,7 +36,7 @@ Cypress.Commands.add( ) Cypress.Commands.add('factory', () => { - return Factory({ seedServerHost, neo4jDriver, neodeInstance: setupNeode(neo4jConfigs) }) + return Factory(factoryOptions) }) Cypress.Commands.add( @@ -55,20 +56,3 @@ Cypress.Commands.add( return factory } ) - -Cypress.Commands.add( - 'mutate', - { prevSubject: true }, - async (factory, mutation, variables) => { - await factory.mutate(mutation, variables) - return factory - } -) - -Cypress.Commands.add( - 'authenticateAs', - { prevSubject: true }, - (factory, loginCredentials) => { - return factory.authenticateAs(loginCredentials) - } -) diff --git a/docker-compose.build-and-test.yml b/docker-compose.build-and-test.yml new file mode 100644 index 000000000..e8e79644f --- /dev/null +++ b/docker-compose.build-and-test.yml @@ -0,0 +1,13 @@ +version: "3.4" + +services: + webapp: + image: humanconnection/nitro-web:build-and-test + build: + context: webapp + target: build-and-test + backend: + image: humanconnection/nitro-backend:build-and-test + build: + context: backend + target: build-and-test diff --git a/docker-compose.override.yml b/docker-compose.override.yml index 5ef013656..ba9b32c18 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -13,57 +13,21 @@ services: target: build-and-test volumes: - ./webapp:/nitro-web - - webapp_node_modules:/nitro-web/node_modules + environment: + - NUXT_BUILD=/tmp/nuxt # avoid file permission issues when `rm -rf .nuxt/` command: yarn run dev - environment: - - NUXT_BUILD=.nuxt-dist # avoid file ownership issues with shared folders - factories: - image: humanconnection/nitro-backend:builder - build: - context: backend - target: builder - ports: - - 4001:4001 - networks: - - hc-network - volumes: - - ./backend:/nitro-backend - - factories_node_modules:/nitro-backend/node_modules - - uploads:/nitro-backend/public/uploads - depends_on: - - neo4j - environment: - - NEO4J_URI=bolt://neo4j:7687 - - GRAPHQL_PORT=4000 - - GRAPHQL_URI=http://localhost:4000 - - CLIENT_URI=http://localhost:3000 - - JWT_SECRET=b/&&7b78BF&fv/Vd - - MAPBOX_TOKEN=pk.eyJ1IjoiaHVtYW4tY29ubmVjdGlvbiIsImEiOiJjajl0cnBubGoweTVlM3VwZ2lzNTNud3ZtIn0.KZ8KK9l70omjXbEkkbHGsQ - - PRIVATE_KEY_PASSPHRASE=a7dsf78sadg87ad87sfagsadg78 - command: yarn run test:before:seeder backend: - image: humanconnection/nitro-backend:builder build: context: backend - target: builder + target: build-and-test volumes: - ./backend:/nitro-backend - - backend_node_modules:/nitro-backend/node_modules - - uploads:/nitro-backend/public/uploads command: yarn run dev environment: - SMTP_HOST=mailserver - SMTP_PORT=25 - SMTP_IGNORE_TLS=true - "DEBUG=${DEBUG}" - neo4j: - environment: - - NEO4J_AUTH=none - ports: - - 7687:7687 - - 7474:7474 - volumes: - - neo4j-data:/data maintenance: image: humanconnection/maintenance:latest build: @@ -74,9 +38,5 @@ services: ports: - 3503:80 -volumes: - webapp_node_modules: - backend_node_modules: - factories_node_modules: - neo4j-data: - uploads: +networks: + hc-network: diff --git a/docker-compose.travis.yml b/docker-compose.travis.yml deleted file mode 100644 index 4a1acb96a..000000000 --- a/docker-compose.travis.yml +++ /dev/null @@ -1,27 +0,0 @@ -version: "3.4" - -services: - neo4j: - environment: - - NEO4J_AUTH=none - ports: - - 7687:7687 - - 7474:7474 - webapp: - build: - context: webapp - target: build-and-test - volumes: - #/nitro-web - - ./webapp/coverage:/nitro-web/coverage - backend: - image: humanconnection/nitro-backend:builder - build: - context: backend - target: builder - volumes: - - ./backend/coverage:/nitro-backend/coverage - ports: - - 4001:4001 - - 4123:4123 - diff --git a/docker-compose.yml b/docker-compose.yml index e782adcfa..37e8eb94d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,6 +10,10 @@ services: - 3000:3000 networks: - hc-network + depends_on: + - backend + volumes: + - webapp_node_modules:/nitro-web/node_modules environment: - HOST=0.0.0.0 - GRAPHQL_URI=http://backend:4000 @@ -25,20 +29,36 @@ services: - neo4j ports: - 4000:4000 + volumes: + - backend_node_modules:/nitro-backend/node_modules + - uploads:/nitro-backend/public/uploads environment: - NEO4J_URI=bolt://neo4j:7687 - GRAPHQL_PORT=4000 - - GRAPHQL_URI=http://localhost:4000 + - GRAPHQL_URI=http://backend:4000 - CLIENT_URI=http://localhost:3000 - JWT_SECRET=b/&&7b78BF&fv/Vd - MAPBOX_TOKEN=pk.eyJ1IjoiaHVtYW4tY29ubmVjdGlvbiIsImEiOiJjajl0cnBubGoweTVlM3VwZ2lzNTNud3ZtIn0.KZ8KK9l70omjXbEkkbHGsQ - PRIVATE_KEY_PASSPHRASE=a7dsf78sadg87ad87sfagsadg78 + - "DEBUG=${DEBUG}" neo4j: image: humanconnection/neo4j:latest build: context: neo4j networks: - hc-network + environment: + - NEO4J_AUTH=none + ports: + - 7687:7687 + - 7474:7474 + volumes: + - neo4j_data:/data networks: hc-network: +volumes: + webapp_node_modules: + backend_node_modules: + neo4j_data: + uploads: diff --git a/webapp/.gitignore b/webapp/.gitignore index bc179d78a..f8c980f7c 100644 --- a/webapp/.gitignore +++ b/webapp/.gitignore @@ -61,8 +61,6 @@ typings/ # nuxt.js build output .nuxt -# also the build output in docker container -.nuxt-dist # Nuxt generate dist diff --git a/webapp/Dockerfile b/webapp/Dockerfile index 2fb807501..d0b758050 100644 --- a/webapp/Dockerfile +++ b/webapp/Dockerfile @@ -14,14 +14,17 @@ WORKDIR $WORKDIR # See: https://github.com/nodejs/docker-node/pull/367#issuecomment-430807898 RUN apk --no-cache add git -COPY . . +COPY package.json yarn.lock ./ +COPY .env.template .env + FROM base as build-and-test -RUN cp .env.template .env RUN yarn install --production=false --frozen-lockfile --non-interactive +COPY . . RUN NODE_ENV=production yarn run build FROM base as production -ENV NODE_ENV=production -COPY --from=build-and-test ./nitro-web/node_modules ./node_modules +RUN yarn install --production=true --frozen-lockfile --non-interactive --no-cache COPY --from=build-and-test ./nitro-web/.nuxt ./.nuxt +COPY nuxt.config.js . +COPY locales locales diff --git a/webapp/package.json b/webapp/package.json index b0a09d817..05166c482 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -74,6 +74,7 @@ "nuxt-env": "~0.1.0", "stack-utils": "^1.0.2", "string-hash": "^1.1.3", + "tippy.js": "^4.3.5", "tiptap": "~1.25.0", "tiptap-extensions": "~1.27.0", "v-tooltip": "~2.0.2", @@ -123,7 +124,6 @@ "sass-loader": "~8.0.0", "style-loader": "~0.23.1", "style-resources-loader": "~1.2.1", - "tippy.js": "^4.3.5", "vue-jest": "~3.0.5", "vue-loader": "~15.7.0", "vue-svg-loader": "~0.12.0",