Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1e558c18af | ||
|
|
e262339fa7 | ||
|
|
af150158ab | ||
|
|
d766747246 | ||
|
|
5f708237a7 | ||
|
|
d9735fb3ce | ||
|
|
cb26668ae7 | ||
|
|
f9070fdad0 | ||
|
|
9bc3bcefbd | ||
|
|
8466d2daa3 | ||
|
|
becc94fa1d | ||
|
|
8dcdfc1f43 | ||
|
|
1f829edc81 | ||
|
|
94e3ded47d |
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'
|
||||
|
||||
+5
-4
@@ -1,10 +1,11 @@
|
||||
version: 2.1
|
||||
|
||||
description: >
|
||||
Munitor (Latin: fortifier, protector) -- KofTwentyTwo's unified CircleCI orb
|
||||
for building, testing, and deploying all repositories. Provides standardized
|
||||
CI/CD pipelines via dynamic configuration so each repo needs only a tiny
|
||||
.munitor.yml to define its pipeline.
|
||||
Munitor (Latin: fortifier, protector) -- a unified CircleCI orb for building,
|
||||
testing, and deploying repositories. Provides standardized CI/CD pipelines via
|
||||
dynamic configuration so each repo needs only a tiny .munitor.yml to define
|
||||
its pipeline. Org-agnostic: override defaults via the optional org section in
|
||||
.munitor.yml.
|
||||
|
||||
display:
|
||||
home_url: https://github.com/KofTwentyTwo/Munitor
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
description: >
|
||||
Build, scan, and push supplemental Docker images alongside the main application image.
|
||||
Each supplemental image shares the same version tag. Requires docker_push_ghcr to have
|
||||
run first (for registry auth and Trivy installation).
|
||||
parameters:
|
||||
supplemental_images:
|
||||
type: string
|
||||
default: "[]"
|
||||
description: JSON array of supplemental image definitions.
|
||||
image_name:
|
||||
type: string
|
||||
description: Docker image name (without registry prefix).
|
||||
registry:
|
||||
type: string
|
||||
default: ghcr.io/KofTwentyTwo
|
||||
description: Container registry URL.
|
||||
steps:
|
||||
- run:
|
||||
name: Build and push supplemental images
|
||||
environment:
|
||||
SUPPLEMENTAL_IMAGES_JSON: << parameters.supplemental_images >>
|
||||
IMAGE_NAME: << parameters.image_name >>
|
||||
REGISTRY: << parameters.registry >>
|
||||
command: << include(scripts/build_push_supplemental.sh) >>
|
||||
@@ -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
|
||||
@@ -15,6 +15,14 @@ parameters:
|
||||
type: string
|
||||
default: "false"
|
||||
description: Start a PostgreSQL sidecar for apps that require a database to boot.
|
||||
health_migrations:
|
||||
type: string
|
||||
default: ""
|
||||
description: Name of supplemental image to run as migrations before the app (e.g. "migrations").
|
||||
health_smoke_paths:
|
||||
type: string
|
||||
default: ""
|
||||
description: Comma-separated API paths to smoke test after health check passes (e.g. "/api/v1/site/query").
|
||||
steps:
|
||||
- run:
|
||||
name: Health check
|
||||
@@ -22,4 +30,6 @@ steps:
|
||||
HEALTH_PATH: << parameters.health_path >>
|
||||
HEALTH_PORT: << parameters.health_port >>
|
||||
HEALTH_DB: << parameters.health_db >>
|
||||
HEALTH_MIGRATIONS: << parameters.health_migrations >>
|
||||
HEALTH_SMOKE_PATHS: << parameters.health_smoke_paths >>
|
||||
command: << include(scripts/health_check.sh) >>
|
||||
@@ -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-
|
||||
@@ -4,7 +4,7 @@ description: >
|
||||
steps:
|
||||
- run:
|
||||
name: Write Trivy version file
|
||||
command: echo "${TRIVY_VERSION:-0.58.2}" > .trivy-version
|
||||
command: echo "${TRIVY_VERSION:-0.69.3}" > .trivy-version
|
||||
- restore_cache:
|
||||
keys:
|
||||
- trivy-bin-v1-{{ checksum ".trivy-version" }}
|
||||
|
||||
@@ -6,7 +6,7 @@ parameters:
|
||||
description: Full image tag to scan (registry/name:tag).
|
||||
trivy_version:
|
||||
type: string
|
||||
default: "0.58.2"
|
||||
default: "0.69.3"
|
||||
description: Trivy version to install.
|
||||
steps:
|
||||
- run:
|
||||
|
||||
@@ -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
|
||||
@@ -3,7 +3,7 @@ description: >
|
||||
steps:
|
||||
- run:
|
||||
name: Write Trivy version file
|
||||
command: echo "${TRIVY_VERSION:-0.58.2}" > .trivy-version
|
||||
command: echo "${TRIVY_VERSION:-0.69.3}" > .trivy-version
|
||||
- save_cache:
|
||||
key: trivy-bin-v1-{{ checksum ".trivy-version" }}
|
||||
paths:
|
||||
|
||||
@@ -38,6 +38,12 @@ parameters:
|
||||
type: string
|
||||
default: ""
|
||||
description: Git author name for CD repo commits.
|
||||
supplemental_images:
|
||||
type: string
|
||||
default: "[]"
|
||||
description: >
|
||||
JSON array of supplemental images. Each entry may contain cd.image_key (Helm)
|
||||
or cd.image_name (Kustomize) for updating the CD repo with supplemental image tags.
|
||||
steps:
|
||||
- run:
|
||||
name: Update CD repo
|
||||
@@ -50,4 +56,5 @@ steps:
|
||||
CD_IMAGE_NAME: << parameters.cd_image_name >>
|
||||
CI_GIT_EMAIL: << parameters.ci_git_email >>
|
||||
CI_GIT_NAME: << parameters.ci_git_name >>
|
||||
SUPPLEMENTAL_IMAGES_JSON: << parameters.supplemental_images >>
|
||||
command: << include(scripts/update_cd_repo.sh) >>
|
||||
@@ -20,6 +20,14 @@ parameters:
|
||||
type: string
|
||||
default: "false"
|
||||
description: Start a PostgreSQL sidecar for apps that require a database to boot.
|
||||
health_migrations:
|
||||
type: string
|
||||
default: ""
|
||||
description: Name of supplemental image to run as migrations before the app (e.g. "migrations").
|
||||
health_smoke_paths:
|
||||
type: string
|
||||
default: ""
|
||||
description: Comma-separated API paths to smoke test after health check passes.
|
||||
resource_class:
|
||||
type: enum
|
||||
enum:
|
||||
@@ -31,6 +39,10 @@ parameters:
|
||||
type: boolean
|
||||
default: true
|
||||
description: Enable Docker Layer Caching for faster builds.
|
||||
supplemental_images:
|
||||
type: string
|
||||
default: "[]"
|
||||
description: JSON array of supplemental images to build, scan, and push alongside the main image.
|
||||
executor:
|
||||
name: machine
|
||||
resource_class: << parameters.resource_class >>
|
||||
@@ -45,12 +57,18 @@ steps:
|
||||
- docker_build:
|
||||
image_name: << parameters.image_name >>
|
||||
registry: << parameters.registry >>
|
||||
- health_check:
|
||||
health_path: << parameters.health_path >>
|
||||
health_port: << parameters.health_port >>
|
||||
health_db: << parameters.health_db >>
|
||||
- restore_trivy_cache
|
||||
- run_trivy_image:
|
||||
image_tag: << parameters.registry >>/<< parameters.image_name >>:${DOCKER_TAG}
|
||||
- save_trivy_cache
|
||||
- docker_push_ghcr
|
||||
- build_push_supplemental:
|
||||
supplemental_images: << parameters.supplemental_images >>
|
||||
image_name: << parameters.image_name >>
|
||||
registry: << parameters.registry >>
|
||||
- health_check:
|
||||
health_path: << parameters.health_path >>
|
||||
health_port: << parameters.health_port >>
|
||||
health_db: << parameters.health_db >>
|
||||
health_migrations: << parameters.health_migrations >>
|
||||
health_smoke_paths: << parameters.health_smoke_paths >>
|
||||
@@ -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 >>
|
||||
@@ -32,6 +32,12 @@ parameters:
|
||||
type: string
|
||||
default: ""
|
||||
description: Git author name for CD repo commits.
|
||||
supplemental_images:
|
||||
type: string
|
||||
default: "[]"
|
||||
description: >
|
||||
JSON array of supplemental images. Each entry may contain cd.image_key (Helm)
|
||||
or cd.image_name (Kustomize) for updating the CD repo with supplemental image tags.
|
||||
executor: base
|
||||
steps:
|
||||
- attach_workspace:
|
||||
@@ -48,3 +54,4 @@ steps:
|
||||
cd_image_name: << parameters.cd_image_name >>
|
||||
ci_git_email: << parameters.ci_git_email >>
|
||||
ci_git_name: << parameters.ci_git_name >>
|
||||
supplemental_images: << parameters.supplemental_images >>
|
||||
@@ -0,0 +1,97 @@
|
||||
#!/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 "build_push_supplemental"
|
||||
munitor_check_tool jq --version
|
||||
munitor_check_tool docker --version
|
||||
|
||||
IMAGES_JSON="${SUPPLEMENTAL_IMAGES_JSON:-[]}"
|
||||
|
||||
# Skip if no supplemental images defined
|
||||
if [[ "${IMAGES_JSON}" == "[]" || "${IMAGES_JSON}" == "null" || -z "${IMAGES_JSON}" ]]; then
|
||||
echo "No supplemental images defined, skipping."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
IMAGE="${IMAGE_NAME:?IMAGE_NAME not set}"
|
||||
REGISTRY="${REGISTRY:-ghcr.io/KofTwentyTwo}"
|
||||
VERSION="${PROJECT_VERSION:?PROJECT_VERSION not set -- run export_version_vars first}"
|
||||
ENV_TAG="${DOCKER_ENV_TAG:-}"
|
||||
|
||||
COUNT=$(echo "${IMAGES_JSON}" | jq 'length')
|
||||
echo "Found ${COUNT} supplemental image(s) to build."
|
||||
|
||||
for i in $(seq 0 $((COUNT - 1))); do
|
||||
ENTRY=$(echo "${IMAGES_JSON}" | jq -c ".[$i]")
|
||||
|
||||
NAME=$(echo "${ENTRY}" | jq -r '.name')
|
||||
BASE=$(echo "${ENTRY}" | jq -r '.base // empty')
|
||||
DOCKERFILE=$(echo "${ENTRY}" | jq -r '.dockerfile // empty')
|
||||
|
||||
DERIVED_NAME="${IMAGE}-${NAME}"
|
||||
FULL_TAG="${REGISTRY}/${DERIVED_NAME}:${VERSION}"
|
||||
|
||||
echo ""
|
||||
echo "--- Supplemental image: ${DERIVED_NAME} ---"
|
||||
|
||||
if [[ -n "${DOCKERFILE}" ]]; then
|
||||
echo "Using provided Dockerfile: ${DOCKERFILE}"
|
||||
elif [[ -n "${BASE}" ]]; then
|
||||
# Auto-generate Dockerfile
|
||||
DOCKERFILE="Dockerfile.${NAME}"
|
||||
echo "Auto-generating ${DOCKERFILE} from base: ${BASE}"
|
||||
|
||||
{
|
||||
echo "FROM ${BASE}"
|
||||
COPY_COUNT=$(echo "${ENTRY}" | jq '.copy // [] | length')
|
||||
for j in $(seq 0 $((COPY_COUNT - 1))); do
|
||||
SRC=$(echo "${ENTRY}" | jq -r ".copy[$j].src")
|
||||
DEST=$(echo "${ENTRY}" | jq -r ".copy[$j].dest")
|
||||
echo "COPY ${SRC} ${DEST}"
|
||||
done
|
||||
} > "${DOCKERFILE}"
|
||||
|
||||
echo "Generated ${DOCKERFILE}:"
|
||||
cat "${DOCKERFILE}"
|
||||
else
|
||||
echo "ERROR: Supplemental image '${NAME}' must specify either 'dockerfile' or 'base'."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Build
|
||||
echo "Building ${FULL_TAG} ..."
|
||||
docker build -f "${DOCKERFILE}" -t "${FULL_TAG}" .
|
||||
|
||||
if [[ -n "${ENV_TAG}" ]]; then
|
||||
ENV_FULL_TAG="${REGISTRY}/${DERIVED_NAME}:${ENV_TAG}"
|
||||
docker tag "${FULL_TAG}" "${ENV_FULL_TAG}"
|
||||
fi
|
||||
|
||||
# Trivy scan
|
||||
echo "Scanning ${FULL_TAG} with Trivy ..."
|
||||
trivy image --severity HIGH,CRITICAL --exit-code 1 "${FULL_TAG}"
|
||||
|
||||
# Push
|
||||
echo "Pushing ${FULL_TAG} ..."
|
||||
docker push "${FULL_TAG}"
|
||||
|
||||
if [[ -n "${ENV_TAG}" ]]; then
|
||||
echo "Pushing ${ENV_FULL_TAG} ..."
|
||||
docker push "${ENV_FULL_TAG}"
|
||||
fi
|
||||
|
||||
echo "--- Done: ${DERIVED_NAME} ---"
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "All supplemental images built, scanned, and pushed."
|
||||
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}/"
|
||||
@@ -27,7 +27,7 @@ BUILD_CMD=(docker build -f "${DOCKERFILE}" -t "${FULL_IMAGE}:${VERSION}")
|
||||
if [[ -n "${ENV_TAG}" ]]; then
|
||||
BUILD_CMD+=(-t "${FULL_IMAGE}:${ENV_TAG}")
|
||||
fi
|
||||
BUILD_CMD+=(--build-arg "VERSION=${VERSION}" .)
|
||||
BUILD_CMD+=(--build-arg "VERSION=${VERSION}" --build-arg "GIT_COMMIT_SHA=${CIRCLE_SHA1:-}" .)
|
||||
|
||||
"${BUILD_CMD[@]}"
|
||||
|
||||
|
||||
@@ -12,18 +12,24 @@ extract_munitor_vars() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
# --- Org defaults (change this block when forking for another org) ---
|
||||
local ORG_DOCKER_REGISTRY="ghcr.io/KofTwentyTwo"
|
||||
local ORG_NPM_SCOPE="@koftwentytwo"
|
||||
local ORG_CI_EMAIL="munitor-ci@koftwentytwo.com"
|
||||
local ORG_CI_NAME="Munitor CI"
|
||||
local ORG_ORB_SLUG="kof22/munitor"
|
||||
# --- Org defaults (overridable via .munitor.yml org section) ---
|
||||
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}")
|
||||
@@ -164,6 +170,19 @@ 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 -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="[]"
|
||||
else
|
||||
MUNITOR_SUPPLEMENTAL="true"
|
||||
fi
|
||||
|
||||
# Derived flags
|
||||
if [[ -n "${MUNITOR_SONAR_PROJECT_KEY}" ]]; then
|
||||
@@ -185,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
|
||||
@@ -202,12 +221,13 @@ 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
|
||||
}
|
||||
|
||||
# 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}'
|
||||
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"
|
||||
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
|
||||
@@ -198,7 +198,7 @@ process_conditionals() {
|
||||
cp "${input}" "${tmpfile}"
|
||||
|
||||
# Process each conditional flag
|
||||
for flag in E2E SBOM SONAR NPM_AUTH SERVICES TEST_SETUP CUSTOM_TEST COVERAGE_CMD GITHUB_RELEASE SAST CD OWASP NVD; do
|
||||
for flag in E2E SBOM SONAR NPM_AUTH SERVICES TEST_SETUP CUSTOM_TEST COVERAGE_CMD GITHUB_RELEASE SAST CD OWASP NVD SUPPLEMENTAL; do
|
||||
local var_name="MUNITOR_${flag}"
|
||||
local value="${!var_name:-false}"
|
||||
local flag_file
|
||||
|
||||
@@ -53,6 +53,8 @@ WORKDIR /app
|
||||
COPY --from=deps /app/node_modules ./node_modules
|
||||
COPY . .
|
||||
ENV STANDALONE=true
|
||||
ARG GIT_COMMIT_SHA
|
||||
ENV GIT_COMMIT_SHA=\${GIT_COMMIT_SHA}
|
||||
RUN npm run build
|
||||
|
||||
FROM node:${MUNITOR_NODE_VERSION}-alpine AS runner
|
||||
@@ -139,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
|
||||
|
||||
@@ -154,6 +204,8 @@ WORKDIR /app
|
||||
COPY package*.json ./
|
||||
RUN npm ci
|
||||
COPY . .
|
||||
ARG GIT_COMMIT_SHA
|
||||
ENV GIT_COMMIT_SHA=\${GIT_COMMIT_SHA}
|
||||
RUN npm run build
|
||||
|
||||
FROM gcr.io/distroless/nodejs${MUNITOR_NODE_VERSION}-debian12 AS runner
|
||||
|
||||
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."
|
||||
@@ -14,6 +14,8 @@ fi
|
||||
HEALTH_PATH="${HEALTH_PATH:-/api/health}"
|
||||
HEALTH_PORT="${HEALTH_PORT:-3000}"
|
||||
HEALTH_DB="${HEALTH_DB:-false}"
|
||||
HEALTH_MIGRATIONS="${HEALTH_MIGRATIONS:-}"
|
||||
HEALTH_SMOKE_PATHS="${HEALTH_SMOKE_PATHS:-}"
|
||||
|
||||
# DOCKER_IMAGE and DOCKER_TAG are exported to BASH_ENV by docker_build.sh
|
||||
IMAGE="${DOCKER_IMAGE:?DOCKER_IMAGE not set -- run docker_build first}"
|
||||
@@ -64,6 +66,23 @@ if [[ "${HEALTH_DB}" == "true" ]]; then
|
||||
sleep 1
|
||||
done
|
||||
|
||||
# Run migrations if a migrations image is specified
|
||||
if [[ -n "${HEALTH_MIGRATIONS}" ]]; then
|
||||
MIGRATIONS_IMAGE="${DOCKER_IMAGE}-${HEALTH_MIGRATIONS}:${TAG}"
|
||||
echo "Running migrations image: ${MIGRATIONS_IMAGE}"
|
||||
docker run --rm \
|
||||
--name "munitor-health-migrations-$$" \
|
||||
--network "${NETWORK_NAME}" \
|
||||
-e RDBMS_HOSTNAME="${DB_CONTAINER_NAME}" \
|
||||
-e RDBMS_PORT=5432 \
|
||||
-e RDBMS_DATABASE_NAME=postgres \
|
||||
-e RDBMS_USERNAME=postgres \
|
||||
-e RDBMS_PASSWORD=postgres \
|
||||
-e LB_CONTEXTS=dev \
|
||||
"${MIGRATIONS_IMAGE}"
|
||||
echo "Migrations completed."
|
||||
fi
|
||||
|
||||
# Start app container on the same network with DB env vars
|
||||
docker run -d \
|
||||
--name "${CONTAINER_NAME}" \
|
||||
@@ -129,3 +148,40 @@ if [[ "${HEALTHY}" != "true" ]]; then
|
||||
echo "--- End container logs ---"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- API smoke tests ---
|
||||
if [[ -n "${HEALTH_SMOKE_PATHS}" ]]; then
|
||||
echo ""
|
||||
echo "Running API smoke tests..."
|
||||
SMOKE_FAILED=false
|
||||
|
||||
IFS=',' read -ra SMOKE_ENDPOINTS <<< "${HEALTH_SMOKE_PATHS}"
|
||||
for endpoint in "${SMOKE_ENDPOINTS[@]}"; do
|
||||
endpoint=$(echo "${endpoint}" | xargs) # trim whitespace
|
||||
SMOKE_URL="http://localhost:${HEALTH_PORT}${endpoint}"
|
||||
echo " Smoke test: GET ${endpoint}"
|
||||
|
||||
SMOKE_CODE=$(curl -s -o /tmp/smoke_response.txt -w "%{http_code}" "${SMOKE_URL}" 2>/dev/null || echo "000")
|
||||
|
||||
if [[ "${SMOKE_CODE}" == "200" ]]; then
|
||||
echo " PASSED (HTTP ${SMOKE_CODE})"
|
||||
else
|
||||
BODY=$(cat /tmp/smoke_response.txt 2>/dev/null || echo "")
|
||||
echo " FAILED (HTTP ${SMOKE_CODE})"
|
||||
echo " Response: ${BODY:0:500}"
|
||||
SMOKE_FAILED=true
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ "${SMOKE_FAILED}" == "true" ]]; then
|
||||
echo ""
|
||||
echo "ERROR: API smoke tests FAILED"
|
||||
echo ""
|
||||
echo "--- Container logs (last 50 lines) ---"
|
||||
docker logs --tail 50 "${CONTAINER_NAME}" 2>&1 || true
|
||||
echo "--- End container logs ---"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "All smoke tests PASSED."
|
||||
fi
|
||||
@@ -12,7 +12,7 @@ elif ! type munitor_header &>/dev/null; then
|
||||
fi
|
||||
|
||||
# tfsec is deprecated/archived -- use trivy config instead
|
||||
TRIVY_VERSION="${TRIVY_VERSION:-0.58.2}"
|
||||
TRIVY_VERSION="${TRIVY_VERSION:-0.69.3}"
|
||||
INSTALL_DIR="${HOME}/bin"
|
||||
export PATH="${INSTALL_DIR}:${PATH}"
|
||||
|
||||
|
||||
@@ -109,18 +109,24 @@ extract_munitor_vars() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
# --- Org defaults (change this block when forking for another org) ---
|
||||
local ORG_DOCKER_REGISTRY="ghcr.io/KofTwentyTwo"
|
||||
local ORG_NPM_SCOPE="@koftwentytwo"
|
||||
local ORG_CI_EMAIL="munitor-ci@koftwentytwo.com"
|
||||
local ORG_CI_NAME="Munitor CI"
|
||||
local ORG_ORB_SLUG="kof22/munitor"
|
||||
# --- Org defaults (overridable via .munitor.yml org section) ---
|
||||
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,6 +267,19 @@ 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 -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="[]"
|
||||
else
|
||||
MUNITOR_SUPPLEMENTAL="true"
|
||||
fi
|
||||
|
||||
# Derived flags
|
||||
if [[ -n "${MUNITOR_SONAR_PROJECT_KEY}" ]]; then
|
||||
@@ -282,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
|
||||
@@ -299,14 +318,15 @@ 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
|
||||
}
|
||||
|
||||
# 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}'
|
||||
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
|
||||
|
||||
@@ -490,6 +510,11 @@ 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:
|
||||
- code-quality
|
||||
- coverage
|
||||
@@ -538,6 +563,9 @@ workflows:
|
||||
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:
|
||||
@@ -579,6 +607,11 @@ 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:
|
||||
@@ -593,6 +626,331 @@ workflows:
|
||||
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##
|
||||
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:
|
||||
@@ -810,6 +1168,9 @@ workflows:
|
||||
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
|
||||
@@ -852,6 +1213,9 @@ workflows:
|
||||
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:
|
||||
@@ -907,6 +1271,9 @@ workflows:
|
||||
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:
|
||||
- build-and-test
|
||||
context:
|
||||
@@ -921,6 +1288,9 @@ workflows:
|
||||
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:
|
||||
@@ -1138,6 +1508,9 @@ workflows:
|
||||
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
|
||||
@@ -1180,6 +1553,9 @@ workflows:
|
||||
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:
|
||||
@@ -1235,6 +1611,9 @@ workflows:
|
||||
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:
|
||||
- build-and-test
|
||||
context:
|
||||
@@ -1249,6 +1628,9 @@ workflows:
|
||||
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:
|
||||
@@ -1811,6 +2193,9 @@ cat > /tmp/munitor/templates/partials/java-webapp-deploy.yml.tpl << 'MUNITOR_PAR
|
||||
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
|
||||
@@ -1857,6 +2242,158 @@ cat > /tmp/munitor/templates/partials/java-webapp-deploy.yml.tpl << 'MUNITOR_PAR
|
||||
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/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:
|
||||
@@ -1961,6 +2498,9 @@ cat > /tmp/munitor/templates/partials/node-api-deploy.yml.tpl << 'MUNITOR_PARTIA
|
||||
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
|
||||
@@ -2001,6 +2541,9 @@ cat > /tmp/munitor/templates/partials/node-api-deploy.yml.tpl << 'MUNITOR_PARTIA
|
||||
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:
|
||||
@@ -2105,6 +2648,9 @@ cat > /tmp/munitor/templates/partials/node-webapp-deploy.yml.tpl << 'MUNITOR_PAR
|
||||
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
|
||||
@@ -2145,6 +2691,9 @@ cat > /tmp/munitor/templates/partials/node-webapp-deploy.yml.tpl << 'MUNITOR_PAR
|
||||
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:
|
||||
@@ -2234,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")
|
||||
;;
|
||||
@@ -2258,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"
|
||||
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
|
||||
@@ -2362,7 +2911,7 @@ process_conditionals() {
|
||||
cp "${input}" "${tmpfile}"
|
||||
|
||||
# Process each conditional flag
|
||||
for flag in E2E SBOM SONAR NPM_AUTH SERVICES TEST_SETUP CUSTOM_TEST COVERAGE_CMD GITHUB_RELEASE SAST CD OWASP NVD; do
|
||||
for flag in E2E SBOM SONAR NPM_AUTH SERVICES TEST_SETUP CUSTOM_TEST COVERAGE_CMD GITHUB_RELEASE SAST CD OWASP NVD SUPPLEMENTAL; do
|
||||
local var_name="MUNITOR_${flag}"
|
||||
local value="${!var_name:-false}"
|
||||
local flag_file
|
||||
|
||||
@@ -109,18 +109,24 @@ extract_munitor_vars() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
# --- Org defaults (change this block when forking for another org) ---
|
||||
local ORG_DOCKER_REGISTRY="ghcr.io/KofTwentyTwo"
|
||||
local ORG_NPM_SCOPE="@koftwentytwo"
|
||||
local ORG_CI_EMAIL="munitor-ci@koftwentytwo.com"
|
||||
local ORG_CI_NAME="Munitor CI"
|
||||
local ORG_ORB_SLUG="kof22/munitor"
|
||||
# --- Org defaults (overridable via .munitor.yml org section) ---
|
||||
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,6 +267,19 @@ 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 -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="[]"
|
||||
else
|
||||
MUNITOR_SUPPLEMENTAL="true"
|
||||
fi
|
||||
|
||||
# Derived flags
|
||||
if [[ -n "${MUNITOR_SONAR_PROJECT_KEY}" ]]; then
|
||||
@@ -282,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
|
||||
@@ -299,14 +318,15 @@ 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
|
||||
}
|
||||
|
||||
# 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}'
|
||||
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
|
||||
|
||||
@@ -368,6 +388,8 @@ WORKDIR /app
|
||||
COPY --from=deps /app/node_modules ./node_modules
|
||||
COPY . .
|
||||
ENV STANDALONE=true
|
||||
ARG GIT_COMMIT_SHA
|
||||
ENV GIT_COMMIT_SHA=\${GIT_COMMIT_SHA}
|
||||
RUN npm run build
|
||||
|
||||
FROM node:${MUNITOR_NODE_VERSION}-alpine AS runner
|
||||
@@ -454,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
|
||||
|
||||
@@ -469,6 +539,8 @@ WORKDIR /app
|
||||
COPY package*.json ./
|
||||
RUN npm ci
|
||||
COPY . .
|
||||
ARG GIT_COMMIT_SHA
|
||||
ENV GIT_COMMIT_SHA=\${GIT_COMMIT_SHA}
|
||||
RUN npm run build
|
||||
|
||||
FROM gcr.io/distroless/nodejs${MUNITOR_NODE_VERSION}-debian12 AS runner
|
||||
|
||||
@@ -11,7 +11,7 @@ elif ! type munitor_header &>/dev/null; then
|
||||
munitor_download_with_retry() { curl -fsSL --retry 3 "$1" -o "$2"; }
|
||||
fi
|
||||
|
||||
TRIVY_VERSION="${TRIVY_VERSION:-0.58.2}"
|
||||
TRIVY_VERSION="${TRIVY_VERSION:-0.69.3}"
|
||||
INSTALL_DIR="${HOME}/bin"
|
||||
mkdir -p "${INSTALL_DIR}"
|
||||
export PATH="${INSTALL_DIR}:${PATH}"
|
||||
|
||||
@@ -11,7 +11,7 @@ elif ! type munitor_header &>/dev/null; then
|
||||
munitor_download_with_retry() { curl -fsSL --retry 3 "$1" -o "$2"; }
|
||||
fi
|
||||
|
||||
TRIVY_VERSION="${TRIVY_VERSION:-0.58.2}"
|
||||
TRIVY_VERSION="${TRIVY_VERSION:-0.69.3}"
|
||||
INSTALL_DIR="${HOME}/bin"
|
||||
mkdir -p "${INSTALL_DIR}"
|
||||
export PATH="${INSTALL_DIR}:${PATH}"
|
||||
|
||||
@@ -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##
|
||||
@@ -177,6 +177,11 @@ 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:
|
||||
- code-quality
|
||||
- coverage
|
||||
@@ -225,6 +230,9 @@ workflows:
|
||||
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:
|
||||
@@ -266,6 +274,11 @@ 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:
|
||||
@@ -280,6 +293,9 @@ workflows:
|
||||
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:
|
||||
|
||||
@@ -191,6 +191,9 @@ workflows:
|
||||
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
|
||||
@@ -233,6 +236,9 @@ workflows:
|
||||
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:
|
||||
@@ -288,6 +294,9 @@ workflows:
|
||||
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:
|
||||
- build-and-test
|
||||
context:
|
||||
@@ -302,6 +311,9 @@ workflows:
|
||||
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:
|
||||
|
||||
@@ -191,6 +191,9 @@ workflows:
|
||||
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
|
||||
@@ -233,6 +236,9 @@ workflows:
|
||||
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:
|
||||
@@ -288,6 +294,9 @@ workflows:
|
||||
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:
|
||||
- build-and-test
|
||||
context:
|
||||
@@ -302,6 +311,9 @@ workflows:
|
||||
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:
|
||||
|
||||
@@ -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##
|
||||
@@ -82,6 +82,9 @@
|
||||
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
|
||||
@@ -128,6 +131,9 @@
|
||||
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:
|
||||
|
||||
@@ -89,6 +89,9 @@
|
||||
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
|
||||
@@ -129,6 +132,9 @@
|
||||
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:
|
||||
|
||||
@@ -89,6 +89,9 @@
|
||||
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
|
||||
@@ -129,6 +132,9 @@
|
||||
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:
|
||||
|
||||
@@ -92,9 +92,45 @@ else
|
||||
git add "${VALUES}"
|
||||
fi
|
||||
|
||||
# Update supplemental image tags (if any)
|
||||
SUPP_JSON="${SUPPLEMENTAL_IMAGES_JSON:-[]}"
|
||||
if [[ "${SUPP_JSON}" != "[]" && "${SUPP_JSON}" != "null" ]]; then
|
||||
SUPP_COUNT=$(echo "${SUPP_JSON}" | jq 'length')
|
||||
echo "Updating ${SUPP_COUNT} supplemental image tag(s)..."
|
||||
|
||||
for ((i = 0; i < SUPP_COUNT; i++)); do
|
||||
SUPP_NAME=$(echo "${SUPP_JSON}" | jq -r ".[$i].name")
|
||||
|
||||
if [[ "${FORMAT}" == "kustomize" ]]; then
|
||||
SUPP_CD_IMAGE=$(echo "${SUPP_JSON}" | jq -r ".[$i].cd.image_name // \"\"")
|
||||
if [[ -z "${SUPP_CD_IMAGE}" ]]; then
|
||||
SUPP_CD_IMAGE="${IMAGE_NAME}-${SUPP_NAME}"
|
||||
fi
|
||||
echo " Kustomize: ${SUPP_CD_IMAGE} -> ${VERSION}"
|
||||
# Upsert: add entry if it doesn't exist, then update
|
||||
EXISTING=$(yq ".images[] | select(.name == \"${SUPP_CD_IMAGE}\") | .name" "${KUST_FILE}")
|
||||
if [[ -z "${EXISTING}" ]]; then
|
||||
echo " (creating new image entry)"
|
||||
yq -i ".images += [{\"name\": \"${SUPP_CD_IMAGE}\", \"newTag\": \"${VERSION}\"}]" "${KUST_FILE}"
|
||||
else
|
||||
yq -i "(.images[] | select(.name == \"${SUPP_CD_IMAGE}\")).newTag = \"${VERSION}\"" "${KUST_FILE}"
|
||||
yq -i "del((.images[] | select(.name == \"${SUPP_CD_IMAGE}\")).digest)" "${KUST_FILE}"
|
||||
fi
|
||||
git add "${KUST_FILE}"
|
||||
else
|
||||
SUPP_IMAGE_KEY=$(echo "${SUPP_JSON}" | jq -r ".[$i].cd.image_key // \"\"")
|
||||
if [[ -n "${SUPP_IMAGE_KEY}" ]]; then
|
||||
echo " Helm: ${SUPP_IMAGE_KEY} -> ${VERSION}"
|
||||
yq -i ".${SUPP_IMAGE_KEY} = \"${VERSION}\"" "${VALUES}"
|
||||
git add "${VALUES}"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Commit and push
|
||||
git config user.email "${CI_GIT_EMAIL:-munitor-ci@koftwentytwo.com}"
|
||||
git config user.name "${CI_GIT_NAME:-Munitor CI}"
|
||||
git config user.email "${CI_GIT_EMAIL:-${MUNITOR_CI_EMAIL:-munitor-ci@koftwentytwo.com}}"
|
||||
git config user.name "${CI_GIT_NAME:-${MUNITOR_CI_NAME:-Munitor CI}}"
|
||||
|
||||
if git diff --cached --quiet; then
|
||||
echo "No changes to commit (version already up to date)."
|
||||
|
||||
+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
|
||||
@@ -0,0 +1,35 @@
|
||||
pipeline: java-webapp
|
||||
orb_version: dev:snapshot
|
||||
|
||||
image_name: me-health-portal
|
||||
java_version: "21"
|
||||
|
||||
sonar:
|
||||
project_key: dmdbrands_me-health-portal
|
||||
|
||||
docker:
|
||||
registry: ghcr.io/dmdbrands
|
||||
|
||||
cd:
|
||||
repo: dmdbrands/me-health-portal-cd-pipeline
|
||||
|
||||
coverage:
|
||||
min_instruction: 80
|
||||
|
||||
e2e: true
|
||||
sbom: true
|
||||
|
||||
contexts:
|
||||
registry: ghcr
|
||||
github: github
|
||||
sonar: sonarcloud
|
||||
nvd: nvd
|
||||
|
||||
supplemental_images:
|
||||
- name: migrations
|
||||
base: liquibase/liquibase:4.31
|
||||
copy:
|
||||
- src: db/changelog/
|
||||
dest: /liquibase/changelog/
|
||||
cd:
|
||||
image_key: migrations.image.tag
|
||||
@@ -263,6 +263,78 @@ assert_eq "health_port default 3000" "3000" "${MUNITOR_HEALTH_PORT}"
|
||||
assert_eq "coverage min default" "70" "${MUNITOR_COVERAGE_MIN}"
|
||||
assert_eq "package_manager default" "npm" "${MUNITOR_PACKAGE_MANAGER}"
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# supplemental_images (enabled)
|
||||
# --------------------------------------------------------------------------
|
||||
echo ""
|
||||
echo "=== extract_munitor_vars: supplemental_images (enabled) ==="
|
||||
extract_munitor_vars "${FIXTURES_DIR}/java-webapp-supplemental.munitor.yml"
|
||||
|
||||
assert_eq "supplemental flag" "true" "${MUNITOR_SUPPLEMENTAL}"
|
||||
assert_eq "supplemental JSON is non-empty" "true" "$([[ "${MUNITOR_SUPPLEMENTAL_IMAGES_JSON}" != "[]" ]] && echo true || echo false)"
|
||||
assert_eq "supplemental JSON is single-line" "1" "$(echo "${MUNITOR_SUPPLEMENTAL_IMAGES_JSON}" | wc -l | tr -d ' ')"
|
||||
assert_eq "supplemental JSON has migrations" "true" "$(echo "${MUNITOR_SUPPLEMENTAL_IMAGES_JSON}" | jq -r '.[0].name' 2>/dev/null | grep -q migrations && echo true || echo false)"
|
||||
assert_eq "supplemental migrations base" "liquibase/liquibase:4.31" "$(echo "${MUNITOR_SUPPLEMENTAL_IMAGES_JSON}" | jq -r '.[0].base')"
|
||||
assert_eq "supplemental migrations cd.image_key" "migrations.image.tag" "$(echo "${MUNITOR_SUPPLEMENTAL_IMAGES_JSON}" | jq -r '.[0].cd.image_key')"
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# supplemental_images (default: disabled)
|
||||
# --------------------------------------------------------------------------
|
||||
echo ""
|
||||
echo "=== extract_munitor_vars: supplemental_images (default disabled) ==="
|
||||
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
|
||||
# --------------------------------------------------------------------------
|
||||
@@ -326,6 +398,15 @@ else
|
||||
FAIL=$((FAIL + 1))
|
||||
fi
|
||||
|
||||
echo -n " TEST: get_envsubst_vars includes MUNITOR_SUPPLEMENTAL_IMAGES_JSON... "
|
||||
if echo "${VARS}" | grep -q 'MUNITOR_SUPPLEMENTAL_IMAGES_JSON'; then
|
||||
echo "PASS"
|
||||
PASS=$((PASS + 1))
|
||||
else
|
||||
echo "FAIL"
|
||||
FAIL=$((FAIL + 1))
|
||||
fi
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
echo ""
|
||||
echo "=== Results: ${PASS} passed, ${FAIL} failed ==="
|
||||
|
||||
@@ -1080,6 +1080,139 @@ run_negative_test "validate-cd-repo: no overlay_dir param (regression)" \
|
||||
"${FIXTURES_DIR}/validate-cd-repo.munitor.yml" \
|
||||
"overlay_dir:"
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Supplemental Images Tests
|
||||
# --------------------------------------------------------------------------
|
||||
echo ""
|
||||
echo "=== Supplemental Images Template Tests ==="
|
||||
|
||||
# java-webapp-supplemental: supplemental_images parameter appears in docker-build-push
|
||||
run_context_test "java-webapp-supplemental: docker-build-push has supplemental_images param" \
|
||||
"${FIXTURES_DIR}/java-webapp-supplemental.munitor.yml" \
|
||||
"name: docker-build-push" \
|
||||
"context:" \
|
||||
"supplemental_images:"
|
||||
|
||||
# java-webapp-supplemental: supplemental_images parameter appears in update-cd-repo
|
||||
run_context_test "java-webapp-supplemental: update-cd-repo has supplemental_images param" \
|
||||
"${FIXTURES_DIR}/java-webapp-supplemental.munitor.yml" \
|
||||
"name: update-cd-repo" \
|
||||
"context:" \
|
||||
"supplemental_images:"
|
||||
|
||||
# java-webapp (no supplemental): supplemental_images should NOT appear
|
||||
run_negative_test "java-webapp: no supplemental_images param when not configured" \
|
||||
"${FIXTURES_DIR}/java-webapp.munitor.yml" \
|
||||
"supplemental_images:"
|
||||
|
||||
# java-webapp-minimal: supplemental_images should NOT appear
|
||||
run_negative_test "java-webapp-minimal: no supplemental_images param" \
|
||||
"${FIXTURES_DIR}/java-webapp-minimal.munitor.yml" \
|
||||
"supplemental_images:"
|
||||
|
||||
# java-webapp-supplemental: still has all normal features (regression)
|
||||
run_test "java-webapp-supplemental: still has e2e" \
|
||||
"${FIXTURES_DIR}/java-webapp-supplemental.munitor.yml" \
|
||||
"e2e-tests"
|
||||
|
||||
run_test "java-webapp-supplemental: still has sonar" \
|
||||
"${FIXTURES_DIR}/java-webapp-supplemental.munitor.yml" \
|
||||
"sonar-scan"
|
||||
|
||||
run_test "java-webapp-supplemental: still has update-cd-repo" \
|
||||
"${FIXTURES_DIR}/java-webapp-supplemental.munitor.yml" \
|
||||
"update-cd-repo"
|
||||
|
||||
run_test "java-webapp-supplemental: has release-candidate workflow" \
|
||||
"${FIXTURES_DIR}/java-webapp-supplemental.munitor.yml" \
|
||||
"release-candidate:"
|
||||
|
||||
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 ==="
|
||||
|
||||
|
||||
@@ -327,6 +327,58 @@ else
|
||||
fail "should delete digest field to prevent kustomize from ignoring newTag"
|
||||
fi
|
||||
|
||||
echo -n " TEST: upserts supplemental images (creates new entry)... "
|
||||
if grep -q '.images += \[{' "${SRC_SCRIPTS}/update_cd_repo.sh"; then
|
||||
pass
|
||||
else
|
||||
fail "should create new image entries for supplemental images"
|
||||
fi
|
||||
|
||||
echo -n " TEST: checks for existing entry before upsert... "
|
||||
if grep -q 'EXISTING=' "${SRC_SCRIPTS}/update_cd_repo.sh" && grep -q 'if \[\[ -z "${EXISTING}"' "${SRC_SCRIPTS}/update_cd_repo.sh"; then
|
||||
pass
|
||||
else
|
||||
fail "should check if image entry exists before deciding to create or update"
|
||||
fi
|
||||
|
||||
# Functional test: verify upsert creates entries in a real kustomization file
|
||||
echo -n " TEST: upsert creates new image entry in kustomization (functional)... "
|
||||
UPSERT_TMPDIR=$(mktemp -d)
|
||||
cat > "${UPSERT_TMPDIR}/kustomization.yaml" <<'KUSTYAML'
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
images:
|
||||
- name: ghcr.io/koftwentytwo/website-backend
|
||||
newTag: "0.1.0"
|
||||
KUSTYAML
|
||||
SUPP_CD_IMAGE="ghcr.io/koftwentytwo/website-backend-migrations"
|
||||
VERSION_TEST="0.2.0-SNAPSHOT.abc1234"
|
||||
EXISTING=$(yq ".images[] | select(.name == \"${SUPP_CD_IMAGE}\") | .name" "${UPSERT_TMPDIR}/kustomization.yaml")
|
||||
if [[ -z "${EXISTING}" ]]; then
|
||||
yq -i ".images += [{\"name\": \"${SUPP_CD_IMAGE}\", \"newTag\": \"${VERSION_TEST}\"}]" "${UPSERT_TMPDIR}/kustomization.yaml"
|
||||
fi
|
||||
RESULT_TAG=$(yq ".images[] | select(.name == \"${SUPP_CD_IMAGE}\") | .newTag" "${UPSERT_TMPDIR}/kustomization.yaml")
|
||||
if [[ "${RESULT_TAG}" == "${VERSION_TEST}" ]]; then
|
||||
pass
|
||||
else
|
||||
fail "expected newTag=${VERSION_TEST}, got ${RESULT_TAG}"
|
||||
fi
|
||||
|
||||
echo -n " TEST: upsert updates existing image entry in kustomization (functional)... "
|
||||
VERSION_TEST2="0.3.0-SNAPSHOT.def5678"
|
||||
EXISTING=$(yq ".images[] | select(.name == \"${SUPP_CD_IMAGE}\") | .name" "${UPSERT_TMPDIR}/kustomization.yaml")
|
||||
if [[ -n "${EXISTING}" ]]; then
|
||||
yq -i "(.images[] | select(.name == \"${SUPP_CD_IMAGE}\")).newTag = \"${VERSION_TEST2}\"" "${UPSERT_TMPDIR}/kustomization.yaml"
|
||||
fi
|
||||
RESULT_TAG2=$(yq ".images[] | select(.name == \"${SUPP_CD_IMAGE}\") | .newTag" "${UPSERT_TMPDIR}/kustomization.yaml")
|
||||
ENTRY_COUNT=$(yq "[.images[] | select(.name == \"${SUPP_CD_IMAGE}\")] | length" "${UPSERT_TMPDIR}/kustomization.yaml")
|
||||
if [[ "${RESULT_TAG2}" == "${VERSION_TEST2}" && "${ENTRY_COUNT}" == "1" ]]; then
|
||||
pass
|
||||
else
|
||||
fail "expected newTag=${VERSION_TEST2} with 1 entry, got tag=${RESULT_TAG2} count=${ENTRY_COUNT}"
|
||||
fi
|
||||
rm -rf "${UPSERT_TMPDIR}"
|
||||
|
||||
# =============================================================================
|
||||
# Test: docker_build.sh - DOCKER_ENV_TAG support
|
||||
# =============================================================================
|
||||
@@ -638,6 +690,89 @@ else
|
||||
fail "should skip missing directories"
|
||||
fi
|
||||
|
||||
# =============================================================================
|
||||
# Test: build_push_supplemental.sh - Supplemental image build
|
||||
# =============================================================================
|
||||
echo ""
|
||||
echo "=== build_push_supplemental.sh Tests ==="
|
||||
|
||||
echo -n " TEST: sources munitor_helpers... "
|
||||
if grep -q 'MUNITOR_HELPERS' "${SRC_SCRIPTS}/build_push_supplemental.sh"; then
|
||||
pass
|
||||
else
|
||||
fail "should source munitor_helpers"
|
||||
fi
|
||||
|
||||
echo -n " TEST: calls munitor_header... "
|
||||
if grep -q 'munitor_header' "${SRC_SCRIPTS}/build_push_supplemental.sh"; then
|
||||
pass
|
||||
else
|
||||
fail "should call munitor_header"
|
||||
fi
|
||||
|
||||
echo -n " TEST: reads SUPPLEMENTAL_IMAGES_JSON... "
|
||||
if grep -q 'SUPPLEMENTAL_IMAGES_JSON' "${SRC_SCRIPTS}/build_push_supplemental.sh"; then
|
||||
pass
|
||||
else
|
||||
fail "should read SUPPLEMENTAL_IMAGES_JSON"
|
||||
fi
|
||||
|
||||
echo -n " TEST: skips when JSON is empty... "
|
||||
if grep -q 'exit 0' "${SRC_SCRIPTS}/build_push_supplemental.sh"; then
|
||||
pass
|
||||
else
|
||||
fail "should exit 0 when no supplemental images"
|
||||
fi
|
||||
|
||||
echo -n " TEST: uses jq to parse JSON... "
|
||||
if grep -q 'jq' "${SRC_SCRIPTS}/build_push_supplemental.sh"; then
|
||||
pass
|
||||
else
|
||||
fail "should use jq"
|
||||
fi
|
||||
|
||||
echo -n " TEST: builds Docker images... "
|
||||
if grep -q 'docker build' "${SRC_SCRIPTS}/build_push_supplemental.sh"; then
|
||||
pass
|
||||
else
|
||||
fail "should run docker build"
|
||||
fi
|
||||
|
||||
echo -n " TEST: scans with Trivy... "
|
||||
if grep -q 'trivy image' "${SRC_SCRIPTS}/build_push_supplemental.sh"; then
|
||||
pass
|
||||
else
|
||||
fail "should scan with trivy"
|
||||
fi
|
||||
|
||||
echo -n " TEST: pushes images... "
|
||||
if grep -q 'docker push' "${SRC_SCRIPTS}/build_push_supplemental.sh"; then
|
||||
pass
|
||||
else
|
||||
fail "should push images"
|
||||
fi
|
||||
|
||||
echo -n " TEST: supports custom Dockerfile... "
|
||||
if grep -q 'dockerfile' "${SRC_SCRIPTS}/build_push_supplemental.sh"; then
|
||||
pass
|
||||
else
|
||||
fail "should support custom dockerfile"
|
||||
fi
|
||||
|
||||
echo -n " TEST: auto-generates Dockerfile from base+copy... "
|
||||
if grep -q 'Dockerfile\.' "${SRC_SCRIPTS}/build_push_supplemental.sh" && grep -q 'FROM' "${SRC_SCRIPTS}/build_push_supplemental.sh"; then
|
||||
pass
|
||||
else
|
||||
fail "should auto-generate Dockerfile"
|
||||
fi
|
||||
|
||||
echo -n " TEST: uses set -euo pipefail... "
|
||||
if grep -q 'set -euo pipefail' "${SRC_SCRIPTS}/build_push_supplemental.sh"; then
|
||||
pass
|
||||
else
|
||||
fail "should use strict mode"
|
||||
fi
|
||||
|
||||
# =============================================================================
|
||||
# Test: Scripts have proper error handling
|
||||
# =============================================================================
|
||||
@@ -736,6 +871,154 @@ else
|
||||
fail "missing munitor_header:${MISSING_HEADER}"
|
||||
fi
|
||||
|
||||
# =============================================================================
|
||||
# Test: External download URLs are reachable
|
||||
# =============================================================================
|
||||
echo ""
|
||||
echo "=== External Download URL Tests ==="
|
||||
|
||||
# Extract pinned versions from scripts (single source of truth)
|
||||
extract_version() { sed -n "s/.*${1}:-\([v0-9.]*\).*/\1/p" "$2" | head -1; }
|
||||
TRIVY_VER=$(extract_version TRIVY_VERSION "${SRC_SCRIPTS}/run_trivy.sh")
|
||||
GH_VER=$(extract_version GH_VERSION "${SRC_SCRIPTS}/install_gh.sh")
|
||||
GITLEAKS_VER=$(extract_version GITLEAKS_VERSION "${SRC_SCRIPTS}/install_gitleaks.sh")
|
||||
KUBE_LINTER_VER=$(extract_version KUBE_LINTER_VERSION "${SRC_SCRIPTS}/install_kube_linter.sh")
|
||||
TERRAGRUNT_VER=$(extract_version TERRAGRUNT_VERSION "${SRC_SCRIPTS}/install_terragrunt.sh")
|
||||
YQ_VER=$(extract_version YQ_VERSION "${SRC_SCRIPTS}/install_yq.sh")
|
||||
KUSTOMIZE_VER=$(extract_version KUSTOMIZE_VERSION "${SRC_SCRIPTS}/install_kustomize.sh")
|
||||
KUBESEC_VER=$(extract_version KUBESEC_VERSION "${SRC_SCRIPTS}/install_kubesec.sh")
|
||||
TFSEC_TRIVY_VER=$(extract_version TRIVY_VERSION "${SRC_SCRIPTS}/install_tfsec.sh")
|
||||
SONAR_VER=$(extract_version SONAR_SCANNER_VERSION "${SRC_SCRIPTS}/npm_sonar.sh")
|
||||
|
||||
# All URLs target linux/amd64 -- matches the CI executor
|
||||
URLS=(
|
||||
"Trivy ${TRIVY_VER}|https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VER}/trivy_${TRIVY_VER}_Linux-64bit.tar.gz"
|
||||
"Trivy/tfsec ${TFSEC_TRIVY_VER}|https://github.com/aquasecurity/trivy/releases/download/v${TFSEC_TRIVY_VER}/trivy_${TFSEC_TRIVY_VER}_Linux-64bit.tar.gz"
|
||||
"gh ${GH_VER}|https://github.com/cli/cli/releases/download/v${GH_VER}/gh_${GH_VER}_linux_amd64.tar.gz"
|
||||
"gitleaks ${GITLEAKS_VER}|https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VER}/gitleaks_${GITLEAKS_VER}_linux_x64.tar.gz"
|
||||
"kube-linter ${KUBE_LINTER_VER}|https://github.com/stackrox/kube-linter/releases/download/v${KUBE_LINTER_VER}/kube-linter-linux.tar.gz"
|
||||
"terragrunt ${TERRAGRUNT_VER}|https://github.com/gruntwork-io/terragrunt/releases/download/v${TERRAGRUNT_VER}/terragrunt_linux_amd64"
|
||||
"yq ${YQ_VER}|https://github.com/mikefarah/yq/releases/download/${YQ_VER}/yq_linux_amd64"
|
||||
"kustomize ${KUSTOMIZE_VER}|https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize%2Fv${KUSTOMIZE_VER}/kustomize_v${KUSTOMIZE_VER}_linux_amd64.tar.gz"
|
||||
"kubesec ${KUBESEC_VER}|https://github.com/controlplaneio/kubesec/releases/download/v${KUBESEC_VER}/kubesec_linux_amd64.tar.gz"
|
||||
"OpenTofu installer|https://get.opentofu.org/install-opentofu.sh"
|
||||
"sonar-scanner ${SONAR_VER}|https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-${SONAR_VER}-linux-x64.zip"
|
||||
)
|
||||
|
||||
for entry in "${URLS[@]}"; do
|
||||
LABEL="${entry%%|*}"
|
||||
URL="${entry##*|}"
|
||||
echo -n " TEST: ${LABEL} download URL is reachable... "
|
||||
HTTP_CODE=$(curl -sI -o /dev/null -w "%{http_code}" -L --retry 2 "${URL}" 2>/dev/null || echo "000")
|
||||
if [[ "${HTTP_CODE}" == "200" ]]; then
|
||||
pass
|
||||
else
|
||||
fail "HTTP ${HTTP_CODE} for ${URL}"
|
||||
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