Skip to content

Commit 7cc0fbc

Browse files
Merge pull request #44 from Arithmomaniac/release/pypi-publishing
Add PyPI publishing infrastructure
2 parents c1c3a0c + 0ff3f50 commit 7cc0fbc

File tree

14 files changed

+464
-31
lines changed

14 files changed

+464
-31
lines changed

.github/copilot-instructions.md

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,24 @@ Run the type checker to ensure type safety:
4242
uv run ty check
4343
```
4444

45-
### 4. Run Tests
45+
### 4. Run Affected Tests
4646

47-
Run the test suite to verify changes don't break existing functionality:
47+
Rather than running the full test suite, identify and run only the tests affected by your changes. The full test suite is enforced by CI on every PR.
48+
49+
```bash
50+
# Map changed source files to their test files:
51+
# src/copilot_session_tools/database.py → tests/test_database.py
52+
# src/copilot_session_tools/scanner/ → tests/test_scanner.py
53+
# src/copilot_session_tools/cli.py → tests/test_cli.py
54+
# src/copilot_session_tools/web/ → tests/test_webapp.py
55+
# src/copilot_session_tools/markdown_exporter.py → tests/test_markdown_exporter.py
56+
# src/copilot_session_tools/html_exporter.py → tests/test_html_exporter.py
57+
58+
# Example: if you changed database.py and scanner/
59+
uv run pytest tests/test_database.py tests/test_scanner.py -v
60+
```
61+
62+
If unsure which tests are affected, run the full suite:
4863

4964
```bash
5065
uv run pytest tests/ --ignore=tests/test_webapp_e2e.py -v
@@ -57,9 +72,9 @@ Before committing any changes:
5772
1. Run `uv run ruff check .` - fix any linting errors
5873
2. Run `uv run ruff format .` - format the code
5974
3. Run `uv run ty check` - fix any type errors
60-
4. Run `uv run pytest tests/ --ignore=tests/test_webapp_e2e.py` - ensure tests pass
75+
4. Run `uv run pytest tests/test_<affected>.py` - run affected tests (CI runs the full suite)
6176

62-
All of these checks are also enforced in CI via GitHub Actions and must pass before merging.
77+
Linting, formatting, and type checks are also enforced by a sessionEnd hook. The full test suite is enforced in CI via GitHub Actions and must pass before merging.
6378

6479
## Project Structure
6580

.github/hooks/hooks.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"version": 1,
3+
"hooks": {
4+
"sessionEnd": [
5+
{
6+
"type": "command",
7+
"bash": "echo '🔍 Running end-of-session lint check...' && uv run ruff check . && uv run ruff format --check . && echo '✅ Lint and format checks passed'",
8+
"powershell": "Write-Host '🔍 Running end-of-session lint check...' && uv run ruff check . && uv run ruff format --check . && Write-Host '✅ Lint and format checks passed'",
9+
"cwd": ".",
10+
"timeoutSec": 60
11+
}
12+
]
13+
}
14+
}

.github/workflows/ci.yml

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@ permissions:
1111

1212
jobs:
1313
lint:
14-
name: Lint & Type Check
15-
runs-on: ubuntu-latest
14+
name: Lint & Type Check (${{ matrix.os }})
15+
runs-on: ${{ matrix.os }}
16+
strategy:
17+
matrix:
18+
os: [ubuntu-latest, windows-latest]
1619
steps:
1720
- name: Checkout code
1821
uses: actions/checkout@v4
@@ -38,8 +41,11 @@ jobs:
3841
run: uv run ty check
3942

4043
test:
41-
name: Tests
42-
runs-on: ubuntu-latest
44+
name: Tests (${{ matrix.os }})
45+
runs-on: ${{ matrix.os }}
46+
strategy:
47+
matrix:
48+
os: [ubuntu-latest, windows-latest]
4349
steps:
4450
- name: Checkout code
4551
uses: actions/checkout@v4
@@ -57,3 +63,39 @@ jobs:
5763

5864
- name: Run tests
5965
run: uv run pytest tests/ --ignore=tests/test_webapp_e2e.py -v
66+
67+
version-check:
68+
name: Version Bump Check
69+
runs-on: ubuntu-latest
70+
if: github.event_name == 'pull_request'
71+
steps:
72+
- name: Checkout PR branch
73+
uses: actions/checkout@v4
74+
75+
- name: Get PR version
76+
id: pr_version
77+
run: |
78+
PR_VERSION=$(grep '^version = ' pyproject.toml | head -1 | sed 's/version = "\(.*\)"/\1/')
79+
echo "version=$PR_VERSION" >> $GITHUB_OUTPUT
80+
echo "PR version: $PR_VERSION"
81+
82+
- name: Checkout main branch
83+
uses: actions/checkout@v4
84+
with:
85+
ref: main
86+
path: main-branch
87+
88+
- name: Get main version
89+
id: main_version
90+
run: |
91+
MAIN_VERSION=$(grep '^version = ' main-branch/pyproject.toml | head -1 | sed 's/version = "\(.*\)"/\1/')
92+
echo "version=$MAIN_VERSION" >> $GITHUB_OUTPUT
93+
echo "Main version: $MAIN_VERSION"
94+
95+
- name: Check version was bumped
96+
run: |
97+
if [ "${{ steps.pr_version.outputs.version }}" = "${{ steps.main_version.outputs.version }}" ]; then
98+
echo "::error::Version in pyproject.toml (${{ steps.pr_version.outputs.version }}) has not been bumped from main (${{ steps.main_version.outputs.version }}). Please update the version before merging."
99+
exit 1
100+
fi
101+
echo "✅ Version bumped: ${{ steps.main_version.outputs.version }} → ${{ steps.pr_version.outputs.version }}"

.github/workflows/release.yml

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
name: Release to PyPI
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*.*.*'
7+
8+
permissions:
9+
contents: write
10+
id-token: write
11+
12+
jobs:
13+
lint:
14+
name: Lint & Type Check
15+
runs-on: ubuntu-latest
16+
steps:
17+
- name: Checkout code
18+
uses: actions/checkout@v4
19+
20+
- name: Install uv
21+
uses: astral-sh/setup-uv@v4
22+
with:
23+
version: "latest"
24+
25+
- name: Set up Python
26+
run: uv python install 3.12
27+
28+
- name: Install dependencies
29+
run: uv sync --all-extras
30+
31+
- name: Run ruff linter
32+
run: uv run ruff check .
33+
34+
- name: Run ruff format check
35+
run: uv run ruff format --check .
36+
37+
- name: Run ty type checker
38+
run: uv run ty check
39+
40+
test:
41+
name: Tests
42+
runs-on: ubuntu-latest
43+
steps:
44+
- name: Checkout code
45+
uses: actions/checkout@v4
46+
47+
- name: Install uv
48+
uses: astral-sh/setup-uv@v4
49+
with:
50+
version: "latest"
51+
52+
- name: Set up Python
53+
run: uv python install 3.12
54+
55+
- name: Install dependencies
56+
run: uv sync --all-extras
57+
58+
- name: Run tests
59+
run: uv run pytest tests/ --ignore=tests/test_webapp_e2e.py -v
60+
61+
build:
62+
name: Build Package
63+
runs-on: ubuntu-latest
64+
needs: [lint, test]
65+
steps:
66+
- name: Checkout code
67+
uses: actions/checkout@v4
68+
69+
- name: Install uv
70+
uses: astral-sh/setup-uv@v4
71+
with:
72+
version: "latest"
73+
74+
- name: Set up Python
75+
run: uv python install 3.12
76+
77+
- name: Verify tag matches package version
78+
run: |
79+
TAG_VERSION=${GITHUB_REF#refs/tags/v}
80+
PKG_VERSION=$(grep '^version = ' pyproject.toml | head -1 | sed 's/version = "\(.*\)"/\1/')
81+
if [ "$TAG_VERSION" != "$PKG_VERSION" ]; then
82+
echo "::error::Tag version ($TAG_VERSION) does not match package version ($PKG_VERSION)"
83+
exit 1
84+
fi
85+
echo "✅ Tag matches package version: $PKG_VERSION"
86+
87+
- name: Build package
88+
run: uv build
89+
90+
- name: Upload build artifacts
91+
uses: actions/upload-artifact@v4
92+
with:
93+
name: dist
94+
path: dist/
95+
96+
publish-testpypi:
97+
name: Publish to TestPyPI
98+
runs-on: ubuntu-latest
99+
needs: [build]
100+
environment: testpypi
101+
steps:
102+
- name: Download build artifacts
103+
uses: actions/download-artifact@v4
104+
with:
105+
name: dist
106+
path: dist/
107+
108+
- name: Publish to TestPyPI
109+
uses: pypa/gh-action-pypi-publish@release/v1
110+
with:
111+
repository-url: https://test.pypi.org/legacy/
112+
113+
publish-pypi:
114+
name: Publish to PyPI
115+
runs-on: ubuntu-latest
116+
needs: [publish-testpypi]
117+
environment: pypi
118+
steps:
119+
- name: Download build artifacts
120+
uses: actions/download-artifact@v4
121+
with:
122+
name: dist
123+
path: dist/
124+
125+
- name: Publish to PyPI
126+
uses: pypa/gh-action-pypi-publish@release/v1
127+
128+
github-release:
129+
name: Create GitHub Release
130+
runs-on: ubuntu-latest
131+
needs: [publish-pypi]
132+
steps:
133+
- name: Checkout code
134+
uses: actions/checkout@v4
135+
136+
- name: Create GitHub Release
137+
uses: softprops/action-gh-release@v2
138+
with:
139+
generate_release_notes: true
140+
draft: false
141+
prerelease: false

CHANGELOG.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7+
8+
## [0.1.0] - 2025-02-13
9+
10+
### Added
11+
12+
- **Scanner**: Scan VS Code workspace storage (Stable and Insiders editions) to find Copilot chat sessions
13+
- **Scanner**: GitHub Copilot CLI chat history support (JSONL format from `~/.copilot/session-state`)
14+
- **Scanner**: Support for VS Code JSONL append-log format (VS Code >=1.109)
15+
- **Database**: SQLite storage with FTS5 full-text search indexing
16+
- **Database**: Two-layer design with raw compressed JSON as source of truth and derived tables
17+
- **Database**: Incremental scan support (only imports new/changed sessions)
18+
- **CLI**: `scan` command to import sessions from VS Code and CLI
19+
- **CLI**: `search` command with advanced query syntax (field filters, exact phrases, boolean logic)
20+
- **CLI**: `stats` command for database statistics
21+
- **CLI**: `export` command for JSON export
22+
- **CLI**: `export-markdown` command for Markdown export
23+
- **CLI**: `export-html` command for self-contained HTML export
24+
- **CLI**: `import-json` command for JSON import
25+
- **CLI**: `rebuild` command to recreate derived tables from raw JSON
26+
- **Web**: Flask-based web interface for browsing chat sessions
27+
- **Web**: Full-text search with highlighting
28+
- **Web**: Dark mode support via CSS `prefers-color-scheme`
29+
- **Web**: Syntax highlighting for code blocks
30+
- **Web**: Incremental refresh without restarting
31+
- **Tracking**: Tool invocations, file changes, and command runs from chat sessions

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# Copilot Session Tools
22

3-
Create a searchable archive of your VS Code and GitHub Copilot CLI chat history, with a web viewer similar to [simonw/claude-code-transcripts](https://github.com/simonw/claude-code-transcripts).
3+
[![CI](https://github.com/Arithmomaniac/copilot-session-tools/actions/workflows/ci.yml/badge.svg)](https://github.com/Arithmomaniac/copilot-session-tools/actions/workflows/ci.yml) [![PyPI](https://img.shields.io/pypi/v/copilot-session-tools)](https://pypi.org/project/copilot-session-tools/) [![Python](https://img.shields.io/pypi/pyversions/copilot-session-tools)](https://pypi.org/project/copilot-session-tools/) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
4+
5+
Create a searchable archiveof your VS Code and GitHub Copilot CLI chat history, with a web viewer similar to [simonw/claude-code-transcripts](https://github.com/simonw/claude-code-transcripts).
46

57
This project was informed by and borrows patterns from several excellent open-source projects:
68

0 commit comments

Comments
 (0)