google-sheets-mcp-and-skill 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- google_sheets_mcp_and_skill-0.4.0/.github/ISSUE_TEMPLATE/bug_report.md +65 -0
- google_sheets_mcp_and_skill-0.4.0/.github/ISSUE_TEMPLATE/config.yml +13 -0
- google_sheets_mcp_and_skill-0.4.0/.github/ISSUE_TEMPLATE/feature_request.md +54 -0
- google_sheets_mcp_and_skill-0.4.0/.github/pull_request_template.md +65 -0
- google_sheets_mcp_and_skill-0.4.0/.github/workflows/ci.yml +23 -0
- google_sheets_mcp_and_skill-0.4.0/.github/workflows/release.yml +59 -0
- google_sheets_mcp_and_skill-0.4.0/.gitignore +53 -0
- google_sheets_mcp_and_skill-0.4.0/CHANGELOG.md +355 -0
- google_sheets_mcp_and_skill-0.4.0/CONTRIBUTING.md +366 -0
- google_sheets_mcp_and_skill-0.4.0/LICENSE +21 -0
- google_sheets_mcp_and_skill-0.4.0/PKG-INFO +373 -0
- google_sheets_mcp_and_skill-0.4.0/README.md +345 -0
- google_sheets_mcp_and_skill-0.4.0/docs/ARCHITECTURE.md +746 -0
- google_sheets_mcp_and_skill-0.4.0/docs/usage.md +305 -0
- google_sheets_mcp_and_skill-0.4.0/examples/README.md +84 -0
- google_sheets_mcp_and_skill-0.4.0/examples/audit_conditional_formatting.sh +55 -0
- google_sheets_mcp_and_skill-0.4.0/examples/audit_tables_and_filters.sh +72 -0
- google_sheets_mcp_and_skill-0.4.0/examples/bulk_find_replace.sh +76 -0
- google_sheets_mcp_and_skill-0.4.0/examples/read_column_formulas.sh +50 -0
- google_sheets_mcp_and_skill-0.4.0/examples/safe_value_write.sh +49 -0
- google_sheets_mcp_and_skill-0.4.0/pyproject.toml +63 -0
- google_sheets_mcp_and_skill-0.4.0/skill/SKILL.md +375 -0
- google_sheets_mcp_and_skill-0.4.0/skill/references/advanced.md +289 -0
- google_sheets_mcp_and_skill-0.4.0/skill/references/basic.md +394 -0
- google_sheets_mcp_and_skill-0.4.0/skill/references/intermediate.md +440 -0
- google_sheets_mcp_and_skill-0.4.0/src/gsheets/__init__.py +41 -0
- google_sheets_mcp_and_skill-0.4.0/src/gsheets/auth/__init__.py +434 -0
- google_sheets_mcp_and_skill-0.4.0/src/gsheets/auth/resolver.py +457 -0
- google_sheets_mcp_and_skill-0.4.0/src/gsheets/cli.py +1742 -0
- google_sheets_mcp_and_skill-0.4.0/src/gsheets/core/__init__.py +55 -0
- google_sheets_mcp_and_skill-0.4.0/src/gsheets/core/addressing.py +492 -0
- google_sheets_mcp_and_skill-0.4.0/src/gsheets/core/banding.py +373 -0
- google_sheets_mcp_and_skill-0.4.0/src/gsheets/core/batch.py +78 -0
- google_sheets_mcp_and_skill-0.4.0/src/gsheets/core/charts.py +431 -0
- google_sheets_mcp_and_skill-0.4.0/src/gsheets/core/colors.py +176 -0
- google_sheets_mcp_and_skill-0.4.0/src/gsheets/core/comments.py +522 -0
- google_sheets_mcp_and_skill-0.4.0/src/gsheets/core/condformat.py +816 -0
- google_sheets_mcp_and_skill-0.4.0/src/gsheets/core/dataops.py +729 -0
- google_sheets_mcp_and_skill-0.4.0/src/gsheets/core/dataselector.py +122 -0
- google_sheets_mcp_and_skill-0.4.0/src/gsheets/core/dimensions.py +575 -0
- google_sheets_mcp_and_skill-0.4.0/src/gsheets/core/errors.py +374 -0
- google_sheets_mcp_and_skill-0.4.0/src/gsheets/core/export.py +217 -0
- google_sheets_mcp_and_skill-0.4.0/src/gsheets/core/fieldsmask.py +108 -0
- google_sheets_mcp_and_skill-0.4.0/src/gsheets/core/filters.py +552 -0
- google_sheets_mcp_and_skill-0.4.0/src/gsheets/core/flatten.py +158 -0
- google_sheets_mcp_and_skill-0.4.0/src/gsheets/core/format.py +487 -0
- google_sheets_mcp_and_skill-0.4.0/src/gsheets/core/formatting.py +291 -0
- google_sheets_mcp_and_skill-0.4.0/src/gsheets/core/formula_patterns.py +355 -0
- google_sheets_mcp_and_skill-0.4.0/src/gsheets/core/multiread.py +173 -0
- google_sheets_mcp_and_skill-0.4.0/src/gsheets/core/paths.py +232 -0
- google_sheets_mcp_and_skill-0.4.0/src/gsheets/core/pivot.py +294 -0
- google_sheets_mcp_and_skill-0.4.0/src/gsheets/core/reads.py +1338 -0
- google_sheets_mcp_and_skill-0.4.0/src/gsheets/core/retry.py +517 -0
- google_sheets_mcp_and_skill-0.4.0/src/gsheets/core/richtext.py +222 -0
- google_sheets_mcp_and_skill-0.4.0/src/gsheets/core/rules.py +626 -0
- google_sheets_mcp_and_skill-0.4.0/src/gsheets/core/service.py +28 -0
- google_sheets_mcp_and_skill-0.4.0/src/gsheets/core/slicers.py +572 -0
- google_sheets_mcp_and_skill-0.4.0/src/gsheets/core/structure.py +1657 -0
- google_sheets_mcp_and_skill-0.4.0/src/gsheets/core/tables.py +422 -0
- google_sheets_mcp_and_skill-0.4.0/src/gsheets/core/values.py +606 -0
- google_sheets_mcp_and_skill-0.4.0/src/gsheets/mcp_server.py +1942 -0
- google_sheets_mcp_and_skill-0.4.0/src/gsheets/models.py +1619 -0
- google_sheets_mcp_and_skill-0.4.0/tests/conftest.py +107 -0
- google_sheets_mcp_and_skill-0.4.0/tests/fixtures/.gitkeep +0 -0
- google_sheets_mcp_and_skill-0.4.0/tests/integration/test_live_smoke.py +365 -0
- google_sheets_mcp_and_skill-0.4.0/tests/integration/test_live_v02.py +817 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/golden/.gitkeep +0 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/golden/a1_to_gridrange.json +83 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/golden/banding_serialize.json +89 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/golden/condformat_boolean_rule.json +15 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/golden/condformat_gradient_rule.json +18 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/golden/describe_region.json +255 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/golden/fieldsmask_cases.json +140 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/golden/filters_serialize.json +87 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/golden/flatten_full.json +50 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/golden/formula_patterns.json +135 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/golden/richtext_runs.json +31 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/golden/slicer_addslicer_request.json +51 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/golden/slicer_serialize.json +48 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/golden/table_serialize.json +45 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_addressing.py +629 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_auth.py +881 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_auth_resolver.py +763 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_banding.py +581 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_batch.py +322 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_boundary_guard.py +128 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_charts.py +1002 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_cli.py +1409 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_colors.py +330 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_comments.py +701 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_condformat.py +1374 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_conftest.py +152 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_core_init.py +128 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_dataops.py +1071 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_dataselector.py +110 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_describe.py +583 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_dimensions.py +1053 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_errors.py +589 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_export.py +456 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_fieldsmask.py +273 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_filters.py +584 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_flatten.py +359 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_format.py +555 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_formatting.py +692 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_formula_patterns.py +411 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_live_denylist_guard.py +96 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_mcp_file_output.py +477 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_mcp_retry.py +148 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_mcp_server.py +719 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_models.py +1157 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_multiread.py +521 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_paths.py +267 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_pivot.py +527 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_pkg_init.py +106 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_pyproject.py +226 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_reads.py +1821 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_retry.py +631 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_richtext.py +328 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_rules.py +966 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_service.py +145 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_slicers.py +689 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_structure.py +2114 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_tables.py +640 -0
- google_sheets_mcp_and_skill-0.4.0/tests/unit/test_values.py +891 -0
- google_sheets_mcp_and_skill-0.4.0/uv.lock +2052 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug report
|
|
3
|
+
about: Report something that is broken or behaves incorrectly
|
|
4
|
+
title: "[Bug] "
|
|
5
|
+
labels: bug
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
<!--
|
|
10
|
+
Thanks for filing a bug. Before you submit:
|
|
11
|
+
- Search existing issues to avoid duplicates.
|
|
12
|
+
- NEVER paste real credentials, tokens, service-account keys, or a real spreadsheet ID.
|
|
13
|
+
Use <YOUR_SPREADSHEET_ID> as a placeholder and redact any personal data.
|
|
14
|
+
-->
|
|
15
|
+
|
|
16
|
+
## What happened
|
|
17
|
+
|
|
18
|
+
A clear, concise description of the bug.
|
|
19
|
+
|
|
20
|
+
## What you expected
|
|
21
|
+
|
|
22
|
+
What you expected to happen instead.
|
|
23
|
+
|
|
24
|
+
## Entrypoint
|
|
25
|
+
|
|
26
|
+
Which adapter were you using? (the behavior should be identical from either)
|
|
27
|
+
|
|
28
|
+
- [ ] CLI (`gsheets`)
|
|
29
|
+
- [ ] MCP server (`google-sheets-mcp`)
|
|
30
|
+
- [ ] Calling `gsheets.core` directly
|
|
31
|
+
|
|
32
|
+
## Which tool / subcommand
|
|
33
|
+
|
|
34
|
+
e.g. `inspect`, `read-conditional-formats`, `format`, `set-conditional-format`, …
|
|
35
|
+
|
|
36
|
+
## Steps to reproduce
|
|
37
|
+
|
|
38
|
+
A minimal reproduction. Redact real IDs.
|
|
39
|
+
|
|
40
|
+
```sh
|
|
41
|
+
# Example — replace <YOUR_SPREADSHEET_ID> with a placeholder, never a real id
|
|
42
|
+
gsheets inspect <YOUR_SPREADSHEET_ID> 'Sheet1!A1:D20' --compact
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Actual output / error
|
|
46
|
+
|
|
47
|
+
Paste the command output or error envelope. Redact any account email or real id.
|
|
48
|
+
|
|
49
|
+
```text
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Environment
|
|
54
|
+
|
|
55
|
+
- Package version (`gsheets --version` or the installed version):
|
|
56
|
+
- Python version (`python --version`):
|
|
57
|
+
- OS:
|
|
58
|
+
- Auth mode (`GSHEETS_AUTH_MODE`): `service_account` / `oauth` / `adc` / `auto`
|
|
59
|
+
- Installed via: `uv sync` from source / `uv tool install` / `uvx` / other
|
|
60
|
+
|
|
61
|
+
## Additional context
|
|
62
|
+
|
|
63
|
+
Anything else that helps — a redacted snippet of the sheet, related issues, a guess at
|
|
64
|
+
the cause. If you can share a minimal redacted golden-master JSON that triggers it, that
|
|
65
|
+
is ideal.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
blank_issues_enabled: false
|
|
2
|
+
contact_links:
|
|
3
|
+
- name: Question or usage help
|
|
4
|
+
url: https://github.com/colindmurray/google-sheets-mcp-and-skill/discussions
|
|
5
|
+
about: >
|
|
6
|
+
For "how do I…" questions, setup/auth help, or general discussion, please open a
|
|
7
|
+
Discussion instead of an issue. Never share real credentials or a real spreadsheet
|
|
8
|
+
ID — use <YOUR_SPREADSHEET_ID>.
|
|
9
|
+
- name: Security vulnerability
|
|
10
|
+
url: https://github.com/colindmurray/google-sheets-mcp-and-skill/security/advisories/new
|
|
11
|
+
about: >
|
|
12
|
+
Report security vulnerabilities privately via a GitHub security advisory, not a
|
|
13
|
+
public issue.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Feature request
|
|
3
|
+
about: Propose a new capability or improvement
|
|
4
|
+
title: "[Feature] "
|
|
5
|
+
labels: enhancement
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
<!--
|
|
10
|
+
Thanks for proposing an improvement. Before you submit:
|
|
11
|
+
- Search existing issues to avoid duplicates.
|
|
12
|
+
- NEVER include real credentials or a real spreadsheet ID. Use <YOUR_SPREADSHEET_ID>.
|
|
13
|
+
- Skim docs/ARCHITECTURE.md and CONTRIBUTING.md — new behavior must fit the
|
|
14
|
+
pure-core / thin-adapter design and map 1:1 to BOTH adapters.
|
|
15
|
+
-->
|
|
16
|
+
|
|
17
|
+
## The problem / use case
|
|
18
|
+
|
|
19
|
+
What are you trying to do with a spreadsheet that you can't (cleanly) do today? Describe
|
|
20
|
+
the workflow, not just the API call.
|
|
21
|
+
|
|
22
|
+
## Proposed solution
|
|
23
|
+
|
|
24
|
+
What would you like to see? If it is a new tool, sketch it:
|
|
25
|
+
|
|
26
|
+
- **Core function name** (and signature, if you have one in mind):
|
|
27
|
+
- **What it reads or writes:**
|
|
28
|
+
- **Return shape** (remember: anything writable should be readable back — CRUD symmetry):
|
|
29
|
+
- **MCP tool name** (`sheets_…`) **and CLI subcommand** (`…`):
|
|
30
|
+
|
|
31
|
+
## Read-side richness?
|
|
32
|
+
|
|
33
|
+
This project's thesis is rich, token-efficient, round-trippable **reads**. Does this
|
|
34
|
+
proposal improve a read (values/formulas/formatting/conditional-format/validation/
|
|
35
|
+
structure)? If so, say how it stays token-efficient (tight `fields` mask, flattened
|
|
36
|
+
output, optional compact mode).
|
|
37
|
+
|
|
38
|
+
## Alternatives considered
|
|
39
|
+
|
|
40
|
+
Including: can the existing `batch` escape hatch already do this? If so, why is a typed
|
|
41
|
+
tool worth adding?
|
|
42
|
+
|
|
43
|
+
## Design fit checklist
|
|
44
|
+
|
|
45
|
+
- [ ] Fits the pure-core / thin-adapter boundary (logic in core, one-line adapter bodies)
|
|
46
|
+
- [ ] Maps 1:1 to both the MCP tool and the CLI subcommand
|
|
47
|
+
- [ ] Preserves CRUD symmetry (writable ⇒ readable back) where applicable
|
|
48
|
+
- [ ] Token-efficient by default (no `includeGridData`; tight `fields` mask)
|
|
49
|
+
- [ ] No real IDs / credentials / personal info anywhere in the proposal
|
|
50
|
+
|
|
51
|
+
## Additional context
|
|
52
|
+
|
|
53
|
+
Examples (using `<YOUR_SPREADSHEET_ID>`), references to the Google Sheets API surface,
|
|
54
|
+
prior art in other tools, or anything else that helps.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Thanks for contributing! Please fill this out so reviewers can move quickly.
|
|
3
|
+
Read CONTRIBUTING.md first if you haven't — especially the pure-core / thin-adapter rule.
|
|
4
|
+
NEVER include real credentials, tokens, keys, or a real spreadsheet ID anywhere in this
|
|
5
|
+
PR. Use <YOUR_SPREADSHEET_ID> in examples.
|
|
6
|
+
-->
|
|
7
|
+
|
|
8
|
+
## What & why
|
|
9
|
+
|
|
10
|
+
What does this PR change, and why? Link any related issue (`Closes #123`).
|
|
11
|
+
|
|
12
|
+
## Type of change
|
|
13
|
+
|
|
14
|
+
- [ ] Bug fix (non-breaking)
|
|
15
|
+
- [ ] New tool / capability (a core function + its model + MCP tool + CLI subcommand)
|
|
16
|
+
- [ ] Improvement to an existing tool
|
|
17
|
+
- [ ] Docs only
|
|
18
|
+
- [ ] Refactor / internal (no behavior change)
|
|
19
|
+
- [ ] Breaking change (changes a public core signature or output shape)
|
|
20
|
+
|
|
21
|
+
## Architecture boundary (must hold)
|
|
22
|
+
|
|
23
|
+
- [ ] No `fastmcp` / `mcp` / `argparse` / `pydantic` / `gsheets.models` import was added
|
|
24
|
+
to any `core/**` or `auth/**` module.
|
|
25
|
+
- [ ] Sheets logic lives in core; adapter tool/subcommand bodies stay essentially
|
|
26
|
+
one-line (resolve services → call core → return/print).
|
|
27
|
+
- [ ] `uv run pytest` passes, **including** the subprocess boundary-guard test.
|
|
28
|
+
|
|
29
|
+
## If this adds or changes a tool
|
|
30
|
+
|
|
31
|
+
Confirm the 1:1 mapping is complete across all entrypoints:
|
|
32
|
+
|
|
33
|
+
- [ ] Core function implemented and re-exported from `gsheets/core/__init__.py`
|
|
34
|
+
- [ ] Unit test added/updated (with a golden-master fixture if it serializes/parses)
|
|
35
|
+
- [ ] Pydantic mirror model in `models.py` (same field names as the core dict)
|
|
36
|
+
- [ ] MCP tool registered with correct `ToolAnnotations` + an example-rich docstring
|
|
37
|
+
- [ ] CLI subcommand added (flags map 1:1 to core kwargs; supports `--json`)
|
|
38
|
+
- [ ] Docs updated (`SKILL.md` command map, `skill/references/*`, `docs/ARCHITECTURE.md`)
|
|
39
|
+
- [ ] CRUD symmetry preserved where applicable (writable ⇒ readable back)
|
|
40
|
+
|
|
41
|
+
## Security & privacy (this repo is public)
|
|
42
|
+
|
|
43
|
+
- [ ] No credentials, tokens, keys, real spreadsheet IDs, or personal info added to the
|
|
44
|
+
committed tree (`src/`, `tests/`, `docs/`, `README`, `SKILL.md`, `examples/`).
|
|
45
|
+
- [ ] Examples use the `<YOUR_SPREADSHEET_ID>` placeholder.
|
|
46
|
+
- [ ] No new error message leaks the operator's account email by default.
|
|
47
|
+
|
|
48
|
+
## Changelog
|
|
49
|
+
|
|
50
|
+
- [ ] Added an entry under `## [Unreleased]` in `CHANGELOG.md`.
|
|
51
|
+
|
|
52
|
+
## How I tested
|
|
53
|
+
|
|
54
|
+
Describe what you ran (e.g. `uv run pytest`, a specific subcommand against a throwaway
|
|
55
|
+
sheet via the env-gated live tests). Redact any real ids.
|
|
56
|
+
|
|
57
|
+
```text
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Breaking changes / notes for reviewers
|
|
62
|
+
|
|
63
|
+
If you changed a public core signature, list every caller you updated (core fn, model,
|
|
64
|
+
MCP tool, CLI subcommand, tests, docs) and why the change was necessary. Otherwise,
|
|
65
|
+
delete this section.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
strategy:
|
|
12
|
+
fail-fast: false
|
|
13
|
+
matrix:
|
|
14
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- uses: astral-sh/setup-uv@v5
|
|
18
|
+
with:
|
|
19
|
+
python-version: ${{ matrix.python-version }}
|
|
20
|
+
- name: Install
|
|
21
|
+
run: uv sync
|
|
22
|
+
- name: Test (mocked suite, includes the boundary-guard test)
|
|
23
|
+
run: uv run pytest
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
name: Release to PyPI
|
|
2
|
+
|
|
3
|
+
# Publishes the package to PyPI via Trusted Publishing (OIDC) — NO stored API token.
|
|
4
|
+
#
|
|
5
|
+
# Triggers:
|
|
6
|
+
# - pushing a version tag (v*), e.g. `git tag -a v0.4.1 && git push origin v0.4.1`
|
|
7
|
+
# - manual `workflow_dispatch` (used for the very first release of an already-cut tag)
|
|
8
|
+
#
|
|
9
|
+
# PyPI side (one-time): register a Trusted Publisher for project
|
|
10
|
+
# `google-sheets-mcp-and-skill` with owner `colindmurray`, repository
|
|
11
|
+
# `google-sheets-mcp-and-skill`, workflow `release.yml`, environment `pypi`.
|
|
12
|
+
|
|
13
|
+
on:
|
|
14
|
+
push:
|
|
15
|
+
tags:
|
|
16
|
+
- "v*"
|
|
17
|
+
workflow_dispatch:
|
|
18
|
+
|
|
19
|
+
permissions:
|
|
20
|
+
contents: read
|
|
21
|
+
|
|
22
|
+
jobs:
|
|
23
|
+
build:
|
|
24
|
+
name: Build & test
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v4
|
|
28
|
+
- uses: astral-sh/setup-uv@v5
|
|
29
|
+
with:
|
|
30
|
+
enable-cache: true
|
|
31
|
+
- name: Run the test suite (gate the release on green tests)
|
|
32
|
+
run: uv run --frozen pytest -q
|
|
33
|
+
- name: Build sdist + wheel
|
|
34
|
+
run: uv build
|
|
35
|
+
- name: Validate distribution metadata
|
|
36
|
+
run: uvx twine check dist/*
|
|
37
|
+
- uses: actions/upload-artifact@v4
|
|
38
|
+
with:
|
|
39
|
+
name: dist
|
|
40
|
+
path: dist/
|
|
41
|
+
|
|
42
|
+
publish:
|
|
43
|
+
name: Publish to PyPI
|
|
44
|
+
needs: build
|
|
45
|
+
runs-on: ubuntu-latest
|
|
46
|
+
# The Trusted Publisher is scoped to this environment on PyPI; it also lets you add
|
|
47
|
+
# an optional required-reviewer protection rule in the repo's Settings → Environments.
|
|
48
|
+
environment:
|
|
49
|
+
name: pypi
|
|
50
|
+
url: https://pypi.org/p/google-sheets-mcp-and-skill
|
|
51
|
+
permissions:
|
|
52
|
+
id-token: write # OIDC: mint the short-lived token PyPI exchanges for upload rights
|
|
53
|
+
steps:
|
|
54
|
+
- uses: actions/download-artifact@v4
|
|
55
|
+
with:
|
|
56
|
+
name: dist
|
|
57
|
+
path: dist/
|
|
58
|
+
- name: Publish to PyPI (Trusted Publishing)
|
|
59
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Internal build brief / design / research — gitignored (contains real IDs)
|
|
2
|
+
internal/
|
|
3
|
+
|
|
4
|
+
# Local stress-test issue log + resolutions — contains real spreadsheet IDs (keep out of this public repo)
|
|
5
|
+
ISSUES.md
|
|
6
|
+
|
|
7
|
+
# Local maintainer planning/working docs — for the maintainer's own use, never part of the public package
|
|
8
|
+
ENHANCEMENTS.md
|
|
9
|
+
SPEC.md
|
|
10
|
+
|
|
11
|
+
# Agent-instruction files — kept locally for AI-assisted dev, intentionally NOT in the public repo
|
|
12
|
+
CLAUDE.md
|
|
13
|
+
AGENTS.md
|
|
14
|
+
GEMINI.md
|
|
15
|
+
.cursorrules
|
|
16
|
+
|
|
17
|
+
# Python build & packaging
|
|
18
|
+
build/
|
|
19
|
+
dist/
|
|
20
|
+
*.egg-info/
|
|
21
|
+
*.egg
|
|
22
|
+
__pycache__/
|
|
23
|
+
*.py[cod]
|
|
24
|
+
*.pyo
|
|
25
|
+
|
|
26
|
+
# Virtual environments
|
|
27
|
+
.venv/
|
|
28
|
+
venv/
|
|
29
|
+
env/
|
|
30
|
+
|
|
31
|
+
# Test & tooling caches
|
|
32
|
+
.pytest_cache/
|
|
33
|
+
.coverage
|
|
34
|
+
.coverage.*
|
|
35
|
+
htmlcov/
|
|
36
|
+
.mypy_cache/
|
|
37
|
+
.ruff_cache/
|
|
38
|
+
.cache/
|
|
39
|
+
|
|
40
|
+
# Credentials — NEVER commit (real creds live outside the repo at runtime)
|
|
41
|
+
gcp-oauth.keys.json
|
|
42
|
+
token.json
|
|
43
|
+
service-account*.json
|
|
44
|
+
credentials.json
|
|
45
|
+
*.pem
|
|
46
|
+
.env
|
|
47
|
+
.env.*
|
|
48
|
+
|
|
49
|
+
# Editor / OS cruft
|
|
50
|
+
.DS_Store
|
|
51
|
+
*.swp
|
|
52
|
+
.idea/
|
|
53
|
+
.vscode/
|