Skip to content

Commit e128bcd

Browse files
author
Jozef Volak
committed
Add services api and github actions
1 parent 0c81db9 commit e128bcd

File tree

168 files changed

+14186
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

168 files changed

+14186
-0
lines changed

.github/scripts/bump-version

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#!/bin/env python3
2+
3+
"""
4+
This script provides a utility for semantic versioning.
5+
6+
It allows you to determine the version change type (MAJOR, MINOR, PATCH)
7+
based on comparing old and new versions, and also bump the version
8+
accordingly.
9+
10+
Usage:
11+
python bump-version --last-image 1.0.0 --new-image 2.0.1 --last-lib 1.0.0
12+
13+
Output:
14+
LEVEL=MAJOR
15+
VERSION=2.0.0
16+
"""
17+
18+
import argparse
19+
from enum import Enum
20+
21+
22+
class SemanticVersion(Enum):
23+
PATCH = 'patch'
24+
MINOR = 'minor'
25+
MAJOR = 'major'
26+
27+
28+
def parse_version(version: str):
29+
major, minor, patch = map(int, version.split('.'))
30+
return major, minor, patch
31+
32+
33+
def get_version_change(old_version: str, new_version: str):
34+
old_major, old_minor, old_patch = parse_version(old_version)
35+
new_major, new_minor, new_patch = parse_version(new_version)
36+
37+
if new_major > old_major:
38+
return SemanticVersion.MAJOR
39+
elif new_minor > old_minor:
40+
return SemanticVersion.MINOR
41+
elif new_patch > old_patch:
42+
return SemanticVersion.PATCH
43+
44+
45+
def bump_version(old_version: str, version_change: SemanticVersion):
46+
major, minor, patch = parse_version(old_version)
47+
48+
if version_change is SemanticVersion.PATCH:
49+
patch += 1
50+
elif version_change is SemanticVersion.MINOR:
51+
minor += 1
52+
patch = 0
53+
elif version_change is SemanticVersion.MAJOR:
54+
major += 1
55+
minor = 0
56+
patch = 0
57+
58+
return f"{major}.{minor}.{patch}"
59+
60+
61+
def main():
62+
parser = argparse.ArgumentParser(description="Semantic Versioning Utility")
63+
parser.add_argument("--last-image", type=str, required=True, help="Old docker image version")
64+
parser.add_argument("--new-image", type=str, required=True, help="New docker image version")
65+
parser.add_argument("--last-lib", type=str, required=True, help="Old package version")
66+
parser.add_argument("--output", type=str, default='VERSION', choices=['VERSION', 'LEVEL'], help="Old package version")
67+
68+
args = parser.parse_args()
69+
70+
version_change = get_version_change(args.last_image, args.new_image)
71+
bumped_version = bump_version(args.last_lib, version_change)
72+
73+
if args.output == "VERSION":
74+
print(bumped_version)
75+
elif args.output == "LEVEL":
76+
print(version_change)
77+
78+
79+
if __name__ == "__main__":
80+
main()
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#!/usr/bin/env python3
2+
3+
"""
4+
This script finds the nearest lower version of a Docker image in the release matrix table
5+
based on the provided version.
6+
7+
Usage:
8+
python find_nearest_lower_version.py --version 4.5.2 --path RELEASE.md
9+
10+
Example:
11+
python find_nearest_lower_version.py --version 4.5.2 --path RELEASE.md
12+
13+
Input:
14+
--image-tag: Version to find the nearest lower version for.
15+
--path: Path to the RELEASE.md file.
16+
17+
Output:
18+
The nearest lower version of the Docker image based on the provided version.
19+
"""
20+
21+
import re
22+
import argparse
23+
import sys
24+
from typing import Any
25+
from enum import Enum
26+
27+
28+
class Exit(Enum):
29+
OK = 0
30+
ERROR = 1
31+
32+
33+
def find_lower_versions(version: str, release_file: str) -> Any:
34+
table_pattern = re.compile(r'\| Docker Image Tag \| Python Library Version \|\n\|(.+)\n', re.DOTALL)
35+
match = table_pattern.search(release_file)
36+
if match:
37+
table = match.group(1).strip().split("\n")
38+
table = table[1:]
39+
lower_version: dict[str, Any] = {}
40+
for row in table:
41+
docker_version = row.split('|')[1]
42+
lib_version = row.split('|')[2]
43+
if docker_version.strip() < version:
44+
lower_version = dict(
45+
docker=docker_version.strip(),
46+
lib=lib_version.strip(),
47+
)
48+
elif docker_version.strip() == version:
49+
print(f'Version {version} already exist')
50+
raise Exception()
51+
return lower_version
52+
53+
54+
def main() -> Exit:
55+
parser = argparse.ArgumentParser(description="Find nearest lower version of Docker image")
56+
parser.add_argument("--image-tag", type=str, required=True, help="Version")
57+
parser.add_argument("--path", type=str, required=True, help="RELEASE.md path")
58+
59+
args = parser.parse_args()
60+
61+
try:
62+
with open(args.path, 'r') as f:
63+
content = f.read()
64+
65+
version = find_lower_versions(args.image_tag, content)
66+
67+
print(f'LAST_DOCKER_TAG={version.get("docker", args.image_tag)}')
68+
print(f'LAST_LIB_VERSION={version.get("lib", "1.0.0")}')
69+
70+
except Exception:
71+
return Exit.ERROR
72+
73+
74+
if __name__ == '__main__':
75+
sys.exit(main())
76+
77+

.github/scripts/release-update

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#!/bin/env python3
2+
3+
"""
4+
This script updates the release matrix table in a RELEASE.md file
5+
by adding a new row with the specified Docker image tag and Python library version.
6+
7+
Usage:
8+
python release-update.py --image-tag 4.0.0 --lib-version 2.0.0 --path RELEASE.md
9+
10+
Example:
11+
python release-update.py --image-tag 4.0.0 --lib-version 2.0.0 --path RELEASE.md
12+
13+
Input:
14+
--image-tag: Docker image tag.
15+
--lib-version: Python library version.
16+
--path: Path to the RELEASE.md file.
17+
18+
Output:
19+
The specified RELEASE.md file will be updated with the new row in the release matrix table.
20+
"""
21+
22+
23+
import re
24+
import argparse
25+
26+
27+
def find_insertion_index(table, version):
28+
for i, row in enumerate(table):
29+
docker_version = row.split('|')[1].strip()
30+
if docker_version >= version:
31+
return i
32+
return len(table)
33+
34+
35+
def update_release_matrix(release_file: str, image_tag: str, lib_version: str) -> None:
36+
with open(release_file, 'r') as f:
37+
content = f.read()
38+
39+
table_pattern = re.compile(r'\| Docker Image Tag \| Python Library Version \|\n\|(.+)', re.DOTALL)
40+
match = table_pattern.search(content)
41+
42+
if match:
43+
table = match.group(1).strip().split("\n")
44+
new_row = f"| {image_tag} | {lib_version} |"
45+
insertion_index = find_insertion_index(table, image_tag)
46+
47+
table.insert(insertion_index, new_row)
48+
updated_table = "\n".join(table)
49+
updated_content = content.replace(table_pattern.search(content).group(1), updated_table)
50+
with open(release_file, 'w') as f:
51+
f.write(updated_content)
52+
53+
else:
54+
print("Table not found in the release file.")
55+
56+
57+
def main():
58+
parser = argparse.ArgumentParser(description="Update release table with new package")
59+
parser.add_argument("--image-tag", type=str, required=True, help="Docker tag")
60+
parser.add_argument("--lib-version", type=str, required=True, help="Python library version")
61+
parser.add_argument("--path", type=str, required=True, help="RELEASE.md path")
62+
63+
args = parser.parse_args()
64+
update_release_matrix(release_file=args.path, image_tag=args.image_tag, lib_version=args.lib_version)
65+
66+
67+
if __name__ == "__main__":
68+
main()

.github/workflows/pr-check.yml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: pr-check
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- main
7+
workflow_dispatch:
8+
9+
jobs:
10+
codespell:
11+
name: Codespell
12+
runs-on: ubuntu-latest
13+
timeout-minutes: 5
14+
steps:
15+
- uses: actions/checkout@v3
16+
- name: Codespell
17+
uses: codespell-project/actions-codespell@master
18+
with:
19+
ignore_words_list: test
20+
check_filenames: true
21+
check_hidden: false
22+
23+
code-validate:
24+
name: Validate code
25+
runs-on: ubuntu-latest
26+
steps:
27+
- uses: actions/checkout@v3
28+
- uses: actions/setup-python@v4
29+
with:
30+
python-version: "3.10"
31+
- run: pip3 install -r requirements.txt
32+
- run: python3 -m ruff .

.github/workflows/pr-create.yml

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
name: pr-create
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
image:
7+
description: 'Docker image name, eg: frinx/schellar:3.0.0'
8+
required: true
9+
10+
jobs:
11+
generate-api-from-image:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v3
15+
- name: Parse docker
16+
run: |
17+
echo "IMAGE_NAMESPACE=$(echo $IMAGE | cut -d '/' -f 1)" >> "$GITHUB_ENV"
18+
echo "IMAGE_REPO=$(echo $IMAGE | cut -d '/' -f 2 | cut -d ':' -f 1)" >> "$GITHUB_ENV"
19+
echo "IMAGE_TAG=$(echo $IMAGE | cut -d ':' -f 2)" >> "$GITHUB_ENV"
20+
env:
21+
IMAGE: ${{ inputs.image }}
22+
- name: Validate input
23+
run: |
24+
echo ${IMAGE_NAMESPACE}
25+
if [[ "${IMAGE_NAMESPACE}" != "frinx" ]]; then
26+
echo "Only images from frinx namespace can be used!"
27+
exit 1
28+
fi
29+
30+
# Semantic version regex pattern
31+
semantic_version_pattern='^[0-9]+\.[0-9]+\.[0-9]+$'
32+
33+
if [[ "${IMAGE_TAG}" =~ $semantic_version_pattern ]]; then
34+
echo "Valid semantic version: ${IMAGE_TAG}"
35+
else
36+
echo "Invalid semantic version: ${IMAGE_TAG}"
37+
exit 1
38+
fi
39+
40+
- name: Start service
41+
run: |
42+
echo "${IMAGE_NAMESPACE} ${IMAGE_REPO} ${IMAGE_TAG}"
43+
docker compose -f ${IMAGE_REPO}/python/docker-compose.yml up -d
44+
45+
- uses: actions/setup-python@v4
46+
with:
47+
python-version: "3.10"
48+
49+
- name: Run image
50+
uses: abatilo/actions-poetry@v2
51+
with:
52+
poetry-version: "1.4.2"
53+
54+
- name: Formatting and validating
55+
run: |
56+
pushd ${IMAGE_REPO}/python/ || exit 1
57+
poetry install
58+
poetry run ruff --fix .
59+
poetry run mypy .
60+
poetry run pyright .
61+
popd || exit 1
62+
63+
- name: Check changed files
64+
uses: tj-actions/verify-changed-files@v16
65+
id: verify-changed-files
66+
67+
- name: Update changelog
68+
if: steps.verify-changed-files.outputs.files_changed == 'true'
69+
run: |
70+
SCRIPT_PATH=".github/scripts"
71+
72+
export $(${SCRIPT_PATH}/find-nearest-lower-version \
73+
--image-tag ${IMAGE_TAG} \
74+
--path ${IMAGE_REPO}/python/RELEASE.md)
75+
76+
echo $LAST_DOCKER_TAG $LAST_LIB_VERSION
77+
78+
LIB_VERSION=$(${SCRIPT_PATH}/bump-version \
79+
--last-image ${LAST_DOCKER_TAG} \
80+
--new-image ${IMAGE_TAG} \
81+
--last-lib ${LAST_LIB_VERSION})
82+
83+
${SCRIPT_PATH}/release-update \
84+
--image-tag ${IMAGE_TAG} \
85+
--lib-version ${LIB_VERSION} \
86+
--path ${IMAGE_REPO}/python/RELEASE.md
87+
88+
sed -i "s/^version = \"[^\"]*\"/version = \"${LIB_VERSION}\"/g" ${IMAGE_REPO}/python/pyproject.toml
89+
90+
- uses: tibdex/github-app-token@v1
91+
if: steps.verify-changed-files.outputs.files_changed == 'true'
92+
id: generate-token
93+
with:
94+
app_id: ${{ secrets.APP_ID }}
95+
private_key: ${{ secrets.APP_PRIVATE_KEY }}
96+
- name: Create Pull Request
97+
if: steps.verify-changed-files.outputs.files_changed == 'true'
98+
uses: peter-evans/create-pull-request@v5
99+
with:
100+
title: "[${{ env.IMAGE_REPO }}] Release package for ${{ inputs.image }}"
101+
commit-message: "[${{ env.IMAGE_REPO }}] Create and publish packages for ${{ env.IMAGE_TAG }}"
102+
branch-suffix: timestamp
103+
labels: automated-pr
104+
delete-branch: true
105+
reviewers: Jozefiel
106+
body: |
107+
Create and publish packages for ${{ env.IMAGE_REPO }}
108+
token: ${{ steps.generate-token.outputs.token }}

0 commit comments

Comments
 (0)