Adds support for GitLabAPI V4 while keeping support for V3 (#614)
This commit is contained in:
parent
ca400c19bc
commit
17e89c3fdd
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.9/apache-maven-3.3.9-bin.zip
|
|
@ -0,0 +1,52 @@
|
|||
language: java
|
||||
|
||||
env:
|
||||
global:
|
||||
- DOCKER_CACHE_DIR=$HOME/.docker-images
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
|
||||
before_install:
|
||||
- chmod +x travis/*.sh
|
||||
|
||||
install: true
|
||||
|
||||
jobs:
|
||||
include:
|
||||
- stage: test
|
||||
script: ./travis/test.sh
|
||||
|
||||
|
||||
- stage: integration-test
|
||||
sudo: required
|
||||
services:
|
||||
- docker
|
||||
env:
|
||||
- GITLAB_VERSION=8.17.4
|
||||
script: ./travis/integration-test.sh
|
||||
|
||||
- stage: integration-test
|
||||
sudo: required
|
||||
services:
|
||||
- docker
|
||||
env:
|
||||
- GITLAB_VERSION=9.5.5
|
||||
script: ./travis/integration-test.sh
|
||||
|
||||
- stage: integration-test
|
||||
sudo: required
|
||||
services:
|
||||
- docker
|
||||
env:
|
||||
- GITLAB_VERSION=latest
|
||||
script: ./travis/integration-test.sh
|
||||
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $DOCKER_CACHE_DIR
|
||||
- $HOME/.m2/repository
|
||||
- $HOME/.m2/wrapper
|
||||
before_cache:
|
||||
- travis/before_cache.sh
|
|
@ -0,0 +1,236 @@
|
|||
#!/bin/sh
|
||||
# ----------------------------------------------------------------------------
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Maven2 Start Up Batch script
|
||||
#
|
||||
# Required ENV vars:
|
||||
# ------------------
|
||||
# JAVA_HOME - location of a JDK home dir
|
||||
#
|
||||
# Optional ENV vars
|
||||
# -----------------
|
||||
# M2_HOME - location of maven2's installed home dir
|
||||
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
# e.g. to debug Maven itself, use
|
||||
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
if [ -z "$MAVEN_SKIP_RC" ] ; then
|
||||
|
||||
if [ -f /etc/mavenrc ] ; then
|
||||
. /etc/mavenrc
|
||||
fi
|
||||
|
||||
if [ -f "$HOME/.mavenrc" ] ; then
|
||||
. "$HOME/.mavenrc"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
# OS specific support. $var _must_ be set to either true or false.
|
||||
cygwin=false;
|
||||
darwin=false;
|
||||
mingw=false
|
||||
case "`uname`" in
|
||||
CYGWIN*) cygwin=true ;;
|
||||
MINGW*) mingw=true;;
|
||||
Darwin*) darwin=true
|
||||
#
|
||||
# Look for the Apple JDKs first to preserve the existing behaviour, and then look
|
||||
# for the new JDKs provided by Oracle.
|
||||
#
|
||||
if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then
|
||||
#
|
||||
# Apple JDKs
|
||||
#
|
||||
export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then
|
||||
#
|
||||
# Apple JDKs
|
||||
#
|
||||
export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then
|
||||
#
|
||||
# Oracle JDKs
|
||||
#
|
||||
export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then
|
||||
#
|
||||
# Apple JDKs
|
||||
#
|
||||
export JAVA_HOME=`/usr/libexec/java_home`
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -z "$JAVA_HOME" ] ; then
|
||||
if [ -r /etc/gentoo-release ] ; then
|
||||
JAVA_HOME=`java-config --jre-home`
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$M2_HOME" ] ; then
|
||||
## resolve links - $0 may be a link to maven's home
|
||||
PRG="$0"
|
||||
|
||||
# need this for relative symlinks
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG="`dirname "$PRG"`/$link"
|
||||
fi
|
||||
done
|
||||
|
||||
saveddir=`pwd`
|
||||
|
||||
M2_HOME=`dirname "$PRG"`/..
|
||||
|
||||
# make it fully qualified
|
||||
M2_HOME=`cd "$M2_HOME" && pwd`
|
||||
|
||||
cd "$saveddir"
|
||||
# echo Using m2 at $M2_HOME
|
||||
fi
|
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched
|
||||
if $cygwin ; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME=`cygpath --unix "$M2_HOME"`
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
|
||||
fi
|
||||
|
||||
# For Migwn, ensure paths are in UNIX format before anything is touched
|
||||
if $mingw ; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME="`(cd "$M2_HOME"; pwd)`"
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
|
||||
# TODO classpath?
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
javaExecutable="`which javac`"
|
||||
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
|
||||
# readlink(1) is not available as standard on Solaris 10.
|
||||
readLink=`which readlink`
|
||||
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
|
||||
if $darwin ; then
|
||||
javaHome="`dirname \"$javaExecutable\"`"
|
||||
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
|
||||
else
|
||||
javaExecutable="`readlink -f \"$javaExecutable\"`"
|
||||
fi
|
||||
javaHome="`dirname \"$javaExecutable\"`"
|
||||
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
|
||||
JAVA_HOME="$javaHome"
|
||||
export JAVA_HOME
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$JAVACMD" ] ; then
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
else
|
||||
JAVACMD="`which java`"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
echo "Error: JAVA_HOME is not defined correctly." >&2
|
||||
echo " We cannot execute $JAVACMD" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ] ; then
|
||||
echo "Warning: JAVA_HOME environment variable is not set."
|
||||
fi
|
||||
|
||||
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
|
||||
|
||||
# traverses directory structure from process work directory to filesystem root
|
||||
# first directory with .mvn subdirectory is considered project base directory
|
||||
find_maven_basedir() {
|
||||
local basedir=$(pwd)
|
||||
local wdir=$(pwd)
|
||||
while [ "$wdir" != '/' ] ; do
|
||||
if [ -d "$wdir"/.mvn ] ; then
|
||||
basedir=$wdir
|
||||
break
|
||||
fi
|
||||
wdir=$(cd "$wdir/.."; pwd)
|
||||
done
|
||||
echo "${basedir}"
|
||||
}
|
||||
|
||||
# concatenates all lines of a file
|
||||
concat_lines() {
|
||||
if [ -f "$1" ]; then
|
||||
echo "$(tr -s '\n' ' ' < "$1")"
|
||||
fi
|
||||
}
|
||||
|
||||
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)}
|
||||
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME=`cygpath --path --windows "$M2_HOME"`
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
|
||||
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
|
||||
MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
|
||||
fi
|
||||
|
||||
# Provide a "standardized" way to retrieve the CLI args that will
|
||||
# work with both Windows and non-Windows executions.
|
||||
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
|
||||
export MAVEN_CMD_LINE_ARGS
|
||||
|
||||
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
# avoid using MAVEN_CMD_LINE_ARGS below since that would loose parameter escaping in $@
|
||||
exec "$JAVACMD" \
|
||||
$MAVEN_OPTS \
|
||||
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
|
||||
"-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
|
||||
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
|
|
@ -0,0 +1,146 @@
|
|||
@REM ----------------------------------------------------------------------------
|
||||
@REM Licensed to the Apache Software Foundation (ASF) under one
|
||||
@REM or more contributor license agreements. See the NOTICE file
|
||||
@REM distributed with this work for additional information
|
||||
@REM regarding copyright ownership. The ASF licenses this file
|
||||
@REM to you under the Apache License, Version 2.0 (the
|
||||
@REM "License"); you may not use this file except in compliance
|
||||
@REM with the License. You may obtain a copy of the License at
|
||||
@REM
|
||||
@REM http://www.apache.org/licenses/LICENSE-2.0
|
||||
@REM
|
||||
@REM Unless required by applicable law or agreed to in writing,
|
||||
@REM software distributed under the License is distributed on an
|
||||
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
@REM KIND, either express or implied. See the License for the
|
||||
@REM specific language governing permissions and limitations
|
||||
@REM under the License.
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Maven2 Start Up Batch script
|
||||
@REM
|
||||
@REM Required ENV vars:
|
||||
@REM JAVA_HOME - location of a JDK home dir
|
||||
@REM
|
||||
@REM Optional ENV vars
|
||||
@REM M2_HOME - location of maven2's installed home dir
|
||||
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
|
||||
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
|
||||
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
@REM e.g. to debug Maven itself, use
|
||||
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
|
||||
@echo off
|
||||
@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
|
||||
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
|
||||
|
||||
@REM set %HOME% to equivalent of $HOME
|
||||
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
|
||||
|
||||
@REM Execute a user defined script before this one
|
||||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
|
||||
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
|
||||
if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
|
||||
:skipRcPre
|
||||
|
||||
@setlocal
|
||||
|
||||
set ERROR_CODE=0
|
||||
|
||||
@REM To isolate internal variables from possible post scripts, we use another setlocal
|
||||
@setlocal
|
||||
|
||||
@REM ==== START VALIDATION ====
|
||||
if not "%JAVA_HOME%" == "" goto OkJHome
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME not found in your environment. >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
:OkJHome
|
||||
if exist "%JAVA_HOME%\bin\java.exe" goto init
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME is set to an invalid directory. >&2
|
||||
echo JAVA_HOME = "%JAVA_HOME%" >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
@REM ==== END VALIDATION ====
|
||||
|
||||
:init
|
||||
|
||||
set MAVEN_CMD_LINE_ARGS=%MAVEN_CONFIG% %*
|
||||
|
||||
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
|
||||
@REM Fallback to current working directory if not found.
|
||||
|
||||
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
|
||||
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
|
||||
|
||||
set EXEC_DIR=%CD%
|
||||
set WDIR=%EXEC_DIR%
|
||||
:findBaseDir
|
||||
IF EXIST "%WDIR%"\.mvn goto baseDirFound
|
||||
cd ..
|
||||
IF "%WDIR%"=="%CD%" goto baseDirNotFound
|
||||
set WDIR=%CD%
|
||||
goto findBaseDir
|
||||
|
||||
:baseDirFound
|
||||
set MAVEN_PROJECTBASEDIR=%WDIR%
|
||||
cd "%EXEC_DIR%"
|
||||
goto endDetectBaseDir
|
||||
|
||||
:baseDirNotFound
|
||||
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
|
||||
cd "%EXEC_DIR%"
|
||||
|
||||
:endDetectBaseDir
|
||||
|
||||
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
|
||||
|
||||
@setlocal EnableExtensions EnableDelayedExpansion
|
||||
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
|
||||
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
|
||||
|
||||
:endReadAdditionalConfig
|
||||
|
||||
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
|
||||
|
||||
set WRAPPER_JAR=""%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar""
|
||||
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
@REM avoid using MAVEN_CMD_LINE_ARGS below since that would loose parameter escaping in %*
|
||||
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
|
||||
if ERRORLEVEL 1 goto error
|
||||
goto end
|
||||
|
||||
:error
|
||||
set ERROR_CODE=1
|
||||
|
||||
:end
|
||||
@endlocal & set ERROR_CODE=%ERROR_CODE%
|
||||
|
||||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
|
||||
@REM check for post script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
|
||||
if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
|
||||
:skipRcPost
|
||||
|
||||
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
|
||||
if "%MAVEN_BATCH_PAUSE%" == "on" pause
|
||||
|
||||
if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
|
||||
|
||||
exit /B %ERROR_CODE%
|
16
pom.xml
16
pom.xml
|
@ -288,7 +288,8 @@
|
|||
<profile>
|
||||
<id>integration-test</id>
|
||||
<properties>
|
||||
<gitlab.version>8.5.8</gitlab.version>
|
||||
<gitlab.version>8.17.4</gitlab.version>
|
||||
<postgres.version>9.5-1</postgres.version>
|
||||
</properties>
|
||||
<build>
|
||||
<plugins>
|
||||
|
@ -359,7 +360,7 @@
|
|||
<verbose>true</verbose>
|
||||
<images>
|
||||
<image>
|
||||
<name>sameersbn/postgresql:9.4-15</name>
|
||||
<name>sameersbn/postgresql:${postgres.version}</name>
|
||||
<alias>it-gitlab-postgres</alias>
|
||||
<run>
|
||||
<namingStrategy>alias</namingStrategy>
|
||||
|
@ -367,6 +368,7 @@
|
|||
<DB_NAME>gitlabhq_production</DB_NAME>
|
||||
<DB_USER>gitlab</DB_USER>
|
||||
<DB_PASS>password</DB_PASS>
|
||||
<DB_EXTENSION>pg_trgm</DB_EXTENSION>
|
||||
</env>
|
||||
<ports>
|
||||
<port>${postgres.port}:5432</port>
|
||||
|
@ -382,7 +384,9 @@
|
|||
</image>
|
||||
<image>
|
||||
<name>sameersbn/gitlab:${gitlab.version}</name>
|
||||
<alias>it-gitlab-gitlab</alias>
|
||||
<run>
|
||||
<namingStrategy>alias</namingStrategy>
|
||||
<links>
|
||||
<link>it-gitlab-postgres:postgresql</link>
|
||||
<link>it-gitlab-redis:redisio</link>
|
||||
|
@ -392,9 +396,15 @@
|
|||
<port>${gitlab.ssh.port}:22</port>
|
||||
</ports>
|
||||
<env>
|
||||
<DEBUG>false</DEBUG>
|
||||
<TZ>Asia/Kolkata</TZ>
|
||||
<GITLAB_TIMEZONE>Kolkata</GITLAB_TIMEZONE>
|
||||
<GITLAB_PORT>${gitlab.http.port}</GITLAB_PORT>
|
||||
<GITLAB_SSH_PORT>${gitlab.ssh.port}</GITLAB_SSH_PORT>
|
||||
<GITLAB_SECRETS_DB_KEY_BASE>abc123</GITLAB_SECRETS_DB_KEY_BASE>
|
||||
<GITLAB_SECRETS_DB_KEY_BASE>long-and-random-alpha-numeric-string</GITLAB_SECRETS_DB_KEY_BASE>
|
||||
<GITLAB_SECRETS_SECRET_KEY_BASE>long-and-random-alphanumeric-string</GITLAB_SECRETS_SECRET_KEY_BASE>
|
||||
<GITLAB_SECRETS_OTP_KEY_BASE>long-and-random-alpha-numeric-string</GITLAB_SECRETS_OTP_KEY_BASE>
|
||||
<GITLAB_HOST>172.17.0.1</GITLAB_HOST>
|
||||
</env>
|
||||
<wait>
|
||||
<http>
|
||||
|
|
|
@ -14,7 +14,7 @@ postgresql:
|
|||
gitlab:
|
||||
container_name: docker-gitlab
|
||||
restart: always
|
||||
image: sameersbn/gitlab:9.4.1
|
||||
image: sameersbn/gitlab:8.17.4
|
||||
links:
|
||||
- redis:redisio
|
||||
- postgresql:postgresql
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.dabsquared.gitlabjenkins;
|
||||
|
||||
|
||||
import com.dabsquared.gitlabjenkins.connection.GitLabConnection;
|
||||
import com.dabsquared.gitlabjenkins.connection.GitLabConnectionConfig;
|
||||
import com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty;
|
||||
|
@ -148,9 +149,11 @@ public class GitLabPushTrigger extends Trigger<Job<?, ?>> {
|
|||
GitLabPushTrigger.DescriptorImpl oldConfig = Trigger.all().get(GitLabPushTrigger.DescriptorImpl.class);
|
||||
if (!oldConfig.jobsMigrated) {
|
||||
GitLabConnectionConfig gitLabConfig = (GitLabConnectionConfig) Jenkins.getInstance().getDescriptor(GitLabConnectionConfig.class);
|
||||
gitLabConfig.getConnections().add(new GitLabConnection(oldConfig.gitlabHostUrl,
|
||||
gitLabConfig.getConnections().add(new GitLabConnection(
|
||||
oldConfig.gitlabHostUrl,
|
||||
oldConfig.gitlabHostUrl,
|
||||
oldConfig.gitlabApiToken,
|
||||
"autodetect",
|
||||
oldConfig.ignoreCertificateErrors,
|
||||
10,
|
||||
10));
|
||||
|
|
|
@ -1,39 +1,83 @@
|
|||
package com.dabsquared.gitlabjenkins.connection;
|
||||
|
||||
|
||||
import com.cloudbees.plugins.credentials.CredentialsMatchers;
|
||||
import com.cloudbees.plugins.credentials.CredentialsProvider;
|
||||
import com.cloudbees.plugins.credentials.CredentialsScope;
|
||||
import com.cloudbees.plugins.credentials.CredentialsStore;
|
||||
import com.cloudbees.plugins.credentials.SystemCredentialsProvider;
|
||||
import com.cloudbees.plugins.credentials.common.StandardCredentials;
|
||||
import com.cloudbees.plugins.credentials.domains.Domain;
|
||||
import com.cloudbees.plugins.credentials.domains.DomainRequirement;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClientBuilder;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.impl.AutodetectGitLabClientBuilder;
|
||||
import hudson.init.InitMilestone;
|
||||
import hudson.init.Initializer;
|
||||
import hudson.model.Item;
|
||||
import hudson.security.ACL;
|
||||
import hudson.util.Secret;
|
||||
import jenkins.model.Jenkins;
|
||||
import org.jenkinsci.plugins.plaincredentials.StringCredentials;
|
||||
import org.kohsuke.accmod.Restricted;
|
||||
import org.kohsuke.accmod.restrictions.NoExternalUse;
|
||||
import org.kohsuke.stapler.DataBoundConstructor;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials;
|
||||
import static com.dabsquared.gitlabjenkins.gitlab.api.GitLabClientBuilder.getGitLabClientBuilderById;
|
||||
|
||||
|
||||
/**
|
||||
* @author Robin Müller
|
||||
*/
|
||||
public class GitLabConnection {
|
||||
|
||||
private final String name;
|
||||
private final String url;
|
||||
private transient String apiToken;
|
||||
// TODO make final when migration code gets removed
|
||||
private String apiTokenId;
|
||||
private GitLabClientBuilder clientBuilder;
|
||||
private final boolean ignoreCertificateErrors;
|
||||
private final Integer connectionTimeout;
|
||||
private final Integer readTimeout;
|
||||
private transient GitLabClient apiCache;
|
||||
|
||||
public GitLabConnection(String name, String url, String apiTokenId, boolean ignoreCertificateErrors, Integer connectionTimeout, Integer readTimeout) {
|
||||
this(
|
||||
name,
|
||||
url,
|
||||
apiTokenId,
|
||||
new AutodetectGitLabClientBuilder(),
|
||||
ignoreCertificateErrors,
|
||||
connectionTimeout,
|
||||
readTimeout
|
||||
);
|
||||
}
|
||||
|
||||
@DataBoundConstructor
|
||||
public GitLabConnection(String name, String url, String apiTokenId, boolean ignoreCertificateErrors, Integer connectionTimeout, Integer readTimeout) {
|
||||
public GitLabConnection(String name, String url, String apiTokenId, String clientBuilderId, boolean ignoreCertificateErrors, Integer connectionTimeout, Integer readTimeout) {
|
||||
this(
|
||||
name,
|
||||
url,
|
||||
apiTokenId,
|
||||
getGitLabClientBuilderById(clientBuilderId),
|
||||
ignoreCertificateErrors,
|
||||
connectionTimeout,
|
||||
readTimeout
|
||||
);
|
||||
}
|
||||
|
||||
@Restricted(NoExternalUse.class)
|
||||
public GitLabConnection(String name, String url, String apiTokenId, GitLabClientBuilder clientBuilder, boolean ignoreCertificateErrors, Integer connectionTimeout, Integer readTimeout) {
|
||||
this.name = name;
|
||||
this.url = url;
|
||||
this.apiTokenId = apiTokenId;
|
||||
this.clientBuilder = clientBuilder;
|
||||
this.ignoreCertificateErrors = ignoreCertificateErrors;
|
||||
this.connectionTimeout = connectionTimeout;
|
||||
this.readTimeout = readTimeout;
|
||||
|
@ -51,6 +95,10 @@ public class GitLabConnection {
|
|||
return apiTokenId;
|
||||
}
|
||||
|
||||
public String getClientBuilderId() {
|
||||
return clientBuilder.id();
|
||||
}
|
||||
|
||||
public boolean isIgnoreCertificateErrors() {
|
||||
return ignoreCertificateErrors;
|
||||
}
|
||||
|
@ -63,10 +111,38 @@ public class GitLabConnection {
|
|||
return readTimeout;
|
||||
}
|
||||
|
||||
public GitLabClient getClient() {
|
||||
if (apiCache == null) {
|
||||
apiCache = clientBuilder.buildClient(url, getApiToken(apiTokenId), ignoreCertificateErrors, connectionTimeout, readTimeout);
|
||||
}
|
||||
|
||||
return apiCache;
|
||||
}
|
||||
|
||||
private String getApiToken(String apiTokenId) {
|
||||
StandardCredentials credentials = CredentialsMatchers.firstOrNull(
|
||||
lookupCredentials(StandardCredentials.class, (Item) null, ACL.SYSTEM, new ArrayList<DomainRequirement>()),
|
||||
CredentialsMatchers.withId(apiTokenId));
|
||||
if (credentials != null) {
|
||||
if (credentials instanceof GitLabApiToken) {
|
||||
return ((GitLabApiToken) credentials).getApiToken().getPlainText();
|
||||
}
|
||||
if (credentials instanceof StringCredentials) {
|
||||
return ((StringCredentials) credentials).getSecret().getPlainText();
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("No credentials found for credentialsId: " + apiTokenId);
|
||||
}
|
||||
|
||||
|
||||
protected GitLabConnection readResolve() {
|
||||
if (connectionTimeout == null || readTimeout == null) {
|
||||
return new GitLabConnection(name, url, apiTokenId, ignoreCertificateErrors, 10, 10);
|
||||
return new GitLabConnection(name, url, apiTokenId, new AutodetectGitLabClientBuilder(), ignoreCertificateErrors, 10, 10);
|
||||
}
|
||||
if (clientBuilder == null) {
|
||||
return new GitLabConnection(name, url, apiTokenId, new AutodetectGitLabClientBuilder(), ignoreCertificateErrors, connectionTimeout, readTimeout);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
package com.dabsquared.gitlabjenkins.connection;
|
||||
|
||||
|
||||
import com.cloudbees.plugins.credentials.Credentials;
|
||||
import com.cloudbees.plugins.credentials.CredentialsMatcher;
|
||||
import com.cloudbees.plugins.credentials.common.AbstractIdCredentialsListBoxModel;
|
||||
import com.cloudbees.plugins.credentials.common.StandardCredentials;
|
||||
import com.cloudbees.plugins.credentials.common.StandardListBoxModel;
|
||||
import com.cloudbees.plugins.credentials.domains.URIRequirementBuilder;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.GitLabClientBuilder;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabApi;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClientBuilder;
|
||||
import edu.umd.cs.findbugs.annotations.NonNull;
|
||||
import hudson.Extension;
|
||||
import hudson.model.Item;
|
||||
|
@ -29,6 +30,9 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.dabsquared.gitlabjenkins.gitlab.api.GitLabClientBuilder.getAllGitLabClientBuilders;
|
||||
|
||||
|
||||
/**
|
||||
* @author Robin Müller
|
||||
*/
|
||||
|
@ -38,7 +42,6 @@ public class GitLabConnectionConfig extends GlobalConfiguration {
|
|||
private Boolean useAuthenticatedEndpoint = true;
|
||||
private List<GitLabConnection> connections = new ArrayList<>();
|
||||
private transient Map<String, GitLabConnection> connectionMap = new HashMap<>();
|
||||
private transient Map<String, GitLabApi> clients = new HashMap<>();
|
||||
|
||||
public GitLabConnectionConfig() {
|
||||
load();
|
||||
|
@ -50,7 +53,6 @@ public class GitLabConnectionConfig extends GlobalConfiguration {
|
|||
connections = req.bindJSONToList(GitLabConnection.class, json.get("connections"));
|
||||
useAuthenticatedEndpoint = json.getBoolean("useAuthenticatedEndpoint");
|
||||
refreshConnectionMap();
|
||||
clients.clear();
|
||||
save();
|
||||
return super.configure(req, json);
|
||||
}
|
||||
|
@ -80,11 +82,11 @@ public class GitLabConnectionConfig extends GlobalConfiguration {
|
|||
}
|
||||
}
|
||||
|
||||
public GitLabApi getClient(String connectionName) {
|
||||
if (!clients.containsKey(connectionName) && connectionMap.containsKey(connectionName)) {
|
||||
clients.put(connectionName, GitLabClientBuilder.buildClient(connectionMap.get(connectionName)));
|
||||
public GitLabClient getClient(String connectionName) {
|
||||
if (!connectionMap.containsKey(connectionName)) {
|
||||
return null;
|
||||
}
|
||||
return clients.get(connectionName);
|
||||
return connectionMap.get(connectionName).getClient();
|
||||
}
|
||||
|
||||
public FormValidation doCheckName(@QueryParameter String id, @QueryParameter String value) {
|
||||
|
@ -131,11 +133,12 @@ public class GitLabConnectionConfig extends GlobalConfiguration {
|
|||
|
||||
public FormValidation doTestConnection(@QueryParameter String url,
|
||||
@QueryParameter String apiTokenId,
|
||||
@QueryParameter String clientBuilderId,
|
||||
@QueryParameter boolean ignoreCertificateErrors,
|
||||
@QueryParameter int connectionTimeout,
|
||||
@QueryParameter int readTimeout) {
|
||||
try {
|
||||
GitLabClientBuilder.buildClient(url, apiTokenId, ignoreCertificateErrors, connectionTimeout, readTimeout).headCurrentUser();
|
||||
new GitLabConnection("", url, apiTokenId, clientBuilderId, ignoreCertificateErrors, connectionTimeout, readTimeout).getClient().headCurrentUser();
|
||||
return FormValidation.ok(Messages.connection_success());
|
||||
} catch (WebApplicationException e) {
|
||||
return FormValidation.error(Messages.connection_error(e.getMessage()));
|
||||
|
@ -167,6 +170,15 @@ public class GitLabConnectionConfig extends GlobalConfiguration {
|
|||
return new StandardListBoxModel();
|
||||
}
|
||||
|
||||
public ListBoxModel doFillClientBuilderIdItems() {
|
||||
ListBoxModel model = new ListBoxModel();
|
||||
for (GitLabClientBuilder builder : getAllGitLabClientBuilders()) {
|
||||
model.add(builder.id());
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
private void refreshConnectionMap() {
|
||||
connectionMap.clear();
|
||||
for (GitLabConnection connection : connections) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.dabsquared.gitlabjenkins.connection;
|
||||
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabApi;
|
||||
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
|
||||
import hudson.Extension;
|
||||
import hudson.model.Job;
|
||||
import hudson.model.JobProperty;
|
||||
|
@ -30,7 +31,7 @@ public class GitLabConnectionProperty extends JobProperty<Job<?, ?>> {
|
|||
return gitLabConnection;
|
||||
}
|
||||
|
||||
public GitLabApi getClient() {
|
||||
public GitLabClient getClient() {
|
||||
if (StringUtils.isNotEmpty(gitLabConnection)) {
|
||||
GitLabConnectionConfig connectionConfig = (GitLabConnectionConfig) Jenkins.getInstance().getDescriptor(GitLabConnectionConfig.class);
|
||||
return connectionConfig != null ? connectionConfig.getClient(gitLabConnection) : null;
|
||||
|
@ -38,7 +39,7 @@ public class GitLabConnectionProperty extends JobProperty<Job<?, ?>> {
|
|||
return null;
|
||||
}
|
||||
|
||||
public static GitLabApi getClient(Run<?, ?> build) {
|
||||
public static GitLabClient getClient(Run<?, ?> build) {
|
||||
final GitLabConnectionProperty connectionProperty = build.getParent().getProperty(GitLabConnectionProperty.class);
|
||||
if (connectionProperty != null) {
|
||||
return connectionProperty.getClient();
|
||||
|
|
|
@ -1,134 +0,0 @@
|
|||
package com.dabsquared.gitlabjenkins.gitlab;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabApi;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabApiClient;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.Branch;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.BuildState;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.Label;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.MergeRequest;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.Project;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.User;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.hook.model.State;
|
||||
|
||||
/**
|
||||
* Implements {@link GitLabApi} by delegating REST-client calls to RESTEasy proxy.
|
||||
*
|
||||
* @author Alexander Leshkin
|
||||
*
|
||||
*/
|
||||
class GitLabApiExtension implements GitLabApi {
|
||||
|
||||
private GitLabApiClient client;
|
||||
private String gitlabHostUrl;
|
||||
|
||||
public GitLabApiExtension(GitLabApiClient client, String gitlabHostUrl) {
|
||||
this.client = client;
|
||||
this.gitlabHostUrl = gitlabHostUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGitLabHostUrl() {
|
||||
return gitlabHostUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Project createProject(String projectName) {
|
||||
return client.createProject(projectName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MergeRequest createMergeRequest(Integer projectId, String sourceBranch, String targetBranch, String title) {
|
||||
return client.createMergeRequest(projectId, sourceBranch, targetBranch, title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Project getProject(String projectName) {
|
||||
return client.getProject(projectName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Project updateProject(String projectId, String name, String path) {
|
||||
return client.updateProject(projectId, name, path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteProject(String projectId) {
|
||||
client.deleteProject(projectId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addProjectHook(String projectId, String url, Boolean pushEvents, Boolean mergeRequestEvents,
|
||||
Boolean noteEvents) {
|
||||
client.addProjectHook(projectId, url, pushEvents, mergeRequestEvents, noteEvents);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changeBuildStatus(String projectId, String sha, BuildState state, String ref, String context,
|
||||
String targetUrl, String description) {
|
||||
client.changeBuildStatus(projectId, sha, state, ref, context, targetUrl, description);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changeBuildStatus(Integer projectId, String sha, BuildState state, String ref, String context,
|
||||
String targetUrl, String description) {
|
||||
client.changeBuildStatus(projectId, sha, state, ref, context, targetUrl, description);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getCommit(String projectId, String sha) {
|
||||
client.getCommit(projectId, sha);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acceptMergeRequest(Integer projectId, Integer mergeRequestId, String mergeCommitMessage,
|
||||
boolean shouldRemoveSourceBranch) {
|
||||
client.acceptMergeRequest(projectId, mergeRequestId, mergeCommitMessage, shouldRemoveSourceBranch);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createMergeRequestNote(Integer projectId, Integer mergeRequestId, String body) {
|
||||
client.createMergeRequestNote(projectId, mergeRequestId, body);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MergeRequest> getMergeRequests(String projectId, State state, int page, int perPage) {
|
||||
return client.getMergeRequests(projectId, state, page, perPage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Branch> getBranches(String projectId) {
|
||||
return client.getBranches(projectId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Branch getBranch(String projectId, String branch) {
|
||||
return client.getBranch(projectId, branch);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void headCurrentUser() {
|
||||
client.headCurrentUser();
|
||||
}
|
||||
|
||||
@Override
|
||||
public User getCurrentUser() {
|
||||
return client.getCurrentUser();
|
||||
}
|
||||
|
||||
@Override
|
||||
public User addUser(String email, String username, String name, String password) {
|
||||
return client.addUser(email, username, name, password);
|
||||
}
|
||||
|
||||
@Override
|
||||
public User updateUser(String userId, String email, String username, String name, String password) {
|
||||
return client.updateUser(userId, email, username, name, password);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Label> getLabels(String projectId) {
|
||||
return client.getLabels(projectId);
|
||||
}
|
||||
}
|
|
@ -1,14 +1,54 @@
|
|||
package com.dabsquared.gitlabjenkins.gitlab.api;
|
||||
|
||||
/**
|
||||
* Extends REST-client interface to provide additional methods for plugin's code.
|
||||
*
|
||||
* @author Alexander Leshkin
|
||||
*
|
||||
*/
|
||||
public interface GitLabApi extends GitLabApiClient {
|
||||
/**
|
||||
* Returns GitLab host base url from plugin confugruation.
|
||||
*/
|
||||
String getGitLabHostUrl();
|
||||
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.*;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.hook.model.State;
|
||||
import org.kohsuke.accmod.Restricted;
|
||||
import org.kohsuke.accmod.restrictions.NoExternalUse;
|
||||
|
||||
import javax.ws.rs.PathParam;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@Restricted(NoExternalUse.class)
|
||||
public interface GitLabApi {
|
||||
Project createProject(String projectName);
|
||||
|
||||
MergeRequest createMergeRequest(Integer projectId, String sourceBranch, String targetBranch, String title);
|
||||
|
||||
Project getProject(String projectName);
|
||||
|
||||
Project updateProject(String projectId, String name, String path);
|
||||
|
||||
void deleteProject(String projectId);
|
||||
|
||||
void addProjectHook(String projectId, String url, Boolean pushEvents, Boolean mergeRequestEvents, Boolean noteEvents);
|
||||
|
||||
void changeBuildStatus(String projectId, String sha, BuildState state, String ref, String context, String targetUrl, String description);
|
||||
|
||||
void changeBuildStatus(Integer projectId, String sha, BuildState state, String ref, String context, String targetUrl, String description);
|
||||
|
||||
void getCommit(String projectId, String sha);
|
||||
|
||||
void acceptMergeRequest(Integer projectId, Integer mergeRequestId, String mergeCommitMessage, boolean shouldRemoveSourceBranch);
|
||||
|
||||
void createMergeRequestNote(Integer projectId, Integer mergeRequestId, String body);
|
||||
|
||||
List<MergeRequest> getMergeRequests(String projectId, State state, int page, int perPage);
|
||||
|
||||
List<Branch> getBranches(String projectId);
|
||||
|
||||
Branch getBranch(String projectId, String branch);
|
||||
|
||||
void headCurrentUser();
|
||||
|
||||
User getCurrentUser();
|
||||
|
||||
User addUser(String email, String username, String name, String password);
|
||||
|
||||
User updateUser(String userId, String email, String username, String name, String password);
|
||||
|
||||
List<Label> getLabels(String projectId);
|
||||
|
||||
List<Pipeline> getPipelines(@PathParam("projectId") String projectName);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
package com.dabsquared.gitlabjenkins.gitlab.api;
|
||||
|
||||
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.*;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.hook.model.State;
|
||||
import org.kohsuke.accmod.Restricted;
|
||||
import org.kohsuke.accmod.restrictions.NoExternalUse;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public final class GitLabClient implements GitLabApi {
|
||||
private final String hostUrl;
|
||||
private final GitLabApi api;
|
||||
|
||||
@Restricted(NoExternalUse.class)
|
||||
public GitLabClient(String hostUrl, GitLabApi api) {
|
||||
this.hostUrl = hostUrl;
|
||||
this.api = api;
|
||||
}
|
||||
|
||||
public final String getHostUrl() {
|
||||
return hostUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Project createProject(String projectName) {
|
||||
return api.createProject(projectName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MergeRequest createMergeRequest(Integer projectId, String sourceBranch, String targetBranch, String title) {
|
||||
return api.createMergeRequest(projectId, sourceBranch, targetBranch, title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Project getProject(String projectName) {
|
||||
return api.getProject(projectName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Project updateProject(String projectId, String name, String path) {
|
||||
return api.updateProject(projectId, name, path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteProject(String projectId) {
|
||||
api.deleteProject(projectId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addProjectHook(String projectId, String url, Boolean pushEvents, Boolean mergeRequestEvents, Boolean noteEvents) {
|
||||
api.addProjectHook(projectId, url, pushEvents, mergeRequestEvents, noteEvents);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changeBuildStatus(String projectId, String sha, BuildState state, String ref, String context, String targetUrl, String description) {
|
||||
api.changeBuildStatus(projectId, sha, state, ref, context, targetUrl, description);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changeBuildStatus(Integer projectId, String sha, BuildState state, String ref, String context, String targetUrl, String description) {
|
||||
api.changeBuildStatus(projectId, sha, state, ref, context, targetUrl, description);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getCommit(String projectId, String sha) {
|
||||
api.getCommit(projectId, sha);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acceptMergeRequest(Integer projectId, Integer mergeRequestId, String mergeCommitMessage, boolean shouldRemoveSourceBranch) {
|
||||
api.acceptMergeRequest(projectId, mergeRequestId, mergeCommitMessage, shouldRemoveSourceBranch);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createMergeRequestNote(Integer projectId, Integer mergeRequestId, String body) {
|
||||
api.createMergeRequestNote(projectId, mergeRequestId, body);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MergeRequest> getMergeRequests(String projectId, State state, int page, int perPage) {
|
||||
return api.getMergeRequests(projectId, state, page, perPage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Branch> getBranches(String projectId) {
|
||||
return api.getBranches(projectId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Branch getBranch(String projectId, String branch) {
|
||||
return api.getBranch(projectId, branch);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void headCurrentUser() {
|
||||
api.headCurrentUser();
|
||||
}
|
||||
|
||||
@Override
|
||||
public User getCurrentUser() {
|
||||
return api.getCurrentUser();
|
||||
}
|
||||
|
||||
@Override
|
||||
public User addUser(String email, String username, String name, String password) {
|
||||
return api.addUser(email, username, name, password);
|
||||
}
|
||||
|
||||
@Override
|
||||
public User updateUser(String userId, String email, String username, String name, String password) {
|
||||
return api.updateUser(userId, email, username, name, password);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Label> getLabels(String projectId) {
|
||||
return api.getLabels(projectId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Pipeline> getPipelines(String projectName) {
|
||||
return api.getPipelines(projectName);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package com.dabsquared.gitlabjenkins.gitlab.api;
|
||||
|
||||
|
||||
import hudson.ExtensionPoint;
|
||||
import jenkins.model.Jenkins;
|
||||
import org.kohsuke.accmod.Restricted;
|
||||
import org.kohsuke.accmod.restrictions.NoExternalUse;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import static java.util.Collections.sort;
|
||||
|
||||
@Restricted(NoExternalUse.class)
|
||||
public abstract class GitLabClientBuilder implements Comparable<GitLabClientBuilder>, ExtensionPoint, Serializable {
|
||||
public static GitLabClientBuilder getGitLabClientBuilderById(String id) {
|
||||
for (GitLabClientBuilder provider : getAllGitLabClientBuilders()) {
|
||||
if (provider.id().equals(id)) {
|
||||
return provider;
|
||||
}
|
||||
}
|
||||
|
||||
throw new NoSuchElementException("unknown client-builder-id: " + id);
|
||||
}
|
||||
|
||||
public static List<GitLabClientBuilder> getAllGitLabClientBuilders() {
|
||||
List<GitLabClientBuilder> builders = new ArrayList<>(Jenkins.getInstance().getExtensionList(GitLabClientBuilder.class));
|
||||
sort(builders);
|
||||
return builders;
|
||||
}
|
||||
|
||||
private final String id;
|
||||
|
||||
protected GitLabClientBuilder(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public final String id() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public abstract GitLabClient buildClient(String url, String token, boolean ignoreCertificateErrors, int connectionTimeout, int readTimeout);
|
||||
|
||||
@Override
|
||||
public final int compareTo(@Nonnull GitLabClientBuilder other) {
|
||||
return id().compareTo(other.id());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package com.dabsquared.gitlabjenkins.gitlab.api.impl;
|
||||
|
||||
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClientBuilder;
|
||||
import hudson.Extension;
|
||||
import org.kohsuke.accmod.Restricted;
|
||||
import org.kohsuke.accmod.restrictions.NoExternalUse;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.ws.rs.NotFoundException;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
|
||||
@Extension
|
||||
@Restricted(NoExternalUse.class)
|
||||
public final class AutodetectGitLabClientBuilder extends GitLabClientBuilder {
|
||||
public AutodetectGitLabClientBuilder() {
|
||||
super("autodetect");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public GitLabClient buildClient(String url, String token, boolean ignoreCertificateErrors, int connectionTimeout, int readTimeout) {
|
||||
return autodetectOrDie(url, token, ignoreCertificateErrors, connectionTimeout, readTimeout);
|
||||
}
|
||||
|
||||
private GitLabClient autodetectOrDie(String url, String token, boolean ignoreCertificateErrors, int connectionTimeout, int readTimeout) {
|
||||
GitLabClient client = autodetect(url, token, ignoreCertificateErrors, connectionTimeout, readTimeout);
|
||||
if (client != null) {
|
||||
return client;
|
||||
}
|
||||
|
||||
throw new NoSuchElementException("no client-builder found that supports server at " + url);
|
||||
}
|
||||
|
||||
private GitLabClient autodetect(String url, String token, boolean ignoreCertificateErrors, int connectionTimeout, int readTimeout) {
|
||||
for (GitLabClientBuilder candidate : getAllGitLabClientBuilders()) {
|
||||
if (candidate == this) {
|
||||
continue; // ignore ourself...
|
||||
}
|
||||
GitLabClient client = candidate.buildClient(url, token, ignoreCertificateErrors, connectionTimeout, readTimeout);
|
||||
try {
|
||||
client.headCurrentUser();
|
||||
return client;
|
||||
} catch (NotFoundException ignored) {
|
||||
// api-endpoint not found (== api-level not supported by this client)
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,12 +1,10 @@
|
|||
package com.dabsquared.gitlabjenkins.gitlab;
|
||||
package com.dabsquared.gitlabjenkins.gitlab.api.impl;
|
||||
|
||||
import com.cloudbees.plugins.credentials.CredentialsMatchers;
|
||||
import com.cloudbees.plugins.credentials.common.StandardCredentials;
|
||||
import com.cloudbees.plugins.credentials.domains.DomainRequirement;
|
||||
import com.dabsquared.gitlabjenkins.connection.GitLabApiToken;
|
||||
import com.dabsquared.gitlabjenkins.connection.GitLabConnection;
|
||||
|
||||
import com.dabsquared.gitlabjenkins.gitlab.JacksonConfig;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabApi;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabApiClient;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClientBuilder;
|
||||
import com.dabsquared.gitlabjenkins.util.JsonUtil;
|
||||
import com.dabsquared.gitlabjenkins.util.LoggerUtil;
|
||||
import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
|
||||
|
@ -16,8 +14,6 @@ import com.google.common.collect.FluentIterable;
|
|||
import hudson.ProxyConfiguration;
|
||||
import hudson.init.InitMilestone;
|
||||
import hudson.init.Initializer;
|
||||
import hudson.model.Item;
|
||||
import hudson.security.ACL;
|
||||
import jenkins.model.Jenkins;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
@ -30,8 +26,10 @@ import org.jboss.resteasy.client.jaxrs.ClientHttpEngine;
|
|||
import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine;
|
||||
import org.jboss.resteasy.plugins.providers.JaxrsFormProvider;
|
||||
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
||||
import org.jenkinsci.plugins.plaincredentials.StringCredentials;
|
||||
import org.kohsuke.accmod.Restricted;
|
||||
import org.kohsuke.accmod.restrictions.NoExternalUse;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.Priority;
|
||||
import javax.ws.rs.Priorities;
|
||||
|
@ -47,96 +45,92 @@ import java.io.IOException;
|
|||
import java.io.InputStream;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.Proxy;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials;
|
||||
|
||||
/**
|
||||
* @author Robin Müller
|
||||
*/
|
||||
public class GitLabClientBuilder {
|
||||
|
||||
private final static Logger LOGGER = Logger.getLogger(GitLabClientBuilder.class.getName());
|
||||
@Restricted(NoExternalUse.class)
|
||||
public class ResteasyGitLabClientBuilder extends GitLabClientBuilder {
|
||||
private static final Logger LOGGER = Logger.getLogger(ResteasyGitLabClientBuilder.class.getName());
|
||||
private static final String PRIVATE_TOKEN = "PRIVATE-TOKEN";
|
||||
|
||||
public static GitLabApi buildClient(String gitlabHostUrl, final String gitlabApiTokenId, boolean ignoreCertificateErrors, int connectionTimeout, int readTimeout) {
|
||||
ResteasyClientBuilder builder = new ResteasyClientBuilder();
|
||||
if (ignoreCertificateErrors) {
|
||||
builder.hostnameVerification(ResteasyClientBuilder.HostnameVerificationPolicy.ANY);
|
||||
builder.disableTrustManager();
|
||||
}
|
||||
ProxyConfiguration proxyConfiguration = Jenkins.getActiveInstance().proxy;
|
||||
Proxy proxy = proxyConfiguration == null ? Proxy.NO_PROXY : proxyConfiguration.createProxy(getHost(gitlabHostUrl));
|
||||
if (!proxy.equals(Proxy.NO_PROXY)) {
|
||||
InetSocketAddress address = (InetSocketAddress) proxy.address();
|
||||
builder.defaultProxy(address.getHostName().replaceFirst("^.*://", ""),
|
||||
address.getPort(),
|
||||
address.getHostName().startsWith("https") ? "https" : "http",
|
||||
proxyConfiguration.getUserName(),
|
||||
proxyConfiguration.getPassword());
|
||||
}
|
||||
|
||||
GitLabApiClient apiClient = builder
|
||||
.connectionPoolSize(60)
|
||||
.maxPooledPerRoute(30)
|
||||
.establishConnectionTimeout(connectionTimeout, TimeUnit.SECONDS)
|
||||
.socketTimeout(readTimeout, TimeUnit.SECONDS)
|
||||
.register(new JacksonJsonProvider())
|
||||
.register(new JacksonConfig())
|
||||
.register(new ApiHeaderTokenFilter(getApiToken(gitlabApiTokenId)))
|
||||
.register(new LoggingFilter())
|
||||
.register(new RemoveAcceptEncodingFilter())
|
||||
.register(new JaxrsFormProvider())
|
||||
.build().target(gitlabHostUrl)
|
||||
.proxyBuilder(GitLabApiClient.class)
|
||||
.classloader(GitLabApiClient.class.getClassLoader())
|
||||
.build();
|
||||
return new GitLabApiExtension(apiClient, gitlabHostUrl);
|
||||
}
|
||||
|
||||
public static GitLabApi buildClient(GitLabConnection connection) {
|
||||
return buildClient(connection.getUrl(),
|
||||
connection.getApiTokenId(),
|
||||
connection.isIgnoreCertificateErrors(),
|
||||
connection.getConnectionTimeout(),
|
||||
connection.getReadTimeout());
|
||||
}
|
||||
|
||||
@Initializer(before = InitMilestone.PLUGINS_STARTED)
|
||||
public static void setRuntimeDelegate() {
|
||||
RuntimeDelegate.setInstance(new ResteasyProviderFactory());
|
||||
}
|
||||
|
||||
private static String getHost(String gitlabUrl) {
|
||||
private final Class<? extends GitLabApi> apiProxyClass;
|
||||
|
||||
ResteasyGitLabClientBuilder(String id, Class<? extends GitLabApi> apiProxyClass) {
|
||||
super(id);
|
||||
this.apiProxyClass = apiProxyClass;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public final GitLabClient buildClient(String url, String token, boolean ignoreCertificateErrors, int connectionTimeout, int readTimeout) {
|
||||
return buildClient(url, token, apiProxyClass, ignoreCertificateErrors, connectionTimeout, readTimeout);
|
||||
}
|
||||
|
||||
private GitLabClient buildClient(String url, String apiToken, Class<? extends GitLabApi> proxyClass, boolean ignoreCertificateErrors, int connectionTimeout, int readTimeout) {
|
||||
Jenkins jenkins = Jenkins.getInstance();
|
||||
ProxyConfiguration proxy = (jenkins != null) ? jenkins.proxy : null;
|
||||
return buildClient(
|
||||
url,
|
||||
apiToken,
|
||||
proxyClass,
|
||||
proxy,
|
||||
ignoreCertificateErrors,
|
||||
connectionTimeout,
|
||||
readTimeout
|
||||
);
|
||||
}
|
||||
|
||||
private GitLabClient buildClient(String url, String apiToken, Class<? extends GitLabApi> proxyClass, ProxyConfiguration httpProxyConfig, boolean ignoreCertificateErrors, int connectionTimeout, int readTimeout) {
|
||||
ResteasyClientBuilder builder = new ResteasyClientBuilder();
|
||||
if (ignoreCertificateErrors) {
|
||||
builder.hostnameVerification(ResteasyClientBuilder.HostnameVerificationPolicy.ANY);
|
||||
builder.disableTrustManager();
|
||||
}
|
||||
|
||||
if (httpProxyConfig != null) {
|
||||
InetSocketAddress address = (InetSocketAddress) httpProxyConfig.createProxy(getHost(url)).address();
|
||||
builder.defaultProxy(address.getHostName().replaceFirst("^.*://", ""),
|
||||
address.getPort(),
|
||||
address.getHostName().startsWith("https") ? "https" : "http",
|
||||
httpProxyConfig.getUserName(),
|
||||
httpProxyConfig.getPassword());
|
||||
}
|
||||
|
||||
GitLabApi apiProxy = builder
|
||||
.connectionPoolSize(60)
|
||||
.maxPooledPerRoute(30)
|
||||
.establishConnectionTimeout(connectionTimeout, TimeUnit.SECONDS)
|
||||
.socketTimeout(readTimeout, TimeUnit.SECONDS)
|
||||
.register(new JacksonJsonProvider())
|
||||
.register(new JacksonConfig())
|
||||
.register(new ApiHeaderTokenFilter(apiToken))
|
||||
.register(new LoggingFilter())
|
||||
.register(new RemoveAcceptEncodingFilter())
|
||||
.register(new JaxrsFormProvider())
|
||||
.build().target(url)
|
||||
.proxyBuilder(proxyClass)
|
||||
.classloader(proxyClass.getClassLoader())
|
||||
.build();
|
||||
return new GitLabClient(url, apiProxy);
|
||||
}
|
||||
|
||||
private String getHost(String url) {
|
||||
try {
|
||||
return new URL(gitlabUrl).getHost();
|
||||
return new URL(url).getHost();
|
||||
} catch (MalformedURLException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static String getApiToken(String apiTokenId) {
|
||||
StandardCredentials credentials = CredentialsMatchers.firstOrNull(
|
||||
lookupCredentials(StandardCredentials.class, (Item) null, ACL.SYSTEM, new ArrayList<DomainRequirement>()),
|
||||
CredentialsMatchers.withId(apiTokenId));
|
||||
if (credentials != null) {
|
||||
if (credentials instanceof GitLabApiToken) {
|
||||
return ((GitLabApiToken) credentials).getApiToken().getPlainText();
|
||||
}
|
||||
if (credentials instanceof StringCredentials) {
|
||||
return ((StringCredentials) credentials).getSecret().getPlainText();
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("No credentials found for credentialsId: " + apiTokenId);
|
||||
}
|
||||
|
||||
@Priority(Priorities.HEADER_DECORATOR)
|
||||
private static class ApiHeaderTokenFilter implements ClientRequestFilter {
|
||||
private final String gitlabApiToken;
|
||||
|
@ -232,7 +226,6 @@ public class GitLabClientBuilder {
|
|||
}
|
||||
|
||||
private static class ResteasyClientBuilder extends org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder {
|
||||
|
||||
private CredentialsProvider proxyCredentials;
|
||||
|
||||
ResteasyClientBuilder defaultProxy(String hostname, int port, final String scheme, String username, String password) {
|
||||
|
@ -244,6 +237,7 @@ public class GitLabClientBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
protected ClientHttpEngine initDefaultEngine() {
|
||||
ApacheHttpClient4Engine httpEngine = (ApacheHttpClient4Engine) super.initDefaultEngine();
|
|
@ -1,11 +1,8 @@
|
|||
package com.dabsquared.gitlabjenkins.gitlab.api;
|
||||
package com.dabsquared.gitlabjenkins.gitlab.api.impl;
|
||||
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.Branch;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.BuildState;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.Label;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.MergeRequest;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.Project;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.User;
|
||||
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabApi;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.*;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.hook.model.State;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
|
@ -22,22 +19,26 @@ import javax.ws.rs.QueryParam;
|
|||
import javax.ws.rs.core.MediaType;
|
||||
import java.util.List;
|
||||
|
||||
import static com.dabsquared.gitlabjenkins.gitlab.api.impl.V3GitLabClientBuilder.ID;
|
||||
|
||||
|
||||
/**
|
||||
* @author Robin Müller
|
||||
*/
|
||||
@Path("/api/v3")
|
||||
public interface GitLabApiClient {
|
||||
|
||||
@Path("/api/" + ID)
|
||||
interface V3GitLabApiProxy extends GitLabApi {
|
||||
@POST
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||
@Path("/projects")
|
||||
@Override
|
||||
Project createProject(@FormParam("name") String projectName);
|
||||
|
||||
@POST
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||
@Path("/projects/{projectId}/merge_requests")
|
||||
@Override
|
||||
MergeRequest createMergeRequest(
|
||||
@PathParam("projectId") Integer projectId,
|
||||
@FormParam("source_branch") String sourceBranch,
|
||||
|
@ -47,24 +48,28 @@ public interface GitLabApiClient {
|
|||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/projects/{projectName}")
|
||||
@Override
|
||||
Project getProject(@PathParam("projectName") String projectName);
|
||||
|
||||
@PUT
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||
@Path("/projects/{projectId}")
|
||||
@Override
|
||||
Project updateProject(@PathParam("projectId") String projectId,
|
||||
@FormParam("name") String name,
|
||||
@FormParam("path") String path);
|
||||
|
||||
@DELETE
|
||||
@Path("/projects/{projectId}")
|
||||
@Override
|
||||
void deleteProject(@PathParam("projectId") String projectId);
|
||||
|
||||
@POST
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||
@Path("/projects/{projectId}/hooks")
|
||||
@Override
|
||||
void addProjectHook(@PathParam("projectId") String projectId,
|
||||
@FormParam("url") String url,
|
||||
@FormParam("push_events") Boolean pushEvents,
|
||||
|
@ -75,6 +80,7 @@ public interface GitLabApiClient {
|
|||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||
@Path("/projects/{projectId}/statuses/{sha}")
|
||||
@Override
|
||||
void changeBuildStatus(@PathParam("projectId") String projectId,
|
||||
@PathParam("sha") String sha,
|
||||
@FormParam("state") BuildState state,
|
||||
|
@ -87,6 +93,7 @@ public interface GitLabApiClient {
|
|||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||
@Path("/projects/{projectId}/statuses/{sha}")
|
||||
@Override
|
||||
void changeBuildStatus(@PathParam("projectId") Integer projectId,
|
||||
@PathParam("sha") String sha,
|
||||
@FormParam("state") BuildState state,
|
||||
|
@ -98,6 +105,7 @@ public interface GitLabApiClient {
|
|||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/projects/{projectId}/repository/commits/{sha}")
|
||||
@Override
|
||||
void getCommit(@PathParam("projectId") String projectId, @PathParam("sha") String sha);
|
||||
|
||||
|
||||
|
@ -105,6 +113,7 @@ public interface GitLabApiClient {
|
|||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||
@Path("/projects/{projectId}/merge_requests/{mergeRequestId}/merge")
|
||||
@Override
|
||||
void acceptMergeRequest(@PathParam("projectId") Integer projectId,
|
||||
@PathParam("mergeRequestId") Integer mergeRequestId,
|
||||
@FormParam("merge_commit_message") String mergeCommitMessage,
|
||||
|
@ -114,6 +123,7 @@ public interface GitLabApiClient {
|
|||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||
@Path("/projects/{projectId}/merge_requests/{mergeRequestId}/notes")
|
||||
@Override
|
||||
void createMergeRequestNote(@PathParam("projectId") Integer projectId,
|
||||
@PathParam("mergeRequestId") Integer mergeRequestId,
|
||||
@FormParam("body") String body);
|
||||
|
@ -121,6 +131,7 @@ public interface GitLabApiClient {
|
|||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/projects/{projectId}/merge_requests")
|
||||
@Override
|
||||
List<MergeRequest> getMergeRequests(@PathParam("projectId") String projectId,
|
||||
@QueryParam("state") State state,
|
||||
@QueryParam("page") int page,
|
||||
|
@ -129,28 +140,33 @@ public interface GitLabApiClient {
|
|||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/projects/{projectId}/repository/branches")
|
||||
@Override
|
||||
List<Branch> getBranches(@PathParam("projectId") String projectId);
|
||||
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/projects/{projectId}/repository/branches/{branch}")
|
||||
@Override
|
||||
Branch getBranch(@PathParam("projectId") String projectId,
|
||||
@PathParam("branch") String branch);
|
||||
|
||||
@HEAD
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/user")
|
||||
@Override
|
||||
void headCurrentUser();
|
||||
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/user")
|
||||
@Override
|
||||
User getCurrentUser();
|
||||
|
||||
@POST
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||
@Path("/users")
|
||||
@Override
|
||||
User addUser(@FormParam("email") String email,
|
||||
@FormParam("username") String username,
|
||||
@FormParam("name") String name,
|
||||
|
@ -160,6 +176,7 @@ public interface GitLabApiClient {
|
|||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||
@Path("/users/{userId}")
|
||||
@Override
|
||||
User updateUser(@PathParam("userId") String userId,
|
||||
@FormParam("email") String email,
|
||||
@FormParam("username") String username,
|
||||
|
@ -169,5 +186,12 @@ public interface GitLabApiClient {
|
|||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/projects/{projectId}/labels")
|
||||
@Override
|
||||
List<Label> getLabels(@PathParam("projectId") String projectId);
|
||||
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/projects/{projectId}/pipelines")
|
||||
@Override
|
||||
List<Pipeline> getPipelines(@PathParam("projectId") String projectId);
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.dabsquared.gitlabjenkins.gitlab.api.impl;
|
||||
|
||||
|
||||
import hudson.Extension;
|
||||
import org.kohsuke.accmod.Restricted;
|
||||
import org.kohsuke.accmod.restrictions.NoExternalUse;
|
||||
|
||||
|
||||
@Extension
|
||||
@Restricted(NoExternalUse.class)
|
||||
public final class V3GitLabClientBuilder extends ResteasyGitLabClientBuilder {
|
||||
static final String ID = "v3";
|
||||
|
||||
public V3GitLabClientBuilder() {
|
||||
super(ID, V3GitLabApiProxy.class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,197 @@
|
|||
package com.dabsquared.gitlabjenkins.gitlab.api.impl;
|
||||
|
||||
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabApi;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.*;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.hook.model.State;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.FormParam;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.HEAD;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import java.util.List;
|
||||
|
||||
import static com.dabsquared.gitlabjenkins.gitlab.api.impl.V4GitLabClientBuilder.ID;
|
||||
|
||||
|
||||
/**
|
||||
* @author Robin Müller
|
||||
*/
|
||||
@Path("/api/" + ID)
|
||||
interface V4GitLabApiProxy extends GitLabApi {
|
||||
@POST
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||
@Path("/projects")
|
||||
@Override
|
||||
Project createProject(@FormParam("name") String projectName);
|
||||
|
||||
@POST
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||
@Path("/projects/{projectId}/merge_requests")
|
||||
@Override
|
||||
MergeRequest createMergeRequest(
|
||||
@PathParam("projectId") Integer projectId,
|
||||
@FormParam("source_branch") String sourceBranch,
|
||||
@FormParam("target_branch") String targetBranch,
|
||||
@FormParam("title") String title);
|
||||
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/projects/{projectName}")
|
||||
@Override
|
||||
Project getProject(@PathParam("projectName") String projectName);
|
||||
|
||||
@PUT
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||
@Path("/projects/{projectId}")
|
||||
@Override
|
||||
Project updateProject(@PathParam("projectId") String projectId,
|
||||
@FormParam("name") String name,
|
||||
@FormParam("path") String path);
|
||||
|
||||
@DELETE
|
||||
@Path("/projects/{projectId}")
|
||||
@Override
|
||||
void deleteProject(@PathParam("projectId") String projectId);
|
||||
|
||||
@POST
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||
@Path("/projects/{projectId}/hooks")
|
||||
@Override
|
||||
void addProjectHook(@PathParam("projectId") String projectId,
|
||||
@FormParam("url") String url,
|
||||
@FormParam("push_events") Boolean pushEvents,
|
||||
@FormParam("merge_requests_events") Boolean mergeRequestEvents,
|
||||
@FormParam("note_events") Boolean noteEvents);
|
||||
|
||||
@POST
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||
@Path("/projects/{projectId}/statuses/{sha}")
|
||||
@Override
|
||||
void changeBuildStatus(@PathParam("projectId") String projectId,
|
||||
@PathParam("sha") String sha,
|
||||
@FormParam("state") BuildState state,
|
||||
@FormParam("ref") String ref,
|
||||
@FormParam("context") String context,
|
||||
@FormParam("target_url") String targetUrl,
|
||||
@FormParam("description") String description);
|
||||
|
||||
@POST
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||
@Path("/projects/{projectId}/statuses/{sha}")
|
||||
@Override
|
||||
void changeBuildStatus(@PathParam("projectId") Integer projectId,
|
||||
@PathParam("sha") String sha,
|
||||
@FormParam("state") BuildState state,
|
||||
@FormParam("ref") String ref,
|
||||
@FormParam("context") String context,
|
||||
@FormParam("target_url") String targetUrl,
|
||||
@FormParam("description") String description);
|
||||
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/projects/{projectId}/repository/commits/{sha}")
|
||||
@Override
|
||||
void getCommit(@PathParam("projectId") String projectId, @PathParam("sha") String sha);
|
||||
|
||||
|
||||
@PUT
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||
@Path("/projects/{projectId}/merge_requests/{mergeRequestIid}/merge")
|
||||
@Override
|
||||
void acceptMergeRequest(@PathParam("projectId") Integer projectId,
|
||||
@PathParam("mergeRequestIid") Integer mergeRequestIid,
|
||||
@FormParam("merge_commit_message") String mergeCommitMessage,
|
||||
@FormParam("should_remove_source_branch") boolean shouldRemoveSourceBranch);
|
||||
|
||||
@POST
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||
@Path("/projects/{projectId}/merge_requests/{mergeRequestIid}/notes")
|
||||
@Override
|
||||
void createMergeRequestNote(@PathParam("projectId") Integer projectId,
|
||||
@PathParam("mergeRequestIid") Integer mergeRequestIid,
|
||||
@FormParam("body") String body);
|
||||
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/projects/{projectId}/merge_requests")
|
||||
@Override
|
||||
List<MergeRequest> getMergeRequests(@PathParam("projectId") String projectId,
|
||||
@QueryParam("state") State state,
|
||||
@QueryParam("page") int page,
|
||||
@QueryParam("per_page") int perPage);
|
||||
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/projects/{projectId}/repository/branches")
|
||||
@Override
|
||||
List<Branch> getBranches(@PathParam("projectId") String projectId);
|
||||
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/projects/{projectId}/repository/branches/{branch}")
|
||||
@Override
|
||||
Branch getBranch(@PathParam("projectId") String projectId,
|
||||
@PathParam("branch") String branch);
|
||||
|
||||
@HEAD
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/user")
|
||||
@Override
|
||||
void headCurrentUser();
|
||||
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/user")
|
||||
@Override
|
||||
User getCurrentUser();
|
||||
|
||||
@POST
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||
@Path("/users")
|
||||
@Override
|
||||
User addUser(@FormParam("email") String email,
|
||||
@FormParam("username") String username,
|
||||
@FormParam("name") String name,
|
||||
@FormParam("password") String password);
|
||||
|
||||
@PUT
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||
@Path("/users/{userId}")
|
||||
@Override
|
||||
User updateUser(@PathParam("userId") String userId,
|
||||
@FormParam("email") String email,
|
||||
@FormParam("username") String username,
|
||||
@FormParam("name") String name,
|
||||
@FormParam("password") String password);
|
||||
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/projects/{projectId}/labels")
|
||||
@Override
|
||||
List<Label> getLabels(@PathParam("projectId") String projectId);
|
||||
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/projects/{projectId}/pipelines")
|
||||
@Override
|
||||
List<Pipeline> getPipelines(@PathParam("projectId") String projectId);
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.dabsquared.gitlabjenkins.gitlab.api.impl;
|
||||
|
||||
|
||||
import hudson.Extension;
|
||||
import org.kohsuke.accmod.Restricted;
|
||||
import org.kohsuke.accmod.restrictions.NoExternalUse;
|
||||
|
||||
|
||||
@Extension
|
||||
@Restricted(NoExternalUse.class)
|
||||
public final class V4GitLabClientBuilder extends ResteasyGitLabClientBuilder {
|
||||
static final String ID = "v4";
|
||||
|
||||
public V4GitLabClientBuilder() {
|
||||
super(ID, V4GitLabApiProxy.class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package com.dabsquared.gitlabjenkins.gitlab.api.model;
|
||||
|
||||
import net.karneim.pojobuilder.GeneratePojoBuilder;
|
||||
|
||||
@GeneratePojoBuilder(intoPackage = "*.builder.generated", withFactoryMethod = "*")
|
||||
public class Pipeline {
|
||||
private Integer id;
|
||||
private String sha;
|
||||
private String status;
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getSha() {
|
||||
return sha;
|
||||
}
|
||||
|
||||
public void setSha(String sha) {
|
||||
this.sha = sha;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package com.dabsquared.gitlabjenkins.publisher;
|
||||
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabApi;
|
||||
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
|
||||
import hudson.Extension;
|
||||
import hudson.model.AbstractProject;
|
||||
import hudson.model.Result;
|
||||
|
@ -44,7 +45,7 @@ public class GitLabAcceptMergeRequestPublisher extends MergeRequestNotifier {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void perform(Run<?, ?> build, TaskListener listener, GitLabApi client, Integer projectId, Integer mergeRequestId) {
|
||||
protected void perform(Run<?, ?> build, TaskListener listener, GitLabClient client, Integer projectId, Integer mergeRequestId) {
|
||||
try {
|
||||
if (build.getResult() == Result.SUCCESS) {
|
||||
client.acceptMergeRequest(projectId, mergeRequestId, "Merge Request accepted by jenkins build success", false);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.dabsquared.gitlabjenkins.publisher;
|
||||
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabApi;
|
||||
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
|
||||
import hudson.Extension;
|
||||
import hudson.Util;
|
||||
import hudson.model.AbstractProject;
|
||||
|
@ -107,7 +108,7 @@ public class GitLabMessagePublisher extends MergeRequestNotifier {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void perform(Run<?, ?> build, TaskListener listener, GitLabApi client, Integer projectId, Integer mergeRequestId) {
|
||||
protected void perform(Run<?, ?> build, TaskListener listener, GitLabClient client, Integer projectId, Integer mergeRequestId) {
|
||||
try {
|
||||
if (!onlyForFailure || build.getResult() == Result.FAILURE || build.getResult() == Result.UNSTABLE) {
|
||||
client.createMergeRequestNote(projectId, mergeRequestId, getNote(build, listener));
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.dabsquared.gitlabjenkins.publisher;
|
||||
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabApi;
|
||||
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
|
||||
import hudson.Extension;
|
||||
import hudson.model.AbstractProject;
|
||||
import hudson.model.Result;
|
||||
|
@ -44,7 +45,7 @@ public class GitLabVotePublisher extends MergeRequestNotifier {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void perform(Run<?, ?> build, TaskListener listener, GitLabApi client, Integer projectId, Integer mergeRequestId) {
|
||||
protected void perform(Run<?, ?> build, TaskListener listener, GitLabClient client, Integer projectId, Integer mergeRequestId) {
|
||||
try {
|
||||
client.createMergeRequestNote(projectId, mergeRequestId, getResultIcon(build.getResult()));
|
||||
} catch (WebApplicationException | ProcessingException e) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package com.dabsquared.gitlabjenkins.publisher;
|
||||
|
||||
import com.dabsquared.gitlabjenkins.cause.GitLabWebHookCause;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabApi;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
|
||||
import hudson.Launcher;
|
||||
import hudson.matrix.MatrixAggregatable;
|
||||
import hudson.matrix.MatrixAggregator;
|
||||
|
@ -27,7 +27,7 @@ public abstract class MergeRequestNotifier extends Notifier implements MatrixAgg
|
|||
|
||||
@Override
|
||||
public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
|
||||
GitLabApi client = getClient(build);
|
||||
GitLabClient client = getClient(build);
|
||||
if (client == null) {
|
||||
listener.getLogger().println("No GitLab connection configured");
|
||||
return true;
|
||||
|
@ -50,7 +50,7 @@ public abstract class MergeRequestNotifier extends Notifier implements MatrixAgg
|
|||
};
|
||||
}
|
||||
|
||||
protected abstract void perform(Run<?, ?> build, TaskListener listener, GitLabApi client, Integer projectId, Integer mergeRequestId);
|
||||
protected abstract void perform(Run<?, ?> build, TaskListener listener, GitLabClient client, Integer projectId, Integer mergeRequestId);
|
||||
|
||||
Integer getProjectId(Run<?, ?> build) {
|
||||
GitLabWebHookCause cause = build.getCause(GitLabWebHookCause.class);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.dabsquared.gitlabjenkins.service;
|
||||
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabApi;
|
||||
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.Branch;
|
||||
import com.dabsquared.gitlabjenkins.util.LoggerUtil;
|
||||
import com.dabsquared.gitlabjenkins.util.ProjectIdUtil;
|
||||
|
@ -37,7 +38,7 @@ public class GitLabProjectBranchesService {
|
|||
return gitLabProjectBranchesService;
|
||||
}
|
||||
|
||||
public List<String> getBranches(GitLabApi client, String sourceRepositoryString) {
|
||||
public List<String> getBranches(GitLabClient client, String sourceRepositoryString) {
|
||||
synchronized (projectBranchCache) {
|
||||
try {
|
||||
return projectBranchCache.get(sourceRepositoryString, new BranchNamesLoader(client, sourceRepositoryString));
|
||||
|
@ -54,10 +55,10 @@ public class GitLabProjectBranchesService {
|
|||
}
|
||||
|
||||
private static class BranchNamesLoader implements Callable<List<String>> {
|
||||
private final GitLabApi client;
|
||||
private final GitLabClient client;
|
||||
private final String sourceRepository;
|
||||
|
||||
private BranchNamesLoader(GitLabApi client, String sourceRepository) {
|
||||
private BranchNamesLoader(GitLabClient client, String sourceRepository) {
|
||||
this.client = client;
|
||||
this.sourceRepository = sourceRepository;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.dabsquared.gitlabjenkins.service;
|
||||
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabApi;
|
||||
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.Label;
|
||||
import com.dabsquared.gitlabjenkins.util.LoggerUtil;
|
||||
import com.dabsquared.gitlabjenkins.util.ProjectIdUtil;
|
||||
|
@ -37,7 +38,7 @@ public class GitLabProjectLabelsService {
|
|||
return instance;
|
||||
}
|
||||
|
||||
public List<String> getLabels(GitLabApi client, String sourceRepositoryString) {
|
||||
public List<String> getLabels(GitLabClient client, String sourceRepositoryString) {
|
||||
synchronized (projectLabelsCache) {
|
||||
try {
|
||||
return projectLabelsCache.get(sourceRepositoryString, new LabelNamesLoader(client, sourceRepositoryString));
|
||||
|
@ -54,10 +55,10 @@ public class GitLabProjectLabelsService {
|
|||
}
|
||||
|
||||
private static class LabelNamesLoader implements Callable<List<String>> {
|
||||
private final GitLabApi client;
|
||||
private final GitLabClient client;
|
||||
private final String sourceRepository;
|
||||
|
||||
private LabelNamesLoader(GitLabApi client, String sourceRepository) {
|
||||
private LabelNamesLoader(GitLabClient client, String sourceRepository) {
|
||||
this.client = client;
|
||||
this.sourceRepository = sourceRepository;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ package com.dabsquared.gitlabjenkins.trigger.handler;
|
|||
import com.dabsquared.gitlabjenkins.cause.CauseData;
|
||||
import com.dabsquared.gitlabjenkins.cause.GitLabWebHookCause;
|
||||
import com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabApi;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.BuildState;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.hook.model.WebHook;
|
||||
import com.dabsquared.gitlabjenkins.publisher.GitLabCommitStatusPublisher;
|
||||
|
@ -63,7 +63,7 @@ public abstract class AbstractWebHookTriggerHandler<H extends WebHook> implement
|
|||
if (job instanceof AbstractProject && ((AbstractProject) job).getPublishersList().get(GitLabCommitStatusPublisher.class) != null) {
|
||||
GitLabCommitStatusPublisher publisher =
|
||||
(GitLabCommitStatusPublisher) ((AbstractProject) job).getPublishersList().get(GitLabCommitStatusPublisher.class);
|
||||
GitLabApi client = job.getProperty(GitLabConnectionProperty.class).getClient();
|
||||
GitLabClient client = job.getProperty(GitLabConnectionProperty.class).getClient();
|
||||
BuildStatusUpdate buildStatusUpdate = retrieveBuildStatusUpdate(hook);
|
||||
try {
|
||||
if (client == null) {
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
package com.dabsquared.gitlabjenkins.trigger.handler.pipeline;
|
||||
|
||||
|
||||
import com.dabsquared.gitlabjenkins.cause.CauseData;
|
||||
import com.dabsquared.gitlabjenkins.cause.GitLabWebHookCause;
|
||||
import com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabApi;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.hook.model.*;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.hook.model.PipelineEventObjectAttributes;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.hook.model.PipelineHook;
|
||||
import com.dabsquared.gitlabjenkins.trigger.exception.NoRevisionToBuildException;
|
||||
import com.dabsquared.gitlabjenkins.trigger.filter.BranchFilter;
|
||||
import com.dabsquared.gitlabjenkins.trigger.filter.MergeRequestLabelFilter;
|
||||
|
@ -46,7 +47,7 @@ class PipelineHookTriggerHandlerImpl extends AbstractWebHookTriggerHandler<Pipel
|
|||
GitLabConnectionProperty property = job.getProperty(GitLabConnectionProperty.class);
|
||||
|
||||
if (property != null && property.getClient() != null) {
|
||||
GitLabApi client = property.getClient();
|
||||
GitLabClient client = property.getClient();
|
||||
com.dabsquared.gitlabjenkins.gitlab.api.model.Project projectForName = client.getProject(hook.getProject().getPathWithNamespace());
|
||||
hook.setProjectId(projectForName.getId());
|
||||
}
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
package com.dabsquared.gitlabjenkins.trigger.handler.push;
|
||||
|
||||
|
||||
import com.dabsquared.gitlabjenkins.GitLabPushTrigger;
|
||||
import com.dabsquared.gitlabjenkins.cause.CauseData;
|
||||
import com.dabsquared.gitlabjenkins.cause.GitLabWebHookCause;
|
||||
import com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabApi;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.Branch;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.BuildState;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.MergeRequest;
|
||||
|
@ -21,11 +22,9 @@ import hudson.model.CauseAction;
|
|||
import hudson.model.Job;
|
||||
import hudson.plugins.git.RevisionParameterAction;
|
||||
import hudson.triggers.Trigger;
|
||||
import hudson.triggers.TriggerDescriptor;
|
||||
import jenkins.model.Jenkins;
|
||||
import jenkins.model.ParameterizedJobMixIn;
|
||||
import jenkins.model.ParameterizedJobMixIn.ParameterizedJob;
|
||||
|
||||
import org.eclipse.jgit.transport.URIish;
|
||||
|
||||
import javax.ws.rs.ProcessingException;
|
||||
|
@ -34,7 +33,6 @@ import java.net.URISyntaxException;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
|
@ -65,7 +63,7 @@ class OpenMergeRequestPushHookTriggerHandler implements PushHookTriggerHandler {
|
|||
final GitLabPushTrigger trigger = (GitLabPushTrigger) t;
|
||||
Integer projectId = hook.getProjectId();
|
||||
if (property != null && property.getClient() != null && projectId != null && trigger != null) {
|
||||
GitLabApi client = property.getClient();
|
||||
GitLabClient client = property.getClient();
|
||||
for (MergeRequest mergeRequest : getOpenMergeRequests(client, projectId.toString())) {
|
||||
if (mergeRequestLabelFilter.isMergeRequestAllowed(mergeRequest.getLabels())) {
|
||||
handleMergeRequest(job, hook, ciSkip, branchFilter, client, mergeRequest);
|
||||
|
@ -83,7 +81,7 @@ class OpenMergeRequestPushHookTriggerHandler implements PushHookTriggerHandler {
|
|||
}
|
||||
}
|
||||
|
||||
private List<MergeRequest> getOpenMergeRequests(GitLabApi client, String projectId) {
|
||||
private List<MergeRequest> getOpenMergeRequests(GitLabClient client, String projectId) {
|
||||
List<MergeRequest> result = new ArrayList<>();
|
||||
Integer page = 1;
|
||||
do {
|
||||
|
@ -94,8 +92,8 @@ class OpenMergeRequestPushHookTriggerHandler implements PushHookTriggerHandler {
|
|||
return result;
|
||||
}
|
||||
|
||||
private void handleMergeRequest(Job<?, ?> job, PushHook hook, boolean ciSkip, BranchFilter branchFilter, GitLabApi client, MergeRequest mergeRequest) {
|
||||
if (ciSkip && mergeRequest.getDescription() != null && mergeRequest.getDescription().contains("[ci-skip]")) {
|
||||
private void handleMergeRequest(Job<?, ?> job, PushHook hook, boolean ciSkip, BranchFilter branchFilter, GitLabClient client, MergeRequest mergeRequest) {
|
||||
if (ciSkip && mergeRequest.getDescription() != null && mergeRequest.getDescription().contains("[ci-skip]")) {
|
||||
LOGGER.log(Level.INFO, "Skipping MR " + mergeRequest.getTitle() + " due to ci-skip.");
|
||||
return;
|
||||
}
|
||||
|
@ -158,7 +156,7 @@ class OpenMergeRequestPushHookTriggerHandler implements PushHookTriggerHandler {
|
|||
if (job instanceof AbstractProject && ((AbstractProject) job).getPublishersList().get(GitLabCommitStatusPublisher.class) != null) {
|
||||
GitLabCommitStatusPublisher publisher =
|
||||
(GitLabCommitStatusPublisher) ((AbstractProject) job).getPublishersList().get(GitLabCommitStatusPublisher.class);
|
||||
GitLabApi client = job.getProperty(GitLabConnectionProperty.class).getClient();
|
||||
GitLabClient client = job.getProperty(GitLabConnectionProperty.class).getClient();
|
||||
try {
|
||||
String targetUrl = Jenkins.getInstance().getRootUrl() + job.getUrl() + job.getNextBuildNumber() + "/";
|
||||
client.changeBuildStatus(projectId, commit, BuildState.pending, ref, publisher.getName(), targetUrl, null);
|
||||
|
|
|
@ -1,28 +1,9 @@
|
|||
package com.dabsquared.gitlabjenkins.util;
|
||||
|
||||
import static com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty.getClient;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.ws.rs.NotFoundException;
|
||||
import javax.ws.rs.ProcessingException;
|
||||
import javax.ws.rs.WebApplicationException;
|
||||
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
|
||||
import com.dabsquared.gitlabjenkins.cause.GitLabWebHookCause;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabApi;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.BuildState;
|
||||
|
||||
import hudson.EnvVars;
|
||||
import hudson.model.Run;
|
||||
import hudson.model.TaskListener;
|
||||
|
@ -33,6 +14,23 @@ import jenkins.model.Jenkins;
|
|||
import jenkins.plugins.git.AbstractGitSCMSource;
|
||||
import jenkins.scm.api.SCMRevision;
|
||||
import jenkins.scm.api.SCMRevisionAction;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
|
||||
import javax.ws.rs.NotFoundException;
|
||||
import javax.ws.rs.ProcessingException;
|
||||
import javax.ws.rs.WebApplicationException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty.getClient;
|
||||
|
||||
/**
|
||||
* @author Robin Müller
|
||||
|
@ -42,7 +40,7 @@ public class CommitStatusUpdater {
|
|||
private final static Logger LOGGER = Logger.getLogger(CommitStatusUpdater.class.getName());
|
||||
|
||||
public static void updateCommitStatus(Run<?, ?> build, TaskListener listener, BuildState state, String name) {
|
||||
GitLabApi client = getClient(build);
|
||||
GitLabClient client = getClient(build);
|
||||
if (client == null) {
|
||||
println(listener, "No GitLab connection configured");
|
||||
return;
|
||||
|
@ -50,7 +48,7 @@ public class CommitStatusUpdater {
|
|||
|
||||
try {
|
||||
final String buildUrl = getBuildUrl(build);
|
||||
|
||||
|
||||
for (final GitLabBranchBuild gitLabBranchBuild : retrieveGitlabProjectIds(build, build.getEnvironment(listener))) {
|
||||
try {
|
||||
if (existsCommit(client, gitLabBranchBuild.getProjectId(), gitLabBranchBuild.getRevisionHash())) {
|
||||
|
@ -82,7 +80,7 @@ public class CommitStatusUpdater {
|
|||
}
|
||||
}
|
||||
|
||||
private static boolean existsCommit(GitLabApi client, String gitlabProjectId, String commitHash) {
|
||||
private static boolean existsCommit(GitLabClient client, String gitlabProjectId, String commitHash) {
|
||||
try {
|
||||
client.getCommit(gitlabProjectId, commitHash);
|
||||
return true;
|
||||
|
@ -111,7 +109,7 @@ public class CommitStatusUpdater {
|
|||
cause.getData().getLastCommit()));
|
||||
}
|
||||
|
||||
final GitLabApi gitLabClient = getClient(build);
|
||||
final GitLabClient gitLabClient = getClient(build);
|
||||
if (gitLabClient == null) {
|
||||
LOGGER.log(Level.WARNING, "No gitlab client found.");
|
||||
return result;
|
||||
|
@ -171,8 +169,8 @@ public class CommitStatusUpdater {
|
|||
return action.getLastBuild(lastBuiltRevision.getSha1()).getMarked().getSha1String();
|
||||
}
|
||||
|
||||
private static void addGitLabBranchBuild(List<GitLabBranchBuild> result, String scmRevisionHash,
|
||||
Set<String> remoteUrls, EnvVars environment, GitLabApi gitLabClient) {
|
||||
private static void addGitLabBranchBuild(List<GitLabBranchBuild> result, String scmRevisionHash,
|
||||
Set<String> remoteUrls, EnvVars environment, GitLabClient gitLabClient) {
|
||||
for (String remoteUrl : remoteUrls) {
|
||||
try {
|
||||
LOGGER.log(Level.INFO, "Retrieving the gitlab project id from remote url {0}", remoteUrl);
|
||||
|
@ -184,7 +182,7 @@ public class CommitStatusUpdater {
|
|||
projectId = gitLabClient.getProject(projectNameWithNameSpace).getId().toString();
|
||||
} catch (WebApplicationException | ProcessingException e) {
|
||||
LOGGER.log(Level.SEVERE, String.format("Failed to retrieve projectId for project '%s'",
|
||||
projectNameWithNameSpace), e);
|
||||
projectNameWithNameSpace), e);
|
||||
}
|
||||
}
|
||||
result.add(new GitLabBranchBuild(projectId, scmRevisionHash));
|
||||
|
@ -197,16 +195,16 @@ public class CommitStatusUpdater {
|
|||
public static class GitLabBranchBuild {
|
||||
private final String projectId;
|
||||
private final String revisionHash;
|
||||
|
||||
|
||||
public GitLabBranchBuild(final String projectId, final String revisionHash) {
|
||||
this.projectId = projectId;
|
||||
this.revisionHash = revisionHash;
|
||||
}
|
||||
|
||||
|
||||
public String getProjectId() {
|
||||
return this.projectId;
|
||||
}
|
||||
|
||||
|
||||
public String getRevisionHash() {
|
||||
return this.revisionHash;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package com.dabsquared.gitlabjenkins.util;
|
||||
|
||||
import org.eclipse.jgit.transport.URIish;
|
||||
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabApi;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
|
||||
import org.eclipse.jgit.transport.URIish;
|
||||
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.regex.Matcher;
|
||||
|
@ -17,10 +17,10 @@ public final class ProjectIdUtil {
|
|||
|
||||
private ProjectIdUtil() { }
|
||||
|
||||
public static String retrieveProjectId(GitLabApi client, String remoteUrl) throws ProjectIdResolutionException {
|
||||
public static String retrieveProjectId(GitLabClient client, String remoteUrl) throws ProjectIdResolutionException {
|
||||
try {
|
||||
String projectId = null;
|
||||
String baseUri = client.getGitLabHostUrl();
|
||||
String baseUri = client.getHostUrl();
|
||||
String projectId;
|
||||
if (baseUri != null && remoteUrl.startsWith(baseUri)) {
|
||||
projectId = new URIish(remoteUrl.substring(baseUri.length(), remoteUrl.length())).getPath();
|
||||
} else {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package com.dabsquared.gitlabjenkins.workflow;
|
||||
|
||||
import com.dabsquared.gitlabjenkins.cause.GitLabWebHookCause;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabApi;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
|
||||
import hudson.Extension;
|
||||
import hudson.model.Run;
|
||||
import hudson.model.TaskListener;
|
||||
|
@ -63,7 +63,7 @@ public class AcceptGitLabMergeRequestStep extends AbstractStepImpl {
|
|||
Integer projectId = cause.getData().getTargetProjectId();
|
||||
Integer mergeRequestId = cause.getData().getMergeRequestId();
|
||||
if (projectId != null && mergeRequestId != null) {
|
||||
GitLabApi client = getClient(run);
|
||||
GitLabClient client = getClient(run);
|
||||
if (client == null) {
|
||||
println("No GitLab connection configured");
|
||||
} else {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package com.dabsquared.gitlabjenkins.workflow;
|
||||
|
||||
import com.dabsquared.gitlabjenkins.cause.GitLabWebHookCause;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabApi;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
|
||||
import hudson.Extension;
|
||||
import hudson.model.Run;
|
||||
import hudson.model.TaskListener;
|
||||
|
@ -63,7 +63,7 @@ public class AddGitLabMergeRequestCommentStep extends AbstractStepImpl {
|
|||
Integer projectId = cause.getData().getTargetProjectId();
|
||||
Integer mergeRequestId = cause.getData().getMergeRequestId();
|
||||
if (projectId != null && mergeRequestId != null) {
|
||||
GitLabApi client = getClient(run);
|
||||
GitLabClient client = getClient(run);
|
||||
if (client == null) {
|
||||
println("No GitLab connection configured");
|
||||
} else {
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
<c:select/>
|
||||
</f:entry>
|
||||
<f:advanced>
|
||||
<f:entry title="${%API-Level}" field="clientBuilderId" description="${%API Level for accessing Gitlab}">
|
||||
<f:select value="${connection.clientBuilderId}" default="autodetect"/>
|
||||
</f:entry>
|
||||
<f:entry title="${%Ignore SSL Certificate Errors}" field="ignoreCertificateErrors">
|
||||
<f:checkbox checked="${connection.ignoreCertificateErrors}"/>
|
||||
</f:entry>
|
||||
|
@ -30,7 +33,7 @@
|
|||
<st:include page="configure-advanced.jelly" optional="true" />
|
||||
</f:advanced>
|
||||
<f:validateButton title="${%Test Connection}" progress="${%Testing...}" method="testConnection"
|
||||
with="apiTokenId,url,ignoreCertificateErrors"/>
|
||||
with="apiTokenId,clientBuilderId,url,ignoreCertificateErrors"/>
|
||||
<f:entry title="">
|
||||
<div align="right">
|
||||
<f:repeatableDeleteButton/>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.dabsquared.gitlabjenkins.connection;
|
||||
|
||||
|
||||
import com.cloudbees.plugins.credentials.CredentialsProvider;
|
||||
import com.cloudbees.plugins.credentials.CredentialsScope;
|
||||
import com.cloudbees.plugins.credentials.CredentialsStore;
|
||||
|
@ -87,7 +88,7 @@ public class GitLabConnectionConfigSSLTest {
|
|||
public void doCheckConnection_ignoreCertificateErrors() {
|
||||
GitLabConnectionConfig connectionConfig = jenkins.get(GitLabConnectionConfig.class);
|
||||
|
||||
FormValidation formValidation = connectionConfig.doTestConnection("https://localhost:" + port + "/gitlab", API_TOKEN_ID, true, 10, 10);
|
||||
FormValidation formValidation = connectionConfig.doTestConnection("https://localhost:" + port + "/gitlab", API_TOKEN_ID, "v3", true, 10, 10);
|
||||
assertThat(formValidation.getMessage(), is(Messages.connection_success()));
|
||||
}
|
||||
|
||||
|
@ -95,7 +96,7 @@ public class GitLabConnectionConfigSSLTest {
|
|||
public void doCheckConnection_certificateError() throws IOException {
|
||||
GitLabConnectionConfig connectionConfig = jenkins.get(GitLabConnectionConfig.class);
|
||||
|
||||
FormValidation formValidation = connectionConfig.doTestConnection("https://localhost:" + port + "/gitlab", API_TOKEN_ID, false, 10, 10);
|
||||
FormValidation formValidation = connectionConfig.doTestConnection("https://localhost:" + port + "/gitlab", API_TOKEN_ID, "v3", false, 10, 10);
|
||||
assertThat(formValidation.getMessage(), containsString(Messages.connection_error("")));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
package com.dabsquared.gitlabjenkins.connection;
|
||||
|
||||
|
||||
import com.cloudbees.plugins.credentials.CredentialsProvider;
|
||||
import com.cloudbees.plugins.credentials.CredentialsScope;
|
||||
import com.cloudbees.plugins.credentials.CredentialsStore;
|
||||
import com.cloudbees.plugins.credentials.SystemCredentialsProvider;
|
||||
import com.cloudbees.plugins.credentials.domains.Domain;
|
||||
import com.dabsquared.gitlabjenkins.GitLabPushTrigger;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.impl.V3GitLabClientBuilder;
|
||||
import hudson.model.FreeStyleProject;
|
||||
import hudson.model.Item;
|
||||
import hudson.security.GlobalMatrixAuthorizationStrategy;
|
||||
|
@ -33,9 +36,11 @@ import java.io.IOException;
|
|||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static junit.framework.TestCase.assertNotNull;
|
||||
import static junit.framework.TestCase.assertSame;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
@ -72,28 +77,29 @@ public class GitLabConnectionConfigTest {
|
|||
|
||||
@Test
|
||||
public void doCheckConnection_success() {
|
||||
HttpRequest request = request().withPath("/gitlab/api/v3/.*").withHeader("PRIVATE-TOKEN", API_TOKEN);
|
||||
mockServerClient.when(request).respond(response().withStatusCode(Response.Status.OK.getStatusCode()));
|
||||
|
||||
GitLabConnectionConfig connectionConfig = jenkins.get(GitLabConnectionConfig.class);
|
||||
FormValidation formValidation = connectionConfig.doTestConnection(gitLabUrl, API_TOKEN_ID, false, 10, 10);
|
||||
|
||||
assertThat(formValidation.getMessage(), is(Messages.connection_success()));
|
||||
mockServerClient.verify(request);
|
||||
String expected = Messages.connection_success();
|
||||
assertThat(doCheckConnection("v3", Response.Status.OK), is(expected));
|
||||
assertThat(doCheckConnection("v4", Response.Status.OK), is(expected));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doCheckConnection_forbidden() throws IOException {
|
||||
HttpRequest request = request().withPath("/gitlab/api/v3/.*").withHeader("PRIVATE-TOKEN", API_TOKEN);
|
||||
mockServerClient.when(request).respond(response().withStatusCode(Response.Status.FORBIDDEN.getStatusCode()));
|
||||
String expected = Messages.connection_error("HTTP 403 Forbidden");
|
||||
assertThat(doCheckConnection("v3", Response.Status.FORBIDDEN), is(expected));
|
||||
assertThat(doCheckConnection("v4", Response.Status.FORBIDDEN), is(expected));
|
||||
}
|
||||
|
||||
private String doCheckConnection(String clientBuilderId, Response.Status status) {
|
||||
HttpRequest request = request().withPath("/gitlab/api/" + clientBuilderId + "/.*").withHeader("PRIVATE-TOKEN", API_TOKEN);
|
||||
mockServerClient.when(request).respond(response().withStatusCode(status.getStatusCode()));
|
||||
|
||||
GitLabConnectionConfig connectionConfig = jenkins.get(GitLabConnectionConfig.class);
|
||||
FormValidation formValidation = connectionConfig.doTestConnection(gitLabUrl, API_TOKEN_ID, false, 10, 10);
|
||||
|
||||
assertThat(formValidation.getMessage(), is(Messages.connection_error("HTTP 403 Forbidden")));
|
||||
FormValidation formValidation = connectionConfig.doTestConnection(gitLabUrl, API_TOKEN_ID, clientBuilderId, false, 10, 10);
|
||||
mockServerClient.verify(request);
|
||||
return formValidation.getMessage();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void authenticationEnabled_anonymous_forbidden() throws IOException, URISyntaxException {
|
||||
Boolean defaultValue = jenkins.get(GitLabConnectionConfig.class).isUseAuthenticatedEndpoint();
|
||||
|
@ -155,8 +161,8 @@ public class GitLabConnectionConfigTest {
|
|||
|
||||
@Test
|
||||
public void setConnectionsTest() {
|
||||
GitLabConnection connection1 = new GitLabConnection("1", "http://localhost", null, false, 10, 10);
|
||||
GitLabConnection connection2 = new GitLabConnection("2", "http://localhost", null, false, 10, 10);
|
||||
GitLabConnection connection1 = new GitLabConnection("1", "http://localhost", null, new V3GitLabClientBuilder(), false, 10, 10);
|
||||
GitLabConnection connection2 = new GitLabConnection("2", "http://localhost", null, new V3GitLabClientBuilder(), false, 10, 10);
|
||||
GitLabConnectionConfig config = jenkins.get(GitLabConnectionConfig.class);
|
||||
List<GitLabConnection> connectionList1 = new ArrayList<>();
|
||||
connectionList1.add(connection1);
|
||||
|
@ -166,7 +172,7 @@ public class GitLabConnectionConfigTest {
|
|||
|
||||
List<GitLabConnection> connectionList2 = new ArrayList<>();
|
||||
connectionList2.add(connection1);
|
||||
connectionList2.add(connection1);
|
||||
connectionList2.add(connection2);
|
||||
|
||||
config.setConnections(connectionList2);
|
||||
assertThat(config.getConnections(), is(connectionList2));
|
||||
|
@ -174,4 +180,17 @@ public class GitLabConnectionConfigTest {
|
|||
config.setConnections(connectionList1);
|
||||
assertThat(config.getConnections(), is(connectionList1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getClient_is_cached() {
|
||||
GitLabConnection connection = new GitLabConnection("test", "http://localhost", API_TOKEN_ID, new V3GitLabClientBuilder(), false, 10, 10);
|
||||
GitLabConnectionConfig config = jenkins.get(GitLabConnectionConfig.class);
|
||||
List<GitLabConnection> connectionList1 = new ArrayList<>();
|
||||
connectionList1.add(connection);
|
||||
config.setConnections(connectionList1);
|
||||
|
||||
GitLabClient client = config.getClient(connection.getName());
|
||||
assertNotNull(client);
|
||||
assertSame(client, config.getClient(connection.getName()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
package com.dabsquared.gitlabjenkins.gitlab.api;
|
||||
|
||||
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.impl.AutodetectGitLabClientBuilder;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.impl.V3GitLabClientBuilder;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.impl.V4GitLabClientBuilder;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.jvnet.hudson.test.JenkinsRule;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import static com.dabsquared.gitlabjenkins.gitlab.api.GitLabClientBuilder.getAllGitLabClientBuilders;
|
||||
import static com.dabsquared.gitlabjenkins.gitlab.api.GitLabClientBuilder.getGitLabClientBuilderById;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.core.IsInstanceOf.instanceOf;
|
||||
|
||||
|
||||
public class GitLabClientBuilderTest {
|
||||
@Rule
|
||||
public JenkinsRule jenkins = new JenkinsRule();
|
||||
|
||||
@Test
|
||||
public void getAllGitLabClientBuilders_list_is_sorted_by_id() {
|
||||
List<GitLabClientBuilder> builders = getAllGitLabClientBuilders();
|
||||
assertThat(builders.get(0), instanceOf(AutodetectGitLabClientBuilder.class));
|
||||
assertThat(builders.get(1), instanceOf(V3GitLabClientBuilder.class));
|
||||
assertThat(builders.get(2), instanceOf(V4GitLabClientBuilder.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getGitLabClientBuilderById_success() {
|
||||
assertThat(getGitLabClientBuilderById(new V3GitLabClientBuilder().id()), instanceOf(V3GitLabClientBuilder.class));
|
||||
}
|
||||
|
||||
@Test(expected = NoSuchElementException.class)
|
||||
public void getGitLabClientBuilderById_no_match() {
|
||||
getGitLabClientBuilderById("unknown");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
package com.dabsquared.gitlabjenkins.gitlab.api.impl;
|
||||
|
||||
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClientBuilder;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.jvnet.hudson.test.JenkinsRule;
|
||||
import org.mockserver.client.server.MockServerClient;
|
||||
import org.mockserver.junit.MockServerRule;
|
||||
import org.mockserver.model.HttpRequest;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import static com.dabsquared.gitlabjenkins.gitlab.api.impl.TestUtility.API_TOKEN;
|
||||
import static com.dabsquared.gitlabjenkins.gitlab.api.impl.TestUtility.addGitLabApiToken;
|
||||
import static com.dabsquared.gitlabjenkins.gitlab.api.impl.TestUtility.buildClientWithDefaults;
|
||||
import static com.dabsquared.gitlabjenkins.gitlab.api.impl.TestUtility.responseNotFound;
|
||||
import static com.dabsquared.gitlabjenkins.gitlab.api.impl.TestUtility.responseOk;
|
||||
import static com.dabsquared.gitlabjenkins.gitlab.api.impl.TestUtility.versionRequest;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
|
||||
public class AutodetectGitLabClientBuilderTest {
|
||||
@Rule
|
||||
public MockServerRule mockServer = new MockServerRule(this);
|
||||
@Rule
|
||||
public JenkinsRule jenkins = new JenkinsRule();
|
||||
private MockServerClient mockServerClient;
|
||||
private String gitLabUrl;
|
||||
private GitLabClientBuilder clientBuilder;
|
||||
private HttpRequest v3Request;
|
||||
private HttpRequest v4Request;
|
||||
|
||||
@Before
|
||||
public void setup() throws IOException {
|
||||
gitLabUrl = "http://localhost:" + mockServer.getPort() + "/gitlab";
|
||||
addGitLabApiToken();
|
||||
|
||||
clientBuilder = new AutodetectGitLabClientBuilder();
|
||||
|
||||
v3Request = versionRequest(V3GitLabClientBuilder.ID);
|
||||
v4Request = versionRequest(V4GitLabClientBuilder.ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildClient_success_v3() throws Exception {
|
||||
mockServerClient.when(v3Request).respond(responseOk());
|
||||
TestUtility.assertApiImpl(buildClientWithDefaults(clientBuilder, gitLabUrl),V3GitLabApiProxy.class);
|
||||
mockServerClient.verify(v3Request);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildClient_success_v4() throws Exception {
|
||||
mockServerClient.when(v3Request).respond(responseNotFound());
|
||||
mockServerClient.when(v4Request).respond(responseOk());
|
||||
TestUtility.assertApiImpl(buildClientWithDefaults(clientBuilder, gitLabUrl),V4GitLabApiProxy.class);
|
||||
mockServerClient.verify(v3Request, v4Request);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildClient_no_match() {
|
||||
mockServerClient.when(v3Request).respond(responseNotFound());
|
||||
mockServerClient.when(v4Request).respond(responseNotFound());
|
||||
try {
|
||||
clientBuilder.buildClient(gitLabUrl, API_TOKEN, true, 10, 10);
|
||||
fail("buildClient should throw exception when no matching candidate is found");
|
||||
} catch (NoSuchElementException e) {
|
||||
mockServerClient.verify(v3Request, v4Request);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package com.dabsquared.gitlabjenkins.gitlab.api.impl;
|
||||
|
||||
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClientBuilder;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.jvnet.hudson.test.JenkinsRule;
|
||||
import org.mockserver.junit.MockServerRule;
|
||||
|
||||
import static com.dabsquared.gitlabjenkins.gitlab.api.impl.TestUtility.assertApiImpl;
|
||||
import static com.dabsquared.gitlabjenkins.gitlab.api.impl.TestUtility.buildClientWithDefaults;
|
||||
|
||||
|
||||
public class ResteasyGitLabClientBuilderTest {
|
||||
@Rule
|
||||
public MockServerRule mockServer = new MockServerRule(this);
|
||||
@Rule
|
||||
public JenkinsRule jenkins = new JenkinsRule();
|
||||
|
||||
@Test
|
||||
public void buildClient() throws Exception {
|
||||
GitLabClientBuilder clientBuilder = new ResteasyGitLabClientBuilder("test", V3GitLabApiProxy.class);
|
||||
assertApiImpl(buildClientWithDefaults(clientBuilder, "http://localhost/"), V3GitLabApiProxy.class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
package com.dabsquared.gitlabjenkins.gitlab.api.impl;
|
||||
|
||||
|
||||
import com.cloudbees.plugins.credentials.CredentialsProvider;
|
||||
import com.cloudbees.plugins.credentials.CredentialsScope;
|
||||
import com.cloudbees.plugins.credentials.CredentialsStore;
|
||||
import com.cloudbees.plugins.credentials.SystemCredentialsProvider;
|
||||
import com.cloudbees.plugins.credentials.domains.Domain;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabApi;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClientBuilder;
|
||||
import hudson.util.Secret;
|
||||
import jenkins.model.Jenkins;
|
||||
import org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl;
|
||||
import org.mockserver.model.HttpRequest;
|
||||
import org.mockserver.model.HttpResponse;
|
||||
|
||||
import javax.ws.rs.core.Response.Status;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
|
||||
import static javax.ws.rs.HttpMethod.HEAD;
|
||||
import static javax.ws.rs.core.Response.Status.NOT_FOUND;
|
||||
import static javax.ws.rs.core.Response.Status.OK;
|
||||
import static javax.ws.rs.core.Response.Status.UNAUTHORIZED;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.mockserver.model.HttpRequest.request;
|
||||
import static org.mockserver.model.HttpResponse.response;
|
||||
|
||||
|
||||
class TestUtility {
|
||||
static final String API_TOKEN = "secret";
|
||||
static final String API_TOKEN_ID = "apiTokenId";
|
||||
static final boolean IGNORE_CERTIFICATE_ERRORS = true;
|
||||
static final int CONNECTION_TIMEOUT = 10;
|
||||
static final int READ_TIMEOUT = 10;
|
||||
|
||||
static void addGitLabApiToken() throws IOException {
|
||||
for (CredentialsStore credentialsStore : CredentialsProvider.lookupStores(Jenkins.getInstance())) {
|
||||
if (credentialsStore instanceof SystemCredentialsProvider.StoreImpl) {
|
||||
List<Domain> domains = credentialsStore.getDomains();
|
||||
credentialsStore.addCredentials(domains.get(0),
|
||||
new StringCredentialsImpl(CredentialsScope.SYSTEM, API_TOKEN_ID, "GitLab API Token", Secret.fromString(API_TOKEN)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static HttpRequest versionRequest(String id) {
|
||||
return request().withMethod(HEAD).withPath("/gitlab/api/" + id + "/.*").withHeader("PRIVATE-TOKEN", API_TOKEN);
|
||||
}
|
||||
|
||||
static HttpResponse responseOk() {
|
||||
return responseWithStatus(OK);
|
||||
}
|
||||
|
||||
static HttpResponse responseNotFound() {
|
||||
return responseWithStatus(NOT_FOUND);
|
||||
}
|
||||
|
||||
static HttpResponse responseUnauthorized() {
|
||||
return responseWithStatus(UNAUTHORIZED);
|
||||
}
|
||||
|
||||
static HttpResponse responseWithStatus(Status status) {
|
||||
return response().withStatusCode(status.getStatusCode());
|
||||
}
|
||||
|
||||
static GitLabClient buildClientWithDefaults(GitLabClientBuilder clientBuilder, String url) {
|
||||
return clientBuilder.buildClient(url, API_TOKEN, IGNORE_CERTIFICATE_ERRORS, CONNECTION_TIMEOUT, READ_TIMEOUT);
|
||||
}
|
||||
|
||||
static void assertApiImpl(GitLabClient client, Class<? extends GitLabApi> apiImplClass) throws Exception {
|
||||
Field apiField = client.getClass().getDeclaredField("api");
|
||||
apiField.setAccessible(true);
|
||||
assertThat(apiField.get(client), instanceOf(apiImplClass));
|
||||
}
|
||||
|
||||
private TestUtility() { /* utility class */ }
|
||||
}
|
|
@ -1,26 +1,10 @@
|
|||
package com.dabsquared.gitlabjenkins.publisher;
|
||||
|
||||
import com.cloudbees.plugins.credentials.CredentialsProvider;
|
||||
import com.cloudbees.plugins.credentials.CredentialsScope;
|
||||
import com.cloudbees.plugins.credentials.CredentialsStore;
|
||||
import com.cloudbees.plugins.credentials.SystemCredentialsProvider;
|
||||
import com.cloudbees.plugins.credentials.domains.Domain;
|
||||
import com.dabsquared.gitlabjenkins.connection.GitLabConnection;
|
||||
import com.dabsquared.gitlabjenkins.connection.GitLabConnectionConfig;
|
||||
import com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty;
|
||||
import hudson.Launcher;
|
||||
import hudson.matrix.MatrixAggregator;
|
||||
import hudson.matrix.MatrixConfiguration;
|
||||
import hudson.matrix.MatrixBuild;
|
||||
|
||||
import hudson.model.AbstractBuild;
|
||||
import hudson.model.AbstractProject;
|
||||
import hudson.model.BuildListener;
|
||||
import hudson.model.Result;
|
||||
import hudson.model.StreamBuildListener;
|
||||
import hudson.plugins.git.util.BuildData;
|
||||
import hudson.util.Secret;
|
||||
import jenkins.model.Jenkins;
|
||||
import org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
|
@ -34,16 +18,16 @@ import org.mockserver.model.HttpRequest;
|
|||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
import static org.mockito.Matchers.any;
|
||||
import static com.dabsquared.gitlabjenkins.publisher.TestUtility.GITLAB_CONNECTION_V3;
|
||||
import static com.dabsquared.gitlabjenkins.publisher.TestUtility.GITLAB_CONNECTION_V4;
|
||||
import static com.dabsquared.gitlabjenkins.publisher.TestUtility.MERGE_REQUEST_ID;
|
||||
import static com.dabsquared.gitlabjenkins.publisher.TestUtility.PROJECT_ID;
|
||||
import static com.dabsquared.gitlabjenkins.publisher.TestUtility.mockSimpleBuild;
|
||||
import static com.dabsquared.gitlabjenkins.publisher.TestUtility.setupGitLabConnections;
|
||||
import static com.dabsquared.gitlabjenkins.publisher.TestUtility.verifyMatrixAggregatable;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockserver.model.HttpRequest.request;
|
||||
import static org.mockserver.model.HttpResponse.response;
|
||||
|
||||
|
@ -51,10 +35,6 @@ import static org.mockserver.model.HttpResponse.response;
|
|||
* @author Nikolay Ustinov
|
||||
*/
|
||||
public class GitLabAcceptMergeRequestPublisherTest {
|
||||
|
||||
private static final String GIT_LAB_CONNECTION = "GitLab";
|
||||
private static final String API_TOKEN = "secret";
|
||||
|
||||
@ClassRule
|
||||
public static MockServerRule mockServer = new MockServerRule(new Object());
|
||||
|
||||
|
@ -65,17 +45,8 @@ public class GitLabAcceptMergeRequestPublisherTest {
|
|||
private BuildListener listener;
|
||||
|
||||
@BeforeClass
|
||||
public static void setupConnection() throws IOException {
|
||||
GitLabConnectionConfig connectionConfig = jenkins.get(GitLabConnectionConfig.class);
|
||||
String apiTokenId = "apiTokenId";
|
||||
for (CredentialsStore credentialsStore : CredentialsProvider.lookupStores(Jenkins.getInstance())) {
|
||||
if (credentialsStore instanceof SystemCredentialsProvider.StoreImpl) {
|
||||
List<Domain> domains = credentialsStore.getDomains();
|
||||
credentialsStore.addCredentials(domains.get(0),
|
||||
new StringCredentialsImpl(CredentialsScope.SYSTEM, apiTokenId, "GitLab API Token", Secret.fromString(API_TOKEN)));
|
||||
}
|
||||
}
|
||||
connectionConfig.addConnection(new GitLabConnection(GIT_LAB_CONNECTION, "http://localhost:" + mockServer.getPort() + "/gitlab", apiTokenId, false, 10, 10));
|
||||
public static void setupClass() throws IOException {
|
||||
setupGitLabConnections(jenkins, mockServer);
|
||||
}
|
||||
|
||||
@Before
|
||||
|
@ -90,84 +61,46 @@ public class GitLabAcceptMergeRequestPublisherTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void matrixAggregatable() throws UnsupportedEncodingException, InterruptedException, IOException {
|
||||
AbstractBuild build = mock(AbstractBuild.class);
|
||||
AbstractProject project = mock(MatrixConfiguration.class);
|
||||
GitLabCommitStatusPublisher publisher = mock(GitLabCommitStatusPublisher.class);
|
||||
MatrixBuild parentBuild = mock(MatrixBuild.class);
|
||||
|
||||
when(build.getParent()).thenReturn(project);
|
||||
when(publisher.createAggregator(any(MatrixBuild.class), any(Launcher.class), any(BuildListener.class))).thenCallRealMethod();
|
||||
when(publisher.perform(any(AbstractBuild.class), any(Launcher.class), any(BuildListener.class))).thenReturn(true);
|
||||
|
||||
MatrixAggregator aggregator = publisher.createAggregator(parentBuild, null, listener);
|
||||
aggregator.startBuild();
|
||||
aggregator.endBuild();
|
||||
verify(publisher).perform(parentBuild, null, listener);
|
||||
public void matrixAggregatable() throws InterruptedException, IOException {
|
||||
verifyMatrixAggregatable(GitLabAcceptMergeRequestPublisher.class, listener);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void success() throws IOException, InterruptedException {
|
||||
Integer buildNumber = 1;
|
||||
Integer projectId = 3;
|
||||
Integer mergeRequestId = 1;
|
||||
AbstractBuild build = mockBuild("/build/123", GIT_LAB_CONNECTION, Result.SUCCESS, buildNumber);
|
||||
publish(mockSimpleBuild(GITLAB_CONNECTION_V3, Result.SUCCESS));
|
||||
publish(mockSimpleBuild(GITLAB_CONNECTION_V4, Result.SUCCESS));
|
||||
|
||||
HttpRequest[] requests = new HttpRequest[] {
|
||||
prepareAcceptMergeRequestWithSuccessResponse(projectId, mergeRequestId)
|
||||
};
|
||||
|
||||
GitLabAcceptMergeRequestPublisher publisher = spy(new GitLabAcceptMergeRequestPublisher());
|
||||
doReturn(projectId).when(publisher).getProjectId(build);
|
||||
doReturn(mergeRequestId).when(publisher).getMergeRequestId(build);
|
||||
publisher.perform(build, null, listener);
|
||||
|
||||
mockServerClient.verify(requests);
|
||||
mockServerClient.verify(
|
||||
prepareAcceptMergeRequestWithSuccessResponse("v3"),
|
||||
prepareAcceptMergeRequestWithSuccessResponse("v4"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failed() throws IOException, InterruptedException {
|
||||
Integer buildNumber = 1;
|
||||
Integer projectId = 3;
|
||||
Integer mergeRequestId = 1;
|
||||
AbstractBuild build = mockBuild("/build/123", GIT_LAB_CONNECTION, Result.FAILURE, buildNumber);
|
||||
|
||||
GitLabAcceptMergeRequestPublisher publisher = spy(new GitLabAcceptMergeRequestPublisher());
|
||||
doReturn(projectId).when(publisher).getProjectId(build);
|
||||
doReturn(mergeRequestId).when(publisher).getMergeRequestId(build);
|
||||
publisher.perform(build, null, listener);
|
||||
publish(mockSimpleBuild(GITLAB_CONNECTION_V3, Result.FAILURE));
|
||||
publish(mockSimpleBuild(GITLAB_CONNECTION_V4, Result.FAILURE));
|
||||
|
||||
mockServerClient.verifyZeroInteractions();
|
||||
}
|
||||
|
||||
private HttpRequest prepareAcceptMergeRequestWithSuccessResponse(Integer projectId, Integer mergeRequestId) throws UnsupportedEncodingException {
|
||||
HttpRequest updateCommitStatus = prepareAcceptMergeRequest(projectId, mergeRequestId);
|
||||
private void publish(AbstractBuild build) throws InterruptedException, IOException {
|
||||
GitLabAcceptMergeRequestPublisher publisher = spy(new GitLabAcceptMergeRequestPublisher());
|
||||
doReturn(PROJECT_ID).when(publisher).getProjectId(build);
|
||||
doReturn(MERGE_REQUEST_ID).when(publisher).getMergeRequestId(build);
|
||||
publisher.perform(build, null, listener);
|
||||
}
|
||||
|
||||
private HttpRequest prepareAcceptMergeRequestWithSuccessResponse(String apiLevel) throws UnsupportedEncodingException {
|
||||
HttpRequest updateCommitStatus = prepareAcceptMergeRequest(apiLevel);
|
||||
mockServerClient.when(updateCommitStatus).respond(response().withStatusCode(200));
|
||||
return updateCommitStatus;
|
||||
}
|
||||
|
||||
private HttpRequest prepareAcceptMergeRequest(Integer projectId, Integer mergeRequestId) throws UnsupportedEncodingException {
|
||||
private HttpRequest prepareAcceptMergeRequest(String apiLevel) throws UnsupportedEncodingException {
|
||||
return request()
|
||||
.withPath("/gitlab/api/v3/projects/" + projectId + "/merge_requests/" + mergeRequestId + "/merge")
|
||||
.withPath("/gitlab/api/" + apiLevel + "/projects/" + PROJECT_ID + "/merge_requests/" + MERGE_REQUEST_ID + "/merge")
|
||||
.withMethod("PUT")
|
||||
.withHeader("PRIVATE-TOKEN", "secret")
|
||||
.withBody("merge_commit_message=Merge+Request+accepted+by+jenkins+build+success&should_remove_source_branch=false");
|
||||
}
|
||||
|
||||
private AbstractBuild mockBuild(String buildUrl, String gitLabConnection, Result result, Integer buildNumber, String... remoteUrls) {
|
||||
AbstractBuild build = mock(AbstractBuild.class);
|
||||
BuildData buildData = mock(BuildData.class);
|
||||
when(buildData.getRemoteUrls()).thenReturn(new HashSet<>(Arrays.asList(remoteUrls)));
|
||||
when(build.getAction(BuildData.class)).thenReturn(buildData);
|
||||
when(build.getResult()).thenReturn(result);
|
||||
when(build.getUrl()).thenReturn(buildUrl);
|
||||
when(build.getResult()).thenReturn(result);
|
||||
when(build.getUrl()).thenReturn(buildUrl);
|
||||
when(build.getNumber()).thenReturn(buildNumber);
|
||||
|
||||
AbstractProject<?, ?> project = mock(AbstractProject.class);
|
||||
when(project.getProperty(GitLabConnectionProperty.class)).thenReturn(new GitLabConnectionProperty(gitLabConnection));
|
||||
when(build.getProject()).thenReturn(project);
|
||||
return build;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,31 +1,23 @@
|
|||
package com.dabsquared.gitlabjenkins.publisher;
|
||||
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockserver.model.HttpRequest.request;
|
||||
import static org.mockserver.model.HttpResponse.response;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.BuildState;
|
||||
import hudson.EnvVars;
|
||||
import hudson.model.AbstractBuild;
|
||||
import hudson.model.AbstractProject;
|
||||
import hudson.model.BuildListener;
|
||||
import hudson.model.Result;
|
||||
import hudson.model.StreamBuildListener;
|
||||
import hudson.model.TaskListener;
|
||||
import hudson.plugins.git.Revision;
|
||||
import hudson.plugins.git.util.Build;
|
||||
import hudson.plugins.git.util.BuildData;
|
||||
import jenkins.plugins.git.AbstractGitSCMSource;
|
||||
import jenkins.scm.api.SCMRevisionAction;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
|
@ -40,42 +32,37 @@ import org.mockserver.model.HttpRequest;
|
|||
import org.mockserver.model.HttpResponse;
|
||||
import org.mockserver.verify.VerificationTimes;
|
||||
|
||||
import com.cloudbees.plugins.credentials.CredentialsProvider;
|
||||
import com.cloudbees.plugins.credentials.CredentialsScope;
|
||||
import com.cloudbees.plugins.credentials.CredentialsStore;
|
||||
import com.cloudbees.plugins.credentials.SystemCredentialsProvider;
|
||||
import com.cloudbees.plugins.credentials.domains.Domain;
|
||||
import com.dabsquared.gitlabjenkins.connection.GitLabConnection;
|
||||
import com.dabsquared.gitlabjenkins.connection.GitLabConnectionConfig;
|
||||
import com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.BuildState;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import hudson.EnvVars;
|
||||
import hudson.Launcher;
|
||||
import hudson.matrix.MatrixAggregator;
|
||||
import hudson.matrix.MatrixConfiguration;
|
||||
import hudson.matrix.MatrixBuild;
|
||||
import hudson.model.AbstractBuild;
|
||||
import hudson.model.AbstractProject;
|
||||
import hudson.model.BuildListener;
|
||||
import hudson.model.Result;
|
||||
import hudson.model.StreamBuildListener;
|
||||
import hudson.model.TaskListener;
|
||||
import hudson.plugins.git.Revision;
|
||||
import hudson.plugins.git.util.Build;
|
||||
import hudson.plugins.git.util.BuildData;
|
||||
import hudson.util.Secret;
|
||||
import jenkins.model.Jenkins;
|
||||
import jenkins.plugins.git.AbstractGitSCMSource;
|
||||
import jenkins.scm.api.SCMRevisionAction;
|
||||
import static com.dabsquared.gitlabjenkins.publisher.TestUtility.BUILD_URL;
|
||||
import static com.dabsquared.gitlabjenkins.publisher.TestUtility.GITLAB_CONNECTION_V3;
|
||||
import static com.dabsquared.gitlabjenkins.publisher.TestUtility.GITLAB_CONNECTION_V4;
|
||||
import static com.dabsquared.gitlabjenkins.publisher.TestUtility.PROJECT_ID;
|
||||
import static com.dabsquared.gitlabjenkins.publisher.TestUtility.setupGitLabConnections;
|
||||
import static com.dabsquared.gitlabjenkins.publisher.TestUtility.verifyMatrixAggregatable;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockserver.model.HttpRequest.request;
|
||||
import static org.mockserver.model.HttpResponse.response;
|
||||
|
||||
/**
|
||||
* @author Robin Müller
|
||||
*/
|
||||
public class GitLabCommitStatusPublisherTest {
|
||||
|
||||
private static final String GIT_LAB_CONNECTION = "GitLab";
|
||||
private static final String API_TOKEN = "secret";
|
||||
private static final String SHA1 = "0616d12a3a24068691027a1e113147e3c1cfa2f4";
|
||||
|
||||
@ClassRule
|
||||
|
@ -88,17 +75,8 @@ public class GitLabCommitStatusPublisherTest {
|
|||
private BuildListener listener;
|
||||
|
||||
@BeforeClass
|
||||
public static void setupConnection() throws IOException {
|
||||
GitLabConnectionConfig connectionConfig = jenkins.get(GitLabConnectionConfig.class);
|
||||
String apiTokenId = "apiTokenId";
|
||||
for (CredentialsStore credentialsStore : CredentialsProvider.lookupStores(Jenkins.getInstance())) {
|
||||
if (credentialsStore instanceof SystemCredentialsProvider.StoreImpl) {
|
||||
List<Domain> domains = credentialsStore.getDomains();
|
||||
credentialsStore.addCredentials(domains.get(0),
|
||||
new StringCredentialsImpl(CredentialsScope.SYSTEM, apiTokenId, "GitLab API Token", Secret.fromString(API_TOKEN)));
|
||||
}
|
||||
}
|
||||
connectionConfig.addConnection(new GitLabConnection(GIT_LAB_CONNECTION, "http://localhost:" + mockServer.getPort() + "/gitlab", apiTokenId, false, 10, 10));
|
||||
public static void setupClass() throws IOException {
|
||||
setupGitLabConnections(jenkins, mockServer);
|
||||
}
|
||||
|
||||
@Before
|
||||
|
@ -113,283 +91,247 @@ public class GitLabCommitStatusPublisherTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void matrixAggregatable() throws UnsupportedEncodingException, InterruptedException, IOException {
|
||||
AbstractBuild build = mock(AbstractBuild.class);
|
||||
AbstractProject project = mock(MatrixConfiguration.class);
|
||||
GitLabCommitStatusPublisher publisher = mock(GitLabCommitStatusPublisher.class);
|
||||
MatrixBuild parentBuild = mock(MatrixBuild.class);
|
||||
|
||||
when(build.getParent()).thenReturn(project);
|
||||
when(publisher.createAggregator(any(MatrixBuild.class), any(Launcher.class), any(BuildListener.class))).thenCallRealMethod();
|
||||
when(publisher.perform(any(AbstractBuild.class), any(Launcher.class), any(BuildListener.class))).thenReturn(true);
|
||||
|
||||
MatrixAggregator aggregator = publisher.createAggregator(parentBuild, null, listener);
|
||||
aggregator.startBuild();
|
||||
aggregator.endBuild();
|
||||
verify(publisher).perform(parentBuild, null, listener);
|
||||
public void matrixAggregatable() throws InterruptedException, IOException {
|
||||
verifyMatrixAggregatable(GitLabCommitStatusPublisher.class, listener);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void running() throws UnsupportedEncodingException {
|
||||
HttpRequest[] requests = new HttpRequest[] {
|
||||
prepareExistsCommitWithSuccessResponse("test/project", SHA1),
|
||||
prepareUpdateCommitStatusWithSuccessResponse("test/project", SHA1, jenkins.getInstance().getRootUrl() + "/build/123", BuildState.running)
|
||||
};
|
||||
AbstractBuild build = mockBuild(SHA1, "/build/123", GIT_LAB_CONNECTION, null, "test/project.git");
|
||||
public void running_v3() throws UnsupportedEncodingException {
|
||||
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V3, null, "test/project.git");
|
||||
HttpRequest[] requests = prepareCheckCommitAndUpdateStatusRequests("v3", BuildState.running);
|
||||
|
||||
GitLabCommitStatusPublisher publisher = new GitLabCommitStatusPublisher("jenkins", false);
|
||||
publisher.prebuild(build, listener);
|
||||
|
||||
mockServerClient.verify(requests);
|
||||
prebuildAndVerify(build, listener, requests);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void running_v4() throws UnsupportedEncodingException {
|
||||
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V4, null, "test/project.git");
|
||||
HttpRequest[] requests = prepareCheckCommitAndUpdateStatusRequests("v4", BuildState.running);
|
||||
|
||||
prebuildAndVerify(build, listener, requests);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void runningWithLibrary() throws UnsupportedEncodingException {
|
||||
HttpRequest[] requests = new HttpRequest[] {
|
||||
prepareExistsCommitWithSuccessResponse("test/project", SHA1),
|
||||
prepareUpdateCommitStatusWithSuccessResponse("test/project", SHA1, jenkins.getInstance().getRootUrl() + "/build/123", BuildState.running)
|
||||
};
|
||||
AbstractBuild build = mockBuildWithLibrary(SHA1, "/build/123", GIT_LAB_CONNECTION, null, "test/project.git");
|
||||
AbstractBuild build = mockBuildWithLibrary(GITLAB_CONNECTION_V4, null, "test/project.git");
|
||||
HttpRequest[] requests = prepareCheckCommitAndUpdateStatusRequests("v4", BuildState.running);
|
||||
|
||||
GitLabCommitStatusPublisher publisher = new GitLabCommitStatusPublisher("jenkins", false);
|
||||
publisher.prebuild(build, listener);
|
||||
|
||||
mockServerClient.verify(requests);
|
||||
prebuildAndVerify(build, listener, requests);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void runningWithDotInProjectId() throws IOException {
|
||||
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V4, null, "test/project.test.git");
|
||||
HttpRequest[] requests = new HttpRequest[] {
|
||||
prepareGetProjectResponse("test/project.test",1),
|
||||
prepareExistsCommitWithSuccessResponse("1", SHA1),
|
||||
prepareUpdateCommitStatusWithSuccessResponse("1", SHA1, jenkins.getInstance().getRootUrl() + "/build/123", BuildState.running)
|
||||
prepareGetProjectResponse("test/project.test"),
|
||||
prepareExistsCommitWithSuccessResponse("v4", String.valueOf(PROJECT_ID)),
|
||||
prepareUpdateCommitStatusWithSuccessResponse("v4", String.valueOf(PROJECT_ID), BuildState.running)
|
||||
};
|
||||
AbstractBuild build = mockBuild(SHA1, "/build/123", GIT_LAB_CONNECTION, null, "test/project.test.git");
|
||||
|
||||
GitLabCommitStatusPublisher publisher = new GitLabCommitStatusPublisher("jenkins", false);
|
||||
publisher.prebuild(build, listener);
|
||||
|
||||
mockServerClient.verify(requests);
|
||||
prebuildAndVerify(build, listener, requests);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void canceled() throws IOException, InterruptedException {
|
||||
HttpRequest[] requests = new HttpRequest[] {
|
||||
prepareExistsCommitWithSuccessResponse("test/project", SHA1),
|
||||
prepareUpdateCommitStatusWithSuccessResponse("test/project", SHA1, jenkins.getInstance().getRootUrl() + "/build/123", BuildState.canceled)
|
||||
};
|
||||
AbstractBuild build = mockBuild(SHA1, "/build/123", GIT_LAB_CONNECTION, Result.ABORTED, "test/project.git");
|
||||
public void canceled_v3() throws IOException, InterruptedException {
|
||||
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V3, Result.ABORTED, "test/project.git");
|
||||
HttpRequest[] requests = prepareCheckCommitAndUpdateStatusRequests("v3", BuildState.canceled);
|
||||
|
||||
GitLabCommitStatusPublisher publisher = new GitLabCommitStatusPublisher("jenkins", false);
|
||||
publisher.perform(build, null, listener);
|
||||
performAndVerify(build, false, requests);
|
||||
}
|
||||
|
||||
mockServerClient.verify(requests);
|
||||
@Test
|
||||
public void canceled_v4() throws IOException, InterruptedException {
|
||||
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V4, Result.ABORTED, "test/project.git");
|
||||
HttpRequest[] requests = prepareCheckCommitAndUpdateStatusRequests("v4", BuildState.canceled);
|
||||
|
||||
performAndVerify(build, false, requests);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void canceledWithLibrary() throws IOException, InterruptedException {
|
||||
HttpRequest[] requests = new HttpRequest[] {
|
||||
prepareExistsCommitWithSuccessResponse("test/project", SHA1),
|
||||
prepareUpdateCommitStatusWithSuccessResponse("test/project", SHA1, jenkins.getInstance().getRootUrl() + "/build/123", BuildState.canceled)
|
||||
};
|
||||
AbstractBuild build = mockBuildWithLibrary(SHA1, "/build/123", GIT_LAB_CONNECTION, Result.ABORTED, "test/project.git");
|
||||
AbstractBuild build = mockBuildWithLibrary(GITLAB_CONNECTION_V4, Result.ABORTED, "test/project.git");
|
||||
HttpRequest[] requests = prepareCheckCommitAndUpdateStatusRequests("v4", BuildState.canceled);
|
||||
|
||||
GitLabCommitStatusPublisher publisher = new GitLabCommitStatusPublisher("jenkins", false);
|
||||
publisher.perform(build, null, listener);
|
||||
|
||||
mockServerClient.verify(requests);
|
||||
performAndVerify(build, false, requests);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void success() throws IOException, InterruptedException {
|
||||
HttpRequest[] requests = new HttpRequest[] {
|
||||
prepareExistsCommitWithSuccessResponse("test/project", SHA1),
|
||||
prepareUpdateCommitStatusWithSuccessResponse("test/project", SHA1, jenkins.getInstance().getRootUrl() + "/build/123", BuildState.success)
|
||||
};
|
||||
AbstractBuild build = mockBuild(SHA1, "/build/123", GIT_LAB_CONNECTION, Result.SUCCESS, "test/project.git");
|
||||
public void success_v3() throws IOException, InterruptedException {
|
||||
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V3, Result.SUCCESS, "test/project.git");
|
||||
HttpRequest[] requests = prepareCheckCommitAndUpdateStatusRequests("v3", BuildState.success);
|
||||
|
||||
GitLabCommitStatusPublisher publisher = new GitLabCommitStatusPublisher("jenkins", false);
|
||||
publisher.perform(build, null, listener);
|
||||
performAndVerify(build, false, requests);
|
||||
}
|
||||
|
||||
mockServerClient.verify(requests);
|
||||
|
||||
@Test
|
||||
public void success_v4() throws IOException, InterruptedException {
|
||||
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V4, Result.SUCCESS, "test/project.git");
|
||||
HttpRequest[] requests = prepareCheckCommitAndUpdateStatusRequests("v4", BuildState.success);
|
||||
|
||||
performAndVerify(build, false, requests);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void successWithLibrary() throws IOException, InterruptedException {
|
||||
HttpRequest[] requests = new HttpRequest[] {
|
||||
prepareExistsCommitWithSuccessResponse("test/project", SHA1),
|
||||
prepareUpdateCommitStatusWithSuccessResponse("test/project", SHA1, jenkins.getInstance().getRootUrl() + "/build/123", BuildState.success)
|
||||
};
|
||||
AbstractBuild build = mockBuildWithLibrary(SHA1, "/build/123", GIT_LAB_CONNECTION, Result.SUCCESS, "test/project.git");
|
||||
AbstractBuild build = mockBuildWithLibrary(GITLAB_CONNECTION_V4, Result.SUCCESS, "test/project.git");
|
||||
HttpRequest[] requests = prepareCheckCommitAndUpdateStatusRequests("v4", BuildState.success);
|
||||
|
||||
GitLabCommitStatusPublisher publisher = new GitLabCommitStatusPublisher("jenkins", false);
|
||||
publisher.perform(build, null, listener);
|
||||
|
||||
mockServerClient.verify(requests);
|
||||
performAndVerify(build, false, requests);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failed() throws IOException, InterruptedException {
|
||||
HttpRequest[] requests = new HttpRequest[] {
|
||||
prepareExistsCommitWithSuccessResponse("test/project", SHA1),
|
||||
prepareUpdateCommitStatusWithSuccessResponse("test/project", SHA1, jenkins.getInstance().getRootUrl() + "/build/123", BuildState.failed)
|
||||
};
|
||||
AbstractBuild build = mockBuild(SHA1, "/build/123", GIT_LAB_CONNECTION, Result.FAILURE, "test/project.git");
|
||||
public void failed_v3() throws IOException, InterruptedException {
|
||||
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V3, Result.FAILURE, "test/project.git");
|
||||
HttpRequest[] requests = prepareCheckCommitAndUpdateStatusRequests("v3", BuildState.failed);
|
||||
|
||||
GitLabCommitStatusPublisher publisher = new GitLabCommitStatusPublisher("jenkins", false);
|
||||
publisher.perform(build, null, listener);
|
||||
performAndVerify(build, false, requests);
|
||||
}
|
||||
|
||||
mockServerClient.verify(requests);
|
||||
@Test
|
||||
public void failed_v4() throws IOException, InterruptedException {
|
||||
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V3, Result.FAILURE, "test/project.git");
|
||||
HttpRequest[] requests = prepareCheckCommitAndUpdateStatusRequests("v3", BuildState.failed);
|
||||
|
||||
performAndVerify(build, false, requests);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failedWithLibrary() throws IOException, InterruptedException {
|
||||
HttpRequest[] requests = new HttpRequest[] {
|
||||
prepareExistsCommitWithSuccessResponse("test/project", SHA1),
|
||||
prepareUpdateCommitStatusWithSuccessResponse("test/project", SHA1, jenkins.getInstance().getRootUrl() + "/build/123", BuildState.failed)
|
||||
};
|
||||
AbstractBuild build = mockBuildWithLibrary(SHA1, "/build/123", GIT_LAB_CONNECTION, Result.FAILURE, "test/project.git");
|
||||
AbstractBuild build = mockBuildWithLibrary(GITLAB_CONNECTION_V4, Result.FAILURE, "test/project.git");
|
||||
HttpRequest[] requests = prepareCheckCommitAndUpdateStatusRequests("v4", BuildState.failed);
|
||||
|
||||
GitLabCommitStatusPublisher publisher = new GitLabCommitStatusPublisher("jenkins", false);
|
||||
publisher.perform(build, null, listener);
|
||||
|
||||
mockServerClient.verify(requests);
|
||||
performAndVerify(build, false, requests);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unstable() throws IOException, InterruptedException {
|
||||
HttpRequest[] requests = new HttpRequest[] {
|
||||
prepareExistsCommitWithSuccessResponse("test/project", SHA1),
|
||||
prepareUpdateCommitStatusWithSuccessResponse("test/project", SHA1, jenkins.getInstance().getRootUrl() + "/build/123", BuildState.failed)
|
||||
};
|
||||
AbstractBuild build = mockBuild(SHA1, "/build/123", GIT_LAB_CONNECTION, Result.UNSTABLE, "test/project.git");
|
||||
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V4, Result.UNSTABLE, "test/project.git");
|
||||
HttpRequest[] requests = prepareCheckCommitAndUpdateStatusRequests("v4", BuildState.failed);
|
||||
|
||||
GitLabCommitStatusPublisher publisher = new GitLabCommitStatusPublisher("jenkins", false);
|
||||
publisher.perform(build, null, listener);
|
||||
|
||||
mockServerClient.verify(requests);
|
||||
performAndVerify(build, false, requests);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unstableWithLibrary() throws IOException, InterruptedException {
|
||||
HttpRequest[] requests = new HttpRequest[] {
|
||||
prepareExistsCommitWithSuccessResponse("test/project", SHA1),
|
||||
prepareUpdateCommitStatusWithSuccessResponse("test/project", SHA1, jenkins.getInstance().getRootUrl() + "/build/123", BuildState.failed)
|
||||
};
|
||||
AbstractBuild build = mockBuildWithLibrary(SHA1, "/build/123", GIT_LAB_CONNECTION, Result.UNSTABLE, "test/project.git");
|
||||
AbstractBuild build = mockBuildWithLibrary(GITLAB_CONNECTION_V4, Result.UNSTABLE, "test/project.git");
|
||||
HttpRequest[] requests = prepareCheckCommitAndUpdateStatusRequests("v4", BuildState.failed);
|
||||
|
||||
GitLabCommitStatusPublisher publisher = new GitLabCommitStatusPublisher("jenkins", false);
|
||||
publisher.perform(build, null, listener);
|
||||
|
||||
mockServerClient.verify(requests);
|
||||
performAndVerify(build, false, requests);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unstableAsSuccess() throws IOException, InterruptedException {
|
||||
HttpRequest[] requests = new HttpRequest[] {
|
||||
prepareExistsCommitWithSuccessResponse("test/project", SHA1),
|
||||
prepareUpdateCommitStatusWithSuccessResponse("test/project", SHA1, jenkins.getInstance().getRootUrl() + "/build/123", BuildState.success)
|
||||
};
|
||||
AbstractBuild build = mockBuild(SHA1, "/build/123", GIT_LAB_CONNECTION, Result.UNSTABLE, "test/project.git");
|
||||
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V4, Result.UNSTABLE, "test/project.git");
|
||||
HttpRequest[] requests = prepareCheckCommitAndUpdateStatusRequests("v4", BuildState.success);
|
||||
|
||||
GitLabCommitStatusPublisher publisher = new GitLabCommitStatusPublisher("jenkins", true);
|
||||
publisher.perform(build, null, listener);
|
||||
|
||||
mockServerClient.verify(requests);
|
||||
performAndVerify(build, true, requests);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void running_multipleRepos() throws UnsupportedEncodingException {
|
||||
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V4, null, "test/project-1.git", "test/project-2.git");
|
||||
HttpRequest[] requests = new HttpRequest[] {
|
||||
prepareExistsCommitWithSuccessResponse("test/project-1", SHA1),
|
||||
prepareUpdateCommitStatusWithSuccessResponse("test/project-1", SHA1, jenkins.getInstance().getRootUrl() + "/build/123", BuildState.running),
|
||||
prepareExistsCommitWithSuccessResponse("test/project-2", SHA1),
|
||||
prepareUpdateCommitStatusWithSuccessResponse("test/project-2", SHA1, jenkins.getInstance().getRootUrl() + "/build/123", BuildState.running)
|
||||
prepareExistsCommitWithSuccessResponse("v4", "test/project-1"),
|
||||
prepareUpdateCommitStatusWithSuccessResponse("v4", "test/project-1", BuildState.running),
|
||||
prepareExistsCommitWithSuccessResponse("v4", "test/project-2"),
|
||||
prepareUpdateCommitStatusWithSuccessResponse("v4", "test/project-2", BuildState.running)
|
||||
};
|
||||
AbstractBuild build = mockBuild(SHA1, "/build/123", GIT_LAB_CONNECTION, null, "test/project-1.git", "test/project-2.git");
|
||||
|
||||
GitLabCommitStatusPublisher publisher = new GitLabCommitStatusPublisher("jenkins", false);
|
||||
publisher.prebuild(build, listener);
|
||||
|
||||
mockServerClient.verify(requests);
|
||||
prebuildAndVerify(build, listener, requests);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void running_commitNotExists() throws UnsupportedEncodingException {
|
||||
HttpRequest updateCommitStatus = prepareUpdateCommitStatusWithSuccessResponse("test/project", SHA1, jenkins.getInstance().getRootUrl() + "/build/123", BuildState.running);
|
||||
AbstractBuild build = mockBuild(SHA1, "/build/123", GIT_LAB_CONNECTION, null, "test/project.git");
|
||||
|
||||
GitLabCommitStatusPublisher publisher = new GitLabCommitStatusPublisher("jenkins", false);
|
||||
publisher.prebuild(build, listener);
|
||||
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V4, null, "test/project.git");
|
||||
HttpRequest updateCommitStatus = prepareUpdateCommitStatusWithSuccessResponse("v4", "test/project", BuildState.running);
|
||||
|
||||
new GitLabCommitStatusPublisher("jenkins", false).prebuild(build, listener);
|
||||
mockServerClient.verify(updateCommitStatus, VerificationTimes.exactly(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void running_failToUpdate() throws UnsupportedEncodingException {
|
||||
prepareExistsCommitWithSuccessResponse("test/project", SHA1);
|
||||
HttpRequest updateCommitStatus = prepareUpdateCommitStatus("test/project", SHA1, jenkins.getInstance().getRootUrl() + "/build/123", BuildState.running);
|
||||
mockServerClient.when(updateCommitStatus).respond(response().withStatusCode(403));
|
||||
AbstractBuild build = mockBuild(SHA1, "/build/123", GIT_LAB_CONNECTION, null, "test/project.git");
|
||||
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V4, null, "test/project.git");
|
||||
BuildListener buildListener = mock(BuildListener.class);
|
||||
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
when(buildListener.getLogger()).thenReturn(new PrintStream(outputStream));
|
||||
|
||||
GitLabCommitStatusPublisher publisher = new GitLabCommitStatusPublisher("jenkins", false);
|
||||
publisher.prebuild(build, buildListener);
|
||||
prepareExistsCommitWithSuccessResponse("v4", "test/project");
|
||||
HttpRequest updateCommitStatus = prepareUpdateCommitStatus("v4", "test/project", BuildState.running);
|
||||
mockServerClient.when(updateCommitStatus).respond(response().withStatusCode(403));
|
||||
|
||||
prebuildAndVerify(build, buildListener, updateCommitStatus);
|
||||
assertThat(outputStream.toString(), CoreMatchers.containsString("Failed to update Gitlab commit status for project 'test/project': HTTP 403 Forbidden"));
|
||||
mockServerClient.verify(updateCommitStatus);
|
||||
}
|
||||
|
||||
private void prebuildAndVerify(AbstractBuild build, BuildListener listener, HttpRequest... requests) {
|
||||
new GitLabCommitStatusPublisher("jenkins", false).prebuild(build, listener);
|
||||
mockServerClient.verify(requests);
|
||||
}
|
||||
|
||||
private HttpRequest prepareUpdateCommitStatusWithSuccessResponse(String projectId, String sha, String targetUrl, BuildState state) throws UnsupportedEncodingException {
|
||||
HttpRequest updateCommitStatus = prepareUpdateCommitStatus(projectId, sha, targetUrl, state);
|
||||
private void performAndVerify(AbstractBuild build, boolean markUnstableAsSuccess, HttpRequest... requests) throws InterruptedException, IOException {
|
||||
new GitLabCommitStatusPublisher("jenkins", markUnstableAsSuccess).perform(build, null, listener);
|
||||
mockServerClient.verify(requests);
|
||||
}
|
||||
|
||||
private HttpRequest[] prepareCheckCommitAndUpdateStatusRequests(String apiLevel, BuildState buildState) throws UnsupportedEncodingException {
|
||||
return new HttpRequest[] {
|
||||
prepareExistsCommitWithSuccessResponse(apiLevel, "test/project"),
|
||||
prepareUpdateCommitStatusWithSuccessResponse(apiLevel, "test/project", buildState)
|
||||
};
|
||||
}
|
||||
|
||||
private HttpRequest prepareUpdateCommitStatusWithSuccessResponse(String apiLevel, String projectName, BuildState state) throws UnsupportedEncodingException {
|
||||
HttpRequest updateCommitStatus = prepareUpdateCommitStatus(apiLevel, projectName, state);
|
||||
mockServerClient.when(updateCommitStatus).respond(response().withStatusCode(200));
|
||||
return updateCommitStatus;
|
||||
}
|
||||
|
||||
|
||||
private HttpRequest prepareUpdateCommitStatus(String projectId, String sha, String targetUrl, BuildState state) throws UnsupportedEncodingException {
|
||||
private HttpRequest prepareUpdateCommitStatus(final String apiLevel, String projectName, BuildState state) throws UnsupportedEncodingException {
|
||||
return request()
|
||||
.withPath("/gitlab/api/v3/projects/" + URLEncoder.encode(projectId, "UTF-8") + "/statuses/" + sha)
|
||||
.withPath("/gitlab/api/" + apiLevel + "/projects/" + URLEncoder.encode(projectName, "UTF-8") + "/statuses/" + SHA1)
|
||||
.withMethod("POST")
|
||||
.withHeader("PRIVATE-TOKEN", "secret")
|
||||
.withBody("state=" + URLEncoder.encode(state.name(), "UTF-8") + "&context=jenkins&" + "target_url=" + URLEncoder.encode(targetUrl, "UTF-8"));
|
||||
.withBody("state=" + URLEncoder.encode(state.name(), "UTF-8") + "&context=jenkins&" + "target_url=" + URLEncoder.encode(jenkins.getInstance().getRootUrl() + BUILD_URL, "UTF-8"));
|
||||
}
|
||||
|
||||
private HttpRequest prepareExistsCommitWithSuccessResponse(String projectId, String sha) throws UnsupportedEncodingException {
|
||||
HttpRequest existsCommit = prepareExistsCommit(projectId, sha);
|
||||
private HttpRequest prepareExistsCommitWithSuccessResponse(String apiLevel, String projectName) throws UnsupportedEncodingException {
|
||||
HttpRequest existsCommit = prepareExistsCommit(apiLevel, projectName);
|
||||
mockServerClient.when(existsCommit).respond(response().withStatusCode(200));
|
||||
return existsCommit;
|
||||
}
|
||||
|
||||
private HttpRequest prepareExistsCommit(String projectId, String sha) throws UnsupportedEncodingException {
|
||||
private HttpRequest prepareExistsCommit(String apiLevel, String projectName) throws UnsupportedEncodingException {
|
||||
return request()
|
||||
.withPath("/gitlab/api/v3/projects/" + URLEncoder.encode(projectId, "UTF-8") + "/repository/commits/" + sha)
|
||||
.withPath("/gitlab/api/" + apiLevel + "/projects/" + URLEncoder.encode(projectName, "UTF-8") + "/repository/commits/" + SHA1)
|
||||
.withMethod("GET")
|
||||
.withHeader("PRIVATE-TOKEN", "secret");
|
||||
}
|
||||
|
||||
private HttpRequest prepareGetProjectResponse(String projectName, int projectId) throws IOException {
|
||||
private HttpRequest prepareGetProjectResponse(String projectName) throws IOException {
|
||||
HttpRequest request= request()
|
||||
.withPath("/gitlab/api/v3/projects/" + URLEncoder.encode(projectName, "UTF-8"))
|
||||
.withPath("/gitlab/api/v4/projects/" + URLEncoder.encode(projectName, "UTF-8"))
|
||||
.withMethod("GET")
|
||||
. withHeader("PRIVATE-TOKEN", "secret");
|
||||
|
||||
HttpResponse response = response().withBody(getSingleProjectJson("GetSingleProject.json",projectName,projectId));
|
||||
HttpResponse response = response().withBody(getSingleProjectJson("GetSingleProject.json", projectName, PROJECT_ID));
|
||||
|
||||
response.withHeader("Content-Type", "application/json");
|
||||
mockServerClient.when(request).respond(response.withStatusCode(200));
|
||||
return request;
|
||||
}
|
||||
|
||||
private AbstractBuild mockBuild(String sha, String buildUrl, String gitLabConnection, Result result, String... remoteUrls) {
|
||||
private AbstractBuild mockBuild(String gitLabConnection, Result result, String... remoteUrls) {
|
||||
AbstractBuild build = mock(AbstractBuild.class);
|
||||
List<BuildData> buildDatas = new ArrayList<BuildData>();
|
||||
List<BuildData> buildDatas = new ArrayList<>();
|
||||
BuildData buildData = mock(BuildData.class);
|
||||
Revision revision = mock(Revision.class);
|
||||
when(revision.getSha1String()).thenReturn(sha);
|
||||
when(revision.getSha1String()).thenReturn(SHA1);
|
||||
when(buildData.getLastBuiltRevision()).thenReturn(revision);
|
||||
when(buildData.getRemoteUrls()).thenReturn(new HashSet<>(Arrays.asList(remoteUrls)));
|
||||
Build gitBuild = mock(Build.class);
|
||||
|
@ -399,7 +341,7 @@ public class GitLabCommitStatusPublisherTest {
|
|||
when(build.getActions(BuildData.class)).thenReturn(buildDatas);
|
||||
when(build.getAction(BuildData.class)).thenReturn(buildData);
|
||||
when(build.getResult()).thenReturn(result);
|
||||
when(build.getUrl()).thenReturn(buildUrl);
|
||||
when(build.getUrl()).thenReturn(BUILD_URL);
|
||||
AbstractProject<?, ?> project = mock(AbstractProject.class);
|
||||
when(project.getProperty(GitLabConnectionProperty.class)).thenReturn(new GitLabConnectionProperty(gitLabConnection));
|
||||
when(build.getProject()).thenReturn(project);
|
||||
|
@ -418,26 +360,26 @@ public class GitLabCommitStatusPublisherTest {
|
|||
return build;
|
||||
}
|
||||
|
||||
private AbstractBuild mockBuildWithLibrary(String sha, String buildUrl, String gitLabConnection, Result result, String... remoteUrls) {
|
||||
private AbstractBuild mockBuildWithLibrary(String gitLabConnection, Result result, String... remoteUrls) {
|
||||
AbstractBuild build = mock(AbstractBuild.class);
|
||||
List<BuildData> buildDatas = new ArrayList<BuildData>();
|
||||
List<BuildData> buildDatas = new ArrayList<>();
|
||||
BuildData buildData = mock(BuildData.class);
|
||||
SCMRevisionAction scmRevisionAction = mock(SCMRevisionAction.class);
|
||||
AbstractGitSCMSource.SCMRevisionImpl revisionImpl = mock(AbstractGitSCMSource.SCMRevisionImpl.class);
|
||||
|
||||
when(build.getAction(SCMRevisionAction.class)).thenReturn(scmRevisionAction);
|
||||
when(scmRevisionAction.getRevision()).thenReturn(revisionImpl);
|
||||
when(revisionImpl.getHash()).thenReturn(sha);
|
||||
when(revisionImpl.getHash()).thenReturn(SHA1);
|
||||
|
||||
Revision revision = mock(Revision.class);
|
||||
when(revision.getSha1String()).thenReturn(sha);
|
||||
when(revision.getSha1String()).thenReturn(SHA1);
|
||||
when(buildData.getLastBuiltRevision()).thenReturn(revision);
|
||||
when(buildData.getRemoteUrls()).thenReturn(new HashSet<>(Arrays.asList(remoteUrls)));
|
||||
|
||||
Build gitBuild = mock(Build.class);
|
||||
|
||||
when(gitBuild.getMarked()).thenReturn(revision);
|
||||
when(gitBuild.getSHA1()).thenReturn(ObjectId.fromString(sha));
|
||||
when(gitBuild.getSHA1()).thenReturn(ObjectId.fromString(SHA1));
|
||||
when(buildData.getLastBuild(any(ObjectId.class))).thenReturn(gitBuild);
|
||||
Map<String, Build> buildsByBranchName = new HashMap<>();
|
||||
buildsByBranchName.put("develop", gitBuild);
|
||||
|
@ -456,7 +398,7 @@ public class GitLabCommitStatusPublisherTest {
|
|||
|
||||
when(build.getActions(BuildData.class)).thenReturn(buildDatas);
|
||||
when(build.getResult()).thenReturn(result);
|
||||
when(build.getUrl()).thenReturn(buildUrl);
|
||||
when(build.getUrl()).thenReturn(BUILD_URL);
|
||||
|
||||
AbstractProject<?, ?> project = mock(AbstractProject.class);
|
||||
when(project.getProperty(GitLabConnectionProperty.class)).thenReturn(new GitLabConnectionProperty(gitLabConnection));
|
||||
|
|
|
@ -1,18 +1,8 @@
|
|||
package com.dabsquared.gitlabjenkins.publisher;
|
||||
|
||||
import com.cloudbees.plugins.credentials.CredentialsProvider;
|
||||
import com.cloudbees.plugins.credentials.CredentialsScope;
|
||||
import com.cloudbees.plugins.credentials.CredentialsStore;
|
||||
import com.cloudbees.plugins.credentials.SystemCredentialsProvider;
|
||||
import com.cloudbees.plugins.credentials.domains.Domain;
|
||||
import com.dabsquared.gitlabjenkins.connection.GitLabConnection;
|
||||
import com.dabsquared.gitlabjenkins.connection.GitLabConnectionConfig;
|
||||
|
||||
import com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty;
|
||||
import hudson.EnvVars;
|
||||
import hudson.Launcher;
|
||||
import hudson.matrix.MatrixAggregator;
|
||||
import hudson.matrix.MatrixConfiguration;
|
||||
import hudson.matrix.MatrixBuild;
|
||||
import hudson.model.AbstractBuild;
|
||||
import hudson.model.AbstractProject;
|
||||
import hudson.model.BuildListener;
|
||||
|
@ -20,9 +10,6 @@ import hudson.model.Result;
|
|||
import hudson.model.StreamBuildListener;
|
||||
import hudson.model.TaskListener;
|
||||
import hudson.plugins.git.util.BuildData;
|
||||
import hudson.util.Secret;
|
||||
import jenkins.model.Jenkins;
|
||||
import org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
|
@ -39,17 +26,23 @@ import java.io.IOException;
|
|||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.Charset;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
import static com.dabsquared.gitlabjenkins.publisher.TestUtility.BUILD_NUMBER;
|
||||
import static com.dabsquared.gitlabjenkins.publisher.TestUtility.BUILD_URL;
|
||||
import static com.dabsquared.gitlabjenkins.publisher.TestUtility.GITLAB_CONNECTION_V3;
|
||||
import static com.dabsquared.gitlabjenkins.publisher.TestUtility.GITLAB_CONNECTION_V4;
|
||||
import static com.dabsquared.gitlabjenkins.publisher.TestUtility.MERGE_REQUEST_ID;
|
||||
import static com.dabsquared.gitlabjenkins.publisher.TestUtility.PROJECT_ID;
|
||||
import static com.dabsquared.gitlabjenkins.publisher.TestUtility.formatNote;
|
||||
import static com.dabsquared.gitlabjenkins.publisher.TestUtility.setupGitLabConnections;
|
||||
import static com.dabsquared.gitlabjenkins.publisher.TestUtility.verifyMatrixAggregatable;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockserver.model.HttpRequest.request;
|
||||
import static org.mockserver.model.HttpResponse.response;
|
||||
|
@ -58,10 +51,6 @@ import static org.mockserver.model.HttpResponse.response;
|
|||
* @author Nikolay Ustinov
|
||||
*/
|
||||
public class GitLabMessagePublisherTest {
|
||||
|
||||
private static final String GIT_LAB_CONNECTION = "GitLab";
|
||||
private static final String API_TOKEN = "secret";
|
||||
|
||||
@ClassRule
|
||||
public static MockServerRule mockServer = new MockServerRule(new Object());
|
||||
|
||||
|
@ -72,17 +61,8 @@ public class GitLabMessagePublisherTest {
|
|||
private BuildListener listener;
|
||||
|
||||
@BeforeClass
|
||||
public static void setupConnection() throws IOException {
|
||||
GitLabConnectionConfig connectionConfig = jenkins.get(GitLabConnectionConfig.class);
|
||||
String apiTokenId = "apiTokenId";
|
||||
for (CredentialsStore credentialsStore : CredentialsProvider.lookupStores(Jenkins.getInstance())) {
|
||||
if (credentialsStore instanceof SystemCredentialsProvider.StoreImpl) {
|
||||
List<Domain> domains = credentialsStore.getDomains();
|
||||
credentialsStore.addCredentials(domains.get(0),
|
||||
new StringCredentialsImpl(CredentialsScope.SYSTEM, apiTokenId, "GitLab API Token", Secret.fromString(API_TOKEN)));
|
||||
}
|
||||
}
|
||||
connectionConfig.addConnection(new GitLabConnection(GIT_LAB_CONNECTION, "http://localhost:" + mockServer.getPort() + "/gitlab", apiTokenId, false, 10, 10));
|
||||
public static void setupClass() throws IOException {
|
||||
setupGitLabConnections(jenkins, mockServer);
|
||||
}
|
||||
|
||||
@Before
|
||||
|
@ -97,229 +77,170 @@ public class GitLabMessagePublisherTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void canceled() throws IOException, InterruptedException {
|
||||
Integer buildNumber = 1;
|
||||
Integer projectId = 3;
|
||||
Integer mergeRequestId = 1;
|
||||
AbstractBuild build = mockBuild("/build/123", GIT_LAB_CONNECTION, Result.ABORTED, buildNumber);
|
||||
String buildUrl = Jenkins.getInstance().getRootUrl() + build.getUrl();
|
||||
String defaultNote = MessageFormat.format(":point_up: Jenkins Build {0}\n\nResults available at: [Jenkins [{1} #{2}]]({3})",
|
||||
Result.ABORTED, build.getParent().getDisplayName(), buildNumber, buildUrl);
|
||||
|
||||
HttpRequest[] requests = new HttpRequest[] {
|
||||
prepareSendMessageWithSuccessResponse(projectId, mergeRequestId, defaultNote)
|
||||
};
|
||||
|
||||
GitLabMessagePublisher publisher = spy(new GitLabMessagePublisher(false, false, false, false, false, null, null, null, null));
|
||||
doReturn(projectId).when(publisher).getProjectId(build);
|
||||
doReturn(mergeRequestId).when(publisher).getMergeRequestId(build);
|
||||
publisher.perform(build, null, listener);
|
||||
|
||||
mockServerClient.verify(requests);
|
||||
public void matrixAggregatable() throws InterruptedException, IOException {
|
||||
verifyMatrixAggregatable(GitLabMessagePublisher.class, listener);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void matrixAggregatable() throws UnsupportedEncodingException, InterruptedException, IOException {
|
||||
AbstractBuild build = mock(AbstractBuild.class);
|
||||
AbstractProject project = mock(MatrixConfiguration.class);
|
||||
GitLabCommitStatusPublisher publisher = mock(GitLabCommitStatusPublisher.class);
|
||||
MatrixBuild parentBuild = mock(MatrixBuild.class);
|
||||
public void canceled_v3() throws IOException, InterruptedException {
|
||||
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V3, Result.ABORTED);
|
||||
String defaultNote = formatNote(build, ":point_up: Jenkins Build {0}\n\nResults available at: [Jenkins [{1} #{2}]]({3})");
|
||||
|
||||
when(build.getParent()).thenReturn(project);
|
||||
when(publisher.createAggregator(any(MatrixBuild.class), any(Launcher.class), any(BuildListener.class))).thenCallRealMethod();
|
||||
when(publisher.perform(any(AbstractBuild.class), any(Launcher.class), any(BuildListener.class))).thenReturn(true);
|
||||
|
||||
MatrixAggregator aggregator = publisher.createAggregator(parentBuild, null, listener);
|
||||
aggregator.startBuild();
|
||||
aggregator.endBuild();
|
||||
verify(publisher).perform(parentBuild, null, listener);
|
||||
performAndVerify(
|
||||
build, defaultNote, false, false, false, false, false,
|
||||
prepareSendMessageWithSuccessResponse("v3", defaultNote));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void canceled_v4() throws IOException, InterruptedException {
|
||||
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V4, Result.ABORTED);
|
||||
String defaultNote = formatNote(build, ":point_up: Jenkins Build {0}\n\nResults available at: [Jenkins [{1} #{2}]]({3})");
|
||||
|
||||
performAndVerify(
|
||||
build, defaultNote, false, false, false, false, false,
|
||||
prepareSendMessageWithSuccessResponse("v4", defaultNote));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void success_v3() throws IOException, InterruptedException {
|
||||
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V3, Result.SUCCESS);
|
||||
String defaultNote = formatNote(build, ":white_check_mark: Jenkins Build {0}\n\nResults available at: [Jenkins [{1} #{2}]]({3})");
|
||||
|
||||
performAndVerify(
|
||||
build, defaultNote, false, false, false, false, false,
|
||||
prepareSendMessageWithSuccessResponse("v3", defaultNote));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void success() throws IOException, InterruptedException {
|
||||
Integer buildNumber = 1;
|
||||
Integer projectId = 3;
|
||||
Integer mergeRequestId = 1;
|
||||
AbstractBuild build = mockBuild("/build/123", GIT_LAB_CONNECTION, Result.SUCCESS, buildNumber);
|
||||
String buildUrl = Jenkins.getInstance().getRootUrl() + build.getUrl();
|
||||
String defaultNote = MessageFormat.format(":white_check_mark: Jenkins Build {0}\n\nResults available at: [Jenkins [{1} #{2}]]({3})",
|
||||
Result.SUCCESS, build.getParent().getDisplayName(), buildNumber, buildUrl);
|
||||
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V4, Result.SUCCESS);
|
||||
String defaultNote = formatNote(build, ":white_check_mark: Jenkins Build {0}\n\nResults available at: [Jenkins [{1} #{2}]]({3})");
|
||||
|
||||
HttpRequest[] requests = new HttpRequest[] {
|
||||
prepareSendMessageWithSuccessResponse(projectId, mergeRequestId, defaultNote)
|
||||
};
|
||||
|
||||
GitLabMessagePublisher publisher = spy(new GitLabMessagePublisher(false, false, false, false, false, null, null, null, null));
|
||||
doReturn(projectId).when(publisher).getProjectId(build);
|
||||
doReturn(mergeRequestId).when(publisher).getMergeRequestId(build);
|
||||
publisher.perform(build, null, listener);
|
||||
|
||||
mockServerClient.verify(requests);
|
||||
performAndVerify(
|
||||
build, defaultNote, false, false, false, false, false,
|
||||
prepareSendMessageWithSuccessResponse("v4", defaultNote));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void success_withOnlyForFailure() throws IOException, InterruptedException {
|
||||
Integer buildNumber = 1;
|
||||
Integer projectId = 3;
|
||||
Integer mergeRequestId = 1;
|
||||
AbstractBuild build = mockBuild("/build/123", GIT_LAB_CONNECTION, Result.SUCCESS, buildNumber);
|
||||
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V4, Result.SUCCESS);
|
||||
|
||||
GitLabMessagePublisher publisher = spy(new GitLabMessagePublisher(true, false, false, false, false, null, null, null, null));
|
||||
doReturn(projectId).when(publisher).getProjectId(build);
|
||||
doReturn(mergeRequestId).when(publisher).getMergeRequestId(build);
|
||||
publisher.perform(build, null, listener);
|
||||
|
||||
mockServerClient.verifyZeroInteractions();
|
||||
performAndVerify(build, "test", true, false, false, false, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failed() throws IOException, InterruptedException {
|
||||
Integer buildNumber = 1;
|
||||
Integer projectId = 3;
|
||||
Integer mergeRequestId = 1;
|
||||
AbstractBuild build = mockBuild("/build/123", GIT_LAB_CONNECTION, Result.FAILURE, buildNumber);
|
||||
String buildUrl = Jenkins.getInstance().getRootUrl() + build.getUrl();
|
||||
String defaultNote = MessageFormat.format(":negative_squared_cross_mark: Jenkins Build {0}\n\nResults available at: [Jenkins [{1} #{2}]]({3})",
|
||||
Result.FAILURE, build.getParent().getDisplayName(), buildNumber, buildUrl);
|
||||
public void failed_v3() throws IOException, InterruptedException {
|
||||
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V3, Result.FAILURE);
|
||||
String defaultNote = formatNote(build, ":negative_squared_cross_mark: Jenkins Build {0}\n\nResults available at: [Jenkins [{1} #{2}]]({3})");
|
||||
|
||||
HttpRequest[] requests = new HttpRequest[] {
|
||||
prepareSendMessageWithSuccessResponse(projectId, mergeRequestId, defaultNote)
|
||||
};
|
||||
|
||||
GitLabMessagePublisher publisher = spy(new GitLabMessagePublisher(false, false, false, false, false, null, null, null, null));
|
||||
doReturn(projectId).when(publisher).getProjectId(build);
|
||||
doReturn(mergeRequestId).when(publisher).getMergeRequestId(build);
|
||||
publisher.perform(build, null, listener);
|
||||
|
||||
mockServerClient.verify(requests);
|
||||
performAndVerify(
|
||||
build, defaultNote, false, false, false, false, false,
|
||||
prepareSendMessageWithSuccessResponse("v3", defaultNote));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failed_v4() throws IOException, InterruptedException {
|
||||
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V4, Result.FAILURE);
|
||||
String defaultNote = formatNote(build, ":negative_squared_cross_mark: Jenkins Build {0}\n\nResults available at: [Jenkins [{1} #{2}]]({3})");
|
||||
|
||||
performAndVerify(
|
||||
build, defaultNote, false, false, false, false, false,
|
||||
prepareSendMessageWithSuccessResponse("v4", defaultNote));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void failed_withOnlyForFailed() throws IOException, InterruptedException {
|
||||
Integer buildNumber = 1;
|
||||
Integer projectId = 3;
|
||||
Integer mergeRequestId = 1;
|
||||
AbstractBuild build = mockBuild("/build/123", GIT_LAB_CONNECTION, Result.FAILURE, buildNumber);
|
||||
String buildUrl = Jenkins.getInstance().getRootUrl() + build.getUrl();
|
||||
String defaultNote = MessageFormat.format(":negative_squared_cross_mark: Jenkins Build {0}\n\nResults available at: [Jenkins [{1} #{2}]]({3})",
|
||||
Result.FAILURE, build.getParent().getDisplayName(), buildNumber, buildUrl);
|
||||
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V4, Result.FAILURE);
|
||||
String defaultNote = formatNote(build, ":negative_squared_cross_mark: Jenkins Build {0}\n\nResults available at: [Jenkins [{1} #{2}]]({3})");
|
||||
|
||||
HttpRequest[] requests = new HttpRequest[] {
|
||||
prepareSendMessageWithSuccessResponse(projectId, mergeRequestId, defaultNote)
|
||||
};
|
||||
|
||||
GitLabMessagePublisher publisher = spy(new GitLabMessagePublisher(true, false, false, false, false, null, null, null, null));
|
||||
doReturn(projectId).when(publisher).getProjectId(build);
|
||||
doReturn(mergeRequestId).when(publisher).getMergeRequestId(build);
|
||||
publisher.perform(build, null, listener);
|
||||
|
||||
mockServerClient.verify(requests);
|
||||
performAndVerify(
|
||||
build, defaultNote, true, false, false, false, false,
|
||||
prepareSendMessageWithSuccessResponse("v4", defaultNote));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void canceledWithCustomNote() throws IOException, InterruptedException {
|
||||
Integer buildNumber = 1;
|
||||
Integer projectId = 3;
|
||||
Integer mergeRequestId = 1;
|
||||
AbstractBuild build = mockBuild("/build/123", GIT_LAB_CONNECTION, Result.ABORTED, buildNumber);
|
||||
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V4, Result.ABORTED);
|
||||
String defaultNote = "abort";
|
||||
|
||||
HttpRequest[] requests = new HttpRequest[] {
|
||||
prepareSendMessageWithSuccessResponse(projectId, mergeRequestId, defaultNote)
|
||||
};
|
||||
|
||||
GitLabMessagePublisher publisher = spy(new GitLabMessagePublisher(false, false, false, true, false, null, null, defaultNote, null));
|
||||
doReturn(projectId).when(publisher).getProjectId(build);
|
||||
doReturn(mergeRequestId).when(publisher).getMergeRequestId(build);
|
||||
publisher.perform(build, null, listener);
|
||||
|
||||
mockServerClient.verify(requests);
|
||||
performAndVerify(
|
||||
build, defaultNote, false, false, false, true, false,
|
||||
prepareSendMessageWithSuccessResponse("v4", defaultNote));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void successWithCustomNote() throws IOException, InterruptedException {
|
||||
Integer buildNumber = 1;
|
||||
Integer projectId = 3;
|
||||
Integer mergeRequestId = 1;
|
||||
AbstractBuild build = mockBuild("/build/123", GIT_LAB_CONNECTION, Result.SUCCESS, buildNumber);
|
||||
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V4, Result.SUCCESS);
|
||||
String defaultNote = "success";
|
||||
|
||||
HttpRequest[] requests = new HttpRequest[] {
|
||||
prepareSendMessageWithSuccessResponse(projectId, mergeRequestId, defaultNote)
|
||||
};
|
||||
|
||||
GitLabMessagePublisher publisher = spy(new GitLabMessagePublisher(false, true, false, false, false, defaultNote, null, null, null));
|
||||
doReturn(projectId).when(publisher).getProjectId(build);
|
||||
doReturn(mergeRequestId).when(publisher).getMergeRequestId(build);
|
||||
publisher.perform(build, null, listener);
|
||||
|
||||
mockServerClient.verify(requests);
|
||||
performAndVerify(
|
||||
build, defaultNote, false, true, false, false, false,
|
||||
prepareSendMessageWithSuccessResponse("v4", defaultNote));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failedWithCustomNote() throws IOException, InterruptedException {
|
||||
Integer buildNumber = 1;
|
||||
Integer projectId = 3;
|
||||
Integer mergeRequestId = 1;
|
||||
AbstractBuild build = mockBuild("/build/123", GIT_LAB_CONNECTION, Result.FAILURE, buildNumber);
|
||||
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V4, Result.FAILURE);
|
||||
String defaultNote = "failure";
|
||||
|
||||
HttpRequest[] requests = new HttpRequest[] {
|
||||
prepareSendMessageWithSuccessResponse(projectId, mergeRequestId, defaultNote)
|
||||
};
|
||||
|
||||
GitLabMessagePublisher publisher = spy(new GitLabMessagePublisher(false, false, true, false, false, null, defaultNote, null, null));
|
||||
doReturn(projectId).when(publisher).getProjectId(build);
|
||||
doReturn(mergeRequestId).when(publisher).getMergeRequestId(build);
|
||||
publisher.perform(build, null, listener);
|
||||
|
||||
mockServerClient.verify(requests);
|
||||
performAndVerify(
|
||||
build, defaultNote, false, false, true, false, false,
|
||||
prepareSendMessageWithSuccessResponse("v4", defaultNote));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unstableWithCustomNote() throws IOException, InterruptedException {
|
||||
Integer buildNumber = 1;
|
||||
Integer projectId = 3;
|
||||
Integer mergeRequestId = 1;
|
||||
AbstractBuild build = mockBuild("/build/123", GIT_LAB_CONNECTION, Result.UNSTABLE, buildNumber);
|
||||
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V4, Result.UNSTABLE);
|
||||
String defaultNote = "unstable";
|
||||
|
||||
HttpRequest[] requests = new HttpRequest[] {
|
||||
prepareSendMessageWithSuccessResponse(projectId, mergeRequestId, defaultNote)
|
||||
};
|
||||
|
||||
GitLabMessagePublisher publisher = spy(new GitLabMessagePublisher(false, false, false, false, true, null, null, null, defaultNote));
|
||||
doReturn(projectId).when(publisher).getProjectId(build);
|
||||
doReturn(mergeRequestId).when(publisher).getMergeRequestId(build);
|
||||
publisher.perform(build, null, listener);
|
||||
|
||||
mockServerClient.verify(requests);
|
||||
performAndVerify(
|
||||
build, defaultNote, false, false, false, false, true,
|
||||
prepareSendMessageWithSuccessResponse("v4", defaultNote));
|
||||
}
|
||||
|
||||
private HttpRequest prepareSendMessageWithSuccessResponse(Integer projectId, Integer mergeRequestId, String body) throws UnsupportedEncodingException {
|
||||
HttpRequest updateCommitStatus = prepareSendMessageStatus(projectId, mergeRequestId, body);
|
||||
private void performAndVerify(AbstractBuild build, String note, boolean onlyForFailure, boolean replaceSuccessNote, boolean replaceFailureNote, boolean replaceAbortNote, boolean replaceUnstableNote, HttpRequest... requests) throws InterruptedException, IOException {
|
||||
String successNoteText = replaceSuccessNote ? note : null;
|
||||
String failureNoteText = replaceFailureNote ? note : null;
|
||||
String abortNoteText = replaceAbortNote ? note : null;
|
||||
String unstableNoteText = replaceUnstableNote ? note : null;
|
||||
GitLabMessagePublisher publisher = spy(new GitLabMessagePublisher(onlyForFailure, replaceSuccessNote, replaceFailureNote, replaceAbortNote, replaceUnstableNote, successNoteText, failureNoteText, abortNoteText, unstableNoteText));
|
||||
doReturn(PROJECT_ID).when(publisher).getProjectId(build);
|
||||
doReturn(MERGE_REQUEST_ID).when(publisher).getMergeRequestId(build);
|
||||
publisher.perform(build, null, listener);
|
||||
|
||||
if (requests.length > 0) {
|
||||
mockServerClient.verify(requests);
|
||||
} else {
|
||||
mockServerClient.verifyZeroInteractions();
|
||||
}
|
||||
}
|
||||
|
||||
private HttpRequest prepareSendMessageWithSuccessResponse(String apiLevel, String body) throws UnsupportedEncodingException {
|
||||
HttpRequest updateCommitStatus = prepareSendMessageStatus(apiLevel, body);
|
||||
mockServerClient.when(updateCommitStatus).respond(response().withStatusCode(200));
|
||||
return updateCommitStatus;
|
||||
}
|
||||
|
||||
private HttpRequest prepareSendMessageStatus(Integer projectId, Integer mergeRequestId, String body) throws UnsupportedEncodingException {
|
||||
private HttpRequest prepareSendMessageStatus(final String apiLevel, String body) throws UnsupportedEncodingException {
|
||||
return request()
|
||||
.withPath("/gitlab/api/v3/projects/" + projectId + "/merge_requests/" + mergeRequestId + "/notes")
|
||||
.withPath("/gitlab/api/" + apiLevel + "/projects/" + PROJECT_ID + "/merge_requests/" + MERGE_REQUEST_ID + "/notes")
|
||||
.withMethod("POST")
|
||||
.withHeader("PRIVATE-TOKEN", "secret")
|
||||
.withBody("body=" + URLEncoder.encode(body, "UTF-8"));
|
||||
}
|
||||
|
||||
private AbstractBuild mockBuild(String buildUrl, String gitLabConnection, Result result, Integer buildNumber, String... remoteUrls) {
|
||||
private AbstractBuild mockBuild(String gitLabConnection, Result result, String... remoteUrls) {
|
||||
AbstractBuild build = mock(AbstractBuild.class);
|
||||
BuildData buildData = mock(BuildData.class);
|
||||
when(buildData.getRemoteUrls()).thenReturn(new HashSet<>(Arrays.asList(remoteUrls)));
|
||||
when(build.getAction(BuildData.class)).thenReturn(buildData);
|
||||
when(build.getResult()).thenReturn(result);
|
||||
when(build.getUrl()).thenReturn(buildUrl);
|
||||
when(build.getUrl()).thenReturn(BUILD_URL);
|
||||
when(build.getResult()).thenReturn(result);
|
||||
when(build.getUrl()).thenReturn(buildUrl);
|
||||
when(build.getNumber()).thenReturn(buildNumber);
|
||||
when(build.getNumber()).thenReturn(BUILD_NUMBER);
|
||||
|
||||
AbstractProject<?, ?> project = mock(AbstractProject.class);
|
||||
when(project.getProperty(GitLabConnectionProperty.class)).thenReturn(new GitLabConnectionProperty(gitLabConnection));
|
||||
|
|
|
@ -1,26 +1,10 @@
|
|||
package com.dabsquared.gitlabjenkins.publisher;
|
||||
|
||||
import com.cloudbees.plugins.credentials.CredentialsProvider;
|
||||
import com.cloudbees.plugins.credentials.CredentialsScope;
|
||||
import com.cloudbees.plugins.credentials.CredentialsStore;
|
||||
import com.cloudbees.plugins.credentials.SystemCredentialsProvider;
|
||||
import com.cloudbees.plugins.credentials.domains.Domain;
|
||||
import com.dabsquared.gitlabjenkins.connection.GitLabConnection;
|
||||
import com.dabsquared.gitlabjenkins.connection.GitLabConnectionConfig;
|
||||
import com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty;
|
||||
import hudson.Launcher;
|
||||
import hudson.matrix.MatrixAggregator;
|
||||
import hudson.matrix.MatrixConfiguration;
|
||||
import hudson.matrix.MatrixBuild;
|
||||
|
||||
import hudson.model.AbstractBuild;
|
||||
import hudson.model.AbstractProject;
|
||||
import hudson.model.BuildListener;
|
||||
import hudson.model.Result;
|
||||
import hudson.model.StreamBuildListener;
|
||||
import hudson.plugins.git.util.BuildData;
|
||||
import hudson.util.Secret;
|
||||
import jenkins.model.Jenkins;
|
||||
import org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
|
@ -35,17 +19,16 @@ import java.io.IOException;
|
|||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.Charset;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
import static org.mockito.Matchers.any;
|
||||
import static com.dabsquared.gitlabjenkins.publisher.TestUtility.GITLAB_CONNECTION_V3;
|
||||
import static com.dabsquared.gitlabjenkins.publisher.TestUtility.GITLAB_CONNECTION_V4;
|
||||
import static com.dabsquared.gitlabjenkins.publisher.TestUtility.MERGE_REQUEST_ID;
|
||||
import static com.dabsquared.gitlabjenkins.publisher.TestUtility.PROJECT_ID;
|
||||
import static com.dabsquared.gitlabjenkins.publisher.TestUtility.formatNote;
|
||||
import static com.dabsquared.gitlabjenkins.publisher.TestUtility.setupGitLabConnections;
|
||||
import static com.dabsquared.gitlabjenkins.publisher.TestUtility.verifyMatrixAggregatable;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockserver.model.HttpRequest.request;
|
||||
import static org.mockserver.model.HttpResponse.response;
|
||||
|
||||
|
@ -53,10 +36,6 @@ import static org.mockserver.model.HttpResponse.response;
|
|||
* @author Nikolay Ustinov
|
||||
*/
|
||||
public class GitLabVotePublisherTest {
|
||||
|
||||
private static final String GIT_LAB_CONNECTION = "GitLab";
|
||||
private static final String API_TOKEN = "secret";
|
||||
|
||||
@ClassRule
|
||||
public static MockServerRule mockServer = new MockServerRule(new Object());
|
||||
|
||||
|
@ -67,17 +46,8 @@ public class GitLabVotePublisherTest {
|
|||
private BuildListener listener;
|
||||
|
||||
@BeforeClass
|
||||
public static void setupConnection() throws IOException {
|
||||
GitLabConnectionConfig connectionConfig = jenkins.get(GitLabConnectionConfig.class);
|
||||
String apiTokenId = "apiTokenId";
|
||||
for (CredentialsStore credentialsStore : CredentialsProvider.lookupStores(Jenkins.getInstance())) {
|
||||
if (credentialsStore instanceof SystemCredentialsProvider.StoreImpl) {
|
||||
List<Domain> domains = credentialsStore.getDomains();
|
||||
credentialsStore.addCredentials(domains.get(0),
|
||||
new StringCredentialsImpl(CredentialsScope.SYSTEM, apiTokenId, "GitLab API Token", Secret.fromString(API_TOKEN)));
|
||||
}
|
||||
}
|
||||
connectionConfig.addConnection(new GitLabConnection(GIT_LAB_CONNECTION, "http://localhost:" + mockServer.getPort() + "/gitlab", apiTokenId, false, 10, 10));
|
||||
public static void setupClass() throws IOException {
|
||||
setupGitLabConnections(jenkins, mockServer);
|
||||
}
|
||||
|
||||
@Before
|
||||
|
@ -92,94 +62,51 @@ public class GitLabVotePublisherTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void matrixAggregatable() throws UnsupportedEncodingException, InterruptedException, IOException {
|
||||
AbstractBuild build = mock(AbstractBuild.class);
|
||||
AbstractProject project = mock(MatrixConfiguration.class);
|
||||
GitLabCommitStatusPublisher publisher = mock(GitLabCommitStatusPublisher.class);
|
||||
MatrixBuild parentBuild = mock(MatrixBuild.class);
|
||||
|
||||
when(build.getParent()).thenReturn(project);
|
||||
when(publisher.createAggregator(any(MatrixBuild.class), any(Launcher.class), any(BuildListener.class))).thenCallRealMethod();
|
||||
when(publisher.perform(any(AbstractBuild.class), any(Launcher.class), any(BuildListener.class))).thenReturn(true);
|
||||
|
||||
MatrixAggregator aggregator = publisher.createAggregator(parentBuild, null, listener);
|
||||
aggregator.startBuild();
|
||||
aggregator.endBuild();
|
||||
verify(publisher).perform(parentBuild, null, listener);
|
||||
public void matrixAggregatable() throws InterruptedException, IOException {
|
||||
verifyMatrixAggregatable(GitLabVotePublisher.class, listener);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void success() throws IOException, InterruptedException {
|
||||
Integer buildNumber = 1;
|
||||
Integer projectId = 3;
|
||||
Integer mergeRequestId = 1;
|
||||
AbstractBuild build = mockBuild("/build/123", GIT_LAB_CONNECTION, Result.SUCCESS, buildNumber);
|
||||
String buildUrl = Jenkins.getInstance().getRootUrl() + build.getUrl();
|
||||
String defaultNote = MessageFormat.format(":+1:",
|
||||
Result.SUCCESS, build.getParent().getDisplayName(), buildNumber, buildUrl);
|
||||
|
||||
HttpRequest[] requests = new HttpRequest[] {
|
||||
prepareSendMessageWithSuccessResponse(projectId, mergeRequestId, defaultNote)
|
||||
};
|
||||
|
||||
GitLabVotePublisher publisher = spy(new GitLabVotePublisher());
|
||||
doReturn(projectId).when(publisher).getProjectId(build);
|
||||
doReturn(mergeRequestId).when(publisher).getMergeRequestId(build);
|
||||
publisher.perform(build, null, listener);
|
||||
|
||||
mockServerClient.verify(requests);
|
||||
public void success_v3() throws IOException, InterruptedException {
|
||||
performAndVerify(TestUtility.mockSimpleBuild(GITLAB_CONNECTION_V3, Result.SUCCESS), "v3", ":+1:");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failed() throws IOException, InterruptedException {
|
||||
Integer buildNumber = 1;
|
||||
Integer projectId = 3;
|
||||
Integer mergeRequestId = 1;
|
||||
AbstractBuild build = mockBuild("/build/123", GIT_LAB_CONNECTION, Result.FAILURE, buildNumber);
|
||||
String buildUrl = Jenkins.getInstance().getRootUrl() + build.getUrl();
|
||||
String defaultNote = MessageFormat.format(":-1:",
|
||||
Result.FAILURE, build.getParent().getDisplayName(), buildNumber, buildUrl);
|
||||
|
||||
HttpRequest[] requests = new HttpRequest[] {
|
||||
prepareSendMessageWithSuccessResponse(projectId, mergeRequestId, defaultNote)
|
||||
};
|
||||
|
||||
GitLabVotePublisher publisher = spy(new GitLabVotePublisher());
|
||||
doReturn(projectId).when(publisher).getProjectId(build);
|
||||
doReturn(mergeRequestId).when(publisher).getMergeRequestId(build);
|
||||
publisher.perform(build, null, listener);
|
||||
|
||||
mockServerClient.verify(requests);
|
||||
public void success_v4() throws IOException, InterruptedException {
|
||||
performAndVerify(TestUtility.mockSimpleBuild(GITLAB_CONNECTION_V4, Result.SUCCESS), "v4", ":+1:");
|
||||
}
|
||||
|
||||
private HttpRequest prepareSendMessageWithSuccessResponse(Integer projectId, Integer mergeRequestId, String body) throws UnsupportedEncodingException {
|
||||
HttpRequest updateCommitStatus = prepareSendMessageStatus(projectId, mergeRequestId, body);
|
||||
@Test
|
||||
public void failed_v3() throws IOException, InterruptedException {
|
||||
performAndVerify(TestUtility.mockSimpleBuild(GITLAB_CONNECTION_V3, Result.FAILURE), "v3", ":-1:");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failed_v4() throws IOException, InterruptedException {
|
||||
performAndVerify(TestUtility.mockSimpleBuild(GITLAB_CONNECTION_V4, Result.FAILURE), "v4", ":-1:");
|
||||
}
|
||||
|
||||
|
||||
private void performAndVerify(AbstractBuild build, String apiLevel, String defaultNote) throws InterruptedException, IOException {
|
||||
GitLabVotePublisher publisher = spy(new GitLabVotePublisher());
|
||||
doReturn(PROJECT_ID).when(publisher).getProjectId(build);
|
||||
doReturn(MERGE_REQUEST_ID).when(publisher).getMergeRequestId(build);
|
||||
publisher.perform(build, null, listener);
|
||||
|
||||
mockServerClient.verify(prepareSendMessageWithSuccessResponse(build, apiLevel, defaultNote));
|
||||
}
|
||||
|
||||
private HttpRequest prepareSendMessageWithSuccessResponse(AbstractBuild build, String apiLevel, String body) throws UnsupportedEncodingException {
|
||||
HttpRequest updateCommitStatus = prepareSendMessageStatus(apiLevel, formatNote(build, body));
|
||||
mockServerClient.when(updateCommitStatus).respond(response().withStatusCode(200));
|
||||
return updateCommitStatus;
|
||||
}
|
||||
|
||||
private HttpRequest prepareSendMessageStatus(Integer projectId, Integer mergeRequestId, String body) throws UnsupportedEncodingException {
|
||||
private HttpRequest prepareSendMessageStatus(final String apiLevel, String body) throws UnsupportedEncodingException {
|
||||
return request()
|
||||
.withPath("/gitlab/api/v3/projects/" + projectId + "/merge_requests/" + mergeRequestId + "/notes")
|
||||
.withPath("/gitlab/api/" + apiLevel + "/projects/" + PROJECT_ID + "/merge_requests/" + MERGE_REQUEST_ID + "/notes")
|
||||
.withMethod("POST")
|
||||
.withHeader("PRIVATE-TOKEN", "secret")
|
||||
.withBody("body=" + URLEncoder.encode(body, "UTF-8"));
|
||||
}
|
||||
|
||||
private AbstractBuild mockBuild(String buildUrl, String gitLabConnection, Result result, Integer buildNumber, String... remoteUrls) {
|
||||
AbstractBuild build = mock(AbstractBuild.class);
|
||||
BuildData buildData = mock(BuildData.class);
|
||||
when(buildData.getRemoteUrls()).thenReturn(new HashSet<>(Arrays.asList(remoteUrls)));
|
||||
when(build.getAction(BuildData.class)).thenReturn(buildData);
|
||||
when(build.getResult()).thenReturn(result);
|
||||
when(build.getUrl()).thenReturn(buildUrl);
|
||||
when(build.getResult()).thenReturn(result);
|
||||
when(build.getUrl()).thenReturn(buildUrl);
|
||||
when(build.getNumber()).thenReturn(buildNumber);
|
||||
|
||||
AbstractProject<?, ?> project = mock(AbstractProject.class);
|
||||
when(project.getProperty(GitLabConnectionProperty.class)).thenReturn(new GitLabConnectionProperty(gitLabConnection));
|
||||
when(build.getProject()).thenReturn(project);
|
||||
return build;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
package com.dabsquared.gitlabjenkins.publisher;
|
||||
|
||||
|
||||
import com.cloudbees.plugins.credentials.CredentialsProvider;
|
||||
import com.cloudbees.plugins.credentials.CredentialsScope;
|
||||
import com.cloudbees.plugins.credentials.CredentialsStore;
|
||||
import com.cloudbees.plugins.credentials.SystemCredentialsProvider;
|
||||
import com.cloudbees.plugins.credentials.domains.Domain;
|
||||
import com.dabsquared.gitlabjenkins.connection.GitLabConnection;
|
||||
import com.dabsquared.gitlabjenkins.connection.GitLabConnectionConfig;
|
||||
import com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.impl.V3GitLabClientBuilder;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.impl.V4GitLabClientBuilder;
|
||||
import hudson.Launcher;
|
||||
import hudson.matrix.MatrixAggregatable;
|
||||
import hudson.matrix.MatrixAggregator;
|
||||
import hudson.matrix.MatrixBuild;
|
||||
import hudson.matrix.MatrixConfiguration;
|
||||
import hudson.model.AbstractBuild;
|
||||
import hudson.model.AbstractProject;
|
||||
import hudson.model.BuildListener;
|
||||
import hudson.model.Result;
|
||||
import hudson.plugins.git.util.BuildData;
|
||||
import hudson.tasks.Notifier;
|
||||
import hudson.util.Secret;
|
||||
import jenkins.model.Jenkins;
|
||||
import org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl;
|
||||
import org.jvnet.hudson.test.JenkinsRule;
|
||||
import org.mockserver.junit.MockServerRule;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
|
||||
final class TestUtility {
|
||||
static final String GITLAB_CONNECTION_V3 = "GitLabV3";
|
||||
static final String GITLAB_CONNECTION_V4 = "GitLabV4";
|
||||
static final String BUILD_URL = "/build/123";
|
||||
static final int BUILD_NUMBER = 1;
|
||||
static final int PROJECT_ID = 3;
|
||||
static final int MERGE_REQUEST_ID = 1;
|
||||
|
||||
private static final String API_TOKEN = "secret";
|
||||
|
||||
static void setupGitLabConnections(JenkinsRule jenkins, MockServerRule mockServer) throws IOException {
|
||||
GitLabConnectionConfig connectionConfig = jenkins.get(GitLabConnectionConfig.class);
|
||||
String apiTokenId = "apiTokenId";
|
||||
for (CredentialsStore credentialsStore : CredentialsProvider.lookupStores(Jenkins.getInstance())) {
|
||||
if (credentialsStore instanceof SystemCredentialsProvider.StoreImpl) {
|
||||
List<Domain> domains = credentialsStore.getDomains();
|
||||
credentialsStore.addCredentials(domains.get(0),
|
||||
new StringCredentialsImpl(CredentialsScope.SYSTEM, apiTokenId, "GitLab API Token", Secret.fromString(TestUtility.API_TOKEN)));
|
||||
}
|
||||
}
|
||||
connectionConfig.addConnection(new GitLabConnection(TestUtility.GITLAB_CONNECTION_V3, "http://localhost:" + mockServer.getPort() + "/gitlab", apiTokenId, new V3GitLabClientBuilder(), false, 10, 10));
|
||||
connectionConfig.addConnection(new GitLabConnection(TestUtility.GITLAB_CONNECTION_V4, "http://localhost:" + mockServer.getPort() + "/gitlab", apiTokenId, new V4GitLabClientBuilder(), false, 10, 10));
|
||||
|
||||
}
|
||||
|
||||
static <T extends Notifier & MatrixAggregatable> void verifyMatrixAggregatable(Class<T> publisherClass, BuildListener listener) throws InterruptedException, IOException {
|
||||
AbstractBuild build = mock(AbstractBuild.class);
|
||||
AbstractProject project = mock(MatrixConfiguration.class);
|
||||
Notifier publisher = mock(publisherClass);
|
||||
MatrixBuild parentBuild = mock(MatrixBuild.class);
|
||||
|
||||
when(build.getParent()).thenReturn(project);
|
||||
when(((MatrixAggregatable) publisher).createAggregator(any(MatrixBuild.class), any(Launcher.class), any(BuildListener.class))).thenCallRealMethod();
|
||||
when(publisher.perform(any(AbstractBuild.class), any(Launcher.class), any(BuildListener.class))).thenReturn(true);
|
||||
|
||||
MatrixAggregator aggregator = ((MatrixAggregatable) publisher).createAggregator(parentBuild, null, listener);
|
||||
aggregator.startBuild();
|
||||
aggregator.endBuild();
|
||||
verify(publisher).perform(parentBuild, null, listener);
|
||||
}
|
||||
|
||||
static AbstractBuild mockSimpleBuild(String gitLabConnection, Result result, String... remoteUrls) {
|
||||
AbstractBuild build = mock(AbstractBuild.class);
|
||||
BuildData buildData = mock(BuildData.class);
|
||||
when(buildData.getRemoteUrls()).thenReturn(new HashSet<>(Arrays.asList(remoteUrls)));
|
||||
when(build.getAction(BuildData.class)).thenReturn(buildData);
|
||||
when(build.getResult()).thenReturn(result);
|
||||
when(build.getUrl()).thenReturn(BUILD_URL);
|
||||
when(build.getResult()).thenReturn(result);
|
||||
when(build.getNumber()).thenReturn(BUILD_NUMBER);
|
||||
|
||||
AbstractProject<?, ?> project = mock(AbstractProject.class);
|
||||
when(project.getProperty(GitLabConnectionProperty.class)).thenReturn(new GitLabConnectionProperty(gitLabConnection));
|
||||
when(build.getProject()).thenReturn(project);
|
||||
return build;
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
static String formatNote(AbstractBuild build, String note) {
|
||||
String buildUrl = Jenkins.getInstance().getRootUrl() + build.getUrl();
|
||||
return MessageFormat.format(note, build.getResult(), build.getParent().getDisplayName(), BUILD_NUMBER, buildUrl);
|
||||
}
|
||||
|
||||
private TestUtility() { /* contains only static utility-methods */ }
|
||||
}
|
|
@ -0,0 +1,161 @@
|
|||
package com.dabsquared.gitlabjenkins.service;
|
||||
|
||||
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabApi;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.*;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.hook.model.State;
|
||||
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
|
||||
|
||||
class GitLabApiStub implements GitLabApi {
|
||||
private final Map<Pair<String, Class>, List<?>> data;
|
||||
private final Map<Pair<String, Class>, Integer> calls;
|
||||
|
||||
GitLabApiStub() {
|
||||
data = new HashMap<>();
|
||||
calls = new HashMap<>();
|
||||
}
|
||||
|
||||
void addBranches(String project, List<Branch> branches) {
|
||||
addData(project, Branch.class, branches);
|
||||
}
|
||||
|
||||
void addLabels(String project, List<Label> labels) {
|
||||
addData(project, Label.class, labels);
|
||||
}
|
||||
|
||||
int calls(String projectId, Class dataClass) {
|
||||
Pair<String, Class> key = createKey(projectId, dataClass);
|
||||
return calls.containsKey(key) ? calls.get(key) : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Branch> getBranches(String projectId) {
|
||||
return getData(projectId, Branch.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Label> getLabels(String projectId) {
|
||||
return getData(projectId, Label.class);
|
||||
}
|
||||
|
||||
private void addData(String projectId, Class dataClass, List<?> datas) {
|
||||
data.put(createKey(projectId, dataClass), datas);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> List<T> getData(String projectId, Class dataClass) {
|
||||
Pair<String, Class> key = createKey(projectId, dataClass);
|
||||
if (!calls.containsKey(key)) {
|
||||
calls.put(key, 0);
|
||||
}
|
||||
|
||||
calls.put(key, calls.get(key) + 1);
|
||||
|
||||
return (List<T>) data.get(key);
|
||||
}
|
||||
|
||||
private Pair<String, Class> createKey(String projectId, Class dataClass) {
|
||||
return new ImmutablePair<>(projectId, dataClass);
|
||||
}
|
||||
|
||||
|
||||
/************** no implementation below ********************************/
|
||||
|
||||
@Override
|
||||
public Project createProject(String projectName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MergeRequest createMergeRequest(Integer projectId, String sourceBranch, String targetBranch, String title) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Project getProject(String projectName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Project updateProject(String projectId, String name, String path) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteProject(String projectId) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addProjectHook(String projectId, String url, Boolean pushEvents, Boolean mergeRequestEvents, Boolean noteEvents) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changeBuildStatus(String projectId, String sha, BuildState state, String ref, String context, String targetUrl, String description) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changeBuildStatus(Integer projectId, String sha, BuildState state, String ref, String context, String targetUrl, String description) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getCommit(String projectId, String sha) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acceptMergeRequest(Integer projectId, Integer mergeRequestId, String mergeCommitMessage, boolean shouldRemoveSourceBranch) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createMergeRequestNote(Integer projectId, Integer mergeRequestId, String body) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MergeRequest> getMergeRequests(String projectId, State state, int page, int perPage) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Branch getBranch(String projectId, String branch) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void headCurrentUser() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public User getCurrentUser() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public User addUser(String email, String username, String name, String password) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public User updateUser(String userId, String email, String username, String name, String password) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Pipeline> getPipelines(String projectName) {
|
||||
return emptyList();
|
||||
}
|
||||
}
|
|
@ -1,12 +1,10 @@
|
|||
package com.dabsquared.gitlabjenkins.service;
|
||||
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabApi;
|
||||
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.Branch;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
@ -14,29 +12,26 @@ import java.util.List;
|
|||
|
||||
import static com.dabsquared.gitlabjenkins.gitlab.api.model.builder.generated.BranchBuilder.branch;
|
||||
import static java.util.Arrays.asList;
|
||||
import static junit.framework.TestCase.assertEquals;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
|
||||
public class GitLabProjectBranchesServiceTest {
|
||||
|
||||
private final static List<String> BRANCH_NAMES_PROJECT_B = asList("master", "B-branch-1", "B-branch-2");
|
||||
|
||||
private GitLabProjectBranchesService branchesService;
|
||||
|
||||
@Mock
|
||||
private GitLabApi gitlabApi;
|
||||
private GitLabApiStub apiStub;
|
||||
private GitLabClient gitlabClient;
|
||||
|
||||
@Before
|
||||
public void setUp() throws IOException {
|
||||
List<Branch> branchNamesProjectA = convert(asList("master", "A-branch-1"));
|
||||
apiStub = new GitLabApiStub();
|
||||
apiStub.addBranches("groupOne/A", convert(asList("master", "A-branch-1")));
|
||||
apiStub.addBranches("groupOne/B", convert(BRANCH_NAMES_PROJECT_B));
|
||||
|
||||
// mock the gitlab factory
|
||||
when(gitlabApi.getBranches("groupOne/A")).thenReturn(branchNamesProjectA);
|
||||
when(gitlabApi.getBranches("groupOne/B")).thenReturn(convert(BRANCH_NAMES_PROJECT_B));
|
||||
gitlabClient = new GitLabClient("", apiStub);
|
||||
|
||||
// never expire cache for tests
|
||||
branchesService = new GitLabProjectBranchesService();
|
||||
|
@ -45,7 +40,7 @@ public class GitLabProjectBranchesServiceTest {
|
|||
@Test
|
||||
public void shouldReturnBranchNamesFromGitlabApi() {
|
||||
// when
|
||||
List<String> actualBranchNames = branchesService.getBranches(gitlabApi, "git@git.example.com:groupOne/B.git");
|
||||
List<String> actualBranchNames = branchesService.getBranches(gitlabClient, "git@git.example.com:groupOne/B.git");
|
||||
|
||||
// then
|
||||
assertThat(actualBranchNames, is(BRANCH_NAMES_PROJECT_B));
|
||||
|
@ -54,11 +49,11 @@ public class GitLabProjectBranchesServiceTest {
|
|||
@Test
|
||||
public void shouldNotMakeUnnecessaryCallsToGitlabApiGetBranches() {
|
||||
// when
|
||||
branchesService.getBranches(gitlabApi, "git@git.example.com:groupOne/A.git");
|
||||
branchesService.getBranches(gitlabClient, "git@git.example.com:groupOne/A.git");
|
||||
|
||||
// then
|
||||
verify(gitlabApi, times(1)).getBranches("groupOne/A");
|
||||
verify(gitlabApi, times(0)).getBranches("groupOne/B");
|
||||
assertEquals(1, apiStub.calls("groupOne/A", Branch.class));
|
||||
assertEquals(0, apiStub.calls("groupOne/B", Branch.class));
|
||||
}
|
||||
|
||||
private List<Branch> convert(List<String> branchNames) {
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
package com.dabsquared.gitlabjenkins.service;
|
||||
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabApi;
|
||||
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.Label;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
@ -14,30 +12,28 @@ import java.util.List;
|
|||
|
||||
import static com.dabsquared.gitlabjenkins.gitlab.api.model.builder.generated.LabelBuilder.label;
|
||||
import static java.util.Arrays.asList;
|
||||
import static junit.framework.TestCase.assertEquals;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
|
||||
public class GitLabProjectLabelsServiceTest {
|
||||
|
||||
private final static List<String> LABELS_PROJECT_B = asList("label1", "label2", "label3");
|
||||
|
||||
private GitLabProjectLabelsService labelsService;
|
||||
|
||||
@Mock
|
||||
private GitLabApi gitlabApi;
|
||||
private GitLabApiStub apiStub;
|
||||
private GitLabClient gitlabClient;
|
||||
|
||||
@Before
|
||||
public void setUp() throws IOException {
|
||||
List<Label> labelsProjectA = convert(asList("label1", "label2"));
|
||||
|
||||
// mock the gitlab factory
|
||||
when(gitlabApi.getLabels("groupOne/A")).thenReturn(labelsProjectA);
|
||||
when(gitlabApi.getLabels("groupOne/B")).thenReturn(convert(LABELS_PROJECT_B));
|
||||
apiStub = new GitLabApiStub();
|
||||
apiStub.addLabels("groupOne/A", convert(asList("label1", "label2")));
|
||||
apiStub.addLabels("groupOne/B", convert(LABELS_PROJECT_B));
|
||||
|
||||
gitlabClient = new GitLabClient("", apiStub);
|
||||
|
||||
// never expire cache for tests
|
||||
labelsService = new GitLabProjectLabelsService();
|
||||
}
|
||||
|
@ -45,7 +41,7 @@ public class GitLabProjectLabelsServiceTest {
|
|||
@Test
|
||||
public void shouldReturnLabelsFromGitlabApi() {
|
||||
// when
|
||||
List<String> actualLabels = labelsService.getLabels(gitlabApi, "git@git.example.com:groupOne/B.git");
|
||||
List<String> actualLabels = labelsService.getLabels(gitlabClient, "git@git.example.com:groupOne/B.git");
|
||||
|
||||
// then
|
||||
assertThat(actualLabels, is(LABELS_PROJECT_B));
|
||||
|
@ -54,11 +50,11 @@ public class GitLabProjectLabelsServiceTest {
|
|||
@Test
|
||||
public void shouldNotMakeUnnecessaryCallsToGitlabApiGetLabels() {
|
||||
// when
|
||||
labelsService.getLabels(gitlabApi, "git@git.example.com:groupOne/A.git");
|
||||
labelsService.getLabels(gitlabClient, "git@git.example.com:groupOne/A.git");
|
||||
|
||||
// then
|
||||
verify(gitlabApi, times(1)).getLabels("groupOne/A");
|
||||
verify(gitlabApi, times(0)).getLabels("groupOne/B");
|
||||
assertEquals(1, apiStub.calls("groupOne/A", Label.class));
|
||||
assertEquals(0, apiStub.calls("groupOne/B", Label.class));
|
||||
}
|
||||
|
||||
private List<Label> convert(List<String> labels) {
|
||||
|
|
|
@ -1,13 +1,23 @@
|
|||
package com.dabsquared.gitlabjenkins.testing.gitlab.rule;
|
||||
|
||||
import com.dabsquared.gitlabjenkins.gitlab.JacksonConfig;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabApi;
|
||||
|
||||
import com.cloudbees.plugins.credentials.CredentialsProvider;
|
||||
import com.cloudbees.plugins.credentials.CredentialsScope;
|
||||
import com.cloudbees.plugins.credentials.CredentialsStore;
|
||||
import com.cloudbees.plugins.credentials.SystemCredentialsProvider;
|
||||
import com.cloudbees.plugins.credentials.domains.Domain;
|
||||
import com.dabsquared.gitlabjenkins.connection.GitLabConnection;
|
||||
import com.dabsquared.gitlabjenkins.connection.GitLabConnectionConfig;
|
||||
import com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.impl.V3GitLabClientBuilder;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.MergeRequest;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.Pipeline;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.Project;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.User;
|
||||
import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
|
||||
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
|
||||
import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine;
|
||||
import hudson.util.Secret;
|
||||
import jenkins.model.Jenkins;
|
||||
import org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl;
|
||||
import org.junit.rules.TestRule;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runners.model.Statement;
|
||||
|
@ -27,21 +37,20 @@ import java.util.UUID;
|
|||
* @author Robin Müller
|
||||
*/
|
||||
public class GitLabRule implements TestRule {
|
||||
private static final String API_TOKEN_ID = "apiTokenId";
|
||||
|
||||
private final GitLabApi client;
|
||||
private final String url;
|
||||
private final int postgresPort;
|
||||
private final GitLabClient client;
|
||||
private final String username;
|
||||
private final String password;
|
||||
|
||||
private List<String> projectIds = new ArrayList<>();
|
||||
|
||||
public GitLabRule(String url, int postgresPort) {
|
||||
client = new ResteasyClientBuilder()
|
||||
.httpEngine(new ApacheHttpClient4Engine())
|
||||
.register(new JacksonJsonProvider())
|
||||
.register(new JacksonConfig())
|
||||
.register(new ApiHeaderTokenFilter(getApiToken(postgresPort))).build().target(url)
|
||||
.proxyBuilder(GitLabApi.class)
|
||||
.build();
|
||||
this.url = url;
|
||||
this.postgresPort = postgresPort;
|
||||
client = new V3GitLabClientBuilder().buildClient(url, getApiToken(), false, -1, -1);
|
||||
User user = client.getCurrentUser();
|
||||
username = user.getUsername();
|
||||
password = "integration-test";
|
||||
|
@ -57,6 +66,10 @@ public class GitLabRule implements TestRule {
|
|||
return client.getProject(projectName);
|
||||
}
|
||||
|
||||
public List<Pipeline> getPipelines(int projectId) {
|
||||
return client.getPipelines(String.valueOf(projectId));
|
||||
}
|
||||
|
||||
public List<String> getProjectIds() {
|
||||
return projectIds;
|
||||
}
|
||||
|
@ -70,6 +83,22 @@ public class GitLabRule implements TestRule {
|
|||
return project.getHttpUrlToRepo();
|
||||
}
|
||||
|
||||
public GitLabConnectionProperty createGitLabConnectionProperty() throws IOException {
|
||||
for (CredentialsStore credentialsStore : CredentialsProvider.lookupStores(Jenkins.getInstance())) {
|
||||
if (credentialsStore instanceof SystemCredentialsProvider.StoreImpl) {
|
||||
List<Domain> domains = credentialsStore.getDomains();
|
||||
credentialsStore.addCredentials(domains.get(0),
|
||||
new StringCredentialsImpl(CredentialsScope.SYSTEM, API_TOKEN_ID, "GitLab API Token", Secret.fromString(getApiToken())));
|
||||
}
|
||||
}
|
||||
|
||||
GitLabConnectionConfig config = Jenkins.getInstance().getDescriptorByType(GitLabConnectionConfig.class);
|
||||
GitLabConnection connection = new GitLabConnection("test", url, API_TOKEN_ID, new V3GitLabClientBuilder(), true,10, 10);
|
||||
config.addConnection(connection);
|
||||
config.save();
|
||||
return new GitLabConnectionProperty(connection.getName());
|
||||
}
|
||||
|
||||
public MergeRequest createMergeRequest(final Integer projectId,
|
||||
final String sourceBranch,
|
||||
final String targetBranch,
|
||||
|
@ -98,7 +127,7 @@ public class GitLabRule implements TestRule {
|
|||
}
|
||||
}
|
||||
|
||||
private String getApiToken(int postgresPort) {
|
||||
private String getApiToken() {
|
||||
try {
|
||||
Class.forName("org.postgresql.Driver");
|
||||
try (Connection connection = DriverManager.getConnection("jdbc:postgresql://localhost:" + postgresPort + "/gitlabhq_production", "gitlab", "password")) {
|
||||
|
|
|
@ -1,23 +1,34 @@
|
|||
package com.dabsquared.gitlabjenkins.testing.integration;
|
||||
|
||||
|
||||
import com.dabsquared.gitlabjenkins.GitLabPushTrigger;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.MergeRequest;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.Pipeline;
|
||||
import com.dabsquared.gitlabjenkins.publisher.GitLabCommitStatusPublisher;
|
||||
import com.dabsquared.gitlabjenkins.testing.gitlab.rule.GitLabRule;
|
||||
import com.dabsquared.gitlabjenkins.trigger.filter.BranchFilterType;
|
||||
import hudson.Launcher;
|
||||
import hudson.model.AbstractBuild;
|
||||
import hudson.model.BuildListener;
|
||||
import hudson.model.Descriptor;
|
||||
import hudson.model.FreeStyleProject;
|
||||
import hudson.tasks.Publisher;
|
||||
import hudson.util.DescribableList;
|
||||
import hudson.util.OneShotEvent;
|
||||
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.eclipse.jgit.api.Git;
|
||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||
import org.eclipse.jgit.lib.StoredConfig;
|
||||
import org.eclipse.jgit.revwalk.RevCommit;
|
||||
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.jvnet.hudson.test.JenkinsRule;
|
||||
import org.jvnet.hudson.test.SleepBuilder;
|
||||
import org.jvnet.hudson.test.TestBuilder;
|
||||
import org.jvnet.hudson.test.TestNotifier;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Inet4Address;
|
||||
|
@ -30,6 +41,9 @@ import java.util.List;
|
|||
import static com.dabsquared.gitlabjenkins.builder.generated.GitLabPushTriggerBuilder.gitLabPushTrigger;
|
||||
import static com.dabsquared.gitlabjenkins.testing.gitlab.rule.builder.generated.ProjectRequestBuilder.projectRequest;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
|
||||
import static org.hamcrest.collection.IsEmptyCollection.empty;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
@ -38,9 +52,10 @@ import static org.junit.Assert.assertTrue;
|
|||
* @author Robin Müller
|
||||
*/
|
||||
public class GitLabIT {
|
||||
private static final String GITLAB_URL = "http://localhost:" + System.getProperty("gitlab.http.port", "10080");
|
||||
|
||||
@Rule
|
||||
public GitLabRule gitlab = new GitLabRule("http://localhost:" + System.getProperty("gitlab.http.port", "10080"),
|
||||
public GitLabRule gitlab = new GitLabRule(GITLAB_URL,
|
||||
Integer.parseInt(System.getProperty("postgres.port", "5432")));
|
||||
|
||||
@Rule
|
||||
|
@ -51,12 +66,6 @@ public class GitLabIT {
|
|||
|
||||
@Test
|
||||
public void buildOnPush() throws IOException, InterruptedException, GitAPIException {
|
||||
final String httpUrl = gitlab.createProject(projectRequest()
|
||||
.withName("test")
|
||||
.withWebHookUrl("http://" + getDocker0Ip() + ":" + jenkins.getURL().getPort() + "/jenkins/project/test")
|
||||
.withPushHook(true)
|
||||
.build());
|
||||
|
||||
final OneShotEvent buildTriggered = new OneShotEvent();
|
||||
FreeStyleProject project = jenkins.createFreeStyleProject("test");
|
||||
GitLabPushTrigger trigger = gitLabPushTrigger().withTriggerOnPush(true).withBranchFilterType(BranchFilterType.All).build();
|
||||
|
@ -71,45 +80,15 @@ public class GitLabIT {
|
|||
});
|
||||
project.setQuietPeriod(0);
|
||||
|
||||
Git.init().setDirectory(tmp.getRoot()).call();
|
||||
tmp.newFile("test");
|
||||
Git git = Git.open(tmp.getRoot());
|
||||
git.add().addFilepattern("test");
|
||||
git.commit().setMessage("test").call();
|
||||
StoredConfig config = git.getRepository().getConfig();
|
||||
config.setString("remote", "origin", "url", httpUrl);
|
||||
config.save();
|
||||
git.push()
|
||||
.setRemote("origin").add("master")
|
||||
.setCredentialsProvider(new UsernamePasswordCredentialsProvider(gitlab.getUsername(), gitlab.getPassword()))
|
||||
.call();
|
||||
createGitLabProject(false,true, true, false);
|
||||
|
||||
buildTriggered.block(10000);
|
||||
assertThat(buildTriggered.isSignaled(), is(true));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void buildOnMergeRequest() throws IOException, InterruptedException, GitAPIException {
|
||||
|
||||
// check for clean slate
|
||||
assertTrue(gitlab.getProjectIds().isEmpty());
|
||||
|
||||
final String httpUrl = gitlab.createProject(projectRequest()
|
||||
.withName("test")
|
||||
.withWebHookUrl("http://" + getDocker0Ip() + ":" + jenkins.getURL().getPort() + "/jenkins/project/test")
|
||||
.withMergeRequestHook(true)
|
||||
.build());
|
||||
|
||||
// Fix: Hack to get the project id
|
||||
// A preferable approach would be here to get the target project by name using getProject function of the
|
||||
// GitLabRule and to use the id from the project instance. However, due to a bug in GitLab (tested on 8.6.1)
|
||||
// retrieving the project by name is not properly working.
|
||||
// (see issue https://github.com/gitlabhq/gitlabhq/issues/4921).
|
||||
// Once the issue is resolved, replace this implementation.
|
||||
final List<String> projectIds = gitlab.getProjectIds();
|
||||
assertSame(projectIds.size(), 1);
|
||||
final Integer projectId = Integer.parseInt(projectIds.get(0));
|
||||
|
||||
final OneShotEvent buildTriggered = new OneShotEvent();
|
||||
FreeStyleProject project = jenkins.createFreeStyleProject("test");
|
||||
GitLabPushTrigger trigger = gitLabPushTrigger().withTriggerOnMergeRequest(true).withBranchFilterType(BranchFilterType.All).build();
|
||||
|
@ -124,30 +103,9 @@ public class GitLabIT {
|
|||
});
|
||||
project.setQuietPeriod(0);
|
||||
|
||||
// Setup git repository
|
||||
Git.init().setDirectory(tmp.getRoot()).call();
|
||||
Git git = Git.open(tmp.getRoot());
|
||||
StoredConfig config = git.getRepository().getConfig();
|
||||
config.setString("remote", "origin", "url", httpUrl);
|
||||
config.save();
|
||||
Pair<Integer, String> gitlabData = createGitLabProject(true,false, false, true);
|
||||
|
||||
// Setup remote master branch
|
||||
tmp.newFile("test");
|
||||
git.add().addFilepattern("test");
|
||||
git.commit().setMessage("test").call();
|
||||
git.push()
|
||||
.setRemote("origin").add("master")
|
||||
.setCredentialsProvider(new UsernamePasswordCredentialsProvider(gitlab.getUsername(), gitlab.getPassword()))
|
||||
.call();
|
||||
|
||||
// Setup remote feature branch
|
||||
git.checkout().setName("feature").setCreateBranch(true).call();
|
||||
tmp.newFile("feature");
|
||||
git.commit().setMessage("feature").call();
|
||||
git.push().setRemote("origin").add("feature").setCredentialsProvider(new UsernamePasswordCredentialsProvider(gitlab.getUsername(), gitlab.getPassword()))
|
||||
.call();
|
||||
|
||||
gitlab.createMergeRequest(projectId, "feature", "master", "Merge feature branch to master.");
|
||||
gitlab.createMergeRequest(gitlabData.getLeft(), "feature", "master", "Merge feature branch to master.");
|
||||
|
||||
buildTriggered.block(10000);
|
||||
assertThat(buildTriggered.isSignaled(), is(true));
|
||||
|
@ -155,26 +113,6 @@ public class GitLabIT {
|
|||
|
||||
@Test
|
||||
public void buildOnNote() throws IOException, InterruptedException, GitAPIException {
|
||||
|
||||
// check for clean slate
|
||||
assertTrue(gitlab.getProjectIds().isEmpty());
|
||||
|
||||
final String httpUrl = gitlab.createProject(projectRequest()
|
||||
.withName("test")
|
||||
.withWebHookUrl("http://" + getDocker0Ip() + ":" + jenkins.getURL().getPort() + "/jenkins/project/test")
|
||||
.withNoteHook(true)
|
||||
.build());
|
||||
|
||||
// Fix: Hack to get the project id
|
||||
// A preferable approach would be here to get the target project by name using getProject function of the
|
||||
// GitLabRule and to use the id from the project instance. However, due to a bug in GitLab (tested on 8.6.1)
|
||||
// retrieving the project by name is not properly working.
|
||||
// (see issue https://github.com/gitlabhq/gitlabhq/issues/4921).
|
||||
// Once the issue is resolved, replace this implementation.
|
||||
final List<String> projectIds = gitlab.getProjectIds();
|
||||
assertSame(projectIds.size(), 1);
|
||||
final Integer projectId = Integer.parseInt(projectIds.get(0));
|
||||
|
||||
final OneShotEvent buildTriggered = new OneShotEvent();
|
||||
FreeStyleProject project = jenkins.createFreeStyleProject("test");
|
||||
GitLabPushTrigger trigger = gitLabPushTrigger()
|
||||
|
@ -190,42 +128,134 @@ public class GitLabIT {
|
|||
});
|
||||
project.setQuietPeriod(0);
|
||||
|
||||
// Setup git repository
|
||||
Git.init().setDirectory(tmp.getRoot()).call();
|
||||
Git git = Git.open(tmp.getRoot());
|
||||
StoredConfig config = git.getRepository().getConfig();
|
||||
config.setString("remote", "origin", "url", httpUrl);
|
||||
config.save();
|
||||
|
||||
// Setup remote master branch
|
||||
tmp.newFile("test");
|
||||
git.add().addFilepattern("test");
|
||||
git.commit().setMessage("test").call();
|
||||
git.push()
|
||||
.setRemote("origin").add("master")
|
||||
.setCredentialsProvider(new UsernamePasswordCredentialsProvider(gitlab.getUsername(), gitlab.getPassword()))
|
||||
.call();
|
||||
|
||||
// Setup remote feature branch
|
||||
git.checkout().setName("feature").setCreateBranch(true).call();
|
||||
tmp.newFile("feature");
|
||||
git.commit().setMessage("feature").call();
|
||||
git.push().setRemote("origin").add("feature").setCredentialsProvider(new UsernamePasswordCredentialsProvider(gitlab.getUsername(), gitlab.getPassword()))
|
||||
.call();
|
||||
Pair<Integer, String> gitlabData = createGitLabProject(true, false, true, false);
|
||||
|
||||
// create merge-request
|
||||
MergeRequest mr = gitlab.createMergeRequest(projectId, "feature", "master", "Merge feature branch to master.");
|
||||
MergeRequest mr = gitlab.createMergeRequest(gitlabData.getLeft(), "feature", "master", "Merge feature branch to master.");
|
||||
|
||||
// add trigger after push/merge-request so it may only receive the note-hook
|
||||
project.addTrigger(trigger);
|
||||
trigger.start(project, true);
|
||||
|
||||
gitlab.createMergeRequestNote(projectId, mr.getId(), "this is a test note");
|
||||
gitlab.createMergeRequestNote(gitlabData.getLeft(), mr.getId(), "this is a test note");
|
||||
|
||||
buildTriggered.block(20000);
|
||||
assertThat(buildTriggered.isSignaled(), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void reportBuildStatus() throws IOException, InterruptedException, GitAPIException {
|
||||
final OneShotEvent buildTriggered = new OneShotEvent();
|
||||
final OneShotEvent buildReported = new OneShotEvent();
|
||||
|
||||
GitLabPushTrigger trigger = gitLabPushTrigger()
|
||||
.withTriggerOnPush(true)
|
||||
.withBranchFilterType(BranchFilterType.All)
|
||||
.build();
|
||||
|
||||
FreeStyleProject project = jenkins.createFreeStyleProject("test");
|
||||
project.addProperty(gitlab.createGitLabConnectionProperty());
|
||||
project.addTrigger(trigger);
|
||||
|
||||
project.getBuildersList().add(new TestBuilder() {
|
||||
@Override
|
||||
public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
|
||||
buildTriggered.signal();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
project.getBuildersList().add(new SleepBuilder(20000));
|
||||
|
||||
DescribableList<Publisher, Descriptor<Publisher>> publishers = project.getPublishersList();
|
||||
publishers.add(new GitLabCommitStatusPublisher("integration-test", false));
|
||||
publishers.add(new TestNotifier() {
|
||||
@Override
|
||||
public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
|
||||
buildReported.signal();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
trigger.start(project, true);
|
||||
project.setQuietPeriod(0);
|
||||
|
||||
|
||||
Pair<Integer, String> gitlabData = createGitLabProject(false,true, true, false);
|
||||
assertThat(gitlab.getPipelines(gitlabData.getLeft()), empty());
|
||||
|
||||
buildTriggered.block(20000);
|
||||
assertThat(buildTriggered.isSignaled(), is(true));
|
||||
assertPipelineStatus(gitlabData, "running");
|
||||
|
||||
buildReported.block(40000);
|
||||
assertThat(buildReported.isSignaled(), is(true));
|
||||
|
||||
Thread.sleep(5000); // wait for gitlab to update
|
||||
assertPipelineStatus(gitlabData, "success");
|
||||
}
|
||||
|
||||
private void assertPipelineStatus(Pair<Integer, String> gitlabData, String status) {
|
||||
List<Pipeline> pipelines = gitlab.getPipelines(gitlabData.getLeft());
|
||||
assertThat(pipelines, hasSize(1));
|
||||
|
||||
Pipeline pipeline = pipelines.get(0);
|
||||
assertEquals(gitlabData.getRight(), pipeline.getSha());
|
||||
assertEquals(status, pipeline.getStatus());
|
||||
}
|
||||
|
||||
private Pair<Integer, String> createGitLabProject(boolean addFeatureBranch, boolean withPushHook, boolean withNoteHook, boolean withMergeRequestHook) throws IOException, GitAPIException {
|
||||
// check for clean slate
|
||||
assertTrue(gitlab.getProjectIds().isEmpty());
|
||||
|
||||
String url = gitlab.createProject(projectRequest()
|
||||
.withName("test")
|
||||
.withWebHookUrl("http://" + getDocker0Ip() + ":" + jenkins.getURL().getPort() + "/jenkins/project/test")
|
||||
.withPushHook(withPushHook)
|
||||
.withNoteHook(withNoteHook)
|
||||
.withMergeRequestHook(withMergeRequestHook)
|
||||
.build());
|
||||
|
||||
String sha = initGitLabProject(url, addFeatureBranch);
|
||||
|
||||
// Fix: Hack to get the project id
|
||||
// A preferable approach would be here to get the target project by name using getProject function of the
|
||||
// GitLabRule and to use the id from the project instance. However, due to a bug in GitLab (tested on 8.6.1)
|
||||
// retrieving the project by name is not properly working.
|
||||
// (see issue https://github.com/gitlabhq/gitlabhq/issues/4921).
|
||||
// Once the issue is resolved, replace this implementation.
|
||||
List<String> projectIds = gitlab.getProjectIds();
|
||||
assertSame(projectIds.size(), 1);
|
||||
return new ImmutablePair<>(Integer.parseInt(projectIds.get(0)), sha);
|
||||
}
|
||||
|
||||
private String initGitLabProject(String url, boolean addFeatureBranch) throws GitAPIException, IOException {
|
||||
// Setup git repository
|
||||
Git.init().setDirectory(tmp.getRoot()).call();
|
||||
Git git = Git.open(tmp.getRoot());
|
||||
StoredConfig config = git.getRepository().getConfig();
|
||||
config.setString("remote", "origin", "url", url);
|
||||
config.save();
|
||||
|
||||
// Setup remote master branch
|
||||
tmp.newFile("test");
|
||||
git.add().addFilepattern("test");
|
||||
RevCommit commit = git.commit().setMessage("test").call();
|
||||
git.push()
|
||||
.setRemote("origin").add("master")
|
||||
.setCredentialsProvider(new UsernamePasswordCredentialsProvider(gitlab.getUsername(), gitlab.getPassword()))
|
||||
.call();
|
||||
|
||||
if (addFeatureBranch) {
|
||||
// Setup remote feature branch
|
||||
git.checkout().setName("feature").setCreateBranch(true).call();
|
||||
tmp.newFile("feature");
|
||||
commit = git.commit().setMessage("feature").call();
|
||||
git.push().setRemote("origin").add("feature").setCredentialsProvider(new UsernamePasswordCredentialsProvider(gitlab.getUsername(), gitlab.getPassword()))
|
||||
.call();
|
||||
}
|
||||
|
||||
return commit.getName();
|
||||
}
|
||||
|
||||
private String getDocker0Ip() {
|
||||
try {
|
||||
Enumeration<InetAddress> docker0Addresses = NetworkInterface.getByName("docker0").getInetAddresses();
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
package com.dabsquared.gitlabjenkins.util;
|
||||
|
||||
import static com.dabsquared.gitlabjenkins.util.ProjectIdUtilTest.TestData.forRemoteUrl;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
|
||||
import org.junit.experimental.theories.DataPoints;
|
||||
import org.junit.experimental.theories.Theories;
|
||||
import org.junit.experimental.theories.Theory;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabApi;
|
||||
import static com.dabsquared.gitlabjenkins.util.ProjectIdUtilTest.TestData.forRemoteUrl;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
|
||||
/**
|
||||
* @author Robin Müller
|
||||
|
@ -33,8 +32,7 @@ public class ProjectIdUtilTest {
|
|||
|
||||
@Theory
|
||||
public void retrieveProjectId(TestData testData) throws ProjectIdUtil.ProjectIdResolutionException {
|
||||
GitLabApi client = mock(GitLabApi.class);
|
||||
when(client.getGitLabHostUrl()).thenReturn(testData.baseUrl);
|
||||
GitLabClient client = new GitLabClient(testData.hostUrl, null);
|
||||
|
||||
String projectId = ProjectIdUtil.retrieveProjectId(client, testData.remoteUrl);
|
||||
|
||||
|
@ -44,12 +42,12 @@ public class ProjectIdUtilTest {
|
|||
|
||||
static final class TestData {
|
||||
|
||||
private final String baseUrl;
|
||||
private final String hostUrl;
|
||||
private final String remoteUrl;
|
||||
private String expectedProjectId;
|
||||
|
||||
private TestData(String baseUrl, String remoteUrl) {
|
||||
this.baseUrl = baseUrl;
|
||||
private TestData(String hostUrl, String remoteUrl) {
|
||||
this.hostUrl = hostUrl;
|
||||
this.remoteUrl = remoteUrl;
|
||||
}
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ public abstract class BuildPageRedirectActionTest {
|
|||
testProject.setScm(new GitSCM(gitRepoUrl));
|
||||
testProject.setQuietPeriod(0);
|
||||
QueueTaskFuture<FreeStyleBuild> future = testProject.scheduleBuild2(0);
|
||||
FreeStyleBuild build = future.get(5, TimeUnit.SECONDS);
|
||||
FreeStyleBuild build = future.get(15, TimeUnit.SECONDS);
|
||||
|
||||
getBuildPageRedirectAction(testProject).execute(response);
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
rm -rf $HOME/.m2/repository/com/dabsquared/gitlabjenkins
|
||||
mkdir -p $DOCKER_CACHE_DIR
|
||||
docker images -a --filter='dangling=false' --format '{{.Repository}}:{{.Tag}} {{.ID}}' | xargs -n 2 -t sh -c 'test -e $DOCKER_CACHE_DIR/$1.tar.gz || docker save $0 | gzip -2 > $DOCKER_CACHE_DIR/$1.tar.gz'
|
|
@ -0,0 +1,7 @@
|
|||
#!/usr/bin/env bash
|
||||
if [[ -d $DOCKER_CACHE_DIR ]]; then
|
||||
echo "Loading cached images into docker..."
|
||||
ls $DOCKER_CACHE_DIR/*.tar.gz | xargs -I {file} sh -c "zcat {file} | docker load";
|
||||
fi
|
||||
|
||||
./mvnw integration-test -P integration-test -Dgitlab.version=$GITLAB_VERSION -Dfindbugs.skip=true -Dmaven.javadoc.skip=true
|
|
@ -0,0 +1,2 @@
|
|||
#!/usr/bin/env bash
|
||||
./mvnw verify -B -Pall-tests,skip-javadoc-with-tests -Dmaven.javadoc.skip=true
|
Loading…
Reference in New Issue