docker-calibre-web/Jenkinsfile

992 lines
52 KiB
Groovy

pipeline {
agent {
label 'X86-64-MULTI'
}
options {
buildDiscarder(logRotator(numToKeepStr: '10', daysToKeepStr: '60'))
parallelsAlwaysFailFast()
}
// Input to determine if this is a package check
parameters {
string(defaultValue: 'false', description: 'package check run', name: 'PACKAGE_CHECK')
}
// Configuration for the variables used for this specific repo
environment {
BUILDS_DISCORD=credentials('build_webhook_url')
GITHUB_TOKEN=credentials('498b4638-2d02-4ce5-832d-8a57d01d97ab')
GITLAB_TOKEN=credentials('b6f0f1dd-6952-4cf6-95d1-9c06380283f0')
GITLAB_NAMESPACE=credentials('gitlab-namespace-id')
SCARF_TOKEN=credentials('scarf_api_key')
EXT_GIT_BRANCH = 'master'
EXT_USER = 'janeczku'
EXT_REPO = 'calibre-web'
BUILD_VERSION_ARG = 'CALIBREWEB_RELEASE'
LS_USER = 'linuxserver'
LS_REPO = 'docker-calibre-web'
CONTAINER_NAME = 'calibre-web'
DOCKERHUB_IMAGE = 'linuxserver/calibre-web'
DEV_DOCKERHUB_IMAGE = 'lsiodev/calibre-web'
PR_DOCKERHUB_IMAGE = 'lspipepr/calibre-web'
DIST_IMAGE = 'ubuntu'
MULTIARCH='true'
CI='true'
CI_WEB='true'
CI_PORT='8083'
CI_SSL='false'
CI_DELAY='120'
CI_DOCKERENV='TZ=US/Pacific'
CI_AUTH='user:password'
CI_WEBPATH=''
}
stages {
// Setup all the basic environment variables needed for the build
stage("Set ENV Variables base"){
steps{
script{
env.EXIT_STATUS = ''
env.LS_RELEASE = sh(
script: '''docker run --rm ghcr.io/linuxserver/alexeiled-skopeo sh -c 'skopeo inspect docker://docker.io/'${DOCKERHUB_IMAGE}':latest 2>/dev/null' | jq -r '.Labels.build_version' | awk '{print $3}' | grep '\\-ls' || : ''',
returnStdout: true).trim()
env.LS_RELEASE_NOTES = sh(
script: '''cat readme-vars.yml | awk -F \\" '/date: "[0-9][0-9].[0-9][0-9].[0-9][0-9]:/ {print $4;exit;}' | sed -E ':a;N;$!ba;s/\\r{0,1}\\n/\\\\n/g' ''',
returnStdout: true).trim()
env.GITHUB_DATE = sh(
script: '''date '+%Y-%m-%dT%H:%M:%S%:z' ''',
returnStdout: true).trim()
env.COMMIT_SHA = sh(
script: '''git rev-parse HEAD''',
returnStdout: true).trim()
env.CODE_URL = 'https://github.com/' + env.LS_USER + '/' + env.LS_REPO + '/commit/' + env.GIT_COMMIT
env.DOCKERHUB_LINK = 'https://hub.docker.com/r/' + env.DOCKERHUB_IMAGE + '/tags/'
env.PULL_REQUEST = env.CHANGE_ID
env.TEMPLATED_FILES = 'Jenkinsfile README.md LICENSE .editorconfig ./.github/CONTRIBUTING.md ./.github/FUNDING.yml ./.github/ISSUE_TEMPLATE/config.yml ./.github/ISSUE_TEMPLATE/issue.bug.md ./.github/ISSUE_TEMPLATE/issue.feature.md ./.github/PULL_REQUEST_TEMPLATE.md ./.github/workflows/external_trigger_scheduler.yml ./.github/workflows/greetings.yml ./.github/workflows/package_trigger_scheduler.yml ./.github/workflows/stale.yml ./.github/workflows/external_trigger.yml ./.github/workflows/package_trigger.yml'
}
script{
env.LS_RELEASE_NUMBER = sh(
script: '''echo ${LS_RELEASE} |sed 's/^.*-ls//g' ''',
returnStdout: true).trim()
}
script{
env.LS_TAG_NUMBER = sh(
script: '''#! /bin/bash
tagsha=$(git rev-list -n 1 ${LS_RELEASE} 2>/dev/null)
if [ "${tagsha}" == "${COMMIT_SHA}" ]; then
echo ${LS_RELEASE_NUMBER}
elif [ -z "${GIT_COMMIT}" ]; then
echo ${LS_RELEASE_NUMBER}
else
echo $((${LS_RELEASE_NUMBER} + 1))
fi''',
returnStdout: true).trim()
}
}
}
/* #######################
Package Version Tagging
####################### */
// Grab the current package versions in Git to determine package tag
stage("Set Package tag"){
steps{
script{
env.PACKAGE_TAG = sh(
script: '''#!/bin/bash
if [ -e package_versions.txt ] ; then
cat package_versions.txt | md5sum | cut -c1-8
else
echo none
fi''',
returnStdout: true).trim()
}
}
}
/* ########################
External Release Tagging
######################## */
// If this is a stable github release use the latest endpoint from github to determine the ext tag
stage("Set ENV github_stable"){
steps{
script{
env.EXT_RELEASE = sh(
script: '''curl -H "Authorization: token ${GITHUB_TOKEN}" -s https://api.github.com/repos/${EXT_USER}/${EXT_REPO}/releases/latest | jq -r '. | .tag_name' ''',
returnStdout: true).trim()
}
}
}
// If this is a stable or devel github release generate the link for the build message
stage("Set ENV github_link"){
steps{
script{
env.RELEASE_LINK = 'https://github.com/' + env.EXT_USER + '/' + env.EXT_REPO + '/releases/tag/' + env.EXT_RELEASE
}
}
}
// Sanitize the release tag and strip illegal docker or github characters
stage("Sanitize tag"){
steps{
script{
env.EXT_RELEASE_CLEAN = sh(
script: '''echo ${EXT_RELEASE} | sed 's/[~,%@+;:/]//g' ''',
returnStdout: true).trim()
env.SEMVER = (new Date()).format('YYYY.MM.dd')
def semver = env.EXT_RELEASE_CLEAN =~ /(\d+)\.(\d+)\.(\d+)$/
if (semver.find()) {
env.SEMVER = "${semver[0][1]}.${semver[0][2]}.${semver[0][3]}"
} else {
semver = env.EXT_RELEASE_CLEAN =~ /(\d+)\.(\d+)(?:\.(\d+))?(.*)$/
if (semver.find()) {
if (semver[0][3]) {
env.SEMVER = "${semver[0][1]}.${semver[0][2]}.${semver[0][3]}"
} else if (!semver[0][3] && !semver[0][4]) {
env.SEMVER = "${semver[0][1]}.${semver[0][2]}.${(new Date()).format('YYYYMMdd')}"
}
}
}
println("SEMVER: ${env.SEMVER}")
}
}
}
// If this is a master build use live docker endpoints
stage("Set ENV live build"){
when {
branch "master"
environment name: 'CHANGE_ID', value: ''
}
steps {
script{
env.IMAGE = env.DOCKERHUB_IMAGE
env.GITHUBIMAGE = 'ghcr.io/' + env.LS_USER + '/' + env.CONTAINER_NAME
env.GITLABIMAGE = 'registry.gitlab.com/linuxserver.io/' + env.LS_REPO + '/' + env.CONTAINER_NAME
env.QUAYIMAGE = 'quay.io/linuxserver.io/' + env.CONTAINER_NAME
if (env.MULTIARCH == 'true') {
env.CI_TAGS = 'amd64-' + env.EXT_RELEASE_CLEAN + '-ls' + env.LS_TAG_NUMBER + '|arm32v7-' + env.EXT_RELEASE_CLEAN + '-ls' + env.LS_TAG_NUMBER + '|arm64v8-' + env.EXT_RELEASE_CLEAN + '-ls' + env.LS_TAG_NUMBER
} else {
env.CI_TAGS = env.EXT_RELEASE_CLEAN + '-ls' + env.LS_TAG_NUMBER
}
env.VERSION_TAG = env.EXT_RELEASE_CLEAN + '-ls' + env.LS_TAG_NUMBER
env.META_TAG = env.EXT_RELEASE_CLEAN + '-ls' + env.LS_TAG_NUMBER
env.EXT_RELEASE_TAG = 'version-' + env.EXT_RELEASE_CLEAN
}
}
}
// If this is a dev build use dev docker endpoints
stage("Set ENV dev build"){
when {
not {branch "master"}
environment name: 'CHANGE_ID', value: ''
}
steps {
script{
env.IMAGE = env.DEV_DOCKERHUB_IMAGE
env.GITHUBIMAGE = 'ghcr.io/' + env.LS_USER + '/lsiodev-' + env.CONTAINER_NAME
env.GITLABIMAGE = 'registry.gitlab.com/linuxserver.io/' + env.LS_REPO + '/lsiodev-' + env.CONTAINER_NAME
env.QUAYIMAGE = 'quay.io/linuxserver.io/lsiodev-' + env.CONTAINER_NAME
if (env.MULTIARCH == 'true') {
env.CI_TAGS = 'amd64-' + env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA + '|arm32v7-' + env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA + '|arm64v8-' + env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA
} else {
env.CI_TAGS = env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA
}
env.VERSION_TAG = env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA
env.META_TAG = env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA
env.EXT_RELEASE_TAG = 'version-' + env.EXT_RELEASE_CLEAN
env.DOCKERHUB_LINK = 'https://hub.docker.com/r/' + env.DEV_DOCKERHUB_IMAGE + '/tags/'
}
}
}
// If this is a pull request build use dev docker endpoints
stage("Set ENV PR build"){
when {
not {environment name: 'CHANGE_ID', value: ''}
}
steps {
script{
env.IMAGE = env.PR_DOCKERHUB_IMAGE
env.GITHUBIMAGE = 'ghcr.io/' + env.LS_USER + '/lspipepr-' + env.CONTAINER_NAME
env.GITLABIMAGE = 'registry.gitlab.com/linuxserver.io/' + env.LS_REPO + '/lspipepr-' + env.CONTAINER_NAME
env.QUAYIMAGE = 'quay.io/linuxserver.io/lspipepr-' + env.CONTAINER_NAME
if (env.MULTIARCH == 'true') {
env.CI_TAGS = 'amd64-' + env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-pr-' + env.PULL_REQUEST + '|arm32v7-' + env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-pr-' + env.PULL_REQUEST + '|arm64v8-' + env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-pr-' + env.PULL_REQUEST
} else {
env.CI_TAGS = env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-pr-' + env.PULL_REQUEST
}
env.VERSION_TAG = env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-pr-' + env.PULL_REQUEST
env.META_TAG = env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-pr-' + env.PULL_REQUEST
env.EXT_RELEASE_TAG = 'version-' + env.EXT_RELEASE_CLEAN
env.CODE_URL = 'https://github.com/' + env.LS_USER + '/' + env.LS_REPO + '/pull/' + env.PULL_REQUEST
env.DOCKERHUB_LINK = 'https://hub.docker.com/r/' + env.PR_DOCKERHUB_IMAGE + '/tags/'
}
}
}
// Run ShellCheck
stage('ShellCheck') {
when {
environment name: 'CI', value: 'true'
}
steps {
withCredentials([
string(credentialsId: 'ci-tests-s3-key-id', variable: 'S3_KEY'),
string(credentialsId: 'ci-tests-s3-secret-access-key', variable: 'S3_SECRET')
]) {
script{
env.SHELLCHECK_URL = 'https://ci-tests.linuxserver.io/' + env.IMAGE + '/' + env.META_TAG + '/shellcheck-result.xml'
}
sh '''curl -sL https://raw.githubusercontent.com/linuxserver/docker-shellcheck/master/checkrun.sh | /bin/bash'''
sh '''#! /bin/bash
set -e
docker pull ghcr.io/linuxserver/lsiodev-spaces-file-upload:latest
docker run --rm \
-e DESTINATION=\"${IMAGE}/${META_TAG}/shellcheck-result.xml\" \
-e FILE_NAME="shellcheck-result.xml" \
-e MIMETYPE="text/xml" \
-v ${WORKSPACE}:/mnt \
-e SECRET_KEY=\"${S3_SECRET}\" \
-e ACCESS_KEY=\"${S3_KEY}\" \
-t ghcr.io/linuxserver/lsiodev-spaces-file-upload:latest \
python /upload.py'''
}
}
}
// Use helper containers to render templated files
stage('Update-Templates') {
when {
branch "master"
environment name: 'CHANGE_ID', value: ''
expression {
env.CONTAINER_NAME != null
}
}
steps {
sh '''#! /bin/bash
set -e
TEMPDIR=$(mktemp -d)
docker pull ghcr.io/linuxserver/jenkins-builder:latest
docker run --rm -e CONTAINER_NAME=${CONTAINER_NAME} -e GITHUB_BRANCH=master -v ${TEMPDIR}:/ansible/jenkins ghcr.io/linuxserver/jenkins-builder:latest
# Stage 1 - Jenkinsfile update
if [[ "$(md5sum Jenkinsfile | awk '{ print $1 }')" != "$(md5sum ${TEMPDIR}/docker-${CONTAINER_NAME}/Jenkinsfile | awk '{ print $1 }')" ]]; then
mkdir -p ${TEMPDIR}/repo
git clone https://github.com/${LS_USER}/${LS_REPO}.git ${TEMPDIR}/repo/${LS_REPO}
cd ${TEMPDIR}/repo/${LS_REPO}
git checkout -f master
cp ${TEMPDIR}/docker-${CONTAINER_NAME}/Jenkinsfile ${TEMPDIR}/repo/${LS_REPO}/
git add Jenkinsfile
git commit -m 'Bot Updating Templated Files'
git push https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/${LS_USER}/${LS_REPO}.git --all
echo "true" > /tmp/${COMMIT_SHA}-${BUILD_NUMBER}
echo "Updating Jenkinsfile"
rm -Rf ${TEMPDIR}
exit 0
else
echo "Jenkinsfile is up to date."
fi
# Stage 2 - Delete old templates
OLD_TEMPLATES=".github/ISSUE_TEMPLATE.md"
for i in ${OLD_TEMPLATES}; do
if [[ -f "${i}" ]]; then
TEMPLATES_TO_DELETE="${i} ${TEMPLATES_TO_DELETE}"
fi
done
if [[ -n "${TEMPLATES_TO_DELETE}" ]]; then
mkdir -p ${TEMPDIR}/repo
git clone https://github.com/${LS_USER}/${LS_REPO}.git ${TEMPDIR}/repo/${LS_REPO}
cd ${TEMPDIR}/repo/${LS_REPO}
git checkout -f master
for i in ${TEMPLATES_TO_DELETE}; do
git rm "${i}"
done
git commit -m 'Bot Updating Templated Files'
git push https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/${LS_USER}/${LS_REPO}.git --all
echo "true" > /tmp/${COMMIT_SHA}-${BUILD_NUMBER}
echo "Deleting old templates"
rm -Rf ${TEMPDIR}
exit 0
else
echo "No templates to delete"
fi
# Stage 3 - Update templates
CURRENTHASH=$(grep -hs ^ ${TEMPLATED_FILES} | md5sum | cut -c1-8)
cd ${TEMPDIR}/docker-${CONTAINER_NAME}
NEWHASH=$(grep -hs ^ ${TEMPLATED_FILES} | md5sum | cut -c1-8)
if [[ "${CURRENTHASH}" != "${NEWHASH}" ]] || ! grep -q '.jenkins-external' "${WORKSPACE}/.gitignore" 2>/dev/null; then
mkdir -p ${TEMPDIR}/repo
git clone https://github.com/${LS_USER}/${LS_REPO}.git ${TEMPDIR}/repo/${LS_REPO}
cd ${TEMPDIR}/repo/${LS_REPO}
git checkout -f master
cd ${TEMPDIR}/docker-${CONTAINER_NAME}
mkdir -p ${TEMPDIR}/repo/${LS_REPO}/.github/workflows
mkdir -p ${TEMPDIR}/repo/${LS_REPO}/.github/ISSUE_TEMPLATE
cp --parents ${TEMPLATED_FILES} ${TEMPDIR}/repo/${LS_REPO}/ || :
cd ${TEMPDIR}/repo/${LS_REPO}/
if ! grep -q '.jenkins-external' .gitignore 2>/dev/null; then
echo ".jenkins-external" >> .gitignore
git add .gitignore
fi
git add ${TEMPLATED_FILES}
git commit -m 'Bot Updating Templated Files'
git push https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/${LS_USER}/${LS_REPO}.git --all
echo "true" > /tmp/${COMMIT_SHA}-${BUILD_NUMBER}
else
echo "false" > /tmp/${COMMIT_SHA}-${BUILD_NUMBER}
fi
mkdir -p ${TEMPDIR}/gitbook
git clone https://github.com/linuxserver/docker-documentation.git ${TEMPDIR}/gitbook/docker-documentation
if [[ ("${BRANCH_NAME}" == "master") || ("${BRANCH_NAME}" == "main") ]] && [[ (! -f ${TEMPDIR}/gitbook/docker-documentation/images/docker-${CONTAINER_NAME}.md) || ("$(md5sum ${TEMPDIR}/gitbook/docker-documentation/images/docker-${CONTAINER_NAME}.md | awk '{ print $1 }')" != "$(md5sum ${TEMPDIR}/docker-${CONTAINER_NAME}/.jenkins-external/docker-${CONTAINER_NAME}.md | awk '{ print $1 }')") ]]; then
cp ${TEMPDIR}/docker-${CONTAINER_NAME}/.jenkins-external/docker-${CONTAINER_NAME}.md ${TEMPDIR}/gitbook/docker-documentation/images/
cd ${TEMPDIR}/gitbook/docker-documentation/
git add images/docker-${CONTAINER_NAME}.md
git commit -m 'Bot Updating Documentation'
git push https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/linuxserver/docker-documentation.git --all
fi
mkdir -p ${TEMPDIR}/unraid
git clone https://github.com/linuxserver/docker-templates.git ${TEMPDIR}/unraid/docker-templates
git clone https://github.com/linuxserver/templates.git ${TEMPDIR}/unraid/templates
if [[ -f ${TEMPDIR}/unraid/docker-templates/linuxserver.io/img/${CONTAINER_NAME}-logo.png ]]; then
sed -i "s|master/linuxserver.io/img/linuxserver-ls-logo.png|master/linuxserver.io/img/${CONTAINER_NAME}-logo.png|" ${TEMPDIR}/docker-${CONTAINER_NAME}/.jenkins-external/${CONTAINER_NAME}.xml
fi
if [[ ("${BRANCH_NAME}" == "master") || ("${BRANCH_NAME}" == "main") ]] && [[ (! -f ${TEMPDIR}/unraid/templates/unraid/${CONTAINER_NAME}.xml) || ("$(md5sum ${TEMPDIR}/unraid/templates/unraid/${CONTAINER_NAME}.xml | awk '{ print $1 }')" != "$(md5sum ${TEMPDIR}/docker-${CONTAINER_NAME}/.jenkins-external/${CONTAINER_NAME}.xml | awk '{ print $1 }')") ]]; then
cd ${TEMPDIR}/unraid/templates/
if grep -wq "${CONTAINER_NAME}" ${TEMPDIR}/unraid/templates/unraid/ignore.list; then
echo "Image is on the ignore list, removing Unraid template"
git rm unraid/${CONTAINER_NAME}.xml || :
git commit -m 'Bot Removing Deprecated Unraid Template' || :
else
cp ${TEMPDIR}/docker-${CONTAINER_NAME}/.jenkins-external/${CONTAINER_NAME}.xml ${TEMPDIR}/unraid/templates/unraid/
git add unraid/${CONTAINER_NAME}.xml
git commit -m 'Bot Updating Unraid Template'
fi
git push https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/linuxserver/templates.git --all
fi
rm -Rf ${TEMPDIR}'''
script{
env.FILES_UPDATED = sh(
script: '''cat /tmp/${COMMIT_SHA}-${BUILD_NUMBER}''',
returnStdout: true).trim()
}
}
}
// Exit the build if the Templated files were just updated
stage('Template-exit') {
when {
branch "master"
environment name: 'CHANGE_ID', value: ''
environment name: 'FILES_UPDATED', value: 'true'
expression {
env.CONTAINER_NAME != null
}
}
steps {
script{
env.EXIT_STATUS = 'ABORTED'
}
}
}
/* #######################
GitLab Mirroring
####################### */
// Ping into Gitlab to mirror this repo and have a registry endpoint
stage("GitLab Mirror"){
when {
environment name: 'EXIT_STATUS', value: ''
}
steps{
sh '''curl -H "Content-Type: application/json" -H "Private-Token: ${GITLAB_TOKEN}" -X POST https://gitlab.com/api/v4/projects \
-d '{"namespace_id":'${GITLAB_NAMESPACE}',\
"name":"'${LS_REPO}'",
"mirror":true,\
"import_url":"https://github.com/linuxserver/'${LS_REPO}'.git",\
"issues_access_level":"disabled",\
"merge_requests_access_level":"disabled",\
"repository_access_level":"enabled",\
"visibility":"public"}' '''
}
}
/* #######################
Scarf.sh package registry
####################### */
// Add package to Scarf.sh and set permissions
stage("Scarf.sh package registry"){
when {
branch "master"
environment name: 'EXIT_STATUS', value: ''
}
steps{
sh '''#! /bin/bash
set -e
PACKAGE_UUID=$(curl -X GET -H "Authorization: Bearer ${SCARF_TOKEN}" https://scarf.sh/api/v1/packages | jq -r '.[] | select(.name=="linuxserver/calibre-web") | .uuid')
if [ -z "${PACKAGE_UUID}" ]; then
echo "Adding package to Scarf.sh"
PACKAGE_UUID=$(curl -sX POST https://scarf.sh/api/v1/packages \
-H "Authorization: Bearer ${SCARF_TOKEN}" \
-H "Content-Type: application/json" \
-d '{"name":"linuxserver/calibre-web",\
"shortDescription":"example description",\
"libraryType":"docker",\
"website":"https://github.com/linuxserver/docker-calibre-web",\
"backendUrl":"https://ghcr.io/linuxserver/calibre-web",\
"publicUrl":"https://lscr.io/linuxserver/calibre-web"}' \
| jq -r .uuid)
else
echo "Package already exists on Scarf.sh"
fi
echo "Setting permissions on Scarf.sh for package ${PACKAGE_UUID}"
curl -X POST https://scarf.sh/api/v1/packages/${PACKAGE_UUID}/permissions \
-H "Authorization: Bearer ${SCARF_TOKEN}" \
-H "Content-Type: application/json" \
-d '[{"userQuery":"Spad","permissionLevel":"admin"},\
{"userQuery":"roxedus","permissionLevel":"admin"},\
{"userQuery":"nemchik","permissionLevel":"admin"},\
{"userQuery":"driz","permissionLevel":"admin"},\
{"userQuery":"aptalca","permissionLevel":"admin"},\
{"userQuery":"saarg","permissionLevel":"admin"},\
{"userQuery":"Stark","permissionLevel":"admin"}]'
'''
}
}
/* ###############
Build Container
############### */
// Build Docker container for push to LS Repo
stage('Build-Single') {
when {
expression {
env.MULTIARCH == 'false' || params.PACKAGE_CHECK == 'true'
}
environment name: 'EXIT_STATUS', value: ''
}
steps {
echo "Running on node: ${NODE_NAME}"
sh "docker build \
--label \"org.opencontainers.image.created=${GITHUB_DATE}\" \
--label \"org.opencontainers.image.authors=linuxserver.io\" \
--label \"org.opencontainers.image.url=https://github.com/linuxserver/docker-calibre-web/packages\" \
--label \"org.opencontainers.image.documentation=https://docs.linuxserver.io/images/docker-calibre-web\" \
--label \"org.opencontainers.image.source=https://github.com/linuxserver/docker-calibre-web\" \
--label \"org.opencontainers.image.version=${EXT_RELEASE_CLEAN}-ls${LS_TAG_NUMBER}\" \
--label \"org.opencontainers.image.revision=${COMMIT_SHA}\" \
--label \"org.opencontainers.image.vendor=linuxserver.io\" \
--label \"org.opencontainers.image.licenses=GPL-3.0-only\" \
--label \"org.opencontainers.image.ref.name=${COMMIT_SHA}\" \
--label \"org.opencontainers.image.title=Calibre-web\" \
--label \"org.opencontainers.image.description=[Calibre-web](https://github.com/janeczku/calibre-web) is a web app providing a clean interface for browsing, reading and downloading eBooks using an existing Calibre database. It is also possible to integrate google drive and edit metadata and your calibre library through the app itself. This software is a fork of library and licensed under the GPL v3 License. \" \
--no-cache --pull -t ${IMAGE}:${META_TAG} \
--build-arg ${BUILD_VERSION_ARG}=${EXT_RELEASE} --build-arg VERSION=\"${VERSION_TAG}\" --build-arg BUILD_DATE=${GITHUB_DATE} ."
}
}
// Build MultiArch Docker containers for push to LS Repo
stage('Build-Multi') {
when {
allOf {
environment name: 'MULTIARCH', value: 'true'
expression { params.PACKAGE_CHECK == 'false' }
}
environment name: 'EXIT_STATUS', value: ''
}
parallel {
stage('Build X86') {
steps {
echo "Running on node: ${NODE_NAME}"
sh "docker build \
--label \"org.opencontainers.image.created=${GITHUB_DATE}\" \
--label \"org.opencontainers.image.authors=linuxserver.io\" \
--label \"org.opencontainers.image.url=https://github.com/linuxserver/docker-calibre-web/packages\" \
--label \"org.opencontainers.image.documentation=https://docs.linuxserver.io/images/docker-calibre-web\" \
--label \"org.opencontainers.image.source=https://github.com/linuxserver/docker-calibre-web\" \
--label \"org.opencontainers.image.version=${EXT_RELEASE_CLEAN}-ls${LS_TAG_NUMBER}\" \
--label \"org.opencontainers.image.revision=${COMMIT_SHA}\" \
--label \"org.opencontainers.image.vendor=linuxserver.io\" \
--label \"org.opencontainers.image.licenses=GPL-3.0-only\" \
--label \"org.opencontainers.image.ref.name=${COMMIT_SHA}\" \
--label \"org.opencontainers.image.title=Calibre-web\" \
--label \"org.opencontainers.image.description=[Calibre-web](https://github.com/janeczku/calibre-web) is a web app providing a clean interface for browsing, reading and downloading eBooks using an existing Calibre database. It is also possible to integrate google drive and edit metadata and your calibre library through the app itself. This software is a fork of library and licensed under the GPL v3 License. \" \
--no-cache --pull -t ${IMAGE}:amd64-${META_TAG} \
--build-arg ${BUILD_VERSION_ARG}=${EXT_RELEASE} --build-arg VERSION=\"${VERSION_TAG}\" --build-arg BUILD_DATE=${GITHUB_DATE} ."
}
}
stage('Build ARMHF') {
agent {
label 'ARMHF'
}
steps {
echo "Running on node: ${NODE_NAME}"
echo 'Logging into Github'
sh '''#! /bin/bash
echo $GITHUB_TOKEN | docker login ghcr.io -u LinuxServer-CI --password-stdin
'''
sh "docker build \
--label \"org.opencontainers.image.created=${GITHUB_DATE}\" \
--label \"org.opencontainers.image.authors=linuxserver.io\" \
--label \"org.opencontainers.image.url=https://github.com/linuxserver/docker-calibre-web/packages\" \
--label \"org.opencontainers.image.documentation=https://docs.linuxserver.io/images/docker-calibre-web\" \
--label \"org.opencontainers.image.source=https://github.com/linuxserver/docker-calibre-web\" \
--label \"org.opencontainers.image.version=${EXT_RELEASE_CLEAN}-ls${LS_TAG_NUMBER}\" \
--label \"org.opencontainers.image.revision=${COMMIT_SHA}\" \
--label \"org.opencontainers.image.vendor=linuxserver.io\" \
--label \"org.opencontainers.image.licenses=GPL-3.0-only\" \
--label \"org.opencontainers.image.ref.name=${COMMIT_SHA}\" \
--label \"org.opencontainers.image.title=Calibre-web\" \
--label \"org.opencontainers.image.description=[Calibre-web](https://github.com/janeczku/calibre-web) is a web app providing a clean interface for browsing, reading and downloading eBooks using an existing Calibre database. It is also possible to integrate google drive and edit metadata and your calibre library through the app itself. This software is a fork of library and licensed under the GPL v3 License. \" \
--no-cache --pull -f Dockerfile.armhf -t ${IMAGE}:arm32v7-${META_TAG} \
--build-arg ${BUILD_VERSION_ARG}=${EXT_RELEASE} --build-arg VERSION=\"${VERSION_TAG}\" --build-arg BUILD_DATE=${GITHUB_DATE} ."
sh "docker tag ${IMAGE}:arm32v7-${META_TAG} ghcr.io/linuxserver/lsiodev-buildcache:arm32v7-${COMMIT_SHA}-${BUILD_NUMBER}"
retry(5) {
sh "docker push ghcr.io/linuxserver/lsiodev-buildcache:arm32v7-${COMMIT_SHA}-${BUILD_NUMBER}"
}
sh '''docker rmi \
${IMAGE}:arm32v7-${META_TAG} \
ghcr.io/linuxserver/lsiodev-buildcache:arm32v7-${COMMIT_SHA}-${BUILD_NUMBER} || :'''
}
}
stage('Build ARM64') {
agent {
label 'ARM64'
}
steps {
echo "Running on node: ${NODE_NAME}"
echo 'Logging into Github'
sh '''#! /bin/bash
echo $GITHUB_TOKEN | docker login ghcr.io -u LinuxServer-CI --password-stdin
'''
sh "docker build \
--label \"org.opencontainers.image.created=${GITHUB_DATE}\" \
--label \"org.opencontainers.image.authors=linuxserver.io\" \
--label \"org.opencontainers.image.url=https://github.com/linuxserver/docker-calibre-web/packages\" \
--label \"org.opencontainers.image.documentation=https://docs.linuxserver.io/images/docker-calibre-web\" \
--label \"org.opencontainers.image.source=https://github.com/linuxserver/docker-calibre-web\" \
--label \"org.opencontainers.image.version=${EXT_RELEASE_CLEAN}-ls${LS_TAG_NUMBER}\" \
--label \"org.opencontainers.image.revision=${COMMIT_SHA}\" \
--label \"org.opencontainers.image.vendor=linuxserver.io\" \
--label \"org.opencontainers.image.licenses=GPL-3.0-only\" \
--label \"org.opencontainers.image.ref.name=${COMMIT_SHA}\" \
--label \"org.opencontainers.image.title=Calibre-web\" \
--label \"org.opencontainers.image.description=[Calibre-web](https://github.com/janeczku/calibre-web) is a web app providing a clean interface for browsing, reading and downloading eBooks using an existing Calibre database. It is also possible to integrate google drive and edit metadata and your calibre library through the app itself. This software is a fork of library and licensed under the GPL v3 License. \" \
--no-cache --pull -f Dockerfile.aarch64 -t ${IMAGE}:arm64v8-${META_TAG} \
--build-arg ${BUILD_VERSION_ARG}=${EXT_RELEASE} --build-arg VERSION=\"${VERSION_TAG}\" --build-arg BUILD_DATE=${GITHUB_DATE} ."
sh "docker tag ${IMAGE}:arm64v8-${META_TAG} ghcr.io/linuxserver/lsiodev-buildcache:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER}"
retry(5) {
sh "docker push ghcr.io/linuxserver/lsiodev-buildcache:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER}"
}
sh '''docker rmi \
${IMAGE}:arm64v8-${META_TAG} \
ghcr.io/linuxserver/lsiodev-buildcache:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} || :'''
}
}
}
}
// Take the image we just built and dump package versions for comparison
stage('Update-packages') {
when {
branch "master"
environment name: 'CHANGE_ID', value: ''
environment name: 'EXIT_STATUS', value: ''
}
steps {
sh '''#! /bin/bash
set -e
TEMPDIR=$(mktemp -d)
if [ "${MULTIARCH}" == "true" ] && [ "${PACKAGE_CHECK}" == "false" ]; then
LOCAL_CONTAINER=${IMAGE}:amd64-${META_TAG}
else
LOCAL_CONTAINER=${IMAGE}:${META_TAG}
fi
if [ "${DIST_IMAGE}" == "alpine" ]; then
docker run --rm --entrypoint '/bin/sh' -v ${TEMPDIR}:/tmp ${LOCAL_CONTAINER} -c '\
apk info -v > /tmp/package_versions.txt && \
sort -o /tmp/package_versions.txt /tmp/package_versions.txt && \
chmod 777 /tmp/package_versions.txt'
elif [ "${DIST_IMAGE}" == "ubuntu" ]; then
docker run --rm --entrypoint '/bin/sh' -v ${TEMPDIR}:/tmp ${LOCAL_CONTAINER} -c '\
apt list -qq --installed | sed "s#/.*now ##g" | cut -d" " -f1 > /tmp/package_versions.txt && \
sort -o /tmp/package_versions.txt /tmp/package_versions.txt && \
chmod 777 /tmp/package_versions.txt'
elif [ "${DIST_IMAGE}" == "fedora" ]; then
docker run --rm --entrypoint '/bin/sh' -v ${TEMPDIR}:/tmp ${LOCAL_CONTAINER} -c '\
rpm -qa > /tmp/package_versions.txt && \
sort -o /tmp/package_versions.txt /tmp/package_versions.txt && \
chmod 777 /tmp/package_versions.txt'
elif [ "${DIST_IMAGE}" == "arch" ]; then
docker run --rm --entrypoint '/bin/sh' -v ${TEMPDIR}:/tmp ${LOCAL_CONTAINER} -c '\
pacman -Q > /tmp/package_versions.txt && \
chmod 777 /tmp/package_versions.txt'
fi
NEW_PACKAGE_TAG=$(md5sum ${TEMPDIR}/package_versions.txt | cut -c1-8 )
echo "Package tag sha from current packages in buit container is ${NEW_PACKAGE_TAG} comparing to old ${PACKAGE_TAG} from github"
if [ "${NEW_PACKAGE_TAG}" != "${PACKAGE_TAG}" ]; then
git clone https://github.com/${LS_USER}/${LS_REPO}.git ${TEMPDIR}/${LS_REPO}
git --git-dir ${TEMPDIR}/${LS_REPO}/.git checkout -f master
cp ${TEMPDIR}/package_versions.txt ${TEMPDIR}/${LS_REPO}/
cd ${TEMPDIR}/${LS_REPO}/
wait
git add package_versions.txt
git commit -m 'Bot Updating Package Versions'
git push https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/${LS_USER}/${LS_REPO}.git --all
echo "true" > /tmp/packages-${COMMIT_SHA}-${BUILD_NUMBER}
echo "Package tag updated, stopping build process"
else
echo "false" > /tmp/packages-${COMMIT_SHA}-${BUILD_NUMBER}
echo "Package tag is same as previous continue with build process"
fi
rm -Rf ${TEMPDIR}'''
script{
env.PACKAGE_UPDATED = sh(
script: '''cat /tmp/packages-${COMMIT_SHA}-${BUILD_NUMBER}''',
returnStdout: true).trim()
}
}
}
// Exit the build if the package file was just updated
stage('PACKAGE-exit') {
when {
branch "master"
environment name: 'CHANGE_ID', value: ''
environment name: 'PACKAGE_UPDATED', value: 'true'
environment name: 'EXIT_STATUS', value: ''
}
steps {
sh '''#! /bin/bash
echo "Packages were updated. Cleaning up the image and exiting."
if [ "${MULTIARCH}" == "true" ] && [ "${PACKAGE_CHECK}" == "false" ]; then
docker rmi ${IMAGE}:amd64-${META_TAG}
else
docker rmi ${IMAGE}:${META_TAG}
fi'''
script{
env.EXIT_STATUS = 'ABORTED'
}
}
}
// Exit the build if this is just a package check and there are no changes to push
stage('PACKAGECHECK-exit') {
when {
branch "master"
environment name: 'CHANGE_ID', value: ''
environment name: 'PACKAGE_UPDATED', value: 'false'
environment name: 'EXIT_STATUS', value: ''
expression {
params.PACKAGE_CHECK == 'true'
}
}
steps {
sh '''#! /bin/bash
echo "There are no package updates. Cleaning up the image and exiting."
if [ "${MULTIARCH}" == "true" ] && [ "${PACKAGE_CHECK}" == "false" ]; then
docker rmi ${IMAGE}:amd64-${META_TAG}
else
docker rmi ${IMAGE}:${META_TAG}
fi'''
script{
env.EXIT_STATUS = 'ABORTED'
}
}
}
/* #######
Testing
####### */
// Run Container tests
stage('Test') {
when {
environment name: 'CI', value: 'true'
environment name: 'EXIT_STATUS', value: ''
}
steps {
withCredentials([
string(credentialsId: 'ci-tests-s3-key-id', variable: 'S3_KEY'),
string(credentialsId: 'ci-tests-s3-secret-access-key ', variable: 'S3_SECRET')
]) {
script{
env.CI_URL = 'https://ci-tests.linuxserver.io/' + env.IMAGE + '/' + env.META_TAG + '/index.html'
}
sh '''#! /bin/bash
set -e
docker pull ghcr.io/linuxserver/ci:latest
if [ "${MULTIARCH}" == "true" ]; then
docker pull ghcr.io/linuxserver/lsiodev-buildcache:arm32v7-${COMMIT_SHA}-${BUILD_NUMBER}
docker pull ghcr.io/linuxserver/lsiodev-buildcache:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER}
docker tag ghcr.io/linuxserver/lsiodev-buildcache:arm32v7-${COMMIT_SHA}-${BUILD_NUMBER} ${IMAGE}:arm32v7-${META_TAG}
docker tag ghcr.io/linuxserver/lsiodev-buildcache:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} ${IMAGE}:arm64v8-${META_TAG}
fi
docker run --rm \
--shm-size=1gb \
-v /var/run/docker.sock:/var/run/docker.sock \
-e IMAGE=\"${IMAGE}\" \
-e DELAY_START=\"${CI_DELAY}\" \
-e TAGS=\"${CI_TAGS}\" \
-e META_TAG=\"${META_TAG}\" \
-e PORT=\"${CI_PORT}\" \
-e SSL=\"${CI_SSL}\" \
-e BASE=\"${DIST_IMAGE}\" \
-e SECRET_KEY=\"${S3_SECRET}\" \
-e ACCESS_KEY=\"${S3_KEY}\" \
-e DOCKER_ENV=\"${CI_DOCKERENV}\" \
-e WEB_SCREENSHOT=\"${CI_WEB}\" \
-e WEB_AUTH=\"${CI_AUTH}\" \
-e WEB_PATH=\"${CI_WEBPATH}\" \
-e DO_REGION="ams3" \
-e DO_BUCKET="lsio-ci" \
-t ghcr.io/linuxserver/ci:latest \
python /ci/ci.py'''
}
}
}
/* ##################
Release Logic
################## */
// If this is an amd64 only image only push a single image
stage('Docker-Push-Single') {
when {
environment name: 'MULTIARCH', value: 'false'
environment name: 'EXIT_STATUS', value: ''
}
steps {
withCredentials([
[
$class: 'UsernamePasswordMultiBinding',
credentialsId: '3f9ba4d5-100d-45b0-a3c4-633fd6061207',
usernameVariable: 'DOCKERUSER',
passwordVariable: 'DOCKERPASS'
],
[
$class: 'UsernamePasswordMultiBinding',
credentialsId: 'Quay.io-Robot',
usernameVariable: 'QUAYUSER',
passwordVariable: 'QUAYPASS'
]
]) {
retry(5) {
sh '''#! /bin/bash
set -e
echo $DOCKERPASS | docker login -u $DOCKERUSER --password-stdin
echo $GITHUB_TOKEN | docker login ghcr.io -u LinuxServer-CI --password-stdin
echo $GITLAB_TOKEN | docker login registry.gitlab.com -u LinuxServer.io --password-stdin
echo $QUAYPASS | docker login quay.io -u $QUAYUSER --password-stdin
for PUSHIMAGE in "${GITHUBIMAGE}" "${GITLABIMAGE}" "${QUAYIMAGE}" "${IMAGE}"; do
docker tag ${IMAGE}:${META_TAG} ${PUSHIMAGE}:${META_TAG}
docker tag ${PUSHIMAGE}:${META_TAG} ${PUSHIMAGE}:latest
docker tag ${PUSHIMAGE}:${META_TAG} ${PUSHIMAGE}:${EXT_RELEASE_TAG}
docker tag ${PUSHIMAGE}:${META_TAG} ${PUSHIMAGE}:${SEMVER}
docker push ${PUSHIMAGE}:latest
docker push ${PUSHIMAGE}:${META_TAG}
docker push ${PUSHIMAGE}:${EXT_RELEASE_TAG}
docker push ${PUSHIMAGE}:${SEMVER}
done
'''
}
sh '''#! /bin/bash
for DELETEIMAGE in "${GITHUBIMAGE}" "${GITLABIMAGE}" "${QUAYIMAGE}" "${IMAGE}"; do
docker rmi \
${DELETEIMAGE}:${META_TAG} \
${DELETEIMAGE}:${EXT_RELEASE_TAG} \
${DELETEIMAGE}:latest \
${DELETEIMAGE}:${SEMVER} || :
done
'''
}
}
}
// If this is a multi arch release push all images and define the manifest
stage('Docker-Push-Multi') {
when {
environment name: 'MULTIARCH', value: 'true'
environment name: 'EXIT_STATUS', value: ''
}
steps {
withCredentials([
[
$class: 'UsernamePasswordMultiBinding',
credentialsId: '3f9ba4d5-100d-45b0-a3c4-633fd6061207',
usernameVariable: 'DOCKERUSER',
passwordVariable: 'DOCKERPASS'
],
[
$class: 'UsernamePasswordMultiBinding',
credentialsId: 'Quay.io-Robot',
usernameVariable: 'QUAYUSER',
passwordVariable: 'QUAYPASS'
]
]) {
retry(5) {
sh '''#! /bin/bash
set -e
echo $DOCKERPASS | docker login -u $DOCKERUSER --password-stdin
echo $GITHUB_TOKEN | docker login ghcr.io -u LinuxServer-CI --password-stdin
echo $GITLAB_TOKEN | docker login registry.gitlab.com -u LinuxServer.io --password-stdin
echo $QUAYPASS | docker login quay.io -u $QUAYUSER --password-stdin
if [ "${CI}" == "false" ]; then
docker pull ghcr.io/linuxserver/lsiodev-buildcache:arm32v7-${COMMIT_SHA}-${BUILD_NUMBER}
docker pull ghcr.io/linuxserver/lsiodev-buildcache:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER}
docker tag ghcr.io/linuxserver/lsiodev-buildcache:arm32v7-${COMMIT_SHA}-${BUILD_NUMBER} ${IMAGE}:arm32v7-${META_TAG}
docker tag ghcr.io/linuxserver/lsiodev-buildcache:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} ${IMAGE}:arm64v8-${META_TAG}
fi
for MANIFESTIMAGE in "${IMAGE}" "${GITLABIMAGE}" "${GITHUBIMAGE}" "${QUAYIMAGE}"; do
docker tag ${IMAGE}:amd64-${META_TAG} ${MANIFESTIMAGE}:amd64-${META_TAG}
docker tag ${IMAGE}:arm32v7-${META_TAG} ${MANIFESTIMAGE}:arm32v7-${META_TAG}
docker tag ${IMAGE}:arm64v8-${META_TAG} ${MANIFESTIMAGE}:arm64v8-${META_TAG}
docker tag ${MANIFESTIMAGE}:amd64-${META_TAG} ${MANIFESTIMAGE}:amd64-latest
docker tag ${MANIFESTIMAGE}:arm32v7-${META_TAG} ${MANIFESTIMAGE}:arm32v7-latest
docker tag ${MANIFESTIMAGE}:arm64v8-${META_TAG} ${MANIFESTIMAGE}:arm64v8-latest
docker tag ${MANIFESTIMAGE}:amd64-${META_TAG} ${MANIFESTIMAGE}:amd64-${EXT_RELEASE_TAG}
docker tag ${MANIFESTIMAGE}:arm32v7-${META_TAG} ${MANIFESTIMAGE}:arm32v7-${EXT_RELEASE_TAG}
docker tag ${MANIFESTIMAGE}:arm64v8-${META_TAG} ${MANIFESTIMAGE}:arm64v8-${EXT_RELEASE_TAG}
docker tag ${MANIFESTIMAGE}:amd64-${META_TAG} ${MANIFESTIMAGE}:amd64-${SEMVER}
docker tag ${MANIFESTIMAGE}:arm32v7-${META_TAG} ${MANIFESTIMAGE}:arm32v7-${SEMVER}
docker tag ${MANIFESTIMAGE}:arm64v8-${META_TAG} ${MANIFESTIMAGE}:arm64v8-${SEMVER}
docker push ${MANIFESTIMAGE}:amd64-${META_TAG}
docker push ${MANIFESTIMAGE}:arm32v7-${META_TAG}
docker push ${MANIFESTIMAGE}:arm64v8-${META_TAG}
docker push ${MANIFESTIMAGE}:amd64-latest
docker push ${MANIFESTIMAGE}:arm32v7-latest
docker push ${MANIFESTIMAGE}:arm64v8-latest
docker push ${MANIFESTIMAGE}:amd64-${EXT_RELEASE_TAG}
docker push ${MANIFESTIMAGE}:arm32v7-${EXT_RELEASE_TAG}
docker push ${MANIFESTIMAGE}:arm64v8-${EXT_RELEASE_TAG}
docker push ${MANIFESTIMAGE}:amd64-${SEMVER}
docker push ${MANIFESTIMAGE}:arm32v7-${SEMVER}
docker push ${MANIFESTIMAGE}:arm64v8-${SEMVER}
docker manifest push --purge ${MANIFESTIMAGE}:latest || :
docker manifest create ${MANIFESTIMAGE}:latest ${MANIFESTIMAGE}:amd64-latest ${MANIFESTIMAGE}:arm32v7-latest ${MANIFESTIMAGE}:arm64v8-latest
docker manifest annotate ${MANIFESTIMAGE}:latest ${MANIFESTIMAGE}:arm32v7-latest --os linux --arch arm
docker manifest annotate ${MANIFESTIMAGE}:latest ${MANIFESTIMAGE}:arm64v8-latest --os linux --arch arm64 --variant v8
docker manifest push --purge ${MANIFESTIMAGE}:${META_TAG} || :
docker manifest create ${MANIFESTIMAGE}:${META_TAG} ${MANIFESTIMAGE}:amd64-${META_TAG} ${MANIFESTIMAGE}:arm32v7-${META_TAG} ${MANIFESTIMAGE}:arm64v8-${META_TAG}
docker manifest annotate ${MANIFESTIMAGE}:${META_TAG} ${MANIFESTIMAGE}:arm32v7-${META_TAG} --os linux --arch arm
docker manifest annotate ${MANIFESTIMAGE}:${META_TAG} ${MANIFESTIMAGE}:arm64v8-${META_TAG} --os linux --arch arm64 --variant v8
docker manifest push --purge ${MANIFESTIMAGE}:${EXT_RELEASE_TAG} || :
docker manifest create ${MANIFESTIMAGE}:${EXT_RELEASE_TAG} ${MANIFESTIMAGE}:amd64-${EXT_RELEASE_TAG} ${MANIFESTIMAGE}:arm32v7-${EXT_RELEASE_TAG} ${MANIFESTIMAGE}:arm64v8-${EXT_RELEASE_TAG}
docker manifest annotate ${MANIFESTIMAGE}:${EXT_RELEASE_TAG} ${MANIFESTIMAGE}:arm32v7-${EXT_RELEASE_TAG} --os linux --arch arm
docker manifest annotate ${MANIFESTIMAGE}:${EXT_RELEASE_TAG} ${MANIFESTIMAGE}:arm64v8-${EXT_RELEASE_TAG} --os linux --arch arm64 --variant v8
docker manifest push --purge ${MANIFESTIMAGE}:${SEMVER} || :
docker manifest create ${MANIFESTIMAGE}:${SEMVER} ${MANIFESTIMAGE}:amd64-${SEMVER} ${MANIFESTIMAGE}:arm32v7-${SEMVER} ${MANIFESTIMAGE}:arm64v8-${SEMVER}
docker manifest annotate ${MANIFESTIMAGE}:${SEMVER} ${MANIFESTIMAGE}:arm32v7-${SEMVER} --os linux --arch arm
docker manifest annotate ${MANIFESTIMAGE}:${SEMVER} ${MANIFESTIMAGE}:arm64v8-${SEMVER} --os linux --arch arm64 --variant v8
docker manifest push --purge ${MANIFESTIMAGE}:latest
docker manifest push --purge ${MANIFESTIMAGE}:${META_TAG}
docker manifest push --purge ${MANIFESTIMAGE}:${EXT_RELEASE_TAG}
docker manifest push --purge ${MANIFESTIMAGE}:${SEMVER}
done
'''
}
sh '''#! /bin/bash
for DELETEIMAGE in "${GITHUBIMAGE}" "${GITLABIMAGE}" "${QUAYIMAGE}" "${IMAGE}"; do
docker rmi \
${DELETEIMAGE}:amd64-${META_TAG} \
${DELETEIMAGE}:amd64-latest \
${DELETEIMAGE}:amd64-${EXT_RELEASE_TAG} \
${DELETEIMAGE}:amd64-${SEMVER} \
${DELETEIMAGE}:arm32v7-${META_TAG} \
${DELETEIMAGE}:arm32v7-latest \
${DELETEIMAGE}:arm32v7-${EXT_RELEASE_TAG} \
${DELETEIMAGE}:arm32v7-${SEMVER} \
${DELETEIMAGE}:arm64v8-${META_TAG} \
${DELETEIMAGE}:arm64v8-latest \
${DELETEIMAGE}:arm64v8-${EXT_RELEASE_TAG} \
${DELETEIMAGE}:arm64v8-${SEMVER} || :
done
docker rmi \
ghcr.io/linuxserver/lsiodev-buildcache:arm32v7-${COMMIT_SHA}-${BUILD_NUMBER} \
ghcr.io/linuxserver/lsiodev-buildcache:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} || :
'''
}
}
}
// If this is a public release tag it in the LS Github
stage('Github-Tag-Push-Release') {
when {
branch "master"
expression {
env.LS_RELEASE != env.EXT_RELEASE_CLEAN + '-ls' + env.LS_TAG_NUMBER
}
environment name: 'CHANGE_ID', value: ''
environment name: 'EXIT_STATUS', value: ''
}
steps {
echo "Pushing New tag for current commit ${META_TAG}"
sh '''curl -H "Authorization: token ${GITHUB_TOKEN}" -X POST https://api.github.com/repos/${LS_USER}/${LS_REPO}/git/tags \
-d '{"tag":"'${META_TAG}'",\
"object": "'${COMMIT_SHA}'",\
"message": "Tagging Release '${EXT_RELEASE_CLEAN}'-ls'${LS_TAG_NUMBER}' to master",\
"type": "commit",\
"tagger": {"name": "LinuxServer Jenkins","email": "jenkins@linuxserver.io","date": "'${GITHUB_DATE}'"}}' '''
echo "Pushing New release for Tag"
sh '''#! /bin/bash
curl -H "Authorization: token ${GITHUB_TOKEN}" -s https://api.github.com/repos/${EXT_USER}/${EXT_REPO}/releases/latest | jq '. |.body' | sed 's:^.\\(.*\\).$:\\1:' > releasebody.json
echo '{"tag_name":"'${META_TAG}'",\
"target_commitish": "master",\
"name": "'${META_TAG}'",\
"body": "**LinuxServer Changes:**\\n\\n'${LS_RELEASE_NOTES}'\\n\\n**'${EXT_REPO}' Changes:**\\n\\n' > start
printf '","draft": false,"prerelease": false}' >> releasebody.json
paste -d'\\0' start releasebody.json > releasebody.json.done
curl -H "Authorization: token ${GITHUB_TOKEN}" -X POST https://api.github.com/repos/${LS_USER}/${LS_REPO}/releases -d @releasebody.json.done'''
}
}
// Use helper container to sync the current README on master to the dockerhub endpoint
stage('Sync-README') {
when {
environment name: 'CHANGE_ID', value: ''
environment name: 'EXIT_STATUS', value: ''
}
steps {
withCredentials([
[
$class: 'UsernamePasswordMultiBinding',
credentialsId: '3f9ba4d5-100d-45b0-a3c4-633fd6061207',
usernameVariable: 'DOCKERUSER',
passwordVariable: 'DOCKERPASS'
]
]) {
sh '''#! /bin/bash
set -e
TEMPDIR=$(mktemp -d)
docker pull ghcr.io/linuxserver/jenkins-builder:latest
docker run --rm -e CONTAINER_NAME=${CONTAINER_NAME} -e GITHUB_BRANCH="${BRANCH_NAME}" -v ${TEMPDIR}:/ansible/jenkins ghcr.io/linuxserver/jenkins-builder:latest
docker pull ghcr.io/linuxserver/readme-sync
docker run --rm=true \
-e DOCKERHUB_USERNAME=$DOCKERUSER \
-e DOCKERHUB_PASSWORD=$DOCKERPASS \
-e GIT_REPOSITORY=${LS_USER}/${LS_REPO} \
-e DOCKER_REPOSITORY=${IMAGE} \
-e GIT_BRANCH=master \
-v ${TEMPDIR}/docker-${CONTAINER_NAME}:/mnt \
ghcr.io/linuxserver/readme-sync bash -c 'node sync'
rm -Rf ${TEMPDIR} '''
}
}
}
// If this is a Pull request send the CI link as a comment on it
stage('Pull Request Comment') {
when {
not {environment name: 'CHANGE_ID', value: ''}
environment name: 'CI', value: 'true'
environment name: 'EXIT_STATUS', value: ''
}
steps {
sh '''curl -H "Authorization: token ${GITHUB_TOKEN}" -X POST https://api.github.com/repos/${LS_USER}/${LS_REPO}/issues/${PULL_REQUEST}/comments \
-d '{"body": "I am a bot, here are the test results for this PR: \\n'${CI_URL}' \\n'${SHELLCHECK_URL}'"}' '''
}
}
}
/* ######################
Send status to Discord
###################### */
post {
always {
script{
if (env.EXIT_STATUS == "ABORTED"){
sh 'echo "build aborted"'
}
else if (currentBuild.currentResult == "SUCCESS"){
sh ''' curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://wiki.jenkins-ci.org/download/attachments/2916393/headshot.png","embeds": [{"color": 1681177,\
"description": "**Build:** '${BUILD_NUMBER}'\\n**CI Results:** '${CI_URL}'\\n**ShellCheck Results:** '${SHELLCHECK_URL}'\\n**Status:** Success\\n**Job:** '${RUN_DISPLAY_URL}'\\n**Change:** '${CODE_URL}'\\n**External Release:**: '${RELEASE_LINK}'\\n**DockerHub:** '${DOCKERHUB_LINK}'\\n"}],\
"username": "Jenkins"}' ${BUILDS_DISCORD} '''
}
else {
sh ''' curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://wiki.jenkins-ci.org/download/attachments/2916393/headshot.png","embeds": [{"color": 16711680,\
"description": "**Build:** '${BUILD_NUMBER}'\\n**CI Results:** '${CI_URL}'\\n**ShellCheck Results:** '${SHELLCHECK_URL}'\\n**Status:** failure\\n**Job:** '${RUN_DISPLAY_URL}'\\n**Change:** '${CODE_URL}'\\n**External Release:**: '${RELEASE_LINK}'\\n**DockerHub:** '${DOCKERHUB_LINK}'\\n"}],\
"username": "Jenkins"}' ${BUILDS_DISCORD} '''
}
}
}
cleanup {
cleanWs()
}
}
}