You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by wo...@apache.org on 2018/12/06 06:58:43 UTC

[couchdb-pkg] branch scripty-fun created (now 56efd8d)

This is an automated email from the ASF dual-hosted git repository.

wohali pushed a change to branch scripty-fun
in repository https://gitbox.apache.org/repos/asf/couchdb-pkg.git.


      at 56efd8d  Refactor pkg build process to not rely on couchdb-ci

This branch includes the following new commits:

     new 56efd8d  Refactor pkg build process to not rely on couchdb-ci

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[couchdb-pkg] 01/01: Refactor pkg build process to not rely on couchdb-ci

Posted by wo...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

wohali pushed a commit to branch scripty-fun
in repository https://gitbox.apache.org/repos/asf/couchdb-pkg.git

commit 56efd8d6aec62544d5cb77ed43ee5c5bb74c21fd
Author: Joan Touzet <wo...@apache.org>
AuthorDate: Wed Dec 5 19:24:30 2018 -0800

    Refactor pkg build process to not rely on couchdb-ci
---
 .gitignore               |   6 +-
 Makefile                 |  32 ++++--
 bin/build-couchdb-pkg.sh |  65 +++++++++++
 bin/build-js.sh          |  60 ++++++++++
 bin/detect-os.sh         | 137 +++++++++++++++++++++++
 build.sh                 | 286 +++++++++++++++++++++++++++++++++++++++++++++++
 make-releases.sh         |  59 ----------
 pkgs/couch/.gitignore    |   2 +
 pkgs/js/.gitignore       |   2 +
 9 files changed, 576 insertions(+), 73 deletions(-)

diff --git a/.gitignore b/.gitignore
index 30fd9cf..8d7d35c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,8 +4,6 @@ debian/*.substvars
 debian/files
 debian/couchdb
 debian/tmp
-js/couch-*
-js/couch-*
 js/build
 rpm/BUILD
 rpm/BUILDROOT
@@ -14,11 +12,9 @@ rpm/SRPMS
 repo/db
 repo/dists
 repo/pool
-pkgs/
-couchdb/
 couchdb_*.snap
 parts/
 prime/
 snap/.snapcraft/
 stage/
-apache-couchdb*.tar.gz
+*.tar.gz
diff --git a/Makefile b/Makefile
index f4f425b..d41f77d 100644
--- a/Makefile
+++ b/Makefile
@@ -20,19 +20,25 @@ export DEBFULLNAME="CouchDB Developers"
 export DEBEMAIL="dev@couchdb.apache.org"
 
 # Debian default
-debian: find-couch-dist copy-debian update-changelog dpkg lintian
+debian: find-couch-dist copy-debian update-changelog dpkg lintian copy-pkgs
 
 # Debian 8
+debian-jessie: PLATFORM=jessie
+debian-jessie: DIST=debian-jessie
 debian-jessie: jessie
 jessie: debian
 
 # Debian 9
+debian-stretch: PLATFORM=stretch
+debian-stretch: DIST=debian-stretch
 debian-stretch: stretch
 stretch: debian
 
 # Ubuntu 12.04
+ubuntu-precise: PLATFORM=precise
+ubuntu-precise: DIST=ubuntu-precise
 ubuntu-precise: precise
-precise: find-couch-dist copy-debian precise-prep update-changelog dpkg
+precise: find-couch-dist copy-debian precise-prep update-changelog dpkg copy-pkgs
 
 precise-prep:
 	sed -i '/dh-systemd/d' $(DISTDIR)/debian/control
@@ -44,8 +50,10 @@ precise-prep:
 # No lintian run because of bogus failure on
 # postrm-does-not-call-updaterc.d-for-init.d-script
 # See Ubuntu ufw changelog for why they disabled this check
+ubuntu-trusty: PLATFORM=trusty
+ubuntu-trusty: DIST=ubuntu-trusty
 ubuntu-trusty: trusty
-trusty: find-couch-dist copy-debian trusty-prep update-changelog dpkg
+trusty: find-couch-dist copy-debian trusty-prep update-changelog dpkg copy-pkgs
 
 # see changelog for ubuntu ufw package, this is safe
 trusty-prep:
@@ -53,19 +61,25 @@ trusty-prep:
 	sed -i '/erlang-*/d' $(DISTDIR)/debian/control
 
 # Ubuntu 16.04
+ubuntu-xenial: PLATFORM=xenial
+ubuntu-xenial: DIST=ubuntu-xenial
 ubuntu-xenial: xenial
 xenial: debian
 
 # Ubuntu 18.04
+ubuntu-bionic: PLATFORM=bionic
+ubuntu-bionic: DIST=ubuntu-bioniC
 ubuntu-bionic: bionic
 bionic: debian
 
 # RPM default
-centos: find-couch-dist link-couch-dist build-rpm
+centos: find-couch-dist link-couch-dist build-rpm copy-pkgs
 
+centos-6: DIST=centos-6
 centos-6: centos6
 centos6: make-rpmbuild centos
 
+centos-7: DIST=centos-7
 centos-7: centos7
 centos7: make-rpmbuild centos
 
@@ -140,13 +154,13 @@ build-rpm:
 
 # ######################################
 copy-pkgs:
-	mkdir -p pkgs/$(PLATFORM)
-	-cp ../rpmbuild/RPMS/x86_64/*.rpm pkgs/$(PLATFORM)
-	-cp ../couchdb/*deb pkgs/$(PLATFORM)
-	-chmod -R a+rwx pkgs/$(PLATFORM)
+	-chmod a+rwx ../rpmbuild/RPMS/x86_64/couchdb-* ../couchdb/couchdb_* 2>/dev/null
+	-mkdir -p pkgs/couch/$(DIST) && chmod 777 pkgs/couch/$(DIST)
+	-cp ../rpmbuild/RPMS/x86_64/couchdb-* pkgs/couch/$(DIST) 2>/dev/null
+	-cp ../couchdb/couchdb_* pkgs/couch/$(DIST) 2>/dev/null
 
 clean:
-	rm -rf couchdb_2.0_amd64.snap parts prime snap/.snapcraft stage js/build
+	rm -rf parts prime stage js/build
 
 # ######################################
 couch-js-clean:
diff --git a/bin/build-couchdb-pkg.sh b/bin/build-couchdb-pkg.sh
new file mode 100755
index 0000000..e7a30e8
--- /dev/null
+++ b/bin/build-couchdb-pkg.sh
@@ -0,0 +1,65 @@
+#!/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.
+
+# This shell script builds and tests CouchDB on the current host.
+# It assumes the build environment is already set up correctly.
+# It needs no special privileges.
+
+# stop on error
+set -e
+
+SCRIPTPATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+
+. ${SCRIPTPATH}/detect-os.sh
+
+redhats='(rhel|centos|fedora)'
+debians='(debian|ubuntu)'
+
+cd /home/jenkins
+
+if [[ $1 ]]; then
+  # use copied package
+  mkdir couchdb
+  tar -xf ${SCRIPTPATH}/../$1 -C couchdb
+  cp ${SCRIPTPATH}/../$1 couchdb
+else
+  # use master branch
+  git clone https://github.com/apache/couchdb
+  cd couchdb
+  ./configure -c
+  make dist
+  cd ..
+fi
+
+# now, build the package
+cd couchdb-pkg
+platform=${ID}-${VERSION_CODENAME}
+make $platform PLATFORM=${VERSION_CODENAME}
+
+# and save the output
+if [[ ${ID} =~ ${redhats} ]]; then
+  mv ../rpmbuild/RPMS/* ${SCRIPTPATH}/../couch/$platform
+elif [[ ${ID} =~ ${debians} ]]; then
+  mv ../couchdb/*.deb ${SCRIPTPATH}/../couch/$platform
+else
+  echo "Sorry, we don't support this Linux (${ID}) yet."
+  exit 1
+fi
+# and make sure we can delete it if necessary
+chmod -R a+rwx  ${SCRIPTPATH}/../couch/$platform/*
diff --git a/bin/build-js.sh b/bin/build-js.sh
new file mode 100755
index 0000000..5eb7e57
--- /dev/null
+++ b/bin/build-js.sh
@@ -0,0 +1,60 @@
+#!/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.
+
+# This shell script builds a CouchDB-compatible SpiderMonkey 1.8.5
+# and assumes the build environment is already set up correctly.
+# It expects to be run as root.
+
+# stop on error
+set -e
+
+# This works if we're not called through a symlink
+# otherwise, see https://stackoverflow.com/questions/59895/
+SCRIPTPATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+ARCH=$(arch)
+
+# Check if running as root
+if [[ ${EUID} -ne 0 ]]; then
+  echo "Sorry, this script must be run as root."
+  echo "Try: sudo $0 $*"
+  exit 1
+fi
+
+. ${SCRIPTPATH}/detect-os.sh
+
+cd ${SCRIPTPATH}/..
+
+redhats='(rhel|centos|fedora)'
+debians='(debian|ubuntu)'
+if [[ ${ID} =~ ${redhats} ]]; then
+  # it will always place the build path at /root/rpmbuild :(
+  cp -r ${SCRIPTPATH}/.. /root/couchdb-pkg
+  cd /root/couchdb-pkg
+  make couch-js-rpms
+  mkdir -p ${SCRIPTPATH}/../pkgs/js/${ID}-${VERSION_CODENAME}
+  mv /root/rpmbuild/RPMS/${ARCH}/couch-js-* ${SCRIPTPATH}/../pkgs/js/${ID}-${VERSION_CODENAME}
+elif [[ ${ID} =~ ${debians} ]]; then
+  make couch-js-debs PLATFORM=${VERSION_CODENAME}
+  mkdir -p pkgs/js/${ID}-${VERSION_CODENAME}
+  mv js/couch-lib* pkgs/js/${ID}-${VERSION_CODENAME}
+else
+  echo "Sorry, we don't support this Linux (${ID}) yet."
+  exit 1
+fi
+chmod a+rw pkgs/js/*
diff --git a/bin/detect-os.sh b/bin/detect-os.sh
new file mode 100755
index 0000000..f664f33
--- /dev/null
+++ b/bin/detect-os.sh
@@ -0,0 +1,137 @@
+#!/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.
+
+# This shell script detects the OS we're on, and sets a number
+# of environment variables the calling script can use.
+
+# It uses the systemd standard of variables, and attempts to
+# populate some of the variables manually if systemd is not
+# present on the underlying OS.
+
+# Example systemd /etc/os-release file:
+# NAME="Ubuntu"
+# VERSION="16.04.4 LTS (Xenial Xerus)"
+# ID=ubuntu
+# ID_LIKE=debian
+# PRETTY_NAME="Ubuntu 16.04.4 LTS"
+# VERSION_ID="16.04"
+# HOME_URL="http://www.ubuntu.com/"
+# SUPPORT_URL="http://help.ubuntu.com/"
+# BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
+# VERSION_CODENAME=xenial
+# UBUNTU_CODENAME=xenial
+
+# While these scripts are primarily written to support building CI
+# Docker images, they can be used on any workstation to install a
+# suitable build environment.
+
+# stop on error
+set -e
+
+case "${OSTYPE}" in
+  linux*)
+    echo "Detected OS: Linux"
+    # Try the new, systemd-based way first
+    . /etc/os-release 2>/dev/null || true
+    # then try lsb_release, which might be installed
+    # os-release doesn't actually give us everything we want...
+    lsb_plat=$(lsb_release -d 2>/dev/null | awk -F"\t" '{print $2}' 2>/dev/null)
+    if [[ ${lsb_plat} ]]; then
+      if [[ ${lsb_plat} =~ "^Debian" ]]; then
+        ID=${ID:-debian}
+        VERSION_ID=${VERSION_ID:-$(echo ${lsb_plat} | awk '{print $3}' | awk -F'.' '{print $1}')}
+        VERSION_CODENAME=${VERSION_CODENAME:-$(echo ${lsb_plat} | awk '{print $4}' | sed 's/[\(\)]//g')}
+        DISTRIB_CODENAME=${DISTRIB_CODENAME:-${VERSION_CODENAME}}
+      elif  [[ ${lsb_plat} =~ "^Ubuntu" ]]; then
+        ID=${ID:-ubuntu}
+        VERSION_ID=${VERSION_ID:-$(echo ${lsb_plat} | awk '{print $2}' | awk -F'.' '{print $1}')}
+        VERSION_CODENAME=${VERSION_CODENAME:-$(lsb_release -cs)}
+        DISTRIB_CODENAME=${DISTRIB_CODENAME:-${VERSION_CODENAME}}
+      fi
+    fi
+    # and finally some rough heuristics
+    if [[ -f /etc/redhat-release ]]; then
+      # /etc/redhat-release is so inconsistent, we use rpm instead
+      rhelish=$(rpm -qa '(redhat|sl|slf|centos|oraclelinux)-release(|-server|-workstation|-client|-computenode)' 2>/dev/null | head -1)
+      if [[ $rhelish ]]; then
+        ID=${ID:-$(echo ${rhelish} | awk -F'-' '{print tolower($1)}')}
+        VERSION_ID=${VERSION_ID:-$(echo ${rhelish} | sed -E 's/([^[:digit:]]+)([[:digit:]]+)(.*)/\2/' )}
+        VERSION_CODENAME=${VERSION_CODENAME:-${VERSION_ID}}
+        DISTRIB_CODENAME=${VERSION_CODENAME:-${VERSION_ID}}
+      fi
+    elif [[ -f /etc/debian_version ]]; then
+      # Ubuntu keeps changing the format of /etc/os-release's VERSION, and
+      # it's numeric, not the codename. Boo.
+      # Also, Debian doesn't supply VERSION_CODENAME. Double Boo.
+      if [[ ${PRETTY_NAME} =~ "Ubuntu" ]]; then
+        # Ubuntu keeps changing the format of /etc/os-release's VERSION, and
+        # the codename is buried. Boo. Let's use a fancy regex.
+        VERSION_CODENAME=${VERSION_CODENAME:-$(echo ${VERSION} | sed -E 's/([0-9.]+)\W+([A-Za-z\,]+)\W+\(?(\w+)(.*)/\L\3/')}
+        DISTRIB_CODENAME=${DISTRIB_CODENAME:-${VERSION_CODENAME}}
+      elif [[ ${PRETTY_NAME} =~ "Debian" ]]; then
+        VERSION_CODENAME=${VERSION_CODENAME:-$(echo ${VERSION} | sed -E 's/(.*)\(([^\]+)\)/\2/')}
+        DISTRIB_CODENAME=${DISTRIB_CODENAME:-${VERSION_CODENAME}}
+      else
+        echo "Unknown Debian-like OS ${PRETTY_NAME}, aborting..."
+        exit 1
+      fi
+    fi
+    if [[ ${ID} && ${VERSION_ID} && ${VERSION_CODENAME} ]]; then
+      echo "Detected distribution: ${ID}, version ${VERSION_ID} (${VERSION_CODENAME})"
+    else
+      echo "Unable to determine Linux distribution! Aborting."
+      exit 1
+    fi
+    ;;
+
+  freebsd*)
+    echo "Detected OS: FreeBSD"
+    # use userland version
+    VERSION=$(freebsd-version -u | cut -d '-' -f1)
+    ;;
+  *bsd*)
+    # TODO: detect netbsd vs. freebsd vs. openbsd?
+    echo "Detected OS: BSD - UNSUPPORTED"
+    exit 1
+    ;;
+  darwin*)
+    # TODO
+    echo "Detected OS: macOS (OSX) - UNSUPPORTED"
+    exit 1
+    ;;
+  solaris*)
+    # TODO
+    echo "Detected OS: Solaris-like"
+    exit 1
+    ;;
+  msys*)
+    # TODO
+    echo "Detected OS: Windows (msys)"
+    exit 1
+    ;;
+  cygwin*)
+    # TODO
+    echo "Detected OS: Windows (cygwin)"
+    exit 1
+    ;;
+  *)
+    echo "Unknown OS detected: ${OSTYPE}"
+    exit 1
+    ;;
+esac
diff --git a/build.sh b/build.sh
new file mode 100755
index 0000000..9b25681
--- /dev/null
+++ b/build.sh
@@ -0,0 +1,286 @@
+#!/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.
+
+# This is the master shell script to build Docker containers
+# for CouchDB 2.x.
+
+# stop on error
+set -e
+
+# This works if we're not called through a symlink
+# otherwise, see https://stackoverflow.com/questions/59895/
+SCRIPTPATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+
+# TODO derive these by interrogating the Docker repo rather tha
+# hard coding the list
+DEBIANS="debian-jessie debian-stretch"
+UBUNTUS="ubuntu-trusty ubuntu-xenial ubuntu-bionic"
+debs="(debian-jessie|debian-stretch|ubuntu-trusty|ubuntu-xenial|ubuntu-bionic)"
+
+CENTOSES="centos-6 centos-7"
+rpms="(centos-6|centos-7)"
+
+BINTRAY_API="https://api.bintray.com"
+ERLANGVERSION=${ERLANGVERSION:-19.3.6}
+
+
+build-js() {
+  # TODO: check if image is built first, if not, complain
+  # invoke as build-js <plat>
+  docker run \
+      --mount type=bind,src=${SCRIPTPATH},dst=/home/jenkins/couchdb-pkg \
+      couchdbdev/$1-base \
+      sudo /home/jenkins/couchdb-pkg/bin/build-js.sh
+}
+
+build-all-js() {
+  rm -rf ${SCRIPTPATH}/pkgs/js/*
+  for plat in $DEBIANS $UBUNTUS $CENTOSES; do
+    build-js $plat
+  done
+}
+
+bintray-check-credentials() {
+  if [[ ! ${BINTRAY_USER} || ! ${BINTRAY_API_KEY} ]]; then
+    echo "Please set your Bintray credentials before using this command:"
+    echo "  export BINTRAY_USER=<username>"
+    echo "  export BINTRAY_API_KEY=<key>"
+    exit 1
+  fi
+}
+
+bintray-upload() {
+  echo "Uploading ${PKG}..."
+  local ret="$(curl \
+      --request PUT \
+      --upload-file $PKG \
+      --user ${BINTRAY_USER}:${BINTRAY_API_KEY} \
+      --header "X-Bintray-Package: ${PKGNAME}" \
+      --header "X-Bintray-Version: ${PKGVERSION}" \
+      --header "X-Bintray-Publish: 0" \
+      --header "X-Bintray-Override: 1" \
+      --header "X-Bintray-Explode: 0" \
+      "${HEADERS[@]}" \
+      "${BINTRAY_API}/content/apache/${REPO}/${RELPATH}")"
+  if [[ ${ret} == '{"message":"success"}' ]]; then
+    echo "Uploaded successfully."
+  else
+    echo "Failed to upload $PKG, ${ret}"
+    exit 1
+  fi
+}
+
+upload-js() {
+  # invoke with $1 as plat, expect to find the binaries under pkgs/js/$plat/*
+  bintray-check-credentials
+  # Debian packages first
+  PKGNAME="spidermonkey"
+  PKGVERSION="1.8.5"
+  for PKG in $(ls pkgs/js/$1/*.deb 2>/dev/null); do
+    # Example filename: couch-libmozjs185-1.0_1.8.5-1.0.0+couch-2~bionic_amd64.deb
+    # TODO: pull this stuff from buildinfo / changes files, perhaps? Not sure it matters.
+    REPO="couchdb-deb"
+    fname=${PKG##*/}
+    DIST=$(echo $fname | cut -d~ -f 2 | cut -d_ -f 1)
+    PKGARCH=$(echo $fname | cut -d_ -f 3 | cut -d. -f 1)
+    RELPATH="pool/s/spidermonkey/${fname}"
+    HEADERS=("--header" "X-Bintray-Debian-Distribution: ${DIST}")
+    HEADERS+=("--header" "X-Bintray-Debian-Component: main")
+    HEADERS+=("--header" "X-Bintray-Debian-Architecture: ${PKGARCH}")
+    bintray-upload
+  done
+  for PKG in $(ls pkgs/js/$1/*.rpm 2>/dev/null); do
+    # Example filename: couch-js-1.8.5-21.el7.x86_64.rpm
+    REPO="couchdb-rpm"
+    fname=${PKG##*/}
+    # better not put any extra . in the filename...
+    DIST=$(echo $fname | cut -d. -f 4)
+    PKGARCH=$(echo $fname | cut -d. -f 5)
+    RELPATH="${DIST}/${PKGARCH}/${fname}"
+    HEADERS=()
+    bintray-upload
+  done
+}
+
+cannot-find-tarball() {
+    echo Must supply path to tarball, either:
+    echo '  - path/to/couchdb-VERSION.tar.gz or'
+    echo '  - http(s)://url/to/couchdb-VERSION.tar.gz'
+    echo
+    exit 1
+}
+
+get-couch-tarball() {
+  if [ $# -ne "1" ]
+  then
+    cannot-find-tarball
+  fi
+  ARG=$1
+  if [ -f $ARG ]
+  then
+    # file
+    cp $ARG . 2>/dev/null || true
+    COUCHTARBALL=$(basename ${ARG})
+  else
+    if [[ $ARG =~ ^http.*$ ]]
+    then
+      #url
+      # thank you, advanced bash scripting guide
+      curl -O $ARG
+      COUCHTARBALL=${ARG##*/}
+    else
+      usage
+    fi
+  fi
+  echo Using ${COUCHTARBALL} to build packages...
+  chmod 777 ${COUCHTARBALL}
+}
+
+build-couch() {
+  # $1 is plat, $2 is the optional path to a dist tarball
+  docker run \
+      --mount type=bind,src=${SCRIPTPATH},dst=/home/jenkins/couchdb-pkg \
+      -w /home/jenkins/couchdb-pkg \
+      couchdbdev/$1-erlang-${ERLANGVERSION} \
+      make copy-couch $1 COUCHTARBALL=${COUCHTARBALL}
+}
+
+build-all-couch() {
+  rm -rf ${SCRIPTPATH}/pkgs/couch/*
+  for plat in $DEBIANS $UBUNTUS $CENTOSES; do
+    build-couch $plat $*
+  done
+}
+
+upload-couch() {
+  # invoke with $1 as plat, expect to find the binaries under pkgs/couch/$plat/*
+  bintray-check-credentials
+  # Debian packages first
+  PKGNAME="CouchDB"
+  for PKG in $(ls pkgs/couch/$1/*.deb 2>/dev/null); do
+    # Example filename: couchdb_2.3.0~jessie_amd64.deb
+    # TODO: pull this stuff from buildinfo / changes files, perhaps? Not sure it matters.
+    fname=${PKG##*/}
+    REPO="couchdb-deb"
+    DIST=$(echo $fname | cut -d~ -f 2 | cut -d_ -f 1)
+    PKGARCH=$(echo $fname | cut -d_ -f 3 | cut -d. -f 1)
+    PKGVERSION=$(echo $fname | cut -d_ -f 2 | cut -d~ -f 1)
+    RELPATH="pool/C/CouchDB/${fname}"
+    HEADERS=("--header" "X-Bintray-Debian-Distribution: ${DIST}")
+    HEADERS+=("--header" "X-Bintray-Debian-Component: main")
+    HEADERS+=("--header" "X-Bintray-Debian-Architecture: ${PKGARCH}")
+    bintray-upload
+  done
+  for PKG in $(ls pkgs/couch/$1/*.rpm 2>/dev/null); do
+    # Example filename: couchdb-2.3.0-1.el7.x86_64.rpm.asc
+    fname=${PKG##*/}
+    REPO="couchdb-rpm"
+    # better not put any extra . in the filename...
+    DIST=$(echo $fname | cut -d. -f 4)
+    PKGARCH=$(echo $fname | cut -d. -f 5)
+    PKGVERSION=$(echo $fname | cut -d- -f 2)
+    RELPATH="${DIST}/${PKGARCH}/${fname}"
+    HEADERS=()
+    bintray-upload
+  done
+}
+
+
+case "$1" in
+  clean)
+    # removes built pkgs for all platforms
+    shift
+    rm -rf ${SCRIPTPATH}/pkgs/js/* ${SCRIPTPATH}/pkgs/couch/*
+    ;;
+  js)
+    # Build js packages for a given platform
+    shift
+    build-js $1
+    ;;
+  js-all)
+    # build all supported JS packages
+    shift
+    build-all-js
+    ;;
+  js-upload)
+    shift
+    upload-js $1
+    ;;
+  js-upload-all)
+    shift
+    for dir in $(ls pkgs/js); do
+      upload-js $dir
+    done
+    ;;
+  couch)
+    # build CouchDB pkgs for <plat>
+    shift
+    get-couch-tarball $2
+    build-couch $*
+    ;;
+  couch-all)
+    # build CouchDB pkgs for all platforms
+    shift
+    get-couch-tarball $1
+    build-all-couch
+    ;;
+  couch-upload)
+    shift
+    upload-couch $1
+    ;;
+  couch-upload-all)
+    shift
+    for dir in $(ls pkgs/couch); do
+      upload-couch $dir
+    done
+    ;;
+  *)
+    if [[ $1 ]]; then
+      echo "Unknown target $1."
+      echo
+    fi
+    cat << EOF
+$0 <command> [OPTIONS]
+
+Recognized commands:
+  clean                 Remove all built package artefacts.
+
+  js                    Builds the JS packages for <plat>.
+  js-all                Builds the JS packages for all platforms.
+  *js-upload <plat>     Uploads the JS packages for <plat> to bintray.
+  *js-upload-all        Uploads the JS packages for all platforms to bintray.
+
+  couch <plat> <src>    Builds CouchDB packages for <plat>.
+  couch-all <src>       Builds CouchDB packages for all platforms.
+  *couch-upload <plat>  Uploads the JS packages for <plat> to bintray.
+  *couch-upload-all     Uploads the JS packages for all platforms to bintray.
+
+  <src> is either
+    - a path/to/a/couchdb.tar.gz, or
+    - a URL to http(s)://domain.com/to/couchdb.tar.gz
+
+  Commands marked with * require BINTRAY_USER and BINTRAY_API_KEY env vars.
+EOF
+    if [[ $1 ]]; then
+      exit 1
+    fi
+    ;;
+esac
+
+exit 0
diff --git a/make-releases.sh b/make-releases.sh
deleted file mode 100755
index 71798dd..0000000
--- a/make-releases.sh
+++ /dev/null
@@ -1,59 +0,0 @@
-#!/bin/bash
-IMAGES=(
-  centos-6-erlang-19.3.6 centos6 \
-  centos-7-erlang-19.3.6 centos7 \
-  debian-jessie-erlang-19.3.6 jessie \
-  debian-stretch-erlang-19.3.6 stretch \
-  ubuntu-trusty-erlang-19.3.6 trusty \
-  ubuntu-xenial-erlang-19.3.6 xenial \
-  ubuntu-bionic-erlang-19.3.6 bionic
-)
-
-usage() {
-  echo $0 takes exactly one argument, either:
-  echo '  - path/to/couchdb-VERSION.tar.gz or'
-  echo '  - http://url/to/couchdb-VERSION.tar.gz'
-  echo
-  exit
-}
-
-if [ $# -ne "1" ]
-then
-  usage
-fi
-
-ARG=$1
-
-if [ -f ${ARG} ]
-then
-  # file
-  cp ${ARG} . 2>/dev/null || true
-  FILE=$(basename ${ARG})
-else
-  if [[ ${ARG} =~ ^http.*$ ]]
-  then
-    # url
-    # thank you, advanced bash scripting guide
-    curl -O ${ARG}
-    FILE=${ARG##*/}
-  else
-    usage
-  fi
-fi
-
-echo Using ${FILE} to build packages...
-chmod 777 ${FILE}
-
-mkdir -p pkgs && chmod 777 pkgs
-
-image_count=${#IMAGES[@]}
-index=0
-
-while [ "$index" -lt "$image_count" ]
-do
-  img=${IMAGES[$index]}
-  ((index++))
-  plat=${IMAGES[$index]}
-  ((index++))
-  docker run -it -w /tmp/couchdb-pkg -v $(readlink -f .):/tmp/couchdb-pkg couchdbdev/$img make copy-couch $plat copy-pkgs PLATFORM=$plat COUCHTARBALL=${FILE}
-done
diff --git a/pkgs/couch/.gitignore b/pkgs/couch/.gitignore
new file mode 100644
index 0000000..d6b7ef3
--- /dev/null
+++ b/pkgs/couch/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
diff --git a/pkgs/js/.gitignore b/pkgs/js/.gitignore
new file mode 100644
index 0000000..d6b7ef3
--- /dev/null
+++ b/pkgs/js/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore