Multi target build (checkpoint before futher refactor)
This commit is contained in:
parent
d4f5a1fff4
commit
385cb85309
15
src/bin/keycloakify/buildJars/buildJar.ts
Normal file
15
src/bin/keycloakify/buildJars/buildJar.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { assert, type Equals } from "tsafe/assert";
|
||||||
|
import { exclude } from "tsafe/exclude";
|
||||||
|
import type { KeycloakAccountV1Versions, KeycloakThemeAdditionalInfoExtensionVersions } from "./extensionVersions";
|
||||||
|
|
||||||
|
export async function buildJar(params: {
|
||||||
|
jarFileBasename: string;
|
||||||
|
keycloakAccountV1Version: KeycloakAccountV1Versions;
|
||||||
|
keycloakThemeAdditionalInfoExtensionVersion: KeycloakThemeAdditionalInfoExtensionVersions;
|
||||||
|
buildOptions: {
|
||||||
|
keycloakifyBuildDirPath: string;
|
||||||
|
};
|
||||||
|
}): Promise<void> {
|
||||||
|
child_process.execSync("mvn clean install", { "cwd": buildOptions.keycloakifyBuildDirPath });
|
||||||
|
// TODO: Implement
|
||||||
|
}
|
57
src/bin/keycloakify/buildJars/buildJars.ts
Normal file
57
src/bin/keycloakify/buildJars/buildJars.ts
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import { assert } from "tsafe/assert";
|
||||||
|
import { exclude } from "tsafe/exclude";
|
||||||
|
import { keycloakAccountV1Versions, keycloakThemeAdditionalInfoExtensionVersions } from "./extensionVersions";
|
||||||
|
import { getKeycloakVersionRangeForJar } from "./getKeycloakVersionRangeForJar";
|
||||||
|
import { buildJar } from "./buildJar";
|
||||||
|
|
||||||
|
export async function buildJars(params: {
|
||||||
|
doImplementAccountTheme: boolean;
|
||||||
|
buildOptions: {
|
||||||
|
keycloakifyBuildDirPath: string;
|
||||||
|
};
|
||||||
|
}): Promise<{ lastJarFileBasename: string }> {
|
||||||
|
const { doImplementAccountTheme, buildOptions } = params;
|
||||||
|
|
||||||
|
let lastJarFileBasename: string | undefined = undefined;
|
||||||
|
|
||||||
|
await Promise.all(
|
||||||
|
keycloakAccountV1Versions
|
||||||
|
.map(keycloakAccountV1Version =>
|
||||||
|
keycloakThemeAdditionalInfoExtensionVersions
|
||||||
|
.map(keycloakThemeAdditionalInfoExtensionVersion => {
|
||||||
|
const keycloakVersionRange = getKeycloakVersionRangeForJar({
|
||||||
|
doImplementAccountTheme,
|
||||||
|
keycloakAccountV1Version,
|
||||||
|
keycloakThemeAdditionalInfoExtensionVersion
|
||||||
|
});
|
||||||
|
|
||||||
|
if (keycloakVersionRange === undefined) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return { keycloakThemeAdditionalInfoExtensionVersion, keycloakVersionRange };
|
||||||
|
})
|
||||||
|
.filter(exclude(undefined))
|
||||||
|
.map(({ keycloakThemeAdditionalInfoExtensionVersion, keycloakVersionRange }) => {
|
||||||
|
const jarFileBasename = `keycloak-theme-for-kc-${keycloakVersionRange}.jar`;
|
||||||
|
|
||||||
|
lastJarFileBasename = jarFileBasename;
|
||||||
|
|
||||||
|
return { keycloakThemeAdditionalInfoExtensionVersion, jarFileBasename };
|
||||||
|
})
|
||||||
|
.map(({ keycloakThemeAdditionalInfoExtensionVersion, jarFileBasename }) =>
|
||||||
|
buildJar({
|
||||||
|
jarFileBasename,
|
||||||
|
keycloakAccountV1Version,
|
||||||
|
keycloakThemeAdditionalInfoExtensionVersion,
|
||||||
|
buildOptions
|
||||||
|
})
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.flat()
|
||||||
|
);
|
||||||
|
|
||||||
|
assert(lastJarFileBasename !== undefined);
|
||||||
|
|
||||||
|
return { lastJarFileBasename };
|
||||||
|
}
|
7
src/bin/keycloakify/buildJars/extensionVersions.ts
Normal file
7
src/bin/keycloakify/buildJars/extensionVersions.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
export const keycloakAccountV1Versions = [null, "0.3", "0.4"] as const;
|
||||||
|
|
||||||
|
export type KeycloakAccountV1Versions = (typeof keycloakAccountV1Versions)[number];
|
||||||
|
|
||||||
|
export const keycloakThemeAdditionalInfoExtensionVersions = [null, "0.1"] as const;
|
||||||
|
|
||||||
|
export type KeycloakThemeAdditionalInfoExtensionVersions = (typeof keycloakThemeAdditionalInfoExtensionVersions)[number];
|
@ -0,0 +1,37 @@
|
|||||||
|
import { assert, type Equals } from "tsafe/assert";
|
||||||
|
import type { KeycloakAccountV1Versions, KeycloakThemeAdditionalInfoExtensionVersions } from "./extensionVersions";
|
||||||
|
|
||||||
|
export function getKeycloakVersionRangeForJar(params: {
|
||||||
|
doImplementAccountTheme: boolean;
|
||||||
|
keycloakAccountV1Version: KeycloakAccountV1Versions;
|
||||||
|
keycloakThemeAdditionalInfoExtensionVersion: KeycloakThemeAdditionalInfoExtensionVersions;
|
||||||
|
}): string | undefined {
|
||||||
|
const { keycloakAccountV1Version, keycloakThemeAdditionalInfoExtensionVersion, doImplementAccountTheme } = params;
|
||||||
|
|
||||||
|
switch (keycloakAccountV1Version) {
|
||||||
|
case null:
|
||||||
|
switch (keycloakThemeAdditionalInfoExtensionVersion) {
|
||||||
|
case null:
|
||||||
|
return doImplementAccountTheme ? "21-and-below" : "21-and-below";
|
||||||
|
case "0.1":
|
||||||
|
return doImplementAccountTheme ? undefined : "22-and-above";
|
||||||
|
}
|
||||||
|
assert<Equals<typeof keycloakThemeAdditionalInfoExtensionVersion, never>>(false);
|
||||||
|
case "0.3":
|
||||||
|
switch (keycloakThemeAdditionalInfoExtensionVersion) {
|
||||||
|
case null:
|
||||||
|
return doImplementAccountTheme ? undefined : undefined;
|
||||||
|
case "0.1":
|
||||||
|
return doImplementAccountTheme ? "23" : undefined;
|
||||||
|
}
|
||||||
|
assert<Equals<typeof keycloakThemeAdditionalInfoExtensionVersion, never>>(false);
|
||||||
|
case "0.4":
|
||||||
|
switch (keycloakThemeAdditionalInfoExtensionVersion) {
|
||||||
|
case null:
|
||||||
|
return doImplementAccountTheme ? undefined : undefined;
|
||||||
|
case "0.1":
|
||||||
|
return doImplementAccountTheme ? "24-and-above" : undefined;
|
||||||
|
}
|
||||||
|
assert<Equals<typeof keycloakThemeAdditionalInfoExtensionVersion, never>>(false);
|
||||||
|
}
|
||||||
|
}
|
1
src/bin/keycloakify/buildJars/index.ts
Normal file
1
src/bin/keycloakify/buildJars/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from "./buildJars";
|
@ -4,7 +4,6 @@ export type UserProvidedBuildOptions = {
|
|||||||
extraThemeProperties?: string[];
|
extraThemeProperties?: string[];
|
||||||
artifactId?: string;
|
artifactId?: string;
|
||||||
groupId?: string;
|
groupId?: string;
|
||||||
doCreateJar?: boolean;
|
|
||||||
loginThemeResourcesFromKeycloakVersion?: string;
|
loginThemeResourcesFromKeycloakVersion?: string;
|
||||||
reactAppBuildDirPath?: string;
|
reactAppBuildDirPath?: string;
|
||||||
keycloakifyBuildDirPath?: string;
|
keycloakifyBuildDirPath?: string;
|
||||||
@ -15,7 +14,6 @@ export const zUserProvidedBuildOptions = z.object({
|
|||||||
"extraThemeProperties": z.array(z.string()).optional(),
|
"extraThemeProperties": z.array(z.string()).optional(),
|
||||||
"artifactId": z.string().optional(),
|
"artifactId": z.string().optional(),
|
||||||
"groupId": z.string().optional(),
|
"groupId": z.string().optional(),
|
||||||
"doCreateJar": z.boolean().optional(),
|
|
||||||
"loginThemeResourcesFromKeycloakVersion": z.string().optional(),
|
"loginThemeResourcesFromKeycloakVersion": z.string().optional(),
|
||||||
"reactAppBuildDirPath": z.string().optional(),
|
"reactAppBuildDirPath": z.string().optional(),
|
||||||
"keycloakifyBuildDirPath": z.string().optional(),
|
"keycloakifyBuildDirPath": z.string().optional(),
|
||||||
|
@ -18,7 +18,6 @@ export type BuildOptions = {
|
|||||||
extraThemeProperties: string[] | undefined;
|
extraThemeProperties: string[] | undefined;
|
||||||
groupId: string;
|
groupId: string;
|
||||||
artifactId: string;
|
artifactId: string;
|
||||||
doCreateJar: boolean;
|
|
||||||
loginThemeResourcesFromKeycloakVersion: string;
|
loginThemeResourcesFromKeycloakVersion: string;
|
||||||
reactAppRootDirPath: string;
|
reactAppRootDirPath: string;
|
||||||
reactAppBuildDirPath: string;
|
reactAppBuildDirPath: string;
|
||||||
@ -115,7 +114,6 @@ export function readBuildOptions(params: { processArgv: string[] }): BuildOption
|
|||||||
);
|
);
|
||||||
})(),
|
})(),
|
||||||
"artifactId": process.env.KEYCLOAKIFY_ARTIFACT_ID ?? userProvidedBuildOptions.artifactId ?? `${themeNames[0]}-keycloak-theme`,
|
"artifactId": process.env.KEYCLOAKIFY_ARTIFACT_ID ?? userProvidedBuildOptions.artifactId ?? `${themeNames[0]}-keycloak-theme`,
|
||||||
"doCreateJar": userProvidedBuildOptions.doCreateJar ?? true,
|
|
||||||
"loginThemeResourcesFromKeycloakVersion": userProvidedBuildOptions.loginThemeResourcesFromKeycloakVersion ?? "24.0.4",
|
"loginThemeResourcesFromKeycloakVersion": userProvidedBuildOptions.loginThemeResourcesFromKeycloakVersion ?? "24.0.4",
|
||||||
reactAppRootDirPath,
|
reactAppRootDirPath,
|
||||||
reactAppBuildDirPath,
|
reactAppBuildDirPath,
|
||||||
|
@ -17,10 +17,11 @@ export type BuildOptionsLike = {
|
|||||||
generateStartKeycloakTestingContainer.basename = "start_keycloak_testing_container.sh";
|
generateStartKeycloakTestingContainer.basename = "start_keycloak_testing_container.sh";
|
||||||
|
|
||||||
const containerName = "keycloak-testing-container";
|
const containerName = "keycloak-testing-container";
|
||||||
|
const keycloakVersion = "24.0.4";
|
||||||
|
|
||||||
/** Files for being able to run a hot reload keycloak container */
|
/** Files for being able to run a hot reload keycloak container */
|
||||||
export function generateStartKeycloakTestingContainer(params: { jarFilePath: string; keycloakVersion: string; buildOptions: BuildOptionsLike }) {
|
export function generateStartKeycloakTestingContainer(params: { jarFilePath: string; buildOptions: BuildOptionsLike }) {
|
||||||
const { jarFilePath, keycloakVersion, buildOptions } = params;
|
const { jarFilePath, buildOptions } = params;
|
||||||
|
|
||||||
const themeRelativeDirPath = pathJoin("src", "main", "resources", "theme");
|
const themeRelativeDirPath = pathJoin("src", "main", "resources", "theme");
|
||||||
const themeDirPath = pathJoin(buildOptions.keycloakifyBuildDirPath, themeRelativeDirPath);
|
const themeDirPath = pathJoin(buildOptions.keycloakifyBuildDirPath, themeRelativeDirPath);
|
||||||
|
@ -31,7 +31,6 @@ export type BuildOptionsLike = {
|
|||||||
cacheDirPath: string;
|
cacheDirPath: string;
|
||||||
assetsDirPath: string;
|
assetsDirPath: string;
|
||||||
urlPathname: string | undefined;
|
urlPathname: string | undefined;
|
||||||
themeNames: string[];
|
|
||||||
npmWorkspaceRootDirPath: string;
|
npmWorkspaceRootDirPath: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -43,7 +42,7 @@ export async function generateTheme(params: {
|
|||||||
keycloakifySrcDirPath: string;
|
keycloakifySrcDirPath: string;
|
||||||
buildOptions: BuildOptionsLike;
|
buildOptions: BuildOptionsLike;
|
||||||
keycloakifyVersion: string;
|
keycloakifyVersion: string;
|
||||||
}): Promise<void> {
|
}): Promise<{ implementedThemeTypes: Record<ThemeType | "email", boolean> }> {
|
||||||
const { themeName, themeSrcDirPath, keycloakifySrcDirPath, buildOptions, keycloakifyVersion } = params;
|
const { themeName, themeSrcDirPath, keycloakifySrcDirPath, buildOptions, keycloakifyVersion } = params;
|
||||||
|
|
||||||
const getThemeTypeDirPath = (params: { themeType: ThemeType | "email" }) => {
|
const getThemeTypeDirPath = (params: { themeType: ThemeType | "email" }) => {
|
||||||
@ -231,14 +230,12 @@ export async function generateTheme(params: {
|
|||||||
|
|
||||||
const parsedKeycloakThemeJson: { themes: { name: string; types: string[] }[] } = { "themes": [] };
|
const parsedKeycloakThemeJson: { themes: { name: string; types: string[] }[] } = { "themes": [] };
|
||||||
|
|
||||||
buildOptions.themeNames.forEach(themeName =>
|
|
||||||
parsedKeycloakThemeJson.themes.push({
|
parsedKeycloakThemeJson.themes.push({
|
||||||
"name": themeName,
|
"name": themeName,
|
||||||
"types": Object.entries(implementedThemeTypes)
|
"types": Object.entries(implementedThemeTypes)
|
||||||
.filter(([, isImplemented]) => isImplemented)
|
.filter(([, isImplemented]) => isImplemented)
|
||||||
.map(([themeType]) => themeType)
|
.map(([themeType]) => themeType)
|
||||||
})
|
});
|
||||||
);
|
|
||||||
|
|
||||||
account_specific_extra_work: {
|
account_specific_extra_work: {
|
||||||
if (!implementedThemeTypes.account) {
|
if (!implementedThemeTypes.account) {
|
||||||
@ -269,4 +266,6 @@ export async function generateTheme(params: {
|
|||||||
|
|
||||||
fs.writeFileSync(keycloakThemeJsonFilePath, Buffer.from(JSON.stringify(parsedKeycloakThemeJson, null, 2), "utf8"));
|
fs.writeFileSync(keycloakThemeJsonFilePath, Buffer.from(JSON.stringify(parsedKeycloakThemeJson, null, 2), "utf8"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return { implementedThemeTypes };
|
||||||
}
|
}
|
||||||
|
12
src/bin/keycloakify/generateThemeVariants.ts
Normal file
12
src/bin/keycloakify/generateThemeVariants.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import type { ThemeType } from "../constants";
|
||||||
|
|
||||||
|
export function generateThemeVariations(params: {
|
||||||
|
themeName: string;
|
||||||
|
themeVariantName: string;
|
||||||
|
implementedThemeTypes: Record<ThemeType | "email", boolean>;
|
||||||
|
buildOptions: {
|
||||||
|
keycloakifyBuildDirPath: string;
|
||||||
|
};
|
||||||
|
}) {
|
||||||
|
//TODO: Implement
|
||||||
|
}
|
@ -10,6 +10,8 @@ import { getThemeSrcDirPath } from "../getThemeSrcDirPath";
|
|||||||
import { getThisCodebaseRootDirPath } from "../tools/getThisCodebaseRootDirPath";
|
import { getThisCodebaseRootDirPath } from "../tools/getThisCodebaseRootDirPath";
|
||||||
import { readThisNpmProjectVersion } from "../tools/readThisNpmProjectVersion";
|
import { readThisNpmProjectVersion } from "../tools/readThisNpmProjectVersion";
|
||||||
import { keycloakifyBuildOptionsForPostPostBuildScriptEnvName } from "../constants";
|
import { keycloakifyBuildOptionsForPostPostBuildScriptEnvName } from "../constants";
|
||||||
|
import { buildJars } from "./buildJars";
|
||||||
|
import { generateThemeVariations } from "./generateThemeVariants";
|
||||||
|
|
||||||
export async function main() {
|
export async function main() {
|
||||||
const buildOptions = readBuildOptions({
|
const buildOptions = readBuildOptions({
|
||||||
@ -21,14 +23,23 @@ export async function main() {
|
|||||||
|
|
||||||
const { themeSrcDirPath } = getThemeSrcDirPath({ "reactAppRootDirPath": buildOptions.reactAppRootDirPath });
|
const { themeSrcDirPath } = getThemeSrcDirPath({ "reactAppRootDirPath": buildOptions.reactAppRootDirPath });
|
||||||
|
|
||||||
for (const themeName of buildOptions.themeNames) {
|
const [themeName, ...themeVariantNames] = buildOptions.themeNames;
|
||||||
await generateTheme({
|
|
||||||
|
const { implementedThemeTypes } = await generateTheme({
|
||||||
themeName,
|
themeName,
|
||||||
themeSrcDirPath,
|
themeSrcDirPath,
|
||||||
"keycloakifySrcDirPath": pathJoin(getThisCodebaseRootDirPath(), "src"),
|
"keycloakifySrcDirPath": pathJoin(getThisCodebaseRootDirPath(), "src"),
|
||||||
"keycloakifyVersion": readThisNpmProjectVersion(),
|
"keycloakifyVersion": readThisNpmProjectVersion(),
|
||||||
buildOptions
|
buildOptions
|
||||||
});
|
});
|
||||||
|
|
||||||
|
for (const themeVariantName of themeVariantNames) {
|
||||||
|
generateThemeVariations({
|
||||||
|
themeName,
|
||||||
|
themeVariantName,
|
||||||
|
implementedThemeTypes,
|
||||||
|
buildOptions
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -37,16 +48,6 @@ export async function main() {
|
|||||||
fs.writeFileSync(pathJoin(buildOptions.keycloakifyBuildDirPath, "pom.xml"), Buffer.from(pomFileCode, "utf8"));
|
fs.writeFileSync(pathJoin(buildOptions.keycloakifyBuildDirPath, "pom.xml"), Buffer.from(pomFileCode, "utf8"));
|
||||||
}
|
}
|
||||||
|
|
||||||
const containerKeycloakVersion = "24.0.4";
|
|
||||||
|
|
||||||
const jarFilePath = pathJoin(buildOptions.keycloakifyBuildDirPath, "target", `${buildOptions.artifactId}-${buildOptions.themeVersion}.jar`);
|
|
||||||
|
|
||||||
generateStartKeycloakTestingContainer({
|
|
||||||
"keycloakVersion": containerKeycloakVersion,
|
|
||||||
jarFilePath,
|
|
||||||
buildOptions
|
|
||||||
});
|
|
||||||
|
|
||||||
fs.writeFileSync(pathJoin(buildOptions.keycloakifyBuildDirPath, ".gitignore"), Buffer.from("*", "utf8"));
|
fs.writeFileSync(pathJoin(buildOptions.keycloakifyBuildDirPath, ".gitignore"), Buffer.from("*", "utf8"));
|
||||||
|
|
||||||
run_post_build_script: {
|
run_post_build_script: {
|
||||||
@ -63,27 +64,24 @@ export async function main() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
create_jar: {
|
const { lastJarFileBasename } = await buildJars({
|
||||||
if (!buildOptions.doCreateJar) {
|
"doImplementAccountTheme": implementedThemeTypes.account,
|
||||||
break create_jar;
|
buildOptions
|
||||||
}
|
});
|
||||||
|
|
||||||
child_process.execSync("mvn clean install", { "cwd": buildOptions.keycloakifyBuildDirPath });
|
generateStartKeycloakTestingContainer({
|
||||||
}
|
"jarFilePath": pathJoin(buildOptions.keycloakifyBuildDirPath, lastJarFileBasename),
|
||||||
|
buildOptions
|
||||||
|
});
|
||||||
|
|
||||||
logger.log(
|
logger.log(
|
||||||
[
|
[
|
||||||
|
`✅ Your keycloak theme has been generated and bundled into .${pathSep}${pathJoin(
|
||||||
|
pathRelative(buildOptions.reactAppRootDirPath, buildOptions.keycloakifyBuildDirPath),
|
||||||
|
"keycloak-theme-for-kc-*.jar"
|
||||||
|
)}`,
|
||||||
"",
|
"",
|
||||||
...(!buildOptions.doCreateJar
|
`To test your theme locally you can spin up a Keycloak container image with the theme pre loaded by running:`,
|
||||||
? []
|
|
||||||
: [
|
|
||||||
`✅ Your keycloak theme has been generated and bundled into .${pathSep}${pathRelative(
|
|
||||||
buildOptions.reactAppRootDirPath,
|
|
||||||
jarFilePath
|
|
||||||
)} 🚀`
|
|
||||||
]),
|
|
||||||
"",
|
|
||||||
`To test your theme locally you can spin up a Keycloak ${containerKeycloakVersion} container image with the theme pre loaded by running:`,
|
|
||||||
"",
|
"",
|
||||||
`👉 $ .${pathSep}${pathRelative(
|
`👉 $ .${pathSep}${pathRelative(
|
||||||
buildOptions.reactAppRootDirPath,
|
buildOptions.reactAppRootDirPath,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user