Skip to content

Merge pull request #2596 from akrherz/492 #3316

Merge pull request #2596 from akrherz/492

Merge pull request #2596 from akrherz/492 #3316

name: Openfire CI
env:
CI: true
on: [push, pull_request]
jobs:
build:
name: Build Openfire from source
runs-on: ubuntu-latest
strategy:
matrix:
java: [ 11, 17 ]
distribution: [ zulu ] # We could add more here: temurin, adopt, liberica, microsoft, corretto
steps:
- uses: actions/checkout@v4
- name: Set up JDK ${{ matrix.java }} ${{ matrix.distribution }}
uses: actions/setup-java@v4
with:
java-version: ${{ matrix.java }}
distribution: ${{ matrix.distribution }}
cache: maven
- name: Build with Maven # We install instead of package, because we want the result in the local mvn repo
run: |
if [[ ${{ github.ref_name }} == 'main' ]]; then
./mvnw -B install -Pcoverage --file pom.xml
else
./mvnw -B install
fi
- name: Upload failed test reports
uses: actions/upload-artifact@v4
if: always()
with:
name: surefire-reports_java${{ matrix.java }}
path: xmppserver/target/surefire-reports
- name: tar distribution # sharing artifacts that consist of many files can be slow. Share one file instead.
if: ${{ matrix.distribution == 'zulu' }}
run: tar -cf distribution-artifact.tar distribution/target/distribution-base
- name: Upload distribution
if: ${{ matrix.distribution == 'zulu' }}
uses: actions/upload-artifact@v4
with:
name: distribution-java${{ matrix.java }}
path: distribution-artifact.tar
- name: Upload coverage report for 'xmppserver' module
if: ${{ matrix.distribution == 'zulu' && matrix.java == 11 && github.ref_name == 'main'}}
uses: actions/upload-artifact@v4
with:
name: Coverage Report for 'xmppserver' module
path: xmppserver/target/site/jacoco/
- name: Temporarily stash openfire artifacts from the mvn repo for later jobs
if: ${{ matrix.distribution == 'zulu' && matrix.java == 11 }}
uses: actions/upload-artifact@v4
with:
name: mvn-repo
path: ~/.m2/repository/org/igniterealtime/openfire/
retention-days: 1
aioxmpp:
name: Execute aioxmpp-based CI tests
runs-on: ubuntu-latest
needs: build
steps:
- name: Checkout local actions (that are invoked in the 'startCIServer' and 'stopCIServer' steps) # Do this _before_ untarring the distribution, as the checkout will empty the directory prior to the checkout!
uses: actions/checkout@v4
with:
sparse-checkout: |
.github
- name: Download distribution artifact from build job.
uses: actions/download-artifact@v4
with:
name: distribution-java11
path: .
- name: untar distribution # sharing artifacts that consist of many files can be slow. Share one file instead.
run: tar -xf distribution-artifact.tar
- name: Checkout aioxmpp devel/head
run: git clone https://codeberg.org/jssfr/aioxmpp.git aioxmpp
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: 3.11
check-latest: true # attempt to prevent to use 3.11.3 by enticing the runner to update (to something later)
- name: Install aoixmpp dependencies
run: python -m pip install setuptools pytest pytest-cov coveralls pyOpenSSL pytz
- name: Build aioxmpp
working-directory: ./aioxmpp
run: python -m pip install .
- name: Create Openfire config file for aioxmpp
working-directory: ./aioxmpp
run: |
cat >"openfire-config.ini" <<EOL
[global]
provisioner=aioxmpp.e2etest.provision.AnonymousProvisioner
[aioxmpp.e2etest.provision.AnonymousProvisioner]
domain=example.org
host=localhost
port=5222
no_verify=true
quirks=["https://zombofant.net/xmlns/aioxmpp/e2etest/quirks#no-adhoc-ping", "https://zombofant.net/xmlns/aioxmpp/e2etest/quirks#no-xep-0049", "https://zombofant.net/xmlns/aioxmpp/e2etest/quirks#muc-no-333"]
EOL
- name: Start CI server from distribution
id: startCIServer
uses: ./.github/actions/startserver-action
- name: Run aioxmpp tests
working-directory: ./aioxmpp
run: |
set -e
mkdir output
# OF-2849 test_publish_and_purge
# OF-2850 test_publish_multiple_and_get_by_id
# OF-2851 test_convert_field_datetime_default_locale
# OF-2853 test_set_topic
python -m pytest -p aioxmpp.e2etest --e2etest-config="openfire-config.ini" -k 'not (test_set_topic or test_publish_and_purge or test_publish_multiple_and_get_by_id or test_convert_field_datetime_default_locale)' tests 2>&1 | tee output/aioxmpp.test.output.txt
if [ ${PIPESTATUS[0]} -ne 0 ]; then false; fi;
- name: Expose test output
if: always()
uses: actions/upload-artifact@v4
with:
name: aioxmpp test output
path: aioxmpp/output
- name: Stop CI server
if: ${{ always() && steps.startCIServer.conclusion == 'success' }} # TODO figure out if this is correct. The intent is to have the server stopped if it was successfully started, even if the tests fail. Failing tests should still cause the job to fail.
uses: ./.github/actions/stopserver-action
- name: Expose openfire output
if: always()
uses: actions/upload-artifact@v4
with:
name: openfire logs
path: distribution/target/distribution-base/logs/*
check_branch:
runs-on: ubuntu-latest
outputs:
is_publishable_branch: ${{ steps.check-branch.outputs.is_publishable_branch }}
steps:
- name: check branch ${{ github.ref }} is either main or a version number
id: check-branch
run: |
if [[ ${{ github.ref }} == 'refs/heads/main' || ${{ github.ref }} =~ refs\/heads\/[0-9]+\.[0-9]+ ]]; then
echo "is_publishable_branch=true" >> $GITHUB_OUTPUT
else
echo "is_publishable_branch=false" >> $GITHUB_OUTPUT
fi
connectivity:
name: Execute Connectivity CI tests
runs-on: ubuntu-latest
needs: build
steps:
- name: Checkout local actions (that are invoked in the 'startCIServer' and 'stopCIServer' steps) # Do this _before_ untarring the distribution, as the checkout will empty the directory prior to the checkout!
uses: actions/checkout@v4
with:
sparse-checkout: |
.github
- name: Download distribution artifact from build job.
uses: actions/download-artifact@v4
with:
name: distribution-java11
path: .
- name: untar distribution # sharing artifacts that consist of many files can be slow. Share one file instead.
run: tar -xf distribution-artifact.tar
- name: Start CI server from distribution
id: startCIServer
uses: ./.github/actions/startserver-action
- name: Run connectivity tests
uses: ./.github/actions/connectivitytests-action
- name: Stop CI server
if: ${{ always() && steps.startCIServer.conclusion == 'success' }} # TODO figure out if this is correct. The intent is to have the server stopped if it was successfully started, even if the tests fail. Failing tests should still cause the job to fail.
uses: ./.github/actions/stopserver-action
smack:
name: Execute Smack-based CI tests
runs-on: ubuntu-latest
needs: build
steps:
- name: Checkout local actions (that are invoked in the 'startCIServer' and 'stopCIServer' steps) # Do this _before_ untarring the distribution, as the checkout will empty the directory prior to the checkout!
uses: actions/checkout@v4
with:
sparse-checkout: |
.github
- name: Download distribution artifact from build job.
uses: actions/download-artifact@v4
with:
name: distribution-java11
path: .
- name: untar distribution # sharing artifacts that consist of many files can be slow. Share one file instead.
run: tar -xf distribution-artifact.tar
- name: Start CI server from distribution
id: startCIServer
uses: ./.github/actions/startserver-action
- name: Run Smack tests against server
uses: XMPP-Interop-Testing/xmpp-interop-tests-action@main
with:
domain: 'example.org'
adminAccountUsername: 'admin'
adminAccountPassword: 'admin'
disabledSpecifications: 'XEP-0045,XEP-0060'
disabledTests: 'EntityCapsTest,SoftwareInfoIntegrationTest,XmppConnectionIntegrationTest,StreamManagementTest,WaitForClosingStreamElementTest,IoTControlIntegrationTest,ModularXmppClientToServerConnectionLowLevelIntegrationTest'
- name: Stop CI server
if: ${{ always() && steps.startCIServer.conclusion == 'success' }} # TODO figure out if this is correct. The intent is to have the server stopped if it was successfully started, even if the tests fail. Failing tests should still cause the job to fail.
uses: ./.github/actions/stopserver-action
should-do-database-upgrade-tests:
name: Check if database upgrade tests should be run
runs-on: ubuntu-latest
permissions:
pull-requests: read
outputs:
check: ${{ steps.filter.outputs.database-relevant-files }}
steps:
- name: Checkout Openfire
uses: actions/checkout@v4
- name: Check for differences
uses: dorny/paths-filter@v3
id: filter
with:
filters: |
database-relevant-files:
- 'distribution/src/database/**'
- 'build/ci/**'
- '.github/workflows/continuous-integration-workflow.yml'
- 'xmppserver/pom.xml'
sqlserver:
name: Test SQL Server Upgrades
needs: [build, should-do-database-upgrade-tests, check_branch]
runs-on: ubuntu-latest
if: ${{ needs.should-do-database-upgrade-tests.outputs.check == 'true' || needs.check_branch.outputs.is_publishable_branch == 'true'}}
steps:
- name: Checkout Openfire
uses: actions/checkout@v4
- name: Set up JDK 11 Zulu
uses: actions/setup-java@v4
with:
java-version: 11
distribution: zulu
cache: maven
- name: Restore mvn repo artifacts from build job
uses: actions/download-artifact@v4
with:
name: mvn-repo
path: ~/.m2/repository/org/igniterealtime/openfire/
- name: Set environment variables
run: |
echo "CONNECTION_STRING=jdbc:sqlserver://localhost:1433;databaseName=openfire;applicationName=Openfire" >> $GITHUB_ENV
echo "CONNECTION_DRIVER=com.microsoft.sqlserver.jdbc.SQLServerDriver" >> $GITHUB_ENV
echo "CONNECTION_USERNAME=sa" >> $GITHUB_ENV
echo "CONNECTION_PASSWORD=SecurePa55w0rd" >> $GITHUB_ENV
OPENFIREVSN=$(./mvnw help:evaluate -Dexpression=project.version -q -DforceStdout)
echo "OPENFIREVSN=$OPENFIREVSN" >> $GITHUB_ENV
echo "JAVA_HOME=$(echo $JAVA_HOME_11_X64)" >> $GITHUB_ENV
- name: Download old Openfire database script
run: |
mkdir olddb
curl https://raw.githubusercontent.com/igniterealtime/Openfire/v3.9.3/src/database/openfire_sqlserver.sql > $GITHUB_WORKSPACE/olddb/openfire_sqlserver.sql
- name: Start database server and install database
run: docker compose -f ./build/ci/compose/mssql.yml up --detach
- name: Build & run update tester
run: |
pushd ./build/ci/updater
./mvnw package
java -jar ./target/updaterunner-1.0.0-jar-with-dependencies.jar
postgres:
name: Test Postgres Upgrades
needs: [build, should-do-database-upgrade-tests, check_branch]
runs-on: ubuntu-latest
if: ${{ needs.should-do-database-upgrade-tests.outputs.check == 'true' || needs.check_branch.outputs.is_publishable_branch == 'true'}}
steps:
- name: Checkout Openfire
uses: actions/checkout@v4
- name: Set up JDK 11 Zulu
uses: actions/setup-java@v4
with:
java-version: 11
distribution: zulu
cache: maven
- name: Restore mvn repo artifacts from build job
uses: actions/download-artifact@v4
with:
name: mvn-repo
path: ~/.m2/repository/org/igniterealtime/openfire/
- name: Set environment variables
run: |
echo "CONNECTION_STRING=jdbc:postgresql://localhost:5432/openfire" >> $GITHUB_ENV
echo "CONNECTION_DRIVER=org.postgresql.Driver" >> $GITHUB_ENV
echo "CONNECTION_USERNAME=openfire" >> $GITHUB_ENV
echo "CONNECTION_PASSWORD=SecurePa55w0rd" >> $GITHUB_ENV
OPENFIREVSN=$(./mvnw help:evaluate -Dexpression=project.version -q -DforceStdout)
echo "OPENFIREVSN=$OPENFIREVSN" >> $GITHUB_ENV
echo "JAVA_HOME=$(echo $JAVA_HOME_11_X64)" >> $GITHUB_ENV
- name: Download old Openfire database script
run: |
mkdir olddb
curl https://raw.githubusercontent.com/igniterealtime/Openfire/v3.9.3/src/database/openfire_postgresql.sql > $GITHUB_WORKSPACE/olddb/openfire_postgresql.sql
- name: Start database server and install database
run: docker compose -f ./build/ci/compose/postgresql.yml up --detach
- name: Build & run update tester
run: |
pushd ./build/ci/updater
./mvnw package
java -jar ./target/updaterunner-1.0.0-jar-with-dependencies.jar
mysql:
name: Test MySQL Upgrades
needs: [build, should-do-database-upgrade-tests, check_branch]
runs-on: ubuntu-latest
if: ${{ needs.should-do-database-upgrade-tests.outputs.check == 'true' || needs.check_branch.outputs.is_publishable_branch == 'true'}}
steps:
- name: Checkout Openfire
uses: actions/checkout@v4
- name: Set up JDK 11 Zulu
uses: actions/setup-java@v4
with:
java-version: 11
distribution: zulu
cache: maven
- name: Restore mvn repo artifacts from build job
uses: actions/download-artifact@v4
with:
name: mvn-repo
path: ~/.m2/repository/org/igniterealtime/openfire/
- name: Set environment variables
run: |
echo "CONNECTION_STRING=jdbc:mysql://localhost:3306/openfire?rewriteBatchedStatements=true&characterEncoding=UTF-8&characterSetResults=UTF-8&serverTimezone=UTC" >> $GITHUB_ENV
echo "CONNECTION_DRIVER=com.mysql.cj.jdbc.Driver" >> $GITHUB_ENV
echo "CONNECTION_USERNAME=root" >> $GITHUB_ENV
echo "CONNECTION_PASSWORD=SecurePa55w0rd" >> $GITHUB_ENV
OPENFIREVSN=$(./mvnw help:evaluate -Dexpression=project.version -q -DforceStdout)
echo "OPENFIREVSN=$OPENFIREVSN" >> $GITHUB_ENV
echo "JAVA_HOME=$(echo $JAVA_HOME_11_X64)" >> $GITHUB_ENV
- name: Download old Openfire database script
run: |
mkdir olddb
curl https://raw.githubusercontent.com/igniterealtime/Openfire/v3.9.3/src/database/openfire_mysql.sql > $GITHUB_WORKSPACE/olddb/openfire_mysql.sql
- name: Start database server and install database
run: docker compose -f ./build/ci/compose/mysql.yml up --detach
- name: Build & run update tester
run: |
pushd ./build/ci/updater
./mvnw package
java -jar ./target/updaterunner-1.0.0-jar-with-dependencies.jar
publish-maven:
name: Publish to Maven
runs-on: ubuntu-latest
needs: [aioxmpp, connectivity, smack, check_branch, sqlserver, postgres, mysql]
if: ${{github.repository == 'igniterealtime/Openfire' && github.event_name == 'push' && needs.check_branch.outputs.is_publishable_branch == 'true'}}
steps:
- uses: actions/checkout@v4
with:
# Defend against another commit quickly following the first
# We want the one that's been tested, rather than the head of main
ref: ${{ github.event.push.after }}
- name: Set up Java for publishing
uses: actions/setup-java@v4
with:
java-version: 11
distribution: zulu
cache: maven
server-id: igniterealtime
server-username: IGNITE_REALTIME_MAVEN_USERNAME
server-password: IGNITE_REALTIME_MAVEN_PASSWORD
- name: Publish
run: ./mvnw -B deploy -Pci -Dmaven.test.skip=true
env:
IGNITE_REALTIME_MAVEN_USERNAME: ${{ secrets.IGNITE_REALTIME_MAVEN_USERNAME }}
IGNITE_REALTIME_MAVEN_PASSWORD: ${{ secrets.IGNITE_REALTIME_MAVEN_PASSWORD }}
can-publish-docker:
# Based on https://github.com/GabLeRoux/github-actions-examples/blob/e0468ce2731b08bd8b1f7cd09d0b94c541310693/.github/workflows/secret_based_conditions.yml
name: Check if Docker Hub secrets exist
runs-on: ubuntu-latest
needs: [build, aioxmpp, connectivity, smack]
outputs:
is_DOCKERHUB_SECRET_set: ${{ steps.checksecret_job.outputs.is_DOCKERHUB_SECRET_set }}
steps:
- name: Check whether Docker Publish should be done
id: checksecret_job
env:
DOCKERHUB_SECRET: ${{ secrets.DOCKERHUB_TOKEN }}
run: |
echo "is_DOCKERHUB_SECRET_set: ${{ env.DOCKERHUB_SECRET != '' }}"
echo "is_DOCKERHUB_SECRET_set=${{ env.DOCKERHUB_SECRET != '' }}" >> $GITHUB_OUTPUT
publish-docker:
name: Publish to Docker Hub
runs-on: ubuntu-latest
needs: [can-publish-docker]
if: |
needs.can-publish-docker.outputs.is_DOCKERHUB_SECRET_set == 'true' &&
github.event_name == 'push' &&
(contains(github.ref, 'refs/tags/') || github.ref == 'refs/heads/main')
outputs:
imagedigest: ${{ steps.docker_build.outputs.digest }}
steps:
- name: Set up variables if we're on main
if: ${{ github.ref == 'refs/heads/main' }}
run: echo "SOURCE_TAG=alpha" >> $GITHUB_ENV
- name: Set up variables if we're on a tag
if: ${{ contains(github.ref, 'refs/tags/') }}
run: echo "SOURCE_TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
- uses: actions/checkout@v4
with:
# Defend against another commit quickly following the first
# We want the one that's been tested, rather than the head of main
ref: ${{ github.event.push.after }}
- name: Download distribution artifact from build job.
uses: actions/download-artifact@v4
with:
name: distribution-java11
path: distribution/target/distribution-base
- name: Fix file permissions
run: find . -type f -name '*.sh' -exec chmod +x {} \;
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Cache Docker layers # TODO: Validate that caches are faster than no caches
uses: actions/cache@v4
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push to Docker Hub
id: docker_build
uses: docker/build-push-action@v6
with:
context: .
push: true
tags: ${{ secrets.DOCKERHUB_OPENFIREIMAGE }}:${{ env.SOURCE_TAG }}
platforms: linux/amd64,linux/arm64
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new
- name: Move cache
# Temp fix
# https://github.com/docker/build-push-action/issues/252
# https://github.com/moby/buildkit/issues/1896
run: |
rm -rf /tmp/.buildx-cache
mv /tmp/.buildx-cache-new /tmp/.buildx-cache
- name: Image digest
run: |
echo Images published:
echo ${{ secrets.DOCKERHUB_OPENFIREIMAGE }}:${{ steps.docker_build.outputs.digest }}
echo ${{ secrets.DOCKERHUB_OPENFIREIMAGE }}:${{ env.SOURCE_TAG }}
test-published-docker:
name: Test tagged images published to Docker Hub
runs-on: ubuntu-latest
needs: [publish-docker]
if: contains(github.ref, 'refs/tags/')
steps:
- name: Launch & Check Openfire
run: |
docker run --name openfire -d -p 9090:9090 ${{ secrets.DOCKERHUB_OPENFIREIMAGE }}@${{needs.publish-docker.outputs.imagedigest}}
attempt_counter=0
max_attempts=30
until $(curl --output /dev/null --silent --head --fail http://127.0.0.1:9090); do
if [ ${attempt_counter} -eq ${max_attempts} ];then
echo "Max attempts reached. Openfire failed to launch."
exit 1
fi
printf '.'
attempt_counter=$(($attempt_counter+1))
sleep 1
done
echo "Openfire Admin is reachable."
docker logs openfire
build-deb-artifact:
name: Generate DEB artifact
runs-on: ubuntu-latest
needs: [build]
steps:
- uses: actions/checkout@v4
with:
# Defend against another commit quickly following the first
# We want the one that's been tested, rather than the head of main
ref: ${{ github.event.push.after }}
- name: Download distribution artifact from build job.
uses: actions/download-artifact@v4
with:
name: distribution-java11
path: .
- name: untar distribution # sharing artifacts that consist of many files can be slow. Share one file instead.
run: tar -xf distribution-artifact.tar
- name: Install build deps
run: sudo apt-get install -y debhelper-compat=13
- name: Run build script
run: bash build/debian/build_debs.sh