Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • eclipsefdn/it/api/git-eca-rest-api
  • zacharysabourin/git-eca-rest-api
  • fgurr/git-eca-rest-api
  • malowe/git-eca-rest-api
  • netomi/git-eca-rest-api
5 results
Show changes
Commits on Source (208)
Showing
with 582 additions and 685 deletions
...@@ -3,14 +3,14 @@ ...@@ -3,14 +3,14 @@
pipeline { pipeline {
agent { agent {
kubernetes { kubernetes {
label 'buildenv-agent' label 'buildenv-agent-eca'
yaml ''' yaml '''
apiVersion: v1 apiVersion: v1
kind: Pod kind: Pod
spec: spec:
containers: containers:
- name: buildcontainer - name: buildcontainer
image: eclipsefdn/stack-build-agent:h111.3-n18.16-jdk11 image: eclipsefdn/stack-build-agent:h111.3-n18.17-jdk17
imagePullPolicy: Always imagePullPolicy: Always
command: command:
- cat - cat
...@@ -51,6 +51,9 @@ ...@@ -51,6 +51,9 @@
- mountPath: "/home/jenkins/.sonar" - mountPath: "/home/jenkins/.sonar"
name: "sonar-cache" name: "sonar-cache"
readOnly: false readOnly: false
- mountPath: "/home/jenkins/.config"
name: "config-folder"
readOnly: false
- name: jnlp - name: jnlp
resources: resources:
requests: requests:
...@@ -74,6 +77,8 @@ ...@@ -74,6 +77,8 @@
emptyDir: {} emptyDir: {}
- name: sonar-cache - name: sonar-cache
emptyDir: {} emptyDir: {}
- name: config-folder
emptyDir: {}
''' '''
} }
} }
...@@ -100,6 +105,16 @@ ...@@ -100,6 +105,16 @@
""", """,
returnStdout: true returnStdout: true
) )
LATEST_TAG_NAME = sh(
script: """
if [ "${env.ENVIRONMENT}" = "staging" ]; then
printf latest-staging
else
printf latest
fi
""",
returnStdout: true
)
} }
options { options {
...@@ -107,22 +122,36 @@ ...@@ -107,22 +122,36 @@
timeout(time: 30, unit: 'MINUTES') timeout(time: 30, unit: 'MINUTES')
} }
triggers {
// build once a week to keep up with parents images updates
cron('H H * * H')
}
stages { stages {
stage('Build Java code') { stage('Build with Sonarcloud scan') {
when {
branch 'main'
}
steps { steps {
container('buildcontainer') { container('buildcontainer') {
readTrusted 'Makefile' readTrusted 'Makefile'
readTrusted 'pom.xml' readTrusted 'pom.xml'
sh 'make compile' sh 'make generate-spec'
withCredentials([string(credentialsId: 'sonarcloud-token-git-eca-rest-api', variable: 'SONAR_TOKEN')]) { withCredentials([string(credentialsId: 'sonarcloud-token-git-eca-rest-api', variable: 'SONAR_TOKEN')]) {
sh 'mvn clean verify -B org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.login=${SONAR_TOKEN} -Dmaven.test.skip=true' sh 'mvn clean verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -B -Dsonar.login=${SONAR_TOKEN}'
} }
stash name: "target", includes: "target/**/*" }
}
}
stage('Build without Sonarcloud scan') {
when {
not {
branch 'main'
}
}
steps {
container('buildcontainer') {
readTrusted 'pom.xml'
sh 'make compile-java'
// only no-scan builds can be deployed as we don't deploy main
stash includes: 'target/', name: 'target'
} }
} }
} }
...@@ -131,12 +160,18 @@ ...@@ -131,12 +160,18 @@
agent { agent {
label 'docker-build' label 'docker-build'
} }
when {
anyOf {
environment name: 'ENVIRONMENT', value: 'production'
environment name: 'ENVIRONMENT', value: 'staging'
}
}
steps { steps {
readTrusted 'src/main/docker/Dockerfile.jvm' readTrusted 'src/main/docker/Dockerfile.jvm'
unstash 'target' unstash 'target'
sh 'docker build -f src/main/docker/Dockerfile.jvm --no-cache -t ${IMAGE_NAME}:${TAG_NAME} -t ${IMAGE_NAME}:latest .' sh 'docker build -f src/main/docker/Dockerfile.jvm --no-cache -t ${IMAGE_NAME}:${TAG_NAME} -t ${IMAGE_NAME}:${LATEST_TAG_NAME} .'
} }
} }
...@@ -154,7 +189,7 @@ ...@@ -154,7 +189,7 @@
withDockerRegistry([credentialsId: '04264967-fea0-40c2-bf60-09af5aeba60f', url: 'https://index.docker.io/v1/']) { withDockerRegistry([credentialsId: '04264967-fea0-40c2-bf60-09af5aeba60f', url: 'https://index.docker.io/v1/']) {
sh ''' sh '''
docker push ${IMAGE_NAME}:${TAG_NAME} docker push ${IMAGE_NAME}:${TAG_NAME}
docker push ${IMAGE_NAME}:latest docker push ${IMAGE_NAME}:${LATEST_TAG_NAME}
''' '''
} }
} }
......
...@@ -17,12 +17,14 @@ generate-spec: validate-spec; ...@@ -17,12 +17,14 @@ generate-spec: validate-spec;
yarn run generate-json-schema yarn run generate-json-schema
validate-spec: install-yarn; validate-spec: install-yarn;
compile-start: compile-quick start; compile-start: compile-quick start;
compile-start-full: compile-quick start-full;
## Docker/service binds - services soft split from application to enable dev-start easier ## Docker/service binds - services soft split from application to enable dev-start easier
start:; start:;
docker compose build docker compose build
docker compose up -d docker compose up -d
start-services: stop-services; start-services: stop-services;
docker compose up mariadb -d docker compose up mariadb -d
start-full: start start-opt;
start-opt: stop-opt; start-opt: stop-opt;
docker compose --profile optional-services up -d docker compose --profile optional-services up -d
stop: stop-application; stop: stop-application;
......
# git-eca-rest-api # git-eca-rest-api
--- ---
**NOTE** **NOTE**
This project was migrated to [Eclipse Gitlab](https://gitlab.eclipse.org/eclipsefdn/it/api/git-eca-rest-api) on October 14, 2021. This project was migrated to [Eclipse Gitlab](https://gitlab.eclipse.org/eclipsefdn/it/api/git-eca-rest-api) on October 14, 2021.
...@@ -30,7 +31,9 @@ If you want to learn more about Quarkus, please visit its website: https://quark ...@@ -30,7 +31,9 @@ If you want to learn more about Quarkus, please visit its website: https://quark
<!-- /TOC --> <!-- /TOC -->
## About validation ## About validation
### What is a valid commit? ### What is a valid commit?
To be considered a valid commit, the following set of rules are checked against all commits that are submitted to this service. If any fail and the commit is related to a project, the service returns a message indicating the commit is not suitable for submission along with messages as hints. To be considered a valid commit, the following set of rules are checked against all commits that are submitted to this service. If any fail and the commit is related to a project, the service returns a message indicating the commit is not suitable for submission along with messages as hints.
1. All users that commit or author changes within a project within the Eclipse space must have a signed [ECA](https://accounts.eclipse.org/user/eca), and therefore, Eclipse accounts. 1. All users that commit or author changes within a project within the Eclipse space must have a signed [ECA](https://accounts.eclipse.org/user/eca), and therefore, Eclipse accounts.
...@@ -74,15 +77,17 @@ Different operating system, different file paths! ...@@ -74,15 +77,17 @@ Different operating system, different file paths!
Windows: C:\Windows\System32\drivers\etc\hosts Windows: C:\Windows\System32\drivers\etc\hosts
Linux / MacOS: /etc/hosts Linux / MacOS: /etc/hosts
``` ```bash
127.0.0.1 api.eclipse.dev.docker 127.0.0.1 api.eclipse.dev.docker
127.0.0.1 gitlab.eclipse.dev.docker 127.0.0.1 gitlab.eclipse.dev.docker
``` ```
## Application setup and operation ## Application setup and operation
### Setting up the application for local use ### Setting up the application for local use
Pre-requisites: Pre-requisites:
- Make - Make
- Maven (apt install maven) - Maven (apt install maven)
- Java 11 > (apt install openjdk-11-jdk) - Java 11 > (apt install openjdk-11-jdk)
...@@ -92,15 +97,21 @@ Pre-requisites: ...@@ -92,15 +97,21 @@ Pre-requisites:
To build and start the server: To build and start the server:
``` ```bash
make compile-start make compile-start
``` ```
To build and start with a running Gitlab instance:
```bash
make compile-start-full
```
### Running the application in dev mode ### Running the application in dev mode
You can run your application in dev mode that enables live coding using: You can run your application in dev mode that enables live coding using:
``` ```bash
make dev-start make dev-start
``` ```
...@@ -113,6 +124,7 @@ Be aware that it’s not an _über-jar_ as the dependencies are copied into the ...@@ -113,6 +124,7 @@ Be aware that it’s not an _über-jar_ as the dependencies are copied into the
The application is now runnable using `java -jar target/git-eca-rest-api-0.0.1-runner.jar`. The application is now runnable using `java -jar target/git-eca-rest-api-0.0.1-runner.jar`.
## Private Project Reports ## Private Project Reports
### Usage ### Usage
The private project reports are accessed through `/git/reports/gitlab/private-projects` and can be filtered using various parameters. The private project reports are accessed through `/git/reports/gitlab/private-projects` and can be filtered using various parameters.
......
eclipse.internal-host=localhost eclipse.internal-host=localhost
## Required for authenticated requests to profile API (api.eclipse.org: git.eclipse.org/r/ (dev-git-eca-rest-api))) ## Required for authenticated requests to profile API (api.eclipse.org: git.eclipse.org/r/ (dev-git-eca-rest-api)))
## Ask webdev@eclipse-foundation.org if you think you should have access to this client. ## Ask webdev@eclipse-foundation.org if you think you should have access to this client.
oauth2.client-id= eclipse.security.oauth2.token-generation.client-id=
oauth2.client-secret= eclipse.security.oauth2.token-generation.client-secret=
## mariadb username and password ## mariadb username and password
quarkus.datasource.username= quarkus.datasource.username=
...@@ -10,4 +10,10 @@ quarkus.datasource.password= ...@@ -10,4 +10,10 @@ quarkus.datasource.password=
## database connection ## database connection
quarkus.datasource.jdbc.url=jdbc:mariadb://mariadb/dev_eclipse_eca quarkus.datasource.jdbc.url=jdbc:mariadb://mariadb/dev_eclipse_eca
%dev.quarkus.datasource.jdbc.url=jdbc:mariadb://${eclipse.internal-host}:10101/dev_eclipse_eca %dev.quarkus.datasource.jdbc.url=jdbc:mariadb://${eclipse.internal-host}:10101/dev_eclipse_eca
\ No newline at end of file
eclipse.gitlab.access-token=
## Used to send mail through the EclipseFdn smtp connection
quarkus.mailer.password=YOURGENERATEDAPPLICATIONPASSWORD
quarkus.mailer.username=YOUREMAIL@gmail.com
\ No newline at end of file
CREATE DATABASE IF NOT EXISTS dev_eclipse_eca;
USE dev_eclipse_eca;
CREATE TABLE IF NOT EXISTS `CommitValidationMessage` ( CREATE TABLE IF NOT EXISTS `CommitValidationMessage` (
`id` SERIAL, `id` SERIAL,
`commit_id` bigint(20) NOT NULL, `commit_id` bigint(20) NOT NULL,
...@@ -12,11 +15,13 @@ CREATE TABLE IF NOT EXISTS `CommitValidationMessage` ( ...@@ -12,11 +15,13 @@ CREATE TABLE IF NOT EXISTS `CommitValidationMessage` (
CREATE TABLE IF NOT EXISTS `CommitValidationStatus` ( CREATE TABLE IF NOT EXISTS `CommitValidationStatus` (
`id` SERIAL, `id` SERIAL,
`commitHash` varchar(100) NOT NULL, `commitHash` varchar(100) NOT NULL,
`userMail` varchar(100) NOT NULL,
`project` varchar(100) NOT NULL, `project` varchar(100) NOT NULL,
`lastModified` datetime DEFAULT NULL, `lastModified` datetime DEFAULT NULL,
`creationDate` datetime DEFAULT NULL, `creationDate` datetime DEFAULT NULL,
`provider` varchar(100) NOT NULL, `provider` varchar(100) NOT NULL,
`repoUrl` varchar(255) DEFAULT NULL, `repoUrl` varchar(255) DEFAULT NULL,
`entimatedLoc` int(11) DEFAULT NULL,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
); );
...@@ -47,5 +52,18 @@ CREATE TABLE GithubWebhookTracking ( ...@@ -47,5 +52,18 @@ CREATE TABLE GithubWebhookTracking (
repositoryFullName varchar(127) NOT NULL, repositoryFullName varchar(127) NOT NULL,
pullRequestNumber int NOT NULL, pullRequestNumber int NOT NULL,
lastUpdated datetime DEFAULT NULL, lastUpdated datetime DEFAULT NULL,
needsRevalidation tinyint(1) DEFAULT 0,
manualRevalidationCount int DEFAULT 0,
PRIMARY KEY (id) PRIMARY KEY (id)
); );
\ No newline at end of file
-- eclipse_eca.GithubApplicationInstallation definition
CREATE TABLE `GithubApplicationInstallation` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`appId` int(11) NOT NULL,
`installationId` int(11) NOT NULL,
`name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
`lastUpdated` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=389 DEFAULT CHARSET=utf8;
\ No newline at end of file
...@@ -18,13 +18,13 @@ services: ...@@ -18,13 +18,13 @@ services:
max_attempts: 5 max_attempts: 5
resources: resources:
limits: limits:
cpus: '0.5' cpus: '1'
memory: 256M memory: 512M
reservations: reservations:
cpus: '0.001' cpus: '1'
memory: 192M memory: 512M
gitlab: gitlab:
image: 'gitlab/gitlab-ee:latest' image: 'gitlab/gitlab-ee:15.11.10-ee.0'
restart: always restart: always
hostname: 'gitlab.eclipse.dev.docker' hostname: 'gitlab.eclipse.dev.docker'
profiles: profiles:
......
<?xml version="1.0"?> <?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>org.eclipsefoundation</groupId> <groupId>org.eclipsefoundation</groupId>
<artifactId>git-eca</artifactId> <artifactId>git-eca</artifactId>
<version>1.1.0</version> <version>1.1.0</version>
<properties> <properties>
<eclipse-api-version>0.7.4</eclipse-api-version> <compiler-plugin.version>3.13.0</compiler-plugin.version>
<compiler-plugin.version>3.8.1</compiler-plugin.version> <maven.compiler.source>17</maven.compiler.source>
<maven.compiler.parameters>true</maven.compiler.parameters> <maven.compiler.target>17</maven.compiler.target>
<maven.compiler.source>11</maven.compiler.source> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.target>11</maven.compiler.target> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <quarkus.platform.group-id>io.quarkus.platform</quarkus.platform.group-id>
<quarkus.platform.artifact-id>quarkus-universe-bom</quarkus.platform.artifact-id> <quarkus.platform.version>3.15.4</quarkus.platform.version>
<quarkus.platform.group-id>io.quarkus</quarkus.platform.group-id> <surefire-plugin.version>3.3.1</surefire-plugin.version>
<quarkus.platform.version>2.14.2.Final</quarkus.platform.version> <maven.compiler.parameters>true</maven.compiler.parameters>
<surefire-plugin.version>2.22.1</surefire-plugin.version> <eclipse-api-version>1.2.3</eclipse-api-version>
<auto-value.version>1.8.2</auto-value.version> <auto-value.version>1.10.4</auto-value.version>
<org.mapstruct.version>1.4.1.Final</org.mapstruct.version> <org.mapstruct.version>1.5.5.Final</org.mapstruct.version>
<sonar.sources>src/main</sonar.sources> <sonar.sources>src/main</sonar.sources>
<sonar.tests>src/test</sonar.tests> <sonar.tests>src/test</sonar.tests>
<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin> <sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
<sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis> <sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
<sonar.coverage.jacoco.xmlReportPaths>${project.basedir}/target/jacoco-report/jacoco.xml</sonar.coverage.jacoco.xmlReportPaths> <sonar.coverage.jacoco.xmlReportPaths>${project.basedir}/target/jacoco-report/jacoco.xml</sonar.coverage.jacoco.xmlReportPaths>
<sonar.junit.reportPath>${project.build.directory}/surefire-reports</sonar.junit.reportPath> <sonar.junit.reportPath>${project.build.directory}/surefire-reports</sonar.junit.reportPath>
<sonar.host.url>https://sonarcloud.io</sonar.host.url> <sonar.host.url>https://sonarcloud.io</sonar.host.url>
<sonar.organization>eclipse-foundation-it</sonar.organization> <sonar.organization>eclipse-foundation-it</sonar.organization>
<sonar.projectKey>eclipse-foundation-it_git-eca-rest-api</sonar.projectKey> <sonar.projectKey>git-eca-rest-api</sonar.projectKey>
</properties> <sonar.projectName>Git ECA REST API</sonar.projectName>
<repositories> </properties>
<repository> <repositories>
<id>eclipsefdn</id> <repository>
<url>https://repo.eclipse.org/content/repositories/eclipsefdn/</url> <id>eclipsefdn</id>
<releases> <url>https://repo.eclipse.org/content/repositories/eclipsefdn/</url>
<enabled>true</enabled> <releases>
</releases> </releases>
<snapshots> <snapshots>
<enabled>true</enabled> </snapshots>
</snapshots> </repository>
</repository> </repositories>
</repositories> <dependencyManagement>
<dependencyManagement> <dependencies>
<dependency>
<groupId>${quarkus.platform.group-id}</groupId>
<artifactId>${quarkus.platform.artifact-id}</artifactId>
<version>${quarkus.platform.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>${quarkus.platform.group-id}</groupId> <groupId>org.eclipsefoundation</groupId>
<artifactId>${quarkus.platform.artifact-id}</artifactId> <artifactId>quarkus-core</artifactId>
<version>${quarkus.platform.version}</version> <version>${eclipse-api-version}</version>
<type>pom</type> </dependency>
<scope>import</scope> <dependency>
</dependency> <groupId>org.eclipsefoundation</groupId>
</dependencies> <artifactId>quarkus-persistence</artifactId>
</dependencyManagement> <version>${eclipse-api-version}</version>
<dependencies> </dependency>
<dependency> <dependency>
<groupId>org.eclipsefoundation</groupId> <groupId>org.eclipsefoundation</groupId>
<artifactId>quarkus-core</artifactId> <artifactId>quarkus-efservices</artifactId>
<version>${eclipse-api-version}</version> <version>${eclipse-api-version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.eclipsefoundation</groupId> <groupId>io.quarkus</groupId>
<artifactId>quarkus-persistence</artifactId> <artifactId>quarkus-smallrye-context-propagation</artifactId>
<version>${eclipse-api-version}</version> </dependency>
</dependency> <dependency>
<dependency> <groupId>io.quarkus</groupId>
<groupId>io.quarkus</groupId> <artifactId>quarkus-smallrye-jwt</artifactId>
<artifactId>quarkus-resteasy</artifactId> </dependency>
</dependency> <dependency>
<dependency> <groupId>io.quarkus</groupId>
<groupId>io.quarkus</groupId> <artifactId>quarkus-mailer</artifactId>
<artifactId>quarkus-resteasy-jackson</artifactId> </dependency>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-context-propagation</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-jwt</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.bouncycastle/bcpkix-jdk15on -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>1.70</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-rest-client</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-qute</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-scheduler</artifactId>
</dependency>
<!-- Annotation preprocessors - reduce all of the boiler plate -->
<dependency>
<groupId>com.google.auto.value</groupId>
<artifactId>auto-value</artifactId>
<version>${auto-value.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.auto.value</groupId>
<artifactId>auto-value-annotations</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
<scope>provided</scope>
</dependency>
<!-- Third-party reqs --> <!-- Annotation preprocessors - reduce all of the boiler plate -->
<dependency> <dependency>
<groupId>com.github.scribejava</groupId> <groupId>com.google.auto.value</groupId>
<artifactId>scribejava-apis</artifactId> <artifactId>auto-value</artifactId>
<version>6.4.1</version> <version>${auto-value.version}</version>
</dependency> <scope>provided</scope>
<!-- Caching --> </dependency>
<dependency> <dependency>
<groupId>com.google.guava</groupId> <groupId>org.mapstruct</groupId>
<artifactId>guava</artifactId> <artifactId>mapstruct</artifactId>
</dependency> <version>${org.mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
<scope>provided</scope>
</dependency>
<!-- Test requirements --> <!-- Test requirements -->
<dependency> <dependency>
<groupId>io.quarkus</groupId> <groupId>org.eclipsefoundation</groupId>
<artifactId>quarkus-junit5</artifactId> <artifactId>quarkus-test-common</artifactId>
<scope>test</scope> <version>${eclipse-api-version}</version>
</dependency> <scope>test</scope>
<dependency> </dependency>
<groupId>io.rest-assured</groupId> <dependency>
<artifactId>rest-assured</artifactId> <groupId>io.quarkus</groupId>
<scope>test</scope> <artifactId>quarkus-jacoco</artifactId>
</dependency> <scope>test</scope>
<dependency> </dependency>
<groupId>io.rest-assured</groupId>
<artifactId>json-schema-validator</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5-mockito</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipsefoundation</groupId>
<artifactId>quarkus-test-common</artifactId>
<version>${eclipse-api-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jacoco</artifactId>
<scope>test</scope>
</dependency>
<!-- Following H2/devservices deps are made to circumvent need for docker --> <!-- Following H2/devservices deps are made to circumvent need for
<dependency> docker -->
<groupId>io.quarkus</groupId> <dependency>
<artifactId>quarkus-devservices-h2</artifactId> <groupId>io.quarkus</groupId>
<scope>test</scope> <artifactId>quarkus-devservices-h2</artifactId>
</dependency> <scope>test</scope>
<dependency> </dependency>
<groupId>io.quarkus</groupId> <dependency>
<artifactId>quarkus-jdbc-h2</artifactId> <groupId>io.quarkus</groupId>
<scope>test</scope> <artifactId>quarkus-jdbc-h2</artifactId>
</dependency> <scope>test</scope>
<dependency> </dependency>
<groupId>com.h2database</groupId> <dependency>
<artifactId>h2</artifactId> <groupId>com.h2database</groupId>
<scope>test</scope> <artifactId>h2</artifactId>
</dependency> <scope>test</scope>
<!-- Flyway specific dependencies, used to setup tables in test --> </dependency>
<dependency> <!-- Flyway specific dependencies, used to setup tables in test -->
<groupId>io.quarkus</groupId> <dependency>
<artifactId>quarkus-flyway</artifactId> <groupId>io.quarkus</groupId>
<scope>test</scope> <artifactId>quarkus-flyway</artifactId>
</dependency> <scope>test</scope>
</dependencies> </dependency>
</dependencies>
<build> <build>
<plugins>
<plugin>
<groupId>${quarkus.platform.group-id}</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>${quarkus.platform.version}</version>
<extensions>true</extensions>
<executions>
<execution>
<goals>
<goal>build</goal>
<goal>generate-code</goal>
<goal>generate-code-tests</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${compiler-plugin.version}</version>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>com.google.auto.value</groupId>
<artifactId>auto-value</artifactId>
<version>${auto-value.version}</version>
</path>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<configuration>
<skipTests>false</skipTests>
<systemPropertyVariables>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
<maven.home>${maven.home}</maven.home>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>native</id>
<activation>
<property>
<name>native</name>
</property>
</activation>
<build>
<plugins> <plugins>
<plugin> <plugin>
<artifactId>maven-failsafe-plugin</artifactId> <groupId>${quarkus.platform.group-id}</groupId>
<version>${surefire-plugin.version}</version> <artifactId>quarkus-maven-plugin</artifactId>
<executions> <version>${quarkus.platform.version}</version>
<execution> <extensions>true</extensions>
<goals> <executions>
<goal>integration-test</goal> <execution>
<goal>verify</goal> <goals>
</goals> <goal>build</goal>
<goal>generate-code</goal>
<goal>generate-code-tests</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${compiler-plugin.version}</version>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>com.google.auto.value</groupId>
<artifactId>auto-value</artifactId>
<version>${auto-value.version}</version>
</path>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<configuration> <configuration>
<systemPropertyVariables> <skipTests>false</skipTests>
<native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path> <systemPropertyVariables>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager> <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
<maven.home>${maven.home}</maven.home> <maven.home>${maven.home}</maven.home>
</systemPropertyVariables> </systemPropertyVariables>
</configuration> </configuration>
</execution> </plugin>
</executions>
</plugin>
</plugins> </plugins>
</build> </build>
<properties>
<quarkus.package.type>native</quarkus.package.type>
</properties>
</profile>
</profiles>
</project> </project>
...@@ -2,6 +2,10 @@ openapi: "3.1.0" ...@@ -2,6 +2,10 @@ openapi: "3.1.0"
info: info:
version: 1.1.0 version: 1.1.0
title: Eclipse Foundation Git ECA API title: Eclipse Foundation Git ECA API
description: Collection of API endpoints used in the validation and management of external Git services, such as Gitlab and Github.
contact:
name: IT support
url: https://gitlab.eclipse.org/eclipsefdn/it/api/git-eca-rest-api/-/issues
license: license:
name: Eclipse Public License - 2.0 name: Eclipse Public License - 2.0
url: https://www.eclipse.org/legal/epl-2.0/ url: https://www.eclipse.org/legal/epl-2.0/
...@@ -11,10 +15,15 @@ servers: ...@@ -11,10 +15,15 @@ servers:
tags: tags:
- name: ECA Validation - name: ECA Validation
description: Definitions in relation to the validation of Git commits through ECA signage description: Definitions in relation to the validation of Git commits through ECA signage
- name: Reports
description: Reports on metadata associated with Git systems managed by the Eclipse Foundation
- name: Integration Webhooks
description: Endpoints related to binding to external Git services through a webhook
paths: paths:
/eca: /eca:
post: post:
operationId: validate
tags: tags:
- ECA Validation - ECA Validation
summary: ECA validation summary: ECA validation
...@@ -25,29 +34,36 @@ paths: ...@@ -25,29 +34,36 @@ paths:
schema: schema:
$ref: "#/components/schemas/ValidationRequest" $ref: "#/components/schemas/ValidationRequest"
responses: responses:
200: "200":
description: Success description: Success
content: content:
application/json: application/json:
schema: schema:
$ref: "#/components/schemas/ValidationResponse" $ref: "#/components/schemas/ValidationResponse"
500: "500":
description: Error while retrieving data description: Error while retrieving data
/eca/status/{fingerprint}: /eca/status/{fingerprint}:
parameters:
- name: fingerprint
in: path
description: Unique ID for the request group
required: true
schema:
type: string
get: get:
operationId: getCommitValidation
tags: tags:
- ECA Validation Status - ECA Validation
summary: Historic ECA validation status summary: Historic ECA validation status
description: Returns a set of validation messages for the given unique fingerprint description: Returns a set of validation messages for the given unique fingerprint
responses: responses:
200: "200":
description: Success description: Success
content: content:
application/json: application/json:
schema: schema:
$ref: "#/components/schemas/CommitValidationStatuses" $ref: "#/components/schemas/CommitValidationStatuses"
500: "500":
description: Error while retrieving data description: Error while retrieving data
/eca/status/{fingerprint}/ui: /eca/status/{fingerprint}/ui:
...@@ -59,34 +75,53 @@ paths: ...@@ -59,34 +75,53 @@ paths:
schema: schema:
type: string type: string
get: get:
operationId: getCommitValidationUI
tags:
- ECA Validation
summary: Historic ECA validation status in a HTML format summary: Historic ECA validation status in a HTML format
description: Returns an HTMl page containing validation messages description: Returns an HTMl page containing validation messages
responses: responses:
200: "200":
description: Success. An HTML page containing status info description: Success. An HTML page containing status info
404: "404":
description: Not Found description: Not Found
500: "500":
description: Error while retrieving data description: Error while retrieving data
/eca/lookup: /eca/lookup:
parameters:
- name: q
in: query
description: Query string containing either email or username. Email is only valid for logged in committers/project leads
schema:
type: string
- name: email
in: query
deprecated: true
description: Email is only valid for logged in committers/project leads. For removal at the end of 2024.
schema:
type: string
get: get:
operationId: getUserStatus
tags:
- ECA Validation
summary: User status lookup summary: User status lookup
description: Returns wether or not the user has a signed ECA description: Returns wether or not the user has a signed ECA
responses: responses:
200: "200":
description: Success description: Success
403: "403":
description: User exists with no ECA description: User exists with no ECA
404: "404":
description: User not found description: User not found
500: "500":
description: Error while retrieving data description: Error while retrieving data
/webhooks/github: /webhooks/github:
post: post:
operationId: processGithubWebhook
tags: tags:
- Github validation processing - Integration Webhooks
summary: Github incoming hook event processing summary: Github incoming hook event processing
description: Process incoming pull request hook events from Github description: Process incoming pull request hook events from Github
parameters: parameters:
...@@ -111,9 +146,9 @@ paths: ...@@ -111,9 +146,9 @@ paths:
schema: schema:
$ref: "#/components/schemas/GithubWebhookEvent" $ref: "#/components/schemas/GithubWebhookEvent"
responses: responses:
200: "200":
description: Success description: Success
500: "500":
description: Error while processing data description: Error while processing data
/webhooks/github/revalidate/{fingerprint}: /webhooks/github/revalidate/{fingerprint}:
parameters: parameters:
...@@ -124,8 +159,9 @@ paths: ...@@ -124,8 +159,9 @@ paths:
schema: schema:
type: string type: string
post: post:
operationId: revalidateWebhookRequest
tags: tags:
- Github validation processing - Integration Webhooks
summary: Gitlab webhook revalidation request summary: Gitlab webhook revalidation request
description: Process incoming system hooks from GitLab description: Process incoming system hooks from GitLab
requestBody: requestBody:
...@@ -134,20 +170,21 @@ paths: ...@@ -134,20 +170,21 @@ paths:
schema: schema:
$ref: '#/components/schemas/RevalidationRequest' $ref: '#/components/schemas/RevalidationRequest'
responses: responses:
200: "200":
description: Success description: Success
400: "400":
description: Bad request description: Bad request
content: content:
application/json: application/json:
schema: schema:
$ref: "#/components/schemas/Error" $ref: "#/components/schemas/Error"
404: "404":
description: Not found description: Not found
/webhooks/gitlab/system: /webhooks/gitlab/system:
post: post:
operationId: processGitlabHook
tags: tags:
- Gitlab system event processing - Integration Webhooks
summary: Gitlab event processing summary: Gitlab event processing
description: Process incoming system hooks from GitLab description: Process incoming system hooks from GitLab
parameters: parameters:
...@@ -162,9 +199,9 @@ paths: ...@@ -162,9 +199,9 @@ paths:
schema: schema:
$ref: "#/components/schemas/SystemHook" $ref: "#/components/schemas/SystemHook"
responses: responses:
200: "200":
description: Success description: Success
500: "500":
description: Error while processing data description: Error while processing data
/reports/gitlab/private-projects: /reports/gitlab/private-projects:
...@@ -194,26 +231,27 @@ paths: ...@@ -194,26 +231,27 @@ paths:
schema: schema:
type: string type: string
get: get:
operationId: getPrivateProjectEvents
tags: tags:
- Private project event report - Reports
summary: Gitlab private project event report summary: Gitlab private project event report
description: Returns list of private project events using desired filters description: Returns list of private project events using desired filters
responses: responses:
200: "200":
description: Success description: Success
content: content:
application/json: application/json:
schema: schema:
$ref: "#/components/schemas/PrivateProjectEvents" $ref: "#/components/schemas/PrivateProjectEvents"
400: "400":
description: Bad Request - invalid non-null prams description: Bad Request - invalid non-null prams
content: content:
application/json: application/json:
schema: schema:
$ref: "#/components/schemas/Error" $ref: "#/components/schemas/Error"
401: "401":
description: Unauthorized - invalid key description: Unauthorized - invalid key
500: "500":
description: Error while processing request description: Error while processing request
components: components:
...@@ -226,7 +264,17 @@ components: ...@@ -226,7 +264,17 @@ components:
DateTime: DateTime:
type: string type: string
format: datetime format: date-time
description: |
Date string in the RFC 3339 format. Example, `1990-12-31T15:59:60-08:00`.
More on this standard can be read at https://tools.ietf.org/html/rfc3339.
NullableDateTime:
type:
- string
- "null"
format: date-time
description: | description: |
Date string in the RFC 3339 format. Example, `1990-12-31T15:59:60-08:00`. Date string in the RFC 3339 format. Example, `1990-12-31T15:59:60-08:00`.
...@@ -234,6 +282,12 @@ components: ...@@ -234,6 +282,12 @@ components:
ValidationRequest: ValidationRequest:
type: object type: object
additionalProperties: false
required:
- provider
- repoUrl
- strictMode
- commits
properties: properties:
provider: provider:
type: string type: string
...@@ -248,7 +302,7 @@ components: ...@@ -248,7 +302,7 @@ components:
strictMode: strictMode:
type: boolean type: boolean
description: Whether to strictly apply validation regardless of project matching description: Whether to strictly apply validation regardless of project matching
estimated_loc: estimatedLoc:
type: type:
- integer - integer
- "null" - "null"
...@@ -258,6 +312,12 @@ components: ...@@ -258,6 +312,12 @@ components:
minimum: 1 minimum: 1
items: items:
type: object type: object
additionalProperties: false
required:
- hash
- author
- committer
- parents
properties: properties:
hash: hash:
type: string type: string
...@@ -274,6 +334,9 @@ components: ...@@ -274,6 +334,9 @@ components:
committer: committer:
$ref: "#/components/schemas/GitUser" $ref: "#/components/schemas/GitUser"
description: The committer of the Git commit description: The committer of the Git commit
last_modification_date:
$ref: "#/components/schemas/NullableDateTime"
description: Last time that the commit was updated
head: head:
type: type:
- boolean - boolean
...@@ -287,6 +350,10 @@ components: ...@@ -287,6 +350,10 @@ components:
GitUser: GitUser:
type: object type: object
additionalProperties: false
required:
- name
- mail
properties: properties:
name: name:
type: string type: string
...@@ -294,9 +361,21 @@ components: ...@@ -294,9 +361,21 @@ components:
mail: mail:
type: string type: string
description: the email address of the user description: the email address of the user
external_id:
$ref: "#/components/schemas/NullableString"
description: the email address of the user
ValidationResponse: ValidationResponse:
type: object type: object
additionalProperties: false
required:
- time
- trackedProject
- strictMode
- fingerprint
- errorCount
- passed
- commits
properties: properties:
time: time:
$ref: "#/components/schemas/DateTime" $ref: "#/components/schemas/DateTime"
...@@ -325,6 +404,11 @@ components: ...@@ -325,6 +404,11 @@ components:
Commit: Commit:
type: object type: object
additionalProperties: false
required:
- errors
- warnings
- messages
properties: properties:
messages: messages:
type: array type: array
...@@ -344,6 +428,10 @@ components: ...@@ -344,6 +428,10 @@ components:
CommitMessage: CommitMessage:
type: object type: object
additionalProperties: false
required:
- code
- message
properties: properties:
code: code:
type: integer type: integer
...@@ -359,13 +447,31 @@ components: ...@@ -359,13 +447,31 @@ components:
CommitValidationStatus: CommitValidationStatus:
type: object type: object
additionalProperties: false
required:
- id
- commit_hash
- project
- repo_url
- provider
- creation_date
- last_modified
- errors
properties: properties:
id: id:
type: integer type: integer
description: internal ID of the commit for tracking description: internal ID of the commit for tracking
sha: commit_hash:
type: string type: string
description: the SHA of the commit that was validated description: the SHA of the commit that was validated
user_mail:
type:
- string
- "null"
description: the email of the user associated with the status
estimated_loc:
type: integer
description: the estimated number of lines of code changed by commit if available.
project: project:
type: string type: string
description: The short project ID of the project that was detected for the commit, if it exists. description: The short project ID of the project that was detected for the commit, if it exists.
...@@ -392,28 +498,46 @@ components: ...@@ -392,28 +498,46 @@ components:
CommitValidationMessage: CommitValidationMessage:
type: object type: object
additionalProperties: false
required:
- id
- status_code
- author_email
properties: properties:
id: id:
type: integer type: integer
description: internal ID of the commit message for tracking description: internal ID of the commit message for tracking
commit_id:
type: integer
description: internal ID of the commit for tracking
status_code: status_code:
type: integer type: integer
description: error code associated with the commit description: error code associated with the commit
eclipse_id: eclipse_id:
type: string $ref: "#/components/schemas/NullableString"
description: the Eclipse Foundation ID of the user description: the Eclipse Foundation ID of the user
author_email: author_email:
type: string type: string
description: Email address of the author of the commit for additional information description: Email address of the author of the commit for additional information
provider_id: committer_email:
type: string type: string
description: Email address of the committer of the commit for additional information
provider_id:
$ref: "#/components/schemas/NullableString"
description: the outward facing URL of the repo the commit belongs to. description: the outward facing URL of the repo the commit belongs to.
SystemHook: SystemHook:
type: object type: object
additionalProperties: false
required:
- created_at
- updated_at
- event_name
- name
- owner_email
- owner_name
- owners
- path
- path_with_namespace
- project_id
- project_visibility
properties: properties:
created_at: created_at:
$ref: "#/components/schemas/DateTime" $ref: "#/components/schemas/DateTime"
...@@ -470,6 +594,13 @@ components: ...@@ -470,6 +594,13 @@ components:
PrivateProjectData: PrivateProjectData:
type: object type: object
additionalProperties: false
required:
- user_id
- project_id
- project_path
- ef_username
- creation_date
properties: properties:
user_id: user_id:
type: integer type: integer
...@@ -532,12 +663,19 @@ components: ...@@ -532,12 +663,19 @@ components:
description: The SHA hash of the head of the pull request. description: The SHA hash of the head of the pull request.
RevalidationRequest: RevalidationRequest:
type: object type: object
additionalProperties: false
required:
- h-form-captcha-response
properties: properties:
h-form-captcha-response: h-form-captcha-response:
type: string type: string
description: the hCaptcha challenge response. description: the hCaptcha challenge response.
Error: Error:
type: object type: object
additionalProperties: false
required:
- status_code
- message
properties: properties:
status_code: status_code:
type: integer type: integer
......
####
# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode
# #
# Before building the docker image run: # Based on a base image defined in the EF dockerfile project under https://github.com/EclipseFdn/dockerfiles/blob/master/java-api-base/Dockerfile.
# #
# mvn package # This image centralizes the base image version as well as any security patches to reduce the need to update all APIs manually in case of vulnerabilities or minor updates.
# #
# Then, build the image with: FROM eclipsefdn/java-api-base:j17-openjdk
#
# docker build -f src/main/docker/Dockerfile.jvm -t eclipsefdn/git-eca-rest-api-jvm .
#
# Then run the container using:
#
# docker run -i --rm -p 8080:8080 eclipsefdn/git-eca-rest-api-jvm
#
###
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.4
ARG JAVA_PACKAGE=java-11-openjdk-headless
ARG RUN_JAVA_VERSION=1.3.8
ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en'
# Install java and the run-java script
# Also set up permissions for user `1001`
RUN microdnf install curl ca-certificates ${JAVA_PACKAGE} \
&& microdnf update \
&& microdnf clean all \
&& mkdir /deployments \
&& chown 1001 /deployments \
&& chmod "g+rwX" /deployments \
&& chown 1001:root /deployments \
&& curl https://repo1.maven.org/maven2/io/fabric8/run-java-sh/${RUN_JAVA_VERSION}/run-java-sh-${RUN_JAVA_VERSION}-sh.sh -o /deployments/run-java.sh \
&& chown 1001 /deployments/run-java.sh \
&& chmod 540 /deployments/run-java.sh \
&& echo "securerandom.source=file:/dev/urandom" >> /etc/alternatives/jre/conf/security/java.security
# Configure the JAVA_OPTIONS, you can add -XshowSettings:vm to also display the heap size.
ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
# We make four distinct layers so if there are application changes the library layers can be re-used # We make four distinct layers so if there are application changes the library layers can be re-used
COPY --chown=1001 target/quarkus-app/lib/ /deployments/lib/ COPY --chown=185 target/quarkus-app/lib/ /deployments/lib/
COPY --chown=1001 target/quarkus-app/*.jar /deployments/ COPY --chown=185 target/quarkus-app/*.jar /deployments/
COPY --chown=1001 target/quarkus-app/app/ /deployments/app/ COPY --chown=185 target/quarkus-app/app/ /deployments/app/
COPY --chown=1001 target/quarkus-app/quarkus/ /deployments/quarkus/ COPY --chown=185 target/quarkus-app/quarkus/ /deployments/quarkus/
EXPOSE 8090 EXPOSE 8090
USER 1001 USER 185
\ No newline at end of file
ENTRYPOINT [ "/deployments/run-java.sh" ]
\ No newline at end of file
/*********************************************************************
* Copyright (c) 2020 Eclipse Foundation.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* Author: Martin Lowe <martin.lowe@eclipse-foundation.org>
*
* SPDX-License-Identifier: EPL-2.0
**********************************************************************/
package org.eclipsefoundation.git.eca.api;
import java.util.List;
import javax.enterprise.context.ApplicationScoped;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
import org.eclipsefoundation.git.eca.api.models.EclipseUser;
/**
* Binding interface for the Eclipse Foundation user account API. Runtime
* implementations are automatically generated by
* Quarkus at compile time. As the API deals with sensitive information,
* authentication is required to access this endpoint.
*
* @author Martin Lowe
*
*/
@ApplicationScoped
@RegisterRestClient
@Produces("application/json")
public interface AccountsAPI {
/**
* Retrieves all user objects that use the given mail address.
*
* @param mail the email address to match against for Eclipse accounts
* @return all matching eclipse accounts
*/
@GET
@Path("/account/profile")
List<EclipseUser> getUsers(@HeaderParam("Authorization") String token, @QueryParam("mail") String mail);
/**
* Retrieves user objects that matches the given Github username.
*
* @param authBearer authorization header value for validating call
* @param uname username of the Github account to retrieve Eclipse Account
* for
* @return the matching Eclipse account or null
*/
@GET
@Path("/github/profile/{uname}")
EclipseUser getUserByGithubUname(@HeaderParam("Authorization") String token, @PathParam("uname") String uname);
}
...@@ -13,10 +13,10 @@ package org.eclipsefoundation.git.eca.api; ...@@ -13,10 +13,10 @@ package org.eclipsefoundation.git.eca.api;
import java.util.List; import java.util.List;
import javax.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.ApplicationScoped;
import javax.ws.rs.GET; import jakarta.ws.rs.GET;
import javax.ws.rs.Path; import jakarta.ws.rs.Path;
import javax.ws.rs.Produces; import jakarta.ws.rs.Produces;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
......
...@@ -11,21 +11,26 @@ ...@@ -11,21 +11,26 @@
*/ */
package org.eclipsefoundation.git.eca.api; package org.eclipsefoundation.git.eca.api;
import javax.ws.rs.BeanParam; import java.util.List;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
import org.eclipsefoundation.core.service.APIMiddleware.BaseAPIParameters; import org.eclipsefoundation.core.service.APIMiddleware.BaseAPIParameters;
import org.eclipsefoundation.git.eca.api.models.GithubAccessToken; import org.eclipsefoundation.git.eca.api.models.GithubAccessToken;
import org.eclipsefoundation.git.eca.api.models.GithubApplicationInstallationData;
import org.eclipsefoundation.git.eca.api.models.GithubCommit;
import org.eclipsefoundation.git.eca.api.models.GithubCommitStatusRequest; import org.eclipsefoundation.git.eca.api.models.GithubCommitStatusRequest;
import org.eclipsefoundation.git.eca.api.models.GithubWebhookRequest.PullRequest; import org.eclipsefoundation.git.eca.api.models.GithubWebhookRequest.PullRequest;
import org.jboss.resteasy.util.HttpHeaderNames; import org.jboss.resteasy.reactive.RestResponse;
import jakarta.ws.rs.BeanParam;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.HeaderParam;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.HttpHeaders;
import jakarta.ws.rs.core.Response;
/** /**
* Bindings used by the webhook logic to retrieve data about the PR to be validated. * Bindings used by the webhook logic to retrieve data about the PR to be validated.
...@@ -47,9 +52,9 @@ public interface GithubAPI { ...@@ -47,9 +52,9 @@ public interface GithubAPI {
* @return information about the given pull request if it exists. * @return information about the given pull request if it exists.
*/ */
@GET @GET
@Path("repos/{repoFull}/pulls/{pullNumber}") @Path("repos/{org}/{repo}/pulls/{pullNumber}")
public PullRequest getPullRequest(@HeaderParam(HttpHeaderNames.AUTHORIZATION) String bearer, public PullRequest getPullRequest(@HeaderParam(HttpHeaders.AUTHORIZATION) String bearer,
@HeaderParam("X-GitHub-Api-Version") String apiVersion, @PathParam("repoFull") String repoFull, @HeaderParam("X-GitHub-Api-Version") String apiVersion, @PathParam("org") String organization, @PathParam("repo") String repo,
@PathParam("pullNumber") int pullNumber); @PathParam("pullNumber") int pullNumber);
/** /**
...@@ -57,36 +62,36 @@ public interface GithubAPI { ...@@ -57,36 +62,36 @@ public interface GithubAPI {
* *
* @param bearer authorization header value, access token for application with access to repo * @param bearer authorization header value, access token for application with access to repo
* @param apiVersion the version of the GH API to target when making the request * @param apiVersion the version of the GH API to target when making the request
* @param repoFull the full repo name that is being targeted * @param repo the repo name that is being targeted
* @param pullNumber the pull request number * @param pullNumber the pull request number
* @return list of commits associated with the pull request, wrapped in a jax-rs response * @return list of commits associated with the pull request, wrapped in a jax-rs response
*/ */
@GET @GET
@Path("repos/{repoFull}/pulls/{pullNumber}/commits") @Path("repos/{org}/{repo}/pulls/{pullNumber}/commits")
public Response getCommits(@HeaderParam(HttpHeaderNames.AUTHORIZATION) String bearer, public RestResponse<List<GithubCommit>> getCommits(@HeaderParam(HttpHeaders.AUTHORIZATION) String bearer,
@HeaderParam("X-GitHub-Api-Version") String apiVersion, @PathParam("repoFull") String repoFull, @HeaderParam("X-GitHub-Api-Version") String apiVersion, @PathParam("org") String organization, @PathParam("repo") String repo,
@PathParam("pullNumber") int pullNumber); @PathParam("pullNumber") int pullNumber);
/** /**
* Posts an update to the Github API, using an access token to update a given pull requests commit status, targeted * Posts an update to the Github API, using an access token to update a given pull requests commit status, targeted using the head sha.
* using the head sha.
* *
* @param bearer authorization header value, access token for application with access to repo * @param bearer authorization header value, access token for application with access to repo
* @param apiVersion the version of the GH API to target when making the request * @param apiVersion the version of the GH API to target when making the request
* @param repoFull the full repo name that is being targeted * @param organization the organization that owns the targeted repo
* @param repo the repo name that is being targeted
* @param prHeadSha the head SHA for the request * @param prHeadSha the head SHA for the request
* @param commitStatusUpdate the status body sent with the request * @param commitStatusUpdate the status body sent with the request
* @return JAX-RS response to check for success or failure based on status code. * @return JAX-RS response to check for success or failure based on status code.
*/ */
@POST @POST
@Path("repos/{repoFull}/statuses/{prHeadSha}") @Path("repos/{org}/{repo}/statuses/{prHeadSha}")
public Response updateStatus(@HeaderParam(HttpHeaderNames.AUTHORIZATION) String bearer, public Response updateStatus(@HeaderParam(HttpHeaders.AUTHORIZATION) String bearer,
@HeaderParam("X-GitHub-Api-Version") String apiVersion, @PathParam("repoFull") String repoFull, @HeaderParam("X-GitHub-Api-Version") String apiVersion, @PathParam("org") String organization, @PathParam("repo") String repo,
@PathParam("prHeadSha") String prHeadSha, GithubCommitStatusRequest commitStatusUpdate); @PathParam("prHeadSha") String prHeadSha, GithubCommitStatusRequest commitStatusUpdate);
/** /**
* Requires a JWT bearer token for the application to retrieve installations for. Returns a list of installations for * Requires a JWT bearer token for the application to retrieve installations for. Returns a list of installations for the given
* the given application. * application.
* *
* @param params the general params for requests, including pagination * @param params the general params for requests, including pagination
* @param bearer JWT bearer token for the target application * @param bearer JWT bearer token for the target application
...@@ -94,7 +99,8 @@ public interface GithubAPI { ...@@ -94,7 +99,8 @@ public interface GithubAPI {
*/ */
@GET @GET
@Path("app/installations") @Path("app/installations")
public Response getInstallations(@BeanParam BaseAPIParameters params, @HeaderParam(HttpHeaderNames.AUTHORIZATION) String bearer); public RestResponse<List<GithubApplicationInstallationData>> getInstallations(@BeanParam BaseAPIParameters params,
@HeaderParam(HttpHeaders.AUTHORIZATION) String bearer);
/** /**
* Retrieves an access token for a specific installation, given the applications JWT bearer and the api version. * Retrieves an access token for a specific installation, given the applications JWT bearer and the api version.
...@@ -106,7 +112,7 @@ public interface GithubAPI { ...@@ -106,7 +112,7 @@ public interface GithubAPI {
*/ */
@POST @POST
@Path("app/installations/{installationId}/access_tokens") @Path("app/installations/{installationId}/access_tokens")
public GithubAccessToken getNewAccessToken(@HeaderParam(HttpHeaderNames.AUTHORIZATION) String bearer, public GithubAccessToken getNewAccessToken(@HeaderParam(HttpHeaders.AUTHORIZATION) String bearer,
@HeaderParam("X-GitHub-Api-Version") String apiVersion, @PathParam("installationId") String installationId); @HeaderParam("X-GitHub-Api-Version") String apiVersion, @PathParam("installationId") String installationId);
/** /**
...@@ -118,7 +124,6 @@ public interface GithubAPI { ...@@ -118,7 +124,6 @@ public interface GithubAPI {
*/ */
@GET @GET
@Path("installation/repositories") @Path("installation/repositories")
public Response getInstallationRepositories(@BeanParam BaseAPIParameters params, public Response getInstallationRepositories(@BeanParam BaseAPIParameters params, @HeaderParam(HttpHeaders.AUTHORIZATION) String bearer);
@HeaderParam(HttpHeaderNames.AUTHORIZATION) String bearer);
} }
...@@ -11,19 +11,21 @@ ...@@ -11,19 +11,21 @@
**********************************************************************/ **********************************************************************/
package org.eclipsefoundation.git.eca.api; package org.eclipsefoundation.git.eca.api;
import javax.enterprise.context.ApplicationScoped; import java.util.List;
import javax.ws.rs.BeanParam;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
import org.eclipsefoundation.core.service.APIMiddleware.BaseAPIParameters; import org.eclipsefoundation.core.service.APIMiddleware.BaseAPIParameters;
import org.eclipsefoundation.git.eca.api.models.GitlabProjectResponse; import org.eclipsefoundation.git.eca.api.models.GitlabProjectResponse;
import org.eclipsefoundation.git.eca.api.models.GitlabUserResponse; import org.eclipsefoundation.git.eca.api.models.GitlabUserResponse;
import org.jboss.resteasy.reactive.RestResponse;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.ws.rs.BeanParam;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.HeaderParam;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.QueryParam;
/** /**
* Interface for interacting with the GitLab API. Used to fetch project data. * Interface for interacting with the GitLab API. Used to fetch project data.
...@@ -33,40 +35,36 @@ import org.eclipsefoundation.git.eca.api.models.GitlabUserResponse; ...@@ -33,40 +35,36 @@ import org.eclipsefoundation.git.eca.api.models.GitlabUserResponse;
public interface GitlabAPI { public interface GitlabAPI {
/** /**
* Fetches data for a project using the projectId. The id and a token of * Fetches data for a project using the projectId. The id and a token of adequate permissions is required.
* adequate permissions is required.
* *
* @param privateToken the header token * @param privateToken the header token
* @param projectId the project id * @param projectId the project id
* @return A GitlabProjectResponse object * @return A GitlabProjectResponse object
*/ */
@GET @GET
@Path("/projects/{id}") @Path("/projects/{id}")
GitlabProjectResponse getProjectInfo(@HeaderParam("PRIVATE-TOKEN") String privateToken, GitlabProjectResponse getProjectInfo(@HeaderParam("PRIVATE-TOKEN") String privateToken, @PathParam("id") int projectId);
@PathParam("id") int projectId);
/** /**
* Fetches data for private projects. A token of adequate permissions is * Fetches data for private projects. A token of adequate permissions is required. Visibility should be set to "private" and per_page
* required. Visibility should be set to "private" and per_page should be set to * should be set to 100 to minimize API calls.
* 100 to minimize API calls.
* *
* @param privateToken the header token * @param privateToken the header token
* @param visibility the project visibility * @param visibility the project visibility
* @param perPage the number of results per page * @param perPage the number of results per page
* @return A Response containing a private project list * @return A Response containing a private project list
*/ */
@GET @GET
@Path("/projects") @Path("/projects")
Response getPrivateProjects(@BeanParam BaseAPIParameters baseParams, RestResponse<List<GitlabProjectResponse>> getPrivateProjects(@BeanParam BaseAPIParameters baseParams,
@HeaderParam("PRIVATE-TOKEN") String privateToken, @QueryParam("visibility") String visibility, @HeaderParam("PRIVATE-TOKEN") String privateToken, @QueryParam("visibility") String visibility,
@QueryParam("per_page") Integer perPage); @QueryParam("per_page") Integer perPage);
/** /**
* Fetches data for a user using the userId. The id and a token of * Fetches data for a user using the userId. The id and a token of adequate permissions is required.
* adequate permissions is required.
* *
* @param privateToken the header token * @param privateToken the header token
* @param userId the project id * @param userId the project id
* @returnA A GitlabUserResponse object * @returnA A GitlabUserResponse object
*/ */
@GET @GET
......
...@@ -11,11 +11,11 @@ ...@@ -11,11 +11,11 @@
*/ */
package org.eclipsefoundation.git.eca.api; package org.eclipsefoundation.git.eca.api;
import javax.ws.rs.FormParam; import jakarta.ws.rs.FormParam;
import javax.ws.rs.POST; import jakarta.ws.rs.POST;
import javax.ws.rs.Path; import jakarta.ws.rs.Path;
import javax.ws.rs.Produces; import jakarta.ws.rs.Produces;
import javax.ws.rs.core.MediaType; import jakarta.ws.rs.core.MediaType;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
import org.eclipsefoundation.git.eca.api.models.CaptchaResponseData; import org.eclipsefoundation.git.eca.api.models.CaptchaResponseData;
......
/*********************************************************************
* Copyright (c) 2022 Eclipse Foundation.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* Author: Martin Lowe <martin.lowe@eclipse-foundation.org>
*
* SPDX-License-Identifier: EPL-2.0
**********************************************************************/
package org.eclipsefoundation.git.eca.api;
import javax.enterprise.context.ApplicationScoped;
import javax.ws.rs.BeanParam;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
import org.eclipsefoundation.core.service.APIMiddleware.BaseAPIParameters;
import org.jboss.resteasy.annotations.GZIP;
/**
* Interface for interacting with the PMI Projects API. Used to link Git
* repos/projects with an Eclipse project to validate committer access.
*
* @author Martin Lowe
*
*/
@ApplicationScoped
@Path("/api")
@RegisterRestClient
@GZIP
public interface ProjectsAPI {
/**
* Retrieves all projects with the given repo URL.
*
* @param repoUrl the target repos URL
* @return a list of Eclipse Foundation projects.
*/
@GET
@Path("projects")
Response getProjects(@BeanParam BaseAPIParameters baseParams);
@GET
@Path("interest-groups")
@Produces("application/json")
Response getInterestGroups(@BeanParam BaseAPIParameters params);
}
...@@ -13,7 +13,7 @@ package org.eclipsefoundation.git.eca.api.models; ...@@ -13,7 +13,7 @@ package org.eclipsefoundation.git.eca.api.models;
import java.util.List; import java.util.List;
import javax.annotation.Nullable; import jakarta.annotation.Nullable;
import org.eclipsefoundation.git.eca.namespace.HCaptchaErrorCodes; import org.eclipsefoundation.git.eca.namespace.HCaptchaErrorCodes;
......
/*********************************************************************
* Copyright (c) 2020 Eclipse Foundation.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* Author: Martin Lowe <martin.lowe@eclipse-foundation.org>
*
* SPDX-License-Identifier: EPL-2.0
**********************************************************************/
package org.eclipsefoundation.git.eca.api.models;
import javax.annotation.Nullable;
import org.eclipsefoundation.git.eca.model.GitUser;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
import com.google.auto.value.AutoValue;
/**
* Represents a users Eclipse Foundation account
*
* @author Martin Lowe
*/
@AutoValue
@JsonDeserialize(builder = AutoValue_EclipseUser.Builder.class)
public abstract class EclipseUser {
public abstract int getUid();
public abstract String getName();
public abstract String getMail();
public abstract ECA getECA();
public abstract boolean getIsCommitter();
@Nullable
public abstract String getGithubHandle();
@Nullable
@JsonIgnore
public abstract Boolean getIsBot();
/**
* Create a bot user stub when there is no real Eclipse account for the bot.
*
* @param user the Git user that was detected to be a bot.
* @return a stubbed Eclipse user bot object.
*/
public static EclipseUser createBotStub(GitUser user) {
return EclipseUser
.builder()
.setUid(0)
.setName(user.getName())
.setMail(user.getMail())
.setECA(ECA.builder().build())
.setIsBot(true)
.build();
}
public static Builder builder() {
return new AutoValue_EclipseUser.Builder().setIsCommitter(false).setIsBot(false);
}
@AutoValue.Builder
@JsonPOJOBuilder(withPrefix = "set")
public abstract static class Builder {
public abstract Builder setUid(int id);
public abstract Builder setName(String name);
public abstract Builder setMail(String mail);
public abstract Builder setECA(ECA eca);
public abstract Builder setIsCommitter(boolean isCommitter);
public abstract Builder setGithubHandle(@Nullable String githubHandle);
@JsonIgnore
public abstract Builder setIsBot(@Nullable Boolean isBot);
public abstract EclipseUser build();
}
@AutoValue
@JsonDeserialize(builder = AutoValue_EclipseUser_ECA.Builder.class)
public abstract static class ECA {
public abstract boolean getSigned();
public abstract boolean getCanContributeSpecProject();
public static Builder builder() {
return new AutoValue_EclipseUser_ECA.Builder().setCanContributeSpecProject(false).setSigned(false);
}
@AutoValue.Builder
@JsonPOJOBuilder(withPrefix = "set")
public abstract static class Builder {
public abstract Builder setSigned(boolean signed);
public abstract Builder setCanContributeSpecProject(boolean canContributeSpecProject);
public abstract ECA build();
}
}
}
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
*/ */
package org.eclipsefoundation.git.eca.api.models; package org.eclipsefoundation.git.eca.api.models;
import jakarta.annotation.Nullable;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
import com.google.auto.value.AutoValue; import com.google.auto.value.AutoValue;
...@@ -22,8 +24,8 @@ import com.google.auto.value.AutoValue; ...@@ -22,8 +24,8 @@ import com.google.auto.value.AutoValue;
* *
*/ */
@AutoValue @AutoValue
@JsonDeserialize(builder = AutoValue_GithubApplicationInstallation.Builder.class) @JsonDeserialize(builder = AutoValue_GithubApplicationInstallationData.Builder.class)
public abstract class GithubApplicationInstallation { public abstract class GithubApplicationInstallationData {
public abstract int getId(); public abstract int getId();
...@@ -31,8 +33,10 @@ public abstract class GithubApplicationInstallation { ...@@ -31,8 +33,10 @@ public abstract class GithubApplicationInstallation {
public abstract String getTargetId(); public abstract String getTargetId();
public abstract Account getAccount();
public static Builder builder() { public static Builder builder() {
return new AutoValue_GithubApplicationInstallation.Builder(); return new AutoValue_GithubApplicationInstallationData.Builder();
} }
@AutoValue.Builder @AutoValue.Builder
...@@ -44,6 +48,31 @@ public abstract class GithubApplicationInstallation { ...@@ -44,6 +48,31 @@ public abstract class GithubApplicationInstallation {
public abstract Builder setTargetId(String targetId); public abstract Builder setTargetId(String targetId);
public abstract GithubApplicationInstallation build(); public abstract Builder setAccount(Account account);
public abstract GithubApplicationInstallationData build();
}
@AutoValue
@JsonDeserialize(builder = AutoValue_GithubApplicationInstallationData_Account.Builder.class)
public abstract static class Account {
public abstract int getId();
@Nullable
public abstract String getLogin();
public static Builder builder() {
return new AutoValue_GithubApplicationInstallationData_Account.Builder();
}
@AutoValue.Builder
@JsonPOJOBuilder(withPrefix = "set")
public abstract static class Builder {
public abstract Builder setId(int id);
public abstract Builder setLogin(@Nullable String login);
public abstract Account build();
}
} }
} }
...@@ -13,6 +13,8 @@ package org.eclipsefoundation.git.eca.api.models; ...@@ -13,6 +13,8 @@ package org.eclipsefoundation.git.eca.api.models;
import java.util.List; import java.util.List;
import jakarta.annotation.Nullable;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
import com.google.auto.value.AutoValue; import com.google.auto.value.AutoValue;
...@@ -28,9 +30,10 @@ public abstract class GithubCommit { ...@@ -28,9 +30,10 @@ public abstract class GithubCommit {
public abstract CommitData getCommit(); public abstract CommitData getCommit();
public abstract CommitUser getCommitter(); @Nullable
public abstract GithubCommitUser getCommitter();
public abstract CommitUser getAuthor(); @Nullable
public abstract GithubCommitUser getAuthor();
public abstract List<ParentCommit> getParents(); public abstract List<ParentCommit> getParents();
...@@ -45,9 +48,9 @@ public abstract class GithubCommit { ...@@ -45,9 +48,9 @@ public abstract class GithubCommit {
public abstract Builder setCommit(CommitData commit); public abstract Builder setCommit(CommitData commit);
public abstract Builder setCommitter(CommitUser committer); public abstract Builder setCommitter(@Nullable GithubCommitUser committer);
public abstract Builder setAuthor(CommitUser author); public abstract Builder setAuthor(@Nullable GithubCommitUser author);
public abstract Builder setParents(List<ParentCommit> parents); public abstract Builder setParents(List<ParentCommit> parents);
...@@ -57,9 +60,11 @@ public abstract class GithubCommit { ...@@ -57,9 +60,11 @@ public abstract class GithubCommit {
@AutoValue @AutoValue
@JsonDeserialize(builder = AutoValue_GithubCommit_CommitData.Builder.class) @JsonDeserialize(builder = AutoValue_GithubCommit_CommitData.Builder.class)
public abstract static class CommitData { public abstract static class CommitData {
public abstract BriefCommitUser getAuthor(); @Nullable
public abstract GitCommitUser getAuthor();
public abstract BriefCommitUser getCommitter(); @Nullable
public abstract GitCommitUser getCommitter();
public static Builder builder() { public static Builder builder() {
return new AutoValue_GithubCommit_CommitData.Builder(); return new AutoValue_GithubCommit_CommitData.Builder();
...@@ -68,23 +73,23 @@ public abstract class GithubCommit { ...@@ -68,23 +73,23 @@ public abstract class GithubCommit {
@AutoValue.Builder @AutoValue.Builder
@JsonPOJOBuilder(withPrefix = "set") @JsonPOJOBuilder(withPrefix = "set")
public abstract static class Builder { public abstract static class Builder {
public abstract Builder setAuthor(BriefCommitUser author); public abstract Builder setAuthor(@Nullable GitCommitUser author);
public abstract Builder setCommitter(BriefCommitUser committer); public abstract Builder setCommitter(@Nullable GitCommitUser committer);
public abstract CommitData build(); public abstract CommitData build();
} }
} }
@AutoValue @AutoValue
@JsonDeserialize(builder = AutoValue_GithubCommit_BriefCommitUser.Builder.class) @JsonDeserialize(builder = AutoValue_GithubCommit_GitCommitUser.Builder.class)
public abstract static class BriefCommitUser { public abstract static class GitCommitUser {
public abstract String getName(); public abstract String getName();
public abstract String getEmail(); public abstract String getEmail();
public static Builder builder() { public static Builder builder() {
return new AutoValue_GithubCommit_BriefCommitUser.Builder(); return new AutoValue_GithubCommit_GitCommitUser.Builder();
} }
@AutoValue.Builder @AutoValue.Builder
...@@ -94,25 +99,26 @@ public abstract class GithubCommit { ...@@ -94,25 +99,26 @@ public abstract class GithubCommit {
public abstract Builder setEmail(String email); public abstract Builder setEmail(String email);
public abstract BriefCommitUser build(); public abstract GitCommitUser build();
} }
} }
@AutoValue @AutoValue
@JsonDeserialize(builder = AutoValue_GithubCommit_CommitUser.Builder.class) @JsonDeserialize(builder = AutoValue_GithubCommit_GithubCommitUser.Builder.class)
public abstract static class CommitUser { public abstract static class GithubCommitUser {
@Nullable
public abstract String getLogin(); public abstract String getLogin();
public static Builder builder() { public static Builder builder() {
return new AutoValue_GithubCommit_CommitUser.Builder(); return new AutoValue_GithubCommit_GithubCommitUser.Builder();
} }
@AutoValue.Builder @AutoValue.Builder
@JsonPOJOBuilder(withPrefix = "set") @JsonPOJOBuilder(withPrefix = "set")
public abstract static class Builder { public abstract static class Builder {
public abstract Builder setLogin(String login); public abstract Builder setLogin(@Nullable String login);
public abstract CommitUser build(); public abstract GithubCommitUser build();
} }
} }
......
...@@ -15,14 +15,17 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize; ...@@ -15,14 +15,17 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
import com.google.auto.value.AutoValue; import com.google.auto.value.AutoValue;
import jakarta.annotation.Nullable;
/** /**
* @author martin * @author Martin Lowe
* *
*/ */
@AutoValue @AutoValue
@JsonDeserialize(builder = AutoValue_GithubCommitStatusRequest.Builder.class) @JsonDeserialize(builder = AutoValue_GithubCommitStatusRequest.Builder.class)
public abstract class GithubCommitStatusRequest { public abstract class GithubCommitStatusRequest {
public abstract String getState(); public abstract String getState();
@Nullable
public abstract String getTargetUrl(); public abstract String getTargetUrl();
public abstract String getDescription(); public abstract String getDescription();
public abstract String getContext(); public abstract String getContext();
...@@ -35,7 +38,7 @@ public abstract class GithubCommitStatusRequest { ...@@ -35,7 +38,7 @@ public abstract class GithubCommitStatusRequest {
@JsonPOJOBuilder(withPrefix = "set") @JsonPOJOBuilder(withPrefix = "set")
public abstract static class Builder { public abstract static class Builder {
public abstract Builder setState(String state); public abstract Builder setState(String state);
public abstract Builder setTargetUrl(String targetUrl); public abstract Builder setTargetUrl(@Nullable String targetUrl);
public abstract Builder setDescription(String description); public abstract Builder setDescription(String description);
public abstract Builder setContext(String context); public abstract Builder setContext(String context);
......