release: v0.2.0 — local stdio package, safe full-API coverage & resource-type authz #63

Merged
Latte merged 25 commits from dev into main 2026-06-27 13:43:56 +00:00
2 changed files with 19 additions and 16 deletions
Showing only changes of commit da66200be7 - Show all commits
+13 -11
View File
@@ -2,8 +2,9 @@ name: publish
# Build the Python package with uv and publish it to the self-hosted Gitea PyPI # Build the Python package with uv and publish it to the self-hosted Gitea PyPI
# registry on a version tag. Gated on lint + tests so a release can never ship # registry on a version tag. Gated on lint + tests so a release can never ship
# red. Publishing uses least-privilege Gitea Actions secrets; if they are absent # red. Publishing reuses the existing REGISTRY_TOKEN package secret (the same one
# the job fails loudly instead of publishing anonymously. # docker.yml uses to push images); if it is absent the job fails loudly instead
# of publishing anonymously.
on: on:
push: push:
tags: tags:
@@ -73,12 +74,11 @@ jobs:
- name: Require publish credentials - name: Require publish credentials
shell: bash shell: bash
env: env:
GITEA_PACKAGE_USER: ${{ secrets.GITEA_PACKAGE_USER }} REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }}
GITEA_PACKAGE_TOKEN: ${{ secrets.GITEA_PACKAGE_TOKEN }}
run: | run: |
if [ -z "${GITEA_PACKAGE_USER}" ] || [ -z "${GITEA_PACKAGE_TOKEN}" ]; then if [ -z "${REGISTRY_TOKEN}" ]; then
echo "::error::GITEA_PACKAGE_USER / GITEA_PACKAGE_TOKEN secrets are not set." >&2 echo "::error::REGISTRY_TOKEN secret is not set." >&2
echo "Configure a least-privilege PAT with write:package as Actions secrets." >&2 echo "Configure a PAT with write:package as the REGISTRY_TOKEN Actions secret." >&2
exit 1 exit 1
fi fi
@@ -95,13 +95,15 @@ jobs:
- name: Publish to Gitea PyPI registry - name: Publish to Gitea PyPI registry
shell: bash shell: bash
env: env:
GITEA_PACKAGE_USER: ${{ secrets.GITEA_PACKAGE_USER }} # Reuse the existing package secret (same one docker.yml uses). The
GITEA_PACKAGE_TOKEN: ${{ secrets.GITEA_PACKAGE_TOKEN }} # token authenticates as its owning Gitea user, so GITHUB_ACTOR is the
# username and the token is the password.
REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }}
run: | run: |
uv publish \ uv publish \
--publish-url https://git.hiddenden.cafe/api/packages/Hiddenden/pypi \ --publish-url https://git.hiddenden.cafe/api/packages/Hiddenden/pypi \
--username "${GITEA_PACKAGE_USER}" \ --username "${GITHUB_ACTOR}" \
--password "${GITEA_PACKAGE_TOKEN}" --password "${REGISTRY_TOKEN}"
# Optional second step to also publish to public PyPI lives behind its own # Optional second step to also publish to public PyPI lives behind its own
# secret. Intentionally left as a disabled stub — this pass does NOT push # secret. Intentionally left as a disabled stub — this pass does NOT push
+6 -5
View File
@@ -66,15 +66,16 @@ first, builds with `uv`, and publishes to the Gitea PyPI registry.
### Required CI secrets ### Required CI secrets
The publish job uses Gitea Actions secretsnever hardcode credentials: The publish job reuses the **existing** `REGISTRY_TOKEN` Actions secret — the same
PAT (`write:package`) that `docker.yml` uses to push images — so no new secret is
needed. The token authenticates as its owning Gitea user, so `GITHUB_ACTOR` is the
username and the token is the password.
| Secret | Purpose | | Secret | Purpose |
|--------|---------| |--------|---------|
| `GITEA_PACKAGE_USER` | Gitea username that owns the package | | `REGISTRY_TOKEN` | PAT with `write:package`; used for both image and package pushes |
| `GITEA_PACKAGE_TOKEN` | least-privilege PAT with `write:package` |
If either secret is absent the job fails loudly rather than publishing If the secret is absent the job fails loudly rather than publishing anonymously.
anonymously.
> Publishing to public PyPI is intentionally **not** configured. A second, > Publishing to public PyPI is intentionally **not** configured. A second,
> separately-gated `uv publish` step would be required and is left as a > separately-gated `uv publish` step would be required and is left as a