generated from coulomb/repo-seed
pypi publication complicatoins
This commit is contained in:
37
.gitea/workflows/publish-python-package.yml
Normal file
37
.gitea/workflows/publish-python-package.yml
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
name: Publish Python package
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- "v*"
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
publish:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Check out source
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: "3.12"
|
||||||
|
|
||||||
|
- name: Install packaging tools
|
||||||
|
run: python -m pip install --upgrade build twine
|
||||||
|
|
||||||
|
- name: Build distributions
|
||||||
|
run: python -m build
|
||||||
|
|
||||||
|
- name: Validate distributions
|
||||||
|
run: python -m twine check dist/*
|
||||||
|
|
||||||
|
- name: Upload to Gitea PyPI
|
||||||
|
env:
|
||||||
|
TWINE_USERNAME: ${{ secrets.GITEA_PACKAGE_USER }}
|
||||||
|
TWINE_PASSWORD: ${{ secrets.GITEA_PACKAGE_TOKEN }}
|
||||||
|
run: >-
|
||||||
|
python -m twine upload
|
||||||
|
--repository-url https://gitea.coulomb.social/api/packages/coulomb/pypi
|
||||||
|
dist/*
|
||||||
31
Makefile
31
Makefile
@@ -37,6 +37,9 @@ help: ## Show issue core capability help
|
|||||||
@echo " test-integration Run integration tests only"
|
@echo " test-integration Run integration tests only"
|
||||||
@echo " test-cov Run tests with coverage report"
|
@echo " test-cov Run tests with coverage report"
|
||||||
@echo " test-verbose Run tests with verbose output"
|
@echo " test-verbose Run tests with verbose output"
|
||||||
|
@echo " package Build source and wheel distributions"
|
||||||
|
@echo " package-check Build and validate distributions"
|
||||||
|
@echo " publish-gitea Publish distributions to Gitea PyPI"
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo "Feedback & Continuous Improvement:"
|
@echo "Feedback & Continuous Improvement:"
|
||||||
@echo " feedback MSG=\"...\" Submit feedback about issue-core"
|
@echo " feedback MSG=\"...\" Submit feedback about issue-core"
|
||||||
@@ -60,6 +63,10 @@ help: ## Show issue core capability help
|
|||||||
# Check if issue command is available
|
# Check if issue command is available
|
||||||
ISSUE_CLI := $(shell command -v issue 2> /dev/null)
|
ISSUE_CLI := $(shell command -v issue 2> /dev/null)
|
||||||
|
|
||||||
|
PYTHON ?= python3
|
||||||
|
GITEA_PACKAGE_OWNER ?= coulomb
|
||||||
|
GITEA_PYPI_REPOSITORY_URL ?= https://gitea.coulomb.social/api/packages/$(GITEA_PACKAGE_OWNER)/pypi
|
||||||
|
|
||||||
# Core Issue Operations
|
# Core Issue Operations
|
||||||
.PHONY: issue-list
|
.PHONY: issue-list
|
||||||
issue-list: ## List all issues from configured backend
|
issue-list: ## List all issues from configured backend
|
||||||
@@ -209,6 +216,28 @@ test-cov: ## Run tests with coverage report (local development)
|
|||||||
test-verbose: ## Run tests with verbose output (local development)
|
test-verbose: ## Run tests with verbose output (local development)
|
||||||
pytest tests/ -v
|
pytest tests/ -v
|
||||||
|
|
||||||
|
.PHONY: clean-dist
|
||||||
|
clean-dist: ## Remove local Python package build artifacts
|
||||||
|
rm -rf build/ dist/ *.egg-info/
|
||||||
|
|
||||||
|
.PHONY: package
|
||||||
|
package: clean-dist ## Build source and wheel distributions
|
||||||
|
$(PYTHON) -m build
|
||||||
|
|
||||||
|
.PHONY: package-check
|
||||||
|
package-check: package ## Build and validate source/wheel distributions
|
||||||
|
$(PYTHON) -m twine check dist/*
|
||||||
|
|
||||||
|
.PHONY: publish-gitea
|
||||||
|
publish-gitea: package-check ## Publish distributions to the Coulomb Gitea PyPI registry
|
||||||
|
ifndef TWINE_USERNAME
|
||||||
|
$(error TWINE_USERNAME is required)
|
||||||
|
endif
|
||||||
|
ifndef TWINE_PASSWORD
|
||||||
|
$(error TWINE_PASSWORD is required)
|
||||||
|
endif
|
||||||
|
$(PYTHON) -m twine upload --repository-url "$(GITEA_PYPI_REPOSITORY_URL)" dist/*
|
||||||
|
|
||||||
# Feedback and Continuous Improvement
|
# Feedback and Continuous Improvement
|
||||||
.PHONY: feedback
|
.PHONY: feedback
|
||||||
feedback: ## Submit feedback (Usage: make feedback MSG="your feedback")
|
feedback: ## Submit feedback (Usage: make feedback MSG="your feedback")
|
||||||
@@ -358,4 +387,4 @@ capability-info: ## Show capability information
|
|||||||
@echo "Supported backends: Local SQLite, GitHub, GitLab, Gitea"
|
@echo "Supported backends: Local SQLite, GitHub, GitLab, Gitea"
|
||||||
@echo "Key features: Repository-aware, offline-capable, unified interface"
|
@echo "Key features: Repository-aware, offline-capable, unified interface"
|
||||||
@echo "Targets:"
|
@echo "Targets:"
|
||||||
@$(MAKE) --no-print-directory help | grep "^ " | sed 's/^ / /'
|
@$(MAKE) --no-print-directory help | grep "^ " | sed 's/^ / /'
|
||||||
|
|||||||
51
docs/package-release.md
Normal file
51
docs/package-release.md
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
# Python Package Release
|
||||||
|
|
||||||
|
`issue-core` publishes as the `issue-core` Python package. The Railiance
|
||||||
|
application deployment path expects the `0.2.x` series to be available from the
|
||||||
|
Coulomb Gitea PyPI registry.
|
||||||
|
|
||||||
|
## Local Release
|
||||||
|
|
||||||
|
Build and validate the release artifacts:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make package-check
|
||||||
|
```
|
||||||
|
|
||||||
|
Publish to the Coulomb organization registry:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
TWINE_USERNAME=<gitea-user> \
|
||||||
|
TWINE_PASSWORD=<package-token> \
|
||||||
|
make publish-gitea
|
||||||
|
```
|
||||||
|
|
||||||
|
The package endpoint is:
|
||||||
|
|
||||||
|
```text
|
||||||
|
https://gitea.coulomb.social/api/packages/coulomb/pypi
|
||||||
|
```
|
||||||
|
|
||||||
|
The matching simple index for consumers is:
|
||||||
|
|
||||||
|
```text
|
||||||
|
https://gitea.coulomb.social/api/packages/coulomb/pypi/simple/
|
||||||
|
```
|
||||||
|
|
||||||
|
Do not commit tokenized package index URLs. CI and local Docker builds should
|
||||||
|
inject registry credentials through environment variables or BuildKit secrets.
|
||||||
|
|
||||||
|
## Gitea Actions Release
|
||||||
|
|
||||||
|
The `.gitea/workflows/publish-python-package.yml` workflow publishes on tags
|
||||||
|
matching `v*`. Configure these repository secrets before cutting a release:
|
||||||
|
|
||||||
|
- `GITEA_PACKAGE_USER`
|
||||||
|
- `GITEA_PACKAGE_TOKEN`
|
||||||
|
|
||||||
|
Release `0.2.0` with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git tag v0.2.0
|
||||||
|
git push origin v0.2.0
|
||||||
|
```
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
[build-system]
|
[build-system]
|
||||||
requires = ["setuptools>=45", "wheel", "setuptools-scm[toml]>=6.2"]
|
requires = ["setuptools>=61,<77", "wheel"]
|
||||||
build-backend = "setuptools.build_meta"
|
build-backend = "setuptools.build_meta"
|
||||||
|
|
||||||
[project]
|
[project]
|
||||||
@@ -37,9 +37,11 @@ dynamic = ["version"]
|
|||||||
|
|
||||||
[project.optional-dependencies]
|
[project.optional-dependencies]
|
||||||
dev = [
|
dev = [
|
||||||
|
"build>=1.3",
|
||||||
"pytest>=6.0",
|
"pytest>=6.0",
|
||||||
"pytest-cov>=2.0",
|
"pytest-cov>=2.0",
|
||||||
"pytest-mock>=3.0",
|
"pytest-mock>=3.0",
|
||||||
|
"twine>=6.0",
|
||||||
"black>=22.0",
|
"black>=22.0",
|
||||||
"isort>=5.0",
|
"isort>=5.0",
|
||||||
"flake8>=4.0",
|
"flake8>=4.0",
|
||||||
@@ -48,7 +50,7 @@ dev = [
|
|||||||
"httpx>=0.27",
|
"httpx>=0.27",
|
||||||
"fastapi>=0.110,<1.0",
|
"fastapi>=0.110,<1.0",
|
||||||
"pydantic>=2.0,<3.0",
|
"pydantic>=2.0,<3.0",
|
||||||
]
|
]
|
||||||
docs = [
|
docs = [
|
||||||
"sphinx>=4.0",
|
"sphinx>=4.0",
|
||||||
"sphinx-rtd-theme>=1.0",
|
"sphinx-rtd-theme>=1.0",
|
||||||
@@ -170,4 +172,4 @@ exclude_lines = [
|
|||||||
"if __name__ == .__main__.:",
|
"if __name__ == .__main__.:",
|
||||||
"class .*\\bProtocol\\):",
|
"class .*\\bProtocol\\):",
|
||||||
"@(abc\\.)?abstractmethod",
|
"@(abc\\.)?abstractmethod",
|
||||||
]
|
]
|
||||||
|
|||||||
83
workplans/ISSUE-WP-0002-gitea-pypi-publication.md
Normal file
83
workplans/ISSUE-WP-0002-gitea-pypi-publication.md
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
---
|
||||||
|
id: ISSUE-WP-0002
|
||||||
|
type: workplan
|
||||||
|
title: "Publish issue-core to Gitea PyPI"
|
||||||
|
domain: custodian
|
||||||
|
repo: issue-core
|
||||||
|
status: blocked
|
||||||
|
owner: codex
|
||||||
|
topic_slug: custodian
|
||||||
|
created: "2026-05-23"
|
||||||
|
updated: "2026-05-23"
|
||||||
|
state_hub_workstream_id: "87a5dcb6-5b2c-4d3f-8d5c-e265889b0fc6"
|
||||||
|
---
|
||||||
|
|
||||||
|
# Publish issue-core to Gitea PyPI
|
||||||
|
|
||||||
|
`issue-core` needs a first real Python package release in the Coulomb Gitea
|
||||||
|
package registry so downstream applications can depend on a versioned package
|
||||||
|
instead of a sibling checkout path.
|
||||||
|
|
||||||
|
## Publish and verify the Gitea PyPI package
|
||||||
|
|
||||||
|
```task
|
||||||
|
id: ISSUE-WP-0002-T01
|
||||||
|
status: blocked
|
||||||
|
priority: high
|
||||||
|
state_hub_task_id: "f0df7dbc-b55d-4835-a528-f44a329efb0e"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Problem.** `vergabe-teilnahme` and future Railiance S5 apps need
|
||||||
|
`issue-core` as a normal package dependency. A local dependency such as
|
||||||
|
`issue-core @ file:///home/worsch/issue-core` makes Docker builds depend on a
|
||||||
|
specific operator workstation and forces non-portable BuildKit named contexts.
|
||||||
|
|
||||||
|
**Current state.** The repo has package release plumbing prepared:
|
||||||
|
|
||||||
|
- `make package-check` builds and validates `issue-core==0.2.0`.
|
||||||
|
- `make publish-gitea` uploads `dist/*` to the Coulomb Gitea PyPI endpoint.
|
||||||
|
- `.gitea/workflows/publish-python-package.yml` can publish on `v*` tags once
|
||||||
|
package registry secrets exist.
|
||||||
|
- `docs/package-release.md` documents local and tag-based publishing.
|
||||||
|
|
||||||
|
**Blocker.** Publishing requires a Gitea package username/token with permission
|
||||||
|
to upload to:
|
||||||
|
|
||||||
|
```text
|
||||||
|
https://gitea.coulomb.social/api/packages/coulomb/pypi
|
||||||
|
```
|
||||||
|
|
||||||
|
No publish credentials are currently available in the shell or standard package
|
||||||
|
config files.
|
||||||
|
|
||||||
|
**Implementation steps.**
|
||||||
|
|
||||||
|
1. Configure Gitea repository or organization secrets:
|
||||||
|
`GITEA_PACKAGE_USER` and `GITEA_PACKAGE_TOKEN`.
|
||||||
|
2. Publish `issue-core==0.2.0` either by pushing tag `v0.2.0` or by running:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
TWINE_USERNAME=<gitea-user> \
|
||||||
|
TWINE_PASSWORD=<package-token> \
|
||||||
|
make publish-gitea
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Verify the simple index exposes the package:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -fsS https://gitea.coulomb.social/api/packages/coulomb/pypi/simple/issue-core/
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Verify a clean environment can install the package from the Gitea simple
|
||||||
|
index with credentials injected outside Git.
|
||||||
|
5. Coordinate with `vergabe-teilnahme` to regenerate its `uv.lock` from the
|
||||||
|
published package and confirm its Docker build no longer needs the sibling
|
||||||
|
`issue-core` checkout.
|
||||||
|
|
||||||
|
**Done when.**
|
||||||
|
|
||||||
|
- `issue-core==0.2.0` is visible in the Coulomb Gitea PyPI simple index.
|
||||||
|
- A clean Python environment can install `issue-core>=0.2,<0.3` from Gitea.
|
||||||
|
- The publish workflow has the required secrets and a documented release path.
|
||||||
|
- The Railiance app deployment blocker can be closed without relying on local
|
||||||
|
path dependencies.
|
||||||
Reference in New Issue
Block a user