mirror of
https://github.com/openSUSE/osc.git
synced 2024-12-25 17:36:13 +01:00
GHA: test if rpmbuild passes
This commit is contained in:
parent
2e50b39ff3
commit
f04035de81
74
.github/workflows/rpmbuild.yaml
vendored
Normal file
74
.github/workflows/rpmbuild.yaml
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
name: 'rpmbuild test'
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ['master']
|
||||
pull_request:
|
||||
branches: ['master']
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: 'rpmbuild test'
|
||||
runs-on: 'ubuntu-latest'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# Testing per python-version using actions/setup-python is not possible,
|
||||
# because rpm doesn't exist on pypi and cannot be installed via pip on ubuntu.
|
||||
# That's why we're going to test on the target distros directly.
|
||||
container:
|
||||
|
||||
# Fedora
|
||||
- 'fedora:36'
|
||||
- 'fedora:rawhide'
|
||||
|
||||
# OpenSUSE
|
||||
# leap < 15.2 doesn't contain git-lfs which causes actions/checkout to fail
|
||||
- 'opensuse/leap:15.2'
|
||||
- 'opensuse/leap:15.3'
|
||||
- 'opensuse/leap:15.4'
|
||||
- 'opensuse/tumbleweed'
|
||||
|
||||
# CentOS Stream
|
||||
- 'quay.io/centos/centos:stream9'
|
||||
|
||||
container:
|
||||
image: ${{ matrix.container }}
|
||||
|
||||
steps:
|
||||
- name: 'Install packages (OpenSUSE)'
|
||||
if: ${{ startsWith(matrix.container, 'opensuse/') }}
|
||||
run: |
|
||||
zypper --non-interactive --gpg-auto-import-keys refresh
|
||||
zypper --non-interactive dist-upgrade
|
||||
zypper --non-interactive install git-lfs rpm-build
|
||||
|
||||
- name: 'Install packages (Fedora/CentOS)'
|
||||
if: ${{ startsWith(matrix.container, 'fedora:') || contains(matrix.container, 'centos:') }}
|
||||
run: |
|
||||
dnf -y makecache
|
||||
dnf -y distro-sync
|
||||
dnf -y install git-lfs rpm-build dnf-plugins-core
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: 'Install build dependencies (OpenSUSE)'
|
||||
if: ${{ startsWith(matrix.container, 'opensuse/') }}
|
||||
run: |
|
||||
zypper --non-interactive install $(rpmspec -q --buildrequires contrib/osc.spec)
|
||||
|
||||
- name: 'Install build dependencies (Fedora/CentOS)'
|
||||
if: ${{ startsWith(matrix.container, 'fedora:') || contains(matrix.container, 'centos:') }}
|
||||
run: |
|
||||
dnf -y builddep contrib/osc.spec
|
||||
|
||||
- name: 'Build SRPM and RPMs'
|
||||
run: |
|
||||
git config --global --add safe.directory "$(pwd)"
|
||||
|
||||
git remote add upstream https://github.com/openSUSE/osc.git
|
||||
git fetch upstream --tags --force
|
||||
|
||||
./contrib/build_rpm.py --srpm --rpm
|
149
contrib/build_rpm.py
Executable file
149
contrib/build_rpm.py
Executable file
@ -0,0 +1,149 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
|
||||
import argparse
|
||||
import glob
|
||||
import os
|
||||
import re
|
||||
from subprocess import check_output, run
|
||||
|
||||
|
||||
PACKAGE_PRERELEASE_RE = re.compile(r"(?<=[\.\d])(?P<prerelease>a|alpha|b|beta|c|rc|pre|preview)(?P<num>\d*)$")
|
||||
SPEC_VERSION_RE = re.compile(r"^(?P<version_tag>Version:[ \t]*).*", re.M)
|
||||
|
||||
|
||||
class Git:
|
||||
def __init__(self, workdir=None):
|
||||
self.workdir = workdir
|
||||
self._topdir = None
|
||||
|
||||
@property
|
||||
def topdir(self):
|
||||
if not self._topdir:
|
||||
cmd = ["git", "rev-parse", "--show-toplevel"]
|
||||
self._topdir = check_output(cmd, cwd=self.workdir, encoding="utf-8").strip()
|
||||
return self._topdir
|
||||
|
||||
def describe(self):
|
||||
cmd = ["git", "describe", "--tags", "--abbrev=0"]
|
||||
git_tag = check_output(cmd, cwd=self.workdir, encoding="utf-8").strip()
|
||||
|
||||
cmd = ["git", "describe", "--tags"]
|
||||
desc = check_output(cmd, cwd=self.workdir, encoding="utf-8").strip()
|
||||
|
||||
if desc == git_tag:
|
||||
# we're at the latest git tag
|
||||
git_commits = 0
|
||||
git_hash = None
|
||||
else:
|
||||
# there are additional commits on top of the latest tag
|
||||
_, git_commits, git_hash = desc.rsplit("-", 2)
|
||||
git_commits = int(git_commits)
|
||||
git_hash = git_hash[1:]
|
||||
|
||||
return git_tag, git_commits, git_hash
|
||||
|
||||
def get_package_version(self):
|
||||
"""
|
||||
Return package version based on a git tag.
|
||||
Pre-releases will be prefixed with '~' to comply with RPM pre-release versioning.
|
||||
"""
|
||||
git_tag, git_commits, git_hash = self.describe()
|
||||
version = PACKAGE_PRERELEASE_RE.sub(r"~\g<prerelease>\g<num>", git_tag)
|
||||
if git_commits:
|
||||
version += f".{git_commits}.g{git_hash}"
|
||||
return version
|
||||
|
||||
def archive(self, pkg_name, destdir=None):
|
||||
pkg_version = self.get_package_version()
|
||||
prefix = f"{pkg_name}-{pkg_version}"
|
||||
destdir = destdir or self.topdir
|
||||
tar_path = os.path.abspath(os.path.join(destdir, f"{prefix}.tar.gz"))
|
||||
cmd = ["git", "archive", "--format=tar.gz", f"--prefix={prefix}/", "HEAD", f"--output={tar_path}"]
|
||||
run(cmd, check=True, cwd=self.topdir)
|
||||
return tar_path
|
||||
|
||||
|
||||
class Spec:
|
||||
@classmethod
|
||||
def find(cls, topdir):
|
||||
paths = ["", "contrib"]
|
||||
for path in paths:
|
||||
spec_paths = glob.glob(os.path.join(topdir, path, "*.spec"))
|
||||
if spec_paths:
|
||||
return cls(spec_paths[0])
|
||||
raise RuntimeError(f"Couldn't find spec under {topdir}")
|
||||
|
||||
def __init__(self, path):
|
||||
self.path = os.path.abspath(path)
|
||||
self.topdir = os.path.dirname(self.path)
|
||||
self._name = None
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
if not self._name:
|
||||
cmd = ["rpmspec", self.path, "-q", "--qf=%{name}"]
|
||||
self._name = check_output(cmd, encoding="utf-8").strip()
|
||||
return self._name
|
||||
|
||||
def set_version(self, version):
|
||||
with open(self.path, "r+", encoding="utf-8") as f:
|
||||
data = f.read()
|
||||
new_data = SPEC_VERSION_RE.sub(fr"\g<version_tag>{version}", data)
|
||||
f.seek(0)
|
||||
f.write(new_data)
|
||||
f.truncate()
|
||||
|
||||
def build(self, srpm=True, rpm=True, nodeps=False):
|
||||
cmd = [
|
||||
"rpmbuild",
|
||||
self.path,
|
||||
"--define", f"_sourcedir {self.topdir}",
|
||||
"--define", f"_srcrpmdir {self.topdir}",
|
||||
]
|
||||
if srpm and rpm:
|
||||
cmd.append("-ba")
|
||||
elif srpm:
|
||||
cmd.append("-bs")
|
||||
elif rpm:
|
||||
cmd.append("-bb")
|
||||
if nodeps:
|
||||
cmd.append("--nodeps")
|
||||
|
||||
env = os.environ.copy()
|
||||
env["LC_ALL"] = "C.UTF-8"
|
||||
env["LANGUAGE"] = "C"
|
||||
run(cmd, check=True, encoding="utf-8", cwd=self.topdir, env=env)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"--rpm",
|
||||
action="store_true",
|
||||
help="Build binary RPMs",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--srpm",
|
||||
action="store_true",
|
||||
help="Build source RPM",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--nodeps",
|
||||
action="store_true",
|
||||
help="Do not verify build dependencies",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
if not args.rpm and not args.srpm:
|
||||
parser.error('No build output specified. Please specify --rpm, --srpm or both.')
|
||||
|
||||
git = Git()
|
||||
spec = Spec.find(git.topdir)
|
||||
git.archive(spec.name, destdir=spec.topdir)
|
||||
spec.set_version(git.get_package_version())
|
||||
spec.build(srpm=args.srpm, rpm=args.rpm, nodeps=args.nodeps)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Loading…
Reference in New Issue
Block a user