Add builds

This commit is contained in:
iliajie
2023-08-02 20:02:54 +03:00
parent 62e1b4c785
commit 3bd37be97b
6 changed files with 710 additions and 0 deletions

221
.github/build/deb.sh vendored Executable file
View File

@@ -0,0 +1,221 @@
#!/usr/bin/env bash
#
# Copyright @iliajie <ilia@webmin.dev>
#
# Automatically builds and updates a repo metadata.
# Pulls latest changes from GitHub, detects release
# version based on what's available in the repo
#
# (Debian)
#
# Usage:
#
# # Pull and build production versions
# # of both Webmin and Usermin
# ./deb.sh
#
# # Pull and build devel versions
# # of both Webmin and Usermin
# ./deb.sh --devel
#
# # Pull and build production Webmin version 2.101, forcing
# # release version 3, displaying detailed output
# ./deb.sh webmin 2.101 3 --debug
#
# # Pull and build production Usermin version 2.000,
# # automatically setting release version to minimal
# ./deb.sh usermin 2.000
#
# shellcheck disable=SC1091
# Source build variables
source ./vars.sh || exit 1
# Source build init
source ./init.sh || exit 1
# Source general build functions
source ./funcs.sh || exit 1
# Build product func
build_prod() {
# Pack with English only in devel builds
local english_only=0
if [[ "'$*'" == *"--devel"* ]]; then
english_only=1
fi
# Always return back to root directory
cd "$root" || exit 1
# Define root
local ver=""
local prod=$1
root_prod="$root/$prod"
root_apt="$root_prod/deb"
# Print build actual date
date=$(get_current_date)
# Print opening header
echo "************************************************************************"
echo " build start date: $date "
echo " package format: DEB "
echo " product: $prod "
(make_prod_repos "$root_prod") &
spinner " package output version:"
# Pull main project first to get the latest tag
cd "$root_prod" || exit 1
cmd="git pull $verbosity_level"
eval "$cmd"
rs1=$?
# Clean and try again
if [ "$rs1" != "0" ]; then
cmd="git checkout \"*\" $verbosity_level && git clean -f -d $verbosity_level && git pull $verbosity_level"
eval "$cmd"
rs1=$?
fi
# Descend to theme dir
cd "authentic-theme" || exit 1
cmd="git pull $verbosity_level"
eval "$cmd"
rs2=$?
# Clean and try again
if [ "$rs2" != "0" ]; then
cmd="git checkout \"*\" $verbosity_level && git clean -f -d $verbosity_level && git pull $verbosity_level"
eval "$cmd"
rs2=$?
fi
if [ "$rs1" != "0" ] || [ "$rs2" != "0" ]; then
rs=1
else
rs=0
fi
# Build number
date_version=$(get_latest_commit_date_version)
# Handle other params
cd "$root_prod" || exit 1
if [[ "'$2'" != *"--"* ]]; then
ver=$2
fi
if [[ "'$3'" != *"--"* ]] && [[ -n "$3" ]]; then
rel=$3
relval="-$3"
else
rel=1
relval=""
fi
if [ -z "$ver" ]; then
ver=$(get_current_repo_tag)
fi
if [[ "'$*'" == *"--devel"* ]]; then
ver="$ver.$date_version"
# Set actual product version
echo "${ver}" >"version"
fi
printf "$ver-$rel\n"
echo "************************************************************************"
echo "Pulling latest changes.."
# We need to pull first to get the latest tag,
# so here we only report an error if any
postcmd $rs
echo
echo "Pre-clean up .."
# Make sure directories exist
make_dir "$root_repos/"
make_dir "$root_apt/"
make_dir "$root_prod/newkey/deb/"
make_dir "$root_prod/umodules/"
make_dir "$root_prod/minimal/"
make_dir "$root_prod/tarballs/"
# Re-create legacy link
rm -rf "$root/webadmin"
ln -s "$root/webmin" "$root/webadmin"
# Purge old files
purge_dir "$root_prod/newkey/deb"
purge_dir "$root_prod/umodules"
purge_dir "$root_prod/minimal"
purge_dir "$root_prod/tarballs"
if [ "$prod" != "" ]; then
# XXXX Need to check for
# product name exactly
rm -f "$root_repos/$prod-latest"*
fi
postcmd $?
echo
# Descend to project dir
cd "$root_prod" || exit 1
if [ "$english_only" = "1" ]; then
echo "Cleaning languages .."
cmd="./bin/language-manager --mode=clean --yes $verbosity_level_with_input"
eval "$cmd"
postcmd $?
echo
else
# Force restore build directory
if [ ! -f "lang/ja" ]; then
echo "Restoring languages .."
cmd="git checkout \"*\" $verbosity_level && git clean -f -d $verbosity_level && git pull $verbosity_level"
eval "$cmd"
postcmd $?
echo
fi
fi
echo "Pre-building package .."
eval "$cmd"
cmd="./makedist.pl \"${ver}${relval}\" $verbosity_level"
eval "$cmd"
postcmd $?
echo
echo "Building package .."
if [ "$relval" == "" ]; then
cmd="./makedebian.pl \"$ver\" $verbosity_level"
else
cmd="./makedebian.pl \"$ver\" \"$rel\" $verbosity_level"
fi
eval "$cmd"
postcmd $?
echo
cd "$root" || exit 1
echo "Preparing built files for upload .."
cmd="cp -f $root_prod/tarballs/${prod}-${ver}*\.tar.gz $root_repos/${prod}-latest.tar.gz $verbosity_level"
eval "$cmd"
cmd="echo $ver-$rel \($date\) > $root_repos/${prod}-latest.version $verbosity_level_to_file"
eval "$cmd"
cmd="find $root_apt -name ${prod}_${ver}${relval}*\.deb -exec mv '{}' $root_repos \; $verbosity_level"
eval "$cmd"
cmd="mv -f $root_repos/${prod}_${ver}${relval}*\.deb $root_repos/${prod}-latest.deb $verbosity_level"
eval "$cmd"
postcmd $?
}
if [ -n "$1" ] && [[ "'$1'" != *"--"* ]]; then
build_prod $@
cloud_upload_list_upload=("$root_repos/$1*")
cloud_upload cloud_upload_list_upload
cloud_repo_sign_and_update
else
build_prod webmin $@
build_prod usermin $@
cloud_upload_list_upload=("$root_repos/*")
cloud_upload cloud_upload_list_upload
cloud_repo_sign_and_update
fi

159
.github/build/funcs.sh vendored Executable file
View File

@@ -0,0 +1,159 @@
#!/usr/bin/env bash
#
# Copyright @iliajie <ilia@webmin.dev>
#
# General build functions
#
#
# Upload to cloud
# Usage:
# cloud_upload_list_delete=("$cloud_upload_ssh_dir/repodata")
# cloud_upload_list_upload=("$root_repos/*" "$root_repos/repodata")
# cloud_upload cloud_upload_list_upload cloud_upload_list_delete
cloud_upload() {
# Print new block only if definded
local ssh_args="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
if [ -n "$1" ]; then
echo
fi
# Delete files on remote if needed
if [ -n "$2" ]; then
echo "Deleting given files in $cloud_upload_ssh_host .."
local -n arr_del=$2
local err=0
for d in "${arr_del[@]}"; do
if [ -n "$d" ]; then
local cmd1="ssh $ssh_args $cloud_upload_ssh_user@$cloud_upload_ssh_host \"rm -rf $d\" $verbosity_level"
eval "$cmd1"
if [ "$?" != "0" ]; then
err=1
fi
fi
done
postcmd $err
echo
fi
# Upload files to remote
if [ -n "$1" ]; then
echo "Uploading built files to $cloud_upload_ssh_host .."
local -n arr_upl=$1
local err=0
for u in "${arr_upl[@]}"; do
if [ -n "$u" ]; then
local cmd2="scp $ssh_args -r $u $cloud_upload_ssh_user@$cloud_upload_ssh_host:$cloud_upload_ssh_dir/ $verbosity_level"
eval "$cmd2"
if [ "$?" != "0" ]; then
err=1
fi
fi
done
postcmd $err
echo
fi
}
# Sign and update repos metadata in remote
cloud_repo_sign_and_update() {
echo "Signing and updating repos metadata in $cloud_upload_ssh_host .."
local ssh_args="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
local remote_cmd="cd ~/.scripts && ./update-repo-packages-signature.bash $cloud_upload_gpg_passphrase"
local cmd1="ssh $ssh_args $cloud_upload_ssh_user@$cloud_upload_ssh_host \"$remote_cmd\" $verbosity_level"
eval "$cmd1"
postcmd $?
echo
}
# Post command func
postcmd() {
if [ "$1" != "0" ]; then
echo ".. failed"
exit 1
else
echo ".. done"
fi
}
# Get max number from array
max() {
local -n arr_nums=$1
IFS=$'\n'
echo "${arr_nums[*]}" | sort -nr | head -n1
}
# Mkdir and children dirs
make_dir() {
if [ ! -d "$1" ]; then
mkdir -p "$1"
fi
}
# Remove all content in dir
purge_dir() {
for file in "$1"/*; do
rm -rf "$file"
done
}
# Get latest tag version
get_current_repo_tag() {
cd "$root_prod" || exit 1
tg=$(git rev-list --tags --max-count=1)
ds=$(git describe --tags "$tg")
echo "$ds" | sed 's/v//'
}
# Get latest commit date
get_current_date() {
echo $(date +'%Y-%m-%d %H:%M:%S %z')
}
# Get latest commit date version
get_latest_commit_date_version() {
local theme_version
local prod_version
local max_prod
local highest_version
theme_version=$(git log -n1 --pretty='format:%cd' --date=format:'%Y%m%d%H%M')
cd "$root_prod" || exit 1
prod_version=$(git log -n1 --pretty='format:%cd' --date=format:'%Y%m%d%H%M')
max_prod=("$theme_version" "$prod_version")
highest_version=$(max max_prod)
echo "$highest_version"
}
# Pull project repo and theme
make_prod_repos() {
# Webmin or Usermin
if [ ! -d "$1" ]; then
local repo="webmin/$prod.git"
cmd="git clone https://github.com/$repo $verbosity_level"
eval "$cmd"
fi
# Theme
theme="authentic-theme"
if [ ! -d "$1/$theme" ]; then
cd "$1" || exit 1
local repo="webmin/$theme.git"
cmd="git clone --depth 1 https://github.com/$repo $verbosity_level"
eval "$cmd"
fi
}
spinner() {
local msg=$1
local pid=$!
local spin='-\|/'
local i=0
printf "$msg "
while kill -0 $pid 2>/dev/null; do
(( i = (i + 1) % 4 ))
# No spinner if not an interactive shell
if [ -n "$PS1" ]; then
printf '%c\b' "${spin:i:1}"
fi
sleep .1
done
}

29
.github/build/init.sh vendored Normal file
View File

@@ -0,0 +1,29 @@
#!/usr/bin/env bash
#
# Copyright @iliajie <ilia@webmin.dev>
#
# Build init
#
#
# Set up SSH dev keys
if [ -n "$WEBMIN_DEV__SSH_PRV_KEY" ] && [ -n "$WEBMIN_DEV__SSH_PUB_KEY" ]; then
# Generate new pair with right permissions
cmd="ssh-keygen -t rsa -q -f \"$HOME/.ssh/id_rsa\" -N \"\"$verbosity_level"
eval "$cmd"
# Import SSH keys from secrets to be able to connect to the remote host
echo "$WEBMIN_DEV__SSH_PRV_KEY" > "$HOME/.ssh/id_rsa"
echo "$WEBMIN_DEV__SSH_PUB_KEY" > "$HOME/.ssh/id_rsa.pub"
# Set up SSH production keys
elif [ -n "$WEBMIN_PROD__SSH_PRV_KEY" ] && [ -n "$WEBMIN_PROD__SSH_PUB_KEY" ]; then
# Generate new pair with right permissions
cmd="ssh-keygen -t rsa -q -f \"$HOME/.ssh/id_rsa\" -N \"\"$verbosity_level"
eval "$cmd"
# Import SSH keys from secrets to be able to connect to the remote host
echo "$WEBMIN_PROD__SSH_PRV_KEY" > "$HOME/.ssh/id_rsa"
echo "$WEBMIN_PROD__SSH_PUB_KEY" > "$HOME/.ssh/id_rsa.pub"
fi
# Create symlink to Perl
ln -fs /usr/bin/perl /usr/local/bin/perl

243
.github/build/rpm.sh vendored Executable file
View File

@@ -0,0 +1,243 @@
#!/usr/bin/env bash
#
# Copyright @iliajie <ilia@webmin.dev>
#
# Automatically builds and updates a repo metadata.
# Pulls latest changes from GitHub, detects release
# version based on what's available in the repo
#
# (RHEL)
#
# Usage:
#
# # Pull and build production versions
# # of both Webmin and Usermin
# ./rpm.sh
#
# # Pull and build devel versions
# # of both Webmin and Usermin
# ./rpm.sh --devel
#
# # Pull and build production Webmin version 2.101, forcing
# # release version 3, displaying detailed output
# ./rpm.sh webmin 2.101 3 --debug
#
# # Pull and build production Usermin version 2.000,
# # automatically setting release version to minimal
# ./rpm.sh usermin 2.000
#
# shellcheck disable=SC1091
# Source build variables
source ./vars.sh || exit 1
# Source build init
source ./init.sh || exit 1
# Source general build functions
source ./funcs.sh || exit 1
# Build product func
build_prod() {
# Pack with English only in devel builds
local english_only=0
if [[ "'$*'" == *"--devel"* ]]; then
english_only=1
fi
# Always return back to root directory
cd "$root" || exit 1
# Define root
local ver=""
local prod=$1
root_prod="$root/$prod"
# Print build actual date
date=$(get_current_date)
# Print opening header
echo "************************************************************************"
echo " build start date: $date "
echo " package format: RPM "
echo " product: $prod "
(make_prod_repos "$root_prod") &
spinner " package output version:"
# Pull main project first to get the latest tag
cd "$root_prod" || exit 1
cmd="git pull $verbosity_level"
eval "$cmd"
rs1=$?
# Clean and try again
if [ "$rs1" != "0" ]; then
cmd="git checkout \"*\" $verbosity_level && git clean -f -d $verbosity_level && git pull $verbosity_level"
eval "$cmd"
rs1=$?
fi
# Pull theme to theme dir
cd "authentic-theme" || exit 1
cmd="git pull $verbosity_level"
eval "$cmd"
rs2=$?
# Clean and try again
if [ "$rs2" != "0" ]; then
cmd="git checkout \"*\" $verbosity_level && git clean -f -d $verbosity_level && git pull $verbosity_level"
eval "$cmd"
rs2=$?
fi
if [ "$rs1" != "0" ] || [ "$rs2" != "0" ]; then
rs=1
else
rs=0
fi
# Build number
date_version=$(get_latest_commit_date_version)
# Handle other params
cd "$root_prod" || exit 1
if [[ "'$2'" != *"--"* ]]; then
ver=$2
fi
if [[ "'$3'" != *"--"* ]] && [[ -n "$3" ]]; then
rel=$3
else
rel=1
fi
if [ -z "$ver" ]; then
ver=$(get_current_repo_tag)
fi
if [[ "'$*'" == *"--devel"* ]]; then
ver="$ver.$date_version"
# Set actual product version
echo "${ver}" >"version"
fi
printf "$ver-$rel\n"
echo "************************************************************************"
echo "Pulling latest changes.."
# We need to pull first to get the latest tag,
# so here we only report an error if any
postcmd $rs
echo
echo "Pre-clean up .."
# Make sure directories exist
make_dir "$root_prod/newkey/rpm/"
make_dir "$root_prod/umodules/"
make_dir "$root_prod/minimal/"
make_dir "$root_prod/tarballs/"
make_dir "$root_build/BUILD/"
make_dir "$root_build/BUILDROOT/"
make_dir "$root_build/RPMS/"
make_dir "$root_build/SOURCES/"
make_dir "$root_build/SPECS/"
make_dir "$root_build/SRPMS/"
make_dir "$root_repos/"
# Re-create legacy link
rm -rf "$root/webadmin"
ln -s "$root/webmin" "$root/webadmin"
# Purge old files
purge_dir "$root_prod/newkey/rpm"
purge_dir "$root_prod/umodules"
purge_dir "$root_prod/minimal"
purge_dir "$root_prod/tarballs"
purge_dir "$root_build/BUILD"
purge_dir "$root_build/BUILDROOT"
purge_dir "$root_build/RPMS"
purge_dir "$root_build/SOURCES"
purge_dir "$root_build/SPECS"
purge_dir "$root_build/SRPMS"
rm -rf "$root_repos/repodata"
if [ "$prod" != "" ]; then
# XXXX Need to check for
# product name exactly
rm -f "$root_repos/$prod-latest"*
fi
postcmd $?
make_dir "$root_build/RPMS/noarch"
echo
# Descend to project dir
cd "$root_prod" || exit 1
if [ "$english_only" = "1" ]; then
echo "Cleaning languages .."
cmd="./bin/language-manager --mode=clean --yes $verbosity_level_with_input"
eval "$cmd"
postcmd $?
echo
else
# Force restore build directory
if [ ! -f "lang/ja" ]; then
echo "Restoring languages .."
cmd="git checkout \"*\" $verbosity_level && git clean -f -d $verbosity_level && git pull $verbosity_level"
eval "$cmd"
postcmd $?
echo
fi
fi
echo "Pre-building package .."
eval "$cmd"
if [ "$rel" = "1" ]; then
args="$ver"
else
args="$ver-$rel"
fi
cmd="./makedist.pl \"$args\" $verbosity_level"
eval "$cmd"
postcmd $?
echo
echo "Building package .."
cmd="./makerpm.pl \"$ver\" \"$rel\" $verbosity_level"
eval "$cmd"
postcmd $?
echo
cd "$root" || exit 1
echo "Preparing built files for upload .."
cmd="cp -f $root_prod/tarballs/$prod-$ver*\.tar.gz $root_repos/${prod}-latest.tar.gz $verbosity_level"
eval "$cmd"
cmd="echo $ver-$rel \($date\) > $root_repos/$prod-latest.version"
eval "$cmd"
cmd="find $root_rpms -name $prod-$ver-$rel*\.rpm -exec mv '{}' $root_repos \; $verbosity_level"
eval "$cmd"
cmd="mv -f $root_repos/$prod-$ver-$rel*\.rpm $root_repos/${prod}-latest.rpm $verbosity_level"
eval "$cmd"
postcmd $?
echo
echo "Post-clean up .."
cd "$root_build" || exit 1
for dir in *; do
cmd="rm -rf \"$dir/*\" $verbosity_level"
eval "$cmd"
done
postcmd $?
}
if [ -n "$1" ] && [[ "'$1'" != *"--"* ]]; then
build_prod $@
cloud_upload_list_upload=("$root_repos/$1*")
cloud_upload cloud_upload_list_upload
cloud_repo_sign_and_update
else
build_prod webmin $@
build_prod usermin $@
cloud_upload_list_upload=("$root_repos/*")
cloud_upload cloud_upload_list_upload
cloud_repo_sign_and_update
fi

27
.github/build/vars.sh vendored Executable file
View File

@@ -0,0 +1,27 @@
#!/usr/bin/env bash
#
# Copyright @iliajie <ilia@webmin.dev>
#
# Build variables
#
#
# Set defaults
root="${ENV_BUILD__ROOT:-$HOME}"
root_repos="${ENV_BUILD__ROOT_REPOS:-$root/repo}"
root_build="${ENV_BUILD__ROOT_BUILD:-$root/rpmbuild}"
root_rpms="${ENV_BUILD__ROOT_RPMS:-$root_build/RPMS/noarch}"
# Cloud upload config
cloud_upload_ssh_user="${ENV_BUILD__CLOUD_UPLOAD_SSH_USER:-webmin.dev}"
cloud_upload_ssh_host="${ENV_BUILD__CLOUD_UPLOAD_SSH_HOST:-webmin.dev}"
cloud_upload_ssh_dir="${ENV_BUILD__CLOUD_UPLOAD_SSH_DIR:-~/domains/builds.webmin.dev/public_html}"
cloud_upload_gpg_passphrase="${WEBMIN_DEV__GPG_PH}"
# Define verbosity level
verbosity_level=' >/dev/null 2>&1 </dev/null'
verbosity_level_to_file='2> /dev/null'
verbosity_level_with_input=' >/dev/null 2>&1'
if [[ "'$*'" == *"--debug"* ]]; then
unset verbosity_level verbosity_level_to_file verbosity_level_with_input
fi

View File

@@ -0,0 +1,31 @@
name: "webmin.dev: Deploy Webmin packages"
on:
push:
branches:
- master
schedule:
- cron: "0 8 * * *"
jobs:
build:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: git tar gzip openssl curl openssh-client rpm perl libdigest-sha-perl liblist-moreutils-perl libencode-detect-perl
version: 1.0
- uses: szenius/set-timezone@v1.2
with:
timezoneLinux: "Europe/Nicosia"
- name: Build and upload packages
env:
WEBMIN_DEV__SSH_PRV_KEY: ${{ secrets.WEBMIN_DEV__SSH_PRV_KEY }}
WEBMIN_DEV__SSH_PUB_KEY: ${{ secrets.WEBMIN_DEV__SSH_PUB_KEY }}
WEBMIN_DEV__GPG_PH: ${{ secrets.WEBMIN_DEV__GPG_PH }}
ENV_BUILD__CLOUD_UPLOAD_SSH_HOST: ${{ secrets.WEBMIN_DEV__IP_ADDR }}
working-directory: ./.github/build
run: |-
./deb.sh webmin --devel
./rpm.sh webmin --devel