Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

initial autopublish #34

Merged
merged 1 commit into from
Mar 22, 2024
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
Empty file added .github/scripts/__init__.py
Empty file.
161 changes: 161 additions & 0 deletions .github/scripts/increment_version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
#!/bin/env python
import argparse
from dataclasses import dataclass

from packaging.version import Version

SETUP_PY_PATH = "setup.py"
DEFAULT_CHANGELOG_PATH = "CHANGELOG.md"
DEFAULT_YDB_VERSION_FILE = "ydb/ydb_version.py"
MARKER = "# AUTOVERSION"


@dataclass(init=False)
class VersionLine:
old_line: str
major: int
minor: int
patch: int
pre: int

def __init__(self, old_line: str, version_str: str):
self.old_line = old_line

version = Version(version_str)
self.major = version.major
self.minor = version.minor
self.micro = version.micro

if version.pre is None:
self.pre = 0
else:
self.pre = version.pre[1]

def increment(self, part_name: str, with_beta: bool):
if part_name == 'minor':
self.increment_minor(with_beta)
elif part_name == 'patch' or part_name == 'micro':
self.increment_micro(with_beta)
else:
raise Exception("unexpected increment type: '%s'" % part_name)

def increment_minor(self, with_beta: bool):
if with_beta:
if self.pre == 0 or self.micro != 0:
self.increment_minor(False)
self.pre += 1
return

if self.micro == 0 and self.pre > 0:
self.pre = 0
return

self.minor += 1
self.micro = 0
self.pre = 0

def increment_micro(self, with_beta: bool):
if with_beta:
if self.pre == 0:
self.increment_micro(False)
self.pre += 1
return

if self.pre > 0:
self.pre = 0
return

self.micro += 1

def __str__(self):
if self.pre > 0:
pre = "b%s" % self.pre
else:
pre = ""

return "%s.%s.%s%s" % (self.major, self.minor, self.micro, pre)

def version_line_with_mark(self):
return 'version="%s", %s' % (str(self), MARKER)


def extract_version(setup_py_content: str):
version_line = ""
for line in setup_py_content.splitlines():
if MARKER in line:
version_line = line
break

if version_line == "":
raise Exception("Not found version line")

version_line = version_line.strip()

parts = version_line.split('"')
version_part = parts[1]

return VersionLine(old_line=version_line, version_str=version_part)


def increment_version_at_setup_py(setup_py_path: str, inc_type: str, with_beta: bool) -> str:
with open(setup_py_path, "rt") as f:
setup_content = f.read()

version = extract_version(setup_content)
version.increment(inc_type, with_beta)
setup_content = setup_content.replace(version.old_line, version.version_line_with_mark())

with open(setup_py_path, "w") as f:
f.write(setup_content)

return str(version)


def add_changelog_version(changelog_path, version: str):
with open(changelog_path, "rt") as f:
content = f.read()
content = content.strip()

if content.startswith("##"):
return

content = """## %s ##
%s
""" % (version, content)
with open(changelog_path, "w") as f:
f.write(content)


def set_version_in_ydb_version_file(file_path: str, version: str):
with open(file_path, "w") as f:
f.write('VERSION = "%s"\n' % version)

def main():
parser = argparse.ArgumentParser()
parser.add_argument(
"--inc-type",
default="minor",
help="increment version type: patch or minor",
choices=["minor", "patch"],
)
parser.add_argument(
"--beta",
choices=["true", "false"],
help="is beta version"
)
parser.add_argument("--changelog-path", default=DEFAULT_CHANGELOG_PATH, help="path to changelog", type=str)
parser.add_argument("--setup-py-path", default=SETUP_PY_PATH)

args = parser.parse_args()

is_beta = args.beta == "true"

new_version = increment_version_at_setup_py(args.setup_py_path, args.inc_type, is_beta)
add_changelog_version(args.changelog_path, new_version)
set_version_in_ydb_version_file(DEFAULT_YDB_VERSION_FILE, new_version)
print(new_version)


if __name__ == '__main__':
main()

28 changes: 28 additions & 0 deletions .github/scripts/increment_version_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import pytest

from .increment_version import VersionLine

@pytest.mark.parametrize(
"source,inc_type,with_beta,result",
[
("0.0.0", 'patch', False, "0.0.1"),
("0.0.1", 'patch', False, "0.0.2"),
("0.0.1b1", 'patch', False, "0.0.1"),
("0.0.0", 'patch', True, "0.0.1b1"),
("0.0.1", 'patch', True, "0.0.2b1"),
("0.0.2b1", 'patch', True, "0.0.2b2"),
("0.0.1", 'minor', False, "0.1.0"),
("0.0.1b1", 'minor', False, "0.1.0"),
("0.1.0b1", 'minor', False, "0.1.0"),
("0.1.0", 'minor', True, "0.2.0b1"),
("0.1.0b1", 'minor', True, "0.1.0b2"),
("0.1.1b1", 'minor', True, "0.2.0b1"),
("3.0.0b1", 'patch', True, "3.0.0b2"),
]
)
def test_increment_version(source, inc_type, with_beta, result):
version = VersionLine("", source)
version.increment(inc_type, with_beta)
incremented = str(version)
assert incremented == result

112 changes: 112 additions & 0 deletions .github/workflows/python-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# This workflow will upload a Python Package using Twine when a release is created
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries

# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.

name: Publish package release

on:
workflow_dispatch:
inputs:
version-change:
description: Version part
required: true
type: choice
default: minor
options:
- minor
- patch
beta:
description: Is beta version
required: true
type: boolean
default: True
jobs:
publish:
env:
VERSION_CHANGE: ${{ github.event.inputs.version-change }}
WITH_BETA: ${{ github.event.inputs.beta }}
# GITHUB_TOKEN: ${{ secrets.YDB_PLATFORM_BOT_TOKEN_REPO }}
CHANGELOG_FILE: CHANGELOG.md
SETUP_PY_PATH: setup.py

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
# with:
# token: ${{ secrets.YDB_PLATFORM_BOT_TOKEN_REPO }}

- name: Set up Python
uses: actions/setup-python@v3
with:
python-version: '3.8'

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install build

- name: read changelog
id: read-changelog
run: |
CHANGELOG=$(cat $CHANGELOG_FILE | sed -e '/^## .*$/,$d')
echo "CHANGELOG<<CHANGELOGEOF_MARKER" >> $GITHUB_ENV
echo "$CHANGELOG" >> $GITHUB_ENV
echo "CHANGELOGEOF_MARKER" >> $GITHUB_ENV
echo "# Changelog" >> $GITHUB_STEP_SUMMARY
echo "$CHANGELOG" >> $GITHUB_STEP_SUMMARY


- name: Increment version
id: increment-version
run: |
NEW_VERSION=$(python3 ./.github/scripts/increment_version.py --inc-type=$VERSION_CHANGE --beta=$WITH_BETA)
echo new version: $NEW_VERSION
echo "NEW_VERSION=$NEW_VERSION" >> $GITHUB_OUTPUT
echo "New version: $NEW_VERSION" >> $GITHUB_STEP_SUMMARY

- name: Build package
run: python -m build

- name: Publish release on github
run: |
if [[ -z "$CHANGELOG" ]]
then
echo "CHANGELOG empty"
exit 1;
fi;

TAG="${{ steps.increment-version.outputs.NEW_VERSION }}"

# Get previous version from changelog
# pre-incremented version not used for consistent changelog with release notes
# for example changelog may be rewrited when switch from beta to release
# and remove internal beta changes
LAST_TAG=$(cat $CHANGELOG_FILE | grep '^## .* ##$' | head -n 2 | tail -n 1 | cut -d ' ' -f 2)

git config --global user.email "robot@umbrella";
git config --global user.name "robot";
git commit -am "Release: $TAG";

git tag "$TAG"
git push && git push --tags

CHANGELOG="$CHANGELOG

Full Changelog: [$LAST_TAG...$TAG](https://github.com/ydb-platform/ydb-sqlalchemy/compare/$LAST_TAG...$TAG)"
if [ "$WITH_BETA" = true ]
then
gh release create --prerelease $TAG --title "$TAG" --notes "$CHANGELOG"
else
gh release create $TAG --title "$TAG" --notes "$CHANGELOG"
fi;

- name: Publish package
uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

setuptools.setup(
name="ydb-sqlalchemy",
version="0.1.0", # AUTOVERSION
version="0.0.0", # AUTOVERSION
description="YDB Dialect for SQLAlchemy",
author="Yandex LLC",
author_email="[email protected]",
Expand Down
Loading