Skip to content

chore: bundle LICENSE and NOTICE in core/cli/starter-app build artifacts - #2597

Merged
bpamiri merged 2 commits into
developfrom
fix/bot-2596-chore-bundle-license-notice-in-core-cli-starter-ap
May 12, 2026
Merged

bpamiri merged 2 commits into
developfrom
fix/bot-2596-chore-bundle-license-notice-in-core-cli-starter-ap

Conversation

@wheels-bot

@wheels-bot wheels-bot Bot commented May 12, 2026

Copy link
Copy Markdown
Contributor

Summary

Apache 2.0 §4(a) requires every distributed artifact to ship LICENSE, and §4(d) requires NOTICE to propagate to derivatives. #2593 covered that bundling for the base-template artifact via tools/build/scripts/prepare-base.sh. The three sibling prepare scripts — prepare-core.sh, prepare-cli.sh, prepare-starterApp.sh — were left bundling neither file, so the wheels-core, wheels-cli, and wheels-starter-app artifacts shipped without the license text or attribution notices.

This PR mirrors the cp LICENSE / cp NOTICE pattern from prepare-base.sh into the other three scripts so every release artifact is Apache 2.0 §4(a)/§4(d) compliant. A new source-level regression guard, vendor/wheels/tests/specs/buildArtifactLicenseSpec.cfc, pins the contract for all four scripts so the bundling can't drift back.

Related Issue

Closes #2596

Type of Change

  • Bug fix
  • New feature
  • Enhancement to existing feature
  • Documentation update
  • Refactoring

Feature Completeness Checklist

  • DCO sign-off — Commit carries Signed-off-by: wheels-bot[bot].
  • Tests — vendor/wheels/tests/specs/buildArtifactLicenseSpec.cfc asserts each of the four prepare-*.sh scripts contains both cp LICENSE "${BUILD_DIR}…" and cp NOTICE "${BUILD_DIR}…". Failing-then-passing locally: 6 fail → 0 fail after the implementation lands; 8/8 pass.
  • Framework Docs — Build/release tooling change; no MDX guide impacted. The bot-update-docs.yml workflow will add follow-up doc commits if it identifies anything worth surfacing.
  • AI Reference Docs — No .ai/wheels/ change required (no framework-layer surface area).
  • CLAUDE.md — No convention change.
  • CHANGELOG.md — Entry added under [Unreleased] → ### Fixed.
  • Test runner passes — Local Lucee 7 / SQLite run: 3447 pass / 0 fail / 0 error across 198 bundles (16 skipped).

Test Plan

  • vendor/wheels/tests/specs/buildArtifactLicenseSpec.cfc exercises every release-artifact prepare script: prepare-base.sh, prepare-core.sh, prepare-cli.sh, prepare-starterApp.sh. Asserted on the source so it runs without spawning a real build context.
  • CI: confirm the next compat-matrix run stays green and that the Build & Publish Release job, when it next runs, drops LICENSE + NOTICE next to the existing files inside each of build-wheels-core/wheels/, build-wheels-cli/wheels-cli/, and build-wheels-starterApp/.

Screenshots / Output

$ jq '.bundleStats[] | select(.name=="wheels.tests.specs.buildArtifactLicenseSpec") | {totalPass, totalFail, totalError, totalSpecs}'
{
  "totalPass": 8,
  "totalFail": 0,
  "totalError": 0,
  "totalSpecs": 8
}

Apache 2.0 §4(a) requires LICENSE in every distributed artifact and §4(d)
requires NOTICE to propagate to derivatives. PR #2593 covered the
base-template artifact via prepare-base.sh but left the three sibling
prepare scripts (core, cli, starter-app) bundling neither file. Mirror
the pattern across all four release-artifact prepare scripts and pin
the contract with a source-level regression guard.

Fixes #2596

Signed-off-by: wheels-bot[bot] <wheels-bot[bot]@users.noreply.github.com>

@wheels-bot wheels-bot Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wheels Bot — Reviewer A

TL;DR: This PR correctly addresses the Apache 2.0 §4(a)/§4(d) compliance gap by mirroring the cp LICENSE / cp NOTICE pattern from prepare-base.sh into the three sibling prepare scripts. The shell-script additions and CHANGELOG entry are clean. However, the regression-guard spec (buildArtifactLicenseSpec.cfc) uses POSIX bracket-expression syntax ([[:space:]]) that is not supported by Java's java.util.regex engine — used by Lucee, Adobe CF, and BoxLang alike. On Adobe CF 2023/2025 and BoxLang the regex compiles but silently fails to match actual whitespace, causing all 8 spec assertions to fail even when the scripts are correct. This is a cross-engine correctness defect that should be fixed before merge. (Verdict would be request changes but GitHub prevents a bot from requesting changes on its own PR; flagging here instead.)


Cross-engine

vendor/wheels/tests/specs/buildArtifactLicenseSpec.cfc, lines 39 and 50 — POSIX character class not supported in Java regex

// line 39
"cp[[:space:]]+LICENSE[[:space:]]+""\$\{BUILD_DIR\}",

// line 50
"cp[[:space:]]+NOTICE[[:space:]]+""\$\{BUILD_DIR\}",

[[:space:]] is POSIX ERE bracket-expression syntax. Java's java.util.regex (the engine under Lucee, Adobe CF 2023/2025, and BoxLang) does not support POSIX named character classes. It treats [[:space:]] as a character class matching the literal characters :, s, p, a, c, e — not whitespace. Because none of those characters appear between cp and LICENSE in any of the prepare scripts, reFindNoCase returns 0 for every call, hasLicense / hasNotice are always false, and all 8 expect(…).toBeTrue() assertions fail on Adobe CF and BoxLang engines. On Lucee 7 the tests may pass if its runtime happens to accept POSIX syntax, but that is engine-specific behaviour the CI matrix cannot rely on across all engines.

The established pattern in this repo for whitespace in regex is \s — confirmed by vendor/wheels/tests/specs/security/McpCommandInjectionSpec.cfc line 93:

expect(reFind("^wheels\s", "wheels test run") > 0).toBeTrue();

Option A — minimal fix, stay with regex:

var hasLicense = reFindNoCase(
    "cp\s+LICENSE\s+""\$\{BUILD_DIR\}",
    src
) > 0;

Option B — preferred, follow sibling spec pattern (no regex needed):

buildInfoSpec.cfc and routesViewBrowserFixturesSpec.cfc — the two specs cited in the comment as the model for this one — use findNoCase/toInclude, not regex. That simpler approach works on every engine with zero ambiguity:

it("copies LICENSE into its BUILD_DIR", () => {
    var src = fileRead(repoRoot & "/" & relPath);
    expect(findNoCase('cp LICENSE "${BUILD_DIR}', src)).toBeGT(
        0,
        relPath & " must bundle LICENSE into its build artifact for Apache 2.0 §4(a) compliance."
    );
});

it("copies NOTICE into its BUILD_DIR", () => {
    var src = fileRead(repoRoot & "/" & relPath);
    expect(findNoCase('cp NOTICE "${BUILD_DIR}', src)).toBeGT(
        0,
        relPath & " must bundle NOTICE into its build artifact for Apache 2.0 §4(d) propagation."
    );
});

Correctness

The shell-script additions are correct and match the compliance intent. The comment added above each cp block clearly states the legal rationale (§4(a)/§4(d)), and the placement relative to the rsync/cp -r block is consistent across all four scripts. No issues here.

The CHANGELOG entry under [Unreleased] → Fixed is accurate and well-worded.


Commits

chore: bundle LICENSE and NOTICE in core/cli/starter-app build artifacts

Type chore, subject within 100 chars, DCO sign-off present — passes commitlint. The body explains the compliance context. No issues.


Tests

Once the POSIX character class is replaced with \s or findNoCase, the spec structure is sound: the IIFE (function(relPath) { ... })(rel) correctly captures the loop variable to prevent all four describe blocks from aliasing to the last script path. Eight assertions across four scripts for LICENSE + NOTICE each — good coverage for the regression contract.

One note for the follow-up: no CI check here confirms that the actual build artifacts produced by prepare-*.sh contain the files at runtime (the test plan's unchecked CI item). That gap is acceptable for now since a shell-level test would require a build context, but it should stay on the radar.

@wheels-bot

wheels-bot Bot commented May 12, 2026

Copy link
Copy Markdown
Contributor Author

Wheels Bot — Reviewer B (round 1)

A's review is technically sound. The POSIX character class finding is correct, well-evidenced, and the two recommended fixes are both actionable. No sycophancy, no false positives, no missed issues. Aligning with A: changes needed before merge.

Sycophancy

None detected. A explicitly withholds approval and flags a defect requiring a fix.

False positives

None detected.

A's core claim — that [[:space:]] is POSIX ERE syntax unsupported by java.util.regex — is correct. Java's regex engine parses [[:space:]] as a nested character class matching the literal characters :, s, p, a, c, e, not whitespace. reFindNoCase("cp[[:space:]]+LICENSE...", src) returns 0 against cp LICENSE "${BUILD_DIR}/" on any engine that routes through java.util.regex (Lucee, Adobe CF 2023/2025, BoxLang). The PR author's 8/8 pass result on Lucee 7 is consistent with A's hedged phrasing ("may pass if its runtime happens to accept POSIX syntax") — Lucee 7 appears to preprocess POSIX character classes before handing off to the Java engine, which is precisely the engine-specific behaviour that makes this a cross-engine defect.

A's citation of vendor/wheels/tests/specs/security/McpCommandInjectionSpec.cfc lines 93/97 is accurate — reFind("^wheels\s", ...) is the established repo pattern for whitespace in regex.

Missed issues

None detected.

The ##2593 in the spec's comment block is double-escaped out of caution but is benign (CFML does not evaluate expressions inside // comments). The expandPath("/wheels/../..") repo-root derivation is consistent with other specs in the suite. The IIFE variable-capture pattern is correctly identified as sound. The fileRead + structural assertion approach is appropriate given the spec runs without a live build context.

Verdict alignment

A's COMMENTED state (unavoidable due to GitHub's restriction on bots reviewing their own PRs) is consistent with the substance: a concrete defect, two actionable fix options, and a clear recommendation not to merge until fixed.

Convergence

Aligned with A. The single defect is well-defined: replace [[:space:]] with \s (Option A) or switch to findNoCase (Option B, preferred per A). Either fix resolves the cross-engine failure. No other issues in the diff.

@bpamiri
bpamiri marked this pull request as ready for review May 12, 2026 02:28
@bpamiri
bpamiri merged commit 42eeca8 into develop May 12, 2026
7 checks passed
@bpamiri
bpamiri deleted the fix/bot-2596-chore-bundle-license-notice-in-core-cli-starter-ap branch May 12, 2026 02:28
@wheels-bot

wheels-bot Bot commented May 12, 2026

Copy link
Copy Markdown
Contributor Author

Wheels Bot — Address Review (no-op: PR already merged)

The convergence loop arrived too late for this PR. Reviewer B's converged-changes comment was posted at 2026-05-12T02:28:07Z and the PR was merged at 2026-05-12T02:28:54Z — 47 seconds later, by a human reviewer. The address-review stage cannot push useful commits to a merged PR's branch: the defect that A and B converged on is already in develop via merge commit 42eeca8a428fd34c8637f79ea745bd7e0a996b94.

Outstanding consensus finding (now in develop)

  • vendor/wheels/tests/specs/buildArtifactLicenseSpec.cfc uses POSIX [[:space:]] inside reFindNoCase, which java.util.regex parses as a literal character class matching :, s, p, a, c, e. This is the cross-engine defect both reviewers agreed on. The recommended fix (B's preferred option, per A) is to replace the regex with findNoCase("cp LICENSE \"${BUILD_DIR}", src) and findNoCase("cp NOTICE \"${BUILD_DIR}", src) — no regex needed since the literal string is sufficient. Alternative: replace [[:space:]]+ with \s+ if the regex form is preferred.

Handing this back to humans — a follow-up PR against develop is the right vehicle, not commits to this merged branch.

bpamiri added a commit that referenced this pull request May 12, 2026
Pick up #2597 (LICENSE/NOTICE bundling for core/cli/starter-app artifacts)
which landed on develop while #2600 was in review. Trivial conflict in
CHANGELOG.md — both branches added an entry to the top of
[Unreleased] > Fixed; both entries kept, ours stays first.

Signed-off-by: Peter Amiri <peter@alurium.com>

# Conflicts:
#	CHANGELOG.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

chore: bundle LICENSE + NOTICE in core / cli / starter-app build artifacts

1 participant