Skip to content

Commit 20798a8

Browse files
chore: implement CI/CD, linting, type checking, and remove due date syncing
- Configure Ruff for linting and formatting - Add Mypy for static type checking and fix existing type errors - Set up GitHub Actions CI workflow with Python 3.13 - Implement pre-commit hooks for local quality checks - Remove due date parsing and syncing as per TASKS.md - Update documentation (README, FORMAT, CONTRIBUTING) to reflect changes - Fix failing tests and clean up unused code
1 parent edc1dd7 commit 20798a8

File tree

18 files changed

+158
-162
lines changed

18 files changed

+158
-162
lines changed

.github/workflows/ci.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
15+
- name: Set up Python
16+
uses: actions/setup-python@v5
17+
with:
18+
python-version: "3.13"
19+
20+
- name: Install dependencies
21+
run: |
22+
python -m pip install --upgrade pip
23+
pip install .[dev]
24+
25+
- name: Run ruff check
26+
run: ruff check .
27+
28+
- name: Run ruff format check
29+
run: ruff format --check .
30+
31+
- name: Run type check
32+
run: mypy tasksmd_sync/
33+
34+
- name: Run tests
35+
run: pytest

.pre-commit-config.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
repos:
2+
- repo: https://github.com/astral-sh/ruff-pre-commit
3+
rev: v0.3.0
4+
hooks:
5+
- id: ruff
6+
args: [--fix, --exit-non-zero-on-fix]
7+
- id: ruff-format
8+
9+
- repo: https://github.com/pre-commit/mirrors-mypy
10+
rev: v1.9.0
11+
hooks:
12+
- id: mypy
13+
additional_dependencies: [httpx, pyyaml]
14+
files: ^tasksmd_sync/

CONTRIBUTING.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Contributing to tasksmd-sync
2+
3+
Thank you for your interest in contributing! This project uses a few tools to ensure code quality and consistency.
4+
5+
## Development Setup
6+
7+
1. Clone the repository
8+
2. Create a virtual environment:
9+
```bash
10+
python -m venv .venv
11+
source .venv/bin/activate # or .venv\Scripts\activate on Windows
12+
```
13+
3. Install the package in editable mode with development dependencies:
14+
```bash
15+
pip install -e ".[dev]"
16+
```
17+
4. Install pre-commit hooks:
18+
```bash
19+
pre-commit install
20+
```
21+
22+
## Code Quality Tools
23+
24+
We use the following tools to maintain code quality:
25+
26+
- **Ruff:** For linting and formatting.
27+
- **Mypy:** For static type checking.
28+
- **Pytest:** For unit testing.
29+
30+
You can run these locally:
31+
32+
```bash
33+
# Run linter
34+
ruff check .
35+
36+
# Run formatter
37+
ruff format .
38+
39+
# Run type checker
40+
mypy tasksmd_sync/
41+
42+
# Run tests
43+
pytest
44+
```
45+
46+
## Workflow
47+
48+
1. Create a new branch for your feature or bugfix.
49+
2. Ensure all tests pass and there are no linting or type errors.
50+
3. Submit a Pull Request.
51+
4. CI will run all checks automatically on your PR.
52+
53+
## Versioning
54+
55+
This project follows [Semantic Versioning](https://semver.org/). Version tags should be created on the `main` branch.

FORMAT.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ A TASKS.md file is organized into **status sections**, each containing **task bl
1717
<!-- id: PVTI_lADOBx... -->
1818
- **Assignee:** @username
1919
- **Labels:** bug, urgent
20-
- **Due:** 2025-03-15
2120

2221
Description of the task goes here. Can be multiple paragraphs,
2322
include code blocks, lists, etc.
@@ -35,7 +34,6 @@ reverse-sync pass.
3534
<!-- id: PVTI_lADOBx456 -->
3635
- **Assignee:** @doc
3736
- **Labels:** feature, core
38-
- **Due:** 2025-06-01
3937

4038
Multi-paragraph description with code:
4139

@@ -74,7 +72,6 @@ Each task block starts with a `### heading` (h3) and continues until the next `#
7472
- `<!-- id: PVTI_... -->` — hidden project board item ID for matching. Injected by the sync tool on creation. If absent, a new board item is created.
7573
- `- **Assignee:** @username` — GitHub username (with or without `@`)
7674
- `- **Labels:** label1, label2` — comma-separated list of labels
77-
- `- **Due:** YYYY-MM-DD` — due date in ISO format
7875

7976
**Description:**
8077
Everything after the metadata lines until the next task or section heading. Supports full GitHub-flavored markdown.
@@ -85,7 +82,6 @@ Everything after the metadata lines until the next task or section heading. Supp
8582
|-------|--------|---------|
8683
| Assignee | `@username` or `username` | `@octocat` |
8784
| Labels | Comma-separated strings | `bug, urgent, P0` |
88-
| Due | ISO 8601 date | `2025-03-15` |
8985
| Status | Determined by parent `##` section | (implicit) |
9086

9187
### ID Comments

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ Tasks are organized by status sections using markdown headings:
3434
<!-- id: PVTI_abc123 -->
3535
- **Assignee:** @alice
3636
- **Labels:** feature, security
37-
- **Due:** 2025-06-01
3837

3938
Description of the task goes here. Supports full GitHub-flavored
4039
markdown including code blocks, lists, and links.
@@ -64,7 +63,6 @@ Configured GitHub Actions for tests and linting.
6463
| Board ID | `<!-- id: PVTI_... -->` | No (auto-assigned) |
6564
| Assignee | `- **Assignee:** @username` | No |
6665
| Labels | `- **Labels:** label1, label2` | No |
67-
| Due Date | `- **Due:** YYYY-MM-DD` | No |
6866
| Status | Determined by parent `##` section | Yes (implicit) |
6967
| Description | Free text after metadata | No |
7068

@@ -106,7 +104,10 @@ tasksmd-sync TASKS.md \
106104
| `--org` | GitHub org login (required) |
107105
| `--project-number` | Project board number (required) |
108106
| `--token` | GitHub token (or set `GITHUB_TOKEN` / `TASKSMD_GITHUB_TOKEN` env var) |
107+
| `--repo` | Target repository for creating real Issues (format: `owner/repo`) |
109108
| `--repo-label` | Label to scope archive detection to this repo's items |
109+
| `--archive-done` | Archive tasks in the `Done` section and remove them from `TASKS.md` |
110+
| `--writeback` | Write board item IDs back into `TASKS.md` (default: false) |
110111
| `--dry-run` | Preview changes without executing |
111112
| `--verbose` / `-v` | Enable debug logging |
112113
| `--output-json` | Write sync results to a JSON file |

TASKS.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Tasks
22

3-
## Todo
3+
## Done
44

55
### Add PR comment summary for dry-run in CI
66
<!-- id: PVTI_lADOC9ysqc4BETyazglCHLI -->
@@ -30,5 +30,3 @@ corresponding GitHub Issues. This includes:
3030
- Adding missing labels to issues.
3131
- Removing labels that are no longer present in TASKS.md.
3232

33-
## Done
34-

action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ runs:
4848
- name: Set up Python
4949
uses: actions/setup-python@v5
5050
with:
51-
python-version: '3.11'
51+
python-version: '3.13'
5252

5353
- name: Install tasksmd-sync
5454
shell: bash

pyproject.toml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,39 @@ dependencies = [
1414
"pyyaml>=6.0",
1515
]
1616

17+
[project.optional-dependencies]
18+
dev = [
19+
"pytest>=8.0",
20+
"ruff>=0.3",
21+
"mypy>=1.0",
22+
"pre-commit>=3.0",
23+
]
24+
1725
[project.scripts]
1826
tasksmd-sync = "tasksmd_sync.cli:main"
1927

28+
[tool.ruff]
29+
line-length = 88
30+
target-version = "py311"
31+
32+
[tool.ruff.lint]
33+
select = [
34+
"E", # pycodestyle errors
35+
"W", # pycodestyle warnings
36+
"F", # pyflakes
37+
"I", # isort
38+
"C", # flake8-comprehensions
39+
"B", # flake8-bugbear
40+
"UP", # pyupgrade
41+
]
42+
ignore = [
43+
"E501", # Line too long
44+
"C901", # Function too complex
45+
"E741", # Ambiguous variable name
46+
]
47+
48+
[tool.ruff.lint.isort]
49+
known-first-party = ["tasksmd_sync"]
50+
2051
[tool.pytest.ini_options]
2152
testpaths = ["tests"]

tasksmd_sync/cli.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from .github_projects import GitHubProjectClient
1212
from .parser import parse_tasks_file
1313
from .sync import execute_sync
14-
from .writeback import writeback_ids, remove_done_tasks
14+
from .writeback import remove_done_tasks, writeback_ids
1515

1616

1717
def main(argv: list[str] | None = None) -> int:

tasksmd_sync/models.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ class Task:
1616
board_item_id: str | None = None
1717
assignee: str | None = None
1818
labels: list[str] = field(default_factory=list)
19-
due_date: date | None = None
2019

2120
@property
2221
def has_board_id(self) -> bool:
@@ -33,8 +32,6 @@ def metadata_dict(self) -> dict:
3332
d["assignee"] = self.assignee
3433
if self.labels:
3534
d["labels"] = sorted(self.labels)
36-
if self.due_date:
37-
d["due_date"] = self.due_date.isoformat()
3835
return d
3936

4037

@@ -54,7 +51,7 @@ def by_status(self) -> dict[str, list[Task]]:
5451

5552
@property
5653
def by_board_id(self) -> dict[str, Task]:
57-
return {t.board_item_id: t for t in self.tasks if t.has_board_id}
54+
return {t.board_item_id: t for t in self.tasks if t.board_item_id is not None}
5855

5956
@property
6057
def unlinked_tasks(self) -> list[Task]:

0 commit comments

Comments
 (0)