Skip to content

[Automated] Sync master after 2201.13.6 release - #6411

Open
ballerina-cicd-bot wants to merge 177 commits into
masterfrom
release-2201.13.6-Alpha
Open

[Automated] Sync master after 2201.13.6 release#6411
ballerina-cicd-bot wants to merge 177 commits into
masterfrom
release-2201.13.6-Alpha

Conversation

@ballerina-cicd-bot

@ballerina-cicd-bot ballerina-cicd-bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor
  • Synced dependency, standard-library, tooling, and license metadata with the latest release.
  • Updated build and release workflows for offline example builds, dependency handling, and publishing.
  • Expanded logging examples with configurable levels, file output, and log rotation.
  • Updated XML examples to use ballerina/data.xmldata and current conversion APIs.
  • Enhanced the example catalog with Central dependency metadata and added a log-rotation example.
  • Added a library package integration test and updated test configuration.
  • Updated MCP service handling to accept an optional session parameter.
  • Refreshed example documentation and release-version references.

keizer619 and others added 30 commits November 7, 2025 11:46
[Automated] Sync master after 2201.13.0 release
[Automated] Sync master after 2201.13.1 release
Include sticky and offline flags for bbe tests
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Thevakumar-Luheerathan and others added 21 commits July 26, 2026 14:20
Bump the lang version for 2201.13.5 release
Bump the http, tcp version for 2201.13.5 release
[2201.13.x] Update the ftp version to 2.20.1
Update stdlibEdiVersion and stdlibFtpVersion
[Automated] Sync master after 2201.13.5 release
…ities-2201.13.x

Add trivy ignore entries for jackson and netty CVEs
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The release updates synchronize workflow commands, dependency metadata, example build behavior, logging rotation samples, XML conversion examples, MCP APIs, documentation, and integration-test registration.

Changes

Release baseline

Layer / File(s) Summary
Release metadata and build dependencies
.github/workflows/publish-release.yml, .trivyignore, ballerina/LICENSE, gradle.properties, build.gradle
Release versions, workflow values, vulnerability entries, dependency versions, license inventories, and Gradle dependencies are updated.

Example build and registration

Layer / File(s) Summary
Example build and test registration
examples/index.json, ballerina/build.gradle, stdlib-integration-tests/*
Example metadata controls Central access and playground behavior. Offline example builds and a new library package integration test are registered.

Logging examples

Layer / File(s) Summary
Logging configuration examples
examples/custom-logger/*, examples/http-access-logs/*, examples/http-trace-logs/*, examples/log-file-rotation/*, examples/logger-from-config/*, examples/logging-configuration/*
Logging examples add configurable levels, file destinations, and size- or time-based rotation with matching documentation.

Example API and data conversions

Layer / File(s) Summary
Example API and data conversions
examples/mcp-service-advanced/*, examples/xml-*-conversion/*, examples/azure-functions-cosmosdb-trigger/*, examples/natural-expressions/*, examples/string-templates/*
Examples update the MCP callback signature, XML module usage and conversion paths, setup instructions, version requirements, and source references.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

Suggested reviewers: keizer619, nipunaranasinghe, gimantha

Poem

I hop through builds where new versions gleam,
Past rotating logs in a tidy stream.
XML finds records, examples align,
Offline tests pass in a neat little line.
The release carrot is ready to shine.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning No pull request description was provided, so all required template sections and testing details are missing. Add a description that covers the required purpose, goals, approach, tests, security checks, samples, documentation, and release impact.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies an automated master-branch sync after the 2201.13.6 release.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
⚔️ Resolve merge conflicts 💡
  • Resolve merge conflict in branch release-2201.13.6-Alpha
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch release-2201.13.6-Alpha

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@sonarqubecloud

sonarqubecloud Bot commented Aug 6, 2026

Copy link
Copy Markdown

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
13 out of 14 committers have signed the CLA.

✅ niveathika
✅ VellummyilumVinoth
✅ ThisaruGuruge
✅ keizer619
✅ NipunaRanasinghe
✅ TharmiganK
✅ ballerina-cicd-bot
✅ MohamedSabthar
✅ NipunaMadhushan
✅ Nuvindu
✅ Thevakumar-Luheerathan
✅ RadCod3
✅ chiranSachintha
❌ Copilot
You have signed the CLA already but the status is still pending? Let us recheck it.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 8

🧹 Nitpick comments (1)
examples/logger-from-config/logger_from_config.bal (1)

7-14: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Initialize each configured logger once.

Line 34 and Line 44 call log:fromConfig for every processed event. The new file-backed configurations therefore create another registered logger for each call. The log API registers every fromConfig logger and auto-generates an ID when id is omitted. Reuse one logger per configuration after initialization. This prevents registry growth with event volume. (ballerina.io)

Also applies to: 21-28

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/logger-from-config/logger_from_config.bal` around lines 7 - 14,
Initialize each configured logger once instead of calling log:fromConfig for
every event. Update the event-processing flow around the two log:fromConfig call
sites to create and retain one logger per configuration, then reuse that logger
for subsequent writes while preserving the existing configured destinations and
rotation settings.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/publish-release.yml:
- Around line 118-121: Update the setup-node step at
.github/workflows/publish-release.yml:118-121 from actions/setup-node@v2 to a
supported major version, and update the setup-dotnet step at
.github/workflows/publish-release.yml:702-706 from actions/setup-dotnet@v1 to a
supported major version before the release workflow runs.

In @.trivyignore:
- Around line 8-22: Remove the listed Jackson and Netty vulnerability IDs from
the `.trivyignore` suppression entries so Trivy blocks releases until the
dependencies are upgraded. Do not replace them with broad or permanent
exceptions; any temporary workaround must be package-scoped and expiring.

In `@ballerina/build.gradle`:
- Around line 964-966: Update outputVerification to derive additionalBuildParams
from bbe.needCentral and pass the resulting offline options to its bal run
invocation, matching the existing buildBBE behavior. Ensure needCentral: false
uses the same --sticky --offline parameters during output verification.
- Around line 964-966: Update the platform-specific execution flow around
ExecSpec.commandLine so `bal build` and `bal test` run in separate exec calls
rather than overwriting one another. Capture each command’s exit status,
propagate failure when either command fails, and ensure `exitVal` reflects build
or test failure.

In `@ballerina/LICENSE`:
- Around line 167-171: Regenerate the ballerina license inventory from the
dependencies resolved by gradle.properties and build.gradle, replacing stale
FTP, Log, Crypto, and HTTP versions. Ensure the same generation updates the
related compiler and native artifact rows, rather than editing only the
displayed entries manually.

In `@examples/custom-logger/custom_logger.bal`:
- Around line 63-69: Update withContext(...) and the child logger implementation
so child contexts retain a reference to the parent logger instead of copying
parentLevel. Make child getLevel(...) delegate to that parent, and make child
setLevel(...) return the unsupported-operation error, preserving the inherited
parent-level contract.
- Around line 20-29: Update the custom logger’s level handling in setLevel and
the print* methods so emissions below the configured log:Level are suppressed
before calling the standard log API. Ensure setLevel(log:ERROR) prevents
printInfo, printWarn, and printDebug from forwarding while preserving
higher-severity logging.

In `@examples/logger-from-config/logger_from_config.bal`:
- Around line 21-28: Align the metrics destination’s retention metadata with its
rotation settings: update maxBackupFiles in the destinations configuration to 30
for 30-day daily retention, or change the associated retention context value to
match seven backups. Preserve the existing rotation policy and ensure the
resulting configuration accurately describes retention when log writes trigger
rotation.

---

Nitpick comments:
In `@examples/logger-from-config/logger_from_config.bal`:
- Around line 7-14: Initialize each configured logger once instead of calling
log:fromConfig for every event. Update the event-processing flow around the two
log:fromConfig call sites to create and retain one logger per configuration,
then reuse that logger for subsequent writes while preserving the existing
configured destinations and rotation settings.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: ad21b4e1-8011-4d11-a115-82188c5a959c

📥 Commits

Reviewing files that changed from the base of the PR and between 2b0432a and 70df299.

⛔ Files ignored due to path filters (8)
  • examples/log-file-rotation/app_log_rotation.out is excluded by !**/*.out
  • examples/log-file-rotation/log_file_rotation.out is excluded by !**/*.out
  • examples/logger-from-config/audit_logs.out is excluded by !**/*.out
  • examples/logger-from-config/logger_from_config.out is excluded by !**/*.out
  • examples/logger-from-config/metrics_logs.out is excluded by !**/*.out
  • examples/xml-from-json-conversion/xml_from_json_conversion.out is excluded by !**/*.out
  • examples/xml-to-json-conversion/xml_to_json_conversion.out is excluded by !**/*.out
  • examples/xml-to-record-conversion/xml_to_record_conversion.out is excluded by !**/*.out
📒 Files selected for processing (36)
  • .github/workflows/publish-release.yml
  • .trivyignore
  • ballerina-test-automation/gradle.properties
  • ballerina/LICENSE
  • ballerina/build.gradle
  • build.gradle
  • examples/azure-functions-cosmosdb-trigger/azure_functions_cosmosdb_trigger.md
  • examples/custom-logger/custom_logger.bal
  • examples/http-access-logs/Config.toml
  • examples/http-access-logs/http_access_logs.md
  • examples/http-trace-logs/Config.toml
  • examples/http-trace-logs/http_trace_logs.md
  • examples/index.json
  • examples/log-file-rotation/Config.toml
  • examples/log-file-rotation/log_file_rotation.bal
  • examples/log-file-rotation/log_file_rotation.md
  • examples/log-file-rotation/log_file_rotation.metatags
  • examples/logger-from-config/logger_from_config.bal
  • examples/logger-from-config/logger_from_config.md
  • examples/logging-configuration/Config.toml
  • examples/logging-configuration/logging_configuration.md
  • examples/mcp-service-advanced/mcp_service_advanced.bal
  • examples/natural-expressions/natural_expressions.md
  • examples/string-templates/string_templates.md
  • examples/xml-from-json-conversion/xml_from_json_conversion.bal
  • examples/xml-from-json-conversion/xml_from_json_conversion.md
  • examples/xml-from-record-conversion/xml_from_record_conversion.bal
  • examples/xml-from-record-conversion/xml_from_record_conversion.md
  • examples/xml-to-json-conversion/xml_to_json_conversion.bal
  • examples/xml-to-json-conversion/xml_to_json_conversion.md
  • examples/xml-to-record-conversion/xml_to_record_conversion.bal
  • examples/xml-to-record-conversion/xml_to_record_conversion.md
  • gradle.properties
  • stdlib-integration-tests/index.json
  • stdlib-integration-tests/library_package_test/Ballerina.toml
  • stdlib-integration-tests/library_package_test/main.bal

Comment on lines 118 to +121
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: '14'
node-version: "14"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== workflow occurrences =="
if [ -f .github/workflows/publish-release.yml ]; then
  nl -ba .github/workflows/publish-release.yml | sed -n '100,130p;692,710p'
  echo "== action action.yml/deprecated mentions =="
  rg -n "setup-node@|setup-dotnet@|node-version:|java-version:|dotnet-version:" .github/workflows/publish-release.yml || true
else
  echo "workflow file missing"
fi

echo
echo "== GitHub API refs/tags if gh available =="
if command -v gh >/dev/null 2>&1; then
  echo "setup-node v2:"
  gh api repos/actions/setup-node/git/refs/tags/v2 --jq '{ref:.ref,type:.object.type,target_sha:(if .object.type=="tag" then "delegated" else .object.sha end)}' || true
  echo "setup-dotnet v1:"
  gh api repos/actions/setup-dotnet/git/refs/tags/v1 --jq '{ref:.ref,type:.object.type,target_sha:(if .object.type=="tag" then "delegated" else .object.sha end)}' || true
else
  echo "gh not available"
fi

echo
echo "== workflow YAML parser check =="
python3 - <<'PY'
from pathlib import Path
p=Path(".github/workflows/publish-release.yml")
if not p.exists():
    raise SystemExit(0)
text=p.read_text()
for needle in ["actions/setup-node@v2", "actions/setup-dotnet@v1"]:
    print(f"{needle}: {text.count(needle)}")
PY

Repository: ballerina-platform/ballerina-distribution

Length of output: 246


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== workflow occurrences =="
if [ -f .github/workflows/publish-release.yml ]; then
  nl -ba .github/workflows/publish-release.yml | sed -n '100,130p;692,710p'
  echo "== action action.yml/deprecated mentions =="
  rg -n "setup-node@|setup-dotnet@|node-version:|java-version:|dotnet-version:" .github/workflows/publish-release.yml || true
else
  echo "workflow file missing"
fi

echo
echo "== GitHub API refs/tags if gh available =="
if command -v gh >/dev/null 2>&1; then
  echo "setup-node v2:"
  gh api repos/actions/setup-node/git/refs/tags/v2 --jq '{ref:.ref,type:.object.type,target_sha:(if .object.type=="tag" then "delegated" else .object.sha end)}' || true
  echo "setup-dotnet v1:"
  gh api repos/actions/setup-dotnet/git/refs/tags/v1 --jq '{ref:.ref,type:.object.type,target_sha:(if .object.type=="tag" then "delegated" else .object.sha en
d)}' || true
else
  echo "gh not available"
fi

echo
echo "== workflow YAML parser check =="
python3 - <<'PY'
from pathlib import Path
p=Path(".github/workflows/publish-release.yml")
if not p.exists():
    raise SystemExit(0)
text=p.read_text()
for needle in ["actions/setup-node@v2", "actions/setup-dotnet@v1"]:
    print(f"{needle}: {text.count(needle)}")
PY

Repository: ballerina-platform/ballerina-distribution

Length of output: 246


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== check presence =="
test -f .github/workflows/publish-release.yml && echo "present" || echo "missing"

echo "== search occurrences with grep =="
grep -nE "actions/setup-node|actions/setup-dotnet|node-version:|java-version:|dotnet-version:" .github/workflows/publish-release.yml || true

echo "== line-numbered snippets with awk =="
awk 'NR>=108 && NR<=124 {printf "%6d  %s\n", NR, $0}' .github/workflows/publish-release.yml
awk 'NR>=696 && NR<=708 {printf "%6d  %s\n", NR, $0}' .github/workflows/publish-release.yml

echo
echo "== repository action occurrences in workflows =="
grep -RnE "actions/(setup-node|setup-dotnet)@" .github/workflows || true

echo
echo "== GitHub API refs/tags if gh available =="
if command -v gh >/dev/null 2>&1; then
  echo "setup-node v2:"
  gh api repos/actions/setup-node/git/refs/tags/v2 --jq '{ref:.ref,type:.object.type,target_sha:(if .object.type=="tag" then "delegated" else .object.sha end)}' || true
  echo "setup-dotnet v1:"
  gh api repos/actions/setup-dotnet/git/refs/tags/v1 --jq '{ref:.ref,type:.object.type,target_sha:(if .object.type=="tag" then "delegated" else .object.sha end)}' || true
else
  echo "gh not available"
fi

echo
echo "== workflow presence check =="
python3 - <<'PY'
from pathlib import Path
text = Path(".github/workflows/publish-release.yml").read_text()
for needle in ["actions/setup-node@v2", "actions/setup-dotnet@v1"]:
    print(f"{needle}: {text.count(needle)}")
PY

Repository: ballerina-platform/ballerina-distribution

Length of output: 2876


🌐 Web query:

actions/setup-node v2 legacy runner node runtime deprecated

💡 Result:

The actions/setup-node v2 action is effectively deprecated and highly recommended against for use in GitHub Actions workflows [1][2]. The primary reasons for its deprecation are: 1. Unsupported Node.js Runtime: The v2 version of the action relies on Node 12 as its underlying execution runtime [1][3][4]. Node 12 reached end-of-life (EOL) years ago and is no longer supported or secure [1]. 2. Deprecated Cache Service: The action uses an outdated implementation of the GitHub Actions cache service (@actions/cache), which has been subject to permanent shutdowns and brownout events [2]. This frequently causes workflows to fail during dependency installation [2]. To maintain secure and reliable CI/CD pipelines, you should update your workflows to the latest version of setup-node (currently v4 or later) [1][2][5]. Modern versions of this action use updated Node.js runtimes (such as Node 20 or Node 24) and the current, supported cache service [1][6][7].

Citations:


🌐 Web query:

actions/setup-dotnet v1 legacy runner deprecation unsupported

💡 Result:

The actions/setup-dotnet v1 action is long deprecated and should not be used in modern GitHub Actions workflows [1]. GitHub Actions and their supporting official actions rely on the underlying runner's environment (Node.js version, platform, etc.) to function [2][3]. As actions evolve—such as moving from older Node.js versions (e.g., node12/16/20) to newer ones like node24—the runners must support these newer requirements [2][3]. Key points regarding the deprecation and transition: 1. Version v1 is obsolete: Users encountering issues with v1 (such as warnings about unexpected inputs or failing workflows) are advised to migrate to newer, supported major versions [1]. As of August 2026, the action is on version 5+ [2][3]. 2. Node.js Compatibility: Newer versions of actions/setup-dotnet (e.g., v5.0.0 and above) require updated runners (v2.327.1 or later) to handle upgraded internal requirements like Node.js 24 [2][3]. 3. Why V1 fails: Older actions often contain deprecated dependencies or rely on environment behaviors that have changed significantly since 2019/2021 [4][3]. 4. Recommended Action: You should update your workflow files to use the latest major version (e.g., uses: actions/setup-dotnet@v5 or newer) to ensure compatibility with GitHub's current hosted runner environment [2][5]. If you are seeing "unsupported" or "deprecated" errors, it is a direct consequence of using an outdated version of the action that is no longer tested or maintained against current GitHub runner software [4][3].

Citations:


Replace the deprecated setup actions.

Both actions/setup-node@v2 and actions/setup-dotnet@v1 are legacy major versions. Update these steps to supported action majors before running the release workflow.

🧰 Tools
🪛 actionlint (1.7.12)

[error] 119-119: the runner of "actions/setup-node@v2" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

📍 Affects 1 file
  • .github/workflows/publish-release.yml#L118-L121 (this comment)
  • .github/workflows/publish-release.yml#L702-L706
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/publish-release.yml around lines 118 - 121, Update the
setup-node step at .github/workflows/publish-release.yml:118-121 from
actions/setup-node@v2 to a supported major version, and update the setup-dotnet
step at .github/workflows/publish-release.yml:702-706 from
actions/setup-dotnet@v1 to a supported major version before the release workflow
runs.

Source: Linters/SAST tools

Comment thread .trivyignore
Comment on lines +8 to +22
CVE-2026-56740
CVE-2026-56741

# jackson-core / jackson-databind - needs dependency upgrade to 2.18.8+/2.21.4+
GHSA-r7wm-3cxj-wff9
CVE-2026-54512
CVE-2026-54513
CVE-2026-54514
CVE-2026-54515
CVE-2026-59888
CVE-2026-59889
GHSA-mhm7-754m-9p8w

# netty-transport-native-epoll / netty-transport-native-kqueue - needs dependency upgrade to 4.1.135.Final/4.2.15.Final+
CVE-2026-45536

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n -C 2 'Need to be fixed|CVE-2026-(56740|56741|54512|54513|54514|54515|59888|59889|45536)' .trivyignore
rg -n 'jackson-(core|databind)-2\.18\.0|netty-(transport|handler|codec)-4\.1\.126\.Final' ballerina/LICENSE
rg -n -C 3 'trivy-action|exit-code' .github/workflows/publish-release.yml

Repository: ballerina-platform/ballerina-distribution

Length of output: 1882


🌐 Web query:

Trivy .trivyignore CVE ID suppression YAML ignore-file expiry PURL documentation

💡 Result:

Trivy supports vulnerability suppression using both a legacy plain-text .trivyignore file and an experimental, structured .trivyignore.yaml file [1][2]. YAML Ignore-File (.trivyignore.yaml) This structured format allows for more granular control over ignored findings by categorizing them into vulnerabilities, misconfigurations, secrets, or licenses [1]. Because this feature is currently experimental, you must explicitly specify the path to your YAML ignore file using the --ignorefile flag (e.g., trivy image --ignorefile.trivyignore.yaml...) [1][2]. Key features of.trivyignore.yaml: - CVE ID Suppression: You can list IDs under their respective categories [1]. - PURL Support: You can restrict suppression to specific packages using the purls field, which accepts a list of Package URLs [1][3][4]. This is currently available only for vulnerabilities [1][3]. - Expiry: You can define an expiration date for an ignore entry using the expired_at field (format: yyyy-mm-dd) [1][5]. Once the date passes, the finding will no longer be ignored [5]. - Statement: An optional field to document the reasoning for the suppression (not used for active filtering) [1][5]. Example structure: vulnerabilities: - id: CVE-2023-3817 purls: - "pkg:deb/debian/libssl1.1" expired_at: 2026-12-31 statement: "Waiting for patch upstream" Legacy Plain-Text (.trivyignore) The legacy format supports simple ID-based suppression [1][5]. It also supports expiration dates by appending exp:yyyy-mm-dd to the line [6][7]. Example: CVE-2019-14697 exp:2026-12-31 Important Note: As of April 2026, development is underway to make the id field optional in.trivyignore.yaml, which would allow users to ignore all findings matching specific PURLs or paths without listing individual IDs [8]. Always check your specific version of Trivy documentation for the most accurate feature support [1].

Citations:


Security Misconfiguration (CWE-693)

Reachability: Internal

Do not suppress vulnerabilities that need fixes.

The CVE IDs in .trivyignore are active suppression rules; the section comments do not exempt them. The release workflow runs Trivy with exit-code: "1", so these entries let affected findings pass without blocking the release. Remove these IDs until the Jackson and Netty dependencies are patched. If a temporary exception is needed, use an expiring, package-scoped override only and remove it before the next release.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.trivyignore around lines 8 - 22, Remove the listed Jackson and Netty
vulnerability IDs from the `.trivyignore` suppression entries so Trivy blocks
releases until the dependencies are upgraded. Do not replace them with broad or
permanent exceptions; any temporary workaround must be package-scoped and
expiring.

Comment thread ballerina/build.gradle
Comment on lines +964 to +966
if (!bbe.needCentral) {
additionalParams += " --sticky --offline"
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Apply offline options during output verification.

outputVerification runs before buildBBE and invokes bal run without --offline. A sample that requires Central can populate the cache during output verification, then pass the later offline build. This makes needCentral: false ineffective for examples with output verification.

Derive additionalBuildParams from bbe.needCentral inside outputVerification and pass the same offline options to bal run.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ballerina/build.gradle` around lines 964 - 966, Update outputVerification to
derive additionalBuildParams from bbe.needCentral and pass the resulting offline
options to its bal run invocation, matching the existing buildBBE behavior.
Ensure needCentral: false uses the same --sticky --offline parameters during
output verification.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '960,983p' ballerina/build.gradle

Repository: ballerina-platform/ballerina-distribution

Length of output: 1217


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '1,1200p' ballerina/build.gradle | nl -ba | sed -n '930,1005p'

Repository: ballerina-platform/ballerina-distribution

Length of output: 219


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== surrounding buildBBE usage =="
rg -n "buildBBE|outputVerification|buildBBE\\(" ballerina/build.gradle

echo "== buildBBE implementation =="
python3 - <<'PY'
from pathlib import Path
p=Path('ballerina/build.gradle')
lines=p.read_text().splitlines()
for i in range(max(0,930-1), min(len(lines),975)):
    print(f"{i+1}: {lines[i]}")
PY

echo "== Gradle ExecSpec docs in installed Gradle, if present =="
if command -v gradle >/dev/null 2>&1; then
  gradle --version | head -3
else
  echo "gradle command not present"
fi

echo "== deterministic parser check of commandLine call semantics in Groovy =="
python3 - <<'PY'
# Gradle Groovy closures are Java-style methods where each call is evaluated;
# the documented ExecSpec.commandLine(String[]) sets the complete command line,
# so a second call replaces the first.
print("If ExecSpec.commandLine sets the whole command line, two sequential calls keep only the second.")
PY

Repository: ballerina-platform/ballerina-distribution

Length of output: 2860


🌐 Web query:

Gradle ExecSpec.commandLine sets full command line documentation

💡 Result:

In the Gradle API, the commandLine method in the ExecSpec interface is used to set the full command line for an execution process, including both the executable itself and any associated arguments [1][2]. Key technical details regarding commandLine: Functionality: It replaces any existing executable or arguments previously set on the ExecSpec object with the new sequence provided [1][3]. Inputs: It accepts multiple formats to define the command line, including varargs (Object...), an Iterable, or a List [1][2][3]. Difference from args: While commandLine sets the entire execution string (executable + arguments), the args method is used solely to add additional arguments to an already specified executable [1][4]. Usage Example: In a Gradle task, you might use it as follows: task myExec(type: Exec) { // Sets both the executable and its arguments commandLine 'cmd.exe', '/c', 'my-script.bat' } This will configure the task to execute cmd.exe with the arguments /c and my-script.bat [4][5].

Citations:


Run build and test in separate exec calls.

ExecSpec.commandLine replaces the full command line, so the second call in each platform branch discards the bal build command. As written, only bal test runs, and exitVal cannot report a build failure. Call them separately and fail the example when either command fails.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ballerina/build.gradle` around lines 964 - 966, Update the platform-specific
execution flow around ExecSpec.commandLine so `bal build` and `bal test` run in
separate exec calls rather than overwriting one another. Capture each command’s
exit status, propagate failure when either command fails, and ensure `exitVal`
reflects build or test failure.

Comment thread ballerina/LICENSE
Comment on lines +167 to +171
ballerina-time-2.8.0.jar jar apache2
ballerina-ftp-2.15.1.jar jar apache2
ballerina-ai.intelligence-1.7.0.jar jar apache2
ballerina-ai.observe-1.7.0.jar jar apache2
ballerina-ai-1.7.0.jar jar apache2

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Regenerate the release license inventory.

gradle.properties resolves newer FTP, Log, Crypto, and HTTP versions, but this inventory records older versions. The released license notice will not describe the dependency set that build.gradle packages.

Generate this file from the resolved release dependencies. Update the related compiler and native artifact rows in the same generation step.

Also applies to: 219-225, 253-254

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ballerina/LICENSE` around lines 167 - 171, Regenerate the ballerina license
inventory from the dependencies resolved by gradle.properties and build.gradle,
replacing stale FTP, Log, Crypto, and HTTP versions. Ensure the same generation
updates the related compiler and native artifact rows, rather than editing only
the displayed entries manually.

Comment on lines +20 to +29
public isolated function getLevel() returns log:Level {
lock {
return self.level;
}
}

public isolated function setLevel(log:Level level) returns error? {
lock {
self.level = level;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show the repository-declared Ballerina and log-module versions.
fd -a -t f 'Ballerina.toml|Dependencies.toml|gradle.properties' . | sort | while IFS= read -r file; do
  echo "===== ${file} ====="
  sed -n '1,180p' "$file"
done

# Inspect every ApplicationLogger emission path and level access.
rg -n -C 8 'ApplicationLogger|function (getLevel|setLevel|printDebug|printInfo|printWarn|printError)' \
  examples/custom-logger

Repository: ballerina-platform/ballerina-distribution

Length of output: 20304


🌐 Web query:

ballerina log API custom Logger setLevel Level printInfo does not check log:Level

💡 Result:

The statement that the Ballerina log API's print functions do not check the log level is incorrect based on official documentation [1][2][3]. The Ballerina log module is designed to filter log messages based on the effective log level of the logger being used [1][3]. When you call a logging function such as log:printInfo(), the implementation automatically checks the logger's effective log level against the level of the message being sent [1][2]. If the message level is lower than the configured effective log level, the message is suppressed [1][3]. Regarding runtime configuration: - Global and custom loggers (created via log:fromConfig) allow setting and modifying the log level at runtime using the setLevel() method [1][2][4]. - Child loggers (created via withContext) do not support setLevel(); they always inherit the effective log level from their parent logger [2][5]. If you attempt to call setLevel() on a child logger, it will return an error [2][4]. - The log:getLevel() function correctly returns the effective log level, which for child loggers is the level inherited from the parent [2]. If you find that logs are being printed when they should be suppressed, ensure that the log level is configured correctly (e.g., in Config.toml using [ballerina.log] level = "...") [1][6] and that you are using the appropriate logger instance for your context [1][3]. Outdated configurations or incorrect module-level settings are common causes for unexpected logging behavior [6].

Citations:


🌐 Web query:

ballerina spec log Logger interfaces getLevel setLevel printInfo Level

💡 Result:

In Ballerina, the log module provides the Logger interface to manage application logging [1][2]. The primary logging functions available on a Logger instance include printDebug, printInfo, printWarn, and printError [1][3]. Regarding the specific methods for log level management: - getLevel: This method returns the effective Level of the logger instance [2][3]. For root and custom loggers created via configuration, it returns the explicitly set level, while for child loggers, it returns the level inherited from the parent logger [2]. - setLevel(Level level): This method updates the log level of a logger at runtime [2][3]. It is supported for root loggers and custom loggers (e.g., those created via log:fromConfig) [4][5]. It typically returns an error if the operation is unsupported, such as when attempting to set the level on a child logger, which is designed to inherit its level from its parent [2][4]. The supported log levels, in descending order of priority, are ERROR, WARN, INFO, and DEBUG [1][5][6]. By default, the system logs at the INFO level and above [5][6]. Runtime log level modification allows for updating loggers registered in the logger registry without restarting the application [5].

Citations:


🌐 Web query:

site:ballerina.io/spec/log printInfo custom logger setLevel level

💡 Result:

In the context of the Ballerina programming language logging library, the setLevel(Level level) function is used to update the log level of a root or custom logger at runtime [1]. Key behavioral details for setLevel include: - Functionality: It updates the log level for the specific logger instance [1]. - Return Value: It returns an error? type, which may indicate an unsupported operation if called incorrectly [1]. - Limitations on Child Loggers: The setLevel function cannot be called directly on child loggers, as they inherit their log level from their parent [1]. Attempting to call setLevel on a child logger will result in an error [1]. To modify the effective log level of a child logger, you must instead call setLevel on its parent logger [1]. While the term printInfo appears as a specific logging method (e.g., printInfo(string|PrintableRawTemplate msg,...)) within the Ballerina log library for logging informational messages, it is distinct from the configuration methods like setLevel used to manage logger behavior [1].

Citations:


🌐 Web query:

ballerina log printInfo checks Logger getSetLevel before emitting

💡 Result:

Yes, the Ballerina log:printInfo function (and other similar logging functions like printDebug, printWarn, and printError) implicitly checks the logger's effective log level before emitting a log message [1][2]. When you call a logging function, the underlying implementation verifies whether the configured log level of the logger is sufficient to permit the message based on its severity (e.g., INFO level logs will not be emitted if the logger is set to WARN or ERROR) [2][3]. To optimize performance and avoid unnecessary computation for logs that will not be emitted—such as constructing complex strings or executing heavy functions—it is a best practice to use lazy evaluation techniques [3]. Specifically, you can pass functions (function pointers) as key-value pairs [3]. If the current effective log level is lower than the severity of the log call, the log module will skip the execution of those function pointers [3]. For example, if you have a printDebug call that includes a heavy computation, passing it as a function ensures the computation only occurs if the DEBUG level is actually enabled: log:printDebug("Checking the duration", duration = isolated function returns float { return heavyComputation; }); In this example, if the logger's level is set to INFO or higher, the function inside the key-value pair will not be executed [3].

Citations:


🌐 Web query:

"ballerina" "Logger interface" "printDebug" "LogLevel" "setLevel"

💡 Result:

In Ballerina, the log module provides a Logger object type that defines the interface for logging messages, including the printDebug method and runtime level management via setLevel [1][2]. The Logger interface provides the following primary methods for logging and managing log levels: Logging Methods You can log messages at the DEBUG level using the printDebug method [1][2]: public isolated function printDebug(string|PrintableRawTemplate msg, error? 'error =, error:StackFrame[]? stackTrace =, *KeyValues keyValues); Similar methods exist for other levels, such as printInfo, printWarn, and printError [1][3]. Runtime Log Level Management The Logger interface includes methods to retrieve and modify the log level at runtime [1]: - getLevel: Returns the effective LogLevel of the logger [1]. - setLevel(Level level): Sets the log level for the logger at runtime [1]. Runtime Modification via Logger Registry For loggers created via log:fromConfig, you can discover and update their log levels at runtime using the logger registry, without restarting the application [4][5]: 1. Access the registry: log:LoggerRegistry registry = log:getLoggerRegistry; [4] 2. Lookup the logger by its ID: log:Logger? logger = registry.getById("your-logger-id"); [4] 3. Update the level: check logger.setLevel(log:DEBUG); [4] Note that log levels for child loggers (created via withContext) are inherited from their parent and cannot be changed independently, and per-module log levels configured via Config.toml are static [4][5].

Citations:


🌐 Web query:

"Ballina" "setLevel" "log" "printInfo" "check"

💡 Result:

In the Ballerina programming language, the log module provides logging functionality with configurable log levels [1][2]. The relevant functions and methods you mentioned are part of this library's API [1][3]. Core Logging Functions The Ballerina log module includes four primary functions to log messages at specific levels [1][2]: * log:printDebug * log:printInfo * log:printWarn * log:printError Runtime Log Level Management You can manage log levels at runtime for specific loggers [1][2]. If you have a log:Logger instance, you can use the following methods [1][2]: * setLevel(Level level): Sets the log level for that logger at runtime [1][2]. It returns an error if the operation is not supported (e.g., on child loggers) [1][2]. * getLevel: Returns the currently effective log level for the logger [1][2]. Configuration * Default Behavior: By default, the system logs messages at the INFO level and above [2][3]. * Static Configuration: You can configure log levels globally or per module using a Config.toml file [2][4]. Note that log levels defined in Config.toml are static and apply at startup [2]. * Runtime Configuration: Loggers created via log:fromConfig can be registered and updated at runtime using setLevel() [2]. Child loggers (created via withContext) inherit their level from the parent and cannot have their level changed independently [1][2]. For further details, consult the official Ballerina log module documentation [1][2].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate any local/log repository sources or docs under the checkout.
printf '%s\n' "===== candidate log documentation/source files ====="
git ls-files | rg 'log($|/)|module-ballerina-log|Ballerina\.toml|ModuleDescription\.toml' | head -200

printf '\n===== file-level indicators about log implementation/spec =====\n'
rg -n 'printDebug|printInfo|printWarn|printError|LogLevel|enum Logger|class Logger|interface Logger|setLevel|getLevel' -g '*.bal' -g '*.md' -g '*.toml' . | head -300

Repository: ballerina-platform/ballerina-distribution

Length of output: 37469


Let setLevel bypass lower-severity emissions too.

Custom loggers are expected to forward the runtime level to backend logging. Since print* methods here always call the standard log API directly, setLevel(log:ERROR) still lets printInfo, printWarn, and printDebug forward lower-priority messages.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/custom-logger/custom_logger.bal` around lines 20 - 29, Update the
custom logger’s level handling in setLevel and the print* methods so emissions
below the configured log:Level are suppressed before calling the standard log
API. Ensure setLevel(log:ERROR) prevents printInfo, printWarn, and printDebug
from forwarding while preserving higher-severity logging.

Comment on lines +63 to +69

log:Level parentLevel;
lock {
// Child loggers inherit the level from the parent logger
parentLevel = self.level;
}
return new ApplicationLogger(self.applicationName, self.version, newContext, parentLevel);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate custom-logger tests and all level-inheritance assertions.
rg -n -C 6 'withContext|setLevel|getLevel|ApplicationLogger' \
  --glob '*test*.bal' --glob '*Test*.bal' --glob '*.bal' .

Repository: ballerina-platform/ballerina-distribution

Length of output: 8946


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Find the core log module sources and any Logger contract/type definitions.
rg -n "type Logger|function getLevel|function setLevel|function withContext|logger" --glob '*.bal' .

# Show likely log package files without executing repo code.
printf '\n--- Candidate files ---\n'
git ls-files | rg '(^|/)log/|Logger|log\.bal' | head -200

Repository: ballerina-platform/ballerina-distribution

Length of output: 2424


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the custom logger implementation around Logger and child behavior.
cat -n examples/custom-logger/custom_logger.bal

# Search the repository only for Logger contract terms in plain files, without excluding examples.
rg -n "log:Logger|function withContext|function getLevel|function setLevel|type Logger|Logger =" --glob '*.bal' .

Repository: ballerina-platform/ballerina-distribution

Length of output: 5674


🌐 Web query:

Ballerina log:Logger withContext getLevel setLevel child logger contract

💡 Result:

In the Ballerina log library, the Logger interface handles contextual logging and runtime log level management through specific behaviors regarding hierarchy and configuration [1][2]. withContext The withContext method is used to create a child logger [1][3]. It accepts key-value pairs and returns a new Logger instance that includes this additional context in its log output [1][2]. Child loggers are not registered in the logger registry [1][2]. getLevel The getLevel method returns the effective log level of a logger [1]. - For root or custom loggers (created via log:fromConfig), it returns the level explicitly set for that logger [1][2]. - For child loggers (created via withContext), it returns the level inherited from its parent [1][2]. If the parent logger's level is updated, the child logger's effective level changes automatically, as getLevel delegates to the parent [1]. setLevel The setLevel method allows modifying the log level of a logger at runtime [2]. - It is supported on root and custom loggers that are registered in the logger registry [2]. - It is NOT supported on child loggers [1][2]. Calling setLevel on a child logger will return an error, as these loggers are designed to strictly inherit their level from their parent [1][4]. To change the effective level of a child logger, you must change the level of the parent logger instead [1][2]. Logger Contract and Registry Loggers created via log:fromConfig are registered in a central logger registry, allowing them to be discovered and managed (e.g., updating levels) at runtime using their unique ID [2]. Child loggers, being transient and linked to a parent's lifecycle, do not participate in this registration process [1][2].

Citations:


🌐 Web query:

Ballerina log module source getLevel setLevel child logger not supported

💡 Result:

In the Ballerina log module, calling setLevel on a child logger is not supported and will result in an error [1]. Child loggers are designed to inherit their log level from their parent logger [1][2]. Consequently, the following behaviors apply: 1. setLevel: Attempting to invoke setLevel on a child logger returns an unsupported operation error [1][2]. To change the effective log level of a child logger, you must instead change the log level of its parent [1]. 2. getLevel: When called on a child logger, getLevel delegates the request to the parent logger to return the effective inherited level [1]. This design choice ensures that child loggers, which are typically created via withContext to add metadata, maintain consistency with the parent's configuration [1][2]. Dynamic log level modification via setLevel is only supported for root loggers and custom loggers [3][2].

Citations:


Keep child loggers linked to the parent level.

withContext(...) copies the parent level once, so a later appLogger.setLevel(...) does not update already created child loggers. The custom child logger also allows setLevel(...), which can break the inherited-child contract. Store the parent logger in child contexts, delegate getLevel(...) to the parent, and make child setLevel(...) return the unsupported-operation error.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/custom-logger/custom_logger.bal` around lines 63 - 69, Update
withContext(...) and the child logger implementation so child contexts retain a
reference to the parent logger instead of copying parentLevel. Make child
getLevel(...) delegate to that parent, and make child setLevel(...) return the
unsupported-operation error, preserving the inherited parent-level contract.

Comment on lines +21 to +28
destinations: [{
path: "./logs/metrics.log",
rotation: {
policy: log:TIME_BASED,
maxAge: 86400, // 24 hours
maxBackupFiles: 7
}
}],

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== file excerpt =="
sed -n '1,80p' examples/logger-from-config/logger_from_config.bal 2>/dev/null || true

echo
echo "== matching metrics/retention references =="
rg -n "retention|metrics|maxBackupFiles|rotation:|destinations" examples examples/logger-from-config . 2>/dev/null || true

echo
echo "== git diff stat/name-only =="
git diff --stat HEAD~1..HEAD 2>/dev/null || true
git diff --name-only HEAD~1..HEAD 2>/dev/null || true

Repository: ballerina-platform/ballerina-distribution

Length of output: 22357


🌐 Web query:

Ballerina log module maxBackupFiles TIME_BASED retention metadata rotation depends on writes

💡 Result:

In the Ballerina log module, the log rotation process, including the application of maxBackupFiles retention, is triggered during log write operations [1]. The rotation behavior depends on the configured policy (SIZE_BASED, TIME_BASED, or BOTH): 1. Dependency on Writes: Log rotation is not an independent background process that runs strictly on a timer. It is performed during log write operations [1]. This means that if no logs are being written, the system will not perform a rotation even if the maxAge (TIME_BASED) threshold has passed. The rotation check occurs when the application attempts to write a log entry [1]. 2. Rotation Policies: - SIZE_BASED: Rotation occurs when the log file reaches the maxFileSize [1]. - TIME_BASED: Rotation occurs when the duration specified by maxAge has elapsed since the last rotation or file creation, but only when a subsequent log write operation is triggered [1]. - BOTH: Rotation occurs when either the maxFileSize OR the maxAge limit is reached, whichever occurs first, checked at the time of a write operation [1]. 3. Retention (maxBackupFiles): The maxBackupFiles parameter defines the maximum number of historical backup log files to retain [2][1]. When a rotation occurs, the current log file is renamed with a timestamp, and the system automatically deletes the oldest backup files if the total count exceeds the value set in maxBackupFiles [2][1]. Because the rotation check is tied to write operations, the file system metadata and rotation logic are updated only when the application actively logs data [1].

Citations:


Align the metrics retention metadata with the rotation configuration.

maxBackupFiles = 7 retains seven rotated backup files, while retention = "30days" advertises 30-day retention. If 30-day daily retention is intended, use maxBackupFiles: 30; otherwise update the retention context value. Also note that rotation only happens when log writes occur, so no writes may leave no backup files despite a configured maxAge.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/logger-from-config/logger_from_config.bal` around lines 21 - 28,
Align the metrics destination’s retention metadata with its rotation settings:
update maxBackupFiles in the destinations configuration to 30 for 30-day daily
retention, or change the associated retention context value to match seven
backups. Preserve the existing rotation policy and ensure the resulting
configuration accurately describes retention when log writes trigger rotation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.