platypush/.drone.yml
Fabio Manganiello 8925405788
All checks were successful
continuous-integration/drone/push Build is passing
Added | head -1 to git log commands that fetch the current head.
The reason is that `git log HEAD...HEAD~1` will return two or more
commits if we're dealing with merge commits, so we must be explicit that
we only need the latest one.
2023-09-20 23:42:34 +02:00

678 lines
19 KiB
YAML

---
kind: pipeline
type: docker
name: default
volumes:
- name: docs
host:
path: /opt/docs/platypush
steps:
###
### Mirror the current repository state to Github
###
- name: github-mirror
image: alpine
environment:
SSH_PUBKEY:
from_secret: ssh_pubkey
SSH_PRIVKEY:
from_secret: ssh_privkey
commands:
- apk add --update --no-cache git openssh
- mkdir -p ~/.ssh
- echo $SSH_PUBKEY > ~/.ssh/id_rsa.pub
- |
cat <<EOF > ~/.ssh/id_rsa
$SSH_PRIVKEY
EOF
- chmod 0600 ~/.ssh/id_rsa
- ssh-keyscan github.com >> ~/.ssh/known_hosts 2>/dev/null
- git config --global --add safe.directory $PWD
- git remote add github git@github.com:/BlackLight/platypush.git
- git pull --rebase github "$(git branch | head -1 | awk '{print $2}')" || echo "No such branch on Github"
- git push --all -v github
###
### Rebuild the docs
###
- name: docs
image: alpine
volumes:
- name: docs
path: /docs
commands:
- echo "Installing required build dependencies"
- apk add --update --no-cache make py3-sphinx py3-pip py3-paho-mqtt
- pip install -U hid sphinx-rtd-theme sphinx-book-theme
- pip install .
- mkdir -p /docs/current
- export APPDIR=$PWD
- rm -rf "$APPDIR/docs/build"
- echo "Building the updated documentation"
- cd "$APPDIR/docs"
- make html
- rm -f config*.yaml
- cd "$APPDIR"
- echo "Copying the new documentation files to the target folder"
- mv -v "$APPDIR/docs/build" /docs/new
- cd /docs
- mv current old
- mv new current
- rm -rf old
when:
event:
- tag
###
### Run the tests
###
- name: tests
image: python:3.11-alpine
commands:
- apk add --update --no-cache redis
- apk add --update --no-cache --virtual build-base g++ rust linux-headers
- pip install -U pip
- pip install .
- pip install -r requirements-tests.txt
- apk del build-base g++ rust linux-headers
- pytest tests
###
### Rebuild the UI files
###
- name: build-ui
image: node:current-alpine3.18
environment:
SSH_PUBKEY:
from_secret: ssh_pubkey
SSH_PRIVKEY:
from_secret: ssh_privkey
PGP_KEY:
from_secret: pgp_key
PGP_KEY_ID:
from_secret: pgp_key_id
when:
branch:
- master
event:
- push
depends_on:
- tests
commands:
- apk add --update --no-cache git
# Backup the original git configuration before changing attributes
- export GIT_CONF=$PWD/.git/config
- cp $GIT_CONF /tmp/git.config.orig
- git config --global --add safe.directory $PWD
- cd platypush/backend/http/webapp
- |
if [ $(git log --pretty=oneline $DRONE_COMMIT_AFTER...$DRONE_COMMIT_BEFORE . | wc -l) -eq 0 ]; then
echo "No UI changes detected, skipping build"
exit 0
fi
- |
if [ "$(git log --pretty=format:%s HEAD...HEAD~1 | head -1)" == "[Automatic] Updated UI files" ]; then
echo "UI changes have already been committed, skipping build"
exit 0
fi
- rm -rf node_modules
- npm install
- npm run build
- |
if [ $(git status --porcelain dist | wc -l) -eq 0 ]; then
echo "No build files have been changed"
exit 0
fi
- apk add --update --no-cache bash gnupg openssh
- mkdir -p ~/.ssh
- |
cat <<EOF | gpg --import --armor
$PGP_KEY
EOF
- echo $SSH_PUBKEY > ~/.ssh/id_rsa.pub
- |
cat <<EOF > ~/.ssh/id_rsa
$SSH_PRIVKEY
EOF
- chmod 0600 ~/.ssh/id_rsa
- ssh-keyscan git.platypush.tech >> ~/.ssh/known_hosts 2>/dev/null
- git config user.name "Platypush CI/CD Automation"
- git config user.email "admin@platypush.tech"
- git config commit.gpgsign true
- git config user.signingkey $PGP_KEY_ID
- git add dist
- git commit dist -S -m "[Automatic] Updated UI files" --no-verify
- git remote rm origin
- git remote add origin git@git.platypush.tech:platypush/platypush.git
- git push origin master
# Restore the original git configuration
- mv /tmp/git.config.orig $GIT_CONF
###
### Update the Arch packages
###
- name: update-arch-packages
image: python:3.11-alpine
environment:
WORKDIR: /tmp/workdir
SSH_PUBKEY:
from_secret: ssh_pubkey
SSH_PRIVKEY:
from_secret: ssh_privkey
when:
branch:
- master
event:
- push
depends_on:
- build-ui
commands:
- echo "-- Installing dependencies"
- apk add --update --no-cache curl git openssh pacman sudo
- echo "--- Parsing metadata"
- git config --global --add safe.directory $PWD
- git pull --rebase origin master --tags
- export VERSION=$(python setup.py --version)
- export HEAD=$(git log --pretty=format:%h HEAD...HEAD~1 | head -1)
- export GIT_VERSION="$VERSION.r$(git log --pretty=oneline HEAD...v$VERSION | wc -l).$HEAD"
- export TAG_URL="https://git.platypush.tech/platypush/platypush/archive/v$VERSION.tar.gz"
- echo "--- Preparing environment"
- mkdir -p ~/.ssh
- echo $SSH_PUBKEY > ~/.ssh/id_rsa.pub
- |
cat <<EOF > ~/.ssh/id_rsa
$SSH_PRIVKEY
EOF
- chmod 0600 ~/.ssh/id_rsa
- ssh-keyscan git.platypush.tech >> ~/.ssh/known_hosts 2>/dev/null
- ssh-keyscan aur.archlinux.org >> ~/.ssh/known_hosts 2>/dev/null
- adduser -u 1000 -D build
- mkdir -p $WORKDIR
- echo "--- Updating Arch git version"
- export PKGDIR=$WORKDIR/git
- git clone ssh://aur@aur.archlinux.org/platypush-git.git $PKGDIR
- git config --global --add safe.directory $PKGDIR
- chown -R build $PKGDIR
- cd $PKGDIR
- |
sed -i 'PKGBUILD' -r \
-e "s/^pkgver=.*/pkgver=$GIT_VERSION/" \
-e "s/^pkgrel=.*/pkgrel=1/" \
- sudo -u build makepkg --printsrcinfo > .SRCINFO
- export FILES_CHANGED=$(git status --porcelain --untracked-files=no | wc -l)
- |
if [ $FILES_CHANGED -gt 0 ]; then
echo "--- Pushing git package version $GIT_VERSION"
git commit -a -m '[Automatic] Package update'
git push origin master
fi
- echo "--- Updating Arch stable version"
- export PKGDIR=$WORKDIR/stable
- git clone ssh://aur@aur.archlinux.org/platypush.git $PKGDIR
- git config --global --add safe.directory $PKGDIR
- chown -R build $PKGDIR
- cd $PKGDIR
- export RELEASED_VERSION=$(grep -e '^pkgver=' PKGBUILD | sed -r -e 's/^pkgver=(.*)\s*/\1/')
- |
if [ "$RELEASED_VERSION" == "$VERSION" ]; then
exit 0
fi
- export TAG_CHECKSUM=$(curl --silent "$TAG_URL" | sha512sum | awk '{print $1}')
- |
sed -i 'PKGBUILD' -r \
-e "s/^pkgver=.*/pkgver=$VERSION/" \
-e "s/^pkgrel=.*/pkgrel=1/" \
-e "s/^sha512sums=.*/sha512sums=('$TAG_CHECKSUM')/"
- sudo -u build makepkg --printsrcinfo > .SRCINFO
- export FILES_CHANGED=$(git status --porcelain --untracked-files=no | wc -l)
- |
if [ $FILES_CHANGED -gt 0 ]; then
echo "--- Pushing stable package version $VERSION"
git commit -a -m '[Automatic] Package update'
git push origin master
fi
###
### Update the Debian (stable) packages
###
- name: update-debian-stable-packages
image: debian:stable
environment:
DEB_VERSION: stable
WORKDIR: /tmp/workdir
STABLE_PKG_NAME: platypush
PKG_NAME: platypush
S3_URL: s3://platypush-pkg/apt
AWS_ENDPOINT_URL: https://s3.nl-ams.scw.cloud
AWS_DEFAULT_REGION: nl-ams
AWS_ACCESS_KEY_ID:
from_secret: aws_access_key_id
AWS_SECRET_ACCESS_KEY:
from_secret: aws_secret_access_key
when:
branch:
- master
event:
- push
depends_on:
- build-ui
commands:
- echo "-- Installing dependencies"
- apt update
- apt install -y curl dpkg-dev gpg git python3 python3-pip
- pip install awscli --break-system-packages
- echo "-- Copying source directory"
- mkdir -p "$WORKDIR"
- export SRCDIR="$WORKDIR/src"
- cp -r "$PWD" "$SRCDIR"
- cd "$SRCDIR"
- echo "--- Parsing metadata"
- git config --global --add safe.directory $PWD
- git pull --rebase origin master --tags
- export VERSION=$(python3 setup.py --version)
- export GIT_VERSION="$VERSION-$(( $(git log --pretty=oneline HEAD...v$VERSION | wc -l) + 1))"
- export GIT_BUILD_DIR="$WORKDIR/$${PKG_NAME}_$${GIT_VERSION}_all"
- export GIT_DEB="$WORKDIR/$${PKG_NAME}_$${GIT_VERSION}_all.deb"
- echo "--- Building git package"
- pip install --prefix="$GIT_BUILD_DIR/usr" --no-cache --no-deps .
- |
find "$GIT_BUILD_DIR" -name "site-packages" | while read dir; do
base="$(dirname "$dir")"
mv "$dir" "$base/dist-packages"
done
- mkdir -p "$GIT_BUILD_DIR/DEBIAN"
- |
cat <<EOF > "$GIT_BUILD_DIR/DEBIAN/control"
Package: $PKG_NAME
Version: $GIT_VERSION
Maintainer: Fabio Manganiello <fabio@platypush.tech>
Depends: $(cat platypush/install/requirements/debian.txt | tr '\n' ',' | sed -re 's/,$//' -e 's/,/, /g')
Architecture: all
Homepage: https://platypush.tech
Description: Universal command executor and automation hub.
EOF
- dpkg --build "$GIT_BUILD_DIR"
- echo "--- Pushing package to the S3 bucket"
- aws s3 cp "$GIT_DEB" "$S3_URL/pool/$DEB_VERSION/dev/"
# If main/all/Packages doesn't exist, then we should create the first main release
- export PKGURL="https://apt.platypush.tech/dists/$DEB_VERSION/main/all/Packages"
- |
[ -z "$UPDATE_STABLE_PKG" ] &&
curl -ILs -o /dev/null -w "%{http_code}" "$PKGURL" |
grep -e '^4' >/dev/null && export UPDATE_STABLE_PKG=1
# If the published release version differs from the current one, then we should publish a new main release
- |
if [ -z "$UPDATE_STABLE_PKG" ]; then
RELEASED_VERSION=$(curl -s "$PKGURL" | grep -e '^Version: ' | head -1 | awk '{print $2}' | cut -d- -f 1)
[ "$RELEASED_VERSION" != "$VERSION" ] && export UPDATE_STABLE_PKG=1
fi
# Don't proceed and update the main release if it hasn't changed
- |
if [ -z "$UPDATE_STABLE_PKG" ]; then
exit 0
fi
- echo "--- Updating main package"
- aws s3 cp "$GIT_DEB" "$S3_URL/pool/$DEB_VERSION/main/$${PKG_NAME}_$${VERSION}-1_all.deb"
###
### Update the Debian (oldstable) packages
###
- name: update-debian-oldstable-packages
image: debian:oldstable
environment:
DEB_VERSION: oldstable
WORKDIR: /tmp/workdir
STABLE_PKG_NAME: platypush
PKG_NAME: platypush
S3_URL: s3://platypush-pkg/apt
AWS_ENDPOINT_URL: https://s3.nl-ams.scw.cloud
AWS_DEFAULT_REGION: nl-ams
AWS_ACCESS_KEY_ID:
from_secret: aws_access_key_id
AWS_SECRET_ACCESS_KEY:
from_secret: aws_secret_access_key
when:
branch:
- master
event:
- push
depends_on:
- build-ui
commands:
- echo "-- Copying source directory"
- mkdir -p "$WORKDIR"
- export SRCDIR="$WORKDIR/src"
- cp -r "$PWD" "$SRCDIR"
- cd "$SRCDIR"
- echo "-- Installing dependencies"
- apt update
- apt install -y curl dpkg-dev gpg git python3 python3-pip
- pip install awscli
- echo "--- Parsing metadata"
- git config --global --add safe.directory $PWD
- git pull --rebase origin master --tags
- export VERSION=$(python3 setup.py --version)
- export GIT_VERSION="$VERSION-$(( $(git log --pretty=oneline HEAD...v$VERSION | wc -l) + 1))"
- export GIT_BUILD_DIR="$WORKDIR/$${PKG_NAME}_$${GIT_VERSION}_all"
- export GIT_DEB="$WORKDIR/$${PKG_NAME}_$${GIT_VERSION}_all.deb"
- echo "--- Building git package"
- pip install --prefix="$GIT_BUILD_DIR/usr" --no-cache --no-deps .
- |
find "$GIT_BUILD_DIR" -name "site-packages" | while read dir; do
base="$(dirname "$dir")"
mv "$dir" "$base/dist-packages"
done
- mkdir -p "$GIT_BUILD_DIR/DEBIAN"
- |
cat <<EOF > "$GIT_BUILD_DIR/DEBIAN/control"
Package: $PKG_NAME
Version: $GIT_VERSION
Maintainer: Fabio Manganiello <fabio@platypush.tech>
Depends: $(cat platypush/install/requirements/debian.txt | tr '\n' ',' | sed -re 's/,$//' -e 's/,/, /g')
Architecture: all
Homepage: https://platypush.tech
Description: Universal command executor and automation hub.
EOF
- dpkg --build "$GIT_BUILD_DIR"
- echo "--- Pushing package to the S3 bucket"
- aws s3 cp "$GIT_DEB" "$S3_URL/pool/$DEB_VERSION/dev/"
# If main/all/Packages doesn't exist, then we should create the first main release
- export PKGURL="https://apt.platypush.tech/dists/$DEB_VERSION/main/all/Packages"
- |
[ -z "$UPDATE_STABLE_PKG" ] &&
curl -ILs -o /dev/null -w "%{http_code}" "$PKGURL" |
grep -e '^4' >/dev/null && export UPDATE_STABLE_PKG=1
# If the published release version differs from the current one, then we should publish a new main release
- |
if [ -z "$UPDATE_STABLE_PKG" ]; then
RELEASED_VERSION=$(curl -s "$PKGURL" | grep -e '^Version: ' | head -1 | awk '{print $2}' | cut -d- -f 1)
[ "$RELEASED_VERSION" != "$VERSION" ] && export UPDATE_STABLE_PKG=1
fi
# Don't proceed and update the main release if it hasn't changed
- |
if [ -z "$UPDATE_STABLE_PKG" ]; then
exit 0
fi
- echo "--- Updating main package"
- aws s3 cp "$GIT_DEB" "$S3_URL/pool/$DEB_VERSION/main/$${PKG_NAME}_$${VERSION}-1_all.deb"
###
### Updates the APT repository after new packages have been pushed
###
- name: update-apt-repo
image: debian:stable
privileged: true # Required to use the FUSE module for s3fs
environment:
S3_BUCKET: platypush-pkg
BUCKET_MNT: /mnt/s3
AWS_ENDPOINT_URL: https://s3.nl-ams.scw.cloud
AWS_DEFAULT_REGION: nl-ams
AWS_ACCESS_KEY_ID:
from_secret: aws_access_key_id
AWS_SECRET_ACCESS_KEY:
from_secret: aws_secret_access_key
PGP_PUBKEY:
from_secret: apt_pgp_pub_key
PGP_PRIVKEY:
from_secret: apt_pgp_priv_key
when:
branch:
- master
event:
- push
depends_on:
- update-debian-stable-packages
- update-debian-oldstable-packages
commands:
- echo "-- Installing dependencies"
- apt update
- apt install -y s3fs dpkg-dev gpg
- echo "-- Mounting the S3 bucket"
- mkdir -p "$BUCKET_MNT"
- s3fs "$S3_BUCKET" "$BUCKET_MNT" -o url="$AWS_ENDPOINT_URL"
- export APT_ROOT="$BUCKET_MNT/apt"
- echo "-- Cleaning up older apt releases"
- |
find "$APT_ROOT/pool" -mindepth 2 -maxdepth 2 -type d | while read reldir; do
pkg_to_remove=$(( $(ls "$reldir"/*.deb | wc -l) - 1 ))
[ $pkg_to_remove -le 0 ] && continue
ls "$reldir"/*.deb | sort -V | head -n$pkg_to_remove | xargs rm -f
done
- echo "-- Updating Packages files"
- |
echo "stable\noldstable" | while read distro; do
echo "main\ndev" | while read branch; do
branch_dir="$APT_ROOT/pool/$distro/$branch"
[ -d "$branch_dir" ] || continue
dist_dir="$APT_ROOT/dists/$distro/$branch/all"
mkdir -p "$dist_dir"
pkg_file="$dist_dir/Packages"
dpkg-scanpackages --arch all "$branch_dir" > "$pkg_file"
sed -i "$pkg_file" -re "s|^Filename: $APT_ROOT/|Filename: |"
cat "$pkg_file" | gzip -9 > "$pkg_file.gz"
done
done
- echo "-- Updating Release files"
- |
add_hashes() {
dist_dir=$1
hash_cmd=$2
hash_label=$3
echo "$hash_label:"
find "$dist_dir" -name 'Packages*' | while read file; do
basename="$(echo "$file" | sed -r -e "s|^$dist_dir/||")"
hash="$($hash_cmd "$file" | cut -d" " -f1)"
size="$(wc -c < $file)"
echo " $hash $size $basename"
echo " $hash $size $(echo $basename | sed -re 's|/all/|/binary-i386/|')"
echo " $hash $size $(echo $basename | sed -re 's|/all/|/binary-amd64/|')"
echo " $hash $size $(echo $basename | sed -re 's|/all/|/binary-armel/|')"
echo " $hash $size $(echo $basename | sed -re 's|/all/|/binary-armhf/|')"
echo " $hash $size $(echo $basename | sed -re 's|/all/|/binary-arm64/|')"
done
}
echo "stable\noldstable" | while read distro; do
dist_dir="$APT_ROOT/dists/$distro"
components=$(find "$dist_dir" -name Packages | awk -F '/' '{print $(NF-2)}' | uniq | tr '\n' ' ')
release_file="$dist_dir/Release"
cat <<EOF > "$release_file"
Origin: Platypush repository
Label: Platypush
Suite: $distro
Codename: $distro
Architectures: i386 amd64 armel armhf arm64
Components: $components
Description: The official APT repository for Platypush
Date: $(date -Ru)
EOF
add_hashes "$dist_dir" "md5sum" "MD5Sum" >> "$release_file"
add_hashes "$dist_dir" "sha1sum" "SHA1" >> "$release_file"
add_hashes "$dist_dir" "sha256sum" "SHA256" >> "$release_file"
done
- echo "-- Importing and refreshing PGP key"
- echo "$PGP_PUBKEY" > "$APT_ROOT/pubkey.txt"
- export PGP_KEYID=$(echo "$PGP_PUBKEY" | gpg --with-colons --import-options show-only --import --fingerprint | grep -e '^fpr:' | head -1 | awk -F ':' '{print $(NF - 1)}')
- |
cat <<EOF | gpg --import --armor
$PGP_PRIVKEY
EOF
- echo "-- Signing Release files"
- |
find "$APT_ROOT/dists" -type f -name Release | while read file; do
dirname="$(dirname "$file")"
cat "$file" | gpg -q --default-key "$PGP_KEYID" -abs > "$file.gpg"
cat "$file" | gpg -q --default-key "$PGP_KEYID" -abs --clearsign > "$dirname/InRelease"
done
###
### Updates the pip package upon new releases
###
- name: update-pip-package
image: python:3.11-alpine
environment:
TWINE_USERNAME:
from_secret: pypi_user
TWINE_PASSWORD:
from_secret: pypi_pass
when:
event:
- tag
depends_on:
- tests
- docs
commands:
- apk add --update --no-cache py3-twine
- python setup.py sdist bdist_wheel
- twine upload dist/platypush-$(python setup.py --version).tar.gz
###
### Checkpoint step that waits for all the package update
### steps to complete before proceeding to the next steps.
###
- name: wait-pkg-update
image: alpine
when:
branch:
- master
event:
- push
- tag
depends_on:
- update-arch-packages
- update-apt-repo
commands:
- echo "All packages have been successfully updated"
###
### Notifies about a new release
###
- name: notify-release
image: python:3.11-alpine
environment:
WORKER_RPC_SECRET:
from_secret: worker_rpc_secret
when:
event:
- tag
depends_on:
- update-pip-package
- wait-pkg-update
commands:
- apk add --update --no-cache curl
- |
curl --silent -XPOST \
-H "X-Token: $WORKER_RPC_SECRET" \
"https://worker.ci-cd.platypush.tech/hook/notify-platypush-release?version=$(python setup.py --version)"
###
### Notifies about a change in the CI/CD build status
###
- name: notify-build-status
image: alpine
environment:
WORKER_RPC_SECRET:
from_secret: worker_rpc_secret
when:
branch:
- master
event:
- push
status:
- success
- failure
depends_on:
- wait-pkg-update
commands:
- apk add --update --no-cache curl
- |
curl --silent -XPOST \
-H "X-Token: $WORKER_RPC_SECRET" \
"https://worker.ci-cd.platypush.tech/hook/notify-platypush-build?status=$DRONE_BUILD_STATUS"