Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/pip package #1

Merged
merged 3 commits into from
Dec 28, 2023
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
50 changes: 42 additions & 8 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Docker Build & Push
name: Build & Push
permissions: write-all

on:
Expand Down Expand Up @@ -41,12 +41,15 @@ jobs:
pip install -U tox
pip install tox
tox

build:
runs-on: ubuntu-latest
needs: unittests
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0

- name: Docker Build
shell: bash
Expand All @@ -55,19 +58,50 @@ jobs:
docker build -t "${{ env.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}" .

- name: Log in to Docker Hub
if: github.ref == 'refs/heads/main'
uses: docker/login-action@v3
with:
username: ${{ env.DOCKER_USERNAME }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: Detect package version
shell: bash
run: |
set -x
PACKAGE_VERSION="$(git tag --contains)"
if [[ "${PACKAGE_VERSION}" == "" ]]; then
PACKAGE_VERSION="$(docker run --rm -v $(pwd):/app -w /app --user "$(id -u):$(id -g)" panpuchkov/pygitver --next-ver)-dev"
PACKAGE_VERSION=$(echo "${PACKAGE_VERSION}" | sed 's/^v*//' )
DOCKER_TAG_LATEST="${PACKAGE_VERSION}"
else
DOCKER_TAG_LATEST="latest"
fi

echo "PACKAGE_VERSION=$PACKAGE_VERSION" >> $GITHUB_ENV
echo "DOCKER_TAG_LATEST=$DOCKER_TAG_LATEST" >> $GITHUB_ENV

- name: Docker Push
shell: bash
run: |
set -x
DOCKER_TAG="$(git tag --contains)"
if [[ "${DOCKER_TAG}" == "" ]]; then
DOCKER_TAG="latest"
# Generate docker tags
IMAGE_NAME_WITH_TAG_VERSION="${{ env.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:${PACKAGE_VERSION}"
IMAGE_NAME_WITH_TAG_LATEST="${{ env.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:${DOCKER_TAG_LATEST}"

# Set docker tag
docker tag "${{ env.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:latest" "${{ env.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:${PACKAGE_VERSION}"
docker push "${IMAGE_NAME_WITH_TAG_VERSION}"

# Push latest if required
if [[ "${IMAGE_NAME_WITH_TAG_LATEST}" != "${IMAGE_NAME_WITH_TAG_LATEST}" ]]; then
docker push "${IMAGE_NAME_WITH_TAG_LATEST}"
fi
IMAGE_NAME_WITH_VERSION="${{ env.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:${DOCKER_TAG}"
docker push "${IMAGE_NAME_WITH_VERSION}"

- name: Pip Build & Push
shell: bash
run: |
set -x
pip install -r requirements-build.txt
python -m build
sudo apt-get -y install twine
twine check dist/*
twine upload --skip-existing -u ${{ secrets.PYPI_USERNAME }} -p ${{ secrets.PYPI_PASSWORD }} dist/* --verbose
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@
.coverage
*/__pycache__/*
venv
dist
*.egg-info
27 changes: 19 additions & 8 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,25 +1,36 @@
################################################################
FROM python:3.12-alpine as build

# Make sure we use the virtualenv:
RUN python -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"

# Install pip requirements
COPY ./requirements.txt /pygitver/requirements.txt
RUN pip install --no-cache-dir -U pip \
&& pip install --no-cache-dir -r /pygitver/requirements.txt
WORKDIR /build-pkg

# Install pip requirements
COPY . /build-pkg

RUN apk add --no-cache git \
&& pip install --no-cache-dir -U pip \
&& pip install --no-cache-dir -r requirements.txt \
&& pip install --no-cache-dir -r requirements-build.txt \
&& rm -rf dist \
&& python -m build \
&& pip install $(ls /build-pkg/dist/pygitver-*.tar.gz) \
&& pip uninstall -r requirements-build.txt -y

################################################################
FROM python:3.12-alpine

ENV PYGITVER_TEMPLATE_CHANGELOG="/pygitver/templates/changelog.tmpl"
ENV PYGITVER_TEMPLATE_CHANGELOG_COMMON="/pygitver/templates/changelog-common.tmpl"
ENV PYGITVER_ROOT="/pygitver"

# Install dependencies
RUN apk add --no-cache git openssh \
&& ln -s /pygitver/pygitver /usr/local/bin/pygitver
RUN apk add --no-cache git openssh

# Copy application code and
COPY ./src /pygitver
COPY ./src/pygitver/templates /pygitver/templates
COPY ./scripts /pygitver/scripts
COPY --from=build /opt/venv /opt/venv

Expand All @@ -28,4 +39,4 @@ WORKDIR /app
# Make sure we use the virtualenv:
ENV PATH="/opt/venv/bin:$PATH"

ENTRYPOINT ["python", "/pygitver/pygitver.py"]
ENTRYPOINT ["pygitver"]
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,24 @@ Features:

# Examples

You may use it as a Python package or a Docker container.

## PIP Package

```shell
$ git tag -l
v0.0.1
v0.0.2
$ pygitver --curr-ver
v0.0.2
$ pygitver --next-ver
v0.0.3

```


## Docker Container

```shell
$ git tag -l
v0.0.1
Expand Down Expand Up @@ -235,3 +253,15 @@ or
```shell
coverage run -m pytest -- ./tests/test_git.py
```

#### Build pip package

Linux
```shell
python3 -m build
```

For `Debian` based OS:
```shell
DEB_PYTHON_INSTALL_LAYOUT=deb_system python3 -m build
```
38 changes: 38 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
[project]
name = "pygitver"
version = "0.1.0-dev"
authors = [
{ name="Yurii Puchkov", email="[email protected]" },
]
license = {text = "GNU General Public License v3 (GPLv3)"}
description = "Manages Git Tag versions and generates ChangeLog"
keywords = ["git tag", "version", "versions", "conventional commit", "semver", "changelog", "changelogs"]
readme = "README.md"
requires-python = ">=3.8"
classifiers = [
"Development Status :: 5 - Production/Stable",
"Environment :: Console",
"Natural Language :: English",
"Programming Language :: Python :: 3",
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
"Operating System :: OS Independent",
]
dependencies = [
"Jinja2==3.1.2"
]


[build-system]
requires = ["setuptools>=63", "wheel"]
build-backend = "setuptools.build_meta"


[project.scripts]
pygitver = "pygitver.pygitver:main"

[metadata]
url = "https://github.com/panpuchkov/pygitver"


[tool.setuptools.package-data]
pygitver = ["*.py", "*.tmpl"]
2 changes: 2 additions & 0 deletions requirements-build.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
build~=1.0
setuptools~=69.0
7 changes: 0 additions & 7 deletions src/pygitver

This file was deleted.

File renamed without changes.
13 changes: 9 additions & 4 deletions src/changelogs_mngr.py → src/pygitver/changelogs_mngr.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os
import pathlib
import json
from git import Git, GitError
from pygitver.git import Git, GitError

from jinja2 import Environment, FileSystemLoader, TemplateNotFound

Expand Down Expand Up @@ -49,9 +50,13 @@ def read_files(self, path: str, file_ext: str = "json"):
self._changelogs["version"] = None
return self._changelogs

def changelog_generate(
self, template_name: str = "templates/changelog-common.tmpl"
) -> str:
def generate(self, template_name: str = "") -> str:
if not template_name:
script_directory = pathlib.Path(__file__).parent.resolve()
template_name = os.getenv(
"PYGITVER_TEMPLATE_CHANGELOG_COMMON",
f"{script_directory}/templates/changelog-common.tmpl",
)
try:
env = Environment(loader=FileSystemLoader(os.path.dirname(template_name)))
template = env.get_template(os.path.basename(template_name))
Expand Down
7 changes: 5 additions & 2 deletions src/git.py → src/pygitver/git.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import json
import os
import pathlib
import json
import re
import subprocess
from jinja2 import Environment, FileSystemLoader, TemplateNotFound
Expand Down Expand Up @@ -252,8 +253,10 @@ def changelog_generate(changelog_group: dict, template_name: str = "") -> str:
:return: string with formatted changelog
"""
if not template_name:
script_directory = pathlib.Path(__file__).parent.resolve()
template_name = os.getenv(
"PYGITVER_TEMPLATE_CHANGELOG", "templates/changelog.tmpl"
"PYGITVER_TEMPLATE_CHANGELOG",
f"{script_directory}/templates/changelog.tmpl",
)
try:
env = Environment(loader=FileSystemLoader(os.path.dirname(template_name)))
Expand Down
8 changes: 3 additions & 5 deletions src/pygitver.py → src/pygitver/pygitver.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import argparse

from git import Git, GitError
from changelogs_mngr import ChangelogsMngr, ChangelogsMngrError
from pygitver.git import Git, GitError
from pygitver.changelogs_mngr import ChangelogsMngr, ChangelogsMngrError
import json


Expand Down Expand Up @@ -116,9 +116,7 @@ def main():
output = join_changelogs.read_files(path=args.dir, file_ext="json")
if args.format == "text":
try:
print(
join_changelogs.changelog_generate(template_name=args.template)
)
print(join_changelogs.generate(template_name=args.template))
except ChangelogsMngrError as err:
print(err)
exit(1)
Expand Down
File renamed without changes.
Empty file removed tests/__init__.py
Empty file.
18 changes: 15 additions & 3 deletions tests/test_changelogs_mngr.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import os
import json
import unittest
from src.changelogs_mngr import ChangelogsMngr, Git, ChangelogsMngrError
from unittest import mock
from pygitver.changelogs_mngr import ChangelogsMngr, ChangelogsMngrError
from pygitver.git import Git


class TestChangelogsMngr(unittest.TestCase):
Expand All @@ -14,10 +16,14 @@ def test_join_changelogs(self, monkeypatch):
expected = json.load(fp)
assert res == expected

@mock.patch.dict(os.environ, {"PYGITVER_TEMPLATE_CHANGELOG_COMMON": "src/pygitver/templates/changelog-common.tmpl"},
clear=True)
def test_join_changelogs_template(self):
join_changelogs = ChangelogsMngr("2.1.2")
join_changelogs.read_files("./tests/data/changelogs/", "json")
res = join_changelogs.changelog_generate(template_name="src/templates/changelog-common.tmpl")

res = join_changelogs.generate()

expected = "# Change Log\n\n" \
"## Version: 3.0.0\n\n\n\n\n\n" \
"## Services\n\n\n\n" \
Expand All @@ -40,6 +46,12 @@ def test_join_changelogs_template(self):
for pos, _ in enumerate(l_res):
self.assertEqual(l_expected[pos], l_res[pos])

res = join_changelogs.generate(template_name="src/pygitver/templates/changelog-common.tmpl")
l_res = res.split("\n")
l_expected = expected.split("\n")
for pos, _ in enumerate(l_res):
self.assertEqual(l_expected[pos], l_res[pos])

def test_init_changelog(self):
chl_mngr = ChangelogsMngr()
chl_mngr._changelogs = {"version": "0.0.0", "services": {"test": None}}
Expand All @@ -53,6 +65,6 @@ def test_changelog_generate(self):
chl_mngr = ChangelogsMngr()

with self.assertRaises(ChangelogsMngrError) as context:
chl_mngr.changelog_generate(template_name=template_name)
chl_mngr.generate(template_name=template_name)
self.assertEqual(f"ERROR: Template '{template_name}' was not found.",
str(context.exception))
4 changes: 2 additions & 2 deletions tests/test_git.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from src.git import Git
from pygitver.git import Git

GIT_LOG_OUTPUT_MOCK = "fix: test fix 1\n" \
"feat(api)!: new api\n" \
Expand Down Expand Up @@ -139,7 +139,7 @@ def test_changelog_generate(monkeypatch):
monkeypatch.setattr(Git, "changelog", value=lambda *args, **kwargs: GIT_LOG_OUTPUT_MOCK)
monkeypatch.setattr(Git, "git_version", value=lambda *args, **kwargs: "git version v1.0.0")
changelog = Git.changelog_generate(changelog_group=Git.changelog_group(),
template_name="src/templates/changelog.tmpl")
template_name="src/pygitver/templates/changelog.tmpl")
assert changelog == "##########\nChange Log\n##########\n\nVersion v1.0.0\n=============\n\n\n\n\n\n" \
"Features\n--------\n\n\n* New api\n\n\n\n\n\n" \
"Bug Fixes\n---------\n\n\n* Test fix 1\n\n* Test fix 2\n\n\n\n\n\n" \
Expand Down