chore(QTDI-3301): Switch TCK release versions to calendar scheme - #1271
chore(QTDI-3301): Switch TCK release versions to calendar scheme#1271lxia-talend wants to merge 6 commits into
Conversation
Align the TCK release version scheme with Connectors: 1.<YYMM>.<patch>. Cut master over to 1.2610.0-SNAPSHOT and delegate the release version arithmetic in ci/Jenkinsfile-release to the VersionController shared library already loaded by the pipeline, so the December to January rollover (1.2612.0 gives 1.2701.0-SNAPSHOT) is handled by the same implementation Connectors use. Add a DRY_RUN parameter that runs release:prepare with -DdryRun=true and skips every publishing stage, so a release can be simulated end to end without tagging, pushing or deploying anything. Fix the same December to January defect in the duplicated bump logic of the legacy bash release path. Co-authored-by: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
With -DdryRun=true the release plugin never rewrites pom.xml in place, so the existing archive of **/*pom.xml captures the unchanged poms. Also archive pom.xml.tag, pom.xml.next and release.properties, which hold the versions the run would have committed, then drop them with release:clean so a later run cannot resume the simulated release. State the dry run in the manual validation prompt, and point the legacy bash comment at VersionController, the real source of truth. Co-authored-by: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
🔍 Scope & Design Review (
|
| # | Severity | File | Description | Suggested Fix |
|---|---|---|---|---|
| 1 | MAJOR | ci/Jenkinsfile-release |
post { always } of Maven release prepare archives **/*pom.xml. With -DdryRun=true the release plugin never rewrites pom.xml in place — it writes pom.xml.tag / pom.xml.next / release.properties. A DRY_RUN therefore archives the unchanged poms, so the artifact that would prove the calendar version rewrite is correct is never captured. This defeats the stated purpose of the new parameter (dev's R4 request). |
Add a DRY_RUN-only archiveArtifacts for **/pom.xml.tag, **/pom.xml.next, release.properties |
| 2 | MINOR | ci/Jenkinsfile-release |
A dry run leaves release.properties + pom.xml.* behind (release:clean is only reached via the skipped Maven release process stage). Pods are ephemeral so the practical risk is low, but in any reused workspace the next release:prepare would resume the simulated release instead of starting fresh. |
Run mvn release:clean at the end of the dry run |
| 3 | MINOR | ci/Jenkinsfile-release |
The manual input gate in Version validation says "You will do a GA release" with no mention of DRY_RUN — an approver reading only the prompt cannot tell a rehearsal from a real release. |
Mention DRY_RUN in checkMsg |
| 4 | MINOR | .jenkins/scripts/release_legacy.sh |
The new comment names ci/Jenkinsfile-release as the source of truth, but that file now delegates to VersionController — the comment points one hop short. |
Point at VersionController.getSnapshotVersion |
| 5 | INFO | ci/Jenkinsfile-release |
assemblyExtraBuildParams now forces scm.repository=$params.FAKE_REPOSITORY when dryRun. Harmless (dry run never pushes) and it is defence in depth, but it couples DRY_RUN to a param a user could blank. Pre-existing pattern for FAKE_RELEASE. |
No change — accepted |
Approval gate: REJECTED — 1 Major must be resolved before PR creation.
Challenges raised and cleared (no finding)
| Challenge | Verdict |
|---|---|
Is VersionController actually resolvable? It is used nowhere else in this repo. |
✅ Confirmed present as vars/VersionController.groovy at the pinned tqa-e2e-tests-tool@v2.4.2-ttp2 (line 19 getSnapshotVersion, line 28 getMaintenanceBranchName) — same library that already provides JenkinsStatusController |
get_release_info was static; a static method cannot resolve a shared-library global var from the script binding. |
✅ Correctly changed to an instance method in the same commit |
writeFile 'target/…' — does the parent dir exist, and does it dirty the SCM tree that release:prepare inspects? |
✅ writeFile creates parents; target is line 2 of .gitignore. Archived before preparationGoals=clean verify can wipe it |
Does build-helper:parse-version (used by documentation/pom.xml, images/pom.xml) survive a 4-digit minor? |
✅ 1.2610.0-SNAPSHOT → major 1 / minor 2610 / incremental 0 under DefaultArtifactVersion |
Are there tracked files still hardcoding 1.96.0 (antora.yml, package.json, generated adoc)? |
✅ All are Maven-filtered in place at process-sources (documentation/pom.xml filter-antora) and re-committed by release-5-prepare-next-iteration.sh; nothing to bump by hand |
Do release-5 / release-6 assume a version format? |
✅ Both are format-agnostic (versions:set with a passed-in value) |
Does Maven version ordering still increase, 1.96.0 → 1.2610.0? |
✅ Minor compared numerically: 2610 > 96 |
Legacy bash guard ${#min} -eq 4 && ${min} == *12 vs library minor.size() == 4 && endsWith("12") |
✅ Logically identical — the two copies are in sync; 1.12.0 → 1.13.0 proves 2-digit minors do not roll over |
Maintenance path: is nextVersion == maintenanceVersion correct? |
✅ Matches the pre-change behaviour (rev + 1) exactly |
maintenanceBranch now always computed (was empty string for maintenance releases) |
✅ Only consumed by Create maintenance branch, gated on isMasterBranch && ACTION == GA |
Round 1 fixes applied
- Finding 1 — DRY_RUN-only
archiveArtifactsfor**/pom.xml.tag, **/pom.xml.next, release.properties(allowEmptyArchive: true). - Finding 2 —
mvn release:cleanafter that archive, viash(returnStatus: true)so cleanup can never fail the build. - Finding 3 —
checkMsgnow rendersas a **DRY RUN** (nothing published). - Finding 4 — comment retargeted at
VersionController.getSnapshotVersion.
Re-verification after the fixes:
| Check | Result |
|---|---|
ci/Jenkinsfile-release Groovy parse (CompilationUnit → Phases.CONVERSION) |
✅ PARSE OK |
VerifyReleaseInfo.groovy against the real VersionManager |
✅ 5/5 PASS |
verify_legacy_bump.sh |
✅ 6/6 PASS |
bash -n on both changed scripts |
✅ OK |
Critic Round 2 — Findings
Re-review of the four fixes only (no other file changed since Round 1).
- Comma-separated Ant patterns in a single
archiveArtifacts— supported. shinsidescript {}inside a stage-levelpost { always {} }— valid declarative syntax; runs on the samekubernetesagent /maincontainer.- Ordering is correct: archive first, clean second, so the evidence is captured before the working files are removed.
returnStatus: trueprevents a cleanup failure from failing an otherwise successful dry run.- The nested ternary inside the triple-quoted
checkMsgGString parses correctly (confirmed by the Groovy parse check).
No Blocker or Major findings.
Approval gate: APPROVED — no Blocker or Major findings. Round 1 Minors 2–4 fixed; INFO 5 accepted as-is.
Final verdict
APPROVED after 2 rounds (limit 3). 1 Major found and fixed, 3 Minors found and fixed, 1 INFO
accepted. No unresolved findings carried into the PR.
Signed: Claude Opus 5
✅ Compliance Report (
|
| # | File(s) | Type | Verdict |
|---|---|---|---|
| 1 | pom.xml + 85 module pom.xml |
build | ✅ PASS |
| 2 | ci/Jenkinsfile-release |
CI (Groovy) | ✅ PASS (2 Warnings) |
| 3 | .jenkins/scripts/release/release-2-prepare.sh |
CI (Bash) | ✅ PASS |
| 4 | .jenkins/scripts/release_legacy.sh |
CI (Bash) | ✅ PASS (1 Info) |
1 — the 86 poms
- Diff is exclusively version lines: filtering the diff for anything other than
1.96.0-SNAPSHOT/1.2610.0-SNAPSHOTreturns zero lines. No stray reformatting, no
dependency edits, no license-header churn. git grep "1\.96\.0-SNAPSHOT" -- '*.xml'→ 0 hits: no module left on the old version, no
orphaned<parent><version>.- Generated by
mvn versions:set, so parent/child coherence is tool-guaranteed and was
independently confirmed bymvn validateacross all 89 modules.
2 — ci/Jenkinsfile-release
- Apache license header intact.
- New
booleanParam(DRY_RUN)sits in the existingseparator-delimited debug section, matching the
surrounding style;defaultValue: falseis the safe default. when { expression { !params.DRY_RUN } }added to every publishing stage — Maven release
process, Release studio modules, Release Docker image, Prepare next iteration, Create
maintenance branch. Enumerated against the full stage list; no publishing stage was missed.get_release_infoJavadoc updated in step with the signature change (static→ instance) and the
return-value semantics.- Shared library is version-pinned (
lib("tqa-e2e-tests-tool@v2.4.2-ttp2")), so the new
VersionControllercalls cannot drift under the job.
3 — .jenkins/scripts/release/release-2-prepare.sh
- Apache license header and
set -xeunchanged. DRY_RUNdocumented in the existing parameter comment block, in the file's own style."${DRY_RUN:-false}"defaults safely, anddryRunParams=()expanded as"${dryRunParams[@]}"
keeps the no-op case a genuine no-op — consistent with howextraBuildParamsis already handled.bash -nclean.
4 — .jenkins/scripts/release_legacy.sh
- Guard
[[ ${#min} -eq 4 && ${min} == *12 ]]is quoted/bracketed correctly;bash -nclean. - Behaviour matches the shared library exactly (6/6 harness cases, including the
1.12.0 → 1.13.0
non-rollover case that proves 2-digit minors are untouched).
Findings
| # | Severity | File | Description | Status |
|---|---|---|---|---|
| 1 | Warning | ci/Jenkinsfile-release |
release:prepare -DdryRun=true leaves the computed versions in pom.xml.tag / pom.xml.next, which the existing **/*pom.xml archive pattern does not match — a dry run would have published no usable evidence. |
FIXED in c19660bec54 — DRY_RUN-only archiveArtifacts for **/pom.xml.tag, **/pom.xml.next, release.properties |
| 2 | Warning | ci/Jenkinsfile-release |
Dry-run leftovers (release.properties, pom.xml.*) were never cleaned, so a reused workspace could resume the simulated release. |
FIXED in c19660bec54 — mvn release:clean via sh(returnStatus: true) |
| 3 | Info | ci/Jenkinsfile-release |
The manual input prompt did not distinguish a rehearsal from a real release. |
FIXED in c19660bec54 |
| 4 | Info | .jenkins/scripts/release_legacy.sh |
"Source of truth" comment pointed at the Jenkinsfile, which now itself delegates. | FIXED in c19660bec54 |
| 5 | Info | repo-wide | component-runtime-beam does not compile on unmodified master (package org.apache.commons.compress.utils does not exist). Pre-existing and unrelated; left alone per core-rules.md §4 scope discipline. |
Not fixed — needs its own ticket |
| 6 | Info | documentation/src/main/frontend/package.json |
Declares 1.91.0-SNAPSHOT while package-lock.json declares 1.96.0-SNAPSHOT. Pre-existing drift; package.json is Maven-filtered at build time so the committed value is inert. Out of scope. |
Not fixed — pre-existing |
Severity counts: Critical fixed: 0 · Warnings: 2 (both fixed) · Info: 4 (2 fixed, 2 pre-existing
and out of scope).
Convention compliance
Rule (git-branch-and-commit.md) |
Value | Verdict |
|---|---|---|
Branch username/JIRA-ID_short_description |
lxia-talend/QTDI-3301_switch_tck_to_calendar_versioning |
✅ real GitHub login, mandatory QTDI-3301, lowercase + underscores, no @ |
Commit <type>(<scope>): <subject> |
chore(QTDI-3301): Switch TCK release versions to calendar scheme (63 ch) · chore(QTDI-3301): Archive and clean the dry run release files (61 ch) |
✅ chore correct for build/CI with no functional product change; capitalized, imperative, no trailing period |
| Body wrapped at 72, explains what/why | both commits | ✅ |
Co-authored-by: per AI tool |
both commits | ✅ |
Rule (core-rules.md) |
Verdict |
|---|---|
| §2 Jira — comment only, no field edits or transitions | ✅ comments 1205688, 1205690, 1205713, 1205807 only |
| §3 GitHub — nothing pushed before agent 05 | ✅ both commits local only |
| §4 Scope discipline — no unrelated fixes | ✅ pre-existing beam breakage deliberately left alone (Info 5) |
Spotless: not applicable — spotless-maven-plugin is declared only in root <pluginManagement> with
no format configuration or execution binding, and the diff contains no Java source.
Verdict
PASS — no Critical findings. Both Warnings were fixed and re-verified (Groovy parse OK, 5/5
version-derivation cases, 6/6 legacy-bump cases, bash -n clean). Info 5 and 6 are pre-existing and
carried into the PR description as known, out-of-scope observations.
Signed: Claude Opus 5
|

0 New Issues
0 Fixed Issues
0 Accepted Issues
No data about coverage (63.30% Estimated after merge)
Requirements
Why this PR is needed?
Jira: QTDI-3301
TCK releases use a plain incremental scheme (
1.96.0) while Connectors already use calendarversioning (
1.<YYMM>.<patch>, e.g.connectors/1.2609.0). Stakeholders cannot tell from a TCKversion which release train it belongs to.
This PR switches TCK to the same
MAJOR.YEARMONTH.PATCHscheme, starting with1.2610.0for theSeptember release (TCK releases M-1, so September produces the
2610line targeting the StudioOctober release).
What does this PR adds (design/code thoughts)?
masterover from1.96.0-SNAPSHOTto1.2610.0-SNAPSHOT(mvn versions:set, 86 poms)pom.xml+ 85 module pomsVersionControllershared library already loaded by the pipeline — the same implementation Connectors use — instead of local string mathci/Jenkinsfile-release1.2612.0→1.2701.0-SNAPSHOT(not1.2613.0)ci/Jenkinsfile-release,.jenkins/scripts/release_legacy.shDRY_RUNparameter: runsrelease:prepare -DdryRun=trueand skips every publishing stage, so a full release can be rehearsed without tagging, pushing or deployingci/Jenkinsfile-release,.jenkins/scripts/release/release-2-prepare.shpom.xml.tag,pom.xml.next,release.properties) andrelease:cleanafterwards, so a rehearsal proves the computed versions and cannot leave a resumable state behindci/Jenkinsfile-releaseDesign notes
get_release_info()changed fromstaticto an instance method — a static method cannot resolve ashared-library global var from the script binding.
tqa-e2e-tests-tool@v2.4.2-ttp2), so the newVersionControllercalls cannot drift under the job..jenkins/scripts/release_legacy.shkeeps its own copy of the bump logic (it does not run underJenkins shared libraries); the December → January defect is fixed there too and the two copies were
verified to be behaviourally identical. A comment points at
VersionController.getSnapshotVersionas the source of truth.maintenance/1.9xbranches keep working — the legacy1.9xscheme is still derived correctly.
How this was verified
mvn -B validate -DskipTestsover the full 89-module reactor — model building, parent resolution, inter-module dependency coherencegrepfor any remaining1.96.0-SNAPSHOTin pomsVersionManager.groovyfrom the pinned shared library — GA, maintenance, Dec→Jan rollover, legacy1.9x1.12.0 → 1.13.0non-rollover guard for 2-digit minorsci/Jenkinsfile-releaseGroovyCompilationUnitparsebash -non both changed scriptstdi-jenkins-job/ TTP version-format audit — no hardcoded version-format assumption foundV3 output (row 2 is the December → January rollover; rows 4–5 prove legacy compatibility):
Suggested reviewer validation: trigger
Jenkinsfile-releaseon this branch withDRY_RUN=trueand check the archived
pom.xml.tag/pom.xml.next/release.properties.Known, out-of-scope observations
Reported here rather than fixed, per scope discipline — each needs its own ticket:
component-runtime-beamdoes not compile on unmodifiedmaster(
package org.apache.commons.compress.utils does not exist). Reproduced with this branch's pomsstashed, so it is pre-existing and unrelated to the version cutover. This is why the reactor-wide
check above is
mvn validaterather thanmvn install.documentation/src/main/frontend/package.jsondeclares1.91.0-SNAPSHOTwhile itspackage-lock.jsondeclares1.96.0-SNAPSHOT. Pre-existing drift;package.jsonisMaven-filtered at build time so the committed value is inert.
Follow-up not covered here
The ticket's nice-to-have — naming TCK Jira release versions
tck/1.2610.0instead of the bareversion — is a Jira administration action, not a code change, and is out of this PR's scope.
AI contribution metrics
100%100%100%AI generated code
https://internal.qlik.dev/general/ways-of-working/code-reviews/#guidelines-for-ai-generated-code