From a313b80f580a9916648aa3fb1901a000a9511bb6 Mon Sep 17 00:00:00 2001 From: Leandro Damascena Date: Tue, 20 Aug 2024 11:50:31 +0100 Subject: [PATCH 1/3] pipeline for BETA V3 --- .github/workflows/publish_v3_layer.yml | 317 +++++++++++++++ .github/workflows/release-v3.yml | 379 ++++++++++++++++++ .../reusable_deploy_v3_layer_stack.yml | 214 ++++++++++ .github/workflows/reusable_deploy_v3_sar.yml | 213 ++++++++++ 4 files changed, 1123 insertions(+) create mode 100644 .github/workflows/publish_v3_layer.yml create mode 100644 .github/workflows/release-v3.yml create mode 100644 .github/workflows/reusable_deploy_v3_layer_stack.yml create mode 100644 .github/workflows/reusable_deploy_v3_sar.yml diff --git a/.github/workflows/publish_v3_layer.yml b/.github/workflows/publish_v3_layer.yml new file mode 100644 index 00000000000..67cffbd7f57 --- /dev/null +++ b/.github/workflows/publish_v3_layer.yml @@ -0,0 +1,317 @@ +name: Deploy v3 layer to all regions + +# PROCESS +# +# 1. Compile Layer using cdk-aws-lambda-powertools-layer CDK construct for Python3.8-3.12 and x86/ARM architectures (uses custom runner as it's CPU heavy) +# 2. Kick off pipeline for beta, prod, and canary releases +# 3. Create PR to update trunk so staged docs also point to the latest Layer ARN, when merged +# 4. Builds and publishes docs with latest Layer ARN using given version (generally coming from release) + +# USAGE +# +# NOTE: meant to be used with ./.github/workflows/release-v3.yml +# +# publish_layer: +# needs: [seal, release, create_tag] +# secrets: inherit +# permissions: +# id-token: write +# contents: write +# pages: write +# pull-requests: write +# uses: ./.github/workflows/publish_v2_layer.yml +# with: +# latest_published_version: ${{ needs.seal.outputs.RELEASE_VERSION }} +# pre_release: ${{ inputs.pre_release }} +# source_code_artifact_name: ${{ needs.seal.outputs.artifact_name }} +# source_code_integrity_hash: ${{ needs.seal.outputs.integrity_hash }} + + +on: + workflow_dispatch: + inputs: + latest_published_version: + description: "Latest PyPi published version to rebuild latest docs for, e.g. 3.0.0, 3.0.0a1 (pre-release)" + required: true + source_code_artifact_name: + description: "Artifact name to restore sealed source code" + type: string + required: true + source_code_integrity_hash: + description: "Sealed source code integrity hash" + type: string + required: true + pre_release: + description: "Publishes documentation using a pre-release tag (3.0.0a1)." + default: false + type: boolean + required: false + workflow_call: + inputs: + latest_published_version: + type: string + description: "Latest PyPi published version to rebuild latest docs for, e.g. 3.0.0, 3.0.0a1 (pre-release)" + required: true + pre_release: + description: "Publishes documentation using a pre-release tag (3.0.0a1)." + default: false + type: boolean + required: false + source_code_artifact_name: + description: "Artifact name to restore sealed source code" + type: string + required: true + source_code_integrity_hash: + description: "Sealed source code integrity hash" + type: string + required: true + +permissions: + contents: read + + +env: + RELEASE_COMMIT: ${{ github.sha }} + +jobs: + build-layer: + permissions: + # lower privilege propagated from parent workflow (release.yml) + contents: read + id-token: write + pages: none + pull-requests: none + runs-on: aws-powertools_ubuntu-latest_8-core + strategy: + max-parallel: 5 + matrix: + python-version: ["3.8","3.9","3.10","3.11","3.12"] + defaults: + run: + working-directory: ./layer_v3 + steps: + - name: checkout + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + with: + ref: ${{ env.RELEASE_COMMIT }} + + - name: Restore sealed source code + uses: ./.github/actions/seal-restore + with: + integrity_hash: ${{ inputs.source_code_integrity_hash }} + artifact_name: ${{ inputs.source_code_artifact_name }} + + - name: Install poetry + run: pipx install git+https://github.com/python-poetry/poetry@68b88e5390720a3dd84f02940ec5200bfce39ac6 # v1.5.0 + - name: Setup Node.js + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + with: + node-version: "18.20.4" + - name: Setup python + uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 + with: + python-version: ${{ matrix.python-version }} + cache: "pip" + - name: Resolve and install project dependencies + # CDK spawns system python when compiling stack + # therefore it ignores both activated virtual env and cached interpreter by GH + run: | + poetry export --format requirements.txt --output requirements.txt + pip install --require-hashes -r requirements.txt + + - name: Set up QEMU + uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v2.0.0 + with: + platforms: arm64 + # NOTE: we need QEMU to build Layer against a different architecture (e.g., ARM) + + - name: Set up Docker Buildx + id: builder + uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb # v3.3.0 + with: + install: true + driver: docker + platforms: linux/amd64,linux/arm64 + + - name: Install CDK + working-directory: ./ + run: | + npm ci + npx cdk --version + + # Baking time for PyPi eventual consistency; 60s seemed more than enough + # https://github.com/aws-powertools/powertools-lambda-python/issues/2491 + - name: Baking time (PyPi) + run: sleep 60 + + - name: CDK build + run: npx cdk synth --verbose --context version="${{ inputs.latest_published_version }}" --context pythonVersion="${{ matrix.python-version }}" -o cdk.out + - name: zip output + run: zip -r cdk.py${{ matrix.python-version }}.out.zip cdk.out + - name: Archive CDK artifacts + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + with: + name: cdk-layer-artifact-py${{ matrix.python-version }} + path: layer/cdk.py${{ matrix.python-version }}.out.zip + + beta: + needs: build-layer + # lower privilege propagated from parent workflow (release.yml) + permissions: + id-token: write + contents: read + pages: write # docs will be updated with latest Layer ARNs + pull-requests: write # creation-action will create a PR with Layer ARN updates + uses: ./.github/workflows/reusable_deploy_v3_layer_stack.yml + secrets: inherit + with: + stage: "BETA" + environment: "layer-beta" + source_code_artifact_name: ${{ inputs.source_code_artifact_name }} + source_code_integrity_hash: ${{ inputs.source_code_integrity_hash }} + + # UNCOMMENT prod JOB + #prod: + # needs: beta + # lower privilege propagated from parent workflow (release.yml) + # permissions: + # id-token: write + # contents: read + # pages: write # docs will be updated with latest Layer ARNs + # pull-requests: write # creation-action will create a PR with Layer ARN updates + # uses: ./.github/workflows/reusable_deploy_v3_layer_stack.yml + # secrets: inherit + # with: + # stage: "PROD" + # environment: "layer-prod" + # source_code_artifact_name: ${{ inputs.source_code_artifact_name }} + # source_code_integrity_hash: ${{ inputs.source_code_integrity_hash }} + + sar-beta: + needs: beta # canaries run on Layer Beta env + permissions: + # lower privilege propagated from parent workflow (release.yml) + id-token: write + contents: read + pull-requests: none + pages: none + uses: ./.github/workflows/reusable_deploy_v3_sar.yml + secrets: inherit + with: + stage: "BETA" + environment: "layer-beta" + package-version: ${{ inputs.latest_published_version }} + source_code_artifact_name: ${{ inputs.source_code_artifact_name }} + source_code_integrity_hash: ${{ inputs.source_code_integrity_hash }} + + # UNCOMMENT sar-prod JOB + #sar-prod: + # needs: sar-beta + # permissions: + # lower privilege propagated from parent workflow (release.yml) + # id-token: write + # contents: read + # pull-requests: none + # pages: none + # uses: ./.github/workflows/reusable_deploy_v3_sar.yml + # secrets: inherit + # with: + # stage: "PROD" + # environment: "layer-prod" + # package-version: ${{ inputs.latest_published_version }} + # source_code_artifact_name: ${{ inputs.source_code_artifact_name }} + # source_code_integrity_hash: ${{ inputs.source_code_integrity_hash }} + + + # Updating the documentation with the latest Layer ARNs is a two-phase process + # + # 1. Update layer ARNs with latest deployed locally and create a PR with these changes + # 2. Pull from temporary branch with these changes and update the docs we're releasing + # + # This keeps our permissions tight and we don't run into a conflict, + # where a new release creates a new doc (2.16.0) while layers are still pointing to 2.15 + # because the PR has to be merged while release process is running + + # UNCOMMENT update_v3_layer_arn_docs JOB + #update_v3_layer_arn_docs: + # needs: prod + # outputs: + # temp_branch: ${{ steps.create-pr.outputs.temp_branch }} + # runs-on: ubuntu-latest + # permissions: + # lower privilege propagated from parent workflow (release.yml) + # contents: write + # pull-requests: write + # id-token: none + # pages: none + # steps: + # - name: Checkout repository # reusable workflows start clean, so we need to checkout again + # uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + # with: + # ref: ${{ env.RELEASE_COMMIT }} + + # - name: Restore sealed source code + # uses: ./.github/actions/seal-restore + # with: + # integrity_hash: ${{ inputs.source_code_integrity_hash }} + # artifact_name: ${{ inputs.source_code_artifact_name }} + + # - name: Download CDK layer artifacts + # uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 + # with: + # path: cdk-layer-stack + # pattern: cdk-layer-stack-* # merge all Layer artifacts created per region earlier (reusable_deploy_v2_layer_stack.yml; step "Save Layer ARN artifact") + # merge-multiple: true + # - name: Replace layer versions in documentation + # run: | + # ls -la cdk-layer-stack/ + # ./layer/scripts/update_layer_arn.sh cdk-layer-stack + # NOTE: It felt unnecessary creating yet another PR to update changelog w/ latest tag + # since this is the only step in the release where we update docs from a temp branch + # - name: Update changelog with latest tag + # run: make changelog + # - name: Create PR + # id: create-pr + # uses: ./.github/actions/create-pr + # with: + # files: "docs/index.md examples CHANGELOG.md" + # temp_branch_prefix: "ci-layer-docs" + # pull_request_title: "chore(ci): layer docs update" + # github_token: ${{ secrets.GITHUB_TOKEN }} + + # UNCOMMENT prepare_docs_alias JOB + #prepare_docs_alias: + # runs-on: ubuntu-latest + # permissions: + # # lower privilege propagated from parent workflow (release.yml) + # contents: read + # pages: none + # id-token: none + # pull-requests: none + # outputs: + # DOCS_ALIAS: ${{ steps.set-alias.outputs.DOCS_ALIAS }} + # steps: + # - name: Set docs alias + # id: set-alias + # run: | + # DOCS_ALIAS=latest + # if [[ "${{ inputs.pre_release }}" == true ]] ; then + # DOCS_ALIAS=alpha + # fi + # echo DOCS_ALIAS="$DOCS_ALIAS" >> "$GITHUB_OUTPUT" + + # UNCOMMENT release_docs JOB + #release_docs: + # needs: [update_v3_layer_arn_docs, prepare_docs_alias] + # permissions: + # # lower privilege propagated from parent workflow (release.yml) + # contents: write + # pages: write + # pull-requests: none + # id-token: write + # secrets: inherit + # uses: ./.github/workflows/reusable_publish_docs.yml + # with: + # version: ${{ inputs.latest_published_version }} + # alias: ${{ needs.prepare_docs_alias.outputs.DOCS_ALIAS }} + # git_ref: ${{ needs.update_v3_layer_arn_docs.outputs.temp_branch }} diff --git a/.github/workflows/release-v3.yml b/.github/workflows/release-v3.yml new file mode 100644 index 00000000000..ee18110a0c3 --- /dev/null +++ b/.github/workflows/release-v3.yml @@ -0,0 +1,379 @@ +name: Release V3 + +# RELEASE PROCESS +# +# === Automated activities === +# +# 1. [Seal] Bump to release version and export source code with integrity hash +# 2. [Quality check] Restore sealed source code, run tests, linting, security and complexity base line +# 3. [Build] Restore sealed source code, create and export hashed build artifact for PyPi release (wheel, tarball) +# 4. [Provenance] Generates provenance for build, signs attestation with GitHub OIDC claims to confirm it came from this release pipeline, commit, org, repo, branch, hash, etc. +# 5. [Release] Restore built artifact, and publish package to PyPi prod repository +# 6. [Create Tag] Restore sealed source code, create a new git tag using released version, uploads provenance to latest draft release +# 7. [PR to bump version] Restore sealed source code, and create a PR to update trunk with latest released project metadata +# 8. [Publish Layer v3] Compile Layer in multiple Python versions and kick off pipeline for beta, prod, and canary releases +# 9. [Publish Layer v3] Update docs with latest Layer ARNs and Changelog +# 10. [Publish Layer v3] Create PR to update trunk so staged docs also point to the latest Layer ARN, when merged +# 12. [Post release] Close all issues labeled "pending-release" and notify customers about the release +# +# === Manual activities === +# +# 1. Kick off this workflow with the intended version +# 2. Update draft release notes after this workflow completes +# 3. If not already set, use `v` as a tag, e.g., v3.0.0, and select develop as target branch + +# NOTE +# +# See MAINTAINERS.md "Releasing a new version" for release mechanisms +# +# Every job is isolated and starts a new fresh container. + +env: + RELEASE_COMMIT: ${{ github.sha }} + RELEASE_TAG_VERSION: ${{ inputs.version_to_publish }} + +on: + workflow_dispatch: + inputs: + version_to_publish: + description: "Version to be released in PyPi, Docs, and Lambda Layer, e.g. v3.0.0, v3.0.0a0 (pre-release)" + default: v3.0.0 + required: true + skip_pypi: + description: "Skip publishing to PyPi as it can't publish more than once. Useful for semi-failed releases" + default: false + type: boolean + required: false + skip_code_quality: + description: "Skip tests, linting, and baseline. Only use if release fail for reasons beyond our control and you need a quick release." + default: false + type: boolean + required: false + pre_release: + description: "Publishes documentation using a pre-release tag (v3.0.0a0). You are still responsible for passing a pre-release version tag to the workflow." + default: false + type: boolean + required: false + +permissions: + contents: read + +jobs: + + # This job bumps the package version to the release version + # creates an integrity hash from the source code + # uploads the artifact with the integrity hash as the key name + # so subsequent jobs can restore from a trusted point in time to prevent tampering + seal: + runs-on: ubuntu-latest + permissions: + contents: read + outputs: + integrity_hash: ${{ steps.seal_source_code.outputs.integrity_hash }} + artifact_name: ${{ steps.seal_source_code.outputs.artifact_name }} + RELEASE_VERSION: ${{ steps.release_version.outputs.RELEASE_VERSION }} + steps: + - name: Export release version + id: release_version + # transform tag format `v` + run: | + RELEASE_VERSION="${RELEASE_TAG_VERSION:1}" + echo "RELEASE_VERSION=${RELEASE_VERSION}" >> "$GITHUB_OUTPUT" + + - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + with: + ref: ${{ env.RELEASE_COMMIT }} + + # We use a pinned version of Poetry to be certain it won't modify source code before we create a hash + - name: Install poetry + run: | + pipx install git+https://github.com/python-poetry/poetry@68b88e5390720a3dd84f02940ec5200bfce39ac6 # v1.5.0 + pipx inject poetry git+https://github.com/monim67/poetry-bumpversion@315fe3324a699fa12ec20e202eb7375d4327d1c4 # v0.3.1 + + - name: Bump package version + id: versioning + run: poetry version "${RELEASE_VERSION}" + env: + RELEASE_VERSION: ${{ steps.release_version.outputs.RELEASE_VERSION}} + + - name: Seal and upload + id: seal_source_code + uses: ./.github/actions/seal + with: + artifact_name_prefix: "source" + + # This job runs our automated test suite, complexity and security baselines + # it ensures previously merged have been tested as part of the pull request process + # + # NOTE + # + # we don't upload the artifact after testing to prevent any tampering of our source code dependencies + quality_check: + needs: seal + runs-on: ubuntu-latest + permissions: + contents: read + steps: + # NOTE: we need actions/checkout to configure git first (pre-commit hooks in make dev) + - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + with: + ref: ${{ env.RELEASE_COMMIT }} + + - name: Restore sealed source code + uses: ./.github/actions/seal-restore + with: + integrity_hash: ${{ needs.seal.outputs.integrity_hash }} + artifact_name: ${{ needs.seal.outputs.artifact_name }} + + - name: Debug cache restore + run: cat pyproject.toml + + - name: Install poetry + run: pipx install git+https://github.com/python-poetry/poetry@68b88e5390720a3dd84f02940ec5200bfce39ac6 # v1.5.0 + - name: Set up Python + uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 + with: + python-version: "3.12" + cache: "poetry" + - name: Install dependencies + run: make dev + - name: Run all tests, linting and baselines + run: make pr + + # This job creates a release artifact (tar.gz, wheel) + # it checks out code from release commit for custom actions to work + # then restores the sealed source code (overwrites any potential tampering) + # it's done separately from release job to enforce least privilege. + # We export just the final build artifact for release + build: + runs-on: ubuntu-latest + needs: [quality_check, seal] + permissions: + contents: read + outputs: + integrity_hash: ${{ steps.seal_build.outputs.integrity_hash }} + artifact_name: ${{ steps.seal_build.outputs.artifact_name }} + attestation_hashes: ${{ steps.encoded_hash.outputs.attestation_hashes }} + steps: + # NOTE: we need actions/checkout to configure git first (pre-commit hooks in make dev) + - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + with: + ref: ${{ env.RELEASE_COMMIT }} + + - name: Restore sealed source code + uses: ./.github/actions/seal-restore + with: + integrity_hash: ${{ needs.seal.outputs.integrity_hash }} + artifact_name: ${{ needs.seal.outputs.artifact_name }} + + - name: Install poetry + run: pipx install git+https://github.com/python-poetry/poetry@68b88e5390720a3dd84f02940ec5200bfce39ac6 # v1.5.0 + - name: Set up Python + uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 + with: + python-version: "3.12" + cache: "poetry" + + - name: Build python package and wheel + run: poetry build + + - name: Seal and upload + id: seal_build + uses: ./.github/actions/seal + with: + artifact_name_prefix: "build" + files: "dist/" + + # NOTE: SLSA retraces our build to its artifact to ensure it wasn't tampered + # coupled with GitHub OIDC, SLSA can then confidently sign it came from this release pipeline+commit+branch+org+repo+actor+integrity hash + - name: Create attestation encoded hash for provenance + id: encoded_hash + working-directory: dist + run: echo "attestation_hashes=$(sha256sum ./* | base64 -w0)" >> "$GITHUB_OUTPUT" + + # This job creates a provenance file that describes how our release was built (all steps) + # after it verifies our build is reproducible within the same pipeline + # it confirms that its own software and the CI build haven't been tampered with (Trust but verify) + # lastly, it creates and sign an attestation (multiple.intoto.jsonl) that confirms + # this build artifact came from this GitHub org, branch, actor, commit ID, inputs that triggered this pipeline, and matches its integrity hash + # NOTE: supply chain threats review (we protect against all of them now): https://slsa.dev/spec/v1.0/threats-overview + provenance: + needs: [seal, build] + permissions: + contents: write # nested job explicitly require despite upload assets being set to false + actions: read # To read the workflow path. + id-token: write # To sign the provenance. + # NOTE: provenance fails if we use action pinning... it's a Github limitation + # because SLSA needs to trace & attest it came from a given branch; pinning doesn't expose that information + # https://github.com/slsa-framework/slsa-github-generator/blob/main/internal/builders/generic/README.md#referencing-the-slsa-generator + uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.0.0 + with: + base64-subjects: ${{ needs.build.outputs.attestation_hashes }} + upload-assets: false # we upload its attestation in create_tag job, otherwise it creates a new release + + # This job uses release artifact to publish to PyPi + # it exchanges JWT tokens with GitHub to obtain PyPi credentials + # since it's already registered as a Trusted Publisher. + # It uses the sealed build artifact (.whl, .tar.gz) to release it + release: + needs: [build, seal, provenance] + environment: release + runs-on: ubuntu-latest + permissions: + id-token: write # OIDC for PyPi Trusted Publisher feature + env: + RELEASE_VERSION: ${{ needs.seal.outputs.RELEASE_VERSION }} + steps: + # NOTE: we need actions/checkout in order to use our local actions (e.g., ./.github/actions) + - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + with: + ref: ${{ env.RELEASE_COMMIT }} + + - name: Restore sealed source code + uses: ./.github/actions/seal-restore + with: + integrity_hash: ${{ needs.build.outputs.integrity_hash }} + artifact_name: ${{ needs.build.outputs.artifact_name }} + + - name: Upload to PyPi prod + if: ${{ !inputs.skip_pypi }} + uses: pypa/gh-action-pypi-publish@81e9d935c883d0b210363ab89cf05f3894778450 # v1.8.14 + + # PyPi test maintenance affected us numerous times, leaving for history purposes + # - name: Upload to PyPi test + # if: ${{ !inputs.skip_pypi }} + # uses: pypa/gh-action-pypi-publish@81e9d935c883d0b210363ab89cf05f3894778450 # v1.8.14 + # with: + # repository-url: https://test.pypi.org/legacy/ + + # We create a Git Tag using our release version (e.g., v3.16.0) + # using our sealed source code we created earlier. + # Because we bumped version of our project as part of CI + # we need to add this into git before pushing the tag + # otherwise the release commit will be used as the basis for the tag. + # Later, we create a PR to update trunk with our newest release version (e.g., bump_version job) + # UNCOMMENT CREATE_TAG JOB + #create_tag: + # needs: [release, seal, provenance] + # runs-on: ubuntu-latest + # permissions: + # contents: write + # steps: + # NOTE: we need actions/checkout to authenticate and configure git first + # - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + # with: + # ref: ${{ env.RELEASE_COMMIT }} + + # - name: Restore sealed source code + # uses: ./.github/actions/seal-restore + # with: + # integrity_hash: ${{ needs.seal.outputs.integrity_hash }} + # artifact_name: ${{ needs.seal.outputs.artifact_name }} + + # - id: setup-git + # name: Git client setup and refresh tip + # run: | + # git config user.name "Powertools for AWS Lambda (Python) bot" + # git config user.email "151832416+aws-powertools-bot@users.noreply.github.com" + # git config remote.origin.url >&- + + # - name: Create Git Tag + # run: | + # git add pyproject.toml aws_lambda_powertools/shared/version.py + # git commit -m "chore: version bump" + # git tag -a v"${RELEASE_VERSION}" -m "release_version: v${RELEASE_VERSION}" + # git push origin v"${RELEASE_VERSION}" + # env: + # RELEASE_VERSION: ${{ needs.seal.outputs.RELEASE_VERSION }} + + # - name: Upload provenance + # id: upload-provenance + # uses: ./.github/actions/upload-release-provenance + # with: + # release_version: ${{ needs.seal.outputs.RELEASE_VERSION }} + # provenance_name: ${{needs.provenance.outputs.provenance-name}} + # github_token: ${{ secrets.GITHUB_TOKEN }} + + # Creates a PR with the latest version we've just released + # since our trunk is protected against any direct pushes from automation + # UNCOMMENT BUMP_VERSION JOB + #bump_version: + # needs: [release, seal] + # permissions: + # contents: write # create-pr action creates a temporary branch + # pull-requests: write # create-pr action creates a PR using the temporary branch + # runs-on: ubuntu-latest + # steps: + # NOTE: we need actions/checkout to authenticate and configure git first + # - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + # with: + # ref: ${{ env.RELEASE_COMMIT }} + + # - name: Restore sealed source code + # uses: ./.github/actions/seal-restore + # with: + # integrity_hash: ${{ needs.seal.outputs.integrity_hash }} + # artifact_name: ${{ needs.seal.outputs.artifact_name }} + + # - name: Create PR + # id: create-pr + # uses: ./.github/actions/create-pr + # with: + # files: "pyproject.toml aws_lambda_powertools/shared/version.py" + # temp_branch_prefix: "ci-bump" + # pull_request_title: "chore(ci): bump version to ${{ needs.seal.outputs.RELEASE_VERSION }}" + # github_token: ${{ secrets.GITHUB_TOKEN }} + + # This job compiles a Lambda Layer optimized for space and speed (e.g., Cython) + # It then deploys to Layer's Beta and Prod account, including SAR Beta and Prod account. + # It uses canaries to attest Layers can be used and imported between stages. + # Lastly, it updates our documentation with the latest Layer ARN for all regions + # + # NOTE + # + # Watch out for the depth limit of 4 nested workflow_calls. + # publish_layer -> publish_3_layer -> reusable_deploy_v3_layer_stack + publish_layer: + # UNCOMMENT THE LINE + #needs: [seal, release, create_tag] + needs: [seal, release] + secrets: inherit + permissions: + id-token: write + contents: write + pages: write + pull-requests: write + uses: ./.github/workflows/publish_v3_layer.yml + with: + latest_published_version: ${{ needs.seal.outputs.RELEASE_VERSION }} + pre_release: ${{ inputs.pre_release }} + source_code_artifact_name: ${{ needs.seal.outputs.artifact_name }} + source_code_integrity_hash: ${{ needs.seal.outputs.integrity_hash }} + + # UNCOMMENT POST_RELEASE JOB + #post_release: + # needs: [seal, release, publish_layer] + # permissions: + # contents: read + # issues: write + # discussions: write + # pull-requests: write + # runs-on: ubuntu-latest + # env: + # RELEASE_VERSION: ${{ needs.seal.outputs.RELEASE_VERSION }} + # steps: + # - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + # with: + # ref: ${{ env.RELEASE_COMMIT }} + # - name: Restore sealed source code + # uses: ./.github/actions/seal-restore + # with: + # integrity_hash: ${{ needs.seal.outputs.integrity_hash }} + # artifact_name: ${{ needs.seal.outputs.artifact_name }} + # - name: Close issues related to this release + # uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 + # with: + # github-token: ${{ secrets.GITHUB_TOKEN }} + # script: | + # const post_release = require('.github/scripts/post_release.js') + # await post_release({github, context, core}) diff --git a/.github/workflows/reusable_deploy_v3_layer_stack.yml b/.github/workflows/reusable_deploy_v3_layer_stack.yml new file mode 100644 index 00000000000..f7f01951a97 --- /dev/null +++ b/.github/workflows/reusable_deploy_v3_layer_stack.yml @@ -0,0 +1,214 @@ +name: Deploy CDK Layer v3 stack + +# PROCESS +# +# 1. Split what AWS regions support ARM vs regions that Lambda support ARM +# 2. We build the Lambda layer for 3.8 to 3.12 Python runtime and both x86_64 and arm64 (see `matrix` section) +# 3. Deploy previously built layer for each AWS commercial region +# 4. Export all published Layers as JSON +# 5. Deploy Canaries to every deployed region to test whether Powertools can be imported etc. + +# USAGE +# +# NOTE: meant to be used with ./.github/workflows/publish_v3_layer.yml +# +# beta: +# needs: build-layer +# # lower privilege propagated from parent workflow (release.yml) +# permissions: +# id-token: write +# contents: read +# pages: write # docs will be updated with latest Layer ARNs +# pull-requests: write # creation-action will create a PR with Layer ARN updates +# uses: ./.github/workflows/reusable_deploy_v3_layer_stack.yml +# secrets: inherit +# with: +# stage: "BETA" +# environment: "layer-beta" +# source_code_artifact_name: code.zip +# source_code_integrity_hash: sha256string + +on: + workflow_call: + inputs: + stage: + description: "Deployment stage (BETA, PROD)" + required: true + type: string + environment: + description: "GitHub Environment to use for encrypted secrets" + required: true + type: string + source_code_artifact_name: + description: "Artifact name to restore sealed source code" + type: string + required: true + source_code_integrity_hash: + description: "Sealed source code integrity hash" + type: string + required: true + +permissions: + contents: read + +env: + RELEASE_COMMIT: ${{ github.sha }} # it gets propagated from the caller for security reasons + +jobs: + deploy-cdk-stack: + runs-on: ubuntu-latest + environment: ${{ inputs.environment }} + # lower privilege propagated from parent workflow (publish_v3_layer.yml) + permissions: + id-token: write + pull-requests: none + contents: read + pages: none + defaults: + run: + working-directory: ./layer_v3 + strategy: + fail-fast: false + matrix: + # To get a list of current regions, use: + # aws ec2 describe-regions --all-regions --query "Regions[].RegionName" --output text | tr "\t" "\n" | sort + region: ["af-south-1", "ap-east-1", "ap-northeast-1", "ap-northeast-2", "ap-northeast-3", + "ap-south-1", "ap-south-2", "ap-southeast-1", "ap-southeast-2", "ap-southeast-3", + "ap-southeast-4", "ca-central-1", "ca-west-1", "eu-central-1", "eu-central-2", + "eu-north-1", "eu-south-1", "eu-south-2", "eu-west-1", "eu-west-2", "eu-west-3", + "il-central-1", "me-central-1", "me-south-1", "sa-east-1", "us-east-1", + "us-east-2", "us-west-1", "us-west-2"] + python-version: ["3.8","3.9","3.10","3.11","3.12"] + include: + - region: "af-south-1" + has_arm64_support: "true" + - region: "ap-east-1" + has_arm64_support: "true" + - region: "ap-northeast-1" + has_arm64_support: "true" + - region: "ap-northeast-2" + has_arm64_support: "true" + - region: "ap-northeast-3" + has_arm64_support: "true" + - region: "ap-south-1" + has_arm64_support: "true" + - region: "ap-south-2" + has_arm64_support: "true" + - region: "ap-southeast-1" + has_arm64_support: "true" + - region: "ap-southeast-2" + has_arm64_support: "true" + - region: "ap-southeast-3" + has_arm64_support: "true" + - region: "ap-southeast-4" + has_arm64_support: "true" + - region: "ca-central-1" + has_arm64_support: "true" + - region: "ca-west-1" + has_arm64_support: "false" + - region: "eu-central-1" + has_arm64_support: "true" + - region: "eu-central-2" + has_arm64_support: "true" + - region: "eu-north-1" + has_arm64_support: "true" + - region: "eu-south-1" + has_arm64_support: "true" + - region: "eu-south-2" + has_arm64_support: "true" + - region: "eu-west-1" + has_arm64_support: "true" + - region: "eu-west-2" + has_arm64_support: "true" + - region: "eu-west-3" + has_arm64_support: "true" + - region: "il-central-1" + has_arm64_support: "true" + - region: "me-central-1" + has_arm64_support: "true" + - region: "me-south-1" + has_arm64_support: "true" + - region: "sa-east-1" + has_arm64_support: "true" + - region: "us-east-1" + has_arm64_support: "true" + - region: "us-east-2" + has_arm64_support: "true" + - region: "us-west-1" + has_arm64_support: "true" + - region: "us-west-2" + has_arm64_support: "true" + steps: + - name: checkout + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + with: + ref: ${{ env.RELEASE_COMMIT }} + + - name: Restore sealed source code + uses: ./.github/actions/seal-restore + with: + integrity_hash: ${{ inputs.source_code_integrity_hash }} + artifact_name: ${{ inputs.source_code_artifact_name }} + + - name: Install poetry + run: pipx install git+https://github.com/python-poetry/poetry@68b88e5390720a3dd84f02940ec5200bfce39ac6 # v1.5.0 + - name: aws credentials + uses: aws-actions/configure-aws-credentials@5fd3084fc36e372ff1fff382a39b10d03659f355 # v2.2.0 + with: + aws-region: ${{ matrix.region }} + role-to-assume: ${{ secrets.AWS_LAYERS_ROLE_ARN }} + - name: Setup Node.js + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + with: + node-version: "18.20.4" + - name: Setup python + uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 + with: + python-version: ${{ matrix.python-version }} + cache: "pip" + - name: Resolve and install project dependencies + # CDK spawns system python when compiling stack + # therefore it ignores both activated virtual env and cached interpreter by GH + run: | + poetry export --format requirements.txt --output requirements.txt + pip install --require-hashes -r requirements.txt + - name: install cdk and deps + working-directory: ./ + run: | + npm ci + npx cdk --version + - name: install deps + run: poetry install + - name: Download artifact + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 + with: + name: cdk-layer-artifact-py${{ matrix.python-version }} + path: layer + - name: unzip artefact + run: unzip cdk.py${{ matrix.python-version }}.out.zip + - name: Define constants + id: constants + run: | + PYTHON_VERSION=$(echo ${{ matrix.python-version }} | tr -d '.') + echo "PYTHON_VERSION=${PYTHON_VERSION}" >> "$GITHUB_OUTPUT" + LAYER_VERSION=${{ matrix.region }}-$PYTHON_VERSION-layer-version.txt + echo "LAYER_VERSION=${LAYER_VERSION}" >> "$GITHUB_OUTPUT" + - name: CDK Deploy Layer + run: npx cdk deploy --app cdk.out --context region=${{ matrix.region }} --parameters HasARM64Support=${{ matrix.has_arm64_support }} "LayerV3Stack-${{steps.constants.outputs.PYTHON_VERSION}}" --require-approval never --verbose --outputs-file cdk-outputs.json + - name: Store latest Layer ARN + if: ${{ inputs.stage == 'PROD' }} + run: | + mkdir cdk-layer-stack + jq -r -c ".[\"LayerV3Stack-${{steps.constants.outputs.PYTHON_VERSION}}\"].LatestLayerArn" cdk-outputs.json > cdk-layer-stack/${{steps.constants.outputs.LAYER_VERSION}} + jq -r -c ".[\"LayerV3Stack-${{steps.constants.outputs.PYTHON_VERSION}}\"].LatestLayerArm64Arn" cdk-outputs.json >> cdk-layer-stack/${{steps.constants.outputs.LAYER_VERSION}} + cat cdk-layer-stack/${{steps.constants.outputs.LAYER_VERSION}} + - name: Save Layer ARN artifact + if: ${{ inputs.stage == 'PROD' }} + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + with: + name: cdk-layer-stack-${{ matrix.region }}-${{ matrix.python-version }} + path: ./layer/cdk-layer-stack/* # NOTE: upload-artifact does not inherit working-directory setting. + if-no-files-found: error + retention-days: 1 + - name: CDK Deploy Canary + run: npx cdk deploy --app cdk.out --context region=${{ matrix.region }} --parameters DeployStage="${{ inputs.stage }}" --parameters HasARM64Support=${{ matrix.has_arm64_support }} "CanaryV3Stack-${{steps.constants.outputs.PYTHON_VERSION}}" --require-approval never --verbose diff --git a/.github/workflows/reusable_deploy_v3_sar.yml b/.github/workflows/reusable_deploy_v3_sar.yml new file mode 100644 index 00000000000..6ca7cea4dfc --- /dev/null +++ b/.github/workflows/reusable_deploy_v3_sar.yml @@ -0,0 +1,213 @@ +name: Deploy V3 SAR + +# PROCESS +# +# 1. This workflow starts after the layer artifact is produced on `publish_v3_layer` +# 2. We use the same layer artifact to ensure the SAR app is consistent with the published Lambda Layer +# 3. We publish the SAR for 3.8 to 3.12 Python runtime and both x86_64 and arm64 (see `matrix` section) +# 4. We use `sam package` and `sam publish` to publish the SAR app +# 5. We remove the previous Canary stack (if present) and deploy a new one to test the SAR App. We retain the Canary in the account for debugging purposes +# 6. Finally the published SAR app is made public on the PROD environment + +# USAGE +# +# NOTE: meant to be used with ./.github/workflows/publish_v3_layer.yml +# +# sar-beta: +# needs: build-layer +# permissions: +# # lower privilege propagated from parent workflow (release.yml) +# id-token: write +# contents: read +# pull-requests: none +# pages: none +# uses: ./.github/workflows/reusable_deploy_v3_sar.yml +# secrets: inherit +# with: +# stage: "BETA" +# environment: "layer-beta" +# package-version: ${{ inputs.latest_published_version }} +# source_code_artifact_name: ${{ inputs.source_code_artifact_name }} +# source_code_integrity_hash: ${{ inputs.source_code_integrity_hash }} + +permissions: + id-token: write + contents: read + +env: + NODE_VERSION: 18.20.4 + AWS_REGION: eu-west-1 + SAR_NAME: aws-lambda-powertools-python-layer-v3 # PROBLEM - WE NEED TO TALK + TEST_STACK_NAME: serverlessrepo-v3-powertools-layer-test-stack + RELEASE_COMMIT: ${{ github.sha }} # it gets propagated from the caller for security reasons + +on: + workflow_call: + inputs: + stage: + description: "Deployment stage (BETA, PROD)" + required: true + type: string + package-version: + description: "The version of the package to deploy" + required: true + type: string + environment: + description: "GitHub Environment to use for encrypted secrets" + required: true + type: string + source_code_artifact_name: + description: "Artifact name to restore sealed source code" + type: string + required: true + source_code_integrity_hash: + description: "Sealed source code integrity hash" + type: string + required: true + +jobs: + deploy-sar-app: + runs-on: ubuntu-latest + environment: ${{ inputs.environment }} + strategy: + matrix: + architecture: ["x86_64", "arm64"] + python-version: ["3.8","3.9","3.10","3.11","3.12"] + steps: + - name: checkout + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + with: + ref: ${{ env.RELEASE_COMMIT }} + + - name: Restore sealed source code + uses: ./.github/actions/seal-restore + with: + integrity_hash: ${{ inputs.source_code_integrity_hash }} + artifact_name: ${{ inputs.source_code_artifact_name }} + + + - name: AWS credentials + uses: aws-actions/configure-aws-credentials@5fd3084fc36e372ff1fff382a39b10d03659f355 # v2.2.0 + with: + aws-region: ${{ env.AWS_REGION }} + role-to-assume: ${{ secrets.AWS_LAYERS_ROLE_ARN }} + + # NOTE + # We connect to Layers account to log our intent to publish a SAR Layer + # we then jump to our specific SAR Account with the correctly scoped IAM Role + # this allows us to have a single trail when a release occurs for a given layer (beta+prod+SAR beta+SAR prod) + - name: AWS credentials SAR role + uses: aws-actions/configure-aws-credentials@5fd3084fc36e372ff1fff382a39b10d03659f355 # v2.2.0 + id: aws-credentials-sar-role + with: + aws-access-key-id: ${{ env.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ env.AWS_SECRET_ACCESS_KEY }} + aws-session-token: ${{ env.AWS_SESSION_TOKEN }} + role-duration-seconds: 1200 + aws-region: ${{ env.AWS_REGION }} + role-to-assume: ${{ secrets.AWS_SAR_V2_ROLE_ARN }} + - name: Setup Node.js + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + with: + node-version: ${{ env.NODE_VERSION }} + - name: Download artifact + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 + with: + name: cdk-layer-artifact-py${{ matrix.python-version }} + - name: Unzip artefact + run: unzip cdk.py${{ matrix.python-version }}.out.zip + - name: normalize Python Version + run: | + PYTHON_VERSION=$(echo ${{ matrix.python-version }} | tr -d '.') + echo "PYTHON_VERSION=${PYTHON_VERSION}" >> "$GITHUB_ENV" + - name: Configure SAR name + run: | + if [[ "${{ inputs.stage }}" == "BETA" ]]; then + SAR_NAME="test-${SAR_NAME}" + fi + ARCH_NAME=$(echo ${{ matrix.architecture }} | tr -d '_') + SAR_NAME="${SAR_NAME}-python${{env.PYTHON_VERSION}}-${ARCH_NAME}" + echo SAR_NAME="${SAR_NAME}" >> "$GITHUB_ENV" + - name: Adds arm64 suffix to SAR name + if: ${{ matrix.architecture == 'arm64' }} + run: echo SAR_NAME="${SAR_NAME}-arm64" >> "$GITHUB_ENV" + - name: Normalize semantic version + id: semantic-version # v2.0.0a0 -> v2.0.0-a0 + env: + VERSION: ${{ inputs.package-version }} + run: | + VERSION="${VERSION/a/-a}" + echo "VERSION=${VERSION}" >> "$GITHUB_OUTPUT" + - name: Prepare SAR App + env: + VERSION: ${{ steps.semantic-version.outputs.VERSION }} + run: | + # From the generated LayerStack cdk.out artifact, find the layer asset path for the correct architecture. + # We'll use this as the source directory of our SAR. This way we are re-using the same layer asset for our SAR. + PYTHON_VERSION=$(echo ${{ matrix.python-version }} | tr -d '.') + asset=$(jq -jc '.Resources[] | select(.Properties.CompatibleArchitectures == ["${{ matrix.architecture }}"]) | .Metadata."aws:asset:path"' "cdk.out/LayerV3Stack-${PYTHON_VERSION}.template.json") + + # fill in the SAR SAM template + sed \ + -e "s||${VERSION}|g" \ + -e "s//${{ env.SAR_NAME }}/g" \ + -e "s||./cdk.out/$asset|g" \ + -e "s||${{ matrix.python-version }}|g" \ + -e "s||${{ matrix.architecture }}|g" \ + layer/sar/template.txt > template.yml + + # SAR needs a README and a LICENSE, so just copy the ones from the repo + cp README.md LICENSE "./cdk.out/$asset/" + - name: Deploy SAR + run: | + # Debug purposes + cat template.yml + + # Package the SAR to our SAR S3 bucket, and publish it + sam package --template-file template.yml --output-template-file packaged.yml --s3-bucket ${{ secrets.AWS_SAR_S3_BUCKET }} + sam publish --template packaged.yml --region "$AWS_REGION" + - name: Deploy BETA canary + if: ${{ inputs.stage == 'BETA' }} + run: | + ARCH_NAME=$(echo ${{ matrix.architecture }} | tr -d '_') + TEST_STACK_NAME="${TEST_STACK_NAME}-python${{env.PYTHON_VERSION}}-${ARCH_NAME}" + + echo "Check if stack does not exist" + stack_exists=$(aws cloudformation list-stacks --query "StackSummaries[?(StackName == '$TEST_STACK_NAME' && StackStatus == 'CREATE_COMPLETE')].{StackId:StackId, StackName:StackName, CreationTime:CreationTime, StackStatus:StackStatus}" --output text) + + if [[ -n "$stack_exists" ]] ; then + echo "Found test deployment stack, removing..." + aws cloudformation delete-stack --stack-name "$TEST_STACK_NAME" + aws cloudformation wait stack-delete-complete --stack-name "$TEST_STACK_NAME" + fi + + echo "Creating canary stack" + echo "Stack name: $TEST_STACK_NAME" + aws serverlessrepo create-cloud-formation-change-set \ + --application-id arn:aws:serverlessrepo:${{ env.AWS_REGION }}:${{ steps.aws-credentials-sar-role.outputs.aws-account-id }}:applications/${{ env.SAR_NAME }} \ + --stack-name "${TEST_STACK_NAME/serverlessrepo-/}" \ + --capabilities CAPABILITY_NAMED_IAM + + CHANGE_SET_ID=$(aws cloudformation list-change-sets --stack-name "$TEST_STACK_NAME" --query 'Summaries[*].ChangeSetId' --output text) + aws cloudformation wait change-set-create-complete --change-set-name "$CHANGE_SET_ID" + aws cloudformation execute-change-set --change-set-name "$CHANGE_SET_ID" + aws cloudformation wait stack-create-complete --stack-name "$TEST_STACK_NAME" + + echo "Waiting until stack deployment completes..." + + echo "Exit with error if stack is not in CREATE_COMPLETE" + stack_exists=$(aws cloudformation list-stacks --query "StackSummaries[?(StackName == '$TEST_STACK_NAME' && StackStatus == 'CREATE_COMPLETE')].{StackId:StackId, StackName:StackName, CreationTime:CreationTime, StackStatus:StackStatus}") + if [[ -z "$stack_exists" ]] ; then + echo "Could find successful deployment, exit error..." + exit 1 + fi + echo "Deployment successful" + - name: Publish SAR + if: ${{ inputs.stage == 'PROD' }} + run: | + # wait until SAR registers the app, otherwise it fails to make it public + sleep 15 + echo "Make SAR app public" + aws serverlessrepo put-application-policy \ + --application-id arn:aws:serverlessrepo:${{ env.AWS_REGION }}:${{ steps.aws-credentials-sar-role.outputs.aws-account-id }}:applications/${{ env.SAR_NAME }} \ + --statements Principals='*',Actions=Deploy From 78a11e6182dabe486a339dd6d1f5502c943d0172 Mon Sep 17 00:00:00 2001 From: Leandro Damascena Date: Wed, 21 Aug 2024 15:38:16 +0100 Subject: [PATCH 2/3] Commenting SAR --- .github/workflows/publish_v3_layer.yml | 32 +++++++++++++------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/.github/workflows/publish_v3_layer.yml b/.github/workflows/publish_v3_layer.yml index 67cffbd7f57..f1f3ad492ca 100644 --- a/.github/workflows/publish_v3_layer.yml +++ b/.github/workflows/publish_v3_layer.yml @@ -187,22 +187,22 @@ jobs: # source_code_artifact_name: ${{ inputs.source_code_artifact_name }} # source_code_integrity_hash: ${{ inputs.source_code_integrity_hash }} - sar-beta: - needs: beta # canaries run on Layer Beta env - permissions: - # lower privilege propagated from parent workflow (release.yml) - id-token: write - contents: read - pull-requests: none - pages: none - uses: ./.github/workflows/reusable_deploy_v3_sar.yml - secrets: inherit - with: - stage: "BETA" - environment: "layer-beta" - package-version: ${{ inputs.latest_published_version }} - source_code_artifact_name: ${{ inputs.source_code_artifact_name }} - source_code_integrity_hash: ${{ inputs.source_code_integrity_hash }} + #sar-beta: + # needs: beta # canaries run on Layer Beta env + # permissions: + # # lower privilege propagated from parent workflow (release.yml) + # id-token: write + # contents: read + # pull-requests: none + # pages: none + # uses: ./.github/workflows/reusable_deploy_v3_sar.yml + # secrets: inherit + # with: + # stage: "BETA" + # environment: "layer-beta" + # package-version: ${{ inputs.latest_published_version }} + # source_code_artifact_name: ${{ inputs.source_code_artifact_name }} + # source_code_integrity_hash: ${{ inputs.source_code_integrity_hash }} # UNCOMMENT sar-prod JOB #sar-prod: From 168fbcfe0d94b5f24a9b0575b743ed3a72f80df5 Mon Sep 17 00:00:00 2001 From: Leandro Damascena Date: Wed, 21 Aug 2024 15:54:16 +0100 Subject: [PATCH 3/3] Removing old comment --- .github/workflows/reusable_deploy_v3_sar.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/reusable_deploy_v3_sar.yml b/.github/workflows/reusable_deploy_v3_sar.yml index 6ca7cea4dfc..0f2cbe2bbaf 100644 --- a/.github/workflows/reusable_deploy_v3_sar.yml +++ b/.github/workflows/reusable_deploy_v3_sar.yml @@ -37,7 +37,7 @@ permissions: env: NODE_VERSION: 18.20.4 AWS_REGION: eu-west-1 - SAR_NAME: aws-lambda-powertools-python-layer-v3 # PROBLEM - WE NEED TO TALK + SAR_NAME: aws-lambda-powertools-python-layer-v3 TEST_STACK_NAME: serverlessrepo-v3-powertools-layer-test-stack RELEASE_COMMIT: ${{ github.sha }} # it gets propagated from the caller for security reasons