ci: add scripts/sign-linux-tarball.sh for GPG signing
Adds `scripts/sign-linux-file.sh` which expectes the following variables set: * `LINUX_GPG_PRIVATE_KEY_FILE` - Path to the GPG export of private key. * `LINUX_GPG_PRIVATE_KEY_PASS` - Password necessary to use the private key. Given a file it creates a file with a `.asc` suffix containing the signature: ``` > wget -q https://status-im-prs.ams3.digitaloceanspaces.com/StatusIm-210809-104514-156806-pr.tar.gz > tar xvf StatusIm-210809-104514-156806-pr.tar.gz StatusIm-210809-104514-156806-pr.AppImage StatusIm-210809-104514-156806-pr.AppImage.asc > gpg --verify StatusIm-210809-104514-156806-pr.AppImage.asc gpg: assuming signed data in 'StatusIm-210809-104514-156806-pr.AppImage' gpg: Signature made Mon 09 Aug 2021 12:54:49 PM CEST using RSA key ID E20B4DFD gpg: Good signature from "Status.im Devel Signing (GPG key for signing Status.im development builds.) <devel@status.im>" [ultimate] Primary key fingerprint: BBF0 5F92 536B ED19 30A9 FD44 009F B3BF E20B 4DFD ``` Issue: https://github.com/status-im/infra-ci/issues/25 Requires: https://github.com/status-im/status-jenkins-lib/pull/32 Signed-off-by: Jakub Sokołowski <jakub@status.im>
This commit is contained in:
parent
50b6b59abf
commit
2df6def7f9
16
Makefile
16
Makefile
|
@ -248,12 +248,13 @@ $(APPIMAGE_TOOL):
|
||||||
echo -e "\e[92mFetching:\e[39m appimagetool"
|
echo -e "\e[92mFetching:\e[39m appimagetool"
|
||||||
rm -rf tmp/linux
|
rm -rf tmp/linux
|
||||||
mkdir -p tmp/linux/tools
|
mkdir -p tmp/linux/tools
|
||||||
wget https://github.com/AppImage/AppImageKit/releases/download/continuous/$(_APPIMAGE_TOOL)
|
wget -nv https://github.com/AppImage/AppImageKit/releases/download/continuous/$(_APPIMAGE_TOOL)
|
||||||
mv $(_APPIMAGE_TOOL) tmp/linux/tools/
|
mv $(_APPIMAGE_TOOL) tmp/linux/tools/
|
||||||
chmod +x $(APPIMAGE_TOOL)
|
chmod +x $(APPIMAGE_TOOL)
|
||||||
|
|
||||||
STATUS_CLIENT_APPIMAGE ?= pkg/Status.AppImage
|
STATUS_CLIENT_APPIMAGE ?= pkg/Status.AppImage
|
||||||
STATUS_CLIENT_TARBALL ?= pkg/Status.tar.gz
|
STATUS_CLIENT_TARBALL ?= pkg/Status.tar.gz
|
||||||
|
STATUS_CLIENT_TARBALL_FULL ?= $(shell realpath $(STATUS_CLIENT_TARBALL))
|
||||||
|
|
||||||
$(STATUS_CLIENT_APPIMAGE): override RESOURCES_LAYOUT := -d:production
|
$(STATUS_CLIENT_APPIMAGE): override RESOURCES_LAYOUT := -d:production
|
||||||
$(STATUS_CLIENT_APPIMAGE): nim_status_client $(APPIMAGE_TOOL) nim-status.desktop
|
$(STATUS_CLIENT_APPIMAGE): nim_status_client $(APPIMAGE_TOOL) nim-status.desktop
|
||||||
|
@ -288,11 +289,18 @@ $(STATUS_CLIENT_APPIMAGE): nim_status_client $(APPIMAGE_TOOL) nim-status.desktop
|
||||||
|
|
||||||
mkdir -p pkg
|
mkdir -p pkg
|
||||||
$(APPIMAGE_TOOL) tmp/linux/dist $(STATUS_CLIENT_APPIMAGE)
|
$(APPIMAGE_TOOL) tmp/linux/dist $(STATUS_CLIENT_APPIMAGE)
|
||||||
|
# if LINUX_GPG_PRIVATE_KEY_FILE is not set then we don't generate a signature
|
||||||
|
ifdef LINUX_GPG_PRIVATE_KEY_FILE
|
||||||
|
scripts/sign-linux-file.sh $(STATUS_CLIENT_APPIMAGE)
|
||||||
|
endif
|
||||||
|
|
||||||
$(STATUS_CLIENT_TARBALL): $(STATUS_CLIENT_APPIMAGE)
|
$(STATUS_CLIENT_TARBALL): $(STATUS_CLIENT_APPIMAGE)
|
||||||
tar czvf $(STATUS_CLIENT_TARBALL) \
|
cd $(shell dirname $(STATUS_CLIENT_APPIMAGE)) && \
|
||||||
-C $(shell dirname $(STATUS_CLIENT_APPIMAGE)) \
|
tar czvf $(STATUS_CLIENT_TARBALL_FULL) --ignore-failed-read \
|
||||||
$(shell basename $(STATUS_CLIENT_APPIMAGE))
|
$(shell basename $(STATUS_CLIENT_APPIMAGE)){,.asc}
|
||||||
|
ifdef LINUX_GPG_PRIVATE_KEY_FILE
|
||||||
|
scripts/sign-linux-file.sh $(STATUS_CLIENT_TARBALL)
|
||||||
|
endif
|
||||||
|
|
||||||
DMG_TOOL := node_modules/.bin/create-dmg
|
DMG_TOOL := node_modules/.bin/create-dmg
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,13 @@ RUN export DEBIAN_FRONTEND=noninteractive \
|
||||||
&& sudo apt install -yq software-properties-common \
|
&& sudo apt install -yq software-properties-common \
|
||||||
&& sudo add-apt-repository -y ppa:git-core/ppa \
|
&& sudo add-apt-repository -y ppa:git-core/ppa \
|
||||||
&& sudo apt update -yq \
|
&& sudo apt update -yq \
|
||||||
|
&& sudo apt purge -yq gnupg \
|
||||||
&& sudo apt install -yq --fix-missing \
|
&& sudo apt install -yq --fix-missing \
|
||||||
build-essential cmake git s3cmd libpcre3-dev libnss3 libxcomposite1 libxtst6 jq gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-tools gstreamer1.0-alsa gstreamer1.0-pulseaudio
|
build-essential cmake jq git s3cmd gnupg2 \
|
||||||
|
libpcre3-dev libnss3 libxcomposite1 libxtst6 \
|
||||||
|
gstreamer1.0-plugins-good gstreamer1.0-plugins-bad \
|
||||||
|
gstreamer1.0-plugins-ugly gstreamer1.0-libav \
|
||||||
|
gstreamer1.0-tools gstreamer1.0-alsa gstreamer1.0-pulseaudio
|
||||||
|
|
||||||
# Installing Golang
|
# Installing Golang
|
||||||
RUN GOLANG_SHA256="aed845e4185a0b2a3c3d5e1d0a35491702c55889192bb9c30e67a3de6849c067" \
|
RUN GOLANG_SHA256="aed845e4185a0b2a3c3d5e1d0a35491702c55889192bb9c30e67a3de6849c067" \
|
||||||
|
@ -40,5 +45,5 @@ USER jenkins
|
||||||
ENV HOME="/home/jenkins"
|
ENV HOME="/home/jenkins"
|
||||||
|
|
||||||
LABEL maintainer="jakub@status.im"
|
LABEL maintainer="jakub@status.im"
|
||||||
LABEL source="https://github.com/status-im/nim-status-client"
|
LABEL source="https://github.com/status-im/status-desktop"
|
||||||
LABEL description="Build image for the Status Desktop client written in Nim."
|
LABEL description="Build image for the Status Desktop client written in Nim."
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
library 'status-jenkins-lib@v1.2.20'
|
library 'status-jenkins-lib@ci-linux-signing'
|
||||||
|
|
||||||
pipeline {
|
pipeline {
|
||||||
agent { label 'linux' }
|
agent { label 'linux' }
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
library 'status-jenkins-lib@v1.2.20'
|
library 'status-jenkins-lib@ci-linux-signing'
|
||||||
|
|
||||||
pipeline {
|
pipeline {
|
||||||
agent {
|
agent {
|
||||||
docker {
|
docker {
|
||||||
label 'linux'
|
label 'linux'
|
||||||
image 'statusteam/nim-status-client-build:1.0.2'
|
image 'statusteam/nim-status-client-build:1.0.3'
|
||||||
/* allows jenkins use cat and mounts '/dev/fuse' for linuxdeployqt */
|
/* allows jenkins use cat and mounts '/dev/fuse' for linuxdeployqt */
|
||||||
args '--entrypoint="" --cap-add SYS_ADMIN --security-opt apparmor:unconfined --device /dev/fuse'
|
args '--entrypoint="" --cap-add SYS_ADMIN --security-opt apparmor:unconfined --device /dev/fuse'
|
||||||
}
|
}
|
||||||
|
@ -64,14 +64,9 @@ pipeline {
|
||||||
}
|
}
|
||||||
|
|
||||||
stage('Package') {
|
stage('Package') {
|
||||||
steps {
|
steps { script {
|
||||||
withCredentials([string(
|
linux.bundle('tgz-linux')
|
||||||
credentialsId: utils.getInfuraTokenCred(),
|
} }
|
||||||
variable: 'INFURA_TOKEN'
|
|
||||||
)]) {
|
|
||||||
sh 'make tgz-linux'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stage('Parallel Upload') {
|
stage('Parallel Upload') {
|
||||||
|
@ -84,7 +79,7 @@ pipeline {
|
||||||
}
|
}
|
||||||
stage('Archive') {
|
stage('Archive') {
|
||||||
steps { script {
|
steps { script {
|
||||||
archiveArtifacts(env.STATUS_CLIENT_TARBALL)
|
archiveArtifacts("${env.STATUS_CLIENT_TARBALL}*")
|
||||||
} }
|
} }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
library 'status-jenkins-lib@v1.2.20'
|
library 'status-jenkins-lib@ci-linux-signing'
|
||||||
|
|
||||||
pipeline {
|
pipeline {
|
||||||
agent {
|
agent {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
library 'status-jenkins-lib@v1.2.20'
|
library 'status-jenkins-lib@ci-linux-signing'
|
||||||
|
|
||||||
pipeline {
|
pipeline {
|
||||||
agent { label 'windows' }
|
agent { label 'windows' }
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -eof pipefail
|
||||||
|
|
||||||
|
# Checks -----------------------------------------------------------------------
|
||||||
|
|
||||||
|
if [[ $(uname) != 'Linux' ]]; then
|
||||||
|
echo 'This only works on Linux.' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ $# -lt 1 ]]; then
|
||||||
|
echo 'sign-linux-tarball.sh <file_to_sign>' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ -z "${LINUX_GPG_PRIVATE_KEY_FILE}" ]]; then
|
||||||
|
echo "Unable to import GPG key file if LINUX_GPG_PRIVATE_KEY_FILE is not set!" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ -z "${LINUX_GPG_PRIVATE_KEY_PASS}" ]]; then
|
||||||
|
echo "Unable to import GPG key file if LINUX_GPG_PRIVATE_KEY_PASS is not set!" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ ! -f "${LINUX_GPG_PRIVATE_KEY_FILE}" ]]; then
|
||||||
|
echo "No such file exists: ${LINUX_GPG_PRIVATE_KEY_FILE}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Signing ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
function clean_up {
|
||||||
|
STATUS=$?
|
||||||
|
if [[ "${STATUS}" -ne 0 ]]; then
|
||||||
|
echo -e "\n###### ERROR: See above for details."
|
||||||
|
fi
|
||||||
|
set +e
|
||||||
|
|
||||||
|
echo -e "\n### Removing Temporary Keyring..."
|
||||||
|
rm -frv "${GNUPGHOME}"
|
||||||
|
exit $STATUS
|
||||||
|
}
|
||||||
|
|
||||||
|
# First and only argument is the file to create signature for
|
||||||
|
TARGET="${1}"
|
||||||
|
|
||||||
|
# Use a temporary GPG home and for the keyring.
|
||||||
|
export GNUPGHOME=$(mktemp -d $HOME/.gnupg.tmp.XXXXXX)
|
||||||
|
# Remove the GPG home along with the keyring regardless of how script exits.
|
||||||
|
trap clean_up EXIT
|
||||||
|
|
||||||
|
# Fix for 'gpg: signing failed: Inappropriate ioctl for device' in Docker
|
||||||
|
echo 'allow-loopback-pinentry' > "${GNUPGHOME}/gpg-agent.conf"
|
||||||
|
echo 'pinentry-mode loopback' > "${GNUPGHOME}/gpg.conf"
|
||||||
|
|
||||||
|
# Import the GPG key file into the temporary keyring.
|
||||||
|
echo -e "\n### Importing GPG private key..."
|
||||||
|
gpg2 --batch --yes --passphrase-fd 0 \
|
||||||
|
--import "${LINUX_GPG_PRIVATE_KEY_FILE}" \
|
||||||
|
<<< "${LINUX_GPG_PRIVATE_KEY_PASS}"
|
||||||
|
|
||||||
|
# Trust all immported keys ultimately.
|
||||||
|
gpg2 --list-secret-keys --with-colons \
|
||||||
|
| awk -F: '/fpr/{printf "%s:6:\n", $10}' \
|
||||||
|
| gpg2 --import-ownertrust --batch
|
||||||
|
|
||||||
|
echo -e "\n### Signing target..."
|
||||||
|
gpg2 --batch --yes --passphrase-fd 0 --verbose \
|
||||||
|
--armor --detach-sign "${TARGET}" \
|
||||||
|
<<< "${LINUX_GPG_PRIVATE_KEY_PASS}"
|
||||||
|
|
||||||
|
echo -e "\n### Verifying signature..."
|
||||||
|
gpg2 --batch --verify "${TARGET}.asc" "${TARGET}"
|
||||||
|
|
||||||
|
echo -e "\n### DONE"
|
|
@ -17,7 +17,9 @@ CODESIGN_OPTS_EXTRA=("${@}")
|
||||||
|
|
||||||
function clean_up {
|
function clean_up {
|
||||||
STATUS=$?
|
STATUS=$?
|
||||||
[[ $? -eq 0 ]] || echo -e "\n###### ERROR: See above for details."
|
if [[ "${STATUS}" -eq 0 ]]; then
|
||||||
|
echo -e "\n###### ERROR: See above for details."
|
||||||
|
fi
|
||||||
set +e
|
set +e
|
||||||
|
|
||||||
echo -e "\n###### Cleaning up..."
|
echo -e "\n###### Cleaning up..."
|
||||||
|
|
Loading…
Reference in New Issue