Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 16 additions & 55 deletions .github/workflows/publish-to-pypi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,10 @@ name: Publish to PyPI
on:
release:
types: [published]
workflow_dispatch:
inputs:
version:
description: "Version to build (e.g., 0.2.1)"
required: true
type: string
publish_to_pypi:
description: "Actually publish to PyPI?"
required: true
default: false
type: boolean

# Least privilege by default: jobs get no GITHUB_TOKEN scopes unless they
# opt in below.
permissions: {}

jobs:
build:
Expand All @@ -24,48 +17,23 @@ jobs:

steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Extract version
id: get_version
run: |
if [ "${{ github.event_name }}" = "release" ]; then
# Strip 'v' prefix from tag (v0.2.1 -> 0.2.1)
VERSION=${GITHUB_REF_NAME#v}
else
# Use manual input
VERSION="${{ github.event.inputs.version }}"
fi
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
echo "Extracted version: $VERSION"

- name: Update version in pyproject.toml
run: |
sed -i "s/^version = .*/version = \"${{ steps.get_version.outputs.VERSION }}\"/" pyproject.toml
echo "Updated pyproject.toml:"
grep "^version" pyproject.toml

- name: Commit version update to repo
if: github.event_name == 'release'
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add pyproject.toml
git commit -m "Bump version to ${{ steps.get_version.outputs.VERSION }}"
git push origin HEAD:main
# hatch-vcs derives the version from git tags, so we need full history.
fetch-depth: 0

- name: Install uv
# uv provisions its own Python (honoring requires-python), so no
# separate actions/setup-python step is needed.
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
echo "$HOME/.local/bin" >> $GITHUB_PATH

- name: Build package
# hatch-vcs reads the version straight from the release tag.
run: |
uv build
echo "Built distributions:"
ls -l dist/

- name: Store the distribution packages
uses: actions/upload-artifact@v4
Expand All @@ -74,7 +42,6 @@ jobs:
path: dist/

- name: Upload assets to GitHub Release
if: github.event_name == 'release'
env:
GH_TOKEN: ${{ github.token }}
run: |
Expand All @@ -83,11 +50,14 @@ jobs:
publish-to-pypi:
name: Publish to PyPI
needs: build
if: github.event_name == 'release' || github.event.inputs.publish_to_pypi == 'true'
runs-on: ubuntu-latest
environment:
name: pypi
url: https://pypi.org/p/codeplain
permissions:
# Mint a short-lived OIDC token so PyPI Trusted Publishing can
# authenticate this run — no long-lived API token needed.
id-token: write

steps:
- name: Download distribution packages
Expand All @@ -96,14 +66,5 @@ jobs:
name: python-package-distributions
path: dist/

- name: Install uv
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
echo "$HOME/.local/bin" >> $GITHUB_PATH

- name: Publish to PyPI
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
run: |
uv tool run twine upload dist/*
uses: pypa/gh-action-pypi-publish@release/v1
1 change: 0 additions & 1 deletion _version.py

This file was deleted.

7 changes: 5 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[build-system]
requires = ["hatchling"]
requires = ["hatchling", "hatch-vcs"]
build-backend = "hatchling.build"

[project]
Expand Down Expand Up @@ -41,8 +41,11 @@ dev = [
[project.scripts]
codeplain = "plain2code:main"

# Derive the version from the git tag (e.g. v0.3.8 -> 0.3.8). The version is
# baked into the package metadata at build time; system_config.py reads it back
# from that metadata (with a git-tag fallback for uninstalled source checkouts).
[tool.hatch.version]
path = "_version.py"
source = "vcs"

[tool.hatch.build.targets.wheel]
include = [
Expand Down
36 changes: 35 additions & 1 deletion system_config.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,46 @@
import importlib.resources
import os
import sys

import yaml

from _version import __version__
from plain2code_console import console


def _resolve_version() -> str:
"""Resolve the client version.

For an installed package the version is read from its metadata (hatch-vcs
bakes it in from the git tag at build time). When running from a source
checkout that hasn't been installed, fall back to the nearest git tag.
"""
from importlib.metadata import PackageNotFoundError, version

try:
return version("codeplain")
except PackageNotFoundError:
pass

try:
import git

# Anchor to this source file's own location so we inspect the
# codeplain checkout's repo, not the caller's working directory
# (codeplain may be run from anywhere).
source_dir = os.path.dirname(os.path.abspath(__file__))
repo = git.Repo(source_dir, search_parent_directories=True)

# Highest version tag, regardless of branch ancestry (a dev run may sit
# on a feature branch that doesn't descend from the latest release tag).
latest_tag = repo.git.tag("--list", "--sort=-v:refname").splitlines()[0]
return latest_tag.lstrip("v")
except Exception:
return "0.0.0.dev0"


__version__ = _resolve_version()


class SystemConfig:
"""Manages system-level configuration including requirements and error messages."""

Expand Down
Loading