Skip to content

Commit

Permalink
Merge pull request #2 from frozenIceage/auto_release_obs
Browse files Browse the repository at this point in the history
auto_release obs
  • Loading branch information
frozenIceage authored Aug 8, 2024
2 parents acb3020 + ed9bf52 commit 5b9df7b
Show file tree
Hide file tree
Showing 3 changed files with 192 additions and 53 deletions.
60 changes: 7 additions & 53 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ jobs:
publish:
name: Publish
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@master
- uses: actions/checkout@v4
- name: Set up Python 3.12
uses: actions/setup-python@v1
uses: actions/setup-python@v5
with:
python-version: 3.12
- name: Install pypa/build
Expand All @@ -34,55 +35,8 @@ jobs:
password: ${{ secrets.PYPI_API_TOKEN }}
skip_existing: true
verbose: true

release-obs:
name: Release on OBS
runs-on: ubuntu-latest
env:
OBS_API: https://api.opensuse.org/
PROJECT: openSUSE:Factory
PACKAGE: osc-tiny
steps:
- uses: actions/checkout@master
- name: Get latest release tag
id: get_latest_release
run: echo "LATEST_TAG=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV
- name: Install osc
run: |
sudo apt-get update -y
sudo apt-get install -y osc
- name: Config osc
run: |
cat <<EOF > $HOME/.oscrc
[general]
apiurl=$OBS_API
[$OBS_API]
user = ${{ secrets.OSC_USER }}
pass = ${{ secrets.OSC_PASS }}
EOF
- name: checkout package
run: osc branchco $PROJECT python-$PACKAGE
- name: Fetch tarball from PyPI
run: |
cd home:*:branches:*/python-$PACKAGE
osc rm *.tar.gz
FILE_NAME=osc_tiny-${{ env.LATEST_TAG }}.tar.gz
FILE_URL=https://files.pythonhosted.org/packages/source/o/osc-tiny
while [ ! -f "$FILE_NAME" ]; do
echo "File not found. Downloading..."
wget "$FILE_URL/$FILE_NAME"
if [ ! -f "$FILE_NAME" ]; then
echo "Download failed. Waiting for 2 seconds before retrying..."
sleep 2
fi
done
osc add $FILE_NAME
- name: Update spec and changes files
- name: Install dependencies
run: |
cd home:*:branches:*/python-$PACKAGE
sed -i "s/^Version:.*/Version: ${{ env.LATEST_TAG }}/" *.spec
sed -i "s/osc-tiny-%{version}/osc_tiny-%{version}/g" *.spec
osc vc -m "Release ${{ env.LATEST_TAG }}"
osc commit -m "Release ${{ env.LATEST_TAG }}" --noservice
osc submitrequest -m "Release ${{ env.LATEST_TAG }}"
python -m pip install --upgrade pip
pip install -r requirements.txt pylint coverage coveralls
python auto_release_obs.py --username ${{ secrets.OSC_USER }} --password ${{ secrets.OSC_PASS }}
153 changes: 153 additions & 0 deletions auto_release_obs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
"""
OBS auto release helper
----------------------
"""
import argparse
import os
import tempfile
import typing
from datetime import datetime
from pathlib import Path
from pytz import _UTC
import requests
from osctiny import Osc
from osctiny.models.request import Action, ActionType, Source, Target
from osctiny.utils.changelog import Entry

def get_latest_release() -> typing.Tuple[str, str]:
"""
Get latest release name and body
"""
response = requests.get(
"https://api.github.com/repos/suse/osc-tiny/releases?per_page=1",
timeout=10)
releases = response.json()
return (releases[0]['tag_name'].strip('v'), releases[0]['body'])

def find_file(directory: str, suffix: str) -> str:
"""
Find file name in directory
"""
for _, _, files in os.walk(directory):
for item in files:
if item.endswith(suffix):
return item
return ""

def read_file(filename: str) -> str:
"""
Read file content
"""
with open(filename, 'r') as fh:
content = fh.readlines()
return content

class Obs:
"""
OBS instance
"""
pproject = "openSUSE:Factory"
package = "python-osc-tiny"
project = None
release_name = None
release_body = None

def __init__(self, **kwargs):
"""
Initialize the obs instance
"""
self.username = kwargs.get("username", "")
self.osc = Osc(
url="https://api.opensuse.org",
username=self.username,
password=kwargs.get("password", ""),
)
self.project = f"home:{self.username}:branches:devel:languages:python"
self.destdir = Path(tempfile.mkdtemp())

def branchco(self):
"""
Branch from parent project and checkout paclage
"""
params = {"force": 1,
"noservice": 1,
"autocleanup": 1,
"target_project": self.project}
# Branch from parent project
self.osc.packages.cmd(self.pproject, self.package, "branch", **params)
self.osc.packages.checkout(self.project, self.package, self.destdir)
self.release_name, self.release_body = get_latest_release()

def modify_spec_file(self) -> None:
"""
Modify spec file
"""
lines = read_file(f"{self.destdir}/{self.package}.spec")
data = ""
for line in lines:
if line.startswith("Version:"):
data += f"Version: {self.release_name}\n"
else:
data += line.replace("osc-tiny-%{version}", "osc_tiny-%{version}")
self.osc.packages.push_file(self.project, self.package, f"{self.package}.spec", data)

def modify_changes_file(self) -> None:
"""
Modify change log
"""
lines = read_file(f"{self.destdir}/{self.package}.changes")

content = f"- Release {self.release_name}\n"
for line in self.release_body.split("\r\n"):
content += f" {line}\n"
entry = Entry(
packager=self.username,
content=content,
timestamp=datetime.now(tz=_UTC())
)
data = str(entry)
for line in lines:
data += line
self.osc.packages.push_file(self.project, self.package,
f"{self.package}.changes", data)

def replace_source_file(self) -> None:
"""
Replace source file
"""
self.osc.packages.delete_file(self.project, self.package,
find_file(self.destdir, ".tar.gz"))
new_file = find_file("./dist", ".tar.gz")
with open(f"./dist/{new_file}", 'rb') as file:
self.osc.packages.push_file(self.project, self.package, new_file, data=file)

def commit(self) -> None:
"""
Commit and create submit request
"""
self.osc.packages.cmd(self.project, self.package, "commit",
comment=f"Release {self.release_name}")
actions = [
Action(
type=ActionType.SUBMIT,
source=Source(project=self.project, package=self.package),
#target=Target(project=self.pproject, package=self.package)
target=Target(project="home:ChHuang", package=self.package)
)
]
self.osc.requests.create(actions=actions)

def __call__(self) -> None:
self.branchco()
self.modify_spec_file()
self.modify_changes_file()
self.replace_source_file()
self.commit()

if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Auto release package to OBS.')
parser.add_argument('--username', required=True, help='Username for login')
parser.add_argument('--password', required=True, help='Password for login')
args = parser.parse_args()
obs = Obs(username=args.username, password=args.password)
obs()
32 changes: 32 additions & 0 deletions osctiny/extensions/packages.py
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,38 @@ def push_file(self, project, package, filename, data, comment=None):
params={"comment": comment}
)

def delete_file(self, project, package, filename, force=False, comment=None):
"""
Delete package
.. versionadded:: {{ NEXT_RELEASE }}
:param project: Project name
:param package: Package name
:param filename: Name of file
:param force: Delete package even if pending requests exist
:param comment: Optional comment
:return: ``True``, if successful. Otherwise API response
:rtype: bool or lxml.objectify.ObjectifiedElement
"""
params = {'force': force}

response = self.osc.request(
url=urljoin(
self.osc.url,
"/".join((self.base_path, project, package, filename))
),
method="DELETE",
params=params,
data=comment
)

parsed = self.osc.get_objectified_xml(response)
if response.status_code == 200 and parsed.get("code") == "ok":
return True

return parsed

def get_attribute(self, project, package, attribute=None):
"""
Get one attribute of a package
Expand Down

0 comments on commit 5b9df7b

Please sign in to comment.