Skip to content

Commit 94d027b

Browse files
authored
Merge pull request #822 from yanjunqiAz/ci/modernize-workflows
Modernize CI workflows
2 parents 0d0929c + 1199647 commit 94d027b

50 files changed

Lines changed: 806 additions & 377 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
2-
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
3-
41
name: Formatting with black & isort
52

63
on:
@@ -10,25 +7,21 @@ on:
107
branches: [ master ]
118

129
jobs:
13-
build:
14-
10+
lint:
1511
runs-on: ubuntu-latest
16-
strategy:
17-
matrix:
18-
python-version: [3.9]
1912

2013
steps:
21-
- uses: actions/checkout@v2
22-
- name: Set up Python ${{ matrix.python-version }}
23-
uses: actions/setup-python@v2
14+
- uses: actions/checkout@v4
15+
- name: Set up Python
16+
uses: actions/setup-python@v5
2417
with:
25-
python-version: ${{ matrix.python-version }}
18+
python-version: "3.9"
2619
- name: Install dependencies
2720
run: |
2821
python -m pip install --upgrade pip setuptools wheel
29-
python setup.py install_egg_info # Workaround https://github.com/pypa/pip/issues/4537
30-
pip install -e .[dev]
31-
pip install black flake8 isort --upgrade # Testing packages
22+
python setup.py install_egg_info
23+
pip install "click<8.1.0"
24+
pip install -e .[test]
3225
- name: Check code format with black and isort
3326
run: |
3427
make lint
Lines changed: 4 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,9 @@
1-
# For most projects, this workflow file will not need changing; you simply need
2-
# to commit it to your repository.
3-
#
4-
# You may wish to alter this file to override the set of languages analyzed,
5-
# or to provide custom queries or build logic.
6-
#
7-
# ******** NOTE ********
8-
# We have attempted to detect the languages in your repository. Please check
9-
# the `language` matrix defined below to confirm you have the correct set of
10-
# supported CodeQL languages.
11-
#
121
name: "CodeQL"
132

143
on:
154
push:
165
branches: [ master, master* ]
176
pull_request:
18-
# The branches below must be a subset of the branches above
197
branches: [ master ]
208
schedule:
219
- cron: '24 1 * * 0'
@@ -29,39 +17,18 @@ jobs:
2917
fail-fast: false
3018
matrix:
3119
language: [ 'python' ]
32-
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
33-
# Learn more:
34-
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
3520

3621
steps:
3722
- name: Checkout repository
38-
uses: actions/checkout@v2
23+
uses: actions/checkout@v4
3924

40-
# Initializes the CodeQL tools for scanning.
4125
- name: Initialize CodeQL
42-
uses: github/codeql-action/init@v1
26+
uses: github/codeql-action/init@v3
4327
with:
4428
languages: ${{ matrix.language }}
45-
# If you wish to specify custom queries, you can do so here or in a config file.
46-
# By default, queries listed here will override any specified in a config file.
47-
# Prefix the list here with "+" to use these queries and those in the config file.
48-
# queries: ./path/to/local/query, your-org/your-repo/queries@main
4929

50-
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
51-
# If this step fails, then you should remove it and run the build manually (see below)
5230
- name: Autobuild
53-
uses: github/codeql-action/autobuild@v1
54-
55-
# ℹ️ Command-line programs to run using the OS shell.
56-
# 📚 https://git.io/JvXDl
57-
58-
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
59-
# and modify them (or add more) to build your code if your project
60-
# uses a compiled language
61-
62-
#- run: |
63-
# make bootstrap
64-
# make release
31+
uses: github/codeql-action/autobuild@v3
6532

6633
- name: Perform CodeQL Analysis
67-
uses: github/codeql-action/analyze@v1
34+
uses: github/codeql-action/analyze@v3

.github/workflows/make-docs.yml

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
2-
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
3-
41
name: Build documentation with Sphinx
52

63
on:
@@ -10,29 +7,23 @@ on:
107
branches: [ master ]
118

129
jobs:
13-
build:
14-
10+
docs:
1511
runs-on: ubuntu-latest
16-
strategy:
17-
matrix:
18-
python-version: [3.8]
1912

2013
steps:
21-
- uses: actions/checkout@v2
22-
- name: Set up Python ${{ matrix.python-version }}
23-
uses: actions/setup-python@v2
14+
- uses: actions/checkout@v4
15+
- name: Set up Python
16+
uses: actions/setup-python@v5
2417
with:
25-
python-version: ${{ matrix.python-version }}
18+
python-version: "3.11"
2619
- name: Install dependencies
2720
run: |
28-
sudo sed -i 's/azure\.//' /etc/apt/sources.list # workaround for flaky pandoc install
29-
sudo apt-get update # from here https://github.com/actions/virtual-environments/issues/675
30-
sudo apt-get install pandoc -o Acquire::Retries=3 # install pandoc
31-
python -m pip install --upgrade pip setuptools wheel # update python
32-
pip install ipython --upgrade # needed for Github for whatever reason
33-
python setup.py install_egg_info # Workaround https://github.com/pypa/pip/issues/4537
34-
pip install -e .[dev]
35-
pip install jupyter 'ipykernel<5.0.0' 'ipython<7.0.0' # ipykernel workaround: github.com/jupyter/notebook/issues/4050
21+
sudo apt-get update
22+
sudo apt-get install pandoc -o Acquire::Retries=3
23+
python -m pip install --upgrade pip setuptools wheel
24+
python setup.py install_egg_info
25+
pip install -e .[docs]
26+
pip install jupyter ipykernel
3627
- name: Build docs with Sphinx and check for errors
3728
run: |
3829
sphinx-build -b html docs docs/_build/html

.github/workflows/publish-to-pypi.yml

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
# This workflows will upload a Python Package using Twine when a release is created
2-
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries
3-
41
name: Upload Python Package to PyPI
52

63
on:
@@ -9,19 +6,17 @@ on:
96

107
jobs:
118
deploy:
12-
139
runs-on: ubuntu-latest
1410

1511
steps:
16-
- uses: actions/checkout@v2
12+
- uses: actions/checkout@v4
1713
- name: Set up Python
18-
uses: actions/setup-python@v2
14+
uses: actions/setup-python@v5
1915
with:
20-
python-version: '3.x'
16+
python-version: "3.11"
2117
- name: Install dependencies
2218
run: |
23-
python -m pip install --upgrade pip setuptools wheel
24-
pip install setuptools wheel twine
19+
python -m pip install --upgrade pip setuptools wheel twine
2520
- name: Build and publish
2621
env:
2722
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}

.github/workflows/run-pytest.yml

Lines changed: 13 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
2-
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
3-
41
name: Test with PyTest
52

63
on:
@@ -10,48 +7,34 @@ on:
107
branches: [ master ]
118

129
jobs:
13-
build:
14-
10+
test:
1511
runs-on: ubuntu-latest
1612
strategy:
1713
matrix:
18-
python-version: [3.8, 3.9]
14+
python-version: ["3.10", "3.11"]
1915

2016
steps:
21-
- uses: actions/checkout@v2
17+
- uses: actions/checkout@v4
2218
- name: Set up Python ${{ matrix.python-version }}
23-
uses: actions/setup-python@v2
19+
uses: actions/setup-python@v5
2420
with:
2521
python-version: ${{ matrix.python-version }}
2622
- name: Install dependencies
2723
run: |
2824
python -m pip install --upgrade pip setuptools wheel
29-
pip install pytest pytest-xdist # Testing packages
30-
pip uninstall textattack --yes # Remove TA if it's already installed
31-
python setup.py install_egg_info # Workaround https://github.com/pypa/pip/issues/4537
32-
pip install -e .[dev]
25+
pip install pytest pytest-xdist
26+
pip uninstall textattack --yes
27+
python setup.py install_egg_info
28+
pip install -e .[test]
3329
pip freeze
30+
- name: Download NLTK data
31+
run: |
32+
python -c "import nltk; nltk.download('punkt_tab'); nltk.download('averaged_perceptron_tagger'); nltk.download('stopwords'); nltk.download('omw-1.4'); nltk.download('wordnet')"
3433
- name: Free disk space
3534
run: |
36-
sudo apt-get remove mysql-client libmysqlclient-dev -y >/dev/null 2>&1
37-
sudo apt-get remove php* -y >/dev/null 2>&1
38-
sudo apt-get autoremove -y >/dev/null 2>&1
39-
sudo apt-get autoclean -y >/dev/null 2>&1
4035
sudo rm -rf /usr/local/lib/android >/dev/null 2>&1
41-
docker rmi $(docker image ls -aq) >/dev/null 2>&1
36+
sudo rm -rf /usr/share/dotnet >/dev/null 2>&1
4237
df -h
43-
- name: Increase swap space
44-
run: |
45-
swapon --show
46-
export SWAP_FILE=$(swapon --show=NAME | tail -n 1)
47-
sudo swapoff $SWAP_FILE
48-
sudo dd if=/dev/zero of=$SWAP_FILE bs=1M count=8k oflag=append conv=notrunc # Increase by 8GB
49-
sudo chmod 0600 $SWAP_FILE
50-
sudo mkswap $SWAP_FILE
51-
sudo swapon $SWAP_FILE
52-
swapon --show
5338
- name: Test with pytest
5439
run: |
55-
echo "skipping tests!"
56-
# pytest tests -v
57-
40+
pytest tests -v

CLAUDE.md

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
TextAttack (v0.3.10) is a Python framework for adversarial attacks, data augmentation, and model training in NLP. It provides a modular system where attacks are composed of four pluggable components: goal functions, constraints, transformations, and search methods. The project is maintained by UVA QData Lab.
8+
9+
## Common Commands
10+
11+
### Installation (dev mode)
12+
```bash
13+
pip install -e .[dev]
14+
```
15+
16+
### Testing
17+
```bash
18+
make test # Run full test suite (pytest --dist=loadfile -n auto)
19+
pytest tests -v # Verbose test run
20+
pytest tests/test_augment_api.py # Run a single test file
21+
pytest --lf # Re-run only last failed tests
22+
```
23+
24+
### Formatting & Linting
25+
```bash
26+
make format # Auto-format with black, isort, docformatter
27+
make lint # Check formatting (black --check, isort --check-only, flake8)
28+
```
29+
30+
### Building Docs
31+
```bash
32+
make docs # Build HTML docs with Sphinx
33+
make docs-auto # Hot-reload docs server on port 8765
34+
```
35+
36+
### CLI Usage
37+
```bash
38+
textattack attack --recipe textfooler --model bert-base-uncased-mr --num-examples 100
39+
textattack augment --input-csv examples.csv --output-csv output.csv --input-column text --recipe embedding
40+
textattack train --model-name-or-path lstm --dataset yelp_polarity --epochs 50
41+
textattack list attack-recipes
42+
textattack peek-dataset --dataset-from-huggingface snli
43+
```
44+
45+
## Architecture
46+
47+
### Core Attack Pipeline (`textattack/attack.py`, `textattack/attacker.py`)
48+
49+
An `Attack` is composed of exactly four components:
50+
1. **GoalFunction** (`textattack/goal_functions/`) - Determines if an attack succeeded. Categories: `classification/` (untargeted, targeted), `text/` (BLEU, translation overlap), `custom/`.
51+
2. **Constraints** (`textattack/constraints/`) - Filter invalid perturbations. Categories: `semantics/` (sentence encoders, word embeddings), `grammaticality/` (POS, language models, grammar tools), `overlap/` (edit distance, BLEU), `pre_transformation/` (restrict search space before transforming).
52+
3. **Transformation** (`textattack/transformations/`) - Generate candidate perturbations. Types: `word_swaps/` (embedding, gradient, homoglyph, WordNet), `word_insertions/`, `word_merges/`, `sentence_transformations/`, `WordDeletion`, `CompositeTransformation`.
53+
4. **SearchMethod** (`textattack/search_methods/`) - Traverse the perturbation space. Includes: `BeamSearch`, `GreedySearch`, `GreedyWordSwapWIR`, `GeneticAlgorithm`, `ParticleSwarmOptimization`, `DifferentialEvolution`.
54+
55+
The `Attacker` class orchestrates running attacks on datasets with parallel processing, checkpointing, and logging.
56+
57+
### Attack Recipes (`textattack/attack_recipes/`)
58+
59+
Pre-built attack configurations from the literature (e.g., TextFooler, DeepWordBug, BAE, BERT-Attack, CLARE, CheckList, etc.). Each recipe subclasses `AttackRecipe` and implements a `build(model_wrapper)` classmethod that returns a configured `Attack` object. Includes multi-lingual recipes for French, Spanish, and Chinese.
60+
61+
### Key Abstractions
62+
63+
- **`AttackedText`** (`textattack/shared/attacked_text.py`) - Central text representation that maintains both token list and original text with punctuation. Used throughout the pipeline instead of raw strings.
64+
- **`ModelWrapper`** (`textattack/models/wrappers/`) - Abstract interface for models. Implementations for PyTorch, HuggingFace, TensorFlow, sklearn. Models must accept string input and return predictions.
65+
- **`Dataset`** (`textattack/datasets/`) - Iterable of `(input, output)` pairs. Supports HuggingFace datasets and custom files.
66+
- **`Augmenter`** (`textattack/augmentation/`) - Uses transformations and constraints for data augmentation (not adversarial attacks). Built-in recipes: wordnet, embedding, charswap, eda, checklist, clare, back_trans.
67+
- **`PromptAugmentationPipeline`** (`textattack/prompt_augmentation/`) - Augments prompts and generates LLM responses.
68+
- **LLM Wrappers** (`textattack/llms/`) - Wrappers for using LLMs (HuggingFace, ChatGPT) with prompt augmentation.
69+
70+
### CLI Commands (`textattack/commands/`)
71+
72+
Entry point: `textattack/commands/textattack_cli.py`. Each command (attack, augment, train, eval-model, list, peek-dataset, benchmark-recipe, attack-resume) is a subclass of `TextAttackCommand` with `register_subcommand()` and `run()` methods.
73+
74+
### Configuration
75+
76+
- Version tracked in `docs/conf.py` (imported by `setup.py`)
77+
- Cache directory: `~/.cache/textattack/` (override with `TA_CACHE_DIR` env var)
78+
- Formatting: black (line length 88), isort (skip `__init__.py`), flake8 (ignores: E203, E266, E501, W503, D203)
79+
80+
### CI Workflows (`.github/workflows/`)
81+
82+
- `check-formatting.yml` - Runs `make lint` on Python 3.9
83+
- `run-pytest.yml` - Sets up Python 3.8/3.9 (pytest currently skipped in CI)
84+
- `publish-to-pypi.yml` - PyPI publishing
85+
- `make-docs.yml` - Documentation build
86+
- `codeql-analysis.yml` - Security analysis
87+
88+
### Test Structure
89+
90+
Tests are in `tests/` organized by feature:
91+
- `test_command_line/` - CLI command integration tests (attack, augment, train, eval, list, loggers)
92+
- `test_constraints/` - Constraint unit tests
93+
- `test_augment_api.py`, `test_transformations.py`, `test_attacked_text.py`, `test_tokenizers.py`, `test_word_embedding.py`, `test_metric_api.py`, `test_prompt_augmentation.py`
94+
- `test_command_line/update_test_outputs.py` - Script to regenerate expected test outputs
95+
96+
### Adding New Components
97+
98+
- **Attack recipe**: Subclass `AttackRecipe` in `textattack/attack_recipes/`, implement `build(model_wrapper)`, add import to `__init__.py`, add doc reference in `docs/attack_recipes.rst`.
99+
- **Transformation**: Subclass `Transformation` in appropriate subfolder under `textattack/transformations/`.
100+
- **Constraint**: Subclass `Constraint` or `PreTransformationConstraint` in appropriate subfolder under `textattack/constraints/`.
101+
- **Search method**: Subclass `SearchMethod` in `textattack/search_methods/`.

0 commit comments

Comments
 (0)