Skip to content

Modernize the Windows MSI: WiX v5, x64, service registration, upgrade from 5.1.1 #1319

Modernize the Windows MSI: WiX v5, x64, service registration, upgrade from 5.1.1

Modernize the Windows MSI: WiX v5, x64, service registration, upgrade from 5.1.1 #1319

Workflow file for this run

# The contents of this file are subject to the terms of the Common Development and
# Distribution License (the License). You may not use this file except in compliance with the
# License.
#
# You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
# specific language governing permission and limitations under the License.
#
# When distributing Covered Software, include this CDDL Header Notice in each file and include
# the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
# Header, with the fields enclosed by brackets [] replaced by your own identifying
# information: "Portions copyright [year] [name of copyright owner]".
#
# Copyright 2021-2026 3A Systems, LLC.
name: Build
on:
push:
branches: [ 'sustaining/4.10.x','master', 'issues/**', 'features/**' ]
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build-maven:
runs-on: ${{ matrix.os }}
strategy:
# The full Java sweep runs on ubuntu only; macOS and Windows build with the
# minimum supported (11) and the latest (26) Java.
matrix:
os: [ 'ubuntu-latest' ]
java: [ '11','17','21','25','26']
include:
- { os: 'macos-latest', java: '11' }
- { os: 'macos-latest', java: '26' }
- { os: 'windows-latest', java: '11' }
- { os: 'windows-latest', java: '26' }
fail-fast: false
steps:
- name: Install rpm for distribution
if: runner.os == 'Linux'
shell: bash
run: |
sudo apt-get update
sudo apt-get install -y rpm
- uses: actions/checkout@v6
with:
fetch-depth: 0
submodules: recursive
- name: Java ${{ matrix.Java }} (${{ matrix.os }})
uses: actions/setup-java@v5
with:
java-version: ${{ matrix.java }}
distribution: 'zulu'
- name: Cache Maven packages
uses: actions/cache@v5
with:
path: ~/.m2/repository
key: ${{ runner.os }}-m2-repository-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-m2-repository
- name: Setup MSVC Developer Command Prompt (x86)
if: runner.os == 'Windows'
uses: ilammy/msvc-dev-cmd@v1
env:
# Opt in to Node.js 24 for this action, which still ships on Node.js 20.
# See https://github.com/ilammy/msvc-dev-cmd/issues/99
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
with:
arch: x86
- name: Build Windows native executables
if: runner.os == 'Windows'
shell: cmd
run: |
cd opendj-server-legacy\src\build-tools\windows
nmake all
xcopy /Y *.exe ..\..\..\lib\
git status
- name: Set Integration Test Environment
id: failsafe
if: runner.os == 'Linux'
run: |
echo "MAVEN_PROFILE_FLAG=-P precommit" >> $GITHUB_OUTPUT
- name: Setup WiX (.NET tool) for MSI
if: runner.os == 'Windows'
shell: bash
run: |
# The MSI builds on Windows only (WiX cannot author MSIs on Linux/macOS). WiX 5 ships as a
# net6.0 tool; allow it to run on the newer .NET runtime present on the runner.
echo "DOTNET_ROLL_FORWARD=Major" >> "$GITHUB_ENV"
export DOTNET_ROLL_FORWARD=Major
dotnet tool install --global wix --version 5.0.2 || dotnet tool update --global wix --version 5.0.2
echo "$HOME/.dotnet/tools" >> "$GITHUB_PATH"
export PATH="$HOME/.dotnet/tools:$PATH"
wix --version
wix extension add -g WixToolset.UI.wixext/5.0.2 || true
- name: Build with Maven
timeout-minutes: 180
env:
MAVEN_OPTS: -Dhttps.protocols=TLSv1.2 -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.requestSentEnabled=true -Dmaven.wagon.http.retryHandler.count=10
run: mvn --batch-mode --errors --update-snapshots verify --file pom.xml ${{ steps.failsafe.outputs.MAVEN_PROFILE_FLAG }}
- name: Test on Unix
if: runner.os == 'Linux'
run: |
export OPENDJ_JAVA_ARGS="-server -Xmx512m"
opendj-server-legacy/target/package/opendj/setup -h localhost -p 1389 --ldapsPort 1636 --adminConnectorPort 4444 --enableStartTLS --generateSelfSignedCertificate --rootUserDN "cn=Directory Manager" --rootUserPassword password --baseDN dc=example,dc=com --sampleData 5000 --cli --acceptLicense --no-prompt
opendj-server-legacy/target/package/opendj/bin/status --hostname localhost --bindDN "cn=Directory Manager" --bindPassword password --trustAll
opendj-server-legacy/target/package/opendj/bin/ldapsearch --hostname localhost --port 1636 --bindDN "cn=Directory Manager" --bindPassword password --useSsl --trustAll --baseDN "dc=example,dc=com" --searchScope base "(objectClass=*)" 1.1
opendj-server-legacy/target/package/opendj/bin/ldapsearch --hostname localhost --port 1636 --bindDN "cn=Directory Manager" --bindPassword password --useSsl --trustAll --baseDN "ou=people,dc=example,dc=com" --searchScope sub "(uid=user.*)" dn | grep ^dn: | wc -l | grep -q 5000
# --- Load-testing tools smoke tests (server online, 5000 sample users) ---
echo "===== searchrate ====="
opendj-server-legacy/target/package/opendj/bin/searchrate --hostname localhost --port 1636 --useSSL --trustAll --bindDN "cn=Directory Manager" --bindPassword password --baseDN "ou=people,dc=example,dc=com" --searchScope sub -c 4 -t 1 -m 2000 -i 1 -g "rand(0,4999)" "(uid=user.%d)" 1.1
echo "===== authrate ====="
opendj-server-legacy/target/package/opendj/bin/authrate --hostname localhost --port 1636 --useSSL --trustAll -D "uid=user.%d,ou=people,dc=example,dc=com" -w password -c 4 -m 2000 -i 1 -g "rand(0,4999)"
echo "===== modrate ====="
opendj-server-legacy/target/package/opendj/bin/modrate --hostname localhost --port 1636 --useSSL --trustAll --bindDN "cn=Directory Manager" --bindPassword password -b "uid=user.%d,ou=people,dc=example,dc=com" -c 4 -t 1 -m 2000 -i 1 -g "rand(0,4999)" "description:modrate-load-test"
echo "===== addrate ====="
cat > /tmp/addrate.template <<'EOF'
define suffix=dc=example,dc=com
branch: ou=People,[suffix]
subordinateTemplate: person
template: person
rdnAttr: uid
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
uid: addrate.<sequential:0>
cn: AddRate {uid}
sn: AddRate
userPassword: password
EOF
opendj-server-legacy/target/package/opendj/bin/addrate --hostname localhost --port 1636 --useSSL --trustAll --bindDN "cn=Directory Manager" --bindPassword password -c 4 -t 1 -m 2000 -i 1 -C fifo -s 100 /tmp/addrate.template
opendj-server-legacy/target/package/opendj/bin/dsconfig create-backend --hostname localhost --port 4444 --bindDN "cn=Directory Manager" --bindPassword password --backend-name=example2 --type je --set=base-dn:dc=example2,dc=com --set=enabled:true --no-prompt --trustAll
opendj-server-legacy/target/package/opendj/bin/makeldif -o /tmp/test.ldif -c suffix=dc=example2,dc=com opendj-server-legacy/target/package/opendj/config/MakeLDIF/example.template
opendj-server-legacy/target/package/opendj/bin/stop-ds
echo "4.9.9.0" > opendj-server-legacy/target/package/opendj/config/buildinfo
opendj-server-legacy/target/package/opendj/upgrade -n
opendj-server-legacy/target/package/opendj/bin/import-ldif --offline --ldifFile /tmp/test.ldif --backendID=example2
opendj-server-legacy/target/package/opendj/bin/rebuild-index --offline --bindDN "cn=Directory Manager" --bindPassword password --baseDN "dc=example2,dc=com" --rebuildAll
opendj-server-legacy/target/package/opendj/bin/start-ds
opendj-server-legacy/target/package/opendj/bin/rebuild-index --bindDN "cn=Directory Manager" --bindPassword password --baseDN "dc=example2,dc=com" --rebuildAll --trustAll
opendj-server-legacy/target/package/opendj/bin/ldapsearch --hostname localhost --port 1636 --bindDN "cn=Directory Manager" --bindPassword password --useSsl --trustAll --baseDN "ou=people,dc=example2,dc=com" --searchScope sub "(uid=user.*)" dn | grep ^dn: | wc -l | grep -q 10000
opendj-server-legacy/target/package/opendj/bin/stop-ds
rm -rf opendj-server-legacy/target/package/opendj/{config,db,changelogDb,logs,tmp}
- name: Test on Unix FIPS
if: runner.os == 'Linux'
run: |
export OPENDJ_JAVA_ARGS="-server -Xmx512m"
echo password > /tmp/opendj.keystore.pin
keytool -genkey -alias server-cert -keyalg rsa \
-dname "CN=example.com,O=OpenDJ RSA Self-Signed Certificate" \
-keystore /tmp/opendj.bcfks -storetype BCFKS -validity 3650 -providername BCFIPS \
-provider org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider \
-providerpath ./opendj-server-legacy/target/package/opendj/lib/org.bouncycastle.bc-fips.jar:./opendj-server-legacy/target/package/opendj/lib/org.bouncycastle.bcpkix-fips.jar \
-keypass:file /tmp/opendj.keystore.pin -storepass:file /tmp/opendj.keystore.pin -keysize 2048 -sigalg SHA256WITHRSA
keytool -selfcert -alias server-cert -keystore /tmp/opendj.bcfks \
-storetype BCFKS -validity 3650 -providername BCFIPS \
-provider org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider \
-providerpath ./opendj-server-legacy/target/package/opendj/lib/org.bouncycastle.bc-fips.jar:./opendj-server-legacy/target/package/opendj/lib/org.bouncycastle.bcpkix-fips.jar \
-storepass:file /tmp/opendj.keystore.pin
keytool -genkey -alias admin-cert -keyalg rsa \
-dname "CN=example.com,O=Administration Connector RSA Self-Signed Certificate" \
-keystore /tmp/opendj.bcfks -storetype BCFKS -validity 3650 -providername BCFIPS \
-provider org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider \
-providerpath ./opendj-server-legacy/target/package/opendj/lib/org.bouncycastle.bc-fips.jar:./opendj-server-legacy/target/package/opendj/lib/org.bouncycastle.bcpkix-fips.jar \
-keypass:file /tmp/opendj.keystore.pin -storepass:file /tmp/opendj.keystore.pin -keysize 2048 -sigalg SHA256WITHRSA
keytool -selfcert -alias admin-cert -keystore /tmp/opendj.bcfks \
-storetype BCFKS -validity 3650 -providername BCFIPS \
-provider org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider \
-providerpath ./opendj-server-legacy/target/package/opendj/lib/org.bouncycastle.bc-fips.jar:./opendj-server-legacy/target/package/opendj/lib/org.bouncycastle.bcpkix-fips.jar \
-storepass:file /tmp/opendj.keystore.pin
echo "useBcfksKeystore=/tmp/opendj.bcfks
keyStorePasswordFile=/tmp/opendj.keystore.pin" > /tmp/opendj-setup.properties.bcfks
opendj-server-legacy/target/package/opendj/setup -h localhost -p 1389 --ldapsPort 1636 --adminConnectorPort 4444 \
--enableStartTLS --certNickname admin-cert --rootUserDN "cn=Directory Manager" --rootUserPassword password \
--baseDN dc=example,dc=com --sampleData 5000 --cli --acceptLicense --no-prompt \
--propertiesFilePath /tmp/opendj-setup.properties.bcfks --doNotStart
opendj-server-legacy/target/package/opendj/bin/start-ds
opendj-server-legacy/target/package/opendj/bin/status --hostname localhost --bindDN "cn=Directory Manager" --bindPassword password --trustAll
opendj-server-legacy/target/package/opendj/bin/ldapsearch --hostname localhost --port 1636 --bindDN "cn=Directory Manager" --bindPassword password --useSsl --trustAll --baseDN "dc=example,dc=com" --searchScope base "(objectClass=*)" 1.1
opendj-server-legacy/target/package/opendj/bin/ldapsearch --hostname localhost --port 1636 --bindDN "cn=Directory Manager" --bindPassword password --useSsl --trustAll --baseDN "ou=people,dc=example,dc=com" --searchScope sub "(uid=user.*)" dn | grep ^dn: | wc -l | grep -q 5000
opendj-server-legacy/target/package/opendj/bin/dsconfig create-backend --hostname localhost --port 4444 --bindDN "cn=Directory Manager" --bindPassword password --backend-name=example2 --type je --set=base-dn:dc=example2,dc=com --set=enabled:true --no-prompt --trustAll
opendj-server-legacy/target/package/opendj/bin/makeldif -o /tmp/test.ldif -c suffix=dc=example2,dc=com opendj-server-legacy/target/package/opendj/config/MakeLDIF/example.template
opendj-server-legacy/target/package/opendj/bin/stop-ds
echo "4.9.9.0" > opendj-server-legacy/target/package/opendj/config/buildinfo
opendj-server-legacy/target/package/opendj/upgrade -n
opendj-server-legacy/target/package/opendj/bin/import-ldif --offline --ldifFile /tmp/test.ldif --backendID=example2
opendj-server-legacy/target/package/opendj/bin/rebuild-index --offline --bindDN "cn=Directory Manager" --bindPassword password --baseDN "dc=example2,dc=com" --rebuildAll
opendj-server-legacy/target/package/opendj/bin/start-ds
opendj-server-legacy/target/package/opendj/bin/rebuild-index --bindDN "cn=Directory Manager" --bindPassword password --baseDN "dc=example2,dc=com" --rebuildAll --trustAll
opendj-server-legacy/target/package/opendj/bin/ldapsearch --hostname localhost --port 1636 --bindDN "cn=Directory Manager" --bindPassword password --useSsl --trustAll --baseDN "ou=people,dc=example2,dc=com" --searchScope sub "(uid=user.*)" dn | grep ^dn: | wc -l | grep -q 10000
opendj-server-legacy/target/package/opendj/bin/stop-ds
rm -rf opendj-server-legacy/target/package/opendj/{config,db,changelogDb,logs,tmp}
- name: Test LDAP in Cassandra
if: runner.os == 'Linux'
run: |
docker run --rm -it -d -p 9042:9042 --name cassandra cassandra
timeout 5m bash -c 'until docker logs cassandra | grep -q "Created default superuser role"; do sleep 5; done'
export OPENDJ_JAVA_ARGS="-server -Xmx512m -Ddatastax-java-driver.basic.contact-points.0=localhost:9042 -Ddatastax-java-driver.basic.load-balancing-policy.local-datacenter=datacenter1"
opendj-server-legacy/target/package/opendj/setup -h localhost -p 1389 --ldapsPort 1636 --adminConnectorPort 4444 --enableStartTLS --generateSelfSignedCertificate --rootUserDN "cn=Directory Manager" --rootUserPassword password --cli --acceptLicense --no-prompt
opendj-server-legacy/target/package/opendj/bin/dsconfig create-backend -h localhost -p 4444 --bindDN "cn=Directory Manager" --bindPassword password --backend-name=userRoot --type cas --set base-dn:dc=example,dc=com --set db-directory:keyspace_name --set enabled:true --no-prompt --trustAll
opendj-server-legacy/target/package/opendj/bin/makeldif -o /tmp/test.ldif -c suffix=dc=example,dc=com opendj-server-legacy/target/package/opendj/config/MakeLDIF/example.template
opendj-server-legacy/target/package/opendj/bin/import-ldif --ldifFile /tmp/test.ldif --backendID=userRoot -h localhost -p 4444 --bindDN "cn=Directory Manager" --bindPassword password --trustAll
opendj-server-legacy/target/package/opendj/bin/status --hostname localhost --bindDN "cn=Directory Manager" --bindPassword password --trustAll
opendj-server-legacy/target/package/opendj/bin/ldapsearch --hostname localhost --port 1636 --bindDN "cn=Directory Manager" --bindPassword password --useSsl --trustAll --baseDN "dc=example,dc=com" --searchScope base "(objectClass=*)" 1.1
opendj-server-legacy/target/package/opendj/bin/ldapsearch --hostname localhost --port 1636 --bindDN "cn=Directory Manager" --bindPassword password --useSsl --trustAll --baseDN "ou=people,dc=example,dc=com" --searchScope sub "(uid=user.*)" dn | grep ^dn: | wc -l | grep -q 10000
opendj-server-legacy/target/package/opendj/bin/stop-ds
rm -rf opendj-server-legacy/target/package/opendj/{config,db,changelogDb,logs,tmp}
- name: Test LDAP in Postgres
if: runner.os == 'Linux'
run: |
docker run --rm -it -d -p 5432:5432 -e POSTGRES_DB=database_name -e POSTGRES_PASSWORD=password --name postgres postgres
timeout 5m bash -c 'until docker logs postgres | grep -q "database system is ready to accept connections"; do sleep 5; done'
export OPENDJ_JAVA_ARGS="-server -Xmx512m"
opendj-server-legacy/target/package/opendj/setup -h localhost -p 1389 --ldapsPort 1636 --adminConnectorPort 4444 --enableStartTLS --generateSelfSignedCertificate --rootUserDN "cn=Directory Manager" --rootUserPassword password --cli --acceptLicense --no-prompt
opendj-server-legacy/target/package/opendj/bin/dsconfig create-backend -h localhost -p 4444 --bindDN "cn=Directory Manager" --bindPassword password --backend-name=userRoot --type jdbc --set base-dn:dc=example,dc=com --set db-directory:jdbc:postgresql://localhost:5432/database_name?user=postgres\&password=password --set enabled:true --no-prompt --trustAll
opendj-server-legacy/target/package/opendj/bin/makeldif -o /tmp/test.ldif -c suffix=dc=example,dc=com opendj-server-legacy/target/package/opendj/config/MakeLDIF/example.template
opendj-server-legacy/target/package/opendj/bin/ldapmodify --hostname localhost --port 1636 --bindDN "cn=Directory Manager" --bindPassword password --useSsl --trustAll -f /tmp/test.ldif -a 1> /dev/null
opendj-server-legacy/target/package/opendj/bin/status --hostname localhost --bindDN "cn=Directory Manager" --bindPassword password --trustAll
opendj-server-legacy/target/package/opendj/bin/ldapsearch --hostname localhost --port 1636 --bindDN "cn=Directory Manager" --bindPassword password --useSsl --trustAll --baseDN "dc=example,dc=com" --searchScope base "(objectClass=*)" 1.1
opendj-server-legacy/target/package/opendj/bin/ldapsearch --hostname localhost --port 1636 --bindDN "cn=Directory Manager" --bindPassword password --useSsl --trustAll --baseDN "ou=people,dc=example,dc=com" --searchScope sub "(uid=user.*)" dn | grep ^dn: | wc -l | grep -q 10000
opendj-server-legacy/target/package/opendj/bin/stop-ds
rm -rf opendj-server-legacy/target/package/opendj/{config,db,changelogDb,logs,tmp}
- name: Test replication
if: runner.os == 'Linux'
run: |
cp -r ./opendj-server-legacy/target/package/opendj ./opendj-server-legacy/target/package/opendj1
cp -r ./opendj-server-legacy/target/package/opendj ./opendj-server-legacy/target/package/opendj2
cp -r ./opendj-server-legacy/target/package/opendj ./opendj-server-legacy/target/package/opendj3
echo "Setup OpenDJ-1"
opendj-server-legacy/target/package/opendj1/setup -h localhost -p 1389 --ldapsPort 1636 --adminConnectorPort 4444 --enableStartTLS \
--generateSelfSignedCertificate --rootUserDN "cn=Directory Manager" --rootUserPassword password --baseDN dc=example,dc=com \
--sampleData 100000 --cli --acceptLicense --no-prompt
echo "Setup OpenDJ-2 with replication"
opendj-server-legacy/target/package/opendj2/setup -h localhost -p 2389 --ldapsPort 2636 --adminConnectorPort 24444 --enableStartTLS \
--generateSelfSignedCertificate --rootUserDN "cn=Directory Manager" --rootUserPassword password --baseDN dc=example,dc=com \
--addBaseEntry --cli --acceptLicense --no-prompt
opendj-server-legacy/target/package/opendj2/bin/dsreplication enable --no-prompt --host1 localhost --port1 4444 --bindDN1 "cn=Directory Manager" --bindPassword1 password --replicationPort1 8989 \
--host2 localhost --port2 24444 --bindDN2 "cn=Directory Manager" --bindPassword2 password --replicationPort2 28989 \
--adminUID admin --adminPassword password --baseDN dc=example,dc=com --trustAll --noPropertiesFile
opendj-server-legacy/target/package/opendj2/bin/dsreplication initialize --baseDN dc=example,dc=com --adminUID admin --adminPassword password --hostSource localhost \
--portSource 4444 --hostDestination localhost --portDestination 24444 -X -n
opendj-server-legacy/target/package/opendj2/bin/ldapsearch --port 2636 --hostname localhost --bindDN "cn=Directory Manager" --bindPassword password --useSsl --trustAll \
--baseDN "ou=people,dc=example,dc=com" --searchScope sub "(uid=user.*)" dn | grep ^dn: | wc -l | grep -q 100000
echo "Setup OpenDJ-3 with replication"
opendj-server-legacy/target/package/opendj3/setup -h localhost -p 3389 --ldapsPort 3636 --adminConnectorPort 34444 --enableStartTLS \
--generateSelfSignedCertificate --rootUserDN "cn=Directory Manager" --rootUserPassword password --baseDN dc=example,dc=com \
--addBaseEntry --cli --acceptLicense --no-prompt
opendj-server-legacy/target/package/opendj3/bin/dsreplication enable --no-prompt --host1 localhost --port1 24444 --bindDN1 "cn=Directory Manager" --bindPassword1 password --replicationPort1 28989 \
--host2 localhost --port2 34444 --bindDN2 "cn=Directory Manager" --bindPassword2 password --replicationPort2 38989 \
--adminUID admin --adminPassword password --baseDN dc=example,dc=com --trustAll --noPropertiesFile
opendj-server-legacy/target/package/opendj3/bin/dsreplication initialize --baseDN dc=example,dc=com --adminUID admin --adminPassword password --hostSource localhost \
--portSource 24444 --hostDestination localhost --portDestination 34444 -X -n
opendj-server-legacy/target/package/opendj2/bin/ldapsearch --port 3636 --hostname localhost --bindDN "cn=Directory Manager" --bindPassword password --useSsl --trustAll \
--baseDN "ou=people,dc=example,dc=com" --searchScope sub "(uid=user.*)" dn | grep ^dn: | wc -l | grep -q 100000
echo "Stopping and removing OpenDJ instances"
opendj-server-legacy/target/package/opendj1/bin/stop-ds
opendj-server-legacy/target/package/opendj2/bin/stop-ds
opendj-server-legacy/target/package/opendj3/bin/stop-ds
rm -rf ./opendj-server-legacy/target/package/opendj1
rm -rf ./opendj-server-legacy/target/package/opendj2
rm -rf ./opendj-server-legacy/target/package/opendj3
- name: Test on Windows
if: runner.os == 'Windows'
run: |
set OPENDJ_JAVA_ARGS="-server -Xmx512m"
opendj-server-legacy\target\package\opendj\setup.bat -h localhost -p 1389 --ldapsPort 1636 --adminConnectorPort 4444 --enableStartTLS --generateSelfSignedCertificate --rootUserDN "cn=Directory Manager" --rootUserPassword password --baseDN dc=example,dc=com --sampleData 5000 --cli --acceptLicense --no-prompt
opendj-server-legacy\target\package\opendj\bat\status.bat --hostname localhost --bindDN "cn=Directory Manager" --bindPassword password --trustAll
opendj-server-legacy\target\package\opendj\bat\ldapsearch.bat --hostname localhost --port 1636 --bindDN "cn=Directory Manager" --bindPassword password --useSsl --trustAll --baseDN "dc=example,dc=com" --searchScope base "(objectClass=*)" 1.1
opendj-server-legacy\target\package\opendj\bat\ldapsearch.bat --hostname localhost --port 1636 --bindDN "cn=Directory Manager" --bindPassword password --useSsl --trustAll --baseDN "dc=example,dc=com" --searchScope sub "(uid=user.*)" dn | find /c '"dn:"' | findstr "5000"
# --- Load-testing tools smoke tests (server online, 5000 sample users) ---
Write-Host "===== searchrate ====="
opendj-server-legacy\target\package\opendj\bat\searchrate.bat --hostname localhost --port 1636 --useSSL --trustAll --bindDN "cn=Directory Manager" --bindPassword password --baseDN "ou=people,dc=example,dc=com" --searchScope sub -c 4 -t 1 -m 2000 -i 1 -g "rand(0,4999)" "(uid=user.%d)" 1.1
if ($LASTEXITCODE -ne 0) { throw "searchrate failed with exit code $LASTEXITCODE" }
Write-Host "===== authrate ====="
opendj-server-legacy\target\package\opendj\bat\authrate.bat --hostname localhost --port 1636 --useSSL --trustAll -D "uid=user.%d,ou=people,dc=example,dc=com" -w password -c 4 -m 2000 -i 1 -g "rand(0,4999)"
if ($LASTEXITCODE -ne 0) { throw "authrate failed with exit code $LASTEXITCODE" }
Write-Host "===== modrate ====="
opendj-server-legacy\target\package\opendj\bat\modrate.bat --hostname localhost --port 1636 --useSSL --trustAll --bindDN "cn=Directory Manager" --bindPassword password -b "uid=user.%d,ou=people,dc=example,dc=com" -c 4 -t 1 -m 2000 -i 1 -g "rand(0,4999)" "description:modrate-load-test"
if ($LASTEXITCODE -ne 0) { throw "modrate failed with exit code $LASTEXITCODE" }
Write-Host "===== addrate ====="
@'
define suffix=dc=example,dc=com
branch: ou=People,[suffix]
subordinateTemplate: person
template: person
rdnAttr: uid
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
uid: addrate.<sequential:0>
cn: AddRate {uid}
sn: AddRate
userPassword: password
'@ | Set-Content -Encoding ascii addrate.template
opendj-server-legacy\target\package\opendj\bat\addrate.bat --hostname localhost --port 1636 --useSSL --trustAll --bindDN "cn=Directory Manager" --bindPassword password -c 4 -t 1 -m 2000 -i 1 -C fifo -s 100 addrate.template
if ($LASTEXITCODE -ne 0) { throw "addrate failed with exit code $LASTEXITCODE" }
opendj-server-legacy\target\package\opendj\bat\dsconfig.bat create-backend --hostname localhost --port 4444 --bindDN "cn=Directory Manager" --bindPassword password --backend-name=example2 --type je --set=base-dn:dc=example2,dc=com --set=enabled:true --no-prompt --trustAll
opendj-server-legacy\target\package\opendj\bat\makeldif.bat -o test.ldif -c suffix=dc=example2,dc=com opendj-server-legacy\target\package\opendj\config\MakeLDIF\example.template
opendj-server-legacy\target\package\opendj\bat\stop-ds.bat
echo "4.9.9.0" > opendj-server-legacy\target\package\opendj\config\buildinfo
opendj-server-legacy\target\package\opendj\upgrade.bat
opendj-server-legacy\target\package\opendj\bat\import-ldif.bat --offline --ldifFile test.ldif --backendID=example2
opendj-server-legacy\target\package\opendj\bat\rebuild-index.bat --offline --bindDN "cn=Directory Manager" --bindPassword password --baseDN "dc=example2,dc=com" --rebuildAll
opendj-server-legacy\target\package\opendj\bat\start-ds.bat
opendj-server-legacy\target\package\opendj\bat\rebuild-index.bat --bindDN "cn=Directory Manager" --bindPassword password --baseDN "dc=example2,dc=com" --rebuildAll --trustAll
opendj-server-legacy\target\package\opendj\bat\ldapsearch.bat --hostname localhost --port 1636 --bindDN "cn=Directory Manager" --bindPassword password --useSsl --trustAll --baseDN "dc=example2,dc=com" --searchScope sub "(uid=user.*)" dn | find /c '"dn:"' | findstr "10000"
opendj-server-legacy\target\package\opendj\bat\stop-ds.bat
opendj-server-legacy\target\package\opendj\bat\windows-service.bat --enableService
net start "OpenDJ Server"
if ($LASTEXITCODE -ne 0) { throw "net start 'OpenDJ Server' failed with exit code $LASTEXITCODE" }
for ($i=0; $i -lt 12; $i++) { try { $c = New-Object System.Net.Sockets.TcpClient('localhost', 1636); $c.Close(); break } catch { Start-Sleep -Seconds 5 } }
opendj-server-legacy\target\package\opendj\bat\ldapsearch.bat --hostname localhost --port 1636 --bindDN "cn=Directory Manager" --bindPassword password --useSsl --trustAll --baseDN "dc=example2,dc=com" --searchScope sub "(uid=user.*)" dn | find /c '"dn:"' | findstr "10000"
net stop "OpenDJ Server"
if ($LASTEXITCODE -ne 0) { throw "net stop 'OpenDJ Server' failed with exit code $LASTEXITCODE" }
opendj-server-legacy\target\package\opendj\bat\windows-service.bat --disableService
- name: Upload Windows exe artifacts
if: runner.os == 'Windows'
uses: actions/upload-artifact@v7
with:
name: windows-exe-${{ matrix.java }}
retention-days: 5
path: opendj-server-legacy/src/build-tools/windows/*.exe
- name: Upload artifacts OpenDJ Server
uses: actions/upload-artifact@v7
with:
name: ${{ matrix.os }}-${{ matrix.java }}
retention-days: 5
path: |
opendj-server-legacy/target/package/*.zip
opendj-ldap-toolkit/target/*.zip
opendj-packages/opendj-deb/opendj-deb-standard/target/*.deb
opendj-packages/opendj-rpm/opendj-rpm-standard/target/rpm/opendj/RPMS/noarch/*.rpm
opendj-packages/opendj-msi/opendj-msi-standard/target/*.msi
opendj-packages/opendj-docker/target/Dockerfile.zip
opendj-packages/opendj-openshift-template/*.yaml
opendj-doc-generated-ref/target/*.zip
opendj-dsml-servlet/target/*.war
opendj-rest2ldap-servlet/target/*.war
build-docker:
needs: build-maven
runs-on: 'ubuntu-latest'
services:
registry:
image: registry:3
ports:
- 5000:5000
steps:
- uses: actions/checkout@v6
with:
sparse-checkout: .github/benchmark
- name: Download artifacts
uses: actions/download-artifact@v8
with:
name: ubuntu-latest-11
- name: Get latest release version
shell: bash
run: |
export git_version_last="$(curl -i -o - --silent https://api.github.com/repos/OpenIdentityPlatform/OpenDJ/releases/latest | grep -m1 "\"name\"" | cut -d\" -f4)" ; echo "last release: $git_version_last"
echo "release_version=$git_version_last" >> $GITHUB_ENV
- name: Docker meta
id: meta
uses: docker/metadata-action@v6
with:
images: |
localhost:5000/${{ github.repository }}
tags: |
type=raw,value=${{ env.release_version }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
with:
driver-opts: network=host
- name: Prepare Dockerfile
shell: bash
run: |
unzip -d ./opendj-packages/opendj-docker ./opendj-packages/opendj-docker/target/Dockerfile.zip
cp ./opendj-server-legacy/target/package/opendj-*.zip ./opendj-packages/opendj-docker
sed -i -E '/^#COPY opendj/s/^#//' ./opendj-packages/opendj-docker/Dockerfile
- name: Build image (default)
uses: docker/build-push-action@v7
with:
context: ./opendj-packages/opendj-docker
file: ./opendj-packages/opendj-docker/Dockerfile
build-args: |
VERSION=${{ env.release_version }}
platforms: linux/amd64, linux/arm64/8, linux/ppc64le, linux/s390x, linux/riscv64 #, linux/arm/v7
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
- name: Docker test
shell: bash
run: |
trap 'code=$?; echo "::group::container logs (test)"; docker logs test 2>&1 || true; echo "::endgroup::"; exit $code' ERR
docker run --rm -it -d --memory="512m" --name=test localhost:5000/${GITHUB_REPOSITORY,,}:${{ env.release_version }}
timeout 3m bash -c 'until docker inspect --format="{{json .State.Health.Status}}" test | grep -q \"healthy\"; do sleep 10; done'
docker exec test 'sh' '-c' '/opt/opendj/bin/dsconfig create-backend --hostname localhost --port 4444 --bindDN "cn=Directory Manager" --bindPassword password --backend-name=example2 --type je --set=base-dn:dc=example2,dc=com --set=enabled:true --no-prompt --trustAll'
docker exec test 'sh' '-c' '/opt/opendj/bin/makeldif -o /tmp/test.ldif -c suffix=dc=example2,dc=com /opt/opendj/data/config/MakeLDIF/example.template'
docker exec test 'sh' '-c' '/opt/opendj/bin/stop-ds'
docker exec test 'sh' '-c' '/opt/opendj/bin/import-ldif --offline --ldifFile /tmp/test.ldif --backendID=example2'
docker exec test 'sh' '-c' '/opt/opendj/bin/rebuild-index --offline --bindDN "cn=Directory Manager" --bindPassword password --baseDN "dc=example2,dc=com" --rebuildAll'
docker exec test 'sh' '-c' '/opt/opendj/bin/start-ds'
docker exec test 'sh' '-c' '/opt/opendj/bin/rebuild-index --bindDN "cn=Directory Manager" --bindPassword password --baseDN "dc=example2,dc=com" --rebuildAll --trustAll'
docker exec test 'sh' '-c' '/opt/opendj/bin/ldapsearch --hostname localhost --port 1636 --bindDN "cn=Directory Manager" --bindPassword password --useSsl --trustAll --baseDN "ou=people,dc=example2,dc=com" --searchScope sub "(uid=user.*)" dn | grep ^dn: | wc -l | grep -q 10000'
docker kill test
- name: Docker test custom password
shell: bash
run: |
trap 'code=$?; echo "::group::container logs (test_custom)"; docker logs test_custom 2>&1 || true; echo "::endgroup::"; exit $code' ERR
docker run --rm -it -d --memory="512m" -e ADD_BASE_ENTRY="--addBaseEntry" -e ROOT_PASSWORD=custom_password --name=test_custom localhost:5000/${GITHUB_REPOSITORY,,}:${{ env.release_version }}
timeout 3m bash -c 'until docker inspect --format="{{json .State.Health.Status}}" test_custom | grep -q \"healthy\"; do sleep 10; done'
docker exec test_custom 'sh' '-c' '/opt/opendj/bin/ldapsearch --hostname localhost --port 1636 --bindDN "cn=Directory Manager" --bindPassword custom_password --useSsl --trustAll --baseDN "dc=example,dc=com" --searchScope base "(objectClass=*)" 1.1'
docker kill test_custom
- name: Cache JMeter
uses: actions/cache@v5
with:
path: ~/jmeter
key: jmeter-5.6.3
- name: Benchmark PDB vs JE
shell: bash
run: |
A_BACKEND=je B_BACKEND=pdb THREADS=200 DURATION=150 bash .github/benchmark/compare-opendj.sh \
"JE" localhost:5000/${GITHUB_REPOSITORY,,}:${{ env.release_version }} \
"PDB" localhost:5000/${GITHUB_REPOSITORY,,}:${{ env.release_version }}
- name: Upload benchmark artifacts (PDB vs JE)
if: always()
uses: actions/upload-artifact@v7
with:
name: benchmark-pdb-vs-je
path: |
a/
b/
*.jtl
*.docker.log
*.jmeter.out
if-no-files-found: warn
retention-days: 3
- name: Benchmark Build vs Release
shell: bash
run: |
THREADS=200 DURATION=150 bash .github/benchmark/compare-opendj.sh \
"Build" localhost:5000/${GITHUB_REPOSITORY,,}:${{ env.release_version }} \
"Release" openidentityplatform/opendj:latest
- name: Upload benchmark artifacts
if: always()
uses: actions/upload-artifact@v7
with:
name: benchmark-build-vs-release
path: |
a/
b/
*.jtl
*.docker.log
*.jmeter.out
if-no-files-found: warn
retention-days: 3
build-docker-alpine:
needs: build-maven
runs-on: 'ubuntu-latest'
services:
registry:
image: registry:3
ports:
- 5000:5000
steps:
- uses: actions/checkout@v6
with:
sparse-checkout: .github/benchmark
- name: Download artifacts
uses: actions/download-artifact@v8
with:
name: ubuntu-latest-11
- name: Get latest release version
shell: bash
run: |
export git_version_last="$(curl -i -o - --silent https://api.github.com/repos/OpenIdentityPlatform/OpenDJ/releases/latest | grep -m1 "\"name\"" | cut -d\" -f4)" ; echo "last release: $git_version_last"
echo "release_version=$git_version_last" >> $GITHUB_ENV
- name: Docker meta
id: meta
uses: docker/metadata-action@v6
with:
images: |
localhost:5000/${{ github.repository }}
tags: |
type=raw,value=alpine
type=raw,value=${{ env.release_version }}-alpine
- name: Set up QEMU
uses: docker/setup-qemu-action@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
with:
driver-opts: network=host
- name: Prepare Dockerfile
shell: bash
run: |
unzip -d ./opendj-packages/opendj-docker ./opendj-packages/opendj-docker/target/Dockerfile.zip
cp ./opendj-server-legacy/target/package/opendj-*.zip ./opendj-packages/opendj-docker
sed -i -E '/^#COPY opendj/s/^#//' ./opendj-packages/opendj-docker/Dockerfile-alpine
- name: Build image
uses: docker/build-push-action@v7
with:
context: ./opendj-packages/opendj-docker
file: ./opendj-packages/opendj-docker/Dockerfile-alpine
build-args: |
VERSION=${{ env.release_version }}
platforms: linux/amd64, linux/arm64/8, linux/s390x, linux/ppc64le, linux/386, linux/riscv64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
- name: Docker test
shell: bash
run: |
trap 'code=$?; echo "::group::container logs (test)"; docker logs test 2>&1 || true; echo "::endgroup::"; exit $code' ERR
docker run --rm -it -d --memory="1g" --name=test localhost:5000/${GITHUB_REPOSITORY,,}:${{ env.release_version }}-alpine
timeout 3m bash -c 'until docker inspect --format="{{json .State.Health.Status}}" test | grep -q \"healthy\"; do sleep 10; done'
docker exec test 'sh' '-c' '/opt/opendj/bin/dsconfig create-backend --hostname localhost --port 4444 --bindDN "cn=Directory Manager" --bindPassword password --backend-name=example2 --type je --set=base-dn:dc=example2,dc=com --set=enabled:true --no-prompt --trustAll'
docker exec test 'sh' '-c' '/opt/opendj/bin/makeldif -o /tmp/test.ldif -c suffix=dc=example2,dc=com /opt/opendj/data/config/MakeLDIF/example.template'
docker exec test 'sh' '-c' '/opt/opendj/bin/stop-ds'
docker exec test 'sh' '-c' '/opt/opendj/bin/import-ldif --offline --ldifFile /tmp/test.ldif --backendID=example2'
docker exec test 'sh' '-c' '/opt/opendj/bin/rebuild-index --offline --bindDN "cn=Directory Manager" --bindPassword password --baseDN "dc=example2,dc=com" --rebuildAll'
docker exec test 'sh' '-c' '/opt/opendj/bin/start-ds'
docker exec test 'sh' '-c' '/opt/opendj/bin/rebuild-index --bindDN "cn=Directory Manager" --bindPassword password --baseDN "dc=example2,dc=com" --rebuildAll --trustAll'
docker exec test 'sh' '-c' '/opt/opendj/bin/ldapsearch --hostname localhost --port 1636 --bindDN "cn=Directory Manager" --bindPassword password --useSsl --trustAll --baseDN "ou=people,dc=example2,dc=com" --searchScope sub "(uid=user.*)" dn | grep ^dn: | wc -l | grep -q 10000'
docker kill test
- name: Docker test custom password
shell: bash
run: |
trap 'code=$?; echo "::group::container logs (test_custom)"; docker logs test_custom 2>&1 || true; echo "::endgroup::"; exit $code' ERR
docker run --rm -it -d --memory="1g" -e ADD_BASE_ENTRY="--addBaseEntry" -e ROOT_PASSWORD=custom_password --name=test_custom localhost:5000/${GITHUB_REPOSITORY,,}:${{ env.release_version }}-alpine
timeout 3m bash -c 'until docker inspect --format="{{json .State.Health.Status}}" test_custom | grep -q \"healthy\"; do sleep 10; done'
docker exec test_custom 'sh' '-c' '/opt/opendj/bin/ldapsearch --hostname localhost --port 1636 --bindDN "cn=Directory Manager" --bindPassword custom_password --useSsl --trustAll --baseDN "dc=example,dc=com" --searchScope base "(objectClass=*)" 1.1'
docker kill test_custom
- name: Cache JMeter
uses: actions/cache@v5
with:
path: ~/jmeter
key: jmeter-5.6.3
- name: Benchmark Build-alpine vs Release-alpine
shell: bash
run: |
THREADS=200 DURATION=150 bash .github/benchmark/compare-opendj.sh \
"Build-alpine" localhost:5000/${GITHUB_REPOSITORY,,}:${{ env.release_version }}-alpine \
"Release-alpine" openidentityplatform/opendj:alpine
- name: Upload benchmark artifacts
if: always()
uses: actions/upload-artifact@v7
with:
name: benchmark-build-vs-release-alpine
path: |
a/
b/
*.jtl
*.docker.log
*.jmeter.out
if-no-files-found: warn
retention-days: 90
test-msi:
needs: build-maven
runs-on: 'windows-latest'
steps:
- name: Download artifacts
uses: actions/download-artifact@v8
with:
name: windows-latest-11
- name: Install must fail without a JRE
shell: pwsh
run: |
# Simulate a machine with no Java. The launch condition is evaluated by the Windows
# Installer service, which sees the MACHINE environment - so hide Java there too and
# restart msiserver to make it pick the change up; restore everything afterwards.
Stop-Service msiserver -Force -ErrorAction SilentlyContinue
$oldJH = [Environment]::GetEnvironmentVariable('JAVA_HOME','Machine')
$oldPM = [Environment]::GetEnvironmentVariable('Path','Machine')
[Environment]::SetEnvironmentVariable('JAVA_HOME',$null,'Machine')
[Environment]::SetEnvironmentVariable('Path',((($oldPM -split ';') | Where-Object { $_ -notmatch 'java|jdk|jre|zulu|javapath' }) -join ';'),'Machine')
$env:JAVA_HOME = ""
$env:PATH = (($env:PATH -split ';') | Where-Object { $_ -notmatch 'java|jdk|jre|zulu|javapath' }) -join ';'
try {
$msi = (Get-ChildItem -Recurse -Filter *.msi -Path opendj-packages/opendj-msi | Select-Object -First 1).FullName
if (-not $msi) { throw "MSI not found in the windows-latest-11 artifact" }
$p = Start-Process msiexec -Wait -PassThru -ArgumentList "/i `"$msi`" /quiet /qn /norestart /l*v install-nojre.log"
if ($p.ExitCode -eq 0) {
Get-Content install-nojre.log -Tail 60
throw "installer succeeded without a JRE, but the Java launch condition must fail it"
}
Write-Host "Installer refused to install without a JRE as expected (exit $($p.ExitCode))"
Select-String -Path install-nojre.log -Pattern "requires Java" | Select-Object -First 1
} finally {
[Environment]::SetEnvironmentVariable('JAVA_HOME',$oldJH,'Machine')
[Environment]::SetEnvironmentVariable('Path',$oldPM,'Machine')
Stop-Service msiserver -Force -ErrorAction SilentlyContinue
}
- name: Set up Java
uses: actions/setup-java@v5
with:
java-version: '25'
distribution: 'zulu'
- name: Install MSI (silent)
shell: pwsh
run: |
$msi = (Get-ChildItem -Recurse -Filter *.msi -Path opendj-packages/opendj-msi | Select-Object -First 1).FullName
if (-not $msi) { throw "MSI not found in the windows-latest-11 artifact" }
Write-Host "MSI: $msi"
# No OPENDJ property: exercise the x64 default C:\Program Files\OpenDJ (a path with
# spaces, which the server scripts must handle).
$p = Start-Process msiexec -Wait -PassThru -ArgumentList "/i `"$msi`" /quiet /qn /norestart /l*v install.log"
if ($p.ExitCode -ne 0) { Get-Content install.log -Tail 80; throw "msiexec /i failed: $($p.ExitCode)" }
$root = "C:\Program Files\OpenDJ"
if (-not (Test-Path "$root\setup.bat")) { Get-Content install.log -Tail 80; throw "OpenDJ not installed into the x64 default $root" }
Write-Host "Installed to $root"
"OPENDJ_ROOT=$root" | Out-File -FilePath $env:GITHUB_ENV -Append
- name: Setup and start/stop the Windows service
shell: pwsh
run: |
$root = $env:OPENDJ_ROOT
$env:OPENDJ_JAVA_ARGS = "-server -Xmx512m"
& "$root\setup.bat" -h localhost -p 1389 --ldapsPort 1636 --adminConnectorPort 4444 --enableStartTLS --generateSelfSignedCertificate --rootUserDN "cn=Directory Manager" --rootUserPassword password --baseDN dc=example,dc=com --addBaseEntry --cli --acceptLicense --no-prompt --doNotStart
if ($LASTEXITCODE -ne 0) { throw "setup.bat failed: $LASTEXITCODE" }
# The service is already registered by the MSI (WiX ServiceInstall); just start it.
net start "OpenDJ Server"
if ($LASTEXITCODE -ne 0) { throw "net start failed: $LASTEXITCODE" }
for ($i=0; $i -lt 12; $i++) { try { $c = New-Object System.Net.Sockets.TcpClient('localhost', 1636); $c.Close(); break } catch { Start-Sleep -Seconds 5 } }
& "$root\bat\ldapsearch.bat" --hostname localhost --port 1636 --bindDN "cn=Directory Manager" --bindPassword password --useSsl --trustAll --baseDN "dc=example,dc=com" --searchScope base "(objectClass=*)" 1.1
if ($LASTEXITCODE -ne 0) { throw "ldapsearch failed: $LASTEXITCODE" }
net stop "OpenDJ Server"
if ($LASTEXITCODE -ne 0) { throw "net stop failed: $LASTEXITCODE" }
- name: Uninstall MSI
shell: pwsh
run: |
$msi = (Get-ChildItem -Recurse -Filter *.msi -Path opendj-packages/opendj-msi | Select-Object -First 1).FullName
$p = Start-Process msiexec -Wait -PassThru -ArgumentList "/x `"$msi`" /quiet /qn /norestart /l*v uninstall.log"
if ($p.ExitCode -ne 0) { Get-Content uninstall.log -Tail 80; throw "msiexec /x failed: $($p.ExitCode)" }
Write-Host "Uninstalled OK"
# Upgrade path: released 5.1.1 x86 MSI (wine-built, WiX3) -> this build's x64 MSI.
# Verifies the new installer detects the legacy Program Files (x86) install, keeps the
# instance data in place, replaces the windows-service.bat service with the MSI-managed
# one, and the upgraded server starts with the old data.
test-msi-upgrade:
needs: build-maven
runs-on: 'windows-latest'
steps:
- name: Download artifacts
uses: actions/download-artifact@v8
with:
name: windows-latest-11
- name: Set up Java
uses: actions/setup-java@v5
with:
java-version: '25'
distribution: 'zulu'
- name: Install released 5.1.1 MSI and configure an instance
shell: pwsh
run: |
Invoke-WebRequest -Uri "https://github.com/OpenIdentityPlatform/OpenDJ/releases/download/5.1.1/opendj-5.1.1.msi" -OutFile opendj-5.1.1.msi
# The released 5.1.1 scripts cannot run from a directory with spaces (unquoted
# java.io.tmpdir), so put the old install into C:\opendj.
$p = Start-Process msiexec -Wait -PassThru -ArgumentList "/i opendj-5.1.1.msi /quiet /qn /norestart OPENDJ=C:\opendj /l*v install-old.log"
if ($p.ExitCode -ne 0) { Get-Content install-old.log -Tail 80; throw "msiexec /i (5.1.1) failed: $($p.ExitCode)" }
$root = "C:\opendj"
if (-not (Test-Path "$root\setup.bat")) { Get-Content install-old.log -Tail 80; throw "5.1.1 install root not found at $root" }
$env:OPENDJ_JAVA_ARGS = "-server -Xmx512m"
& "$root\setup.bat" -h localhost -p 1389 --ldapsPort 1636 --adminConnectorPort 4444 --enableStartTLS --generateSelfSignedCertificate --rootUserDN "cn=Directory Manager" --rootUserPassword password --baseDN dc=example,dc=com --addBaseEntry --cli --acceptLicense --no-prompt --doNotStart
if ($LASTEXITCODE -ne 0) { throw "setup.bat (5.1.1) failed: $LASTEXITCODE" }
# Register the LEGACY service the pre-MSI way and prove it works, then stop it.
& "$root\bat\windows-service.bat" --enableService
if ($LASTEXITCODE -ne 0) { throw "windows-service --enableService failed: $LASTEXITCODE" }
net start "OpenDJ Server"
if ($LASTEXITCODE -ne 0) { throw "net start (5.1.1) failed: $LASTEXITCODE" }
net stop "OpenDJ Server"
if ($LASTEXITCODE -ne 0) { throw "net stop (5.1.1) failed: $LASTEXITCODE" }
- name: Upgrade with the newly built MSI (same directory passed explicitly)
shell: pwsh
run: |
$msi = (Get-ChildItem -Recurse -Filter *.msi -Path opendj-packages/opendj-msi | Select-Object -First 1).FullName
if (-not $msi) { throw "MSI not found in the windows-latest-11 artifact" }
$p = Start-Process msiexec -Wait -PassThru -ArgumentList "/i `"$msi`" /quiet /qn /norestart OPENDJ=C:\opendj /l*v upgrade.log"
if ($p.ExitCode -ne 0) { Get-Content upgrade.log -Tail 120; throw "msiexec /i (upgrade) failed: $($p.ExitCode)" }
$root = "C:\opendj"
# New package files landed in the old directory, not the x64 default
if (-not (Test-Path "$root\setup.bat")) { throw "upgrade did not keep the old install dir" }
if (Test-Path "C:\Program Files\OpenDJ") { throw "upgrade unexpectedly installed into the x64 default dir" }
# Instance data survived
if (-not (Test-Path "$root\config\config.ldif")) { throw "instance data (config\config.ldif) lost by the upgrade" }
# Legacy service replaced by the MSI-managed one: display name maps to key 'OpenDJ'
$key = (sc.exe getkeyname "OpenDJ Server" | Select-String -Pattern "Name = (.+)").Matches[0].Groups[1].Value.Trim()
if ($key -ne "OpenDJ") { sc.exe query; throw "expected MSI-managed service key 'OpenDJ', got '$key'" }
sc.exe qc OpenDJ
"OPENDJ_ROOT=$root" | Out-File -FilePath $env:GITHUB_ENV -Append
- name: Run upgrade.bat and start the upgraded server
shell: pwsh
run: |
$root = $env:OPENDJ_ROOT
$env:OPENDJ_JAVA_ARGS = "-server -Xmx512m"
& "$root\upgrade.bat" --no-prompt --acceptLicense --force
if ($LASTEXITCODE -ne 0) { throw "upgrade.bat failed: $LASTEXITCODE" }
net start "OpenDJ Server"
if ($LASTEXITCODE -ne 0) { throw "net start (upgraded) failed: $LASTEXITCODE" }
for ($i=0; $i -lt 12; $i++) { try { $c = New-Object System.Net.Sockets.TcpClient('localhost', 1636); $c.Close(); break } catch { Start-Sleep -Seconds 5 } }
# The pre-upgrade data must still be served
& "$root\bat\ldapsearch.bat" --hostname localhost --port 1636 --bindDN "cn=Directory Manager" --bindPassword password --useSsl --trustAll --baseDN "dc=example,dc=com" --searchScope base "(objectClass=*)" 1.1
if ($LASTEXITCODE -ne 0) { throw "ldapsearch after upgrade failed: $LASTEXITCODE" }
net stop "OpenDJ Server"
if ($LASTEXITCODE -ne 0) { throw "net stop (upgraded) failed: $LASTEXITCODE" }
- name: Auto-detect the legacy default directory on a fresh install
shell: pwsh
run: |
$msi = (Get-ChildItem -Recurse -Filter *.msi -Path opendj-packages/opendj-msi | Select-Object -First 1).FullName
# Clean up the previous scenario first.
$p = Start-Process msiexec -Wait -PassThru -ArgumentList "/x `"$msi`" /quiet /qn /norestart /l*v uninstall1.log"
if ($p.ExitCode -ne 0) { Get-Content uninstall1.log -Tail 80; throw "msiexec /x failed: $($p.ExitCode)" }
if (Get-Service OpenDJ -ErrorAction SilentlyContinue) { throw "service not removed by uninstall" }
# An existing legacy default directory must be picked up when OPENDJ is not given.
New-Item -ItemType Directory -Force "C:\Program Files (x86)\OpenDJ" | Out-Null
$p = Start-Process msiexec -Wait -PassThru -ArgumentList "/i `"$msi`" /quiet /qn /norestart /l*v install-autodetect.log"
if ($p.ExitCode -ne 0) { Get-Content install-autodetect.log -Tail 80; throw "msiexec /i (autodetect) failed: $($p.ExitCode)" }
if (-not (Test-Path "C:\Program Files (x86)\OpenDJ\setup.bat")) { Get-Content install-autodetect.log -Tail 80; throw "installer did not auto-detect the legacy default dir" }
if (Test-Path "C:\Program Files\OpenDJ") { throw "installer used the x64 default dir despite an existing legacy dir" }
Write-Host "Legacy default directory auto-detected OK"
$p = Start-Process msiexec -Wait -PassThru -ArgumentList "/x `"$msi`" /quiet /qn /norestart /l*v uninstall2.log"
if ($p.ExitCode -ne 0) { Get-Content uninstall2.log -Tail 80; throw "msiexec /x (cleanup) failed: $($p.ExitCode)" }