fix: bootstrap apps without version config
This commit is contained in:
1 parent
0848079db3
commit
e42b7ea882
5 files changed
+63
-9
No files matched your search
@@ -58,9 +58,11 @@ jobs:
|
|||||||
|
|
||||||
- name: Prepare version
|
- name: Prepare version
|
||||||
id: version
|
id: version
|
||||||
uses: Nurinda/bump-erp-app-version@v1
|
# The absolute URL is required when Gitea's DEFAULT_ACTIONS_URL is "github".
|
||||||
|
uses: https://gitea.cptckp.com/Nurinda/bump-erp-app-version@v1
|
||||||
with:
|
with:
|
||||||
config-file: pyproject.toml
|
config-file: pyproject.toml
|
||||||
|
version-file: erp_operations/__init__.py
|
||||||
base-branch: main
|
base-branch: main
|
||||||
target-branch: develop
|
target-branch: develop
|
||||||
bump: patch
|
bump: patch
|
||||||
@@ -78,6 +80,7 @@ Gitea may suppress workflows caused by pushes authenticated with its built-in `G
|
|||||||
| Input | Default | Description |
|
| Input | Default | Description |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `config-file` | `pyproject.toml` | `bump-my-version` TOML configuration |
|
| `config-file` | `pyproject.toml` | `bump-my-version` TOML configuration |
|
||||||
|
| `version-file` | empty | App `__init__.py` used to bootstrap a base branch that predates the configuration |
|
||||||
| `base-branch` | `main` | Branch providing the baseline version |
|
| `base-branch` | `main` | Branch providing the baseline version |
|
||||||
| `target-branch` | `develop` | Checked-out branch receiving the commit |
|
| `target-branch` | `develop` | Checked-out branch receiving the commit |
|
||||||
| `bump` | `patch` | `major`, `minor`, or `patch` |
|
| `bump` | `patch` | `major`, `minor`, or `patch` |
|
||||||
@@ -101,6 +104,8 @@ Gitea may suppress workflows caused by pushes authenticated with its built-in `G
|
|||||||
|
|
||||||
The action does not force-push, create tags, publish releases, or call forge APIs. Concurrent release jobs are resolved safely by the remote rejecting a non-fast-forward push. Configure workflow-level concurrency if release PRs can overlap.
|
The action does not force-push, create tags, publish releases, or call forge APIs. Concurrent release jobs are resolved safely by the remote rejecting a non-fast-forward push. Configure workflow-level concurrency if release PRs can overlap.
|
||||||
|
|
||||||
|
For the first versioned release, the base branch might not contain `[tool.bumpversion]` yet. Set `version-file` to the app's `__init__.py`; the action will read its base-branch `__version__` as the bootstrap baseline. Once the configuration reaches the base branch, it becomes the authoritative baseline.
|
||||||
|
|
||||||
## Releasing the action
|
## Releasing the action
|
||||||
|
|
||||||
Create and push an immutable semantic-version tag:
|
Create and push an immutable semantic-version tag:
|
||||||
|
|||||||
@@ -5,6 +5,10 @@ inputs:
|
|||||||
description: Path to the bump-my-version TOML configuration
|
description: Path to the bump-my-version TOML configuration
|
||||||
required: false
|
required: false
|
||||||
default: pyproject.toml
|
default: pyproject.toml
|
||||||
|
version-file:
|
||||||
|
description: App __init__.py used to bootstrap when the base branch has no bump-my-version config
|
||||||
|
required: false
|
||||||
|
default: ""
|
||||||
base-branch:
|
base-branch:
|
||||||
description: Branch whose version is used as the release baseline
|
description: Branch whose version is used as the release baseline
|
||||||
required: false
|
required: false
|
||||||
@@ -62,6 +66,7 @@ runs:
|
|||||||
shell: bash
|
shell: bash
|
||||||
env:
|
env:
|
||||||
INPUT_CONFIG_FILE: ${{ inputs.config-file }}
|
INPUT_CONFIG_FILE: ${{ inputs.config-file }}
|
||||||
|
INPUT_VERSION_FILE: ${{ inputs.version-file }}
|
||||||
INPUT_BASE_BRANCH: ${{ inputs.base-branch }}
|
INPUT_BASE_BRANCH: ${{ inputs.base-branch }}
|
||||||
INPUT_TARGET_BRANCH: ${{ inputs.target-branch }}
|
INPUT_TARGET_BRANCH: ${{ inputs.target-branch }}
|
||||||
INPUT_BUMP: ${{ inputs.bump }}
|
INPUT_BUMP: ${{ inputs.bump }}
|
||||||
|
|||||||
+6
-1
@@ -2,6 +2,7 @@
|
|||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
: "${INPUT_CONFIG_FILE:?config-file is required}"
|
: "${INPUT_CONFIG_FILE:?config-file is required}"
|
||||||
|
: "${INPUT_VERSION_FILE:=}"
|
||||||
: "${INPUT_BASE_BRANCH:?base-branch is required}"
|
: "${INPUT_BASE_BRANCH:?base-branch is required}"
|
||||||
: "${INPUT_TARGET_BRANCH:?target-branch is required}"
|
: "${INPUT_TARGET_BRANCH:?target-branch is required}"
|
||||||
: "${INPUT_BUMP:?bump is required}"
|
: "${INPUT_BUMP:?bump is required}"
|
||||||
@@ -45,7 +46,11 @@ git fetch "${INPUT_REMOTE}" \
|
|||||||
script_dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
|
script_dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
|
||||||
base_ref="refs/remotes/${INPUT_REMOTE}/${INPUT_BASE_BRANCH}"
|
base_ref="refs/remotes/${INPUT_REMOTE}/${INPUT_BASE_BRANCH}"
|
||||||
current_version=$(python3 "${script_dir}/read_version.py" "${INPUT_CONFIG_FILE}")
|
current_version=$(python3 "${script_dir}/read_version.py" "${INPUT_CONFIG_FILE}")
|
||||||
base_version=$(python3 "${script_dir}/read_version.py" "${INPUT_CONFIG_FILE}" --ref "${base_ref}")
|
base_version_args=("${INPUT_CONFIG_FILE}" --ref "${base_ref}")
|
||||||
|
if [[ -n "${INPUT_VERSION_FILE}" ]]; then
|
||||||
|
base_version_args+=(--fallback-version-file "${INPUT_VERSION_FILE}")
|
||||||
|
fi
|
||||||
|
base_version=$(python3 "${script_dir}/read_version.py" "${base_version_args[@]}")
|
||||||
|
|
||||||
comparison=$(python3 - "${current_version}" "${base_version}" <<'PY'
|
comparison=$(python3 - "${current_version}" "${base_version}" <<'PY'
|
||||||
import re
|
import re
|
||||||
|
|||||||
+31
-1
@@ -4,7 +4,9 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
import re
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
|
|
||||||
|
|
||||||
@@ -12,9 +14,35 @@ def parse_args() -> argparse.Namespace:
|
|||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument("config_file")
|
parser.add_argument("config_file")
|
||||||
parser.add_argument("--ref")
|
parser.add_argument("--ref")
|
||||||
|
parser.add_argument("--fallback-version-file")
|
||||||
return parser.parse_args()
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
def read_bootstrap_version(args: argparse.Namespace, config_error: KeyError) -> str:
|
||||||
|
if not args.ref or not args.fallback_version_file:
|
||||||
|
raise SystemExit(
|
||||||
|
f"Could not read tool.bumpversion.current_version from {args.config_file}: {config_error}"
|
||||||
|
) from config_error
|
||||||
|
|
||||||
|
try:
|
||||||
|
version_content = subprocess.check_output(
|
||||||
|
["git", "show", f"{args.ref}:{args.fallback_version_file}"],
|
||||||
|
text=True,
|
||||||
|
)
|
||||||
|
except (OSError, subprocess.CalledProcessError) as error:
|
||||||
|
raise SystemExit(
|
||||||
|
f"Could not load bootstrap version file {args.fallback_version_file}: {error}"
|
||||||
|
) from error
|
||||||
|
|
||||||
|
match = re.search(r'^__version__ = "(\d+\.\d+\.\d+)"$', version_content, re.MULTILINE)
|
||||||
|
if not match:
|
||||||
|
raise SystemExit(f"Could not read __version__ from bootstrap file {args.fallback_version_file}")
|
||||||
|
|
||||||
|
version = match.group(1)
|
||||||
|
print(f"Using bootstrap version {version} from {args.fallback_version_file}", file=sys.stderr)
|
||||||
|
return version
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
args = parse_args()
|
args = parse_args()
|
||||||
try:
|
try:
|
||||||
@@ -30,7 +58,9 @@ def main() -> None:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
version = tomllib.loads(content.decode())["tool"]["bumpversion"]["current_version"]
|
version = tomllib.loads(content.decode())["tool"]["bumpversion"]["current_version"]
|
||||||
except (KeyError, TypeError, UnicodeDecodeError, tomllib.TOMLDecodeError) as error:
|
except KeyError as error:
|
||||||
|
version = read_bootstrap_version(args, error)
|
||||||
|
except (TypeError, UnicodeDecodeError, tomllib.TOMLDecodeError) as error:
|
||||||
raise SystemExit(
|
raise SystemExit(
|
||||||
f"Could not read tool.bumpversion.current_version from {args.config_file}: {error}"
|
f"Could not read tool.bumpversion.current_version from {args.config_file}: {error}"
|
||||||
) from error
|
) from error
|
||||||
|
|||||||
+15
-6
@@ -12,6 +12,18 @@ git config user.name Test
|
|||||||
git config user.email test@example.com
|
git config user.email test@example.com
|
||||||
mkdir erp_operations
|
mkdir erp_operations
|
||||||
cat > pyproject.toml <<'TOML'
|
cat > pyproject.toml <<'TOML'
|
||||||
|
[project]
|
||||||
|
name = "erp_operations"
|
||||||
|
dynamic = ["version"]
|
||||||
|
TOML
|
||||||
|
printf '%s\n' '__version__ = "0.0.1"' > erp_operations/__init__.py
|
||||||
|
git add .
|
||||||
|
git commit -qm initial
|
||||||
|
git remote add origin "${test_root}/remote.git"
|
||||||
|
git push -qu origin main
|
||||||
|
git switch -qc develop
|
||||||
|
cat >> pyproject.toml <<'TOML'
|
||||||
|
|
||||||
[tool.bumpversion]
|
[tool.bumpversion]
|
||||||
current_version = "0.0.1"
|
current_version = "0.0.1"
|
||||||
commit = false
|
commit = false
|
||||||
@@ -22,15 +34,12 @@ filename = "erp_operations/__init__.py"
|
|||||||
search = '__version__ = "{current_version}"'
|
search = '__version__ = "{current_version}"'
|
||||||
replace = '__version__ = "{new_version}"'
|
replace = '__version__ = "{new_version}"'
|
||||||
TOML
|
TOML
|
||||||
printf '%s\n' '__version__ = "0.0.1"' > erp_operations/__init__.py
|
git add pyproject.toml
|
||||||
git add .
|
git commit -qm 'configure versioning'
|
||||||
git commit -qm initial
|
|
||||||
git remote add origin "${test_root}/remote.git"
|
|
||||||
git push -qu origin main
|
|
||||||
git switch -qc develop
|
|
||||||
git push -qu origin develop
|
git push -qu origin develop
|
||||||
|
|
||||||
export INPUT_CONFIG_FILE=pyproject.toml
|
export INPUT_CONFIG_FILE=pyproject.toml
|
||||||
|
export INPUT_VERSION_FILE=erp_operations/__init__.py
|
||||||
export INPUT_BASE_BRANCH=main
|
export INPUT_BASE_BRANCH=main
|
||||||
export INPUT_TARGET_BRANCH=develop
|
export INPUT_TARGET_BRANCH=develop
|
||||||
export INPUT_BUMP=patch
|
export INPUT_BUMP=patch
|
||||||
|
|||||||
Reference in new issue
Block a user