Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ permissions:
contents: read
id-token: write

on: [pull_request, workflow_call]
on: [pull_request]

jobs:
shared-ci:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/daily_ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ jobs:
strategy:
matrix:
branch: [master, v4.x]
uses: ./.github/workflows/ci.yml
uses: ./.github/workflows/shared-ci.yml
with:
branch: ${{ matrix.branch }}
ref: ${{ matrix.branch }}
notify:
needs:
[
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/prod-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ jobs:
cache: 'npm'

- name: Install dependencies
run: npm ci --unsafe-perm
run: npm ci

- name: Configure AWS Credentials for Release
uses: aws-actions/configure-aws-credentials@v5
Expand Down
26 changes: 23 additions & 3 deletions .github/workflows/shared-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@ on:
required: false
type: boolean
default: false
ref:
description: 'Git ref (branch, tag, or SHA) to check out and test. Defaults to the ref that triggered the workflow.'
required: false
type: string
default: ''

env:
NODE_OPTIONS: "--max-old-space-size=4096"
NPM_CONFIG_UNSAFE_PERM: true

jobs:
test:
Expand All @@ -34,13 +38,29 @@ jobs:
# Always need repo for test scripts and configuration, even when testing published packages
uses: actions/checkout@v4
with:
ref: ${{ inputs.ref }}
fetch-depth: 0
submodules: true

- name: Resolve Node.js version
id: node-version
env:
REQUESTED_NODE_VERSION: ${{ matrix.node-version }}
run: |
if [ "$REQUESTED_NODE_VERSION" = "latest" ]; then
# setup-node's `latest` takes the newest entry in nodejs.org/dist/index.json,
# which can be a prerelease (e.g. v27.0.0-alpha). Use the newest stable release.
version=$(curl -fsSL https://nodejs.org/dist/index.json | jq -r '[.[] | select(.version | test("-") | not)][0].version')
else
version="$REQUESTED_NODE_VERSION"
fi
echo "Using Node.js $version"
echo "version=$version" >> "$GITHUB_OUTPUT"

- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
node-version: ${{ steps.node-version.outputs.version }}
cache: 'npm'

- name: Configure AWS Credentials for Tests
Expand All @@ -51,7 +71,7 @@ jobs:
role-session-name: JavaScriptTests

- name: Install dependencies
run: npm ci --unsafe-perm
run: npm ci

- name: Build (for source code testing)
if: ${{ !inputs.test-published-packages }}
Expand Down
170 changes: 17 additions & 153 deletions .github/workflows/test-server.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ on:
- "test-server/**"
- ".github/workflows/test-server.yml"
push:
branches:
- master
paths:
- "test-server/**"
- ".github/workflows/test-server.yml"
Expand All @@ -30,7 +32,7 @@ jobs:
cache: "npm"

- name: Install dependencies
run: npm ci --unsafe-perm
run: npm ci

- name: Build modules
run: npm run build-node
Expand All @@ -43,158 +45,20 @@ jobs:
working-directory: test-server
run: npm test

# The complete cross-language TestServer run: `make test-server` clones commons and
# the orchestrator materializes + builds + launches every configured Language_Server
# (this working tree is the live server), runs the full pairwise matrix, and tears
# down. Provisions the full toolchain matrix + the commons build caches. Needs the
# COMMONS_REPO_PAT secret (read on commons + java + rust).
# The cross-language TestServer run, from the shared commons workflow. This
# checkout supplies the javascript server and library; every other server comes from
# its configured branch. Only the pairs involving javascript run; the full matrix
# runs in commons. repo-pat reads the private aws-crypto-tools-rust clones.
test-server:
name: Cross-language TestServer run
runs-on: ubuntu-latest
name: TestServer
permissions:
id-token: write
contents: read
env:
AWS_REGION: us-west-2
GRADLE_OPTS: -Dorg.gradle.daemon=false
# Cold builds (Java gradle/maven, Rust aws-lc-sys, .NET dafny transpile) exceed
# the orchestrator's 180s default server-readiness window; widen it so the first
# (cold-cache) run fits. Warm runs are fast via the build caches above.
ESDK_TESTSERVER_READY_TIMEOUT_SECONDS: "1800"
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false

- name: Set up JDK 17 (Temurin) — exposes JAVA_HOME_17_X64 for the MPL stub jar
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: "17"

- name: Set up JDK 21 (Temurin) — the commons orchestrator (smithy-java) needs 21+
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: "21"

- name: Set up Python 3.11 (the materialized Python Language_Server needs >=3.11)
uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Set up Node.js 22 (the materialized JavaScript Language_Server build needs 17+)
uses: actions/setup-node@v4
with:
node-version: "22"

- name: Set up Go (Go Language_Server + the Rust servers' aws-lc-sys native builds)
uses: actions/setup-go@v5
with:
go-version: "stable"

- name: Set up the Rust toolchain (Rust Language_Server builds)
run: |
set -euo pipefail
rustup toolchain install stable --profile minimal
rustup default stable
cargo --version

- name: Set up .NET (the materialized .NET Language_Server build)
uses: actions/setup-dotnet@v5
with:
dotnet-version: |
6.0.x
8.0.x

- name: Install Dafny 4.9.0 (the .NET library transpile in the materialized clone)
run: |
set -euo pipefail
dotnet tool install --global dafny --version 4.9.0
echo "$HOME/.dotnet/tools" >> "$GITHUB_PATH"
"$HOME/.dotnet/tools/dafny" --version

- name: Build aws-c-common (the materialized C Language_Server cmake requires it)
run: |
set -euo pipefail
git clone --depth 1 https://github.com/awslabs/aws-c-common "$RUNNER_TEMP/aws-c-common"
cmake -S "$RUNNER_TEMP/aws-c-common" -B "$RUNNER_TEMP/aws-c-common-build" \
-DCMAKE_INSTALL_PREFIX="${{ github.workspace }}/.aws-c-common-install" \
-DBUILD_TESTING=OFF
cmake --build "$RUNNER_TEMP/aws-c-common-build" --target install -- -j
echo "CMAKE_PREFIX_PATH=${{ github.workspace }}/.aws-c-common-install" >> "$GITHUB_ENV"

- name: Restore build caches (Gradle/Maven/Cargo/NuGet/Go/npm)
uses: actions/cache/restore@v4
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
~/.m2/repository
~/.cargo/registry
~/.cargo/git
~/.nuget/packages
~/go/pkg/mod
~/.cache/go-build
~/.npm
key: ${{ runner.os }}-esdk-ts-build-${{ github.run_id }}
restore-keys: |
${{ runner.os }}-esdk-ts-build-

- name: Install stub for the unpublished MPL test-vectors artifact
# The materialized Java Language_Server build runs `mvn install`, which
# resolves a test-scope MPL artifact (TestAwsCryptographicMaterialProviders)
# that is not on Maven Central; a stub jar satisfies resolution (tests skip).
run: |
set -euo pipefail
tmp="$(mktemp -d)"
echo placeholder > "$tmp/README.txt"
"$JAVA_HOME_17_X64/bin/jar" cf "$tmp/stub.jar" -C "$tmp" README.txt
mvn -q -e org.apache.maven.plugins:maven-install-plugin:3.1.1:install-file \
-Dfile="$tmp/stub.jar" \
-DgroupId=software.amazon.cryptography \
-DartifactId=TestAwsCryptographicMaterialProviders \
-Dversion=1.7.0 \
-Dpackaging=jar

- name: Authenticate the private clones (commons, java, rust)
env:
PAT: ${{ secrets.COMMONS_REPO_PAT }}
run: |
test -n "$PAT" || { echo "::error::COMMONS_REPO_PAT is empty/unset in this repo"; exit 1; }
git config --global url."https://x-access-token:${PAT}@github.com/".insteadOf "[email protected]:"

- name: Configure AWS credentials via OIDC (required KMS scenarios)
id: aws-credentials
continue-on-error: true
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ vars.ESDK_TEST_SERVER_KMS_ROLE_ARN || 'arn:aws:iam::370957321024:role/esdk-test-server-ci-kms-role' }}
aws-region: us-west-2

- name: Verify AWS credentials are active (gates the orchestrated run)
run: |
if ! aws sts get-caller-identity; then
echo "::error::No usable AWS credentials for the required KMS scenarios." >&2
exit 1
fi

- name: Run the orchestrated TestServer
working-directory: test-server
run: make test-server

- name: Save build caches
if: always()
uses: actions/cache/save@v4
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
~/.m2/repository
~/.cargo/registry
~/.cargo/git
~/.nuget/packages
~/go/pkg/mod
~/.cache/go-build
~/.npm
key: ${{ runner.os }}-esdk-ts-build-${{ github.run_id }}
actions: read
id-token: write
uses: aws/aws-crypto-tools-commons/.github/workflows/esdk-test-server-reusable.yml@main
with:
focus: javascript
checkout-languages: javascript
runner: ubuntu-latest
secrets:
repo-pat: ${{ secrets.COMMONS_REPO_PAT }}
13 changes: 13 additions & 0 deletions modules/integration-browser/karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,19 @@ module.exports = function (config) {
test: /yauzl/,
use: 'null-loader',
},
{
// Our packages set "sideEffects": false in package.json. Since
// webpack 5.112, development builds use that flag to skip modules
// that are only re-exported (`export * from ...`), and they skip
// some that are needed, e.g. @aws-crypto/cache-material. The
// bundle still compiles, but the tests fail with "Cannot find
// module". `sideEffects: true` tells webpack to ignore the flag
// and include every module. This can't go in
// `optimization.sideEffects` because karma-webpack drops any
// `optimization` settings.
test: /\.js$/,
sideEffects: true,
},
]
},
mode: 'development',
Expand Down
17 changes: 16 additions & 1 deletion modules/kms-keyring-node/src/kms_hkeyring_node_helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,22 @@ export async function getBranchKeyMaterials(
branchKeyMaterials = cacheEntry.response
}

return branchKeyMaterials
/* Hand back a copy the cache can never touch. The CMC zeroes a material's
* buffer in place on eviction; callers read the branch key AFTER this await,
* so a concurrent eviction (overwrite, TTL, or tail) could otherwise zero the
* buffer mid-derivation. */
return deepCopyBranchKeyMaterial(branchKeyMaterials)
}

function deepCopyBranchKeyMaterial(
material: NodeBranchKeyMaterial
): NodeBranchKeyMaterial {
return new NodeBranchKeyMaterial(
Buffer.from(material.branchKey()),
material.branchKeyIdentifier,
material.branchKeyVersion.toString('utf-8'),
{ ...material.encryptionContext }
)
}

//= aws-encryption-sdk-specification/framework/aws-kms/aws-kms-hierarchical-keyring.md#onencrypt
Expand Down
Loading
Loading