This is the operational runbook for maintainers of Powertools for AWS Lambda (TypeScript): who the maintainers are, the labels we use, and the step-by-step processes we follow to triage, release, and operate the project.
If you're looking to contribute, read CONTRIBUTING.md instead.
Security reports come before features and bugs. This repository is monitored and supported 24/7 by Amazon Security — see SECURITY.md for how vulnerabilities are reported and handled.
| Maintainer | GitHub ID | Affiliation |
|---|---|---|
| Andrea Amorosi | dreamorosi | Amazon |
| Swopnil Dangol | sdangol | Amazon |
| Stefano Vozza | svozza | Amazon |
Previous active maintainers who contributed to this project.
| Maintainer | GitHub ID | Affiliation |
|---|---|---|
| Alexander Schueren | am29d | OpenAI |
| Simon Thulbourn | sthulb | |
| Sara Gerion | saragerion | Amazon |
| Florian Chazal | flochaz | |
| Chadchapol Vittavutkarnvej | ijemmy | Booking.com |
| Alan Churley | alan-churley | CloudCall |
| Michael Bahr | bahrmichael | Stedi |
Labels we actually use, and what applies them. Anything marked manual is only ever set by a maintainer, so don't assume it's there.
| Label | Usage | Applied by |
|---|---|---|
triage |
Not yet triaged; remove it once you've validated the request or repro | Issue templates |
researching |
Still being discussed or refined; we'll update once we know more | Manual |
need-more-information |
Missing information before we can make a call | Manual |
need-customer-feedback |
Needs more customer input before deciding or revisiting a decision | Manual |
need-response |
Waiting on the author; opts the issue into org-level stale automation | Manual |
pending-close-response-required |
Went stale waiting for a response and will be closed unless it moves | Organization-level automation |
blocked |
Progress is blocked by an external dependency or reason | Manual |
on-hold |
Parked and will be revisited in the future | Manual |
next-major-version |
Deferred to the next major version | Manual |
pending-release |
Merged and shipping in the next release | Organization-level automation, when the PR merges |
Issue type — bug, feature, documentation, or maintenance — is tracked with GitHub Issue Types rather than labels. What's left are the labels that qualify an item further.
| Label | Usage | Applied by |
|---|---|---|
bug-upstream |
Bug caused by an upstream dependency | Manual |
good-first-issue |
Suitable for someone who wants to start contributing | Manual |
help-wanted |
We'd appreciate support from the community on this one | Manual |
customer-reference |
Authorization to use a customer name publicly | support_powertools.yml issue template |
community-content |
Community content to feature in the documentation | share_your_work.yml issue template |
Area labels flag which part of the library an item belongs to: logger, metrics, tracer, parameters, idempotency, batch, parser, validation, jmespath, event-handler, data-masking, kafka, signer, commons, layers, and automation for CI/CD and workflows.
| Label | Usage | Applied by |
|---|---|---|
do-not-merge |
Blocks the merge; .github/workflows/on_pr_updates.yml fails while it's set |
Manual |
need-issue |
PR is missing a related issue | Organization-level PR checks |
dependencies |
Touches dependencies | Dependabot, alongside an ecosystem label |
javascript, github_actions, docker, python |
Ecosystem a Dependabot PR updates | Dependabot |
skip-changelog |
Excluded from the drafted release notes, see .github/release-drafter.yml |
Automation, on the version bump and layer ARN docs PRs |
size/XS … size/XXL |
Rough PR size, from 0-9 LOC up to 1K+ LOC | Organization-level automation |
Remove triage once you can confirm a request is valid or a bug reproduces, then set a state label from the table above if one applies — an item with no state label is one whose scope is clear and that nothing is blocking. Give priority to the original author for implementation, unless the task is sensitive enough that it's better handled by maintainers.
Not everything needs a label: close an issue as duplicate when it repeats an existing one, and as not planned when we won't work on it. The close reason is what customers see, and it keeps the label list to what's actionable.
Issues are tracked on the board of activities.
A bug produces incorrect or unexpected results at runtime that differ from the intended behavior, is reproducible, and affects customers who follow the recommended usage. Documentation snippets, use of internal components, and unadvertised functionality are not bugs — close the issue as not planned and explain why.
For bugs caused by an upstream dependency, apply bug-upstream and ask the author whether they'd like to raise the issue upstream or prefer us to. Assess the impact and decide whether an emergency release is warranted; ask another maintainer when in doubt.
PR titles must follow Conventional Commits — they feed the changelog and the drafted release notes, so make sure they read well to a human. PR titles, related issues, and the acknowledgment checkbox are enforced by organization-level checks, not by workflows in this repository.
Labels need no action when you merge: organization-level automation applies pending-release when the PR merges and removes it automatically when the release ships.
Two things need to happen before a brand-new package (e.g. a new utility) can ship: its name has to exist on npm, and CI has to know about it.
Make Release publishes with npm Trusted Publishing via GitHub Actions OIDC, so we get provenance without storing a long-lived NPM_TOKEN.
Trusted publishers can only be configured for a package that already exists on npm, so a new package can't reserve its own name that way the first time around: a maintainer has to publish a placeholder version manually, once, before the first real release.
-
Create a temporary local package using the same placeholder shape every utility has used before its first release:
{ "name": "@aws-lambda-powertools/<name>", "version": "0.0.0", "description": "The <name> package for the Powertools for AWS Lambda (TypeScript) library", "author": { "name": "Amazon Web Services", "url": "https://aws.amazon.com" }, "publishConfig": { "access": "public" }, "homepage": "https://github.com/aws-powertools/powertools-lambda-typescript", "license": "MIT-0", "main": "./lib/index.js", "types": "./lib/index.d.ts", "files": ["lib"], "repository": { "type": "git", "url": "git+https://github.com/aws-powertools/powertools-lambda-typescript.git" }, "bugs": { "url": "https://github.com/aws-powertools/powertools-lambda-typescript/issues" }, "dependencies": {}, "keywords": ["aws", "lambda", "powertools", "handler", "nodejs", "serverless"], "devDependencies": {} }Add a
README.mdwith the same "do not use this in production yet" disclaimer other placeholders use —@aws-lambda-powertools/validation@0.0.0is a good reference — and alib/index.js/lib/index.d.tspair where the former only logs that it's a placeholder reserving the name. -
Authenticate locally as an npm user who's a member of the
@aws-lambda-powertoolsorg with publish rights. Use a short-lived, least-privilege token, never commit it to.npmrc, and revoke it as soon as you're done. -
Publish with the
predist-tag, notlatest:npm publish --access public --tag pre
npm always assigns
latestto the very first version ever published for a package, regardless of--tag, so0.0.0will briefly carry bothlatestandpre. That's expected and self-corrects: the next real release moveslatestforward, whileprestays pinned to0.0.0as a permanent marker of the placeholder. -
Configure Trusted Publishing at
https://www.npmjs.com/package/<name>/access: add a Trusted Publisher for GitHub Actions pointing at this repository and themake-release.ymlworkflow. This is what letsMake Releasepublish real versions with OIDC and provenance, without anNPM_TOKEN.
The PR that adds the package must also add it to the workspaces array in the root package.json. That is all CI needs: the unit test and e2e workflows derive their package lists from it through .github/scripts/list_workspaces.js, the e2e workflow picking up any workspace with suites under tests/e2e.
The same array is what gets the package into the Lambda layer, since the layer bundles every non-private @aws-lambda-powertools/* workspace.
Once that's done, the package ships like any other on the next Make Release run.
It usually takes under an hour end to end, most of it spent waiting on the layer rollout and on the two PRs that need a human review.
- Run the end-to-end tests via the
Run e2e Testsworkflow and make sure they pass. - Run
Make Version(.github/workflows/make-version.yml) and pick a release type —autounless you have a reason not to. It bumps every package version, regenerates the changelogs, updates the user agent version inpackages/commons/src/version.ts, and opens achore(ci): bump version to X.Y.ZPR. - Review and merge the version PR. Read the diff carefully: the version numbers and the changelog are what customers will see.
.github/workflows/on_version_bump_pr_merge.ymlwatches for that merge and dispatchesMake Releasefor you. - Approve the
Releasedeployment whenMake Releaseasks for it — that's the gate in front of publishing to npm. - Let
Make Releaserun. In order, it:- runs linting and unit tests;
- publishes every workspace to npm with provenance, then waits until the registry actually serves the new versions;
- creates and pushes the
vX.Y.Ztag; - builds the layer and rolls it out to Beta and then Prod across commercial Regions, with a canary in each;
- writes the Prod SSM parameters;
- copies the layer into the GovCloud and China partitions, Gamma then Prod, both in parallel;
- opens a
chore(ci): update layer ARN on documentationPR once all three Prod deployments are done.
- Review and merge the layer ARN docs PR.
.github/workflows/on_layer_docs_pr_merge.ymlpicks up the merge and dispatchesRebuild latest docs, which republishes the user guide and API reference. - Draft and publish the release notes (see below). Organization-level automation removes
pending-releasefrom shipped issues once the release is published.
There is no workflow for publishing a single package. Trusted Publishing only trusts make-release.yml, and npm only issues provenance attestations from CI, so a one-off publish of one package has to be done from a maintainer's machine with a short-lived token, as described in Reserving the package name on npm.
It ships without provenance, so treat it as a last resort and prefer fixing forward with a regular release.
The GitHub Actions UI is the source of truth; this is a close visual representation of the main steps, with approximate durations.
gantt
title Release process
dateFormat HH:mm
axisFormat %H:%M
Release start : milestone, m1, 10:00, 8s
section Version
Bump versions and changelogs : active, 8s
Open version PR : active, 8s
Review and merge version PR : milestone, m2
section QA
Linting and unit tests : active, 2.4m
section npm
Publish workspaces (provenance) : active, npm, 10:03, 40s
Verify registry propagation : active, after npm, 30s
npmjs.com release : milestone, m3
section Git release
Create and push tag : active, 8s
section Layer release
Build layer : active, layer_build, 10:05, 2.5m
Deploy Beta (incl. canary) : active, layer_beta, after layer_build, 6m
Deploy Prod (incl. canary) : active, layer_prod, after layer_beta, 6m
Layer release : milestone, m4
section SSM
Update SSM parameters (Prod) : active, after layer_prod, 2m
section GovCloud
Publish GovCloud layers (Gamma) : active, govcloud_gamma, after layer_prod, 8s
Publish GovCloud layers (Prod) : active, govcloud_prod, after govcloud_gamma, 8s
GovCloud layers published : milestone, m5
section China
Publish China layers (Gamma) : active, china_gamma, after layer_prod, 8s
Publish China layers (Prod) : active, china_prod, after china_gamma, 8s
China layers published : milestone, m6
section Docs
Commit layer ARNs : active, after govcloud_prod china_prod, 8s
Open docs PR : active, 8s
Review and merge docs PR : milestone, m7
Publish updated docs : active, 2m
Documentation release : milestone, m8
Release complete : milestone, m9
.github/workflows/release-drafter.yml keeps a draft release ready on the Releases page — open it with the edit pencil.
Check that the tag field is the version you're releasing, the target branch is main, and the release title matches the tag, e.g. v2.28.0. Changes are grouped by label according to the categories in .github/release-drafter.yml.
I spotted a typo or incorrect grouping — how do I fix it? Edit the PR title and labels, then re-run the Release Drafter workflow to regenerate the draft.
This won't change the changelog, since the merge commit is immutable — that's fine. We'd only ever rewrite git history if it could genuinely confuse customers, and we'd pair with another maintainer to do it.
Then replace the [Human readable summary of changes] placeholder with what you want customers to take away from this release. Questions worth asking yourself:
- Can customers understand at a high level what changed?
- Is there a link to the documentation for each main change?
- Would a graphic or code snippet make it easier to read?
- Is there a key contributor worth calling out? Everyone is credited automatically, so use this for exceptional cases. If someone is missing from the generated list, add them manually.
Once you're happy, hit Publish release.
End-to-end tests must pass before a release. Run them via the Run e2e Tests workflow. Also run them manually for large maintainer-authored contributions before merging to main.
To run them locally you need the AWS CDK CLI and a bootstrapped account. With a default AWS CLI profile configured, or AWS_PROFILE set:
npm run test:e2e # every package, sequentially
npm run test:e2e -w packages/logger # a single packageThese tests deploy real infrastructure. .github/workflows/sweep-stale-e2e-stacks.yml sweeps up anything a failed run leaves behind, but prefer cleaning up after yourself.
You can republish the documentation without a full release via the Rebuild latest docs workflow. Choose Run workflow, keep main as the branch, and pass the latest published version. This updates both the user guide and the API reference.
When a new AWS Region becomes available, check that it supports AWS Lambda and the Node.js runtimes we publish for, then:
- Run the
Region Bootstrapworkflow (.github/workflows/bootstrap_region.yml) once forbetaand once forprod, passing the new Region. It bootstraps CDK in that Region, then runs thelayer-balancerbalancecommand to copy every existing layer version fromus-east-1, so the new Region ends up with the same layer version numbers as everywhere else. - Add the Region to the
regionmatrix in.github/workflows/reusable_deploy_layer_stack.ymland to theregionmatrix in.github/workflows/update_ssm.yml, so future releases deploy the layer and publish SSM parameters there. - Add a row for the Region to the ARN table in
docs/getting-started/lambda-layers.md, using the layer version currently published. From then on.github/scripts/update_layer_arn.shkeeps it current on every release.
If an existing Region drifts behind — a failed deployment, for instance — run Region Balance (.github/workflows/layer_balance.yml) to copy the missing versions across, optionally passing start_at to resume from a specific layer version.
Regions temporarily excluded from releases are commented out in the deploy matrices and listed in paused_regions in .github/scripts/update_layer_arn.sh, so their frozen ARNs aren't bumped in the docs. Keep the two in sync.
To re-deploy a partition outside the normal release flow, run Layer Deployment (Partitions) (.github/workflows/layers_partitions.yml) with the target partition.