Release version 0.2.0

This commit is contained in:
Kevin Veen-Birkenbach
2025-12-08 20:31:19 +01:00
parent cd62af41d1
commit 71823c2f48
7 changed files with 148 additions and 21 deletions

View File

@@ -1,3 +1,8 @@
## [0.2.0] - 2025-12-08
* Add preview-first release workflow and extended packaging support (see ChatGPT conversation: https://chatgpt.com/share/693722b4-af9c-800f-bccc-8a4036e99630)
## [0.1.0] - 2025-12-08
* Updated to correct version

View File

@@ -1,7 +1,7 @@
# Maintainer: Kevin Veen-Birkenbach <info@veen.world>
pkgname=package-manager
pkgver=0.1.0
pkgver=0.2.0
pkgrel=1
pkgdesc="Local-flake wrapper for Kevin's package-manager (Nix-based)."
arch=('any')

6
debian/changelog vendored
View File

@@ -1,3 +1,9 @@
package-manager (0.2.0-1) unstable; urgency=medium
* Add preview-first release workflow and extended packaging support (see ChatGPT conversation: https://chatgpt.com/share/693722b4-af9c-800f-bccc-8a4036e99630)
-- Kevin Veen-Birkenbach <kevin@veen.world> Mon, 08 Dec 2025 20:31:19 +0100
package-manager (0.1.0-1) unstable; urgency=medium
* Updated to correct version

View File

@@ -31,7 +31,7 @@
rec {
pkgmgr = pyPkgs.buildPythonApplication {
pname = "package-manager";
version = "0.1.0";
version = "0.2.0";
# Use the git repo as source
src = ./.;

View File

@@ -1,5 +1,5 @@
Name: package-manager
Version: 0.1.0
Version: 0.2.0
Release: 1%{?dist}
Summary: Wrapper that runs Kevin's package-manager via Nix flake

View File

@@ -18,6 +18,11 @@ Additional behaviour:
- If `preview=True` (from --preview), no files are written and no
Git commands are executed. Instead, a detailed summary of the
planned changes and commands is printed.
- If `preview=False` and not forced, the release is executed in two
phases:
1) Preview-only run (dry-run).
2) Interactive confirmation, then real release if confirmed.
This confirmation can be skipped with the `-f/--force` flag.
"""
from __future__ import annotations
@@ -598,11 +603,11 @@ def update_debian_changelog(
# ---------------------------------------------------------------------------
# Public release entry point
# Internal implementation (single-phase, preview or real)
# ---------------------------------------------------------------------------
def release(
def _release_impl(
pyproject_path: str = "pyproject.toml",
changelog_path: str = "CHANGELOG.md",
release_type: str = "patch",
@@ -610,22 +615,16 @@ def release(
preview: bool = False,
) -> None:
"""
Perform a release by:
Internal implementation that performs a single-phase release.
1. Determining the current version from Git tags.
2. Computing the next version (major/minor/patch).
3. Updating pyproject.toml with the new version.
4. Updating CHANGELOG.md with a new entry.
5. Updating additional packaging files where present:
- flake.nix
- PKGBUILD
- debian/changelog
- package-manager.spec
6. Staging all these files.
7. Committing, tagging, and pushing the changes.
If `preview` is True:
- No files are written.
- No git commands are executed.
- Planned actions are printed.
If `preview` is True, no files are written and no Git commands
are executed. Instead, the planned actions are printed.
If `preview` is False:
- Files are updated.
- Git commit, tag, and push are executed.
"""
# 1) Determine the current version from Git tags.
current_ver = _determine_current_version()
@@ -716,6 +715,109 @@ def release(
print(f"Release {new_ver_str} completed.")
# ---------------------------------------------------------------------------
# Public release entry point (with preview-first + confirmation logic)
# ---------------------------------------------------------------------------
def release(
pyproject_path: str = "pyproject.toml",
changelog_path: str = "CHANGELOG.md",
release_type: str = "patch",
message: Optional[str] = None,
preview: bool = False,
force: bool = False,
) -> None:
"""
High-level release entry point.
Modes:
- preview=True:
* Single-phase PREVIEW only.
* No files are changed, no git commands are executed.
* `force` is ignored in this mode.
- preview=False, force=True:
* Single-phase REAL release, no interactive preview.
* Files are changed and git commands are executed immediately.
- preview=False, force=False:
* Two-phase flow (intended default for interactive CLI use):
1) PREVIEW: dry-run, printing all planned actions.
2) Ask the user for confirmation:
"Proceed with the actual release? [y/N]: "
If confirmed, perform the REAL release.
Otherwise, abort without changes.
* In non-interactive environments (stdin not a TTY), the
confirmation step is skipped automatically and a single
REAL phase is executed, to avoid blocking on input().
"""
# Explicit preview mode: just do a single PREVIEW phase and exit.
if preview:
_release_impl(
pyproject_path=pyproject_path,
changelog_path=changelog_path,
release_type=release_type,
message=message,
preview=True,
)
return
# Non-preview, but forced: run REAL release directly.
if force:
_release_impl(
pyproject_path=pyproject_path,
changelog_path=changelog_path,
release_type=release_type,
message=message,
preview=False,
)
return
# Non-interactive environment? Skip confirmation to avoid blocking.
if not sys.stdin.isatty():
_release_impl(
pyproject_path=pyproject_path,
changelog_path=changelog_path,
release_type=release_type,
message=message,
preview=False,
)
return
# Interactive two-phase flow:
print("[INFO] Running preview before actual release...\n")
_release_impl(
pyproject_path=pyproject_path,
changelog_path=changelog_path,
release_type=release_type,
message=message,
preview=True,
)
# Ask for confirmation
try:
answer = input("Proceed with the actual release? [y/N]: ").strip().lower()
except (EOFError, KeyboardInterrupt):
print("\n[INFO] Release aborted (no confirmation).")
return
if answer not in ("y", "yes"):
print("Release aborted by user. No changes were made.")
return
print("\n[INFO] Running REAL release...\n")
_release_impl(
pyproject_path=pyproject_path,
changelog_path=changelog_path,
release_type=release_type,
message=message,
preview=False,
)
# ---------------------------------------------------------------------------
# CLI entry point for standalone use
# ---------------------------------------------------------------------------
@@ -750,7 +852,20 @@ def _parse_args(argv: Optional[list[str]] = None) -> argparse.Namespace:
parser.add_argument(
"--preview",
action="store_true",
help="Preview release changes without modifying files or running git.",
help=(
"Preview release changes without modifying files or running git. "
"This mode never executes the real release."
),
)
parser.add_argument(
"-f",
"--force",
dest="force",
action="store_true",
help=(
"Skip the interactive preview+confirmation step and run the "
"release directly."
),
)
return parser.parse_args(argv)
@@ -763,4 +878,5 @@ if __name__ == "__main__":
release_type=args.release_type,
message=args.message,
preview=args.preview,
force=args.force,
)

View File

@@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "package-manager"
version = "0.1.0"
version = "0.2.0"
description = "Kevin's package-manager tool (pkgmgr)"
readme = "README.md"
requires-python = ">=3.11"