This repository was archived by the owner on Jun 10, 2026. It is now read-only.
[ENH] Pre-publish CI: run aws-sam-cli durable integration tests against candidate emulator image #225
Copy link
Copy link
Closed as not planned
Closed as not planned
Copy link
Description
Activity
Concrete proposal for the workflow
Sketching out the YAML so this is easy to pick up. Uses an explicit file list (sam-cli's
build.ymlonly lists three of the five, but two more —tests/integration/local/callback/test_callback.pyandtests/integration/local/execution/test_execution.py— also inherit fromDurableIntegBaseand need the emulator)..github/workflows/sam-cli-compat.ymlname: sam-cli-compat on: pull_request: branches: [main] paths: - 'src/**' - 'Dockerfile' - '.github/workflows/sam-cli-compat.yml' jobs: sam-cli-durable-integ: runs-on: ubuntu-latest timeout-minutes: 25 steps: - uses: actions/checkout@v4 - name: Build emulator image from this PR run: | TAG="pr-${{ github.event.pull_request.head.sha }}" docker build -t "public.ecr.aws/durable-functions/aws-durable-execution-emulator:${TAG}" . echo "EMULATOR_TAG=${TAG}" >> "$GITHUB_ENV" - uses: actions/setup-python@v5 with: python-version: '3.11' - uses: actions/setup-python@v5 with: python-version: '3.13' # for the durable test-app Lambda runtime - name: Checkout aws-sam-cli uses: actions/checkout@v4 with: repository: aws/aws-sam-cli ref: ${{ vars.SAM_CLI_REF || 'develop' }} # override per-PR if a sam-cli fix is needed path: sam-cli - name: Install samdev working-directory: sam-cli env: SAM_CLI_DEV: '1' run: pip install -e '.[dev]' - name: Run sam-cli durable integration tests working-directory: sam-cli env: SAM_CLI_DEV: '1' SAM_CLI_TELEMETRY: '0' DURABLE_EXECUTIONS_EMULATOR_IMAGE_TAG: ${{ env.EMULATOR_TAG }} run: | pytest -vv \ tests/integration/local/invoke/test_invoke_durable.py \ tests/integration/local/start_api/test_start_api_durable.py \ tests/integration/local/start_lambda/test_start_lambda_durable.py \ tests/integration/local/callback/test_callback.py \ tests/integration/local/execution/test_execution.py
Then in Settings → Branches → main → Branch protection rules, mark
sam-cli-durable-integas a required check.Notes
- File list is hand-curated. All five files inherit from
tests/integration/durable_integ_base.DurableIntegBaseat sam-clidevelopHEAD. There's no formal contract enforcing that — if sam-cli adds a new emulator-dependent test that doesn't extendDurableIntegBase, this list will go stale silently. A follow-up to ask sam-cli for@pytest.mark.durableso we can dopytest -m durableinstead is worth filing separately. - Chicken-and-egg escape hatch.
ref: ${{ vars.SAM_CLI_REF || 'develop' }}lets a testing-lib PR that requires a corresponding sam-cli fix point the workflow at a specific sam-cli SHA via repo variable. Without that, this gate would have blocked PR [fix]: input payload too big to fit in initial execution state #216 from merging until fix(local-lambda): accept documented Lambda DurableExecutionArn shape aws-sam-cli#9040 existed — useful, but only if there's a way to coordinate. - Runtime. Locally these five files take ~5–7 min once images are warm, ~7–10 min cold. Expect 8–12 min on GitHub-hosted runners.
- File list is hand-curated. All five files inherit from
Metadata
Metadata
Assignees
Labels
No labels
Type
Projects
- StatusShow more project fieldsDone
Background
The emulator image
public.ecr.aws/durable-functions/aws-durable-execution-emulator:latestis consumed automatically byaws-sam-cli: on everysam local invokeof a durable function, sam-cli pulls:latestand refreshes the local cache (seedurable_functions_emulator_container.py; customers can override per-invoke withDURABLE_EXECUTIONS_EMULATOR_IMAGE_TAGbut the default is:latest). This means any image we publish ships immediately to every durable-functions customer running sam-cli, with no version pin in between.PR #216 in this repo recently demonstrated the blast radius: ~26 sam-cli durable integration tests went red across
local-invoke,local-start-lambda,tier1-finch, andtier1-windows-otherjobs (e.g. aws-sam-cli Integration Tests #496, run #8779 / local-start-lambda) the moment v1.2.0 went to:latest. Customer-visible symptom: a freshsamdev local invokeagainst any durable function 500s on first checkpoint or 404s on firstlocal execution get|history|stop|callback. Mitigations are in flight on the sam-cli side (aws/aws-sam-cli#9038 merged, #9040 open) but they do not address the class problem: this repo's release pipeline has no signal from sam-cli before publishing:latest.Why our existing tests didn't catch this
tests/web/e2e/routes_arn_encoding_int_test.py(added in #222) drives a real boto client against this repo'sWebServerand would have caught the emulator-side routing bug. It does not — and cannot — exercise sam-cli'sLocalLambdaHttpService, which is a separate Flask service that customers' boto clients actually hit when usingsamdev local invoke. Anything we change in the ARN, callback ID, or function-qualifier shape can break sam-cli's service without touching ours.Proposal
Add a pre-publish CI step that builds the candidate emulator image and runs sam-cli's durable integration suite against it. Concrete shape:
ecr-release.yml).aws-durable-execution-emulator:pr-${SHA}.aws/aws-sam-cliatdevelop, install inSAM_CLI_DEV=1mode.DURABLE_EXECUTIONS_EMULATOR_IMAGE_TAG=pr-${SHA}:Gate this on PRs that touch
src/**so we get the signal pre-merge as well as pre-publish.Acceptance criteria
.github/workflows/sam-cli-compat.yml) that runs the four sam-cli durable test files against the locally-built emulator image and is required for PRs that changesrc/.ecr-release.yml) gated on the same workflow's success.Out of scope
References
DurableExecutionArnshape:arn:<partition>:lambda:<region>:<account>:function:<fn>:<qualifier>/durable-execution/<execution-name>/<execution-id>(API_GetDurableExecution)[Bug]: Durable integration tests can't extract execution ARN that contains "/"fix(tests): accept '/' in durable execution ARN regex[Bug]: Local Lambda HTTP service rejects DurableExecutionArn / CallbackId containing "/"fix(local-lambda): accept documented Lambda DurableExecutionArn shape/), [Bug]: WebServer route layer doesn't URL-decode path segments #222 (URL-decode in own WebServer)