docs(quarkus): merge quarkus/CONTRIBUING.md into quarkus/README.md (#46033)

Closes #45805

Signed-off-by: Michal Vavřík <michal.vavrik@aol.com>
This commit is contained in:
Michal Vavřík 2026-02-09 09:45:16 +01:00 committed by GitHub
parent d95f456b4f
commit 0d28b664d3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 226 additions and 299 deletions

View file

@ -1,279 +0,0 @@
# Contributing guide
## Keycloak Quarkus Extension
Keycloak on Quarkus is basically a Quarkus Extension. For more details about extensions, please take a look at [Writing Your Own Extension](https://quarkus.io/guides/writing-extensions) guide.
As an extension, the server can be embedded in any Quarkus application by adding the following dependency:
```
<dependencies>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-quarkus-server</artifactId>
</dependency>
</dependencies>
```
Just like any other extension, the server extension has two main modules:
* `deployment`
* `runtime`
Within the `deployment` module you'll find the implementation for the build steps that run when (re)augmenting the application. This module
is responsible for all metadata processing, such as:
* Lookup SPIs and their providers and enable/disable them accordingly
* Create a closed-world assumption about the providers that should be registered to the `KeycloakSessionFactory`
* Customizations to how Hibernate, Resteasy, Liquibase, Infinispan, and other dependencies are configured and bootstrapped
* Creating Jandex indexes for some server dependencies
The output of this module is bytecode generated by Quarkus that improves the server startup time and memory usage so that any processing
done during (re)augmentation does not happen again when actually starting the server. Note that the code from this module does
not run at all at runtime (when running the server) but only when building the project (the `server` module in particular, more on that later) or when triggering
a re-augmentation when running the `build` command.
Within the `runtime` module you'll find the code that is run at runtime when starting and running the server. The main link between
the `deployment` and `runtime` modules is the `org.keycloak.quarkus.runtime.KeycloakRecorder` class. The `KeycloakRecorder` holds
a set of methods that are invoked from build steps that will end up in recorded bytecode. The recorded bytecode executes those methods at runtime
just like they were called when a build step is run, with the exact same arguments and values, if any.
As an example, let us look at how the SPIs and their providers are discovered and how the `KeycloakSessionFactory` is created.
Quarkus will run the `org.keycloak.quarkus.deployment.KeycloakProcessor.configureProviders` build step whenever you are (re)augmenting the server. The main outcome from this method
is to invoke the `org.keycloak.quarkus.runtime.KeycloakRecorder.configSessionFactory` so that the code from this method is executed at
*runtime* with a closed-world assumption about the providers that should be registered to the `KeycloakSessionFactory`. At runtime the code from that method is executed
and a `KeycloakSessionFactory` is created without any processing to discover SPIs and their providers.
There are a few reasons why we have Keycloak as a Quarkus extension:
* More control over the build-time augmentation and runtime stages.
* More flexibility when extending Quarkus itself and the extensions used by the server (e.g.: Hibernate, Resteasy, etc.)
* Make it easier to embed the server into Quarkus applications
* Make it possible to allow Keycloak developers to customize the server distribution
## Keycloak Server
The `server` module holds the Keycloak Server itself. It is basically a regular Quarkus application using the `keycloak-quarkus-server` extension. If you look at the
[pom.xml](server/pom.xml) from this module you'll notice that it is a very simple Quarkus application with the bare minimum configuration
to actually build and run the server.
As Quarkus application, the server is a [mutable](https://quarkus.io/guides/reaugmentation#how-to-re-augment-a-quarkus-application) application using the
[mutable-jar](server/src/main/resources/application.properties) package type. As a mutable application, Keycloak is able to allow
users to configure some aspects of the server without having to re-build this module, something impractical from a user perspective.
The mutability of the server is directly related to the `build` command. As mentioned before, the build steps from the `deployment` module
are only run when (re)augmenting the server and when running the `build` command, the server will indicate to Quarkus that the build steps
should re-run and the recorded bytecode should be updated to reflect any change to the server configuration.
From a Quarkus perspective, the server is also a [Command Mode Application](https://quarkus.io/guides/command-mode-reference) and provides
a CLI based on [Picocli](https://picocli.info/). As such, there is a single entrypoint that executes the code to execute the CLI and bootstrap the server. This entry point
is the `org.keycloak.quarkus.runtime.KeycloakMain` class from the `runtime` module.
## Keycloak Distribution
The server distribution is created by build the `dist` module. This module basically consists of packaging the `deployment`, `runtime`,
and `server` modules artifacts and their dependencies to a `ZIP` or tarball file.
Within this directory you'll find the directory structure of the distribution and what is included in it.
## Running the server in development mode
As a regular Quarkus application, you are able to run the `server` module in [dev mode](https://quarkus.io/guides/maven-tooling#dev-mode) just like any regular application:
```
cd server
mvn clean quarkus:dev -Dquarkus.args="start-dev"
```
You can set any command or configuration option to the server by setting the `quarkus.args` environment variable.
When running in dev mode, you can benefit from the dev mode capabilities from Quarkus but with some limitations. The main limitations you'll find
at the moment are:
* Changes are only automatically reflected at runtime if you are changing resources from the `deployment`, `runtime`, and `server` modules. Other modules, such as `keycloak-services` still rely on Hot Swap in Java debuggers to reload classes.
* There is nothing in the Dev UI related to the server itself, although you can still change some configuration from there.
* There are some limitations when passing some options when running in dev mode. You should expect more improvements in this area.
We are working to improve the dev experience, and you should expect improvements over time.
## Debugging the server distribution
The `kc.sh|bat` script allows you to remotely debug the distribution. For that, you should run the server as follows:
```
kc.sh --debug start-dev
```
By default, the debug port is available at `8787` on localhost. Additionally, you can specify IPv4 or bracketed IPv6 addresses with optional ports, e.g. `--debug 127.0.0.1:8786`, `--debug [::1]:8785`. Make sure to exercise caution when setting IP addresses in the `--debug` parameter, since a value such as `--debug 0.0.0.0:8787` will expose the debug port to all network interfaces!
An additional environment variable `DEBUG_SUSPEND` can be set to suspend the JVM, when launched in debug mode. The `DEBUG_SUSPEND` variable supports the following values:
* `y` - The debug mode JVM launch is suspended
* `n` - The debug mode JVM is started without suspending
Suspending the JVM when in debug mode is useful if you want to debug the early stages of the bootstrap code.
When making changes to the `deployment`, `runtime`, or `server` modules, you can update the distribution with the new artifacts by executing
the following command:
```
mvn -DskipTests clean install
```
After the `quarkus` module and sub-modules are built, you can update the distribution as follows:
```
cp -r server/target/lib ${KC_HOME_DIR}
```
In the example above, the `${KC_HOME_DIR}` variable points to the root directory of the distribution.
You should also be able to update a server dependency directly. For that, copy the jar to the following location:
```
cp services/target/keycloak-services-${KC_VERSION}.jar ${KC_HOME_DIR}/lib/lib/main/org.keycloak.keycloak-services-${KC_VERSION}.jar
```
## Running tests
The distribution has its own distribution and the main tests are within the [tests/integration](tests/integration) module.
The test suite has two main types of tests:
* `jvm`
* `distribution`
The `jvm` tests execute both the test class and server within the same JVM. While the `distribution` tests execute the server
by running the distribution in a separate JVM.
The `distribution` tests are marked as such using the `DistributionTest` annotation. If not marked with this annotation, the test is a `JVM` test.
To run the tests, execute the following command within the `quarkus` module:
```
mvn clean install
```
By default, the tests will run using a raw distribution. If you want to run tests from the [tests/integration](tests/integration) module directly,
please make sure the distribution was built with the latest changes you did to it and its dependencies.
### Running tests using a container
You can also run tests using a container instead of the raw distribution by setting the `kc.quarkus.tests.dist` property as follows:
```
mvn clean install -Dkc.quarkus.tests.dist=docker
```
When setting the `kc.quarkus.tests.dist` to `docker` tests will run using a container instead of the raw distribution.
### Running storage tests
The storage tests are disabled by default but can be activated using the `test-database` profile:
```
mvn clean install -Ptest-database -Dtest=PostgreSQLDistTest
```
### Running tests from the IDE
You are also able to run tests from your IDE. For that, choose a test from the [tests/integration](tests/integration) module
and execute it accordingly.
### Running tests from the `base` testsuite
Sometimes you might want to run the tests from the `base` test suite using the distribution. For that, make sure you have built the `quarkus` module
and then execute the following command from the project root directory:
```
mvn -f testsuite/integration-arquillian/pom.xml clean install -Pauth-server-quarkus -Dtest=OIDCProtocolMappersTest
```
### Resolving DNS names when running tests
In order to avoid using external services for DNS resolution, the tests are executed using a local host file by setting the `-Djdk.net.hosts.file=${project.build.testOutputDirectory}/hosts_file` system property.
## Documentation
The documentation is a set of guides available from the [docs](../docs/guides/src/main/server) module. Please,
look at the this [guide](../docs/building.md) about how to update and build the distribution guides.
## Before contributing the changes
Before contributing changes, make to read the main [Keycloak Contributing Guide](https://github.com/keycloak/keycloak/blob/main/CONTRIBUTING.md).
Please, make sure:
* Documentation is updated if you are introducing any new behavior or changing an existing one that needs to be communicated
* Make sure you have a test within the [tests/integration](tests/integration) module to cover the changes
* You probably want to run a full build of the `quarkus` module, including running tests, to make sure you won't be surprised by failures in CI.
## Upgrading Quarkus Version
Upgrading Quarkus requires a few steps:
* Change the Quarkus version
* Change the dependencies we are using from Quarkus
* Run a build to make sure the server extension is not broken
The steps still require a lot of manual work, and we should be improving this.
### Changing the Quarkus version
To change the Quarkus version, you can run the following script:
```bash
./set-quarkus-version.sh <version>
```
The `set-quarkus-version.sh` script is enough to change the version for all dependencies we are
using from Quarkus.
The `<version>` should point to a branch or a tag from Quarkus repository.
It is also possible to change to a snapshot version by running:
```bash
./set-quarkus-version.sh
```
After setting the version, please verify that:
* `org.apache.maven` dependencies used by the test suite (and arquillian) are the same from the new Quarkus version
### Run a local build
After changing the dependency versions, you can run a local build to make sure the server extension is not broken by API changes and if
all tests are passing:
```
mvn clean install
```
### Changing versions of JDBC Extensions
It might happen that when upgrading a version for any of the JDBC extensions (e.g.: `quarkus-jdbc-postgresql`) you also need to make sure the server extension is using the same JDBC Drivers.
For that, you should look at the `deployment` module of the corresponding JDBC extension from Quarkus (e.g.: https://github.com/quarkusio/quarkus/blob/main/extensions/jdbc/jdbc-postgresql/deployment/src/main/java/io/quarkus/jdbc/postgresql/deployment/JDBCPostgreSQLProcessor.java) to check if they match with the drivers used by the server extension by looking at the `org.keycloak.config.database.Database` class.
### Changing versions of Quarkiverse dependencies
Make sure the Quarkiverse dependencies are also updated and in sync with the Quarkus version you are upgrading.
For now, we only have this Quarkiverse dependency:
* https://github.com/quarkiverse/quarkus-vault
### What can go wrong when upgrading?
The perfect scenario is that after performing all the steps above the server extension will compile, the distribution can be built,
and all tests will pass.
However, it is expected breaking changes between Quarkus upgrades that break the integration code we have in both [deployment](deployment) and [runtime](runtime) modules. When this happens,
you should understand what is breaking and upgrade the integration code accordingly.
## References
* [Configuration Guide](https://www.keycloak.org/server/configuration)
* [Re-augmentation](https://quarkus.io/guides/reaugmentation)
* [Command Mode Application](https://quarkus.io/guides/command-mode-reference)

View file

@ -8,6 +8,9 @@ and prerequisites](https://github.com/keycloak/keycloak/blob/main/docs/building.
This module holds the codebase to run Keycloak on top of [Quarkus](https://quarkus.io/):
```
├── config-api
│   ├── Configuration API for modules to avoid direct Quarkus coupling (e.g. for REST services module)
├── container
│   ├── Dockerfile, e.g. used by the Testsuite
@ -15,7 +18,7 @@ This module holds the codebase to run Keycloak on top of [Quarkus](https://quark
│   ├── Build-time codebase with all the necessary steps to build and configure the server
├── dist
│   ├── Packaging the quarkus distribution
│   ├── Packaging the Quarkus distribution
├── runtime
│   ├── Runtime codebase with all the runtime code
@ -24,9 +27,85 @@ This module holds the codebase to run Keycloak on top of [Quarkus](https://quark
│   ├── The server itself, only responsible for generating the server artifacts
└── tests
├── Integration tests for the quarkus distribution
├── Integration tests for the Quarkus distribution
```
### Keycloak Quarkus Extension
Keycloak on Quarkus is basically a Quarkus Extension. For more details about extensions, please take a look at [Writing Your Own Extension](https://quarkus.io/guides/writing-extensions) guide.
As an extension, the server can be embedded in any Quarkus application by adding the following dependency:
```
<dependencies>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-quarkus-server</artifactId>
</dependency>
</dependencies>
```
Just like any other extension, the server extension has two main modules:
* `deployment`
* `runtime`
Within the `deployment` module you'll find the implementation for the build steps that run when (re)augmenting the application. This module
is responsible for all metadata processing, such as:
* Lookup SPIs and their providers and enable/disable them accordingly
* Create a closed-world assumption about the providers that should be registered to the `KeycloakSessionFactory`
* Customizations to how Hibernate, Quarkus REST, Liquibase, Infinispan, and other dependencies are configured and bootstrapped
* Creating Jandex indexes for some server dependencies
The output of this module is bytecode generated by Quarkus that improves the server startup time and memory usage so that any processing
done during (re)augmentation does not happen again when actually starting the server. Note that the code from this module does
not run at all at runtime (when running the server) but only when building the project (the `server` module in particular, more on that later) or when triggering
a re-augmentation when running the `build` command.
Within the `runtime` module you'll find the code that is run at runtime when starting and running the server. The main link between
the `deployment` and `runtime` modules is the `org.keycloak.quarkus.runtime.KeycloakRecorder` class. The `KeycloakRecorder` holds
a set of methods that are invoked from build steps that will end up in recorded bytecode. The recorded bytecode executes those methods at runtime
just like they were called when a build step was run, with the exact same arguments and values, if any.
As an example, let us look at how the SPIs and their providers are discovered and how the `KeycloakSessionFactory` is created.
Quarkus will run the `org.keycloak.quarkus.deployment.KeycloakProcessor.configSessionFactory` build step whenever you are (re)augmenting the server. The main outcome from this method
is to invoke the `org.keycloak.quarkus.runtime.KeycloakRecorder.configSessionFactory` so that the code from this method is executed at
*runtime* with a closed-world assumption about the providers that should be registered to the `KeycloakSessionFactory`. At runtime the code from that method is executed
and a `KeycloakSessionFactory` is created without any processing to discover SPIs and their providers.
There are a few reasons why we have Keycloak as a Quarkus extension:
* More control over the build-time augmentation and runtime stages.
* More flexibility when extending Quarkus itself and the extensions used by the server (e.g.: Hibernate, Quarkus REST, etc.)
* Make it easier to embed the server into Quarkus applications
* Make it possible to allow Keycloak developers to customize the server distribution
### Keycloak Server
The `server` module holds the Keycloak Server itself. It is basically a regular Quarkus application using the `keycloak-quarkus-server` extension. If you look at the
[pom.xml](server/pom.xml) from this module you'll notice that it is a very simple Quarkus application with the bare minimum configuration
to actually build and run the server.
As Quarkus application, the server is a [mutable](https://quarkus.io/guides/reaugmentation#how-to-re-augment-a-quarkus-application) application using the
[mutable-jar](server/src/main/resources/application.properties) package type. As a mutable application, Keycloak is able to allow
users to configure some aspects of the server without having to re-build this module, something impractical from a user perspective.
The mutability of the server is directly related to the `build` command. As mentioned before, the build steps from the `deployment` module
are only run when (re)augmenting the server and when running the `build` command, the server will indicate to Quarkus that the build steps
should re-run and the recorded bytecode should be updated to reflect any change to the server configuration.
From a Quarkus perspective, the server is also a [Command Mode Application](https://quarkus.io/guides/command-mode-reference) and provides
a CLI based on [Picocli](https://picocli.info/). As such, there is a single entrypoint that executes the code to execute the CLI and bootstrap the server. This entry point
is the `org.keycloak.quarkus.runtime.KeycloakMain` class from the `runtime` module.
### Keycloak Distribution
The server distribution is created by build the `dist` module. This module basically consists of packaging the `deployment`, `runtime`,
and `server` modules artifacts and their dependencies to a `ZIP` or tarball file.
Within this directory you'll find the directory structure of the distribution and what is included in it.
## Prerequisites
Before using this module, make sure you have a compatible JDK installed. (See [main build instructions](https://github.com/keycloak/keycloak/blob/main/docs/building.md)). Your shell is located at the `quarkus` submodule:
@ -34,9 +113,6 @@ Before using this module, make sure you have a compatible JDK installed. (See [m
* `KEYCLOAK_HOME` is the directory where you cloned the Keycloak repository.
### Activating the Module from the root directory
When a build from the project root directory is started, this module is only enabled if your installed JDK is 11 or newer.
## Building the project the first time
To build this module and produce the artifacts to run a server, you first need to build the main codebase once. This step will put required modules of keycloak into your local maven cache in package `org.keycloak`:
@ -47,11 +123,11 @@ This build can take some time, usually around two to four minutes depending on y
## Building the Keycloak Quarkus distribution
After the main codebase is built, you can build the quarkus distribution, including the zip and tar.gz files, by invoking the following command:
After the main codebase is built, you can build the Quarkus distribution, including the zip and tar.gz files, by invoking the following command:
<KEYCLOAK_HOME>/quarkus $ ../mvnw clean install -DskipTests
This command produces the distribution artifacts as ZIP and TAR file. The artifacts for the quarkus distribution will be available at the `/dist/target` subdirectory afterwards.
This command produces the distribution artifacts as ZIP and TAR file. The artifacts for the Quarkus distribution will be available at the `/dist/target` subdirectory afterwards.
As an alternative, you can build the distribution artifacts directly without a rebuild of the code by running the following command:
@ -81,6 +157,7 @@ To run the server in Quarkus' development mode, invoke the following command:
<KEYCLOAK_HOME>/quarkus $ ../mvnw -f server/pom.xml compile quarkus:dev -Dkc.config.built=true -Dquarkus.args="start-dev"
You will be able to attach your debugger to port `5005`.
You can set any command or configuration option to the server by setting the `quarkus.args` environment variable.
For debugging the build steps right after start, you can suspend the JVM by running:
@ -90,40 +167,94 @@ For debugging the build steps right after start, you can suspend the JVM by runn
When running using `quarkus:dev` you are able to do live coding whenever you change / add code in the `server` module, for example when creating a new custom provider.
There are currently limitations when running in development mode that block us to use all capabilities the Quarkus development mode has to offer. For instance, hot-reload of transient dependencies from keycloak (e.g.: keycloak-* dependencies) do not work. Expect more improvements in this area, and feel free to reach out if you want to help, using our [discussions](https://github.com/keycloak/keycloak/discussions/categories/keycloak-x-quarkus-distribution) or the development mailing list.
There are currently limitations when running in development mode that block us to use all capabilities the Quarkus development mode has to offer.
The main limitations you'll find at the moment are:
* Changes are only automatically reflected at runtime if you are changing resources from the `deployment`, `runtime`, and `server` modules. Other modules, such as `keycloak-services` still rely on Hot Swap in Java debuggers to reload classes.
* There is nothing in the Dev UI related to the server itself, although you can still change some configuration from there.
* There are some limitations when passing some options when running in dev mode. You should expect more improvements in this area.
### Debugging the server distribution
The `kc.sh|bat` script allows you to remotely debug the distribution. For that, you should run the server as follows:
```
kc.sh --debug start-dev
```
By default, the debug port is available at `8787` on localhost. Additionally, you can specify IPv4 or bracketed IPv6 addresses with optional ports, e.g. `--debug 127.0.0.1:8786`, `--debug [::1]:8785`. Make sure to exercise caution when setting IP addresses in the `--debug` parameter, since a value such as `--debug 0.0.0.0:8787` will expose the debug port to all network interfaces!
An additional environment variable `DEBUG_SUSPEND` can be set to suspend the JVM, when launched in debug mode. The `DEBUG_SUSPEND` variable supports the following values:
* `y` - The debug mode JVM launch is suspended
* `n` - The debug mode JVM is started without suspending
Suspending the JVM when in debug mode is useful if you want to debug the early stages of the bootstrap code.
When making changes to the `deployment`, `runtime`, or `server` modules, you can update the distribution with the new artifacts by executing
the following command:
```
mvn -DskipTests clean install
```
After the `quarkus` module and sub-modules are built, you can update the distribution as follows:
```
cp -r server/target/lib ${KC_HOME_DIR}
```
In the example above, the `${KC_HOME_DIR}` variable points to the root directory of the distribution.
You should also be able to update a server dependency directly. For that, copy the jar to the following location:
```
cp services/target/keycloak-services-${KC_VERSION}.jar ${KC_HOME_DIR}/lib/lib/main/org.keycloak.keycloak-services-${KC_VERSION}.jar
```
## Documentation
The documentation is a set of guides available from the [docs](../docs/guides/server) module.
Please, look at the [guide](../docs/building.md) about how to update and build the distribution guides.
## Contributing
Please make sure to read our [Contribution Guidelines](../CONTRIBUTING.md) before contributing.
Before contributing changes, make sure to read the main [Keycloak Contributing Guide](https://github.com/keycloak/keycloak/blob/main/CONTRIBUTING.md).
Please, make sure:
* Documentation is updated if you are introducing any new behavior or changing an existing one that needs to be communicated
* Make sure you have a test within the [tests/integration](tests/integration) module to cover the changes
* You probably want to run a full build of the `quarkus` module, including running tests, to make sure you won't be surprised by failures in CI.
## Running tests
Keycloaks Quarkus distribution module uses a new testsuite more integrated into the quarkus platform.
Keycloak Quarkus distribution module uses a new testsuite more integrated into the Quarkus platform.
### Running tests from your IDE
The tests can also be run from an IDE GUI such as Intellij IDEA. There are different kinds of tests:
* Unit tests: Located in the respective module (`deployment`, `runtime`)
* Integration tests:
* `@CLITest` annotated: These tests have no prerequisites and are whitebox tests, so you can easily debug them.
* `@DistributionTest` annotated: These tests need a build of the distribution artifacts first to run. These are blackbox tests, so not as easily debuggable as `@CLITest` annotated tests. Mostly used for scenarios when a `build` is involved or build options need to change, as this invocation happens in a different JVM.
* `@DistributionTest` annotated: These tests need a build of the distribution artifacts first to run. These are blackbox tests, so not as easily debuggable as `@CLITest` annotated tests. Mostly used for scenarios when a `build` is involved or build options need to change, as this invocation may happen in a different JVM.
### Running container-based tests
The `@DistributionTest` annotated tests can use different runtimes, e.g. plain JVM or a docker container. Per default, they use the plain JVM mode.
The `@DistributionTest` annotated tests can use different runtimes, e.g. plain JVM or a Docker container. Per default, they use the plain JVM mode.
To run them from a container image instead, you need to build the distribution first. Then you can use the flag `-Dkc.quarkus.tests.dist=docker`. This builds a docker image from the provided distribution archives and runs the `@DistributionTest` annotated tests for them.
To run them from a container image instead, you need to build the distribution first. Then you can use the flag `-Dkc.quarkus.tests.dist=docker`. This builds a Docker image from the provided distribution archives and runs the `@DistributionTest` annotated tests for them.
There are some tests annotated `@RawDistOnly` which prevents them from running in docker. You'll find a short reason in the respective annotation.
The container based tests are using Testcontainers to spin up the container image and can be considered tech preview.
There are some tests annotated `@RawDistOnly` which prevents them from running in Docker. You'll find a short reason in the respective annotation.
### Running database tests
There are also some container based tests to check if Keycloak starts using one of the supported database vendors. They are annotated with `@WithDatabase`.
These tests are disabled by default. They using Quarkus development mode predefined database containers by default and can be run in the `tests` subdirectory by using e.g.
The storage tests are disabled by default but can be activated using the `test-database` profile.
They're using Quarkus development mode predefined database containers by default and can be run in the `tests` subdirectory by using e.g.
<KEYCLOAK_HOME>/quarkus $ ../mvnw clean install -Ptest-database -Dtest=MariaDBDistTest
to spin up a MariaDB container and start Keycloak with it.
To use a specific database container image, use the option `-Dkc.db.postgresql.container.image` to specify the image tag of the postgres image to use or `-Dkc.db.mariadb.container.image=<name:tag>` for mariadb.
To use a specific database container image, use the option `-Dkc.db.postgresql.container.image` to specify the image tag of the Postgres image to use or `-Dkc.db.mariadb.container.image=<name:tag>` for MariaDB.
Example:
@ -131,8 +262,83 @@ Example:
### Updating Expectations
Changing to the help output will cause HelpCommandDistTest to fail. This test uses [ApprovalTests](https://github.com/approvals/ApprovalTests.Java) which creates `.received.txt` files containing the actual output when tests fail. To update the expected output (see [Approving The Result](https://github.com/approvals/ApprovalTests.Java/blob/master/approvaltests/docs/tutorials/GettingStarted.md#approving-the-result)) run:
Changing to the help output will cause `HelpCommandDistTest` to fail. This test uses [ApprovalTests](https://github.com/approvals/ApprovalTests.Java) which creates `.received.txt` files containing the actual output when tests fail. To update the expected output (see [Approving The Result](https://github.com/approvals/ApprovalTests.Java/blob/master/approvaltests/docs/tutorials/GettingStarted.md#approving-the-result)) run:
KEYCLOAK_REPLACE_EXPECTED=true ../mvnw clean install -Dtest=HelpCommandDistTest
KEYCLOAK_REPLACE_EXPECTED=true ../mvnw clean install -Dtest=HelpCommandDistTest
then use a diff to ensure the changes look good.
### Running tests from the `base` testsuite
Sometimes you might want to run the tests from the `base` test suite using the distribution. For that, make sure you have built the `quarkus` module
and then execute the following command from the project root directory:
```
mvn -f testsuite/integration-arquillian/pom.xml clean install -Pauth-server-quarkus -Dtest=OIDCProtocolMappersTest
```
### Resolving DNS names when running tests
In order to avoid using external services for DNS resolution, the tests are executed using a local host file by setting the `-Djdk.net.hosts.file=${project.build.testOutputDirectory}/hosts_file` system property.
## Upgrading Quarkus Version
Upgrading Quarkus requires a few steps:
* Change the Quarkus version
* Change the dependencies we are using from Quarkus
* Run a build to make sure the server extension is not broken
The steps still require a lot of manual work, and we should be improving this.
### Changing the Quarkus version
To change the Quarkus version, you can run the following script:
```bash
./set-quarkus-version.sh <version>
```
The `set-quarkus-version.sh` script is enough to change the version for all dependencies we are
using from Quarkus.
The `<version>` should point to a branch or a tag from Quarkus repository.
It is also possible to change to a snapshot version by running:
```bash
./set-quarkus-version.sh
```
After setting the version, please verify that:
* `org.apache.maven` dependencies used by the test suite (and arquillian) are the same from the new Quarkus version
### Run a local build
After changing the dependency versions, you can run a local build to make sure the server extension is not broken by API changes and if
all tests are passing:
```
mvn clean install
```
### Changing versions of JDBC Extensions
It might happen that when upgrading a version for any of the JDBC extensions (e.g.: `quarkus-jdbc-postgresql`) you also need to make sure the server extension is using the same JDBC Drivers.
For that, you should look at the `deployment` module of the corresponding JDBC extension from Quarkus (e.g.: https://github.com/quarkusio/quarkus/blob/main/extensions/jdbc/jdbc-postgresql/deployment/src/main/java/io/quarkus/jdbc/postgresql/deployment/JDBCPostgreSQLProcessor.java) to check if they match with the drivers used by the server extension by looking at the `org.keycloak.config.database.Database` class.
### What can go wrong when upgrading?
The perfect scenario is that after performing all the steps above the server extension will compile, the distribution can be built,
and all tests will pass.
However, it is expected breaking changes between Quarkus upgrades that break the integration code we have in both [deployment](deployment) and [runtime](runtime) modules. When this happens,
you should understand what is breaking and upgrade the integration code accordingly.
## References
* [Configuration Guide](https://www.keycloak.org/server/configuration)
* [Re-augmentation](https://quarkus.io/guides/reaugmentation)
* [Command Mode Application](https://quarkus.io/guides/command-mode-reference)