Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ if(NOT CMAKE_BUILD_TYPE)
endif()

project(paimon
VERSION 0.4.0
VERSION 0.5.0
DESCRIPTION "Paimon C++ Project")

string(TOUPPER "${CMAKE_BUILD_TYPE}" UPPERCASE_BUILD_TYPE)
Expand Down
2 changes: 1 addition & 1 deletion docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@
# The master toctree document.
master_doc = "index"

version = "0.4.0"
version = "0.5.0"

# Documentation channel, set by the paimon-website build pipeline:
# "main" (default) for the main-branch docs published under main/, "stable"
Expand Down
32 changes: 25 additions & 7 deletions scripts/releasing/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,21 @@ version; replace these illustrative values with the versions for your release:
scripts/releasing/bump_version.py --check 0.2.0
```

After publishing a release, start the next development cycle and review the diff:
After cutting a release branch, advance the main branch before publishing the
release with:

```bash
scripts/releasing/bump_version.py --dev-only 0.2.0 0.3.0
scripts/releasing/bump_version.py --check 0.3.0
```

This updates only CMake and `docs/source/conf.py` to the next development
version. It leaves `docs/source/_static/versions.json` unchanged, including the
stable release and archived versions. Cutting a release branch does not make
that version stable.

After publishing a release, you can instead start the next development cycle
and promote the released version together:

```bash
scripts/releasing/bump_version.py 0.2.0 0.3.0
Expand All @@ -83,9 +97,9 @@ development version and updates the documentation version switcher:
label. If the released version is already stable, no additional archive is
created.

Run the two-version command after publishing the old version, since it marks
that version stable. It updates local metadata; publishing documentation remains
a separate step.
Without `--dev-only`, run the two-version command after publishing the old
version, since it marks that version stable. It updates local metadata;
publishing documentation remains a separate step.

To promote the current project version without starting a development cycle,
use the independent operation:
Expand All @@ -98,7 +112,11 @@ This only updates `docs/source/_static/versions.json` and requires CMake and
`docs/source/conf.py` to use the version being promoted. Repeating it does not
add an archive.

Both update operations support `--dry-run`, which validates the inputs and lists
If main was already advanced with `--dev-only`, run `--promote-stable` on the
release branch after publication, then carry the `versions.json` update back to
main.

All update modes support `--dry-run`, which validates the inputs and lists
the files that would be written without modifying them. `--root PATH` selects a
different source tree. `--check VERSION` remains a read-only consistency check:
CMake must match `VERSION`, and the documentation version may match either CMake
Expand Down Expand Up @@ -269,8 +287,8 @@ than ASF's general one-hour minimum.
## Individual tools

- `bump_version.py`: check version metadata, start the next development cycle
while marking the released version stable, or independently promote stable
documentation.
with or without promoting the released version, or independently promote
stable documentation.
- `create_source_release.sh`: deterministically create an archive with GNU
gzip, a SHA-512 checksum, and an optional detached signature from an immutable
Git ref.
Expand Down
23 changes: 18 additions & 5 deletions scripts/releasing/bump_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

"""Check versions or start the next development cycle after a release."""
"""Check versions, start the next development cycle, or promote stable docs."""

import argparse
import json
Expand Down Expand Up @@ -162,8 +162,10 @@ def checked_files(root: Path, expected: str) -> Dict[Path, str]:
}


def updated_files(root: Path, current: str, new: str) -> Dict[Path, str]:
"""Promote the released version and start the next development cycle."""
def updated_files(
root: Path, current: str, new: str, *, dev_only: bool = False
) -> Dict[Path, str]:
"""Start the next development cycle, optionally promoting the released version."""
files = checked_files(root, current)
cmake_path = root / "CMakeLists.txt"
docs_path = root / "docs/source/conf.py"
Expand All @@ -181,6 +183,9 @@ def updated_files(root: Path, current: str, new: str) -> Dict[Path, str]:
f"documentation version {current}",
)

if dev_only:
return {cmake_path: files[cmake_path], docs_path: files[docs_path]}

versions_path = root / "docs/source/_static/versions.json"
versions = load_versions(versions_path)
promote_stable(versions, current)
Expand Down Expand Up @@ -211,10 +216,17 @@ def promoted_files(root: Path, version: str) -> Dict[Path, str]:

def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("current_version", nargs="?", help="just-released project version")
parser.add_argument(
"current_version", nargs="?", help="current project version (released unless --dev-only)"
)
parser.add_argument("new_version", nargs="?", help="next development version")
mode = parser.add_mutually_exclusive_group()
mode.add_argument("--check", metavar="VERSION", help="validate version metadata")
mode.add_argument(
"--dev-only",
action="store_true",
help="update development versions without promoting stable docs",
)
mode.add_argument(
"--promote-stable",
metavar="VERSION",
Expand Down Expand Up @@ -249,7 +261,8 @@ def main() -> int:
if args.current_version == args.new_version:
raise VersionError("current and new versions must differ")
files = updated_files(
args.root.resolve(), args.current_version, args.new_version
args.root.resolve(), args.current_version, args.new_version,
dev_only=args.dev_only,
)
for path, content in files.items():
if args.dry_run:
Expand Down
38 changes: 38 additions & 0 deletions scripts/releasing/tests/test_release_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,36 @@ def test_version_tool_bumps_dev_and_promotes_released_version(self) -> None:
json.loads(versions_path.read_text(encoding="utf-8")), versions
)

def test_version_tool_bumps_dev_without_promoting_stable(self) -> None:
for docs_version in ("1.2.3", "1.1.0"):
with self.subTest(docs_version=docs_version), tempfile.TemporaryDirectory() as temp:
root = Path(temp)
self.create_version_tree(root)
docs_path = root / "docs/source/conf.py"
docs_path.write_text(f'version = "{docs_version}"\n', encoding="utf-8")
versions_path = root / "docs/source/_static/versions.json"
versions = json.loads(versions_path.read_text(encoding="utf-8"))
versions[0]["name"] = "main (development)"
versions.append({
"name": "1.0.0",
"version": "1.0",
"url": "https://paimon.apache.org/docs/cpp/1.0/",
})
# Preserve existing labels, archives, and formatting byte for byte.
versions_path.write_text(json.dumps(versions), encoding="utf-8")
before = versions_path.read_bytes()
result = self.run_tool(
VERSION_TOOL, "--root", str(root), "--dev-only", "1.2.3", "1.3.0"
)
self.assertEqual(
result.stdout.splitlines(),
[f"Updated {root / path}" for path in ("CMakeLists.txt", "docs/source/conf.py")],
)
self.assertIn("VERSION 1.3.0", (root / "CMakeLists.txt").read_text())
self.assertEqual(docs_path.read_text(), 'version = "1.3.0"\n')
self.assertEqual(versions_path.read_bytes(), before)
self.run_tool(VERSION_TOOL, "--root", str(root), "--check", "1.3.0")

def test_version_tool_promotes_series_on_patch_release(self) -> None:
with tempfile.TemporaryDirectory() as temp:
root = Path(temp)
Expand Down Expand Up @@ -820,6 +850,7 @@ def test_version_tool_dry_run_leaves_all_files_unchanged(self) -> None:
["CMakeLists.txt", "docs/source/conf.py", "docs/source/_static/versions.json"],
),
(("--promote-stable", "1.2.3"), ["docs/source/_static/versions.json"]),
(("--dev-only", "1.2.3", "1.3.0"), ["CMakeLists.txt", "docs/source/conf.py"]),
]:
with self.subTest(arguments=arguments), tempfile.TemporaryDirectory() as temp:
root = Path(temp)
Expand All @@ -841,6 +872,13 @@ def test_version_tool_rejects_invalid_operations_without_writes(self) -> None:
(("--promote-stable", "1.2"), 1),
(("--promote-stable", "1.2.3", "1.2.3", "1.3.0"), 1),
(("--check", "1.2.3", "--promote-stable", "1.2.3"), 2),
(("--dev-only", "--check", "1.2.3"), 2),
(("--dev-only", "--promote-stable", "1.2.3"), 2),
(("--dev-only",), 1),
(("--dev-only", "1.2.3"), 1),
(("--dev-only", "1.2.3", "1.2.3"), 1),
(("--dev-only", "1.2.3", "1.3"), 1),
(("--dev-only", "1.2.4", "1.3.0"), 1),
(("1.2.3", "1.2.3"), 1),
(("1.2.3", "1.3"), 1),
(("1.2.4", "1.3.0"), 1),
Expand Down
Loading