From 894a550312a45bee6a4fe689138d01ca6267a311 Mon Sep 17 00:00:00 2001 From: James Maes Date: Sat, 11 Jul 2026 13:42:35 -0500 Subject: [PATCH] fix: preserve node-webapp Dockerfiles Add an opt-in repository Dockerfile path while retaining generated images by default. Closes #7 --- README.md | 5 ++- docs/PLAN-node-webapp-dockerfile.md | 13 ++++++++ docs/TODO.md | 1 + src/scripts/generate_dockerfile.sh | 14 ++++++-- src/scripts/packed_generate_dockerfile.sh | 14 ++++++-- tests/test_generate_dockerfile.sh | 40 +++++++++++++++++++++++ 6 files changed, 80 insertions(+), 7 deletions(-) create mode 100644 docs/PLAN-node-webapp-dockerfile.md diff --git a/README.md b/README.md index f25055f..b3e7652 100644 --- a/README.md +++ b/README.md @@ -149,6 +149,7 @@ orb_version: dev:snapshot image_name: my-webapp docker: registry: ghcr.io/KofTwentyTwo + use_repo_dockerfile: true contexts: registry: ghcr github: github @@ -167,6 +168,7 @@ sonar: docker: registry: ghcr.io/KofTwentyTwo + use_repo_dockerfile: true # preserve the repository Dockerfile cd: repo: KofTwentyTwo/my-webapp-cd # omit to skip GitOps CD updates @@ -212,7 +214,7 @@ contexts: sonar: sonarcloud ``` -**Dockerfile:** You must provide your own `Dockerfile` in the repo root. Munitor builds it, runs a health check, scans with Trivy, and pushes to the registry. This is the key difference from `node-api`, which auto-generates a Dockerfile. +**Dockerfile:** Set `docker.use_repo_dockerfile: true` and provide `Dockerfile` in the repo root when the application owns its runtime contract. Munitor preserves and builds it, runs a health check, scans with Trivy, and pushes to the registry. Without the option, Munitor retains the legacy generated Dockerfile behavior. Use `node-api` when an always-generated framework Dockerfile is preferred. ### `java-webapp` @@ -465,6 +467,7 @@ Tags follow the format `vX.Y.Z` (git tag) and `X.Y.Z` (Docker tag). Tags are imm | `java_version` | string | `21` | java-webapp | Java major version | | `sonar.project_key` | string | -- | node-api, node-webapp, java-webapp | SonarCloud project key. Omit to skip | | `docker.registry` | string | *required** | node-api, node-webapp, java-webapp | Container registry URL | +| `docker.use_repo_dockerfile` | bool | `false` | node-webapp | Preserve and build the repository-root Dockerfile instead of generating one | | `cd.repo` | string | -- | node-api, node-webapp, java-webapp | GitOps CD repo (`org/repo`). Omit to skip | | `cd.env.release` | string | `staging` | node-api, node-webapp, java-webapp | CD target environment for release branches | | `coverage.min_instruction` | int | `70` | node-api, node-webapp, java-webapp | Minimum coverage percentage | diff --git a/docs/PLAN-node-webapp-dockerfile.md b/docs/PLAN-node-webapp-dockerfile.md new file mode 100644 index 0000000..5490375 --- /dev/null +++ b/docs/PLAN-node-webapp-dockerfile.md @@ -0,0 +1,13 @@ +# PLAN: Preserve node-webapp Dockerfiles + +## Goal + +Allow `node-webapp` consumers to preserve a repository-owned Dockerfile without breaking existing generated-image consumers. + +## Steps + +1. [x] Add an opt-in `docker.use_repo_dockerfile` manifest field. +2. [x] Fail clearly when an opted-in repository has no root Dockerfile. +3. [x] Add regression coverage and update the public reference. +4. [ ] Pack, validate, test, and publish the development orb. +5. [ ] Verify the Investing in Chester production image pipeline with the new orb. diff --git a/docs/TODO.md b/docs/TODO.md index a687d8e..73841e0 100644 --- a/docs/TODO.md +++ b/docs/TODO.md @@ -13,6 +13,7 @@ ## Completed +- [x] Add opt-in repository Dockerfile preservation for node-webapp (GH-7) - [x] Implement first-class pnpm support (GH-5, 17 commits, 219 tests) - [x] Rename all npm_* orb components to node_* (backward-incompatible, pre-1.0) - [x] Thread package_manager through full job/command/script chain diff --git a/src/scripts/generate_dockerfile.sh b/src/scripts/generate_dockerfile.sh index f3a5df6..67571c0 100755 --- a/src/scripts/generate_dockerfile.sh +++ b/src/scripts/generate_dockerfile.sh @@ -261,8 +261,15 @@ DOCKERFILE ;; node-webapp) - echo "Generating Dockerfile for node-webapp (node ${MUNITOR_NODE_VERSION})" - case "${MUNITOR_PACKAGE_MANAGER}" in + if yq -e '.docker.use_repo_dockerfile == true' "${CONFIG_FILE}" &>/dev/null; then + echo "Using repository Dockerfile for node-webapp" + if [[ ! -f Dockerfile ]]; then + echo "ERROR: docker.use_repo_dockerfile requires a Dockerfile in the repository root." >&2 + exit 1 + fi + else + echo "Generating Dockerfile for node-webapp (node ${MUNITOR_NODE_VERSION})" + case "${MUNITOR_PACKAGE_MANAGER}" in pnpm) cat > Dockerfile </dev/null; then + echo "Using repository Dockerfile for node-webapp" + if [[ ! -f Dockerfile ]]; then + echo "ERROR: docker.use_repo_dockerfile requires a Dockerfile in the repository root." >&2 + exit 1 + fi + else + echo "Generating Dockerfile for node-webapp (node ${MUNITOR_NODE_VERSION})" + case "${MUNITOR_PACKAGE_MANAGER}" in pnpm) cat > Dockerfile < "${WORK_DIR}/.munitor.yml" <<'EOF' +pipeline: node-webapp +image_name: my-webapp +docker: + use_repo_dockerfile: true +EOF +echo "CUSTOM RUNTIME" > "${WORK_DIR}/Dockerfile" +OUTPUT=$(run_generate) +if grep -q "CUSTOM RUNTIME" "${WORK_DIR}/Dockerfile" && echo "${OUTPUT}" | grep -q "Using repository Dockerfile"; then + pass +else + fail "repository Dockerfile was not preserved" +fi +teardown + +echo -n " TEST: rejects opt-in when Dockerfile is missing... " +setup +cat > "${WORK_DIR}/.munitor.yml" <<'EOF' +pipeline: node-webapp +image_name: my-webapp +docker: + use_repo_dockerfile: true +EOF +if OUTPUT=$(run_generate); then + fail "expected missing Dockerfile to fail" +elif echo "${OUTPUT}" | grep -q "requires a Dockerfile"; then + pass +else + fail "expected a clear missing Dockerfile error" +fi +teardown + # ============================================================================= # Test: node-webapp with pnpm generates correct Dockerfile # ============================================================================= -- 2.54.0