diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 80ac36b..b907c6b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,8 +16,8 @@ jobs: python: ["3.11", "3.12", "3.13"] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 + - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 with: python-version: ${{ matrix.python }} - run: python -m pip install -e ".[dev]" @@ -28,3 +28,5 @@ jobs: - run: python -m pip install --force-reinstall --no-deps dist/*.whl shell: bash - run: codex-profile-sync --version + - run: test "$(codex-profile-sync --version)" = "0.1.1" + shell: bash diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..8c3ea2f --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,67 @@ +name: Publish distributions + +on: + workflow_dispatch: + release: + types: [published] + +permissions: + contents: read + +jobs: + build: + name: Build and inspect distributions + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 + - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 + with: + python-version: "3.13" + - name: Install build tools + run: python -m pip install --disable-pip-version-check "build==1.3.0" "twine==6.2.0" + - name: Build wheel and source distribution + run: python -m build + - name: Check package metadata + run: python -m twine check --strict dist/* + - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + with: + name: python-package-distributions + path: dist/ + + publish-testpypi: + name: Publish to TestPyPI + if: github.event_name == 'workflow_dispatch' + needs: build + runs-on: ubuntu-latest + environment: + name: testpypi + url: https://test.pypi.org/p/codex-profile-sync + permissions: + id-token: write + steps: + - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 + with: + name: python-package-distributions + path: dist/ + - name: Publish distributions to TestPyPI + uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2 + with: + repository-url: https://test.pypi.org/legacy/ + + publish-pypi: + name: Publish to PyPI + if: github.event_name == 'release' && github.event.action == 'published' + needs: build + runs-on: ubuntu-latest + environment: + name: pypi + url: https://pypi.org/p/codex-profile-sync + permissions: + id-token: write + steps: + - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 + with: + name: python-package-distributions + path: dist/ + - name: Publish distributions to PyPI + uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2 diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..28a1619 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,24 @@ +# Changelog + +All notable public releases are documented here. + +## Unreleased + +No changes yet. + +## 0.1.1 - 2026-08-07 + +### Changed + +- Prepared package metadata and first-class `pipx`/`uv` installation from PyPI. +- Added project, issue, documentation, and homepage links plus the public author + identity. +- Pinned all GitHub Actions to immutable commits and added OIDC-only Trusted + Publishing workflows for separately gated TestPyPI and PyPI environments. + +### Validation + +- Added an automated consistency check for package, source, and bilingual + README versions. + +No CLI command, exit code, source-bundle schema, or protected path changed. diff --git a/README.md b/README.md index 14d386e..b8d0c36 100644 --- a/README.md +++ b/README.md @@ -32,10 +32,12 @@ and [user skills](https://learn.chatgpt.com/docs/customization/skills). Python 3.11 or newer is required. ```shell -pipx install . +pipx install codex-profile-sync +# or +uv tool install codex-profile-sync ``` -For development: +For development from a source checkout: ```shell python -m pip install -e '.[dev]' @@ -147,5 +149,5 @@ real Codex configuration. ## Status -Version `0.1.0` is an alpha release. The source-bundle schema is versioned, but +Version `0.1.1` is an alpha release. The source-bundle schema is versioned, but the CLI may gain additional safe, backwards-compatible checks before `1.0`. diff --git a/README.zh-CN.md b/README.zh-CN.md index 1f4cd24..cbb51c0 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -30,10 +30,12 @@ memories、插件缓存或任何其他 Codex 运行时状态。完整边界请 需要 Python 3.11 或更高版本。 ```shell -pipx install . +pipx install codex-profile-sync +# 或 +uv tool install codex-profile-sync ``` -开发环境安装: +从源码 checkout 安装开发环境: ```shell python -m pip install -e '.[dev]' @@ -138,5 +140,5 @@ python scripts/audit_public_tree.py . ## 当前状态 -`0.1.0` 是 alpha 版本。Source-bundle schema 已进行版本化,但在 `1.0` 之前,CLI +`0.1.1` 是 alpha 版本。Source-bundle schema 已进行版本化,但在 `1.0` 之前,CLI 仍可能增加安全且向后兼容的检查。 diff --git a/pyproject.toml b/pyproject.toml index 988396a..b1b17c8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,12 +4,12 @@ build-backend = "hatchling.build" [project] name = "codex-profile-sync" -version = "0.1.0" +version = "0.1.1" description = "Safely apply a private, portable Codex profile across operating systems." readme = "README.md" requires-python = ">=3.11" license = { file = "LICENSE" } -authors = [{ name = "codex-profile-sync contributors" }] +authors = [{ name = "Gerui Lv" }] keywords = ["codex", "configuration", "sync", "skills"] classifiers = [ "Development Status :: 3 - Alpha", @@ -28,6 +28,12 @@ dependencies = [ "tomlkit>=0.11,<1", ] +[project.urls] +Homepage = "https://greenlv.github.io/blogs/one-codex-setup-safely-reused-across-computers/" +Repository = "https://github.com/GreenLv/codex-profile-sync" +Issues = "https://github.com/GreenLv/codex-profile-sync/issues" +Documentation = "https://github.com/GreenLv/codex-profile-sync#readme" + [project.optional-dependencies] dev = [ "build>=1.2", diff --git a/src/codex_profile_sync/__init__.py b/src/codex_profile_sync/__init__.py index 9d7afb9..f44752c 100644 --- a/src/codex_profile_sync/__init__.py +++ b/src/codex_profile_sync/__init__.py @@ -1,3 +1,3 @@ """Public package metadata for codex-profile-sync.""" -__version__ = "0.1.0" +__version__ = "0.1.1" diff --git a/tests/test_version.py b/tests/test_version.py new file mode 100644 index 0000000..9236cee --- /dev/null +++ b/tests/test_version.py @@ -0,0 +1,17 @@ +from __future__ import annotations + +import tomllib +from pathlib import Path + +from codex_profile_sync import __version__ + +ROOT = Path(__file__).resolve().parents[1] + + +def test_version_is_consistent_across_package_metadata_and_readmes(): + project = tomllib.loads((ROOT / "pyproject.toml").read_text(encoding="utf-8")) + assert project["project"]["version"] == __version__ + for filename in ("README.md", "README.zh-CN.md"): + readme = (ROOT / filename).read_text(encoding="utf-8") + assert f"`{__version__}`" in readme + assert "`0.1.0`" not in readme