diff --git a/.github/scripts/update_layer_arn.sh b/.github/scripts/update_layer_arn.sh new file mode 100755 index 0000000000..51a7149880 --- /dev/null +++ b/.github/scripts/update_layer_arn.sh @@ -0,0 +1,72 @@ +#!/bin/bash + +# This script is run during the reusable_update_v2_layer_arn_docs CI job, +# and it is responsible for replacing the layer ARN in our documentation, +# based on the output files generated by CDK when deploying to each pseudo_region. +# +# see .github/workflows/reusable_deploy_v2_layer_stack.yml + +set -eo pipefail + +if [[ $# -ne 1 ]]; then + cat < line + # sed doesn't support \d+ in a portable way, so we cheat with (:digit: :digit: *) + sed -i -e "s/$prefix:[[:digit:]][[:digit:]]*/$line/g" docs/index.md + + # We use the eu-central-1 layer as the version for all the frameworks (SAM, CDK, SLS, etc) + # We could have used any other region. What's important is the version at the end. + + # Examples of strings found in the documentation with pseudo regions: + # arn:aws:lambda:{region}:094274105915:layer:AWSLambdaPowertoolsTypeScript:39 + # arn:aws:lambda:${AWS::Region}:094274105915:layer:AWSLambdaPowertoolsTypeScript:39 + # arn:aws:lambda:${aws:region}:094274105915:layer:AWSLambdaPowertoolsTypeScript:39 + # arn:aws:lambda:{env.region}:094274105915:layer:AWSLambdaPowertoolsTypeScript:39 + if [[ "$line" == *"eu-central-1"* ]]; then + # These are all the framework pseudo parameters currently found in the docs + for pseudo_region in '{region}' '${AWS::Region}' '${aws::region}' '{aws::region}' '{env.region}' '${cdk.Stack.of(this).region}' '${aws.getRegionOutput().name}'; do + prefix_pseudo_region=$(echo "$prefix" | sed "s/eu-central-1/${pseudo_region}/") + # prefix_pseudo_region = arn:aws:lambda:${AWS::Region}:094274105915:layer:AWSLambdaPowertoolsTypeScript + + line_pseudo_region=$(echo "$line" | sed "s/eu-central-1/${pseudo_region}/") + # line_pseudo_region = arn:aws:lambda:${AWS::Region}:094274105915:layer:AWSLambdaPowertoolsTypeScript:49 + + # Replace all the "prefix_pseudo_region"'s in the file + # prefix_pseudo_region:\d+ ==> line_pseudo_region + sed -i -e "s/$prefix_pseudo_region:[[:digit:]][[:digit:]]*/$line_pseudo_region/g" docs/index.md + done + fi + done +done diff --git a/.github/workflows/make-release.yml b/.github/workflows/make-release.yml index 838081df3c..812c0e93c4 100644 --- a/.github/workflows/make-release.yml +++ b/.github/workflows/make-release.yml @@ -9,6 +9,8 @@ jobs: publish-npm: needs: run-unit-tests runs-on: ubuntu-latest + outputs: + RELEASE_VERSION: ${{ steps.set-release-version.outputs.RELEASE_VERSION }} steps: - name: Checkout code uses: actions/checkout@v3 @@ -47,3 +49,21 @@ jobs: git remote set-url origin https://x-access-token:${GH_TOKEN}@github.com/$GITHUB_REPOSITORY npx lerna version --conventional-commits --force-publish --yes npx lerna publish from-git --no-verify-access --yes + - name: Set release version + id: set-release-version + run: | + RELEASE=$(npm view @aws-lambda-powertools/tracer version) + echo RELEASE_VERSION="$RELEASE_VERSION" >> "$GITHUB_OUTPUT" + + # NOTE: Watch out for the depth limit of 4 nested workflow_calls. + # publish_layer -> reusable_deploy_layer_stack -> reusable_update_layer_arn_docs + publish_layer: + needs: publish-npm + secrets: inherit + permissions: + id-token: write + contents: write + pages: write + uses: ./.github/workflows/publish_layer.yml + with: + latest_published_version: ${{ needs.publish-npm.outputs.RELEASE_VERSION }} diff --git a/.github/workflows/on-merge-to-main.yml b/.github/workflows/on-merge-to-main.yml index 411cd14ee8..8ebd13984a 100644 --- a/.github/workflows/on-merge-to-main.yml +++ b/.github/workflows/on-merge-to-main.yml @@ -21,15 +21,6 @@ jobs: needs: get_pr_details if: ${{ needs.get_pr_details.outputs.prIsMerged == 'true' }} uses: ./.github/workflows/reusable-run-linting-check-and-unit-tests.yml - publish: - needs: - [get_pr_details, run-unit-tests] - uses: ./.github/workflows/reusable-publish-docs.yml - with: - workflow_origin: ${{ github.event.repository.full_name }} - prIsMerged: ${{ needs.get_pr_details.outputs.prIsMerged }} - secrets: - token: ${{ secrets.GITHUB_TOKEN }} update-release-draft: needs: publish runs-on: ubuntu-latest diff --git a/.github/workflows/on_doc_merge.yml b/.github/workflows/on_doc_merge.yml new file mode 100644 index 0000000000..d412082ee7 --- /dev/null +++ b/.github/workflows/on_doc_merge.yml @@ -0,0 +1,24 @@ +name: Docs + +on: + push: + branches: + - main + paths: + - "docs/**" + - "mkdocs.yml" + - "examples/**" + +jobs: + release-docs: + needs: changelog + permissions: + contents: write + pages: write + uses: ./.github/workflows/reusable-publish-docs.yml + with: + workflow_origin: ${{ github.event.repository.full_name }} + version: dev + alias: stage + secrets: + token: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/publish-docs-on-release.yml b/.github/workflows/publish-docs-on-release.yml deleted file mode 100644 index 7d5a4fdcc3..0000000000 --- a/.github/workflows/publish-docs-on-release.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: Publish docs on release - -on: - # Triggered manually - workflow_dispatch: - inputs: - versionNumber: - required: true - type: string - description: "If running this manually please insert a version number that corresponds to the latest published in the GitHub releases (i.e. v1.1.1)" - # Or triggered as result of a release - release: - types: [released] - -jobs: - publish-docs: - uses: ./.github/workflows/reusable-publish-docs.yml - with: - workflow_origin: ${{ github.event.repository.full_name }} - isRelease: "true" - versionNumber: ${{ inputs.versionNumber }} - secrets: - token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/publish_layer.yaml b/.github/workflows/publish_layer.yaml index 0131612aa6..0f3968dba8 100644 --- a/.github/workflows/publish_layer.yaml +++ b/.github/workflows/publish_layer.yaml @@ -12,11 +12,18 @@ on: description: "Latest npm published version to rebuild corresponding layer for, e.g. v1.0.2" default: "v1.0.2" required: true - # Automatic trigger after release - workflow_run: - workflows: ["Make Release"] - types: - - completed + + workflow_call: + inputs: + latest_published_version: + type: string + description: "Latest npm published version to rebuild latest docs for, e.g. 2.0.0, 2.0.0a1 (pre-release)" + required: true + pre_release: + description: "Publishes documentation using a pre-release tag (2.0.0a1)." + default: false + type: boolean + required: false jobs: # Build layer by running cdk synth in layer-publisher directory and uploading cdk.out for deployment @@ -73,6 +80,7 @@ jobs: with: stage: "BETA" artifact-name: "cdk-layer-artifact" + latest_published_version: ${{ inputs.latest_published_version }} secrets: target-account-role: ${{ secrets.AWS_LAYERS_BETA_ROLE_ARN }} @@ -84,5 +92,33 @@ jobs: with: stage: "PROD" artifact-name: "cdk-layer-artifact" + latest_published_version: ${{ inputs.latest_published_version }} secrets: - target-account-role: ${{ secrets.AWS_LAYERS_PROD_ROLE_ARN }} \ No newline at end of file + target-account-role: ${{ secrets.AWS_LAYERS_PROD_ROLE_ARN }} + + prepare_docs_alias: + runs-on: ubuntu-latest + permissions: + contents: read + 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" + + release-docs: + needs: [ prod, prepare_docs_alias ] + permissions: + contents: write + pages: write + uses: ./.github/workflows/reusable_publish_docs.yml + with: + version: ${{ inputs.latest_published_version }} + alias: ${{ needs.prepare_docs_alias.outputs.DOCS_ALIAS }} + detached_mode: true diff --git a/.github/workflows/reusable-publish-docs.yml b/.github/workflows/reusable-publish-docs.yml index b2d3aed5da..6c1990a0bb 100644 --- a/.github/workflows/reusable-publish-docs.yml +++ b/.github/workflows/reusable-publish-docs.yml @@ -1,22 +1,28 @@ name: Reusable Publish docs +env: + BRANCH: main + ORIGIN: awslabs/aws-lambda-powertools-typescript + + on: workflow_call: inputs: - workflow_origin: # see https://github.com/awslabs/aws-lambda-powertools-python/issues/1349 + version: + description: "Version to build and publish docs (1.28.0, develop)" required: true type: string - prIsMerged: - required: false - default: "false" - type: string - isRelease: - required: false - default: "false" + alias: + description: "Alias to associate version (latest, stage)" + required: true type: string - versionNumber: + detached_mode: + description: "Whether it's running in git detached mode to ensure git is sync'd" required: false - default: "" + default: false + type: boolean + workflow_origin: # see https://github.com/awslabs/aws-lambda-powertools-python/issues/1349 + required: true type: string secrets: token: @@ -65,32 +71,6 @@ jobs: uses: actions/setup-python@v4 with: python-version: "3.8" - # We run this step only when the workflow has been triggered by a release - # in this case we publish the docs to `/latest` - - name: (Conditional) Set RELEASE_VERSION env var to `latest` - if: ${{ inputs.isRelease == 'true' }} - run: | - RELEASE_VERSION=$(echo ${{ github.ref_name }} | sed 's/v//') - EXPLICIT_RELEASE_VERSION=$(echo ${{ inputs.versionNumber }} | sed 's/v//') - if [ $EXPLICIT_RELEASE_VERSION != "" ]; then - echo "RELEASE_VERSION=${EXPLICIT_RELEASE_VERSION}" - echo "RELEASE_VERSION=${EXPLICIT_RELEASE_VERSION}" >> $GITHUB_ENV - else - echo "RELEASE_VERSION=${RELEASE_VERSION}" - echo "RELEASE_VERSION=${RELEASE_VERSION}" >> $GITHUB_ENV - fi - # We run this step only when the workflow has been triggered by a PR merge - # in this case we publish the docs to `/dev` - - name: (Conditional) Set RELEASE_VERSION env var to `dev` - if: ${{ inputs.prIsMerged == 'true' }} - run: | - echo "RELEASE_VERSION=dev" >> $GITHUB_ENV - - name: Check RELEASE_VERSION env var - if: ${{ env.RELEASE_VERSION == '' }} - uses: actions/github-script@v3 - with: - script: | - core.setFailed('RELEASE_VERSION env var is empty.') - name: Install doc generation dependencies run: | pip install --upgrade pip @@ -98,35 +78,41 @@ jobs: - name: Setup doc deploy run: | git config --global user.name Docs deploy - git config --global user.email docs@dummy.bot.com - - name: Publish docs to latest if isRelease - if: ${{ env.RELEASE_VERSION != 'dev' }} + git config --global user.email aws-devax-open-source@amazon.com + - name: Git refresh tip (detached mode) + # Git Detached mode (release notes) doesn't have origin + if: ${{ inputs.detached_mode }} + run: | + git config pull.rebase true + git config remote.origin.url >&- || git remote add origin https://github.com/"$ORIGIN" + git pull origin "$BRANCH" + - name: Build docs website and API reference + run: | + make release-docs VERSION="$VERSION" ALIAS="$ALIAS" + poetry run mike set-default --push latest + - name: Build docs website and API reference + env: + VERSION: ${{ inputs.version }} + ALIAS: ${{ inputs.alias }} run: | rm -rf site mkdocs build - mike deploy --push --update-aliases --no-redirect "${{ env.RELEASE_VERSION }}" "latest" + mike deploy --push --update-aliases --no-redirect ${{ env.VERSION }} ${{ env.ALIAS }}" # Set latest version as a default mike set-default --push latest - - name: Publish docs to dev - if: ${{ env.RELEASE_VERSION == 'dev' }} - run: | - rm -rf site - mkdocs build - mike deploy --push dev - - name: Build API docs - run: | - rm -rf api - npm run docs-generateApiDoc + - name: Release API docs - uses: peaceiris/actions-gh-pages@v3 + uses: peaceiris/actions-gh-pages@bd8c6b06eba6b3d25d72b7a1767993c0aeee42e7 # v3.9.2 + env: + VERSION: ${{ inputs.version }} with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./api keep_files: true - destination_dir: ${{ env.RELEASE_VERSION }}/api - - name: Release API docs to latest if isRelease - if: ${{ env.RELEASE_VERSION != 'dev' }} - uses: peaceiris/actions-gh-pages@v3 + destination_dir: ${{ env.VERSION }}/api + - name: Release API docs to latest + if: ${{ input.alias == 'latest' }} + uses: peaceiris/actions-gh-pages@bd8c6b06eba6b3d25d72b7a1767993c0aeee42e7 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./api diff --git a/.github/workflows/reusable_deploy_layer_stack.yml b/.github/workflows/reusable_deploy_layer_stack.yml index 9d56cd9678..cd5961b85b 100644 --- a/.github/workflows/reusable_deploy_layer_stack.yml +++ b/.github/workflows/reusable_deploy_layer_stack.yml @@ -8,15 +8,22 @@ on: workflow_call: inputs: stage: + description: "Deployment stage (BETA, PROD)" required: true type: string artifact-name: + description: "CDK Layer artifact name to download" + required: true + type: string + latest_published_version: + description: "Latest version that is published" required: true type: string secrets: target-account-role: required: true + jobs: deploy-cdk-stack: runs-on: ubuntu-latest @@ -84,4 +91,24 @@ jobs: - name: Unzip artifact run: unzip cdk.out.zip - name: Deploy Layer - run: npm run cdk -w layers -- deploy --app cdk.out --context region=${{ matrix.region }} 'LayerPublisherStack' --require-approval never --verbose + run: npm run cdk -w layers -- deploy --app cdk.out --context region=${{ matrix.region }} 'LayerPublisherStack' --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 '.LayerPublisherStack.LatestLayerArn' cdk-outputs.json > cdk-layer-stack/${{ matrix.region }}-layer-version.txt + cat cdk-layer-stack/${{ matrix.region }}-layer-version.txt + - name: Save Layer ARN artifact + if: ${{ inputs.stage == 'PROD' }} + uses: actions/upload-artifact@v3 + with: + name: cdk-layer-stack + path: ./layer/cdk-layer-stack/* # NOTE: upload-artifact does not inherit working-directory setting. + if-no-files-found: error + retention-days: 1 + update_v2_layer_arn_docs: + needs: deploy-cdk-stack + if: ${{ inputs.stage == 'PROD' }} + uses: ./.github/workflows/reusable_update_layer_arn_docs.yml + with: + latest_published_version: ${{ inputs.latest_published_version }} \ No newline at end of file diff --git a/.github/workflows/reusable_update_layer_arn_docs.yml b/.github/workflows/reusable_update_layer_arn_docs.yml new file mode 100644 index 0000000000..db63440d43 --- /dev/null +++ b/.github/workflows/reusable_update_layer_arn_docs.yml @@ -0,0 +1,52 @@ +name: Update V2 Layer ARN Docs + +on: + workflow_call: + inputs: + latest_published_version: + description: "Latest NPM published version to rebuild latest docs for, e.g. 1.5.1" + type: string + required: true + +permissions: + contents: write + +env: + BRANCH: main + +jobs: + publish_layer_arn: + # Force Github action to run only a single job at a time (based on the group name) + # This is to prevent race-condition and inconsistencies with changelog push + concurrency: + group: changelog-build + runs-on: ubuntu-latest + steps: + - name: Checkout repository # reusable workflows start clean, so we need to checkout again + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Git client setup and refresh tip + run: | + git config user.name "Release bot" + git config user.email "aws-devax-open-source@amazon.com" + git config pull.rebase true + git config remote.origin.url >&- || git remote add origin https://github.com/"${origin}" # Git Detached mode (release notes) doesn't have origin + git pull origin "${BRANCH}" + - name: Download CDK layer artifact + uses: actions/download-artifact@v3 + with: + name: cdk-layer-stack + path: cdk-layer-stack/ + - name: Replace layer versions in documentation + run: | + ls -la cdk-layer-stack/ + ./.github/scripts/update_layer_arn.sh cdk-layer-stack + - name: Update documentation in trunk + run: | + HAS_CHANGE=$(git status --porcelain) + test -z "${HAS_CHANGE}" && echo "Nothing to update" && exit 0 + git add docs/index.md + git commit -m "chore: update layer ARN on documentation" + git pull origin "${BRANCH}" # prevents concurrent branch update failing push + git push origin HEAD:refs/heads/"${BRANCH}"