Skip to content

Commit 3c3061a

Browse files
committed
Add support to create pre-releases with a generated changelog
Signed-off-by: Tobias Wolf <wolf@b1-systems.de> On-behalf-of: SAP <tobias.wolf@sap.com>
1 parent 95a3985 commit 3c3061a

File tree

15 files changed

+942
-390
lines changed

15 files changed

+942
-390
lines changed

.github/actions/features_parse/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ outputs:
1111
runs:
1212
using: composite
1313
steps:
14-
- uses: gardenlinux/python-gardenlinux-lib/.github/actions/setup@0.10.8
14+
- uses: gardenlinux/python-gardenlinux-lib/.github/actions/setup@0.10.9
1515
- id: result
1616
shell: bash
1717
run: |

.github/actions/flavors_parse/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ outputs:
1313
runs:
1414
using: composite
1515
steps:
16-
- uses: gardenlinux/python-gardenlinux-lib/.github/actions/setup@0.10.8
16+
- uses: gardenlinux/python-gardenlinux-lib/.github/actions/setup@0.10.9
1717
- id: matrix
1818
shell: bash
1919
run: |

.github/actions/setup/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ description: Installs the given GardenLinux Python library
44
inputs:
55
version:
66
description: GardenLinux Python library version
7-
default: "0.10.8"
7+
default: "0.10.9"
88
python_version:
99
description: Python version to setup
1010
default: "3.13"

.github/workflows/release.yml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
name: pre-release
2+
3+
on:
4+
push:
5+
tags: [ "[0-9]+.[0-9]+.[0-9]+*" ]
6+
7+
jobs:
8+
create-pre-release:
9+
runs-on: ubuntu-latest
10+
permissions:
11+
contents: write
12+
13+
steps:
14+
- name: Checkout commit
15+
uses: actions/checkout@v6
16+
with:
17+
sparse-checkout: |
18+
cliff.toml
19+
sparse-checkout-cone-mode: false
20+
- uses: gardenlinux/python-gardenlinux-lib/.github/actions/setup@main
21+
with:
22+
version: 1.0.0-pre1
23+
- name: Use cargo cache
24+
id: cache-cargo
25+
uses: actions/cache@v4
26+
with:
27+
path: |
28+
~/.cargo
29+
key: gh-release-${{ runner.os }}-cargo-${{ hashFiles('~/.cargo/.crates.toml') }}
30+
restore-keys: gh-release-${{ runner.os }}-cargo-
31+
- name: Install git-cliff
32+
if: steps.cache-cargo.outputs.cache-hit != 'true'
33+
run: |
34+
cargo install git-cliff
35+
- name: Get the Git tag name
36+
id: get-tag-name
37+
run: echo "tag-name=${GITHUB_REF/refs\/tags\//}" | tee -a "$GITHUB_OUTPUT"
38+
- id: release
39+
name: Create changelog and release
40+
env:
41+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
42+
run: |
43+
gl-gh-release create \
44+
--repo "python-gardenlinux-lib" \
45+
--tag "${{ steps.get-tag-name.outputs.tag-name }}" \
46+
--commit "${{ github.sha }}" \
47+
--name 'python-gardenlinux-lib v${{ steps.get-tag-name.outputs.tag-name }}' \
48+
--latest \
49+
--body "
50+
$(git-cliff -o - --current)
51+
"

poetry.lock

Lines changed: 317 additions & 248 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,31 @@
11
[tool.poetry]
22
name = "gardenlinux"
3-
version = "0.10.8"
3+
version = "0.10.9"
44
description = "Contains tools to work with the features directory of gardenlinux, for example deducting dependencies from feature sets or validating cnames"
55
authors = ["Garden Linux Maintainers <contact@gardenlinux.io>"]
66
license = "Apache-2.0"
77
readme = "README.md"
88
packages = [{ include = "gardenlinux", from = "src" }]
99

1010
[tool.poetry.dependencies]
11-
python = ">=3.13, <3.14"
11+
python = ">=3.13,!=3.14.1"
1212
apt-repo = "^0.5"
13-
boto3 = "^1.42.10"
13+
boto3 = "^1.42.30"
1414
click = "^8.3.1"
1515
cryptography = "^46.0.3"
16-
jsonschema = "^4.25.1"
16+
jsonschema = "^4.26.0"
1717
networkx = "^3.6"
1818
oras = "^0.2.38"
19-
pygit2 = "^1.19.0"
19+
pygit2 = "^1.19.1"
2020
pygments = "^2.19.2"
21+
PyGithub = "^2.8.1"
2122
PyYAML = "^6.0.2"
2223
gitpython = "^3.1.45"
2324

2425
[tool.poetry.group.dev.dependencies]
25-
bandit = "^1.9.2"
26-
moto = "^5.1.16"
27-
pre-commit = "^4.5.0"
26+
bandit = "^1.9.3"
27+
moto = "^5.1.20"
28+
pre-commit = "^4.5.1"
2829
python-dotenv = "^1.2.1"
2930
pytest = "^9.0.2"
3031
pytest-cov = "^7.0.0"
@@ -34,7 +35,7 @@ mypy = "1.18.2"
3435
types-click = "^7.1.8"
3536
types-pyyaml = "^6.0.12.20250915"
3637
types-requests = "^2.32.4.20260107"
37-
boto3-stubs = { extras = ["s3"], version = "^1.42.25" }
38+
boto3-stubs = { extras = ["s3"], version = "^1.42.30" }
3839

3940
[tool.poetry.group.docs.dependencies]
4041
sphinx-rtd-theme = "^3.0.2"

src/gardenlinux/github/__init__.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# -*- coding: utf-8 -*-
2+
3+
"""
4+
GitHub module
5+
"""
6+
7+
from .client import Client
8+
9+
__all__ = ["Client"]

src/gardenlinux/github/client.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# -*- coding: utf-8 -*-
2+
3+
"""
4+
GitHub client
5+
"""
6+
7+
from logging import Logger
8+
from os import environ
9+
from typing import Any, Optional
10+
11+
from github import Auth, Github
12+
13+
from ..logger import LoggerSetup
14+
15+
16+
class Client(object):
17+
"""
18+
GitHub client instance to provide methods for interaction with GitHub API.
19+
20+
:author: Garden Linux Maintainers
21+
:copyright: Copyright 2024 SAP SE
22+
:package: gardenlinux
23+
:subpackage: github
24+
:since: 1.0.0
25+
:license: https://www.apache.org/licenses/LICENSE-2.0
26+
Apache License, Version 2.0
27+
"""
28+
29+
def __init__(self, token: Optional[str] = None, logger: Optional[Logger] = None):
30+
"""
31+
Constructor __init__(Client)
32+
33+
:param token: GitHub access token
34+
:param logger: Logger instance
35+
36+
:since: 1.0.0
37+
"""
38+
39+
self._client = None
40+
self._token = token
41+
42+
if self._token is None or self._token.strip() == "":
43+
self._token = environ.get("GITHUB_TOKEN")
44+
45+
if self._token is None:
46+
raise ValueError("GITHUB_TOKEN environment variable not set")
47+
48+
if logger is None or not logger.hasHandlers():
49+
logger = LoggerSetup.get_logger("gardenlinux.github")
50+
51+
self._logger = logger
52+
53+
@property
54+
def instance(self) -> Github:
55+
if self._client is None:
56+
self._client = Github(auth=Auth.Token(self._token))
57+
58+
return self._client
59+
60+
def __getattr__(self, name: str) -> Any:
61+
"""
62+
python.org: Called when an attribute lookup has not found the attribute in
63+
the usual places (i.e. it is not an instance attribute nor is it found in the
64+
class tree for self).
65+
66+
:param name: Attribute name
67+
68+
:return: (mixed) Attribute
69+
:since: 0.8.0
70+
"""
71+
72+
self._logger.debug(f"gardenlinux.github.Client.{name} accessed")
73+
return getattr(self.instance, name)

src/gardenlinux/github/release/__init__.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55

66
import requests
77

8-
from gardenlinux.constants import RELEASE_ID_FILE, REQUESTS_TIMEOUTS
9-
from gardenlinux.logger import LoggerSetup
8+
from ...constants import RELEASE_ID_FILE, REQUESTS_TIMEOUTS
9+
from ...logger import LoggerSetup
10+
from .release import Release
1011

1112
LOGGER = LoggerSetup.get_logger("gardenlinux.github.release", logging.INFO)
1213

@@ -103,3 +104,6 @@ def upload_to_github_release_page(
103104
f"Upload failed with status code {response.status_code}: {response.text}"
104105
)
105106
response.raise_for_status()
107+
108+
109+
__all__ = ["Release", "write_to_release_id_file", "upload_to_github_release_page"]

src/gardenlinux/github/release/__main__.py

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66

77
from ..release_notes import create_github_release_notes
88
from . import (
9-
create_github_release,
109
upload_to_github_release_page,
1110
write_to_release_id_file,
1211
)
12+
from .release import Release
1313

1414
LOGGER = LoggerSetup.get_logger("gardenlinux.github", logging.INFO)
1515

@@ -22,9 +22,19 @@ def main() -> None:
2222
create_parser.add_argument("--owner", default="gardenlinux")
2323
create_parser.add_argument("--repo", default="gardenlinux")
2424
create_parser.add_argument("--tag", required=True)
25-
create_parser.add_argument("--commit", required=True)
25+
create_parser.add_argument("--name")
26+
create_parser.add_argument("--body", required=True)
27+
create_parser.add_argument("--commit")
28+
create_parser.add_argument("--pre-release", action="store_true", default=True)
2629
create_parser.add_argument("--latest", action="store_true", default=False)
27-
create_parser.add_argument("--dry-run", action="store_true", default=False)
30+
31+
create_parser_gl = subparsers.add_parser("create-with-gl-release-notes")
32+
create_parser_gl.add_argument("--owner", default="gardenlinux")
33+
create_parser_gl.add_argument("--repo", default="gardenlinux")
34+
create_parser_gl.add_argument("--tag", required=True)
35+
create_parser_gl.add_argument("--commit", required=True)
36+
create_parser_gl.add_argument("--latest", action="store_true", default=False)
37+
create_parser_gl.add_argument("--dry-run", action="store_true", default=False)
2838

2939
upload_parser = subparsers.add_parser("upload")
3040
upload_parser.add_argument("--owner", default="gardenlinux")
@@ -36,6 +46,15 @@ def main() -> None:
3646
args = parser.parse_args()
3747

3848
if args.command == "create":
49+
release = Release(args.repo, args.owner)
50+
release.tag = args.tag
51+
release.name = args.name
52+
release.body = args.body
53+
release.commit_hash = args.commit
54+
release.is_pre_release = args.pre_release
55+
release.is_latest = args.latest
56+
release.create()
57+
elif args.command == "create-with-gl-release-notes":
3958
body = create_github_release_notes(
4059
args.tag, args.commit, GARDENLINUX_GITHUB_RELEASE_BUCKET_NAME
4160
)
@@ -44,9 +63,13 @@ def main() -> None:
4463
print("This release would be created:")
4564
print(body)
4665
else:
47-
release_id = create_github_release(
48-
args.owner, args.repo, args.tag, args.commit, args.latest, body
49-
)
66+
release = Release(args.repo, args.owner)
67+
release.tag = args.tag
68+
release.body = body
69+
release.commit_hash = args.commit
70+
release.is_latest = args.latest
71+
72+
release_id = release.create()
5073
write_to_release_id_file(f"{release_id}")
5174
LOGGER.info(f"Release created with ID: {release_id}")
5275
elif args.command == "upload":

0 commit comments

Comments
 (0)