From 57acac9d897326cce4231869d04b75d24ed1eb4b Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Thu, 13 Jul 2023 10:55:27 +0200 Subject: [PATCH 1/4] docs(security): explain our automated checks --- docs/security.md | 60 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/docs/security.md b/docs/security.md index edaedaf1ecd..d2116ec31b2 100644 --- a/docs/security.md +++ b/docs/security.md @@ -85,18 +85,78 @@ You can do this manually or automated via a shell script. We maintain the latter ---8<-- ".github/actions/verify-provenance/verify_provenance.sh" ``` + + ### Continuous integration practices !!! note "We adhere to industry recommendations from the [OSSF Scorecard project](https://bestpractices.coreinfrastructure.org/en/criteria){target="_blank"}, among [others](https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions){target="_blank"}." Since all code changes require a pull request (PR) along with one or more reviewers, we automate quality and security checks **before**, **during**, and **after** a PR is merged to trunk (`develop`). +We use a combination of tools coupled with peer review to increase its compound effect in detecting issues early. + This is a snapshot of our automated checks at a glance. ![Continuous Integration practices](./media/continuous_integration_practices.png) +#### Pre-commit checks + +> [**Pre-commit configuration**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.pre-commit-config.yaml){target="_blank"}. + +Pre-commit checks are crucial for a fast feedback loop while ensuring security practices at the individual change level. + +To prevent scenarios where these checks are intentionally omitted at the client side, we run at [CI level too](#pull-request-checks). + +!!! note "These run locally only for changed files" + +* [**Merge conflict check**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.pre-commit-config.yaml#L10){target="_blank"}. Checks for merge strings in each individual change accidentally left unresolved to prevent breakage. +* [**Code linting**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/Makefile#L22){target="_blank"}. Linter checks for industry quality standards and known bad practices that could lead to abuse. +* [**CloudFormation linting**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.pre-commit-config.yaml#L34){target="_blank"}. `cfn-lint` ensures [best practices](https://github.com/aws-cloudformation/cfn-lint/blob/86f0370bd43b400ed4c485180dbc2697f73367b2/docs/rules.md){target=""_blank"} at our documentation examples. +* [**Markdown linting**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.pre-commit-config.yaml#L25){target="_blank}. Primarily [industry markdown practices](https://github.com/DavidAnson/markdownlint/blob/d01180ec5a014083ee9d574b693a8d7fbc1e566d/README.md#rules--aliases){target="_blank"}. We intend to create our own once we have a definitive style guide. +* [**GitHub Actions linting**](https://github.com/rhysd/actionlint/blob/main/docs/checks.md){target="_blank"}. `actionlint` ensures workflows follow [GitHub Actions security practices](https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions){target="_blank"}. It guards against numerous [leading practices](https://github.com/rhysd/actionlint/blob/main/docs/checks.md){target="_blank"} to prevent common configuration mistakes, insecure inline scripts, among many others. +* [**Terraform linting**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.pre-commit-config.yaml#L43){target="_blank"}. As of now, largely formatting until we increase our Terraform coverage in documentation examples. +* [**Secrets linting**](https://github.com/aws-powertools/powertools-lambda-python/blob/develop/.pre-commit-config.yaml#L49){target="_blank"}. Detects industry credentials that might be accidentally leaked in source code. + +#### Pre-Pull Request checks + +For an improved contributing experience, most of our checks can run locally. For maintainers, this also means increased focus on reviewing actual value instead of standards and security malpractices that can be caught earlier. + +!!! note "These are in addition to [pre-commit checks](#pre-commit-checks)." + +* [**Static typing analysis**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/Makefile#L108). `mypy` checks for static typing annotations to prevent common bugs in Python that may or may not lead to abuse. +* [**Tests**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/Makefile#L31){target="_blank"}. We run `unit`, `functional`, and `performance` tests ([_see our definition_](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/CONTRIBUTING.md#testing-definition){target="_blank"}). Besides breaking changes, we are investing in mutation testing to find additional sources of bugs and potential abuse. +* [**Security baseline**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/CONTRIBUTING.md#testing-definition){target="_blank"}. `bandit` detects common security issues defined by Python Code Quality Authority (PyCQA). +* [**Complexity baseline**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/Makefile#L79){target="_blank"}. We run a series of maintenability and cyclomatic checks to reduce code and logic complexity. This aids reviewers' cognitive overhead and long-term maintainers revisiting legacy code at a later date. + +#### Pull Request checks + +While we trust contributors and maintainers do go through pre-commit and pre-pull request due diligence, we verify them at CI level. + +!!! note "Checks described earlier are omitted to improve reading experience." + +* [**Semantic PR title**](https://github.com/Ezard/semantic-prs){target="_blank"}. We enforce PR titles follow semantic naming, for example `chore(category): change`. This benefits contributors with a lower entry bar, no need for semantic commits. It also benefits everyone looking for an [useful changelog message](https://docs.powertools.aws.dev/lambda/python/latest/changelog/){target="_blank"} on **what** changed and **where**. +* [**Related issue check**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/workflows/on_opened_pr.yml#L44){target="_blank"}. [Every change require an issue](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/CONTRIBUTING.md#contributing-via-pull-requests){target="_blank"} describing its needs. This enforces a PR has a related issue by blocking merge operations if missing. +* [**Acknowledgment check**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/workflows/on_opened_pr.yml#L63){target="_blank"}. [Ensures PR template](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/PULL_REQUEST_TEMPLATE.md#L36){target="_blank"} is used and every contributor is aware of code redistribution. +* [**Code coverage diff**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/workflows/quality_check.yml#L73){target="_blank"}. Educates contributors and maintainers about code coverage differences for a given change. +* [**Contribution size check**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/workflows/on_label_added.yml#L44){target="_blank"}. Suggests contributors and maintainers to break up large changes (100-499 LOC) in smaller PRs. It helps reduce overlooking security and other practices due to increased cognitive overhead. +* [**Dependency vulnerability check**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/workflows/dependency-review.yml#L22){target="_blank"}. Verifies any dependency changes for common vulnerability exposures (CVEs), in addition to our daily check on any dependencies used (e.g., Python, Docker, Go, etc.) +* [**GitHub Actions security check**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/workflows/secure_workflows.yml#L35){target="_blank"}. Enforces use of immutable 3rd-party GitHub Actions (_e.g., `actions/checkout@_`) to prevent abuse. Upgrades are handled by a [separate automated process](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/dependabot.yml#L4){target="_blank"} that includes a maintainer review to also prevent unexpected behavior changes. + +#### After merge checks + +!!! note "Checks described earlier are omitted to improve reading experience." + +We strike a balance in security and contribution experience. These automated checks take several minutes to complete. Failures are reviewed by a maintainer on-call and before a release. + +* [**End-to-end tests**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/workflows/run-e2e-tests.yml#L41){target="_blank"}. We run E2E with a [high degree of parallelization](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/MAINTAINERS.md#test-runner-parallelization). While it is designed to also run locally, it may incur AWS charges to contributors. For additional security, all infrastructure is ephemeral per change and per Python version. +* [**SAST check**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/workflows/codeql-analysis.yml#L20){target="_blank"}. GitHub CodeQL runs ~30m static analysis in the entire codebase. +* [**Security posture check**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/workflows/ossf_scorecard.yml#L14){target="_blank"}. OSSF Scorecard runs numerous automated checks upon changes, and raises security alerts if [OSSF security practices](https://bestpractices.coreinfrastructure.org/en/criteria){target="_blank"} are no longer followed. +* [**Rebuild Changelog**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/workflows/build_changelog.yml#L23){target="_blank"}. We rebuild our entire changelog upon changes and create a PR for maintainers. This has the added benefit in keeping a [protected branch](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/about-protected-branches){target="_blank"} while keeping removing error-prone tasks from maintainers. +* [**Stage documentation**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/workflows/on_push_docs.yml#L27C16-L27C16){target="_blank"}. We rebuild and deploy changes to the documentation to a [staged version](https://docs.powertools.aws.dev/lambda/python/stage/){target="_blank"}. This gives us safety that our docs can always be rebuilt, and ready to release to production when needed. +* [**Update draft release**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/workflows/release-drafter.yml#L25){target="_blank"}. We use [Release Drafter](https://github.com/release-drafter/release-drafter){target="_blank"} to generate a portion of our release notes and to always keep a fresh draft upon changes. You can read our [thoughts on a good quality release notes here](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/MAINTAINERS.md#drafting-release-notes){target="_blank"} (human readable changes + automation). + ### Continuous deployment practices !!! note "We adhere to industry recommendations from the [OSSF Scorecard project](https://bestpractices.coreinfrastructure.org/en/criteria){target="_blank"}, among [others](https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions){target="_blank"}." From e478ff46295b13eb8ec11f6e6fd9627bedca295c Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Thu, 13 Jul 2023 14:38:54 +0200 Subject: [PATCH 2/4] docs: split automation and security, use tabs navigation --- docs/automation.md | 90 ++++++++++++++++++++++++++++++++++++++ docs/security.md | 82 ---------------------------------- docs/stylesheets/extra.css | 8 ++++ mkdocs.yml | 59 +++++++++++++------------ 4 files changed, 129 insertions(+), 110 deletions(-) create mode 100644 docs/automation.md diff --git a/docs/automation.md b/docs/automation.md new file mode 100644 index 00000000000..d0aacb89977 --- /dev/null +++ b/docs/automation.md @@ -0,0 +1,90 @@ +--- +title: Automation +description: Automation practices and processes for Powertools for AWS Lambda (Python) +--- + + + +## Continuous integration practices + +!!! note "We adhere to industry recommendations from the [OSSF Scorecard project](https://bestpractices.coreinfrastructure.org/en/criteria){target="_blank"}, among [others](https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions){target="_blank"}." + +Since all code changes require a pull request (PR) along with one or more reviewers, we automate quality and security checks **before**, **during**, and **after** a PR is merged to trunk (`develop`). + +We use a combination of tools coupled with peer review to increase its compound effect in detecting issues early. + +This is a snapshot of our automated checks at a glance. + + + +![Continuous Integration practices](./media/continuous_integration_practices.png) + +### Pre-commit checks + +> [**Pre-commit configuration**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.pre-commit-config.yaml){target="_blank"}. + +Pre-commit checks are crucial for a fast feedback loop while ensuring security practices at the individual change level. + +To prevent scenarios where these checks are intentionally omitted at the client side, we run at [CI level too](#pull-request-checks). + +!!! note "These run locally only for changed files" + +* [**Merge conflict check**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.pre-commit-config.yaml#L10){target="_blank"}. Checks for merge strings in each individual change accidentally left unresolved to prevent breakage. +* [**Code linting**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/Makefile#L22){target="_blank"}. Linter checks for industry quality standards and known bad practices that could lead to abuse. +* [**CloudFormation linting**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.pre-commit-config.yaml#L34){target="_blank"}. `cfn-lint` ensures [best practices](https://github.com/aws-cloudformation/cfn-lint/blob/86f0370bd43b400ed4c485180dbc2697f73367b2/docs/rules.md){target=""_blank"} at our documentation examples. +* [**Markdown linting**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.pre-commit-config.yaml#L25){target="_blank}. Primarily [industry markdown practices](https://github.com/DavidAnson/markdownlint/blob/d01180ec5a014083ee9d574b693a8d7fbc1e566d/README.md#rules--aliases){target="_blank"} at this stage. +* [**GitHub Actions linting**](https://github.com/rhysd/actionlint/blob/main/docs/checks.md){target="_blank"}. `actionlint` ensures workflows follow [GitHub Actions security practices](https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions){target="_blank"}. It guards against numerous [leading practices](https://github.com/rhysd/actionlint/blob/main/docs/checks.md){target="_blank"} to prevent common configuration mistakes, insecure inline scripts, among many others. +* [**Terraform linting**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.pre-commit-config.yaml#L43){target="_blank"}. As of now, largely formatting until we increase our Terraform coverage in documentation examples. +* [**Secrets linting**](https://github.com/aws-powertools/powertools-lambda-python/blob/develop/.pre-commit-config.yaml#L49){target="_blank"}. Detects industry credentials that might be accidentally leaked in source code. + +### Pre-Pull Request checks + +For an improved contributing experience, most of our checks can run locally. For maintainers, this also means increased focus on reviewing actual value instead of standards and security malpractices that can be caught earlier. + +!!! note "These are in addition to [pre-commit checks](#pre-commit-checks)." + +* [**Static typing analysis**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/Makefile#L108). `mypy` checks for static typing annotations to prevent common bugs in Python that may or may not lead to abuse. +* [**Tests**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/Makefile#L31){target="_blank"}. We run `unit`, `functional`, and `performance` tests ([_see our definition_](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/CONTRIBUTING.md#testing-definition){target="_blank"}). Besides breaking changes, we are investing in mutation testing to find additional sources of bugs and potential abuse. +* [**Security baseline**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/CONTRIBUTING.md#testing-definition){target="_blank"}. `bandit` detects common security issues defined by Python Code Quality Authority (PyCQA). +* [**Complexity baseline**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/Makefile#L79){target="_blank"}. We run a series of maintenability and cyclomatic checks to reduce code and logic complexity. This aids reviewers' cognitive overhead and long-term maintainers revisiting legacy code at a later date. + +### Pull Request checks + +While we trust contributors and maintainers do go through pre-commit and pre-pull request due diligence, we verify them at CI level. + +!!! note "Checks described earlier are omitted to improve reading experience." + +* [**Semantic PR title**](https://github.com/Ezard/semantic-prs){target="_blank"}. We enforce PR titles follow semantic naming, for example `chore(category): change`. This benefits contributors with a lower entry bar, no need for semantic commits. It also benefits everyone looking for an [useful changelog message](https://docs.powertools.aws.dev/lambda/python/latest/changelog/){target="_blank"} on **what** changed and **where**. +* [**Related issue check**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/workflows/on_opened_pr.yml#L44){target="_blank"}. [Every change require an issue](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/CONTRIBUTING.md#contributing-via-pull-requests){target="_blank"} describing its needs. This enforces a PR has a related issue by blocking merge operations if missing. +* [**Acknowledgment check**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/workflows/on_opened_pr.yml#L63){target="_blank"}. [Ensures PR template](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/PULL_REQUEST_TEMPLATE.md#L36){target="_blank"} is used and every contributor is aware of code redistribution. +* [**Code coverage diff**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/workflows/quality_check.yml#L73){target="_blank"}. Educates contributors and maintainers about code coverage differences for a given change. +* [**Contribution size check**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/workflows/on_label_added.yml#L44){target="_blank"}. Suggests contributors and maintainers to break up large changes (100-499 LOC) in smaller PRs. It helps reduce overlooking security and other practices due to increased cognitive overhead. +* [**Dependency vulnerability check**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/workflows/dependency-review.yml#L22){target="_blank"}. Verifies any dependency changes for common vulnerability exposures (CVEs), in addition to our daily check on any dependencies used (e.g., Python, Docker, Go, etc.) +* [**GitHub Actions security check**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/workflows/secure_workflows.yml#L35){target="_blank"}. Enforces use of immutable 3rd-party GitHub Actions (_e.g., `actions/checkout@_`) to prevent abuse. Upgrades are handled by a [separate automated process](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/dependabot.yml#L4){target="_blank"} that includes a maintainer review to also prevent unexpected behavior changes. + +### After merge checks + +!!! note "Checks described earlier are omitted to improve reading experience." + +We strike a balance in security and contribution experience. These automated checks take several minutes to complete. Failures are reviewed by a maintainer on-call and before a release. + +* [**End-to-end tests**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/workflows/run-e2e-tests.yml#L41){target="_blank"}. We run E2E with a [high degree of parallelization](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/MAINTAINERS.md#test-runner-parallelization). While it is designed to also run locally, it may incur AWS charges to contributors. For additional security, all infrastructure is ephemeral per change and per Python version. +* [**SAST check**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/workflows/codeql-analysis.yml#L20){target="_blank"}. GitHub CodeQL runs ~30m static analysis in the entire codebase. +* [**Security posture check**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/workflows/ossf_scorecard.yml#L14){target="_blank"}. OSSF Scorecard runs numerous automated checks upon changes, and raises security alerts if [OSSF security practices](https://bestpractices.coreinfrastructure.org/en/criteria){target="_blank"} are no longer followed. +* [**Rebuild Changelog**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/workflows/build_changelog.yml#L23){target="_blank"}. We rebuild our entire changelog upon changes and create a PR for maintainers. This has the added benefit in keeping a [protected branch](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/about-protected-branches){target="_blank"} while keeping removing error-prone tasks from maintainers. +* [**Stage documentation**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/workflows/on_push_docs.yml#L27C16-L27C16){target="_blank"}. We rebuild and deploy changes to the documentation to a [staged version](https://docs.powertools.aws.dev/lambda/python/stage/){target="_blank"}. This gives us safety that our docs can always be rebuilt, and ready to release to production when needed. +* [**Update draft release**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/workflows/release-drafter.yml#L25){target="_blank"}. We use [Release Drafter](https://github.com/release-drafter/release-drafter){target="_blank"} to generate a portion of our release notes and to always keep a fresh draft upon changes. You can read our [thoughts on a good quality release notes here](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/MAINTAINERS.md#drafting-release-notes){target="_blank"} (human readable changes + automation). + +## Continuous deployment practices + +!!! note "We adhere to industry recommendations from the [OSSF Scorecard project](https://bestpractices.coreinfrastructure.org/en/criteria){target="_blank"}, among [others](https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions){target="_blank"}." + +Releases are triggered by maintainers along with a reviewer - [detailed info here](https://github.com/aws-powertools/powertools-lambda-python/blob/develop/MAINTAINERS.md#releasing-a-new-version){target="_blank"}. In addition to [checks that run for every code change](#continuous-integration-practices), our pipeline requires a manual approval before releasing. + +We use a combination of provenance and signed attestation for our builds, source code sealing, SAST scanners, Python specific static code analysis, ephemeral credentials that last a given job step, and more. + +This is a snapshot of our automated checks at a glance. + +![Continuous Deployment practices](./media/continuous_deployment_practices.png) + +!!! info "More details to come" diff --git a/docs/security.md b/docs/security.md index d2116ec31b2..b3475e2c0c0 100644 --- a/docs/security.md +++ b/docs/security.md @@ -86,85 +86,3 @@ You can do this manually or automated via a shell script. We maintain the latter ``` - -### Continuous integration practices - -!!! note "We adhere to industry recommendations from the [OSSF Scorecard project](https://bestpractices.coreinfrastructure.org/en/criteria){target="_blank"}, among [others](https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions){target="_blank"}." - -Since all code changes require a pull request (PR) along with one or more reviewers, we automate quality and security checks **before**, **during**, and **after** a PR is merged to trunk (`develop`). - -We use a combination of tools coupled with peer review to increase its compound effect in detecting issues early. - -This is a snapshot of our automated checks at a glance. - - - -![Continuous Integration practices](./media/continuous_integration_practices.png) - -#### Pre-commit checks - -> [**Pre-commit configuration**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.pre-commit-config.yaml){target="_blank"}. - -Pre-commit checks are crucial for a fast feedback loop while ensuring security practices at the individual change level. - -To prevent scenarios where these checks are intentionally omitted at the client side, we run at [CI level too](#pull-request-checks). - -!!! note "These run locally only for changed files" - -* [**Merge conflict check**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.pre-commit-config.yaml#L10){target="_blank"}. Checks for merge strings in each individual change accidentally left unresolved to prevent breakage. -* [**Code linting**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/Makefile#L22){target="_blank"}. Linter checks for industry quality standards and known bad practices that could lead to abuse. -* [**CloudFormation linting**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.pre-commit-config.yaml#L34){target="_blank"}. `cfn-lint` ensures [best practices](https://github.com/aws-cloudformation/cfn-lint/blob/86f0370bd43b400ed4c485180dbc2697f73367b2/docs/rules.md){target=""_blank"} at our documentation examples. -* [**Markdown linting**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.pre-commit-config.yaml#L25){target="_blank}. Primarily [industry markdown practices](https://github.com/DavidAnson/markdownlint/blob/d01180ec5a014083ee9d574b693a8d7fbc1e566d/README.md#rules--aliases){target="_blank"}. We intend to create our own once we have a definitive style guide. -* [**GitHub Actions linting**](https://github.com/rhysd/actionlint/blob/main/docs/checks.md){target="_blank"}. `actionlint` ensures workflows follow [GitHub Actions security practices](https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions){target="_blank"}. It guards against numerous [leading practices](https://github.com/rhysd/actionlint/blob/main/docs/checks.md){target="_blank"} to prevent common configuration mistakes, insecure inline scripts, among many others. -* [**Terraform linting**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.pre-commit-config.yaml#L43){target="_blank"}. As of now, largely formatting until we increase our Terraform coverage in documentation examples. -* [**Secrets linting**](https://github.com/aws-powertools/powertools-lambda-python/blob/develop/.pre-commit-config.yaml#L49){target="_blank"}. Detects industry credentials that might be accidentally leaked in source code. - -#### Pre-Pull Request checks - -For an improved contributing experience, most of our checks can run locally. For maintainers, this also means increased focus on reviewing actual value instead of standards and security malpractices that can be caught earlier. - -!!! note "These are in addition to [pre-commit checks](#pre-commit-checks)." - -* [**Static typing analysis**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/Makefile#L108). `mypy` checks for static typing annotations to prevent common bugs in Python that may or may not lead to abuse. -* [**Tests**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/Makefile#L31){target="_blank"}. We run `unit`, `functional`, and `performance` tests ([_see our definition_](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/CONTRIBUTING.md#testing-definition){target="_blank"}). Besides breaking changes, we are investing in mutation testing to find additional sources of bugs and potential abuse. -* [**Security baseline**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/CONTRIBUTING.md#testing-definition){target="_blank"}. `bandit` detects common security issues defined by Python Code Quality Authority (PyCQA). -* [**Complexity baseline**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/Makefile#L79){target="_blank"}. We run a series of maintenability and cyclomatic checks to reduce code and logic complexity. This aids reviewers' cognitive overhead and long-term maintainers revisiting legacy code at a later date. - -#### Pull Request checks - -While we trust contributors and maintainers do go through pre-commit and pre-pull request due diligence, we verify them at CI level. - -!!! note "Checks described earlier are omitted to improve reading experience." - -* [**Semantic PR title**](https://github.com/Ezard/semantic-prs){target="_blank"}. We enforce PR titles follow semantic naming, for example `chore(category): change`. This benefits contributors with a lower entry bar, no need for semantic commits. It also benefits everyone looking for an [useful changelog message](https://docs.powertools.aws.dev/lambda/python/latest/changelog/){target="_blank"} on **what** changed and **where**. -* [**Related issue check**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/workflows/on_opened_pr.yml#L44){target="_blank"}. [Every change require an issue](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/CONTRIBUTING.md#contributing-via-pull-requests){target="_blank"} describing its needs. This enforces a PR has a related issue by blocking merge operations if missing. -* [**Acknowledgment check**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/workflows/on_opened_pr.yml#L63){target="_blank"}. [Ensures PR template](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/PULL_REQUEST_TEMPLATE.md#L36){target="_blank"} is used and every contributor is aware of code redistribution. -* [**Code coverage diff**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/workflows/quality_check.yml#L73){target="_blank"}. Educates contributors and maintainers about code coverage differences for a given change. -* [**Contribution size check**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/workflows/on_label_added.yml#L44){target="_blank"}. Suggests contributors and maintainers to break up large changes (100-499 LOC) in smaller PRs. It helps reduce overlooking security and other practices due to increased cognitive overhead. -* [**Dependency vulnerability check**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/workflows/dependency-review.yml#L22){target="_blank"}. Verifies any dependency changes for common vulnerability exposures (CVEs), in addition to our daily check on any dependencies used (e.g., Python, Docker, Go, etc.) -* [**GitHub Actions security check**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/workflows/secure_workflows.yml#L35){target="_blank"}. Enforces use of immutable 3rd-party GitHub Actions (_e.g., `actions/checkout@_`) to prevent abuse. Upgrades are handled by a [separate automated process](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/dependabot.yml#L4){target="_blank"} that includes a maintainer review to also prevent unexpected behavior changes. - -#### After merge checks - -!!! note "Checks described earlier are omitted to improve reading experience." - -We strike a balance in security and contribution experience. These automated checks take several minutes to complete. Failures are reviewed by a maintainer on-call and before a release. - -* [**End-to-end tests**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/workflows/run-e2e-tests.yml#L41){target="_blank"}. We run E2E with a [high degree of parallelization](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/MAINTAINERS.md#test-runner-parallelization). While it is designed to also run locally, it may incur AWS charges to contributors. For additional security, all infrastructure is ephemeral per change and per Python version. -* [**SAST check**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/workflows/codeql-analysis.yml#L20){target="_blank"}. GitHub CodeQL runs ~30m static analysis in the entire codebase. -* [**Security posture check**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/workflows/ossf_scorecard.yml#L14){target="_blank"}. OSSF Scorecard runs numerous automated checks upon changes, and raises security alerts if [OSSF security practices](https://bestpractices.coreinfrastructure.org/en/criteria){target="_blank"} are no longer followed. -* [**Rebuild Changelog**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/workflows/build_changelog.yml#L23){target="_blank"}. We rebuild our entire changelog upon changes and create a PR for maintainers. This has the added benefit in keeping a [protected branch](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/about-protected-branches){target="_blank"} while keeping removing error-prone tasks from maintainers. -* [**Stage documentation**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/workflows/on_push_docs.yml#L27C16-L27C16){target="_blank"}. We rebuild and deploy changes to the documentation to a [staged version](https://docs.powertools.aws.dev/lambda/python/stage/){target="_blank"}. This gives us safety that our docs can always be rebuilt, and ready to release to production when needed. -* [**Update draft release**](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/.github/workflows/release-drafter.yml#L25){target="_blank"}. We use [Release Drafter](https://github.com/release-drafter/release-drafter){target="_blank"} to generate a portion of our release notes and to always keep a fresh draft upon changes. You can read our [thoughts on a good quality release notes here](https://github.com/aws-powertools/powertools-lambda-python/blob/0523ff64606514ea3e59c07c8c69c83d751f61fa/MAINTAINERS.md#drafting-release-notes){target="_blank"} (human readable changes + automation). - -### Continuous deployment practices - -!!! note "We adhere to industry recommendations from the [OSSF Scorecard project](https://bestpractices.coreinfrastructure.org/en/criteria){target="_blank"}, among [others](https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions){target="_blank"}." - -Releases are triggered by maintainers along with a reviewer - [detailed info here](https://github.com/aws-powertools/powertools-lambda-python/blob/develop/MAINTAINERS.md#releasing-a-new-version){target="_blank"}. In addition to [checks that run for every code change](#continuous-integration-practices), our pipeline requires a manual approval before releasing. - -We use a combination of provenance and signed attestation for our builds, source code sealing, SAST scanners, Python specific static code analysis, ephemeral credentials that last a given job step, and more. - -This is a snapshot of our automated checks at a glance. - -![Continuous Deployment practices](./media/continuous_deployment_practices.png) diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css index ca6ab06903d..8d6903b5f75 100644 --- a/docs/stylesheets/extra.css +++ b/docs/stylesheets/extra.css @@ -22,6 +22,14 @@ font-size: 0.75rem } +.md-tabs__link { + font-size: 0.8rem +} + +.md-tabs__link--active { + border-bottom: 6px solid white +} + .md-nav__link--active { font-weight: bold } diff --git a/mkdocs.yml b/mkdocs.yml index 2315152a3c9..1b9c7db95a3 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -5,34 +5,36 @@ repo_url: https://github.com/aws-powertools/powertools-lambda-python edit_uri: edit/develop/docs nav: - - Homepage: index.md - - Changelog: changelog.md + - Homepage: + - index.md + - Changelog: changelog.md + - API reference: api/" target="_blank + - Upgrade guide: upgrade.md + - Features: + - core/tracer.md + - core/logger.md + - core/metrics.md + - Event Handler: + - core/event_handler/api_gateway.md + - core/event_handler/appsync.md + - utilities/parameters.md + - utilities/batch.md + - utilities/typing.md + - utilities/validation.md + - utilities/data_classes.md + - utilities/parser.md + - utilities/idempotency.md + - utilities/feature_flags.md + - utilities/streaming.md + - utilities/middleware_factory.md + - utilities/jmespath_functions.md + - CloudFormation Custom Resources: https://github.com/aws-cloudformation/custom-resource-helper" target="_blank - Tutorial: tutorial/index.md - - Roadmap: roadmap.md - - API reference: api/" target="_blank - - Upgrade guide: upgrade.md - We Made This (Community): we_made_this.md - - Security: security.md - - Core utilities: - - core/tracer.md - - core/logger.md - - core/metrics.md - - Event Handler: - - core/event_handler/api_gateway.md - - core/event_handler/appsync.md - - Utilities: - - utilities/parameters.md - - utilities/batch.md - - utilities/typing.md - - utilities/validation.md - - utilities/data_classes.md - - utilities/parser.md - - utilities/idempotency.md - - utilities/feature_flags.md - - utilities/streaming.md - - utilities/middleware_factory.md - - utilities/jmespath_functions.md - - CloudFormation Custom Resources: https://github.com/aws-cloudformation/custom-resource-helper" target="_blank + - Processes: + - Security: security.md + - Automation: automation.md + - Roadmap: roadmap.md theme: name: material @@ -42,13 +44,13 @@ theme: - scheme: default primary: deep purple toggle: - icon: material/toggle-switch-off-outline + icon: material/lightbulb name: Switch to dark mode - scheme: slate primary: indigo accent: teal toggle: - icon: material/toggle-switch + icon: material/lightbulb-outline name: Switch to light mode features: - header.autohide @@ -58,6 +60,7 @@ theme: - navigation.instant - navigation.indexes - navigation.tracking + - navigation.tabs - content.code.annotate - content.code.copy icon: From 8a6fa941a4225cb1f3c21a0df0e1e1f45011e2f0 Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Thu, 13 Jul 2023 14:59:48 +0200 Subject: [PATCH 3/4] docs(process): move maintainers playbook to docs --- MAINTAINERS.md | 805 +-------------------------------- docs/diagram_src/cicd_steps.md | 106 +++++ docs/maintainers.md | 662 +++++++++++++++++++++++++++ mkdocs.yml | 3 +- 4 files changed, 772 insertions(+), 804 deletions(-) create mode 100644 docs/diagram_src/cicd_steps.md create mode 100644 docs/maintainers.md diff --git a/MAINTAINERS.md b/MAINTAINERS.md index be831ef46d4..2fa7b2eed23 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -1,804 +1,3 @@ - -## Table of contents + -- [Overview](#overview) -- [Current Maintainers](#current-maintainers) -- [Emeritus](#emeritus) -- [Labels](#labels) -- [Maintainer Responsibilities](#maintainer-responsibilities) - - [Uphold Code of Conduct](#uphold-code-of-conduct) - - [Prioritize Security](#prioritize-security) - - [Review Pull Requests](#review-pull-requests) - - [Triage New Issues](#triage-new-issues) - - [Triage Bug Reports](#triage-bug-reports) - - [Triage RFCs](#triage-rfcs) - - [Releasing a new version](#releasing-a-new-version) - - [Release process visualized](#release-process-visualized) - - [Drafting release notes](#drafting-release-notes) - - [Run end to end tests](#run-end-to-end-tests) - - [Releasing a documentation hotfix](#releasing-a-documentation-hotfix) - - [Maintain Overall Health of the Repo](#maintain-overall-health-of-the-repo) - - [Manage Roadmap](#manage-roadmap) - - [Add Continuous Integration Checks](#add-continuous-integration-checks) - - [Negative Impact on the Project](#negative-impact-on-the-project) - - [Becoming a maintainer](#becoming-a-maintainer) -- [Common scenarios](#common-scenarios) - - [Contribution is stuck](#contribution-is-stuck) - - [Insufficient feedback or information](#insufficient-feedback-or-information) - - [Crediting contributions](#crediting-contributions) - - [Is that a bug?](#is-that-a-bug) - - [Mentoring contributions](#mentoring-contributions) - - [Long running issues or PRs](#long-running-issues-or-prs) -- [E2E framework](#e2e-framework) - - [Structure](#structure) - - [Mechanics](#mechanics) - - [Authoring a new feature E2E test](#authoring-a-new-feature-e2e-test) - - [1. Define infrastructure](#1-define-infrastructure) - - [2. Deploy/Delete infrastructure when tests run](#2-deploydelete-infrastructure-when-tests-run) - - [3. Access stack outputs for E2E tests](#3-access-stack-outputs-for-e2e-tests) - - [Internals](#internals) - - [Test runner parallelization](#test-runner-parallelization) - - [CDK CLI parallelization](#cdk-cli-parallelization) - -## Overview - -> **Please treat this content as a living document.** - -This is document explains who the maintainers are (see below), what they do in this repo, and how they should be doing it. If you're interested in contributing, see [CONTRIBUTING](CONTRIBUTING.md). - -## Current Maintainers - -| Maintainer | GitHub ID | Affiliation | -| ----------------- | ------------------------------------------------------- | ----------- | -| Heitor Lessa | [heitorlessa](https://github.com/heitorlessa) | Amazon | -| Simon Thulbourn | [sthulb](https://github.com/sthulb) | Amazon | -| Ruben Fonseca | [rubenfonseca](https://github.com/rubenfonseca) | Amazon | -| Leandro Damascena | [leandrodamascena](https://github.com/leandrodamascena) | Amazon | - -## Emeritus - -Previous active maintainers who contributed to this project. - -| Maintainer | GitHub ID | Affiliation | -| ----------------- | ----------------------------------------------- | ----------- | -| Tom McCarthy | [cakepietoast](https://github.com/cakepietoast) | MongoDB | -| Nicolas Moutschen | [nmoutschen](https://github.com/nmoutschen) | Apollo | -| Alexander Melnyk | [am29d](https://github.com/am29d) | Amazon | -| Michal Ploski | [mploski](https://github.com/mploski) | Amazon | - -## Labels - -These are the most common labels used by maintainers to triage issues, pull requests (PR), and for project management: - -| Label | Usage | Notes | -| ---------------------- | ---------------------------------------------------------------------------------------- | --------------------------------------------------------------- | -| triage | New issues that require maintainers review | Issue template | -| bug | Unexpected, reproducible and unintended software behavior | PR/Release automation; Doc snippets are excluded; | -| not-a-bug | New and existing bug reports incorrectly submitted as bug | Analytics | -| documentation | Documentation improvements | PR/Release automation; Doc additions, fixes, etc.; | -| feature-request | New or enhancements to existing features | Issue template | -| typing | New or enhancements to static typing | Issue template | -| RFC | Technical design documents related to a feature request | Issue template | -| bug-upstream | Bug caused by upstream dependency | | -| help wanted | Tasks you want help from anyone to move forward | Bandwidth, complex topics, etc. | -| need-customer-feedback | Tasks that need more feedback before proceeding | 80/20% rule, uncertain, etc. | -| need-more-information | Missing information before making any calls | | -| need-documentation | PR is missing or has incomplete documentation | | -| need-issue | PR is missing a related issue for tracking change | PR automation | -| need-rfc | Feature request requires a RFC to improve discussion | | -| pending-release | Merged changes that will be available soon | Release automation auto-closes/notifies it | -| revisit-in-3-months | Blocked issues/PRs that need to be revisited | Often related to `need-customer-feedback`, prioritization, etc. | -| breaking-change | Changes that will cause customer impact and need careful triage | | -| do-not-merge | PRs that are blocked for varying reasons | Timeline is uncertain | -| size/XS | PRs between 0-9 LOC | PR automation | -| size/S | PRs between 10-29 LOC | PR automation | -| size/M | PRs between 30-99 LOC | PR automation | -| size/L | PRs between 100-499 LOC | PR automation | -| size/XL | PRs between 500-999 LOC, often PRs that grown with feedback | PR automation | -| size/XXL | PRs with 1K+ LOC, largely documentation related | PR automation | -| tests | PRs that add or change tests | PR automation | -| `` | PRs related to a Powertools for AWS Lambda (Python) utility, e.g. `parameters`, `tracer` | PR automation | -| feature | New features or minor changes | PR/Release automation | -| dependencies | Changes that touch dependencies, e.g. Dependabot, etc. | PR/ automation | -| github-actions | Changes in GitHub workflows | PR automation | -| github-templates | Changes in GitHub issue/PR templates | PR automation | -| internal | Changes in governance and chores (linting setup, baseline, etc.) | PR automation | -| tech-debt | Changes in tech debt | | -| customer-reference | Authorization to use company name in our documentation | Public Relations | -| community-content | Suggested content to feature in our documentation | Public Relations | - -## Maintainer Responsibilities - -Maintainers are active and visible members of the community, and have [maintain-level permissions on a repository](https://docs.github.com/en/organizations/managing-access-to-your-organizations-repositories/repository-permission-levels-for-an-organization). Use those privileges to serve the community and evolve code as follows. - -Be aware of recurring ambiguous situations and [document them](#common-scenarios) to help your fellow maintainers. - -### Uphold Code of Conduct - -Model the behavior set forward by the [Code of Conduct](CODE_OF_CONDUCT.md) and raise any violations to other maintainers and admins. There could be unusual circumstances where inappropriate behavior does not immediately fall within the [Code of Conduct](CODE_OF_CONDUCT.md). - -These might be nuanced and should be handled with extra care - when in doubt, do not engage and reach out to other maintainers and admins. - -### Prioritize Security - -Security is your number one priority. Maintainer's Github keys must be password protected securely and any reported security vulnerabilities are addressed before features or bugs. - -Note that this repository is monitored and supported 24/7 by Amazon Security, see [Reporting a Vulnerability](SECURITY.md) for details. - -### Review Pull Requests - -Review pull requests regularly, comment, suggest, reject, merge and close. Accept only high quality pull-requests. Provide code reviews and guidance on incoming pull requests. - -PRs are [labeled](#labels) based on file changes and semantic title. Pay attention to whether labels reflect the current state of the PR and correct accordingly. - -Use and enforce [semantic versioning](https://semver.org/) pull request titles, as these will be used for [CHANGELOG](CHANGELOG.md) and [Release notes](https://github.com/aws-powertools/powertools-lambda-python/releases) - make sure they communicate their intent at the human level. - -> TODO: This is an area we want to automate using the new GitHub GraphQL API. - -For issues linked to a PR, make sure `pending release` label is applied to them when merging. [Upon release](#releasing-a-new-version), these issues will be notified which release version contains their change. - -See [Common scenarios](#common-scenarios) section for additional guidance. - -### Triage New Issues - -Manage [labels](#labels), review issues regularly, and create new labels as needed by the project. Remove `triage` label when you're able to confirm the validity of a request, a bug can be reproduced, etc. Give priority to the original author for implementation, unless it is a sensitive task that is best handled by maintainers. - -> TODO: This is an area we want to automate using the new GitHub GraphQL API. - -Make sure issues are assigned to our [board of activities](https://github.com/orgs/awslabs/projects/51/) and have the right [status](https://docs.powertools.aws.dev/lambda/python/latest/roadmap/#roadmap-status-definition). - -Use our [labels](#labels) to signal good first issues to new community members, and to set expectation that this might need additional feedback from the author, other customers, experienced community members and/or maintainers. - -Be aware of [casual contributors](https://opensource.com/article/17/10/managing-casual-contributors) and recurring contributors. Provide the experience and attention you wish you had if you were starting in open source. - -See [Common scenarios](#common-scenarios) section for additional guidance. - -### Triage Bug Reports - -Be familiar with [our definition of bug](#is-that-a-bug). If it's not a bug, you can close it or adjust its title and labels - always communicate the reason accordingly. - -For bugs caused by upstream dependencies, replace `bug` with `bug-upstream` label. Ask the author whether they'd like to raise the issue upstream or if they prefer us to do so. - -Assess the impact and make the call on whether we need an emergency release. Contact other [maintainers](#current-maintainers) when in doubt. - -See [Common scenarios](#common-scenarios) section for additional guidance. - -### Triage RFCs - -RFC is a collaborative process to help us get to the most optimal solution given the context. Their purpose is to ensure everyone understands what this context is, their trade-offs, and alternative solutions that were part of the research before implementation begins. - -Make sure you ask these questions in mind when reviewing: - -- Does it use our [RFC template](https://github.com/aws-powertools/powertools-lambda-python/issues/new?assignees=&labels=RFC%2Ctriage&template=rfc.yml&title=RFC%3A+TITLE)? -- Does the match our [Tenets](https://docs.powertools.aws.dev/lambda/python/latest/#tenets)? -- Does the proposal address the use case? If so, is the recommended usage explicit? -- Does it focus on the mechanics to solve the use case over fine-grained implementation details? -- Can anyone familiar with the code base implement it? -- If approved, are they interested in contributing? Do they need any guidance? -- Does this significantly increase the overall project maintenance? Do we have the skills to maintain it? -- If we can't take this use case, are there alternative projects we could recommend? Or does it call for a new project altogether? - -When necessary, be upfront that the time to review, approve, and implement a RFC can vary - see [Contribution is stuck](#contribution-is-stuck). Some RFCs may be further updated after implementation, as certain areas become clearer. - -Some examples using our initial and new RFC templates: #92, #94, #95, #991, #1226 - -### Releasing a new version - -Firstly, make sure the commit history in the `develop` branch **(1)** it's up to date, **(2)** commit messages are semantic, and **(3)** commit messages have their respective area, for example `feat(logger): `, `chore(ci): ...`). - -**Looks good, what's next?** - -Kickoff the `Release` workflow with the intended version - this might take around 25m-30m to complete. - -Once complete, you can start drafting the release notes to let customers know **what changed and what's in it for them (a.k.a why they should care)**. We have guidelines in the release notes section so you know what good looks like. - -> **NOTE**: Documentation might take a few minutes to reflect the latest version due to caching and CDN invalidations. - -#### Release process visualized - -Every release makes hundreds of checks, security scans, canaries and deployments - all of these are automated. - -This is a close visual representation of the main steps (GitHub Actions UI should be the source of truth), along with the approximate time it takes for each key step to complete. - - - -```mermaid -gantt - -title Release process -dateFormat HH:mm -axisFormat %H:%M - -Release commit : milestone, m1, 10:00,2m - -section Seal - Bump release version : active, 8s - Prevent source tampering : active, 43s -section QA - Quality checks : active, 2.2m -section Build - Checksum : active, 8s - Build release artifact : active, 39s - Seal : active, 8s -section Provenance - Attest build : active, 8s - Sign attestation : active, attestation, 10:06, 8s - -section Release - Checksum : active, 8s - PyPi temp credentials : active, 8s - Publish PyPi : active, pypi, 10:07, 29s - -PyPi release : milestone, m2, 10:07,1s - -section Git release - Checksum : active, after pypi, 8s - Git Tag : active, 8s - Bump package version : active, 8s - Create PR : active, 8s - Upload attestation : active, 8s - -section Layer release - Build (x86+ARM) : active, layer_build, 10:08, 6m - Deploy Beta : active, layer_beta, after layer_build, 6.3m - Deploy Prod : active, layer_prod, after layer_beta, 6.3m - -Layer release : milestone, m3, 10:26,1s - -section SAR release - Deploy Beta : active, sar_beta, after layer_beta, 2.2m - Deploy Prod : active, sar_prod, after sar_beta, 2.2m - -SAR release : milestone, m4, 10:25,1s - -section Docs - Create PR (Layer ARN) : active, after layer_prod, 8s - Release versioned docs : active, 2.2m - -Documentation release : milestone, m4, 10:28,1m - -section Post-release - Close pending issues : active, 8s - -Release complete : milestone, m6, 10:31,2m -``` - -If we combine our CI and CD pipelines into a single diagram, it looks like this: - -```mermaid -timeline - title Powertools for AWS Lambda (Python) CI/CD pipeline - - section Continuous Integration - Project setup
(make dev) : Code checkout - : Virtual environment - : Dependencies - : Git pre-commit hooks - : Local branch - : Local changes - : Local tests - - Pre-commit checks
(git commit) : Merge conflict check - : Trailing whitespaces - : TOML checks - : Code linting (standards) - : Markdown linting - : CloudFormation linting - : GitHub Actions linting - : Terraform linting - : Secrets linting - - Pre-Pull Request
(make pr) : Code linting - : Docs linting - : Static typing analysis - : Tests (unit|functional|perf) - : Security baseline - : Complexity baseline - : +pre-commit checks - - Pull Request
(CI checks) : Semantic PR title check - : Related issue check - : Acknowledgment check - : Code coverage diff - : Contribution size check - : Contribution category check - : Dependency vulnerability check - : GitHub Actions security check - : +pre-pull request checks - - After merge
(CI checks) : End-to-end tests - : Longer SAST check - : Security posture check (scorecard) - : GitHub Actions security check - : Rebuild Changelog - : Deploy staging docs - : Update draft release - - section Continuous Delivery - - Source code anti-tampering : Checkout release commit code - : Bump release version - : Seal and upload artifact - - Quality Assurance : Restore sealed code - : +Continuous Integration checks - - Build : Restore sealed code - : Integrity check - : Build release artifact - : Seal and upload artifact - - Provenance : Detect build environment - : Generate SLSA Builder - : Verify SLSA Builder provenance - : Create and sign provenance - : Seal and upload artifact - : Write to public ledger - - Release : Restore sealed build - : Integrity check - : PyPi ephemeral credentials - : Publish PyPi - : Baking time - - Git tagging : Restore sealed code - : Integrity check - : Bump git tag - : Create temporary branch - : Create PR - - Lambda Layers : Fetch PyPi release - : Build x86 architecture - : Build ARM architecture - : Deploy Beta - : Canary testing - : Deploy Prod - - Lambda Layers SAR : Deploy Beta - : Deploy Prod - - Documentation : Update Lambda Layer ARNs - : Build User Guide - : Build API Guide - : Rebuild Changelog - : Release new version - : Update latest alias - : Create temporary branch - : Create PR - - Post-release : Close pending-release issues - : Notify customers -``` - -#### Drafting release notes - -Visit the [Releases page](https://github.com/aws-powertools/powertools-lambda-python/releases) and choose the edit pencil button. - -Make sure the `tag` field reflects the new version you're releasing, the target branch field is set to `develop`, and `release title` matches your tag e.g., `v1.26.0`. - -You'll notice we group all changes based on their [labels](#labels) like `feature`, `bug`, `documentation`, etc. - -**I spotted a typo or incorrect grouping - how do I fix it?** - -Edit the respective PR title and update their [labels](#labels). Then run the [Release Drafter workflow](https://github.com/aws-powertools/powertools-lambda-python/actions/workflows/release-drafter.yml) to update the Draft release. - -> **NOTE**: This won't change the CHANGELOG as the merge commit is immutable. Don't worry about it. We'd only rewrite git history only if this can lead to confusion and we'd pair with another maintainer. - -**All looking good, what's next?** - -The best part comes now. Replace the placeholder `[Human readable summary of changes]` with what you'd like to communicate to customers what this release is all about. Rule of thumb: always put yourself in the customers shoes. - -These are some questions to keep in mind when drafting your first or future release notes: - -- Can customers understand at a high level what changed in this release? -- Is there a link to the documentation where they can read more about each main change? -- Are there any graphics or [code snippets](carbon.now.sh/) that can enhance readability? -- Are we calling out any key contributor(s) to this release? - - All contributors are automatically credited, use this as an exceptional case to feature them - -Once you're happy, hit `Publish release` πŸŽ‰πŸŽ‰πŸŽ‰. - -This will kick off the [Publishing workflow](https://github.com/aws-powertools/powertools-lambda-python/actions/workflows/release.yml) and within a few minutes you should see the latest version in PyPi, and all issues labeled as `pending-release` will be closed and notified. - -### Run end to end tests - -E2E tests are run on every push to `develop` or manually via [run-e2e-tests workflow](https://github.com/aws-powertools/powertools-lambda-python/actions/workflows/run-e2e-tests.yml). - -To run locally, you need [AWS CDK CLI](https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html#getting_started_prerequisites) and an [account bootstrapped](https://docs.aws.amazon.com/cdk/v2/guide/bootstrapping.html) (`cdk bootstrap`). With a default AWS CLI profile configured, or `AWS_PROFILE` environment variable set, run `make e2e tests`. - -### Releasing a documentation hotfix - -You can rebuild the latest documentation without a full release via this [GitHub Actions Workflow](https://github.com/aws-powertools/powertools-lambda-python/actions/workflows/rebuild_latest_docs.yml). Choose `Run workflow`, keep `develop` as the branch, and input the latest Powertools for AWS Lambda (Python) version available. - -This workflow will update both user guide and API documentation. - -### Maintain Overall Health of the Repo - -> TODO: Coordinate renaming `develop` to `main` - -Keep the `develop` branch at production quality at all times. Backport features as needed. Cut release branches and tags to enable future patches. - -### Manage Roadmap - -See [Roadmap section](https://docs.powertools.aws.dev/lambda/python/latest/roadmap/) - -Ensure the repo highlights features that should be elevated to the project roadmap. Be clear about the feature’s status, priority, target version, and whether or not it should be elevated to the roadmap. - -### Add Continuous Integration Checks - -Add integration checks that validate pull requests and pushes to ease the burden on Pull Request reviewers. Continuously revisit areas of improvement to reduce operational burden in all parties involved. - -### Negative Impact on the Project - -Actions that negatively impact the project will be handled by the admins, in coordination with other maintainers, in balance with the urgency of the issue. Examples would be [Code of Conduct](CODE_OF_CONDUCT.md) violations, deliberate harmful or malicious actions, spam, monopolization, and security risks. - -### Becoming a maintainer - -In 2023, we will revisit this. We need to improve our understanding of how other projects are doing, their mechanisms to promote key contributors, and how they interact daily. - -We suspect this process might look similar to the [OpenSearch project](https://github.com/opensearch-project/.github/blob/main/MAINTAINERS.md#becoming-a-maintainer). - -## Common scenarios - -These are recurring ambiguous situations that new and existing maintainers may encounter. They serve as guidance. It is up to each maintainer to follow, adjust, or handle in a different manner as long as [our conduct is consistent](#uphold-code-of-conduct) - -### Contribution is stuck - -A contribution can get stuck often due to lack of bandwidth and language barrier. For bandwidth issues, check whether the author needs help. Make sure you get their permission before pushing code into their existing PR - do not create a new PR unless strictly necessary. - -For language barrier and others, offer a 1:1 chat to get them unblocked. Often times, English might not be their primary language, and writing in public might put them off, or come across not the way they intended to be. - -In other cases, you may have constrained capacity. Use `help wanted` label when you want to signal other maintainers and external contributors that you could use a hand to move it forward. - -### Insufficient feedback or information - -When in doubt, use `need-more-information` or `need-customer-feedback` labels to signal more context and feedback are necessary before proceeding. You can also use `revisit-in-3-months` label when you expect it might take a while to gather enough information before you can decide. - -### Crediting contributions - -We credit all contributions as part of each [release note](https://github.com/aws-powertools/powertools-lambda-python/releases) as an automated process. If you find contributors are missing from the release note you're producing, please add them manually. - -### Is that a bug? - -A bug produces incorrect or unexpected results at runtime that differ from its intended behavior. Bugs must be reproducible. They directly affect customers experience at runtime despite following its recommended usage. - -Documentation snippets, use of internal components, or unadvertised functionalities are not considered bugs. - -### Mentoring contributions - -Always favor mentoring issue authors to contribute, unless they're not interested or the implementation is sensitive (_e.g., complexity, time to release, etc._). - -Make use of `help wanted` and `good first issue` to signal additional contributions the community can help. - -### Long running issues or PRs - -Try offering a 1:1 call in the attempt to get to a mutual understanding and clarify areas that maintainers could help. - -In the rare cases where both parties don't have the bandwidth or expertise to continue, it's best to use the `revisit-in-3-months` label. By then, see if it's possible to break the PR or issue in smaller chunks, and eventually close if there is no progress. - -## E2E framework - -### Structure - -Our E2E framework relies on [Pytest fixtures](https://docs.pytest.org/en/6.2.x/fixture.html) to coordinate infrastructure and test parallelization - see [Test Parallelization](#test-runner-parallelization) and [CDK CLI Parallelization](#cdk-cli-parallelization). - -**tests/e2e structure** - -```shell -. -β”œβ”€β”€ __init__.py -β”œβ”€β”€ conftest.py # builds Lambda Layer once -β”œβ”€β”€ logger -β”‚ β”œβ”€β”€ __init__.py -β”‚ β”œβ”€β”€ conftest.py # deploys LoggerStack -β”‚ β”œβ”€β”€ handlers -β”‚ β”‚ └── basic_handler.py -β”‚ β”œβ”€β”€ infrastructure.py # LoggerStack definition -β”‚ └── test_logger.py -β”œβ”€β”€ metrics -β”‚ β”œβ”€β”€ __init__.py -β”‚ β”œβ”€β”€ conftest.py # deploys MetricsStack -β”‚ β”œβ”€β”€ handlers -β”‚ β”‚ β”œβ”€β”€ basic_handler.py -β”‚ β”‚ └── cold_start.py -β”‚ β”œβ”€β”€ infrastructure.py # MetricsStack definition -β”‚ └── test_metrics.py -β”œβ”€β”€ tracer -β”‚ β”œβ”€β”€ __init__.py -β”‚ β”œβ”€β”€ conftest.py # deploys TracerStack -β”‚ β”œβ”€β”€ handlers -β”‚ β”‚ β”œβ”€β”€ async_capture.py -β”‚ β”‚ └── basic_handler.py -β”‚ β”œβ”€β”€ infrastructure.py # TracerStack definition -β”‚ └── test_tracer.py -└── utils - β”œβ”€β”€ __init__.py - β”œβ”€β”€ data_builder # build_service_name(), build_add_dimensions_input, etc. - β”œβ”€β”€ data_fetcher # get_traces(), get_logs(), get_lambda_response(), etc. - β”œβ”€β”€ infrastructure.py # base infrastructure like deploy logic, etc. -``` - -Where: - -- **`/infrastructure.py`**. Uses CDK to define the infrastructure a given feature needs. -- **`/handlers/`**. Lambda function handlers to build, deploy, and exposed as stack output in PascalCase (e.g., `BasicHandler`). -- **`utils/`**. Test utilities to build data and fetch AWS data to ease assertion -- **`conftest.py`**. Deploys and deletes a given feature infrastructure. Hierarchy matters: - - **Top-level (`e2e/conftest`)**. Builds Lambda Layer only once and blocks I/O across all CPU workers. - - **Feature-level (`e2e//conftest`)**. Deploys stacks in parallel and make them independent of each other. - -### Mechanics - -Under [`BaseInfrastructure`](https://github.com/aws-powertools/powertools-lambda-python/blob/develop/tests/e2e/utils/infrastructure.py), we hide the complexity of deployment and delete coordination under `deploy`, `delete`, and `create_lambda_functions` methods. - -This allows us to benefit from test and deployment parallelization, use IDE step-through debugging for a single test, run one, subset, or all tests and only deploy their related infrastructure, without any custom configuration. - -> Class diagram to understand abstraction built when defining a new stack (`LoggerStack`) - -```mermaid -classDiagram - class InfrastructureProvider { - <> - +deploy() Dict - +delete() - +create_resources() - +create_lambda_functions() Dict~Functions~ - } - - class BaseInfrastructure { - +deploy() Dict - +delete() - +create_lambda_functions() Dict~Functions~ - +add_cfn_output() - } - - class TracerStack { - +create_resources() - } - - class LoggerStack { - +create_resources() - } - - class MetricsStack { - +create_resources() - } - - class EventHandlerStack { - +create_resources() - } - - InfrastructureProvider <|-- BaseInfrastructure : implement - BaseInfrastructure <|-- TracerStack : inherit - BaseInfrastructure <|-- LoggerStack : inherit - BaseInfrastructure <|-- MetricsStack : inherit - BaseInfrastructure <|-- EventHandlerStack : inherit -``` - -### Authoring a new feature E2E test - -Imagine you're going to create E2E for Event Handler feature for the first time. Keep the following mental model when reading: - -```mermaid -graph LR - A["1. Define infrastructure"]-->B["2. Deploy/Delete infrastructure"]-->C["3.Access Stack outputs" ] -``` - -#### 1. Define infrastructure - -We use CDK as our Infrastructure as Code tool of choice. Before you start using CDK, you'd take the following steps: - -1. Create `tests/e2e/event_handler/infrastructure.py` file -2. Create a new class `EventHandlerStack` and inherit from `BaseInfrastructure` -3. Override `create_resources` method and define your infrastructure using CDK -4. (Optional) Create a Lambda function under `handlers/alb_handler.py` - -> Excerpt `tests/e2e/event_handler/infrastructure.py` - -```python -class EventHandlerStack(BaseInfrastructure): - def create_resources(self): - functions = self.create_lambda_functions() - - self._create_alb(function=functions["AlbHandler"]) - ... - - def _create_alb(self, function: Function): - vpc = ec2.Vpc.from_lookup( - self.stack, - "VPC", - is_default=True, - region=self.region, - ) - - alb = elbv2.ApplicationLoadBalancer(self.stack, "ALB", vpc=vpc, internet_facing=True) - CfnOutput(self.stack, "ALBDnsName", value=alb.load_balancer_dns_name) - ... -``` - -> Excerpt `tests/e2e/event_handler/handlers/alb_handler.py` - -```python -from aws_lambda_powertools.event_handler import ALBResolver, Response, content_types - -app = ALBResolver() - - -@app.get("/todos") -def hello(): - return Response( - status_code=200, - content_type=content_types.TEXT_PLAIN, - body="Hello world", - cookies=["CookieMonster", "MonsterCookie"], - headers={"Foo": ["bar", "zbr"]}, - ) - - -def lambda_handler(event, context): - return app.resolve(event, context) -``` - -#### 2. Deploy/Delete infrastructure when tests run - -We need to create a Pytest fixture for our new feature under `tests/e2e/event_handler/conftest.py`. - -This will instruct Pytest to deploy our infrastructure when our tests start, and delete it when they complete whether tests are successful or not. Note that this file will not need any modification in the future. - -> Excerpt `conftest.py` for Event Handler - -```python -import pytest - -from tests.e2e.event_handler.infrastructure import EventHandlerStack - - -@pytest.fixture(autouse=True, scope="module") -def infrastructure(): - """Setup and teardown logic for E2E test infrastructure - - Yields - ------ - Dict[str, str] - CloudFormation Outputs from deployed infrastructure - """ - stack = EventHandlerStack() - try: - yield stack.deploy() - finally: - stack.delete() - -``` - -#### 3. Access stack outputs for E2E tests - -Within our tests, we should now have access to the `infrastructure` fixture we defined earlier in `tests/e2e/event_handler/conftest.py`. - -We can access any Stack Output using pytest dependency injection. - -> Excerpt `tests/e2e/event_handler/test_header_serializer.py` - -```python -@pytest.fixture -def alb_basic_listener_endpoint(infrastructure: dict) -> str: - dns_name = infrastructure.get("ALBDnsName") - port = infrastructure.get("ALBBasicListenerPort", "") - return f"http://{dns_name}:{port}" - - -def test_alb_headers_serializer(alb_basic_listener_endpoint): - # GIVEN - url = f"{alb_basic_listener_endpoint}/todos" - ... -``` - -### Internals - -#### Test runner parallelization - -Besides speed, we parallelize our end-to-end tests to ease asserting async side-effects may take a while per test too, _e.g., traces to become available_. - -The following diagram demonstrates the process we take every time you use `make e2e` locally or at CI: - -```mermaid -graph TD - A[make e2e test] -->Spawn{"Split and group tests
by feature and CPU"} - - Spawn -->|Worker0| Worker0_Start["Load tests"] - Spawn -->|Worker1| Worker1_Start["Load tests"] - Spawn -->|WorkerN| WorkerN_Start["Load tests"] - - Worker0_Start -->|Wait| LambdaLayer["Lambda Layer build"] - Worker1_Start -->|Wait| LambdaLayer["Lambda Layer build"] - WorkerN_Start -->|Wait| LambdaLayer["Lambda Layer build"] - - LambdaLayer -->|Worker0| Worker0_Deploy["Launch feature stack"] - LambdaLayer -->|Worker1| Worker1_Deploy["Launch feature stack"] - LambdaLayer -->|WorkerN| WorkerN_Deploy["Launch feature stack"] - - Worker0_Deploy -->|Worker0| Worker0_Tests["Run tests"] - Worker1_Deploy -->|Worker1| Worker1_Tests["Run tests"] - WorkerN_Deploy -->|WorkerN| WorkerN_Tests["Run tests"] - - Worker0_Tests --> ResultCollection - Worker1_Tests --> ResultCollection - WorkerN_Tests --> ResultCollection - - ResultCollection{"Wait for workers
Collect test results"} - ResultCollection --> TestEnd["Report results"] - ResultCollection --> DeployEnd["Delete Stacks"] -``` - -#### CDK CLI parallelization - -For CDK CLI to work with [independent CDK Apps](https://docs.aws.amazon.com/cdk/v2/guide/apps.html), we specify an output directory when synthesizing our stack and deploy from said output directory. - -```mermaid -flowchart TD - subgraph "Deploying distinct CDK Apps" - EventHandlerInfra["Event Handler CDK App"] --> EventHandlerSynth - TracerInfra["Tracer CDK App"] --> TracerSynth - EventHandlerSynth["cdk synth --out cdk.out/event_handler"] --> EventHandlerDeploy["cdk deploy --app cdk.out/event_handler"] - - TracerSynth["cdk synth --out cdk.out/tracer"] --> TracerDeploy["cdk deploy --app cdk.out/tracer"] - end -``` - -We create the typical CDK `app.py` at runtime when tests run, since we know which feature and Python version we're dealing with (locally or at CI). - -> Excerpt `cdk_app_V39.py` for Event Handler created at deploy phase - -```python -from tests.e2e.event_handler.infrastructure import EventHandlerStack -stack = EventHandlerStack() -stack.create_resources() -stack.app.synth() -``` - -When we run E2E tests for a single feature or all of them, our `cdk.out` looks like this: - -```shell -total 8 -drwxr-xr-x 18 lessa staff 576B Sep 6 15:38 event-handler -drwxr-xr-x 3 lessa staff 96B Sep 6 15:08 layer_build --rw-r--r-- 1 lessa staff 32B Sep 6 15:08 layer_build.diff -drwxr-xr-x 18 lessa staff 576B Sep 6 15:38 logger -drwxr-xr-x 18 lessa staff 576B Sep 6 15:38 metrics -drwxr-xr-x 22 lessa staff 704B Sep 9 10:52 tracer -``` - -```mermaid -classDiagram - class CdkOutDirectory { - feature_name/ - layer_build/ - layer_build.diff - } - - class EventHandler { - manifest.json - stack_outputs.json - cdk_app_V39.py - asset.uuid/ - ... - } - - class StackOutputsJson { - BasicHandlerArn: str - ALBDnsName: str - ... - } - - CdkOutDirectory <|-- EventHandler : feature_name/ - StackOutputsJson <|-- EventHandler -``` - -Where: - -- **``**. Contains CDK Assets, CDK `manifest.json`, our `cdk_app_.py` and `stack_outputs.json` -- **`layer_build`**. Contains our Lambda Layer source code built once, used by all stacks independently -- **`layer_build.diff`**. Contains a hash on whether our source code has changed to speed up further deployments and E2E tests - -Together, all of this allows us to use Pytest like we would for any project, use CDK CLI and its [context methods](https://docs.aws.amazon.com/cdk/v2/guide/context.html#context_methods) (`from_lookup`), and use step-through debugging for a single E2E test without any extra configuration. - -> NOTE: VSCode doesn't support debugging processes spawning sub-processes (like CDK CLI does w/ shell and CDK App). Maybe [this works](https://stackoverflow.com/a/65339352). PyCharm works just fine. +Maintainers' playbook moved: https://docs.powertools.aws.dev/lambda/python/latest/maintainers/ diff --git a/docs/diagram_src/cicd_steps.md b/docs/diagram_src/cicd_steps.md new file mode 100644 index 00000000000..381ec9ea5b3 --- /dev/null +++ b/docs/diagram_src/cicd_steps.md @@ -0,0 +1,106 @@ + + +```mermaid +timeline + title Powertools for AWS Lambda (Python) CI/CD pipeline + + section Continuous Integration + Project setup
(make dev) : Code checkout + : Virtual environment + : Dependencies + : Git pre-commit hooks + : Local branch + : Local changes + : Local tests + + Pre-commit checks
(git commit) : Merge conflict check + : Trailing whitespaces + : TOML checks + : Code linting (standards) + : Markdown linting + : CloudFormation linting + : GitHub Actions linting + : Terraform linting + : Secrets linting + + Pre-Pull Request
(make pr) : Code linting + : Docs linting + : Static typing analysis + : Tests (unit|functional|perf) + : Security baseline + : Complexity baseline + : +pre-commit checks + + Pull Request
(CI checks) : Semantic PR title check + : Related issue check + : Acknowledgment check + : Code coverage diff + : Contribution size check + : Contribution category check + : Dependency vulnerability check + : GitHub Actions security check + : +pre-pull request checks + + After merge
(CI checks) : End-to-end tests + : Longer SAST check + : Security posture check (scorecard) + : GitHub Actions security check + : Rebuild Changelog + : Deploy staging docs + : Update draft release + + section Continuous Delivery + + Source code anti-tampering : Checkout release commit code + : Bump release version + : Seal and upload artifact + + Quality Assurance : Restore sealed code + : +Continuous Integration checks + + Build : Restore sealed code + : Integrity check + : Build release artifact + : Seal and upload artifact + + Provenance : Detect build environment + : Generate SLSA Builder + : Verify SLSA Builder provenance + : Create and sign provenance + : Seal and upload artifact + : Write to public ledger + + Release : Restore sealed build + : Integrity check + : PyPi ephemeral credentials + : Publish PyPi + : Baking time + + Git tagging : Restore sealed code + : Integrity check + : Bump git tag + : Create temporary branch + : Create PR + + Lambda Layers : Fetch PyPi release + : Build x86 architecture + : Build ARM architecture + : Deploy Beta + : Canary testing + : Deploy Prod + + Lambda Layers SAR : Deploy Beta + : Deploy Prod + + Documentation : Update Lambda Layer ARNs + : Build User Guide + : Build API Guide + : Rebuild Changelog + : Release new version + : Update latest alias + : Create temporary branch + : Create PR + + Post-release : Close pending-release issues + : Notify customers +``` diff --git a/docs/maintainers.md b/docs/maintainers.md new file mode 100644 index 00000000000..6fc00c83cd9 --- /dev/null +++ b/docs/maintainers.md @@ -0,0 +1,662 @@ +--- +title: Maintainers playbook +description: Playbook for active maintainers in Powertools for AWS Lambda (Python) +--- + + + +## Overview + +!!! note "Please treat this content as a living document." + +This is document explains who the maintainers are, their responsibilities, and how they should be doing it. If you're interested in contributing, see [CONTRIBUTING](CONTRIBUTING.md). + +## Current Maintainers + +| Maintainer | GitHub ID | Affiliation | +| ----------------- | ------------------------------------------------------- | ----------- | +| Heitor Lessa | [heitorlessa](https://github.com/heitorlessa) | Amazon | +| Simon Thulbourn | [sthulb](https://github.com/sthulb) | Amazon | +| Ruben Fonseca | [rubenfonseca](https://github.com/rubenfonseca) | Amazon | +| Leandro Damascena | [leandrodamascena](https://github.com/leandrodamascena) | Amazon | + +## Emeritus + +Previous active maintainers who contributed to this project. + +| Maintainer | GitHub ID | Affiliation | +| ----------------- | ----------------------------------------------- | ----------- | +| Tom McCarthy | [cakepietoast](https://github.com/cakepietoast) | MongoDB | +| Nicolas Moutschen | [nmoutschen](https://github.com/nmoutschen) | Apollo | +| Alexander Melnyk | [am29d](https://github.com/am29d) | Amazon | +| Michal Ploski | [mploski](https://github.com/mploski) | Amazon | + +## Labels + +These are the most common labels used by maintainers to triage issues, pull requests (PR), and for project management: + +| Label | Usage | Notes | +| ---------------------- | ---------------------------------------------------------------------------------------- | --------------------------------------------------------------- | +| triage | New issues that require maintainers review | Issue template | +| bug | Unexpected, reproducible and unintended software behavior | PR/Release automation; Doc snippets are excluded; | +| not-a-bug | New and existing bug reports incorrectly submitted as bug | Analytics | +| documentation | Documentation improvements | PR/Release automation; Doc additions, fixes, etc.; | +| feature-request | New or enhancements to existing features | Issue template | +| typing | New or enhancements to static typing | Issue template | +| RFC | Technical design documents related to a feature request | Issue template | +| bug-upstream | Bug caused by upstream dependency | | +| help wanted | Tasks you want help from anyone to move forward | Bandwidth, complex topics, etc. | +| need-customer-feedback | Tasks that need more feedback before proceeding | 80/20% rule, uncertain, etc. | +| need-more-information | Missing information before making any calls | | +| need-documentation | PR is missing or has incomplete documentation | | +| need-issue | PR is missing a related issue for tracking change | PR automation | +| need-rfc | Feature request requires a RFC to improve discussion | | +| pending-release | Merged changes that will be available soon | Release automation auto-closes/notifies it | +| revisit-in-3-months | Blocked issues/PRs that need to be revisited | Often related to `need-customer-feedback`, prioritization, etc. | +| breaking-change | Changes that will cause customer impact and need careful triage | | +| do-not-merge | PRs that are blocked for varying reasons | Timeline is uncertain | +| size/XS | PRs between 0-9 LOC | PR automation | +| size/S | PRs between 10-29 LOC | PR automation | +| size/M | PRs between 30-99 LOC | PR automation | +| size/L | PRs between 100-499 LOC | PR automation | +| size/XL | PRs between 500-999 LOC, often PRs that grown with feedback | PR automation | +| size/XXL | PRs with 1K+ LOC, largely documentation related | PR automation | +| tests | PRs that add or change tests | PR automation | +| `` | PRs related to a Powertools for AWS Lambda (Python) utility, e.g. `parameters`, `tracer` | PR automation | +| feature | New features or minor changes | PR/Release automation | +| dependencies | Changes that touch dependencies, e.g. Dependabot, etc. | PR/ automation | +| github-actions | Changes in GitHub workflows | PR automation | +| github-templates | Changes in GitHub issue/PR templates | PR automation | +| internal | Changes in governance and chores (linting setup, baseline, etc.) | PR automation | +| tech-debt | Changes in tech debt | | +| customer-reference | Authorization to use company name in our documentation | Public Relations | +| community-content | Suggested content to feature in our documentation | Public Relations | + +## Maintainer Responsibilities + +Maintainers are active and visible members of the community, and have [maintain-level permissions on a repository](https://docs.github.com/en/organizations/managing-access-to-your-organizations-repositories/repository-permission-levels-for-an-organization). Use those privileges to serve the community and evolve code as follows. + +Be aware of recurring ambiguous situations and [document them](#common-scenarios) to help your fellow maintainers. + +### Uphold Code of Conduct + +Model the behavior set forward by the [Code of Conduct](CODE_OF_CONDUCT.md) and raise any violations to other maintainers and admins. There could be unusual circumstances where inappropriate behavior does not immediately fall within the [Code of Conduct](CODE_OF_CONDUCT.md). + +These might be nuanced and should be handled with extra care - when in doubt, do not engage and reach out to other maintainers and admins. + +### Prioritize Security + +Security is your number one priority. Maintainer's Github keys must be password protected securely and any reported security vulnerabilities are addressed before features or bugs. + +Note that this repository is monitored and supported 24/7 by Amazon Security, see [Reporting a Vulnerability](SECURITY.md) for details. + +### Review Pull Requests + +Review pull requests regularly, comment, suggest, reject, merge and close. Accept only high quality pull-requests. Provide code reviews and guidance on incoming pull requests. + +PRs are [labeled](#labels) based on file changes and semantic title. Pay attention to whether labels reflect the current state of the PR and correct accordingly. + +Use and enforce [semantic versioning](https://semver.org/) pull request titles, as these will be used for [CHANGELOG](CHANGELOG.md) and [Release notes](https://github.com/aws-powertools/powertools-lambda-python/releases) - make sure they communicate their intent at the human level. + +> TODO: This is an area we want to automate using the new GitHub GraphQL API. + +For issues linked to a PR, make sure `pending release` label is applied to them when merging. [Upon release](#releasing-a-new-version), these issues will be notified which release version contains their change. + +See [Common scenarios](#common-scenarios) section for additional guidance. + +### Triage New Issues + +Manage [labels](#labels), review issues regularly, and create new labels as needed by the project. Remove `triage` label when you're able to confirm the validity of a request, a bug can be reproduced, etc. Give priority to the original author for implementation, unless it is a sensitive task that is best handled by maintainers. + +> TODO: This is an area we want to automate using the new GitHub GraphQL API. + +Make sure issues are assigned to our [board of activities](https://github.com/orgs/awslabs/projects/51/) and have the right [status](https://docs.powertools.aws.dev/lambda/python/latest/roadmap/#roadmap-status-definition). + +Use our [labels](#labels) to signal good first issues to new community members, and to set expectation that this might need additional feedback from the author, other customers, experienced community members and/or maintainers. + +Be aware of [casual contributors](https://opensource.com/article/17/10/managing-casual-contributors) and recurring contributors. Provide the experience and attention you wish you had if you were starting in open source. + +See [Common scenarios](#common-scenarios) section for additional guidance. + +### Triage Bug Reports + +Be familiar with [our definition of bug](#is-that-a-bug). If it's not a bug, you can close it or adjust its title and labels - always communicate the reason accordingly. + +For bugs caused by upstream dependencies, replace `bug` with `bug-upstream` label. Ask the author whether they'd like to raise the issue upstream or if they prefer us to do so. + +Assess the impact and make the call on whether we need an emergency release. Contact other [maintainers](#current-maintainers) when in doubt. + +See [Common scenarios](#common-scenarios) section for additional guidance. + +### Triage RFCs + +RFC is a collaborative process to help us get to the most optimal solution given the context. Their purpose is to ensure everyone understands what this context is, their trade-offs, and alternative solutions that were part of the research before implementation begins. + +Make sure you ask these questions in mind when reviewing: + +- Does it use our [RFC template](https://github.com/aws-powertools/powertools-lambda-python/issues/new?assignees=&labels=RFC%2Ctriage&template=rfc.yml&title=RFC%3A+TITLE)? +- Does the match our [Tenets](https://docs.powertools.aws.dev/lambda/python/latest/#tenets)? +- Does the proposal address the use case? If so, is the recommended usage explicit? +- Does it focus on the mechanics to solve the use case over fine-grained implementation details? +- Can anyone familiar with the code base implement it? +- If approved, are they interested in contributing? Do they need any guidance? +- Does this significantly increase the overall project maintenance? Do we have the skills to maintain it? +- If we can't take this use case, are there alternative projects we could recommend? Or does it call for a new project altogether? + +When necessary, be upfront that the time to review, approve, and implement a RFC can vary - see [Contribution is stuck](#contribution-is-stuck). Some RFCs may be further updated after implementation, as certain areas become clearer. + +Some examples using our initial and new RFC templates: #92, #94, #95, #991, #1226 + +### Releasing a new version + +Firstly, make sure the commit history in the `develop` branch **(1)** it's up to date, **(2)** commit messages are semantic, and **(3)** commit messages have their respective area, for example `feat(logger): `, `chore(ci): ...`). + +**Looks good, what's next?** + +Kickoff the `Release` workflow with the intended version - this might take around 25m-30m to complete. + +Once complete, you can start drafting the release notes to let customers know **what changed and what's in it for them (a.k.a why they should care)**. We have guidelines in the release notes section so you know what good looks like. + +> **NOTE**: Documentation might take a few minutes to reflect the latest version due to caching and CDN invalidations. + +#### Release process visualized + +Every release makes hundreds of checks, security scans, canaries and deployments - all of these are automated. + +This is a close visual representation of the main steps (GitHub Actions UI should be the source of truth), along with the approximate time it takes for each key step to complete. + + + +```mermaid +gantt + +title Release process +dateFormat HH:mm +axisFormat %H:%M + +Release commit : milestone, m1, 10:00,2m + +section Seal + Bump release version : active, 8s + Prevent source tampering : active, 43s +section QA + Quality checks : active, 2.2m +section Build + Checksum : active, 8s + Build release artifact : active, 39s + Seal : active, 8s +section Provenance + Attest build : active, 8s + Sign attestation : active, attestation, 10:06, 8s + +section Release + Checksum : active, 8s + PyPi temp credentials : active, 8s + Publish PyPi : active, pypi, 10:07, 29s + +PyPi release : milestone, m2, 10:07,1s + +section Git release + Checksum : active, after pypi, 8s + Git Tag : active, 8s + Bump package version : active, 8s + Create PR : active, 8s + Upload attestation : active, 8s + +section Layer release + Build (x86+ARM) : active, layer_build, 10:08, 6m + Deploy Beta : active, layer_beta, after layer_build, 6.3m + Deploy Prod : active, layer_prod, after layer_beta, 6.3m + +Layer release : milestone, m3, 10:26,1s + +section SAR release + Deploy Beta : active, sar_beta, after layer_beta, 2.2m + Deploy Prod : active, sar_prod, after sar_beta, 2.2m + +SAR release : milestone, m4, 10:25,1s + +section Docs + Create PR (Layer ARN) : active, after layer_prod, 8s + Release versioned docs : active, 2.2m + +Documentation release : milestone, m4, 10:28,1m + +section Post-release + Close pending issues : active, 8s + +Release complete : milestone, m6, 10:31,2m +``` + +#### Drafting release notes + +Visit the [Releases page](https://github.com/aws-powertools/powertools-lambda-python/releases) and choose the edit pencil button. + +Make sure the `tag` field reflects the new version you're releasing, the target branch field is set to `develop`, and `release title` matches your tag e.g., `v1.26.0`. + +You'll notice we group all changes based on their [labels](#labels) like `feature`, `bug`, `documentation`, etc. + +**I spotted a typo or incorrect grouping - how do I fix it?** + +Edit the respective PR title and update their [labels](#labels). Then run the [Release Drafter workflow](https://github.com/aws-powertools/powertools-lambda-python/actions/workflows/release-drafter.yml) to update the Draft release. + +> **NOTE**: This won't change the CHANGELOG as the merge commit is immutable. Don't worry about it. We'd only rewrite git history only if this can lead to confusion and we'd pair with another maintainer. + +**All looking good, what's next?** + +The best part comes now. Replace the placeholder `[Human readable summary of changes]` with what you'd like to communicate to customers what this release is all about. Rule of thumb: always put yourself in the customers shoes. + +These are some questions to keep in mind when drafting your first or future release notes: + +- Can customers understand at a high level what changed in this release? +- Is there a link to the documentation where they can read more about each main change? +- Are there any graphics or [code snippets](carbon.now.sh/) that can enhance readability? +- Are we calling out any key contributor(s) to this release? + - All contributors are automatically credited, use this as an exceptional case to feature them + +Once you're happy, hit `Publish release` πŸŽ‰πŸŽ‰πŸŽ‰. + +This will kick off the [Publishing workflow](https://github.com/aws-powertools/powertools-lambda-python/actions/workflows/release.yml) and within a few minutes you should see the latest version in PyPi, and all issues labeled as `pending-release` will be closed and notified. + +### Run end to end tests + +E2E tests are run on every push to `develop` or manually via [run-e2e-tests workflow](https://github.com/aws-powertools/powertools-lambda-python/actions/workflows/run-e2e-tests.yml). + +To run locally, you need [AWS CDK CLI](https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html#getting_started_prerequisites) and an [account bootstrapped](https://docs.aws.amazon.com/cdk/v2/guide/bootstrapping.html) (`cdk bootstrap`). With a default AWS CLI profile configured, or `AWS_PROFILE` environment variable set, run `make e2e tests`. + +### Releasing a documentation hotfix + +You can rebuild the latest documentation without a full release via this [GitHub Actions Workflow](https://github.com/aws-powertools/powertools-lambda-python/actions/workflows/rebuild_latest_docs.yml). Choose `Run workflow`, keep `develop` as the branch, and input the latest Powertools for AWS Lambda (Python) version available. + +This workflow will update both user guide and API documentation. + +### Maintain Overall Health of the Repo + +> TODO: Coordinate renaming `develop` to `main` + +Keep the `develop` branch at production quality at all times. Backport features as needed. Cut release branches and tags to enable future patches. + +### Manage Roadmap + +See [Roadmap section](https://docs.powertools.aws.dev/lambda/python/latest/roadmap/) + +Ensure the repo highlights features that should be elevated to the project roadmap. Be clear about the feature’s status, priority, target version, and whether or not it should be elevated to the roadmap. + +### Add Continuous Integration Checks + +Add integration checks that validate pull requests and pushes to ease the burden on Pull Request reviewers. Continuously revisit areas of improvement to reduce operational burden in all parties involved. + +### Negative Impact on the Project + +Actions that negatively impact the project will be handled by the admins, in coordination with other maintainers, in balance with the urgency of the issue. Examples would be [Code of Conduct](CODE_OF_CONDUCT.md) violations, deliberate harmful or malicious actions, spam, monopolization, and security risks. + +### Becoming a maintainer + +In 2023, we will revisit this. We need to improve our understanding of how other projects are doing, their mechanisms to promote key contributors, and how they interact daily. + +We suspect this process might look similar to the [OpenSearch project](https://github.com/opensearch-project/.github/blob/main/MAINTAINERS.md#becoming-a-maintainer). + +## Common scenarios + +These are recurring ambiguous situations that new and existing maintainers may encounter. They serve as guidance. It is up to each maintainer to follow, adjust, or handle in a different manner as long as [our conduct is consistent](#uphold-code-of-conduct) + +### Contribution is stuck + +A contribution can get stuck often due to lack of bandwidth and language barrier. For bandwidth issues, check whether the author needs help. Make sure you get their permission before pushing code into their existing PR - do not create a new PR unless strictly necessary. + +For language barrier and others, offer a 1:1 chat to get them unblocked. Often times, English might not be their primary language, and writing in public might put them off, or come across not the way they intended to be. + +In other cases, you may have constrained capacity. Use `help wanted` label when you want to signal other maintainers and external contributors that you could use a hand to move it forward. + +### Insufficient feedback or information + +When in doubt, use `need-more-information` or `need-customer-feedback` labels to signal more context and feedback are necessary before proceeding. You can also use `revisit-in-3-months` label when you expect it might take a while to gather enough information before you can decide. + +### Crediting contributions + +We credit all contributions as part of each [release note](https://github.com/aws-powertools/powertools-lambda-python/releases) as an automated process. If you find contributors are missing from the release note you're producing, please add them manually. + +### Is that a bug? + +A bug produces incorrect or unexpected results at runtime that differ from its intended behavior. Bugs must be reproducible. They directly affect customers experience at runtime despite following its recommended usage. + +Documentation snippets, use of internal components, or unadvertised functionalities are not considered bugs. + +### Mentoring contributions + +Always favor mentoring issue authors to contribute, unless they're not interested or the implementation is sensitive (_e.g., complexity, time to release, etc._). + +Make use of `help wanted` and `good first issue` to signal additional contributions the community can help. + +### Long running issues or PRs + +Try offering a 1:1 call in the attempt to get to a mutual understanding and clarify areas that maintainers could help. + +In the rare cases where both parties don't have the bandwidth or expertise to continue, it's best to use the `revisit-in-3-months` label. By then, see if it's possible to break the PR or issue in smaller chunks, and eventually close if there is no progress. + +## E2E framework + +### Structure + +Our E2E framework relies on [Pytest fixtures](https://docs.pytest.org/en/6.2.x/fixture.html) to coordinate infrastructure and test parallelization - see [Test Parallelization](#test-runner-parallelization) and [CDK CLI Parallelization](#cdk-cli-parallelization). + +**tests/e2e structure** + +```shell +. +β”œβ”€β”€ __init__.py +β”œβ”€β”€ conftest.py # builds Lambda Layer once +β”œβ”€β”€ logger +β”‚ β”œβ”€β”€ __init__.py +β”‚ β”œβ”€β”€ conftest.py # deploys LoggerStack +β”‚ β”œβ”€β”€ handlers +β”‚ β”‚ └── basic_handler.py +β”‚ β”œβ”€β”€ infrastructure.py # LoggerStack definition +β”‚ └── test_logger.py +β”œβ”€β”€ metrics +β”‚ β”œβ”€β”€ __init__.py +β”‚ β”œβ”€β”€ conftest.py # deploys MetricsStack +β”‚ β”œβ”€β”€ handlers +β”‚ β”‚ β”œβ”€β”€ basic_handler.py +β”‚ β”‚ └── cold_start.py +β”‚ β”œβ”€β”€ infrastructure.py # MetricsStack definition +β”‚ └── test_metrics.py +β”œβ”€β”€ tracer +β”‚ β”œβ”€β”€ __init__.py +β”‚ β”œβ”€β”€ conftest.py # deploys TracerStack +β”‚ β”œβ”€β”€ handlers +β”‚ β”‚ β”œβ”€β”€ async_capture.py +β”‚ β”‚ └── basic_handler.py +β”‚ β”œβ”€β”€ infrastructure.py # TracerStack definition +β”‚ └── test_tracer.py +└── utils + β”œβ”€β”€ __init__.py + β”œβ”€β”€ data_builder # build_service_name(), build_add_dimensions_input, etc. + β”œβ”€β”€ data_fetcher # get_traces(), get_logs(), get_lambda_response(), etc. + β”œβ”€β”€ infrastructure.py # base infrastructure like deploy logic, etc. +``` + +Where: + +- **`/infrastructure.py`**. Uses CDK to define the infrastructure a given feature needs. +- **`/handlers/`**. Lambda function handlers to build, deploy, and exposed as stack output in PascalCase (e.g., `BasicHandler`). +- **`utils/`**. Test utilities to build data and fetch AWS data to ease assertion +- **`conftest.py`**. Deploys and deletes a given feature infrastructure. Hierarchy matters: + - **Top-level (`e2e/conftest`)**. Builds Lambda Layer only once and blocks I/O across all CPU workers. + - **Feature-level (`e2e//conftest`)**. Deploys stacks in parallel and make them independent of each other. + +### Mechanics + +Under [`BaseInfrastructure`](https://github.com/aws-powertools/powertools-lambda-python/blob/develop/tests/e2e/utils/infrastructure.py), we hide the complexity of deployment and delete coordination under `deploy`, `delete`, and `create_lambda_functions` methods. + +This allows us to benefit from test and deployment parallelization, use IDE step-through debugging for a single test, run one, subset, or all tests and only deploy their related infrastructure, without any custom configuration. + +> Class diagram to understand abstraction built when defining a new stack (`LoggerStack`) + +```mermaid +classDiagram + class InfrastructureProvider { + <> + +deploy() Dict + +delete() + +create_resources() + +create_lambda_functions() Dict~Functions~ + } + + class BaseInfrastructure { + +deploy() Dict + +delete() + +create_lambda_functions() Dict~Functions~ + +add_cfn_output() + } + + class TracerStack { + +create_resources() + } + + class LoggerStack { + +create_resources() + } + + class MetricsStack { + +create_resources() + } + + class EventHandlerStack { + +create_resources() + } + + InfrastructureProvider <|-- BaseInfrastructure : implement + BaseInfrastructure <|-- TracerStack : inherit + BaseInfrastructure <|-- LoggerStack : inherit + BaseInfrastructure <|-- MetricsStack : inherit + BaseInfrastructure <|-- EventHandlerStack : inherit +``` + +### Authoring a new feature E2E test + +Imagine you're going to create E2E for Event Handler feature for the first time. Keep the following mental model when reading: + +```mermaid +graph LR + A["1. Define infrastructure"]-->B["2. Deploy/Delete infrastructure"]-->C["3.Access Stack outputs" ] +``` + +#### 1. Define infrastructure + +We use CDK as our Infrastructure as Code tool of choice. Before you start using CDK, you'd take the following steps: + +1. Create `tests/e2e/event_handler/infrastructure.py` file +2. Create a new class `EventHandlerStack` and inherit from `BaseInfrastructure` +3. Override `create_resources` method and define your infrastructure using CDK +4. (Optional) Create a Lambda function under `handlers/alb_handler.py` + +> Excerpt `tests/e2e/event_handler/infrastructure.py` + +```python +class EventHandlerStack(BaseInfrastructure): + def create_resources(self): + functions = self.create_lambda_functions() + + self._create_alb(function=functions["AlbHandler"]) + ... + + def _create_alb(self, function: Function): + vpc = ec2.Vpc.from_lookup( + self.stack, + "VPC", + is_default=True, + region=self.region, + ) + + alb = elbv2.ApplicationLoadBalancer(self.stack, "ALB", vpc=vpc, internet_facing=True) + CfnOutput(self.stack, "ALBDnsName", value=alb.load_balancer_dns_name) + ... +``` + +> Excerpt `tests/e2e/event_handler/handlers/alb_handler.py` + +```python +from aws_lambda_powertools.event_handler import ALBResolver, Response, content_types + +app = ALBResolver() + + +@app.get("/todos") +def hello(): + return Response( + status_code=200, + content_type=content_types.TEXT_PLAIN, + body="Hello world", + cookies=["CookieMonster", "MonsterCookie"], + headers={"Foo": ["bar", "zbr"]}, + ) + + +def lambda_handler(event, context): + return app.resolve(event, context) +``` + +#### 2. Deploy/Delete infrastructure when tests run + +We need to create a Pytest fixture for our new feature under `tests/e2e/event_handler/conftest.py`. + +This will instruct Pytest to deploy our infrastructure when our tests start, and delete it when they complete whether tests are successful or not. Note that this file will not need any modification in the future. + +> Excerpt `conftest.py` for Event Handler + +```python +import pytest + +from tests.e2e.event_handler.infrastructure import EventHandlerStack + + +@pytest.fixture(autouse=True, scope="module") +def infrastructure(): + """Setup and teardown logic for E2E test infrastructure + + Yields + ------ + Dict[str, str] + CloudFormation Outputs from deployed infrastructure + """ + stack = EventHandlerStack() + try: + yield stack.deploy() + finally: + stack.delete() + +``` + +#### 3. Access stack outputs for E2E tests + +Within our tests, we should now have access to the `infrastructure` fixture we defined earlier in `tests/e2e/event_handler/conftest.py`. + +We can access any Stack Output using pytest dependency injection. + +> Excerpt `tests/e2e/event_handler/test_header_serializer.py` + +```python +@pytest.fixture +def alb_basic_listener_endpoint(infrastructure: dict) -> str: + dns_name = infrastructure.get("ALBDnsName") + port = infrastructure.get("ALBBasicListenerPort", "") + return f"http://{dns_name}:{port}" + + +def test_alb_headers_serializer(alb_basic_listener_endpoint): + # GIVEN + url = f"{alb_basic_listener_endpoint}/todos" + ... +``` + +### Internals + +#### Test runner parallelization + +Besides speed, we parallelize our end-to-end tests to ease asserting async side-effects may take a while per test too, _e.g., traces to become available_. + +The following diagram demonstrates the process we take every time you use `make e2e` locally or at CI: + +```mermaid +graph TD + A[make e2e test] -->Spawn{"Split and group tests
by feature and CPU"} + + Spawn -->|Worker0| Worker0_Start["Load tests"] + Spawn -->|Worker1| Worker1_Start["Load tests"] + Spawn -->|WorkerN| WorkerN_Start["Load tests"] + + Worker0_Start -->|Wait| LambdaLayer["Lambda Layer build"] + Worker1_Start -->|Wait| LambdaLayer["Lambda Layer build"] + WorkerN_Start -->|Wait| LambdaLayer["Lambda Layer build"] + + LambdaLayer -->|Worker0| Worker0_Deploy["Launch feature stack"] + LambdaLayer -->|Worker1| Worker1_Deploy["Launch feature stack"] + LambdaLayer -->|WorkerN| WorkerN_Deploy["Launch feature stack"] + + Worker0_Deploy -->|Worker0| Worker0_Tests["Run tests"] + Worker1_Deploy -->|Worker1| Worker1_Tests["Run tests"] + WorkerN_Deploy -->|WorkerN| WorkerN_Tests["Run tests"] + + Worker0_Tests --> ResultCollection + Worker1_Tests --> ResultCollection + WorkerN_Tests --> ResultCollection + + ResultCollection{"Wait for workers
Collect test results"} + ResultCollection --> TestEnd["Report results"] + ResultCollection --> DeployEnd["Delete Stacks"] +``` + +#### CDK CLI parallelization + +For CDK CLI to work with [independent CDK Apps](https://docs.aws.amazon.com/cdk/v2/guide/apps.html), we specify an output directory when synthesizing our stack and deploy from said output directory. + +```mermaid +flowchart TD + subgraph "Deploying distinct CDK Apps" + EventHandlerInfra["Event Handler CDK App"] --> EventHandlerSynth + TracerInfra["Tracer CDK App"] --> TracerSynth + EventHandlerSynth["cdk synth --out cdk.out/event_handler"] --> EventHandlerDeploy["cdk deploy --app cdk.out/event_handler"] + + TracerSynth["cdk synth --out cdk.out/tracer"] --> TracerDeploy["cdk deploy --app cdk.out/tracer"] + end +``` + +We create the typical CDK `app.py` at runtime when tests run, since we know which feature and Python version we're dealing with (locally or at CI). + +> Excerpt `cdk_app_V39.py` for Event Handler created at deploy phase + +```python +from tests.e2e.event_handler.infrastructure import EventHandlerStack +stack = EventHandlerStack() +stack.create_resources() +stack.app.synth() +``` + +When we run E2E tests for a single feature or all of them, our `cdk.out` looks like this: + +```shell +total 8 +drwxr-xr-x 18 lessa staff 576B Sep 6 15:38 event-handler +drwxr-xr-x 3 lessa staff 96B Sep 6 15:08 layer_build +-rw-r--r-- 1 lessa staff 32B Sep 6 15:08 layer_build.diff +drwxr-xr-x 18 lessa staff 576B Sep 6 15:38 logger +drwxr-xr-x 18 lessa staff 576B Sep 6 15:38 metrics +drwxr-xr-x 22 lessa staff 704B Sep 9 10:52 tracer +``` + +```mermaid +classDiagram + class CdkOutDirectory { + feature_name/ + layer_build/ + layer_build.diff + } + + class EventHandler { + manifest.json + stack_outputs.json + cdk_app_V39.py + asset.uuid/ + ... + } + + class StackOutputsJson { + BasicHandlerArn: str + ALBDnsName: str + ... + } + + CdkOutDirectory <|-- EventHandler : feature_name/ + StackOutputsJson <|-- EventHandler +``` + +Where: + +- **``**. Contains CDK Assets, CDK `manifest.json`, our `cdk_app_.py` and `stack_outputs.json` +- **`layer_build`**. Contains our Lambda Layer source code built once, used by all stacks independently +- **`layer_build.diff`**. Contains a hash on whether our source code has changed to speed up further deployments and E2E tests + +Together, all of this allows us to use Pytest like we would for any project, use CDK CLI and its [context methods](https://docs.aws.amazon.com/cdk/v2/guide/context.html#context_methods) (`from_lookup`), and use step-through debugging for a single E2E test without any extra configuration. + +> NOTE: VSCode doesn't support debugging processes spawning sub-processes (like CDK CLI does w/ shell and CDK App). Maybe [this works](https://stackoverflow.com/a/65339352). PyCharm works just fine. diff --git a/mkdocs.yml b/mkdocs.yml index 1b9c7db95a3..06cfc8c6c49 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -35,6 +35,7 @@ nav: - Security: security.md - Automation: automation.md - Roadmap: roadmap.md + - Maintainers: maintainers.md theme: name: material @@ -95,7 +96,7 @@ markdown_extensions: class: mermaid format: !!python/name:pymdownx.superfences.fence_code_format -copyright: Copyright © 2022 Amazon Web Services +copyright: Copyright © 2023 Amazon Web Services plugins: - git-revision-date From 13599f22774c31035b0440cafc615e31059d88c7 Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Thu, 13 Jul 2023 15:16:09 +0200 Subject: [PATCH 4/4] docs(homepage): address leandro's feedback; quality improvements --- docs/index.md | 8 +++++--- mkdocs.yml | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/index.md b/docs/index.md index 939a2da9c29..aab8f441b1e 100644 --- a/docs/index.md +++ b/docs/index.md @@ -26,10 +26,12 @@ Powertools for AWS Lambda (Python) is a developer toolkit to implement Serverles You can install Powertools for AWS Lambda (Python) using one of the following options: -* **Lambda Layer (x86_64)**: [**arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:37**](#){: .copyMe}:clipboard: -* **Lambda Layer (arm64)**: [**arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:37**](#){: .copyMe}:clipboard: +* **Lambda Layer (x86_64)**: [**arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:37**](# "Replace {region} with your AWS region, e.g., eu-west-1"){: .copyMe}:clipboard: +* **Lambda Layer (arm64)**: [**arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:37**](# "Replace {region} with your AWS region, e.g., eu-west-1"){: .copyMe}:clipboard: * **Pip**: **[`pip install "aws-lambda-powertools"`](#){: .copyMe}:clipboard:** +!!! question "Looking for Pip signed releases? [Learn more about verifying signed builds](./security.md#verifying-signed-builds)" + ??? question "Using Pip? You might need to install additional dependencies." [**Tracer**](./core/tracer.md){target="_blank"}, [**Validation**](./utilities/validation.md){target="_blank"} and [**Parser**](./utilities/parser.md){target="_blank"} require additional dependencies. If you prefer to install all of them, use [**`pip install "aws-lambda-powertools[all]"`**](#){: .copyMe}:clipboard:. @@ -42,7 +44,7 @@ You can install Powertools for AWS Lambda (Python) using one of the following op ### Local development -!!! info "Using Powertools for AWS Lambda (Python) via Lambda Layer? Simply add [**`"aws-lambda-powertools[all]"`**](#){: .copyMe}:clipboard: as a development dependency." +!!! info "Using Lambda Layer? Simply add [**`"aws-lambda-powertools[all]"`**](#){: .copyMe}:clipboard: as a development dependency." Powertools for AWS Lambda (Python) relies on the [AWS SDK bundled in the Lambda runtime](https://docs.aws.amazon.com/lambda/latest/dg/lambda-python.html){target="_blank"}. This helps us achieve an optimal package size and initialization. However, when developing locally, you need to install AWS SDK as a development dependency (not as a production dependency): diff --git a/mkdocs.yml b/mkdocs.yml index 06cfc8c6c49..77322a535be 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -10,6 +10,7 @@ nav: - Changelog: changelog.md - API reference: api/" target="_blank - Upgrade guide: upgrade.md + - We Made This (Community): we_made_this.md - Features: - core/tracer.md - core/logger.md @@ -30,7 +31,6 @@ nav: - utilities/jmespath_functions.md - CloudFormation Custom Resources: https://github.com/aws-cloudformation/custom-resource-helper" target="_blank - Tutorial: tutorial/index.md - - We Made This (Community): we_made_this.md - Processes: - Security: security.md - Automation: automation.md