diff --git a/Jenkinsfile b/Jenkinsfile index 6783a49..3fc7768 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -16,6 +16,7 @@ pipeline { 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') JSON_URL = 'https://plex.tv/api/downloads/5.json' JSON_PATH = '.computer.Linux.version' BUILD_VERSION_ARG = 'PLEX_RELEASE' @@ -118,6 +119,23 @@ pipeline { 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}") } } } @@ -132,6 +150,7 @@ pipeline { 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 { @@ -154,6 +173,7 @@ pipeline { 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 { @@ -176,6 +196,7 @@ pipeline { 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 { @@ -371,6 +392,48 @@ pipeline { "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/plex") | .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/plex",\ + "shortDescription":"example description",\ + "libraryType":"docker",\ + "website":"https://github.com/linuxserver/docker-plex",\ + "backendUrl":"https://ghcr.io/linuxserver/plex",\ + "publicUrl":"https://lscr.io/linuxserver/plex"}' \ + | 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 ############### */ @@ -378,7 +441,7 @@ pipeline { stage('Build-Single') { when { expression { - env.MULTIARCH == 'false' || params.PACKAGE_CHECK == 'true' + env.MULTIARCH == 'false' || params.PACKAGE_CHECK == 'true' } environment name: 'EXIT_STATUS', value: '' } @@ -672,6 +735,12 @@ pipeline { credentialsId: '3f9ba4d5-100d-45b0-a3c4-633fd6061207', usernameVariable: 'DOCKERUSER', passwordVariable: 'DOCKERPASS' + ], + [ + $class: 'UsernamePasswordMultiBinding', + credentialsId: 'Quay.io-Robot', + usernameVariable: 'QUAYUSER', + passwordVariable: 'QUAYPASS' ] ]) { retry(5) { @@ -680,22 +749,26 @@ pipeline { 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 - for PUSHIMAGE in "${GITHUBIMAGE}" "${GITLABIMAGE}" "${IMAGE}"; do + 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}" "${IMAGE}"; do + for DELETEIMAGE in "${GITHUBIMAGE}" "${GITLABIMAGE}" "${QUAYIMAGE}" "${IMAGE}"; do docker rmi \ ${DELETEIMAGE}:${META_TAG} \ ${DELETEIMAGE}:${EXT_RELEASE_TAG} \ - ${DELETEIMAGE}:latest || : + ${DELETEIMAGE}:latest \ + ${DELETEIMAGE}:${SEMVER} || : done ''' } @@ -714,6 +787,12 @@ pipeline { credentialsId: '3f9ba4d5-100d-45b0-a3c4-633fd6061207', usernameVariable: 'DOCKERUSER', passwordVariable: 'DOCKERPASS' + ], + [ + $class: 'UsernamePasswordMultiBinding', + credentialsId: 'Quay.io-Robot', + usernameVariable: 'QUAYUSER', + passwordVariable: 'QUAYPASS' ] ]) { retry(5) { @@ -722,13 +801,14 @@ pipeline { 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}"; do + 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} @@ -738,6 +818,9 @@ pipeline { 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} @@ -747,6 +830,9 @@ pipeline { 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 @@ -759,24 +845,32 @@ pipeline { 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}" "${IMAGE}"; do + 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-${EXT_RELEASE_TAG} \ + ${DELETEIMAGE}:arm64v8-${SEMVER} || : done docker rmi \ ghcr.io/linuxserver/lsiodev-buildcache:arm32v7-${COMMIT_SHA}-${BUILD_NUMBER} \