Skip to content

Python

Python #13023

Workflow file for this run

name: Python
on:
push:
branches:
- main
pull_request:
schedule:
- cron: "0 8 * * *"
concurrency:
group: check-${{ github.ref }}
cancel-in-progress: true
jobs:
validate-pr-title:
name: Validate PR Title
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
permissions:
pull-requests: read
steps:
- uses: amannn/action-semantic-pull-request@48f256284bd46cdaab1048c3721360e808335d50 # v6.1.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
types: |
feat
fix
docs
style
refactor
perf
test
build
ci
chore
revert
requireScope: false
subjectPattern: ^(?![A-Z]).+$
subjectPatternError: |
The subject "{subject}" found in the pull request title "{title}"
didn't match the configured pattern. Please ensure that the subject
doesn't start with an uppercase character.
wip: false
validateSingleCommit: false
validateSingleCommitMatchesPrTitle: false
lint:
name: Lint & Type Check
runs-on: ubuntu-latest
permissions: {}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install uv
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
with:
enable-cache: true
python-version: "3.13"
- name: Install dependencies
run: uv sync --all-extras --locked
- name: Ruff lint
run: uv run ruff check .
- name: Ruff format
run: uv run ruff format --check .
- name: Mypy
run: uv run mypy descope tests samples
- name: License check
run: uv run --with pylic pylic check
build:
name: test with ${{ matrix.py }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
permissions: {}
strategy:
fail-fast: false
matrix:
py:
- "3.14"
- "3.13"
- "3.12"
- "3.11"
- "3.10"
- "3.9"
os:
- ubuntu-latest
- macos-latest
- windows-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
- name: Install uv
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
with:
enable-cache: true
python-version: ${{ matrix.py }}
- name: Install dependencies
run: uv sync --all-extras --locked
- name: Run test suite
run: uv run coverage run -m pytest tests --ignore=tests/e2e
env:
COVERAGE_FILE: "coverage.${{ matrix.os }}.${{ matrix.py }}"
- name: Store coverage file
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: coverage.${{ matrix.os }}.${{ matrix.py }}
path: coverage.${{ matrix.os }}.${{ matrix.py }}
if-no-files-found: error
coverage:
if: github.event_name != 'schedule'
name: Coverage
runs-on: ubuntu-latest
needs: build
permissions:
pull-requests: write
contents: write
env:
COVERAGE_FILE: "coverage"
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
id: download
with:
pattern: coverage.*
merge-multiple: true
- name: Coverage comment
id: coverage_comment
uses: py-cov-action/python-coverage-comment-action@b3d7e98bf5528b07d6951ef7a93e2b156f960112 # v3.1.0
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
MERGE_COVERAGE_FILES: true
ANNOTATE_MISSING_LINES: true
VERBOSE: true
- name: Store Pull Request comment to be posted
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: steps.coverage_comment.outputs.COMMENT_FILE_WRITTEN == 'true'
with:
name: python-coverage-comment-action
path: python-coverage-comment-action.txt
e2e-sandbox:
name: E2E Tests
runs-on: ubuntu-latest
permissions:
checks: write
if: >
github.event_name != 'pull_request' ||
(github.event.pull_request.draft != true &&
github.event.pull_request.head.repo.fork == false)
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Install uv
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
with:
enable-cache: true
python-version: "3.13"
- name: Install dependencies
run: uv sync --all-extras --locked
- name: Run e2e tests
if: github.actor != 'renovate[bot]'
run: uv run pytest tests/e2e -v -m e2e --junitxml=e2e-report.xml
env:
DESCOPE_PROJECT_ID: ${{ secrets.DESCOPE_SANDBOX_PROJECT_ID }}
DESCOPE_MANAGEMENT_KEY: ${{ secrets.DESCOPE_SANDBOX_MANAGEMENT_KEY }}
DESCOPE_BASE_URI: ${{ secrets.DESCOPE_SANDBOX_BASE_URI }}
- name: Publish e2e test report
if: always() && github.actor != 'renovate[bot]'
uses: mikepenz/action-junit-report@d9f48fc87bc235f7e214acf696ca5abc0a986f16 # v6.4.2
with:
report_paths: e2e-report.xml
check_name: E2E Test Report
gitleaks:
name: gitleaks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
- uses: gitleaks/gitleaks-action@e0c47f4f8be36e29cdc102c57e68cb5cbf0e8d1e # v3.0.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE }}
done:
name: All Checks Passed
runs-on: ubuntu-latest
permissions: {}
needs: [validate-pr-title, lint, build, coverage, gitleaks, e2e-sandbox]
# Must run unconditionally so this required status check always reports a
# real conclusion. If it were skipped (e.g. via an `if` that drops out when
# a dependency fails), branch protection would treat the skip as a pass.
if: always()
steps:
- name: Fail if any dependency failed or was cancelled
if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')
run: exit 1
- name: Yey, all checks passed!
run: echo "All checks passed! :tada:"