From e2567a680e6327153769ec61c2a9a486d28dbf23 Mon Sep 17 00:00:00 2001 From: Ran Benita Date: Sun, 16 May 2021 11:12:23 +0300 Subject: [PATCH 1/3] scripts: improve upload-coverage.sh Mostly, verify the bash uploader hash and make it more strict and verbose. --- scripts/upload-coverage.sh | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/scripts/upload-coverage.sh b/scripts/upload-coverage.sh index ad3dd4828..089fb67bf 100755 --- a/scripts/upload-coverage.sh +++ b/scripts/upload-coverage.sh @@ -1,16 +1,28 @@ #!/usr/bin/env bash -set -e +set -euo pipefail set -x -if [ -z "$TOXENV" ]; then +# Install coverage. +if [[ -z ${TOXENV+x} || -z $TOXENV ]]; then python -m pip install coverage else # Add last TOXENV to $PATH. PATH="$PWD/.tox/${TOXENV##*,}/bin:$PATH" fi +# Run coverage. python -m coverage xml + +# Download and verify latest Codecov bash uploader. # Set --connect-timeout to work around https://github.com/curl/curl/issues/4461 -curl -S -L --connect-timeout 5 --retry 6 -s https://codecov.io/bash -o codecov-upload.sh -bash codecov-upload.sh -Z -X fix -f coverage.xml "$@" +curl --silent --show-error --location --connect-timeout 5 --retry 6 -o codecov https://codecov.io/bash +VERSION=$(grep --only-matching 'VERSION=\"[0-9\.]*\"' codecov | cut -d'"' -f2) +if command -v sha256sum; then + sha256sum --check --strict --ignore-missing --quiet <(curl --silent "https://raw.githubusercontent.com/codecov/codecov-bash/${VERSION}/SHA256SUM") +else + shasum --algorithm 256 --check --strict --ignore-missing --quiet <(curl --silent "https://raw.githubusercontent.com/codecov/codecov-bash/${VERSION}/SHA256SUM") +fi + +# Upload coverage. +bash codecov -Z -X fix -f coverage.xml "$@" From 6bc6ec323af51605c4503afa00239c32867435b8 Mon Sep 17 00:00:00 2001 From: Ran Benita Date: Sun, 16 May 2021 11:17:05 +0300 Subject: [PATCH 2/3] ci: reduce workflow permissions Decrease security exposure by restricting what the code executing in the actions is allowed to do (in terms of GitHub operations). --- .github/workflows/main.yml | 27 ++++++++++++++++++++++++ .github/workflows/prepare-release-pr.yml | 6 ++++++ .github/workflows/release-on-comment.yml | 8 +++++++ .github/workflows/update-plugin-list.yml | 13 ++++++++++++ 4 files changed, 54 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 756aade8c..4c390b452 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -13,13 +13,19 @@ on: branches: - main - "[0-9]+.[0-9]+.x" + env: PYTEST_ADDOPTS: "--color=yes" +# Set permissions at the job level. +permissions: {} + jobs: build: runs-on: ${{ matrix.os }} timeout-minutes: 30 + permissions: + contents: read strategy: fail-fast: false @@ -139,10 +145,13 @@ jobs: - uses: actions/checkout@v2 with: fetch-depth: 0 + persist-credentials: false + - name: Set up Python ${{ matrix.python }} uses: actions/setup-python@v2 with: python-version: ${{ matrix.python }} + - name: Install dependencies run: | python -m pip install --upgrade pip @@ -164,19 +173,29 @@ jobs: linting: runs-on: ubuntu-latest + permissions: + contents: read + steps: - uses: actions/checkout@v2 + with: + persist-credentials: false + - uses: actions/setup-python@v2 + - name: set PY run: echo "name=PY::$(python -c 'import hashlib, sys;print(hashlib.sha256(sys.version.encode()+sys.executable.encode()).hexdigest())')" >> $GITHUB_ENV + - uses: actions/cache@v2 with: path: ~/.cache/pre-commit key: pre-commit|${{ env.PY }}|${{ hashFiles('.pre-commit-config.yaml') }} + - name: Install dependencies run: | python -m pip install --upgrade pip pip install tox + - run: tox -e linting deploy: @@ -184,6 +203,8 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 30 + permissions: + contents: read needs: [build] @@ -191,22 +212,28 @@ jobs: - uses: actions/checkout@v2 with: fetch-depth: 0 + persist-credentials: false + - name: Set up Python uses: actions/setup-python@v2 with: python-version: "3.7" + - name: Install dependencies run: | python -m pip install --upgrade pip pip install --upgrade wheel setuptools tox + - name: Build package run: | python setup.py sdist bdist_wheel + - name: Publish package to PyPI uses: pypa/gh-action-pypi-publish@master with: user: __token__ password: ${{ secrets.pypi_token }} + - name: Publish GitHub release notes env: GH_RELEASE_NOTES_TOKEN: ${{ secrets.release_notes }} diff --git a/.github/workflows/prepare-release-pr.yml b/.github/workflows/prepare-release-pr.yml index dec352364..7a610638a 100644 --- a/.github/workflows/prepare-release-pr.yml +++ b/.github/workflows/prepare-release-pr.yml @@ -12,14 +12,20 @@ on: required: true default: 'no' +# Set permissions at the job level. +permissions: {} + jobs: build: runs-on: ubuntu-latest + permissions: + contents: read steps: - uses: actions/checkout@v2 with: fetch-depth: 0 + persist-credentials: false - name: Set up Python uses: actions/setup-python@v2 diff --git a/.github/workflows/release-on-comment.yml b/.github/workflows/release-on-comment.yml index 94863d896..cca908aa6 100644 --- a/.github/workflows/release-on-comment.yml +++ b/.github/workflows/release-on-comment.yml @@ -7,9 +7,14 @@ on: issue_comment: types: [created, edited] +# Set permissions at the job level. +permissions: {} + jobs: build: runs-on: ubuntu-latest + permissions: + contents: read if: (github.event.comment && startsWith(github.event.comment.body, '@pytestbot please')) || (github.event.issue && !github.event.comment && startsWith(github.event.issue.body, '@pytestbot please')) @@ -17,15 +22,18 @@ jobs: - uses: actions/checkout@v2 with: fetch-depth: 0 + persist-credentials: false - name: Set up Python uses: actions/setup-python@v2 with: python-version: "3.8" + - name: Install dependencies run: | python -m pip install --upgrade pip pip install --upgrade setuptools tox + - name: Prepare release run: | tox -e release-on-comment -- $GITHUB_EVENT_PATH ${{ secrets.chatops }} diff --git a/.github/workflows/update-plugin-list.yml b/.github/workflows/update-plugin-list.yml index 9b071aa3d..d5a6efb54 100644 --- a/.github/workflows/update-plugin-list.yml +++ b/.github/workflows/update-plugin-list.yml @@ -7,22 +7,35 @@ on: - cron: '0 0 * * 0' workflow_dispatch: +# Set permissions at the job level. +permissions: {} + jobs: createPullRequest: runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + steps: - name: Checkout uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: Setup Python uses: actions/setup-python@v2 with: python-version: 3.8 + - name: Install dependencies run: | python -m pip install --upgrade pip pip install packaging requests tabulate[widechars] + - name: Update Plugin List run: python scripts/update-plugin-list.py + - name: Create Pull Request uses: peter-evans/create-pull-request@2455e1596942c2902952003bbb574afbbe2ab2e6 with: From 864a2bc0a3180efa76de0e9b1ee28b81c6f437bb Mon Sep 17 00:00:00 2001 From: Ran Benita Date: Sun, 16 May 2021 11:37:21 +0300 Subject: [PATCH 3/3] ci: use GitHub Actions token instead of `chatops`/`release_notes` secrets It seems more secure to use the controlled & limited token than an ambient secret. --- .github/workflows/main.yml | 4 ++-- .github/workflows/prepare-release-pr.yml | 7 ++++--- .github/workflows/release-on-comment.yml | 5 +++-- scripts/prepare-release-pr.py | 5 ++--- scripts/release-on-comment.py | 4 ++-- 5 files changed, 13 insertions(+), 12 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4c390b452..c58a50ff0 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -204,7 +204,7 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 30 permissions: - contents: read + contents: write needs: [build] @@ -236,7 +236,7 @@ jobs: - name: Publish GitHub release notes env: - GH_RELEASE_NOTES_TOKEN: ${{ secrets.release_notes }} + GH_RELEASE_NOTES_TOKEN: ${{ github.token }} run: | sudo apt-get install pandoc tox -e publish-gh-release-notes diff --git a/.github/workflows/prepare-release-pr.yml b/.github/workflows/prepare-release-pr.yml index 7a610638a..91977f5b2 100644 --- a/.github/workflows/prepare-release-pr.yml +++ b/.github/workflows/prepare-release-pr.yml @@ -19,7 +19,8 @@ jobs: build: runs-on: ubuntu-latest permissions: - contents: read + contents: write + pull-requests: write steps: - uses: actions/checkout@v2 @@ -40,9 +41,9 @@ jobs: - name: Prepare release PR (minor/patch release) if: github.event.inputs.major == 'no' run: | - tox -e prepare-release-pr -- ${{ github.event.inputs.branch }} ${{ secrets.chatops }} + tox -e prepare-release-pr -- ${{ github.event.inputs.branch }} ${{ github.token }} - name: Prepare release PR (major release) if: github.event.inputs.major == 'yes' run: | - tox -e prepare-release-pr -- ${{ github.event.inputs.branch }} ${{ secrets.chatops }} --major + tox -e prepare-release-pr -- ${{ github.event.inputs.branch }} ${{ github.token }} --major diff --git a/.github/workflows/release-on-comment.yml b/.github/workflows/release-on-comment.yml index cca908aa6..32d221552 100644 --- a/.github/workflows/release-on-comment.yml +++ b/.github/workflows/release-on-comment.yml @@ -14,7 +14,8 @@ jobs: build: runs-on: ubuntu-latest permissions: - contents: read + contents: write + issues: write if: (github.event.comment && startsWith(github.event.comment.body, '@pytestbot please')) || (github.event.issue && !github.event.comment && startsWith(github.event.issue.body, '@pytestbot please')) @@ -36,4 +37,4 @@ jobs: - name: Prepare release run: | - tox -e release-on-comment -- $GITHUB_EVENT_PATH ${{ secrets.chatops }} + tox -e release-on-comment -- $GITHUB_EVENT_PATH ${{ github.token }} diff --git a/scripts/prepare-release-pr.py b/scripts/prepare-release-pr.py index 5ba174f23..ca5ed411a 100644 --- a/scripts/prepare-release-pr.py +++ b/scripts/prepare-release-pr.py @@ -9,9 +9,8 @@ The appropriate version will be obtained based on the given branch automatically After that, it will create a release using the `release` tox environment, and push a new PR. -**Secret**: currently the secret is defined in the @pytestbot account, -which the core maintainers have access to. There we created a new secret named `chatops` -with write access to the repository. +**Token**: currently the token from the GitHub Actions is used, pushed with +`pytest bot ` commit author. """ import argparse import re diff --git a/scripts/release-on-comment.py b/scripts/release-on-comment.py index f33def3ef..d5996aa40 100644 --- a/scripts/release-on-comment.py +++ b/scripts/release-on-comment.py @@ -23,8 +23,8 @@ Then the appropriate version will be obtained based on the given branch name: After that, it will create a release using the `release` tox environment, and push a new PR. -**Secret**: currently the secret is defined in the @pytestbot account, which the core maintainers -have access to. There we created a new secret named `chatops` with write access to the repository. +**Token**: currently the token from the GitHub Actions is used, pushed with +`pytest bot ` commit author. """ import argparse import json