diff --git a/.github/actions/configure-maven-mirror/action.yml b/.github/actions/configure-maven-mirror/action.yml
new file mode 100644
index 000000000..ce309a8f7
--- /dev/null
+++ b/.github/actions/configure-maven-mirror/action.yml
@@ -0,0 +1,42 @@
+name: Configure Maven CodeArtifact mirror
+description: Configure Maven to resolve dependencies through the release CodeArtifact repository.
+
+runs:
+ using: composite
+ steps:
+ - shell: bash
+ run: |
+ CA_DOMAIN=aws-lambda
+ CA_REPO=maven-central-store
+
+ # Uses the ambient region and caller account.
+ TOKEN=$(aws codeartifact get-authorization-token \
+ --domain "$CA_DOMAIN" --query authorizationToken --output text)
+ echo "::add-mask::$TOKEN"
+
+ CA_URL=$(aws codeartifact get-repository-endpoint \
+ --domain "$CA_DOMAIN" --repository "$CA_REPO" --format maven \
+ --query repositoryEndpoint --output text)
+
+ # * routes all resolution through the mirror;
+ # deployment uses distributionManagement and is unaffected.
+ mkdir -p "$HOME/.m2"
+ cat > "$HOME/.m2/settings.xml" <
+
+
+ codeartifact-mirror
+ aws
+ ${TOKEN}
+
+
+
+
+ codeartifact-mirror
+ release CodeArtifact Maven Central proxy
+ ${CA_URL}
+ *
+
+
+
+ EOF
diff --git a/.github/actions/configure-release-aws-credentials/action.yml b/.github/actions/configure-release-aws-credentials/action.yml
new file mode 100644
index 000000000..6a34f6480
--- /dev/null
+++ b/.github/actions/configure-release-aws-credentials/action.yml
@@ -0,0 +1,28 @@
+name: "Configure AWS credentials for release (OIDC)"
+description: >
+ Assumes the release OIDC role via aws-actions/configure-aws-credentials so the
+ job can read the signing key and Sonatype token from Secrets Manager. Pinning
+ of the underlying action lives here so it is updated in one place.
+
+inputs:
+ aws-region:
+ description: "AWS region to operate in."
+ required: true
+ role-to-assume:
+ description: "ARN of the OIDC role to assume."
+ required: true
+ role-session-name:
+ description: "Session name for the assumed role (helps distinguish callers in CloudTrail)."
+ required: true
+
+runs:
+ using: composite
+ steps:
+ - uses: aws-actions/configure-aws-credentials@7474bc4690e29a8392af63c5b98e7449536d5c3a # v4
+ with:
+ aws-region: ${{ inputs.aws-region }}
+ role-to-assume: ${{ inputs.role-to-assume }}
+ role-session-name: ${{ inputs.role-session-name }}
+ # Kept short: the job only needs the role briefly to read two secrets.
+ # 900s is STS's minimum for assume-role; anything lower is rejected.
+ role-duration-seconds: 900
diff --git a/.github/actions/resolve-release-version/action.yml b/.github/actions/resolve-release-version/action.yml
new file mode 100644
index 000000000..06d3f4f1e
--- /dev/null
+++ b/.github/actions/resolve-release-version/action.yml
@@ -0,0 +1,54 @@
+name: "Resolve and validate release version"
+description: >
+ Reads the module POM version (the source of truth), verifies it is a
+ -SNAPSHOT, and derives the effective release version (the optional override,
+ or the POM version with -SNAPSHOT stripped). Exports CURRENT_VERSION and
+ EFFECTIVE_RELEASE_VERSION to the job environment for subsequent steps.
+
+inputs:
+ module:
+ description: "Module directory containing the pom.xml to release."
+ required: true
+ release-version-override:
+ description: "Optional release version; defaults to the POM version without -SNAPSHOT."
+ required: false
+ default: ""
+ validate-module-dir:
+ description: "Fail if the module directory or its pom.xml is missing (use for the choice-driven workflow)."
+ required: false
+ default: "false"
+
+runs:
+ using: composite
+ steps:
+ - name: Resolve and validate release version
+ shell: bash
+ env:
+ MODULE: ${{ inputs.module }}
+ RELEASE_VERSION_OVERRIDE: ${{ inputs.release-version-override }}
+ VALIDATE_MODULE_DIR: ${{ inputs.validate-module-dir }}
+ run: |
+ if [[ "$VALIDATE_MODULE_DIR" == "true" ]]; then
+ if [[ ! -d "$MODULE" ]]; then
+ echo "::error::Module directory '$MODULE' does not exist"
+ exit 1
+ fi
+ if [[ ! -f "$MODULE/pom.xml" ]]; then
+ echo "::error::No pom.xml found in '$MODULE'"
+ exit 1
+ fi
+ fi
+
+ # The POM version is the source of truth and must be a SNAPSHOT.
+ CURRENT_VERSION=$(mvn -q -DforceStdout help:evaluate -Dexpression=project.version --file "$MODULE/pom.xml")
+ CURRENT_VERSION="${CURRENT_VERSION//[$'\r\n']/}"
+ if [[ "$CURRENT_VERSION" != *-SNAPSHOT ]]; then
+ echo "::error::POM version '$CURRENT_VERSION' is not a SNAPSHOT"
+ exit 1
+ fi
+
+ # Optional override; default strips -SNAPSHOT.
+ EFFECTIVE_RELEASE_VERSION="${RELEASE_VERSION_OVERRIDE:-${CURRENT_VERSION%-SNAPSHOT}}"
+
+ echo "CURRENT_VERSION=$CURRENT_VERSION" >> "$GITHUB_ENV"
+ echo "EFFECTIVE_RELEASE_VERSION=$EFFECTIVE_RELEASE_VERSION" >> "$GITHUB_ENV"
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 3722537ae..88f18ea29 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -1,6 +1,9 @@
version: 2
updates:
-
+ - package-ecosystem: "maven"
+ directory: "/aws-lambda-java-runtime-interface"
+ schedule:
+ interval: "weekly"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
diff --git a/.github/test-matrix.json b/.github/test-matrix.json
new file mode 100644
index 000000000..7e6539cb6
--- /dev/null
+++ b/.github/test-matrix.json
@@ -0,0 +1,16 @@
+{
+ "arch": [
+ {
+ "runner": "ubuntu-latest",
+ "label": "x64",
+ "sam_arch": "x86_64",
+ "java_suffix": "X64"
+ },
+ {
+ "runner": "ubuntu-24.04-arm",
+ "label": "arm64",
+ "sam_arch": "arm64",
+ "java_suffix": "ARM64"
+ }
+ ]
+}
diff --git a/.github/workflows/aws-lambda-java-core.yml b/.github/workflows/aws-lambda-java-core.yml
index 267d901c9..3e4364672 100644
--- a/.github/workflows/aws-lambda-java-core.yml
+++ b/.github/workflows/aws-lambda-java-core.yml
@@ -1,9 +1,10 @@
# This workflow will be triggered if there will be changes to aws-lambda-java-core
-# package and it builds the package and the packages that depend on it.
+# package and it builds the package.
name: Java CI aws-lambda-java-core
on:
+ workflow_dispatch:
push:
branches: [ main ]
paths:
@@ -14,30 +15,22 @@ on:
- 'aws-lambda-java-core/**'
- '.github/workflows/aws-lambda-java-core.yml'
+permissions:
+ contents: read
+
jobs:
build:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
- name: Set up JDK 1.8
- uses: actions/setup-java@v4
+ uses: actions/setup-java@v5
with:
java-version: 8
distribution: corretto
-
- # Install base module
+ cache: maven
+
- name: Install core with Maven
run: mvn -B install --file aws-lambda-java-core/pom.xml
-
- # Package modules that depend on base module
- - name: Package log4j2 with Maven
- run: mvn -B package --file aws-lambda-java-log4j2/pom.xml
-
- # Test Runtime Interface Client
- - name: Run 'pr' target
- working-directory: ./aws-lambda-java-runtime-interface-client
- run: make pr
- env:
- IS_JAVA_8: true
diff --git a/.github/workflows/aws-lambda-java-events-sdk-transformer.yml b/.github/workflows/aws-lambda-java-events-sdk-transformer.yml
index 66f6b2bfe..144d52f86 100644
--- a/.github/workflows/aws-lambda-java-events-sdk-transformer.yml
+++ b/.github/workflows/aws-lambda-java-events-sdk-transformer.yml
@@ -1,36 +1,43 @@
-# This workflow will be triggered if there will be changes to
-# aws-lambda-java-events-sdk-transformer package and it builds the package.
+# This workflow will be triggered if there will be changes to
+# aws-lambda-java-events-sdk-transformer package or its dependency (events),
+# and it builds the package.
name: Java CI aws-lambda-java-events-sdk-transformer
on:
+ workflow_dispatch:
push:
branches: [ main ]
paths:
- 'aws-lambda-java-events-sdk-transformer/**'
+ - 'aws-lambda-java-events/**'
pull_request:
branches: [ '*' ]
paths:
- 'aws-lambda-java-events-sdk-transformer/**'
+ - 'aws-lambda-java-events/**'
- '.github/workflows/aws-lambda-java-events-sdk-transformer.yml'
+permissions:
+ contents: read
+
jobs:
build:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
- name: Set up JDK 1.8
- uses: actions/setup-java@v4
+ uses: actions/setup-java@v5
with:
java-version: 8
distribution: corretto
+ cache: maven
- # Install base module
+ # Install dependency
- name: Install events with Maven
run: mvn -B install --file aws-lambda-java-events/pom.xml
# Package target module
- name: Package events-sdk-transformer with Maven
run: mvn -B package --file aws-lambda-java-events-sdk-transformer/pom.xml
-
diff --git a/.github/workflows/aws-lambda-java-events.yml b/.github/workflows/aws-lambda-java-events.yml
index 04ab53a50..18be63cf9 100644
--- a/.github/workflows/aws-lambda-java-events.yml
+++ b/.github/workflows/aws-lambda-java-events.yml
@@ -1,9 +1,10 @@
# This workflow will be triggered if there will be changes to aws-lambda-java-events
-# package and it builds the package and the packages that depend on it.
+# package and it builds the package.
name: Java CI aws-lambda-java-events
on:
+ workflow_dispatch:
push:
branches: [ main ]
paths:
@@ -14,26 +15,22 @@ on:
- 'aws-lambda-java-events/**'
- '.github/workflows/aws-lambda-java-events.yml'
+permissions:
+ contents: read
+
jobs:
build:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
- name: Set up JDK 1.8
- uses: actions/setup-java@v4
+ uses: actions/setup-java@v5
with:
java-version: 8
distribution: corretto
-
- # Install base module
+ cache: maven
+
- name: Install events with Maven
run: mvn -B install --file aws-lambda-java-events/pom.xml
-
- # Package modules that depend on base module
- - name: Package serialization with Maven
- run: mvn -B package --file aws-lambda-java-serialization/pom.xml
- - name: Package events-sdk-transformer with Maven
- run: mvn -B package --file aws-lambda-java-events-sdk-transformer/pom.xml
-
diff --git a/.github/workflows/aws-lambda-java-log4j2.yml b/.github/workflows/aws-lambda-java-log4j2.yml
index 7ae54cbe1..945a1cb30 100644
--- a/.github/workflows/aws-lambda-java-log4j2.yml
+++ b/.github/workflows/aws-lambda-java-log4j2.yml
@@ -1,36 +1,42 @@
-# This workflow will be triggered if there will be changes to
-# aws-lambda-java-log4j2 package and it builds the package.
+# This workflow will be triggered if there will be changes to
+# aws-lambda-java-log4j2 package or its dependency (core), and it builds the package.
name: Java CI aws-lambda-java-log4j2
on:
push:
+ workflow_dispatch:
branches: [ main ]
paths:
- 'aws-lambda-java-log4j2/**'
+ - 'aws-lambda-java-core/**'
pull_request:
branches: [ '*' ]
paths:
- 'aws-lambda-java-log4j2/**'
+ - 'aws-lambda-java-core/**'
- '.github/workflows/aws-lambda-java-log4j2.yml'
+permissions:
+ contents: read
+
jobs:
build:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
- name: Set up JDK 1.8
- uses: actions/setup-java@v4
+ uses: actions/setup-java@v5
with:
java-version: 8
distribution: corretto
-
- # Install base module
+ cache: maven
+
+ # Install dependency
- name: Install core with Maven
run: mvn -B install --file aws-lambda-java-core/pom.xml
# Package target module
- name: Package log4j2 with Maven
run: mvn -B package --file aws-lambda-java-log4j2/pom.xml
-
diff --git a/.github/workflows/aws-lambda-java-profiler.yml b/.github/workflows/aws-lambda-java-profiler.yml
index db9fc225e..a098bfd14 100644
--- a/.github/workflows/aws-lambda-java-profiler.yml
+++ b/.github/workflows/aws-lambda-java-profiler.yml
@@ -22,16 +22,17 @@ jobs:
contents: read
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Set up JDK
- uses: actions/setup-java@v4
+ uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5
with:
java-version: 21
distribution: corretto
+ cache: maven
- name: Issue AWS credentials
- uses: aws-actions/configure-aws-credentials@v4
+ uses: aws-actions/configure-aws-credentials@7474bc4690e29a8392af63c5b98e7449536d5c3a # v4
with:
aws-region: ${{ secrets.AWS_REGION_PROFILER_EXTENSION_INTEGRATION_TEST }}
role-to-assume: ${{ secrets.AWS_ROLE_PROFILER_EXTENSION_INTEGRATION_TEST }}
@@ -58,12 +59,16 @@ jobs:
working-directory: ./experimental/aws-lambda-java-profiler
run: ./integration_tests/invoke_function.sh
+ - name: Invoke Java Custom Options function
+ working-directory: ./experimental/aws-lambda-java-profiler
+ run: ./integration_tests/invoke_function_custom_options.sh
+
- name: Download from s3
working-directory: ./experimental/aws-lambda-java-profiler
run: ./integration_tests/download_from_s3.sh
- name: Upload profiles
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: profiles
path: /tmp/s3-artifacts
diff --git a/.github/workflows/aws-lambda-java-serialization.yml b/.github/workflows/aws-lambda-java-serialization.yml
index c24c48d72..f52c96fed 100644
--- a/.github/workflows/aws-lambda-java-serialization.yml
+++ b/.github/workflows/aws-lambda-java-serialization.yml
@@ -1,39 +1,46 @@
-# This workflow will be triggered if there will be changes to aws-lambda-java-serialization
-# package and it builds the package and the packages that depend on it.
+# This workflow will be triggered if there will be changes to aws-lambda-java-serialization
+# package or its dependency (events), and it builds the package.
name: Java CI aws-lambda-java-serialization
on:
+ workflow_dispatch:
push:
branches: [ main ]
paths:
- 'aws-lambda-java-serialization/**'
+ - 'aws-lambda-java-events/**'
pull_request:
branches: [ '*' ]
paths:
- 'aws-lambda-java-serialization/**'
+ - 'aws-lambda-java-events/**'
- '.github/workflows/aws-lambda-java-serialization.yml'
+permissions:
+ contents: read
+
jobs:
build:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
- name: Set up JDK 1.8
- uses: actions/setup-java@v4
+ uses: actions/setup-java@v5
with:
java-version: 8
distribution: corretto
-
- # Install base module
+ cache: maven
+
+ # Install dependency
- name: Install events with Maven
run: mvn -B install --file aws-lambda-java-events/pom.xml
# Package and install target module
- name: Package serialization with Maven
- run: mvn -B package install --file aws-lambda-java-serialization/pom.xml
+ run: mvn -B install --file aws-lambda-java-serialization/pom.xml
# Run tests
- name: Run tests from aws-lambda-java-tests
diff --git a/.github/workflows/aws-lambda-java-tests.yml b/.github/workflows/aws-lambda-java-tests.yml
index a28bca886..324c44514 100644
--- a/.github/workflows/aws-lambda-java-tests.yml
+++ b/.github/workflows/aws-lambda-java-tests.yml
@@ -1,33 +1,42 @@
# This workflow will be triggered if there will be changes to aws-lambda-java-tests
-# package and it builds the package and the packages that depend on it.
+# package or its dependencies (events, serialization), and it builds the package.
name: Java CI aws-lambda-java-tests
on:
+ workflow_dispatch:
push:
branches: [ main ]
paths:
- 'aws-lambda-java-tests/**'
+ - 'aws-lambda-java-events/**'
+ - 'aws-lambda-java-serialization/**'
pull_request:
branches: [ '*' ]
paths:
- 'aws-lambda-java-tests/**'
+ - 'aws-lambda-java-events/**'
+ - 'aws-lambda-java-serialization/**'
- '.github/workflows/aws-lambda-java-tests.yml'
+permissions:
+ contents: read
+
jobs:
build:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
- name: Set up JDK 1.8
- uses: actions/setup-java@v4
+ uses: actions/setup-java@v5
with:
java-version: 8
distribution: corretto
-
- # Install base module
+ cache: maven
+
+ # Install dependencies
- name: Install events with Maven
run: mvn -B install --file aws-lambda-java-events/pom.xml
- name: Install serialization with Maven
@@ -36,4 +45,3 @@ jobs:
# Package target module
- name: Package tests with Maven
run: mvn -B package --file aws-lambda-java-tests/pom.xml
-
diff --git a/.github/workflows/build-integration-test.yml b/.github/workflows/build-integration-test.yml
new file mode 100644
index 000000000..2a6bb30c5
--- /dev/null
+++ b/.github/workflows/build-integration-test.yml
@@ -0,0 +1,86 @@
+# this workflow verifies that the integration test Lambda function builds successfully.
+# it does NOT deploy or run the tests (that requires AWS credentials and is done in
+# run-integration-test.yml).
+
+name: Build integration tests
+
+on:
+ push:
+ branches: [ main ]
+ paths:
+ - 'aws-lambda-java-log4j2/**'
+ - 'aws-lambda-java-core/**'
+ - 'lambda-integration-tests/**'
+ pull_request:
+ branches: [ '*' ]
+ paths:
+ - 'aws-lambda-java-log4j2/**'
+ - 'aws-lambda-java-core/**'
+ - 'lambda-integration-tests/**'
+ - '.github/workflows/build-integration-test.yml'
+
+permissions:
+ contents: read
+
+jobs:
+ load-matrix:
+ runs-on: ubuntu-latest
+ outputs:
+ matrix: ${{ steps.set.outputs.matrix }}
+ steps:
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+
+ - name: Load test matrix
+ id: set
+ run: |
+ MATRIX=$(jq -c '.' .github/test-matrix.json)
+ echo "matrix=${MATRIX}" >> "$GITHUB_OUTPUT"
+
+ build-arch:
+ needs: load-matrix
+ runs-on: ${{ matrix.arch.runner }}
+ strategy:
+ fail-fast: false
+ matrix: ${{ fromJson(needs.load-matrix.outputs.matrix) }}
+ name: "build (${{ matrix.arch.label }})"
+ steps:
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+
+ - name: Set up JDK
+ uses: actions/setup-java@1bcf9fb12cf4aa7d266a90ae39939e61372fe520 # v5.4.0
+ with:
+ java-version: |
+ 8
+ 21
+ distribution: corretto
+ cache: maven
+
+ - name: Install core with Maven
+ run: |
+ export JAVA_HOME=$JAVA_HOME_8_${{ matrix.arch.java_suffix }}
+ mvn -B install --file aws-lambda-java-core/pom.xml
+
+ - name: Install log4j2 with Maven
+ run: |
+ export JAVA_HOME=$JAVA_HOME_8_${{ matrix.arch.java_suffix }}
+ mvn -B install --file aws-lambda-java-log4j2/pom.xml
+
+ # build the integration test function
+ # this verifies that the function compiles and packages correctly.
+ # the tests will run in run-integration-test.yml which deploys to AWS.
+ - name: Package integration test function
+ run: |
+ export JAVA_HOME=$JAVA_HOME_21_${{ matrix.arch.java_suffix }}
+ mvn -B package --file lambda-integration-tests/log4j2-test-function/pom.xml
+
+ build:
+ needs: build-arch
+ if: always()
+ runs-on: ubuntu-latest
+ steps:
+ - name: Check build results
+ run: |
+ if [ "${{ needs.build-arch.result }}" != "success" ]; then
+ echo "Build failed on one or more architectures"
+ exit 1
+ fi
diff --git a/.github/workflows/release-runtime-interface-client.yml b/.github/workflows/release-runtime-interface-client.yml
new file mode 100644
index 000000000..e41dcfc61
--- /dev/null
+++ b/.github/workflows/release-runtime-interface-client.yml
@@ -0,0 +1,361 @@
+name: Release RIC to Maven Central
+
+# RIC ships a native JNI lib for 4 targets + a main JAR (5 artifacts). Each
+# native lib is built on its own architecture (x86_64 and aarch64 CodeBuild
+# runners) instead of emulating with QEMU. A build matrix produces the
+# classifier JARs, then one job assembles and publishes them.
+
+on:
+ workflow_dispatch:
+ inputs:
+ releaseVersion:
+ description: 'Release version override (optional; defaults to the POM version without -SNAPSHOT)'
+ required: false
+ type: string
+ developmentVersion:
+ description: 'Next development version override (optional, must end with -SNAPSHOT)'
+ required: false
+ type: string
+ skip_publish:
+ description: 'Skip publish (dry-run validation)'
+ required: false
+ type: boolean
+ default: false
+
+permissions:
+ contents: write # push release commit and tag
+ id-token: write # assume the OIDC role for secret retrieval
+
+# Share the repo-wide "release" group with release.yml so RIC and the pure-Java
+# modules can never publish concurrently. Never cancel in-flight: it could leave
+# a half-published state.
+concurrency:
+ group: release
+ cancel-in-progress: false
+
+env:
+ MODULE: aws-lambda-java-runtime-interface-client
+ RELEASE_VERSION_INPUT: ${{ github.event.inputs.releaseVersion }}
+ DEVELOPMENT_VERSION_INPUT: ${{ github.event.inputs.developmentVersion }}
+ MAVEN_ARGS: "-B --no-transfer-progress"
+ AWS_REGION: ${{ vars.AWS_REGION_MAVEN_RELEASE }}
+ OIDC_ROLE_ARN: ${{ secrets.AWS_ROLE_MAVEN_RELEASE }}
+ # ECR pull-through cache used for the native JNI base images. ECR_REGISTRY is
+ # the login target; BASE_REGISTRY (with the /ecr-public prefix) is passed to
+ # the Dockerfiles as a build-arg.
+ ECR_REGISTRY: ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.${{ vars.AWS_REGION_MAVEN_RELEASE }}.amazonaws.com
+ BASE_REGISTRY: ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.${{ vars.AWS_REGION_MAVEN_RELEASE }}.amazonaws.com/ecr-public
+
+jobs:
+ # Build each architecture's native libs (glibc + musl) on a native runner.
+ build-natives:
+ strategy:
+ fail-fast: true
+ matrix:
+ include:
+ - arch: x86_64
+ runner: codebuild-aws-lambda-java-libs-test-trigger-x86-${{ github.run_id }}-${{ github.run_attempt }}
+ profiles: linux-x86_64 linux_musl-x86_64
+ - arch: aarch64
+ runner: codebuild-aws-lambda-java-libs-test-trigger-arm64-${{ github.run_id }}-${{ github.run_attempt }}
+ profiles: linux-aarch64 linux_musl-aarch64
+ runs-on: ${{ matrix.runner }}
+ timeout-minutes: 45
+ steps:
+ # Manual (workflow_dispatch) releases must only run from main, never from
+ # an arbitrary branch that could carry unreviewed release logic. Guarding
+ # the first job blocks the whole pipeline (release needs build-natives).
+ - name: Verify release branch
+ run: |
+ if [[ "$GITHUB_REF_NAME" != "main" ]]; then
+ echo "::error::Releases must run from the main branch, got '$GITHUB_REF_NAME'"
+ exit 1
+ fi
+
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ # Use the CodeBuild image's preinstalled Corretto 8. The image ships it at
+ # $JAVA_8_HOME but defaults JAVA_HOME to Java 25, so point JAVA_HOME/PATH at
+ # 8. Avoids actions/setup-java, which fetches from corretto.github.io +
+ # corretto.aws, both blocked by the runner egress lock. $JAVA_8_HOME
+ # resolves per-arch (x86_64/aarch64).
+ - name: Use the runner image's preinstalled Corretto 8
+ run: |
+ echo "JAVA_HOME=$JAVA_8_HOME" >> "$GITHUB_ENV"
+ echo "$JAVA_8_HOME/bin" >> "$GITHUB_PATH"
+ "$JAVA_8_HOME/bin/java" -version
+ mkdir -p "$HOME/.m2"
+ cat > "$HOME/.m2/toolchains.xml" <
+
+
+ jdk
+ 8
+ $JAVA_8_HOME
+
+
+ EOF
+
+ # Route all mvn resolution through the CodeArtifact mirror. Must precede
+ # resolve-release-version, which invokes `mvn help:evaluate`. Ambient
+ # CodeBuild runner-role creds supply the token; no OIDC step in this job.
+ - name: Configure Maven CodeArtifact mirror
+ uses: ./.github/actions/configure-maven-mirror
+
+ - name: Resolve and validate release version
+ uses: ./.github/actions/resolve-release-version
+ with:
+ module: ${{ env.MODULE }}
+ release-version-override: ${{ env.RELEASE_VERSION_INPUT }}
+
+ # The native JNI build shells out to `docker build` against the ECR
+ # pull-through cache (see src/main/jni/Dockerfile.*). Authenticate first so
+ # the base-image pulls don't hit public.ecr.aws. Uses ambient runner creds.
+ - name: Log in to Amazon ECR (pull-through cache)
+ run: |
+ aws ecr get-login-password --region "$AWS_REGION" \
+ | docker login --username AWS --password-stdin "$ECR_REGISTRY"
+
+ # -DskipTests: only installed so the module compiles, not released here.
+ - name: Install intra-repo dependencies
+ run: |
+ for dep in aws-lambda-java-core aws-lambda-java-serialization; do
+ mvn install -DskipTests --file "$dep/pom.xml"
+ done
+
+ # Build at the release version (matches the JAR names the release job
+ # attaches).
+ - name: Build native classifier JARs (${{ matrix.arch }})
+ env:
+ IS_JAVA_8: true
+ run: |
+ mvn versions:set -DnewVersion="$EFFECTIVE_RELEASE_VERSION" -DgenerateBackupPoms=false --file "$MODULE/pom.xml"
+ for profile in ${{ matrix.profiles }}; do
+ echo "::group::Building $profile"
+ mvn package -P "$profile" -DmultiArch=false -DskipTests --file "$MODULE/pom.xml"
+ echo "::endgroup::"
+ done
+
+ # JARs to attach + .so files to assemble the fat main JAR.
+ - name: Upload native artifacts
+ uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
+ with:
+ name: ric-natives-${{ matrix.arch }}
+ if-no-files-found: error
+ path: |
+ ${{ env.MODULE }}/target/*-linux*.jar
+ ${{ env.MODULE }}/target/classes/jni/*.so
+
+ # Remove the user settings holding the CodeArtifact mirror token once the
+ # build is done. Ephemeral runner, so defence-in-depth, not load-bearing.
+ - name: Scrub Maven settings
+ if: always()
+ run: rm -f "$HOME/.m2/settings.xml"
+
+ # Assemble all native builds and publish.
+ release:
+ needs: build-natives
+ runs-on: codebuild-aws-lambda-java-libs-test-trigger-x86-${{ github.run_id }}-${{ github.run_attempt }}
+ environment: Release
+ timeout-minutes: 30
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+ with:
+ fetch-depth: 0 # full history for tagging/pushing
+
+ # Use the CodeBuild image's preinstalled Corretto 8. The image ships it at
+ # $JAVA_8_HOME but defaults JAVA_HOME to Java 25, so point JAVA_HOME/PATH at
+ # 8. Avoids actions/setup-java, which fetches from corretto.github.io +
+ # corretto.aws, both blocked by the runner egress lock. $JAVA_8_HOME
+ # resolves per-arch (x86_64/aarch64).
+ - name: Use the runner image's preinstalled Corretto 8
+ run: |
+ echo "JAVA_HOME=$JAVA_8_HOME" >> "$GITHUB_ENV"
+ echo "$JAVA_8_HOME/bin" >> "$GITHUB_PATH"
+ "$JAVA_8_HOME/bin/java" -version
+ mkdir -p "$HOME/.m2"
+ cat > "$HOME/.m2/toolchains.xml" <
+
+
+ jdk
+ 8
+ $JAVA_8_HOME
+
+
+ EOF
+
+ # Route all mvn resolution through the CodeArtifact mirror. Must precede
+ # resolve-release-version (which invokes `mvn help:evaluate`) and the OIDC
+ # step (which would shadow the runner-role creds this needs). Runs on every
+ # path, since dependency resolution happens on dry-runs too.
+ - name: Configure Maven CodeArtifact mirror
+ uses: ./.github/actions/configure-maven-mirror
+
+ - name: Resolve and validate release version
+ uses: ./.github/actions/resolve-release-version
+ with:
+ module: ${{ env.MODULE }}
+ release-version-override: ${{ env.RELEASE_VERSION_INPUT }}
+
+ # The native JNI build shells out to `docker build` against the ECR
+ # pull-through cache (see src/main/jni/Dockerfile.*). Authenticate first so
+ # the base-image pulls don't hit public.ecr.aws. Uses ambient runner creds.
+ - name: Log in to Amazon ECR (pull-through cache)
+ run: |
+ aws ecr get-login-password --region "$AWS_REGION" \
+ | docker login --username AWS --password-stdin "$ECR_REGISTRY"
+
+ - name: Resolve next development version and tag
+ run: |
+ # Next development version: use the override, or bump the patch.
+ if [[ -n "$DEVELOPMENT_VERSION_INPUT" ]]; then
+ if [[ "$DEVELOPMENT_VERSION_INPUT" != *-SNAPSHOT ]]; then
+ echo "::error::developmentVersion '$DEVELOPMENT_VERSION_INPUT' must end with -SNAPSHOT"
+ exit 1
+ fi
+ NEXT_DEV_VERSION="$DEVELOPMENT_VERSION_INPUT"
+ else
+ IFS='.' read -r MA MI PA <<< "$EFFECTIVE_RELEASE_VERSION"
+ NEXT_DEV_VERSION="${MA}.${MI}.$((PA + 1))-SNAPSHOT"
+ fi
+
+ echo "NEXT_DEV_VERSION=$NEXT_DEV_VERSION" >> "$GITHUB_ENV"
+ echo "TAG_NAME=${MODULE}-${EFFECTIVE_RELEASE_VERSION}" >> "$GITHUB_ENV"
+ echo "::notice::Releasing $MODULE $EFFECTIVE_RELEASE_VERSION (next dev $NEXT_DEV_VERSION)"
+
+ - name: Configure git user
+ run: |
+ git config user.name "github-actions[bot]"
+ git config user.email "github-actions[bot]@users.noreply.github.com"
+
+ # -DskipTests: only installed so the module compiles, not released here.
+ - name: Install intra-repo dependencies
+ run: |
+ for dep in aws-lambda-java-core aws-lambda-java-serialization; do
+ mvn install -DskipTests --file "$dep/pom.xml"
+ done
+
+ - name: Set release version
+ run: mvn versions:set -DnewVersion="$EFFECTIVE_RELEASE_VERSION" -DgenerateBackupPoms=false --file "$MODULE/pom.xml"
+
+ # Test gate before publish.
+ - name: Run tests
+ env:
+ IS_JAVA_8: true
+ run: mvn test -DargLineForReflectionTestOnly="" --file "$MODULE/pom.xml"
+
+ # JARs to attach + .so files for the fat main JAR.
+ - name: Download native artifacts
+ uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
+ with:
+ pattern: ric-natives-*
+ path: ric-natives
+
+ - name: Stage native artifacts
+ run: |
+ mkdir -p "$MODULE/target/classes/jni"
+ find ric-natives -name '*.jar' -exec cp {} "$MODULE/target/" \;
+ find ric-natives -name '*.so' -exec cp {} "$MODULE/target/classes/jni/" \;
+ echo "Staged native artifacts:"
+ ls -1 "$MODULE/target/"*-linux*.jar "$MODULE/target/classes/jni/"*.so
+
+ - name: Configure AWS credentials (OIDC)
+ if: ${{ github.event.inputs.skip_publish != 'true' }}
+ uses: ./.github/actions/configure-release-aws-credentials
+ with:
+ aws-region: ${{ env.AWS_REGION }}
+ role-to-assume: ${{ env.OIDC_ROLE_ARN }}
+ role-session-name: GitHubActionsRicMavenCentralRelease
+
+ # Fetch signing material and publish in a single step so the GPG passphrase
+ # and Sonatype token stay in this shell and never cross a $GITHUB_ENV
+ # boundary, where a later (possibly compromised) step could read them.
+ # -DmultiArch=false builds only the host .so; the aarch_64 .so is already
+ # staged, so the main JAR still bundles all four. build-helper attaches
+ # the staged classifier JARs. Gate already ran, so -DskipTests.
+ - name: Publish to Maven Central
+ if: ${{ github.event.inputs.skip_publish != 'true' }}
+ env:
+ IS_JAVA_8: true
+ run: |
+ # Scrub the settings.xml (contains the Sonatype token) and the keyring
+ # on exit, so no sensitive file is left on the runner even on failure.
+ MAVEN_SETTINGS="$RUNNER_TEMP/settings.xml"
+ export GNUPGHOME=$(mktemp -d)
+ trap 'rm -rf "$MAVEN_SETTINGS" "$GNUPGHOME"' EXIT
+
+ # --- Signing key + Sonatype token (shared secrets from LambdaMavenDeploy) ---
+ GPG_JSON=$(aws secretsmanager get-secret-value --secret-id lambda-runtimes/java/gpg-signing-key --query SecretString --output text)
+ CREDS_JSON=$(aws secretsmanager get-secret-value --secret-id lambda-runtimes/java/maven-sonatype-creds --query SecretString --output text)
+ GPG_PRIVATE_KEY=$(jq -r '.private' <<< "$GPG_JSON")
+ GPG_PASSPHRASE=$(jq -r '.passphrase' <<< "$GPG_JSON")
+ SONATYPE_USERNAME=$(jq -r '."maven-central-login"' <<< "$CREDS_JSON")
+ SONATYPE_PASSWORD=$(jq -r '."maven-central-password"' <<< "$CREDS_JSON")
+ echo "::add-mask::$GPG_PASSPHRASE"
+ echo "::add-mask::$SONATYPE_USERNAME"
+ echo "::add-mask::$SONATYPE_PASSWORD"
+
+ # Import the key with loopback pinentry so Maven can sign non-interactively.
+ chmod 700 "$GNUPGHOME"
+ echo "allow-loopback-pinentry" > "$GNUPGHOME/gpg-agent.conf"
+ echo "pinentry-mode loopback" > "$GNUPGHOME/gpg.conf"
+ gpgconf --kill gpg-agent || true
+ gpg --batch --import <<< "$GPG_PRIVATE_KEY"
+ GPG_KEYNAME=$(gpg --list-secret-keys --with-colons | awk -F: '/^sec:/ {print $5; exit}')
+
+ # Global settings holding only the Sonatype "central" server for upload.
+ # Passed to Maven as -gs (global) so it MERGES with the CodeArtifact
+ # mirror in ~/.m2/settings.xml (user) that the mirror step wrote: deps
+ # resolve through the mirror, upload goes to central, and the mirror
+ # token stays in that user file instead of being re-passed here.
+ {
+ echo ''
+ echo "central"
+ echo "${SONATYPE_USERNAME}"
+ echo "${SONATYPE_PASSWORD}"
+ echo ''
+ } > "$MAVEN_SETTINGS"
+
+ # --- Publish --- (-gs: merge Sonatype creds with the ~/.m2 mirror)
+ mvn deploy -Prelease -DskipTests -DmultiArch=false \
+ -gs "$MAVEN_SETTINGS" \
+ -Dgpg.keyname="$GPG_KEYNAME" -Dgpg.passphrase="$GPG_PASSPHRASE" \
+ --file "$MODULE/pom.xml"
+
+ - name: Tag and push (only after publish succeeds)
+ if: ${{ github.event.inputs.skip_publish != 'true' }}
+ run: |
+ git commit -am "chore(ric): release ${EFFECTIVE_RELEASE_VERSION}"
+ git tag "$TAG_NAME"
+ mvn versions:set -DnewVersion="$NEXT_DEV_VERSION" -DgenerateBackupPoms=false --file "$MODULE/pom.xml"
+ git commit -am "chore(ric): prepare next development ${NEXT_DEV_VERSION}"
+ git push --atomic origin "HEAD:${GITHUB_REF_NAME}" "refs/tags/${TAG_NAME}"
+
+ # Dry-run: validate assembly, no publish/push.
+ - name: Dry-run assemble (no publish)
+ if: ${{ github.event.inputs.skip_publish == 'true' }}
+ env:
+ IS_JAVA_8: true
+ run: mvn package -DskipTests -DmultiArch=false --file "$MODULE/pom.xml"
+
+ # Nothing was pushed, so this only cleans the runner.
+ - name: Roll back local tag on failure
+ if: ${{ failure() && github.event.inputs.skip_publish != 'true' }}
+ run: |
+ git tag -d "$TAG_NAME" 2>/dev/null || true
+ echo "::warning::Release failed. The remote was not modified; safe to retry."
+
+ - name: Summary
+ if: ${{ github.event.inputs.skip_publish != 'true' }}
+ run: |
+ echo "## Release Summary" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "| Field | Value |" >> $GITHUB_STEP_SUMMARY
+ echo "|-------|-------|" >> $GITHUB_STEP_SUMMARY
+ echo "| Module | \`$MODULE\` |" >> $GITHUB_STEP_SUMMARY
+ echo "| Version | \`$EFFECTIVE_RELEASE_VERSION\` |" >> $GITHUB_STEP_SUMMARY
+ echo "| Tag | \`$TAG_NAME\` |" >> $GITHUB_STEP_SUMMARY
+ echo "| Artifacts | main JAR + linux/linux_musl x x86_64/aarch_64 classifier JARs |" >> $GITHUB_STEP_SUMMARY
+ echo "| Built natively | x86_64 and aarch_64 on CodeBuild runners (no QEMU) |" >> $GITHUB_STEP_SUMMARY
+ echo "| Maven Central | [com.amazonaws:$MODULE:$EFFECTIVE_RELEASE_VERSION](https://central.sonatype.com/artifact/com.amazonaws/$MODULE/$EFFECTIVE_RELEASE_VERSION) |" >> $GITHUB_STEP_SUMMARY
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 000000000..7ff834e56
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,297 @@
+name: Release to Maven Central
+
+# Builds, tests, and publishes a module to Maven Central in one environment.
+
+on:
+ workflow_dispatch:
+ inputs:
+ module:
+ description: 'Module to release (directory name, e.g. aws-lambda-java-log4j2)'
+ required: true
+ type: choice
+ # aws-lambda-java-runtime-interface-client is intentionally excluded: it
+ # ships a cross-compiled JNI native library and has its own dedicated
+ # pipeline, .github/workflows/release-runtime-interface-client.yml.
+ options:
+ - aws-lambda-java-core
+ - aws-lambda-java-events
+ - aws-lambda-java-events-sdk-transformer
+ - aws-lambda-java-log4j2
+ - aws-lambda-java-serialization
+ - aws-lambda-java-tests
+ releaseVersion:
+ description: 'Release version override (optional; defaults to the POM version without -SNAPSHOT)'
+ required: false
+ type: string
+ developmentVersion:
+ description: 'Next development version override (optional, must end with -SNAPSHOT)'
+ required: false
+ type: string
+ skip_publish:
+ description: 'Skip publish (dry-run validation)'
+ required: false
+ type: boolean
+ default: false
+
+permissions:
+ contents: write
+ id-token: write
+
+# Serialize all releases repo-wide to avoid concurrent pushes racing on the
+# default branch. Never cancel in-flight: it could leave a half-published state.
+concurrency:
+ group: release
+ cancel-in-progress: false
+
+env:
+ MODULE: ${{ github.event.inputs.module }}
+ RELEASE_VERSION_INPUT: ${{ github.event.inputs.releaseVersion }}
+ DEVELOPMENT_VERSION_INPUT: ${{ github.event.inputs.developmentVersion }}
+ # Batch mode + no transfer-progress spam for every Maven call (Maven 3.9+).
+ MAVEN_ARGS: "-B --no-transfer-progress"
+ AWS_REGION: ${{ vars.AWS_REGION_MAVEN_RELEASE }}
+ OIDC_ROLE_ARN: ${{ secrets.AWS_ROLE_MAVEN_RELEASE }}
+
+jobs:
+ # Pre-publish gate for log4j2: deploy a real Lambda, invoke it,
+ # and assert the log line reaches CloudWatch. Binds the end-to-end validation
+ # to the publish event itself. Skipped for every other module, which are
+ # covered by their own tests (or the cross-module gate below).
+ integration-test:
+ if: ${{ github.event.inputs.module == 'aws-lambda-java-log4j2' }}
+ uses: ./.github/workflows/run-integration-test.yml
+ secrets: inherit
+
+ release:
+ needs: [integration-test]
+ # Publish when the gate passed, or when it was skipped for a non-log4j2
+ # module. A failed or cancelled gate blocks the release.
+ if: ${{ always() && (needs.integration-test.result == 'success' || needs.integration-test.result == 'skipped') }}
+ runs-on: codebuild-aws-lambda-java-libs-test-trigger-x86-${{ github.run_id }}-${{ github.run_attempt }}
+ environment: Release
+ timeout-minutes: 30
+
+ steps:
+ # Manual (workflow_dispatch) releases must only run from main, never from
+ # an arbitrary branch that could carry unreviewed release logic.
+ - name: Verify release branch
+ run: |
+ if [[ "$GITHUB_REF_NAME" != "main" ]]; then
+ echo "::error::Releases must run from the main branch, got '$GITHUB_REF_NAME'"
+ exit 1
+ fi
+
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+ with:
+ fetch-depth: 0 # full history for tagging/pushing
+
+ # Use the CodeBuild image's preinstalled Corretto 8. The image ships it at
+ # $JAVA_8_HOME but defaults JAVA_HOME to Java 25, so point JAVA_HOME/PATH at
+ # 8. Avoids actions/setup-java, which fetches from corretto.github.io +
+ # corretto.aws, both blocked by the runner egress lock. $JAVA_8_HOME
+ # resolves per-arch (x86_64/aarch64).
+ - name: Use the runner image's preinstalled Corretto 8
+ run: |
+ echo "JAVA_HOME=$JAVA_8_HOME" >> "$GITHUB_ENV"
+ echo "$JAVA_8_HOME/bin" >> "$GITHUB_PATH"
+ "$JAVA_8_HOME/bin/java" -version
+ mkdir -p "$HOME/.m2"
+ cat > "$HOME/.m2/toolchains.xml" <
+
+
+ jdk
+ 8
+ $JAVA_8_HOME
+
+
+ EOF
+
+ # Route all mvn resolution through the CodeArtifact mirror. Runs before the
+ # OIDC step (which would shadow the runner-role creds this needs) and on
+ # every path, since dependency resolution happens on dry-runs too.
+ - name: Configure Maven CodeArtifact mirror
+ uses: ./.github/actions/configure-maven-mirror
+
+ - name: Resolve and validate release version
+ uses: ./.github/actions/resolve-release-version
+ with:
+ module: ${{ env.MODULE }}
+ release-version-override: ${{ env.RELEASE_VERSION_INPUT }}
+ validate-module-dir: "true"
+
+ - name: Validate development version override
+ run: |
+ if [[ -n "$DEVELOPMENT_VERSION_INPUT" && "$DEVELOPMENT_VERSION_INPUT" != *-SNAPSHOT ]]; then
+ echo "::error::developmentVersion '$DEVELOPMENT_VERSION_INPUT' must end with -SNAPSHOT"
+ exit 1
+ fi
+ echo "::notice::Releasing $MODULE $EFFECTIVE_RELEASE_VERSION (POM currently $CURRENT_VERSION)"
+
+ - name: Configure git user
+ run: |
+ git config user.name "github-actions[bot]"
+ git config user.email "github-actions[bot]@users.noreply.github.com"
+
+ - name: Install intra-repo dependencies
+ run: |
+ # Installed so the target compiles. -DskipTests: not released here,
+ # only the target module gets the full verify gate below.
+ declare -A DEPS
+ DEPS[aws-lambda-java-core]=""
+ DEPS[aws-lambda-java-events]=""
+ DEPS[aws-lambda-java-serialization]=""
+ DEPS[aws-lambda-java-log4j2]="aws-lambda-java-core"
+ DEPS[aws-lambda-java-events-sdk-transformer]="aws-lambda-java-events"
+ DEPS[aws-lambda-java-tests]="aws-lambda-java-core aws-lambda-java-serialization aws-lambda-java-events"
+
+ DEP_LIST="${DEPS[$MODULE]}"
+ if [[ -n "$DEP_LIST" ]]; then
+ for dep in $DEP_LIST; do
+ echo "::group::Installing dependency: $dep"
+ mvn install -DskipTests --file "$dep/pom.xml"
+ echo "::endgroup::"
+ done
+ else
+ echo "::notice::No intra-repo dependencies for $MODULE"
+ fi
+
+ - name: Run tests
+ run: mvn verify --file "$MODULE/pom.xml"
+
+ # Cross-module gate: serialization has no tests in its own build, so the
+ # `mvn verify` above exercises nothing. Its behavioral coverage lives in
+ # aws-lambda-java-tests, which depends on serialization via a version
+ # property. Install the just-built serialization and run that suite
+ # against it, so we never publish serialization the suite hasn't exercised.
+ - name: Run cross-module test gate
+ run: |
+ case "$MODULE" in
+ aws-lambda-java-serialization)
+ MOD_VER=$(mvn -q -DforceStdout help:evaluate -Dexpression=project.version --file "$MODULE/pom.xml")
+ MOD_VER="${MOD_VER//[$'\r\n']/}"
+ echo "::group::Installing $MODULE $MOD_VER for the gate"
+ mvn install -DskipTests --file "$MODULE/pom.xml"
+ echo "::endgroup::"
+ echo "::notice::Gating $MODULE on aws-lambda-java-tests (aws-lambda-java-serialization.version=$MOD_VER)"
+ mvn verify -Daws-lambda-java-serialization.version="$MOD_VER" --file aws-lambda-java-tests/pom.xml
+ ;;
+ *)
+ echo "::notice::No cross-module test gate for $MODULE"
+ ;;
+ esac
+
+ - name: Configure AWS credentials (OIDC)
+ if: ${{ github.event.inputs.skip_publish != 'true' }}
+ uses: ./.github/actions/configure-release-aws-credentials
+ with:
+ aws-region: ${{ env.AWS_REGION }}
+ role-to-assume: ${{ env.OIDC_ROLE_ARN }}
+ role-session-name: GitHubActionsMavenCentralRelease
+
+ # Fetch signing material and publish in a single step so the GPG passphrase
+ # and Sonatype token stay in this shell and never cross a $GITHUB_ENV
+ # boundary, where a later (possibly compromised) step could read them.
+ # prepare/perform aren't atomic: prepare locally, publish, push only after.
+ - name: Release (prepare locally, publish, then push)
+ if: ${{ github.event.inputs.skip_publish != 'true' }}
+ run: |
+ # Scrub the settings.xml (contains the Sonatype token) and the keyring
+ # on exit, so no sensitive file is left on the runner even on failure.
+ MAVEN_SETTINGS="$RUNNER_TEMP/settings.xml"
+ export GNUPGHOME=$(mktemp -d)
+ trap 'rm -rf "$MAVEN_SETTINGS" "$GNUPGHOME"' EXIT
+
+ # --- Signing key + Sonatype token (shared secrets from LambdaMavenDeploy) ---
+ GPG_JSON=$(aws secretsmanager get-secret-value --secret-id lambda-runtimes/java/gpg-signing-key --query SecretString --output text)
+ CREDS_JSON=$(aws secretsmanager get-secret-value --secret-id lambda-runtimes/java/maven-sonatype-creds --query SecretString --output text)
+ GPG_PRIVATE_KEY=$(jq -r '.private' <<< "$GPG_JSON")
+ GPG_PASSPHRASE=$(jq -r '.passphrase' <<< "$GPG_JSON")
+ SONATYPE_USERNAME=$(jq -r '."maven-central-login"' <<< "$CREDS_JSON")
+ SONATYPE_PASSWORD=$(jq -r '."maven-central-password"' <<< "$CREDS_JSON")
+ echo "::add-mask::$GPG_PASSPHRASE"
+ echo "::add-mask::$SONATYPE_USERNAME"
+ echo "::add-mask::$SONATYPE_PASSWORD"
+
+ # Import the key with loopback pinentry so Maven can sign non-interactively.
+ chmod 700 "$GNUPGHOME"
+ echo "allow-loopback-pinentry" > "$GNUPGHOME/gpg-agent.conf"
+ echo "pinentry-mode loopback" > "$GNUPGHOME/gpg.conf"
+ gpgconf --kill gpg-agent || true
+ gpg --batch --import <<< "$GPG_PRIVATE_KEY"
+ GPG_KEYNAME=$(gpg --list-secret-keys --with-colons | awk -F: '/^sec:/ {print $5; exit}')
+
+ # Global settings holding only the Sonatype "central" server for upload.
+ # Passed to Maven as -gs (global) so it MERGES with the CodeArtifact
+ # mirror in ~/.m2/settings.xml (user) that the mirror step wrote: deps
+ # resolve through the mirror, upload goes to central, and the mirror
+ # token stays in that user file instead of being re-passed here.
+ {
+ echo ''
+ echo "central"
+ echo "${SONATYPE_USERNAME}"
+ echo "${SONATYPE_PASSWORD}"
+ echo ''
+ } > "$MAVEN_SETTINGS"
+
+ # --- Release: build args as an array so each value is a single,
+ # properly quoted argument (no word-splitting of untrusted input). ---
+ RELEASE_ARGS=(-DreleaseVersion="$EFFECTIVE_RELEASE_VERSION")
+ if [[ -n "$DEVELOPMENT_VERSION_INPUT" ]]; then
+ RELEASE_ARGS+=(-DdevelopmentVersion="$DEVELOPMENT_VERSION_INPUT")
+ fi
+
+ # Prepare locally (no push): release commits + tag.
+ mvn release:prepare -DpushChanges=false "${RELEASE_ARGS[@]}" --file "$MODULE/pom.xml"
+
+ # perform forks a fresh build. Pass the Sonatype creds as GLOBAL
+ # settings (-gs) so the fork still auto-reads ~/.m2/settings.xml (the
+ # mirror) and merges the two.
+ mvn release:perform -DlocalCheckout=true \
+ -Darguments="-gs $MAVEN_SETTINGS -Prelease -Dgpg.keyname=$GPG_KEYNAME -Dgpg.passphrase=$GPG_PASSPHRASE" \
+ --file "$MODULE/pom.xml"
+
+ # Push commits + tag atomically, only after publish succeeded.
+ git push --atomic origin \
+ "HEAD:${GITHUB_REF_NAME}" \
+ "refs/tags/${MODULE}-${EFFECTIVE_RELEASE_VERSION}"
+
+ - name: Dry-run release (prepare only, no publish)
+ if: ${{ github.event.inputs.skip_publish == 'true' }}
+ run: |
+ RELEASE_ARGS=(-DreleaseVersion="$EFFECTIVE_RELEASE_VERSION")
+ if [[ -n "$DEVELOPMENT_VERSION_INPUT" ]]; then
+ RELEASE_ARGS+=(-DdevelopmentVersion="$DEVELOPMENT_VERSION_INPUT")
+ fi
+ mvn release:prepare -DdryRun=true "${RELEASE_ARGS[@]}" --file "$MODULE/pom.xml"
+ mvn release:clean --file "$MODULE/pom.xml" || true
+
+ # Nothing was pushed, so this only cleans the runner for a retry.
+ - name: Roll back release on failure
+ if: ${{ failure() && github.event.inputs.skip_publish != 'true' }}
+ run: |
+ mvn release:rollback --file "$MODULE/pom.xml" || true
+ mvn release:clean --file "$MODULE/pom.xml" || true
+ git tag -d "${MODULE}-${EFFECTIVE_RELEASE_VERSION}" 2>/dev/null || true
+ echo "::warning::Release failed before publish completed. The remote was not modified; the runner state has been rolled back. Safe to retry."
+
+ - name: Summary
+ if: ${{ github.event.inputs.skip_publish != 'true' }}
+ run: |
+ TAG_NAME="${MODULE}-${EFFECTIVE_RELEASE_VERSION}"
+ echo "## Release Summary" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "| Field | Value |" >> $GITHUB_STEP_SUMMARY
+ echo "|-------|-------|" >> $GITHUB_STEP_SUMMARY
+ echo "| Module | \`$MODULE\` |" >> $GITHUB_STEP_SUMMARY
+ echo "| Version | \`$EFFECTIVE_RELEASE_VERSION\` |" >> $GITHUB_STEP_SUMMARY
+ echo "| Tag | \`$TAG_NAME\` |" >> $GITHUB_STEP_SUMMARY
+ echo "| Maven Central | [com.amazonaws:$MODULE:$EFFECTIVE_RELEASE_VERSION](https://central.sonatype.com/artifact/com.amazonaws/$MODULE/$EFFECTIVE_RELEASE_VERSION) |" >> $GITHUB_STEP_SUMMARY
+
+ # Symmetry with the publish step's in-shell scrub: remove the user settings
+ # holding the CodeArtifact mirror token. Last step, after the mvn-using
+ # rollback path, so nothing still needs it. The runner is ephemeral, so
+ # this is defence-in-depth, not load-bearing.
+ - name: Scrub Maven settings
+ if: always()
+ run: rm -f "$HOME/.m2/settings.xml"
diff --git a/.github/workflows/repo-sync.yml b/.github/workflows/repo-sync.yml
index 25f05029a..4934754d8 100644
--- a/.github/workflows/repo-sync.yml
+++ b/.github/workflows/repo-sync.yml
@@ -9,6 +9,10 @@ on:
- '.github/workflows/repo-sync.yml'
workflow_dispatch:
+permissions:
+ contents: write
+ pull-requests: write
+
jobs:
repo-sync:
name: Repo Sync
@@ -16,9 +20,9 @@ jobs:
env:
IS_CONFIGURED: ${{ secrets.SOURCE_REPO != '' }}
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
if: ${{ env.IS_CONFIGURED == 'true' }}
- - uses: repo-sync/github-sync@v2
+ - uses: repo-sync/github-sync@3832fe8e2be32372e1b3970bbae8e7079edeec88 # v2.3.0
name: Sync repo to branch
if: ${{ env.IS_CONFIGURED == 'true' }}
with:
@@ -26,7 +30,7 @@ jobs:
source_branch: main
destination_branch: ${{ secrets.INTERMEDIATE_BRANCH }}
github_token: ${{ secrets.GITHUB_TOKEN }}
- - uses: repo-sync/pull-request@v2
+ - uses: repo-sync/pull-request@7e79a9f5dc3ad0ce53138f01df2fad14a04831c5 # v2.12.1
name: Create pull request
if: ${{ env.IS_CONFIGURED == 'true' }}
with:
diff --git a/.github/workflows/run-integration-test.yml b/.github/workflows/run-integration-test.yml
new file mode 100644
index 000000000..35456a7c5
--- /dev/null
+++ b/.github/workflows/run-integration-test.yml
@@ -0,0 +1,139 @@
+# this workflow deploys a Lambda function that uses aws-lambda-java-log4j2,
+# invokes it, and verifies that logs arrive in CloudWatch.
+
+name: Run integration tests
+
+permissions:
+ id-token: write
+ contents: read
+
+on:
+ workflow_dispatch:
+ workflow_call:
+ push:
+ branches: [ main ]
+ paths:
+ - 'aws-lambda-java-log4j2/**'
+ - 'aws-lambda-java-core/**'
+ - 'lambda-integration-tests/**'
+
+jobs:
+ load-matrix:
+ runs-on: ubuntu-latest
+ outputs:
+ matrix: ${{ steps.set.outputs.matrix }}
+ steps:
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+
+ - name: Load test matrix
+ id: set
+ run: |
+ MATRIX=$(jq -c '.' .github/test-matrix.json)
+ echo "matrix=${MATRIX}" >> "$GITHUB_OUTPUT"
+
+ run-integration-tests:
+ needs: load-matrix
+ # Only run on the main repo, not forks
+ if: ${{ github.repository_owner == 'aws' }}
+ runs-on: ${{ matrix.arch.runner }}
+ strategy:
+ fail-fast: false
+ matrix: ${{ fromJson(needs.load-matrix.outputs.matrix) }}
+ name: "integration-test (${{ matrix.arch.label }})"
+ concurrency:
+ group: integration-test-${{ matrix.arch.label }}
+ cancel-in-progress: false
+ steps:
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+
+ - name: Set up JDK
+ uses: actions/setup-java@1bcf9fb12cf4aa7d266a90ae39939e61372fe520 # v5.4.0
+ with:
+ java-version: |
+ 8
+ 21
+ distribution: corretto
+ cache: maven
+
+ - name: Install SAM CLI
+ uses: aws-actions/setup-sam@f84ec7d548307efafe33230528756de3c5841a17 # v2
+ with:
+ use-installer: true
+
+ - name: Configure AWS credentials
+ uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7 # v6.0.0
+ with:
+ role-to-assume: ${{ secrets.AWS_ROLE_LOG4J2_INTEG_TEST }}
+ role-session-name: GitHubActionsLog4j2IntegTest
+ aws-region: ${{ secrets.AWS_REGION_LOG4J2_INTEG_TEST }}
+
+ - name: Install core with Maven
+ run: |
+ export JAVA_HOME=$JAVA_HOME_8_${{ matrix.arch.java_suffix }}
+ mvn -B install --file aws-lambda-java-core/pom.xml
+
+ - name: Install log4j2 with Maven
+ run: |
+ export JAVA_HOME=$JAVA_HOME_8_${{ matrix.arch.java_suffix }}
+ mvn -B install --file aws-lambda-java-log4j2/pom.xml
+
+ - name: Build SAM stack
+ run: |
+ export JAVA_HOME=$JAVA_HOME_21_${{ matrix.arch.java_suffix }}
+ cd lambda-integration-tests && sam build
+
+ - name: Validate SAM stack
+ run: cd lambda-integration-tests && sam validate --lint
+
+ - name: Deploy stack
+ id: deploy_stack
+ env:
+ AWS_REGION: ${{ secrets.AWS_REGION_LOG4J2_INTEG_TEST }}
+ run: |
+ cd lambda-integration-tests
+ stackName="aws-lambda-java-log4j2-integ-test-${{ matrix.arch.label }}-$GITHUB_RUN_ID"
+ echo "STACK_NAME=$stackName" >> "$GITHUB_OUTPUT"
+ echo "Stack name = $stackName"
+ sam deploy \
+ --stack-name "${stackName}" \
+ --parameter-overrides "ParameterKey=LambdaRole,ParameterValue=${{ secrets.AWS_LAMBDA_ROLE_LOG4J2_INTEG_TEST }} ParameterKey=Architecture,ParameterValue=${{ matrix.arch.sam_arch }}" \
+ --no-confirm-changeset \
+ --no-progressbar \
+ --s3-bucket "${{ secrets.S3_BUCKET_LOG4J2_INTEG_TEST }}" \
+ --capabilities CAPABILITY_IAM \
+ 2>&1 | tee /tmp/sam-deploy.log | tail -n 20
+
+ # Verify stack is in a healthy state
+ STACK_STATUS=$(aws cloudformation describe-stacks \
+ --stack-name "${stackName}" \
+ --region "${AWS_REGION}" \
+ --query 'Stacks[0].StackStatus' \
+ --output text 2>&1)
+ echo "Stack status: $STACK_STATUS"
+ if [ "$STACK_STATUS" != "CREATE_COMPLETE" ] && [ "$STACK_STATUS" != "UPDATE_COMPLETE" ]; then
+ echo "FAIL: Stack is not in a healthy state (status: $STACK_STATUS)"
+ aws cloudformation describe-stack-events \
+ --stack-name "${stackName}" \
+ --region "${AWS_REGION}" \
+ --query 'StackEvents[?ResourceStatus==`CREATE_FAILED` || ResourceStatus==`UPDATE_FAILED`].[LogicalResourceId,ResourceStatusReason]' \
+ --output table 2>&1 || true
+ exit 1
+ fi
+
+ LOG4J2_TEST_FUNCTION=$(sam list stack-outputs --stack-name "${stackName}" --output json | jq -r '.[] | select(.OutputKey=="Log4j2TestFunction") | .OutputValue')
+ echo "LOG4J2_TEST_FUNCTION=$LOG4J2_TEST_FUNCTION" >> "$GITHUB_OUTPUT"
+ echo "Function name: $LOG4J2_TEST_FUNCTION"
+
+ - name: Run integration test
+ env:
+ LOG4J2_TEST_FUNCTION: ${{ steps.deploy_stack.outputs.LOG4J2_TEST_FUNCTION }}
+ AWS_REGION: ${{ secrets.AWS_REGION_LOG4J2_INTEG_TEST }}
+ run: ./lambda-integration-tests/run-tests.sh
+
+ - name: Cleanup
+ if: always() && steps.deploy_stack.outputs.STACK_NAME
+ env:
+ AWS_REGION: ${{ secrets.AWS_REGION_LOG4J2_INTEG_TEST }}
+ STACK_NAME: ${{ steps.deploy_stack.outputs.STACK_NAME }}
+ run: |
+ sam delete --stack-name "${STACK_NAME}" --no-prompts --region "${AWS_REGION}"
diff --git a/.github/workflows/runtime-interface-client_merge_to_main.yml b/.github/workflows/runtime-interface-client_merge_to_main.yml
index e07b191e1..d0d479111 100644
--- a/.github/workflows/runtime-interface-client_merge_to_main.yml
+++ b/.github/workflows/runtime-interface-client_merge_to_main.yml
@@ -11,12 +11,12 @@
name: Publish artifact for aws-lambda-java-runtime-interface-client
on:
+ workflow_dispatch:
push:
branches: [ main ]
paths:
- 'aws-lambda-java-runtime-interface-client/**'
- '.github/workflows/runtime-interface-client_*.yml'
- workflow_dispatch:
jobs:
@@ -28,25 +28,30 @@ jobs:
contents: read
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Set up JDK 1.8
- uses: actions/setup-java@v4
+ uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5
with:
java-version: 8
distribution: corretto
+ cache: maven
- name: Set up QEMU
- uses: docker/setup-qemu-action@v3
+ uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3
- name: Set up Docker Buildx
- uses: docker/setup-buildx-action@v3
+ uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
with:
install: true
- name: Available buildx platforms
run: echo ${{ steps.buildx.outputs.platforms }}
+ - name: Build and install serialization dependency locally
+ working-directory: ./aws-lambda-java-serialization
+ run: mvn clean install
+
- name: Test Runtime Interface Client xplatform build - Run 'build' target
working-directory: ./aws-lambda-java-runtime-interface-client
run: make build
@@ -57,7 +62,7 @@ jobs:
if: env.ENABLE_SNAPSHOT != null
env:
ENABLE_SNAPSHOT: ${{ secrets.ENABLE_SNAPSHOT }}
- uses: aws-actions/configure-aws-credentials@v4
+ uses: aws-actions/configure-aws-credentials@7474bc4690e29a8392af63c5b98e7449536d5c3a # v4
with:
aws-region: ${{ secrets.AWS_REGION }}
role-to-assume: ${{ secrets.AWS_ROLE }}
@@ -86,6 +91,6 @@ jobs:
- name: Upload coverage to Codecov
if: env.CODECOV_TOKEN != null
- uses: codecov/codecov-action@v5
+ uses: codecov/codecov-action@75cd11691c0faa626561e295848008c8a7dddffe # v5
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
diff --git a/.github/workflows/runtime-interface-client_pr.yml b/.github/workflows/runtime-interface-client_pr.yml
index 33c6df50b..bc9e3f3eb 100644
--- a/.github/workflows/runtime-interface-client_pr.yml
+++ b/.github/workflows/runtime-interface-client_pr.yml
@@ -1,70 +1,186 @@
-# This workflow will be triggered if there will be changes to
-# aws-lambda-java-runtime-interface-client package and it builds the package.
+# This workflow will be triggered if there will be changes to
+# aws-lambda-java-runtime-interface-client package or its dependencies (core, serialization),
+# and it builds the package.
name: PR to runtime-interface-client
on:
+ workflow_dispatch:
pull_request:
branches: [ '*' ]
paths:
- 'aws-lambda-java-runtime-interface-client/**'
+ - 'aws-lambda-java-core/**'
+ - 'aws-lambda-java-serialization/**'
- '.github/workflows/runtime-interface-client_*.yml'
+permissions:
+ contents: read
+
jobs:
- smoke-test:
- runs-on: ubuntu-latest
+ smoke-test-arch:
+ strategy:
+ fail-fast: true
+ matrix:
+ include:
+ - arch: x86_64
+ runner: ubuntu-latest
+ - arch: aarch64
+ runner: ubuntu-24.04-arm
+ runs-on: ${{ matrix.runner }}
+ name: "smoke-test (${{ matrix.arch }})"
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Set up JDK 1.8
- uses: actions/setup-java@v4
+ uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5
with:
java-version: 8
distribution: corretto
+ cache: maven
+
+ - name: Build and install core dependency locally
+ working-directory: ./aws-lambda-java-core
+ run: mvn clean install
- - name: Runtime Interface Client smoke tests - Run 'pr' target
+ - name: Build and install serialization dependency locally
+ working-directory: ./aws-lambda-java-serialization
+ run: mvn clean install
+
+ - name: Runtime Interface Client smoke tests - Run 'pr-${{ matrix.arch }}' target
working-directory: ./aws-lambda-java-runtime-interface-client
- run: make pr
+ run: make pr-${{ matrix.arch }}
env:
IS_JAVA_8: true
-
- build:
- runs-on: ubuntu-latest
+
+ build-arch:
+ strategy:
+ fail-fast: true
+ matrix:
+ include:
+ - arch: x86_64
+ runner: ubuntu-latest
+ - arch: aarch64
+ runner: ubuntu-24.04-arm
+ runs-on: ${{ matrix.runner }}
+ name: "build (${{ matrix.arch }})"
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Set up JDK 1.8
- uses: actions/setup-java@v4
+ uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5
with:
java-version: 8
distribution: corretto
-
- - name: Set up QEMU
- uses: docker/setup-qemu-action@v3
+ cache: maven
- name: Set up Docker Buildx
- uses: docker/setup-buildx-action@v3
+ uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
with:
install: true
- - name: Available buildx platforms
- run: echo ${{ steps.buildx.outputs.platforms }}
+ - name: Build and install core dependency locally
+ working-directory: ./aws-lambda-java-core
+ run: mvn clean install
+
+ - name: Build and install serialization dependency locally
+ working-directory: ./aws-lambda-java-serialization
+ run: mvn clean install
- - name: Test Runtime Interface Client xplatform build - Run 'build' target
+ - name: Test Runtime Interface Client build - Run 'build-${{ matrix.arch }}' target
working-directory: ./aws-lambda-java-runtime-interface-client
- run: make build
+ run: make build-${{ matrix.arch }}
env:
IS_JAVA_8: true
- name: Save the built jar
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
- name: aws-lambda-java-runtime-interface-client
+ name: aws-lambda-java-runtime-interface-client-${{ matrix.arch }}
path: ./aws-lambda-java-runtime-interface-client/target/aws-lambda-java-runtime-interface-client-*.jar
- name: Upload coverage to Codecov
if: env.CODECOV_TOKEN != null
- uses: codecov/codecov-action@v5
+ uses: codecov/codecov-action@75cd11691c0faa626561e295848008c8a7dddffe # v5
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
+
+ integration-test-matrix:
+ runs-on: ${{ matrix.arch.runner }}
+ strategy:
+ # Run every OS/arch combination to completion so one failure doesn't mask the others.
+ fail-fast: false
+ matrix:
+ buildspec:
+ - buildspec.os.alpine.yml
+ - buildspec.os.amazoncorretto.yml
+ - buildspec.os.amazonlinux.1.yml
+ - buildspec.os.amazonlinux.2.yml
+ - buildspec.os.debian.yml
+ - buildspec.os.ubuntu.yml
+ arch:
+ - label: x64
+ runner: ubuntu-latest
+ platform: linux/amd64
+ - label: arm64
+ runner: ubuntu-24.04-arm
+ platform: linux/arm64/v8
+ exclude:
+ # Amazon Linux 1 was never published for ARM64 (x86_64 only), so
+ # public.ecr.aws/amazonlinux/amazonlinux:1 has no arm64 manifest.
+ - buildspec: buildspec.os.amazonlinux.1.yml
+ arch:
+ label: arm64
+ runner: ubuntu-24.04-arm
+ platform: linux/arm64/v8
+ name: "integration-test (${{ matrix.buildspec }} / ${{ matrix.arch.label }})"
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
+ with:
+ install: true
+
+ - name: Run OS integration test - 'test-integ' target
+ working-directory: ./aws-lambda-java-runtime-interface-client
+ run: make test-integ BUILDSPEC=test/integration/codebuild/${{ matrix.buildspec }}
+ env:
+ PLATFORM_FILTER: ${{ matrix.arch.platform }}
+
+ integration-test:
+ needs: integration-test-matrix
+ if: always()
+ runs-on: ubuntu-latest
+ steps:
+ - name: Check integration-test results
+ run: |
+ if [ "${{ needs.integration-test-matrix.result }}" != "success" ]; then
+ echo "Integration tests failed on one or more OS/arch combinations"
+ exit 1
+ fi
+
+ smoke-test:
+ needs: smoke-test-arch
+ if: always()
+ runs-on: ubuntu-latest
+ steps:
+ - name: Check smoke-test results
+ run: |
+ if [ "${{ needs.smoke-test-arch.result }}" != "success" ]; then
+ echo "Smoke tests failed on one or more architectures"
+ exit 1
+ fi
+
+ build:
+ needs: build-arch
+ if: always()
+ runs-on: ubuntu-latest
+ steps:
+ - name: Check build results
+ run: |
+ if [ "${{ needs.build-arch.result }}" != "success" ]; then
+ echo "Build failed on one or more architectures"
+ exit 1
+ fi
diff --git a/.github/workflows/samples.yml b/.github/workflows/samples.yml
index 8346b7c2f..68e25827d 100644
--- a/.github/workflows/samples.yml
+++ b/.github/workflows/samples.yml
@@ -1,37 +1,46 @@
-# This workflow will be triggered if there will be changes to aws-lambda-java-core
-# package and it builds the package and the packages that depend on it.
+# This workflow will be triggered if there will be changes to samples
+# or their dependencies (events, serialization, tests).
name: Java CI samples
on:
+ workflow_dispatch:
push:
branches: [ main ]
paths:
- 'samples/**'
+ - 'aws-lambda-java-events/**'
+ - 'aws-lambda-java-serialization/**'
+ - 'aws-lambda-java-tests/**'
pull_request:
branches: [ '*' ]
paths:
- 'samples/**'
+ - 'aws-lambda-java-events/**'
+ - 'aws-lambda-java-serialization/**'
+ - 'aws-lambda-java-tests/**'
- '.github/workflows/samples.yml'
+permissions:
+ contents: read
+
jobs:
build:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
- name: Set up JDK 1.8
- uses: actions/setup-java@v4
+ uses: actions/setup-java@v5
with:
java-version: 8
distribution: corretto
+ cache: maven
- # Install events module
+ # Install dependencies
- name: Install events with Maven
run: mvn -B install --file aws-lambda-java-events/pom.xml
- # Install serialization module
- name: Install serialization with Maven
run: mvn -B install --file aws-lambda-java-serialization/pom.xml
- # Install tests module
- name: Install tests with Maven
run: mvn -B install --file aws-lambda-java-tests/pom.xml
@@ -42,15 +51,16 @@ jobs:
custom-serialization:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
# Set up both Java 8 and 21
- name: Set up Java 8 and 21
- uses: actions/setup-java@v4
+ uses: actions/setup-java@v5
with:
java-version: |
8
21
distribution: corretto
+ cache: maven
# Install events module using Java 8
- name: Install events with Maven
@@ -63,7 +73,7 @@ jobs:
# Build custom-serialization samples
- name: install sam
- uses: aws-actions/setup-sam@v2
+ uses: aws-actions/setup-sam@d78e1a4a9656d3b223e59b80676a797f20093133 # v2
- name: test fastJson
run: cd samples/custom-serialization/fastJson && sam build && sam local invoke -e events/event.json | grep 200
- name: test gson
diff --git a/.gitignore b/.gitignore
index 9f99cc415..5a277e5d6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,3 +35,7 @@ experimental/aws-lambda-java-profiler/extension/build/
experimental/aws-lambda-java-profiler/integration_tests/helloworld/bin
!experimental/aws-lambda-java-profiler/extension/gradle/wrapper/*.jar
/scratch/
+.vscode
+.kiro
+build
+mise.toml
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index a1241783c..7e8164689 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -36,6 +36,25 @@ To send us a pull request, please:
5. Send us a pull request, answering any default questions in the pull request interface.
6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation.
+
+## Build Prerequisites
+
+This project uses the Maven Toolchains Plugin to pin compilation to JDK 8. If you don't have a `~/.m2/toolchains.xml` configured, builds will fail with:
+
+```
+No toolchain found for type jdk [ version='[1.8,9)' ]
+```
+
+To fix this, copy the example file to your Maven config directory and update the path:
+
+```bash
+cp toolchains.xml.example ~/.m2/toolchains.xml
+```
+
+Then edit `~/.m2/toolchains.xml` and set `` to your local JDK 8 installation path.
+
+Note: if you use `actions/setup-java` in CI (as our GitHub Actions workflows do), this file is generated automatically.
+
GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and
[creating a pull request](https://help.github.com/articles/creating-a-pull-request/).
diff --git a/README.md b/README.md
index fdc08a759..580e14e41 100644
--- a/README.md
+++ b/README.md
@@ -43,7 +43,7 @@ public class HandlerStream implements RequestStreamHandler {
com.amazonaws
aws-lambda-java-core
- 1.2.3
+ 1.3.0
```
@@ -75,7 +75,7 @@ public class SqsHandler implements RequestHandler {
com.amazonaws
aws-lambda-java-events
- 3.15.0
+ 3.16.0
```
@@ -163,7 +163,7 @@ The purpose of this package is to allow developers to deploy their applications
com.amazonaws
aws-lambda-java-runtime-interface-client
- 2.6.0
+ 2.10.1
```
diff --git a/aws-lambda-java-core/RELEASE.CHANGELOG.md b/aws-lambda-java-core/RELEASE.CHANGELOG.md
index ebd0566ff..aebc8ecd9 100644
--- a/aws-lambda-java-core/RELEASE.CHANGELOG.md
+++ b/aws-lambda-java-core/RELEASE.CHANGELOG.md
@@ -1,3 +1,11 @@
+### September 3, 2025
+`1.4.0`
+- Getter support for x-ray trace ID through the Context object
+
+### May 26, 2025
+`1.3.0`
+- Adding support for multi tenancy ([#545](https://github.com/aws/aws-lambda-java-libs/pull/545))
+
### August 17, 2023
`1.2.3`:
- Extended logger interface with level-aware logging backend functions
diff --git a/aws-lambda-java-core/pom.xml b/aws-lambda-java-core/pom.xml
index 0dd848a96..f45b32fb6 100644
--- a/aws-lambda-java-core/pom.xml
+++ b/aws-lambda-java-core/pom.xml
@@ -5,7 +5,7 @@
com.amazonaws
aws-lambda-java-core
- 1.2.3
+ 1.4.0-SNAPSHOT
jar
AWS Lambda Java Core Library
@@ -22,6 +22,9 @@
https://github.com/aws/aws-lambda-java-libs.git
+ scm:git:https://github.com/aws/aws-lambda-java-libs.git
+ scm:git:https://github.com/aws/aws-lambda-java-libs.git
+ HEAD
@@ -36,12 +39,42 @@
1.8
-
-
- sonatype-nexus-staging
- https://oss.sonatype.org/service/local/staging/deploy/maven2/
-
-
+
+
+
+ org.apache.maven.plugins
+ maven-release-plugin
+ 3.1.1
+
+ aws-lambda-java-core-@{project.version}
+ true
+ release
+ deploy
+
+
+
+ org.apache.maven.plugins
+ maven-toolchains-plugin
+ 3.2.0
+
+
+
+
+ [1.8,9)
+
+
+
+
+
+
+ toolchain
+
+
+
+
+
+
@@ -115,14 +148,13 @@
- org.sonatype.plugins
- nexus-staging-maven-plugin
- 1.6.3
+ org.sonatype.central
+ central-publishing-maven-plugin
+ 0.8.0
true
- sonatype-nexus-staging
- https://aws.oss.sonatype.org/
- false
+ central
+ false
diff --git a/aws-lambda-java-core/src/main/java/com/amazonaws/services/lambda/runtime/Context.java b/aws-lambda-java-core/src/main/java/com/amazonaws/services/lambda/runtime/Context.java
index a0850e78c..ed9311a11 100644
--- a/aws-lambda-java-core/src/main/java/com/amazonaws/services/lambda/runtime/Context.java
+++ b/aws-lambda-java-core/src/main/java/com/amazonaws/services/lambda/runtime/Context.java
@@ -100,4 +100,23 @@ public interface Context {
*/
LambdaLogger getLogger();
+ /**
+ *
+ * Returns the tenant ID associated with the request.
+ *
+ * @return null by default
+ */
+ default String getTenantId() {
+ return null;
+ }
+
+ /**
+ *
+ * Returns the X-Ray trace ID associated with the request.
+ *
+ * @return null by default
+ */
+ default String getXrayTraceId() {
+ return null;
+ }
}
diff --git a/aws-lambda-java-events-sdk-transformer/pom.xml b/aws-lambda-java-events-sdk-transformer/pom.xml
index 6a2b1735c..f66020068 100644
--- a/aws-lambda-java-events-sdk-transformer/pom.xml
+++ b/aws-lambda-java-events-sdk-transformer/pom.xml
@@ -5,7 +5,7 @@
com.amazonaws
aws-lambda-java-events-sdk-transformer
- 3.1.0
+ 3.1.1-SNAPSHOT
jar
AWS Lambda Java Events SDK Transformer Library
@@ -24,6 +24,9 @@
https://github.com/aws/aws-lambda-java-libs.git
+ scm:git:https://github.com/aws/aws-lambda-java-libs.git
+ scm:git:https://github.com/aws/aws-lambda-java-libs.git
+ HEAD
@@ -38,6 +41,8 @@
1.8
1.11.914
2.15.40
+ 5.12.2
+ 3.5.4
@@ -63,27 +68,62 @@
com.amazonaws
aws-lambda-java-events
- 3.11.2
+ 3.16.1
provided
org.junit.jupiter
junit-jupiter-engine
- 5.7.0
+ ${junit-jupiter.version}
test
+
+ org.apache.maven.plugins
+ maven-release-plugin
+ 3.1.1
+
+ aws-lambda-java-events-sdk-transformer-@{project.version}
+ true
+ release
+ deploy
+
+
+
+ org.apache.maven.plugins
+ maven-toolchains-plugin
+ 3.2.0
+
+
+
+
+ [1.8,9)
+
+
+
+
+
+
+ toolchain
+
+
+
+
maven-surefire-plugin
- 2.22.2
+ ${maven-surefire-plugin.version}
+
+ true
+
maven-failsafe-plugin
- 2.22.2
+ ${maven-surefire-plugin.version}
@@ -160,18 +200,17 @@
- org.sonatype.plugins
- nexus-staging-maven-plugin
- 1.6.3
+ org.sonatype.central
+ central-publishing-maven-plugin
+ 0.8.0
true
- sonatype-nexus-staging
- https://aws.oss.sonatype.org/
- false
+ central
+ false
-
+
\ No newline at end of file
diff --git a/aws-lambda-java-events/README.md b/aws-lambda-java-events/README.md
index 87c61f345..43c25d76a 100644
--- a/aws-lambda-java-events/README.md
+++ b/aws-lambda-java-events/README.md
@@ -74,7 +74,7 @@
com.amazonaws
aws-lambda-java-events
- 3.15.0
+ 3.16.0
...
diff --git a/aws-lambda-java-events/RELEASE.CHANGELOG.md b/aws-lambda-java-events/RELEASE.CHANGELOG.md
index 6c1769751..a4bcd10a0 100644
--- a/aws-lambda-java-events/RELEASE.CHANGELOG.md
+++ b/aws-lambda-java-events/RELEASE.CHANGELOG.md
@@ -1,3 +1,7 @@
+### June 17, 2025
+`3.16.0`:
+- Add Schema metadata related attributes in KafkaEvent ([#548](https://github.com/aws/aws-lambda-java-libs/pull/548))
+
### January 31, 2025
`3.15.0`:
- Fix `CognitoUserPoolPreTokenGenerationEventV2` model ([#519](https://github.com/aws/aws-lambda-java-libs/pull/519))
diff --git a/aws-lambda-java-events/pom.xml b/aws-lambda-java-events/pom.xml
index f1364e7ab..0b69b03e6 100644
--- a/aws-lambda-java-events/pom.xml
+++ b/aws-lambda-java-events/pom.xml
@@ -1,11 +1,11 @@
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
4.0.0
com.amazonaws
aws-lambda-java-events
- 3.15.0
+ 3.16.1-SNAPSHOT
jar
AWS Lambda Java Events Library
@@ -22,6 +22,9 @@
https://github.com/aws/aws-lambda-java-libs.git
+ scm:git:https://github.com/aws/aws-lambda-java-libs.git
+ scm:git:https://github.com/aws/aws-lambda-java-libs.git
+ HEAD
@@ -37,8 +40,48 @@
1.18.22
UTF-8
UTF-8
+ 2.20.1
+ 2.40.1
+ 5.12.2
+
+
+
+ org.apache.maven.plugins
+ maven-toolchains-plugin
+ 3.2.0
+
+
+
+
+ [1.8,9)
+
+
+
+
+
+
+ toolchain
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-release-plugin
+ 3.1.1
+
+ aws-lambda-java-events-@{project.version}
+ true
+ release
+ deploy
+
+
+
+
+
sonatype-nexus-staging
@@ -56,19 +99,19 @@
org.junit.jupiter
junit-jupiter-engine
- 5.9.2
+ ${junit-jupiter.version}
test
com.fasterxml.jackson.core
jackson-databind
- 2.14.2
+ ${jackson.version}
test
net.javacrumbs.json-unit
json-unit-assertj
- 2.36.1
+ ${json.unit}
test
@@ -152,20 +195,19 @@
- org.sonatype.plugins
- nexus-staging-maven-plugin
- 1.6.3
+ org.sonatype.central
+ central-publishing-maven-plugin
+ 0.8.0
true
- sonatype-nexus-staging
- https://aws.oss.sonatype.org/
- false
+ central
+ false
org.apache.maven.plugins
maven-resources-plugin
- 3.2.0
+ 3.3.1
UTF-8
@@ -173,7 +215,7 @@
org.apache.maven.plugins
maven-compiler-plugin
- 3.8.1
+ 3.11.0
@@ -189,4 +231,4 @@
-
+
\ No newline at end of file
diff --git a/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/ConnectEvent.java b/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/ConnectEvent.java
index 38547ac2a..e94875614 100644
--- a/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/ConnectEvent.java
+++ b/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/ConnectEvent.java
@@ -59,7 +59,7 @@ public static class ContactData implements Serializable, Cloneable {
private String initiationMethod;
private String instanceArn;
private String previousContactId;
- private String queue;
+ private Queue queue;
private SystemEndpoint systemEndpoint;
}
@@ -80,4 +80,13 @@ public static class SystemEndpoint implements Serializable, Cloneable {
private String address;
private String type;
}
+ @Data
+ @Builder(setterPrefix = "with")
+ @NoArgsConstructor
+ @AllArgsConstructor
+ public static class Queue implements Serializable, Cloneable {
+ private String name;
+ private String ARN;
+ }
+
}
diff --git a/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/KafkaEvent.java b/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/KafkaEvent.java
index dd051d48f..aa6c00de3 100644
--- a/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/KafkaEvent.java
+++ b/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/KafkaEvent.java
@@ -43,6 +43,8 @@ public static class KafkaEventRecord {
private String key;
private String value;
private List