diff --git a/RELEASING.md b/RELEASING.md
index 8f28427c..79b0b1ec 100644
--- a/RELEASING.md
+++ b/RELEASING.md
@@ -111,5 +111,7 @@ This applies to all releases, i.e. M1, M2, M3, RC1 and R. Everything except R is
These jobs should be completed by approximately 10am Ottawa time on release days.
-- [ ] The current release needs to be promoted as "latest" under https://download.eclipse.org/technology/epp/packages/latest/ . This should be a composite pointing to specific https://download.eclipse.org/technology/epp/packages/yyyy-MM/ . This is achieved by triggering the [epp-promoteReleaseToLatest](https://ci.eclipse.org/packaging/job/epp-promoteReleaseToLatest).
-- [ ] The _next_ release sub-directory needs to be created immediately, i.e. when 2019-12 was released, a directory 2020-03 had been created with an empty p2 composite repository pointing to 2019-12 until M1. (Use Job https://ci.eclipse.org/packaging/job/epp-createNextRelease/) On M1 release day this changes to a composite p2 repository with M1 content. On other release days, add the new releases as children and on final release this changes to a composite with just the one child.
+- [ ] Run the [Finalize Release](https://ci.eclipse.org/packaging/job/finalize-release/) CI job to create the "next" release and updated the "latest" release as follows:
+ - The current release needs to be promoted as "latest" under https://download.eclipse.org/technology/epp/packages/latest/ . This should be a composite pointing to specific https://download.eclipse.org/technology/epp/packages/yyyy-MM/ .
+ - The _next_ release sub-directory needs to be created immediately, i.e. when 2019-12 was released, a directory 2020-03 had been created with an empty p2 composite repository pointing to 2019-12 until M1. On M1 release day this changes to a composite p2 repository with M1 content.
+ - [ ] _Optional - useful when testing changes to the promotion scripts:_ Run the build once in `DRY_RUN` mode to ensure that the output is correct before it applies changes to download.eclipse.org.
diff --git a/releng/org.eclipse.epp.config/tools/finalize-release.Jenkinsfile b/releng/org.eclipse.epp.config/tools/finalize-release.Jenkinsfile
new file mode 100644
index 00000000..41df4514
--- /dev/null
+++ b/releng/org.eclipse.epp.config/tools/finalize-release.Jenkinsfile
@@ -0,0 +1,29 @@
+// Based on https://wiki.eclipse.org/Jenkins#Pipeline_job_without_custom_pod_template
+pipeline {
+ agent any
+ parameters {
+ booleanParam(defaultValue: true, description: 'Do a dry run of the operation', name: 'DRY_RUN')
+ }
+ options {
+ timestamps()
+ disableConcurrentBuilds()
+ }
+ tools {
+ maven 'apache-maven-latest'
+ jdk 'temurin-jdk17-latest'
+ }
+ stages {
+ stage('Finalize Release') {
+ steps {
+ sshagent ( ['projects-storage.eclipse.org-bot-ssh']) {
+ sh './releng/org.eclipse.epp.config/tools/finalize-release.sh'
+ }
+ }
+ }
+ }
+ post {
+ cleanup {
+ cleanWs()
+ }
+ }
+}
diff --git a/releng/org.eclipse.epp.config/tools/finalize-release.sh b/releng/org.eclipse.epp.config/tools/finalize-release.sh
new file mode 100755
index 00000000..416c20c5
--- /dev/null
+++ b/releng/org.eclipse.epp.config/tools/finalize-release.sh
@@ -0,0 +1,142 @@
+#!/bin/bash
+
+set -u # run with unset flag error so that missing parameters cause build failure
+set -e # error out on any failed commands
+set -x # echo all commands used for debugging purposes
+
+DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
+# Read a property from the epp.properties file (which needs to be generated)
+# Usage: get_property KEY
+function get_property
+{
+ grep "^$1=" "${DIR}/epp.properties" | cut -d'=' -f2 | sed '-es,\\:,:,'
+}
+
+echo Create the epp.properties file
+MVN=/opt/tools/apache-maven/latest/bin/mvn
+if [ ! -f "$MVN" ]; then
+ MVN=mvn
+fi
+${MVN} clean package -f ${DIR}
+
+RELEASE_NAME=$(get_property RELEASE_NAME)
+PREV_RELEASE_NAME=$(get_property PREV_RELEASE_NAME)
+NEXT_RELEASE_NAME=$(get_property NEXT_RELEASE_NAME)
+RELEASE_MILESTONE=$(get_property RELEASE_MILESTONE)
+RELEASE_DIR=$(get_property RELEASE_DIR)
+SIMREL_REPO=$(get_property SIMREL_REPO)
+EPP_DOWNLOADS=/home/data/httpd/download.eclipse.org/technology/epp
+DOWNLOADS=${EPP_DOWNLOADS}/downloads/release/${RELEASE_NAME}
+REPO=${EPP_DOWNLOADS}/packages/${RELEASE_NAME}/
+
+SSHUSER="genie.packaging@projects-storage.eclipse.org"
+SSH="ssh ${SSHUSER}"
+SCP="scp"
+
+
+ECHO=echo
+if [ "$DRY_RUN" == "false" ]; then
+ ECHO=""
+else
+ echo Dry run of build:
+fi
+
+if [ "$RELEASE_MILESTONE" != "R" ]; then
+ $ECHO "This job is only inteded for R builds"
+ exit 1
+fi
+
+
+echo "----------------------------------------------------------------------------------------------"
+echo "Prepare compositeArtifacts.xml/compositeContent.xml for "latest" that points at RELEASE_NAME"
+$ECHO ${SSH} mkdir ${EPP_DOWNLOADS}/packages/latest/
+
+TIMESTAMP=$(date +%s000)
+
+CONTENTXML="
+
+
+
+
+
+
+
+
+
+"
+
+echo "$CONTENTXML" > ./compositeContent.xml
+echo "==== Start Content of compositeContent.xml ===="
+cat ./compositeContent.xml
+echo "==== End Content of compositeContent.xml ===="
+$ECHO $SCP compositeContent.xml "${SSHUSER}:"${EPP_DOWNLOADS}/packages/latest/
+
+ARTIFACTXML="
+
+
+
+
+
+
+
+
+
+"
+
+echo "$ARTIFACTXML" > ./compositeArtifacts.xml
+echo "==== Start Content of compositeArtifacts.xml ===="
+cat ./compositeArtifacts.xml
+echo "==== End Content of compositeArtifacts.xml ===="
+$ECHO $SCP compositeArtifacts.xml "${SSHUSER}:"${EPP_DOWNLOADS}/packages/latest/
+
+
+echo "----------------------------------------------------------------------------------------------"
+echo "Prepare compositeArtifacts.xml/compositeContent.xml for next release that points at RELEASE_NAME"
+$ECHO ${SSH} mkdir ${EPP_DOWNLOADS}/packages/${NEXT_RELEASE_NAME}/
+
+TIMESTAMP=$(date +%s000)
+
+CONTENTXML="
+
+
+
+
+
+
+
+
+
+"
+
+echo "$CONTENTXML" > ./compositeContent.xml
+echo "==== Start Content of compositeArtifacts.xml ===="
+cat ./compositeArtifacts.xml
+echo "==== End Content of compositeArtifacts.xml ===="
+$ECHO $SCP compositeContent.xml "${SSHUSER}:"${EPP_DOWNLOADS}/packages/${NEXT_RELEASE_NAME}/
+
+ARTIFACTXML="
+
+
+
+
+
+
+
+
+
+"
+
+echo "$ARTIFACTXML" > ./compositeArtifacts.xml
+echo "==== Start Content of compositeArtifacts.xml ===="
+cat ./compositeArtifacts.xml
+echo "==== End Content of compositeArtifacts.xml ===="
+$ECHO $SCP compositeArtifacts.xml "${SSHUSER}:"${EPP_DOWNLOADS}/packages/${NEXT_RELEASE_NAME}/
+