Newer
Older
/*
* Copyright (C) 2023 Das Land Schleswig-Holstein vertreten durch den
* Ministerpräsidenten des Landes Schleswig-Holstein
* Staatskanzlei
* Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
*
* Lizenziert unter der EUPL, Version 1.2 oder - sobald
* diese von der Europäischen Kommission genehmigt wurden -
* Folgeversionen der EUPL ("Lizenz");
* Sie dürfen dieses Werk ausschließlich gemäß
* dieser Lizenz nutzen.
* Eine Kopie der Lizenz finden Sie hier:
*
* https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
*
* Sofern nicht durch anwendbare Rechtsvorschriften
* gefordert oder in schriftlicher Form vereinbart, wird
* die unter der Lizenz verbreitete Software "so wie sie
* ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
* ausdrücklich oder stillschweigend - verbreitet.
* Die sprachspezifischen Genehmigungen und Beschränkungen
* unter der Lizenz sind dem Lizenztext zu entnehmen.
*/
agent {
node {
label 'ozgcloud-jenkins-build-agent-jdk21-node20'
triggers {
// upstream(upstreamProjects: getUpstreamProjects(), threshold: hudson.model.Result.SUCCESS)
cron('0 18-23,0-5 * * *')
}
environment {
JENKINS_URL = "https://jenkins.infra.ozg-cloud.systems/job/codeSH_E2E/job/${env.BRANCH_NAME}/${env.BUILD_NUMBER}/"
BUNDESLAND = "by"
SSO_URL = "sso.dev.by.ozg-cloud.de"
CLUSTER_BASE_URL = "dev.by.ozg-cloud.de"
FAILED_STAGE = ""
FAILED_PARALLEL_STAGE = " "
EA_BEZEICHNER = generateBezeichner("e2e-ea")
MAIN_BEZEICHNER = generateBezeichner("e2e-main")
ADMIN_BEZEICHNER = generateBezeichner("e2e-admin")
SH_SUCCESS_STATUS_CODE = 0
FORCE_COLOR = 0
NO_COLOR = 1
NX_DISABLE_DB = true
KEYCLOAK_CLIENT_ADMIN_APP = "admin"
KEYCLOAK_CLIENT_ALFA_APP = "alfa"
}
options {
timeout(time: 2, unit: 'HOURS')
disableConcurrentBuilds()
buildDiscarder(logRotator(numToKeepStr: '15'))
skipDefaultCheckout(true)
}
stages {
stage('Checkout build trigger') {
when {
not {
anyOf {
triggeredBy 'UpstreamCause'
triggeredBy 'BuildUpstreamCause'
triggeredBy cause: 'UserIdCause'
triggeredBy 'TimerTrigger'
}
}
steps {
script {
SKIP_RUN = true
currentBuild.result = "UNSTABLE"
}
}
stage('Check branch') {
when {
triggeredBy 'TimerTrigger'
}
steps {
script {
if (!isMainBranch()) {
echo "Branchname " + env.BRANCH_NAME + " does not match, skipping e2e tests"
SKIP_RUN = true
}
}
}
stage('Checkout SCM') {
when {
expression { !SKIP_RUN }
}
steps {
script {
FAILED_STAGE = env.STAGE_NAME
checkout scm
}
}
}
stage("Clone Gitops Repo") {
when {
expression { !SKIP_RUN }
}
steps {
script {
FAILED_STAGE = env.STAGE_NAME
cloneGitopsRepo()
}
}
}
stage("Init Default Versions") {
when {
expression { !SKIP_RUN }
}
steps {
script {
FAILED_STAGE = env.STAGE_NAME
initEnvAdminDefaultVersions()
initEnvAlfaDefaultVersions()
initEnvAlfaClientDefaultVersion()
initEnvVorgangManagerDefaultVersions()
initEnvUserManagerDefaultVersions()
stage("Set User Versions") {
when {
expression { !SKIP_RUN }
beforeInput true
triggeredBy cause: "UserIdCause"
}
steps {
script {
FAILED_STAGE = env.STAGE_NAME
catchError {
timeout(time: 5, unit: 'MINUTES') {
userVersions = input message: "Edit Default Values",
parameters: [
string(name: "AlfaImageTag", defaultValue: env.ALFA_IMAGE_TAG, trim: true),
string(name: "AlfaHelmChartVersion", defaultValue: env.ALFA_HELM_CHART_VERSION, trim: true),
string(name: "AlfaHelmRepoUrl", defaultValue: env.ALFA_HELM_REPO_URL, trim: true),
string(name: "AlfaClientImageTag", defaultValue: env.ALFA_CLIENT_IMAGE_TAG, trim: true),
string(name: "AlfaClientHelmChartVersion", defaultValue: env.ALFA_CLIENT_HELM_CHART_VERSION, trim: true),
string(name: "AlfaClientHelmRepoUrl", defaultValue: env.ALFA_CLIENT_HELM_REPO_URL, trim: true),
string(name: "AdministrationImageTag", defaultValue: env.ADMINISTRATION_IMAGE_TAG, trim: true),
string(name: "AdministrationHelmChartVersion", defaultValue: env.ADMINISTRATION_HELM_CHART_VERSION, trim: true),
string(name: "AdministrationHelmRepoUrl", defaultValue: env.ADMINISTRATION_HELM_REPO_URL, trim: true),
string(name: "AdminClientImageTag", defaultValue: env.ADMIN_CLIENT_IMAGE_TAG, trim: true),
string(name: "AdminClientHelmChartVersion", defaultValue: env.ADMIN_CLIENT_HELM_CHART_VERSION, trim: true),
string(name: "AdminClientHelmRepoUrl", defaultValue: env.ADMIN_CLIENT_HELM_REPO_URL, trim: true),
string(name: "VorgangManagerImageTag", defaultValue: env.VORGANG_MANAGER_IMAGE_TAG, trim: true),
string(name: "VorgangManagerHelmChartVersion", defaultValue: env.VORGANG_MANAGER_HELM_CHART_VERSION, trim: true),
string(name: "VorgangManagerHelmRepoUrl", defaultValue: env.VORGANG_MANAGER_HELM_REPO_URL, trim: true),
string(name: "UserManagerImageTag", defaultValue: env.USER_MANAGER_IMAGE_TAG, trim: true),
string(name: "UserManagerHelmChartVersion", defaultValue: env.USER_MANAGER_HELM_CHART_VERSION, trim: true),
string(name: "UserManagerHelmRepoUrl", defaultValue: env.USER_MANAGER_HELM_REPO_URL, trim: true)
]
initEnvUserVersions(userVersions)
stage('Init k8s') {
when {
expression { !SKIP_RUN }
}
steps {
script {
FAILED_STAGE = env.STAGE_NAME
configFileProvider([configFile(fileId: 'kubeconfig-dev-okd-cluster', variable: 'KUBE_CONFIG')]) {
sh 'mkdir ~/.kube'
sh 'cp ${KUBE_CONFIG} ~/.kube/config'
}
stage('Rollout E2E Namespaces') {
when {
expression { !SKIP_RUN }
}
steps {
script {
FAILED_STAGE = env.STAGE_NAME
deleteNamespaces([env.EA_BEZEICHNER, env.MAIN_BEZEICHNER, env.ADMIN_BEZEICHNER])
pushGitopsRepo()
}
}
post {
failure {
script {
deleteNamespaces([env.EA_BEZEICHNER, env.MAIN_BEZEICHNER, env.ADMIN_BEZEICHNER])
}
stage("Install Cypress") {
when {
expression { !SKIP_RUN }
}
steps {
script {
FAILED_STAGE = env.STAGE_NAME
withNPM(npmrcConfig: 'npm-nexus-auth') {
sh 'pnpm --version'
dir('alfa-client') {
sh 'pnpm install --frozen-lockfile --network-concurrency=8'
sh "pnpm run cypress:install"
stage('Wait for Rollout E2E Namespaces') {
when {
expression { !SKIP_RUN }
}
steps {
script {
FAILED_STAGE = env.STAGE_NAME
waitForAdminRollout(env.ADMIN_BEZEICHNER)
waitForAlfaRollout([env.EA_BEZEICHNER, env.MAIN_BEZEICHNER])
}
}
post {
failure {
script {
deleteNamespaces([env.EA_BEZEICHNER, env.MAIN_BEZEICHNER, env.ADMIN_BEZEICHNER])
}
stage('Init PortForwards') {
when {
expression { !SKIP_RUN }
}
steps {
script {
FAILED_STAGE = env.STAGE_NAME
//stage('Run E2E-Tests') {
// when {
// expression { !SKIP_RUN }
// }
// failFast false
// parallel {
stage('E2E-Alfa-EA') {
when {
expression { !SKIP_RUN }
}
steps {
catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
script {
def bezeichner = env.EA_BEZEICHNER
Integer mongoDbPort = forwardMongoDbPort(generateNamespace(bezeichner))
runTests(bezeichner, 'alfa-e2e', 'einheitlicher-ansprechpartner', env.KEYCLOAK_CLIENT_ALFA_APP, mongoDbPort, env.STAGE_NAME)
stopForwardMongoDbPort(generateNamespace(bezeichner))
}
}
post {
failure {
script {
FAILED_PARALLEL_STAGE += "${env.STAGE_NAME} "
}
}
always {
script {
publishAlfaE2ETestResult("einheitlicher-ansprechpartner", "Alfa E2E-Tests EA")
}
}
}
}
stage('E2E-Alfa-Main') {
when {
expression { !SKIP_RUN }
}
steps {
catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
script {
def bezeichner = env.MAIN_BEZEICHNER
Integer mongoDbPort = forwardMongoDbPort(generateNamespace(bezeichner))
runTests(bezeichner, 'alfa-e2e', 'main-tests', env.KEYCLOAK_CLIENT_ALFA_APP, mongoDbPort, env.STAGE_NAME)
stopForwardMongoDbPort(generateNamespace(bezeichner))
}
}
}
post {
failure {
script {
FAILED_PARALLEL_STAGE += "${env.STAGE_NAME} "
}
}
always {
script {
publishAlfaE2ETestResult("main-tests", "Alfa E2E-Tests main")
}
}
}
stage('E2E-Admin-Main') {
when {
expression { !SKIP_RUN }
}
steps {
catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
script {
String bezeichner = env.ADMIN_BEZEICHNER
Integer mongoDbPort = forwardMongoDbPort(generateNamespace(bezeichner))
runTests(bezeichner, 'admin-e2e', 'main-tests', env.KEYCLOAK_CLIENT_ADMIN_APP, mongoDbPort, env.STAGE_NAME)
stopForwardMongoDbPort(generateNamespace(bezeichner))
}
}
}
post {
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
script {
FAILED_PARALLEL_STAGE += "${env.STAGE_NAME} "
}
}
always {
script {
publishAdminE2ETestResult()
}
}
}
}
// }
//}
stage('Delete E2E Namespaces') {
when {
expression { !SKIP_RUN }
}
steps {
script {
FAILED_STAGE = env.STAGE_NAME
deleteNamespaces([env.EA_BEZEICHNER, env.MAIN_BEZEICHNER, env.ADMIN_BEZEICHNER])
}
}
}
}
post {
failure {
script {
if (isMainBranch() || isReleaseBranch()) {
sendFailureMessage()
}
String getUpstreamProjects() {
if (isMainBranch() || isReleaseBranch()) {
return "alfa/${env.BRANCH_NAME},vorgang-manager/${env.BRANCH_NAME},user-manager/${env.BRANCH_NAME}"
}
final email = "jenkins@ozg-sh.de"
final name = "jenkins"
withCredentials([usernamePassword(credentialsId: 'jenkins-gitea-access-token', passwordVariable: 'TOKEN', usernameVariable: 'USER')]) {
sh 'git clone https://${USER}:${TOKEN}@git.ozg-sh.de/ozgcloud-devops/gitops.git'
dir("gitops") {
sh "git config user.email '${email}'"
sh "git config user.name '${name}'"
}
Map getApplicationValues(String application) {
def applicationValues = readYaml file: "gitops/${getEnvironment()}/application/values/${application}-values.yaml"
return applicationValues.get(application.replaceAll("-", "_"))
if (isReleaseBranch()) {
return "test"
}
}
String getImageTag(Map applicationValues) {
}
String getHelmChartVersion(Map applicationValues) {
return applicationValues.helm.version
if (isReleaseBranch()) {
return "https://nexus.ozg-sh.de/repository/ozg-base-apps"
}
return "https://nexus.ozg-sh.de/repository/ozg-base-apps-snapshot"
Void initEnvAdminDefaultVersions() {
def values = getApplicationValues('administration')
env.ADMINISTRATION_IMAGE_TAG = getImageTag(values)
env.ADMINISTRATION_HELM_CHART_VERSION = getHelmChartVersion(values)
env.ADMINISTRATION_HELM_REPO_URL = getHelmRepoUrl()
values = getApplicationValues('administration-client')
env.ADMIN_CLIENT_IMAGE_TAG = getImageTag(values)
env.ADMIN_CLIENT_HELM_CHART_VERSION = getHelmChartVersion(values)
env.ADMIN_CLIENT_HELM_REPO_URL = getHelmRepoUrl()
}
Void initEnvAlfaDefaultVersions() {
def values = getApplicationValues('alfa')
env.ALFA_IMAGE_TAG = getImageTag(values)
env.ALFA_HELM_CHART_VERSION = getHelmChartVersion(values)
env.ALFA_HELM_REPO_URL = getHelmRepoUrl()
}
Void initEnvAlfaClientDefaultVersion() {
def values = getApplicationValues('alfa-client')
env.ALFA_CLIENT_IMAGE_TAG = getImageTag(values)
env.ALFA_CLIENT_HELM_CHART_VERSION = getHelmChartVersion(values)
env.ALFA_CLIENT_HELM_REPO_URL = getHelmRepoUrl()
}
Void initEnvVorgangManagerDefaultVersions() {
def values = getApplicationValues('vorgang-manager')
env.VORGANG_MANAGER_IMAGE_TAG = getImageTag(values)
env.VORGANG_MANAGER_HELM_CHART_VERSION = getHelmChartVersion(values)
env.VORGANG_MANAGER_HELM_REPO_URL = getHelmRepoUrl()
}
Void initEnvUserManagerDefaultVersions() {
def values = getApplicationValues('user-manager')
env.USER_MANAGER_IMAGE_TAG = getImageTag(values)
env.USER_MANAGER_HELM_CHART_VERSION = getHelmChartVersion(values)
env.USER_MANAGER_HELM_REPO_URL = getHelmRepoUrl()
}
Void initEnvUserVersions(userVersions) {
env.ALFA_IMAGE_TAG = userVersions.AlfaImageTag
env.ALFA_CLIENT_IMAGE_TAG = userVersions.AlfaClientImageTag
env.ALFA_HELM_CHART_VERSION = userVersions.AlfaHelmChartVersion
env.ALFA_HELM_REPO_URL = userVersions.AlfaHelmRepoUrl
env.ADMINISTRATION_IMAGE_TAG = userVersions.AdministrationImageTag
env.ADMINISTRATION_HELM_CHART_VERSION = userVersions.AdministrationHelmChartVersion
env.ADMINISTRATION_HELM_REPO_URL = userVersions.AdministrationHelmRepoUrl
env.ADMIN_CLIENT_IMAGE_TAG = userVersions.AdminClientImageTag
env.ADMIN_CLIENT_HELM_CHART_VERSION = userVersions.AdminClientHelmChartVersion
env.ADMIN_CLIENT_HELM_REPO_URL = userVersions.AdminClientHelmRepoUrl
env.VORGANG_MANAGER_IMAGE_TAG = userVersions.VorgangManagerImageTag
env.VORGANG_MANAGER_HELM_CHART_VERSION = userVersions.VorgangManagerHelmChartVersion
env.VORGANG_MANAGER_HELM_REPO_URL = userVersions.VorgangManagerHelmRepoUrl
env.USER_MANAGER_IMAGE_TAG = userVersions.UserManagerImageTag
env.USER_MANAGER_HELM_CHART_VERSION = userVersions.UserManagerHelmChartVersion
env.USER_MANAGER_HELM_REPO_URL = userVersions.UserManagerHelmRepoUrl
withCredentials([usernamePassword(credentialsId: 'jenkins-gitea-access-token', passwordVariable: 'TOKEN', usernameVariable: 'USER')]) {
dir('gitops') {
if (hasUnpushedCommits()) {
sh 'git config pull.rebase false'
sh 'git pull'
sh 'git push https://${USER}:${TOKEN}@git.ozg-sh.de/ozgcloud-devops/gitops.git'
}
return sh(script: "git cherry -v | grep .", returnStatus: true) == env.SH_SUCCESS_STATUS_CODE as Integer
dir('gitops') {
sh 'git checkout e2e'
}

OZGCloud
committed
Void generateNamespaces() {
def y1 = generateAdminNamespaceYaml()
def y2 = generateEaNamespaceYaml()
def y3 = generateMainNamespaceYaml()
sh "git commit -m 'add e2e namespaces for testrun'"
}
}
Void generateAdminNamespaceYaml() {
def bezeichner = env.ADMIN_BEZEICHNER
def envValues
dir("alfa-client/apps/admin-e2e/") {
envValues = readYaml file: "src/fixtures/argocd/by-admin-dev.yaml";
envValues.ozgcloud.bezeichner = bezeichner
envValues.administration.put("image", ['tag': env.ADMINISTRATION_IMAGE_TAG])
envValues.administration.put("helm", ['version': env.ADMINISTRATION_HELM_CHART_VERSION, 'repoUrl': env.ADMINISTRATION_HELM_REPO_URL])
envValues.administration.put("ozgcloud", ['feature': ['organisationsEinheiten': "true"], 'organisationEinheit': ['zufiSearchUri': generateZufiSearchUri(bezeichner)]])
envValues.administration_client.put("image", ['tag': env.ADMIN_CLIENT_IMAGE_TAG])
envValues.administration_client.put("helm", ['version': env.ADMIN_CLIENT_HELM_CHART_VERSION, 'repoUrl': env.ADMIN_CLIENT_HELM_REPO_URL])
}
return writeYamlToGitOps(bezeichner, envValues);
}
String generateZufiSearchUri(String bezeichner) {
return "https://${bezeichner}.dev.by.ozg-cloud.de/api/organisationseinheits?searchBy={searchBy}"
String generateEaNamespaceYaml() {
return generateNamespaceYaml(env.EA_BEZEICHNER, "by-ea-dev.yaml");
String generateMainNamespaceYaml() {
return generateNamespaceYaml(env.MAIN_BEZEICHNER, "by-main-dev.yaml");
String generateNamespaceYaml(String bezeichner, String valuesPathSuffix) {
def envValues
dir('alfa-client/apps/alfa-e2e/') {
envValues = readYaml file: "src/fixtures/argocd/" + valuesPathSuffix;
envValues.ozgcloud.bezeichner = bezeichner
envValues.alfa.put("image", ['tag': env.ALFA_IMAGE_TAG])
envValues.alfa.put("helm", ['version': env.ALFA_HELM_CHART_VERSION, 'repoUrl': env.ALFA_HELM_REPO_URL])
envValues.alfa_client.put("image", ['tag': env.ALFA_CLIENT_IMAGE_TAG])
envValues.alfa_client.put("helm", ['version': env.ALFA_CLIENT_HELM_CHART_VERSION, 'repoUrl': env.ALFA_CLIENT_HELM_REPO_URL])
envValues.vorgang_manager.put("image", ['tag': env.VORGANG_MANAGER_IMAGE_TAG])
envValues.vorgang_manager.put("helm", ['version': env.VORGANG_MANAGER_HELM_CHART_VERSION, 'repoUrl': env.VORGANG_MANAGER_HELM_REPO_URL])
envValues.user_manager.put("image", ['tag': env.USER_MANAGER_IMAGE_TAG])
envValues.user_manager.put("helm", ['version': env.USER_MANAGER_HELM_CHART_VERSION, 'repoUrl': env.USER_MANAGER_HELM_REPO_URL])
}
return writeYamlToGitOps(bezeichner, envValues);
}
String writeYamlToGitOps(String bezeichner, Object envValues) {
def bezeichnerYaml = "dev/namespace/namespaces/by-${bezeichner}-dev.yaml"
writeYaml file: "gitops/${bezeichnerYaml}", data: envValues, overwrite: true
sh "cat gitops/${bezeichnerYaml}"
return bezeichnerYaml;

OZGCloud
committed
Void deleteNamespaces(ozgCloudBezeichner) {
for (bezeichner in ozgCloudBezeichner) {
if (hasNamespaceFile(bezeichner)) {
removeNamespaceFile(bezeichner)
for (bezeichner in ozgCloudBezeichner) {
waitForDeletion(bezeichner)
}
}
Void removeNamespaceFile(String bezeichner) {
dir("gitops/dev/namespace/namespaces") {
sh "rm by-${bezeichner}-dev.yaml"
sh "git add by-${bezeichner}-dev.yaml"
sh "git commit -m 'delete e2e by-${bezeichner}-dev.yaml'"
}
}
Boolean hasNamespaceFile(String bezeichner) {
return sh(script: "ls gitops/dev/namespace/namespaces | grep 'by-${bezeichner}-dev.yaml'", returnStatus: true) == env.SH_SUCCESS_STATUS_CODE as Integer
sh "kubectl wait --for=delete applications/by-${bezeichner}-dev-application -n argocd --timeout=120s"
sh """
kubectl patch applications.argoproj.io by-${bezeichner}-dev-application -n argocd --type=json -p '[{"op": "remove", "path": "/metadata/finalizers"}]'
"""
sh "kubectl wait --for=delete applications/by-${bezeichner}-dev-application -n argocd --timeout=120s"
} catch (Exception e2) {
error("Application by-${bezeichner}-dev-application konnte nicht gelöscht werden")
}
for (bezeichner in ozgCloudBezeichner) {
waitForAlfaRollout(bezeichner)
}
Void waitForAdminRollout(String bezeichner) {
waitForHealthyApplication(bezeichner, 'administration')
waitForHealthyApplication(bezeichner, 'administration-client')
}
Void waitForAlfaRollout(String bezeichner) {
waitForHealthyApplication(bezeichner, 'application')
waitForHealthyApplication(bezeichner, 'vorgang-manager')
waitForHealthyApplication(bezeichner, 'user-manager')
waitForHealthyApplication(bezeichner, 'alfa')
}
Void waitForHealthyApplication(String bezeichner, String application) {
try {
def countRetry = 0
def maxRetry = 24
while (!isApplicationPresent(bezeichner, application) && countRetry < maxRetry) {
countRetry++
sh "sleep 20"
}
if (!isApplicationHealthy(bezeichner, application)) {
waitForHealthyStatus(bezeichner, application)
} catch (Exception e) {
echo "waitForHealthyApplication Exception: ${e}"
error("Application ${application} unhealthy")
}
}
Boolean isApplicationPresent(String bezeichner, String application) {
return sh(script: "kubectl get applications -n argocd | grep 'by-${bezeichner}-dev-${application}'", returnStatus: true) == env.SH_SUCCESS_STATUS_CODE as Integer
}
Boolean isApplicationHealthy(String bezeichner, String application) {
return sh(script: "kubectl get application/by-${bezeichner}-dev-${application} -n argocd -o=jsonpath='{.status.health.status}' | grep Healthy", returnStatus: true) == env.SH_SUCCESS_STATUS_CODE as Integer
}
Void waitForHealthyStatus(String bezeichner, String application) {
sh "kubectl wait --for=jsonpath='{.status.health.status}'=Healthy applications/by-${bezeichner}-dev-${application} -n argocd --timeout=900s"
Void publishAlfaE2ETestResult(String appVariant, String reportName) {
publishE2ETestResult("alfa-e2e", appVariant, reportName);
Void publishAdminE2ETestResult() {
publishE2ETestResult("admin-e2e", "main-tests", "Admin E2E-Tests main");

OZGCloud
committed
}
Void publishE2ETestResult(String appName, String appVariant, String reportName) {
def reportDir = "alfa-client/apps/" + appName + "/reports/" + appVariant;

OZGCloud
committed
target: [

OZGCloud
committed
alwaysLinkToLastBuild: false,
keepAll : true,
reportDir : reportDir,
reportFiles : 'report.html',
reportName : reportName

OZGCloud
committed
]
)
String runTests(String bezeichner, String appName, String appVariant, String keycloakClientName, Integer dbPort, String stageName) {
def config = generateCypressConfig(bezeichner, appName, appVariant, keycloakClientName, dbPort)
sh "apps/run-tests.sh ${appName} ${appVariant} ${config}"
} catch (Exception e) {
printNpmDebugLog()
error("Fehler in Stage ${stageName}")
}
if (hasNpmDebugLog()) {
sh "cat pnpm-debug.log"
} else {
echo "pnpm debug log not found"
}
return input.replaceAll(/[^a-zA-Z0-9]+/, "").toLowerCase()
def branchName = makeUrlConform(env.BRANCH_NAME)
def stageName = makeUrlConform(stage)
return "${cutBranchNameForKeycloakRealm(branchName, stageName)}-${stageName}"
}
String cutBranchNameForKeycloakRealm(String branchName, String stageName) {
def cutBranchNamePosition = maxKeycloakRealmLength - (stageName.length() + "${env.BUNDESLAND}---dev".length())
return branchName.take(cutBranchNamePosition)
String generateCypressConfig(String bezeichner, String appName, String appVariant, String keycloakClientName, Integer dbPort) {
def namespace = generateNamespace(bezeichner)
def configName = "cypress-ci-" + appVariant + ".json"
dir("alfa-client/apps/${appName}/") {
def config = readJSON file: 'cypress-ci.json'
def vorgangManagerDatabaseSecret = getVorgangManagerDatabaseSecret(namespace);
def decodedPassword = decodeString(vorgangManagerDatabaseSecret.password);
def parsablePassword = makePasswordUrlConform(decodedPassword);
config.baseUrl = "https://${generateUrlBezeichner(bezeichner, appName)}.${env.CLUSTER_BASE_URL}" as String
config.env.dbUrl = "mongodb://${decodeString(vorgangManagerDatabaseSecret.username)}:${parsablePassword}@localhost:${dbPort}/admin?ssl=false&directConnection=true&socketTimeoutMS=30000&heartbeatFrequencyMS=10000" as String
config.env.keycloakUrl = "https://${env.SSO_URL}/" as String
config.env.keycloakRealm = namespace as String
config.env.keycloakClient = keycloakClientName as String
config.videosFolder = "./reports/${appVariant}/videos" as String
config.screenshotsFolder = "./reports/${appVariant}/screenshots" as String
config.reporterOptions.reportDir = "./reports/${appVariant}/mochawesome-report" as String
config.specPattern = "src/e2e/${appVariant}/**/*.cy.{js,jsx,ts,tsx}" as String
config.env.put("search", getElasticsearchEnv(namespace))
config.env.put("userManager", getUserManagerEnv(namespace, dbPort))
config.env.put("smocker", getSmockerEnv(namespace))
writeJSON file: configName, json: config
sh "cat ${configName}"
}
return "cypress-ci-" + appVariant + ".config.ts"
String generateUrlBezeichner(String bezeichner, String appName) {
if (appName == 'admin-e2e') {
String makePasswordUrlConform(String password) {
return sh(script: "printf %s ${password} | jq -sRr @uri", returnStdout: true);
}
Map getVorgangManagerDatabaseSecret(String namespace) {
return readJSON(text: sh(script: "kubectl get secret ozg-mongodb-admin-vorgang-manager-user -n ${namespace} -o jsonpath={.data}", returnStdout: true))
Map getUserManagerEnv(String namespace, dbPort) {
def userManagerDatabaseSecret = getUserManagerDatabaseSecret(namespace);
def decodedPassword = decodeString(userManagerDatabaseSecret.password);
def parsablePassword = makePasswordUrlConform(decodedPassword);
return [
"dbUrl" : "mongodb://${decodeString(userManagerDatabaseSecret.username)}:${parsablePassword}@localhost:${dbPort}/admin?ssl=false&directConnection=true&socketTimeoutMS=30000&heartbeatFrequencyMS=10000" as String,
"database": "user-manager-database"
]
Map getUserManagerDatabaseSecret(String namespace) {
return readJSON(text: sh(script: "kubectl get secret ozg-mongodb-admin-user-manager-user -n ${namespace} -o jsonpath={.data}", returnStdout: true))
def data = [
"msgtype" : "m.text",
"body" : "E2E-Tests: Failed stage: ${getFailedStage()} Build-ID: ${env.BUILD_NUMBER} Link: ${JENKINS_URL}" as String,
"format" : "org.matrix.custom.html",
"formatted_body": "E2E-Tests: Failed stage: ${getFailedStage()} Build-ID: <a href='${JENKINS_URL}'>${env.BUILD_NUMBER}</a>" as String
]
sh "curl -XPOST -H 'authorization: Bearer ${getElementAccessToken()}' -d '${JsonOutput.toJson(data)}' https://matrix.ozg-sh.de/_matrix/client/v3/rooms/${getElementRoomId()}/send/m.room.message"
if (FAILED_PARALLEL_STAGE.trim()) {
return FAILED_PARALLEL_STAGE.trim()
}
final releaseRoomId = "!oWZpUGTFsxkJIYNfYg:matrix.ozg-sh.de"
final masterRoomId = "!iQPAvQIiRwRpNOszjw:matrix.ozg-sh.de"
if (isReleaseBranch()) {
return releaseRoomId
}
withCredentials([string(credentialsId: 'element-login-json', variable: 'LOGIN_JSON')]) {
return readJSON(text: sh(script: '''curl -XPOST -d \"$LOGIN_JSON\" https://matrix.ozg-sh.de/_matrix/client/v3/login''', returnStdout: true)).access_token
}
def elasticsearchSecret = getElasticsearchSecret(namespace)
return [
"user" : decodeString(elasticsearchSecret.username),
"password": decodeString(elasticsearchSecret.password),
"index" : decodeString(elasticsearchSecret.index),
"url" : "https://localhost:9200"
]
Void forwardMongoDbPort(String namespace) {
try {
def minPort = 20000
def portRange = 20000
//def dbPort = "${Math.abs(new Random().nextInt(portRange+1))+minPort}" as Integer
def dbPort = Math.abs(new Random().nextInt(portRange + 1)) + minPort
echo "Forwarding MongoDB Port to local port ${dbPort}"
def pidFile = generateMongoDbPortForwardPidFile(namespace)
sh "kubectl port-forward ozg-mongodb-0 ${dbPort}:27017 -n ${namespace} & echo \$! > ${pidFile}"
return dbPort
}
catch (Exception e) {
echo "forwardMongoDbPort Exception: ${e}"
error("Error forwarding service")
}
Void stopForwardMongoDbPort(String namespace) {
echo "Removing forwarding MongoDB Port to local port for ${namespace}"
def pidFile = generateMongoDbPortForwardPidFile(namespace)
dir('alfa-client/apps/alfa-e2e/src/jenkins-build-files') {
sh "./kill-pid-by-filename.sh ${pidFile}"
}
}
Void generateMongoDbPortForwardPidFile(String namespace) {
return "/tmp/pid_file_mongodb_port_forward_${namespace}.pid"
if (!isElasticSearchForwarded()) {
sh "kubectl port-forward ozg-search-cluster-es-ozg-search-0 9200:9200 -n elastic-system &"
}
return sh(script: "lsof -i -P -n | grep LISTEN | grep :9200", returnStatus: true) == env.SH_SUCCESS_STATUS_CODE as Integer
}
String generateNamespace(String bezeichner) {
return "${env.BUNDESLAND}-${bezeichner}-dev"
return sh(script: "echo -n ${encoded} | base64 --decode", returnStdout: true)
}
Map getElasticsearchSecret(String namespace) {
return readJSON(text: sh(script: "kubectl get secret elasticsearch-credentials -n ${namespace} -o jsonpath={.data}", returnStdout: true))
return sh(script: "ls -l pnpm-debug.log", returnStatus: true) == env.SH_SUCCESS_STATUS_CODE as Integer
}
Map getSmockerEnv(String namespace) {
return [
"url": "https://${namespace}-smocker.dev.by.ozg-cloud.de".toString()
]