Skip to content

Contributing

Everyone, including the repository owner, follows the same path: issue → agreed scope → branch or fork → pull request → checks and review → merge. This is an independent community implementation, not an official AWS distribution. Read the compatibility boundaries before proposing parity work.

1. Open an issue

Search existing issues and the roadmap first, then choose a form in New issue:

  • Bug report: affected module/version or commit, Go/runtime environment, a minimal reproduction, expected behavior, and actual behavior
  • Feature proposal: the problem, proposed behavior, alternatives, compatibility impact, and observable acceptance criteria
  • Documentation request: the affected guide, example or site page and the requested correction
  • CI/CD request: the affected workflow, observed behavior and completion criteria
  • Maintenance request: the affected tool or repository area and a scoped change
  • Usage question: the module, what you tried and what answer would resolve it
  • Release tracking: the unified version, accumulated changes and publication acceptance

Each form assigns its matching label. The maintained definitions are in the label catalog:

Label Color Purpose
bug Red #d73a4a Incorrect behavior
enhancement Light blue #a2eeef New capability or behavior
documentation Blue #0075ca Guides, examples and the documentation site
cicd Purple #5319e7 GitHub Actions, CI checks and delivery workflows
maintenance Gray #ededed Repository upkeep, tooling and refactoring
release Green #0e8a16 Version preparation and publication tracking
question Pink #d876e3 Usage and compatibility questions

Combine type and area labels when useful: a workflow bug can have bug and cicd; a documentation feature can have enhancement and documentation. Labels organize work; they do not select CI suites or authorize publication.

Maintainers assign one priority label when triaging an issue:

Priority label Color Scheduling guidance
priority:P0 Dark red #b60205 Urgent: active severe impact requiring immediate attention
priority:P1 Orange #d93f0b High: significant impact or a blocker to prioritize next
priority:P2 Yellow #fbca04 Normal: planned work without an urgent blocker
priority:P3 Light green #c2e0c6 Low: optional improvements or work that can wait

An issue without a priority label is untriaged, not implicitly P2. Keep at most one priority label per issue; remove the previous priority when changing it and explain the decision in a comment when useful. Priority describes scheduling urgency rather than issue type or a delivery deadline. The owner can self-triage. Issue forms and automatic classification do not infer priorities; module edits and catalog synchronization preserve manually assigned priority labels.

Module labels use module:<directory>, for example module:logger and module:eventhandler/http/metrics. The root uses module:powertools-lambda-go. The catalog covers every manifest module, including development modules and the frozen X-Ray adapter; a label does not change a module's publication status. Select one or more Affected modules in the issue form, or Repository only for repository work. The Issue labels workflow applies module and category labels on creation, editing, or reopening. Editing this selector replaces its previous module labels and preserves unrelated labels. Older forms are classified additively from their explicit affected-area field; narrative text is not used.

CLI/API-created module issues can include the same field, for example:

### Affected modules

logger, metrics

Run Issue labels from the Actions tab on main to synchronize the label catalog and backfill open and closed issues. Pull requests are excluded, and unrelated repository labels are retained. Unified release issues use release without attaching every module label. Release preparation sets this label directly for new and reused tracking issues, including built-in-token creation that does not trigger another Actions workflow.

When creating an issue with gh issue create, pass labels explicitly, for example --label bug --label cicd: CLI/API creation with a body does not apply web form defaults. Maintainers keep the catalog and repository labels in sync; unrelated standard labels such as help wanted are retained. To create or update a catalog label, use its name, color and description with gh label create --force, for example:

gh label create cicd --color 5319e7 --description "GitHub Actions, CI checks, and delivery workflows" --force

Track one independently verifiable outcome per issue, not one issue per commit. The owner can self-triage and assign their own work. Several commits or partial PRs may share a tracking issue; questions and ideas do not have to become implementation tasks.

Use small synthetic examples. Remove credentials, account identifiers, personal information, and production payloads from logs and attachments. Do not report a suspected vulnerability in a public issue or PR. Use private reporting on the Security page if available; otherwise ask a maintainer for a private reporting route without disclosing the vulnerability publicly.

A maintainer checks for duplicates, confirms the scope and acceptance criteria, and comments that the work is ready. Labels such as bug, enhancement, documentation, help wanted, or good first issue are optional triage aids, not prerequisites. Contributors do not need permission to label or assign issues. Comment before starting to avoid duplicate work. Large API, dependency, or compatibility changes should wait for agreement; a small fix may be proposed as a draft while its issue is being triaged. The owner records the same scope and acceptance decision on their own issue. No response-time guarantee is implied.

2. Work on a branch

External contributors fork the repository; maintainers can branch in the main repository. Do not commit directly to main. For a fork, replace YOUR-USERNAME and 123 below with your account and real issue number:

git clone https://github.com/YOUR-USERNAME/powertools-lambda-go.git
cd powertools-lambda-go
git remote add upstream https://github.com/rambow-cloud/powertools-lambda-go.git
git fetch upstream
git switch -c fix/123-short-description upstream/main

For an existing maintainer checkout:

git fetch origin
git switch -c fix/123-short-description origin/main

Use a focused branch such as fix/123-description, feat/123-description, or docs/123-description. Keep unrelated cleanup in separate issues/PRs. Write documentation and code comments in English; keep feedback respectful and specific. Original contributions use the repository's MIT license; preserve upstream licenses and attribution for third-party material.

For documentation/example versions and source-versus-public acceptance identity, follow the version policy. The proposed stable scope and remaining v1 audit are tracked in v1 readiness.

3. Implement and verify

Read AGENTS.md and module development. Use Go 1.27 or newer, uv, and Python 3.14 for documentation. Always set CGO_ENABLED=0; do not run the race detector. Root go test ./... does not cover nested modules.

Use encoding/json/v2 for JSON serialization and encoding/json/jsontext for tokens, streams and new raw JSON values. Do not use v1 operations or legacy default options. The encoding/json.Number type remains necessary for exact numeric interoperability, and existing public RawMessage signatures retain their types. These type references do not select v1 serialization behavior. Run go run ./tools/jsonapi with CGO_ENABLED=0 to check this policy; CI checks all first-party Go files, including tests and examples.

For code changes, add regression tests and run the packaged module and license checks from the repository root:

export CGO_ENABLED=0
uv run --no-project python tools/licenses.py --check
uv run --no-project python tools/modules.py check

In PowerShell, use $env:CGO_ENABLED = '0' instead of export. Use tools/modules.py tidy when dependency metadata must change; keep filesystem replace directives out of go.mod. Focused check --only MODULE runs help iteration, but are not full-workspace acceptance. Ordinary CI uses scoped packaged checks; release preparation and manual full runs check every module and both Linux Lambda architectures.

For documentation changes (no Go toolchain is needed):

uv lock --project website --check
uv run --project website --frozen python website/check_navigation.py
uv run --project website --frozen python website/check_guides.py
uv run --project website --frozen python website/test_guides.py
uv run --project website --frozen zensical build --clean --strict --config-file mkdocs.yml

For issue forms or repository automation changes, run actionlint and:

uv run --project website --frozen python tools/test_contribution_workflow.py
uv run --project website --frozen python tools/test_ci_changes.py

Release tooling changes additionally run tools/test_release.py and tools/test_release_automation.py with the same Python command, Go installed, CGO disabled, and the pinned GoReleaser version from Releasing modules.

How CI selects checks

The CI workflow compares the complete PR diff (merge base to head) or main push diff (before to after), including deleted and renamed paths. It calls separate documentation and repository automation workflows as needed:

Changed inputs Checks
Documentation, Markdown, site assets or site configuration Documentation navigation, guides, strict build and links
Issue forms, PR template or label configuration Workflow lint, contribution/metadata tests and CI routing tests
Documentation workflow Documentation and automation checks
Release tools or release workflows Automation checks plus offline GoReleaser/release tests
Go production source or a module's go.mod/go.sum Changed modules and transitive consumers of their current local versions; Go source also checks documentation
Go tests or module testdata Owning modules; production consumers do not import these test files
Parameters, Idempotency or shared DynamoDB changes Affected module checks plus the dedicated DynamoDB Local suite
DynamoDB Local tests or runner Integration module checks and DynamoDB Local; no unrelated runtime simulation
Runtime scripts, fixtures or TypeScript reference Integration module checks and runtime simulation
Release plans, module manifest, shared workspace/build tools, CI routing, shared actions or unknown paths Full regression: all modules, both architectures, runtime, DynamoDB Local, documentation and automation/release checks

Mixed changes select the union. Shared documentation/Python dependency changes also run automation/release tests. Run workflow on CI runs every suite. No workflow-level path filter can leave a required check pending.

Module ownership uses the longest manifest-directory match, so eventhandler/http/metrics is distinct from eventhandler/http. Dependency expansion follows current manifest versions, matching the packaged checker; older pinned releases use their published contents. The selection job lists the chosen modules and suites in its summary. Deleted and renamed paths take part in the same selection, including both sides of a rename.

The module job invokes tools/modules.py check --only DIRECTORY for each selected module and verifies tests, vet, tidy metadata and independent public consumers with GOWORK=off. License checks remain repository-wide. Full runs omit --only and additionally produce both Lambda architecture artifacts. Runtime simulation and DynamoDB Local use separate selection flags. A DynamoDB-related production change includes consumers but does not run the unrelated complete Lambda simulation; that simulation runs for runtime inputs and full regression.

The main ruleset requires PR contribution policy and CI gate. The gate always runs and fails if classification fails, outputs are missing, or any selected suite fails, is cancelled, or is unexpectedly skipped. Only suites explicitly excluded by classification may be skipped. Release publication additionally requires Full regression and actual module, runtime, DynamoDB Local, documentation and release-tooling success on the preparation PR and exact main commit. The full marker runs only for complete regression and depends on the successful gate; a scoped run or skipped check cannot authorize publication.

For behavior involving the Lambda runtime, use the maintained local Docker integration runner. It includes the module checks and both architecture builds, so do not repeat them unnecessarily. Cloud AWS testing requires explicit authorization and explicit account/profile configuration; it is not a contribution prerequisite. Keep generated caches, binaries, private evidence, and credentials out of Git. Update project progress only for verified acceptance milestones, not routine wording fixes.

4. Open a pull request

Commit your focused changes and push the feature branch to your fork or the main repository. Open a draft PR targeting main. Use the PR template to explain what changed, why, the actual tests/results, and remaining risks. Prefer titles such as fix(logger): preserve invocation fields or docs: clarify local setup.

In the PR description's Issue section, put one reference per line:

Closes #123

Use Refs #123 for a partial step that should leave its tracking issue open. Fixes and Resolves are also accepted. A same-repository full issue URL or rambow-cloud/powertools-lambda-go#123 is accepted after the keyword. The number must identify a real issue in this repository, not another PR. References inside HTML comments or code blocks do not count. GitHub closes issues from closing keywords when the PR is merged into the default branch; Refs does not auto-close.

The PR contribution policy check verifies the issue reference and nonempty Summary and Testing sections, plus structured Release notes. Write one - MODULE | TYPE | Description. entry per user-visible change, or None: <specific reason> when there is no release impact. Use module directories from tools/modules.json; repository denotes repository-only work. See Releasing modules for types and examples. Notes accumulate until the relevant module is released. State the commands and results, or explain why a check is not applicable or blocked; do not claim unrun tests passed. This metadata check cannot judge scope agreement or test quality: maintainers still review both. Owner and dependency-bot PRs need the same tracking issue; a maintainer can edit a bot PR description to add it and the missing sections. Drafts may fail until their description is complete.

The CI gate runs for every PR and verifies the suites selected from its changed files, as described above. A first-time fork contribution may wait for a maintainer to approve running Actions. This is expected, not a request for credentials or repository write access. PR jobs receive no AWS credentials and do not deploy. Edit the PR body to rerun the policy check; push a new commit to rerun code checks, or ask a maintainer to rerun a transient failure.

5. Review and merge

When ready, leave draft mode and request review. Address feedback on the same branch; keep the PR description and evidence current. Update from main when required and resolve conflicts. A maintainer checks the issue's acceptance criteria, source changes (especially workflows), tests, documentation, and compatibility impact before merging. Passing CI does not guarantee acceptance.

With one maintainer, formal required approvals stay at zero because authors cannot approve their own PRs. The owner still opens an issue and PR, reviews the diff, records test evidence, and waits for all required checks. With a second active maintainer, administrators can require one independent approval.

Prefer squash merging with a meaningful title. A completed issue closes through the PR's closing keyword; leave partial tracking issues open. Delete the merged feature branch when no longer needed. Merging source does not publish Go module versions; releasing modules remains a separate decision.