From 8e3bc03ecf3bdfb4db35dc24dd19bcbdfc73f638 Mon Sep 17 00:00:00 2001 From: dev-dsp Date: Wed, 3 Dec 2025 18:21:28 +0400 Subject: [PATCH] ci: Harden GitHub Actions workflows security - Pin all GitHub Actions to specific SHA hashes to prevent supply chain attacks - Move workflow permissions from workflow to job level for least privilege - Add concurrency controls to prevent redundant workflow runs - Upgrade release-please action from v3 to v4.4.0 - Move release-please configuration to manifest file (.release-manifest.json) - Add persist-credentials: false to checkout steps - Add descriptive job names for better workflow visibility --- .github/workflows/release-please.yml | 12 ++++++------ .github/workflows/ruff-formatter.yml | 14 ++++++++++++-- .github/workflows/ruff-linter.yml | 13 +++++++++++-- .github/workflows/tests.yml | 19 ++++++++++++++----- .release-manifest.json | 4 ++++ 5 files changed, 47 insertions(+), 15 deletions(-) create mode 100644 .release-manifest.json diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index 9c9569d..b256b8f 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -3,9 +3,7 @@ on: branches: - main -permissions: - contents: write - pull-requests: write +permissions: {} name: release-please @@ -13,8 +11,10 @@ jobs: release-please: runs-on: ubuntu-latest steps: - - uses: googleapis/release-please-action@v3 + - uses: googleapis/release-please-action@16a9c90856f42705d54a6fda1823352bdc62cf38 # v4.4.0 with: release-type: python - package-name: sparqlx - bump-minor-pre-major: true + manifest-file: .release-manifest.json + permissions: + contents: write + pull-requests: write diff --git a/.github/workflows/ruff-formatter.yml b/.github/workflows/ruff-formatter.yml index 3eaf458..8e683d7 100644 --- a/.github/workflows/ruff-formatter.yml +++ b/.github/workflows/ruff-formatter.yml @@ -2,16 +2,25 @@ name: Run ruff formatter on: [push, pull_request] +permissions: {} + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true jobs: run-ruff-format: + name: Check code formatting with Ruff runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - name: Checkout + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + with: + persist-credentials: false - name: Install uv - uses: astral-sh/setup-uv@v5 + uses: astral-sh/setup-uv@1e862dfacbd1d6d858c55d9b792c756523627244 # v7.1.4 with: enable-cache: true cache-dependency-glob: "uv.lock" @@ -21,3 +30,4 @@ jobs: - name: Run ruff run: uv run ruff format --check . + diff --git a/.github/workflows/ruff-linter.yml b/.github/workflows/ruff-linter.yml index 0fbeb96..37e2edc 100644 --- a/.github/workflows/ruff-linter.yml +++ b/.github/workflows/ruff-linter.yml @@ -2,15 +2,24 @@ name: Run ruff linter on: [push, pull_request] +permissions: {} + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + jobs: run-ruff-linter: + name: Check code quality with Ruff runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + with: + persist-credentials: false - name: Install uv - uses: astral-sh/setup-uv@v5 + uses: astral-sh/setup-uv@1e862dfacbd1d6d858c55d9b792c756523627244 # v7.1.4 with: enable-cache: true cache-dependency-glob: "uv.lock" diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 712fc90..620d5af 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -5,24 +5,33 @@ on: branches: [main] pull_request: +permissions: {} + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: false + jobs: build: - + name: Run tests on supported Python versions runs-on: ubuntu-latest strategy: matrix: python-version: ["3.12", "3.13"] steps: - - uses: actions/checkout@v4 + - name: Checkout + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + with: + persist-credentials: false - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0 with: python-version: ${{ matrix.python-version }} - name: Install uv - uses: astral-sh/setup-uv@v5 + uses: astral-sh/setup-uv@1e862dfacbd1d6d858c55d9b792c756523627244 # v7.1.4 with: enable-cache: true cache-dependency-glob: "uv.lock" @@ -41,6 +50,6 @@ jobs: uv run pytest --cov src/sparqlx/ --cov-report xml - name: Upload coverage data to coveralls - uses: coverallsapp/github-action@v2.2.3 + uses: coverallsapp/github-action@648a8eb78e6d50909eff900e4ec85cab4524a45b # v2.3.6 with: github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.release-manifest.json b/.release-manifest.json new file mode 100644 index 0000000..0889682 --- /dev/null +++ b/.release-manifest.json @@ -0,0 +1,4 @@ +{ + "bump-minor-pre-major": true, + "package-name": "sparqlx" +}