Skip to content

Commit

Permalink
ci: add prerelease and build to release
Browse files Browse the repository at this point in the history
  • Loading branch information
PhilippeCrassous committed Sep 9, 2020
1 parent d8c63f3 commit 147fa30
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 50 deletions.
4 changes: 3 additions & 1 deletion .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ zip:
.on_version_tag: &tpl_on_version_tag
only:
refs:
- /^v[0-9]+.[0-9]+.[0-9]+$/
# see inject_version.py
- /^v([0-9]+)\.([0-9]+)\.([0-9]+)(\-[0-9A-Za-z-]+)?(\+[0-9A-Za-z-]+)?$/


release:
<<: *tpl_on_version_tag
Expand Down
23 changes: 14 additions & 9 deletions doc/release.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
# How to release a new version ?

The release process of Mixer is handled with CI/CD and based on git tags. Each tag with a name `v{major}.{minor}.{bugfix}` is considered to be a release tag and should trigger the release job of the CI/CD.
The release process of Mixer is handled with CI/CD and based on git tags. The tags that are considered to be a release tag and should trigger the release job of the CI/CD are :

The preliminary steps for creating a release `v{major}.{minor}.{bugfix}` are :
- check that the tag `v{major}.{minor}.{bugfix}` does not exist
- `v{major}.{minor}.{bugfix}`
- `v{major}.{minor}.{bugfix}-{prerelease}`
- `v{major}.{minor}.{bugfix}+{build}`
- `v{major}.{minor}.{bugfix}-{prerelease}+{build}`

The preliminary steps for creating a release tagged as described above are :
- check that the tag does not exist
- ensure all the changes have been committed
- edit `CHANGELOG.md` to add a section describing the release and starting with `# <major>.<minor>.<bugfix>`
- commit with a message like `doc:update CHANGELOG.md for <major>.<minor>.<bugfix>`
- edit `CHANGELOG.md` to add a section describing the release and starting with a comment line containing the release tag
- commit with a message like `doc:update CHANGELOG.md for <release tag>`

Do not add the tag manually, instead run the script:
Do not add the tag manually, instead run the script as follows:

```bash
python -m extra.prepare_release <major> <minor> <bugfix>
python -m extra.prepare_release <major> <minor> <bugfix> [--prerelease <prerelease>] [--build <build>]
```

The script will inject the new version number in the addon `bl_info` dictionnary and tag the commit.
The script will inject the new version number in the addon `bl_info` dictionary and tag the commit.

You can then push the tag:

Expand All @@ -29,6 +34,6 @@ Then watch your pipeline on Gitlab and wait for the release notes to appear on t

## What if I did a mistake ?

It may happen. In that case just go to gitlab and remove the tag. It will also remove the release.
It may happen. In that case just go to Gitlab and remove the tag. It will also remove the release.

In your local repository manually delete the tag.
73 changes: 39 additions & 34 deletions extra/inject_version.py
Original file line number Diff line number Diff line change
@@ -1,56 +1,61 @@
import os
import re
import subprocess
from typing import Tuple


def get_version():
cp = subprocess.run(["git", "describe", "--tags", "--dirty", "--match=v*"], stdout=subprocess.PIPE, check=True,)
version = str(cp.stdout, encoding="utf8").strip()
return version

version_tokens = version.split("-")
if len(version_tokens) == 1:
return version_tokens[0]
return version_tokens[0] + "+" + "-".join(version_tokens[1:])

def parse(version) -> Tuple[Tuple[int], str]:
"""Parse version string like "v1.0.4-14-g241472-dirty" into ((0,14,0), "-g241472-dirty")
"""
# similar regexp in gitlab .yml files
# tested with https://regoio.herokuapp.com/

def main():
version = get_version()
# vMAJOR.MINOR.PATCH-PRERELEASE+BUILD as in https://semver.org/
re_string = r"^v([0-9]+)\.([0-9]+)\.([0-9]+)((?:\-[0-9A-Za-z-]+)?(?:\+[0-9A-Za-z-]+)?)?$"
match = re.match(re_string, version)
groups = match.groups()

pyproject_file = "pyproject.toml"
new_projectfile_str = ""
tool_poetry_found = False
with open(pyproject_file, "r") as fp:
for line in fp.readlines():
if line.startswith("[tool.poetry]"):
tool_poetry_found = True
if tool_poetry_found and line.startswith("version = "):
new_projectfile_str += f'version = "{version}"\n'
tool_poetry_found = False
else:
new_projectfile_str += f"{line}"
with open(pyproject_file, "w") as fp:
fp.write(new_projectfile_str)
# ([0-9]+)\.([0-9]+)\.([0-9]+)
# e.g. 0.15.15
version = tuple((int(s) for s in groups[0:3]))

# ((?:\-[0-9A-Za-z-]+)?(?:\+[0-9A-Za-z-]+)?)?
# e.g. "" or "-xxx" or "+yyy" or "-xxx+yyy"
prerelease_build = "" if len(groups) < 4 else groups[3]

version_numbers = [int(n) for n in version[1:].split("+")[0].split("-")[0].split(".")]
if "+" in version:
commit_version_str = version[1:].split("+")[1].split("-")[0]
if commit_version_str != "dirty":
version_numbers += [int(commit_version_str)]
return version, prerelease_build


def main():
version = get_version()
version_numbers, suffix = parse(version)
version_strings = [str(i) for i in version_numbers]
version_string = ".".join(version_strings)

init_file = os.path.join("mixer", "__init__.py")
new_init_file_str = ""
bl_info_state = 0
done = False
comment = " # Generated by inject_version.py"
with open(init_file, "r") as fp:
for line in fp.readlines():
if bl_info_state == 0 and "bl_info" in line:
bl_info_state = 1
if bl_info_state == 1 and '"version"' in line:
offset = line.find("(")
line = line[:offset] + str(tuple(version_numbers))
new_init_file_str += f"{line},\n"
bl_info_state = 2
if not done:
if line.startswith("__version__ = "):
new_init_file_str += f'__version__ = "v{version_string}"{comment}\n'
elif line.startswith("display_version = "):
new_init_file_str += f'display_version = "v{version_string}{suffix}"{comment}\n'
elif line.startswith(' "version": ('):
new_init_file_str += f' "version": {str(tuple(version_numbers))},{comment}\n'
done = True
else:
new_init_file_str += f"{line}"
else:
new_init_file_str += f"{line}"

with open(init_file, "w") as fp:
fp.write(new_init_file_str)

Expand Down
19 changes: 18 additions & 1 deletion extra/prepare_release.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from extra.get_release_description import get_release_description

import argparse
import re
import subprocess


Expand All @@ -20,14 +21,30 @@ def main():

parser = argparse.ArgumentParser(description="Set a new version number for the project.")

# See https://semver.org/ in mind
parser.add_argument("major", type=int, help="Major version number")
parser.add_argument("minor", type=int, help="Minor version number")
parser.add_argument("bugfix", type=int, help="Bugfix version number")
parser.add_argument("--skip-tests", action="store_true", help="If specified, skip tests for the taggued commit.")
parser.add_argument("--prerelease", type=str, default="", help="Prerelease (optional)")
parser.add_argument("--build", type=str, default="", help="Build suffix (optional)")
parser.add_argument("--skip-tests", action="store_true", help="If specified, skip tests for the tagged commit.")

args = parser.parse_args()

pattern = "^[0-9A-Za-z-]+$"

tag_name = f"v{args.major}.{args.minor}.{args.bugfix}"
if args.prerelease:
if not re.match(pattern, args.prerelease):
print(f'--prerelease argument "{args.prerelease}" does not match pattern {pattern}')
exit(1)
tag_name += f"-{args.prerelease}"
if args.build:
if not re.match(pattern, args.build):
print(f'--build argument "{args.build}" does not match pattern {pattern}')
exit(1)
tag_name += f"+{args.build}"

version_string = tag_name[1:]

if tag_name in all_tags:
Expand Down
3 changes: 2 additions & 1 deletion gitlab/gitlab.com-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ zip:
.on_version_tag: &tpl_on_version_tag
only:
refs:
- /^v[0-9]+.[0-9]+.[0-9]+$/
# see inject_version.py
- /^v([0-9]+)\.([0-9]+)\.([0-9]+)(\-[0-9A-Za-z-]+)?(\+[0-9A-Za-z-]+)?$/

release:
<<: *tpl_on_version_tag
Expand Down
5 changes: 3 additions & 2 deletions mixer/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
import logging
from pathlib import Path

__version__ = ""
display_version = ""

bl_info = {
"name": "Mixer",
"author": "Ubisoft Animation Studio",
Expand All @@ -22,8 +25,6 @@
"category": "Collaboration",
}

__version__ = f"v{bl_info['version'][0]}.{bl_info['version'][1]}.{bl_info['version'][2]}"

logger = logging.getLogger(__name__)
logger.propagate = False
MODULE_PATH = Path(__file__).parent.parent
Expand Down
4 changes: 2 additions & 2 deletions mixer/bl_panels.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from mixer.share_data import share_data
from mixer.broadcaster.common import ClientAttributes
from mixer.blender_data.debug_addon import DebugDataPanel
from mixer import __version__
from mixer import display_version

if TYPE_CHECKING:
from mixer.bl_preferences import MixerPreferences
Expand Down Expand Up @@ -204,7 +204,7 @@ def draw_preferences_ui(mixer_prefs: MixerPreferences, context: bpy.types.Contex


class MixerSettingsPanel(bpy.types.Panel):
bl_label = f"Mixer {__version__}"
bl_label = f"Mixer {display_version or '(Unknown version)'}"
bl_idname = "MIXER_PT_mixer_settings"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
Expand Down

0 comments on commit 147fa30

Please sign in to comment.