Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build-with-bal-test-graalvm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:
call_stdlib_workflow:
name: Run StdLib Workflow
if: ${{ github.event_name != 'schedule' || (github.event_name == 'schedule' && github.repository_owner == 'ballerina-platform') }}
uses: ballerina-platform/ballerina-library/.github/workflows/build-with-bal-test-graalvm-template.yml@main
uses: ballerina-platform/ballerina-library/.github/workflows/build-with-bal-test-graalvm-template.yml@java-25-migration

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify mutable workflow refs in repo workflows.
rg -nP '^\s*uses:\s*[^#\n]+@((main|master|[A-Za-z0-9._/-]+))\s*$' .github/workflows
# Expected: this line should be gone once pinned to a 40-char SHA.

Repository: ballerina-platform/module-ballerina-http

Length of output: 2936


Pin reusable workflow reference in build-with-bal-test-graalvm.yml to a commit SHA
./.github/workflows/build-with-bal-test-graalvm.yml line 43 references a reusable workflow with the mutable ref @java-25-migration—use the full commit SHA instead to keep CI behavior deterministic.

🔒 Suggested fix
-        uses: ballerina-platform/ballerina-library/.github/workflows/build-with-bal-test-graalvm-template.yml@java-25-migration
+        uses: ballerina-platform/ballerina-library/.github/workflows/build-with-bal-test-graalvm-template.yml@<full_commit_sha>
🧰 Tools
🪛 zizmor (1.25.2)

[error] 43-43: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 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/build-with-bal-test-graalvm.yml at line 43, Update the
reusable workflow reference on the "uses:" line that currently ends with
"`@java-25-migration`" to a fixed commit SHA (replace "`@java-25-migration`" with
"@<full-commit-sha>") so CI is deterministic; locate the "uses:
ballerina-platform/ballerina-library/.github/workflows/build-with-bal-test-graalvm-template.yml@java-25-migration"
entry in build-with-bal-test-graalvm.yml and swap the mutable ref for the full
commit SHA of the target repo/tag, commit the change, and verify the workflow
runs.

with:
lang_tag: ${{ inputs.lang_tag }}
lang_version: ${{ inputs.lang_version }}
Expand Down
8 changes: 6 additions & 2 deletions .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
name: PR Build

on: [pull_request]
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
cancel-in-progress: true

on: pull_request

jobs:
call_workflow:
name: Run PR Build Workflow
if: ${{ github.repository_owner == 'ballerina-platform' }}
uses: ballerina-platform/ballerina-library/.github/workflows/pull-request-build-template.yml@main
uses: ballerina-platform/ballerina-library/.github/workflows/pull-request-build-template.yml@java-25-migration
secrets: inherit
Comment on lines +13 to 14

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find reusable workflow calls that are mutable and/or inherit all secrets.
rg -nP '^\s*uses:\s*[^#\n]+@([A-Za-z0-9._/-]+)\s*$|^\s*secrets:\s*inherit\s*$' .github/workflows
# Expected after fix:
# - `uses:` for external/reusable workflows pinned to full SHAs
# - no unconditional `secrets: inherit` unless explicitly justified

Repository: ballerina-platform/module-ballerina-http

Length of output: 3349


🏁 Script executed:

#!/bin/bash
set -euo pipefail
FILE=".github/workflows/pull-request.yml"
echo "== File: $FILE =="
nl -ba "$FILE" | sed -n '1,80p'

Repository: ballerina-platform/module-ballerina-http

Length of output: 192


🌐 Web query:

GitHub Actions reusable workflow security pin commit SHA secrets: inherit

💡 Result:

In a GitHub Actions workflow that calls a reusable workflow, secrets: inherit is supported and it passes the caller workflow’s secrets to the directly called reusable workflow. Specifically, reusable workflow docs show secrets: inherit in a job that uses another workflow via uses: owner/repo/.github/workflows/<file>@<ref>, and they note that you can reference inherited secrets even when they’re not explicitly defined under the reusable workflow’s on: workflow_call secret list [1]. The workflow syntax reference also describes passing secrets and the jobs.<job_id>.secrets.inherit form for passing all calling-workflow secrets into the directly called workflow [2]. For security pinning: when referencing reusable workflows (and third-party actions), you should pin the uses: reference to a specific immutable identifier. GitHub’s “Secure use” guidance says using a full-length commit SHA is the only way to treat an action as an immutable release, and pinning to a full-length commit SHA mitigates the risk of a backdoor being added to the action’s repository [3]. The reusable-workflow docs explicitly state that the {ref} portion can be a SHA, release tag, or branch name, and that using the commit SHA is the safest option for stability and security [1]. So the best practice pattern is: - Pin the reusable workflow uses: ref to a full-length commit SHA (not a branch like main, not a moving tag) [1][3]. - If you need secrets from the caller, use secrets: inherit only when the called workflow is trusted and you intentionally want to pass all caller secrets through the workflow chain (note secrets are only passed to the directly called workflow, not implicitly further) [2][4]. Example (caller workflow job that pins reusable workflow and inherits secrets): - uses: ORG/REPO/.github/workflows/reusable.yml@<full-length-commit-sha> - secrets: inherit [1][2]. Security note on scope: GitHub docs clarify that in a workflow chain A > B > C, workflow C will only receive secrets from A if A passes secrets to B, and then B passes them to C; secrets: inherit does not automatically propagate beyond the directly called workflow [4].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail
FILE=".github/workflows/pull-request.yml"
echo "== $FILE (lines 8-22) =="
awk 'NR>=8 && NR<=22 {printf "%d:%s\n", NR, $0}' "$FILE"

Repository: ballerina-platform/module-ballerina-http

Length of output: 412


🌐 Web query:

ballerina-platform/ballerina-library pull-request-build-template.yml java-25-migration secrets inherit

💡 Result:

I couldn’t locate the specific file path you mentioned (ballerina-platform/ballerina-library pull-request-build-template.yml java-25-migration secrets inherit). What I can confirm from authoritative sources is the following relevant parts: 1) How secrets: inherit works for reusable GitHub workflows - In GitHub Actions, you can call a reusable workflow and pass secrets implicitly using secrets: inherit. The called (reusable) workflow can then reference those secrets even if they aren’t explicitly defined in the called workflow’s on inputs/keys. [1] - You can also pass all calling workflow secrets to a directly called workflow with jobs.<job_id>.secrets.inherit. [1] 2) Example showing secrets: inherit used with a Ballerina-library reusable workflow - In ballerina-platform/module-ballerinax-azure.ai.search, the repository’s .github/workflows/pull-request.yml calls a reusable workflow in ballerina-platform/ballerina-library and sets secrets: inherit. [2] 3) Evidence around “Java 25 migration” context (Ballerina-related) - There is an open issue about “Getting warnings when running in Java 25” in ballerina-platform/ballerina-lang, indicating Java 25-specific runtime warnings are a consideration in the Ballerina ecosystem. [3] - A Java 25 migration guide exists (OpenRewrite) but it’s about upgrading Java codebases broadly; it doesn’t directly confirm any specific pull-request-build-template.yml behavior in ballerina-library. [4] If you share the exact repo URL (or paste the relevant portion of the pull-request-build-template.yml and/or the java-25-migration job block), I can verify precisely whether and where secrets: inherit is used and how the Java 25 migration is wired in that template.

Citations:


Pin the reusable workflow ref to an immutable commit SHA and avoid secrets: inherit
.github/workflows/pull-request.yml calls ballerina-platform/ballerina-library/.github/workflows/pull-request-build-template.yml@java-25-migration and uses secrets: inherit, forwarding all caller secrets to the reusable workflow.

    uses: ballerina-platform/ballerina-library/.github/workflows/pull-request-build-template.yml@java-25-migration
    secrets: inherit
🔐 Suggested hardening
-    uses: ballerina-platform/ballerina-library/.github/workflows/pull-request-build-template.yml@java-25-migration
-    secrets: inherit
+    uses: ballerina-platform/ballerina-library/.github/workflows/pull-request-build-template.yml@<full_commit_sha>
+    secrets:
+      REQUIRED_SECRET_NAME: ${{ secrets.REQUIRED_SECRET_NAME }}
🧰 Tools
🪛 zizmor (1.25.2)

[error] 13-13: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[warning] 13-13: secrets unconditionally inherited by called workflow (secrets-inherit): this reusable workflow

(secrets-inherit)

🤖 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/pull-request.yml around lines 13 - 14, The reusable
workflow invocation currently uses a mutable branch ref and forwards all secrets
with "secrets: inherit", which is unsafe; change the "uses:
ballerina-platform/ballerina-library/.github/workflows/pull-request-build-template.yml@java-25-migration"
to a specific immutable commit SHA (replace the `@java-25-migration` ref with the
exact commit SHA) and remove "secrets: inherit", instead explicitly pass only
the needed secrets (e.g., "secrets: MY_SECRET: ${{ secrets.MY_SECRET }}" for
each required secret) so that you pin the workflow version and limit secret
exposure.

9 changes: 8 additions & 1 deletion ballerina-tests/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ plugins {
apply plugin: 'java'

import org.apache.tools.ant.taskdefs.condition.Os
import org.gradle.process.ExecOperations
import javax.inject.Inject

abstract class BallerinaTestsExecHelper {
@Inject abstract ExecOperations getExecOperations()
}

description = 'Ballerina - HTTP/WS Ballerina Tests'

Expand Down Expand Up @@ -98,13 +104,14 @@ task updateTomlVersions {
}

task commitTomlFiles {
def execHelper = project.objects.newInstance(BallerinaTestsExecHelper)
doLast {
def files = "${testCommonPackage}/Ballerina.toml ${testCommonPackage}/Dependencies.toml "
testPackages.each{ testPackage ->
files += "${testPackage}/Ballerina.toml ${testPackage}/Dependencies.toml "
}

project.exec {
execHelper.execOperations.exec {
ignoreExitValue true
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
commandLine 'cmd', '/c', "git commit -m \"[Automated] Update the native jar versions\" ${files}"
Expand Down
4 changes: 2 additions & 2 deletions ballerina-tests/http-advanced-tests/Ballerina.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ name = "http_test_common"
repository = "local"
version = "2.17.0"

[platform.java21]
[platform.java25]
graalvmCompatible = true

[[platform.java21.dependency]]
[[platform.java25.dependency]]
scope = "testOnly"
path = "../../test-utils/build/libs/http-test-utils-2.17.0-SNAPSHOT.jar"
4 changes: 2 additions & 2 deletions ballerina-tests/http-client-tests/Ballerina.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ name = "http_test_common"
repository = "local"
version = "2.17.0"

[platform.java21]
[platform.java25]
graalvmCompatible = true

[[platform.java21.dependency]]
[[platform.java25.dependency]]
scope = "testOnly"
path = "../../test-utils/build/libs/http-test-utils-2.17.0-SNAPSHOT.jar"
4 changes: 2 additions & 2 deletions ballerina-tests/http-dispatching-tests/Ballerina.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ name = "http_test_common"
repository = "local"
version = "2.17.0"

[platform.java21]
[platform.java25]
graalvmCompatible = true

[[platform.java21.dependency]]
[[platform.java25.dependency]]
scope = "testOnly"
path = "../../test-utils/build/libs/http-test-utils-2.17.0-SNAPSHOT.jar"
4 changes: 2 additions & 2 deletions ballerina-tests/http-interceptor-tests/Ballerina.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ name = "http_test_common"
repository = "local"
version = "2.17.0"

[platform.java21]
[platform.java25]
graalvmCompatible = true

[[platform.java21.dependency]]
[[platform.java25.dependency]]
scope = "testOnly"
path = "../../test-utils/build/libs/http-test-utils-2.17.0-SNAPSHOT.jar"
4 changes: 2 additions & 2 deletions ballerina-tests/http-misc-tests/Ballerina.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ name = "http_test_common"
repository = "local"
version = "2.17.0"

[platform.java21]
[platform.java25]
graalvmCompatible = true

[[platform.java21.dependency]]
[[platform.java25.dependency]]
scope = "testOnly"
path = "../../test-utils/build/libs/http-test-utils-2.17.0-SNAPSHOT.jar"
4 changes: 2 additions & 2 deletions ballerina-tests/http-resiliency-tests/Ballerina.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ name = "http_test_common"
repository = "local"
version = "2.17.0"

[platform.java21]
[platform.java25]
graalvmCompatible = true

[[platform.java21.dependency]]
[[platform.java25.dependency]]
scope = "testOnly"
path = "../../test-utils/build/libs/http-test-utils-2.17.0-SNAPSHOT.jar"
4 changes: 2 additions & 2 deletions ballerina-tests/http-security-tests/Ballerina.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ name = "http_test_common"
repository = "local"
version = "2.17.0"

[platform.java21]
[platform.java25]
graalvmCompatible = true

[[platform.java21.dependency]]
[[platform.java25.dependency]]
scope = "testOnly"
path = "../../test-utils/build/libs/http-test-utils-2.17.0-SNAPSHOT.jar"
4 changes: 2 additions & 2 deletions ballerina-tests/http-service-tests/Ballerina.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ name = "http_test_common"
repository = "local"
version = "2.17.0"

[platform.java21]
[platform.java25]
graalvmCompatible = true

[[platform.java21.dependency]]
[[platform.java25.dependency]]
scope = "testOnly"
path = "../../test-utils/build/libs/http-test-utils-2.17.0-SNAPSHOT.jar"
4 changes: 2 additions & 2 deletions ballerina-tests/http2-tests/Ballerina.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ name = "http_test_common"
repository = "local"
version = "2.17.0"

[platform.java21]
[platform.java25]
graalvmCompatible = true

[[platform.java21.dependency]]
[[platform.java25.dependency]]
scope = "testOnly"
path = "../../test-utils/build/libs/http-test-utils-2.17.0-SNAPSHOT.jar"
62 changes: 31 additions & 31 deletions ballerina/Ballerina.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,170 +7,170 @@ keywords = ["http", "network", "service", "listener", "client"]
repository = "https://github.com/ballerina-platform/module-ballerina-http"
icon = "icon.png"
license = ["Apache-2.0"]
distribution = "2201.13.3"
distribution = "2201.14.0-SNAPSHOT"

[[package.modules]]
name = "http.httpscerr"
description = "This module provides status code error types."
export = true

[platform.java21]
[platform.java25]
graalvmCompatible = true

[[platform.java21.dependency]]
[[platform.java25.dependency]]
groupId = "io.ballerina.stdlib"
artifactId = "http-native"
version = "2.17.0"
path = "../native/build/libs/http-native-2.17.0-SNAPSHOT.jar"

[[platform.java21.dependency]]
[[platform.java25.dependency]]
groupId = "io.ballerina.stdlib"
artifactId = "mime-native"
version = "2.12.1"
path = "./lib/mime-native-2.12.1.jar"

[[platform.java21.dependency]]
[[platform.java25.dependency]]
groupId = "io.ballerina.stdlib"
artifactId = "constraint-native"
version = "1.7.0"
path = "./lib/constraint-native-1.7.0.jar"

[[platform.java21.dependency]]
[[platform.java25.dependency]]
groupId = "io.netty"
artifactId = "netty-common"
version = "4.1.132.Final"
path = "./lib/netty-common-4.1.132.Final.jar"

[[platform.java21.dependency]]
[[platform.java25.dependency]]
groupId = "io.netty"
artifactId = "netty-buffer"
version = "4.1.132.Final"
path = "./lib/netty-buffer-4.1.132.Final.jar"

[[platform.java21.dependency]]
[[platform.java25.dependency]]
groupId = "io.netty"
artifactId = "netty-transport"
version = "4.1.132.Final"
path = "./lib/netty-transport-4.1.132.Final.jar"

[[platform.java21.dependency]]
[[platform.java25.dependency]]
groupId = "io.netty"
artifactId = "netty-resolver"
version = "4.1.132.Final"
path = "./lib/netty-resolver-4.1.132.Final.jar"

[[platform.java21.dependency]]
[[platform.java25.dependency]]
groupId = "io.netty"
artifactId = "netty-handler"
version = "4.1.132.Final"
path = "./lib/netty-handler-4.1.132.Final.jar"

[[platform.java21.dependency]]
[[platform.java25.dependency]]
groupId = "io.netty"
artifactId = "netty-codec-http"
version = "4.1.132.Final"
path = "./lib/netty-codec-http-4.1.132.Final.jar"

[[platform.java21.dependency]]
[[platform.java25.dependency]]
groupId = "io.netty"
artifactId = "netty-codec"
version = "4.1.132.Final"
path = "./lib/netty-codec-4.1.132.Final.jar"

[[platform.java21.dependency]]
[[platform.java25.dependency]]
groupId = "io.netty"
artifactId = "netty-handler-proxy"
version = "4.1.132.Final"
path = "./lib/netty-handler-proxy-4.1.132.Final.jar"

[[platform.java21.dependency]]
[[platform.java25.dependency]]
groupId = "io.netty"
artifactId = "netty-codec-http2"
version = "4.1.132.Final"
path = "./lib/netty-codec-http2-4.1.132.Final.jar"

[[platform.java21.dependency]]
[[platform.java25.dependency]]
groupId = "commons-pool.wso2"
artifactId = "commons-pool"
version = "1.5.6.wso2v1"
path = "./lib/commons-pool-1.5.6.wso2v1.jar"

[[platform.java21.dependency]]
[[platform.java25.dependency]]
groupId = "io.netty"
artifactId = "netty-transport-native-unix-common"
version = "4.1.132.Final"
path = "./lib/netty-transport-native-unix-common-4.1.132.Final.jar"

[[platform.java21.dependency]]
[[platform.java25.dependency]]
groupId = "org.bouncycastle"
artifactId = "bcprov-jdk18on"
version = "1.84"
path = "./lib/bcprov-jdk18on-1.84.jar"

[[platform.java21.dependency]]
[[platform.java25.dependency]]
groupId = "org.bouncycastle"
artifactId = "bcutil-jdk18on"
version = "1.84"
path = "./lib/bcutil-jdk18on-1.84.jar"

[[platform.java21.dependency]]
[[platform.java25.dependency]]
groupId = "org.bouncycastle"
artifactId = "bcpkix-jdk18on"
version = "1.84"
path = "./lib/bcpkix-jdk18on-1.84.jar"

[[platform.java21.dependency]]
[[platform.java25.dependency]]
groupId = "io.netty"
artifactId = "netty-tcnative-boringssl-static"
version = "2.0.75.Final"
path = "./lib/netty-tcnative-boringssl-static-2.0.75.Final.jar"

[[platform.java21.dependency]]
[[platform.java25.dependency]]
path = "./lib/netty-tcnative-boringssl-static-2.0.75.Final-windows-x86_64.jar"

[[platform.java21.dependency]]
[[platform.java25.dependency]]
path = "./lib/netty-tcnative-boringssl-static-2.0.75.Final-linux-aarch_64.jar"

[[platform.java21.dependency]]
[[platform.java25.dependency]]
path = "./lib/netty-tcnative-boringssl-static-2.0.75.Final-linux-x86_64.jar"

[[platform.java21.dependency]]
[[platform.java25.dependency]]
path = "./lib/netty-tcnative-boringssl-static-2.0.75.Final-osx-aarch_64.jar"

[[platform.java21.dependency]]
[[platform.java25.dependency]]
path = "./lib/netty-tcnative-boringssl-static-2.0.75.Final-osx-x86_64.jar"

[[platform.java21.dependency]]
[[platform.java25.dependency]]
groupId = "io.netty"
artifactId = "netty-tcnative-classes"
version = "2.0.75.Final"
path = "./lib/netty-tcnative-classes-2.0.75.Final.jar"

[[platform.java21.dependency]]
[[platform.java25.dependency]]
groupId = "org.jvnet.mimepull"
artifactId = "mimepull"
version = "1.9.11"
path = "./lib/mimepull-1.9.11.jar"

[[platform.java21.dependency]]
[[platform.java25.dependency]]
groupId = "io.netty"
artifactId = "netty-codec-socks"
version = "4.1.132.Final"
path = "./lib/netty-codec-socks-4.1.132.Final.jar"

[[platform.java21.dependency]]
[[platform.java25.dependency]]
groupId = "org.jboss.marshalling"
artifactId = "jboss-marshalling"
version = "2.0.5.Final"
path = "./lib/jboss-marshalling-2.0.5.Final.jar"

[[platform.java21.dependency]]
[[platform.java25.dependency]]
groupId = "at.yawk.lz4"
artifactId = "lz4-java"
version = "1.10.1"
path = "./lib/lz4-java-1.10.1.jar"

[[platform.java21.dependency]]
[[platform.java25.dependency]]
groupId = "com.google.protobuf"
artifactId = "protobuf-java"
version = "3.25.5"
Expand Down
2 changes: 1 addition & 1 deletion ballerina/Dependencies.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

[ballerina]
dependencies-toml-version = "2"
distribution-version = "2201.13.3"
distribution-version = "2201.14.0-SNAPSHOT"

[[package]]
org = "ballerina"
Expand Down
Loading