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=frontendCompiles and hot-reloads for development
npm run serveCompiles and minifies for production
npm run buildRun your unit tests
Unit tests are written with Jest and Jasmine.
npm run test:unitRun 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 CILints and fixes files
npm run lintAuthentication 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.
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 codegenThis 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.
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.
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.
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 patchThe command:
- updates the CHANGELOG.md
- creates a git tag for the new version
- adds a new release to Github
The creation of the tag triggers a job which builds a new Docker image containing the frontend application, which then is served by NGINX.
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.
