You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We build with **uv**, test locally (wheel), then push to **TestPyPI** before PyPI.
464
-
The examples below use the Twine utility.
463
+
We build with **uv** and publish via a GitHub Actions release workflow. Releases are not created on every commit — a release is triggered explicitly by pushing a git tag.
465
464
466
465
### Versions
467
466
- The CLI reads its version from package metadata (`importlib.metadata`).
468
467
-**Bump only in `pyproject.toml`** (do not hardcode in code).
469
468
- You **cannot overwrite** an existing version on PyPI/TestPyPI — always increment.
470
469
471
-
### 1) Build artifacts
470
+
### Automated release workflow
471
+
472
+
The release workflow is defined in [`.github/workflows/release.yml`](../../.github/workflows/release.yml) and runs the following stages in order:
Each stage must succeed before the next starts. The `publish-pypi` job requires manual approval via the `pypi` GitHub Environment — this gives you time to verify the TestPyPI package before it goes to production.
479
+
480
+
#### One-time GitHub setup
481
+
482
+
> **VPN required** — you must be connected to the Teradata VPN to access the GitHub repository settings and to generate or retrieve API tokens from PyPI and TestPyPI.
483
+
484
+
**Secrets** — add these in *Settings → Secrets and variables → Actions*:
485
+
486
+
| Secret | Where to get it |
487
+
|---|---|
488
+
|`TEST_PYPI_TOKEN`|[test.pypi.org](https://test.pypi.org) → Account → API tokens |
489
+
|`PYPI_TOKEN`|[pypi.org](https://pypi.org) → Account → API tokens |
490
+
491
+
If you have previously published manually using Twine, your tokens are already stored locally in `~/.pypirc` — copy the `password` values from there rather than generating new ones.
492
+
493
+
**Environments** — create two environments in *Settings → Environments*:
494
+
-`test-pypi` — no protection rules required
495
+
-`pypi` — add yourself (or your team) as a **Required reviewer** to enable the approval gate
496
+
497
+
#### Triggering a release
498
+
499
+
Releases are grouped across multiple commits. When you are ready to ship:
500
+
501
+
```bash
502
+
# 1. Bump the version in pyproject.toml, commit, and push to main as normal
503
+
git add pyproject.toml
504
+
git commit -m "chore: bump version to 0.2.3"
505
+
git push
506
+
507
+
# 2. Tag the commit — pushing the tag fires the release workflow
508
+
git tag v0.2.3
509
+
git push origin v0.2.3
510
+
```
511
+
512
+
The tag must match the version in `pyproject.toml`. The workflow reads the version from `pyproject.toml` at build time and uses it throughout.
513
+
514
+
#### Approving a production release
515
+
516
+
After the TestPyPI publish and smoke test succeed, the workflow pauses before publishing to production PyPI and waits for a human to approve. Here is what happens:
517
+
518
+
1. GitHub sends you an **email notification** and a bell notification in the GitHub UI
519
+
2. Open the Actions run — you will see a yellow banner: *"This workflow is waiting for a review before continuing"*
520
+
3. Click **Review deployments**, tick the `pypi` environment checkbox, and click **Approve and deploy**
521
+
4. The `publish-pypi` job starts and the package is published to production PyPI
522
+
523
+
If something looks wrong (e.g., the TestPyPI smoke test installed the wrong version), click **Reject** instead — nothing is published to production and the run is cancelled. Fix the issue, bump the version, and start a new release.
524
+
525
+
> **Note:** Only the GitHub users configured as Required reviewers on the `pypi` environment can approve. The reviewer should confirm the TestPyPI smoke test passed before approving.
526
+
527
+
#### Re-running a failed publish
528
+
529
+
If a publish step fails (e.g., a transient network error), use the **Run workflow** button on the [Actions tab](https://github.com/Teradata/teradata-mcp-server/actions/workflows/release.yml) to re-trigger without creating a new tag.
530
+
531
+
#### What the workflow does
532
+
533
+
1.**Build & Verify** — runs `uv build --no-cache`, verifies metadata with `uvx twine check`, and smoke-tests the wheel locally
534
+
2.**Create GitHub Release** — creates a GitHub Release for the tag with auto-generated release notes and attaches the wheel and tarball as downloadable assets
535
+
3.**Publish to TestPyPI** — uploads with `uvx twine upload --repository testpypi`, then verifies installation with `uvx`
536
+
4.**Approval gate** — workflow pauses; reviewer approves in the GitHub UI after checking the TestPyPI package
537
+
5.**Publish to PyPI** — uploads with `uvx twine upload`, then runs a final smoke test from production PyPI
538
+
539
+
### Manual publish (fallback)
540
+
541
+
If you need to publish outside of CI, the steps below replicate what the workflow does.
542
+
543
+
#### 1) Build artifacts
472
544
```bash
473
545
uv build --no-cache
474
546
# Produces dist/teradata_mcp_server-<ver>-py3-none-any.whl and .tar.gz
475
547
```
476
548
477
-
### 2) Test the wheel locally (no install)
549
+
####2) Test the wheel locally (no install)
478
550
```bash
479
551
# Run the installed console entry point from the wheel
0 commit comments