Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
af150158ab |
No files matched your search
@@ -39,7 +39,7 @@ echo "Packing generate_config.sh..."
|
||||
echo ''
|
||||
|
||||
# Embed each template
|
||||
for tpl in java-webapp node-api node-webapp terraform sdk-distribution validate-cd-repo argocd-apps; do
|
||||
for tpl in java-webapp gradle-webapp node-api node-webapp terraform sdk-distribution validate-cd-repo argocd-apps; do
|
||||
echo "cat > /tmp/munitor/templates/${tpl}.yml.tpl << 'MUNITOR_TPL_EOF'"
|
||||
cat "${SRC}/templates/${tpl}.yml.tpl"
|
||||
echo 'MUNITOR_TPL_EOF'
|
||||
@@ -47,7 +47,7 @@ echo "Packing generate_config.sh..."
|
||||
done
|
||||
|
||||
# Embed partials
|
||||
for partial in java-webapp-deploy node-api-deploy node-webapp-deploy; do
|
||||
for partial in java-webapp-deploy gradle-webapp-deploy node-api-deploy node-webapp-deploy; do
|
||||
echo "cat > /tmp/munitor/templates/partials/${partial}.yml.tpl << 'MUNITOR_PARTIAL_EOF'"
|
||||
cat "${SRC}/templates/partials/${partial}.yml.tpl"
|
||||
echo 'MUNITOR_PARTIAL_EOF'
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
description: >
|
||||
Run Gradle build (compile + package, skip tests).
|
||||
steps:
|
||||
- run:
|
||||
name: Gradle build
|
||||
command: << include(scripts/gradle_build.sh) >>
|
||||
@@ -0,0 +1,6 @@
|
||||
description: >
|
||||
Run Gradle Checkstyle analysis (skips gracefully if plugin not applied).
|
||||
steps:
|
||||
- run:
|
||||
name: Gradle Checkstyle
|
||||
command: << include(scripts/gradle_checkstyle.sh) >>
|
||||
@@ -0,0 +1,13 @@
|
||||
description: >
|
||||
Generate JaCoCo coverage report and enforce minimum thresholds.
|
||||
parameters:
|
||||
min_instruction:
|
||||
type: string
|
||||
default: "70"
|
||||
description: Minimum instruction coverage percentage.
|
||||
steps:
|
||||
- run:
|
||||
name: Gradle JaCoCo coverage
|
||||
environment:
|
||||
MIN_INSTRUCTION: << parameters.min_instruction >>
|
||||
command: << include(scripts/gradle_jacoco.sh) >>
|
||||
@@ -0,0 +1,6 @@
|
||||
description: >
|
||||
Run Gradle PMD static analysis (skips gracefully if plugin not applied).
|
||||
steps:
|
||||
- run:
|
||||
name: Gradle PMD
|
||||
command: << include(scripts/gradle_pmd.sh) >>
|
||||
@@ -0,0 +1,6 @@
|
||||
description: >
|
||||
Run Gradle SpotBugs static analysis (skips gracefully if plugin not applied).
|
||||
steps:
|
||||
- run:
|
||||
name: Gradle SpotBugs
|
||||
command: << include(scripts/gradle_spotbugs.sh) >>
|
||||
@@ -0,0 +1,15 @@
|
||||
description: >
|
||||
Run Gradle tests and store JUnit XML results.
|
||||
steps:
|
||||
- run:
|
||||
name: Gradle test
|
||||
command: << include(scripts/gradle_test.sh) >>
|
||||
- run:
|
||||
name: Collect test results
|
||||
command: << include(scripts/collect_gradle_test_results.sh) >>
|
||||
when: always
|
||||
- store_test_results:
|
||||
path: /tmp/test-results
|
||||
- store_artifacts:
|
||||
path: /tmp/test-results
|
||||
destination: test-results
|
||||
@@ -0,0 +1,7 @@
|
||||
description: >
|
||||
Restore the Gradle caches based on wrapper and settings checksums.
|
||||
steps:
|
||||
- restore_cache:
|
||||
keys:
|
||||
- gradle-v1-{{ checksum "gradle/wrapper/gradle-wrapper.properties" }}-{{ checksum "settings.gradle.kts" }}
|
||||
- gradle-v1-
|
||||
@@ -0,0 +1,8 @@
|
||||
description: >
|
||||
Save the Gradle caches for future builds.
|
||||
steps:
|
||||
- save_cache:
|
||||
key: gradle-v1-{{ checksum "gradle/wrapper/gradle-wrapper.properties" }}-{{ checksum "settings.gradle.kts" }}
|
||||
paths:
|
||||
- ~/.gradle/caches
|
||||
- ~/.gradle/wrapper
|
||||
@@ -0,0 +1,43 @@
|
||||
description: >
|
||||
Full Gradle build and test job. Installs Java, restores cache, calculates
|
||||
version, builds, tests, saves cache, and persists the workspace for
|
||||
downstream jobs.
|
||||
parameters:
|
||||
java_version:
|
||||
type: string
|
||||
default: "21"
|
||||
description: Java major version to install.
|
||||
resource_class:
|
||||
type: enum
|
||||
enum:
|
||||
- medium
|
||||
- large
|
||||
- xlarge
|
||||
default: large
|
||||
description: Machine resource class.
|
||||
executor:
|
||||
name: machine
|
||||
resource_class: << parameters.resource_class >>
|
||||
steps:
|
||||
- checkout
|
||||
- install_java:
|
||||
version: << parameters.java_version >>
|
||||
- restore_gradle_cache
|
||||
- calculate_version
|
||||
- export_version_vars
|
||||
- gradle_build
|
||||
- gradle_test
|
||||
- run:
|
||||
name: Collect test results
|
||||
command: << include(scripts/collect_gradle_test_results.sh) >>
|
||||
when: always
|
||||
- store_test_results:
|
||||
path: /tmp/test-results
|
||||
- run:
|
||||
name: Persist version metadata
|
||||
command: <<include(scripts/persist_version_metadata.sh)>>
|
||||
- save_gradle_cache
|
||||
- persist_to_workspace:
|
||||
root: .
|
||||
paths:
|
||||
- "."
|
||||
@@ -0,0 +1,27 @@
|
||||
description: >
|
||||
Run code quality checks: Checkstyle, SpotBugs, and PMD.
|
||||
Requires workspace from gradle_build_and_test.
|
||||
Skips individual tools gracefully if their Gradle plugin is not applied.
|
||||
parameters:
|
||||
java_version:
|
||||
type: string
|
||||
default: "21"
|
||||
description: Java major version to install.
|
||||
resource_class:
|
||||
type: enum
|
||||
enum:
|
||||
- medium
|
||||
- large
|
||||
default: large
|
||||
description: Docker resource class.
|
||||
executor:
|
||||
name: java
|
||||
java_version: << parameters.java_version >>
|
||||
resource_class: << parameters.resource_class >>
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- restore_gradle_cache
|
||||
- gradle_checkstyle
|
||||
- gradle_spotbugs
|
||||
- gradle_pmd
|
||||
@@ -0,0 +1,29 @@
|
||||
description: >
|
||||
Generate coverage report and enforce minimum thresholds.
|
||||
Requires workspace from gradle_build_and_test.
|
||||
parameters:
|
||||
java_version:
|
||||
type: string
|
||||
default: "21"
|
||||
description: Java major version to install.
|
||||
min_instruction:
|
||||
type: string
|
||||
default: "70"
|
||||
description: Minimum instruction coverage percentage.
|
||||
resource_class:
|
||||
type: enum
|
||||
enum:
|
||||
- medium
|
||||
- large
|
||||
default: large
|
||||
description: Docker resource class.
|
||||
executor:
|
||||
name: java
|
||||
java_version: << parameters.java_version >>
|
||||
resource_class: << parameters.resource_class >>
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- restore_gradle_cache
|
||||
- gradle_jacoco:
|
||||
min_instruction: << parameters.min_instruction >>
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Source shared helpers
|
||||
MUNITOR_HELPERS="${MUNITOR_HELPERS:-$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)/munitor_helpers.sh}"
|
||||
# shellcheck source=munitor_helpers.sh
|
||||
if [[ -f "${MUNITOR_HELPERS}" ]]; then source "${MUNITOR_HELPERS}"
|
||||
elif ! type munitor_header &>/dev/null; then
|
||||
munitor_header() { echo "=== Munitor: ${1:-unknown} ==="; }
|
||||
munitor_check_tool() { command -v "$1" &>/dev/null || { echo "ERROR: $1 not found"; exit 1; }; }
|
||||
munitor_download_with_retry() { curl -fsSL --retry 3 "$1" -o "$2"; }
|
||||
fi
|
||||
|
||||
munitor_header "collect_gradle_test_results"
|
||||
|
||||
DEST="/tmp/test-results"
|
||||
mkdir -p "${DEST}"
|
||||
|
||||
find . -path "*/build/test-results/test/*.xml" -exec cp {} "${DEST}/" \;
|
||||
|
||||
COUNT=$(find "${DEST}" -name "*.xml" 2>/dev/null | wc -l | tr -d ' ')
|
||||
echo "Collected ${COUNT} test result file(s) to ${DEST}/"
|
||||
@@ -13,17 +13,23 @@ extract_munitor_vars() {
|
||||
fi
|
||||
|
||||
# --- Org defaults (overridable via .munitor.yml org section) ---
|
||||
local ORG_DOCKER_REGISTRY=$(yq '.org.docker_registry // "ghcr.io/KofTwentyTwo"' "${config_file}")
|
||||
local ORG_NPM_SCOPE=$(yq '.org.npm_scope // "@koftwentytwo"' "${config_file}")
|
||||
local ORG_CI_EMAIL=$(yq '.org.ci_email // "munitor-ci@koftwentytwo.com"' "${config_file}")
|
||||
local ORG_CI_NAME=$(yq '.org.ci_name // "Munitor CI"' "${config_file}")
|
||||
local ORG_ORB_SLUG=$(yq '.org.orb_slug // "kof22/munitor"' "${config_file}")
|
||||
local ORG_DOCKER_REGISTRY
|
||||
ORG_DOCKER_REGISTRY=$(yq '.org.docker_registry // "ghcr.io/KofTwentyTwo"' "${config_file}")
|
||||
local ORG_NPM_SCOPE
|
||||
ORG_NPM_SCOPE=$(yq '.org.npm_scope // "@koftwentytwo"' "${config_file}")
|
||||
local ORG_CI_EMAIL
|
||||
ORG_CI_EMAIL=$(yq '.org.ci_email // "munitor-ci@koftwentytwo.com"' "${config_file}")
|
||||
local ORG_CI_NAME
|
||||
ORG_CI_NAME=$(yq '.org.ci_name // "Munitor CI"' "${config_file}")
|
||||
local ORG_ORB_SLUG
|
||||
ORG_ORB_SLUG=$(yq '.org.orb_slug // "kof22/munitor"' "${config_file}")
|
||||
|
||||
# Core pipeline settings
|
||||
MUNITOR_PIPELINE=$(yq '.pipeline' "${config_file}")
|
||||
MUNITOR_ORB_VERSION=$(yq '.orb_version // ""' "${config_file}")
|
||||
MUNITOR_IMAGE_NAME=$(yq '.image_name // ""' "${config_file}")
|
||||
MUNITOR_JAVA_VERSION=$(yq '.java_version // "21"' "${config_file}")
|
||||
MUNITOR_SERVER_MODULE=$(yq '.server_module // ""' "${config_file}")
|
||||
MUNITOR_NODE_VERSION=$(yq '.node_version // "20"' "${config_file}")
|
||||
MUNITOR_SONAR_PROJECT_KEY=$(yq '.sonar.project_key // ""' "${config_file}")
|
||||
MUNITOR_DOCKER_REGISTRY=$(yq '.docker.registry // ""' "${config_file}")
|
||||
@@ -198,7 +204,7 @@ extract_munitor_vars() {
|
||||
fi
|
||||
|
||||
# Export all variables
|
||||
export MUNITOR_PIPELINE MUNITOR_ORB_VERSION MUNITOR_IMAGE_NAME MUNITOR_JAVA_VERSION MUNITOR_NODE_VERSION
|
||||
export MUNITOR_PIPELINE MUNITOR_ORB_VERSION MUNITOR_IMAGE_NAME MUNITOR_JAVA_VERSION MUNITOR_NODE_VERSION MUNITOR_SERVER_MODULE
|
||||
export MUNITOR_SONAR_PROJECT_KEY MUNITOR_DOCKER_REGISTRY MUNITOR_CD_REPO MUNITOR_CD_FORMAT
|
||||
export MUNITOR_CD_ENV_DEVELOP MUNITOR_CD_ENV_STAGING MUNITOR_CD_ENV_PROD MUNITOR_CD_ENV_RELEASE
|
||||
export MUNITOR_COVERAGE_MIN MUNITOR_E2E MUNITOR_SBOM MUNITOR_OWASP
|
||||
@@ -223,5 +229,5 @@ extract_munitor_vars() {
|
||||
# Build the envsubst variable list
|
||||
get_envsubst_vars() {
|
||||
# shellcheck disable=SC2016
|
||||
echo '${MUNITOR_PIPELINE} ${MUNITOR_ORB_VERSION} ${MUNITOR_IMAGE_NAME} ${MUNITOR_JAVA_VERSION} ${MUNITOR_NODE_VERSION} ${MUNITOR_SONAR_PROJECT_KEY} ${MUNITOR_DOCKER_REGISTRY} ${MUNITOR_CD_REPO} ${MUNITOR_CD_FORMAT} ${MUNITOR_CD_ENV_DEVELOP} ${MUNITOR_CD_ENV_STAGING} ${MUNITOR_CD_ENV_PROD} ${MUNITOR_CD_ENV_RELEASE} ${MUNITOR_COVERAGE_MIN} ${MUNITOR_E2E} ${MUNITOR_SBOM} ${MUNITOR_OWASP} ${MUNITOR_CONTEXT_REGISTRY} ${MUNITOR_CONTEXT_GITHUB} ${MUNITOR_CONTEXT_SONAR} ${MUNITOR_CONTEXT_NVD} ${MUNITOR_NPM_AUTH} ${MUNITOR_NPM_SCOPES} ${MUNITOR_SERVICES_JSON} ${MUNITOR_TEST_SETUP_SCRIPT} ${MUNITOR_TEST_COMMANDS_JSON} ${MUNITOR_COVERAGE_TOOL} ${MUNITOR_COVERAGE_COMMAND} ${MUNITOR_GITHUB_RELEASE} ${MUNITOR_SAST} ${MUNITOR_SAST_FAIL_ON_FINDINGS} ${MUNITOR_HEALTH_PATH} ${MUNITOR_HEALTH_PORT} ${MUNITOR_HEALTH_DB} ${MUNITOR_HEALTH_MIGRATIONS} ${MUNITOR_HEALTH_SMOKE_PATHS} ${MUNITOR_TF_PATH} ${MUNITOR_TF_LIVE_PATH} ${MUNITOR_TF_ENVIRONMENTS} ${MUNITOR_CHECKOV_SKIP} ${MUNITOR_KUSTOMIZE_VERSION} ${MUNITOR_KUSTOMIZE_BASE_PATH} ${MUNITOR_KUSTOMIZE_LOAD_RESTRICTOR} ${MUNITOR_KUSTOMIZE_SCAN_OVERLAY} ${MUNITOR_KUSTOMIZE_OVERLAYS} ${MUNITOR_KUSTOMIZE_OVERLAY_DIR} ${MUNITOR_KUBE_LINTER_CONFIG} ${MUNITOR_YAMLLINT_PATHS} ${MUNITOR_CI_EMAIL} ${MUNITOR_CI_NAME} ${MUNITOR_NPM_DEFAULT_SCOPE} ${MUNITOR_ORB_SLUG} ${MUNITOR_PACKAGE_MANAGER} ${MUNITOR_SUPPLEMENTAL_IMAGES_JSON}'
|
||||
echo '${MUNITOR_PIPELINE} ${MUNITOR_ORB_VERSION} ${MUNITOR_IMAGE_NAME} ${MUNITOR_JAVA_VERSION} ${MUNITOR_NODE_VERSION} ${MUNITOR_SONAR_PROJECT_KEY} ${MUNITOR_DOCKER_REGISTRY} ${MUNITOR_CD_REPO} ${MUNITOR_CD_FORMAT} ${MUNITOR_CD_ENV_DEVELOP} ${MUNITOR_CD_ENV_STAGING} ${MUNITOR_CD_ENV_PROD} ${MUNITOR_CD_ENV_RELEASE} ${MUNITOR_COVERAGE_MIN} ${MUNITOR_E2E} ${MUNITOR_SBOM} ${MUNITOR_OWASP} ${MUNITOR_CONTEXT_REGISTRY} ${MUNITOR_CONTEXT_GITHUB} ${MUNITOR_CONTEXT_SONAR} ${MUNITOR_CONTEXT_NVD} ${MUNITOR_NPM_AUTH} ${MUNITOR_NPM_SCOPES} ${MUNITOR_SERVICES_JSON} ${MUNITOR_TEST_SETUP_SCRIPT} ${MUNITOR_TEST_COMMANDS_JSON} ${MUNITOR_COVERAGE_TOOL} ${MUNITOR_COVERAGE_COMMAND} ${MUNITOR_GITHUB_RELEASE} ${MUNITOR_SAST} ${MUNITOR_SAST_FAIL_ON_FINDINGS} ${MUNITOR_HEALTH_PATH} ${MUNITOR_HEALTH_PORT} ${MUNITOR_HEALTH_DB} ${MUNITOR_HEALTH_MIGRATIONS} ${MUNITOR_HEALTH_SMOKE_PATHS} ${MUNITOR_TF_PATH} ${MUNITOR_TF_LIVE_PATH} ${MUNITOR_TF_ENVIRONMENTS} ${MUNITOR_CHECKOV_SKIP} ${MUNITOR_KUSTOMIZE_VERSION} ${MUNITOR_KUSTOMIZE_BASE_PATH} ${MUNITOR_KUSTOMIZE_LOAD_RESTRICTOR} ${MUNITOR_KUSTOMIZE_SCAN_OVERLAY} ${MUNITOR_KUSTOMIZE_OVERLAYS} ${MUNITOR_KUSTOMIZE_OVERLAY_DIR} ${MUNITOR_KUBE_LINTER_CONFIG} ${MUNITOR_YAMLLINT_PATHS} ${MUNITOR_CI_EMAIL} ${MUNITOR_CI_NAME} ${MUNITOR_NPM_DEFAULT_SCOPE} ${MUNITOR_ORB_SLUG} ${MUNITOR_PACKAGE_MANAGER} ${MUNITOR_SUPPLEMENTAL_IMAGES_JSON} ${MUNITOR_SERVER_MODULE}'
|
||||
}
|
||||
@@ -70,7 +70,7 @@ validate_required_fields() {
|
||||
[[ -z "$(yq '.orb_version // ""' "${config}")" ]] && missing+=("orb_version")
|
||||
|
||||
case "${pipeline}" in
|
||||
java-webapp|node-api|node-webapp)
|
||||
java-webapp|gradle-webapp|node-api|node-webapp)
|
||||
[[ -z "$(yq '.image_name // ""' "${config}")" ]] && missing+=("image_name")
|
||||
[[ -z "$(yq '.docker.registry // ""' "${config}")" ]] && missing+=("docker.registry")
|
||||
;;
|
||||
@@ -94,7 +94,7 @@ validate_required_fields "${PIPELINE_TYPE}" "${CONFIG_FILE}"
|
||||
# --------------------------------------------------------------------------
|
||||
# Warn about unknown top-level keys (catches typos like java_verion)
|
||||
# --------------------------------------------------------------------------
|
||||
KNOWN_KEYS="pipeline orb_version image_name java_version node_version sonar docker cd coverage e2e sbom owasp contexts npm node services test terraform sast health kustomize kube_linter_config package_manager yamllint_paths supplemental_images"
|
||||
KNOWN_KEYS="pipeline orb_version image_name server_module java_version node_version sonar docker cd coverage e2e sbom owasp contexts npm node services test terraform sast health kustomize kube_linter_config package_manager yamllint_paths supplemental_images"
|
||||
ACTUAL_KEYS=$(yq 'keys | .[]' "${CONFIG_FILE}" 2>/dev/null || true)
|
||||
for key in ${ACTUAL_KEYS}; do
|
||||
if ! echo "${KNOWN_KEYS}" | grep -qw "${key}"; then
|
||||
|
||||
@@ -141,6 +141,54 @@ ENV JAVA_OPTS="-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0 -XX:+ExitOnOut
|
||||
|
||||
EXPOSE ${MUNITOR_HEALTH_PORT}
|
||||
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \\
|
||||
CMD wget --no-verbose --tries=1 --spider http://localhost:${MUNITOR_HEALTH_PORT}${MUNITOR_HEALTH_PATH} || exit 1
|
||||
|
||||
ENTRYPOINT ["sh", "-c", "java \$JAVA_OPTS -jar app.jar"]
|
||||
DOCKERFILE
|
||||
;;
|
||||
|
||||
gradle-webapp)
|
||||
echo "Generating Dockerfile for gradle-webapp (java ${MUNITOR_JAVA_VERSION})"
|
||||
|
||||
# Find the shadow JAR in the server module's build output
|
||||
SEARCH_DIR="build/libs"
|
||||
if [[ -n "${MUNITOR_SERVER_MODULE:-}" ]]; then
|
||||
SEARCH_DIR="${MUNITOR_SERVER_MODULE}/build/libs"
|
||||
fi
|
||||
|
||||
APP_JAR=$(find "${SEARCH_DIR}" -maxdepth 1 -name "*.jar" \
|
||||
! -name "*-plain.jar" ! -name "*-sources.jar" ! -name "*-javadoc.jar" \
|
||||
2>/dev/null | head -1) || true
|
||||
|
||||
if [[ -z "${APP_JAR}" ]]; then
|
||||
echo "ERROR: No application JAR found in ${SEARCH_DIR}/" >&2
|
||||
echo "Ensure shadowJar or bootJar is configured in build.gradle.kts" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Using JAR: ${APP_JAR}"
|
||||
|
||||
cat > Dockerfile <<DOCKERFILE
|
||||
FROM eclipse-temurin:${MUNITOR_JAVA_VERSION}-jre-alpine
|
||||
|
||||
RUN apk update && apk upgrade --no-cache
|
||||
|
||||
RUN addgroup -g 1001 -S appgroup && \\
|
||||
adduser -u 1001 -S appuser -G appgroup
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY ${APP_JAR} app.jar
|
||||
|
||||
RUN chown -R appuser:appgroup /app
|
||||
|
||||
USER appuser
|
||||
|
||||
ENV JAVA_OPTS="-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0 -XX:+ExitOnOutOfMemoryError"
|
||||
|
||||
EXPOSE ${MUNITOR_HEALTH_PORT}
|
||||
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \\
|
||||
CMD wget --no-verbose --tries=1 --spider http://localhost:${MUNITOR_HEALTH_PORT}${MUNITOR_HEALTH_PATH} || exit 1
|
||||
|
||||
|
||||
Executable
+30
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Source shared helpers
|
||||
MUNITOR_HELPERS="${MUNITOR_HELPERS:-$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)/munitor_helpers.sh}"
|
||||
# shellcheck source=munitor_helpers.sh
|
||||
if [[ -f "${MUNITOR_HELPERS}" ]]; then source "${MUNITOR_HELPERS}"
|
||||
elif ! type munitor_header &>/dev/null; then
|
||||
munitor_header() { echo "=== Munitor: ${1:-unknown} ==="; }
|
||||
munitor_check_tool() { command -v "$1" &>/dev/null || { echo "ERROR: $1 not found"; exit 1; }; }
|
||||
munitor_download_with_retry() { curl -fsSL --retry 3 "$1" -o "$2"; }
|
||||
fi
|
||||
|
||||
munitor_header "gradle_build"
|
||||
|
||||
if [[ ! -f "./gradlew" ]]; then
|
||||
echo "ERROR: ./gradlew not found. Ensure the Gradle wrapper is present."
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -x "./gradlew" ]]; then
|
||||
chmod +x ./gradlew
|
||||
fi
|
||||
|
||||
munitor_check_tool java -version
|
||||
|
||||
echo "Running Gradle build..."
|
||||
|
||||
./gradlew build -x test --no-daemon --console=plain
|
||||
|
||||
echo "Gradle build complete."
|
||||
Executable
+34
@@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Source shared helpers
|
||||
MUNITOR_HELPERS="${MUNITOR_HELPERS:-$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)/munitor_helpers.sh}"
|
||||
# shellcheck source=munitor_helpers.sh
|
||||
if [[ -f "${MUNITOR_HELPERS}" ]]; then source "${MUNITOR_HELPERS}"
|
||||
elif ! type munitor_header &>/dev/null; then
|
||||
munitor_header() { echo "=== Munitor: ${1:-unknown} ==="; }
|
||||
munitor_check_tool() { command -v "$1" &>/dev/null || { echo "ERROR: $1 not found"; exit 1; }; }
|
||||
munitor_download_with_retry() { curl -fsSL --retry 3 "$1" -o "$2"; }
|
||||
fi
|
||||
|
||||
munitor_header "gradle_checkstyle"
|
||||
|
||||
if [[ ! -f "./gradlew" ]]; then
|
||||
echo "ERROR: ./gradlew not found. Ensure the Gradle wrapper is present."
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -x "./gradlew" ]]; then
|
||||
chmod +x ./gradlew
|
||||
fi
|
||||
|
||||
# Detect if checkstyle plugin is applied
|
||||
if ! ./gradlew tasks --all 2>/dev/null | grep -q "checkstyleMain"; then
|
||||
echo "Checkstyle plugin not applied, skipping."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Running Checkstyle..."
|
||||
|
||||
./gradlew checkstyleMain checkstyleTest --no-daemon --console=plain
|
||||
|
||||
echo "Checkstyle passed."
|
||||
Executable
+91
@@ -0,0 +1,91 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Source shared helpers
|
||||
MUNITOR_HELPERS="${MUNITOR_HELPERS:-$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)/munitor_helpers.sh}"
|
||||
# shellcheck source=munitor_helpers.sh
|
||||
if [[ -f "${MUNITOR_HELPERS}" ]]; then source "${MUNITOR_HELPERS}"
|
||||
elif ! type munitor_header &>/dev/null; then
|
||||
munitor_header() { echo "=== Munitor: ${1:-unknown} ==="; }
|
||||
munitor_check_tool() { command -v "$1" &>/dev/null || { echo "ERROR: $1 not found"; exit 1; }; }
|
||||
munitor_download_with_retry() { curl -fsSL --retry 3 "$1" -o "$2"; }
|
||||
fi
|
||||
|
||||
MIN="${MIN_INSTRUCTION:-70}"
|
||||
|
||||
munitor_header "gradle_jacoco (min: ${MIN}%)"
|
||||
|
||||
# Validate MIN_INSTRUCTION is numeric
|
||||
if ! [[ "${MIN}" =~ ^[0-9]+$ ]]; then
|
||||
echo "ERROR: MIN_INSTRUCTION must be a whole number, got '${MIN}'."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -f "./gradlew" ]]; then
|
||||
echo "ERROR: ./gradlew not found. Ensure the Gradle wrapper is present."
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -x "./gradlew" ]]; then
|
||||
chmod +x ./gradlew
|
||||
fi
|
||||
|
||||
echo "Generating JaCoCo report..."
|
||||
|
||||
./gradlew jacocoTestReport --no-daemon --console=plain
|
||||
|
||||
# Show what JaCoCo produced for diagnostics
|
||||
echo ""
|
||||
echo "Searching for JaCoCo reports..."
|
||||
find . -path "*/build/reports/jacoco" -type d 2>/dev/null | while read -r dir; do
|
||||
echo " Found: ${dir}/"
|
||||
for f in "${dir}"/test/*; do
|
||||
[[ -e "${f}" ]] && echo " $(basename "${f}")"
|
||||
done
|
||||
done
|
||||
|
||||
# Find ALL CSV report files across all subprojects
|
||||
CSV_FILES=$(find . -path "*/build/reports/jacoco/test/jacocoTestReport.csv" -type f)
|
||||
|
||||
if [[ -z "${CSV_FILES}" ]]; then
|
||||
echo ""
|
||||
echo "ERROR: No JaCoCo CSV reports found."
|
||||
echo ""
|
||||
echo "Gradle does not generate CSV reports by default. Add this to your"
|
||||
echo "build.gradle.kts (in each module or via allprojects/subprojects):"
|
||||
echo ""
|
||||
echo ' tasks.jacocoTestReport {'
|
||||
echo ' dependsOn(tasks.test)'
|
||||
echo ' reports {'
|
||||
echo ' csv.required.set(true)'
|
||||
echo ' }'
|
||||
echo ' }'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Found CSV reports:"
|
||||
echo "${CSV_FILES}" | sed 's/^/ /'
|
||||
|
||||
# Parse CSV: sum INSTRUCTION_MISSED (col 4) and INSTRUCTION_COVERED (col 5) across ALL files
|
||||
# CSV header: GROUP,PACKAGE,CLASS,INSTRUCTION_MISSED,INSTRUCTION_COVERED,...
|
||||
read -r MISSED COVERED <<< "$(awk -F',' 'NR>1 { m+=$4; c+=$5 } END { print m, c }' ${CSV_FILES})"
|
||||
|
||||
TOTAL=$((MISSED + COVERED))
|
||||
|
||||
if [[ "${TOTAL}" -eq 0 ]]; then
|
||||
echo "WARNING: No instruction data found in JaCoCo report (0 instructions total)."
|
||||
echo "JaCoCo coverage: N/A (no code to measure)"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Calculate percentage (integer arithmetic, truncated)
|
||||
PCT=$((COVERED * 100 / TOTAL))
|
||||
|
||||
echo "JaCoCo coverage: ${PCT}% (${COVERED}/${TOTAL} instructions covered, minimum: ${MIN}%)"
|
||||
|
||||
if [[ "${PCT}" -lt "${MIN}" ]]; then
|
||||
echo "FAILED: Coverage ${PCT}% is below minimum threshold of ${MIN}%."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "JaCoCo coverage passed (>= ${MIN}%)."
|
||||
Executable
+34
@@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Source shared helpers
|
||||
MUNITOR_HELPERS="${MUNITOR_HELPERS:-$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)/munitor_helpers.sh}"
|
||||
# shellcheck source=munitor_helpers.sh
|
||||
if [[ -f "${MUNITOR_HELPERS}" ]]; then source "${MUNITOR_HELPERS}"
|
||||
elif ! type munitor_header &>/dev/null; then
|
||||
munitor_header() { echo "=== Munitor: ${1:-unknown} ==="; }
|
||||
munitor_check_tool() { command -v "$1" &>/dev/null || { echo "ERROR: $1 not found"; exit 1; }; }
|
||||
munitor_download_with_retry() { curl -fsSL --retry 3 "$1" -o "$2"; }
|
||||
fi
|
||||
|
||||
munitor_header "gradle_pmd"
|
||||
|
||||
if [[ ! -f "./gradlew" ]]; then
|
||||
echo "ERROR: ./gradlew not found. Ensure the Gradle wrapper is present."
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -x "./gradlew" ]]; then
|
||||
chmod +x ./gradlew
|
||||
fi
|
||||
|
||||
# Detect if pmd plugin is applied
|
||||
if ! ./gradlew tasks --all 2>/dev/null | grep -q "pmdMain"; then
|
||||
echo "PMD plugin not applied, skipping."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Running PMD..."
|
||||
|
||||
./gradlew pmdMain --no-daemon --console=plain
|
||||
|
||||
echo "PMD passed."
|
||||
Executable
+34
@@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Source shared helpers
|
||||
MUNITOR_HELPERS="${MUNITOR_HELPERS:-$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)/munitor_helpers.sh}"
|
||||
# shellcheck source=munitor_helpers.sh
|
||||
if [[ -f "${MUNITOR_HELPERS}" ]]; then source "${MUNITOR_HELPERS}"
|
||||
elif ! type munitor_header &>/dev/null; then
|
||||
munitor_header() { echo "=== Munitor: ${1:-unknown} ==="; }
|
||||
munitor_check_tool() { command -v "$1" &>/dev/null || { echo "ERROR: $1 not found"; exit 1; }; }
|
||||
munitor_download_with_retry() { curl -fsSL --retry 3 "$1" -o "$2"; }
|
||||
fi
|
||||
|
||||
munitor_header "gradle_spotbugs"
|
||||
|
||||
if [[ ! -f "./gradlew" ]]; then
|
||||
echo "ERROR: ./gradlew not found. Ensure the Gradle wrapper is present."
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -x "./gradlew" ]]; then
|
||||
chmod +x ./gradlew
|
||||
fi
|
||||
|
||||
# Detect if spotbugs plugin is applied
|
||||
if ! ./gradlew tasks --all 2>/dev/null | grep -q "spotbugsMain"; then
|
||||
echo "SpotBugs plugin not applied, skipping."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Running SpotBugs..."
|
||||
|
||||
./gradlew spotbugsMain --no-daemon --console=plain
|
||||
|
||||
echo "SpotBugs passed."
|
||||
Executable
+28
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Source shared helpers
|
||||
MUNITOR_HELPERS="${MUNITOR_HELPERS:-$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)/munitor_helpers.sh}"
|
||||
# shellcheck source=munitor_helpers.sh
|
||||
if [[ -f "${MUNITOR_HELPERS}" ]]; then source "${MUNITOR_HELPERS}"
|
||||
elif ! type munitor_header &>/dev/null; then
|
||||
munitor_header() { echo "=== Munitor: ${1:-unknown} ==="; }
|
||||
munitor_check_tool() { command -v "$1" &>/dev/null || { echo "ERROR: $1 not found"; exit 1; }; }
|
||||
munitor_download_with_retry() { curl -fsSL --retry 3 "$1" -o "$2"; }
|
||||
fi
|
||||
|
||||
munitor_header "gradle_test"
|
||||
|
||||
if [[ ! -f "./gradlew" ]]; then
|
||||
echo "ERROR: ./gradlew not found. Ensure the Gradle wrapper is present."
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -x "./gradlew" ]]; then
|
||||
chmod +x ./gradlew
|
||||
fi
|
||||
|
||||
echo "Running Gradle tests..."
|
||||
|
||||
./gradlew test --no-daemon --console=plain
|
||||
|
||||
echo "Gradle tests complete."
|
||||
@@ -110,17 +110,23 @@ extract_munitor_vars() {
|
||||
fi
|
||||
|
||||
# --- Org defaults (overridable via .munitor.yml org section) ---
|
||||
local ORG_DOCKER_REGISTRY=$(yq '.org.docker_registry // "ghcr.io/KofTwentyTwo"' "${config_file}")
|
||||
local ORG_NPM_SCOPE=$(yq '.org.npm_scope // "@koftwentytwo"' "${config_file}")
|
||||
local ORG_CI_EMAIL=$(yq '.org.ci_email // "munitor-ci@koftwentytwo.com"' "${config_file}")
|
||||
local ORG_CI_NAME=$(yq '.org.ci_name // "Munitor CI"' "${config_file}")
|
||||
local ORG_ORB_SLUG=$(yq '.org.orb_slug // "kof22/munitor"' "${config_file}")
|
||||
local ORG_DOCKER_REGISTRY
|
||||
ORG_DOCKER_REGISTRY=$(yq '.org.docker_registry // "ghcr.io/KofTwentyTwo"' "${config_file}")
|
||||
local ORG_NPM_SCOPE
|
||||
ORG_NPM_SCOPE=$(yq '.org.npm_scope // "@koftwentytwo"' "${config_file}")
|
||||
local ORG_CI_EMAIL
|
||||
ORG_CI_EMAIL=$(yq '.org.ci_email // "munitor-ci@koftwentytwo.com"' "${config_file}")
|
||||
local ORG_CI_NAME
|
||||
ORG_CI_NAME=$(yq '.org.ci_name // "Munitor CI"' "${config_file}")
|
||||
local ORG_ORB_SLUG
|
||||
ORG_ORB_SLUG=$(yq '.org.orb_slug // "kof22/munitor"' "${config_file}")
|
||||
|
||||
# Core pipeline settings
|
||||
MUNITOR_PIPELINE=$(yq '.pipeline' "${config_file}")
|
||||
MUNITOR_ORB_VERSION=$(yq '.orb_version // ""' "${config_file}")
|
||||
MUNITOR_IMAGE_NAME=$(yq '.image_name // ""' "${config_file}")
|
||||
MUNITOR_JAVA_VERSION=$(yq '.java_version // "21"' "${config_file}")
|
||||
MUNITOR_SERVER_MODULE=$(yq '.server_module // ""' "${config_file}")
|
||||
MUNITOR_NODE_VERSION=$(yq '.node_version // "20"' "${config_file}")
|
||||
MUNITOR_SONAR_PROJECT_KEY=$(yq '.sonar.project_key // ""' "${config_file}")
|
||||
MUNITOR_DOCKER_REGISTRY=$(yq '.docker.registry // ""' "${config_file}")
|
||||
@@ -261,9 +267,13 @@ extract_munitor_vars() {
|
||||
esac
|
||||
fi
|
||||
MUNITOR_HEALTH_DB=$(yq '.health.db // false' "${config_file}")
|
||||
MUNITOR_HEALTH_MIGRATIONS=$(yq '.health.migrations // ""' "${config_file}")
|
||||
if [[ "${MUNITOR_HEALTH_MIGRATIONS}" == "null" ]]; then MUNITOR_HEALTH_MIGRATIONS=""; fi
|
||||
MUNITOR_HEALTH_SMOKE_PATHS=$(yq '.health.smoke_paths // [] | join(",")' "${config_file}")
|
||||
if [[ "${MUNITOR_HEALTH_SMOKE_PATHS}" == "null" ]]; then MUNITOR_HEALTH_SMOKE_PATHS=""; fi
|
||||
|
||||
# Supplemental images (e.g., migrations, db-backup)
|
||||
MUNITOR_SUPPLEMENTAL_IMAGES_JSON=$(yq '.supplemental_images // [] | tojson' "${config_file}")
|
||||
MUNITOR_SUPPLEMENTAL_IMAGES_JSON=$(yq -o=json -I=0 '.supplemental_images // []' "${config_file}")
|
||||
if [[ "${MUNITOR_SUPPLEMENTAL_IMAGES_JSON}" == "[]" || "${MUNITOR_SUPPLEMENTAL_IMAGES_JSON}" == "null" ]]; then
|
||||
MUNITOR_SUPPLEMENTAL="false"
|
||||
MUNITOR_SUPPLEMENTAL_IMAGES_JSON="[]"
|
||||
@@ -291,7 +301,7 @@ extract_munitor_vars() {
|
||||
fi
|
||||
|
||||
# Export all variables
|
||||
export MUNITOR_PIPELINE MUNITOR_ORB_VERSION MUNITOR_IMAGE_NAME MUNITOR_JAVA_VERSION MUNITOR_NODE_VERSION
|
||||
export MUNITOR_PIPELINE MUNITOR_ORB_VERSION MUNITOR_IMAGE_NAME MUNITOR_JAVA_VERSION MUNITOR_NODE_VERSION MUNITOR_SERVER_MODULE
|
||||
export MUNITOR_SONAR_PROJECT_KEY MUNITOR_DOCKER_REGISTRY MUNITOR_CD_REPO MUNITOR_CD_FORMAT
|
||||
export MUNITOR_CD_ENV_DEVELOP MUNITOR_CD_ENV_STAGING MUNITOR_CD_ENV_PROD MUNITOR_CD_ENV_RELEASE
|
||||
export MUNITOR_COVERAGE_MIN MUNITOR_E2E MUNITOR_SBOM MUNITOR_OWASP
|
||||
@@ -308,7 +318,7 @@ extract_munitor_vars() {
|
||||
export MUNITOR_KUBE_LINTER_CONFIG MUNITOR_YAMLLINT_PATHS
|
||||
export MUNITOR_NODE_FRAMEWORK MUNITOR_PACKAGE_MANAGER
|
||||
export MUNITOR_CI_EMAIL MUNITOR_CI_NAME MUNITOR_NPM_DEFAULT_SCOPE MUNITOR_ORB_SLUG
|
||||
export MUNITOR_HEALTH_PATH MUNITOR_HEALTH_PORT MUNITOR_HEALTH_DB
|
||||
export MUNITOR_HEALTH_PATH MUNITOR_HEALTH_PORT MUNITOR_HEALTH_DB MUNITOR_HEALTH_MIGRATIONS MUNITOR_HEALTH_SMOKE_PATHS
|
||||
export MUNITOR_SUPPLEMENTAL MUNITOR_SUPPLEMENTAL_IMAGES_JSON
|
||||
export MUNITOR_SONAR MUNITOR_CD MUNITOR_NVD
|
||||
}
|
||||
@@ -316,7 +326,7 @@ extract_munitor_vars() {
|
||||
# Build the envsubst variable list
|
||||
get_envsubst_vars() {
|
||||
# shellcheck disable=SC2016
|
||||
echo '${MUNITOR_PIPELINE} ${MUNITOR_ORB_VERSION} ${MUNITOR_IMAGE_NAME} ${MUNITOR_JAVA_VERSION} ${MUNITOR_NODE_VERSION} ${MUNITOR_SONAR_PROJECT_KEY} ${MUNITOR_DOCKER_REGISTRY} ${MUNITOR_CD_REPO} ${MUNITOR_CD_FORMAT} ${MUNITOR_CD_ENV_DEVELOP} ${MUNITOR_CD_ENV_STAGING} ${MUNITOR_CD_ENV_PROD} ${MUNITOR_CD_ENV_RELEASE} ${MUNITOR_COVERAGE_MIN} ${MUNITOR_E2E} ${MUNITOR_SBOM} ${MUNITOR_OWASP} ${MUNITOR_CONTEXT_REGISTRY} ${MUNITOR_CONTEXT_GITHUB} ${MUNITOR_CONTEXT_SONAR} ${MUNITOR_CONTEXT_NVD} ${MUNITOR_NPM_AUTH} ${MUNITOR_NPM_SCOPES} ${MUNITOR_SERVICES_JSON} ${MUNITOR_TEST_SETUP_SCRIPT} ${MUNITOR_TEST_COMMANDS_JSON} ${MUNITOR_COVERAGE_TOOL} ${MUNITOR_COVERAGE_COMMAND} ${MUNITOR_GITHUB_RELEASE} ${MUNITOR_SAST} ${MUNITOR_SAST_FAIL_ON_FINDINGS} ${MUNITOR_HEALTH_PATH} ${MUNITOR_HEALTH_PORT} ${MUNITOR_HEALTH_DB} ${MUNITOR_TF_PATH} ${MUNITOR_TF_LIVE_PATH} ${MUNITOR_TF_ENVIRONMENTS} ${MUNITOR_CHECKOV_SKIP} ${MUNITOR_KUSTOMIZE_VERSION} ${MUNITOR_KUSTOMIZE_BASE_PATH} ${MUNITOR_KUSTOMIZE_LOAD_RESTRICTOR} ${MUNITOR_KUSTOMIZE_SCAN_OVERLAY} ${MUNITOR_KUSTOMIZE_OVERLAYS} ${MUNITOR_KUSTOMIZE_OVERLAY_DIR} ${MUNITOR_KUBE_LINTER_CONFIG} ${MUNITOR_YAMLLINT_PATHS} ${MUNITOR_CI_EMAIL} ${MUNITOR_CI_NAME} ${MUNITOR_NPM_DEFAULT_SCOPE} ${MUNITOR_ORB_SLUG} ${MUNITOR_PACKAGE_MANAGER} ${MUNITOR_SUPPLEMENTAL_IMAGES_JSON}'
|
||||
echo '${MUNITOR_PIPELINE} ${MUNITOR_ORB_VERSION} ${MUNITOR_IMAGE_NAME} ${MUNITOR_JAVA_VERSION} ${MUNITOR_NODE_VERSION} ${MUNITOR_SONAR_PROJECT_KEY} ${MUNITOR_DOCKER_REGISTRY} ${MUNITOR_CD_REPO} ${MUNITOR_CD_FORMAT} ${MUNITOR_CD_ENV_DEVELOP} ${MUNITOR_CD_ENV_STAGING} ${MUNITOR_CD_ENV_PROD} ${MUNITOR_CD_ENV_RELEASE} ${MUNITOR_COVERAGE_MIN} ${MUNITOR_E2E} ${MUNITOR_SBOM} ${MUNITOR_OWASP} ${MUNITOR_CONTEXT_REGISTRY} ${MUNITOR_CONTEXT_GITHUB} ${MUNITOR_CONTEXT_SONAR} ${MUNITOR_CONTEXT_NVD} ${MUNITOR_NPM_AUTH} ${MUNITOR_NPM_SCOPES} ${MUNITOR_SERVICES_JSON} ${MUNITOR_TEST_SETUP_SCRIPT} ${MUNITOR_TEST_COMMANDS_JSON} ${MUNITOR_COVERAGE_TOOL} ${MUNITOR_COVERAGE_COMMAND} ${MUNITOR_GITHUB_RELEASE} ${MUNITOR_SAST} ${MUNITOR_SAST_FAIL_ON_FINDINGS} ${MUNITOR_HEALTH_PATH} ${MUNITOR_HEALTH_PORT} ${MUNITOR_HEALTH_DB} ${MUNITOR_HEALTH_MIGRATIONS} ${MUNITOR_HEALTH_SMOKE_PATHS} ${MUNITOR_TF_PATH} ${MUNITOR_TF_LIVE_PATH} ${MUNITOR_TF_ENVIRONMENTS} ${MUNITOR_CHECKOV_SKIP} ${MUNITOR_KUSTOMIZE_VERSION} ${MUNITOR_KUSTOMIZE_BASE_PATH} ${MUNITOR_KUSTOMIZE_LOAD_RESTRICTOR} ${MUNITOR_KUSTOMIZE_SCAN_OVERLAY} ${MUNITOR_KUSTOMIZE_OVERLAYS} ${MUNITOR_KUSTOMIZE_OVERLAY_DIR} ${MUNITOR_KUBE_LINTER_CONFIG} ${MUNITOR_YAMLLINT_PATHS} ${MUNITOR_CI_EMAIL} ${MUNITOR_CI_NAME} ${MUNITOR_NPM_DEFAULT_SCOPE} ${MUNITOR_ORB_SLUG} ${MUNITOR_PACKAGE_MANAGER} ${MUNITOR_SUPPLEMENTAL_IMAGES_JSON} ${MUNITOR_SERVER_MODULE}'
|
||||
}
|
||||
MUNITOR_EXTRACT_EOF
|
||||
|
||||
@@ -500,6 +510,8 @@ workflows:
|
||||
health_path: ${MUNITOR_HEALTH_PATH}
|
||||
health_port: "${MUNITOR_HEALTH_PORT}"
|
||||
health_db: "${MUNITOR_HEALTH_DB}"
|
||||
health_migrations: "${MUNITOR_HEALTH_MIGRATIONS}"
|
||||
health_smoke_paths: "${MUNITOR_HEALTH_SMOKE_PATHS}"
|
||||
##IF_SUPPLEMENTAL##
|
||||
supplemental_images: '${MUNITOR_SUPPLEMENTAL_IMAGES_JSON}'
|
||||
##ENDIF_SUPPLEMENTAL##
|
||||
@@ -595,6 +607,330 @@ workflows:
|
||||
health_path: ${MUNITOR_HEALTH_PATH}
|
||||
health_port: "${MUNITOR_HEALTH_PORT}"
|
||||
health_db: "${MUNITOR_HEALTH_DB}"
|
||||
health_migrations: "${MUNITOR_HEALTH_MIGRATIONS}"
|
||||
health_smoke_paths: "${MUNITOR_HEALTH_SMOKE_PATHS}"
|
||||
##IF_SUPPLEMENTAL##
|
||||
supplemental_images: '${MUNITOR_SUPPLEMENTAL_IMAGES_JSON}'
|
||||
##ENDIF_SUPPLEMENTAL##
|
||||
requires:
|
||||
- build-and-test
|
||||
context:
|
||||
- ${MUNITOR_CONTEXT_REGISTRY}
|
||||
filters:
|
||||
branches:
|
||||
only: main
|
||||
##IF_CD##
|
||||
- munitor/update_cd_repo:
|
||||
name: update-cd-repo
|
||||
cd_repo: ${MUNITOR_CD_REPO}
|
||||
environment: ${MUNITOR_CD_ENV_PROD}
|
||||
cd_format: ${MUNITOR_CD_FORMAT}
|
||||
cd_image_name: ${MUNITOR_DOCKER_REGISTRY}/${MUNITOR_IMAGE_NAME}
|
||||
##IF_SUPPLEMENTAL##
|
||||
supplemental_images: '${MUNITOR_SUPPLEMENTAL_IMAGES_JSON}'
|
||||
##ENDIF_SUPPLEMENTAL##
|
||||
ci_git_email: '${MUNITOR_CI_EMAIL}'
|
||||
ci_git_name: '${MUNITOR_CI_NAME}'
|
||||
requires:
|
||||
- docker-build-push
|
||||
context:
|
||||
- ${MUNITOR_CONTEXT_GITHUB}
|
||||
filters:
|
||||
branches:
|
||||
only: main
|
||||
##ENDIF_CD##
|
||||
##IF_GITHUB_RELEASE##
|
||||
- munitor/github_release:
|
||||
name: github-release
|
||||
requires:
|
||||
- docker-build-push
|
||||
context:
|
||||
- ${MUNITOR_CONTEXT_GITHUB}
|
||||
filters:
|
||||
branches:
|
||||
only: main
|
||||
##ENDIF_GITHUB_RELEASE##
|
||||
MUNITOR_TPL_EOF
|
||||
|
||||
cat > /tmp/munitor/templates/gradle-webapp.yml.tpl << 'MUNITOR_TPL_EOF'
|
||||
version: 2.1
|
||||
|
||||
orbs:
|
||||
munitor: ${MUNITOR_ORB_SLUG}@${MUNITOR_ORB_VERSION}
|
||||
|
||||
workflows:
|
||||
pr-checks:
|
||||
jobs:
|
||||
- munitor/gradle_build_and_test:
|
||||
name: build-and-test
|
||||
java_version: "${MUNITOR_JAVA_VERSION}"
|
||||
context:
|
||||
- ${MUNITOR_CONTEXT_GITHUB}
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /feature\/.*/
|
||||
- /hotfix\/.*/
|
||||
- munitor/secrets_scan:
|
||||
name: secrets-scan
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /feature\/.*/
|
||||
- /hotfix\/.*/
|
||||
- munitor/sast_scan:
|
||||
name: sast-scan
|
||||
fail_on_findings: "${MUNITOR_SAST_FAIL_ON_FINDINGS}"
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /feature\/.*/
|
||||
- /hotfix\/.*/
|
||||
- munitor/gradle_code_quality:
|
||||
name: code-quality
|
||||
java_version: "${MUNITOR_JAVA_VERSION}"
|
||||
requires:
|
||||
- build-and-test
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /feature\/.*/
|
||||
- /hotfix\/.*/
|
||||
- munitor/gradle_coverage:
|
||||
name: coverage
|
||||
java_version: "${MUNITOR_JAVA_VERSION}"
|
||||
min_instruction: "${MUNITOR_COVERAGE_MIN}"
|
||||
requires:
|
||||
- build-and-test
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /feature\/.*/
|
||||
- /hotfix\/.*/
|
||||
- munitor/security_scan:
|
||||
name: security-scan
|
||||
java_version: "${MUNITOR_JAVA_VERSION}"
|
||||
owasp: ${MUNITOR_OWASP}
|
||||
##IF_OWASP##
|
||||
##IF_NVD##
|
||||
context:
|
||||
- ${MUNITOR_CONTEXT_NVD}
|
||||
##ENDIF_NVD##
|
||||
##ENDIF_OWASP##
|
||||
requires:
|
||||
- build-and-test
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /feature\/.*/
|
||||
- /hotfix\/.*/
|
||||
##IF_E2E##
|
||||
- munitor/mvn_e2e_test:
|
||||
name: e2e-tests
|
||||
java_version: "${MUNITOR_JAVA_VERSION}"
|
||||
requires:
|
||||
- build-and-test
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /feature\/.*/
|
||||
- /hotfix\/.*/
|
||||
##ENDIF_E2E##
|
||||
|
||||
##INCLUDE_DEPLOY gradle-webapp-deploy develop develop ${MUNITOR_CD_ENV_DEVELOP}##
|
||||
##INCLUDE_DEPLOY gradle-webapp-deploy staging staging ${MUNITOR_CD_ENV_STAGING}##
|
||||
|
||||
release-candidate:
|
||||
jobs:
|
||||
- munitor/gradle_build_and_test:
|
||||
name: build-and-test
|
||||
java_version: "${MUNITOR_JAVA_VERSION}"
|
||||
context:
|
||||
- ${MUNITOR_CONTEXT_GITHUB}
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /release\/.*/
|
||||
- munitor/secrets_scan:
|
||||
name: secrets-scan
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /release\/.*/
|
||||
- munitor/sast_scan:
|
||||
name: sast-scan
|
||||
fail_on_findings: "${MUNITOR_SAST_FAIL_ON_FINDINGS}"
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /release\/.*/
|
||||
- munitor/gradle_code_quality:
|
||||
name: code-quality
|
||||
java_version: "${MUNITOR_JAVA_VERSION}"
|
||||
requires:
|
||||
- build-and-test
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /release\/.*/
|
||||
- munitor/gradle_coverage:
|
||||
name: coverage
|
||||
java_version: "${MUNITOR_JAVA_VERSION}"
|
||||
min_instruction: "${MUNITOR_COVERAGE_MIN}"
|
||||
requires:
|
||||
- build-and-test
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /release\/.*/
|
||||
- munitor/security_scan:
|
||||
name: security-scan
|
||||
java_version: "${MUNITOR_JAVA_VERSION}"
|
||||
owasp: ${MUNITOR_OWASP}
|
||||
##IF_OWASP##
|
||||
##IF_NVD##
|
||||
context:
|
||||
- ${MUNITOR_CONTEXT_NVD}
|
||||
##ENDIF_NVD##
|
||||
##ENDIF_OWASP##
|
||||
requires:
|
||||
- build-and-test
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /release\/.*/
|
||||
##IF_E2E##
|
||||
- munitor/mvn_e2e_test:
|
||||
name: e2e-tests
|
||||
java_version: "${MUNITOR_JAVA_VERSION}"
|
||||
requires:
|
||||
- build-and-test
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /release\/.*/
|
||||
##ENDIF_E2E##
|
||||
##IF_SONAR##
|
||||
- munitor/sonar_scan:
|
||||
name: sonar-scan
|
||||
java_version: "${MUNITOR_JAVA_VERSION}"
|
||||
sonar_project_key: ${MUNITOR_SONAR_PROJECT_KEY}
|
||||
requires:
|
||||
- build-and-test
|
||||
- coverage
|
||||
context:
|
||||
- ${MUNITOR_CONTEXT_SONAR}
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /release\/.*/
|
||||
##ENDIF_SONAR##
|
||||
- munitor/docker_build_push:
|
||||
name: docker-build-push
|
||||
image_name: ${MUNITOR_IMAGE_NAME}
|
||||
registry: ${MUNITOR_DOCKER_REGISTRY}
|
||||
health_path: ${MUNITOR_HEALTH_PATH}
|
||||
health_port: "${MUNITOR_HEALTH_PORT}"
|
||||
health_db: "${MUNITOR_HEALTH_DB}"
|
||||
health_migrations: "${MUNITOR_HEALTH_MIGRATIONS}"
|
||||
health_smoke_paths: "${MUNITOR_HEALTH_SMOKE_PATHS}"
|
||||
##IF_SUPPLEMENTAL##
|
||||
supplemental_images: '${MUNITOR_SUPPLEMENTAL_IMAGES_JSON}'
|
||||
##ENDIF_SUPPLEMENTAL##
|
||||
requires:
|
||||
- code-quality
|
||||
- coverage
|
||||
- secrets-scan
|
||||
- sast-scan
|
||||
- security-scan
|
||||
##IF_SONAR##
|
||||
- sonar-scan
|
||||
##ENDIF_SONAR##
|
||||
##IF_E2E##
|
||||
- e2e-tests
|
||||
##ENDIF_E2E##
|
||||
context:
|
||||
- ${MUNITOR_CONTEXT_REGISTRY}
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /release\/.*/
|
||||
##IF_SBOM##
|
||||
- munitor/sbom:
|
||||
name: sbom
|
||||
java_version: "${MUNITOR_JAVA_VERSION}"
|
||||
context:
|
||||
- ${MUNITOR_CONTEXT_GITHUB}
|
||||
requires:
|
||||
- code-quality
|
||||
- coverage
|
||||
- secrets-scan
|
||||
- sast-scan
|
||||
- security-scan
|
||||
##IF_SONAR##
|
||||
- sonar-scan
|
||||
##ENDIF_SONAR##
|
||||
##IF_E2E##
|
||||
- e2e-tests
|
||||
##ENDIF_E2E##
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /release\/.*/
|
||||
##ENDIF_SBOM##
|
||||
##IF_CD##
|
||||
- munitor/update_cd_repo:
|
||||
name: update-cd-repo
|
||||
cd_repo: ${MUNITOR_CD_REPO}
|
||||
environment: ${MUNITOR_CD_ENV_RELEASE}
|
||||
cd_format: ${MUNITOR_CD_FORMAT}
|
||||
cd_image_name: ${MUNITOR_DOCKER_REGISTRY}/${MUNITOR_IMAGE_NAME}
|
||||
##IF_SUPPLEMENTAL##
|
||||
supplemental_images: '${MUNITOR_SUPPLEMENTAL_IMAGES_JSON}'
|
||||
##ENDIF_SUPPLEMENTAL##
|
||||
ci_git_email: '${MUNITOR_CI_EMAIL}'
|
||||
ci_git_name: '${MUNITOR_CI_NAME}'
|
||||
requires:
|
||||
- docker-build-push
|
||||
context:
|
||||
- ${MUNITOR_CONTEXT_GITHUB}
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /release\/.*/
|
||||
##ENDIF_CD##
|
||||
##IF_GITHUB_RELEASE##
|
||||
- munitor/github_release:
|
||||
name: github-release
|
||||
requires:
|
||||
- docker-build-push
|
||||
context:
|
||||
- ${MUNITOR_CONTEXT_GITHUB}
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /release\/.*/
|
||||
##ENDIF_GITHUB_RELEASE##
|
||||
|
||||
production:
|
||||
jobs:
|
||||
- munitor/gradle_build_and_test:
|
||||
name: build-and-test
|
||||
java_version: "${MUNITOR_JAVA_VERSION}"
|
||||
context:
|
||||
- ${MUNITOR_CONTEXT_GITHUB}
|
||||
filters:
|
||||
branches:
|
||||
only: main
|
||||
- munitor/docker_build_push:
|
||||
name: docker-build-push
|
||||
image_name: ${MUNITOR_IMAGE_NAME}
|
||||
registry: ${MUNITOR_DOCKER_REGISTRY}
|
||||
health_path: ${MUNITOR_HEALTH_PATH}
|
||||
health_port: "${MUNITOR_HEALTH_PORT}"
|
||||
health_db: "${MUNITOR_HEALTH_DB}"
|
||||
health_migrations: "${MUNITOR_HEALTH_MIGRATIONS}"
|
||||
health_smoke_paths: "${MUNITOR_HEALTH_SMOKE_PATHS}"
|
||||
##IF_SUPPLEMENTAL##
|
||||
supplemental_images: '${MUNITOR_SUPPLEMENTAL_IMAGES_JSON}'
|
||||
##ENDIF_SUPPLEMENTAL##
|
||||
@@ -1921,6 +2257,155 @@ cat > /tmp/munitor/templates/partials/java-webapp-deploy.yml.tpl << 'MUNITOR_PAR
|
||||
##ENDIF_CD##
|
||||
MUNITOR_PARTIAL_EOF
|
||||
|
||||
cat > /tmp/munitor/templates/partials/gradle-webapp-deploy.yml.tpl << 'MUNITOR_PARTIAL_EOF'
|
||||
__WORKFLOW_NAME__:
|
||||
jobs:
|
||||
- munitor/gradle_build_and_test:
|
||||
name: build-and-test
|
||||
java_version: "${MUNITOR_JAVA_VERSION}"
|
||||
context:
|
||||
- ${MUNITOR_CONTEXT_GITHUB}
|
||||
filters:
|
||||
branches:
|
||||
only: __BRANCH_FILTER__
|
||||
- munitor/secrets_scan:
|
||||
name: secrets-scan
|
||||
filters:
|
||||
branches:
|
||||
only: __BRANCH_FILTER__
|
||||
- munitor/sast_scan:
|
||||
name: sast-scan
|
||||
fail_on_findings: "${MUNITOR_SAST_FAIL_ON_FINDINGS}"
|
||||
filters:
|
||||
branches:
|
||||
only: __BRANCH_FILTER__
|
||||
- munitor/gradle_code_quality:
|
||||
name: code-quality
|
||||
java_version: "${MUNITOR_JAVA_VERSION}"
|
||||
requires:
|
||||
- build-and-test
|
||||
filters:
|
||||
branches:
|
||||
only: __BRANCH_FILTER__
|
||||
- munitor/gradle_coverage:
|
||||
name: coverage
|
||||
java_version: "${MUNITOR_JAVA_VERSION}"
|
||||
min_instruction: "${MUNITOR_COVERAGE_MIN}"
|
||||
requires:
|
||||
- build-and-test
|
||||
filters:
|
||||
branches:
|
||||
only: __BRANCH_FILTER__
|
||||
- munitor/security_scan:
|
||||
name: security-scan
|
||||
java_version: "${MUNITOR_JAVA_VERSION}"
|
||||
owasp: ${MUNITOR_OWASP}
|
||||
##IF_OWASP##
|
||||
##IF_NVD##
|
||||
context:
|
||||
- ${MUNITOR_CONTEXT_NVD}
|
||||
##ENDIF_NVD##
|
||||
##ENDIF_OWASP##
|
||||
requires:
|
||||
- build-and-test
|
||||
filters:
|
||||
branches:
|
||||
only: __BRANCH_FILTER__
|
||||
##IF_E2E##
|
||||
- munitor/mvn_e2e_test:
|
||||
name: e2e-tests
|
||||
java_version: "${MUNITOR_JAVA_VERSION}"
|
||||
requires:
|
||||
- build-and-test
|
||||
filters:
|
||||
branches:
|
||||
only: __BRANCH_FILTER__
|
||||
##ENDIF_E2E##
|
||||
##IF_SONAR##
|
||||
- munitor/sonar_scan:
|
||||
name: sonar-scan
|
||||
java_version: "${MUNITOR_JAVA_VERSION}"
|
||||
sonar_project_key: ${MUNITOR_SONAR_PROJECT_KEY}
|
||||
requires:
|
||||
- build-and-test
|
||||
- coverage
|
||||
context:
|
||||
- ${MUNITOR_CONTEXT_SONAR}
|
||||
filters:
|
||||
branches:
|
||||
only: __BRANCH_FILTER__
|
||||
##ENDIF_SONAR##
|
||||
- munitor/docker_build_push:
|
||||
name: docker-build-push
|
||||
image_name: ${MUNITOR_IMAGE_NAME}
|
||||
registry: ${MUNITOR_DOCKER_REGISTRY}
|
||||
health_path: ${MUNITOR_HEALTH_PATH}
|
||||
health_port: "${MUNITOR_HEALTH_PORT}"
|
||||
health_db: "${MUNITOR_HEALTH_DB}"
|
||||
##IF_SUPPLEMENTAL##
|
||||
supplemental_images: '${MUNITOR_SUPPLEMENTAL_IMAGES_JSON}'
|
||||
##ENDIF_SUPPLEMENTAL##
|
||||
requires:
|
||||
- code-quality
|
||||
- coverage
|
||||
- secrets-scan
|
||||
- sast-scan
|
||||
- security-scan
|
||||
##IF_SONAR##
|
||||
- sonar-scan
|
||||
##ENDIF_SONAR##
|
||||
##IF_E2E##
|
||||
- e2e-tests
|
||||
##ENDIF_E2E##
|
||||
context:
|
||||
- ${MUNITOR_CONTEXT_REGISTRY}
|
||||
filters:
|
||||
branches:
|
||||
only: __BRANCH_FILTER__
|
||||
##IF_SBOM##
|
||||
- munitor/sbom:
|
||||
name: sbom
|
||||
java_version: "${MUNITOR_JAVA_VERSION}"
|
||||
context:
|
||||
- ${MUNITOR_CONTEXT_GITHUB}
|
||||
requires:
|
||||
- code-quality
|
||||
- coverage
|
||||
- secrets-scan
|
||||
- sast-scan
|
||||
- security-scan
|
||||
##IF_SONAR##
|
||||
- sonar-scan
|
||||
##ENDIF_SONAR##
|
||||
##IF_E2E##
|
||||
- e2e-tests
|
||||
##ENDIF_E2E##
|
||||
filters:
|
||||
branches:
|
||||
only: __BRANCH_FILTER__
|
||||
##ENDIF_SBOM##
|
||||
##IF_CD##
|
||||
- munitor/update_cd_repo:
|
||||
name: update-cd-repo
|
||||
cd_repo: ${MUNITOR_CD_REPO}
|
||||
environment: __CD_ENVIRONMENT__
|
||||
cd_format: ${MUNITOR_CD_FORMAT}
|
||||
cd_image_name: ${MUNITOR_DOCKER_REGISTRY}/${MUNITOR_IMAGE_NAME}
|
||||
##IF_SUPPLEMENTAL##
|
||||
supplemental_images: '${MUNITOR_SUPPLEMENTAL_IMAGES_JSON}'
|
||||
##ENDIF_SUPPLEMENTAL##
|
||||
ci_git_email: '${MUNITOR_CI_EMAIL}'
|
||||
ci_git_name: '${MUNITOR_CI_NAME}'
|
||||
requires:
|
||||
- docker-build-push
|
||||
context:
|
||||
- ${MUNITOR_CONTEXT_GITHUB}
|
||||
filters:
|
||||
branches:
|
||||
only: __BRANCH_FILTER__
|
||||
##ENDIF_CD##
|
||||
MUNITOR_PARTIAL_EOF
|
||||
|
||||
cat > /tmp/munitor/templates/partials/node-api-deploy.yml.tpl << 'MUNITOR_PARTIAL_EOF'
|
||||
__WORKFLOW_NAME__:
|
||||
jobs:
|
||||
@@ -2298,7 +2783,7 @@ validate_required_fields() {
|
||||
[[ -z "$(yq '.orb_version // ""' "${config}")" ]] && missing+=("orb_version")
|
||||
|
||||
case "${pipeline}" in
|
||||
java-webapp|node-api|node-webapp)
|
||||
java-webapp|gradle-webapp|node-api|node-webapp)
|
||||
[[ -z "$(yq '.image_name // ""' "${config}")" ]] && missing+=("image_name")
|
||||
[[ -z "$(yq '.docker.registry // ""' "${config}")" ]] && missing+=("docker.registry")
|
||||
;;
|
||||
@@ -2322,7 +2807,7 @@ validate_required_fields "${PIPELINE_TYPE}" "${CONFIG_FILE}"
|
||||
# --------------------------------------------------------------------------
|
||||
# Warn about unknown top-level keys (catches typos like java_verion)
|
||||
# --------------------------------------------------------------------------
|
||||
KNOWN_KEYS="pipeline orb_version image_name java_version node_version sonar docker cd coverage e2e sbom owasp contexts npm node services test terraform sast health kustomize kube_linter_config package_manager yamllint_paths supplemental_images"
|
||||
KNOWN_KEYS="pipeline orb_version image_name server_module java_version node_version sonar docker cd coverage e2e sbom owasp contexts npm node services test terraform sast health kustomize kube_linter_config package_manager yamllint_paths supplemental_images"
|
||||
ACTUAL_KEYS=$(yq 'keys | .[]' "${CONFIG_FILE}" 2>/dev/null || true)
|
||||
for key in ${ACTUAL_KEYS}; do
|
||||
if ! echo "${KNOWN_KEYS}" | grep -qw "${key}"; then
|
||||
|
||||
@@ -110,17 +110,23 @@ extract_munitor_vars() {
|
||||
fi
|
||||
|
||||
# --- Org defaults (overridable via .munitor.yml org section) ---
|
||||
local ORG_DOCKER_REGISTRY=$(yq '.org.docker_registry // "ghcr.io/KofTwentyTwo"' "${config_file}")
|
||||
local ORG_NPM_SCOPE=$(yq '.org.npm_scope // "@koftwentytwo"' "${config_file}")
|
||||
local ORG_CI_EMAIL=$(yq '.org.ci_email // "munitor-ci@koftwentytwo.com"' "${config_file}")
|
||||
local ORG_CI_NAME=$(yq '.org.ci_name // "Munitor CI"' "${config_file}")
|
||||
local ORG_ORB_SLUG=$(yq '.org.orb_slug // "kof22/munitor"' "${config_file}")
|
||||
local ORG_DOCKER_REGISTRY
|
||||
ORG_DOCKER_REGISTRY=$(yq '.org.docker_registry // "ghcr.io/KofTwentyTwo"' "${config_file}")
|
||||
local ORG_NPM_SCOPE
|
||||
ORG_NPM_SCOPE=$(yq '.org.npm_scope // "@koftwentytwo"' "${config_file}")
|
||||
local ORG_CI_EMAIL
|
||||
ORG_CI_EMAIL=$(yq '.org.ci_email // "munitor-ci@koftwentytwo.com"' "${config_file}")
|
||||
local ORG_CI_NAME
|
||||
ORG_CI_NAME=$(yq '.org.ci_name // "Munitor CI"' "${config_file}")
|
||||
local ORG_ORB_SLUG
|
||||
ORG_ORB_SLUG=$(yq '.org.orb_slug // "kof22/munitor"' "${config_file}")
|
||||
|
||||
# Core pipeline settings
|
||||
MUNITOR_PIPELINE=$(yq '.pipeline' "${config_file}")
|
||||
MUNITOR_ORB_VERSION=$(yq '.orb_version // ""' "${config_file}")
|
||||
MUNITOR_IMAGE_NAME=$(yq '.image_name // ""' "${config_file}")
|
||||
MUNITOR_JAVA_VERSION=$(yq '.java_version // "21"' "${config_file}")
|
||||
MUNITOR_SERVER_MODULE=$(yq '.server_module // ""' "${config_file}")
|
||||
MUNITOR_NODE_VERSION=$(yq '.node_version // "20"' "${config_file}")
|
||||
MUNITOR_SONAR_PROJECT_KEY=$(yq '.sonar.project_key // ""' "${config_file}")
|
||||
MUNITOR_DOCKER_REGISTRY=$(yq '.docker.registry // ""' "${config_file}")
|
||||
@@ -261,9 +267,13 @@ extract_munitor_vars() {
|
||||
esac
|
||||
fi
|
||||
MUNITOR_HEALTH_DB=$(yq '.health.db // false' "${config_file}")
|
||||
MUNITOR_HEALTH_MIGRATIONS=$(yq '.health.migrations // ""' "${config_file}")
|
||||
if [[ "${MUNITOR_HEALTH_MIGRATIONS}" == "null" ]]; then MUNITOR_HEALTH_MIGRATIONS=""; fi
|
||||
MUNITOR_HEALTH_SMOKE_PATHS=$(yq '.health.smoke_paths // [] | join(",")' "${config_file}")
|
||||
if [[ "${MUNITOR_HEALTH_SMOKE_PATHS}" == "null" ]]; then MUNITOR_HEALTH_SMOKE_PATHS=""; fi
|
||||
|
||||
# Supplemental images (e.g., migrations, db-backup)
|
||||
MUNITOR_SUPPLEMENTAL_IMAGES_JSON=$(yq '.supplemental_images // [] | tojson' "${config_file}")
|
||||
MUNITOR_SUPPLEMENTAL_IMAGES_JSON=$(yq -o=json -I=0 '.supplemental_images // []' "${config_file}")
|
||||
if [[ "${MUNITOR_SUPPLEMENTAL_IMAGES_JSON}" == "[]" || "${MUNITOR_SUPPLEMENTAL_IMAGES_JSON}" == "null" ]]; then
|
||||
MUNITOR_SUPPLEMENTAL="false"
|
||||
MUNITOR_SUPPLEMENTAL_IMAGES_JSON="[]"
|
||||
@@ -291,7 +301,7 @@ extract_munitor_vars() {
|
||||
fi
|
||||
|
||||
# Export all variables
|
||||
export MUNITOR_PIPELINE MUNITOR_ORB_VERSION MUNITOR_IMAGE_NAME MUNITOR_JAVA_VERSION MUNITOR_NODE_VERSION
|
||||
export MUNITOR_PIPELINE MUNITOR_ORB_VERSION MUNITOR_IMAGE_NAME MUNITOR_JAVA_VERSION MUNITOR_NODE_VERSION MUNITOR_SERVER_MODULE
|
||||
export MUNITOR_SONAR_PROJECT_KEY MUNITOR_DOCKER_REGISTRY MUNITOR_CD_REPO MUNITOR_CD_FORMAT
|
||||
export MUNITOR_CD_ENV_DEVELOP MUNITOR_CD_ENV_STAGING MUNITOR_CD_ENV_PROD MUNITOR_CD_ENV_RELEASE
|
||||
export MUNITOR_COVERAGE_MIN MUNITOR_E2E MUNITOR_SBOM MUNITOR_OWASP
|
||||
@@ -308,7 +318,7 @@ extract_munitor_vars() {
|
||||
export MUNITOR_KUBE_LINTER_CONFIG MUNITOR_YAMLLINT_PATHS
|
||||
export MUNITOR_NODE_FRAMEWORK MUNITOR_PACKAGE_MANAGER
|
||||
export MUNITOR_CI_EMAIL MUNITOR_CI_NAME MUNITOR_NPM_DEFAULT_SCOPE MUNITOR_ORB_SLUG
|
||||
export MUNITOR_HEALTH_PATH MUNITOR_HEALTH_PORT MUNITOR_HEALTH_DB
|
||||
export MUNITOR_HEALTH_PATH MUNITOR_HEALTH_PORT MUNITOR_HEALTH_DB MUNITOR_HEALTH_MIGRATIONS MUNITOR_HEALTH_SMOKE_PATHS
|
||||
export MUNITOR_SUPPLEMENTAL MUNITOR_SUPPLEMENTAL_IMAGES_JSON
|
||||
export MUNITOR_SONAR MUNITOR_CD MUNITOR_NVD
|
||||
}
|
||||
@@ -316,7 +326,7 @@ extract_munitor_vars() {
|
||||
# Build the envsubst variable list
|
||||
get_envsubst_vars() {
|
||||
# shellcheck disable=SC2016
|
||||
echo '${MUNITOR_PIPELINE} ${MUNITOR_ORB_VERSION} ${MUNITOR_IMAGE_NAME} ${MUNITOR_JAVA_VERSION} ${MUNITOR_NODE_VERSION} ${MUNITOR_SONAR_PROJECT_KEY} ${MUNITOR_DOCKER_REGISTRY} ${MUNITOR_CD_REPO} ${MUNITOR_CD_FORMAT} ${MUNITOR_CD_ENV_DEVELOP} ${MUNITOR_CD_ENV_STAGING} ${MUNITOR_CD_ENV_PROD} ${MUNITOR_CD_ENV_RELEASE} ${MUNITOR_COVERAGE_MIN} ${MUNITOR_E2E} ${MUNITOR_SBOM} ${MUNITOR_OWASP} ${MUNITOR_CONTEXT_REGISTRY} ${MUNITOR_CONTEXT_GITHUB} ${MUNITOR_CONTEXT_SONAR} ${MUNITOR_CONTEXT_NVD} ${MUNITOR_NPM_AUTH} ${MUNITOR_NPM_SCOPES} ${MUNITOR_SERVICES_JSON} ${MUNITOR_TEST_SETUP_SCRIPT} ${MUNITOR_TEST_COMMANDS_JSON} ${MUNITOR_COVERAGE_TOOL} ${MUNITOR_COVERAGE_COMMAND} ${MUNITOR_GITHUB_RELEASE} ${MUNITOR_SAST} ${MUNITOR_SAST_FAIL_ON_FINDINGS} ${MUNITOR_HEALTH_PATH} ${MUNITOR_HEALTH_PORT} ${MUNITOR_HEALTH_DB} ${MUNITOR_TF_PATH} ${MUNITOR_TF_LIVE_PATH} ${MUNITOR_TF_ENVIRONMENTS} ${MUNITOR_CHECKOV_SKIP} ${MUNITOR_KUSTOMIZE_VERSION} ${MUNITOR_KUSTOMIZE_BASE_PATH} ${MUNITOR_KUSTOMIZE_LOAD_RESTRICTOR} ${MUNITOR_KUSTOMIZE_SCAN_OVERLAY} ${MUNITOR_KUSTOMIZE_OVERLAYS} ${MUNITOR_KUSTOMIZE_OVERLAY_DIR} ${MUNITOR_KUBE_LINTER_CONFIG} ${MUNITOR_YAMLLINT_PATHS} ${MUNITOR_CI_EMAIL} ${MUNITOR_CI_NAME} ${MUNITOR_NPM_DEFAULT_SCOPE} ${MUNITOR_ORB_SLUG} ${MUNITOR_PACKAGE_MANAGER} ${MUNITOR_SUPPLEMENTAL_IMAGES_JSON}'
|
||||
echo '${MUNITOR_PIPELINE} ${MUNITOR_ORB_VERSION} ${MUNITOR_IMAGE_NAME} ${MUNITOR_JAVA_VERSION} ${MUNITOR_NODE_VERSION} ${MUNITOR_SONAR_PROJECT_KEY} ${MUNITOR_DOCKER_REGISTRY} ${MUNITOR_CD_REPO} ${MUNITOR_CD_FORMAT} ${MUNITOR_CD_ENV_DEVELOP} ${MUNITOR_CD_ENV_STAGING} ${MUNITOR_CD_ENV_PROD} ${MUNITOR_CD_ENV_RELEASE} ${MUNITOR_COVERAGE_MIN} ${MUNITOR_E2E} ${MUNITOR_SBOM} ${MUNITOR_OWASP} ${MUNITOR_CONTEXT_REGISTRY} ${MUNITOR_CONTEXT_GITHUB} ${MUNITOR_CONTEXT_SONAR} ${MUNITOR_CONTEXT_NVD} ${MUNITOR_NPM_AUTH} ${MUNITOR_NPM_SCOPES} ${MUNITOR_SERVICES_JSON} ${MUNITOR_TEST_SETUP_SCRIPT} ${MUNITOR_TEST_COMMANDS_JSON} ${MUNITOR_COVERAGE_TOOL} ${MUNITOR_COVERAGE_COMMAND} ${MUNITOR_GITHUB_RELEASE} ${MUNITOR_SAST} ${MUNITOR_SAST_FAIL_ON_FINDINGS} ${MUNITOR_HEALTH_PATH} ${MUNITOR_HEALTH_PORT} ${MUNITOR_HEALTH_DB} ${MUNITOR_HEALTH_MIGRATIONS} ${MUNITOR_HEALTH_SMOKE_PATHS} ${MUNITOR_TF_PATH} ${MUNITOR_TF_LIVE_PATH} ${MUNITOR_TF_ENVIRONMENTS} ${MUNITOR_CHECKOV_SKIP} ${MUNITOR_KUSTOMIZE_VERSION} ${MUNITOR_KUSTOMIZE_BASE_PATH} ${MUNITOR_KUSTOMIZE_LOAD_RESTRICTOR} ${MUNITOR_KUSTOMIZE_SCAN_OVERLAY} ${MUNITOR_KUSTOMIZE_OVERLAYS} ${MUNITOR_KUSTOMIZE_OVERLAY_DIR} ${MUNITOR_KUBE_LINTER_CONFIG} ${MUNITOR_YAMLLINT_PATHS} ${MUNITOR_CI_EMAIL} ${MUNITOR_CI_NAME} ${MUNITOR_NPM_DEFAULT_SCOPE} ${MUNITOR_ORB_SLUG} ${MUNITOR_PACKAGE_MANAGER} ${MUNITOR_SUPPLEMENTAL_IMAGES_JSON} ${MUNITOR_SERVER_MODULE}'
|
||||
}
|
||||
MUNITOR_EXTRACT_EOF
|
||||
|
||||
@@ -466,6 +476,54 @@ ENV JAVA_OPTS="-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0 -XX:+ExitOnOut
|
||||
|
||||
EXPOSE ${MUNITOR_HEALTH_PORT}
|
||||
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \\
|
||||
CMD wget --no-verbose --tries=1 --spider http://localhost:${MUNITOR_HEALTH_PORT}${MUNITOR_HEALTH_PATH} || exit 1
|
||||
|
||||
ENTRYPOINT ["sh", "-c", "java \$JAVA_OPTS -jar app.jar"]
|
||||
DOCKERFILE
|
||||
;;
|
||||
|
||||
gradle-webapp)
|
||||
echo "Generating Dockerfile for gradle-webapp (java ${MUNITOR_JAVA_VERSION})"
|
||||
|
||||
# Find the shadow JAR in the server module's build output
|
||||
SEARCH_DIR="build/libs"
|
||||
if [[ -n "${MUNITOR_SERVER_MODULE:-}" ]]; then
|
||||
SEARCH_DIR="${MUNITOR_SERVER_MODULE}/build/libs"
|
||||
fi
|
||||
|
||||
APP_JAR=$(find "${SEARCH_DIR}" -maxdepth 1 -name "*.jar" \
|
||||
! -name "*-plain.jar" ! -name "*-sources.jar" ! -name "*-javadoc.jar" \
|
||||
2>/dev/null | head -1) || true
|
||||
|
||||
if [[ -z "${APP_JAR}" ]]; then
|
||||
echo "ERROR: No application JAR found in ${SEARCH_DIR}/" >&2
|
||||
echo "Ensure shadowJar or bootJar is configured in build.gradle.kts" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Using JAR: ${APP_JAR}"
|
||||
|
||||
cat > Dockerfile <<DOCKERFILE
|
||||
FROM eclipse-temurin:${MUNITOR_JAVA_VERSION}-jre-alpine
|
||||
|
||||
RUN apk update && apk upgrade --no-cache
|
||||
|
||||
RUN addgroup -g 1001 -S appgroup && \\
|
||||
adduser -u 1001 -S appuser -G appgroup
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY ${APP_JAR} app.jar
|
||||
|
||||
RUN chown -R appuser:appgroup /app
|
||||
|
||||
USER appuser
|
||||
|
||||
ENV JAVA_OPTS="-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0 -XX:+ExitOnOutOfMemoryError"
|
||||
|
||||
EXPOSE ${MUNITOR_HEALTH_PORT}
|
||||
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \\
|
||||
CMD wget --no-verbose --tries=1 --spider http://localhost:${MUNITOR_HEALTH_PORT}${MUNITOR_HEALTH_PATH} || exit 1
|
||||
|
||||
|
||||
@@ -0,0 +1,319 @@
|
||||
version: 2.1
|
||||
|
||||
orbs:
|
||||
munitor: ${MUNITOR_ORB_SLUG}@${MUNITOR_ORB_VERSION}
|
||||
|
||||
workflows:
|
||||
pr-checks:
|
||||
jobs:
|
||||
- munitor/gradle_build_and_test:
|
||||
name: build-and-test
|
||||
java_version: "${MUNITOR_JAVA_VERSION}"
|
||||
context:
|
||||
- ${MUNITOR_CONTEXT_GITHUB}
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /feature\/.*/
|
||||
- /hotfix\/.*/
|
||||
- munitor/secrets_scan:
|
||||
name: secrets-scan
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /feature\/.*/
|
||||
- /hotfix\/.*/
|
||||
- munitor/sast_scan:
|
||||
name: sast-scan
|
||||
fail_on_findings: "${MUNITOR_SAST_FAIL_ON_FINDINGS}"
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /feature\/.*/
|
||||
- /hotfix\/.*/
|
||||
- munitor/gradle_code_quality:
|
||||
name: code-quality
|
||||
java_version: "${MUNITOR_JAVA_VERSION}"
|
||||
requires:
|
||||
- build-and-test
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /feature\/.*/
|
||||
- /hotfix\/.*/
|
||||
- munitor/gradle_coverage:
|
||||
name: coverage
|
||||
java_version: "${MUNITOR_JAVA_VERSION}"
|
||||
min_instruction: "${MUNITOR_COVERAGE_MIN}"
|
||||
requires:
|
||||
- build-and-test
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /feature\/.*/
|
||||
- /hotfix\/.*/
|
||||
- munitor/security_scan:
|
||||
name: security-scan
|
||||
java_version: "${MUNITOR_JAVA_VERSION}"
|
||||
owasp: ${MUNITOR_OWASP}
|
||||
##IF_OWASP##
|
||||
##IF_NVD##
|
||||
context:
|
||||
- ${MUNITOR_CONTEXT_NVD}
|
||||
##ENDIF_NVD##
|
||||
##ENDIF_OWASP##
|
||||
requires:
|
||||
- build-and-test
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /feature\/.*/
|
||||
- /hotfix\/.*/
|
||||
##IF_E2E##
|
||||
- munitor/mvn_e2e_test:
|
||||
name: e2e-tests
|
||||
java_version: "${MUNITOR_JAVA_VERSION}"
|
||||
requires:
|
||||
- build-and-test
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /feature\/.*/
|
||||
- /hotfix\/.*/
|
||||
##ENDIF_E2E##
|
||||
|
||||
##INCLUDE_DEPLOY gradle-webapp-deploy develop develop ${MUNITOR_CD_ENV_DEVELOP}##
|
||||
##INCLUDE_DEPLOY gradle-webapp-deploy staging staging ${MUNITOR_CD_ENV_STAGING}##
|
||||
|
||||
release-candidate:
|
||||
jobs:
|
||||
- munitor/gradle_build_and_test:
|
||||
name: build-and-test
|
||||
java_version: "${MUNITOR_JAVA_VERSION}"
|
||||
context:
|
||||
- ${MUNITOR_CONTEXT_GITHUB}
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /release\/.*/
|
||||
- munitor/secrets_scan:
|
||||
name: secrets-scan
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /release\/.*/
|
||||
- munitor/sast_scan:
|
||||
name: sast-scan
|
||||
fail_on_findings: "${MUNITOR_SAST_FAIL_ON_FINDINGS}"
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /release\/.*/
|
||||
- munitor/gradle_code_quality:
|
||||
name: code-quality
|
||||
java_version: "${MUNITOR_JAVA_VERSION}"
|
||||
requires:
|
||||
- build-and-test
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /release\/.*/
|
||||
- munitor/gradle_coverage:
|
||||
name: coverage
|
||||
java_version: "${MUNITOR_JAVA_VERSION}"
|
||||
min_instruction: "${MUNITOR_COVERAGE_MIN}"
|
||||
requires:
|
||||
- build-and-test
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /release\/.*/
|
||||
- munitor/security_scan:
|
||||
name: security-scan
|
||||
java_version: "${MUNITOR_JAVA_VERSION}"
|
||||
owasp: ${MUNITOR_OWASP}
|
||||
##IF_OWASP##
|
||||
##IF_NVD##
|
||||
context:
|
||||
- ${MUNITOR_CONTEXT_NVD}
|
||||
##ENDIF_NVD##
|
||||
##ENDIF_OWASP##
|
||||
requires:
|
||||
- build-and-test
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /release\/.*/
|
||||
##IF_E2E##
|
||||
- munitor/mvn_e2e_test:
|
||||
name: e2e-tests
|
||||
java_version: "${MUNITOR_JAVA_VERSION}"
|
||||
requires:
|
||||
- build-and-test
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /release\/.*/
|
||||
##ENDIF_E2E##
|
||||
##IF_SONAR##
|
||||
- munitor/sonar_scan:
|
||||
name: sonar-scan
|
||||
java_version: "${MUNITOR_JAVA_VERSION}"
|
||||
sonar_project_key: ${MUNITOR_SONAR_PROJECT_KEY}
|
||||
requires:
|
||||
- build-and-test
|
||||
- coverage
|
||||
context:
|
||||
- ${MUNITOR_CONTEXT_SONAR}
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /release\/.*/
|
||||
##ENDIF_SONAR##
|
||||
- munitor/docker_build_push:
|
||||
name: docker-build-push
|
||||
image_name: ${MUNITOR_IMAGE_NAME}
|
||||
registry: ${MUNITOR_DOCKER_REGISTRY}
|
||||
health_path: ${MUNITOR_HEALTH_PATH}
|
||||
health_port: "${MUNITOR_HEALTH_PORT}"
|
||||
health_db: "${MUNITOR_HEALTH_DB}"
|
||||
health_migrations: "${MUNITOR_HEALTH_MIGRATIONS}"
|
||||
health_smoke_paths: "${MUNITOR_HEALTH_SMOKE_PATHS}"
|
||||
##IF_SUPPLEMENTAL##
|
||||
supplemental_images: '${MUNITOR_SUPPLEMENTAL_IMAGES_JSON}'
|
||||
##ENDIF_SUPPLEMENTAL##
|
||||
requires:
|
||||
- code-quality
|
||||
- coverage
|
||||
- secrets-scan
|
||||
- sast-scan
|
||||
- security-scan
|
||||
##IF_SONAR##
|
||||
- sonar-scan
|
||||
##ENDIF_SONAR##
|
||||
##IF_E2E##
|
||||
- e2e-tests
|
||||
##ENDIF_E2E##
|
||||
context:
|
||||
- ${MUNITOR_CONTEXT_REGISTRY}
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /release\/.*/
|
||||
##IF_SBOM##
|
||||
- munitor/sbom:
|
||||
name: sbom
|
||||
java_version: "${MUNITOR_JAVA_VERSION}"
|
||||
context:
|
||||
- ${MUNITOR_CONTEXT_GITHUB}
|
||||
requires:
|
||||
- code-quality
|
||||
- coverage
|
||||
- secrets-scan
|
||||
- sast-scan
|
||||
- security-scan
|
||||
##IF_SONAR##
|
||||
- sonar-scan
|
||||
##ENDIF_SONAR##
|
||||
##IF_E2E##
|
||||
- e2e-tests
|
||||
##ENDIF_E2E##
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /release\/.*/
|
||||
##ENDIF_SBOM##
|
||||
##IF_CD##
|
||||
- munitor/update_cd_repo:
|
||||
name: update-cd-repo
|
||||
cd_repo: ${MUNITOR_CD_REPO}
|
||||
environment: ${MUNITOR_CD_ENV_RELEASE}
|
||||
cd_format: ${MUNITOR_CD_FORMAT}
|
||||
cd_image_name: ${MUNITOR_DOCKER_REGISTRY}/${MUNITOR_IMAGE_NAME}
|
||||
##IF_SUPPLEMENTAL##
|
||||
supplemental_images: '${MUNITOR_SUPPLEMENTAL_IMAGES_JSON}'
|
||||
##ENDIF_SUPPLEMENTAL##
|
||||
ci_git_email: '${MUNITOR_CI_EMAIL}'
|
||||
ci_git_name: '${MUNITOR_CI_NAME}'
|
||||
requires:
|
||||
- docker-build-push
|
||||
context:
|
||||
- ${MUNITOR_CONTEXT_GITHUB}
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /release\/.*/
|
||||
##ENDIF_CD##
|
||||
##IF_GITHUB_RELEASE##
|
||||
- munitor/github_release:
|
||||
name: github-release
|
||||
requires:
|
||||
- docker-build-push
|
||||
context:
|
||||
- ${MUNITOR_CONTEXT_GITHUB}
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /release\/.*/
|
||||
##ENDIF_GITHUB_RELEASE##
|
||||
|
||||
production:
|
||||
jobs:
|
||||
- munitor/gradle_build_and_test:
|
||||
name: build-and-test
|
||||
java_version: "${MUNITOR_JAVA_VERSION}"
|
||||
context:
|
||||
- ${MUNITOR_CONTEXT_GITHUB}
|
||||
filters:
|
||||
branches:
|
||||
only: main
|
||||
- munitor/docker_build_push:
|
||||
name: docker-build-push
|
||||
image_name: ${MUNITOR_IMAGE_NAME}
|
||||
registry: ${MUNITOR_DOCKER_REGISTRY}
|
||||
health_path: ${MUNITOR_HEALTH_PATH}
|
||||
health_port: "${MUNITOR_HEALTH_PORT}"
|
||||
health_db: "${MUNITOR_HEALTH_DB}"
|
||||
health_migrations: "${MUNITOR_HEALTH_MIGRATIONS}"
|
||||
health_smoke_paths: "${MUNITOR_HEALTH_SMOKE_PATHS}"
|
||||
##IF_SUPPLEMENTAL##
|
||||
supplemental_images: '${MUNITOR_SUPPLEMENTAL_IMAGES_JSON}'
|
||||
##ENDIF_SUPPLEMENTAL##
|
||||
requires:
|
||||
- build-and-test
|
||||
context:
|
||||
- ${MUNITOR_CONTEXT_REGISTRY}
|
||||
filters:
|
||||
branches:
|
||||
only: main
|
||||
##IF_CD##
|
||||
- munitor/update_cd_repo:
|
||||
name: update-cd-repo
|
||||
cd_repo: ${MUNITOR_CD_REPO}
|
||||
environment: ${MUNITOR_CD_ENV_PROD}
|
||||
cd_format: ${MUNITOR_CD_FORMAT}
|
||||
cd_image_name: ${MUNITOR_DOCKER_REGISTRY}/${MUNITOR_IMAGE_NAME}
|
||||
##IF_SUPPLEMENTAL##
|
||||
supplemental_images: '${MUNITOR_SUPPLEMENTAL_IMAGES_JSON}'
|
||||
##ENDIF_SUPPLEMENTAL##
|
||||
ci_git_email: '${MUNITOR_CI_EMAIL}'
|
||||
ci_git_name: '${MUNITOR_CI_NAME}'
|
||||
requires:
|
||||
- docker-build-push
|
||||
context:
|
||||
- ${MUNITOR_CONTEXT_GITHUB}
|
||||
filters:
|
||||
branches:
|
||||
only: main
|
||||
##ENDIF_CD##
|
||||
##IF_GITHUB_RELEASE##
|
||||
- munitor/github_release:
|
||||
name: github-release
|
||||
requires:
|
||||
- docker-build-push
|
||||
context:
|
||||
- ${MUNITOR_CONTEXT_GITHUB}
|
||||
filters:
|
||||
branches:
|
||||
only: main
|
||||
##ENDIF_GITHUB_RELEASE##
|
||||
@@ -0,0 +1,146 @@
|
||||
__WORKFLOW_NAME__:
|
||||
jobs:
|
||||
- munitor/gradle_build_and_test:
|
||||
name: build-and-test
|
||||
java_version: "${MUNITOR_JAVA_VERSION}"
|
||||
context:
|
||||
- ${MUNITOR_CONTEXT_GITHUB}
|
||||
filters:
|
||||
branches:
|
||||
only: __BRANCH_FILTER__
|
||||
- munitor/secrets_scan:
|
||||
name: secrets-scan
|
||||
filters:
|
||||
branches:
|
||||
only: __BRANCH_FILTER__
|
||||
- munitor/sast_scan:
|
||||
name: sast-scan
|
||||
fail_on_findings: "${MUNITOR_SAST_FAIL_ON_FINDINGS}"
|
||||
filters:
|
||||
branches:
|
||||
only: __BRANCH_FILTER__
|
||||
- munitor/gradle_code_quality:
|
||||
name: code-quality
|
||||
java_version: "${MUNITOR_JAVA_VERSION}"
|
||||
requires:
|
||||
- build-and-test
|
||||
filters:
|
||||
branches:
|
||||
only: __BRANCH_FILTER__
|
||||
- munitor/gradle_coverage:
|
||||
name: coverage
|
||||
java_version: "${MUNITOR_JAVA_VERSION}"
|
||||
min_instruction: "${MUNITOR_COVERAGE_MIN}"
|
||||
requires:
|
||||
- build-and-test
|
||||
filters:
|
||||
branches:
|
||||
only: __BRANCH_FILTER__
|
||||
- munitor/security_scan:
|
||||
name: security-scan
|
||||
java_version: "${MUNITOR_JAVA_VERSION}"
|
||||
owasp: ${MUNITOR_OWASP}
|
||||
##IF_OWASP##
|
||||
##IF_NVD##
|
||||
context:
|
||||
- ${MUNITOR_CONTEXT_NVD}
|
||||
##ENDIF_NVD##
|
||||
##ENDIF_OWASP##
|
||||
requires:
|
||||
- build-and-test
|
||||
filters:
|
||||
branches:
|
||||
only: __BRANCH_FILTER__
|
||||
##IF_E2E##
|
||||
- munitor/mvn_e2e_test:
|
||||
name: e2e-tests
|
||||
java_version: "${MUNITOR_JAVA_VERSION}"
|
||||
requires:
|
||||
- build-and-test
|
||||
filters:
|
||||
branches:
|
||||
only: __BRANCH_FILTER__
|
||||
##ENDIF_E2E##
|
||||
##IF_SONAR##
|
||||
- munitor/sonar_scan:
|
||||
name: sonar-scan
|
||||
java_version: "${MUNITOR_JAVA_VERSION}"
|
||||
sonar_project_key: ${MUNITOR_SONAR_PROJECT_KEY}
|
||||
requires:
|
||||
- build-and-test
|
||||
- coverage
|
||||
context:
|
||||
- ${MUNITOR_CONTEXT_SONAR}
|
||||
filters:
|
||||
branches:
|
||||
only: __BRANCH_FILTER__
|
||||
##ENDIF_SONAR##
|
||||
- munitor/docker_build_push:
|
||||
name: docker-build-push
|
||||
image_name: ${MUNITOR_IMAGE_NAME}
|
||||
registry: ${MUNITOR_DOCKER_REGISTRY}
|
||||
health_path: ${MUNITOR_HEALTH_PATH}
|
||||
health_port: "${MUNITOR_HEALTH_PORT}"
|
||||
health_db: "${MUNITOR_HEALTH_DB}"
|
||||
##IF_SUPPLEMENTAL##
|
||||
supplemental_images: '${MUNITOR_SUPPLEMENTAL_IMAGES_JSON}'
|
||||
##ENDIF_SUPPLEMENTAL##
|
||||
requires:
|
||||
- code-quality
|
||||
- coverage
|
||||
- secrets-scan
|
||||
- sast-scan
|
||||
- security-scan
|
||||
##IF_SONAR##
|
||||
- sonar-scan
|
||||
##ENDIF_SONAR##
|
||||
##IF_E2E##
|
||||
- e2e-tests
|
||||
##ENDIF_E2E##
|
||||
context:
|
||||
- ${MUNITOR_CONTEXT_REGISTRY}
|
||||
filters:
|
||||
branches:
|
||||
only: __BRANCH_FILTER__
|
||||
##IF_SBOM##
|
||||
- munitor/sbom:
|
||||
name: sbom
|
||||
java_version: "${MUNITOR_JAVA_VERSION}"
|
||||
context:
|
||||
- ${MUNITOR_CONTEXT_GITHUB}
|
||||
requires:
|
||||
- code-quality
|
||||
- coverage
|
||||
- secrets-scan
|
||||
- sast-scan
|
||||
- security-scan
|
||||
##IF_SONAR##
|
||||
- sonar-scan
|
||||
##ENDIF_SONAR##
|
||||
##IF_E2E##
|
||||
- e2e-tests
|
||||
##ENDIF_E2E##
|
||||
filters:
|
||||
branches:
|
||||
only: __BRANCH_FILTER__
|
||||
##ENDIF_SBOM##
|
||||
##IF_CD##
|
||||
- munitor/update_cd_repo:
|
||||
name: update-cd-repo
|
||||
cd_repo: ${MUNITOR_CD_REPO}
|
||||
environment: __CD_ENVIRONMENT__
|
||||
cd_format: ${MUNITOR_CD_FORMAT}
|
||||
cd_image_name: ${MUNITOR_DOCKER_REGISTRY}/${MUNITOR_IMAGE_NAME}
|
||||
##IF_SUPPLEMENTAL##
|
||||
supplemental_images: '${MUNITOR_SUPPLEMENTAL_IMAGES_JSON}'
|
||||
##ENDIF_SUPPLEMENTAL##
|
||||
ci_git_email: '${MUNITOR_CI_EMAIL}'
|
||||
ci_git_name: '${MUNITOR_CI_NAME}'
|
||||
requires:
|
||||
- docker-build-push
|
||||
context:
|
||||
- ${MUNITOR_CONTEXT_GITHUB}
|
||||
filters:
|
||||
branches:
|
||||
only: __BRANCH_FILTER__
|
||||
##ENDIF_CD##
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
pipeline: gradle-webapp
|
||||
orb_version: "0.1"
|
||||
|
||||
image_name: concilium
|
||||
java_version: "21"
|
||||
server_module: "concilium-server"
|
||||
|
||||
docker:
|
||||
registry: ghcr.io/koftwentytwo
|
||||
|
||||
cd:
|
||||
repo: KofTwentyTwo/Concilium-CD
|
||||
format: kustomize
|
||||
env:
|
||||
develop: dev
|
||||
|
||||
coverage:
|
||||
min_instruction: "50"
|
||||
|
||||
sast:
|
||||
fail_on_findings: true
|
||||
|
||||
sbom: true
|
||||
owasp: false
|
||||
|
||||
health:
|
||||
path: /api/health
|
||||
port: "8000"
|
||||
|
||||
contexts:
|
||||
registry: ghcr
|
||||
github: github
|
||||
@@ -287,6 +287,54 @@ extract_munitor_vars "${FIXTURES_DIR}/java-webapp.munitor.yml"
|
||||
assert_eq "supplemental flag default" "false" "${MUNITOR_SUPPLEMENTAL}"
|
||||
assert_eq "supplemental JSON default empty" "[]" "${MUNITOR_SUPPLEMENTAL_IMAGES_JSON}"
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# gradle-webapp fixture
|
||||
# --------------------------------------------------------------------------
|
||||
echo ""
|
||||
echo "=== extract_munitor_vars: gradle-webapp fixture ==="
|
||||
extract_munitor_vars "${FIXTURES_DIR}/gradle-webapp.munitor.yml"
|
||||
|
||||
assert_eq "pipeline type" "gradle-webapp" "${MUNITOR_PIPELINE}"
|
||||
assert_eq "image_name" "concilium" "${MUNITOR_IMAGE_NAME}"
|
||||
assert_eq "java_version" "21" "${MUNITOR_JAVA_VERSION}"
|
||||
assert_eq "server_module" "concilium-server" "${MUNITOR_SERVER_MODULE}"
|
||||
assert_eq "docker registry" "ghcr.io/koftwentytwo" "${MUNITOR_DOCKER_REGISTRY}"
|
||||
assert_eq "cd repo" "KofTwentyTwo/Concilium-CD" "${MUNITOR_CD_REPO}"
|
||||
assert_eq "cd flag" "true" "${MUNITOR_CD}"
|
||||
assert_eq "cd format" "kustomize" "${MUNITOR_CD_FORMAT}"
|
||||
assert_eq "cd env develop" "dev" "${MUNITOR_CD_ENV_DEVELOP}"
|
||||
assert_eq "coverage min" "50" "${MUNITOR_COVERAGE_MIN}"
|
||||
assert_eq "sbom" "true" "${MUNITOR_SBOM}"
|
||||
assert_eq "owasp" "false" "${MUNITOR_OWASP}"
|
||||
assert_eq "sast" "true" "${MUNITOR_SAST}"
|
||||
assert_eq "sast fail_on_findings" "true" "${MUNITOR_SAST_FAIL_ON_FINDINGS}"
|
||||
assert_eq "health_path" "/api/health" "${MUNITOR_HEALTH_PATH}"
|
||||
assert_eq "health_port" "8000" "${MUNITOR_HEALTH_PORT}"
|
||||
assert_eq "context registry" "ghcr" "${MUNITOR_CONTEXT_REGISTRY}"
|
||||
assert_eq "context github" "github" "${MUNITOR_CONTEXT_GITHUB}"
|
||||
assert_eq "github_release flag" "true" "${MUNITOR_GITHUB_RELEASE}"
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# server_module defaults (empty when not set)
|
||||
# --------------------------------------------------------------------------
|
||||
echo ""
|
||||
echo "=== extract_munitor_vars: server_module default ==="
|
||||
extract_munitor_vars "${FIXTURES_DIR}/java-webapp.munitor.yml"
|
||||
assert_eq "server_module default (empty)" "" "${MUNITOR_SERVER_MODULE}"
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# get_envsubst_vars includes MUNITOR_SERVER_MODULE
|
||||
# --------------------------------------------------------------------------
|
||||
echo -n " TEST: get_envsubst_vars includes MUNITOR_SERVER_MODULE... "
|
||||
VARS_CHECK=$(get_envsubst_vars)
|
||||
if echo "${VARS_CHECK}" | grep -q 'MUNITOR_SERVER_MODULE'; then
|
||||
echo "PASS"
|
||||
PASS=$((PASS + 1))
|
||||
else
|
||||
echo "FAIL"
|
||||
FAIL=$((FAIL + 1))
|
||||
fi
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Missing config file
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
@@ -1131,6 +1131,88 @@ run_test "java-webapp-supplemental: has production workflow" \
|
||||
"${FIXTURES_DIR}/java-webapp-supplemental.munitor.yml" \
|
||||
"production:"
|
||||
|
||||
# ==========================================================================
|
||||
# gradle-webapp template rendering
|
||||
# ==========================================================================
|
||||
echo ""
|
||||
echo "=== gradle-webapp Template Rendering Tests ==="
|
||||
|
||||
run_test "gradle-webapp: renders image_name" \
|
||||
"${FIXTURES_DIR}/gradle-webapp.munitor.yml" \
|
||||
"concilium"
|
||||
|
||||
run_test "gradle-webapp: renders java_version" \
|
||||
"${FIXTURES_DIR}/gradle-webapp.munitor.yml" \
|
||||
"java_version: \"21\""
|
||||
|
||||
run_test "gradle-webapp: uses gradle_build_and_test job" \
|
||||
"${FIXTURES_DIR}/gradle-webapp.munitor.yml" \
|
||||
"munitor/gradle_build_and_test"
|
||||
|
||||
run_test "gradle-webapp: uses gradle_code_quality job" \
|
||||
"${FIXTURES_DIR}/gradle-webapp.munitor.yml" \
|
||||
"munitor/gradle_code_quality"
|
||||
|
||||
run_test "gradle-webapp: uses gradle_coverage job" \
|
||||
"${FIXTURES_DIR}/gradle-webapp.munitor.yml" \
|
||||
"munitor/gradle_coverage"
|
||||
|
||||
run_negative_test "gradle-webapp: does not use mvn_build_and_test" \
|
||||
"${FIXTURES_DIR}/gradle-webapp.munitor.yml" \
|
||||
"munitor/mvn_build_and_test"
|
||||
|
||||
run_negative_test "gradle-webapp: does not use mvn_code_quality" \
|
||||
"${FIXTURES_DIR}/gradle-webapp.munitor.yml" \
|
||||
"munitor/mvn_code_quality"
|
||||
|
||||
run_negative_test "gradle-webapp: does not use mvn_coverage" \
|
||||
"${FIXTURES_DIR}/gradle-webapp.munitor.yml" \
|
||||
"munitor/mvn_coverage"
|
||||
|
||||
run_test "gradle-webapp: includes sast-scan" \
|
||||
"${FIXTURES_DIR}/gradle-webapp.munitor.yml" \
|
||||
"sast-scan"
|
||||
|
||||
run_test "gradle-webapp: includes sbom when enabled" \
|
||||
"${FIXTURES_DIR}/gradle-webapp.munitor.yml" \
|
||||
"sbom"
|
||||
|
||||
run_test "gradle-webapp: owasp disabled when false" \
|
||||
"${FIXTURES_DIR}/gradle-webapp.munitor.yml" \
|
||||
"owasp: false"
|
||||
|
||||
run_test "gradle-webapp: has cd repo update" \
|
||||
"${FIXTURES_DIR}/gradle-webapp.munitor.yml" \
|
||||
"update-cd-repo"
|
||||
|
||||
run_test "gradle-webapp: has release-candidate workflow" \
|
||||
"${FIXTURES_DIR}/gradle-webapp.munitor.yml" \
|
||||
"release-candidate:"
|
||||
|
||||
run_test "gradle-webapp: has production workflow" \
|
||||
"${FIXTURES_DIR}/gradle-webapp.munitor.yml" \
|
||||
"production:"
|
||||
|
||||
run_test "gradle-webapp: has pr-checks workflow" \
|
||||
"${FIXTURES_DIR}/gradle-webapp.munitor.yml" \
|
||||
"pr-checks:"
|
||||
|
||||
run_test "gradle-webapp: coverage min is 50" \
|
||||
"${FIXTURES_DIR}/gradle-webapp.munitor.yml" \
|
||||
'min_instruction: "50"'
|
||||
|
||||
run_test "gradle-webapp: health_port is 8000" \
|
||||
"${FIXTURES_DIR}/gradle-webapp.munitor.yml" \
|
||||
'health_port: "8000"'
|
||||
|
||||
run_negative_test "gradle-webapp: no e2e block (e2e not enabled)" \
|
||||
"${FIXTURES_DIR}/gradle-webapp.munitor.yml" \
|
||||
"e2e-tests"
|
||||
|
||||
run_negative_test "gradle-webapp: no sonar block (sonar not configured)" \
|
||||
"${FIXTURES_DIR}/gradle-webapp.munitor.yml" \
|
||||
"sonar-scan"
|
||||
|
||||
echo ""
|
||||
echo "=== Results: ${PASS} passed, ${FAIL} failed ==="
|
||||
|
||||
|
||||
@@ -917,6 +917,108 @@ for entry in "${URLS[@]}"; do
|
||||
fi
|
||||
done
|
||||
|
||||
# =============================================================================
|
||||
# Test: Gradle scripts - structural tests
|
||||
# =============================================================================
|
||||
echo ""
|
||||
echo "=== Gradle Scripts Tests ==="
|
||||
|
||||
for GRADLE_SCRIPT in gradle_build gradle_test gradle_jacoco gradle_checkstyle gradle_spotbugs gradle_pmd; do
|
||||
SCRIPT_FILE="${SRC_SCRIPTS}/${GRADLE_SCRIPT}.sh"
|
||||
|
||||
echo -n " TEST: ${GRADLE_SCRIPT}.sh exists... "
|
||||
if [[ -f "${SCRIPT_FILE}" ]]; then
|
||||
pass
|
||||
else
|
||||
fail "file not found"
|
||||
continue
|
||||
fi
|
||||
|
||||
echo -n " TEST: ${GRADLE_SCRIPT}.sh is executable... "
|
||||
if [[ -x "${SCRIPT_FILE}" ]]; then
|
||||
pass
|
||||
else
|
||||
fail "not executable"
|
||||
fi
|
||||
|
||||
echo -n " TEST: ${GRADLE_SCRIPT}.sh sources munitor_helpers.sh... "
|
||||
if grep -q 'munitor_helpers.sh' "${SCRIPT_FILE}"; then
|
||||
pass
|
||||
else
|
||||
fail "should source munitor_helpers.sh"
|
||||
fi
|
||||
|
||||
echo -n " TEST: ${GRADLE_SCRIPT}.sh uses set -euo pipefail... "
|
||||
if grep -q 'set -euo pipefail' "${SCRIPT_FILE}"; then
|
||||
pass
|
||||
else
|
||||
fail "should use set -euo pipefail"
|
||||
fi
|
||||
|
||||
echo -n " TEST: ${GRADLE_SCRIPT}.sh uses gradlew... "
|
||||
if grep -q 'gradlew' "${SCRIPT_FILE}"; then
|
||||
pass
|
||||
else
|
||||
fail "should use ./gradlew"
|
||||
fi
|
||||
done
|
||||
|
||||
echo -n " TEST: gradle_build.sh uses --no-daemon... "
|
||||
if grep -q '\-\-no-daemon' "${SRC_SCRIPTS}/gradle_build.sh"; then
|
||||
pass
|
||||
else
|
||||
fail "should use --no-daemon"
|
||||
fi
|
||||
|
||||
echo -n " TEST: gradle_build.sh skips tests (-x test)... "
|
||||
if grep -q '\-x test' "${SRC_SCRIPTS}/gradle_build.sh"; then
|
||||
pass
|
||||
else
|
||||
fail "should skip tests with -x test"
|
||||
fi
|
||||
|
||||
echo -n " TEST: gradle_jacoco.sh validates MIN_INSTRUCTION... "
|
||||
if grep -q 'MIN_INSTRUCTION' "${SRC_SCRIPTS}/gradle_jacoco.sh"; then
|
||||
pass
|
||||
else
|
||||
fail "should use MIN_INSTRUCTION"
|
||||
fi
|
||||
|
||||
echo -n " TEST: gradle_jacoco.sh aggregates multi-module CSVs... "
|
||||
if grep -q 'find' "${SRC_SCRIPTS}/gradle_jacoco.sh" && grep -q 'jacocoTestReport.csv' "${SRC_SCRIPTS}/gradle_jacoco.sh"; then
|
||||
pass
|
||||
else
|
||||
fail "should find jacocoTestReport.csv files"
|
||||
fi
|
||||
|
||||
echo -n " TEST: gradle_checkstyle.sh detects plugin availability... "
|
||||
if grep -q 'tasks --all' "${SRC_SCRIPTS}/gradle_checkstyle.sh" && grep -q 'checkstyleMain' "${SRC_SCRIPTS}/gradle_checkstyle.sh"; then
|
||||
pass
|
||||
else
|
||||
fail "should detect checkstyleMain task"
|
||||
fi
|
||||
|
||||
echo -n " TEST: gradle_checkstyle.sh skips gracefully... "
|
||||
if grep -q 'skipping\|Skipping\|skip\|not applied' "${SRC_SCRIPTS}/gradle_checkstyle.sh"; then
|
||||
pass
|
||||
else
|
||||
fail "should skip gracefully when plugin not applied"
|
||||
fi
|
||||
|
||||
echo -n " TEST: gradle_spotbugs.sh detects plugin availability... "
|
||||
if grep -q 'tasks --all' "${SRC_SCRIPTS}/gradle_spotbugs.sh" && grep -q 'spotbugsMain' "${SRC_SCRIPTS}/gradle_spotbugs.sh"; then
|
||||
pass
|
||||
else
|
||||
fail "should detect spotbugsMain task"
|
||||
fi
|
||||
|
||||
echo -n " TEST: gradle_pmd.sh detects plugin availability... "
|
||||
if grep -q 'tasks --all' "${SRC_SCRIPTS}/gradle_pmd.sh" && grep -q 'pmdMain' "${SRC_SCRIPTS}/gradle_pmd.sh"; then
|
||||
pass
|
||||
else
|
||||
fail "should detect pmdMain task"
|
||||
fi
|
||||
|
||||
# =============================================================================
|
||||
# Summary
|
||||
# =============================================================================
|
||||
|
||||
Reference in new issue
Block a user