├── .gitignore ├── .github ├── release-drafter.yml ├── dependabot.yml └── workflows │ └── release-drafter.yml ├── logos ├── beekeeper.png ├── buttler_jon_snow.png ├── buttler_stay_safe.png └── buttler_jenkins_is_the_way.png ├── updatecli ├── values.yaml ├── scripts │ └── generate-pr-body.sh └── updatecli.d │ └── jenkins-core-and-plugins.yaml ├── Jenkinsfile_k8s ├── Dockerfile ├── Jenkinsfile_updatecli ├── README.md ├── cst.yml └── plugins.txt /.gitignore: -------------------------------------------------------------------------------- 1 | hadolint.json 2 | *.tar 3 | -------------------------------------------------------------------------------- /.github/release-drafter.yml: -------------------------------------------------------------------------------- 1 | _extends: .github 2 | -------------------------------------------------------------------------------- /logos/beekeeper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkins-infra/docker-jenkins-lts/main/logos/beekeeper.png -------------------------------------------------------------------------------- /logos/buttler_jon_snow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkins-infra/docker-jenkins-lts/main/logos/buttler_jon_snow.png -------------------------------------------------------------------------------- /logos/buttler_stay_safe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkins-infra/docker-jenkins-lts/main/logos/buttler_stay_safe.png -------------------------------------------------------------------------------- /logos/buttler_jenkins_is_the_way.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkins-infra/docker-jenkins-lts/main/logos/buttler_jenkins_is_the_way.png -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: 2 3 | updates: 4 | - package-ecosystem: "github-actions" 5 | directory: "/" 6 | schedule: 7 | interval: "daily" 8 | -------------------------------------------------------------------------------- /updatecli/values.yaml: -------------------------------------------------------------------------------- 1 | github: 2 | user: Jenkins Infra Bot (updatecli) 3 | email: 60776566+jenkins-infra-bot@users.noreply.github.com 4 | token: UPDATECLI_GITHUB_TOKEN 5 | branch: main 6 | owner: jenkins-infra 7 | repository: docker-jenkins-lts 8 | -------------------------------------------------------------------------------- /Jenkinsfile_k8s: -------------------------------------------------------------------------------- 1 | buildDockerAndPublishImage('jenkins-lts', [ 2 | publishToPrivateAzureRegistry: true, 3 | targetplatforms: 'linux/arm64', 4 | nextVersionCommand: 'echo "$(jx-release-version -next-version=semantic:strip-prerelease)-$(grep "FROM jenkins" Dockerfile | cut -d: -f2 | cut -d- -f1)"', 5 | ]) 6 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM jenkins/jenkins:2.528.3-jdk21 2 | 3 | COPY logos /usr/share/jenkins/ref/userContent/logos 4 | COPY plugins.txt /usr/share/jenkins/ref/plugins.txt 5 | RUN jenkins-plugin-cli \ 6 | --jenkins-update-center='https://azure.updates.jenkins.io/update-center.json' \ 7 | --jenkins-plugin-info='https://azure.updates.jenkins.io/plugin-versions.json' \ 8 | --plugin-file /usr/share/jenkins/ref/plugins.txt \ 9 | --verbose 10 | -------------------------------------------------------------------------------- /Jenkinsfile_updatecli: -------------------------------------------------------------------------------- 1 | final String cronExpr = env.BRANCH_IS_PRIMARY ? '@daily' : '' 2 | 3 | properties([ 4 | buildDiscarder(logRotator(numToKeepStr: '10')), 5 | disableConcurrentBuilds(abortPrevious: true), 6 | pipelineTriggers([cron(cronExpr)]), 7 | ]) 8 | 9 | node('linux-arm64-docker') { 10 | timeout(time: 10, unit: 'MINUTES') { 11 | final String updatecliAction = env.BRANCH_IS_PRIMARY ? 'apply' : 'diff' 12 | stage("Run updatecli action: ${updatecliAction}") { 13 | updatecli( 14 | action: updatecliAction, 15 | runInCurrentAgent: true, 16 | ) 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /.github/workflows/release-drafter.yml: -------------------------------------------------------------------------------- 1 | name: Release Drafter 2 | on: 3 | push: 4 | workflow_dispatch: 5 | release: 6 | # Only allow 1 release-drafter build at a time to avoid creating multiple "next" releases 7 | concurrency: "release-drafter" 8 | jobs: 9 | deploy: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Check out 13 | uses: actions/checkout@v6 14 | with: 15 | fetch-depth: 0 16 | - name: Release Drafter 17 | uses: release-drafter/release-drafter@b1476f6e6eb133afa41ed8589daba6dc69b4d3f5 # v6.1.0 18 | with: 19 | name: next 20 | tag: next 21 | version: next 22 | env: 23 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # docker-jenkins-lts 2 | 3 | [![](https://img.shields.io/docker/pulls/jenkinsciinfra/ldap?label=jenkinsciinfra%2Fjenkins-lts&logo=docker&logoColor=white)](https://hub.docker.com/r/jenkinsciinfra/jenkins-lts/tags) 4 | 5 | A docker image containing the latest jenkins lts release and plugins used by the Jenkins infrastructure. 6 | 7 | ## Updating Plugins 8 | 9 | ``` 10 | bash ./bin/update-plugins.sh 11 | ``` 12 | 13 | This script uses the [Jenkins Plugin Manager Tool command line](https://github.com/jenkinsci/plugin-installation-manager-tool) under the hood to update the plugins. 14 | 15 | ## Update Jenkins Version 16 | 17 | ``` 18 | VERSION=$(jv get --version-identifier lts) 19 | SUFFIX=lts-jdk21 20 | FULL_VERSION=jenkins/jenkins:${VERSION}-${SUFFIX} 21 | sed -i 's|FROM .*|FROM '"${FULL_VERSION}"'|' Dockerfile 22 | ``` 23 | -------------------------------------------------------------------------------- /cst.yml: -------------------------------------------------------------------------------- 1 | --- 2 | schemaVersion: 2.0.0 3 | fileExistenceTests: 4 | - name: 'plugins.txt' 5 | path: '/usr/share/jenkins/ref/plugins.txt' 6 | shouldExist: true 7 | - name: 'default plugin - kubernetes' 8 | path: '/usr/share/jenkins/ref/plugins/kubernetes.jpi' 9 | shouldExist: true 10 | - name: 'default plugin - workflow-aggregator' 11 | path: '/usr/share/jenkins/ref/plugins/workflow-aggregator.jpi' 12 | shouldExist: true 13 | - name: 'default plugin - git' 14 | path: '/usr/share/jenkins/ref/plugins/git.jpi' 15 | shouldExist: true 16 | - name: 'default plugin - configuration-as-code' 17 | path: '/usr/share/jenkins/ref/plugins/configuration-as-code.jpi' 18 | shouldExist: true 19 | - name: 'Azure VM Agents' 20 | path: '/usr/share/jenkins/ref/plugins/azure-vm-agents.jpi' 21 | shouldExist: true 22 | -------------------------------------------------------------------------------- /updatecli/scripts/generate-pr-body.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -eux -o pipefail 4 | 5 | new_plugins_file="${1}" 6 | orig_plugins_file="${2}" 7 | diff_file="$(mktemp)" 8 | 9 | # Store comparison between original and updated 10 | diff --unified=0 "${orig_plugins_file}" "${new_plugins_file}" > "${diff_file}" || true 11 | if [ -s "${diff_file}" ] 12 | then 13 | pluginsdiff="$(tail --lines +3 "${diff_file}" | grep -v '@')" 14 | newlines=$(echo "${pluginsdiff}" | grep '+') 15 | links='' 23 | 24 | echo "${links}" 25 | fi 26 | -------------------------------------------------------------------------------- /updatecli/updatecli.d/jenkins-core-and-plugins.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bump Jenkins Core and/or Plugins 3 | 4 | scms: 5 | default: 6 | kind: github 7 | spec: 8 | user: "{{ .github.user }}" 9 | email: "{{ .github.email }}" 10 | owner: "{{ .github.owner }}" 11 | repository: "{{ .github.repository }}" 12 | token: "{{ requiredEnv .github.token }}" 13 | username: "{{ .github.username }}" 14 | branch: "{{ .github.branch }}" 15 | 16 | sources: 17 | getCurrentDockerTagSuffix: 18 | name: Get current Jenkins base image 19 | kind: file 20 | spec: 21 | file: ./Dockerfile 22 | transformers: 23 | - findsubmatch: 24 | pattern: "FROM jenkins/jenkins:(.*)-(.*)" 25 | captureindex: 2 26 | getLatestJenkinsVersion: 27 | kind: jenkins 28 | name: Get the latest weekly Jenkins version 29 | spec: 30 | release: stable # LTS line 31 | transformers: 32 | - addsuffix: '-{{ source "getCurrentDockerTagSuffix" }}' 33 | getLatestPluginsToTempFile: 34 | name: Update Jenkins plugins 35 | kind: shell 36 | spec: 37 | command: | 38 | temp_file="$(mktemp)" 39 | docker container run --rm --volume=$(pwd):/data:ro --entrypoint=bash jenkins/jenkins:{{ source "getLatestJenkinsVersion" }} \ 40 | -c 'jenkins-plugin-cli --plugin-file /data/plugins.txt --available-updates --output txt' > "${temp_file}" 41 | echo "${temp_file}" 42 | getprbody: 43 | name: Generate PR Body to ease maintainers life (used by action github/pullrequest) 44 | kind: shell 45 | spec: 46 | command: bash ./updatecli/scripts/generate-pr-body.sh '{{ source "getLatestPluginsToTempFile" }}' ./plugins.txt 47 | getLatestPlugins: 48 | name: Get list of latest plugins 49 | kind: file 50 | spec: 51 | file: '{{ source "getLatestPluginsToTempFile" }}' 52 | 53 | conditions: 54 | testDockerImageExists: 55 | name: Does the Docker Image exist on the Docker Hub? 56 | kind: dockerimage 57 | sourceid: getLatestJenkinsVersion 58 | spec: 59 | image: jenkins/jenkins 60 | architectures: 61 | - amd64 62 | - arm64 63 | 64 | targets: 65 | updateDockerfile: 66 | name: Update the Dockerfile with the new version 67 | kind: dockerfile 68 | sourceid: getLatestJenkinsVersion 69 | spec: 70 | file: Dockerfile 71 | instruction: 72 | keyword: FROM 73 | matcher: jenkins/jenkins 74 | scmid: default 75 | updatePlugins: 76 | name: Update Jenkins plugins 77 | sourceid: getLatestPlugins 78 | kind: file 79 | spec: 80 | file: ./plugins.txt 81 | scmid: default 82 | 83 | actions: 84 | default: 85 | kind: github/pullrequest 86 | scmid: default 87 | title: Bump Jenkins Core and/or Plugins 88 | spec: 89 | description: | 90 |

Link(s):

91 |
92 | {{ source `getprbody` }} 93 |
94 | labels: 95 | - dependencies 96 | - jenkins-core 97 | - jenkins-plugins 98 | -------------------------------------------------------------------------------- /plugins.txt: -------------------------------------------------------------------------------- 1 | analysis-model-api:13.18.0-935.v784ca_107400a_ 2 | ansicolor:1.0.6 3 | antisamy-markup-formatter:173.v680e3a_b_69ff3 4 | apache-httpcomponents-client-4-api:4.5.14-269.vfa_2321039a_83 5 | authentication-tokens:1.144.v5ff4a_5ec5c33 6 | azure-credentials:404.vd0fb_33a_8a_14e 7 | azure-sdk:259.vf079c96088a_f 8 | azure-vm-agents:1075.v0de0eb_b_27544 9 | basic-branch-build-strategies:275.vde2351b_4a_58b_ 10 | bootstrap5-api:5.3.8-895.v4d0d8e47fea_d 11 | bouncycastle-api:2.30.1.82-277.v70ca_0b_877184 12 | branch-api:2.1268.v044a_87612da_8 13 | caffeine-api:3.2.3-194.v31a_b_f7a_b_5a_81 14 | checks-api:373.vfe7645102093 15 | cloud-stats:377.vd8a_6c953e98e 16 | cloudbees-bitbucket-branch-source:937.2.2 17 | cloudbees-folder:6.1073.va_7888eb_dd514 18 | cloudbees-jenkins-advisor:392.v6ca_b_ff4e12fa_ 19 | command-launcher:123.v37cfdc92ef67 20 | commons-lang3-api:3.20.0-109.ve43756e2d2b_4 21 | commons-text-api:1.15.0-210.v7480a_da_70b_9e 22 | configuration-as-code:2006.v001a_2ca_6b_574 23 | copyartifact:770.va_6c69e063442 24 | coverage:2.3060.v035a_5557cdb_c 25 | credentials:1453.v9b_a_29777a_b_fd 26 | credentials-binding:702.vfe613e537e88 27 | csp:1.43.vb_e0a_fd67d28d 28 | customizable-header:251.251.v49b_7da_e6c61a_ 29 | dark-theme:574.va_19f05d54df5 30 | data-tables-api:2.3.5-1497.v38449eb_7d5a_1 31 | display-url-api:2.217.va_6b_de84cc74b_ 32 | docker-commons:457.v0f62a_94f11a_3 33 | durable-task:639.vefb_3d8372f6d 34 | echarts-api:6.0.0-1165.vd1283a_3e37d4 35 | extended-read-permission:68.vd270568a_7520 36 | font-awesome-api:7.1.0-882.v1dfb_771e3278 37 | forensics-api:3.1772.v99ca_3d83b_9fa_ 38 | git:5.8.1 39 | git-client:6.4.3 40 | git-forensics:3.2138.vf25ea_d549e33 41 | github:1.45.0 42 | github-api:1.330-492.v3941a_032db_2a_ 43 | github-branch-source:1917.v9ee8a_39b_3d0d 44 | github-checks:634.v371dc6d978a_3 45 | github-label-filter:1.0.0 46 | groovy:497.v7b_061a_a_de65d 47 | handy-uri-templates-2-api:2.1.8-38.vcea_5d521d5f3 48 | htmlpublisher:427 49 | inline-pipeline:1.0.32.vf433f2d57630 50 | instance-identity:203.v15e81a_1b_7a_38 51 | ionicons-api:94.vcc3065403257 52 | jackson2-api:2.20.1-423.v13951f6b_6532 53 | jakarta-activation-api:2.1.4-1 54 | jakarta-mail-api:2.1.5-1 55 | javax-activation-api:1.2.0-8 56 | javax-mail-api:1.6.2-11 57 | jaxb:2.3.9-133.vb_ec76a_73f706 58 | jdk-tool:83.v417146707a_3d 59 | jersey2-api:2.47-165.ve7809a_3e87e0 60 | jjwt-api:0.11.5-120.v0268cf544b_89 61 | jnr-posix-api:3.1.21-186.vb_7ec9b_23ce83 62 | job-dsl:1.93 63 | jquery3-api:3.7.1-619.vdb_10e002501a_ 64 | jsch:0.2.16-95.v3eecb_55fa_b_78 65 | junit:1369.v15da_00283f06 66 | kubernetes:4398.vb_b_33d9e7fe23 67 | kubernetes-client-api:7.3.1-256.v788a_0b_787114 68 | kubernetes-credentials:206.vde31a_b_0f71a_c 69 | kubernetes-credentials-provider:1.299.v610fa_e76761a_ 70 | ldap:793.v754d6b_41b_ea_4 71 | mailer:525.v2458b_d8a_1a_71 72 | matrix-auth:3.2.9 73 | matrix-project:870.v9db_fcfc2f45b_ 74 | metrics:4.2.37-489.vb_6db_69b_ce753 75 | mina-sshd-api-common:2.16.0-167.va_269f38cc024 76 | mina-sshd-api-core:2.16.0-167.va_269f38cc024 77 | node-iterator-api:72.vc90e81737df1 78 | okhttp-api:4.12.0-195.vc02552c04ffd 79 | pipeline-build-step:571.v08a_fffd4b_0ce 80 | pipeline-github:2.8-162.382498405fdc 81 | pipeline-graph-analysis:245.v88f03631a_b_21 82 | pipeline-graph-view:661.v6003f4542123 83 | pipeline-groovy-lib:787.ve2fef0efdca_6 84 | pipeline-input-step:540.v14b_100d754dd 85 | pipeline-milestone-step:138.v78ca_76831a_43 86 | pipeline-model-api:2.2277.v00573e73ddf1 87 | pipeline-model-definition:2.2277.v00573e73ddf1 88 | pipeline-model-extensions:2.2277.v00573e73ddf1 89 | pipeline-rest-api:2.38 90 | pipeline-stage-step:322.vecffa_99f371c 91 | pipeline-stage-view:2.38 92 | plain-credentials:199.v9f8e1f741799 93 | plugin-util-api:6.1192.v30fe6e2837ff 94 | prism-api:1.30.0-630.va_e19d17f83b_0 95 | pubsub-light:1.19 96 | scm-api:724.v7d839074eb_5c 97 | scm-filter-branch-pr:222.v72301ecb_a_ee7 98 | script-security:1385.v7d2d9ec4d909 99 | snakeyaml-api:2.5-143.v93b_c004f89de 100 | sse-gateway:1.28 101 | ssh-agent:386.v36cc0c7582f0 102 | ssh-credentials:361.vb_f6760818e8c 103 | sshd:3.374.v19b_d59ce6610 104 | structs:362.va_b_695ef4fdf9 105 | support-core:1763.ve4ce0d10a_3f0 106 | theme-manager:327.v780d7096ec29 107 | timestamper:1.30 108 | token-macro:477.vd4f0dc3cb_cf1 109 | trilead-api:2.284.v1974ea_324382 110 | variant:70.va_d9f17f859e0 111 | warnings-ng:12.9936.vda_5743ded29a_ 112 | windows-azure-storage:519.vd15db_1004122 113 | workflow-aggregator:608.v67378e9d3db_1 114 | workflow-api:1384.vdc05a_48f535f 115 | workflow-basic-steps:1098.v808b_fd7f8cf4 116 | workflow-cps:4238.va_6fb_65c1f699 117 | workflow-durable-task-step:1464.v2d3f5c68f84c 118 | workflow-job:1559.va_a_533730b_ea_d 119 | workflow-multibranch:821.vc3b_4ea_780798 120 | workflow-scm-step:466.va_d69e602552b_ 121 | workflow-step-api:710.v3e456cc85233 122 | workflow-support:1010.vb_b_39488a_9841 123 | --------------------------------------------------------------------------------