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
2 changes: 1 addition & 1 deletion .github/actions/security-issues/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ runs:
- name: Install Python Toolbox / Security tool
shell: bash
run: |
pip install exasol-toolbox==0.8.0
pip install exasol-toolbox==1.0.0

- name: Create Security Issue Report
shell: bash
Expand Down
9 changes: 1 addition & 8 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,21 +40,16 @@ jobs:
Changelog:
name: Changelog Update Check
runs-on: ubuntu-24.04
if: ${{ github.ref != 'refs/heads/main' && github.ref != 'refs/heads/master' }}

steps:
- name: SCM Checkout
uses: actions/checkout@v4

- name: Fetch the main branch
run: git fetch origin main

- name: Setup Python & Poetry Environment
uses: ./.github/actions/python-environment
with:
python-version: "3.9"

- name: Run changelog update check
if: ${{ github.ref != 'refs/heads/main' }}
run: poetry run -- nox -s changelog:updated

build-matrix:
Expand Down Expand Up @@ -147,8 +142,6 @@ jobs:

- name: Setup Python & Poetry Environment
uses: ./.github/actions/python-environment
with:
python-version: "3.9"

- name: Run format check
run: poetry run -- nox -s project:format
Expand Down
6 changes: 5 additions & 1 deletion doc/changes/unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,8 @@

## Bugfixes

* #397: Fix handling empty coverage
* #397: Fixed handling empty coverage

## Refactorings

* #399: Modified `release:prepare` to update `.github/actions` with new PTB version
4 changes: 2 additions & 2 deletions exasol/toolbox/nox/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def prepare_release_update_version(self, session, config, version):
@hookspec
def prepare_release_add_files(self, session, config):
"""
Files which should be added to the prepare relase commit should be added using add.
Files which should be added to the prepare release commit should be added using add.

Args:
session (nox.Session):
Expand All @@ -64,7 +64,7 @@ def pre_integration_tests_hook(self, session, config, context):

This function acts as a hook that gets called before the execution of integration tests.
It can be used to execute any project-specific tasks that need to be performed before
the tests run, such as starting or initalizing a database.
the tests run, such as starting or initializing a database.

Args:
session (nox.Session):
Expand Down
7 changes: 2 additions & 5 deletions exasol/toolbox/templates/github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,14 @@ jobs:
Changelog:
name: Changelog Update Check
runs-on: ubuntu-24.04
if: ${{ github.ref != 'refs/heads/main' && github.ref != 'refs/heads/master' }}

steps:
- name: SCM Checkout
uses: actions/checkout@v4

- name: Setup Python & Poetry Environment
uses: ./.github/actions/python-environment
with:
python-version: "3.9"
uses: exasol/python-toolbox/.github/actions/[email protected]

- name: Run changelog update check
run: poetry run -- nox -s changelog:updated
Expand Down Expand Up @@ -149,8 +148,6 @@ jobs:

- name: Setup Python & Poetry Environment
uses: exasol/python-toolbox/.github/actions/[email protected]
with:
python-version: "3.9"

- name: Run format check
run: poetry run -- nox -s project:format
Expand Down
63 changes: 44 additions & 19 deletions exasol/toolbox/tools/replace_version.py
Original file line number Diff line number Diff line change
@@ -1,34 +1,59 @@
import re
from dataclasses import dataclass
from enum import Enum
from pathlib import Path
from typing import List


def update_workflow(template: Path, version: str) -> None:
"""Updates versions of XYZ in GitHub workflow ..."""
def update_github_yml(template: Path, version: str) -> None:
"""Updates versions in GitHub workflows and actions"""
with open(template, encoding="utf-8") as file:
content = file.readlines()

content = update_versions(
lines=content, matcher="exasol/python-toolbox/.github/", version=version
)
content = update_versions(lines=content, version=version)

with open(template, "w", encoding="utf-8") as file:
file.writelines(content)


def is_update_required(line, matcher):
return matcher in line and "@" in line
@dataclass(frozen=True)
class Pattern:
match_pattern: str
break_pattern: str

@property
def version_pattern(self) -> str:
return r"[0-9]+\.[0-9]+\.[0-9]+"

@property
def full_pattern(self) -> str:
return f"{self.match_pattern}{self.break_pattern}{self.version_pattern}"

def replace_version(self, line: str, version: str) -> str:
return re.sub(
f"{self.break_pattern}{self.version_pattern}",
f"{self.break_pattern}{version}",
line,
)


class ToolboxPattern(Enum):
github = Pattern(
match_pattern="exasol/python-toolbox/.github/[^/]+/[^/]+",
break_pattern="@",
)
pypi = Pattern(
match_pattern="exasol-toolbox",
break_pattern="==",
)


def update_version(line, version):
keep = line[: line.index("@") + 1]
updated = f"{version}\n"
return f"{keep}{updated}"
def _update_line_with_version(line: str, version: str) -> str:
for pattern in ToolboxPattern:
match = re.search(pattern.value.full_pattern, line)
if match:
return pattern.value.replace_version(line=line, version=version)
return line


def update_versions(lines, matcher, version) -> list[str]:
result = []
for line in lines:
if is_update_required(line, matcher):
line = update_version(line, version)
result.append(line)
return result
def update_versions(lines: list[str], version: str) -> list[str]:
return [_update_line_with_version(line=line, version=version) for line in lines]
2 changes: 1 addition & 1 deletion exasol/toolbox/tools/workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def update_workflow(
Path("./.github/workflows"), help="target directory to install the workflow to."
),
confirm: bool = typer.Option(
False, help="Automatically confirm overwritting exsisting workflow(s)"
False, help="Automatically confirm overwriting the existing workflow(s)"
),
) -> None:
"""Similar to install but checks for existing workflows and shows diff"""
Expand Down
22 changes: 15 additions & 7 deletions noxconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,34 @@
from pathlib import Path

from exasol.toolbox.nox.plugin import hookimpl
from exasol.toolbox.tools.replace_version import update_workflow
from exasol.toolbox.tools.replace_version import update_github_yml


class UpdateTemplates:
TEMPLATE_PATH: Path = Path(__file__).parent / "exasol" / "toolbox" / "templates"
PARENT_PATH: Path = Path(__file__).parent

@property
def workflows(self):
def template_workflows(self) -> list[Path]:
gh_workflows = self.TEMPLATE_PATH / "github" / "workflows"
gh_workflows = [f for f in gh_workflows.iterdir() if f.is_file()]
return gh_workflows
return [f for f in gh_workflows.iterdir() if f.is_file()]

@property
def actions(self) -> list[Path]:
gh_actions = self.PARENT_PATH / ".github" / "actions"
return [f for f in gh_actions.rglob("*") if f.is_file()]

@hookimpl
def prepare_release_update_version(self, session, config, version):
for workflow in self.workflows:
update_workflow(workflow, version)
for workflow in self.template_workflows:
update_github_yml(workflow, version)

for action in self.actions:
update_github_yml(action, version)

@hookimpl
def prepare_release_add_files(self, session, config):
return self.workflows
return self.template_workflows + self.actions


@dataclass(frozen=True)
Expand Down
80 changes: 40 additions & 40 deletions test/unit/replace_version_test.py
Original file line number Diff line number Diff line change
@@ -1,59 +1,59 @@
import pytest

from exasol.toolbox.tools.replace_version import (
is_update_required,
update_version,
_update_line_with_version,
update_versions,
)


@pytest.mark.parametrize(
"line,matcher,expected",
"line,expected",
[
("hallo/world@all", "hallo", True),
("hallo/world@all", "foo", False),
("hallo/world/all", "hallo", False),
("hallo/world/all", "foo", False),
pytest.param(
"exasol/python-toolbox/.github/actions/[email protected]",
"exasol/python-toolbox/.github/actions/[email protected]",
id="github_action",
),
pytest.param(
"pip install exasol-toolbox==1.0.0\n",
"pip install exasol-toolbox==2.0.0\n",
id="pypi_version",
),
pytest.param(
"- name: Create Security Issue Report",
"- name: Create Security Issue Report",
id="no_change_expected",
),
],
)
def test_is_update_required(line, matcher, expected):
actual = is_update_required(line, matcher)
def test_update_line_with_version(line: str, expected: str):
actual = _update_line_with_version(line=line, version="2.0.0")
assert actual == expected


@pytest.mark.parametrize(
"line,version,expected",
"line_to_change, expected",
[
("hallo/[email protected]\n", "2.3.4", "hallo/[email protected]\n"),
("hallo/[email protected]\n", "9.9.9", "hallo/[email protected]\n"),
pytest.param(
"exasol/python-toolbox/.github/actions/[email protected]",
"exasol/python-toolbox/.github/actions/[email protected]",
id="github_action",
),
pytest.param(
"pip install exasol-toolbox==1.0.0\n",
"pip install exasol-toolbox==2.0.0\n",
id="pypi_version",
),
],
)
def test_update_version(line, version, expected):
actual = update_version(line, version)
assert actual == expected

def test_update_versions(line_to_change, expected):
dummy_lines = [
"exasol/python-toolbox/.github/actions/python-environment@dummy\n",
"- name: Create Security Issue Report\n",
"pip install exasol-toolbox==dummy\n",
]
lines = dummy_lines + [line_to_change]
expected_lines = dummy_lines + [expected]

@pytest.mark.parametrize(
"lines,matcher,version,expected",
[
(
[
"hallo/[email protected]\n",
"foo/[email protected]\n",
"hallo/world/3.4.5\n",
"foo/world/3.4.5\n",
],
"hallo",
"4.5.6",
[
"hallo/[email protected]\n",
"foo/[email protected]\n",
"hallo/world/3.4.5\n",
"foo/world/3.4.5\n",
],
)
],
)
def test_update_versions(lines, matcher, version, expected):
actual = update_versions(lines, matcher, version)
assert actual == expected
actual = update_versions(lines=lines, version="2.0.0")
assert actual == expected_lines