175 lines
6.0 KiB
Python
Executable File
175 lines
6.0 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import datetime
|
|
import glob
|
|
import os
|
|
import re
|
|
import sys
|
|
|
|
import requests
|
|
import semver
|
|
|
|
|
|
def release():
|
|
major_version = 4
|
|
|
|
gitlab_project_id = os.environ["CI_PROJECT_ID"]
|
|
api_token = os.environ["CISCRIPT_API_TOKEN"]
|
|
minor_version = os.environ["MINOR_VERSION"]
|
|
if minor_version == "minor":
|
|
minor_version = None
|
|
else:
|
|
try:
|
|
minor_version = int(minor_version)
|
|
except ValueError:
|
|
sys.exit(f"minor version must be number but is '{minor_version}'")
|
|
patch_version = os.environ["PATCH_VERSION"]
|
|
if patch_version == "patch":
|
|
patch_version = None
|
|
else:
|
|
try:
|
|
patch_version = int(patch_version)
|
|
except ValueError:
|
|
sys.exit(f"patch version must be number but is '{patch_version}'")
|
|
|
|
branch = os.environ["CI_COMMIT_BRANCH"]
|
|
print(f"branch '{branch}'")
|
|
if branch == "master":
|
|
if minor_version is None:
|
|
sys.exit("minor version must be set")
|
|
if patch_version is None:
|
|
patch_version = 0
|
|
future_version = f"{major_version}.{minor_version}.{patch_version}"
|
|
response = requests.get(
|
|
(
|
|
f"https://gitlab.princip.cz/"
|
|
f"api/v4/projects/{gitlab_project_id}/repository/tags"
|
|
),
|
|
headers={"PRIVATE-TOKEN": api_token},
|
|
params={"search": "^v"},
|
|
)
|
|
for tag_dict in response.json():
|
|
tag_name = tag_dict["name"]
|
|
if (re.match(r"^v\d+\.\d+\.\d+$", tag_name)
|
|
and semver.compare(future_version, tag_name[1:]) < 1):
|
|
sys.exit(
|
|
f"existing version '{tag_name[1:]}' "
|
|
f"is greater than or equal to future version "
|
|
f"'{future_version}'"
|
|
)
|
|
elif match := re.match(r"^stable-(\d+)\.(\d+)$", branch):
|
|
if patch_version is None:
|
|
sys.exit("patch version must be set")
|
|
major_version = int(match.group(1))
|
|
branch_minor_version = int(match.group(2))
|
|
if minor_version is None:
|
|
minor_version = branch_minor_version
|
|
elif minor_version != branch_minor_version:
|
|
sys.exit(
|
|
f"minor version on branch '{branch}' "
|
|
f"must be '{branch_minor_version}' or blank (default)"
|
|
)
|
|
future_version = f"{major_version}.{minor_version}.{patch_version}"
|
|
response = requests.get(
|
|
(
|
|
f"https://gitlab.princip.cz/"
|
|
f"api/v4/projects/{gitlab_project_id}/repository/tags"
|
|
),
|
|
headers={"PRIVATE-TOKEN": api_token},
|
|
params={"search": f"^v{major_version}.{minor_version}"},
|
|
)
|
|
for tag_dict in response.json():
|
|
tag_name = tag_dict["name"]
|
|
if semver.compare(future_version, tag_name[1:]) < 1:
|
|
sys.exit(
|
|
f"existing version '{tag_name[1:]}' "
|
|
f"is greater than or equal to future version "
|
|
f"'{future_version}'"
|
|
)
|
|
else:
|
|
sys.exit(f"release on branch '{branch}' is forbidden")
|
|
print(f"future version '{future_version}'")
|
|
future_tag_name = f"v{future_version}"
|
|
print(f"future tag name '{future_tag_name}'")
|
|
|
|
response = requests.get(
|
|
(
|
|
f"https://gitlab.princip.cz/"
|
|
f"api/v4/projects/{gitlab_project_id}/repository/tags"
|
|
f"/{future_tag_name}"
|
|
),
|
|
headers={"PRIVATE-TOKEN": api_token},
|
|
)
|
|
if response.status_code != 404:
|
|
sys.exit(f"tag '{future_tag_name}' already exists")
|
|
|
|
commit_message = f"update files for {future_version}"
|
|
payload_dict = {
|
|
"branch": branch, "commit_message": commit_message, "actions": []}
|
|
today_date = datetime.datetime.today().strftime("%Y-%m-%d")
|
|
release_description = f"## {future_version} ({today_date})\n"
|
|
change_file_fps = glob.glob(os.path.join("incoming_changes", "*.md"))
|
|
if not change_file_fps:
|
|
sys.exit("no change file")
|
|
for change_file_fp in change_file_fps:
|
|
change_file_fn = os.path.basename(change_file_fp)
|
|
match = re.match(r"^(\d+)-\S+.md$", change_file_fn)
|
|
if match:
|
|
issue_no = match.group(1)
|
|
else:
|
|
issue_no = None
|
|
with open(change_file_fp, "r") as change_file:
|
|
for line in change_file:
|
|
line = line.strip()
|
|
if issue_no:
|
|
line += f" #{issue_no}"
|
|
release_description += f"{line}\n"
|
|
payload_dict["actions"].append(
|
|
{"action": "delete", "file_path": change_file_fp})
|
|
with open("CHANGELOG.md", "r+") as changelog_file:
|
|
content = changelog_file.read()
|
|
new_changelog_content = f"{release_description}\n\n{content}"
|
|
payload_dict["actions"].append({
|
|
"action": "update",
|
|
"file_path": "CHANGELOG.md",
|
|
"content": new_changelog_content,
|
|
})
|
|
print("CHANGELOG.md updated")
|
|
|
|
response = requests.post(
|
|
(
|
|
f"https://gitlab.princip.cz/"
|
|
f"api/v4/projects/{gitlab_project_id}/repository/commits"
|
|
),
|
|
headers={"PRIVATE-TOKEN": api_token},
|
|
json=payload_dict,
|
|
)
|
|
if response.status_code == 201:
|
|
print(f"commit '{commit_message}' created")
|
|
else:
|
|
sys.exit(
|
|
f"error creating commit '{commit_message}', "
|
|
f"status code '{response.status_code}', json '{response.json()}'"
|
|
)
|
|
|
|
response = requests.post(
|
|
(
|
|
f"https://gitlab.princip.cz/"
|
|
f"api/v4/projects/{gitlab_project_id}/repository/tags"
|
|
),
|
|
headers={"PRIVATE-TOKEN": api_token},
|
|
params={"tag_name": future_tag_name, "ref": branch},
|
|
)
|
|
if response.status_code == 201:
|
|
print(f"tag '{future_tag_name}' created")
|
|
else:
|
|
sys.exit(
|
|
f"error creating tag '{future_tag_name}', "
|
|
f"status code '{response.status_code}', "
|
|
f"json '{response.json()}'"
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
release()
|