Developer Reference
Events
Listening to events
To listen to an event, you need to create a method with one of the event annotations:
class CreateComment {
void onOpen(@Issue.Opened GHEventPayload.Issue issuePayload) throws IOException {
issuePayload.getIssue().comment("Hello from my GitHub App");
}
}
A few observations:
-
The method may either be package-protected or public.
-
Most of the GitHub API methods throw
IOException
s so your methods need to propagate it. We have some nice error handling. -
The payload type needs to be consistent with the event type.
A method may listen to several events as long as they share the same payload type:
class IssueListener {
void onOpenOrEdit(@Issue.Opened @Issue.Edited GHEventPayload.Issue issuePayload) {
// do something
}
}
Several methods can listen to the same event types but you cannot control the order of their execution. We use CDI events under the hood and the execution of event observer methods cannot be ordered. If you need ordering for several steps, use a single method to control the execution of these steps. They can be split in smaller private methods if need be.
Event types
Here are all the events currently supported, together with the type of the payload that will be injected.
GitHub Event Type | Events | Payload |
---|---|---|
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
|
|
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
If you want to access the low level JSON payload, you can use the raw GitHubEvent
, either by substituting it to the API payload:
class TriageIssue {
void triageIssue(@Issue.Opened GitHubEvent gitHubEvent) {
// do something
}
}
Or by adding it as an additional parameter:
class TriageIssue {
void triageIssue(@Issue.Opened GHEventPayload.Issue issuePayload, GitHubEvent gitHubEvent) {
// do something
}
}
The GitHubEvent
exposes the raw JSON either as a string (via GitHubEvent#getPayload()
) or as a Vert.x JsonObject
(via GitHubEvent#getParsedPayload()
),
together with some additional information like the installation id, the event or the action.
If you miss an event type, it is also possible to listen to events by using the @RawEvent
annotation.
The @RawEvent
annotation allows you to listen to all events/actions, and you may also specify the event and the action you want to listen to.
When using the @RawEvent
annotation, the only allowed payload parameter type is GitHubEvent
.
class ActOnDeploymentProtectionRule {
void onDeploymentProtectionRule(@RawEvent(event = "deployment_protection_rule", action = "requested") GitHubEvent gitHubEvent) {
// do something
}
}
Both event
and action
are optional and you can listen to all events by using the following code:
class CatchAll {
void catchAll(@RawEvent GitHubEvent gitHubEvent) {
// do something
}
}
If you miss an event type, please report it by creating an issue. We try to add to contribute to the Hub4j GitHub API all the event types that are useful. When missing an event type, there are two options:
|
Configuration file
For some usage, you might need to include a configuration file that is repository-specific and versioned.
The Quarkus GitHub App extension supports the following features:
-
Automatic injection of config files into your methods.
-
YAML, JSON or text config files.
-
Automatic deserialization of your YAML or JSON config files into Java POJOs using Jackson.
Injecting a configuration file in your method is as simple as:
class TriageIssue {
void triageIssue(@Issue.Opened GHEventPayload.Issue issuePayload,
@ConfigFile("quarkus-bot-java.yml") QuarkusBotConfigFile quarkusBotConfigFile) {
// do something
}
}
The configuration file .github/quarkus-bot-java.yml
present in the default branch of the repository
for which the event has been triggered
is parsed and deserialized to a QuarkusBotConfigFile
instance using Jackson.
If the file does not exist in the repository, quarkusBotConfigFile
will be null.
If you want to get the content of the configuration file as is, use a String
.
Note that @ConfigFile
injection supports using Optional<YourConfigType>
.
If your repository is private, reading configuration files requires your GitHub App to have the |
By default, the config file path is relative to the You can reference a file outside this directory by using an |
Error handler
The Quarkus GitHub App extension provides an error handler that will log errors with as many details as possible.
You can customize the error handler by creating a CDI bean implementing io.quarkiverse.githubapp.error.ErrorHandler
:
Some errors may be triggered before the payload has been parsed.
In this case, the |
Injecting a GitHub instance
When you need to access the authenticated GitHub
instance, for instance to call GitHub#getMyself()
,
simply inject it into your method:
class TriageIssue {
void triageIssue(@Issue.Opened GHEventPayload.Issue issuePayload, GitHub gitHub) {
gitHub.getMyself();
}
}
The injected GitHub
instance is authenticated as an installation.
Injecting a GraphQL client
For some purposes, using the GitHub GraphQL API might get handy (typically to access the Discussions API that is only available in the GraphQL API).
In the same way you can inject an authenticated GitHub
instance, you can inject an authenticated DynamicGraphQLClient
as follows:
class TriageIssue {
void triageIssue(@Issue.Opened GHEventPayload.Issue issuePayload, DynamicGraphQLClient gitHubGraphQLClient) {
// do something GraphQLy with gitHubGraphQLClient
}
}
The injected DynamicGraphQLClient
instance is authenticated as an installation.
Webhook events
While Quarkus GitHub App was primarily designed as a tool to develop GitHub Apps, it is also possible to use it to handle your webhook requests.
It will take care of all the ceremony of authenticating the requests and will save you a lot of boilerplate.
There are a few differences though:
-
You will have to use
@RawEvent
to listen to the events and get the raw JSON of the payload. -
Webhook requests don’t provide an installation id so we can’t initialize an installation GitHub client nor a GraphQL client.
The default GitHub
REST client instance that can be injected is an application client and has so few permissions that it is not really useful.
While it could be a major inconvenience, we present a nice feature dedicated to this use case in the following section.
Providing a personal access token
When using Quarkus GitHub App, in most cases, the REST and GraphQL clients provided by the installation are what you are looking for: they have the permissions allowed for this GitHub App and it should be enough to do what your GitHub App has been designed for.
However, there are corner cases where you might need a client with additional permissions, the most common one is when you deal with webhooks as presented in the previous section.
For this situation, you can define a personal access token by using the quarkus.github-app.personal-access-token
configuration property.
The personal access token provided in this property will be used to initialize:
-
an authenticated
GitHub
REST client -
an authenticated
DynamicGraphQL
GraphQL client
These clients will be automatically injected in your methods when injecting clients if the payload doesn’t provide an installation id (if it does provide one, the regular installation clients will be injected).
It is also possible to directly obtain the clients authenticated with the personal access token by injecting the TokenGitHubClients
CDI bean.
It provides methods to get the authenticated REST and GraphQL clients.
Credentials provider
Quarkus GitHub App supports the usage of a CredentialsProvider
to provide some of the configuration properties
that you might not want to appear in a configuration file.
You can find all the information you need about CredentialsProvider
s in the dedicated guide.
The basic principle is that you provide a CDI bean that will implement the CredentialsProvider
and will provide the values for the supported configuration properties.
It can either be provided by the Vault extension if you are using HashiCorp Vault or you can provide you own custom CredentialsProvider
implementation.
Using a CredentialsProvider
is easy:
-
Make sure you have an implementation of
CredentialsProvider
and that it is a@Singleton
or@ApplicationScoped
CDI bean. -
Set the
quarkus.github-app.credentials-provider
to define the name of the credentials provider. See it as the name of a keyring containing your Quarkus GitHub App secrets. -
For the given name, your
CredentialsProvider
may return aMap
containing entries forgithubAppPrivateKey
and/orgithubAppWebhookSecret
. You can use the constants present inio.quarkiverse.githubapp.Credentials
for practicality.
That is all you need to do:
Quarkus GitHub App will then automatically use the values provided by the CredentialsProvider
for the private key and the webhook secret.
Customizing the GitHub clients
You can customize the GitHub clients initialized by Quarkus GitHub App
by creating a CDI bean implementing io.quarkiverse.githubapp.GitHubCustomizer
.
For instance:
@Singleton
public class MyGitHubCustomizer implements GitHubCustomizer {
@Override
public void customize(GitHubBuilder builder) {
// call methods of the builder
}
}
This will apply the customizations to both the application clients and the installation clients.
However, some customizations can’t be applied to the application clients such as configuring a rate limit checker.
You may customize the application clients differently by implementing customizeApplicationClient(GitHubBuilder)
:
@Singleton
public class MyGitHubCustomizer implements GitHubCustomizer {
@Override
public void customize(GitHubBuilder builder) { (1)
// call methods of the builder
}
@Override
public void customizeApplicationClient(GitHubBuilder builder) { (2)
// call methods of the builder
}
}
1 | Customize the installation clients. |
2 | Customize the application clients. |
About application and installation clients
A GitHub App relies on two types of GitHub clients:
|
Configuration Reference
The Quarkus GitHub App extension exposes the following configuration properties:
Configuration property fixed at build time - All other configuration properties are overridable at runtime
Type |
Default |
|
---|---|---|
The numeric application id provided by GitHub. Optional for tests, but mandatory in production and dev mode. Environment variable: |
string |
|
The GitHub name of the application. Optional, only used for improving the user experience. Environment variable: |
string |
|
Read the configuration files from the source repository in case of a fork. Environment variable: |
boolean |
|
The RSA private key. Optional for tests, but mandatory in production and dev mode. Environment variable: |
||
The webhook URL path on which the GitHub App route is mounted. It defaults to the root Environment variable: |
|
|
The webhook secret if defined in the GitHub UI. Environment variable: |
string |
|
The credentials provider name. This is the name of the "keyring" containing the GitHub App secrets. Key names are defined in Environment variable: |
string |
|
The credentials provider bean name. This is a bean name (as in For Vault, the credentials provider bean name is Environment variable: |
string |
|
The Smee.io proxy URL used when testing locally. Environment variable: |
string |
|
The GitHub instance endpoint. Defaults to the public github.com instance. Environment variable: |
||
The REST API endpoint. Defaults to the public github.com instance REST API endpoint. Environment variable: |
|
|
The GraphQL API endpoint. Defaults to the public github.com instance GraphQL endpoint. Environment variable: |
|
|
A personal access token for use with For standard use cases, you will use the installation client which comes with the installation permissions. It can be injected directly in your method. However, if your payload comes from a webhook and doesn’t have an installation id, it’s handy to be able to use a client authenticated with a personal access token as the application client permissions are very limited. This token will be used to authenticate the clients provided by Environment variable: |
string |
|
A directory in which the payloads are saved. Environment variable: |
path |