init
This commit is contained in:
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
||||||
47
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
47
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="DuplicatedCode" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||||
|
<Languages>
|
||||||
|
<language minSize="69" name="Python" />
|
||||||
|
</Languages>
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="HtmlUnknownAttribute" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<option name="myValues">
|
||||||
|
<value>
|
||||||
|
<list size="1">
|
||||||
|
<item index="0" class="java.lang.String" itemvalue="images" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
<option name="myCustomValuesEnabled" value="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="HtmlUnknownTag" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<option name="myValues">
|
||||||
|
<value>
|
||||||
|
<list size="11">
|
||||||
|
<item index="0" class="java.lang.String" itemvalue="nobr" />
|
||||||
|
<item index="1" class="java.lang.String" itemvalue="noembed" />
|
||||||
|
<item index="2" class="java.lang.String" itemvalue="comment" />
|
||||||
|
<item index="3" class="java.lang.String" itemvalue="noscript" />
|
||||||
|
<item index="4" class="java.lang.String" itemvalue="embed" />
|
||||||
|
<item index="5" class="java.lang.String" itemvalue="script" />
|
||||||
|
<item index="6" class="java.lang.String" itemvalue="frameset" />
|
||||||
|
<item index="7" class="java.lang.String" itemvalue="html_file" />
|
||||||
|
<item index="8" class="java.lang.String" itemvalue="body_file" />
|
||||||
|
<item index="9" class="java.lang.String" itemvalue="body2" />
|
||||||
|
<item index="10" class="java.lang.String" itemvalue="pre" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
<option name="myCustomValuesEnabled" value="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyPep8NamingInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||||
|
<option name="ignoredErrors">
|
||||||
|
<list>
|
||||||
|
<option value="N803" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</inspection_tool>
|
||||||
|
</profile>
|
||||||
|
</component>
|
||||||
6
.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
6
.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<settings>
|
||||||
|
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||||
|
<version value="1.0" />
|
||||||
|
</settings>
|
||||||
|
</component>
|
||||||
4
.idea/misc.xml
generated
Normal file
4
.idea/misc.xml
generated
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.9" project-jdk-type="Python SDK" />
|
||||||
|
</project>
|
||||||
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/skeleton-small_project.iml" filepath="$PROJECT_DIR$/.idea/skeleton-small_project.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
8
.idea/skeleton-small_project.iml
generated
Normal file
8
.idea/skeleton-small_project.iml
generated
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="PYTHON_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
0
CHANGELOG.md
Normal file
0
CHANGELOG.md
Normal file
1
MANIFEST.in
Normal file
1
MANIFEST.in
Normal file
@@ -0,0 +1 @@
|
|||||||
|
include VERSION.txt
|
||||||
46
Makefile
Normal file
46
Makefile
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
.PHONY: build build-pkg change_file clean dev mrproper namespace pep8 rebuild run static-checks test
|
||||||
|
|
||||||
|
build: build-pkg
|
||||||
|
|
||||||
|
build-pkg:
|
||||||
|
python3 -m pip install --upgrade build
|
||||||
|
python3 -m build
|
||||||
|
|
||||||
|
change_file:
|
||||||
|
/bin/bash scripts/create_change_file.sh
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -fv **/*.pyc
|
||||||
|
rm -fv **/*.pyo
|
||||||
|
rm -rfv .pytest_cache
|
||||||
|
rm -rfv .coverage
|
||||||
|
rm -rfv dist
|
||||||
|
rm -rfv src/*.egg-info
|
||||||
|
rm -rfv __pycache__
|
||||||
|
rm -rfv **/__pycache__
|
||||||
|
|
||||||
|
dev:
|
||||||
|
skaffold dev
|
||||||
|
|
||||||
|
hosts:
|
||||||
|
echo "`minikube ip` CHANGEME.local"
|
||||||
|
|
||||||
|
mrproper: clean
|
||||||
|
rm -f VERSION.txt
|
||||||
|
|
||||||
|
namespace:
|
||||||
|
kubectl config set-context --current --namespace=CHANGEME-desktop-dev
|
||||||
|
|
||||||
|
pep8:
|
||||||
|
flake8 src/ tests/
|
||||||
|
|
||||||
|
rebuild:
|
||||||
|
skaffold build -p rebuild
|
||||||
|
|
||||||
|
run:
|
||||||
|
skaffold run --tail
|
||||||
|
|
||||||
|
static-checks: pep8
|
||||||
|
|
||||||
|
test:
|
||||||
|
PYTHONPATH=src/ pytest -vv --cov-report term-missing --cov=src
|
||||||
16
README.md
Normal file
16
README.md
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# skeleton-small_project
|
||||||
|
|
||||||
|
Template for "small" project
|
||||||
|
|
||||||
|
* Export it and import as your new project.
|
||||||
|
* Change `small_project` to your project name.
|
||||||
|
|
||||||
|
Make sure `CISCRIPT_API_TOKEN` is available in CI/CD variables.
|
||||||
|
|
||||||
|
If a python package is not needed, you can get rid of:
|
||||||
|
* `MANIFEST.in`
|
||||||
|
* `pyproject.toml`
|
||||||
|
* `setup.cfg`
|
||||||
|
* `Makefile`: `build-pkg`
|
||||||
|
|
||||||
|
Fill your project name in `CHANGEME` placeholder in `Makefile`.
|
||||||
0
incoming_changes/.keep
Normal file
0
incoming_changes/.keep
Normal file
6
pyproject.toml
Normal file
6
pyproject.toml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
[build-system]
|
||||||
|
requires = [
|
||||||
|
"setuptools>=42",
|
||||||
|
"wheel"
|
||||||
|
]
|
||||||
|
build-backend = "setuptools.build_meta"
|
||||||
4
requirements.txt
Normal file
4
requirements.txt
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# tests
|
||||||
|
flake8
|
||||||
|
pytest
|
||||||
|
pytest-cov
|
||||||
0
scripts/__init__.py
Normal file
0
scripts/__init__.py
Normal file
16
scripts/create_change_file.sh
Executable file
16
scripts/create_change_file.sh
Executable file
@@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
BRANCH=`git rev-parse --abbrev-ref HEAD`
|
||||||
|
if [ "x${BRANCH}" != "x" ] && [ "${BRANCH}" != "HEAD" ]
|
||||||
|
then
|
||||||
|
FILE="incoming_changes/${BRANCH}.md"
|
||||||
|
if [ -e $FILE ]
|
||||||
|
then
|
||||||
|
echo "file '${FILE}' already exists"
|
||||||
|
else
|
||||||
|
touch "${FILE}"
|
||||||
|
echo "file '${FILE}' created"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "branch name '${BRANCH}' is not valid"
|
||||||
|
fi
|
||||||
174
scripts/release.py
Executable file
174
scripts/release.py
Executable file
@@ -0,0 +1,174 @@
|
|||||||
|
#!/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()
|
||||||
47
scripts/start_pre_release_build.py
Executable file
47
scripts/start_pre_release_build.py
Executable file
@@ -0,0 +1,47 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import requests
|
||||||
|
import semver
|
||||||
|
|
||||||
|
|
||||||
|
def start_pre_release_build():
|
||||||
|
gitlab_project_id = os.environ["CI_PROJECT_ID"]
|
||||||
|
api_token = os.environ["CISCRIPT_API_TOKEN"]
|
||||||
|
branch = os.environ["CI_COMMIT_BRANCH"]
|
||||||
|
print(f"branch '{branch}'")
|
||||||
|
major_version = minor_version = 0
|
||||||
|
patch_version = int(os.environ["CI_PIPELINE_ID"])
|
||||||
|
commit_short_sha = os.environ["CI_COMMIT_SHORT_SHA"]
|
||||||
|
future_version = str(
|
||||||
|
semver.VersionInfo(
|
||||||
|
major=major_version,
|
||||||
|
minor=minor_version,
|
||||||
|
patch=patch_version,
|
||||||
|
prerelease="beta",
|
||||||
|
build=commit_short_sha,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
future_tag_name = f"v{future_version}"
|
||||||
|
print(f"future tag name '{future_tag_name}'")
|
||||||
|
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}', json '{response.json()}'"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
start_pre_release_build()
|
||||||
20
setup.cfg
Normal file
20
setup.cfg
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
[metadata]
|
||||||
|
name = small_project
|
||||||
|
version = file: VERSION.txt
|
||||||
|
author = Princip a. s.
|
||||||
|
author_email = lab-sw@eurowag.com
|
||||||
|
description = TBD
|
||||||
|
long_description = file: README.md
|
||||||
|
long_description_content_type = text/markdown
|
||||||
|
url = https://gitlab.princip.cz/lab/sw/small_project
|
||||||
|
classifiers =
|
||||||
|
Programming Language :: Python :: 3
|
||||||
|
|
||||||
|
[options]
|
||||||
|
package_dir =
|
||||||
|
= src
|
||||||
|
packages = find:
|
||||||
|
python_requires = >=3.9
|
||||||
|
|
||||||
|
[options.packages.find]
|
||||||
|
where = src
|
||||||
0
tests/.keep
Normal file
0
tests/.keep
Normal file
2
tests/test_placeholder.py
Normal file
2
tests/test_placeholder.py
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
def test_placeholder():
|
||||||
|
"Replace me with the real deal..."
|
||||||
Reference in New Issue
Block a user