From 6a9e2046297e23a6e7633c3ca631edb997026836 Mon Sep 17 00:00:00 2001 From: Trivernis Date: Thu, 19 Dec 2019 19:12:46 +0100 Subject: [PATCH 1/9] Added jenkins build config --- Jenkinsfile | 16 ++++++++++++++++ package-lock.json | 14 +++++++------- package.json | 2 +- 3 files changed, 24 insertions(+), 8 deletions(-) create mode 100644 Jenkinsfile diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..d933f33 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,16 @@ +pipeline { + stage('Stylecheck') { + steps { + echo 'Checking Style...' + sh 'npm i' + sh 'npm i tslint --dev' + sh 'tslint src/**/*.ts' + } + } + stage('Build') { + steps { + echo 'Building...' + sh 'ng build --prod' + } + } +} diff --git a/package-lock.json b/package-lock.json index c537c0a..924a6ab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4521,9 +4521,9 @@ } }, "commander": { - "version": "2.17.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", - "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, "commondir": { @@ -12844,12 +12844,12 @@ }, "dependencies": { "resolve": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", - "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.14.1.tgz", + "integrity": "sha512-fn5Wobh4cxbLzuHaE+nphztHy43/b++4M6SsGFC2gB8uYwf0C8LcarfCz1un7UTW8OFQg9iNjZ4xpcFVGebDPg==", "dev": true, "requires": { - "path-parse": "^1.0.5" + "path-parse": "^1.0.6" } } } diff --git a/package.json b/package.json index 5249fab..d16e192 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "karma-jasmine-html-reporter": "^0.2.2", "protractor": "~5.4.0", "ts-node": "~7.0.0", - "tslint": "~5.11.0", + "tslint": "^5.11.0", "typescript": "~3.5.0" } } From 602d74eadb9ae47bcd9fa6d32582f90f9030881c Mon Sep 17 00:00:00 2001 From: Trivernis Date: Thu, 19 Dec 2019 19:15:58 +0100 Subject: [PATCH 2/9] Jenkins config - added agent information --- Jenkinsfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Jenkinsfile b/Jenkinsfile index d933f33..698129e 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,4 +1,6 @@ pipeline { + agent any + stage('Stylecheck') { steps { echo 'Checking Style...' From 02db6bd65b59b65b44504075d3b39693ca3282bc Mon Sep 17 00:00:00 2001 From: Trivernis Date: Thu, 19 Dec 2019 19:18:02 +0100 Subject: [PATCH 3/9] Jenkins config - fixed stage declaration --- Jenkinsfile | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 698129e..aa7e8c8 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,18 +1,20 @@ pipeline { agent any - stage('Stylecheck') { + stages { + stage('Stylecheck') { steps { echo 'Checking Style...' sh 'npm i' sh 'npm i tslint --dev' sh 'tslint src/**/*.ts' } - } - stage('Build') { - steps { - echo 'Building...' - sh 'ng build --prod' + } + stage('Build') { + steps { + echo 'Building...' + sh 'ng build --prod' + } } } } From bea2e225191f10cd7ecd41ceb792c72383a7a4d2 Mon Sep 17 00:00:00 2001 From: Trivernis Date: Thu, 19 Dec 2019 19:24:39 +0100 Subject: [PATCH 4/9] Jenkins config nodejs - added nodejs plugin and config --- Jenkinsfile | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index aa7e8c8..4b60814 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -5,15 +5,19 @@ pipeline { stage('Stylecheck') { steps { echo 'Checking Style...' - sh 'npm i' - sh 'npm i tslint --dev' - sh 'tslint src/**/*.ts' + nodejs { + sh 'npm i' + sh 'npm i tslint --dev' + sh 'tslint src/**/*.ts' + } } } stage('Build') { steps { echo 'Building...' - sh 'ng build --prod' + nodejs { + sh 'ng build --prod' + } } } } From edf2fee7e0ab80ae090144913bbf5209d3eaaf8b Mon Sep 17 00:00:00 2001 From: Trivernis Date: Thu, 19 Dec 2019 19:26:21 +0100 Subject: [PATCH 5/9] Jenkins config nodejs - added nodejs version --- Jenkinsfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 4b60814..925340a 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -5,7 +5,7 @@ pipeline { stage('Stylecheck') { steps { echo 'Checking Style...' - nodejs { + nodejs(nodeJSInstallationName: 'Node 12.x') { sh 'npm i' sh 'npm i tslint --dev' sh 'tslint src/**/*.ts' @@ -15,7 +15,7 @@ pipeline { stage('Build') { steps { echo 'Building...' - nodejs { + nodejs(nodeJSInstallationName: 'Node 12.x') { sh 'ng build --prod' } } From fc15558644b28b6fc29ba586a9731a1697fc97f0 Mon Sep 17 00:00:00 2001 From: Trivernis Date: Thu, 19 Dec 2019 19:31:31 +0100 Subject: [PATCH 6/9] Jenkins config ts - added typescript module to npm installation --- Jenkinsfile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 925340a..5c53f8a 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -7,8 +7,8 @@ pipeline { echo 'Checking Style...' nodejs(nodeJSInstallationName: 'Node 12.x') { sh 'npm i' - sh 'npm i tslint --dev' - sh 'tslint src/**/*.ts' + sh 'npm i typescript tslint' + sh 'tslint "src/**/*.ts"' } } } @@ -16,6 +16,7 @@ pipeline { steps { echo 'Building...' nodejs(nodeJSInstallationName: 'Node 12.x') { + sh 'npm i @angular/cli' sh 'ng build --prod' } } From c3ed16b2390ec8ffe0be8bbfe47e2c6af6db87cc Mon Sep 17 00:00:00 2001 From: Trivernis Date: Thu, 19 Dec 2019 20:01:26 +0100 Subject: [PATCH 7/9] Applied style fixes - fixed all tslint errors/warnings --- src/app/app.component.ts | 2 +- .../app-scaffold/app-scaffold.component.ts | 6 ++- src/app/components/feed/feed.component.ts | 6 +-- src/app/components/login/login.component.ts | 18 ++++----- .../main-navigation.component.ts | 8 +++- .../components/register/register.component.ts | 2 +- .../social/groups/groups.component.ts | 7 +++- src/app/models/levellist.ts | 9 +++-- src/app/models/post.ts | 12 +++++- src/app/models/user.ts | 24 +++++------ src/app/services/chat/chat.service.ts | 16 +++++--- src/app/services/feed/feed.service.ts | 40 ++++++++++++------- src/app/services/login/login.service.ts | 6 +-- src/app/services/register/register.service.ts | 11 ++++- src/tslint.json | 1 - 15 files changed, 109 insertions(+), 59 deletions(-) diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 573d806..4467c78 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -34,7 +34,7 @@ export class AppComponent implements OnInit { console.log(this.userInfo); this.data.changeChatIDs(user.chatIDs); }); - if (this.loggedIn != true) { + if (this.loggedIn !== true) { this.selfservice.checkIfLoggedIn(); } } diff --git a/src/app/components/app-scaffold/app-scaffold.component.ts b/src/app/components/app-scaffold/app-scaffold.component.ts index 2ad77f7..5945031 100644 --- a/src/app/components/app-scaffold/app-scaffold.component.ts +++ b/src/app/components/app-scaffold/app-scaffold.component.ts @@ -26,7 +26,11 @@ export class AppScaffoldComponent implements OnInit { dropdownShown = false; - constructor(private data: DatasharingService, private selfservice: SelfService, private http: Http, private router: Router) { } + constructor( + private data: DatasharingService, + private selfservice: SelfService, + private http: Http, + private router: Router) { } ngOnInit() { this.data.currentUserInfo.subscribe(user => { diff --git a/src/app/components/feed/feed.component.ts b/src/app/components/feed/feed.component.ts index f374334..fd38752 100644 --- a/src/app/components/feed/feed.component.ts +++ b/src/app/components/feed/feed.component.ts @@ -28,14 +28,14 @@ export class FeedComponent implements OnInit { userId: number; user: User; - constructor(private feedService: FeedService,private data: DatasharingService) { } + constructor(private feedService: FeedService, private data: DatasharingService) { } ngOnInit() { this.data.currentUserInfo.subscribe(user => { this.user = user; this.loggedIn = user.loggedIn; - if(this.loggedIn) this.userId = user.userID; - console.log("the userId is " + this.userId); + if (this.loggedIn) { this.userId = user.userID; } + console.log('the userId is ' + this.userId); }); this.feedService.getAllPostsRawByUserId(this.userId).subscribe(response => { this.feedNew = this.feedService.renderAllPosts(response.json()); diff --git a/src/app/components/login/login.component.ts b/src/app/components/login/login.component.ts index 6821abd..8ece19b 100644 --- a/src/app/components/login/login.component.ts +++ b/src/app/components/login/login.component.ts @@ -11,20 +11,21 @@ import * as sha512 from 'js-sha512'; styleUrls: ['./login.component.sass'] }) export class LoginComponent implements OnInit { - login: Login; - hide = true; - errorOccurred: boolean = false; - errorMessage: string; - constructor(private loginService: LoginService,private router: Router) { + constructor(private loginService: LoginService, private router: Router) { this.login = {passwordHash: null, email: null}; } + login: Login; + hide = true; + errorOccurred = false; + errorMessage: string; + email = new FormControl('', [Validators.required, Validators.email]); - public getErrorMessage(){ + public getErrorMessage() { return this.errorMessage; } - public loginError(error : any){ + public loginError(error: any) { console.log(error.errors[0].message); this.errorOccurred = true; this.errorMessage = error.errors[0].message; @@ -33,7 +34,7 @@ export class LoginComponent implements OnInit { onClickSubmit(pEmail: string, pPasswordHash: string) { console.log('try to login with mail adress:' + pEmail); this.errorOccurred = false; - this.errorMessage = " "; + this.errorMessage = ' '; this.login.email = pEmail.trim(); this.login.passwordHash = sha512.sha512(pPasswordHash); console.log(this.login.passwordHash); @@ -42,7 +43,6 @@ export class LoginComponent implements OnInit { this.loginService.login(this.login, error => this.loginError(error.json())); } - email = new FormControl('', [Validators.required, Validators.email]); ngOnInit() {} } diff --git a/src/app/components/main-navigation/main-navigation.component.ts b/src/app/components/main-navigation/main-navigation.component.ts index a16c49f..dc6b72d 100644 --- a/src/app/components/main-navigation/main-navigation.component.ts +++ b/src/app/components/main-navigation/main-navigation.component.ts @@ -18,7 +18,13 @@ import { OverlayContainer} from '@angular/cdk/overlay'; }) export class MainNavigationComponent implements OnInit { - constructor(public overlayContainer: OverlayContainer, private data: DatasharingService, private selfservice: SelfService, private breakpointObserver: BreakpointObserver, private http: Http, private router: Router) { + constructor( + public overlayContainer: OverlayContainer, + private data: DatasharingService, + private selfservice: SelfService, + private breakpointObserver: BreakpointObserver, + private http: Http, private router: Router + ) { this.overlay = overlayContainer.getContainerElement(); } loggedIn = false; diff --git a/src/app/components/register/register.component.ts b/src/app/components/register/register.component.ts index 92af91e..ec0f2e5 100644 --- a/src/app/components/register/register.component.ts +++ b/src/app/components/register/register.component.ts @@ -40,7 +40,7 @@ export class RegisterComponent implements OnInit { } passwordSame(pwd: string, pwd2: string) { - if (pwd == pwd2) { + if (pwd === pwd2) { console.log('password same'); return true; } else { diff --git a/src/app/components/social/groups/groups.component.ts b/src/app/components/social/groups/groups.component.ts index dc4fa74..8263d7e 100644 --- a/src/app/components/social/groups/groups.component.ts +++ b/src/app/components/social/groups/groups.component.ts @@ -7,7 +7,12 @@ import { GroupInfo } from 'src/app/models/groupinfo'; styleUrls: ['./groups.component.sass'] }) export class GroupsComponent implements OnInit { - groups: Array = [new GroupInfo(1, 'Group 1', []), new GroupInfo(1, 'Group 2', []), new GroupInfo(1, 'Group 3', []), new GroupInfo(1, 'Group 4', [])]; + // TODO: replace with actual logic that loads the groups from the backend + groups: Array = [ + new GroupInfo(1, 'Group 1', []), + new GroupInfo(1, 'Group 2', []), + new GroupInfo(1, 'Group 3', []), + new GroupInfo(1, 'Group 4', [])]; constructor() { } ngOnInit() { diff --git a/src/app/models/levellist.ts b/src/app/models/levellist.ts index 45c4692..cb28476 100644 --- a/src/app/models/levellist.ts +++ b/src/app/models/levellist.ts @@ -9,13 +9,14 @@ export class Levellist { {level: 6, name: 'Intergallactic Superhero', points: 600 }, ]; - getLevelName(lev: number): any { + getLevelName(level: number): any { let name = 'not defined'; - this.levels.forEach(rank => { - if (lev == rank.level) { + + for (const rank of this.levels) { + if (level === rank.level) { name = rank.name; } - }); + } return name; } diff --git a/src/app/models/post.ts b/src/app/models/post.ts index 0271d27..583935c 100644 --- a/src/app/models/post.ts +++ b/src/app/models/post.ts @@ -10,7 +10,17 @@ export class Post { userVote: string; author: Author; - constructor(pId: number, pContent: string, pHtmlContent: string, pUpvotes: number, pDownvotes: number, pUserVote: string, pDate: string, pAuthor: Author) { + // TODO: constructor properties need normal names + constructor( + pId: number, + pContent: string, + pHtmlContent: string, + pUpvotes: number, + pDownvotes: number, + pUserVote: string, + pDate: string, + pAuthor: Author + ) { this.id = pId; this.content = pContent; this.htmlContent = pHtmlContent; diff --git a/src/app/models/user.ts b/src/app/models/user.ts index 619d6b7..615281b 100644 --- a/src/app/models/user.ts +++ b/src/app/models/user.ts @@ -1,15 +1,15 @@ export class User { - loggedIn : boolean - userID : number - username : string - handle : string - email : string - points : number - level : number + loggedIn: boolean; + userID: number; + username: string; + handle: string; + email: string; + points: number; + level: number; - friendIDs : number[] - groupIDs : number[] - chatIDs : number[] + friendIDs: number[]; + groupIDs: number[]; + chatIDs: number[]; - requestIDs : number[] -} \ No newline at end of file + requestIDs: number[]; +} diff --git a/src/app/services/chat/chat.service.ts b/src/app/services/chat/chat.service.ts index 5d22553..315c532 100644 --- a/src/app/services/chat/chat.service.ts +++ b/src/app/services/chat/chat.service.ts @@ -89,8 +89,12 @@ export class ChatService { this.http.post(url, this.getBodyForNewChat(pUserID)); } + /** + * TODO: Needs to be used somewhere or it will be removed + */ public requestAllChatPartners(): Array { const url = environment.graphQLUrl; + // tslint:disable-next-line:prefer-const let chatPartners: Array; let temp; @@ -107,7 +111,7 @@ export class ChatService { let memberName: string; let memberLevel: number; for (const member of chat.members) { - if (member.id != this.ownID) { + if (member.id !== this.ownID) { memberID = member.id; memberName = member.name; memberLevel = member.level; @@ -154,7 +158,7 @@ export class ChatService { public renderMessages(pResponse: any): Array { const messages = new Array(); for (const message of pResponse.data.getChat.messages) { - if (message.author.id == this.ownID) { + if (message.author.id === this.ownID) { messages.push(new Chatmessage(message.content, message.createdAt, true)); } else { messages.push(new Chatmessage(message.content, message.createdAt, false)); @@ -169,14 +173,14 @@ export class ChatService { let memberID: number; let memberName: string; for (const member of chat.members) { - if (member.id != this.ownID) { + if (member.id !== this.ownID) { memberID = member.id; memberName = member.name; } } const messages = new Array(); for (const message of chat.messages) { - if (message.author.id == this.ownID) { + if (message.author.id === this.ownID) { messages.push(new Chatmessage(message.content, message.createdAt, true)); } else { messages.push(new Chatmessage(message.content, message.createdAt, false)); @@ -192,14 +196,14 @@ export class ChatService { let memberId: number; let memberName: string; for (const member of pResponse.data.getChat.members) { - if (member.id != this.ownID) { + if (member.id !== this.ownID) { memberId = member.id; memberName = member.name; } } const messages = new Array(); for (const message of pResponse.data.getChat.messages) { - if (message.author.id == this.ownID) { + if (message.author.id === this.ownID) { messages.push(new Chatmessage(message.content, message.createdAt, true)); } else { messages.push(new Chatmessage(message.content, message.createdAt, false)); diff --git a/src/app/services/feed/feed.service.ts b/src/app/services/feed/feed.service.ts index 19fb90f..3cd3adb 100644 --- a/src/app/services/feed/feed.service.ts +++ b/src/app/services/feed/feed.service.ts @@ -117,29 +117,41 @@ export class FeedService { return this.http.post(url, this.getBodyForGetAllPostsByUserId(userId)); } - /*getBodyForGetAllPostsByUserId(pUserId: number) { - const body = {query: `query ($userId: ID) { - getPosts (first: 1000, offset: 0, userId: $userId) {id, content, htmlContent, upvotes, downvotes, userVote, author{name, handle, id}, createdAt} - }`, variables: { - userId: pUserId - }}; - return body - }*/ - getBodyForGetAllPostsByUserId(pUserId: number) { const body = {query: `query ($userId: ID!) { - getPosts (first: 1000, offset: 0) {id, content, htmlContent, upvotes, downvotes, userVote(userId: $userId), author{name, handle, id}, createdAt} + getPosts (first: 1000, offset: 0) { + id, + content, + htmlContent, + upvotes, + downvotes, + userVote(userId: $userId), + author{ + name, + handle, + id}, + createdAt} }`, variables: { userId: pUserId }}; - return body + return body; } getBodyForGetAllPosts() { const body = {query: `query { - getPosts (first: 1000, offset: 0) {id, content, htmlContent, upvotes, downvotes, author{name, handle, id}, createdAt} + getPosts (first: 1000, offset: 0) { + id, + content, + htmlContent, + upvotes, + downvotes, + author{ + name, + handle, + id}, + createdAt} }` - } - return body + }; + return body; } public renderAllPosts(pResponse: any): Array { diff --git a/src/app/services/login/login.service.ts b/src/app/services/login/login.service.ts index 2c73a59..c61156c 100644 --- a/src/app/services/login/login.service.ts +++ b/src/app/services/login/login.service.ts @@ -33,7 +33,7 @@ export class LoginService { this.router.navigateByUrl(''); } - public updateUserInfo(response : any){ + public updateUserInfo(response: any) { const user: User = new User(); user.loggedIn = true; user.userID = response.data.login.id; @@ -47,8 +47,8 @@ export class LoginService { user.chatIDs = response.data.login.chats; user.requestIDs = response.data.login.requests; - this.data.changeUserInfo(user) - + this.data.changeUserInfo(user); + } public buildJson(login: Login): any { diff --git a/src/app/services/register/register.service.ts b/src/app/services/register/register.service.ts index 1f04c25..0e2ef11 100644 --- a/src/app/services/register/register.service.ts +++ b/src/app/services/register/register.service.ts @@ -56,7 +56,16 @@ export class RegisterService { public buildJson(registration: Registration): any { const body = {query: `mutation($username: String, $email: String, $pwHash: String) { - register(username: $username, email: $email, passwordHash: $pwHash) {id, name, handle, points, level, friends{id}, groups{id},chats{id}} + register(username: $username, email: $email, passwordHash: $pwHash) { + id, + name, + handle, + points, + level, + friends{id}, + groups{id}, + chats{id} + } }`, variables: { email: registration.email, pwHash: registration.passwordHash, diff --git a/src/tslint.json b/src/tslint.json index 25509b1..cc64294 100644 --- a/src/tslint.json +++ b/src/tslint.json @@ -10,7 +10,6 @@ "component-selector": [ true, "element", - "app", "kebab-case" ], "indent": { From 481de04ee5944374dd23f6abfa976e1a055b6c68 Mon Sep 17 00:00:00 2001 From: Trivernis Date: Thu, 19 Dec 2019 20:11:22 +0100 Subject: [PATCH 8/9] Jenkins config dependencies - added extra task to install dependencies for time tracking --- Jenkinsfile | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 5c53f8a..6f7ffd3 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -2,21 +2,28 @@ pipeline { agent any stages { - stage('Stylecheck') { - steps { - echo 'Checking Style...' - nodejs(nodeJSInstallationName: 'Node 12.x') { - sh 'npm i' - sh 'npm i typescript tslint' - sh 'tslint "src/**/*.ts"' + stage('Dependencies') { + steps { + echo 'Installing Dependencies...' + nodejs(nodeJSInstallationName: 'Node 12.x') { + sh 'npm i @angular/cli' + sh 'npm i' + sh 'tslint "src/**/*.ts"' + } } } + stage('Stylecheck') { + steps { + echo 'Checking Style...' + nodejs(nodeJSInstallationName: 'Node 12.x') { + sh 'tslint "src/**/*.ts"' + } + } } stage('Build') { steps { echo 'Building...' nodejs(nodeJSInstallationName: 'Node 12.x') { - sh 'npm i @angular/cli' sh 'ng build --prod' } } From bd310ab287fcbe73d5828933a2047339d3e65eb5 Mon Sep 17 00:00:00 2001 From: Trivernis Date: Fri, 20 Dec 2019 23:52:12 +0100 Subject: [PATCH 9/9] Jenkings config artifact - added the build output as an artifact - removed tslint call in Dependencies stage --- Jenkinsfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 6f7ffd3..0f6d0ad 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -8,7 +8,6 @@ pipeline { nodejs(nodeJSInstallationName: 'Node 12.x') { sh 'npm i @angular/cli' sh 'npm i' - sh 'tslint "src/**/*.ts"' } } } @@ -26,6 +25,8 @@ pipeline { nodejs(nodeJSInstallationName: 'Node 12.x') { sh 'ng build --prod' } + sh '/bin/tar -zcvf greenvironment-frontend.tar.gz dist' + archiveArtifacts artifacts: 'greenvironment-frontend.tar.gz', fingerprint: true } } }