Skip to content

Commit

Permalink
Integrate docker compose (#27062)
Browse files Browse the repository at this point in the history
  • Loading branch information
mshima authored Sep 14, 2024
1 parent 4827440 commit 55d8df8
Show file tree
Hide file tree
Showing 57 changed files with 638 additions and 95 deletions.
4 changes: 4 additions & 0 deletions .blueprint/cli/commands.mts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ const defaultCommands = {
desc: 'Generate a test sample',
blueprint: '@jhipster/jhipster-dev',
},
'github-build-matrix': {
desc: 'Generate a matrix for GitHub Actions',
blueprint: '@jhipster/jhipster-dev',
},
'update-vscode': {
desc: 'Update generator-jhipster vscode files',
blueprint: '@jhipster/jhipster-dev',
Expand Down
14 changes: 14 additions & 0 deletions .blueprint/github-build-matrix/command.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import type { JHipsterCommandDefinition } from '../../generators/index.js';

export default {
configs: {
workflow: {
description: 'Workflow',
argument: {
type: String,
},
scope: 'generator',
choices: ['testcontainers'],
},
},
} as const satisfies JHipsterCommandDefinition;
22 changes: 22 additions & 0 deletions .blueprint/github-build-matrix/generator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import BaseGenerator from '../../generators/base/index.js';
import { setGithubTaskOutput } from '../../lib/testing/index.js';
import { convertToGitHubMatrix } from './support/github-ci-matrix.js';
import { dockerComposeMatrix } from './samples/docker-compose-integration.js';

export default class extends BaseGenerator {
workflow;

constructor(args, opts, features) {
super(args, opts, { queueCommandTasks: true, ...features, jhipsterBootstrap: false });
}

get [BaseGenerator.WRITING]() {
return this.asWritingTaskGroup({
async buildMatrix() {
if (this.workflow === 'docker-compose-integration') {
setGithubTaskOutput('matrix', JSON.stringify(convertToGitHubMatrix(dockerComposeMatrix), null, 2));
}
},
});
}
}
2 changes: 2 additions & 0 deletions .blueprint/github-build-matrix/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default } from './generator.js';
export { default as command } from './command.js';
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { extendMatrix, fromMatrix } from '../../../lib/testing/index.js';
import { convertOptionsToJDL } from '../support/jdl.js';

// Supported containers: https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection
export const dockerComposeMatrix = Object.fromEntries(
[
...Object.entries(
extendMatrix(
{
...fromMatrix({
databaseType: ['cassandra', 'mongodb', 'neo4j'],
reactive: [undefined, true],
}),
...extendMatrix(
fromMatrix({
prodDatabaseType: ['postgresql', 'mysql', 'mariadb'],
reactive: [undefined],
}),
{ cacheProvider: ['no', 'redis', 'memcached'] },
),
...fromMatrix({
prodDatabaseType: ['postgresql', 'mysql', 'mariadb'],
reactive: [true],
}),
},
{
buildTool: ['maven', 'gradle'],
searchEngine: [undefined, 'elasticsearch'],
authenticationType: ['jwt', 'oauth2'],
serviceDiscoveryType: [undefined, 'eureka', 'consul'],
messageBroker: [undefined, 'kafka'],
},
),
),
['h2', { devDatabaseType: 'h2Disk' }],
].map(([key, value]) => [
key,
{
'cmd-e2e': 'npm run ci:e2e:dev',
args: 'jdl',
jdl: convertOptionsToJDL(value),
},
]),
);
13 changes: 13 additions & 0 deletions .blueprint/github-build-matrix/support/cli-args.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { kebabCase } from 'lodash-es';

export const convertToCliArgs = (opts: Record<string, any>): string => {
return Object.entries(opts)
.map(([key, value]) => {
key = kebabCase(key);
if (typeof value === 'boolean') {
return `--${value ? '' : 'no-'}${key}`;
}
return `--${key} ${value}`;
})
.join(' ');
};
38 changes: 38 additions & 0 deletions .blueprint/github-build-matrix/support/github-ci-matrix.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { RECOMMENDED_JAVA_VERSION, RECOMMENDED_NODE_VERSION } from '../../../generators/index.js';

type GitHubMatrix = {
os: string;
'node-version': string;
'java-version': string;
'default-environment': string;
'job-name': string;
args: string;
};

type GitHubMatrixOutput = {
include: GitHubMatrix[];
};

export const defaultEnvironment = {
os: 'ubuntu-latest',
'node-version': RECOMMENDED_NODE_VERSION,
'java-version': RECOMMENDED_JAVA_VERSION,
'default-environment': 'prod',
};

export const defaultEnvironmentMatrix = {
os: ['ubuntu-latest'],
'node-version': [RECOMMENDED_NODE_VERSION],
'java-version': [RECOMMENDED_JAVA_VERSION],
'default-environment': ['prod'],
};

export const convertToGitHubMatrix = (matrix: Record<string, any>): GitHubMatrixOutput => {
return {
include: Object.entries(matrix).map(([key, value]) => ({
'job-name': key,
...defaultEnvironment,
...value,
})),
};
};
11 changes: 11 additions & 0 deletions .blueprint/github-build-matrix/support/jdl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export const convertOptionsToJDL = (opts: Record<string, any>): string => {
return `application {
config {
testFrameworks [cypress]
${Object.entries(opts)
.filter(([_key, value]) => value !== undefined)
.map(([key, value]) => ` ${key} ${value}`)
.join('\n')}
}
}`;
};
109 changes: 109 additions & 0 deletions .github/workflows/docker-compose-integration.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#
# Copyright 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.
#

name: Testcontainers Integration
concurrency:
# Group PRs by head_ref, push to main branch by commit id, and others branch by ref.
group: ${{ github.workflow }}-${{ github.head_ref || (github.ref == 'refs/heads/main' && github.sha) || github.ref }}
cancel-in-progress: true
on:
pull_request:
types: [closed, opened, synchronize, reopened]
branches:
- '*'
jobs:
build-matrix:
runs-on: ubuntu-20.04
if: >-
contains(github.event.pull_request.labels.*.name, 'pr: docker-compose integration')
outputs:
matrix: ${{ steps.build.outputs.matrix }}
empty-matrix: ${{ steps.build.outputs.empty-matrix }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 1
- uses: actions/setup-node@v4
with:
node-version: '20'
- run: npm ci --ignore-scripts
- id: build
run: bin/jhipster.cjs github-build-matrix docker-compose-integration
applications:
name: ${{ matrix.job-name }}
needs: build-matrix
runs-on: ${{ matrix.os }}
defaults:
run:
working-directory: ${{ github.workspace }}/app
timeout-minutes: 40
strategy:
fail-fast: false
matrix: ${{fromJson(needs.build-matrix.outputs.matrix)}}
steps:
#----------------------------------------------------------------------
# Install all tools and check configuration
#----------------------------------------------------------------------
- name: 'SETUP: Checkout generator-jhipster'
uses: actions/checkout@v4
with:
path: generator-jhipster
fetch-depth: 2
- uses: jhipster/actions/setup-runner@v0
with:
node-version: ${{ matrix.node-version }}
java-version: ${{ matrix.java-version }}
npm-version: ${{ matrix.npm-version }}
maven-cache: true
gradle-cache: ${{ matrix.gradle-cache }}
binary-dir: ${{ github.workspace }}/generator-jhipster/bin
- run: npm ci --ignore-scripts
working-directory: ${{ github.workspace }}/generator-jhipster
- uses: jhipster/actions/build-jhipster-bom@v0
with:
jhipster-bom-ref: main
- name: Generate project
run: jhipster.cjs ${{ matrix.args }} --defaults
env:
JHIPSTER_DEPENDENCIES_VERSION: 0.0.0-CICD
JHI_SKIP_JHIPSTER_DEPENDENCIES: true
JHI_PROFILE: ${{ matrix.default-environment }}
JHI_JDL: ${{ matrix.jdl }}
- run: jhipster.cjs info
- run: ${{ matrix.cmd-e2e }}
id: e2e
- name: Upload cypress screenshots
uses: actions/upload-artifact@v4
if: always() && steps.e2e.outcome == 'failure'
with:
name: screenshots-${{ matrix.name }}
path: ${{ github.workspace }}app//*/cypress/screenshots
check-workflow:
permissions:
contents: none
runs-on: ubuntu-latest
needs: [applications]
if: always()
steps:
- run: |
echo '${{ toJSON(needs) }}'
if [ 'skipped' == '${{ needs.applications.result }}' ] || [ 'success' == '${{ needs.applications.result }}' ] || [ 'closed' == '${{ github.event.action }}' ]; then
exit 0
fi
exit 1
2 changes: 2 additions & 0 deletions .github/workflows/docker-image-publish-github-registry.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ on:
tags:
- 'v*.*.*'

env:
FORCE_COLOR: 1
jobs:
build:
runs-on: ubuntu-20.04
Expand Down
14 changes: 7 additions & 7 deletions generators/app/__snapshots__/generator.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Options:
--force-install Fail on install dependencies error (default: false)
--ask-answered Show prompts for already configured options (default: false)
--base-name <value> Application base name
--skip-jhipster-dependencies Don't write jhipster dependencies to package.json.
--skip-jhipster-dependencies Don't write jhipster dependencies to package.json. (env: JHI_SKIP_JHIPSTER_DEPENDENCIES)
--creation-timestamp <value> Project creation timestamp (used for reproducible builds)
--jdl-store <value> JDL store
--prettier-tab-width <value> Default tab width for prettier
Expand Down Expand Up @@ -287,7 +287,7 @@ exports[`generator - app with default config should match snapshot 1`] = `
"defaultPackaging": "jar",
"devDatabaseExtraOptions": "",
"devDatabaseName": "jhipster",
"devDatabasePassword": "",
"devDatabasePassword": "password",
"devDatabaseType": "postgresql",
"devDatabaseTypeH2Any": false,
"devDatabaseTypeH2Disk": false,
Expand Down Expand Up @@ -741,7 +741,7 @@ exports[`generator - app with default config should match snapshot 1`] = `
},
"prodDatabaseExtraOptions": "",
"prodDatabaseName": "jhipster",
"prodDatabasePassword": "",
"prodDatabasePassword": "password",
"prodDatabaseType": "postgresql",
"prodDatabaseTypeMariadb": false,
"prodDatabaseTypeMssql": false,
Expand Down Expand Up @@ -901,7 +901,7 @@ exports[`generator - app with gateway should match snapshot 1`] = `
"defaultPackaging": "jar",
"devDatabaseExtraOptions": "",
"devDatabaseName": "jhipster",
"devDatabasePassword": "",
"devDatabasePassword": "password",
"devDatabaseType": "postgresql",
"devDatabaseTypeH2Any": false,
"devDatabaseTypeH2Disk": false,
Expand Down Expand Up @@ -1351,7 +1351,7 @@ exports[`generator - app with gateway should match snapshot 1`] = `
},
"prodDatabaseExtraOptions": "",
"prodDatabaseName": "jhipster",
"prodDatabasePassword": "",
"prodDatabasePassword": "password",
"prodDatabaseType": "postgresql",
"prodDatabaseTypeMariadb": false,
"prodDatabaseTypeMssql": false,
Expand Down Expand Up @@ -1510,7 +1510,7 @@ exports[`generator - app with microservice should match snapshot 1`] = `
"defaultPackaging": "jar",
"devDatabaseExtraOptions": "",
"devDatabaseName": "jhipster",
"devDatabasePassword": "",
"devDatabasePassword": "password",
"devDatabaseType": "postgresql",
"devDatabaseTypeH2Any": false,
"devDatabaseTypeH2Disk": false,
Expand Down Expand Up @@ -1907,7 +1907,7 @@ exports[`generator - app with microservice should match snapshot 1`] = `
},
"prodDatabaseExtraOptions": "",
"prodDatabaseName": "jhipster",
"prodDatabasePassword": "",
"prodDatabasePassword": "password",
"prodDatabaseType": "postgresql",
"prodDatabaseTypeMariadb": false,
"prodDatabaseTypeMssql": false,
Expand Down
7 changes: 7 additions & 0 deletions generators/base/support/secret.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,10 @@ export function createBase64Secret(len?: number | boolean, reproducible = false)
}
return Buffer.from(createSecret(len)).toString('base64');
}

/**
* Create a strong secret from a timestamp and a base name
*/
export function createSafeSecret(timestamp: number, baseName: string) {
return Buffer.from(`${timestamp}-${baseName}`).toString('base64');
}
1 change: 1 addition & 0 deletions generators/bootstrap-application-base/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const command = {
skipJhipsterDependencies: {
description: "Don't write jhipster dependencies to package.json.",
type: Boolean,
env: 'JHI_SKIP_JHIPSTER_DEPENDENCIES',
scope: 'storage',
},
creationTimestamp: {
Expand Down
4 changes: 4 additions & 0 deletions generators/client/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ const command = {
},
clientTestFrameworks: {
description: 'Client test frameworks',
cli: {
type: Array,
hide: true,
},
prompt: ({ jhipsterConfigWithDefaults: config }) => ({
when: answers => [ANGULAR, REACT, VUE].includes(answers.clientFramework ?? config.clientFramework),
type: 'checkbox',
Expand Down
6 changes: 5 additions & 1 deletion generators/common/__snapshots__/generator.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,12 @@ sonar.exclusions = src/main/webapp/content/**/*.*, src/main/webapp/i18n/*.js, \\
target/classes/static/**/*.*
sonar.issue.ignore.multicriteria = \\
S1192,S125,S3437,S4502,S4684,S5145,UndocumentedApi
S6437,S1192,S125,S3437,S4502,S4684,S5145,UndocumentedApi
# Rule https://rules.sonarsource.com/java/RSPEC-6437 is ignored, hardcoded
# passwords are provided for development purposes
sonar.issue.ignore.multicriteria.S6437.resourceKey = src/main/resources/config/*
sonar.issue.ignore.multicriteria.S6437.ruleKey = java:S6437
# Rule https://rules.sonarsource.com/java/RSPEC-3437 is ignored, as a
# JPA-managed field cannot be transient
sonar.issue.ignore.multicriteria.S3437.resourceKey = src/main/java/**/*
Expand Down
Loading

0 comments on commit 55d8df8

Please sign in to comment.