Metadata-Version: 2.4
Name: tg-engine
Version: 1.0.1
Summary: TigerGate scan engine — static analysis for many languages, packaged for the TigerGate platform.
Author-email: TigerGate <support@tigergate.dev>
License-Expression: LGPL-2.1-or-later
Project-URL: Homepage, https://tigergate.dev
Classifier: Environment :: Console
Classifier: Operating System :: MacOS
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Security
Classifier: Topic :: Software Development :: Quality Assurance
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: attrs>=21.3
Requires-Dist: boltons~=21.0
Requires-Dist: click-option-group~=0.5
Requires-Dist: click~=8.1.8
Requires-Dist: colorama~=0.4.0
Requires-Dist: exceptiongroup~=1.2.0
Requires-Dist: glom>=23.3
Requires-Dist: jsonschema~=4.25.1
Requires-Dist: mcp==1.23.3
Requires-Dist: opentelemetry-api~=1.37.0
Requires-Dist: opentelemetry-sdk~=1.37.0
Requires-Dist: opentelemetry-exporter-otlp-proto-http~=1.37.0
Requires-Dist: opentelemetry-instrumentation-requests~=0.58b0
Requires-Dist: opentelemetry-instrumentation-threading~=0.58b0
Requires-Dist: packaging>=21.0
Requires-Dist: peewee~=3.14
Requires-Dist: pyjwt[crypto]~=2.12.0
Requires-Dist: requests~=2.22
Requires-Dist: rich>=13.5.2
Requires-Dist: ruamel.yaml>=0.18.15
Requires-Dist: ruamel.yaml.clib==0.2.14
Requires-Dist: semantic-version~=2.10.0
Requires-Dist: tomli~=2.0.1
Requires-Dist: typing-extensions~=4.2
Requires-Dist: urllib3~=2.0
Requires-Dist: wcmatch~=8.3
Requires-Dist: pywin32==311; sys_platform == "win32"
Dynamic: description
Dynamic: description-content-type
Dynamic: license-file

# tg-engine

TigerGate scan engine — fast static analysis for many languages, packaged for the TigerGate platform.

The engine is fully self-contained: no outbound telemetry, no version-check pings, no third-party metrics. All scanning happens locally on the machine that runs `tg-engine`.

| | |
|---|---|
| Version | `1.0.0` |
| Distribution name (PyPI) | `tg-engine` |
| Console script | `tg-engine` |
| Telemetry | disabled — no outbound network calls from the engine |
| License | LGPL-2.1-or-later — see [LICENSE](LICENSE) |

---

## Install

```bash
pip install tg-engine
tg-engine --version
```

That single `pip install` brings down the Python CLI plus the native scanner binary for your platform (Linux x64, Linux arm64, macOS arm64, Windows x64). No extra setup, no `apt`/`brew` packages, no environment variables.

---

## Build from source

A self-contained release wheel for your current platform is produced by:

```bash
./scripts/build-wheel.sh
```

Output: `cli/dist/tg_engine-<version>-<python-tags>-<platform>.whl` (~70 MB; includes the native scanner binary and its companion shared libraries).

See [scripts/build-wheel.sh](scripts/build-wheel.sh) for the exact mechanics.

### Smoke test the wheel

```bash
python3 -m venv /tmp/tg-smoke
source /tmp/tg-smoke/bin/activate
pip install cli/dist/tg_engine-*.whl

pip show tg-engine                                  # Name: tg-engine, Version: 1.0.0
which tg-engine                                     # /tmp/tg-smoke/bin/tg-engine
tg-engine --version
tg-engine scan --config p/python /path/to/some.py   # produces findings
```

---

## Release setup

The high-level shape:

```
For each target platform: build a per-platform wheel
   └── twine check
       └── twine upload --repository testpypi      ← rehearsal
           └── pip install from TestPyPI; verify
               └── twine upload                    ← real publish
                   └── git tag tg-engine-<ver>
```

### One-time setup

1. **PyPI accounts.** Create one at https://pypi.org and one at https://test.pypi.org. Enable 2FA on both.
2. **Local tooling** (only needed for laptop releases — CI does this automatically):
   ```bash
   pip install --upgrade build twine
   ```
3. **Credentials.** For laptop releases, put API tokens in `~/.pypirc` (chmod 0600):
   ```ini
   [distutils]
   index-servers =
       pypi
       testpypi

   [pypi]
   username = __token__
   password = pypi-<your-token>

   [testpypi]
   repository = https://test.pypi.org/legacy/
   username = __token__
   password = pypi-<your-testpypi-token>
   ```

### Per-release flow

1. **Bump version.** Updates both `pyproject.toml` and the package's `__VERSION__` in lockstep:
   ```bash
   ./scripts/bump-version.sh X.Y.Z
   ```
2. **Build per-platform wheels.** Locally you can only build for your current platform; the rest needs CI (see below).
   ```bash
   ./scripts/build-wheel.sh
   ```
3. **Verify.**
   ```bash
   twine check cli/dist/*
   ```
4. **TestPyPI rehearsal.**
   ```bash
   twine upload --repository testpypi cli/dist/*
   python3 -m venv /tmp/tg-release-test
   /tmp/tg-release-test/bin/pip install \
     --index-url https://test.pypi.org/simple/ \
     --extra-index-url https://pypi.org/simple/ \
     tg-engine
   /tmp/tg-release-test/bin/tg-engine --version
   ```
5. **Real publish.**
   ```bash
   twine upload cli/dist/*
   ```
6. **Tag the release.**
   ```bash
   git tag -a tg-engine-X.Y.Z -m "tg-engine X.Y.Z"
   git push origin main --tags
   ```

### CI release via GitHub Actions

The full multi-arch build + publish flow lives in [.github/workflows/release.yml](.github/workflows/release.yml). It builds four wheels in parallel (Linux x64, Linux arm64, macOS arm64, Windows x64), then publishes them in a single approved-gated job.

**Trigger map:**

| Tag pushed | Build | Publish | GitHub release |
|---|---|---|---|
| `tg-engine-1.0.0` | all 4 archs | **PyPI** | yes |
| `tg-engine-1.0.0-rc.1` (also `-alpha`, `-beta`) | all 4 archs | **TestPyPI** | yes (prerelease) |
| `tg-engine-1.0.0-dev` | all 4 archs | none (artifacts only) | yes (prerelease) |
| manual `workflow_dispatch` | all 4 archs | chosen via input dropdown | no |

**Cutting a release:**

```bash
./scripts/bump-version.sh 1.0.1
git commit -am "Release 1.0.1"

git tag -a tg-engine-1.0.1 -m "tg-engine 1.0.1"
git push origin main --tags
# → CI builds all archs, waits at the `release` environment for approval,
#   then publishes to PyPI + cuts a GitHub release with the wheels attached.
```

### One-time CI setup (do this before the first release)

1. **PyPI OIDC trusted publisher.** No API token needed — PyPI verifies GitHub's OIDC claim directly. Go to https://pypi.org/manage/account/publishing/ → Add a new pending publisher:
   - PyPI Project Name: `tg-engine`
   - Owner: your GitHub org/user
   - Repository name: your repo name
   - Workflow filename: `release.yml`
   - Environment name: `release`

   For TestPyPI, repeat at https://test.pypi.org/manage/account/publishing/.

2. **GitHub Environment with required reviewer.** This is the approval gate before any upload happens. In repo Settings → Environments:
   - Click "New environment", name it `release`.
   - Under "Deployment protection rules", enable "Required reviewers" and add yourself (or the relevant team).
   - Save.

3. **Push a test tag** to verify the wiring:
   ```bash
   git tag -a tg-engine-1.0.0-dev -m "wiring test"
   git push origin tg-engine-1.0.0-dev
   ```
   This builds all 4 wheels and creates a GitHub prerelease without uploading anywhere. Check that all 4 wheels are attached to the release before doing a real publish.

### Publishing to a private index

Replace the `twine upload` call with the private index URL (or add to `~/.pypirc`):

```bash
twine upload --repository-url https://pypi.tigergate.dev/simple/ cli/dist/*
```

### Versioning policy

This project uses SemVer (`MAJOR.MINOR.PATCH`). Bump:

- **MAJOR** on any breaking change to the public CLI/LSP contract.
- **MINOR** on a new feature or scanner-version bump.
- **PATCH** on bug fixes and internal-only changes.

---

## License

LGPL-2.1-or-later. See [LICENSE](LICENSE) for the full license text and required attributions.
