From 90790ebd2573096dac17b298d880b65616efa678 Mon Sep 17 00:00:00 2001 From: Paul Williams Date: Sun, 14 Jun 2026 18:39:41 +0530 Subject: [PATCH 1/7] feat: initial prompt --- .../maven-upgrade-java-spring-boot.prompt.md | 47 +++- .../maven-upgrade-java-spring-boot/SKILL.md | 84 +++++++ .../scripts/common.sh | 220 ++++++++++++++++++ .../scripts/execute-rewrite.sh | 101 ++++++++ .../scripts/orchestrator.sh | 164 +++++++++++++ .../scripts/pre-flight.sh | 132 +++++++++++ 6 files changed, 743 insertions(+), 5 deletions(-) create mode 100644 .github/skills/maven-upgrade-java-spring-boot/SKILL.md create mode 100755 .github/skills/maven-upgrade-java-spring-boot/scripts/common.sh create mode 100755 .github/skills/maven-upgrade-java-spring-boot/scripts/execute-rewrite.sh create mode 100755 .github/skills/maven-upgrade-java-spring-boot/scripts/orchestrator.sh create mode 100755 .github/skills/maven-upgrade-java-spring-boot/scripts/pre-flight.sh diff --git a/.github/prompts/maven-upgrade-java-spring-boot.prompt.md b/.github/prompts/maven-upgrade-java-spring-boot.prompt.md index 59db346..f594d3e 100644 --- a/.github/prompts/maven-upgrade-java-spring-boot.prompt.md +++ b/.github/prompts/maven-upgrade-java-spring-boot.prompt.md @@ -4,20 +4,57 @@ description: "GitHub copilot prompt to upgrade java and spring-boot" # argument-hint: "Optional arguments (for example: name=Paul)" agent: agent model: gpt-5.3-codex -tools: ['editFiles'] +tools: ['runCommands'] authors: ["paul58914080@gmail.com"] --- -[//]: # (todo: Describe the persona and goal of this prompt) +You are a Maven Java and Spring Boot upgrade automation agent. Your goal is to +validate upgrade inputs, orchestrate a safe and traceable pre-flight and +OpenRewrite execution workflow, and produce run artifacts under a single +timestamped directory per invocation. ## Execution order -[//]: # (todo: Describe the execution order of the prompt, for example: "The agent will first do X, then Y, and finally Z.") +1. Collect input values: + - `application-id` (required) + - `module-name` (optional, default `.`) + - `java-version` (optional, default `25`) + - `spring-boot-version` (optional, default `4.0`) +2. Compute a single run timestamp in format `yyyyMMdd-HHmmss` and reuse the + same value throughout the entire run. +3. Call `.github/skills/maven-upgrade-java-spring-boot/SKILL.md`. +4. Run orchestrator script: + - `.github/skills/maven-upgrade-java-spring-boot/scripts/orchestrator.sh` +5. The orchestrator must: + - call pre-flight validation + - launch execute-rewrite in non-blocking mode + - update `run.log` status transitions and log paths +6. Report output summary with final known state and artifact locations. ## Hard constraints -[//]: # (todo: Describe the hard constraints of the prompt, for example: "The agent must always do X, and never do Y.") +1. `application-id` must be present or fail fast before script execution. +2. The exact same computed timestamp must be reused across orchestrator, + pre-flight, execute-rewrite, and all artifact paths. +3. Do not block on `mvn rewrite:run` completion; it must be launched + asynchronously. +4. Always create or update run artifacts under: + `maven-upgrade-java-spring-boot///`. +5. Always write and maintain `run.log` with schema fields: + `runId`, `timestamp`, `overallStatus`, `status`, and `log`. +6. Handle failures gracefully and record them in script-specific logs and + `run.log` statuses. ## Output expectations -[//]: # (todo: Describe the output expectations of the prompt, for example: "The agent should output X, and never output Y.") +Return a concise execution summary that includes: +1. normalized input values used for execution +2. computed shared timestamp +3. orchestrator outcome and current overall run status +4. absolute or workspace-relative paths for: + - `run.log` + - `orchestrator.log` + - `preflight.log` + - `execute-rewrite.log` + - `pre-flight-error.log` (if present) +5. note that rewrite execution is asynchronous and may still be running. diff --git a/.github/skills/maven-upgrade-java-spring-boot/SKILL.md b/.github/skills/maven-upgrade-java-spring-boot/SKILL.md new file mode 100644 index 0000000..2bce59d --- /dev/null +++ b/.github/skills/maven-upgrade-java-spring-boot/SKILL.md @@ -0,0 +1,84 @@ +# Maven Upgrade Java Spring Boot Skill + +This skill orchestrates Maven-based Java and Spring Boot upgrades with +validated inputs, timestamped run artifacts, and non-blocking OpenRewrite +execution. + +## Inputs + +- `application-id` (required) +- `module-name` (optional, defaults to `.`) +- `java-version` (optional, defaults to `25`) +- `spring-boot-version` (optional, defaults to `4.0`) +- `timestamp` (optional externally, otherwise computed once by orchestrator in + format `yyyyMMdd-HHmmss`) + +## Scripts + +All scripts are under `.github/skills/maven-upgrade-java-spring-boot/scripts`. + +1. `orchestrator.sh` + - Computes defaults and timestamp once. + - Initializes run artifacts and `run.log`. + - Calls `pre-flight.sh`. + - Calls `execute-rewrite.sh` in non-blocking mode. + - Maintains `run.log` status and log pointers. + +2. `pre-flight.sh` + - Validates: + - Java version in `{17, 21, 25}` + - Spring Boot version in `{3.5, 4.0}` + - module name is `.` or listed in root `pom.xml` modules + - target module has a valid `pom.xml` + - Writes validation output to `preflight.log`. + - On failure writes `pre-flight-error.log` and exits non-zero. + +3. `execute-rewrite.sh` + - Launches `mvn rewrite:run` against root module or selected module. + - Supports single-module and multi-module projects. + - Runs asynchronously and returns immediately. + - Writes launch/runtime details to `execute-rewrite.log`. + +## Artifacts + +Per run artifacts are stored at: + +`maven-upgrade-java-spring-boot///` + +Files: + +- `run.log` +- `orchestrator.log` +- `preflight.log` +- `execute-rewrite.log` +- `pre-flight-error.log` (on pre-flight failures) + +## run.log Schema + +```json +{ + "runId": "", + "timestamp": "", + "overallStatus": "STARTED|IN-PROGRESS|FAILED|COMPLETED", + "status": { + "orchestrator": "SUCCESS|FAILED", + "preflight": "SUCCESS|FAILED", + "execute-rewrite": "SUCCESS|FAILED" + }, + "log": { + "orchestrator": "maven-upgrade-java-spring-boot///orchestrator.log", + "preflight": "maven-upgrade-java-spring-boot///preflight.log", + "execute-rewrite": "maven-upgrade-java-spring-boot///execute-rewrite.log" + } +} +``` + +## Suggested Invocation + +```bash +bash .github/skills/maven-upgrade-java-spring-boot/scripts/orchestrator.sh \ + --application-id "my-app" \ + --module-name "." \ + --java-version "25" \ + --spring-boot-version "4.0" +``` \ No newline at end of file diff --git a/.github/skills/maven-upgrade-java-spring-boot/scripts/common.sh b/.github/skills/maven-upgrade-java-spring-boot/scripts/common.sh new file mode 100755 index 0000000..d754969 --- /dev/null +++ b/.github/skills/maven-upgrade-java-spring-boot/scripts/common.sh @@ -0,0 +1,220 @@ +#!/usr/bin/env bash + +set -euo pipefail + +timestamp_now() { + date +"%Y%m%d-%H%M%S" +} + +normalize_module_name() { + local value="${1:-}" + if [[ -z "$value" ]]; then + echo "." + else + echo "$value" + fi +} + +normalize_java_version() { + local value="${1:-}" + if [[ -z "$value" ]]; then + echo "25" + else + echo "$value" + fi +} + +normalize_spring_boot_version() { + local value="${1:-}" + if [[ -z "$value" ]]; then + echo "4.0" + return + fi + + if [[ "$value" == "4" ]]; then + echo "4.0" + return + fi + + echo "$value" +} + +generate_run_id() { + if command -v uuidgen >/dev/null 2>&1; then + uuidgen + else + echo "run-$(timestamp_now)-$$" + fi +} + +json_escape() { + echo "${1:-}" | sed 's/\\/\\\\/g; s/"/\\"/g' +} + +run_output_dir() { + local workspace_root="$1" + local timestamp="$2" + local module_name="$3" + local module_segment + module_segment="$(artifact_module_segment "$module_name")" + echo "$workspace_root/maven-upgrade-java-spring-boot/$timestamp/$module_segment" +} + +artifact_module_segment() { + local module_name="$1" + if [[ "$module_name" == "." ]]; then + echo "root" + else + echo "$module_name" + fi +} + +write_run_log() { + local run_log_file="$1" + local run_id="$2" + local timestamp="$3" + local overall_status="$4" + local orchestrator_status="$5" + local preflight_status="$6" + local execute_rewrite_status="$7" + local orchestrator_log="$8" + local preflight_log="$9" + local execute_rewrite_log="${10}" + + local tmp_file + tmp_file="$(mktemp)" + + cat >"$tmp_file" < 0) { + value = substr($0, RSTART + 3, RLENGTH - 4) + print value + exit + } + } + ' "$file" +} + +extract_status_value() { + local key="$1" + local file="$2" + + if [[ ! -f "$file" ]]; then + echo "" + return + fi + + awk -v key="$key" ' + /"status"[[:space:]]*:[[:space:]]*\{/ { in_status = 1; next } + in_status && /\}/ { in_status = 0 } + in_status && $0 ~ "\\\"" key "\\\"" { + match($0, /: "[^"]*"/) + if (RSTART > 0) { + value = substr($0, RSTART + 3, RLENGTH - 4) + print value + exit + } + } + ' "$file" +} + +extract_log_value() { + local key="$1" + local file="$2" + + if [[ ! -f "$file" ]]; then + echo "" + return + fi + + awk -v key="$key" ' + /"log"[[:space:]]*:[[:space:]]*\{/ { in_log = 1; next } + in_log && /\}/ { in_log = 0 } + in_log && $0 ~ "\\\"" key "\\\"" { + match($0, /: "[^"]*"/) + if (RSTART > 0) { + value = substr($0, RSTART + 3, RLENGTH - 4) + print value + exit + } + } + ' "$file" +} + +update_run_log_stage() { + local run_log_file="$1" + local stage_key="$2" + local stage_status="$3" + local overall_status="$4" + + local run_id timestamp current_orchestrator current_preflight current_execute + local orchestrator_log preflight_log execute_rewrite_log + + run_id="$(extract_json_value "runId" "$run_log_file")" + timestamp="$(extract_json_value "timestamp" "$run_log_file")" + current_orchestrator="$(extract_status_value "orchestrator" "$run_log_file")" + current_preflight="$(extract_status_value "preflight" "$run_log_file")" + current_execute="$(extract_status_value "execute-rewrite" "$run_log_file")" + orchestrator_log="$(extract_log_value "orchestrator" "$run_log_file")" + preflight_log="$(extract_log_value "preflight" "$run_log_file")" + execute_rewrite_log="$(extract_log_value "execute-rewrite" "$run_log_file")" + + case "$stage_key" in + orchestrator) + current_orchestrator="$stage_status" + ;; + preflight) + current_preflight="$stage_status" + ;; + execute-rewrite) + current_execute="$stage_status" + ;; + *) + echo "Unsupported stage key: $stage_key" >&2 + return 1 + ;; + esac + + write_run_log \ + "$run_log_file" \ + "$run_id" \ + "$timestamp" \ + "$overall_status" \ + "$current_orchestrator" \ + "$current_preflight" \ + "$current_execute" \ + "$orchestrator_log" \ + "$preflight_log" \ + "$execute_rewrite_log" +} \ No newline at end of file diff --git a/.github/skills/maven-upgrade-java-spring-boot/scripts/execute-rewrite.sh b/.github/skills/maven-upgrade-java-spring-boot/scripts/execute-rewrite.sh new file mode 100755 index 0000000..5c066ff --- /dev/null +++ b/.github/skills/maven-upgrade-java-spring-boot/scripts/execute-rewrite.sh @@ -0,0 +1,101 @@ +#!/usr/bin/env bash + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "$SCRIPT_DIR/common.sh" + +APPLICATION_ID="" +MODULE_NAME="" +JAVA_VERSION="" +SPRING_BOOT_VERSION="" +TIMESTAMP="" +RUN_ID="" +WORKSPACE_ROOT="$(pwd)" + +while [[ $# -gt 0 ]]; do + case "$1" in + --application-id) + APPLICATION_ID="${2:-}" + shift 2 + ;; + --module-name) + MODULE_NAME="${2:-}" + shift 2 + ;; + --java-version) + JAVA_VERSION="${2:-}" + shift 2 + ;; + --spring-boot-version) + SPRING_BOOT_VERSION="${2:-}" + shift 2 + ;; + --timestamp) + TIMESTAMP="${2:-}" + shift 2 + ;; + --run-id) + RUN_ID="${2:-}" + shift 2 + ;; + --workspace-root) + WORKSPACE_ROOT="${2:-}" + shift 2 + ;; + *) + echo "Unknown argument: $1" >&2 + exit 2 + ;; + esac +done + +MODULE_NAME="$(normalize_module_name "$MODULE_NAME")" +JAVA_VERSION="$(normalize_java_version "$JAVA_VERSION")" +SPRING_BOOT_VERSION="$(normalize_spring_boot_version "$SPRING_BOOT_VERSION")" + +if [[ -z "$TIMESTAMP" ]]; then + TIMESTAMP="$(timestamp_now)" +fi + +RUN_DIR="$(run_output_dir "$WORKSPACE_ROOT" "$TIMESTAMP" "$MODULE_NAME")" +mkdir -p "$RUN_DIR" + +RUN_LOG="$RUN_DIR/run.log" +EXECUTE_REWRITE_LOG="$RUN_DIR/execute-rewrite.log" +PID_FILE="$RUN_DIR/execute-rewrite.pid" + +if [[ "$MODULE_NAME" == "." ]]; then + MVN_CMD=(mvn rewrite:run) +else + MVN_CMD=(mvn -pl "$MODULE_NAME" -am rewrite:run) +fi + +{ + echo "[$(date +"%Y-%m-%d %H:%M:%S")] execute-rewrite launch" + echo "application-id=$APPLICATION_ID module-name=$MODULE_NAME java-version=$JAVA_VERSION spring-boot-version=$SPRING_BOOT_VERSION" + printf "command=" + printf '%q ' "${MVN_CMD[@]}" + echo +} >>"$EXECUTE_REWRITE_LOG" + +( + set +e + cd "$WORKSPACE_ROOT" || exit 1 + "${MVN_CMD[@]}" >>"$EXECUTE_REWRITE_LOG" 2>&1 + rewrite_exit_code=$? + + if [[ -f "$RUN_LOG" ]]; then + if [[ $rewrite_exit_code -eq 0 ]]; then + update_run_log_stage "$RUN_LOG" "execute-rewrite" "SUCCESS" "COMPLETED" || true + else + update_run_log_stage "$RUN_LOG" "execute-rewrite" "FAILED" "FAILED" || true + fi + fi + + echo "[$(date +"%Y-%m-%d %H:%M:%S")] execute-rewrite finished with code=$rewrite_exit_code" >>"$EXECUTE_REWRITE_LOG" +) & + +bg_pid=$! +echo "$bg_pid" >"$PID_FILE" +echo "[$(date +"%Y-%m-%d %H:%M:%S")] execute-rewrite started in background pid=$bg_pid" >>"$EXECUTE_REWRITE_LOG" \ No newline at end of file diff --git a/.github/skills/maven-upgrade-java-spring-boot/scripts/orchestrator.sh b/.github/skills/maven-upgrade-java-spring-boot/scripts/orchestrator.sh new file mode 100755 index 0000000..ae5fb3c --- /dev/null +++ b/.github/skills/maven-upgrade-java-spring-boot/scripts/orchestrator.sh @@ -0,0 +1,164 @@ +#!/usr/bin/env bash + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "$SCRIPT_DIR/common.sh" + +APPLICATION_ID="" +MODULE_NAME="" +JAVA_VERSION="" +SPRING_BOOT_VERSION="" +TIMESTAMP="" +WORKSPACE_ROOT="$(pwd)" + +while [[ $# -gt 0 ]]; do + case "$1" in + --application-id) + APPLICATION_ID="${2:-}" + shift 2 + ;; + --module-name) + MODULE_NAME="${2:-}" + shift 2 + ;; + --java-version) + JAVA_VERSION="${2:-}" + shift 2 + ;; + --spring-boot-version) + SPRING_BOOT_VERSION="${2:-}" + shift 2 + ;; + --timestamp) + TIMESTAMP="${2:-}" + shift 2 + ;; + --workspace-root) + WORKSPACE_ROOT="${2:-}" + shift 2 + ;; + *) + echo "Unknown argument: $1" >&2 + exit 2 + ;; + esac +done + +if [[ -z "$APPLICATION_ID" ]]; then + echo "application-id is required" >&2 + exit 1 +fi + +MODULE_NAME="$(normalize_module_name "$MODULE_NAME")" +JAVA_VERSION="$(normalize_java_version "$JAVA_VERSION")" +SPRING_BOOT_VERSION="$(normalize_spring_boot_version "$SPRING_BOOT_VERSION")" + +if [[ -z "$TIMESTAMP" ]]; then + TIMESTAMP="$(timestamp_now)" +fi + +RUN_ID="$(generate_run_id)" +RUN_DIR="$(run_output_dir "$WORKSPACE_ROOT" "$TIMESTAMP" "$MODULE_NAME")" +mkdir -p "$RUN_DIR" + +RUN_LOG="$RUN_DIR/run.log" +ORCHESTRATOR_LOG="$RUN_DIR/orchestrator.log" +PREFLIGHT_LOG="$RUN_DIR/preflight.log" +EXECUTE_REWRITE_LOG="$RUN_DIR/execute-rewrite.log" +MODULE_SEGMENT="$(artifact_module_segment "$MODULE_NAME")" + +echo "[$(date +"%Y-%m-%d %H:%M:%S")] orchestrator started runId=$RUN_ID" >>"$ORCHESTRATOR_LOG" + +REL_ORCHESTRATOR_LOG="maven-upgrade-java-spring-boot/$TIMESTAMP/$MODULE_SEGMENT/orchestrator.log" +REL_PREFLIGHT_LOG="maven-upgrade-java-spring-boot/$TIMESTAMP/$MODULE_SEGMENT/preflight.log" +REL_EXECUTE_REWRITE_LOG="maven-upgrade-java-spring-boot/$TIMESTAMP/$MODULE_SEGMENT/execute-rewrite.log" + +write_run_log \ + "$RUN_LOG" \ + "$RUN_ID" \ + "$TIMESTAMP" \ + "STARTED" \ + "FAILED" \ + "FAILED" \ + "FAILED" \ + "$REL_ORCHESTRATOR_LOG" \ + "$REL_PREFLIGHT_LOG" \ + "$REL_EXECUTE_REWRITE_LOG" + +echo "[$(date +"%Y-%m-%d %H:%M:%S")] invoking pre-flight" >>"$ORCHESTRATOR_LOG" +if ! bash "$SCRIPT_DIR/pre-flight.sh" \ + --application-id "$APPLICATION_ID" \ + --module-name "$MODULE_NAME" \ + --java-version "$JAVA_VERSION" \ + --spring-boot-version "$SPRING_BOOT_VERSION" \ + --timestamp "$TIMESTAMP" \ + --workspace-root "$WORKSPACE_ROOT"; then + echo "[$(date +"%Y-%m-%d %H:%M:%S")] pre-flight failed" >>"$ORCHESTRATOR_LOG" + write_run_log \ + "$RUN_LOG" \ + "$RUN_ID" \ + "$TIMESTAMP" \ + "FAILED" \ + "FAILED" \ + "FAILED" \ + "FAILED" \ + "$REL_ORCHESTRATOR_LOG" \ + "$REL_PREFLIGHT_LOG" \ + "$REL_EXECUTE_REWRITE_LOG" + exit 1 +fi + +echo "[$(date +"%Y-%m-%d %H:%M:%S")] pre-flight succeeded" >>"$ORCHESTRATOR_LOG" + +write_run_log \ + "$RUN_LOG" \ + "$RUN_ID" \ + "$TIMESTAMP" \ + "IN-PROGRESS" \ + "SUCCESS" \ + "SUCCESS" \ + "FAILED" \ + "$REL_ORCHESTRATOR_LOG" \ + "$REL_PREFLIGHT_LOG" \ + "$REL_EXECUTE_REWRITE_LOG" + +echo "[$(date +"%Y-%m-%d %H:%M:%S")] launching execute-rewrite" >>"$ORCHESTRATOR_LOG" +if ! bash "$SCRIPT_DIR/execute-rewrite.sh" \ + --application-id "$APPLICATION_ID" \ + --module-name "$MODULE_NAME" \ + --java-version "$JAVA_VERSION" \ + --spring-boot-version "$SPRING_BOOT_VERSION" \ + --timestamp "$TIMESTAMP" \ + --run-id "$RUN_ID" \ + --workspace-root "$WORKSPACE_ROOT"; then + echo "[$(date +"%Y-%m-%d %H:%M:%S")] execute-rewrite launch failed" >>"$ORCHESTRATOR_LOG" + write_run_log \ + "$RUN_LOG" \ + "$RUN_ID" \ + "$TIMESTAMP" \ + "FAILED" \ + "FAILED" \ + "SUCCESS" \ + "FAILED" \ + "$REL_ORCHESTRATOR_LOG" \ + "$REL_PREFLIGHT_LOG" \ + "$REL_EXECUTE_REWRITE_LOG" + exit 1 +fi + +echo "[$(date +"%Y-%m-%d %H:%M:%S")] execute-rewrite launched in non-blocking mode" >>"$ORCHESTRATOR_LOG" + +write_run_log \ + "$RUN_LOG" \ + "$RUN_ID" \ + "$TIMESTAMP" \ + "IN-PROGRESS" \ + "SUCCESS" \ + "SUCCESS" \ + "SUCCESS" \ + "$REL_ORCHESTRATOR_LOG" \ + "$REL_PREFLIGHT_LOG" \ + "$REL_EXECUTE_REWRITE_LOG" + +echo "[$(date +"%Y-%m-%d %H:%M:%S")] orchestrator completed without waiting for rewrite" >>"$ORCHESTRATOR_LOG" \ No newline at end of file diff --git a/.github/skills/maven-upgrade-java-spring-boot/scripts/pre-flight.sh b/.github/skills/maven-upgrade-java-spring-boot/scripts/pre-flight.sh new file mode 100755 index 0000000..0f36c56 --- /dev/null +++ b/.github/skills/maven-upgrade-java-spring-boot/scripts/pre-flight.sh @@ -0,0 +1,132 @@ +#!/usr/bin/env bash + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "$SCRIPT_DIR/common.sh" + +APPLICATION_ID="" +MODULE_NAME="" +JAVA_VERSION="" +SPRING_BOOT_VERSION="" +TIMESTAMP="" +WORKSPACE_ROOT="$(pwd)" + +while [[ $# -gt 0 ]]; do + case "$1" in + --application-id) + APPLICATION_ID="${2:-}" + shift 2 + ;; + --module-name) + MODULE_NAME="${2:-}" + shift 2 + ;; + --java-version) + JAVA_VERSION="${2:-}" + shift 2 + ;; + --spring-boot-version) + SPRING_BOOT_VERSION="${2:-}" + shift 2 + ;; + --timestamp) + TIMESTAMP="${2:-}" + shift 2 + ;; + --workspace-root) + WORKSPACE_ROOT="${2:-}" + shift 2 + ;; + *) + echo "Unknown argument: $1" >&2 + exit 2 + ;; + esac +done + +MODULE_NAME="$(normalize_module_name "$MODULE_NAME")" +JAVA_VERSION="$(normalize_java_version "$JAVA_VERSION")" +SPRING_BOOT_VERSION="$(normalize_spring_boot_version "$SPRING_BOOT_VERSION")" + +if [[ -z "$TIMESTAMP" ]]; then + TIMESTAMP="$(timestamp_now)" +fi + +RUN_DIR="$(run_output_dir "$WORKSPACE_ROOT" "$TIMESTAMP" "$MODULE_NAME")" +mkdir -p "$RUN_DIR" + +PREFLIGHT_LOG="$RUN_DIR/preflight.log" +PREFLIGHT_ERROR_LOG="$RUN_DIR/pre-flight-error.log" + +log() { + echo "[$(date +"%Y-%m-%d %H:%M:%S")] $*" | tee -a "$PREFLIGHT_LOG" +} + +fail() { + local message="$1" + log "ERROR: $message" + echo "$message" >>"$PREFLIGHT_ERROR_LOG" + exit 1 +} + +log "Starting pre-flight validation" +log "application-id=$APPLICATION_ID module-name=$MODULE_NAME java-version=$JAVA_VERSION spring-boot-version=$SPRING_BOOT_VERSION" + +if [[ -z "$APPLICATION_ID" ]]; then + fail "application-id is required" +fi + +case "$JAVA_VERSION" in + 17|21|25) + ;; + *) + fail "java-version must be one of: 17, 21, 25" + ;; +esac + +case "$SPRING_BOOT_VERSION" in + 3.5|4.0) + ;; + *) + fail "spring-boot-version must be one of: 3.5, 4.0" + ;; +esac + +ROOT_POM="$WORKSPACE_ROOT/pom.xml" +if [[ ! -f "$ROOT_POM" ]]; then + fail "root pom.xml not found at $ROOT_POM" +fi + +if [[ "$MODULE_NAME" == "." ]]; then + TARGET_POM="$ROOT_POM" +else + TARGET_POM="$WORKSPACE_ROOT/$MODULE_NAME/pom.xml" + + MODULE_LIST="$(awk ' + // { in_modules=1; next } + /<\/modules>/ { in_modules=0 } + in_modules { + gsub(/^[ \t]+|[ \t]+$/, "", $0) + if ($0 ~ //) { + gsub(/|<\/module>/, "", $0) + gsub(/^[ \t]+|[ \t]+$/, "", $0) + print $0 + } + } + ' "$ROOT_POM")" + + if ! echo "$MODULE_LIST" | grep -Fxq "$MODULE_NAME"; then + fail "module-name '$MODULE_NAME' is not declared in root pom.xml " + fi +fi + +if [[ ! -f "$TARGET_POM" ]]; then + fail "target pom.xml not found at $TARGET_POM" +fi + +if ! grep -q ") at $TARGET_POM" +fi + +log "Pre-flight validation completed successfully" \ No newline at end of file From 95e9cc30274644c87f8e2b04cf1a430b7ca81417 Mon Sep 17 00:00:00 2001 From: Paul Williams Date: Sun, 14 Jun 2026 18:55:43 +0530 Subject: [PATCH 2/7] refactor: update the instruction of prompt and skill --- .../maven-upgrade-java-spring-boot.prompt.md | 54 ++++--------------- .../maven-upgrade-java-spring-boot/SKILL.md | 43 +++++++-------- 2 files changed, 29 insertions(+), 68 deletions(-) diff --git a/.github/prompts/maven-upgrade-java-spring-boot.prompt.md b/.github/prompts/maven-upgrade-java-spring-boot.prompt.md index f594d3e..3bc9bbb 100644 --- a/.github/prompts/maven-upgrade-java-spring-boot.prompt.md +++ b/.github/prompts/maven-upgrade-java-spring-boot.prompt.md @@ -1,10 +1,10 @@ --- name: "maven-upgrade-java-spring-boot" description: "GitHub copilot prompt to upgrade java and spring-boot" -# argument-hint: "Optional arguments (for example: name=Paul)" +argument-hint: "application-id (required), module-name (optional), java-version (optional), spring-boot-version (optional)" agent: agent -model: gpt-5.3-codex -tools: ['runCommands'] +model: GPT-5.3-Codex (copilot) +tools: ['execute', 'read', 'edit'] authors: ["paul58914080@gmail.com"] --- @@ -15,46 +15,14 @@ timestamped directory per invocation. ## Execution order -1. Collect input values: - - `application-id` (required) - - `module-name` (optional, default `.`) - - `java-version` (optional, default `25`) - - `spring-boot-version` (optional, default `4.0`) -2. Compute a single run timestamp in format `yyyyMMdd-HHmmss` and reuse the - same value throughout the entire run. -3. Call `.github/skills/maven-upgrade-java-spring-boot/SKILL.md`. -4. Run orchestrator script: - - `.github/skills/maven-upgrade-java-spring-boot/scripts/orchestrator.sh` -5. The orchestrator must: - - call pre-flight validation - - launch execute-rewrite in non-blocking mode - - update `run.log` status transitions and log paths -6. Report output summary with final known state and artifact locations. +1. Start the skill `.github/skills/maven-upgrade-java-spring-boot/SKILL.md`. Do not block waiting for completion of any scripts. The skill will manage the overall workflow and timing. ## Hard constraints -1. `application-id` must be present or fail fast before script execution. -2. The exact same computed timestamp must be reused across orchestrator, - pre-flight, execute-rewrite, and all artifact paths. -3. Do not block on `mvn rewrite:run` completion; it must be launched - asynchronously. -4. Always create or update run artifacts under: - `maven-upgrade-java-spring-boot///`. -5. Always write and maintain `run.log` with schema fields: - `runId`, `timestamp`, `overallStatus`, `status`, and `log`. -6. Handle failures gracefully and record them in script-specific logs and - `run.log` statuses. - -## Output expectations - -Return a concise execution summary that includes: -1. normalized input values used for execution -2. computed shared timestamp -3. orchestrator outcome and current overall run status -4. absolute or workspace-relative paths for: - - `run.log` - - `orchestrator.log` - - `preflight.log` - - `execute-rewrite.log` - - `pre-flight-error.log` (if present) -5. note that rewrite execution is asynchronous and may still be running. +1. Do not run copy/cd/mvn commands before the pre-flight validation script (`pre-flight.sh`) has completed successfully. +2. Do not run the OpenRewrite execution script (`execute-rewrite.sh`) before the pre-flight validation has completed successfully. +3. All scripts must be executed in the context of the root directory. +4. All outputs and logs must be written to the timestamped run directory. +5. If pre-flight validation fails, stop execution immediately and write the error details to `pre-flight-error.log` in the run directory. +6. After pre-flight validation succeeds, launch the OpenRewrite execution script in non-blocking mode and return immediately. +7. Maintain a `run.log` in the run directory that captures the overall execution status and pointers to all relevant logs and artifacts. \ No newline at end of file diff --git a/.github/skills/maven-upgrade-java-spring-boot/SKILL.md b/.github/skills/maven-upgrade-java-spring-boot/SKILL.md index 2bce59d..e7c6f7e 100644 --- a/.github/skills/maven-upgrade-java-spring-boot/SKILL.md +++ b/.github/skills/maven-upgrade-java-spring-boot/SKILL.md @@ -1,3 +1,9 @@ +--- +name: "maven-upgrade-java-spring-boot" +description: "Skill to upgrade java and spring-boot" +argument-hint: "application-id (required), module-name (optional), java-version (optional), spring-boot-version (optional)" +--- + # Maven Upgrade Java Spring Boot Skill This skill orchestrates Maven-based Java and Spring Boot upgrades with @@ -13,31 +19,18 @@ execution. - `timestamp` (optional externally, otherwise computed once by orchestrator in format `yyyyMMdd-HHmmss`) -## Scripts - -All scripts are under `.github/skills/maven-upgrade-java-spring-boot/scripts`. - -1. `orchestrator.sh` - - Computes defaults and timestamp once. - - Initializes run artifacts and `run.log`. - - Calls `pre-flight.sh`. - - Calls `execute-rewrite.sh` in non-blocking mode. - - Maintains `run.log` status and log pointers. - -2. `pre-flight.sh` - - Validates: - - Java version in `{17, 21, 25}` - - Spring Boot version in `{3.5, 4.0}` - - module name is `.` or listed in root `pom.xml` modules - - target module has a valid `pom.xml` - - Writes validation output to `preflight.log`. - - On failure writes `pre-flight-error.log` and exits non-zero. - -3. `execute-rewrite.sh` - - Launches `mvn rewrite:run` against root module or selected module. - - Supports single-module and multi-module projects. - - Runs asynchronously and returns immediately. - - Writes launch/runtime details to `execute-rewrite.log`. +## Execution + +Run this from the repository root after replacing the placeholders with your actual values: + +```bash +bash .github/skills/maven-upgrade-java-spring-boot/scripts/orchestrator.sh \ + --application-id "" \ + --module-name "" \ + --java-version "" \ + --spring-boot-version "" +``` + ## Artifacts From 55b4e62c9beab5be3517c5f5a7d57f75eb3dbacd Mon Sep 17 00:00:00 2001 From: Paul Williams Date: Sun, 14 Jun 2026 19:18:58 +0530 Subject: [PATCH 3/7] chore: rewrite resources --- .../resources/rewrite/java/17/artifact-coordinates.txt | 1 + .../resources/rewrite/java/17/rewrite.yml | 6 ++++++ .../resources/rewrite/java/21/artifact-coordinates.txt | 1 + .../resources/rewrite/java/21/rewrite.yml | 6 ++++++ .../resources/rewrite/java/25/artifact-coordinates.txt | 1 + .../resources/rewrite/java/25/rewrite.yml | 6 ++++++ .../rewrite/spring-boot/3_5/artifact-coordinates.txt | 1 + .../resources/rewrite/spring-boot/3_5/rewrite.yml | 6 ++++++ .../rewrite/spring-boot/4_0/artifact-coordinates.txt | 1 + .../resources/rewrite/spring-boot/4_0/rewrite.yml | 6 ++++++ 10 files changed, 35 insertions(+) create mode 100644 .github/skills/maven-upgrade-java-spring-boot/resources/rewrite/java/17/artifact-coordinates.txt create mode 100644 .github/skills/maven-upgrade-java-spring-boot/resources/rewrite/java/17/rewrite.yml create mode 100644 .github/skills/maven-upgrade-java-spring-boot/resources/rewrite/java/21/artifact-coordinates.txt create mode 100644 .github/skills/maven-upgrade-java-spring-boot/resources/rewrite/java/21/rewrite.yml create mode 100644 .github/skills/maven-upgrade-java-spring-boot/resources/rewrite/java/25/artifact-coordinates.txt create mode 100644 .github/skills/maven-upgrade-java-spring-boot/resources/rewrite/java/25/rewrite.yml create mode 100644 .github/skills/maven-upgrade-java-spring-boot/resources/rewrite/spring-boot/3_5/artifact-coordinates.txt create mode 100644 .github/skills/maven-upgrade-java-spring-boot/resources/rewrite/spring-boot/3_5/rewrite.yml create mode 100644 .github/skills/maven-upgrade-java-spring-boot/resources/rewrite/spring-boot/4_0/artifact-coordinates.txt create mode 100644 .github/skills/maven-upgrade-java-spring-boot/resources/rewrite/spring-boot/4_0/rewrite.yml diff --git a/.github/skills/maven-upgrade-java-spring-boot/resources/rewrite/java/17/artifact-coordinates.txt b/.github/skills/maven-upgrade-java-spring-boot/resources/rewrite/java/17/artifact-coordinates.txt new file mode 100644 index 0000000..ea5eaab --- /dev/null +++ b/.github/skills/maven-upgrade-java-spring-boot/resources/rewrite/java/17/artifact-coordinates.txt @@ -0,0 +1 @@ +org.openrewrite.recipe:rewrite-migrate-java:3.36.0 \ No newline at end of file diff --git a/.github/skills/maven-upgrade-java-spring-boot/resources/rewrite/java/17/rewrite.yml b/.github/skills/maven-upgrade-java-spring-boot/resources/rewrite/java/17/rewrite.yml new file mode 100644 index 0000000..810998b --- /dev/null +++ b/.github/skills/maven-upgrade-java-spring-boot/resources/rewrite/java/17/rewrite.yml @@ -0,0 +1,6 @@ +--- +type: specs.openrewrite.org/v1beta/recipe +name: org.cortexaidevkit.java.UpgradeJava17 +displayName: Upgrade Java to 17 +recipeList: + - org.openrewrite.java.migrate.UpgradeToJava17 \ No newline at end of file diff --git a/.github/skills/maven-upgrade-java-spring-boot/resources/rewrite/java/21/artifact-coordinates.txt b/.github/skills/maven-upgrade-java-spring-boot/resources/rewrite/java/21/artifact-coordinates.txt new file mode 100644 index 0000000..ea5eaab --- /dev/null +++ b/.github/skills/maven-upgrade-java-spring-boot/resources/rewrite/java/21/artifact-coordinates.txt @@ -0,0 +1 @@ +org.openrewrite.recipe:rewrite-migrate-java:3.36.0 \ No newline at end of file diff --git a/.github/skills/maven-upgrade-java-spring-boot/resources/rewrite/java/21/rewrite.yml b/.github/skills/maven-upgrade-java-spring-boot/resources/rewrite/java/21/rewrite.yml new file mode 100644 index 0000000..211670d --- /dev/null +++ b/.github/skills/maven-upgrade-java-spring-boot/resources/rewrite/java/21/rewrite.yml @@ -0,0 +1,6 @@ +--- +type: specs.openrewrite.org/v1beta/recipe +name: org.cortexaidevkit.java.UpgradeJava21 +displayName: Upgrade Java to 21 +recipeList: + - org.openrewrite.java.migrate.UpgradeToJava21 \ No newline at end of file diff --git a/.github/skills/maven-upgrade-java-spring-boot/resources/rewrite/java/25/artifact-coordinates.txt b/.github/skills/maven-upgrade-java-spring-boot/resources/rewrite/java/25/artifact-coordinates.txt new file mode 100644 index 0000000..ea5eaab --- /dev/null +++ b/.github/skills/maven-upgrade-java-spring-boot/resources/rewrite/java/25/artifact-coordinates.txt @@ -0,0 +1 @@ +org.openrewrite.recipe:rewrite-migrate-java:3.36.0 \ No newline at end of file diff --git a/.github/skills/maven-upgrade-java-spring-boot/resources/rewrite/java/25/rewrite.yml b/.github/skills/maven-upgrade-java-spring-boot/resources/rewrite/java/25/rewrite.yml new file mode 100644 index 0000000..d1c8b2d --- /dev/null +++ b/.github/skills/maven-upgrade-java-spring-boot/resources/rewrite/java/25/rewrite.yml @@ -0,0 +1,6 @@ +--- +type: specs.openrewrite.org/v1beta/recipe +name: org.cortexaidevkit.java.UpgradeJava25 +displayName: Upgrade Java to 25 +recipeList: + - org.openrewrite.java.migrate.UpgradeToJava25 \ No newline at end of file diff --git a/.github/skills/maven-upgrade-java-spring-boot/resources/rewrite/spring-boot/3_5/artifact-coordinates.txt b/.github/skills/maven-upgrade-java-spring-boot/resources/rewrite/spring-boot/3_5/artifact-coordinates.txt new file mode 100644 index 0000000..62ea1d2 --- /dev/null +++ b/.github/skills/maven-upgrade-java-spring-boot/resources/rewrite/spring-boot/3_5/artifact-coordinates.txt @@ -0,0 +1 @@ +org.openrewrite.recipe:rewrite-spring:6.32.0 \ No newline at end of file diff --git a/.github/skills/maven-upgrade-java-spring-boot/resources/rewrite/spring-boot/3_5/rewrite.yml b/.github/skills/maven-upgrade-java-spring-boot/resources/rewrite/spring-boot/3_5/rewrite.yml new file mode 100644 index 0000000..7ca06ad --- /dev/null +++ b/.github/skills/maven-upgrade-java-spring-boot/resources/rewrite/spring-boot/3_5/rewrite.yml @@ -0,0 +1,6 @@ +--- +type: specs.openrewrite.org/v1beta/recipe +name: org.cortexaidevkit.spring.boot.UpgradeSpringBoot_4_0 +displayName: Migrate to Spring Boot 4.0 +recipeList: + - org.openrewrite.java.spring.boot4.UpgradeSpringBoot_4_0 \ No newline at end of file diff --git a/.github/skills/maven-upgrade-java-spring-boot/resources/rewrite/spring-boot/4_0/artifact-coordinates.txt b/.github/skills/maven-upgrade-java-spring-boot/resources/rewrite/spring-boot/4_0/artifact-coordinates.txt new file mode 100644 index 0000000..62ea1d2 --- /dev/null +++ b/.github/skills/maven-upgrade-java-spring-boot/resources/rewrite/spring-boot/4_0/artifact-coordinates.txt @@ -0,0 +1 @@ +org.openrewrite.recipe:rewrite-spring:6.32.0 \ No newline at end of file diff --git a/.github/skills/maven-upgrade-java-spring-boot/resources/rewrite/spring-boot/4_0/rewrite.yml b/.github/skills/maven-upgrade-java-spring-boot/resources/rewrite/spring-boot/4_0/rewrite.yml new file mode 100644 index 0000000..3c7b191 --- /dev/null +++ b/.github/skills/maven-upgrade-java-spring-boot/resources/rewrite/spring-boot/4_0/rewrite.yml @@ -0,0 +1,6 @@ +--- +type: specs.openrewrite.org/v1beta/recipe +name: org.cortexaidevkit.spring.boot.UpgradeSpringBoot_4_0 +displayName: Migrate to Spring Boot 4.0 +recipeList: + - org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_5 \ No newline at end of file From 90d679bbd70194b7e907ed889a34807561dc71af Mon Sep 17 00:00:00 2001 From: Paul Williams Date: Sun, 14 Jun 2026 19:24:23 +0530 Subject: [PATCH 4/7] refactor: externalize the version of rewrite-maven-plugin --- .../scripts/execute-rewrite.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/skills/maven-upgrade-java-spring-boot/scripts/execute-rewrite.sh b/.github/skills/maven-upgrade-java-spring-boot/scripts/execute-rewrite.sh index 5c066ff..39eb184 100755 --- a/.github/skills/maven-upgrade-java-spring-boot/scripts/execute-rewrite.sh +++ b/.github/skills/maven-upgrade-java-spring-boot/scripts/execute-rewrite.sh @@ -64,11 +64,12 @@ mkdir -p "$RUN_DIR" RUN_LOG="$RUN_DIR/run.log" EXECUTE_REWRITE_LOG="$RUN_DIR/execute-rewrite.log" PID_FILE="$RUN_DIR/execute-rewrite.pid" +REWRITE_MAVEN_PLUGIN_VERSION="6.40.0" if [[ "$MODULE_NAME" == "." ]]; then - MVN_CMD=(mvn rewrite:run) + MVN_CMD=(mvn -U org.openrewrite.maven:rewrite-maven-plugin:$REWRITE_MAVEN_PLUGIN_VERSION:run) else - MVN_CMD=(mvn -pl "$MODULE_NAME" -am rewrite:run) + MVN_CMD=(mvn -pl "$MODULE_NAME" -am org.openrewrite.maven:rewrite-maven-plugin:$REWRITE_MAVEN_PLUGIN_VERSION:run) fi { From c38e93c900868ef7623bc6aea49360b073076484 Mon Sep 17 00:00:00 2001 From: Paul Williams Date: Sun, 14 Jun 2026 23:41:27 +0530 Subject: [PATCH 5/7] feat: generate recipes and coordinates perform cleanup of rewrite.yml --- .../rewrite/spring-boot/4_0/rewrite.yml | 2 +- .../scripts/execute-rewrite.sh | 29 ++- .../scripts/generate-rewrite-config.sh | 242 ++++++++++++++++++ 3 files changed, 270 insertions(+), 3 deletions(-) create mode 100755 .github/skills/maven-upgrade-java-spring-boot/scripts/generate-rewrite-config.sh diff --git a/.github/skills/maven-upgrade-java-spring-boot/resources/rewrite/spring-boot/4_0/rewrite.yml b/.github/skills/maven-upgrade-java-spring-boot/resources/rewrite/spring-boot/4_0/rewrite.yml index 3c7b191..7ca06ad 100644 --- a/.github/skills/maven-upgrade-java-spring-boot/resources/rewrite/spring-boot/4_0/rewrite.yml +++ b/.github/skills/maven-upgrade-java-spring-boot/resources/rewrite/spring-boot/4_0/rewrite.yml @@ -3,4 +3,4 @@ type: specs.openrewrite.org/v1beta/recipe name: org.cortexaidevkit.spring.boot.UpgradeSpringBoot_4_0 displayName: Migrate to Spring Boot 4.0 recipeList: - - org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_5 \ No newline at end of file + - org.openrewrite.java.spring.boot4.UpgradeSpringBoot_4_0 \ No newline at end of file diff --git a/.github/skills/maven-upgrade-java-spring-boot/scripts/execute-rewrite.sh b/.github/skills/maven-upgrade-java-spring-boot/scripts/execute-rewrite.sh index 39eb184..9658a47 100755 --- a/.github/skills/maven-upgrade-java-spring-boot/scripts/execute-rewrite.sh +++ b/.github/skills/maven-upgrade-java-spring-boot/scripts/execute-rewrite.sh @@ -65,16 +65,36 @@ RUN_LOG="$RUN_DIR/run.log" EXECUTE_REWRITE_LOG="$RUN_DIR/execute-rewrite.log" PID_FILE="$RUN_DIR/execute-rewrite.pid" REWRITE_MAVEN_PLUGIN_VERSION="6.40.0" +ROOT_REWRITE_FILE="$WORKSPACE_ROOT/rewrite.yml" + +GENERATE_REWRITE_SCRIPT="$SCRIPT_DIR/generate-rewrite-config.sh" +if [[ ! -x "$GENERATE_REWRITE_SCRIPT" ]]; then + echo "generate rewrite script is missing or not executable: $GENERATE_REWRITE_SCRIPT" >&2 + exit 1 +fi + +REWRITE_FLAGS="$($GENERATE_REWRITE_SCRIPT \ + --java-version "$JAVA_VERSION" \ + --spring-boot-version "$SPRING_BOOT_VERSION" \ + --workspace-root "$WORKSPACE_ROOT")" + +if [[ -z "$REWRITE_FLAGS" ]]; then + echo "failed to generate rewrite flags" >&2 + exit 1 +fi + +read -r -a REWRITE_FLAGS_ARRAY <<< "$REWRITE_FLAGS" if [[ "$MODULE_NAME" == "." ]]; then - MVN_CMD=(mvn -U org.openrewrite.maven:rewrite-maven-plugin:$REWRITE_MAVEN_PLUGIN_VERSION:run) + MVN_CMD=(mvn -U org.openrewrite.maven:rewrite-maven-plugin:$REWRITE_MAVEN_PLUGIN_VERSION:run "${REWRITE_FLAGS_ARRAY[@]}") else - MVN_CMD=(mvn -pl "$MODULE_NAME" -am org.openrewrite.maven:rewrite-maven-plugin:$REWRITE_MAVEN_PLUGIN_VERSION:run) + MVN_CMD=(mvn -pl "$MODULE_NAME" -am org.openrewrite.maven:rewrite-maven-plugin:$REWRITE_MAVEN_PLUGIN_VERSION:run "${REWRITE_FLAGS_ARRAY[@]}") fi { echo "[$(date +"%Y-%m-%d %H:%M:%S")] execute-rewrite launch" echo "application-id=$APPLICATION_ID module-name=$MODULE_NAME java-version=$JAVA_VERSION spring-boot-version=$SPRING_BOOT_VERSION" + echo "rewrite-flags=$REWRITE_FLAGS" printf "command=" printf '%q ' "${MVN_CMD[@]}" echo @@ -82,6 +102,11 @@ fi ( set +e + cleanup_generated_rewrite() { + rm -f "$ROOT_REWRITE_FILE" + } + trap cleanup_generated_rewrite EXIT + cd "$WORKSPACE_ROOT" || exit 1 "${MVN_CMD[@]}" >>"$EXECUTE_REWRITE_LOG" 2>&1 rewrite_exit_code=$? diff --git a/.github/skills/maven-upgrade-java-spring-boot/scripts/generate-rewrite-config.sh b/.github/skills/maven-upgrade-java-spring-boot/scripts/generate-rewrite-config.sh new file mode 100755 index 0000000..3baab1b --- /dev/null +++ b/.github/skills/maven-upgrade-java-spring-boot/scripts/generate-rewrite-config.sh @@ -0,0 +1,242 @@ +#!/usr/bin/env bash + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +RESOURCE_ROOT="$SCRIPT_DIR/../resources/rewrite" +WORKSPACE_ROOT="$(pwd)" +OUTPUT_FILE="" +JAVA_VERSION="" +SPRING_BOOT_VERSION="" + +usage() { + cat <<'EOF' +Usage: + generate-rewrite-config.sh --java-version <17|21|25> --spring-boot-version <3.5|4.0> [--workspace-root ] [--output-file ] + +Description: + 1) Reads rewrite resources for the selected Java and Spring Boot versions. + 2) Generates a combined rewrite.yml at the repository root (or --output-file). + 3) Prints a Maven flags string: + -Drewrite.activeRecipes= -Drewrite.recipeArtifactCoordinates= +EOF +} + +trim() { + local value="$1" + value="${value#"${value%%[![:space:]]*}"}" + value="${value%"${value##*[![:space:]]}"}" + printf '%s' "$value" +} + +normalize_spring_boot_dir() { + local value="$1" + case "$value" in + 3.5) + echo "3_5" + ;; + 4.0|4) + echo "4_0" + ;; + *) + echo "" + ;; + esac +} + +get_recipe_name() { + local file="$1" + awk '/^name:[[:space:]]+/ {print $2; exit}' "$file" +} + +dedupe_documents_by_name() { + local input_file="$1" + local output_file="$2" + + awk ' + function ltrim(s) { sub(/^[ \t\r\n]+/, "", s); return s } + function rtrim(s) { sub(/[ \t\r\n]+$/, "", s); return s } + function trim(s) { return rtrim(ltrim(s)) } + + BEGIN { + RS="---[ \t\r\n]*\n" + ORS="" + } + + { + block = trim($0) + if (block == "") { + next + } + + recipe_name = "" + n = split(block, lines, /\n/) + for (i = 1; i <= n; i++) { + if (lines[i] ~ /^name:[ \t]+/) { + recipe_name = lines[i] + sub(/^name:[ \t]+/, "", recipe_name) + recipe_name = trim(recipe_name) + break + } + } + + if (recipe_name == "") { + key = block + } else { + key = "name::" recipe_name + } + + if (!(key in seen)) { + seen[key] = 1 + print "---\n" block "\n\n" + } + } + ' "$input_file" > "$output_file" +} + +build_unique_coordinates_csv() { + local java_coords_file="$1" + local spring_coords_file="$2" + + awk -F',' ' + function ltrim(s) { sub(/^[ \t\r\n]+/, "", s); return s } + function rtrim(s) { sub(/[ \t\r\n]+$/, "", s); return s } + function trim(s) { return rtrim(ltrim(s)) } + + { + for (i = 1; i <= NF; i++) { + token = trim($i) + if (token != "" && !(token in seen)) { + seen[token] = 1 + ordered[++count] = token + } + } + } + + END { + for (i = 1; i <= count; i++) { + printf "%s", ordered[i] + if (i < count) { + printf "," + } + } + } + ' "$java_coords_file" "$spring_coords_file" +} + +while [[ $# -gt 0 ]]; do + case "$1" in + --java-version) + JAVA_VERSION="${2:-}" + shift 2 + ;; + --spring-boot-version) + SPRING_BOOT_VERSION="${2:-}" + shift 2 + ;; + --workspace-root) + WORKSPACE_ROOT="${2:-}" + shift 2 + ;; + --output-file) + OUTPUT_FILE="${2:-}" + shift 2 + ;; + -h|--help) + usage + exit 0 + ;; + *) + echo "Unknown argument: $1" >&2 + usage >&2 + exit 2 + ;; + esac +done + +if [[ -z "$JAVA_VERSION" || -z "$SPRING_BOOT_VERSION" ]]; then + echo "Both --java-version and --spring-boot-version are required." >&2 + usage >&2 + exit 1 +fi + +case "$JAVA_VERSION" in + 17|21|25) + ;; + *) + echo "Unsupported java version: $JAVA_VERSION (expected 17, 21, or 25)." >&2 + exit 1 + ;; +esac + +SPRING_BOOT_DIR="$(normalize_spring_boot_dir "$SPRING_BOOT_VERSION")" +if [[ -z "$SPRING_BOOT_DIR" ]]; then + echo "Unsupported spring boot version: $SPRING_BOOT_VERSION (expected 3.5 or 4.0)." >&2 + exit 1 +fi + +if [[ "$SPRING_BOOT_VERSION" == "4" ]]; then + SPRING_BOOT_VERSION="4.0" +fi + +JAVA_DIR="$RESOURCE_ROOT/java/$JAVA_VERSION" +SPRING_DIR="$RESOURCE_ROOT/spring-boot/$SPRING_BOOT_DIR" + +JAVA_REWRITE_FILE="$JAVA_DIR/rewrite.yml" +SPRING_REWRITE_FILE="$SPRING_DIR/rewrite.yml" +JAVA_COORDS_FILE="$JAVA_DIR/artifact-coordinates.txt" +SPRING_COORDS_FILE="$SPRING_DIR/artifact-coordinates.txt" + +for path in "$JAVA_REWRITE_FILE" "$SPRING_REWRITE_FILE" "$JAVA_COORDS_FILE" "$SPRING_COORDS_FILE"; do + if [[ ! -f "$path" ]]; then + echo "Required file not found: $path" >&2 + exit 1 + fi +done + +if [[ -z "$OUTPUT_FILE" ]]; then + OUTPUT_FILE="$WORKSPACE_ROOT/rewrite.yml" +fi + +JAVA_RECIPE_NAME="$(get_recipe_name "$JAVA_REWRITE_FILE")" +SPRING_RECIPE_NAME="$(get_recipe_name "$SPRING_REWRITE_FILE")" + +if [[ -z "$JAVA_RECIPE_NAME" || -z "$SPRING_RECIPE_NAME" ]]; then + echo "Failed to parse recipe names from source rewrite.yml files." >&2 + exit 1 +fi + +SPRING_BOOT_UNDERSCORE="${SPRING_BOOT_VERSION//./_}" +COMBINED_RECIPE_NAME="org.cortexaidevkit.java.spring.boot.UpgradeJava${JAVA_VERSION}SpringBoot_${SPRING_BOOT_UNDERSCORE}" + +TMP_INPUT="$(mktemp)" +TMP_OUTPUT="$(mktemp)" +trap 'rm -f "$TMP_INPUT" "$TMP_OUTPUT"' EXIT + +{ + cat "$JAVA_REWRITE_FILE" + echo + cat "$SPRING_REWRITE_FILE" + echo + cat < "$TMP_INPUT" + +dedupe_documents_by_name "$TMP_INPUT" "$TMP_OUTPUT" +mv "$TMP_OUTPUT" "$OUTPUT_FILE" + +COORDINATES_CSV="$(build_unique_coordinates_csv "$JAVA_COORDS_FILE" "$SPRING_COORDS_FILE")" + +if [[ -z "$COORDINATES_CSV" ]]; then + echo "Failed to resolve rewrite recipe artifact coordinates." >&2 + exit 1 +fi + +echo "-Drewrite.activeRecipes=$COMBINED_RECIPE_NAME -Drewrite.recipeArtifactCoordinates=$COORDINATES_CSV" From 76f905e3a80a4acc8e720215be195db02ee4ea41 Mon Sep 17 00:00:00 2001 From: Paul Williams Date: Mon, 15 Jun 2026 00:43:24 +0530 Subject: [PATCH 6/7] feat: update run with inputs, rewrite --- .DS_Store | Bin 0 -> 6148 bytes .../maven-upgrade-java-spring-boot.prompt.md | 10 +-- .../maven-upgrade-java-spring-boot/SKILL.md | 43 +++---------- .../scripts/common.sh | 58 +++++++++++++++--- .../scripts/execute-rewrite.sh | 51 ++++++++++----- .../scripts/orchestrator.sh | 20 ++++++ .gitignore | 3 + 7 files changed, 120 insertions(+), 65 deletions(-) create mode 100644 .DS_Store create mode 100644 .gitignore diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..d82eb4e1cb790da44fe1fa56361cd399135a9941 GIT binary patch literal 6148 zcmeHK%}T>S5T32orW7Fug&r5Y7Ohr9@e-=OfDt{Y)Wj4Uj9FC>4~NjO~x;d$IIdhXhhO7kF2`$Jt2M}17Wx`@+A6TAacQE@rxlvfCuYZ%HLH zp(lTsCMvzd$aKT$MvTk=Gr$ZiBm?%aa~ccT9XG`cFay6~fX)YrO6XZE4eFx8_QiH>f0(R~q~% k!G*qxF_*65CaM" ``` - -## Artifacts - -Per run artifacts are stored at: - -`maven-upgrade-java-spring-boot///` - -Files: - -- `run.log` -- `orchestrator.log` -- `preflight.log` -- `execute-rewrite.log` -- `pre-flight-error.log` (on pre-flight failures) - -## run.log Schema - -```json -{ - "runId": "", - "timestamp": "", - "overallStatus": "STARTED|IN-PROGRESS|FAILED|COMPLETED", - "status": { - "orchestrator": "SUCCESS|FAILED", - "preflight": "SUCCESS|FAILED", - "execute-rewrite": "SUCCESS|FAILED" - }, - "log": { - "orchestrator": "maven-upgrade-java-spring-boot///orchestrator.log", - "preflight": "maven-upgrade-java-spring-boot///preflight.log", - "execute-rewrite": "maven-upgrade-java-spring-boot///execute-rewrite.log" - } -} -``` - ## Suggested Invocation ```bash @@ -74,4 +39,10 @@ bash .github/skills/maven-upgrade-java-spring-boot/scripts/orchestrator.sh \ --module-name "." \ --java-version "25" \ --spring-boot-version "4.0" -``` \ No newline at end of file +``` + +## Hard constraints + +Strict mode: execute only requested Execution, no extra validation, no assumptions, no follow-up actions without my explicit go-ahead. + +Post-execution stop rule: once the orchestrator command returns, exit immediately. Do not run artifact checks, log reads, process polling, or any additional commands unless explicitly requested. \ No newline at end of file diff --git a/.github/skills/maven-upgrade-java-spring-boot/scripts/common.sh b/.github/skills/maven-upgrade-java-spring-boot/scripts/common.sh index d754969..0222cef 100755 --- a/.github/skills/maven-upgrade-java-spring-boot/scripts/common.sh +++ b/.github/skills/maven-upgrade-java-spring-boot/scripts/common.sh @@ -73,13 +73,17 @@ write_run_log() { local run_log_file="$1" local run_id="$2" local timestamp="$3" - local overall_status="$4" - local orchestrator_status="$5" - local preflight_status="$6" - local execute_rewrite_status="$7" - local orchestrator_log="$8" - local preflight_log="$9" - local execute_rewrite_log="${10}" + local application_id="$4" + local module_name="$5" + local java_version="$6" + local spring_boot_version="$7" + local overall_status="$8" + local orchestrator_status="$9" + local preflight_status="${10}" + local execute_rewrite_status="${11}" + local orchestrator_log="${12}" + local preflight_log="${13}" + local execute_rewrite_log="${14}" local tmp_file tmp_file="$(mktemp)" @@ -88,6 +92,12 @@ write_run_log() { { "runId": "$(json_escape "$run_id")", "timestamp": "$(json_escape "$timestamp")", + "inputs": { + "application-id": "$(json_escape "$application_id")", + "module-name": "$(json_escape "$module_name")", + "java-version": "$(json_escape "$java_version")", + "spring-boot-version": "$(json_escape "$spring_boot_version")" + }, "overallStatus": "$(json_escape "$overall_status")", "status": { "orchestrator": "$(json_escape "$orchestrator_status")", @@ -172,17 +182,45 @@ extract_log_value() { ' "$file" } +extract_input_value() { + local key="$1" + local file="$2" + + if [[ ! -f "$file" ]]; then + echo "" + return + fi + + awk -v key="$key" ' + /"inputs"[[:space:]]*:[[:space:]]*\{/ { in_input = 1; next } + in_input && /\}/ { in_input = 0 } + in_input && $0 ~ "\\\"" key "\\\"" { + match($0, /: "[^"]*"/) + if (RSTART > 0) { + value = substr($0, RSTART + 3, RLENGTH - 4) + print value + exit + } + } + ' "$file" +} + update_run_log_stage() { local run_log_file="$1" local stage_key="$2" local stage_status="$3" local overall_status="$4" - local run_id timestamp current_orchestrator current_preflight current_execute + local run_id timestamp application_id module_name java_version spring_boot_version + local current_orchestrator current_preflight current_execute local orchestrator_log preflight_log execute_rewrite_log run_id="$(extract_json_value "runId" "$run_log_file")" timestamp="$(extract_json_value "timestamp" "$run_log_file")" + application_id="$(extract_input_value "application-id" "$run_log_file")" + module_name="$(extract_input_value "module-name" "$run_log_file")" + java_version="$(extract_input_value "java-version" "$run_log_file")" + spring_boot_version="$(extract_input_value "spring-boot-version" "$run_log_file")" current_orchestrator="$(extract_status_value "orchestrator" "$run_log_file")" current_preflight="$(extract_status_value "preflight" "$run_log_file")" current_execute="$(extract_status_value "execute-rewrite" "$run_log_file")" @@ -210,6 +248,10 @@ update_run_log_stage() { "$run_log_file" \ "$run_id" \ "$timestamp" \ + "$application_id" \ + "$module_name" \ + "$java_version" \ + "$spring_boot_version" \ "$overall_status" \ "$current_orchestrator" \ "$current_preflight" \ diff --git a/.github/skills/maven-upgrade-java-spring-boot/scripts/execute-rewrite.sh b/.github/skills/maven-upgrade-java-spring-boot/scripts/execute-rewrite.sh index 9658a47..9c66dfe 100755 --- a/.github/skills/maven-upgrade-java-spring-boot/scripts/execute-rewrite.sh +++ b/.github/skills/maven-upgrade-java-spring-boot/scripts/execute-rewrite.sh @@ -64,8 +64,23 @@ mkdir -p "$RUN_DIR" RUN_LOG="$RUN_DIR/run.log" EXECUTE_REWRITE_LOG="$RUN_DIR/execute-rewrite.log" PID_FILE="$RUN_DIR/execute-rewrite.pid" +REWRITE_COPY_FILE="$RUN_DIR/rewrite.yml" REWRITE_MAVEN_PLUGIN_VERSION="6.40.0" -ROOT_REWRITE_FILE="$WORKSPACE_ROOT/rewrite.yml" +WORKSPACE_REWRITE_FILE="$WORKSPACE_ROOT/rewrite.yml" + +log_execute_rewrite_line() { + echo "[$(date +"%Y-%m-%d %H:%M:%S")] $1" >>"$EXECUTE_REWRITE_LOG" +} + +log_execute_rewrite_command() { + local label="$1" + shift + + log_execute_rewrite_line "$label" + for argument in "$@"; do + printf ' %q\n' "$argument" >>"$EXECUTE_REWRITE_LOG" + done +} GENERATE_REWRITE_SCRIPT="$SCRIPT_DIR/generate-rewrite-config.sh" if [[ ! -x "$GENERATE_REWRITE_SCRIPT" ]]; then @@ -83,27 +98,35 @@ if [[ -z "$REWRITE_FLAGS" ]]; then exit 1 fi +if [[ ! -f "$WORKSPACE_REWRITE_FILE" ]]; then + echo "generated rewrite file not found: $WORKSPACE_REWRITE_FILE" >&2 + exit 1 +fi + +cp "$WORKSPACE_REWRITE_FILE" "$REWRITE_COPY_FILE" + read -r -a REWRITE_FLAGS_ARRAY <<< "$REWRITE_FLAGS" if [[ "$MODULE_NAME" == "." ]]; then - MVN_CMD=(mvn -U org.openrewrite.maven:rewrite-maven-plugin:$REWRITE_MAVEN_PLUGIN_VERSION:run "${REWRITE_FLAGS_ARRAY[@]}") + MVN_CMD=(mvn -B -U org.openrewrite.maven:rewrite-maven-plugin:$REWRITE_MAVEN_PLUGIN_VERSION:run "${REWRITE_FLAGS_ARRAY[@]}") else - MVN_CMD=(mvn -pl "$MODULE_NAME" -am org.openrewrite.maven:rewrite-maven-plugin:$REWRITE_MAVEN_PLUGIN_VERSION:run "${REWRITE_FLAGS_ARRAY[@]}") + MVN_CMD=(mvn -B -pl "$MODULE_NAME" -am org.openrewrite.maven:rewrite-maven-plugin:$REWRITE_MAVEN_PLUGIN_VERSION:run "${REWRITE_FLAGS_ARRAY[@]}") fi -{ - echo "[$(date +"%Y-%m-%d %H:%M:%S")] execute-rewrite launch" - echo "application-id=$APPLICATION_ID module-name=$MODULE_NAME java-version=$JAVA_VERSION spring-boot-version=$SPRING_BOOT_VERSION" - echo "rewrite-flags=$REWRITE_FLAGS" - printf "command=" - printf '%q ' "${MVN_CMD[@]}" - echo -} >>"$EXECUTE_REWRITE_LOG" +log_execute_rewrite_line "execute-rewrite launch" +log_execute_rewrite_line "application-id=$APPLICATION_ID" +log_execute_rewrite_line "module-name=$MODULE_NAME" +log_execute_rewrite_line "java-version=$JAVA_VERSION" +log_execute_rewrite_line "spring-boot-version=$SPRING_BOOT_VERSION" +log_execute_rewrite_line "rewrite-file=$REWRITE_COPY_FILE" +log_execute_rewrite_line "rewrite-flags:" +printf ' %s\n' "$REWRITE_FLAGS" >>"$EXECUTE_REWRITE_LOG" +log_execute_rewrite_command "command:" "${MVN_CMD[@]}" ( set +e cleanup_generated_rewrite() { - rm -f "$ROOT_REWRITE_FILE" + rm -f "$WORKSPACE_REWRITE_FILE" } trap cleanup_generated_rewrite EXIT @@ -119,9 +142,9 @@ fi fi fi - echo "[$(date +"%Y-%m-%d %H:%M:%S")] execute-rewrite finished with code=$rewrite_exit_code" >>"$EXECUTE_REWRITE_LOG" + log_execute_rewrite_line "execute-rewrite finished with code=$rewrite_exit_code" ) & bg_pid=$! echo "$bg_pid" >"$PID_FILE" -echo "[$(date +"%Y-%m-%d %H:%M:%S")] execute-rewrite started in background pid=$bg_pid" >>"$EXECUTE_REWRITE_LOG" \ No newline at end of file +log_execute_rewrite_line "execute-rewrite started in background pid=$bg_pid" \ No newline at end of file diff --git a/.github/skills/maven-upgrade-java-spring-boot/scripts/orchestrator.sh b/.github/skills/maven-upgrade-java-spring-boot/scripts/orchestrator.sh index ae5fb3c..7b99a8a 100755 --- a/.github/skills/maven-upgrade-java-spring-boot/scripts/orchestrator.sh +++ b/.github/skills/maven-upgrade-java-spring-boot/scripts/orchestrator.sh @@ -78,6 +78,10 @@ write_run_log \ "$RUN_LOG" \ "$RUN_ID" \ "$TIMESTAMP" \ + "$APPLICATION_ID" \ + "$MODULE_NAME" \ + "$JAVA_VERSION" \ + "$SPRING_BOOT_VERSION" \ "STARTED" \ "FAILED" \ "FAILED" \ @@ -99,6 +103,10 @@ if ! bash "$SCRIPT_DIR/pre-flight.sh" \ "$RUN_LOG" \ "$RUN_ID" \ "$TIMESTAMP" \ + "$APPLICATION_ID" \ + "$MODULE_NAME" \ + "$JAVA_VERSION" \ + "$SPRING_BOOT_VERSION" \ "FAILED" \ "FAILED" \ "FAILED" \ @@ -115,6 +123,10 @@ write_run_log \ "$RUN_LOG" \ "$RUN_ID" \ "$TIMESTAMP" \ + "$APPLICATION_ID" \ + "$MODULE_NAME" \ + "$JAVA_VERSION" \ + "$SPRING_BOOT_VERSION" \ "IN-PROGRESS" \ "SUCCESS" \ "SUCCESS" \ @@ -137,6 +149,10 @@ if ! bash "$SCRIPT_DIR/execute-rewrite.sh" \ "$RUN_LOG" \ "$RUN_ID" \ "$TIMESTAMP" \ + "$APPLICATION_ID" \ + "$MODULE_NAME" \ + "$JAVA_VERSION" \ + "$SPRING_BOOT_VERSION" \ "FAILED" \ "FAILED" \ "SUCCESS" \ @@ -153,6 +169,10 @@ write_run_log \ "$RUN_LOG" \ "$RUN_ID" \ "$TIMESTAMP" \ + "$APPLICATION_ID" \ + "$MODULE_NAME" \ + "$JAVA_VERSION" \ + "$SPRING_BOOT_VERSION" \ "IN-PROGRESS" \ "SUCCESS" \ "SUCCESS" \ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ff7f85b --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +.idea +*.iml \ No newline at end of file From 3566d5414a8fc060a99f9a7b8357f7153a9f7774 Mon Sep 17 00:00:00 2001 From: Paul Williams Date: Mon, 15 Jun 2026 00:57:16 +0530 Subject: [PATCH 7/7] refactor: handle awk, json and xml lint --- .../maven-upgrade-java-spring-boot.prompt.md | 2 +- .../scripts/common.sh | 26 ++++++++++++++++++- .../scripts/pre-flight.sh | 26 ++++++++++++------- 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/.github/prompts/maven-upgrade-java-spring-boot.prompt.md b/.github/prompts/maven-upgrade-java-spring-boot.prompt.md index 6a62ba9..f2eee90 100644 --- a/.github/prompts/maven-upgrade-java-spring-boot.prompt.md +++ b/.github/prompts/maven-upgrade-java-spring-boot.prompt.md @@ -4,7 +4,7 @@ description: "GitHub copilot prompt to upgrade java and spring-boot" argument-hint: "application-id (required), module-name (optional), java-version (optional), spring-boot-version (optional)" agent: agent model: GPT-5.3-Codex (copilot) -tools: ['execute', 'read', 'edit'] +tools: ['codebase', 'search', 'editFiles', 'runCommands'] authors: ["paul58914080@gmail.com"] --- diff --git a/.github/skills/maven-upgrade-java-spring-boot/scripts/common.sh b/.github/skills/maven-upgrade-java-spring-boot/scripts/common.sh index 0222cef..f8746c8 100755 --- a/.github/skills/maven-upgrade-java-spring-boot/scripts/common.sh +++ b/.github/skills/maven-upgrade-java-spring-boot/scripts/common.sh @@ -48,7 +48,11 @@ generate_run_id() { } json_escape() { - echo "${1:-}" | sed 's/\\/\\\\/g; s/"/\\"/g' + printf '%s' "${1:-}" | awk '{ + gsub(/\\/, "\\\\"); gsub(/"/, "\\\"") + gsub(/\t/, "\\t"); gsub(/\r/, "\\r") + printf "%s%s", sep, $0; sep = "\\n" + }' } run_output_dir() { @@ -124,6 +128,11 @@ extract_json_value() { return fi + if command -v jq >/dev/null 2>&1; then + jq -r --arg k "$key" '.[$k] // empty' "$file" 2>/dev/null || echo "" + return + fi + awk -v key="$key" ' $0 ~ "\\\"" key "\\\"" { match($0, /: "[^"]*"/) @@ -145,6 +154,11 @@ extract_status_value() { return fi + if command -v jq >/dev/null 2>&1; then + jq -r --arg k "$key" '.status[$k] // empty' "$file" 2>/dev/null || echo "" + return + fi + awk -v key="$key" ' /"status"[[:space:]]*:[[:space:]]*\{/ { in_status = 1; next } in_status && /\}/ { in_status = 0 } @@ -168,6 +182,11 @@ extract_log_value() { return fi + if command -v jq >/dev/null 2>&1; then + jq -r --arg k "$key" '.log[$k] // empty' "$file" 2>/dev/null || echo "" + return + fi + awk -v key="$key" ' /"log"[[:space:]]*:[[:space:]]*\{/ { in_log = 1; next } in_log && /\}/ { in_log = 0 } @@ -191,6 +210,11 @@ extract_input_value() { return fi + if command -v jq >/dev/null 2>&1; then + jq -r --arg k "$key" '.inputs[$k] // empty' "$file" 2>/dev/null || echo "" + return + fi + awk -v key="$key" ' /"inputs"[[:space:]]*:[[:space:]]*\{/ { in_input = 1; next } in_input && /\}/ { in_input = 0 } diff --git a/.github/skills/maven-upgrade-java-spring-boot/scripts/pre-flight.sh b/.github/skills/maven-upgrade-java-spring-boot/scripts/pre-flight.sh index 0f36c56..04295d1 100755 --- a/.github/skills/maven-upgrade-java-spring-boot/scripts/pre-flight.sh +++ b/.github/skills/maven-upgrade-java-spring-boot/scripts/pre-flight.sh @@ -103,18 +103,24 @@ if [[ "$MODULE_NAME" == "." ]]; then else TARGET_POM="$WORKSPACE_ROOT/$MODULE_NAME/pom.xml" - MODULE_LIST="$(awk ' - // { in_modules=1; next } - /<\/modules>/ { in_modules=0 } - in_modules { - gsub(/^[ \t]+|[ \t]+$/, "", $0) - if ($0 ~ //) { - gsub(/|<\/module>/, "", $0) + if command -v xmllint >/dev/null 2>&1; then + MODULE_LIST="$(xmllint --xpath '//modules/module/text()' "$ROOT_POM" 2>/dev/null \ + | tr ' ' '\n' | grep -v '^$' || true)" + else + # awk fallback: handles simple single-line elements only + MODULE_LIST="$(awk ' + // { in_modules=1; next } + /<\/modules>/ { in_modules=0 } + in_modules { gsub(/^[ \t]+|[ \t]+$/, "", $0) - print $0 + if ($0 ~ //) { + gsub(/|<\/module>/, "", $0) + gsub(/^[ \t]+|[ \t]+$/, "", $0) + print $0 + } } - } - ' "$ROOT_POM")" + ' "$ROOT_POM")" + fi if ! echo "$MODULE_LIST" | grep -Fxq "$MODULE_NAME"; then fail "module-name '$MODULE_NAME' is not declared in root pom.xml "