Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 71 additions & 74 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,46 +7,77 @@ on:
pull_request:
schedule:
- cron: '0 0 * * *'
# Allow release.yml to call this workflow
workflow_call:

jobs:
#
# Verify the build and installation of SDB.
# Consolidated linting job: pylint + ruff + yapf
#
install:
# All linters run on a single Python version since they check code quality,
# not runtime behavior.
#
lint:
runs-on: ubuntu-24.04
strategy:
matrix:
python-version: ['3.10', '3.12']
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- run: python3 -m pip install --upgrade pip setuptools wheel
python-version: '3.10'
- run: ./.github/scripts/install-drgn.sh
- run: python3 -m pip install pylint pytest ruff yapf
- run: python3 -m pip install .
#
# The statement below is used for debugging the Github job.
#
- run: python3 --version
#
# Verify "pylint" runs successfully.
#
# Note, we need to have "drgn" installed in order to run "pylint".
# Thus, prior to running "pylint" we have to clone, build, and install
#
# Pylint checks
#
- name: Run pylint on sdb
run: pylint -d duplicate-code -d invalid-name -d missing-docstring -d import-outside-toplevel -d too-many-branches -d missing-module-docstring -d missing-function-docstring sdb
- name: Run pylint on tests
run: pylint -d duplicate-code -d invalid-name -d missing-docstring -d import-outside-toplevel -d too-many-branches -d missing-module-docstring -d missing-function-docstring tests
#
# Ruff checks (fast Python linter)
#
- name: Run ruff
run: ruff check sdb tests
#
# YAPF formatting check
#
- name: Check formatting with yapf (sdb)
run: yapf --diff --style google --recursive sdb
- name: Check formatting with yapf (tests)
run: yapf --diff --style google --recursive tests
#
# Type checking with mypy and pyright
#
# Note, we need to have "drgn" installed in order to run type checkers.
# Thus, prior to running them we have to clone, build, and install
# the "drgn" from source (there's no package currently available).
#
pylint:
type-check:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.10'
- run: ./.github/scripts/install-drgn.sh
- run: python3 -m pip install pylint pytest
- run: python3 -m pip install mypy pyright pytest
- run: python3 -m pip install .
- run: pylint -d duplicate-code -d invalid-name -d missing-docstring -d import-outside-toplevel -d too-many-branches -d missing-module-docstring -d missing-function-docstring sdb
- run: pylint -d duplicate-code -d invalid-name -d missing-docstring -d import-outside-toplevel -d too-many-branches -d missing-module-docstring -d missing-function-docstring tests
#
# Mypy checks
# Note: --ignore-missing-imports for tests because pytest doesn't provide stubs
#
- name: Run mypy on sdb
run: python3 -m mypy --strict --show-error-codes -p sdb
- name: Run mypy on tests
run: python3 -m mypy --strict --ignore-missing-imports --show-error-codes -p tests
#
# Pyright checks
#
- name: Run pyright on sdb
run: pyright sdb
- name: Run pyright on tests
run: pyright tests
#
# Verify "pytest" runs successfully on unit tests.
#
Expand All @@ -72,9 +103,6 @@ jobs:
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./coverage.xml
fail_ci_if_error: false
verbose: true
#
# Verify "pytest" runs successfully on integration tests with crash dumps.
#
Expand All @@ -100,58 +128,27 @@ jobs:
- run: ./.github/scripts/download-dumps-from-gdrive.sh
- run: ./.github/scripts/extract-dump.sh dump.201912060006.tar.lzma
- run: ./.github/scripts/extract-dump.sh dump.202303131823.tar.gz
- run: pytest -v --cov sdb --cov-report xml tests/integration
#
# Run integration tests. Use -s flag to show size comparison output
# for record-replay tests. Use set -o pipefail to ensure test failures
# are properly reported even when piping output.
#
- name: Run integration tests
run: |
set -o pipefail
pytest -v -s --cov sdb --cov-report xml tests/integration 2>&1 | tee test_output.txt
#
# Extract and display record-replay size comparison in GitHub summary
#
- name: Add size comparison to summary
if: always()
run: |
echo "## Record-Replay Size Comparison" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
grep -A 8 "DUMP SIZE COMPARISON" test_output.txt >> $GITHUB_STEP_SUMMARY || echo "No size comparison data found" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./coverage.xml
fail_ci_if_error: false
verbose: true
#
# Verify "yapf" runs successfully.
#
yapf:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.10'
- run: python3 -m pip install yapf
- run: yapf --diff --style google --recursive sdb
- run: yapf --diff --style google --recursive tests
#
# Verify "ruff" runs successfully.
#
ruff:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.10'
- run: python3 -m pip install ruff
- run: ruff check sdb tests
#
# Verify "mypy" runs successfully.
#
# Note, we need to have "drgn" installed in order to run "mypy".
# Thus, prior to running "mypy" we have to clone, build, and install
# the "drgn" from source (there's no package currently available).
#
# Also note that we supply --ignore-missing-imports to the tests package
# because pytest doesn't provide stubs on typeshed.
#
mypy:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.10'
- run: ./.github/scripts/install-drgn.sh
- run: python3 -m pip install mypy pytest
- run: python3 -m pip install .
- run: python3 -m mypy --strict --show-error-codes -p sdb
- run: python3 -m mypy --strict --ignore-missing-imports --show-error-codes -p tests
108 changes: 16 additions & 92 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#
# Release workflow - triggered on version tag push (e.g., v0.2.0) or manually
# Release workflow - triggered on version tag push (e.g., v0.2.0)
#
# This workflow:
# 1. Runs all CI checks (lint, type-check, tests)
# 1. Runs all CI checks via the main workflow
# 2. Builds the package (sdist + wheel)
# 3. Publishes to PyPI using Trusted Publishing (OIDC)
# 4. Creates a GitHub Release with auto-generated notes
Expand All @@ -12,18 +12,7 @@ name: Release
on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+'
- 'v[0-9]+.[0-9]+.[0-9]+-*' # Allow pre-release tags like v0.2.0-beta1
workflow_dispatch:
inputs:
tag:
description: 'Tag to release (e.g., v0.2.0)'
required: true
type: string

env:
# Use input tag for workflow_dispatch, or ref_name for tag push
RELEASE_TAG: ${{ inputs.tag || github.ref_name }}
- 'v*'

# Required for PyPI Trusted Publishing (OIDC)
permissions:
Expand All @@ -32,87 +21,21 @@ permissions:

jobs:
#
# Run all CI checks before releasing
# Run all CI checks by calling the main workflow
#
lint:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
with:
ref: ${{ inputs.tag || github.ref_name }}
- uses: actions/setup-python@v5
with:
python-version: '3.10'
- run: ./.github/scripts/install-drgn.sh
- run: python3 -m pip install pylint pytest ruff yapf
- run: pylint -d duplicate-code -d invalid-name -d missing-docstring -d import-outside-toplevel -d too-many-branches -d missing-module-docstring -d missing-function-docstring sdb
- run: pylint -d duplicate-code -d invalid-name -d missing-docstring -d import-outside-toplevel -d too-many-branches -d missing-module-docstring -d missing-function-docstring tests
- run: ruff check sdb tests
- run: yapf --diff --style google --recursive sdb
- run: yapf --diff --style google --recursive tests

type-check:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
with:
ref: ${{ inputs.tag || github.ref_name }}
- uses: actions/setup-python@v5
with:
python-version: '3.10'
- run: ./.github/scripts/install-drgn.sh
- run: python3 -m pip install mypy pytest
- run: python3 -m mypy --strict --show-error-codes -p sdb
- run: python3 -m mypy --strict --ignore-missing-imports --show-error-codes -p tests

test-unit:
runs-on: ubuntu-24.04
strategy:
matrix:
python-version: ['3.10', '3.12']
steps:
- uses: actions/checkout@v4
with:
ref: ${{ inputs.tag || github.ref_name }}
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- run: python3 -m pip install pytest pytest-cov
- run: ./.github/scripts/install-drgn.sh
- run: pytest -v --cov sdb --cov-report xml tests/unit

test-integration:
runs-on: ubuntu-24.04
strategy:
matrix:
python-version: ['3.10', '3.12']
env:
AWS_DEFAULT_REGION: 'us-west-2'
steps:
- uses: actions/checkout@v4
with:
ref: ${{ inputs.tag || github.ref_name }}
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- run: python3 -m pip install pytest pytest-cov
- run: ./.github/scripts/install-libkdumpfile.sh
- run: ./.github/scripts/install-drgn.sh
- run: ./.github/scripts/download-dumps-from-gdrive.sh
- run: ./.github/scripts/extract-dump.sh dump.201912060006.tar.lzma
- run: ./.github/scripts/extract-dump.sh dump.202303131823.tar.gz
- run: pytest -v --cov sdb --cov-report xml tests/integration
ci:
uses: ./.github/workflows/main.yml
secrets: inherit

#
# Build the package
#
build:
needs: [lint, type-check, test-unit, test-integration]
needs: ci
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
with:
ref: ${{ inputs.tag || github.ref_name }}
fetch-depth: 0 # Required for setuptools_scm to get version from tags
- uses: actions/setup-python@v5
with:
Expand Down Expand Up @@ -154,18 +77,19 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
ref: ${{ inputs.tag || github.ref_name }}
fetch-depth: 0 # Required for generating release notes
- name: Download build artifacts
uses: actions/download-artifact@v4
with:
name: dist
path: dist/
- name: Get version from tag
id: version
run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
name: sdb ${{ steps.version.outputs.VERSION }}
generate_release_notes: true
env:
GITHUB_TOKEN: ${{ github.token }}
run: |
gh release create '${{ env.RELEASE_TAG }}' \
--title 'sdb ${{ env.RELEASE_TAG }}' \
--generate-notes \
dist/*
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
14 changes: 14 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,20 @@ ignore_missing_imports = true
module = "sdb._version"
ignore_missing_imports = true

# Pyright configuration
[tool.pyright]
pythonVersion = "3.10"
typeCheckingMode = "basic"
# drgn.Object is designed to be used interchangeably with int in many contexts
# These are intentional design patterns, not bugs
reportArgumentType = "warning"
reportReturnType = "warning"
# Dynamic attributes added by decorators (e.g., input_typename_handled)
reportFunctionMemberAccess = "none"
reportAttributeAccessIssue = "warning"
# Operator type issues in tests (drgn.Type.size can be None but is always int for our types)
reportOperatorIssue = "warning"

# Pytest configuration
[tool.pytest.ini_options]
testpaths = ["tests"]
Expand Down
6 changes: 6 additions & 0 deletions sdb/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@
# the modules are imported and attempt to have a cleaner
# separation of concerns between modules.
#
# Export submodules for direct access (e.g., sdb.target.create_object())
from sdb import error
from sdb import target

from sdb.error import (
Error,
CommandNotFoundError,
Expand Down Expand Up @@ -88,6 +92,8 @@
'__version__',
'Address',
'All',
'error',
'target',
'Cast',
'Command',
'CommandArgumentsError',
Expand Down
Loading
Loading