Skip to content

Commit

Permalink
make deployments reproducible
Browse files Browse the repository at this point in the history
  • Loading branch information
mshima committed Sep 25, 2024
1 parent 0ae952e commit e062140
Show file tree
Hide file tree
Showing 13 changed files with 91 additions and 35 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/angular.yml
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ jobs:
env:
JHI_FOLDER_APP: ${{ github.workspace }}/app
JHIPSTER_DEPENDENCIES_VERSION: ${{ matrix.jhipster-bom-cicd-version }}
JHI_JWT_SECRET_KEY: ${{ matrix.jwt-secret-key }}
- run: jhipster.cjs info
#----------------------------------------------------------------------
# Detect changes against base commit
Expand All @@ -123,6 +124,7 @@ jobs:
# generate-sample uses JHI_FOLDER_APP to generate the application.
JHI_FOLDER_APP: ${{ github.workspace }}/base/app
JHIPSTER_DEPENDENCIES_VERSION: ${{ matrix.jhipster-bom-cicd-version }}
JHI_JWT_SECRET_KEY: ${{ matrix.jwt-secret-key }}
#----------------------------------------------------------------------
# Launch tests
#----------------------------------------------------------------------
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/react.yml
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ jobs:
env:
JHI_FOLDER_APP: ${{ github.workspace }}/app
JHIPSTER_DEPENDENCIES_VERSION: ${{ matrix.jhipster-bom-cicd-version }}
JHI_JWT_SECRET_KEY: ${{ matrix.jwt-secret-key }}
- run: jhipster.cjs info
#----------------------------------------------------------------------
# Detect changes against base commit
Expand All @@ -123,6 +124,7 @@ jobs:
# generate-sample uses JHI_FOLDER_APP to generate the application.
JHI_FOLDER_APP: ${{ github.workspace }}/base/app
JHIPSTER_DEPENDENCIES_VERSION: ${{ matrix.jhipster-bom-cicd-version }}
JHI_JWT_SECRET_KEY: ${{ matrix.jwt-secret-key }}
#----------------------------------------------------------------------
# Launch tests
#----------------------------------------------------------------------
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/vue.yml
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ jobs:
env:
JHI_FOLDER_APP: ${{ github.workspace }}/app
JHIPSTER_DEPENDENCIES_VERSION: ${{ matrix.jhipster-bom-cicd-version }}
JHI_JWT_SECRET_KEY: ${{ matrix.jwt-secret-key }}
- run: jhipster.cjs info
#----------------------------------------------------------------------
# Detect changes against base commit
Expand All @@ -123,6 +124,7 @@ jobs:
# generate-sample uses JHI_FOLDER_APP to generate the application.
JHI_FOLDER_APP: ${{ github.workspace }}/base/app
JHIPSTER_DEPENDENCIES_VERSION: ${{ matrix.jhipster-bom-cicd-version }}
JHI_JWT_SECRET_KEY: ${{ matrix.jwt-secret-key }}
#----------------------------------------------------------------------
# Launch tests
#----------------------------------------------------------------------
Expand Down
4 changes: 1 addition & 3 deletions generators/base-workspaces/internal/docker-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,7 @@ export function checkImages() {
* Generate Jwt Secret
*/
export function generateJwtSecret() {
if (this.jwtSecretKey === undefined) {
this.jwtSecretKey = this.jhipsterConfig.jwtSecretKey = createBase64Secret(this.options.reproducibleTests);
}
this.jwtSecretKey = this.jhipsterConfig.jwtSecretKey = this.jwtSecretKey ?? createBase64Secret(this.options.reproducibleTests);
}

/**
Expand Down
7 changes: 7 additions & 0 deletions generators/base/generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,13 @@ export default class JHipsterBaseBlueprintGenerator<TaskTypes extends BaseTaskTy
return this.delegateToBlueprint ? ({} as TaskGroupType) : tasksGetter();
}

/**
* Utility method to get typed objects for autocomplete.
*/
asAnyTaskGroup<const K extends string>(taskGroup: GenericTaskGroup<this, any, K>): GenericTaskGroup<any, any, K> {
return taskGroup;
}

/**
* Priority API stub for blueprints.
*
Expand Down
10 changes: 9 additions & 1 deletion generators/docker-compose/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,15 @@ const command: JHipsterCommandDefinition = {
description: 'Application folders',
},
},
options: {},
configs: {
jwtSecretKey: {
cli: {
type: String,
env: 'JHI_JWT_SECRET_KEY',
},
scope: 'generator',
},
},
};

export default command;
53 changes: 27 additions & 26 deletions generators/docker-compose/generator.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// @ts-nocheck
/**
* Copyright 2013-2024 the original author or authors from the JHipster project.
*
Expand Down Expand Up @@ -45,10 +44,11 @@ const { Options: DeploymentOptions } = deploymentOptions;
*/
export default class DockerComposeGenerator extends BaseWorkspacesGenerator {
existingDeployment;
jwtSecretKey!: string;

async beforeQueue() {
this.parseJHipsterArguments(command.arguments);
if (this.appsFolders?.length > 0) {
if (this.appsFolders && this.appsFolders.length > 0) {
this.jhipsterConfig.appsFolders = this.appsFolders;
}

Expand All @@ -59,7 +59,7 @@ export default class DockerComposeGenerator extends BaseWorkspacesGenerator {
}

get initializing() {
return {
return this.asInitializingTaskGroup({
sayHello() {
this.log.log(chalk.white(`${chalk.bold('🐳')} Welcome to the JHipster Docker Compose Sub-Generator ${chalk.bold('🐳')}`));
this.log.log(chalk.white(`Files will be generated in folder: ${chalk.yellow(this.destinationRoot())}`));
Expand All @@ -75,27 +75,27 @@ export default class DockerComposeGenerator extends BaseWorkspacesGenerator {
`);
}
},
};
});
}

get [BaseWorkspacesGenerator.INITIALIZING]() {
return this.delegateTasksToBlueprint(() => this.initializing);
}

get loading() {
return {
return this.asLoadingTaskGroup({
loadWorkspacesConfig() {
this.loadWorkspacesConfig();
},
};
});
}

get [BaseWorkspacesGenerator.LOADING]() {
return this.delegateTasksToBlueprint(() => this.loading);
}

get promptingWorkspaces() {
return {
return this.asAnyTaskGroup({
async askForMonitoring({ workspaces }) {
if (workspaces.existingWorkspaces && !this.options.askAnswered) return;

Expand All @@ -111,30 +111,31 @@ export default class DockerComposeGenerator extends BaseWorkspacesGenerator {

await this.askForServiceDiscovery({ applications });
},
};
});
}

get [BaseWorkspacesGenerator.PROMPTING_WORKSPACES]() {
return this.delegateTasksToBlueprint(() => this.promptingWorkspaces);
}

get configuringWorkspaces() {
return {
return this.asAnyTaskGroup({
configureBaseDeployment({ applications }) {
this.jhipsterConfig.jwtSecretKey = this.jhipsterConfig.jwtSecretKey ?? createBase64Secret(this.options.reproducibleTests);
this.jhipsterConfig.jwtSecretKey =
this.jhipsterConfig.jwtSecretKey ?? this.jwtSecretKey ?? createBase64Secret(this.options.reproducibleTests);
if (applications.some(app => app.serviceDiscoveryEureka)) {
this.jhipsterConfig.adminPassword = this.jhipsterConfig.adminPassword ?? 'admin';
}
},
};
});
}

get [BaseWorkspacesGenerator.CONFIGURING_WORKSPACES]() {
return this.delegateTasksToBlueprint(() => this.configuringWorkspaces);
}

get loadingWorkspaces() {
return {
return this.asAnyTaskGroup({
async loadBaseDeployment({ deployment }) {
deployment.jwtSecretKey = this.jhipsterConfig.jwtSecretKey;

Expand All @@ -143,27 +144,27 @@ export default class DockerComposeGenerator extends BaseWorkspacesGenerator {
loadPlatformConfig({ deployment }) {
this.loadDeploymentConfig({ deployment });
},
};
});
}

get [BaseWorkspacesGenerator.LOADING_WORKSPACES]() {
return this.delegateTasksToBlueprint(() => this.loadingWorkspaces);
}

get preparingWorkspaces() {
return {
return this.asAnyTaskGroup({
prepareDeployment({ deployment, applications }) {
this.prepareDeploymentDerivedProperties({ deployment, applications });
},
};
});
}

get [BaseWorkspacesGenerator.PREPARING_WORKSPACES]() {
return this.delegateTasksToBlueprint(() => this.preparingWorkspaces);
}

get default() {
return {
return this.asAnyTaskGroup({
async setAppsYaml({ workspaces, deployment, applications }) {
const faker = await createFaker();

Expand All @@ -174,7 +175,7 @@ export default class DockerComposeGenerator extends BaseWorkspacesGenerator {
const parentConfiguration = {};
const path = this.destinationPath(workspaces.directoryPath, appConfig.appFolder);
// Add application configuration
const yaml = parseYaml(this.fs.read(`${path}/src/main/docker/app.yml`));
const yaml = parseYaml(this.fs.read(`${path}/src/main/docker/app.yml`)!);
const yamlConfig = yaml.services.app;
if (yamlConfig.depends_on) {
yamlConfig.depends_on = Object.fromEntries(
Expand Down Expand Up @@ -253,15 +254,15 @@ export default class DockerComposeGenerator extends BaseWorkspacesGenerator {
if (appConfig.databaseTypeAny && !appConfig.prodDatabaseTypeOracle) {
const database = appConfig.databaseTypeSql ? appConfig.prodDatabaseType : appConfig.databaseType;
const relativePath = normalize(pathjs.relative(this.destinationRoot(), `${path}/src/main/docker`));
const databaseYaml = parseYaml(this.fs.read(`${path}/src/main/docker/${database}.yml`));
const databaseYaml = parseYaml(this.fs.read(`${path}/src/main/docker/${database}.yml`)!);
const databaseServiceName = `${lowercaseBaseName}-${database}`;
let databaseYamlConfig = databaseYaml.services[database];
// Don't export database ports
delete databaseYamlConfig.ports;

if (appConfig.databaseTypeCassandra) {
// migration service config
const cassandraMigrationYaml = parseYaml(this.fs.read(`${path}/src/main/docker/cassandra-migration.yml`));
const cassandraMigrationYaml = parseYaml(this.fs.read(`${path}/src/main/docker/cassandra-migration.yml`)!);
const cassandraMigrationConfig = cassandraMigrationYaml.services[`${database}-migration`];
cassandraMigrationConfig.build.context = relativePath;
const cqlFilesRelativePath = normalize(pathjs.relative(this.destinationRoot(), `${path}/src/main/resources/config/cql`));
Expand All @@ -275,7 +276,7 @@ export default class DockerComposeGenerator extends BaseWorkspacesGenerator {
}

if (appConfig.clusteredDb) {
const clusterDbYaml = parseYaml(this.fs.read(`${path}/src/main/docker/${database}-cluster.yml`));
const clusterDbYaml = parseYaml(this.fs.read(`${path}/src/main/docker/${database}-cluster.yml`)!);
const dbNodeConfig = clusterDbYaml.services[`${database}-node`];
dbNodeConfig.build.context = relativePath;
databaseYamlConfig = clusterDbYaml.services[database];
Expand All @@ -294,22 +295,22 @@ export default class DockerComposeGenerator extends BaseWorkspacesGenerator {
if (appConfig.searchEngineElasticsearch) {
// Add search engine configuration
const searchEngine = appConfig.searchEngine;
const searchEngineYaml = parseYaml(this.fs.read(`${path}/src/main/docker/${searchEngine}.yml`));
const searchEngineYaml = parseYaml(this.fs.read(`${path}/src/main/docker/${searchEngine}.yml`)!);
const searchEngineConfig = searchEngineYaml.services[searchEngine];
delete searchEngineConfig.ports;
parentConfiguration[`${lowercaseBaseName}-${searchEngine}`] = searchEngineConfig;
}
// Add Memcached support
if (appConfig.cacheProviderMemcached) {
const memcachedYaml = parseYaml(this.readDestination(`${path}/src/main/docker/memcached.yml`));
const memcachedYaml = parseYaml(this.readDestination(`${path}/src/main/docker/memcached.yml`)!.toString());
const memcachedConfig = memcachedYaml.services.memcached;
delete memcachedConfig.ports;
parentConfiguration[`${lowercaseBaseName}-memcached`] = memcachedConfig;
}

// Add Redis support
if (appConfig.cacheProviderRedis) {
const redisYaml = parseYaml(this.readDestination(`${path}/src/main/docker/redis.yml`));
const redisYaml = parseYaml(this.readDestination(`${path}/src/main/docker/redis.yml`)!.toString());
const redisConfig = redisYaml.services.redis;
delete redisConfig.ports;
parentConfiguration[`${lowercaseBaseName}-redis`] = redisConfig;
Expand All @@ -329,7 +330,7 @@ export default class DockerComposeGenerator extends BaseWorkspacesGenerator {
return yamlString;
});
},
};
});
}

get [BaseWorkspacesGenerator.DEFAULT]() {
Expand All @@ -345,7 +346,7 @@ export default class DockerComposeGenerator extends BaseWorkspacesGenerator {
}

get end() {
return {
return this.asAnyTaskGroup({
end({ workspaces, applications }) {
this.checkApplicationsDockerImages({ workspaces, applications });

Expand All @@ -361,7 +362,7 @@ export default class DockerComposeGenerator extends BaseWorkspacesGenerator {
this.log.log('\n');
}
},
};
});
}

get [BaseWorkspacesGenerator.END]() {
Expand Down
8 changes: 3 additions & 5 deletions generators/java/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { asCommand } from '../type-utils.js';
import type { JHipsterCommandDefinition } from '../../lib/command/types.js';

const command = {
options: {},
import: ['jhipster:java:bootstrap', 'jhipster:java:domain', 'jhipster:java:build-tool'],
};
} as const satisfies JHipsterCommandDefinition;

export type Coomand = typeof command;

export default asCommand(command);
export default command;
1 change: 1 addition & 0 deletions generators/kubernetes-helm/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export { default as command } from '../kubernetes/command.js';
export { default } from './generator.js';
1 change: 1 addition & 0 deletions generators/kubernetes-knative/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export { default as command } from '../kubernetes/command.js';
export { default } from './generator.js';
33 changes: 33 additions & 0 deletions generators/kubernetes/command.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* Copyright 2013-2024 the original author or authors from the JHipster project.
*
* This file is part of the JHipster project, see https://www.jhipster.tech/
* for more information.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import type { JHipsterCommandDefinition } from '../../lib/command/types.js';

const command = {
configs: {
jwtSecretKey: {
cli: {
type: String,
env: 'JHI_JWT_SECRET_KEY',
},
scope: 'generator',
},
},
} as const satisfies JHipsterCommandDefinition;

export default command;
1 change: 1 addition & 0 deletions generators/kubernetes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export { default as command } from './command.js';
export { default } from './generator.js';
2 changes: 2 additions & 0 deletions test-integration/scripts/99-write-matrix.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ writeFileSync(
...sample,
'skip-backend-tests': sample['skip-backend-tests'] ? 'true' : 'false',
'skip-frontend-tests': sample['skip-frontend-tests'] ? 'true' : 'false',
'jwt-secret-key':
'ZjY4MTM4YjI5YzMwZjhjYjI2OTNkNTRjMWQ5Y2Q0Y2YwOWNmZTE2NzRmYzU3NTMwM2NjOTE3MTllOTM3MWRkMzcyYTljMjVmNmQ0Y2MxOTUzODc0MDhhMTlkMDIxMzI2YzQzZDM2ZDE3MmQ3NjVkODk3OTVmYzljYTQyZDNmMTQ=',
};
});
} catch (error) {
Expand Down

0 comments on commit e062140

Please sign in to comment.