diff --git a/.github/labeler.yml b/.github/labeler.yml index c85b14f..ffa7d18 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -45,6 +45,14 @@ python: - changed-files: - any-glob-to-any-file: - "**/*.py" +shell script: + - changed-files: + - any-glob-to-any-file: + # If this project has any shell scripts that do not end in the ".sh" + # extension, add them below. + - "**/*.sh" + - bump-version + - setup-env terraform: - changed-files: - any-glob-to-any-file: diff --git a/.github/labels.yml b/.github/labels.yml index 650ed7c..69f0a2d 100644 --- a/.github/labels.yml +++ b/.github/labels.yml @@ -2,7 +2,7 @@ # Rather than breaking up descriptions into multiline strings we disable that # specific rule in yamllint for this file. # yamllint disable rule:line-length -- color: f15a53 +- color: ff5850 description: Pull requests that update Ansible code name: ansible - color: eb6420 @@ -20,7 +20,7 @@ - color: 0366d6 description: Pull requests that update a dependency file name: dependencies -- color: 2497ed +- color: 1d63ed description: Pull requests that update Docker code name: docker - color: 5319e7 @@ -47,7 +47,7 @@ - color: fef2c0 description: This issue or pull request is not applicable, incorrect, or obsolete name: invalid -- color: f1d642 +- color: f0db4f description: Pull requests that update JavaScript code name: javascript - color: ce099a @@ -62,7 +62,7 @@ - color: 02a8ef description: Pull requests that update Packer code name: packer -- color: 3772a4 +- color: 3776ab description: Pull requests that update Python code name: python - color: ef476c @@ -71,13 +71,16 @@ - color: d73a4a description: This issue or pull request addresses a security issue name: security +- color: 4eaa25 + description: Pull requests that update shell scripts + name: shell script - color: 7b42bc description: Pull requests that update Terraform code name: terraform - color: 00008b description: This issue or pull request adds or otherwise modifies test code name: test -- color: 2b6ebf +- color: 2678c5 description: Pull requests that update TypeScript code name: typescript - color: 1d76db diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 60dc4ec..fbef599 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -101,7 +101,7 @@ jobs: permissions_monitoring_config: ${{ vars.ACTIONS_PERMISSIONS_CONFIG }} - id: setup-env uses: cisagov/setup-env-github-action@v1 - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - id: setup-python uses: actions/setup-python@v6 with: @@ -231,7 +231,7 @@ jobs: permissions_monitoring_config: ${{ vars.ACTIONS_PERMISSIONS_CONFIG }} - id: setup-env uses: cisagov/setup-env-github-action@v1 - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - id: setup-python uses: actions/setup-python@v6 with: @@ -292,7 +292,7 @@ jobs: # monitoring configuration *does not* require you to modify # this workflow. permissions_monitoring_config: ${{ vars.ACTIONS_PERMISSIONS_CONFIG }} - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Get the short SHA for the commit being used run: | echo "GH_SHORT_SHA=${GITHUB_SHA::7}" >> $GITHUB_ENV diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index e868cd3..91c62d7 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -114,11 +114,11 @@ jobs: permissions_monitoring_config: ${{ vars.ACTIONS_PERMISSIONS_CONFIG }} - name: Checkout repository - uses: actions/checkout@v5 + uses: actions/checkout@v6 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v3 + uses: github/codeql-action/init@v4 with: languages: ${{ matrix.language }} @@ -126,7 +126,7 @@ jobs: # Java). If this step fails, then you should remove it and run the build # manually (see below). - name: Autobuild - uses: github/codeql-action/autobuild@v3 + uses: github/codeql-action/autobuild@v4 # â„šī¸ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -140,4 +140,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 + uses: github/codeql-action/analyze@v4 diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index bc859d1..580fa9c 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -89,7 +89,7 @@ jobs: permissions_monitoring_config: ${{ vars.ACTIONS_PERMISSIONS_CONFIG }} - id: checkout-repo name: Checkout the repository - uses: actions/checkout@v5 + uses: actions/checkout@v6 - id: dependency-review name: Review dependency changes for vulnerabilities and license changes uses: actions/dependency-review-action@v4 diff --git a/.github/workflows/label-prs.yml b/.github/workflows/label-prs.yml index 9d78e39..412cc4a 100644 --- a/.github/workflows/label-prs.yml +++ b/.github/workflows/label-prs.yml @@ -59,7 +59,6 @@ jobs: permissions: # Permissions required by actions/labeler contents: read - issues: write pull-requests: write runs-on: ubuntu-latest steps: diff --git a/.github/workflows/sync-labels.yml b/.github/workflows/sync-labels.yml index 19e0129..f60bc84 100644 --- a/.github/workflows/sync-labels.yml +++ b/.github/workflows/sync-labels.yml @@ -84,7 +84,7 @@ jobs: # monitoring configuration *does not* require you to modify # this workflow. permissions_monitoring_config: ${{ vars.ACTIONS_PERMISSIONS_CONFIG }} - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Sync repository labels if: success() uses: crazy-max/ghaction-github-labeler@v5 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 630f743..1c8d0e3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -63,20 +63,20 @@ repos: # GitHub Actions hooks - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.33.3 + rev: 0.35.0 hooks: - id: check-github-actions - id: check-github-workflows # pre-commit hooks - repo: https://github.com/pre-commit/pre-commit - rev: v4.3.0 + rev: v4.4.0 hooks: - id: validate_manifest # Go hooks - repo: https://github.com/TekWizely/pre-commit-golang - rev: v1.0.0-rc.2 + rev: v1.0.0-rc.4 hooks: # Go Build - id: go-build-repo-mod @@ -130,7 +130,7 @@ repos: # Python hooks # Run bandit on the tests directory with a custom configuration - repo: https://github.com/PyCQA/bandit - rev: 1.8.6 + rev: 1.9.1 hooks: - id: bandit name: bandit (tests directory) @@ -139,13 +139,13 @@ repos: - --config=.bandit.yml # Run bandit on everything but the tests directory - repo: https://github.com/PyCQA/bandit - rev: 1.8.6 + rev: 1.9.1 hooks: - id: bandit name: bandit (everything but the tests directory) exclude: tests - repo: https://github.com/psf/black-pre-commit-mirror - rev: 25.1.0 + rev: 25.11.0 hooks: - id: black - repo: https://github.com/PyCQA/flake8 @@ -155,11 +155,11 @@ repos: additional_dependencies: - flake8-docstrings==1.7.0 - repo: https://github.com/PyCQA/isort - rev: 6.0.1 + rev: 7.0.0 hooks: - id: isort - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.18.1 + rev: v1.18.2 hooks: - id: mypy - repo: https://github.com/pypa/pip-audit @@ -175,13 +175,19 @@ repos: - --requirement - requirements.txt - repo: https://github.com/asottile/pyupgrade - rev: v3.20.0 + rev: v3.21.1 hooks: - id: pyupgrade + args: + # Python 3.10 is currently the oldest non-EOL version of + # Python, so we want to apply all rules that apply to this + # version or later. See here for more details: + # https://www.gyford.com/phil/writing/2025/08/26/how-to-use-pyupgrade/ + - --py310-plus # Ansible hooks - repo: https://github.com/ansible/ansible-lint - rev: v25.9.0 + rev: v25.11.1 hooks: - id: ansible-lint additional_dependencies: @@ -197,35 +203,17 @@ repos: # hook identifies a vulnerability in ansible-core 2.16.13, # but all versions of ansible 9 have a dependency on # ~=2.16.X. - # - # It is also a good idea to go ahead and upgrade to version - # 10 since version 9 is going EOL at the end of November: - # https://endoflife.date/ansible # - ansible>=10,<11 - # ansible-core 2.16.3 through 2.16.6 suffer from the bug - # discussed in ansible/ansible#82702, which breaks any - # symlinked files in vars, tasks, etc. for any Ansible role - # installed via ansible-galaxy. Hence we never want to - # install those versions. - # - # Note that the pip-audit pre-commit hook identifies a - # vulnerability in ansible-core 2.16.13. The pin of - # ansible-core to >=2.17 effectively also pins ansible to - # >=10. - # - # It is also a good idea to go ahead and upgrade to - # ansible-core 2.17 since security support for ansible-core - # 2.16 ends this month: - # https://docs.ansible.com/ansible/devel/reference_appendices/release_and_maintenance.html#ansible-core-support-matrix + # ansible-core<2.17.7 suffers from GHSA-99w6-3xph-cx78. # # Note that any changes made to this dependency must also be # made in requirements.txt in cisagov/skeleton-packer and # requirements-test.txt in cisagov/skeleton-ansible-role. - - ansible-core>=2.17 + - ansible-core>=2.17.7 # Terraform hooks - repo: https://github.com/antonbabenko/pre-commit-terraform - rev: v1.100.0 + rev: v1.103.0 hooks: - id: terraform_fmt - id: terraform_validate diff --git a/Dockerfile b/Dockerfile index 505b296..3ec57d7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,9 @@ -# The runtime tag must match the version of Python specified in the Pipfile. -FROM amazon/aws-lambda-python:3.9 AS install-stage +# The runtime tag must match the version of Python specified in the +# Pipfile. +# +# Official Docker images are in the form library/ while +# non-official images are in the form /. +FROM docker.io/amazon/aws-lambda-python:3.9 AS install-stage # Install the Python packages necessary to install the Lambda dependencies. RUN python3 -m pip install --no-cache-dir \ @@ -21,8 +25,12 @@ COPY build/Pipfile build/Pipfile.lock ./ # underlying pip calls. RUN pipenv sync --system --extra-pip-args="--no-cache-dir --target ${LAMBDA_TASK_ROOT}" -# The runtime tag must match the version of Python specified in the Pipfile. -FROM amazon/aws-lambda-python:3.9 AS build-stage +# The runtime tag must match the version of Python specified in the +# Pipfile. +# +# Official Docker images are in the form library/ while +# non-official images are in the form /. +FROM docker.io/amazon/aws-lambda-python:3.9 AS build-stage ### # For a list of pre-defined annotation keys and value types see: diff --git a/README.md b/README.md index abdd61e..ee6db90 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # skeleton-aws-lambda-python # [![GitHub Build Status](https://github.com/cisagov/skeleton-aws-lambda-python/workflows/build/badge.svg)](https://github.com/cisagov/skeleton-aws-lambda-python/actions) +[![License](https://img.shields.io/github/license/cisagov/skeleton-aws-lambda-python)](https://spdx.org/licenses/) +[![CodeQL](https://github.com/cisagov/skeleton-aws-lambda-python/workflows/CodeQL/badge.svg)](https://github.com/cisagov/skeleton-aws-lambda-python/actions/workflows/codeql-analysis.yml) This is a generic skeleton project that can be used to quickly get a new [cisagov](https://github.com/cisagov) GitHub diff --git a/docker-compose.yml b/compose.yml similarity index 100% rename from docker-compose.yml rename to compose.yml diff --git a/src/lambda_handler.py b/src/lambda_handler.py index 74ca692..6975086 100644 --- a/src/lambda_handler.py +++ b/src/lambda_handler.py @@ -4,7 +4,7 @@ from datetime import datetime, timezone import logging import os -from typing import Any, Optional, Union +from typing import Any # Third-Party Libraries import cowsay @@ -36,9 +36,9 @@ def task_default(event): return result -def task_cowsay(event) -> dict[str, Union[Optional[str], bool]]: +def task_cowsay(event) -> dict[str, str | None | bool]: """Generate an output message using the provided information.""" - result: dict[str, Union[Optional[str], bool]] = {"message": None, "success": True} + result: dict[str, str | None | bool] = {"message": None, "success": True} character: str = event.get("character", "tux") if character not in cowsay.characters.CHARS.keys(): @@ -55,9 +55,9 @@ def task_cowsay(event) -> dict[str, Union[Optional[str], bool]]: return result -def task_divide(event) -> dict[str, Union[Optional[float], bool]]: +def task_divide(event) -> dict[str, float | None | bool]: """Divide one number by another and provide the result.""" - result: dict[str, Union[Optional[float], bool]] = {"result": None, "success": True} + result: dict[str, float | None | bool] = {"result": None, "success": True} numerator: str = event.get("numerator", None) denominator: str = event.get("denominator", None) @@ -83,7 +83,7 @@ def task_divide(event) -> dict[str, Union[Optional[float], bool]]: return result -def handler(event, context) -> dict[str, Optional[str]]: +def handler(event, context) -> dict[str, str | None]: """Process the event and generate a response. The event should have a task member that is one of the supported tasks. @@ -94,7 +94,7 @@ def handler(event, context) -> dict[str, Optional[str]]: :return: The result of the action. """ old_log_level = None - response: dict[str, Optional[str]] = {"timestamp": str(datetime.now(timezone.utc))} + response: dict[str, str | None] = {"timestamp": str(datetime.now(timezone.utc))} # Update the logging level if necessary new_log_level = os.environ.get("log_level", default_log_level).upper()