Skip to content
Snippets Groups Projects
Commit 5f19bc14 authored by FORESTIER Fabien's avatar FORESTIER Fabien
Browse files

Update CI/CD workflow and variable config handling

parent 43910796
Branches
Tags
No related merge requests found
Pipeline #
Showing
with 198 additions and 232 deletions
......@@ -4,39 +4,61 @@ stages:
build_development:
stage: build
tags:
- build
only:
- master
- development
script:
- export NODE_ENV=DEV
- docker-compose --project-name admin-gui-dev build --build-arg env=dev admin-gui
- export TAG=dev
- export APP_PORT=8090
- export CONFIG_FILE_PATH=./config/config.json
- docker-compose build --build-arg conf=dev admin-gui
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker-compose push
build_release:
stage: build
tags:
- build
only:
- tags
except:
- /^(?!master).+@/
script:
- export TAG=$(echo $CI_COMMIT_TAG | sed 's/v//g')
- export APP_PORT=8090
- export CONFIG_FILE_PATH=./config/config.json
- docker-compose build --build-arg conf=prod admin-gui
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker-compose push
deploy_development:
stage: deploy
only:
- master
- development
script:
- export NODE_ENV=DEV
- docker-compose --project-name admin-gui-dev up -d
- export TAG=dev
- export APP_PORT=8090
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker-compose pull
- export CONFIG_FILE_PATH=./config/config-dev.json
- docker-compose --project-name admin-gui-${TAG} up -d --force-recreate
environment:
name: development
# url:
build_staging:
stage: build
only:
- staging
script:
- export NODE_ENV=REC
- sed -i 's/DEV_/REC_/g' docker-compose.yml
- docker-compose --project-name admin-gui-rec build --build-arg env=rec admin-gui
deploy_staging:
stage: deploy
only:
- staging
- development
when: manual
script:
- export NODE_ENV=REC
- sed -i 's/DEV_/REC_/g' docker-compose.yml
- docker-compose --project-name admin-gui-rec up -d
- export TAG=staging
- export APP_PORT=8190
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- TAG=dev docker-compose pull
- docker tag $CI_REGISTRY/refonte-data/admin-gui:dev $CI_REGISTRY/refonte-data/admin-gui:${TAG}
- docker push $CI_REGISTRY/refonte-data/admin-gui:${TAG}
- export CONFIG_FILE_PATH=./config/config-rec.json
- docker-compose --project-name admin-gui-${TAG} up -d --force-recreate
environment:
name: staging
......@@ -9,10 +9,10 @@ RUN npm install
# Copy the project
COPY . /app
ARG env
ARG conf
# Building the Angular app /dist
RUN npm run build:${env}
RUN npm run build:${conf}
# Stage 1, based on Nginx, to have only the compiled app
FROM nginx
......
......@@ -23,33 +23,28 @@
"src/assets"
],
"styles": [
"src/styles.scss",
"src/styles.scss"
],
"scripts": []
},
"configurations": {
"development": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.dev.ts"
}
],
"optimization": true,
"optimization": false,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"sourceMap": true,
"extractCss": false,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true
"buildOptimizer": false,
"fileReplacements": []
},
"recette": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.rec.ts"
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
......
{
"organizations": {
"url": "https://kong-dev.alpha.grandlyon.com/organizations/"
},
"resources": {
"url": "https://kong-dev.alpha.grandlyon.com/resources/resources/"
}
}
\ No newline at end of file
{
"organizations": {
"url": "https://kong-rec.alpha.grandlyon.com/organizations/"
},
"resources": {
"url": "https://kong-rec.alpha.grandlyon.com/resources/resources/"
}
}
\ No newline at end of file
version: "2"
version: "3.1"
services:
admin-gui:
container_name: admin-gui-${NODE_ENV}
build:
context: ./
build: .
image: registry.alpha.grandlyon.com/refonte-data/admin-gui:${TAG}
volumes:
- ./nginx.conf.template:/etc/nginx/conf.d/default.conf
- ${CONFIG_FILE_PATH}:/usr/share/nginx/html/assets/config/config.json
ports:
- ${DEV_APP_PORT}:80
- ${APP_PORT}:80
restart: unless-stopped
\ No newline at end of file
......@@ -5,8 +5,8 @@
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"build:dev": "ng build --prod --configuration=development",
"build:rec": "ng build --prod --configuration=recette",
"build:dev": "node --max_old_space_size=4096 ./node_modules/@angular/cli/bin/ng build --configuration=development",
"build:prod": "node --max_old_space_size=4096 ./node_modules/@angular/cli/bin/ng build --configuration=production",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
......
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { NgModule, APP_INITIALIZER } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { AppComponent } from './app.component';
import { OrganizationsComponent } from './components/organizations/list/organizations.component';
import { OrganizationService } from './services/organization.service';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import { RouterModule } from '@angular/router';
import { MenuComponent } from './components/menu/menu.component';
import { AppRoutingModule } from './app.routing.module';
import { WelcomeComponent } from './components/welcome/welcome.component';
import { OrganizationDetailComponent } from './components/organizations/detail/organization-detail.component';
import { OrganizationFormComponent } from './components/organizations/edit/organization-form.component';
import { PaginatorComponent } from './components/paginator/paginator.component';
import { ResourcesComponent } from './components/resources/list/resources.component';
import { ResourceService } from './services/resource.service';
import { ResourceFormComponent } from './components/resources/edit/resource-form.component';
import { ResourceDetailComponent } from './components/resources/detail/resource-detail.component';
import { AppServices, AppConfigService } from './services';
import { AppComponents } from './components';
export function initAppConfig(appConfigService: AppConfigService) {
return (): Promise<any> => {
return new Promise((resolve, reject) => {
appConfigService.load();
resolve();
});
};
}
@NgModule({
declarations: [
AppComponent,
OrganizationsComponent,
PaginatorComponent,
OrganizationDetailComponent,
OrganizationFormComponent,
MenuComponent,
WelcomeComponent,
ResourcesComponent,
ResourceFormComponent,
ResourceDetailComponent,
...AppComponents,
],
imports: [
AppRoutingModule,
......@@ -41,8 +33,13 @@ import { ResourceDetailComponent } from './components/resources/detail/resource-
ReactiveFormsModule,
],
providers: [
OrganizationService,
ResourceService,
...AppServices,
{
provide: APP_INITIALIZER,
useFactory: initAppConfig,
deps: [AppConfigService],
multi: true,
},
],
bootstrap: [AppComponent]
})
......
import { MenuComponent } from './menu/menu.component';
import { OrganizationDetailComponent } from './organizations/detail/organization-detail.component';
import { OrganizationFormComponent } from './organizations/edit/organization-form.component';
import { OrganizationsComponent } from './organizations/list/organizations.component';
import { PaginatorComponent } from './paginator/paginator.component';
import { ResourceDetailComponent } from './resources/detail/resource-detail.component';
import { ResourceFormComponent } from './resources/edit/resource-form.component';
import { ResourcesComponent } from './resources/list/resources.component';
import { WelcomeComponent } from './welcome/welcome.component';
export {
MenuComponent,
OrganizationDetailComponent,
OrganizationFormComponent,
OrganizationsComponent,
PaginatorComponent,
ResourceDetailComponent,
ResourceFormComponent,
ResourcesComponent,
WelcomeComponent,
};
// tslint:disable-next-line:variable-name
export const AppComponents = [
MenuComponent,
OrganizationDetailComponent,
OrganizationFormComponent,
OrganizationsComponent,
PaginatorComponent,
ResourceDetailComponent,
ResourceFormComponent,
ResourcesComponent,
WelcomeComponent,
];
......@@ -56,6 +56,7 @@ export class OrganizationsComponent implements OnInit {
private search() {
this.organizationsService.getOrganizations()
.subscribe((items: OrganizationRO) => {
console.log(items);
this.organizations = items.organizations;
this.totalElement = items.totalCount;
......
import { Injectable } from '@angular/core';
export class AppConfig {
organizations: {
url: string;
};
resources: {
url: string;
};
}
export let APP_CONFIG: AppConfig;
@Injectable()
export class AppConfigService {
constructor() { }
public load() {
return new Promise((resolve, reject) => {
const conf = new AppConfig();
APP_CONFIG = Object.assign(conf, window['adminGuiEnvConfig']);
resolve();
});
}
}
import { AppConfigService } from './app-config.service';
import { OrganizationService } from './organization.service';
import { ResourceService } from './resource.service';
export {
AppConfigService,
OrganizationService,
ResourceService,
};
// tslint:disable-next-line:variable-name
export const AppServices = [
AppConfigService,
OrganizationService,
ResourceService,
];
......@@ -3,7 +3,8 @@ import { Observable , Subject } from 'rxjs';
import { map } from 'rxjs/operators';
import { HttpClient } from '@angular/common/http';
import { Organization, IOrganization, OrganizationRO } from '../models/organization.model';
import { environment } from 'src/environments/environment';
import { APP_CONFIG } from './app-config.service';
@Injectable()
export class OrganizationService {
......@@ -30,7 +31,7 @@ export class OrganizationService {
query += '&offset=' + (this.pageNumber ? (this.pageNumber - 1) * this.limit : 0);
query += '&sort_by=' + this.sortOptions.value + '.' + this.sortOptions.order;
return this._httpClient.get<IOrganization[]>(environment.organizations.url + query, { observe: 'response' }).pipe(
return this._httpClient.get<IOrganization[]>(APP_CONFIG.organizations.url + query, { observe: 'response' }).pipe(
map((response) => {
const totalCount = response.headers.get('Content-Range');
const organizations = [];
......@@ -42,7 +43,7 @@ export class OrganizationService {
}
findById(id): Observable<Organization> {
return this._httpClient.get<IOrganization>(environment.organizations.url + id).pipe(
return this._httpClient.get<IOrganization>(APP_CONFIG.organizations.url + id).pipe(
map((response) => {
return new Organization(response);
}
......@@ -50,12 +51,12 @@ export class OrganizationService {
}
delete(id) {
return this._httpClient.delete(environment.organizations.url + id);
return this._httpClient.delete(APP_CONFIG.organizations.url + id);
}
replaceOrCreate(data: Organization): Observable<Organization> {
if (data.id) {
return this._httpClient.put<IOrganization>(environment.organizations.url + data.id, data).pipe(
return this._httpClient.put<IOrganization>(APP_CONFIG.organizations.url + data.id, data).pipe(
map((response) => {
return new Organization(response);
}
......@@ -65,7 +66,7 @@ export class OrganizationService {
data.links.forEach((link) => {
delete link.id;
});
return this._httpClient.post<IOrganization>(environment.organizations.url, data).pipe(
return this._httpClient.post<IOrganization>(APP_CONFIG.organizations.url, data).pipe(
map((response) => {
return new Organization(response);
}
......
......@@ -3,7 +3,7 @@ import { Observable , Subject } from 'rxjs';
import { map } from 'rxjs/operators';
import { HttpClient } from '@angular/common/http';
import { Resource, IResource, ResourceRO } from '../models/resource.model';
import { environment } from 'src/environments/environment';
import { APP_CONFIG } from './app-config.service';
@Injectable()
export class ResourceService {
......@@ -30,7 +30,7 @@ export class ResourceService {
query += '&offset=' + (this.pageNumber ? (this.pageNumber - 1) * this.limit : 0);
query += '&sort_by=' + this.sortOptions.value + '.' + this.sortOptions.order;
return this._httpClient.get<IResource[]>(environment.resources.url + query, { observe: 'response' }).pipe(
return this._httpClient.get<IResource[]>(APP_CONFIG.resources.url + query, { observe: 'response' }).pipe(
map((response) => {
const totalCount = response.headers.get('Content-Range');
const resources = [];
......@@ -42,7 +42,7 @@ export class ResourceService {
}
findById(id): Observable<Resource> {
return this._httpClient.get<IResource>(environment.resources.url + id).pipe(
return this._httpClient.get<IResource>(APP_CONFIG.resources.url + id).pipe(
map((response) => {
return new Resource(response);
}
......@@ -50,18 +50,18 @@ export class ResourceService {
}
delete(id) {
return this._httpClient.delete(environment.resources.url + id);
return this._httpClient.delete(APP_CONFIG.resources.url + id);
}
replaceOrCreate(data): Observable<Resource> {
if (data.id) {
return this._httpClient.put<IResource>(environment.resources.url + data.id, data).pipe(
return this._httpClient.put<IResource>(APP_CONFIG.resources.url + data.id, data).pipe(
map((response) => {
return new Resource(response);
}
));
}
return this._httpClient.post<IResource>(environment.resources.url, data).pipe(
return this._httpClient.post<IResource>(APP_CONFIG.resources.url, data).pipe(
map((response) => {
return new Resource(response);
}
......
{
"organizations": {
"url": "https://kong-dev.alpha.grandlyon.com/organizations/"
},
"resources": {
"url": "https://kong-dev.alpha.grandlyon.com/resources/resources/"
}
}
\ No newline at end of file
{
"swagger": "2.0",
"info": {
"description": "The actors API description",
"version": "1.0",
"title": "Actors example"
},
"basePath": "/localhost:3001",
"tags": [],
"schemes": ["http"],
"paths": {
"/organizations": {
"get": {
"summary": "Get all organizations",
"responses": {
"200": {
"description": ""
}
},
"tags": ["organizations"],
"produces": ["application/json"],
"consumes": ["application/json"]
},
"post": {
"summary": "Create one organization",
"parameters": [{
"name": "Organization",
"required": true,
"in": "body",
"schema": {
"$ref": "#/definitions/Organization"
}
}],
"responses": {
"201": {
"description": "The record has been successfully created."
}
},
"tags": ["organizations"],
"produces": ["application/json"],
"consumes": ["application/json"]
}
}
},
"definitions": {
"Organization": {
"type": "object",
"properties": {
"id": {
"type": "number"
},
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"website": {
"type": "string"
},
"logo": {
"type": "string"
}
},
"required": ["id", "name", "description"]
}
}
}
\ No newline at end of file
{
"swagger": "2.0",
"info": {
"description": "The actors API description",
"version": "1.0",
"title": "Actors example"
},
"basePath": "/localhost:3001",
"tags": [],
"schemes": ["http"],
"paths": {
"/organizations": {
"get": {
"summary": "Get all organizations",
"responses": {
"200": {
"description": ""
}
},
"tags": ["organizations"],
"produces": ["application/json"],
"consumes": ["application/json"]
},
"post": {
"summary": "Create one organization",
"parameters": [{
"name": "Organization",
"required": true,
"in": "body",
"schema": {
"$ref": "#/definitions/Organization"
}
}],
"responses": {
"201": {
"description": "The record has been successfully created."
}
},
"tags": ["organizations"],
"produces": ["application/json"],
"consumes": ["application/json"]
}
}
},
"definitions": {
"Organization": {
"type": "object",
"properties": {
"id": {
"type": "number"
},
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"website": {
"type": "string"
},
"logo": {
"type": "string"
}
},
"required": ["id", "name", "description"]
}
}
}
\ No newline at end of file
......@@ -3,11 +3,4 @@ const kongBaseUrl = 'https://kong-dev.alpha.grandlyon.com';
export const environment = {
production: true,
organizations: {
url: kongBaseUrl + '/organizations/',
},
resources: {
url: kongBaseUrl + '/resources/',
},
};
const kongBaseUrl = 'https://kong-rec.alpha.grandlyon.com';
export const environment = {
production: true,
organizations: {
url: kongBaseUrl + '/organizations/',
},
resources: {
url: kongBaseUrl + '/resources/',
},
};
......@@ -4,12 +4,5 @@
export const environment = {
production: false,
organizations: {
url: 'http://localhost:3000/organizations/',
},
resources: {
url: 'http://localhost:3003/resources/',
},
};
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment