diff --git a/.github/workflows/ci_codebuild_batch.yml b/.github/workflows/ci_codebuild_batch.yml index 243638f65..1038136d0 100644 --- a/.github/workflows/ci_codebuild_batch.yml +++ b/.github/workflows/ci_codebuild_batch.yml @@ -1298,6 +1298,25 @@ jobs: buildspec-override: codebuild/py312/decrypt_golden_manifest_with_masterkey.yml image-override: aws/codebuild/standard:7.0 + # Python Release Validation with examples as alternate + python_release_examples_validation: + name: Python Release Validation with Examples + runs-on: ubuntu-latest + steps: + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v2 + with: + role-to-assume: ${{ secrets.CI_AWS_ROLE_ARN }} + aws-region: us-west-2 + role-duration-seconds: 7200 + - name: Run CodeBuild + uses: aws-actions/aws-codebuild-run-build@v1 + timeout-minutes: 120 + with: + project-name: python-esdk + buildspec-override: codebuild/release/validate_with_examples.yml + image-override: aws/codebuild/standard:7.0 + # Code Coverage and Compliance jobs code_coverage: name: Code Coverage diff --git a/codebuild/release/validate_with_examples.yml b/codebuild/release/validate_with_examples.yml new file mode 100644 index 000000000..45f1a0246 --- /dev/null +++ b/codebuild/release/validate_with_examples.yml @@ -0,0 +1,73 @@ +version: 0.2 + +env: + variables: + # Default VERSION if not provided externally + VERSION: 4.0.2 + REGION: "us-west-2" + AWS_ENCRYPTION_SDK_PYTHON_INTEGRATION_TEST_AWS_KMS_KEY_ID: >- + arn:aws:kms:us-west-2:658956600833:key/b3537ef1-d8dc-4780-9f5a-55776cbb2f7f + AWS_ENCRYPTION_SDK_PYTHON_INTEGRATION_TEST_AWS_KMS_KEY_ID_2: >- + arn:aws:kms:eu-central-1:658956600833:key/75414c93-5285-4b57-99c9-30c1cf0a22c2 + AWS_ENCRYPTION_SDK_PYTHON_INTEGRATION_TEST_AWS_KMS_MRK_KEY_ID_1: >- + arn:aws:kms:us-west-2:658956600833:key/mrk-80bd8ecdcd4342aebd84b7dc9da498a7 + AWS_ENCRYPTION_SDK_PYTHON_INTEGRATION_TEST_AWS_KMS_MRK_KEY_ID_2: >- + arn:aws:kms:us-east-1:658956600833:key/mrk-80bd8ecdcd4342aebd84b7dc9da498a7 + +phases: + install: + runtime-versions: + python: 3.11 + commands: + - pip install "tox < 4.0" + - pip install --upgrade pip + build: + commands: + # Set initial retry count + - NUM_RETRIES=3 + + # Run non-MPL-specific tests with the MPL installed + - | + while [ $NUM_RETRIES -gt 0 ] + do + VERSION=$VERSION tox -e validate-pypi-release + if [ $? -eq 0 ]; then + echo "Standard examples successful" + break + fi + NUM_RETRIES=$((NUM_RETRIES-1)) + if [ $NUM_RETRIES -eq 0 ]; then + echo "All standard example attempts failed, stopping" + exit 1 + else + echo "Standard examples failed, retrying in 60 seconds; will retry $NUM_RETRIES more times" && sleep 60 + fi + done + + # Assume special role for MPL-specific tests + - echo "Running tests with special role for MPL features" + - TMP_ROLE=$(aws sts assume-role --role-arn "arn:aws:iam::370957321024:role/GitHub-CI-Public-ESDK-Python-Role-us-west-2" --role-session-name "CB-ValidateReleased") + - export TMP_ROLE + - export AWS_ACCESS_KEY_ID=$(echo "${TMP_ROLE}" | jq -r '.Credentials.AccessKeyId') + - export AWS_SECRET_ACCESS_KEY=$(echo "${TMP_ROLE}" | jq -r '.Credentials.SecretAccessKey') + - export AWS_SESSION_TOKEN=$(echo "${TMP_ROLE}" | jq -r '.Credentials.SessionToken') + - aws sts get-caller-identity + + # Run MPL examples with a fresh retry count + - NUM_RETRIES=3 + - | + while [ $NUM_RETRIES -gt 0 ] + do + VERSION=$VERSION tox -e validate-pypi-release-mpl + if [ $? -eq 0 ]; then + echo "MPL examples successful" + break + fi + NUM_RETRIES=$((NUM_RETRIES-1)) + if [ $NUM_RETRIES -eq 0 ]; then + echo "All MPL example attempts failed, stopping" + exit 1 + else + echo "MPL examples failed, retrying in 60 seconds; will retry $NUM_RETRIES more times" && sleep 60 + fi + done \ No newline at end of file diff --git a/tox.ini b/tox.ini index 2a1121409..5514c7964 100644 --- a/tox.ini +++ b/tox.ini @@ -52,6 +52,8 @@ envlist = # build :: Builds source and wheel dist files. # test-release :: Builds dist files and uploads to testpypi pypirc profile. # release :: Builds dist files and uploads to pypi pypirc profile. +# validate-pypi-release :: Tests a released version from PyPI instead of source. +# validate-pypi-release-mpl :: Tests a released version with MPL features. # Reporting environments: # @@ -395,3 +397,48 @@ passenv = commands = {[testenv:release-base]commands} twine upload --skip-existing --repository pypi {toxinidir}/dist/* + +# Test the PyPI released version (not local source code) +[testenv:py-validate-base] +basepython = python3 +skip_install = true +passenv = {[testenv]passenv} +deps = + pytest + pytest-mock + mock + coverage + # Add dev requirements for testing + -rdev_requirements/test-requirements.txt + +# Standard test environment for PyPI-released version (no MPL) +[testenv:validate-pypi-release] +basepython = {[testenv:py-validate-base]basepython} +skip_install = {[testenv:py-validate-base]skip_install} +passenv = {[testenv:py-validate-base]passenv} +deps = {[testenv:py-validate-base]deps} +setenv = + VERSION = {env:VERSION:latest} +commands = + # Install the specified version from PyPI (without MPL extras) + pip install "aws-encryption-sdk=={env:VERSION}" --force-reinstall + # Run non-MPL examples + {[testenv:base-command]commands} examples/test/legacy/ -m examples + +# MPL test environment for PyPI-released version +[testenv:validate-pypi-release-mpl] +basepython = {[testenv:py-validate-base]basepython} +skip_install = {[testenv:py-validate-base]skip_install} +passenv = {[testenv:py-validate-base]passenv} +deps = + {[testenv:py-validate-base]deps} + boto3 +setenv = + VERSION = {env:VERSION:latest} +commands = + # Install the specified version from PyPI with MPL extras + pip install "aws-encryption-sdk[MPL]=={env:VERSION}" --force-reinstall + # Install MPL requirements needed for MPL examples + pip install -r requirements_mpl.txt + # Run MPL-specific examples + {[testenv:base-command]commands} examples/test/ -m examples --ignore examples/test/legacy/