Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
1717e4c
build: migrate from Poetry to uv with automated releases
seansica Dec 22, 2025
599170d
build: update ruff-pre-commit config
seansica Dec 23, 2025
708e245
style: apply ruff formatting
seansica Dec 23, 2025
0b57c82
Merge branch 'main' into semantic-release
seansica Dec 23, 2025
c6e8807
build: update uv.lock
seansica Dec 23, 2025
5141c5d
build: update read-the-docs config to use uv
seansica Dec 23, 2025
02278d5
ci: small improvements to ci-cd uv build process
seansica Dec 23, 2025
3c496a9
chore(pre-commit): bump commitizen to 4.10.1
seansica Dec 23, 2025
d0494b7
ci: set python version with a matrix
seansica Dec 23, 2025
8dd5a29
chore(ci): upgrade setup-uv to v7
seansica Dec 23, 2025
f981996
build(read-the-docs): migrate to build.jobs
seansica Dec 23, 2025
6e075c2
build: replace hatch build backend with uv
seansica Dec 23, 2025
35c6552
ci: unset git_committer_name and email in PSR step
seansica Dec 23, 2025
634f249
build(just): add upgrade script
seansica Dec 23, 2025
abd4a7b
Apply suggestions from code review
jondricek Dec 24, 2025
1e77de2
chore: add cz-check-good-commit and cz-check-bad-commit scripts to ju…
seansica Feb 13, 2026
5a28257
build(ci): update astral-sh/setup-uv from v5 to v7
seansica Feb 13, 2026
3d43662
build: update uv.lock
seansica Feb 13, 2026
61f4ffd
Merge branch 'main' into semantic-release
seansica Feb 13, 2026
bb955b9
build: remove unused sections from pyproject.toml
seansica Feb 13, 2026
8982a9f
build: add "revert" as permissible conventional commit prefix
seansica Feb 13, 2026
c9ebd39
ci: improve dynamics of setup phase
seansica Feb 13, 2026
a808ca5
ci: update commitlint job to validate the PR title for PRs
seansica Feb 13, 2026
10b1dfb
Merge branch 'semantic-release' of github.com:mitre-attack/mitreattac…
seansica Feb 13, 2026
1a04175
ci: streamline the python setup process
seansica Feb 13, 2026
088f445
ci: streamline the python setup process
seansica Feb 13, 2026
46e9493
ci: enable gh actions to read PR information
seansica Feb 13, 2026
3a49500
ci: split PR linting into separate workflow
seansica Feb 13, 2026
7912993
ci: update download-artifact version
jondricek Feb 13, 2026
5797a2f
docs: update release+contrib documentation
seansica Feb 13, 2026
b14107c
Merge branch 'semantic-release' of github.com:mitre-attack/mitreattac…
seansica Feb 13, 2026
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
181 changes: 181 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

permissions:
contents: read

jobs:
# Validate the squash merge commit message on pushes to main.
# PR title validation is handled separately in pr-title.yml.
commitlint:
if: github.event_name == 'push'
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 2

- name: Install uv
uses: astral-sh/setup-uv@v7
with:
version: "latest"

- name: Install Python and dependencies
run: |
uv python install 3.11
uv sync --all-extras

- name: Validate commit message
run: uv run cz check --rev-range HEAD~1..HEAD

lint:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.11"] # TODO see https://github.com/mitre-attack/mitreattack-python/issues/176
steps:
- uses: actions/checkout@v6

- name: Install the latest version of uv
uses: astral-sh/setup-uv@v7
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: uv sync --all-extras

- name: Lint with ruff
run: uv run ruff check --output-format github

- name: Check formatting with ruff
run: uv run ruff format --check

test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.11"] # TODO see https://github.com/mitre-attack/mitreattack-python/issues/176
steps:
- uses: actions/checkout@v6

- name: Install the latest version of uv
uses: astral-sh/setup-uv@v7
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: uv sync --all-extras

- name: Run pytest
run: uv run pytest --cov=mitreattack

release:
needs: [commitlint, lint, test]
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
strategy:
matrix:
python-version: ["3.11"] # TODO see https://github.com/mitre-attack/mitreattack-python/issues/176
runs-on: ubuntu-latest
# The concurrency block prevents multiple release jobs from running simultaneously for the same branch.
# This is particularly useful for releases since you typically want sequential deployments (finish
# current release before starting next) rather than canceling in-progress releases or running them
# in parallel.
concurrency:
# Creates a concurrency group keyed by workflow name + "release" + branch name (e.g., "Continuous Delivery-release-main")
group: ${{ github.workflow }}-release-${{ github.ref_name }}
# If a release is already running and a new push triggers another, the new job waits rather than canceling the running one
# If you changed cancel-in-progress to true, a new push would cancel the currently running release job.
cancel-in-progress: false

permissions:
contents: write

steps:
# Note: We checkout the repository at the branch that triggered the workflow.
# Python Semantic Release will automatically convert shallow clones to full clones
# if needed to ensure proper history evaluation. However, we forcefully reset the
# branch to the workflow sha because it is possible that the branch was updated
# while the workflow was running, which prevents accidentally releasing un-evaluated
# changes.
- name: Setup | Checkout Repository on Release Branch
uses: actions/checkout@v6
with:
fetch-depth: 0
ref: ${{ github.ref_name }}

- name: Setup | Force release branch to be at workflow sha
run: |
git reset --hard ${{ github.sha }}

- name: Setup | Install uv
uses: astral-sh/setup-uv@v7
with:
python-version: ${{ matrix.python-version }}

- name: Setup | Install Python
run: uv python install ${{ matrix.python-version }}

- name: Setup | Install dependencies
run: uv sync --all-extras

- name: Semantic Release
id: release
uses: python-semantic-release/python-semantic-release@v10.5.3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
# NOTE: git_committer_name and git_committer_email are optional
# We omit them because, if set, they must be associated with the provided token
# and we don't really care to have a specific committer for automated releases.

- name: Upload to GitHub Release Assets
uses: python-semantic-release/publish-action@v10.5.3
if: steps.release.outputs.released == 'true'
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
tag: ${{ steps.release.outputs.tag }}

- name: Upload distribution artifacts
uses: actions/upload-artifact@v6
if: steps.release.outputs.released == 'true'
with:
name: distribution-artifacts
path: dist
if-no-files-found: error

outputs:
released: ${{ steps.release.outputs.released || 'false' }}

publish:
# 1. Separate out the deploy step from the publish step to run each step at
# the least amount of token privilege
# 2. Also, deployments can fail, and its better to have a separate job if you need to retry
# and it won't require reversing the release.
needs: release
if: needs.release.outputs.released == 'true'
runs-on: ubuntu-latest
environment: release

permissions:
contents: read
id-token: write

steps:
- name: Download build artifacts
uses: actions/download-artifact@v7
id: artifact-download
with:
name: distribution-artifacts
path: dist

- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: dist
print-hash: true
verbose: true
60 changes: 0 additions & 60 deletions .github/workflows/lint-publish.yml

This file was deleted.

36 changes: 36 additions & 0 deletions .github/workflows/pr-title.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: PR Title

# Validate that PR titles follow Conventional Commits format.
# Since we squash merge PRs, the PR title becomes the merge commit message,
# which Python Semantic Release uses to determine version bumps.
#
# This avoids burdening external contributors with conventional commit enforcement
# on every individual commit. See: https://www.conventionalcommits.org/en/v1.0.0/
#
# NOTE: pull_request_target is used instead of pull_request because it runs in the
# context of the base branch and has reliable access to the GITHUB_TOKEN for reading
# PR metadata.

on:
pull_request_target:
types: [opened, edited, synchronize, reopened]
branches: [main]

permissions:
pull-requests: read

jobs:
validate:
runs-on: ubuntu-latest
steps:
- name: Validate PR title
uses: amannn/action-semantic-pull-request@v5
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
# For work-in-progress PRs you can typically use draft pull requests from GitHub.
# This action allows us to use the special "[WIP]" prefix to indicate a draft state
# without actually flagging the PR as a draft.
# Example:
# `[WIP] feat: Add support for Node.js 18` <--- will not be validated!
wip: true
15 changes: 15 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.14.10
hooks:
# Run the linter (disabled for now)
# - id: ruff-check
# args: [--fix]
# Run the formatter
- id: ruff-format

- repo: https://github.com/commitizen-tools/commitizen
rev: v4.10.1
hooks:
- id: commitizen
stages: [commit-msg]
12 changes: 8 additions & 4 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@ build:
os: ubuntu-24.04
tools:
python: "3.11"
# For details on how to customize the build process, see:
# https://docs.readthedocs.com/platform/stable/builds.html
# https://docs.readthedocs.com/platform/stable/build-customization.html
jobs:
post_create_environment:
- pip install poetry
post_install:
- VIRTUAL_ENV=$READTHEDOCS_VIRTUALENV_PATH poetry install --with docs
install:
- pip install uv
- uv sync --extra docs
build:
- uv run sphinx-build -b html docs $READTHEDOCS_OUTPUT/html

sphinx:
configuration: docs/conf.py
71 changes: 57 additions & 14 deletions docs/CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,65 @@
# Contributors

## Reporting Issues
If you encounter an issue with the `mitreattack-python` library, please let us know by filing a [Github issue](https://github.com/mitre-attack/mitreattack-python/issues). When doing so, please make sure you provide the following information:
* Describe (in detail as possible) what occurred and what you were expecting to occur. Any information you can provide, such stack traces or errors are very helpful.
* Describe the steps necessary to replicate the issue.
* Indicate your OS and python versions.

If you encounter an issue with the `mitreattack-python` library, please let us know by filing a [GitHub issue](https://github.com/mitre-attack/mitreattack-python/issues). When doing so, please make sure you provide the following information:

- Describe (in as much detail as possible) what occurred and what you were expecting to occur. Any information you can provide, such as stack traces or errors, is very helpful.
- Describe the steps necessary to replicate the issue.
- Indicate your OS and Python versions.

## Suggested New Features
If you have an idea for a new feature for `mitreattack-python`, please let us know by filing a [Github issue](https://github.com/mitre-attack/mitreattack-python/issues). When doing so, please make sure you provide the following information:
* Explain the functionality you are proposing, and its use case - what would it be useful for or allow you to do?
* List what existing ATT&CK tools or resources map to the proposed functionality
* If applicable, provide examples of other requests for the proposed functionality

If you have an idea for a new feature for `mitreattack-python`, please let us know by filing a [GitHub issue](https://github.com/mitre-attack/mitreattack-python/issues). When doing so, please make sure you provide the following information:

- Explain the functionality you are proposing, and its use case — what would it be useful for or allow you to do?
- List what existing ATT&CK tools or resources map to the proposed functionality.
- If applicable, provide examples of other requests for the proposed functionality.

## Developing
If you want to work on the `mitreattack-python` library and contribute to its ongoing development, we welcome merge requests! You can set up an environment for development by following this process:
1. Clone the repository - `git clone https://github.com/mitre-attack/mitreattack-python`.
2. Create a virtual environment, and activate it - `python3 -m venv venv`/`. venv/bin/activate`.
3. Install the appropriate python modules via pip - `pip install -r requirements-dev.txt`.

### Merge Requests
When making a merge request, please make sure to include a summary of what the changes are intended to do, functionality wise, and the testing performed to validate the changes (ideally in the form of new pytests integrated into the `tests/` collection, though this is not strictly required). In addition, the complete pytest test battery `tests/` must be passed without errors in order for any code to actually be merged.
We welcome pull requests! To set up a local development environment:

### Prerequisites

- [Python 3.11+](https://www.python.org/downloads/)
- [uv](https://docs.astral.sh/uv/getting-started/installation/) — fast Python package manager
- [just](https://github.com/casey/just#installation) — command runner (optional, but recommended)

### Setup

```bash
# Clone the repository
git clone https://github.com/mitre-attack/mitreattack-python
cd mitreattack-python

# Install all dependencies (including dev and docs extras)
just install
# or without just:
uv sync --all-extras

# (Optional) Install pre-commit hooks for local linting and commit message validation
just setup-hooks
# or without just:
uv run pre-commit install
uv run pre-commit install --hook-type commit-msg
```

### Common Commands

Run `just` with no arguments to see all available commands. Here are the most common ones:

```bash
just lint # Run pre-commit hooks (ruff format) on all files
just test # Run tests
just test-cov # Run tests with coverage report
just build # Build the package
```

### Pull Requests

When making a pull request, please make sure to:

- Include a summary of what the changes are intended to do and the testing performed to validate them (ideally in the form of new pytests in the `tests/` collection, though this is not strictly required).
- **Use a [Conventional Commits](https://www.conventionalcommits.org) formatted PR title** (e.g., `feat: add new export format`, `fix: handle missing data sources`). PRs are squash-merged, so the PR title becomes the merge commit message — individual commit messages within the PR do not need to follow any convention.
- All pytest tests in `tests/` must pass, and ruff linting/formatting checks must be clean.
Loading