Metadata-Version: 2.5
Name: conduit-repo-client
Version: 0.1.0
Summary: Shared client for committing files to a project's GitHub or Azure DevOps repository (incl. ADO wiki backing repos)
Requires-Python: >=3.11
Requires-Dist: httpx>=0.25
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == 'dev'
Description-Content-Type: text/markdown

# conduit-repo-client

Shared client for committing files to a Conduit project's configured repository —
GitHub (Contents API) or Azure DevOps (Git Items + Pushes API). No clone, no
local git. Extracted from Conduit Scripter's plan 069 P2 repo-sync
implementation as plan 031 v2's shared package.

## Install

```
pip install conduit-repo-client
```

## Usage

```python
import conduit_repo_client as repo_client

creds = admin_client.get_project_credentials(project_id)  # Admin repo_* fields

# Code repo target (e.g. Scripter deployed procedures)
settings = repo_client.repo_settings(creds)
if settings:
    result = repo_client.commit_file(
        settings, "usp_Transform_CustTable.sql", script_sql,
        message="Deploy usp_Transform_CustTable",
        author_name=user.name, author_email=user.email,
        committer_name="Conduit Scripter", committer_email="scripter@conduitai.net",
    )
    # result: {"status": "committed" | "unchanged", "commit_sha", "file_url"}

# Wiki target (plan 031 v2 — e.g. Profiler publishing generated documents)
wiki = repo_client.repo_settings(creds, target="wiki")
if wiki:
    repo_client.commit_file(
        wiki, "Data-Migration/Profiler/Quality-Standards/CustTable.md", markdown,
        message="Publish Data Quality Standards — CustTable",
        author_name=user.name, author_email=user.email,
    )
```

Key behaviours:

- `repo_settings` returns `None` when the project has no usable configuration
  for the target — callers skip publishing/committing silently.
- **Idempotent:** unchanged content is a no-op (`status: "unchanged"`), decided
  by git blob-sha comparison before any write — identical semantics on both
  providers.
- The caller's primary action stands if the commit fails (`RepoCommitError`) —
  never roll back a deploy/publish because the repository was unreachable.
- Path defaults: the **repo** target defaults to the repository root (Scripter
  supplies its own `procedures/` default); the **wiki** target always uses the
  root — consumers pass full page paths.
- **Wiki resolution:** explicit `wiki_url` wins; otherwise, for ADO code repos,
  the project wiki's backing git repo is inferred
  (`…/{project}/_git/{project}.wiki`, default branch `wikiMaster`). GitHub
  wikis are NOT reachable via the Contents API — GitHub projects must point
  `wiki_url` at an ordinary docs repo instead. The same Code (Read & Write)
  PAT authenticates both targets.

## Data-boundary rule (plan 031 v2)

This package is a dumb push client — what is pushable is each consumer's
policy decision. Documents containing customer row-level values (e.g. Validator
reconciliation/evidence output) must **never** be published through it.

## Development

```
pip install -e .[dev]
pytest
```
