Compare commits

..

No commits in common. "main" and "0.6.1" have entirely different histories.
main ... 0.6.1

11 changed files with 122 additions and 148 deletions

69
.gitlab-ci.yml Normal file
View file

@ -0,0 +1,69 @@
---
include:
- local: .gitlab-ci/versioning/gitversion.yml
- local: .gitlab-ci/git/create_tag.yml
stages:
- build
- release
gitversion:
extends: .versioning:gitversion
stage: .pre
tags:
- gitlab-org-docker
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Run this job when commits are pushed or merged to the default branch
build:
stage: build
image: python:3.9.21
tags:
- gitlab-org-docker
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Run this job when commits are pushed or merged to the default branch
needs:
- job: gitversion
artifacts: true
script:
- sed -i "s/^__version__ = .*/__version__ = \"${GitVersion_MajorMinorPatch}\"/" src/PyPiUpdater/__init__.py
- cat src/PyPiUpdater/__init__.py
- python3 -m pip install build
- python3 -m build
artifacts:
paths:
- dist/*
expire_in: 1 day
publish:
stage: release
image: python:3.9.21
tags:
- gitlab-org-docker
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Run this job when commits are pushed or merged to the default branch
variables:
TWINE_USERNAME: "__token__"
TWINE_PASSWORD: $TWINE_API
needs:
- job: build
artifacts: true
script:
- python3 -m pip install twine
- python3 -m twine upload dist/*
create_tag:
extends: .git:create_tag
stage: release
tags:
- gitlab-org-docker
variables:
VERSION: $GitVersion_SemVer
TOKEN: $GITLAB_TOKEN
needs:
- job: gitversion
artifacts: true
rules:
- if: $CI_COMMIT_TAG
when: never # Do not run this job when a tag is created manually
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Run this job when commits are pushed or merged to the default branch

View file

@ -0,0 +1,15 @@
---
.git:create_tag:
image: alpine:3.21
variables:
GIT_STRATEGY: clone
GIT_DEPTH: 0
GIT_LFS_SKIP_SMUDGE: 1
VERSION: ''
TOKEN: '' # Token with push privileges
script:
- apk add git
- git remote set-url origin https://oauth2:$TOKEN@$CI_SERVER_HOST/$CI_PROJECT_PATH
- git tag $VERSION
- git push origin tag $VERSION

View file

@ -0,0 +1,31 @@
---
.versioning:gitversion:
image:
name: mcr.microsoft.com/dotnet/sdk:9.0
variables:
GIT_STRATEGY: clone
GIT_DEPTH: 0 # force a deep/non-shallow fetch need by gitversion
GIT_LFS_SKIP_SMUDGE: 1
cache: [] # caches and before / after scripts can mess things up
script:
- |
dotnet tool install --global GitVersion.Tool --version 5.*
export PATH="$PATH:/root/.dotnet/tools"
dotnet-gitversion -output buildserver
# We could just collect the output file gitversion.properties (with artifacts:report:dotenv: gitversion.properties as it is already in DOTENV format,
# however it contains ~33 variables which unnecessarily consumes many of the 50 max DOTENV variables of the free GitLab version.
# Limits are higher for licensed editions, see https://docs.gitlab.com/ee/ci/yaml/artifacts_reports.html#artifactsreportsdotenv
grep 'GitVersion_LegacySemVer=' gitversion.properties >> gitversion.env
grep 'GitVersion_SemVer=' gitversion.properties >> gitversion.env
grep 'GitVersion_FullSemVer=' gitversion.properties >> gitversion.env
grep 'GitVersion_Major=' gitversion.properties >> gitversion.env
grep 'GitVersion_Minor=' gitversion.properties >> gitversion.env
grep 'GitVersion_Patch=' gitversion.properties >> gitversion.env
grep 'GitVersion_MajorMinorPatch=' gitversion.properties >> gitversion.env
grep 'GitVersion_BuildMetaData=' gitversion.properties >> gitversion.env
artifacts:
reports:
# propagates variables into the pipeline level
dotenv: gitversion.env

View file

@ -1,92 +0,0 @@
steps:
- name: gitversion
depends_on: [] # nothing start emititly
when:
event: push
branch: main
image: mcr.microsoft.com/dotnet/sdk:9.0
environment:
CI_TOKEN:
from_secret: CI_TOKEN
commands:
- git remote set-url origin https://CodeByMrFinchum:$CI_TOKEN@code.boxyfoxy.net/$CI_REPO.git
- git fetch --unshallow --tags
- apt-get update && apt-get install -y jq
- dotnet tool install --global GitVersion.Tool --version 5.*
- export PATH="$PATH:/root/.dotnet/tools"
- dotnet-gitversion -output json > version.json
- ls
- cat version.json
- |
echo "GitVersion_SemVer=$(jq -r '.SemVer' version.json)" >> gitversion.env
echo "GitVersion_LegacySemVer=$(jq -r '.LegacySemVer' version.json)" >> gitversion.env
echo "GitVersion_FullSemVer=$(jq -r '.FullSemVer' version.json)" >> gitversion.env
echo "GitVersion_Major=$(jq -r '.Major' version.json)" >> gitversion.env
echo "GitVersion_Minor=$(jq -r '.Minor' version.json)" >> gitversion.env
echo "GitVersion_Patch=$(jq -r '.Patch' version.json)" >> gitversion.env
echo "GitVersion_MajorMinorPatch=$(jq -r '.MajorMinorPatch' version.json)" >> gitversion.env
echo "GitVersion_BuildMetaData=$(jq -r '.BuildMetaData' version.json)" >> gitversion.env
- name: tagging
depends_on: [gitversion]
when:
event: push
branch: main
image: alpine/git
environment:
CI_TOKEN:
from_secret: CI_TOKEN
commands:
- ls
- cat gitversion.env
- git config --global user.email "ci@noreply.boxyfoxy.net"
- git config --global user.name "CI Bot"
- git remote set-url origin https://CodeByMrFinchum:$${CI_TOKEN}@code.boxyfoxy.net/$${CI_REPO}.git
- . gitversion.env
- git tag $GitVersion_SemVer
- git push origin tag $GitVersion_SemVer
- name: build
depends_on: [gitversion, tagging]
when:
event: push
branch: main
image: python:3.9.21
commands:
- ls
- cat gitversion.env
- export $(cat gitversion.env | xargs)
- sed -i "s/^__version__ = .*/__version__ = \"$GitVersion_SemVer\"/" src/PyPiUpdater/__init__.py
- cat src/PyPiUpdater/__init__.py
- python3 -m pip install build
- python3 -m build
- name: publish_pypi
depends_on: [gitversion, tagging, build]
when:
event: push
branch: main
image: python:3.9.21
environment:
TWINE_PASSWORD:
from_secret: TWINE_API
TWINE_USERNAME: "__token__"
commands:
- ls
- python3 -m pip install twine
- python3 -m twine upload dist/*
- name: publish_forgejo
depends_on: [gitversion, tagging, build]
when:
event: push
branch: main
image: python:3.9.21
environment:
TWINE_PASSWORD:
from_secret: PKG_TOKEN
TWINE_USERNAME: "CodeByMrFinchum"
commands:
- ls
- python3 -m pip install twine
- python3 -m twine upload --verbose --repository-url https://code.boxyfoxy.net/api/packages/CodeByMrFinchum/pypi dist/*

View file

@ -1,21 +1,5 @@
# Changelog # Changelog
## 0.8-0.9: CI woodpecker (25.04.10-11)
- Changes to the pipeline no
## 0.7.x
### 0.7.2: Removed Debugging Leftovers
- Cleaned up code used for debugging.
### 0.7.1: Fixed Prerelease Update Detection
- Prevented prerelease versions from being listed as updates, as they must be installed manually.
### 0.7.0: Added Function to Install Packages
- Introduced the `install_package` function, allowing packages to be installed directly through the app.
- Useful for optional dependencies that need to be installed separately. This enables installation via the UI.
---
## 0.6.x ## 0.6.x
### 0.6.1: Classifier ### 0.6.1: Classifier
- Added Classifier for pypi - Added Classifier for pypi

View file

@ -1,6 +1,4 @@
# PyPiUpdater # PyPiUpdater
Developed on my [forgejo instance](https://code.boxyfoxy.net/CodeByMrFinchum), [GitLab](https://gitlab.com/CodeByMrFinchum) is used as backup.
**UNFINISHED** Still early code, functions might change drasticly **UNFINISHED** Still early code, functions might change drasticly
**PyPiUpdater** is a Python library for managing updates of packages installed via `pip`. **PyPiUpdater** is a Python library for managing updates of packages installed via `pip`.

View file

@ -1,3 +1,3 @@
Simple program to update package from PyPi with pip. Simple program to update package from PyPi with pip.
For more info see [PyPiUpdater forgejo](https://code.boxyfoxy.net/CodeByMrFinchum/PyPiUpdater) or backup repo [PyPiUpdater gitlab](https://gitlab.com/CodeByMrFinchum/PyPiUpdater#). For more info see [PyPiUpdater gitlab](https://gitlab.com/CodeByMrFinchum/PyPiUpdater#).

View file

@ -11,7 +11,7 @@ readme = "README.md"
requires-python = ">=3.8" requires-python = ">=3.8"
dependencies = ["requests", "packaging"] dependencies = ["requests", "packaging"]
classifiers = [ classifiers = [
"Development Status :: 3 - Alpha", "Development Status :: 4 - Beta",
"Programming Language :: Python :: 3", "Programming Language :: Python :: 3",
"Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Software Development :: Libraries :: Python Modules",
"License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)", "License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)",

View file

@ -1,5 +1,4 @@
from .single_updater import PyPiUpdater from .pypi_updater import PyPiUpdater
#from .multi_updater import MultiPackageUpdater
__all__ = ["PyPiUpdater"] __all__ = ["PyPiUpdater"]

View file

@ -1,4 +0,0 @@
class MultiPackageUpdater:
def __init__(self, log_path):
print("Not ready yet...")

View file

@ -6,7 +6,6 @@ import time
import json import json
import re import re
from packaging import version from packaging import version
from packaging.version import parse, Version
from xml.etree import ElementTree as ET from xml.etree import ElementTree as ET
class PyPiUpdater: class PyPiUpdater:
@ -26,7 +25,7 @@ class PyPiUpdater:
self.last_update_check = 0.1 self.last_update_check = 0.1
def _get_latest_version(self): def _get_latest_version(self):
"""Fetch the latest stable version from PyPI RSS feed.""" """Fetch the latest version from PyPI RSS feed."""
rss_url = f"https://pypi.org/rss/project/{self.package_name.lower()}/releases.xml" rss_url = f"https://pypi.org/rss/project/{self.package_name.lower()}/releases.xml"
try: try:
@ -34,23 +33,9 @@ class PyPiUpdater:
response.raise_for_status() response.raise_for_status()
root = ET.fromstring(response.content) root = ET.fromstring(response.content)
# Extract all versions from the feed latest_version = root.find(".//item/title").text.strip()
versions = []
for item in root.findall(".//item/title"):
version_text = item.text.strip()
parsed_version = parse(version_text)
# Check if the version is stable (not a pre-release)
if isinstance(parsed_version, Version) and not parsed_version.is_prerelease:
versions.append(parsed_version)
# Return the latest stable version
if versions:
latest_version = str(max(versions))
self.latest_version = latest_version self.latest_version = latest_version
return [latest_version, None] return [latest_version, None]
return [None, "No stable versions found"]
except requests.exceptions.RequestException as e: except requests.exceptions.RequestException as e:
return [None, f"Network error: {str(e)}"] return [None, f"Network error: {str(e)}"]
except Exception as e: except Exception as e:
@ -161,14 +146,3 @@ class PyPiUpdater:
"""Write data to JSON log file.""" """Write data to JSON log file."""
with open(self.log_path, "w") as f: with open(self.log_path, "w") as f:
json.dump(data, f, indent=4) json.dump(data, f, indent=4)
@staticmethod
def install_package(package_name):
"""Attempts to install a package via pip."""
try:
subprocess.run([sys.executable, "-m", "pip", "install", package_name], check = True)
print("Successfull")
return [True, f"{package_name} installed successfully!"]
except subprocess.CalledProcessError as e:
print("Failed")
return [False, f"Failed to install {package_name}:\n{e.stderr}"]