diff --git a/.github/scripts/label_missing_acknowledgement_section.js b/.github/scripts/label_missing_acknowledgement_section.js new file mode 100644 index 0000000000..9b8e1b07f2 --- /dev/null +++ b/.github/scripts/label_missing_acknowledgement_section.js @@ -0,0 +1,50 @@ +const { + PR_ACTION, + PR_AUTHOR, + PR_BODY, + PR_NUMBER, + IGNORE_AUTHORS, + LABEL_BLOCK, + LABEL_BLOCK_MISSING_LICENSE_AGREEMENT, +} = require('./constants'); + +module.exports = async ({ github, context, core }) => { + if (IGNORE_AUTHORS.includes(PR_AUTHOR)) { + return core.notice('Author in IGNORE_AUTHORS list; skipping...'); + } + + if (PR_ACTION != 'opened') { + return core.notice( + 'Only newly open PRs are labelled to avoid spam; skipping' + ); + } + + const RELATED_ACK_SECTION_REGEX = + /By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice./; + + const isMatch = RELATED_ACK_SECTION_REGEX.exec(PR_BODY); + + if (isMatch == null) { + core.info( + `No acknowledgement section found, maybe the author didn't use the template but there is one.` + ); + + const msg = + "No acknowledgement section found. Please make sure you used the template to open a PR and didn't remove the acknowledgment section. Check the template here: https://github.com/aws-powertools/powertools-lambda-python/blob/develop/.github/PULL_REQUEST_TEMPLATE.md#acknowledgment"; + + await Promise.allSettled([ + github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + body: msg, + issue_number: PR_NUMBER, + }), + github.rest.issues.addLabels({ + issue_number: PR_NUMBER, + owner: context.repo.owner, + repo: context.repo.repo, + labels: [LABEL_BLOCK, LABEL_BLOCK_MISSING_LICENSE_AGREEMENT], + }), + ]); + } +}; diff --git a/.github/workflows/closed-issues-message.yml b/.github/workflows/closed-issues-message.yml deleted file mode 100644 index dafafb698d..0000000000 --- a/.github/workflows/closed-issues-message.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: Closed Issue Message -on: - issues: - types: [closed] - -permissions: - contents: read - -jobs: - auto_comment: - runs-on: ubuntu-latest - permissions: - issues: write - steps: - - uses: aws-actions/closed-issue-message@36b7048ea77bb834d16e7a7c5b5471ac767a4ca1 # v1.0.0 - with: - # These inputs are both required - repo-token: "${{ secrets.GITHUB_TOKEN }}" - message: | - ### ⚠️ COMMENT VISIBILITY WARNING ⚠️ - Comments on closed issues are hard for our team to see. - If you need more assistance, please either tag a team member or open a new issue that references this one. - If you wish to keep having a conversation with other community members under this issue feel free to do so. \ No newline at end of file diff --git a/.github/workflows/dispatch_analytics.yml b/.github/workflows/dispatch_analytics.yml index b614d21058..1d33e78251 100644 --- a/.github/workflows/dispatch_analytics.yml +++ b/.github/workflows/dispatch_analytics.yml @@ -1,5 +1,15 @@ name: Dispatch analytics +# PROCESS +# +# 1. Trade GitHub JWT token with AWS credentials for the analytics account +# 2. Invoke a Lambda function dispatcher synchronously with the read-only scoped JWT token +# 3. The dispatcher function will call GitHub APIs to read data from the last hour and aggregate for operational analytics + +# USAGE +# +# NOTE: meant to use as a scheduled task only (or manually for debugging purposes). + on: workflow_dispatch: @@ -7,19 +17,7 @@ on: - cron: '0 * * * *' permissions: - id-token: write - actions: read - checks: read contents: read - deployments: read - issues: read - discussions: read - packages: read - pages: read - pull-requests: read - repository-projects: read - security-events: read - statuses: read jobs: dispatch_token: @@ -28,6 +26,20 @@ jobs: group: analytics runs-on: ubuntu-latest environment: analytics + permissions: + id-token: write + actions: read + checks: read + contents: read # previously we needed `write` to use GH_TOKEN in our dispatcher (Lambda) + deployments: read + issues: read + discussions: read + packages: read + pages: read + pull-requests: read + repository-projects: read + security-events: read + statuses: read steps: - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@010d0da01d0b5a38af31e9c3470dbfdabdecca3a # v4.0.1 @@ -39,7 +51,16 @@ jobs: - name: Invoke Lambda function run: | payload=$(echo -n '{"githubToken": "${{ secrets.GITHUB_TOKEN }}"}' | base64) - aws lambda invoke \ - --function-name ${{ secrets.AWS_ANALYTICS_DISPATCHER_ARN }} \ - --payload "$payload" response.json - cat response.json + response=$(aws lambda invoke \ + --function-name "${{ secrets.AWS_ANALYTICS_DISPATCHER_ARN }}" \ + --payload "$payload" \ + response.json \ + --query 'FunctionError' \ + --output text) + + cat response.json ; echo # add newline at the end + + if [ "$response" != "None" ]; then + echo "Error invoking lambda function: $response. Aborting." + exit 1 + fi \ No newline at end of file diff --git a/.github/workflows/label_pr_on_title.yml b/.github/workflows/label_pr_on_title.yml index 3b84c63bd9..e1c6fb581d 100644 --- a/.github/workflows/label_pr_on_title.yml +++ b/.github/workflows/label_pr_on_title.yml @@ -1,5 +1,24 @@ name: Label PR based on title +# PROCESS +# +# 1. Fetch PR details previously saved from untrusted location +# 2. Parse details for safety +# 3. Label PR based on semantic title (e.g., area, change type) + +# USAGE +# +# NOTE: meant to be used with ./.github/workflows/record_pr.yml +# +# Security Note: +# +# This workflow depends on "Record PR" workflow that runs in an untrusted location (forks) instead of `pull_request_target`. +# This enforces zero trust where "Record PR" workflow always runs on fork with zero permissions on GH_TOKEN. +# When "Record PR" completes, this workflow runs in our repository with the appropriate permissions and sanitize inputs. +# +# Coupled with "Approve GitHub Action to run on forks", we have confidence no privilege can be escalated, +# since any malicious change would need to be approved, and upon social engineering, it'll have zero permissions. + on: workflow_run: workflows: ["Record PR details"] @@ -11,6 +30,9 @@ permissions: jobs: get_pr_details: + permissions: + actions: read # download PR artifact + contents: read # checkout code # Guardrails to only ever run if PR recording workflow was indeed # run in a PR event and ran successfully if: ${{ github.event.workflow_run.conclusion == 'success' }} @@ -18,16 +40,13 @@ jobs: with: record_pr_workflow_id: ${{ github.event.workflow_run.id }} workflow_origin: ${{ github.event.repository.full_name }} - permissions: - contents: read - pull-requests: read secrets: token: ${{ secrets.GITHUB_TOKEN }} label_pr: - permissions: - pull-requests: write needs: get_pr_details runs-on: ubuntu-latest + permissions: + pull-requests: write # label respective PR steps: - name: Checkout repository uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 @@ -43,4 +62,4 @@ jobs: # and label PR based on semantic title accordingly script: | const script = require('.github/scripts/label_pr_based_on_title.js') - await script({github, context, core}) + await script({github, context, core}) \ No newline at end of file diff --git a/.github/workflows/measure-packages-size.yml b/.github/workflows/measure-packages-size.yml deleted file mode 100644 index a8e0563266..0000000000 --- a/.github/workflows/measure-packages-size.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: Measure packages size - -on: - workflow_dispatch: - inputs: - prNumber: - description: "PR Number" - required: true - -permissions: - contents: read - -jobs: - measure-utils-sizes: - permissions: - pull-requests: write - runs-on: ubuntu-latest - env: - NODE_ENV: dev - PR_NUMBER: ${{ inputs.prNumber }} - steps: - # Since we are manually triggering the workflow the previous checkout has the main branch. In order to checkout the branch/code of the PR - # we need first to use the PR number to retrieve the PR SHA number. This means we need three steps to: checkout the repo, - # run a custom script to get the SHA, and then finally checkout the PR branch - - name: Checkout Repo - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - - name: Extract PR details - id: extract_PR_details - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 - with: - script: | - const script = require('.github/scripts/get_pr_info.js'); - await script({github, context, core}); - - name: Checkout PR code - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - with: - ref: ${{ steps.extract_PR_details.outputs.headSHA }} - - name: Packages size report - uses: flochaz/pkg-size-action@1f56793682d897eb0860d98637fa4ea8fe7d37b8 # v.2.0.1 - with: - build-command: mkdir dist && npm run package -w packages/logger -w packages/tracer -w packages/metrics -w packages/commons -w packages/parameters && npm run package-bundle -w packages/logger -w packages/tracer -w packages/metrics -w packages/commons -w packages/parameters && bash -c "mv ./packages/*/dist/* dist/" && ls dist - dist-directory: /dist - pr-number: ${{ inputs.prNumber }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/on-doc-v2-merge.yml b/.github/workflows/on-doc-v2-merge.yml deleted file mode 100644 index cb552d880e..0000000000 --- a/.github/workflows/on-doc-v2-merge.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: Docs v2 Publish (merge) - -on: - push: - branches: - - feat/v2 - paths: - - "docs/**" - - "mkdocs.yml" - -permissions: - contents: read - -jobs: - release-docs: - permissions: - contents: write - pages: write - id-token: write - secrets: inherit - uses: ./.github/workflows/reusable-publish-docs.yml - with: - version: next - alias: next - detached_mode: false \ No newline at end of file diff --git a/.github/workflows/on_closed_issues.yml b/.github/workflows/on_closed_issues.yml new file mode 100644 index 0000000000..527b0f7d47 --- /dev/null +++ b/.github/workflows/on_closed_issues.yml @@ -0,0 +1,34 @@ +name: Closed Issue Message + +# PROCESS +# +# 1. Comment on recently closed issues to warn future responses may not be looked after + +# USAGE +# +# Always triggered upon issue closure + +on: + issues: + types: [closed] + +permissions: + contents: read + +jobs: + auto_comment: + runs-on: ubuntu-latest + permissions: + issues: write # comment on issues + steps: + - uses: aws-actions/closed-issue-message@36b7048ea77bb834d16e7a7c5b5471ac767a4ca1 # v1.0.0 + with: + repo-token: "${{ secrets.GITHUB_TOKEN }}" + message: | + ⚠️ **COMMENT VISIBILITY WARNING** ⚠️ + + This issue is now closed. Please be mindful that future comments are hard for our team to see. + + If you need more assistance, please either tag a [team member](https://docs.powertools.aws.dev/lambda/typescript/latest/maintainers/#current-maintainers) or open a new issue that references this one. + + If you wish to keep having a conversation with other community members under this issue feel free to do so. \ No newline at end of file diff --git a/.github/workflows/on_doc_merge.yml b/.github/workflows/on_doc_merge.yml index 13f374945e..bcea9b0d7b 100644 --- a/.github/workflows/on_doc_merge.yml +++ b/.github/workflows/on_doc_merge.yml @@ -14,8 +14,7 @@ permissions: jobs: release-docs: permissions: - contents: write - pages: write + actions: write id-token: write secrets: inherit uses: ./.github/workflows/reusable-publish-docs.yml diff --git a/.github/workflows/on-merge-to-main.yml b/.github/workflows/on_merged_pr.yml similarity index 53% rename from .github/workflows/on-merge-to-main.yml rename to .github/workflows/on_merged_pr.yml index 356af15fc8..2daae2b1b3 100644 --- a/.github/workflows/on-merge-to-main.yml +++ b/.github/workflows/on_merged_pr.yml @@ -1,14 +1,31 @@ name: On PR merge +# PROCESS +# +# 1. Fetch PR details previously saved from untrusted location +# 2. Parse details for safety +# 3. Add `pending-release` label for related issue +# 4. Make a comment in PR if related issue is invalid or can't be labeled + +# USAGE +# +# NOTE: meant to be used with ./.github/workflows/record_pr.yml +# +# Security Note: +# +# This workflow depends on "Record PR" workflow that runs in an untrusted location (forks) instead of `pull_request_target`. +# This enforces zero trust where "Record PR" workflow always runs on fork with zero permissions on GH_TOKEN. +# When "Record PR" completes, this workflow runs in our repository with the appropriate permissions and sanitize inputs. +# +# Coupled with "Approve GitHub Action to run on forks", we have confidence no privilege can be escalated, +# since any malicious change would need to be approved, and upon social engineering, it'll have zero permissions. + on: workflow_run: workflows: ["Record PR details"] types: - completed -concurrency: - group: on-merge-to-main - permissions: contents: read @@ -16,36 +33,21 @@ jobs: get_pr_details: if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success' permissions: - contents: read - pull-requests: read + actions: read # download PR artifact + contents: read # checkout code uses: ./.github/workflows/reusable_export_pr_details.yml with: record_pr_workflow_id: ${{ github.event.workflow_run.id }} workflow_origin: ${{ github.event.repository.full_name }} secrets: token: ${{ secrets.GITHUB_TOKEN }} - run-unit-tests: + release_label_on_merge: needs: get_pr_details - if: ${{ needs.get_pr_details.outputs.prIsMerged == 'true' }} - uses: ./.github/workflows/reusable-run-linting-check-and-unit-tests.yml - update-release-draft: - permissions: - contents: write - needs: run-unit-tests runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - - name: Update release draft - uses: release-drafter/release-drafter@09c613e259eb8d4e7c81c2cb00618eb5fc4575a7 # v5.25.0 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - release_label_on_merge: permissions: - pull-requests: read - contents: write - needs: [get_pr_details, update-release-draft] - runs-on: ubuntu-latest + pull-requests: write # make a comment in PR if unable to find related issue + issues: write # label issue with pending-release + if: needs.get_pr_details.outputs.prIsMerged == 'true' steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: "Label PR related issue for release" diff --git a/.github/workflows/on_opened_pr.yml b/.github/workflows/on_opened_pr.yml index dc9078eea2..dcd6f0c7ad 100644 --- a/.github/workflows/on_opened_pr.yml +++ b/.github/workflows/on_opened_pr.yml @@ -1,5 +1,25 @@ name: On new PR +# PROCESS +# +# 1. Fetch PR details previously saved from untrusted location +# 2. Parse details for safety +# 3. Confirm there is a related issue for newly opened PR +# 4. Verify if PR template is used and legal acknowledgement hasn't been removed + +# USAGE +# +# NOTE: meant to be used with ./.github/workflows/record_pr.yml +# +# Security Note: +# +# This workflow depends on "Record PR" workflow that runs in an untrusted location (forks) instead of `pull_request_target`. +# This enforces zero trust where "Record PR" workflow always runs on fork with zero permissions on GH_TOKEN. +# When "Record PR" completes, this workflow runs in our repository with the appropriate permissions and sanitize inputs. +# +# Coupled with "Approve GitHub Action to run on forks", we have confidence no privilege can be escalated, +# since any malicious change would need to be approved, and upon social engineering, it'll have zero permissions. + on: workflow_run: workflows: ["Record PR details"] @@ -11,6 +31,9 @@ permissions: jobs: get_pr_details: + permissions: + actions: read # download PR artifact + contents: read # checkout code if: ${{ github.event.workflow_run.conclusion == 'success' }} uses: ./.github/workflows/reusable_export_pr_details.yml with: @@ -18,18 +41,13 @@ jobs: workflow_origin: ${{ github.event.repository.full_name }} secrets: token: ${{ secrets.GITHUB_TOKEN }} - permissions: - pull-requests: read check_related_issue: permissions: - issues: read - pull-requests: write + pull-requests: write # label and comment on PR if missing related issue (requirement) needs: get_pr_details runs-on: ubuntu-latest steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - - name: "Debug workflow_run event" - run: echo "${{ github }}" - name: "Ensure related issue is present" uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 env: @@ -42,3 +60,22 @@ jobs: script: | const script = require('.github/scripts/label_missing_related_issue.js') await script({github, context, core}) + check_acknowledge_section: + needs: get_pr_details + runs-on: ubuntu-latest + permissions: + pull-requests: write # label and comment on PR if missing acknowledge section (requirement) + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - name: "Ensure acknowledgement section is present" + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 + env: + PR_BODY: ${{ needs.get_pr_details.outputs.prBody }} + PR_NUMBER: ${{ needs.get_pr_details.outputs.prNumber }} + PR_ACTION: ${{ needs.get_pr_details.outputs.prAction }} + PR_AUTHOR: ${{ needs.get_pr_details.outputs.prAuthor }} + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const script = require('.github/scripts/label_missing_acknowledgement_section.js') + await script({github, context, core}) \ No newline at end of file diff --git a/.github/workflows/on_pr_updates.yml b/.github/workflows/on_pr_updates.yml new file mode 100644 index 0000000000..acd301f676 --- /dev/null +++ b/.github/workflows/on_pr_updates.yml @@ -0,0 +1,35 @@ +name: PR requirements + +# PROCESS +# +# 1. Verify whether 'do-not-merge' label is present +# 2. Fail PR to prevent merging until resolved +# 3. Pass PR if do-not-merge label is removed by a maintainer + +# USAGE +# +# Always triggered on PR labeling changes. + +# NOTES +# +# PR requirements are checked async in on_opened_pr.yml and enforced here synchronously +# due to limitations in GH API. + +on: + pull_request: + types: + - opened + - labeled + - unlabeled + +permissions: {} # no permission required + +jobs: + check-requirements: + runs-on: ubuntu-latest + steps: + - name: Block if it doesn't minimum requirements + if: contains(github.event.pull_request.labels.*.name, 'do-not-merge') + run: | + echo "This PR does not meet minimum requirements (check PR comments)." + exit 1 \ No newline at end of file diff --git a/.github/workflows/rebuild-latest-docs.yml b/.github/workflows/rebuild-latest-docs.yml deleted file mode 100644 index a60edd953f..0000000000 --- a/.github/workflows/rebuild-latest-docs.yml +++ /dev/null @@ -1,29 +0,0 @@ -name: Rebuild latest docs - -# -# === Documentation hotfix === -# -# 1. Trigger "Rebuild latest docs" workflow manually: https://docs.github.com/en/actions/managing-workflow-runs/manually-running-a-workflow -# 2. Use the latest version released under Releases e.g. 1.6.0 - -on: - workflow_dispatch: - inputs: - latest_published_version: - description: "Latest npm published version to rebuild latest docs for, e.g. 1.6.0" - required: true - -permissions: - contents: read - -jobs: - release-docs: - permissions: - contents: write - pages: write - id-token: write - secrets: inherit - uses: ./.github/workflows/reusable-publish-docs.yml - with: - version: ${{ inputs.latest_published_version }} - alias: latest \ No newline at end of file diff --git a/.github/workflows/rebuild_latest_docs.yml b/.github/workflows/rebuild_latest_docs.yml new file mode 100644 index 0000000000..9b1f0b8908 --- /dev/null +++ b/.github/workflows/rebuild_latest_docs.yml @@ -0,0 +1,37 @@ +name: Rebuild latest docs + +# PROCESS +# +# 1. Build User Guide and API docs +# 2. Publish to GitHub Pages +# 3. Publish to S3 (new home) + +# USAGE +# +# Only used for deploying a documentation hotfix to /latest and its associated version w/o a full release. +# +# Steps: +# +# 1. Trigger "Rebuild latest docs" workflow manually: https://docs.github.com/en/actions/managing-workflow-runs/manually-running-a-workflow +# 2. Use the latest version released under Releases e.g. 2.0.0 + +on: + workflow_dispatch: + inputs: + latest_published_version: + description: "Latest npm published version to rebuild latest docs for, e.g. 1.8.0" + required: true + +permissions: + contents: read + +jobs: + release-docs: + permissions: + actions: write # upload artifacts (for debugging issues with the docs build) + id-token: write # trade JWT token for AWS credentials in AWS Docs account + secrets: inherit + uses: ./.github/workflows/reusable_publish_docs.yml + with: + version: ${{ inputs.latest_published_version }} + alias: latest \ No newline at end of file diff --git a/.github/workflows/record_pr.yml b/.github/workflows/record_pr.yml index e8d2a57426..dd3046c77a 100644 --- a/.github/workflows/record_pr.yml +++ b/.github/workflows/record_pr.yml @@ -1,8 +1,41 @@ name: Record PR details +# PROCESS +# +# 1. Runs in fork location upon PR creation or changes +# 2. Saves GitHub Pull Request Webhook payload +# 3. Uploads as a temporary GitHub Action Artifact with shortest retention + +# USAGE +# +# see .github/workflows/on_merged_pr.yml and related for full example. +# +# on: +# workflow_run: +# workflows: ["Record PR details"] +# types: +# - completed +# +# Security Note: +# +# For security, this is intended to be a 2-step process: (1) collect PR, (2) act on PR. +# Do not ever use `pull_request_target` to "simplify", as it sends a write-token to the fork. Our linter should catch it. +# +# The first step runs in untrusted location (fork), therefore we limit permissions to only check out code. +# +# The second step will be workflows that want to act on a given PR, this time with intended permissions, and +# it runs on its base location (this repo!). +# +# This enforces zero trust where this workflow always runs on fork with zero permissions on GH_TOKEN. +# When this workflow completes, X workflows run in our repository with the appropriate permissions and sanitize inputs. +# +# Coupled with "Approve GitHub Action to run on forks", we have confidence no privilege can be escalated, +# since any malicious change would need to be approved, and upon social engineering, it'll have zero permissions. + + on: pull_request: - types: [opened, edited, closed] + types: [opened, edited, closed, labeled] permissions: contents: read @@ -10,7 +43,8 @@ permissions: jobs: record_pr: runs-on: ubuntu-latest - + permissions: + contents: read # NOTE: treat as untrusted location steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: "Extract PR details" @@ -22,4 +56,5 @@ jobs: - uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 # v4.3.0 with: name: pr - path: pr.txt \ No newline at end of file + path: pr.txt + retention-days: 1 \ No newline at end of file diff --git a/.github/workflows/reusable_export_pr_details.yml b/.github/workflows/reusable_export_pr_details.yml index dd1392ce8d..dc9b44309b 100644 --- a/.github/workflows/reusable_export_pr_details.yml +++ b/.github/workflows/reusable_export_pr_details.yml @@ -1,16 +1,32 @@ name: Export previously recorded PR +# PROCESS +# +# 1. Fetch PR details previously saved from untrusted location +# 2. Parse details for safety +# 3. Export only what's needed for automation, e.g., PR number, title, body, author, action, whether is merged + +# USAGE +# +# see .github/workflows/on_merged_pr.yml and related for full example. +# +# NOTE: meant to be used with workflows that react to a given PR state (labeling, new, merged, etc.) +# done separately to isolate security practices and make it reusable. + on: workflow_call: inputs: record_pr_workflow_id: + description: "Record PR workflow execution ID to download PR details" required: true type: number workflow_origin: # see https://github.com/aws-powertools/powertools-lambda-python/issues/1349 + description: "Repository full name for runner integrity" required: true type: string secrets: token: + description: "GitHub Actions temporary and scoped token" required: true # Map the workflow outputs to job outputs outputs: @@ -32,16 +48,19 @@ on: prIsMerged: description: "Whether PR is merged" value: ${{ jobs.export_pr_details.outputs.prIsMerged }} + prLabels: + description: "PR Labels" + value: ${{ jobs.export_pr_details.outputs.prLabels }} permissions: contents: read jobs: export_pr_details: + permissions: + actions: read # download PR artifact # see https://github.com/aws-powertools/powertools-lambda-python/issues/1349 if: inputs.workflow_origin == 'aws-powertools/powertools-lambda-typescript' - permissions: - pull-requests: read runs-on: ubuntu-latest env: FILENAME: pr.txt @@ -53,6 +72,7 @@ jobs: prAuthor: ${{ steps.prAuthor.outputs.prAuthor }} prAction: ${{ steps.prAction.outputs.prAction }} prIsMerged: ${{ steps.prIsMerged.outputs.prIsMerged }} + prLabels: ${{ steps.prLabels.outputs.prLabels }} steps: - name: Checkout repository # in case caller workflow doesn't checkout thus failing with file not found uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 @@ -89,3 +109,6 @@ jobs: - name: "Export Pull Request Merged status" id: prIsMerged run: echo prIsMerged="$(jq -c '.pull_request.merged' "${FILENAME}")" >> "$GITHUB_OUTPUT" + - name: "Export Pull Request labels" + id: prLabels + run: echo prLabels="$(jq -c '.labels' "${FILENAME}")" >> "$GITHUB_OUTPUT" \ No newline at end of file diff --git a/.github/workflows/reusable-publish-docs.yml b/.github/workflows/reusable_publish_docs.yml similarity index 86% rename from .github/workflows/reusable-publish-docs.yml rename to .github/workflows/reusable_publish_docs.yml index 5a654d640f..542dc6ac48 100644 --- a/.github/workflows/reusable-publish-docs.yml +++ b/.github/workflows/reusable_publish_docs.yml @@ -1,9 +1,9 @@ name: Reusable Publish docs +# see .github/workflows/on_push_docs.yml for docs + env: - BRANCH: main ORIGIN: aws-powertools/powertools-lambda-typescript - VERSION: "" on: workflow_call: @@ -28,22 +28,30 @@ on: required: false default: false type: boolean + git_ref: + description: "Branch or commit ID to checkout from" + required: false + type: string + default: develop permissions: - contents: write - id-token: write - pages: write + contents: read jobs: - publish-docs: + publish_docs: + if: github.repository == 'aws-powertools/powertools-lambda-python' + # Force Github action to run only a single job at a time (based on the group name) + # This is to prevent "race-condition" in publishing a new version of doc to `gh-pages` + concurrency: + group: on-docs-rebuild runs-on: ubuntu-latest environment: Docs + permissions: + actions: write # upload artifacts (for debugging issues with the docs build) + id-token: write # trade JWT token for AWS credentials in AWS Docs account steps: - name: Checkout code uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - with: - # While `fetch-depth` is used to allow the workflow to later commit & push the changes. - fetch-depth: 0 - name: Setup NodeJS uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1 with: @@ -54,14 +62,10 @@ jobs: - name: Set up Python uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5.0.0 with: - python-version: "3.11" + python-version: "3.12" - name: Install doc generation dependencies run: | pip install --require-hashes -r docs/requirements.txt - - name: Setup doc deploy - run: | - git config --global user.name Docs deploy - 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 }} @@ -69,6 +73,8 @@ jobs: git config pull.rebase true git config remote.origin.url >&- || git remote add origin https://github.com/"$ORIGIN" git pull origin "$BRANCH" + env: + BRANCH: ${{ inputs.git_ref }} - name: Normalize Version Number run: echo "VERSION=$(echo ${{ inputs.version }} | sed 's/v//')" >> $GITHUB_ENV - name: Build docs website and API reference @@ -77,9 +83,6 @@ jobs: run: | rm -rf site mkdocs build - mike deploy --update-aliases --no-redirect ${{ env.VERSION }} ${{ env.ALIAS }} --branch backup-gh-pages - # Set latest version as a default - mike set-default latest --branch backup-gh-pages - name: Build API docs run: | rm -rf api diff --git a/.github/workflows/on-workflows-push-pr.yml b/.github/workflows/secure-workflows.yml similarity index 50% rename from .github/workflows/on-workflows-push-pr.yml rename to .github/workflows/secure-workflows.yml index b9d0f96cfe..c0c1fde8bf 100644 --- a/.github/workflows/on-workflows-push-pr.yml +++ b/.github/workflows/secure-workflows.yml @@ -1,5 +1,16 @@ name: Lockdown untrusted workflows +# PROCESS +# +# 1. Scans for any external GitHub Action being used without version pinning (@ vs @v3) +# 2. Scans for insecure practices for inline bash scripts (shellcheck) +# 3. Fail CI and prevent PRs to be merged if any malpractice is found + +# USAGE +# +# Always triggered on new PR, PR changes and PR merge. + + on: push: paths: @@ -16,9 +27,11 @@ jobs: name: Harden Security runs-on: ubuntu-latest permissions: - actions: read + contents: read # checkout code and subsequently GitHub action workflows steps: - name: Checkout code uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Ensure 3rd party workflows have SHA pinned - uses: zgosalvez/github-actions-ensure-sha-pinned-actions@ba37328d4ea95eaf8b3bd6c6cef308f709a5f2ec # v3.0.3 \ No newline at end of file + uses: zgosalvez/github-actions-ensure-sha-pinned-actions@ba37328d4ea95eaf8b3bd6c6cef308f709a5f2ec # v3.0.3 + with: + allowlist: slsa-framework/slsa-github-generator \ No newline at end of file