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
18 changes: 9 additions & 9 deletions .github/workflows/version-bump-on-development.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,18 @@ jobs:
import re
from pathlib import Path

version_file = Path('app/main.cpp')
version_file = Path('app/main.cpp')
text = version_file.read_text(encoding='utf-8')

major = re.search(r'^#define\s+VERSION_MAJOR\s+(\d+)', text, re.M)
minor = re.search(r'^#define\s+VERSION_MINOR\s+(\d+)', text, re.M)
patch = re.search(r'^#define\s+VERSION_PATCH\s+(\d+)', text, re.M)
major = re.search(r'^#define\s+VERSION_MAJOR\s+(\d+)', text, re.M)
minor = re.search(r'^#define\s+VERSION_MINOR\s+(\d+)', text, re.M)
patch = re.search(r'^#define\s+VERSION_PATCH\s+(\d+)', text, re.M)

if not (major and minor and patch):
raise SystemExit('Unable to determine version from app/main.cpp')
next_version = f"{major.group(1)}.{minor.group(1)}.{int(patch.group(1)) + 1}"
if not (major and minor and patch):
raise SystemExit('Unable to determine version from app/main.cpp')
next_version = f"{major.group(1)}.{minor.group(1)}.{int(patch.group(1)) + 1}"
with open(os.environ['GITHUB_OUTPUT'], 'a', encoding='utf-8') as out:
out.write(f'version={next_version}\n')
out.write(f'version={next_version}\n')

print(f'Computed next version: {next_version}')

Expand All @@ -82,7 +82,7 @@ jobs:
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"

git add CMakeLists.txt app/main.cpp
git add -u
if git diff --cached --quiet; then
echo "No version changes detected. Nothing to commit."
exit 0
Expand Down
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,18 +140,22 @@ By default, `linux_build.sh` uses the `Output` directory. Its executable is:
Versions use the `MAJOR.MINOR.PATCH` format and are updated with:

```bash
python3 make_release.py 0.1.1 --skip-build
python3 make_release.py 0.1.1
```

The script synchronizes:

- the CMake project version in `CMakeLists.txt`;
- the `@version` field in `app/main.cpp`;
- the `VERSION_MAJOR`, `VERSION_MINOR`, and `VERSION_PATCH` macros;
- the embedded `FileVersion` and `ProductVersion` strings.
- the embedded `FileVersion` and `ProductVersion` strings;
- the version shown in `README.md`, `docs/mainpage.md`, and `docs/Doxyfile`.

Without `--skip-build`, the script builds the project after updating metadata
and restores the previous files if the build fails.

CI can update only the version metadata by passing `--skip-build`.

Without `--skip-build`, the script builds the project after updating the
metadata and restores the previous files if the build fails.

## Next Steps

Expand Down
82 changes: 53 additions & 29 deletions make_release.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,30 +94,52 @@ def validate(self) -> bool:
print("{} is not available".format(self.CMAKE_FILE))
return False

required_files = (
self.MAIN_CPP_FILE,
self.MAINPAGE_FILE,
self.DOXYFILE,
)
required_files = (self.MAINPAGE_FILE, self.DOXYFILE)
for file in required_files:
if not isfile(file):
print("{} is not available".format(file))
return False

if not self.findSourceFiles():
print("No project source files were found in {}".format(self.CMAKE_FILE))
return False

self.check_passed = True
return True

def isValid(self) -> bool:
return self.check_passed

# Read project source paths from the CMake source and header lists.
def findSourceFiles(self) -> tuple:
with File(self.CMAKE_FILE, "r") as opened_file:
cmake_content = opened_file.read()

source_files = []
for list_name in ("SOURCES_LIST", "HEADERS_LIST"):
match = re.search(
r"set\s*\(\s*{}\s*(.*?)\)".format(list_name),
cmake_content,
re.DOTALL,
)
if match is None:
continue

for line in match.group(1).splitlines():
path = line.split("#", 1)[0].strip()
if path and "${" not in path and isfile(path):
source_files.append(path)

return tuple(source_files)

# Step 2: collect the files that need version metadata updates.
def findLibFiles(self) -> tuple:
flist = [
self.CMAKE_FILE,
self.MAIN_CPP_FILE,
self.MAINPAGE_FILE,
self.DOXYFILE,
]
flist.extend(self.findSourceFiles())
if not self.skip_readme and isfile(self.README_FILE):
flist.append(self.README_FILE)
return tuple(flist)
Expand Down Expand Up @@ -184,6 +206,7 @@ def updateFiles(self, ftuple: tuple = ()) -> None:
)
MAINPAGE_VER = r"(\*\*Version:\*\*\s+)\d+\.\d+\.\d+"
DOXYFILE_VER = r"(?m)^(PROJECT_NUMBER\s+=\s+)\d+\.\d+\.\d+"
source_files = self.findSourceFiles()

VER = self.lib_ver.split('.')
for file in ftuple:
Expand All @@ -201,35 +224,36 @@ def updateFiles(self, ftuple: tuple = ()) -> None:
content,
count=1,
)
elif file == self.MAIN_CPP_FILE:
elif file in source_files:
content = re.sub(
HEADER,
rf"\g<1>{self.lib_ver}",
content,
count=1,
)
major, minor, patch = VER
content = re.sub(MAJOR_VER, rf"\g<1>{major}", content, count=1)
content = re.sub(MINOR_VER, rf"\g<1>{minor}", content, count=1)
content = re.sub(PATCH_VER, rf"\g<1>{patch}", content, count=1)
content = re.sub(
FILE_VER,
rf"\g<1>{major}.{minor}.{patch}.0\g<2>",
content,
count=1,
)
content = re.sub(
PROD_VER,
rf"\g<1>{major}.{minor}.{patch}.0\g<2>",
content,
count=1,
)
content = re.sub(
COPYRIGHT,
rf"\g<1>Anton Chernov, {YEAR}\g<2>",
content,
count=1,
)
if file == self.MAIN_CPP_FILE:
major, minor, patch = VER
content = re.sub(MAJOR_VER, rf"\g<1>{major}", content, count=1)
content = re.sub(MINOR_VER, rf"\g<1>{minor}", content, count=1)
content = re.sub(PATCH_VER, rf"\g<1>{patch}", content, count=1)
content = re.sub(
FILE_VER,
rf"\g<1>{major}.{minor}.{patch}.0\g<2>",
content,
count=1,
)
content = re.sub(
PROD_VER,
rf"\g<1>{major}.{minor}.{patch}.0\g<2>",
content,
count=1,
)
content = re.sub(
COPYRIGHT,
rf"\g<1>Anton Chernov, {YEAR}\g<2>",
content,
count=1,
)
elif file == self.README_FILE:
if self.skip_readme:
continue
Expand Down
Loading