2022-02-06 23:07:52 +03:00
#!/usr/bin/env bash
2023-03-29 11:21:43 +03:00
# This is an update script for forgejo installed via the binary distribution
# from codeberg.org/forgejo/forgejo on linux as systemd service. It
# performs a backup and updates Forgejo in place.
# NOTE: This adds the GPG Signing Key of the Forgejo maintainers to the keyring.
2022-03-27 20:48:08 +03:00
# Depends on: bash, curl, xz, sha256sum. optionally jq, gpg
2022-02-06 23:07:52 +03:00
# See section below for available environment vars.
# When no version is specified, updates to the latest release.
# Examples:
# upgrade.sh 1.15.10
2023-03-29 11:21:43 +03:00
# forgejohome=/opt/forgejo forgejoconf=$forgejohome/app.ini upgrade.sh
2022-02-06 23:07:52 +03:00
2023-03-29 11:21:43 +03:00
# Check if forgejo service is running
if ! pidof forgejo & > /dev/null; then
echo "Error: forgejo is not running."
2023-04-25 20:19:58 +03:00
exit 1
fi
2023-03-29 11:21:43 +03:00
# Continue with rest of the script if forgejo is running
echo "Forgejo is running. Continuing with rest of script..."
2023-04-25 20:19:58 +03:00
2022-03-27 20:48:08 +03:00
# apply variables from environment
2023-03-29 11:21:43 +03:00
: " ${ forgejobin : = "/usr/local/bin/forgejo" } "
: " ${ forgejohome : = "/var/lib/forgejo" } "
: " ${ forgejoconf : = "/etc/forgejo/app.ini" } "
: " ${ forgejouser : = "git" } "
2022-03-27 20:48:08 +03:00
: " ${ sudocmd : = "sudo" } "
: " ${ arch : = "linux-amd64" } "
2023-03-29 11:21:43 +03:00
: " ${ service_start : = " $sudocmd systemctl start forgejo " } "
: " ${ service_stop : = " $sudocmd systemctl stop forgejo " } "
: " ${ service_status : = " $sudocmd systemctl status forgejo " } "
: " ${ backupopts : = "" } " # see `forgejo dump --help` for available options
2022-03-09 01:58:14 +03:00
2023-03-29 11:21:43 +03:00
function forgejocmd {
2022-03-27 20:48:08 +03:00
if [ [ $sudocmd = "su" ] ] ; then
2022-04-27 06:30:29 +03:00
# `-c` only accept one string as argument.
2023-03-29 11:21:43 +03:00
" $sudocmd " - " $forgejouser " -c " $( printf "%q " " $forgejobin " "--config" " $forgejoconf " "--work-path" " $forgejohome " " $@ " ) "
2022-03-27 20:48:08 +03:00
else
2023-03-29 11:21:43 +03:00
" $sudocmd " --user " $forgejouser " " $forgejobin " --config " $forgejoconf " --work-path " $forgejohome " " $@ "
2022-03-27 20:48:08 +03:00
fi
}
2022-03-09 01:58:14 +03:00
function require {
for exe in " $@ " ; do
command -v " $exe " & >/dev/null || ( echo " missing dependency ' $exe ' " ; exit 1)
done
}
2022-03-27 20:48:08 +03:00
# parse command line arguments
while true; do
case " $1 " in
2023-03-29 11:21:43 +03:00
-v | --version ) forgejoversion = " $2 " ; shift 2 ; ;
2022-03-27 20:48:08 +03:00
-y | --yes ) no_confirm = "yes" ; shift ; ;
--ignore-gpg) ignore_gpg = "yes" ; shift ; ;
"" | -- ) shift; break ; ;
* ) echo "Usage: [<environment vars>] upgrade.sh [-v <version>] [-y] [--ignore-gpg]" ; exit 1; ;
esac
done
2022-03-09 01:58:14 +03:00
2022-03-27 20:48:08 +03:00
# exit once any command fails. this means that each step should be idempotent!
set -euo pipefail
2022-03-09 01:58:14 +03:00
if [ [ -f /etc/os-release ] ] ; then
os_release = $( cat /etc/os-release)
if [ [ " $os_release " = ~ "OpenWrt" ] ] ; then
sudocmd = "su"
2023-03-29 11:21:43 +03:00
service_start = "/etc/init.d/forgejo start"
service_stop = "/etc/init.d/forgejo stop"
service_status = "/etc/init.d/forgejo status"
2022-03-09 01:58:14 +03:00
else
require systemctl
fi
fi
2022-03-27 20:48:08 +03:00
require curl xz sha256sum " $sudocmd "
2022-02-06 23:07:52 +03:00
# select version to install
2023-03-29 11:21:43 +03:00
if [ [ -z " ${ forgejoversion :- } " ] ] ; then
2022-02-06 23:07:52 +03:00
require jq
2023-03-29 11:21:43 +03:00
forgejoversion = $( curl --connect-timeout 10 -sL 'https://codeberg.org/api/v1/repos/forgejo/forgejo/releases?draft=false&pre-release=false&limit=1' -H 'accept: application/json' | jq -r '.[0].tag_name | sub("v"; "")' )
echo " Latest available version is $forgejoversion "
2022-02-06 23:07:52 +03:00
fi
# confirm update
2022-03-27 20:48:08 +03:00
echo "Checking currently installed version..."
2023-03-29 11:21:43 +03:00
current = $( forgejocmd --version | cut -d ' ' -f 3)
[ [ " $current " = = " $forgejoversion " ] ] && echo " $current is already installed, stopping. " && exit 1
2022-03-09 01:58:14 +03:00
if [ [ -z " ${ no_confirm :- } " ] ] ; then
2023-03-29 11:21:43 +03:00
echo "Make sure to read the changelog first: https://codeberg.org/forgejo/forgejo/src/branch/forgejo/CHANGELOG.md"
echo " Are you ready to update forgejo from ${ current } to ${ forgejoversion } ? (y/N) "
2022-03-09 01:58:14 +03:00
read -r confirm
[ [ " $confirm " = = "y" ] ] || [ [ " $confirm " = = "Y" ] ] || exit 1
fi
2023-03-29 11:21:43 +03:00
echo " Upgrading forgejo from $current to $forgejoversion ... "
2022-02-06 23:07:52 +03:00
pushd " $( pwd ) " & >/dev/null
2023-03-29 11:21:43 +03:00
cd " $forgejohome " # needed for forgejo dump later
2022-02-06 23:07:52 +03:00
# download new binary
2023-03-29 11:21:43 +03:00
binname = " forgejo- ${ forgejoversion } - ${ arch } "
binurl = " https://codeberg.org/forgejo/forgejo/releases/download/v ${ forgejoversion } / ${ binname } .xz "
2022-02-06 23:07:52 +03:00
echo " Downloading $binurl ... "
curl --connect-timeout 10 --silent --show-error --fail --location -O " $binurl {,.sha256,.asc} "
2022-03-27 20:48:08 +03:00
# validate checksum & gpg signature
2022-03-09 01:58:14 +03:00
sha256sum -c " ${ binname } .xz.sha256 "
if [ [ -z " ${ ignore_gpg :- } " ] ] ; then
2022-03-27 20:48:08 +03:00
require gpg
2023-03-29 11:21:43 +03:00
gpg --keyserver keys.openpgp.org --recv EB114F5E6C0DC2BCDD183550A4B61A2DC5923710
2022-03-09 01:58:14 +03:00
gpg --verify " ${ binname } .xz.asc " " ${ binname } .xz " || { echo 'Signature does not match' ; exit 1; }
fi
2022-02-06 23:07:52 +03:00
rm " ${ binname } " .xz.{ sha256,asc}
# unpack binary + make executable
2022-03-27 20:48:08 +03:00
xz --decompress --force " ${ binname } .xz "
2023-03-29 11:21:43 +03:00
chown " $forgejouser " " $binname "
2022-02-06 23:07:52 +03:00
chmod +x " $binname "
2023-03-29 11:21:43 +03:00
# stop forgejo, create backup, replace binary, restart forgejo
echo " Flushing forgejo queues at $( date) "
forgejocmd manager flush-queues
echo " Stopping forgejo at $( date) "
2022-03-09 01:58:14 +03:00
$service_stop
2023-03-29 11:21:43 +03:00
echo " Creating backup in $forgejohome "
forgejocmd dump $backupopts
echo " Updating binary at $forgejobin "
cp -f " $forgejobin " " $forgejobin .bak " && mv -f " $binname " " $forgejobin "
2022-03-09 01:58:14 +03:00
$service_start
$service_status
2023-03-29 11:21:43 +03:00
echo " Upgrade to $forgejoversion successful! "
2022-02-06 23:07:52 +03:00
popd