This is an automated email from the ASF dual-hosted git repository.
tison pushed a commit to branch unstable
in repository https://gitbox.apache.org/repos/asf/incubator-kvrocks.git
The following commit(s) were added to refs/heads/unstable by this push:
new ed83dee Add fpm packaging to x.py (#752)
ed83dee is described below
commit ed83deebc525f1d71d84cee36ccc96462e1943e5
Author: Twice <[email protected]>
AuthorDate: Tue Jul 26 16:17:28 2022 +0800
Add fpm packaging to x.py (#752)
---
.github/workflows/release.yaml | 140 ----------------------------------
package.sh | 28 -------
x.py | 169 +++++++++++++++++++++++++++--------------
3 files changed, 114 insertions(+), 223 deletions(-)
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
deleted file mode 100644
index a033ee6..0000000
--- a/.github/workflows/release.yaml
+++ /dev/null
@@ -1,140 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-name: release linux packages and docker image
-
-on:
- push:
- tags:
- - v*
-
-env:
- FPM_OPTS: "-s dir --prefix '/www/kvrocks' -n kvrocks --epoch 7 \
- --config-files /www/kvrocks/conf/kvrocks.conf --iteration release \
- --verbose --category 'kvrocks/projects' --description 'kvrocks' \
- --url 'https://github.com/apache/incubator-kvrocks' --license
'Apache2.0'"
-
-jobs:
- release-deb-packages-and-docker-image:
- name: Release Deb Packages And Docker Image
- runs-on: ubuntu-18.04
- steps:
-
- - name: Checkout Code Base
- uses: actions/[email protected]
- with:
- fetch-depth: 64
-
- - name: Install Dependencies
- run: |
- sudo apt-get install -y tar cmake
- mkdir -p build/release/bin
- mkdir -p build/release/conf
-
- - name: Build
- run: |
- ./x.py build
- cd build
- cp kvrocks release/bin/
- cp kvrocks2redis release/bin/
- cp ../kvrocks.conf release/conf/
- cd ..
-
- - name: Set ENV
- run: |
- echo "RELEASE_TAG=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
- echo "VERSION=${GITHUB_REF#refs/*/v}" >> $GITHUB_ENV
-
- - name: Package Deb
- uses: bpicode/[email protected]
- with:
- fpm_args: '.'
- fpm_opts: '-t deb -v ${{ env.VERSION }} -C ./build/release ${{
env.FPM_OPTS }}'
-
- - name: Release
- uses: softprops/action-gh-release@v1
- with:
- files: |
- ./*.deb
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-
- - name: Login Docker Hub
- uses: docker/login-action@v1
- with:
- username: ${{ secrets.DOCKER_USERNAME }}
- password: ${{ secrets.DOCKER_PASSWORD }}
-
- - name: Set up QEMU
- uses: docker/setup-qemu-action@v1
-
- - name: Set up Docker Buildx
- id: buildx
- uses: docker/setup-buildx-action@v1
-
- - name: Available platforms
- run: echo ${{ steps.buildx.outputs.platforms }}
-
- - name: Build And Push Docker Image
- run: |
- docker buildx build --platform linux/amd64,linux/arm64 --tag
kvrocks/kvrocks:$RELEASE_TAG --tag kvrocks/kvrocks:latest .
-
- release-rpm-packages:
- name: Release Rpm Packages
- runs-on: ubuntu-18.04
- container: centos:7
- steps:
-
- - name: Install Dependencies
- run: |
- yum install -y epel-release
- yum install -y
https://packages.endpointdev.com/rhel/7/os/x86_64/endpoint-repo.x86_64.rpm
- yum install -y git gcc gcc-c++ make cmake autoconf automake libtool
which
-
- - name: Checkout Code Base
- uses: actions/[email protected]
- with:
- fetch-depth: 64
-
- - name: Build
- run: |
- mkdir -p build/release
- ./x.py build
- cd build
- mkdir -p release/bin release/conf
- cp kvrocks release/bin/
- cp kvrocks2redis release/bin/
- cp ../kvrocks.conf release/conf/
- cd ..
-
- - name: Set ENV
- run: |
- echo "VERSION=${GITHUB_REF#refs/*/v}" >> $GITHUB_ENV
-
- - name: Package Rpm
- uses: bpicode/[email protected]
- with:
- fpm_args: '.'
- fpm_opts: "-t rpm -v ${{ env.VERSION }} -C ./build/release ${{
env.FPM_OPTS }}"
-
- - name: Release
- uses: softprops/action-gh-release@v1
- with:
- files: |
- ./*.rpm
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/package.sh b/package.sh
deleted file mode 100644
index 7377685..0000000
--- a/package.sh
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/usr/bin/env bash
-
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-NAME="kvrocks"
-VERSION=`_build/bin/kvrocks -v|awk '{printf $2;}'`
-STAGE=${STAGE:-release}
-fpm -f -s dir -t rpm --prefix '/www/kvrocks' -n ${NAME} --epoch 7 \
- --config-files /www/kvrocks/conf/kvrocks.conf \
- -v ${VERSION} --iteration ${CI_PIPELINE_ID}.${STAGE} -C ./_build \
- --verbose --category 'kvrockslabs/projects' --description 'kvrocks' \
- --url 'https://github.com/apache/incubator-kvrocks' --license 'Apache2.0'
-
diff --git a/x.py b/x.py
index 3a86f89..a5d9c9e 100755
--- a/x.py
+++ b/x.py
@@ -17,13 +17,15 @@
# specific language governing permissions and limitations
# under the License.
-import argparse
-import glob
-import os
-import pathlib
+from argparse import Namespace, ArgumentParser, ArgumentDefaultsHelpFormatter
+from glob import glob
+from os import makedirs
+from pathlib import Path
import re
-import subprocess
+from subprocess import Popen, PIPE
import sys
+from typing import Callable, List, Any, Optional, TextIO
+from shutil import copyfile
CMAKE_REQUIRE_VERSION = (3, 13, 0)
SEMVER_REGEX = re.compile(
@@ -47,9 +49,12 @@ SEMVER_REGEX = re.compile(
re.VERBOSE,
)
-def run(args, msg=None, **kwargs):
+def run(*args: str, msg: Optional[str]=None, verbose: bool=False, **kwargs:
Any) -> Popen:
sys.stdout.flush()
- p = subprocess.Popen(args, **kwargs)
+ if verbose:
+ print(f"$ {' '.join(args)}")
+
+ p = Popen(args, **kwargs)
code = p.wait()
if code != 0:
err = f"""
@@ -58,38 +63,36 @@ exit with code: {code}
error message: {msg}
"""
raise RuntimeError(err)
- else:
- return p.stdout
+
+ return p
-def find_command(command, msg=None):
- output = run(["bash", "-c", f"command -v {command}"],
stdout=subprocess.PIPE)
- path = output.read().decode().strip()
- run(["test", "-x", path], msg=msg)
- return path
+def run_pipe(*args: str, msg: Optional[str]=None, verbose: bool=False,
**kwargs: Any) -> TextIO:
+ p = run(*args, msg=msg, verbose=verbose, stdout=PIPE, text=True, **kwargs)
+ return p.stdout # type: ignore
-def build(args):
- (dir, jobs, ghproxy, ninja, unittest, compiler, d) = (args.dir, args.jobs,
args.ghproxy, args.ninja, args.unittest, args.compiler, args.D)
+def find_command(command: str, msg: Optional[str]=None):
+ return run_pipe("which", command, msg=msg).read().strip()
- basedir = pathlib.Path(__file__).parent.absolute()
+def build(dir: str, jobs: int, ghproxy: bool, ninja: bool, unittest: bool,
compiler: str, cmake_path: str, D: List[str]) -> None:
+ basedir = Path(__file__).parent.absolute()
find_command("autoconf", msg="autoconf is required to build jemalloc")
- cmake = find_command("cmake", msg="CMake is required")
+ cmake = find_command(cmake_path, msg="CMake is required")
- output = run([cmake, "-version"], stdout=subprocess.PIPE)
- output = run(["head", "-n", "1"], stdin=output, stdout=subprocess.PIPE)
- output = run(["sed", "s/[^0-9.]*//g"], stdin=output,
stdout=subprocess.PIPE)
- cmake_version = output.read().decode().strip()
+ output = run_pipe(cmake, "-version")
+ output = run_pipe("head", "-n", "1", stdin=output)
+ output = run_pipe("sed", "s/[^0-9.]*//g", stdin=output)
+ cmake_version = output.read().strip()
cmake_require_version = '.'.join(map(str, CMAKE_REQUIRE_VERSION))
- cmake_semver = SEMVER_REGEX.match(cmake_version)
- if cmake_semver is None:
+ cmake_semver_match = SEMVER_REGEX.match(cmake_version)
+ if cmake_semver_match is None:
raise RuntimeError(f"CMake {cmake_require_version} or higher is
required, got: {cmake_version}")
- cmake_semver = cmake_semver.groupdict()
- cmake_semver = (int(cmake_semver["major"]), int(cmake_semver["minor"]),
int(cmake_semver["patch"]))
+ cmake_semver_dict = cmake_semver_match.groupdict()
+ cmake_semver = (int(cmake_semver_dict["major"]),
int(cmake_semver_dict["minor"]), int(cmake_semver_dict["patch"]))
if cmake_semver < CMAKE_REQUIRE_VERSION:
raise RuntimeError(f"CMake {cmake_require_version} or higher is
required, got: {cmake_version}")
- os.makedirs(dir, exist_ok=True)
- os.chdir(dir)
+ makedirs(dir, exist_ok=True)
cmake_options = ["-DCMAKE_BUILD_TYPE=RelWithDebInfo"]
if ghproxy:
@@ -100,22 +103,22 @@ def build(args):
cmake_options += ["-DCMAKE_C_COMPILER=gcc", "-DCMAKE_CXX_COMPILER=g++"]
elif compiler == 'clang':
cmake_options += ["-DCMAKE_C_COMPILER=clang",
"-DCMAKE_CXX_COMPILER=clang++"]
- if d:
- cmake_options += [f"-D{o}" for o in d]
- run([cmake, basedir, *cmake_options])
+ if D:
+ cmake_options += [f"-D{o}" for o in D]
+ run(cmake, str(basedir), *cmake_options, verbose=True, cwd=dir)
target = ["kvrocks", "kvrocks2redis"]
if unittest:
target.append("unittest")
- run([cmake, "--build", ".", f"-j{jobs}", "-t", *target])
+ run(cmake, "--build", ".", f"-j{jobs}", "-t", *target, verbose=True,
cwd=dir)
-def cpplint(args):
+def cpplint() -> None:
command = find_command("cpplint", msg="cpplint is required")
options = ["--linelength=120",
"--filter=-build/include_subdir,-legal/copyright,-build/c++11"]
- sources = [*glob.glob("src/*.h"), *glob.glob("src/*.cc")]
- run([command, *options, *sources])
+ sources = [*glob("src/*.h"), *glob("src/*.cc")]
+ run(command, *options, *sources)
-def cppcheck(args):
+def cppcheck() -> None:
command = find_command("cppcheck", msg="cppcheck is required")
options = ["-x", "c++"]
@@ -129,41 +132,83 @@ def cppcheck(args):
sources = ["src"]
- run([command, *options, *sources])
+ run(command, *options, *sources)
-def package_source(args):
- version = args.release_version.strip()
+def write_version(release_version: str) -> str:
+ version = release_version.strip()
if SEMVER_REGEX.match(version) is None:
raise RuntimeError(f"Kvrocks version should follow semver spec, got:
{version}")
- # 0. Write input version to VERSION file
with open('VERSION', 'w+') as f:
f.write(version)
+
+ return version
+
+def package_source(release_version: str) -> None:
+ # 0. Write input version to VERSION file
+ version = write_version(release_version)
# 1. Git commit and tag
git = find_command('git', msg='git is required for source packaging')
- run([git, 'commit', '-a', '-m', f'[source-release] prepare release
apache-kvrocks-{version}'], stdout=subprocess.PIPE)
- run([git, 'tag', '-a', f'v{version}', '-m', '[source-release] copy for tag
v{version}'], stdout=subprocess.PIPE)
+ run(git, 'commit', '-a', '-m', f'[source-release] prepare release
apache-kvrocks-{version}')
+ run(git, 'tag', '-a', f'v{version}', '-m', '[source-release] copy for tag
v{version}')
tarball = f'apache-kvrocks-{version}-incubating-src.tar.gz'
# 2. Create the source tarball
- output = run([git, 'ls-files'], stdout=subprocess.PIPE)
- run(['xargs', 'tar', '-czf', tarball], stdin=output,
stdout=subprocess.PIPE)
+ output = run_pipe(git, 'ls-files')
+ run('xargs', 'tar', '-czf', tarball, stdin=output)
# 3. GPG Sign
gpg = find_command('gpg', msg='gpg is required for source packaging')
- run([gpg, '--detach-sign', '--armor', tarball], stdout=subprocess.PIPE)
+ run(gpg, '--detach-sign', '--armor', tarball)
# 4. Generate sha512 checksum
sha512sum = find_command('sha512sum', msg='sha512sum is required for
source packaging')
- output = run([sha512sum, tarball], stdout=subprocess.PIPE)
- payload = output.read().decode().strip()
+ output = run_pipe(sha512sum, tarball)
+ payload = output.read().strip()
with open(f'{tarball}.sha512', 'w+') as f:
f.write(payload)
+def package_fpm(package_type: str, release_version: str, dir: str, jobs: int)
-> None:
+ fpm = find_command('fpm', msg=f'fpm is required for {package_type}
packaging')
+
+ version = write_version(release_version)
+
+ build(dir=dir, jobs=jobs, ghproxy=False, ninja=False, unittest=False,
compiler='auto', cmake_path='cmake', D=[])
+
+ package_dir = Path(dir) / 'package-fpm'
+ makedirs(str(package_dir), exist_ok=False)
+ makedirs(str(package_dir / 'bin'))
+ makedirs(str(package_dir / 'conf'))
+
+ basedir = Path(__file__).parent.absolute()
+
+ copyfile(str(Path(dir) / 'kvrocks'), str(package_dir / 'bin' / 'kvrocks'))
+ copyfile(str(Path(dir) / 'kvrocks2redis'), str(package_dir / 'bin' /
'kvrocks2redis'))
+ copyfile(str(basedir / 'kvrocks.conf'), str(package_dir / 'conf' /
'kvrocks.conf'))
+
+ fpm_opts = [
+ '-t', package_type,
+ '-v', version,
+ '-C', str(package_dir),
+ '-s', 'dir',
+ '--prefix', '/www/kvrocks',
+ '-n', 'kvrocks',
+ '--epoch', '7',
+ '--config-files', '/www/kvrocks/conf/kvrocks.conf',
+ '--iteration', 'release',
+ '--verbose',
+ '--category', 'kvrocks/projects',
+ '--description', 'kvrocks',
+ '--url', 'https://github.com/apache/incubator-kvrocks',
+ '--license', 'Apache-2.0'
+ ]
+
+ run(fpm, *fpm_opts)
+
if __name__ == '__main__':
- parser =
argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
- parser.set_defaults(func=lambda _: parser.print_help())
+ parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter)
+ parser.set_defaults(func=parser.print_help)
subparsers = parser.add_subparsers()
@@ -171,7 +216,7 @@ if __name__ == '__main__':
'check',
description="Check code with cpplint or cppcheck",
help="Check code with cpplint or cppcheck")
- parser_check.set_defaults(func=lambda _: parser_check.print_help())
+ parser_check.set_defaults(func=parser_check.print_help)
parser_check_subparsers = parser_check.add_subparsers()
parser_check_cpplint = parser_check_subparsers.add_parser(
'cpplint',
@@ -182,7 +227,7 @@ if __name__ == '__main__':
'cppcheck',
description="Check code with cppcheck
(https://github.com/danmar/cppcheck)",
help="Check code with cppcheck (https://github.com/danmar/cppcheck)",
- formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ formatter_class=ArgumentDefaultsHelpFormatter,
)
parser_check_cppcheck.set_defaults(func=cppcheck)
@@ -190,7 +235,7 @@ if __name__ == '__main__':
'build',
description="Build executables to BUILD_DIR [default: build]",
help="Build executables to BUILD_DIR [default: build]",
- formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ formatter_class=ArgumentDefaultsHelpFormatter,
)
parser_build.add_argument('dir', metavar='BUILD_DIR', nargs='?',
default='build', help="directory to store cmake-generated and build files")
parser_build.add_argument('-j', '--jobs', default=4, metavar='N',
help='execute N build jobs concurrently')
@@ -198,6 +243,7 @@ if __name__ == '__main__':
parser_build.add_argument('--ninja', default=False, action='store_true',
help='use Ninja to build kvrocks')
parser_build.add_argument('--unittest', default=False,
action='store_true', help='build unittest target')
parser_build.add_argument('--compiler', default='auto', choices=('auto',
'gcc', 'clang'), help="compiler used to build kvrocks")
+ parser_build.add_argument('--cmake-path', default='cmake', help="path of
cmake binary used to build kvrocks")
parser_build.add_argument('-D', nargs='*', metavar='key=value',
help='extra CMake definitions')
parser_build.set_defaults(func=build)
@@ -205,9 +251,9 @@ if __name__ == '__main__':
'package',
description="Package the source tarball or binary installer",
help="Package the source tarball or binary installer",
- formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ formatter_class=ArgumentDefaultsHelpFormatter,
)
- parser_package.set_defaults(func=lambda _: parser_package.print_help())
+ parser_package.set_defaults(func=parser_package.print_help)
parser_package_subparsers = parser_package.add_subparsers()
parser_package_source = parser_package_subparsers.add_parser(
'source',
@@ -216,6 +262,19 @@ if __name__ == '__main__':
)
parser_package_source.add_argument('-v', '--release-version',
required=True, metavar='VERSION', help='current releasing version')
parser_package_source.set_defaults(func=package_source)
+ parser_package_fpm = parser_package_subparsers.add_parser(
+ 'fpm',
+ description="Package built binaries to an rpm/deb package",
+ help="Package built binaries to an rpm/deb package",
+ )
+ parser_package_fpm.add_argument('-v', '--release-version', required=True,
metavar='VERSION', help='current releasing version')
+ parser_package_fpm.add_argument('-t', '--package-type', required=True,
choices=('rpm', 'deb'), help='package type for fpm to build')
+ parser_package_fpm.add_argument('dir', metavar='BUILD_DIR',
help="directory to store cmake-generated and build files")
+ parser_package_fpm.add_argument('-j', '--jobs', default=4, metavar='N',
help='execute N build jobs concurrently')
+ parser_package_fpm.set_defaults(func=package_fpm)
args = parser.parse_args()
- args.func(args)
+
+ arg_dict = dict(vars(args))
+ del arg_dict['func']
+ args.func(**arg_dict)