Compare commits

...

20 Commits

Author SHA1 Message Date
LinuxServer-CI
83e9ee723c Bot Updating Templated Files 2026-04-10 19:13:21 +00:00
LinuxServer-CI
69f8714750 Bot Updating Package Versions 2026-03-27 19:14:15 +00:00
LinuxServer-CI
fb0817506c Bot Updating Package Versions 2026-03-20 19:09:06 +00:00
LinuxServer-CI
812f33861c Bot Updating Package Versions 2026-03-13 19:03:25 +00:00
LinuxServer-CI
0ea5f069a1 Bot Updating Package Versions 2026-02-20 19:08:26 +00:00
LinuxServer-CI
0bbf23fef2 Bot Updating Templated Files 2026-02-13 19:12:34 +00:00
LinuxServer-CI
745334ec1d Bot Updating Templated Files 2026-02-13 19:10:27 +00:00
LinuxServer-CI
5ce6c7af4a Bot Updating Package Versions 2026-02-06 19:10:18 +00:00
LinuxServer-CI
4070c6c1c1 Bot Updating Package Versions 2026-01-30 19:04:04 +00:00
LinuxServer-CI
6f90ce6e0d Bot Updating Package Versions 2026-01-23 18:55:21 +00:00
LinuxServer-CI
2b346cb9fa Bot Updating Package Versions 2026-01-02 18:49:15 +00:00
LinuxServer-CI
a40f07406b Bot Updating Package Versions 2025-12-26 18:47:23 +00:00
LinuxServer-CI
1c1f459dc4 Bot Updating Package Versions 2025-12-19 18:48:19 +00:00
LinuxServer-CI
302ee1006f Bot Updating Package Versions 2025-12-12 18:49:33 +00:00
LinuxServer-CI
fcc5f92e92 Bot Updating Package Versions 2025-11-28 18:44:27 +00:00
LinuxServer-CI
9fea03932a Bot Updating Package Versions 2025-11-21 18:46:07 +00:00
LinuxServer-CI
74ec59b86d Bot Updating Templated Files 2025-11-21 18:41:24 +00:00
LinuxServer-CI
724ba9ef76 Bot Updating Package Versions 2025-11-14 18:46:12 +00:00
LinuxServer-CI
f50233ce8b Bot Updating Package Versions 2025-10-24 18:44:06 +00:00
LinuxServer-CI
c73a11aba7 Bot Updating Templated Files 2025-10-24 18:41:03 +00:00
3 changed files with 202 additions and 164 deletions

284
Jenkinsfile vendored
View File

@@ -78,6 +78,7 @@ pipeline {
''' '''
script{ script{
env.EXIT_STATUS = '' env.EXIT_STATUS = ''
env.CI_TEST_ATTEMPTED = ''
env.LS_RELEASE = sh( env.LS_RELEASE = sh(
script: '''docker run --rm quay.io/skopeo/stable:v1 inspect docker://ghcr.io/${LS_USER}/${CONTAINER_NAME}:latest 2>/dev/null | jq -r '.Labels.build_version' | awk '{print $3}' | grep '\\-ls' || : ''', script: '''docker run --rm quay.io/skopeo/stable:v1 inspect docker://ghcr.io/${LS_USER}/${CONTAINER_NAME}:latest 2>/dev/null | jq -r '.Labels.build_version' | awk '{print $3}' | grep '\\-ls' || : ''',
returnStdout: true).trim() returnStdout: true).trim()
@@ -218,6 +219,7 @@ pipeline {
env.META_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 env.EXT_RELEASE_TAG = 'version-' + env.EXT_RELEASE_CLEAN
env.BUILDCACHE = 'docker.io/lsiodev/buildcache,registry.gitlab.com/linuxserver.io/docker-jenkins-builder/lsiodev-buildcache,ghcr.io/linuxserver/lsiodev-buildcache,quay.io/linuxserver.io/lsiodev-buildcache' env.BUILDCACHE = 'docker.io/lsiodev/buildcache,registry.gitlab.com/linuxserver.io/docker-jenkins-builder/lsiodev-buildcache,ghcr.io/linuxserver/lsiodev-buildcache,quay.io/linuxserver.io/lsiodev-buildcache'
env.CITEST_IMAGETAG = 'latest'
} }
} }
} }
@@ -243,6 +245,7 @@ pipeline {
env.EXT_RELEASE_TAG = 'version-' + env.EXT_RELEASE_CLEAN env.EXT_RELEASE_TAG = 'version-' + env.EXT_RELEASE_CLEAN
env.DOCKERHUB_LINK = 'https://hub.docker.com/r/' + env.DEV_DOCKERHUB_IMAGE + '/tags/' env.DOCKERHUB_LINK = 'https://hub.docker.com/r/' + env.DEV_DOCKERHUB_IMAGE + '/tags/'
env.BUILDCACHE = 'docker.io/lsiodev/buildcache,registry.gitlab.com/linuxserver.io/docker-jenkins-builder/lsiodev-buildcache,ghcr.io/linuxserver/lsiodev-buildcache,quay.io/linuxserver.io/lsiodev-buildcache' env.BUILDCACHE = 'docker.io/lsiodev/buildcache,registry.gitlab.com/linuxserver.io/docker-jenkins-builder/lsiodev-buildcache,ghcr.io/linuxserver/lsiodev-buildcache,quay.io/linuxserver.io/lsiodev-buildcache'
env.CITEST_IMAGETAG = 'develop'
} }
} }
} }
@@ -268,6 +271,7 @@ pipeline {
env.CODE_URL = 'https://github.com/' + env.LS_USER + '/' + env.LS_REPO + '/pull/' + env.PULL_REQUEST 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/' env.DOCKERHUB_LINK = 'https://hub.docker.com/r/' + env.PR_DOCKERHUB_IMAGE + '/tags/'
env.BUILDCACHE = 'docker.io/lsiodev/buildcache,registry.gitlab.com/linuxserver.io/docker-jenkins-builder/lsiodev-buildcache,ghcr.io/linuxserver/lsiodev-buildcache,quay.io/linuxserver.io/lsiodev-buildcache' env.BUILDCACHE = 'docker.io/lsiodev/buildcache,registry.gitlab.com/linuxserver.io/docker-jenkins-builder/lsiodev-buildcache,ghcr.io/linuxserver/lsiodev-buildcache,quay.io/linuxserver.io/lsiodev-buildcache'
env.CITEST_IMAGETAG = 'develop'
} }
} }
} }
@@ -290,7 +294,7 @@ pipeline {
-v ${WORKSPACE}:/mnt \ -v ${WORKSPACE}:/mnt \
-e AWS_ACCESS_KEY_ID=\"${S3_KEY}\" \ -e AWS_ACCESS_KEY_ID=\"${S3_KEY}\" \
-e AWS_SECRET_ACCESS_KEY=\"${S3_SECRET}\" \ -e AWS_SECRET_ACCESS_KEY=\"${S3_SECRET}\" \
ghcr.io/linuxserver/baseimage-alpine:3.20 s6-envdir -fn -- /var/run/s6/container_environment /bin/bash -c "\ ghcr.io/linuxserver/baseimage-alpine:3.23 s6-envdir -fn -- /var/run/s6/container_environment /bin/bash -c "\
apk add --no-cache python3 && \ apk add --no-cache python3 && \
python3 -m venv /lsiopy && \ python3 -m venv /lsiopy && \
pip install --no-cache-dir -U pip && \ pip install --no-cache-dir -U pip && \
@@ -625,13 +629,16 @@ pipeline {
echo $GITHUB_TOKEN | docker login ghcr.io -u LinuxServer-CI --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 $GITLAB_TOKEN | docker login registry.gitlab.com -u LinuxServer.io --password-stdin
echo $QUAYPASS | docker login quay.io -u $QUAYUSER --password-stdin echo $QUAYPASS | docker login quay.io -u $QUAYUSER --password-stdin
if [[ "${PACKAGE_CHECK}" != "true" ]]; then if [[ "${PACKAGE_CHECK}" != "true" ]]; then
declare -A pids
IFS=',' read -ra CACHE <<< "$BUILDCACHE" IFS=',' read -ra CACHE <<< "$BUILDCACHE"
for i in "${CACHE[@]}"; do for i in "${CACHE[@]}"; do
docker push ${i}:amd64-${COMMIT_SHA}-${BUILD_NUMBER} & docker push ${i}:amd64-${COMMIT_SHA}-${BUILD_NUMBER} &
pids[$!]="$i"
done done
for p in $(jobs -p); do for p in "${!pids[@]}"; do
wait "$p" || { echo "job $p failed" >&2; exit 1; } wait "$p" || { [[ "${pids[$p]}" != *"quay.io"* ]] && exit 1; }
done done
fi fi
''' '''
@@ -691,13 +698,16 @@ pipeline {
echo $GITHUB_TOKEN | docker login ghcr.io -u LinuxServer-CI --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 $GITLAB_TOKEN | docker login registry.gitlab.com -u LinuxServer.io --password-stdin
echo $QUAYPASS | docker login quay.io -u $QUAYUSER --password-stdin echo $QUAYPASS | docker login quay.io -u $QUAYUSER --password-stdin
if [[ "${PACKAGE_CHECK}" != "true" ]]; then if [[ "${PACKAGE_CHECK}" != "true" ]]; then
declare -A pids
IFS=',' read -ra CACHE <<< "$BUILDCACHE" IFS=',' read -ra CACHE <<< "$BUILDCACHE"
for i in "${CACHE[@]}"; do for i in "${CACHE[@]}"; do
docker push ${i}:amd64-${COMMIT_SHA}-${BUILD_NUMBER} & docker push ${i}:amd64-${COMMIT_SHA}-${BUILD_NUMBER} &
pids[$!]="$i"
done done
for p in $(jobs -p); do for p in "${!pids[@]}"; do
wait "$p" || { echo "job $p failed" >&2; exit 1; } wait "$p" || { [[ "${pids[$p]}" != *"quay.io"* ]] && exit 1; }
done done
fi fi
''' '''
@@ -751,12 +761,14 @@ pipeline {
echo $GITLAB_TOKEN | docker login registry.gitlab.com -u LinuxServer.io --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 echo $QUAYPASS | docker login quay.io -u $QUAYUSER --password-stdin
if [[ "${PACKAGE_CHECK}" != "true" ]]; then if [[ "${PACKAGE_CHECK}" != "true" ]]; then
declare -A pids
IFS=',' read -ra CACHE <<< "$BUILDCACHE" IFS=',' read -ra CACHE <<< "$BUILDCACHE"
for i in "${CACHE[@]}"; do for i in "${CACHE[@]}"; do
docker push ${i}:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} & docker push ${i}:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} &
pids[$!]="$i"
done done
for p in $(jobs -p); do for p in "${!pids[@]}"; do
wait "$p" || { echo "job $p failed" >&2; exit 1; } wait "$p" || { [[ "${pids[$p]}" != *"quay.io"* ]] && exit 1; }
done done
fi fi
''' '''
@@ -870,6 +882,7 @@ pipeline {
script{ script{
env.CI_URL = 'https://ci-tests.linuxserver.io/' + env.IMAGE + '/' + env.META_TAG + '/index.html' env.CI_URL = 'https://ci-tests.linuxserver.io/' + env.IMAGE + '/' + env.META_TAG + '/index.html'
env.CI_JSON_URL = 'https://ci-tests.linuxserver.io/' + env.IMAGE + '/' + env.META_TAG + '/report.json' env.CI_JSON_URL = 'https://ci-tests.linuxserver.io/' + env.IMAGE + '/' + env.META_TAG + '/report.json'
env.CI_TEST_ATTEMPTED = 'true'
} }
sh '''#! /bin/bash sh '''#! /bin/bash
set -e set -e
@@ -881,7 +894,7 @@ pipeline {
CI_DOCKERENV="LSIO_FIRST_PARTY=true" CI_DOCKERENV="LSIO_FIRST_PARTY=true"
fi fi
fi fi
docker pull ghcr.io/linuxserver/ci:latest docker pull ghcr.io/linuxserver/ci:${CITEST_IMAGETAG}
if [ "${MULTIARCH}" == "true" ]; then if [ "${MULTIARCH}" == "true" ]; then
docker pull ghcr.io/linuxserver/lsiodev-buildcache:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} --platform=arm64 docker pull ghcr.io/linuxserver/lsiodev-buildcache:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} --platform=arm64
docker tag ghcr.io/linuxserver/lsiodev-buildcache:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} ${IMAGE}:arm64v8-${META_TAG} docker tag ghcr.io/linuxserver/lsiodev-buildcache:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} ${IMAGE}:arm64v8-${META_TAG}
@@ -905,7 +918,9 @@ pipeline {
-e WEB_PATH=\"${CI_WEBPATH}\" \ -e WEB_PATH=\"${CI_WEBPATH}\" \
-e NODE_NAME=\"${NODE_NAME}\" \ -e NODE_NAME=\"${NODE_NAME}\" \
-e SYFT_IMAGE_TAG=\"${CI_SYFT_IMAGE_TAG:-${SYFT_IMAGE_TAG}}\" \ -e SYFT_IMAGE_TAG=\"${CI_SYFT_IMAGE_TAG:-${SYFT_IMAGE_TAG}}\" \
-t ghcr.io/linuxserver/ci:latest \ -e COMMIT_SHA=\"${COMMIT_SHA}\" \
-e BUILD_NUMBER=\"${BUILD_NUMBER}\" \
-t ghcr.io/linuxserver/ci:${CITEST_IMAGETAG} \
python3 test_build.py''' python3 test_build.py'''
} }
} }
@@ -931,9 +946,11 @@ pipeline {
CACHEIMAGE=${i} CACHEIMAGE=${i}
fi fi
done done
docker buildx imagetools create --prefer-index=false -t ${PUSHIMAGE}:${META_TAG} -t ${PUSHIMAGE}:latest -t ${PUSHIMAGE}:${EXT_RELEASE_TAG} ${CACHEIMAGE}:amd64-${COMMIT_SHA}-${BUILD_NUMBER} docker buildx imagetools create --prefer-index=false -t ${PUSHIMAGE}:${META_TAG} -t ${PUSHIMAGE}:latest -t ${PUSHIMAGE}:${EXT_RELEASE_TAG} ${CACHEIMAGE}:amd64-${COMMIT_SHA}-${BUILD_NUMBER} || \
{ if [[ "${PUSHIMAGE}" != "${QUAYIMAGE}" ]]; then exit 1; fi; }
if [ -n "${SEMVER}" ]; then if [ -n "${SEMVER}" ]; then
docker buildx imagetools create --prefer-index=false -t ${PUSHIMAGE}:${SEMVER} ${CACHEIMAGE}:amd64-${COMMIT_SHA}-${BUILD_NUMBER} docker buildx imagetools create --prefer-index=false -t ${PUSHIMAGE}:${SEMVER} ${CACHEIMAGE}:amd64-${COMMIT_SHA}-${BUILD_NUMBER} || \
{ if [[ "${PUSHIMAGE}" != "${QUAYIMAGE}" ]]; then exit 1; fi; }
fi fi
done done
''' '''
@@ -958,20 +975,27 @@ pipeline {
CACHEIMAGE=${i} CACHEIMAGE=${i}
fi fi
done done
docker buildx imagetools create --prefer-index=false -t ${MANIFESTIMAGE}:amd64-${META_TAG} -t ${MANIFESTIMAGE}:amd64-latest -t ${MANIFESTIMAGE}:amd64-${EXT_RELEASE_TAG} ${CACHEIMAGE}:amd64-${COMMIT_SHA}-${BUILD_NUMBER} docker buildx imagetools create --prefer-index=false -t ${MANIFESTIMAGE}:amd64-${META_TAG} -t ${MANIFESTIMAGE}:amd64-latest -t ${MANIFESTIMAGE}:amd64-${EXT_RELEASE_TAG} ${CACHEIMAGE}:amd64-${COMMIT_SHA}-${BUILD_NUMBER} || \
docker buildx imagetools create --prefer-index=false -t ${MANIFESTIMAGE}:arm64v8-${META_TAG} -t ${MANIFESTIMAGE}:arm64v8-latest -t ${MANIFESTIMAGE}:arm64v8-${EXT_RELEASE_TAG} ${CACHEIMAGE}:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} { if [[ "${MANIFESTIMAGE}" != "${QUAYIMAGE}" ]]; then exit 1; fi; }
docker buildx imagetools create --prefer-index=false -t ${MANIFESTIMAGE}:arm64v8-${META_TAG} -t ${MANIFESTIMAGE}:arm64v8-latest -t ${MANIFESTIMAGE}:arm64v8-${EXT_RELEASE_TAG} ${CACHEIMAGE}:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} || \
{ if [[ "${MANIFESTIMAGE}" != "${QUAYIMAGE}" ]]; then exit 1; fi; }
if [ -n "${SEMVER}" ]; then if [ -n "${SEMVER}" ]; then
docker buildx imagetools create --prefer-index=false -t ${MANIFESTIMAGE}:amd64-${SEMVER} ${CACHEIMAGE}:amd64-${COMMIT_SHA}-${BUILD_NUMBER} docker buildx imagetools create --prefer-index=false -t ${MANIFESTIMAGE}:amd64-${SEMVER} ${CACHEIMAGE}:amd64-${COMMIT_SHA}-${BUILD_NUMBER} || \
docker buildx imagetools create --prefer-index=false -t ${MANIFESTIMAGE}:arm64v8-${SEMVER} ${CACHEIMAGE}:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} { if [[ "${MANIFESTIMAGE}" != "${QUAYIMAGE}" ]]; then exit 1; fi; }
docker buildx imagetools create --prefer-index=false -t ${MANIFESTIMAGE}:arm64v8-${SEMVER} ${CACHEIMAGE}:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} || \
{ if [[ "${MANIFESTIMAGE}" != "${QUAYIMAGE}" ]]; then exit 1; fi; }
fi fi
done done
for MANIFESTIMAGE in "${IMAGE}" "${GITLABIMAGE}" "${GITHUBIMAGE}" "${QUAYIMAGE}"; do for MANIFESTIMAGE in "${IMAGE}" "${GITLABIMAGE}" "${GITHUBIMAGE}" "${QUAYIMAGE}"; do
docker buildx imagetools create -t ${MANIFESTIMAGE}:latest ${MANIFESTIMAGE}:amd64-latest ${MANIFESTIMAGE}:arm64v8-latest docker buildx imagetools create -t ${MANIFESTIMAGE}:latest ${MANIFESTIMAGE}:amd64-latest ${MANIFESTIMAGE}:arm64v8-latest || \
docker buildx imagetools create -t ${MANIFESTIMAGE}:${META_TAG} ${MANIFESTIMAGE}:amd64-${META_TAG} ${MANIFESTIMAGE}:arm64v8-${META_TAG} { if [[ "${MANIFESTIMAGE}" != "${QUAYIMAGE}" ]]; then exit 1; fi; }
docker buildx imagetools create -t ${MANIFESTIMAGE}:${META_TAG} ${MANIFESTIMAGE}:amd64-${META_TAG} ${MANIFESTIMAGE}:arm64v8-${META_TAG} || \
docker buildx imagetools create -t ${MANIFESTIMAGE}:${EXT_RELEASE_TAG} ${MANIFESTIMAGE}:amd64-${EXT_RELEASE_TAG} ${MANIFESTIMAGE}:arm64v8-${EXT_RELEASE_TAG} { if [[ "${MANIFESTIMAGE}" != "${QUAYIMAGE}" ]]; then exit 1; fi; }
docker buildx imagetools create -t ${MANIFESTIMAGE}:${EXT_RELEASE_TAG} ${MANIFESTIMAGE}:amd64-${EXT_RELEASE_TAG} ${MANIFESTIMAGE}:arm64v8-${EXT_RELEASE_TAG} || \
{ if [[ "${MANIFESTIMAGE}" != "${QUAYIMAGE}" ]]; then exit 1; fi; }
if [ -n "${SEMVER}" ]; then if [ -n "${SEMVER}" ]; then
docker buildx imagetools create -t ${MANIFESTIMAGE}:${SEMVER} ${MANIFESTIMAGE}:amd64-${SEMVER} ${MANIFESTIMAGE}:arm64v8-${SEMVER} docker buildx imagetools create -t ${MANIFESTIMAGE}:${SEMVER} ${MANIFESTIMAGE}:amd64-${SEMVER} ${MANIFESTIMAGE}:arm64v8-${SEMVER} || \
{ if [[ "${MANIFESTIMAGE}" != "${QUAYIMAGE}" ]]; then exit 1; fi; }
fi fi
done done
''' '''
@@ -989,23 +1013,41 @@ pipeline {
environment name: 'EXIT_STATUS', value: '' environment name: 'EXIT_STATUS', value: ''
} }
steps { 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-CI","email": "ci@linuxserver.io","date": "'${GITHUB_DATE}'"}}' '''
echo "Pushing New release for Tag"
sh '''#! /bin/bash 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 "Auto-generating release notes"
echo '{"tag_name":"'${META_TAG}'",\ if [ "$(git tag --points-at HEAD)" != "" ]; then
"target_commitish": "master",\ echo "Existing tag points to current commit, suggesting no new LS changes"
"name": "'${META_TAG}'",\ AUTO_RELEASE_NOTES="No changes"
"body": "**CI Report:**\\n\\n'${CI_URL:-N/A}'\\n\\n**LinuxServer Changes:**\\n\\n'${LS_RELEASE_NOTES}'\\n\\n**Remote Changes:**\\n\\n' > start else
printf '","draft": false,"prerelease": false}' >> releasebody.json AUTO_RELEASE_NOTES=$(curl -fsL -H "Authorization: token ${GITHUB_TOKEN}" -H "Accept: application/vnd.github+json" -X POST https://api.github.com/repos/${LS_USER}/${LS_REPO}/releases/generate-notes \
paste -d'\\0' start releasebody.json > releasebody.json.done -d '{"tag_name":"'${META_TAG}'",\
curl -H "Authorization: token ${GITHUB_TOKEN}" -X POST https://api.github.com/repos/${LS_USER}/${LS_REPO}/releases -d @releasebody.json.done''' "target_commitish": "master"}' \
| jq -r '.body' | sed 's|## What.s Changed||')
fi
echo "Pushing New tag for current commit ${META_TAG}"
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-CI","email": "ci@linuxserver.io","date": "'${GITHUB_DATE}'"}}'
echo "Pushing New release for Tag"
curl -H "Authorization: token ${GITHUB_TOKEN}" -s https://api.github.com/repos/${EXT_USER}/${EXT_REPO}/releases/latest | jq -r '. |.body' > releasebody.json
jq -n \
--arg tag_name "$META_TAG" \
--arg target_commitish "master" \
--arg ci_url "${CI_URL:-N/A}" \
--arg ls_notes "$AUTO_RELEASE_NOTES" \
--arg remote_notes "$(cat releasebody.json)" \
'{
"tag_name": $tag_name,
"target_commitish": $target_commitish,
"name": $tag_name,
"body": ("**CI Report:**\\n\\n" + $ci_url + "\\n\\n**LinuxServer Changes:**\\n\\n" + $ls_notes + "\\n\\n**Remote Changes:**\\n\\n" + $remote_notes),
"draft": false,
"prerelease": false }' > 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
'''
} }
} }
// Add protection to the release branch // Add protection to the release branch
@@ -1043,98 +1085,13 @@ EOF
) ''' ) '''
} }
} }
// 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: 'EXIT_STATUS', value: ''
}
steps {
sh '''#! /bin/bash
# Function to retrieve JSON data from URL
get_json() {
local url="$1"
local response=$(curl -s "$url")
if [ $? -ne 0 ]; then
echo "Failed to retrieve JSON data from $url"
return 1
fi
local json=$(echo "$response" | jq .)
if [ $? -ne 0 ]; then
echo "Failed to parse JSON data from $url"
return 1
fi
echo "$json"
}
build_table() {
local data="$1"
# Get the keys in the JSON data
local keys=$(echo "$data" | jq -r 'to_entries | map(.key) | .[]')
# Check if keys are empty
if [ -z "$keys" ]; then
echo "JSON report data does not contain any keys or the report does not exist."
return 1
fi
# Build table header
local header="| Tag | Passed |\\n| --- | --- |\\n"
# Loop through the JSON data to build the table rows
local rows=""
for build in $keys; do
local status=$(echo "$data" | jq -r ".[\\"$build\\"].test_success")
if [ "$status" = "true" ]; then
status="✅"
else
status="❌"
fi
local row="| "$build" | "$status" |\\n"
rows="${rows}${row}"
done
local table="${header}${rows}"
local escaped_table=$(echo "$table" | sed 's/\"/\\\\"/g')
echo "$escaped_table"
}
if [[ "${CI}" = "true" ]]; then
# Retrieve JSON data from URL
data=$(get_json "$CI_JSON_URL")
# Create table from JSON data
table=$(build_table "$data")
echo -e "$table"
curl -X POST -H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
"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}\\n${table}\\"}"
else
curl -X POST -H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/$LS_USER/$LS_REPO/issues/$PULL_REQUEST/comments" \
-d "{\\"body\\": \\"I am a bot, here is the pushed image/manifest for this PR: \\n\\n\\`${GITHUBIMAGE}:${META_TAG}\\`\\"}"
fi
'''
}
}
} }
/* ###################### /* ######################
Send status to Discord Comment on PR and Send status to Discord
###################### */ ###################### */
post { post {
always { always {
sh '''#!/bin/bash script {
rm -rf /config/.ssh/id_sign
rm -rf /config/.ssh/id_sign.pub
git config --global --unset gpg.format
git config --global --unset user.signingkey
git config --global --unset commit.gpgsign
'''
script{
env.JOB_DATE = sh( env.JOB_DATE = sh(
script: '''date '+%Y-%m-%dT%H:%M:%S%:z' ''', script: '''date '+%Y-%m-%dT%H:%M:%S%:z' ''',
returnStdout: true).trim() returnStdout: true).trim()
@@ -1177,6 +1134,87 @@ EOF
"username": "Jenkins"}' ${BUILDS_DISCORD} ''' "username": "Jenkins"}' ${BUILDS_DISCORD} '''
} }
} }
script {
if (env.GITHUBIMAGE =~ /lspipepr/){
if (env.CI_TEST_ATTEMPTED == "true"){
sh '''#! /bin/bash
# Function to retrieve JSON data from URL
get_json() {
local url="$1"
local response=$(curl -s "$url")
if [ $? -ne 0 ]; then
echo "Failed to retrieve JSON data from $url"
return 1
fi
local json=$(echo "$response" | jq .)
if [ $? -ne 0 ]; then
echo "Failed to parse JSON data from $url"
return 1
fi
echo "$json"
}
build_table() {
local data="$1"
# Get the keys in the JSON data
local keys=$(echo "$data" | jq -r 'to_entries | map(.key) | .[]')
# Check if keys are empty
if [ -z "$keys" ]; then
echo "JSON report data does not contain any keys or the report does not exist."
return 1
fi
# Build table header
local header="| Tag | Passed |\\n| --- | --- |\\n"
# Loop through the JSON data to build the table rows
local rows=""
for build in $keys; do
local status=$(echo "$data" | jq -r ".[\\"$build\\"].test_success")
if [ "$status" = "true" ]; then
status="✅"
else
status="❌"
fi
local row="| "$build" | "$status" |\\n"
rows="${rows}${row}"
done
local table="${header}${rows}"
local escaped_table=$(echo "$table" | sed 's/\"/\\\\"/g')
echo "$escaped_table"
}
if [[ "${CI}" = "true" ]]; then
# Retrieve JSON data from URL
data=$(get_json "$CI_JSON_URL")
# Create table from JSON data
table=$(build_table "$data")
echo -e "$table"
curl -X POST -H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
"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}\\n${table}\\"}"
else
curl -X POST -H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/$LS_USER/$LS_REPO/issues/$PULL_REQUEST/comments" \
-d "{\\"body\\": \\"I am a bot, here is the pushed image/manifest for this PR: \\n\\n\\`${GITHUBIMAGE}:${META_TAG}\\`\\"}"
fi
'''
}
}
}
sh '''#!/bin/bash
rm -rf /config/.ssh/id_sign
rm -rf /config/.ssh/id_sign.pub
git config --global --unset gpg.format
git config --global --unset user.signingkey
git config --global --unset commit.gpgsign
'''
} }
cleanup { cleanup {
sh '''#! /bin/bash sh '''#! /bin/bash

View File

@@ -80,7 +80,7 @@ This image now supports password protection through htpasswd. Run the following
To help you get started creating a container from this image you can either use docker-compose or the docker cli. To help you get started creating a container from this image you can either use docker-compose or the docker cli.
>[!NOTE] >[!NOTE]
>Unless a parameter is flaged as 'optional', it is *mandatory* and a value must be provided. >Unless a parameter is flagged as 'optional', it is *mandatory* and a value must be provided.
### docker-compose (recommended, [click here for more info](https://docs.linuxserver.io/general/docker-compose)) ### docker-compose (recommended, [click here for more info](https://docs.linuxserver.io/general/docker-compose))

View File

@@ -4,8 +4,8 @@ acl-libs 2.3.2-r1 apk
alpine-baselayout 3.7.0-r0 apk alpine-baselayout 3.7.0-r0 apk
alpine-baselayout-data 3.7.0-r0 apk alpine-baselayout-data 3.7.0-r0 apk
alpine-keys 2.5-r0 apk alpine-keys 2.5-r0 apk
alpine-release 3.22.2-r0 apk alpine-release 3.22.3-r0 apk
apache2-utils 2.4.65-r0 apk apache2-utils 2.4.66-r0 apk
apk-tools 2.14.9-r3 apk apk-tools 2.14.9-r3 apk
apr 1.7.5-r0 apk apr 1.7.5-r0 apk
apr-util 1.6.3-r1 apk apr-util 1.6.3-r1 apk
@@ -17,15 +17,15 @@ barryvdh/reflection-docblock v2.3.1 php-composer
bash 5.2.37-r0 apk bash 5.2.37-r0 apk
brick/math 0.12.3 php-composer brick/math 0.12.3 php-composer
brotli-libs 1.1.0-r2 apk brotli-libs 1.1.0-r2 apk
busybox 1.37.0-r19 apk busybox 1.37.0-r20 apk
busybox-binsh 1.37.0-r19 apk busybox-binsh 1.37.0-r20 apk
c-ares 1.34.5-r0 apk c-ares 1.34.6-r0 apk
ca-certificates 20250911-r0 apk ca-certificates 20250911-r0 apk
ca-certificates-bundle 20250911-r0 apk ca-certificates-bundle 20250911-r0 apk
carbonphp/carbon-doctrine-types 3.2.0 php-composer carbonphp/carbon-doctrine-types 3.2.0 php-composer
catatonit 0.2.1-r0 apk catatonit 0.2.1-r0 apk
clue/stream-filter v1.7.0 php-composer clue/stream-filter v1.7.0 php-composer
composer 2.8.12 binary composer 2.9.5 binary
composer/class-map-generator 1.6.1 php-composer composer/class-map-generator 1.6.1 php-composer
composer/pcre 3.3.2 php-composer composer/pcre 3.3.2 php-composer
coreutils 9.7-r1 apk coreutils 9.7-r1 apk
@@ -56,7 +56,7 @@ guzzlehttp/uri-template v1.0.4 php-composer
hamcrest/hamcrest-php v2.1.1 php-composer hamcrest/hamcrest-php v2.1.1 php-composer
icu-data-en 76.1-r1 apk icu-data-en 76.1-r1 apk
icu-libs 76.1-r1 apk icu-libs 76.1-r1 apk
jq 1.8.0-r0 apk jq 1.8.1-r0 apk
knplabs/github-api v3.16.0 php-composer knplabs/github-api v3.16.0 php-composer
laravel/framework v11.45.1 php-composer laravel/framework v11.45.1 php-composer
laravel/prompts v0.3.6 php-composer laravel/prompts v0.3.6 php-composer
@@ -76,19 +76,19 @@ libapk2 2.14.9-r3 apk
libattr 2.5.2-r2 apk libattr 2.5.2-r2 apk
libbsd 0.12.2-r0 apk libbsd 0.12.2-r0 apk
libbz2 1.0.8-r6 apk libbz2 1.0.8-r6 apk
libcrypto3 3.5.4-r0 apk libcrypto3 3.5.5-r0 apk
libcurl 8.14.1-r2 apk libcurl 8.14.1-r2 apk
libedit 20250104.3.1-r1 apk libedit 20250104.3.1-r1 apk
libexpat 2.7.3-r0 apk libexpat 2.7.5-r0 apk
libgcc 14.2.0-r6 apk libgcc 14.2.0-r6 apk
libidn2 2.3.7-r0 apk libidn2 2.3.7-r0 apk
libintl 0.24.1-r0 apk libintl 0.24.1-r0 apk
libmd 1.1.0-r0 apk libmd 1.1.0-r0 apk
libncursesw 6.5_p20250503-r0 apk libncursesw 6.5_p20250503-r0 apk
libpq 17.6-r0 apk libpq 17.9-r0 apk
libproc2 4.0.4-r3 apk libproc2 4.0.4-r3 apk
libpsl 0.21.5-r3 apk libpsl 0.21.5-r3 apk
libssl3 3.5.4-r0 apk libssl3 3.5.5-r0 apk
libstdc++ 14.2.0-r6 apk libstdc++ 14.2.0-r6 apk
libunistring 1.3-r0 apk libunistring 1.3-r0 apk
libuuid 2.41-r9 apk libuuid 2.41-r9 apk
@@ -109,13 +109,13 @@ netcat-openbsd 1.229.1-r0 apk
nette/schema v1.3.2 php-composer nette/schema v1.3.2 php-composer
nette/utils v4.0.7 php-composer nette/utils v4.0.7 php-composer
nghttp2-libs 1.65.0-r0 apk nghttp2-libs 1.65.0-r0 apk
nginx 1.28.0-r3 apk nginx 1.28.3-r0 apk
nikic/php-parser v5.5.0 php-composer nikic/php-parser v5.5.0 php-composer
nunomaduro/collision v8.5.0 php-composer nunomaduro/collision v8.5.0 php-composer
nunomaduro/termwind v2.3.1 php-composer nunomaduro/termwind v2.3.1 php-composer
oniguruma 6.9.10-r0 apk oniguruma 6.9.10-r0 apk
openssl 3.5.4-r0 apk openssl 3.5.5-r0 apk
pcre2 10.43-r1 apk pcre2 10.46-r0 apk
phar-io/manifest 2.0.4 php-composer phar-io/manifest 2.0.4 php-composer
phar-io/version 3.2.1 php-composer phar-io/version 3.2.1 php-composer
php-http/cache-plugin 2.0.1 php-composer php-http/cache-plugin 2.0.1 php-composer
@@ -125,30 +125,30 @@ php-http/httplug 2.4.1 php-composer
php-http/message 1.16.2 php-composer php-http/message 1.16.2 php-composer
php-http/multipart-stream-builder 1.4.2 php-composer php-http/multipart-stream-builder 1.4.2 php-composer
php-http/promise 1.3.1 php-composer php-http/promise 1.3.1 php-composer
php84 8.4.13-r0 apk php84 8.4.16-r0 apk
php84-common 8.4.13-r0 apk php84-common 8.4.16-r0 apk
php84-ctype 8.4.13-r0 apk php84-ctype 8.4.16-r0 apk
php84-curl 8.4.13-r0 apk php84-curl 8.4.16-r0 apk
php84-dom 8.4.13-r0 apk php84-dom 8.4.16-r0 apk
php84-fileinfo 8.4.13-r0 apk php84-fileinfo 8.4.16-r0 apk
php84-fpm 8.4.13-r0 apk php84-fpm 8.4.16-r0 apk
php84-iconv 8.4.13-r0 apk php84-iconv 8.4.16-r0 apk
php84-intl 8.4.13-r0 apk php84-intl 8.4.16-r0 apk
php84-mbstring 8.4.13-r0 apk php84-mbstring 8.4.16-r0 apk
php84-mysqlnd 8.4.13-r0 apk php84-mysqlnd 8.4.16-r0 apk
php84-opcache 8.4.13-r0 apk php84-opcache 8.4.16-r0 apk
php84-openssl 8.4.13-r0 apk php84-openssl 8.4.16-r0 apk
php84-pdo 8.4.13-r0 apk php84-pdo 8.4.16-r0 apk
php84-pdo_mysql 8.4.13-r0 apk php84-pdo_mysql 8.4.16-r0 apk
php84-pdo_pgsql 8.4.13-r0 apk php84-pdo_pgsql 8.4.16-r0 apk
php84-pdo_sqlite 8.4.13-r0 apk php84-pdo_sqlite 8.4.16-r0 apk
php84-phar 8.4.13-r0 apk php84-phar 8.4.16-r0 apk
php84-session 8.4.13-r0 apk php84-session 8.4.16-r0 apk
php84-simplexml 8.4.13-r0 apk php84-simplexml 8.4.16-r0 apk
php84-tokenizer 8.4.13-r0 apk php84-tokenizer 8.4.16-r0 apk
php84-xml 8.4.13-r0 apk php84-xml 8.4.16-r0 apk
php84-xmlwriter 8.4.13-r0 apk php84-xmlwriter 8.4.16-r0 apk
php84-zip 8.4.13-r0 apk php84-zip 8.4.16-r0 apk
phpoption/phpoption 1.9.3 php-composer phpoption/phpoption 1.9.3 php-composer
phpunit/php-code-coverage 10.1.16 php-composer phpunit/php-code-coverage 10.1.16 php-composer
phpunit/php-file-iterator 4.1.0 php-composer phpunit/php-file-iterator 4.1.0 php-composer
@@ -198,7 +198,7 @@ spatie/laravel-html 3.12.0 php-composer
spatie/laravel-ignition 2.9.1 php-composer spatie/laravel-ignition 2.9.1 php-composer
sqlite-libs 3.49.2-r1 apk sqlite-libs 3.49.2-r1 apk
squizlabs/php_codesniffer 3.13.2 php-composer squizlabs/php_codesniffer 3.13.2 php-composer
ssl_client 1.37.0-r19 apk ssl_client 1.37.0-r20 apk
symfony/cache v7.3.1 php-composer symfony/cache v7.3.1 php-composer
symfony/cache-contracts v3.6.0 php-composer symfony/cache-contracts v3.6.0 php-composer
symfony/clock v7.3.0 php-composer symfony/clock v7.3.0 php-composer
@@ -235,7 +235,7 @@ symfony/var-exporter v7.3.0 php-composer
symfony/yaml v7.3.1 php-composer symfony/yaml v7.3.1 php-composer
theseer/tokenizer 1.2.3 php-composer theseer/tokenizer 1.2.3 php-composer
tijsverkoyen/css-to-inline-styles v2.3.0 php-composer tijsverkoyen/css-to-inline-styles v2.3.0 php-composer
tzdata 2025b-r0 apk tzdata 2026a-r0 apk
utmps-libs 0.1.3.1-r0 apk utmps-libs 0.1.3.1-r0 apk
vlucas/phpdotenv v5.6.2 php-composer vlucas/phpdotenv v5.6.2 php-composer
voku/portable-ascii 2.0.3 php-composer voku/portable-ascii 2.0.3 php-composer