unikubehq / frontend

Frontend for the Unikube platform. Run k8s 🐳 🚢 dev setups 🤓 with ease! 🤩
https://unikube.io
Apache License 2.0
13 stars 2 forks source link
casl cloud-native cypress docker frontend graphql helm kubernetes typescript unikube vue vuetify

Coverage Status SonarCloud Quality Gate License GitHub release Unikube Slack Community

Unikube Frontend

Table of contents

Development

Before you start - you need a local instance of the unikube cluster.

After that setup the frontend as follows:

npm install

The unikube frontend projects is mostly written with Vue, TypeScript and SASS.

Notable packages used:

Create a file called .env.development.local (and adapt according to your cluster):

VUE_APP_UPLOAD_URL=http://gateway.unikube.127.0.0.1.nip.io:8085/upload
VUE_APP_GRAPHQL_URL=http://gateway.unikube.127.0.0.1.nip.io:8085/graphql
VUE_APP_KEYCLOAK_JS=/js/keycloak.js
VUE_APP_KEYCLOAK_AUTHZ_JS=/js/keycloak-authz.js
VUE_APP_KEYCLOAK_URL=http://keycloak.127.0.0.1.nip.io:8085/auth
VUE_APP_KEYCLOAK_REALM=unikube
VUE_APP_KEYCLOAK_CLIENT_ID=frontend

Compiles and hot-reloads for development

npm run serve

Compiles and minifies for production

npm run build

Run your unit tests

Unit tests are written with Jest and Jasmine.

npm run test:unit

Run your end-to-end tests

This command starts integration testing with Cypress. Cypress runs through different views and imitates user workflows.

npm run test:e2e
# or
npm run test:e2e:ci # for CI

Lints and fixes files

npm run lint

Authentication

Authentication as well as authorization happens via Keycloak. To make sure a user is authenticated before entering the frontend application it (the VueJS app) is wrapped into a "Keycloak validation".

If everything is fine - the application is initialized with all its plugins. Unauthenticated users will be redirected onto the Keycloak authentication page.

The Keycloak auth token is updated as soon as it is valid for less than 30 seconds.

GraphQL

Unikube makes heavy use of GraphQL between frontend and multiple microservices. To perform queries we're leveraging Apollo with vue-apollo.

For enhanced type-safety we're converting the GraphQL schema provided by the API-Gateway into TypeScript types/enums/interfaces. With a local cluster the TypeScript definitions can be updated via the following command.

npm run codegen

This command is provided by the GraphQL-Code-Generator. The configuration can be found in codegen.yml.

It is extended by a custom command (npm run kindify) which extends the GraphQL converted nodes (TypeScript types then) by a field kind. The command is called as part of an afterOneFileWrite hook configured in codegen.yml. This field contains an identifier which then is used by CASL to determine what kind of object it deals with when it comes to permissions.

The automatically generated types are stored within generated/graphql.ts.

Permissions

We're using CASL to handle frontend permissions. The auth.ts vuex store module converts information from the Keycloak RPT token into CASL permissions.

CASL is neatly integrated with Vue in this project. Therefore, it is possible to create a permission-based reactive frontend. Meaning as soon as the (rpt) token for the frontend's requests gets updated the frontend rerenders based on the updated permissions. Tokens usually have a short lifetime.

CASL Example

import { TProjectNode } from './graphql';

export default class ProjectList extends Vue {
  get projects() {
    this.projectList.filter((project: TProjectNode) => {
      this.$can('view', project)
    })
  }
}

The example above may not be needed in a real case, since the backend will probably not return any TProjectNode objects which are not viewable for the user.

New Releases

The versioning system used for this project is semantic versioning.

We're using release-it and auto-changelog for an automated release workflow.

Depending on the kind of release (patch, minor, major) you would like to create run the following command:

npm run release patch

The command:

The creation of the tag triggers a job which builds a new Docker image containing the frontend application, which then is served by NGINX.

Docker Image

On a new release a Docker image is automatically created and pushed to quay.

There are 2 versions of the image - production and development. The development, which image is used for local development with Unikube, is tagged with a -dev suffix.

For every release 2 new tags are created, based on the version e.g. 1.0.0 and 1.0.0-dev.

Furthermore the latest and latest-dev tag are bumped to the latest release.