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>
|
<profile>
|
||||||
<id>integration-test</id>
|
<id>integration-test</id>
|
||||||
<properties>
|
<properties>
|
||||||
<gitlab.version>8.5.8</gitlab.version>
|
<gitlab.version>8.17.4</gitlab.version>
|
||||||
|
<postgres.version>9.5-1</postgres.version>
|
||||||
</properties>
|
</properties>
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
|
@ -359,7 +360,7 @@
|
||||||
<verbose>true</verbose>
|
<verbose>true</verbose>
|
||||||
<images>
|
<images>
|
||||||
<image>
|
<image>
|
||||||
<name>sameersbn/postgresql:9.4-15</name>
|
<name>sameersbn/postgresql:${postgres.version}</name>
|
||||||
<alias>it-gitlab-postgres</alias>
|
<alias>it-gitlab-postgres</alias>
|
||||||
<run>
|
<run>
|
||||||
<namingStrategy>alias</namingStrategy>
|
<namingStrategy>alias</namingStrategy>
|
||||||
|
@ -367,6 +368,7 @@
|
||||||
<DB_NAME>gitlabhq_production</DB_NAME>
|
<DB_NAME>gitlabhq_production</DB_NAME>
|
||||||
<DB_USER>gitlab</DB_USER>
|
<DB_USER>gitlab</DB_USER>
|
||||||
<DB_PASS>password</DB_PASS>
|
<DB_PASS>password</DB_PASS>
|
||||||
|
<DB_EXTENSION>pg_trgm</DB_EXTENSION>
|
||||||
</env>
|
</env>
|
||||||
<ports>
|
<ports>
|
||||||
<port>${postgres.port}:5432</port>
|
<port>${postgres.port}:5432</port>
|
||||||
|
@ -382,7 +384,9 @@
|
||||||
</image>
|
</image>
|
||||||
<image>
|
<image>
|
||||||
<name>sameersbn/gitlab:${gitlab.version}</name>
|
<name>sameersbn/gitlab:${gitlab.version}</name>
|
||||||
|
<alias>it-gitlab-gitlab</alias>
|
||||||
<run>
|
<run>
|
||||||
|
<namingStrategy>alias</namingStrategy>
|
||||||
<links>
|
<links>
|
||||||
<link>it-gitlab-postgres:postgresql</link>
|
<link>it-gitlab-postgres:postgresql</link>
|
||||||
<link>it-gitlab-redis:redisio</link>
|
<link>it-gitlab-redis:redisio</link>
|
||||||
|
@ -392,9 +396,15 @@
|
||||||
<port>${gitlab.ssh.port}:22</port>
|
<port>${gitlab.ssh.port}:22</port>
|
||||||
</ports>
|
</ports>
|
||||||
<env>
|
<env>
|
||||||
|
<DEBUG>false</DEBUG>
|
||||||
|
<TZ>Asia/Kolkata</TZ>
|
||||||
|
<GITLAB_TIMEZONE>Kolkata</GITLAB_TIMEZONE>
|
||||||
<GITLAB_PORT>${gitlab.http.port}</GITLAB_PORT>
|
<GITLAB_PORT>${gitlab.http.port}</GITLAB_PORT>
|
||||||
<GITLAB_SSH_PORT>${gitlab.ssh.port}</GITLAB_SSH_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>
|
</env>
|
||||||
<wait>
|
<wait>
|
||||||
<http>
|
<http>
|
||||||
|
|
|
@ -14,7 +14,7 @@ postgresql:
|
||||||
gitlab:
|
gitlab:
|
||||||
container_name: docker-gitlab
|
container_name: docker-gitlab
|
||||||
restart: always
|
restart: always
|
||||||
image: sameersbn/gitlab:9.4.1
|
image: sameersbn/gitlab:8.17.4
|
||||||
links:
|
links:
|
||||||
- redis:redisio
|
- redis:redisio
|
||||||
- postgresql:postgresql
|
- postgresql:postgresql
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.dabsquared.gitlabjenkins;
|
package com.dabsquared.gitlabjenkins;
|
||||||
|
|
||||||
|
|
||||||
import com.dabsquared.gitlabjenkins.connection.GitLabConnection;
|
import com.dabsquared.gitlabjenkins.connection.GitLabConnection;
|
||||||
import com.dabsquared.gitlabjenkins.connection.GitLabConnectionConfig;
|
import com.dabsquared.gitlabjenkins.connection.GitLabConnectionConfig;
|
||||||
import com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty;
|
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);
|
GitLabPushTrigger.DescriptorImpl oldConfig = Trigger.all().get(GitLabPushTrigger.DescriptorImpl.class);
|
||||||
if (!oldConfig.jobsMigrated) {
|
if (!oldConfig.jobsMigrated) {
|
||||||
GitLabConnectionConfig gitLabConfig = (GitLabConnectionConfig) Jenkins.getInstance().getDescriptor(GitLabConnectionConfig.class);
|
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.gitlabHostUrl,
|
||||||
oldConfig.gitlabApiToken,
|
oldConfig.gitlabApiToken,
|
||||||
|
"autodetect",
|
||||||
oldConfig.ignoreCertificateErrors,
|
oldConfig.ignoreCertificateErrors,
|
||||||
10,
|
10,
|
||||||
10));
|
10));
|
||||||
|
|
|
@ -1,39 +1,83 @@
|
||||||
package com.dabsquared.gitlabjenkins.connection;
|
package com.dabsquared.gitlabjenkins.connection;
|
||||||
|
|
||||||
|
|
||||||
|
import com.cloudbees.plugins.credentials.CredentialsMatchers;
|
||||||
import com.cloudbees.plugins.credentials.CredentialsProvider;
|
import com.cloudbees.plugins.credentials.CredentialsProvider;
|
||||||
import com.cloudbees.plugins.credentials.CredentialsScope;
|
import com.cloudbees.plugins.credentials.CredentialsScope;
|
||||||
import com.cloudbees.plugins.credentials.CredentialsStore;
|
import com.cloudbees.plugins.credentials.CredentialsStore;
|
||||||
import com.cloudbees.plugins.credentials.SystemCredentialsProvider;
|
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.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.InitMilestone;
|
||||||
import hudson.init.Initializer;
|
import hudson.init.Initializer;
|
||||||
|
import hudson.model.Item;
|
||||||
|
import hudson.security.ACL;
|
||||||
import hudson.util.Secret;
|
import hudson.util.Secret;
|
||||||
import jenkins.model.Jenkins;
|
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 org.kohsuke.stapler.DataBoundConstructor;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
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
|
* @author Robin Müller
|
||||||
*/
|
*/
|
||||||
public class GitLabConnection {
|
public class GitLabConnection {
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
private final String url;
|
private final String url;
|
||||||
private transient String apiToken;
|
private transient String apiToken;
|
||||||
// TODO make final when migration code gets removed
|
// TODO make final when migration code gets removed
|
||||||
private String apiTokenId;
|
private String apiTokenId;
|
||||||
|
private GitLabClientBuilder clientBuilder;
|
||||||
private final boolean ignoreCertificateErrors;
|
private final boolean ignoreCertificateErrors;
|
||||||
private final Integer connectionTimeout;
|
private final Integer connectionTimeout;
|
||||||
private final Integer readTimeout;
|
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
|
@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.name = name;
|
||||||
this.url = url;
|
this.url = url;
|
||||||
this.apiTokenId = apiTokenId;
|
this.apiTokenId = apiTokenId;
|
||||||
|
this.clientBuilder = clientBuilder;
|
||||||
this.ignoreCertificateErrors = ignoreCertificateErrors;
|
this.ignoreCertificateErrors = ignoreCertificateErrors;
|
||||||
this.connectionTimeout = connectionTimeout;
|
this.connectionTimeout = connectionTimeout;
|
||||||
this.readTimeout = readTimeout;
|
this.readTimeout = readTimeout;
|
||||||
|
@ -51,6 +95,10 @@ public class GitLabConnection {
|
||||||
return apiTokenId;
|
return apiTokenId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getClientBuilderId() {
|
||||||
|
return clientBuilder.id();
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isIgnoreCertificateErrors() {
|
public boolean isIgnoreCertificateErrors() {
|
||||||
return ignoreCertificateErrors;
|
return ignoreCertificateErrors;
|
||||||
}
|
}
|
||||||
|
@ -63,10 +111,38 @@ public class GitLabConnection {
|
||||||
return readTimeout;
|
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() {
|
protected GitLabConnection readResolve() {
|
||||||
if (connectionTimeout == null || readTimeout == null) {
|
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;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
package com.dabsquared.gitlabjenkins.connection;
|
package com.dabsquared.gitlabjenkins.connection;
|
||||||
|
|
||||||
|
|
||||||
import com.cloudbees.plugins.credentials.Credentials;
|
import com.cloudbees.plugins.credentials.Credentials;
|
||||||
import com.cloudbees.plugins.credentials.CredentialsMatcher;
|
import com.cloudbees.plugins.credentials.CredentialsMatcher;
|
||||||
import com.cloudbees.plugins.credentials.common.AbstractIdCredentialsListBoxModel;
|
import com.cloudbees.plugins.credentials.common.AbstractIdCredentialsListBoxModel;
|
||||||
import com.cloudbees.plugins.credentials.common.StandardCredentials;
|
import com.cloudbees.plugins.credentials.common.StandardCredentials;
|
||||||
import com.cloudbees.plugins.credentials.common.StandardListBoxModel;
|
import com.cloudbees.plugins.credentials.common.StandardListBoxModel;
|
||||||
import com.cloudbees.plugins.credentials.domains.URIRequirementBuilder;
|
import com.cloudbees.plugins.credentials.domains.URIRequirementBuilder;
|
||||||
import com.dabsquared.gitlabjenkins.gitlab.GitLabClientBuilder;
|
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
|
||||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabApi;
|
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClientBuilder;
|
||||||
import edu.umd.cs.findbugs.annotations.NonNull;
|
import edu.umd.cs.findbugs.annotations.NonNull;
|
||||||
import hudson.Extension;
|
import hudson.Extension;
|
||||||
import hudson.model.Item;
|
import hudson.model.Item;
|
||||||
|
@ -29,6 +30,9 @@ import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static com.dabsquared.gitlabjenkins.gitlab.api.GitLabClientBuilder.getAllGitLabClientBuilders;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Robin Müller
|
* @author Robin Müller
|
||||||
*/
|
*/
|
||||||
|
@ -38,7 +42,6 @@ public class GitLabConnectionConfig extends GlobalConfiguration {
|
||||||
private Boolean useAuthenticatedEndpoint = true;
|
private Boolean useAuthenticatedEndpoint = true;
|
||||||
private List<GitLabConnection> connections = new ArrayList<>();
|
private List<GitLabConnection> connections = new ArrayList<>();
|
||||||
private transient Map<String, GitLabConnection> connectionMap = new HashMap<>();
|
private transient Map<String, GitLabConnection> connectionMap = new HashMap<>();
|
||||||
private transient Map<String, GitLabApi> clients = new HashMap<>();
|
|
||||||
|
|
||||||
public GitLabConnectionConfig() {
|
public GitLabConnectionConfig() {
|
||||||
load();
|
load();
|
||||||
|
@ -50,7 +53,6 @@ public class GitLabConnectionConfig extends GlobalConfiguration {
|
||||||
connections = req.bindJSONToList(GitLabConnection.class, json.get("connections"));
|
connections = req.bindJSONToList(GitLabConnection.class, json.get("connections"));
|
||||||
useAuthenticatedEndpoint = json.getBoolean("useAuthenticatedEndpoint");
|
useAuthenticatedEndpoint = json.getBoolean("useAuthenticatedEndpoint");
|
||||||
refreshConnectionMap();
|
refreshConnectionMap();
|
||||||
clients.clear();
|
|
||||||
save();
|
save();
|
||||||
return super.configure(req, json);
|
return super.configure(req, json);
|
||||||
}
|
}
|
||||||
|
@ -80,11 +82,11 @@ public class GitLabConnectionConfig extends GlobalConfiguration {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public GitLabApi getClient(String connectionName) {
|
public GitLabClient getClient(String connectionName) {
|
||||||
if (!clients.containsKey(connectionName) && connectionMap.containsKey(connectionName)) {
|
if (!connectionMap.containsKey(connectionName)) {
|
||||||
clients.put(connectionName, GitLabClientBuilder.buildClient(connectionMap.get(connectionName)));
|
return null;
|
||||||
}
|
}
|
||||||
return clients.get(connectionName);
|
return connectionMap.get(connectionName).getClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
public FormValidation doCheckName(@QueryParameter String id, @QueryParameter String value) {
|
public FormValidation doCheckName(@QueryParameter String id, @QueryParameter String value) {
|
||||||
|
@ -131,11 +133,12 @@ public class GitLabConnectionConfig extends GlobalConfiguration {
|
||||||
|
|
||||||
public FormValidation doTestConnection(@QueryParameter String url,
|
public FormValidation doTestConnection(@QueryParameter String url,
|
||||||
@QueryParameter String apiTokenId,
|
@QueryParameter String apiTokenId,
|
||||||
|
@QueryParameter String clientBuilderId,
|
||||||
@QueryParameter boolean ignoreCertificateErrors,
|
@QueryParameter boolean ignoreCertificateErrors,
|
||||||
@QueryParameter int connectionTimeout,
|
@QueryParameter int connectionTimeout,
|
||||||
@QueryParameter int readTimeout) {
|
@QueryParameter int readTimeout) {
|
||||||
try {
|
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());
|
return FormValidation.ok(Messages.connection_success());
|
||||||
} catch (WebApplicationException e) {
|
} catch (WebApplicationException e) {
|
||||||
return FormValidation.error(Messages.connection_error(e.getMessage()));
|
return FormValidation.error(Messages.connection_error(e.getMessage()));
|
||||||
|
@ -167,6 +170,15 @@ public class GitLabConnectionConfig extends GlobalConfiguration {
|
||||||
return new StandardListBoxModel();
|
return new StandardListBoxModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ListBoxModel doFillClientBuilderIdItems() {
|
||||||
|
ListBoxModel model = new ListBoxModel();
|
||||||
|
for (GitLabClientBuilder builder : getAllGitLabClientBuilders()) {
|
||||||
|
model.add(builder.id());
|
||||||
|
}
|
||||||
|
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
private void refreshConnectionMap() {
|
private void refreshConnectionMap() {
|
||||||
connectionMap.clear();
|
connectionMap.clear();
|
||||||
for (GitLabConnection connection : connections) {
|
for (GitLabConnection connection : connections) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.dabsquared.gitlabjenkins.connection;
|
package com.dabsquared.gitlabjenkins.connection;
|
||||||
|
|
||||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabApi;
|
|
||||||
|
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
|
||||||
import hudson.Extension;
|
import hudson.Extension;
|
||||||
import hudson.model.Job;
|
import hudson.model.Job;
|
||||||
import hudson.model.JobProperty;
|
import hudson.model.JobProperty;
|
||||||
|
@ -30,7 +31,7 @@ public class GitLabConnectionProperty extends JobProperty<Job<?, ?>> {
|
||||||
return gitLabConnection;
|
return gitLabConnection;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GitLabApi getClient() {
|
public GitLabClient getClient() {
|
||||||
if (StringUtils.isNotEmpty(gitLabConnection)) {
|
if (StringUtils.isNotEmpty(gitLabConnection)) {
|
||||||
GitLabConnectionConfig connectionConfig = (GitLabConnectionConfig) Jenkins.getInstance().getDescriptor(GitLabConnectionConfig.class);
|
GitLabConnectionConfig connectionConfig = (GitLabConnectionConfig) Jenkins.getInstance().getDescriptor(GitLabConnectionConfig.class);
|
||||||
return connectionConfig != null ? connectionConfig.getClient(gitLabConnection) : null;
|
return connectionConfig != null ? connectionConfig.getClient(gitLabConnection) : null;
|
||||||
|
@ -38,7 +39,7 @@ public class GitLabConnectionProperty extends JobProperty<Job<?, ?>> {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GitLabApi getClient(Run<?, ?> build) {
|
public static GitLabClient getClient(Run<?, ?> build) {
|
||||||
final GitLabConnectionProperty connectionProperty = build.getParent().getProperty(GitLabConnectionProperty.class);
|
final GitLabConnectionProperty connectionProperty = build.getParent().getProperty(GitLabConnectionProperty.class);
|
||||||
if (connectionProperty != null) {
|
if (connectionProperty != null) {
|
||||||
return connectionProperty.getClient();
|
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;
|
package com.dabsquared.gitlabjenkins.gitlab.api;
|
||||||
|
|
||||||
/**
|
|
||||||
* Extends REST-client interface to provide additional methods for plugin's code.
|
import com.dabsquared.gitlabjenkins.gitlab.api.model.*;
|
||||||
*
|
import com.dabsquared.gitlabjenkins.gitlab.hook.model.State;
|
||||||
* @author Alexander Leshkin
|
import org.kohsuke.accmod.Restricted;
|
||||||
*
|
import org.kohsuke.accmod.restrictions.NoExternalUse;
|
||||||
*/
|
|
||||||
public interface GitLabApi extends GitLabApiClient {
|
import javax.ws.rs.PathParam;
|
||||||
/**
|
import java.util.List;
|
||||||
* Returns GitLab host base url from plugin confugruation.
|
|
||||||
*/
|
|
||||||
String getGitLabHostUrl();
|
@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.dabsquared.gitlabjenkins.gitlab.JacksonConfig;
|
||||||
import com.cloudbees.plugins.credentials.domains.DomainRequirement;
|
|
||||||
import com.dabsquared.gitlabjenkins.connection.GitLabApiToken;
|
|
||||||
import com.dabsquared.gitlabjenkins.connection.GitLabConnection;
|
|
||||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabApi;
|
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.JsonUtil;
|
||||||
import com.dabsquared.gitlabjenkins.util.LoggerUtil;
|
import com.dabsquared.gitlabjenkins.util.LoggerUtil;
|
||||||
import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
|
import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
|
||||||
|
@ -16,8 +14,6 @@ import com.google.common.collect.FluentIterable;
|
||||||
import hudson.ProxyConfiguration;
|
import hudson.ProxyConfiguration;
|
||||||
import hudson.init.InitMilestone;
|
import hudson.init.InitMilestone;
|
||||||
import hudson.init.Initializer;
|
import hudson.init.Initializer;
|
||||||
import hudson.model.Item;
|
|
||||||
import hudson.security.ACL;
|
|
||||||
import jenkins.model.Jenkins;
|
import jenkins.model.Jenkins;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.lang.StringUtils;
|
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.client.jaxrs.engines.ApacheHttpClient4Engine;
|
||||||
import org.jboss.resteasy.plugins.providers.JaxrsFormProvider;
|
import org.jboss.resteasy.plugins.providers.JaxrsFormProvider;
|
||||||
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
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.Nullable;
|
||||||
import javax.annotation.Priority;
|
import javax.annotation.Priority;
|
||||||
import javax.ws.rs.Priorities;
|
import javax.ws.rs.Priorities;
|
||||||
|
@ -47,96 +45,92 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.Proxy;
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import static com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials;
|
@Restricted(NoExternalUse.class)
|
||||||
|
public class ResteasyGitLabClientBuilder extends GitLabClientBuilder {
|
||||||
/**
|
private static final Logger LOGGER = Logger.getLogger(ResteasyGitLabClientBuilder.class.getName());
|
||||||
* @author Robin Müller
|
|
||||||
*/
|
|
||||||
public class GitLabClientBuilder {
|
|
||||||
|
|
||||||
private final static Logger LOGGER = Logger.getLogger(GitLabClientBuilder.class.getName());
|
|
||||||
private static final String PRIVATE_TOKEN = "PRIVATE-TOKEN";
|
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)
|
@Initializer(before = InitMilestone.PLUGINS_STARTED)
|
||||||
public static void setRuntimeDelegate() {
|
public static void setRuntimeDelegate() {
|
||||||
RuntimeDelegate.setInstance(new ResteasyProviderFactory());
|
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 {
|
try {
|
||||||
return new URL(gitlabUrl).getHost();
|
return new URL(url).getHost();
|
||||||
} catch (MalformedURLException e) {
|
} catch (MalformedURLException e) {
|
||||||
return null;
|
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)
|
@Priority(Priorities.HEADER_DECORATOR)
|
||||||
private static class ApiHeaderTokenFilter implements ClientRequestFilter {
|
private static class ApiHeaderTokenFilter implements ClientRequestFilter {
|
||||||
private final String gitlabApiToken;
|
private final String gitlabApiToken;
|
||||||
|
@ -232,7 +226,6 @@ public class GitLabClientBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ResteasyClientBuilder extends org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder {
|
private static class ResteasyClientBuilder extends org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder {
|
||||||
|
|
||||||
private CredentialsProvider proxyCredentials;
|
private CredentialsProvider proxyCredentials;
|
||||||
|
|
||||||
ResteasyClientBuilder defaultProxy(String hostname, int port, final String scheme, String username, String password) {
|
ResteasyClientBuilder defaultProxy(String hostname, int port, final String scheme, String username, String password) {
|
||||||
|
@ -244,6 +237,7 @@ public class GitLabClientBuilder {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
@Override
|
@Override
|
||||||
protected ClientHttpEngine initDefaultEngine() {
|
protected ClientHttpEngine initDefaultEngine() {
|
||||||
ApacheHttpClient4Engine httpEngine = (ApacheHttpClient4Engine) super.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.GitLabApi;
|
||||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.Label;
|
import com.dabsquared.gitlabjenkins.gitlab.api.model.*;
|
||||||
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;
|
import com.dabsquared.gitlabjenkins.gitlab.hook.model.State;
|
||||||
|
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
|
@ -22,22 +19,26 @@ import javax.ws.rs.QueryParam;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static com.dabsquared.gitlabjenkins.gitlab.api.impl.V3GitLabClientBuilder.ID;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Robin Müller
|
* @author Robin Müller
|
||||||
*/
|
*/
|
||||||
@Path("/api/v3")
|
@Path("/api/" + ID)
|
||||||
public interface GitLabApiClient {
|
interface V3GitLabApiProxy extends GitLabApi {
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||||
@Path("/projects")
|
@Path("/projects")
|
||||||
|
@Override
|
||||||
Project createProject(@FormParam("name") String projectName);
|
Project createProject(@FormParam("name") String projectName);
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||||
@Path("/projects/{projectId}/merge_requests")
|
@Path("/projects/{projectId}/merge_requests")
|
||||||
|
@Override
|
||||||
MergeRequest createMergeRequest(
|
MergeRequest createMergeRequest(
|
||||||
@PathParam("projectId") Integer projectId,
|
@PathParam("projectId") Integer projectId,
|
||||||
@FormParam("source_branch") String sourceBranch,
|
@FormParam("source_branch") String sourceBranch,
|
||||||
|
@ -47,24 +48,28 @@ public interface GitLabApiClient {
|
||||||
@GET
|
@GET
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Path("/projects/{projectName}")
|
@Path("/projects/{projectName}")
|
||||||
|
@Override
|
||||||
Project getProject(@PathParam("projectName") String projectName);
|
Project getProject(@PathParam("projectName") String projectName);
|
||||||
|
|
||||||
@PUT
|
@PUT
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||||
@Path("/projects/{projectId}")
|
@Path("/projects/{projectId}")
|
||||||
|
@Override
|
||||||
Project updateProject(@PathParam("projectId") String projectId,
|
Project updateProject(@PathParam("projectId") String projectId,
|
||||||
@FormParam("name") String name,
|
@FormParam("name") String name,
|
||||||
@FormParam("path") String path);
|
@FormParam("path") String path);
|
||||||
|
|
||||||
@DELETE
|
@DELETE
|
||||||
@Path("/projects/{projectId}")
|
@Path("/projects/{projectId}")
|
||||||
|
@Override
|
||||||
void deleteProject(@PathParam("projectId") String projectId);
|
void deleteProject(@PathParam("projectId") String projectId);
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||||
@Path("/projects/{projectId}/hooks")
|
@Path("/projects/{projectId}/hooks")
|
||||||
|
@Override
|
||||||
void addProjectHook(@PathParam("projectId") String projectId,
|
void addProjectHook(@PathParam("projectId") String projectId,
|
||||||
@FormParam("url") String url,
|
@FormParam("url") String url,
|
||||||
@FormParam("push_events") Boolean pushEvents,
|
@FormParam("push_events") Boolean pushEvents,
|
||||||
|
@ -75,6 +80,7 @@ public interface GitLabApiClient {
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||||
@Path("/projects/{projectId}/statuses/{sha}")
|
@Path("/projects/{projectId}/statuses/{sha}")
|
||||||
|
@Override
|
||||||
void changeBuildStatus(@PathParam("projectId") String projectId,
|
void changeBuildStatus(@PathParam("projectId") String projectId,
|
||||||
@PathParam("sha") String sha,
|
@PathParam("sha") String sha,
|
||||||
@FormParam("state") BuildState state,
|
@FormParam("state") BuildState state,
|
||||||
|
@ -87,6 +93,7 @@ public interface GitLabApiClient {
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||||
@Path("/projects/{projectId}/statuses/{sha}")
|
@Path("/projects/{projectId}/statuses/{sha}")
|
||||||
|
@Override
|
||||||
void changeBuildStatus(@PathParam("projectId") Integer projectId,
|
void changeBuildStatus(@PathParam("projectId") Integer projectId,
|
||||||
@PathParam("sha") String sha,
|
@PathParam("sha") String sha,
|
||||||
@FormParam("state") BuildState state,
|
@FormParam("state") BuildState state,
|
||||||
|
@ -98,6 +105,7 @@ public interface GitLabApiClient {
|
||||||
@GET
|
@GET
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Path("/projects/{projectId}/repository/commits/{sha}")
|
@Path("/projects/{projectId}/repository/commits/{sha}")
|
||||||
|
@Override
|
||||||
void getCommit(@PathParam("projectId") String projectId, @PathParam("sha") String sha);
|
void getCommit(@PathParam("projectId") String projectId, @PathParam("sha") String sha);
|
||||||
|
|
||||||
|
|
||||||
|
@ -105,6 +113,7 @@ public interface GitLabApiClient {
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||||
@Path("/projects/{projectId}/merge_requests/{mergeRequestId}/merge")
|
@Path("/projects/{projectId}/merge_requests/{mergeRequestId}/merge")
|
||||||
|
@Override
|
||||||
void acceptMergeRequest(@PathParam("projectId") Integer projectId,
|
void acceptMergeRequest(@PathParam("projectId") Integer projectId,
|
||||||
@PathParam("mergeRequestId") Integer mergeRequestId,
|
@PathParam("mergeRequestId") Integer mergeRequestId,
|
||||||
@FormParam("merge_commit_message") String mergeCommitMessage,
|
@FormParam("merge_commit_message") String mergeCommitMessage,
|
||||||
|
@ -114,6 +123,7 @@ public interface GitLabApiClient {
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||||
@Path("/projects/{projectId}/merge_requests/{mergeRequestId}/notes")
|
@Path("/projects/{projectId}/merge_requests/{mergeRequestId}/notes")
|
||||||
|
@Override
|
||||||
void createMergeRequestNote(@PathParam("projectId") Integer projectId,
|
void createMergeRequestNote(@PathParam("projectId") Integer projectId,
|
||||||
@PathParam("mergeRequestId") Integer mergeRequestId,
|
@PathParam("mergeRequestId") Integer mergeRequestId,
|
||||||
@FormParam("body") String body);
|
@FormParam("body") String body);
|
||||||
|
@ -121,6 +131,7 @@ public interface GitLabApiClient {
|
||||||
@GET
|
@GET
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Path("/projects/{projectId}/merge_requests")
|
@Path("/projects/{projectId}/merge_requests")
|
||||||
|
@Override
|
||||||
List<MergeRequest> getMergeRequests(@PathParam("projectId") String projectId,
|
List<MergeRequest> getMergeRequests(@PathParam("projectId") String projectId,
|
||||||
@QueryParam("state") State state,
|
@QueryParam("state") State state,
|
||||||
@QueryParam("page") int page,
|
@QueryParam("page") int page,
|
||||||
|
@ -129,28 +140,33 @@ public interface GitLabApiClient {
|
||||||
@GET
|
@GET
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Path("/projects/{projectId}/repository/branches")
|
@Path("/projects/{projectId}/repository/branches")
|
||||||
|
@Override
|
||||||
List<Branch> getBranches(@PathParam("projectId") String projectId);
|
List<Branch> getBranches(@PathParam("projectId") String projectId);
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Path("/projects/{projectId}/repository/branches/{branch}")
|
@Path("/projects/{projectId}/repository/branches/{branch}")
|
||||||
|
@Override
|
||||||
Branch getBranch(@PathParam("projectId") String projectId,
|
Branch getBranch(@PathParam("projectId") String projectId,
|
||||||
@PathParam("branch") String branch);
|
@PathParam("branch") String branch);
|
||||||
|
|
||||||
@HEAD
|
@HEAD
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Path("/user")
|
@Path("/user")
|
||||||
|
@Override
|
||||||
void headCurrentUser();
|
void headCurrentUser();
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Path("/user")
|
@Path("/user")
|
||||||
|
@Override
|
||||||
User getCurrentUser();
|
User getCurrentUser();
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||||
@Path("/users")
|
@Path("/users")
|
||||||
|
@Override
|
||||||
User addUser(@FormParam("email") String email,
|
User addUser(@FormParam("email") String email,
|
||||||
@FormParam("username") String username,
|
@FormParam("username") String username,
|
||||||
@FormParam("name") String name,
|
@FormParam("name") String name,
|
||||||
|
@ -160,6 +176,7 @@ public interface GitLabApiClient {
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||||
@Path("/users/{userId}")
|
@Path("/users/{userId}")
|
||||||
|
@Override
|
||||||
User updateUser(@PathParam("userId") String userId,
|
User updateUser(@PathParam("userId") String userId,
|
||||||
@FormParam("email") String email,
|
@FormParam("email") String email,
|
||||||
@FormParam("username") String username,
|
@FormParam("username") String username,
|
||||||
|
@ -169,5 +186,12 @@ public interface GitLabApiClient {
|
||||||
@GET
|
@GET
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Path("/projects/{projectId}/labels")
|
@Path("/projects/{projectId}/labels")
|
||||||
|
@Override
|
||||||
List<Label> getLabels(@PathParam("projectId") String projectId);
|
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;
|
package com.dabsquared.gitlabjenkins.publisher;
|
||||||
|
|
||||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabApi;
|
|
||||||
|
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
|
||||||
import hudson.Extension;
|
import hudson.Extension;
|
||||||
import hudson.model.AbstractProject;
|
import hudson.model.AbstractProject;
|
||||||
import hudson.model.Result;
|
import hudson.model.Result;
|
||||||
|
@ -44,7 +45,7 @@ public class GitLabAcceptMergeRequestPublisher extends MergeRequestNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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 {
|
try {
|
||||||
if (build.getResult() == Result.SUCCESS) {
|
if (build.getResult() == Result.SUCCESS) {
|
||||||
client.acceptMergeRequest(projectId, mergeRequestId, "Merge Request accepted by jenkins build success", false);
|
client.acceptMergeRequest(projectId, mergeRequestId, "Merge Request accepted by jenkins build success", false);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.dabsquared.gitlabjenkins.publisher;
|
package com.dabsquared.gitlabjenkins.publisher;
|
||||||
|
|
||||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabApi;
|
|
||||||
|
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
|
||||||
import hudson.Extension;
|
import hudson.Extension;
|
||||||
import hudson.Util;
|
import hudson.Util;
|
||||||
import hudson.model.AbstractProject;
|
import hudson.model.AbstractProject;
|
||||||
|
@ -107,7 +108,7 @@ public class GitLabMessagePublisher extends MergeRequestNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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 {
|
try {
|
||||||
if (!onlyForFailure || build.getResult() == Result.FAILURE || build.getResult() == Result.UNSTABLE) {
|
if (!onlyForFailure || build.getResult() == Result.FAILURE || build.getResult() == Result.UNSTABLE) {
|
||||||
client.createMergeRequestNote(projectId, mergeRequestId, getNote(build, listener));
|
client.createMergeRequestNote(projectId, mergeRequestId, getNote(build, listener));
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.dabsquared.gitlabjenkins.publisher;
|
package com.dabsquared.gitlabjenkins.publisher;
|
||||||
|
|
||||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabApi;
|
|
||||||
|
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
|
||||||
import hudson.Extension;
|
import hudson.Extension;
|
||||||
import hudson.model.AbstractProject;
|
import hudson.model.AbstractProject;
|
||||||
import hudson.model.Result;
|
import hudson.model.Result;
|
||||||
|
@ -44,7 +45,7 @@ public class GitLabVotePublisher extends MergeRequestNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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 {
|
try {
|
||||||
client.createMergeRequestNote(projectId, mergeRequestId, getResultIcon(build.getResult()));
|
client.createMergeRequestNote(projectId, mergeRequestId, getResultIcon(build.getResult()));
|
||||||
} catch (WebApplicationException | ProcessingException e) {
|
} catch (WebApplicationException | ProcessingException e) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package com.dabsquared.gitlabjenkins.publisher;
|
package com.dabsquared.gitlabjenkins.publisher;
|
||||||
|
|
||||||
import com.dabsquared.gitlabjenkins.cause.GitLabWebHookCause;
|
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.Launcher;
|
||||||
import hudson.matrix.MatrixAggregatable;
|
import hudson.matrix.MatrixAggregatable;
|
||||||
import hudson.matrix.MatrixAggregator;
|
import hudson.matrix.MatrixAggregator;
|
||||||
|
@ -27,7 +27,7 @@ public abstract class MergeRequestNotifier extends Notifier implements MatrixAgg
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
|
public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
|
||||||
GitLabApi client = getClient(build);
|
GitLabClient client = getClient(build);
|
||||||
if (client == null) {
|
if (client == null) {
|
||||||
listener.getLogger().println("No GitLab connection configured");
|
listener.getLogger().println("No GitLab connection configured");
|
||||||
return true;
|
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) {
|
Integer getProjectId(Run<?, ?> build) {
|
||||||
GitLabWebHookCause cause = build.getCause(GitLabWebHookCause.class);
|
GitLabWebHookCause cause = build.getCause(GitLabWebHookCause.class);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.dabsquared.gitlabjenkins.service;
|
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.gitlab.api.model.Branch;
|
||||||
import com.dabsquared.gitlabjenkins.util.LoggerUtil;
|
import com.dabsquared.gitlabjenkins.util.LoggerUtil;
|
||||||
import com.dabsquared.gitlabjenkins.util.ProjectIdUtil;
|
import com.dabsquared.gitlabjenkins.util.ProjectIdUtil;
|
||||||
|
@ -37,7 +38,7 @@ public class GitLabProjectBranchesService {
|
||||||
return gitLabProjectBranchesService;
|
return gitLabProjectBranchesService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getBranches(GitLabApi client, String sourceRepositoryString) {
|
public List<String> getBranches(GitLabClient client, String sourceRepositoryString) {
|
||||||
synchronized (projectBranchCache) {
|
synchronized (projectBranchCache) {
|
||||||
try {
|
try {
|
||||||
return projectBranchCache.get(sourceRepositoryString, new BranchNamesLoader(client, sourceRepositoryString));
|
return projectBranchCache.get(sourceRepositoryString, new BranchNamesLoader(client, sourceRepositoryString));
|
||||||
|
@ -54,10 +55,10 @@ public class GitLabProjectBranchesService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class BranchNamesLoader implements Callable<List<String>> {
|
private static class BranchNamesLoader implements Callable<List<String>> {
|
||||||
private final GitLabApi client;
|
private final GitLabClient client;
|
||||||
private final String sourceRepository;
|
private final String sourceRepository;
|
||||||
|
|
||||||
private BranchNamesLoader(GitLabApi client, String sourceRepository) {
|
private BranchNamesLoader(GitLabClient client, String sourceRepository) {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.sourceRepository = sourceRepository;
|
this.sourceRepository = sourceRepository;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.dabsquared.gitlabjenkins.service;
|
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.gitlab.api.model.Label;
|
||||||
import com.dabsquared.gitlabjenkins.util.LoggerUtil;
|
import com.dabsquared.gitlabjenkins.util.LoggerUtil;
|
||||||
import com.dabsquared.gitlabjenkins.util.ProjectIdUtil;
|
import com.dabsquared.gitlabjenkins.util.ProjectIdUtil;
|
||||||
|
@ -37,7 +38,7 @@ public class GitLabProjectLabelsService {
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getLabels(GitLabApi client, String sourceRepositoryString) {
|
public List<String> getLabels(GitLabClient client, String sourceRepositoryString) {
|
||||||
synchronized (projectLabelsCache) {
|
synchronized (projectLabelsCache) {
|
||||||
try {
|
try {
|
||||||
return projectLabelsCache.get(sourceRepositoryString, new LabelNamesLoader(client, sourceRepositoryString));
|
return projectLabelsCache.get(sourceRepositoryString, new LabelNamesLoader(client, sourceRepositoryString));
|
||||||
|
@ -54,10 +55,10 @@ public class GitLabProjectLabelsService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class LabelNamesLoader implements Callable<List<String>> {
|
private static class LabelNamesLoader implements Callable<List<String>> {
|
||||||
private final GitLabApi client;
|
private final GitLabClient client;
|
||||||
private final String sourceRepository;
|
private final String sourceRepository;
|
||||||
|
|
||||||
private LabelNamesLoader(GitLabApi client, String sourceRepository) {
|
private LabelNamesLoader(GitLabClient client, String sourceRepository) {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.sourceRepository = sourceRepository;
|
this.sourceRepository = sourceRepository;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ package com.dabsquared.gitlabjenkins.trigger.handler;
|
||||||
import com.dabsquared.gitlabjenkins.cause.CauseData;
|
import com.dabsquared.gitlabjenkins.cause.CauseData;
|
||||||
import com.dabsquared.gitlabjenkins.cause.GitLabWebHookCause;
|
import com.dabsquared.gitlabjenkins.cause.GitLabWebHookCause;
|
||||||
import com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty;
|
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.api.model.BuildState;
|
||||||
import com.dabsquared.gitlabjenkins.gitlab.hook.model.WebHook;
|
import com.dabsquared.gitlabjenkins.gitlab.hook.model.WebHook;
|
||||||
import com.dabsquared.gitlabjenkins.publisher.GitLabCommitStatusPublisher;
|
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) {
|
if (job instanceof AbstractProject && ((AbstractProject) job).getPublishersList().get(GitLabCommitStatusPublisher.class) != null) {
|
||||||
GitLabCommitStatusPublisher publisher =
|
GitLabCommitStatusPublisher publisher =
|
||||||
(GitLabCommitStatusPublisher) ((AbstractProject) job).getPublishersList().get(GitLabCommitStatusPublisher.class);
|
(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);
|
BuildStatusUpdate buildStatusUpdate = retrieveBuildStatusUpdate(hook);
|
||||||
try {
|
try {
|
||||||
if (client == null) {
|
if (client == null) {
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
package com.dabsquared.gitlabjenkins.trigger.handler.pipeline;
|
package com.dabsquared.gitlabjenkins.trigger.handler.pipeline;
|
||||||
|
|
||||||
|
|
||||||
import com.dabsquared.gitlabjenkins.cause.CauseData;
|
import com.dabsquared.gitlabjenkins.cause.CauseData;
|
||||||
import com.dabsquared.gitlabjenkins.cause.GitLabWebHookCause;
|
|
||||||
import com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty;
|
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.hook.model.*;
|
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.exception.NoRevisionToBuildException;
|
||||||
import com.dabsquared.gitlabjenkins.trigger.filter.BranchFilter;
|
import com.dabsquared.gitlabjenkins.trigger.filter.BranchFilter;
|
||||||
import com.dabsquared.gitlabjenkins.trigger.filter.MergeRequestLabelFilter;
|
import com.dabsquared.gitlabjenkins.trigger.filter.MergeRequestLabelFilter;
|
||||||
|
@ -46,7 +47,7 @@ class PipelineHookTriggerHandlerImpl extends AbstractWebHookTriggerHandler<Pipel
|
||||||
GitLabConnectionProperty property = job.getProperty(GitLabConnectionProperty.class);
|
GitLabConnectionProperty property = job.getProperty(GitLabConnectionProperty.class);
|
||||||
|
|
||||||
if (property != null && property.getClient() != null) {
|
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());
|
com.dabsquared.gitlabjenkins.gitlab.api.model.Project projectForName = client.getProject(hook.getProject().getPathWithNamespace());
|
||||||
hook.setProjectId(projectForName.getId());
|
hook.setProjectId(projectForName.getId());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
package com.dabsquared.gitlabjenkins.trigger.handler.push;
|
package com.dabsquared.gitlabjenkins.trigger.handler.push;
|
||||||
|
|
||||||
|
|
||||||
import com.dabsquared.gitlabjenkins.GitLabPushTrigger;
|
import com.dabsquared.gitlabjenkins.GitLabPushTrigger;
|
||||||
import com.dabsquared.gitlabjenkins.cause.CauseData;
|
import com.dabsquared.gitlabjenkins.cause.CauseData;
|
||||||
import com.dabsquared.gitlabjenkins.cause.GitLabWebHookCause;
|
import com.dabsquared.gitlabjenkins.cause.GitLabWebHookCause;
|
||||||
import com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty;
|
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.Branch;
|
||||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.BuildState;
|
import com.dabsquared.gitlabjenkins.gitlab.api.model.BuildState;
|
||||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.MergeRequest;
|
import com.dabsquared.gitlabjenkins.gitlab.api.model.MergeRequest;
|
||||||
|
@ -21,11 +22,9 @@ import hudson.model.CauseAction;
|
||||||
import hudson.model.Job;
|
import hudson.model.Job;
|
||||||
import hudson.plugins.git.RevisionParameterAction;
|
import hudson.plugins.git.RevisionParameterAction;
|
||||||
import hudson.triggers.Trigger;
|
import hudson.triggers.Trigger;
|
||||||
import hudson.triggers.TriggerDescriptor;
|
|
||||||
import jenkins.model.Jenkins;
|
import jenkins.model.Jenkins;
|
||||||
import jenkins.model.ParameterizedJobMixIn;
|
import jenkins.model.ParameterizedJobMixIn;
|
||||||
import jenkins.model.ParameterizedJobMixIn.ParameterizedJob;
|
import jenkins.model.ParameterizedJobMixIn.ParameterizedJob;
|
||||||
|
|
||||||
import org.eclipse.jgit.transport.URIish;
|
import org.eclipse.jgit.transport.URIish;
|
||||||
|
|
||||||
import javax.ws.rs.ProcessingException;
|
import javax.ws.rs.ProcessingException;
|
||||||
|
@ -34,7 +33,6 @@ import java.net.URISyntaxException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
@ -65,7 +63,7 @@ class OpenMergeRequestPushHookTriggerHandler implements PushHookTriggerHandler {
|
||||||
final GitLabPushTrigger trigger = (GitLabPushTrigger) t;
|
final GitLabPushTrigger trigger = (GitLabPushTrigger) t;
|
||||||
Integer projectId = hook.getProjectId();
|
Integer projectId = hook.getProjectId();
|
||||||
if (property != null && property.getClient() != null && projectId != null && trigger != null) {
|
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())) {
|
for (MergeRequest mergeRequest : getOpenMergeRequests(client, projectId.toString())) {
|
||||||
if (mergeRequestLabelFilter.isMergeRequestAllowed(mergeRequest.getLabels())) {
|
if (mergeRequestLabelFilter.isMergeRequestAllowed(mergeRequest.getLabels())) {
|
||||||
handleMergeRequest(job, hook, ciSkip, branchFilter, client, mergeRequest);
|
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<>();
|
List<MergeRequest> result = new ArrayList<>();
|
||||||
Integer page = 1;
|
Integer page = 1;
|
||||||
do {
|
do {
|
||||||
|
@ -94,8 +92,8 @@ class OpenMergeRequestPushHookTriggerHandler implements PushHookTriggerHandler {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleMergeRequest(Job<?, ?> job, PushHook hook, boolean ciSkip, BranchFilter branchFilter, GitLabApi client, MergeRequest mergeRequest) {
|
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]")) {
|
if (ciSkip && mergeRequest.getDescription() != null && mergeRequest.getDescription().contains("[ci-skip]")) {
|
||||||
LOGGER.log(Level.INFO, "Skipping MR " + mergeRequest.getTitle() + " due to ci-skip.");
|
LOGGER.log(Level.INFO, "Skipping MR " + mergeRequest.getTitle() + " due to ci-skip.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -158,7 +156,7 @@ class OpenMergeRequestPushHookTriggerHandler implements PushHookTriggerHandler {
|
||||||
if (job instanceof AbstractProject && ((AbstractProject) job).getPublishersList().get(GitLabCommitStatusPublisher.class) != null) {
|
if (job instanceof AbstractProject && ((AbstractProject) job).getPublishersList().get(GitLabCommitStatusPublisher.class) != null) {
|
||||||
GitLabCommitStatusPublisher publisher =
|
GitLabCommitStatusPublisher publisher =
|
||||||
(GitLabCommitStatusPublisher) ((AbstractProject) job).getPublishersList().get(GitLabCommitStatusPublisher.class);
|
(GitLabCommitStatusPublisher) ((AbstractProject) job).getPublishersList().get(GitLabCommitStatusPublisher.class);
|
||||||
GitLabApi client = job.getProperty(GitLabConnectionProperty.class).getClient();
|
GitLabClient client = job.getProperty(GitLabConnectionProperty.class).getClient();
|
||||||
try {
|
try {
|
||||||
String targetUrl = Jenkins.getInstance().getRootUrl() + job.getUrl() + job.getNextBuildNumber() + "/";
|
String targetUrl = Jenkins.getInstance().getRootUrl() + job.getUrl() + job.getNextBuildNumber() + "/";
|
||||||
client.changeBuildStatus(projectId, commit, BuildState.pending, ref, publisher.getName(), targetUrl, null);
|
client.changeBuildStatus(projectId, commit, BuildState.pending, ref, publisher.getName(), targetUrl, null);
|
||||||
|
|
|
@ -1,28 +1,9 @@
|
||||||
package com.dabsquared.gitlabjenkins.util;
|
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.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 com.dabsquared.gitlabjenkins.gitlab.api.model.BuildState;
|
||||||
|
|
||||||
import hudson.EnvVars;
|
import hudson.EnvVars;
|
||||||
import hudson.model.Run;
|
import hudson.model.Run;
|
||||||
import hudson.model.TaskListener;
|
import hudson.model.TaskListener;
|
||||||
|
@ -33,6 +14,23 @@ import jenkins.model.Jenkins;
|
||||||
import jenkins.plugins.git.AbstractGitSCMSource;
|
import jenkins.plugins.git.AbstractGitSCMSource;
|
||||||
import jenkins.scm.api.SCMRevision;
|
import jenkins.scm.api.SCMRevision;
|
||||||
import jenkins.scm.api.SCMRevisionAction;
|
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
|
* @author Robin Müller
|
||||||
|
@ -42,7 +40,7 @@ public class CommitStatusUpdater {
|
||||||
private final static Logger LOGGER = Logger.getLogger(CommitStatusUpdater.class.getName());
|
private final static Logger LOGGER = Logger.getLogger(CommitStatusUpdater.class.getName());
|
||||||
|
|
||||||
public static void updateCommitStatus(Run<?, ?> build, TaskListener listener, BuildState state, String name) {
|
public static void updateCommitStatus(Run<?, ?> build, TaskListener listener, BuildState state, String name) {
|
||||||
GitLabApi client = getClient(build);
|
GitLabClient client = getClient(build);
|
||||||
if (client == null) {
|
if (client == null) {
|
||||||
println(listener, "No GitLab connection configured");
|
println(listener, "No GitLab connection configured");
|
||||||
return;
|
return;
|
||||||
|
@ -50,7 +48,7 @@ public class CommitStatusUpdater {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final String buildUrl = getBuildUrl(build);
|
final String buildUrl = getBuildUrl(build);
|
||||||
|
|
||||||
for (final GitLabBranchBuild gitLabBranchBuild : retrieveGitlabProjectIds(build, build.getEnvironment(listener))) {
|
for (final GitLabBranchBuild gitLabBranchBuild : retrieveGitlabProjectIds(build, build.getEnvironment(listener))) {
|
||||||
try {
|
try {
|
||||||
if (existsCommit(client, gitLabBranchBuild.getProjectId(), gitLabBranchBuild.getRevisionHash())) {
|
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 {
|
try {
|
||||||
client.getCommit(gitlabProjectId, commitHash);
|
client.getCommit(gitlabProjectId, commitHash);
|
||||||
return true;
|
return true;
|
||||||
|
@ -111,7 +109,7 @@ public class CommitStatusUpdater {
|
||||||
cause.getData().getLastCommit()));
|
cause.getData().getLastCommit()));
|
||||||
}
|
}
|
||||||
|
|
||||||
final GitLabApi gitLabClient = getClient(build);
|
final GitLabClient gitLabClient = getClient(build);
|
||||||
if (gitLabClient == null) {
|
if (gitLabClient == null) {
|
||||||
LOGGER.log(Level.WARNING, "No gitlab client found.");
|
LOGGER.log(Level.WARNING, "No gitlab client found.");
|
||||||
return result;
|
return result;
|
||||||
|
@ -171,8 +169,8 @@ public class CommitStatusUpdater {
|
||||||
return action.getLastBuild(lastBuiltRevision.getSha1()).getMarked().getSha1String();
|
return action.getLastBuild(lastBuiltRevision.getSha1()).getMarked().getSha1String();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void addGitLabBranchBuild(List<GitLabBranchBuild> result, String scmRevisionHash,
|
private static void addGitLabBranchBuild(List<GitLabBranchBuild> result, String scmRevisionHash,
|
||||||
Set<String> remoteUrls, EnvVars environment, GitLabApi gitLabClient) {
|
Set<String> remoteUrls, EnvVars environment, GitLabClient gitLabClient) {
|
||||||
for (String remoteUrl : remoteUrls) {
|
for (String remoteUrl : remoteUrls) {
|
||||||
try {
|
try {
|
||||||
LOGGER.log(Level.INFO, "Retrieving the gitlab project id from remote url {0}", remoteUrl);
|
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();
|
projectId = gitLabClient.getProject(projectNameWithNameSpace).getId().toString();
|
||||||
} catch (WebApplicationException | ProcessingException e) {
|
} catch (WebApplicationException | ProcessingException e) {
|
||||||
LOGGER.log(Level.SEVERE, String.format("Failed to retrieve projectId for project '%s'",
|
LOGGER.log(Level.SEVERE, String.format("Failed to retrieve projectId for project '%s'",
|
||||||
projectNameWithNameSpace), e);
|
projectNameWithNameSpace), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result.add(new GitLabBranchBuild(projectId, scmRevisionHash));
|
result.add(new GitLabBranchBuild(projectId, scmRevisionHash));
|
||||||
|
@ -197,16 +195,16 @@ public class CommitStatusUpdater {
|
||||||
public static class GitLabBranchBuild {
|
public static class GitLabBranchBuild {
|
||||||
private final String projectId;
|
private final String projectId;
|
||||||
private final String revisionHash;
|
private final String revisionHash;
|
||||||
|
|
||||||
public GitLabBranchBuild(final String projectId, final String revisionHash) {
|
public GitLabBranchBuild(final String projectId, final String revisionHash) {
|
||||||
this.projectId = projectId;
|
this.projectId = projectId;
|
||||||
this.revisionHash = revisionHash;
|
this.revisionHash = revisionHash;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getProjectId() {
|
public String getProjectId() {
|
||||||
return this.projectId;
|
return this.projectId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRevisionHash() {
|
public String getRevisionHash() {
|
||||||
return this.revisionHash;
|
return this.revisionHash;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package com.dabsquared.gitlabjenkins.util;
|
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.net.URISyntaxException;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
|
@ -17,10 +17,10 @@ public final class ProjectIdUtil {
|
||||||
|
|
||||||
private ProjectIdUtil() { }
|
private ProjectIdUtil() { }
|
||||||
|
|
||||||
public static String retrieveProjectId(GitLabApi client, String remoteUrl) throws ProjectIdResolutionException {
|
public static String retrieveProjectId(GitLabClient client, String remoteUrl) throws ProjectIdResolutionException {
|
||||||
try {
|
try {
|
||||||
String projectId = null;
|
String baseUri = client.getHostUrl();
|
||||||
String baseUri = client.getGitLabHostUrl();
|
String projectId;
|
||||||
if (baseUri != null && remoteUrl.startsWith(baseUri)) {
|
if (baseUri != null && remoteUrl.startsWith(baseUri)) {
|
||||||
projectId = new URIish(remoteUrl.substring(baseUri.length(), remoteUrl.length())).getPath();
|
projectId = new URIish(remoteUrl.substring(baseUri.length(), remoteUrl.length())).getPath();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package com.dabsquared.gitlabjenkins.workflow;
|
package com.dabsquared.gitlabjenkins.workflow;
|
||||||
|
|
||||||
import com.dabsquared.gitlabjenkins.cause.GitLabWebHookCause;
|
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.Extension;
|
||||||
import hudson.model.Run;
|
import hudson.model.Run;
|
||||||
import hudson.model.TaskListener;
|
import hudson.model.TaskListener;
|
||||||
|
@ -63,7 +63,7 @@ public class AcceptGitLabMergeRequestStep extends AbstractStepImpl {
|
||||||
Integer projectId = cause.getData().getTargetProjectId();
|
Integer projectId = cause.getData().getTargetProjectId();
|
||||||
Integer mergeRequestId = cause.getData().getMergeRequestId();
|
Integer mergeRequestId = cause.getData().getMergeRequestId();
|
||||||
if (projectId != null && mergeRequestId != null) {
|
if (projectId != null && mergeRequestId != null) {
|
||||||
GitLabApi client = getClient(run);
|
GitLabClient client = getClient(run);
|
||||||
if (client == null) {
|
if (client == null) {
|
||||||
println("No GitLab connection configured");
|
println("No GitLab connection configured");
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package com.dabsquared.gitlabjenkins.workflow;
|
package com.dabsquared.gitlabjenkins.workflow;
|
||||||
|
|
||||||
import com.dabsquared.gitlabjenkins.cause.GitLabWebHookCause;
|
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.Extension;
|
||||||
import hudson.model.Run;
|
import hudson.model.Run;
|
||||||
import hudson.model.TaskListener;
|
import hudson.model.TaskListener;
|
||||||
|
@ -63,7 +63,7 @@ public class AddGitLabMergeRequestCommentStep extends AbstractStepImpl {
|
||||||
Integer projectId = cause.getData().getTargetProjectId();
|
Integer projectId = cause.getData().getTargetProjectId();
|
||||||
Integer mergeRequestId = cause.getData().getMergeRequestId();
|
Integer mergeRequestId = cause.getData().getMergeRequestId();
|
||||||
if (projectId != null && mergeRequestId != null) {
|
if (projectId != null && mergeRequestId != null) {
|
||||||
GitLabApi client = getClient(run);
|
GitLabClient client = getClient(run);
|
||||||
if (client == null) {
|
if (client == null) {
|
||||||
println("No GitLab connection configured");
|
println("No GitLab connection configured");
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -18,6 +18,9 @@
|
||||||
<c:select/>
|
<c:select/>
|
||||||
</f:entry>
|
</f:entry>
|
||||||
<f:advanced>
|
<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:entry title="${%Ignore SSL Certificate Errors}" field="ignoreCertificateErrors">
|
||||||
<f:checkbox checked="${connection.ignoreCertificateErrors}"/>
|
<f:checkbox checked="${connection.ignoreCertificateErrors}"/>
|
||||||
</f:entry>
|
</f:entry>
|
||||||
|
@ -30,7 +33,7 @@
|
||||||
<st:include page="configure-advanced.jelly" optional="true" />
|
<st:include page="configure-advanced.jelly" optional="true" />
|
||||||
</f:advanced>
|
</f:advanced>
|
||||||
<f:validateButton title="${%Test Connection}" progress="${%Testing...}" method="testConnection"
|
<f:validateButton title="${%Test Connection}" progress="${%Testing...}" method="testConnection"
|
||||||
with="apiTokenId,url,ignoreCertificateErrors"/>
|
with="apiTokenId,clientBuilderId,url,ignoreCertificateErrors"/>
|
||||||
<f:entry title="">
|
<f:entry title="">
|
||||||
<div align="right">
|
<div align="right">
|
||||||
<f:repeatableDeleteButton/>
|
<f:repeatableDeleteButton/>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.dabsquared.gitlabjenkins.connection;
|
package com.dabsquared.gitlabjenkins.connection;
|
||||||
|
|
||||||
|
|
||||||
import com.cloudbees.plugins.credentials.CredentialsProvider;
|
import com.cloudbees.plugins.credentials.CredentialsProvider;
|
||||||
import com.cloudbees.plugins.credentials.CredentialsScope;
|
import com.cloudbees.plugins.credentials.CredentialsScope;
|
||||||
import com.cloudbees.plugins.credentials.CredentialsStore;
|
import com.cloudbees.plugins.credentials.CredentialsStore;
|
||||||
|
@ -87,7 +88,7 @@ public class GitLabConnectionConfigSSLTest {
|
||||||
public void doCheckConnection_ignoreCertificateErrors() {
|
public void doCheckConnection_ignoreCertificateErrors() {
|
||||||
GitLabConnectionConfig connectionConfig = jenkins.get(GitLabConnectionConfig.class);
|
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()));
|
assertThat(formValidation.getMessage(), is(Messages.connection_success()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,7 +96,7 @@ public class GitLabConnectionConfigSSLTest {
|
||||||
public void doCheckConnection_certificateError() throws IOException {
|
public void doCheckConnection_certificateError() throws IOException {
|
||||||
GitLabConnectionConfig connectionConfig = jenkins.get(GitLabConnectionConfig.class);
|
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("")));
|
assertThat(formValidation.getMessage(), containsString(Messages.connection_error("")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
package com.dabsquared.gitlabjenkins.connection;
|
package com.dabsquared.gitlabjenkins.connection;
|
||||||
|
|
||||||
|
|
||||||
import com.cloudbees.plugins.credentials.CredentialsProvider;
|
import com.cloudbees.plugins.credentials.CredentialsProvider;
|
||||||
import com.cloudbees.plugins.credentials.CredentialsScope;
|
import com.cloudbees.plugins.credentials.CredentialsScope;
|
||||||
import com.cloudbees.plugins.credentials.CredentialsStore;
|
import com.cloudbees.plugins.credentials.CredentialsStore;
|
||||||
import com.cloudbees.plugins.credentials.SystemCredentialsProvider;
|
import com.cloudbees.plugins.credentials.SystemCredentialsProvider;
|
||||||
import com.cloudbees.plugins.credentials.domains.Domain;
|
import com.cloudbees.plugins.credentials.domains.Domain;
|
||||||
import com.dabsquared.gitlabjenkins.GitLabPushTrigger;
|
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.FreeStyleProject;
|
||||||
import hudson.model.Item;
|
import hudson.model.Item;
|
||||||
import hudson.security.GlobalMatrixAuthorizationStrategy;
|
import hudson.security.GlobalMatrixAuthorizationStrategy;
|
||||||
|
@ -33,9 +36,11 @@ import java.io.IOException;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.util.List;
|
|
||||||
import java.util.ArrayList;
|
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.hamcrest.CoreMatchers.is;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
@ -72,28 +77,29 @@ public class GitLabConnectionConfigTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void doCheckConnection_success() {
|
public void doCheckConnection_success() {
|
||||||
HttpRequest request = request().withPath("/gitlab/api/v3/.*").withHeader("PRIVATE-TOKEN", API_TOKEN);
|
String expected = Messages.connection_success();
|
||||||
mockServerClient.when(request).respond(response().withStatusCode(Response.Status.OK.getStatusCode()));
|
assertThat(doCheckConnection("v3", Response.Status.OK), is(expected));
|
||||||
|
assertThat(doCheckConnection("v4", Response.Status.OK), is(expected));
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void doCheckConnection_forbidden() throws IOException {
|
public void doCheckConnection_forbidden() throws IOException {
|
||||||
HttpRequest request = request().withPath("/gitlab/api/v3/.*").withHeader("PRIVATE-TOKEN", API_TOKEN);
|
String expected = Messages.connection_error("HTTP 403 Forbidden");
|
||||||
mockServerClient.when(request).respond(response().withStatusCode(Response.Status.FORBIDDEN.getStatusCode()));
|
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);
|
GitLabConnectionConfig connectionConfig = jenkins.get(GitLabConnectionConfig.class);
|
||||||
FormValidation formValidation = connectionConfig.doTestConnection(gitLabUrl, API_TOKEN_ID, false, 10, 10);
|
FormValidation formValidation = connectionConfig.doTestConnection(gitLabUrl, API_TOKEN_ID, clientBuilderId, false, 10, 10);
|
||||||
|
|
||||||
assertThat(formValidation.getMessage(), is(Messages.connection_error("HTTP 403 Forbidden")));
|
|
||||||
mockServerClient.verify(request);
|
mockServerClient.verify(request);
|
||||||
|
return formValidation.getMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void authenticationEnabled_anonymous_forbidden() throws IOException, URISyntaxException {
|
public void authenticationEnabled_anonymous_forbidden() throws IOException, URISyntaxException {
|
||||||
Boolean defaultValue = jenkins.get(GitLabConnectionConfig.class).isUseAuthenticatedEndpoint();
|
Boolean defaultValue = jenkins.get(GitLabConnectionConfig.class).isUseAuthenticatedEndpoint();
|
||||||
|
@ -155,8 +161,8 @@ public class GitLabConnectionConfigTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void setConnectionsTest() {
|
public void setConnectionsTest() {
|
||||||
GitLabConnection connection1 = new GitLabConnection("1", "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, false, 10, 10);
|
GitLabConnection connection2 = new GitLabConnection("2", "http://localhost", null, new V3GitLabClientBuilder(), false, 10, 10);
|
||||||
GitLabConnectionConfig config = jenkins.get(GitLabConnectionConfig.class);
|
GitLabConnectionConfig config = jenkins.get(GitLabConnectionConfig.class);
|
||||||
List<GitLabConnection> connectionList1 = new ArrayList<>();
|
List<GitLabConnection> connectionList1 = new ArrayList<>();
|
||||||
connectionList1.add(connection1);
|
connectionList1.add(connection1);
|
||||||
|
@ -166,7 +172,7 @@ public class GitLabConnectionConfigTest {
|
||||||
|
|
||||||
List<GitLabConnection> connectionList2 = new ArrayList<>();
|
List<GitLabConnection> connectionList2 = new ArrayList<>();
|
||||||
connectionList2.add(connection1);
|
connectionList2.add(connection1);
|
||||||
connectionList2.add(connection1);
|
connectionList2.add(connection2);
|
||||||
|
|
||||||
config.setConnections(connectionList2);
|
config.setConnections(connectionList2);
|
||||||
assertThat(config.getConnections(), is(connectionList2));
|
assertThat(config.getConnections(), is(connectionList2));
|
||||||
|
@ -174,4 +180,17 @@ public class GitLabConnectionConfigTest {
|
||||||
config.setConnections(connectionList1);
|
config.setConnections(connectionList1);
|
||||||
assertThat(config.getConnections(), is(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;
|
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.AbstractBuild;
|
||||||
import hudson.model.AbstractProject;
|
|
||||||
import hudson.model.BuildListener;
|
import hudson.model.BuildListener;
|
||||||
import hudson.model.Result;
|
import hudson.model.Result;
|
||||||
import hudson.model.StreamBuildListener;
|
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.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
|
@ -34,16 +18,16 @@ import org.mockserver.model.HttpRequest;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.nio.charset.Charset;
|
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.doReturn;
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.spy;
|
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.HttpRequest.request;
|
||||||
import static org.mockserver.model.HttpResponse.response;
|
import static org.mockserver.model.HttpResponse.response;
|
||||||
|
|
||||||
|
@ -51,10 +35,6 @@ import static org.mockserver.model.HttpResponse.response;
|
||||||
* @author Nikolay Ustinov
|
* @author Nikolay Ustinov
|
||||||
*/
|
*/
|
||||||
public class GitLabAcceptMergeRequestPublisherTest {
|
public class GitLabAcceptMergeRequestPublisherTest {
|
||||||
|
|
||||||
private static final String GIT_LAB_CONNECTION = "GitLab";
|
|
||||||
private static final String API_TOKEN = "secret";
|
|
||||||
|
|
||||||
@ClassRule
|
@ClassRule
|
||||||
public static MockServerRule mockServer = new MockServerRule(new Object());
|
public static MockServerRule mockServer = new MockServerRule(new Object());
|
||||||
|
|
||||||
|
@ -65,17 +45,8 @@ public class GitLabAcceptMergeRequestPublisherTest {
|
||||||
private BuildListener listener;
|
private BuildListener listener;
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void setupConnection() throws IOException {
|
public static void setupClass() throws IOException {
|
||||||
GitLabConnectionConfig connectionConfig = jenkins.get(GitLabConnectionConfig.class);
|
setupGitLabConnections(jenkins, mockServer);
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
|
@ -90,84 +61,46 @@ public class GitLabAcceptMergeRequestPublisherTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void matrixAggregatable() throws UnsupportedEncodingException, InterruptedException, IOException {
|
public void matrixAggregatable() throws InterruptedException, IOException {
|
||||||
AbstractBuild build = mock(AbstractBuild.class);
|
verifyMatrixAggregatable(GitLabAcceptMergeRequestPublisher.class, listener);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void success() throws IOException, InterruptedException {
|
public void success() throws IOException, InterruptedException {
|
||||||
Integer buildNumber = 1;
|
publish(mockSimpleBuild(GITLAB_CONNECTION_V3, Result.SUCCESS));
|
||||||
Integer projectId = 3;
|
publish(mockSimpleBuild(GITLAB_CONNECTION_V4, Result.SUCCESS));
|
||||||
Integer mergeRequestId = 1;
|
|
||||||
AbstractBuild build = mockBuild("/build/123", GIT_LAB_CONNECTION, Result.SUCCESS, buildNumber);
|
|
||||||
|
|
||||||
HttpRequest[] requests = new HttpRequest[] {
|
mockServerClient.verify(
|
||||||
prepareAcceptMergeRequestWithSuccessResponse(projectId, mergeRequestId)
|
prepareAcceptMergeRequestWithSuccessResponse("v3"),
|
||||||
};
|
prepareAcceptMergeRequestWithSuccessResponse("v4"));
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void failed() throws IOException, InterruptedException {
|
public void failed() throws IOException, InterruptedException {
|
||||||
Integer buildNumber = 1;
|
publish(mockSimpleBuild(GITLAB_CONNECTION_V3, Result.FAILURE));
|
||||||
Integer projectId = 3;
|
publish(mockSimpleBuild(GITLAB_CONNECTION_V4, Result.FAILURE));
|
||||||
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);
|
|
||||||
|
|
||||||
mockServerClient.verifyZeroInteractions();
|
mockServerClient.verifyZeroInteractions();
|
||||||
}
|
}
|
||||||
|
|
||||||
private HttpRequest prepareAcceptMergeRequestWithSuccessResponse(Integer projectId, Integer mergeRequestId) throws UnsupportedEncodingException {
|
private void publish(AbstractBuild build) throws InterruptedException, IOException {
|
||||||
HttpRequest updateCommitStatus = prepareAcceptMergeRequest(projectId, mergeRequestId);
|
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));
|
mockServerClient.when(updateCommitStatus).respond(response().withStatusCode(200));
|
||||||
return updateCommitStatus;
|
return updateCommitStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
private HttpRequest prepareAcceptMergeRequest(Integer projectId, Integer mergeRequestId) throws UnsupportedEncodingException {
|
private HttpRequest prepareAcceptMergeRequest(String apiLevel) throws UnsupportedEncodingException {
|
||||||
return request()
|
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")
|
.withMethod("PUT")
|
||||||
.withHeader("PRIVATE-TOKEN", "secret")
|
.withHeader("PRIVATE-TOKEN", "secret")
|
||||||
.withBody("merge_commit_message=Merge+Request+accepted+by+jenkins+build+success&should_remove_source_branch=false");
|
.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;
|
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.apache.commons.io.IOUtils;
|
||||||
import org.eclipse.jgit.lib.ObjectId;
|
import org.eclipse.jgit.lib.ObjectId;
|
||||||
import org.hamcrest.CoreMatchers;
|
import org.hamcrest.CoreMatchers;
|
||||||
import org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl;
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
|
@ -40,42 +32,37 @@ import org.mockserver.model.HttpRequest;
|
||||||
import org.mockserver.model.HttpResponse;
|
import org.mockserver.model.HttpResponse;
|
||||||
import org.mockserver.verify.VerificationTimes;
|
import org.mockserver.verify.VerificationTimes;
|
||||||
|
|
||||||
import com.cloudbees.plugins.credentials.CredentialsProvider;
|
import java.io.ByteArrayOutputStream;
|
||||||
import com.cloudbees.plugins.credentials.CredentialsScope;
|
import java.io.IOException;
|
||||||
import com.cloudbees.plugins.credentials.CredentialsStore;
|
import java.io.PrintStream;
|
||||||
import com.cloudbees.plugins.credentials.SystemCredentialsProvider;
|
import java.io.UnsupportedEncodingException;
|
||||||
import com.cloudbees.plugins.credentials.domains.Domain;
|
import java.net.URLEncoder;
|
||||||
import com.dabsquared.gitlabjenkins.connection.GitLabConnection;
|
import java.nio.charset.Charset;
|
||||||
import com.dabsquared.gitlabjenkins.connection.GitLabConnectionConfig;
|
import java.util.ArrayList;
|
||||||
import com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty;
|
import java.util.Arrays;
|
||||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.BuildState;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import hudson.EnvVars;
|
import static com.dabsquared.gitlabjenkins.publisher.TestUtility.BUILD_URL;
|
||||||
import hudson.Launcher;
|
import static com.dabsquared.gitlabjenkins.publisher.TestUtility.GITLAB_CONNECTION_V3;
|
||||||
import hudson.matrix.MatrixAggregator;
|
import static com.dabsquared.gitlabjenkins.publisher.TestUtility.GITLAB_CONNECTION_V4;
|
||||||
import hudson.matrix.MatrixConfiguration;
|
import static com.dabsquared.gitlabjenkins.publisher.TestUtility.PROJECT_ID;
|
||||||
import hudson.matrix.MatrixBuild;
|
import static com.dabsquared.gitlabjenkins.publisher.TestUtility.setupGitLabConnections;
|
||||||
import hudson.model.AbstractBuild;
|
import static com.dabsquared.gitlabjenkins.publisher.TestUtility.verifyMatrixAggregatable;
|
||||||
import hudson.model.AbstractProject;
|
import static org.junit.Assert.assertThat;
|
||||||
import hudson.model.BuildListener;
|
import static org.mockito.Matchers.any;
|
||||||
import hudson.model.Result;
|
import static org.mockito.Matchers.anyString;
|
||||||
import hudson.model.StreamBuildListener;
|
import static org.mockito.Mockito.mock;
|
||||||
import hudson.model.TaskListener;
|
import static org.mockito.Mockito.when;
|
||||||
import hudson.plugins.git.Revision;
|
import static org.mockserver.model.HttpRequest.request;
|
||||||
import hudson.plugins.git.util.Build;
|
import static org.mockserver.model.HttpResponse.response;
|
||||||
import hudson.plugins.git.util.BuildData;
|
|
||||||
import hudson.util.Secret;
|
|
||||||
import jenkins.model.Jenkins;
|
|
||||||
import jenkins.plugins.git.AbstractGitSCMSource;
|
|
||||||
import jenkins.scm.api.SCMRevisionAction;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Robin Müller
|
* @author Robin Müller
|
||||||
*/
|
*/
|
||||||
public class GitLabCommitStatusPublisherTest {
|
public class GitLabCommitStatusPublisherTest {
|
||||||
|
|
||||||
private static final String GIT_LAB_CONNECTION = "GitLab";
|
|
||||||
private static final String API_TOKEN = "secret";
|
|
||||||
private static final String SHA1 = "0616d12a3a24068691027a1e113147e3c1cfa2f4";
|
private static final String SHA1 = "0616d12a3a24068691027a1e113147e3c1cfa2f4";
|
||||||
|
|
||||||
@ClassRule
|
@ClassRule
|
||||||
|
@ -88,17 +75,8 @@ public class GitLabCommitStatusPublisherTest {
|
||||||
private BuildListener listener;
|
private BuildListener listener;
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void setupConnection() throws IOException {
|
public static void setupClass() throws IOException {
|
||||||
GitLabConnectionConfig connectionConfig = jenkins.get(GitLabConnectionConfig.class);
|
setupGitLabConnections(jenkins, mockServer);
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
|
@ -113,283 +91,247 @@ public class GitLabCommitStatusPublisherTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void matrixAggregatable() throws UnsupportedEncodingException, InterruptedException, IOException {
|
public void matrixAggregatable() throws InterruptedException, IOException {
|
||||||
AbstractBuild build = mock(AbstractBuild.class);
|
verifyMatrixAggregatable(GitLabCommitStatusPublisher.class, listener);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void running() throws UnsupportedEncodingException {
|
public void running_v3() throws UnsupportedEncodingException {
|
||||||
HttpRequest[] requests = new HttpRequest[] {
|
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V3, null, "test/project.git");
|
||||||
prepareExistsCommitWithSuccessResponse("test/project", SHA1),
|
HttpRequest[] requests = prepareCheckCommitAndUpdateStatusRequests("v3", BuildState.running);
|
||||||
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);
|
prebuildAndVerify(build, listener, requests);
|
||||||
publisher.prebuild(build, listener);
|
|
||||||
|
|
||||||
mockServerClient.verify(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
|
@Test
|
||||||
public void runningWithLibrary() throws UnsupportedEncodingException {
|
public void runningWithLibrary() throws UnsupportedEncodingException {
|
||||||
HttpRequest[] requests = new HttpRequest[] {
|
AbstractBuild build = mockBuildWithLibrary(GITLAB_CONNECTION_V4, null, "test/project.git");
|
||||||
prepareExistsCommitWithSuccessResponse("test/project", SHA1),
|
HttpRequest[] requests = prepareCheckCommitAndUpdateStatusRequests("v4", BuildState.running);
|
||||||
prepareUpdateCommitStatusWithSuccessResponse("test/project", SHA1, jenkins.getInstance().getRootUrl() + "/build/123", BuildState.running)
|
|
||||||
};
|
|
||||||
AbstractBuild build = mockBuildWithLibrary(SHA1, "/build/123", GIT_LAB_CONNECTION, null, "test/project.git");
|
|
||||||
|
|
||||||
GitLabCommitStatusPublisher publisher = new GitLabCommitStatusPublisher("jenkins", false);
|
prebuildAndVerify(build, listener, requests);
|
||||||
publisher.prebuild(build, listener);
|
|
||||||
|
|
||||||
mockServerClient.verify(requests);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void runningWithDotInProjectId() throws IOException {
|
public void runningWithDotInProjectId() throws IOException {
|
||||||
|
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V4, null, "test/project.test.git");
|
||||||
HttpRequest[] requests = new HttpRequest[] {
|
HttpRequest[] requests = new HttpRequest[] {
|
||||||
prepareGetProjectResponse("test/project.test",1),
|
prepareGetProjectResponse("test/project.test"),
|
||||||
prepareExistsCommitWithSuccessResponse("1", SHA1),
|
prepareExistsCommitWithSuccessResponse("v4", String.valueOf(PROJECT_ID)),
|
||||||
prepareUpdateCommitStatusWithSuccessResponse("1", SHA1, jenkins.getInstance().getRootUrl() + "/build/123", BuildState.running)
|
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);
|
prebuildAndVerify(build, listener, requests);
|
||||||
publisher.prebuild(build, listener);
|
|
||||||
|
|
||||||
mockServerClient.verify(requests);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void canceled() throws IOException, InterruptedException {
|
public void canceled_v3() throws IOException, InterruptedException {
|
||||||
HttpRequest[] requests = new HttpRequest[] {
|
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V3, Result.ABORTED, "test/project.git");
|
||||||
prepareExistsCommitWithSuccessResponse("test/project", SHA1),
|
HttpRequest[] requests = prepareCheckCommitAndUpdateStatusRequests("v3", BuildState.canceled);
|
||||||
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");
|
|
||||||
|
|
||||||
GitLabCommitStatusPublisher publisher = new GitLabCommitStatusPublisher("jenkins", false);
|
performAndVerify(build, false, requests);
|
||||||
publisher.perform(build, null, listener);
|
}
|
||||||
|
|
||||||
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
|
@Test
|
||||||
public void canceledWithLibrary() throws IOException, InterruptedException {
|
public void canceledWithLibrary() throws IOException, InterruptedException {
|
||||||
HttpRequest[] requests = new HttpRequest[] {
|
AbstractBuild build = mockBuildWithLibrary(GITLAB_CONNECTION_V4, Result.ABORTED, "test/project.git");
|
||||||
prepareExistsCommitWithSuccessResponse("test/project", SHA1),
|
HttpRequest[] requests = prepareCheckCommitAndUpdateStatusRequests("v4", BuildState.canceled);
|
||||||
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");
|
|
||||||
|
|
||||||
GitLabCommitStatusPublisher publisher = new GitLabCommitStatusPublisher("jenkins", false);
|
performAndVerify(build, false, requests);
|
||||||
publisher.perform(build, null, listener);
|
|
||||||
|
|
||||||
mockServerClient.verify(requests);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void success() throws IOException, InterruptedException {
|
public void success_v3() throws IOException, InterruptedException {
|
||||||
HttpRequest[] requests = new HttpRequest[] {
|
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V3, Result.SUCCESS, "test/project.git");
|
||||||
prepareExistsCommitWithSuccessResponse("test/project", SHA1),
|
HttpRequest[] requests = prepareCheckCommitAndUpdateStatusRequests("v3", BuildState.success);
|
||||||
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");
|
|
||||||
|
|
||||||
GitLabCommitStatusPublisher publisher = new GitLabCommitStatusPublisher("jenkins", false);
|
performAndVerify(build, false, requests);
|
||||||
publisher.perform(build, null, listener);
|
}
|
||||||
|
|
||||||
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
|
@Test
|
||||||
public void successWithLibrary() throws IOException, InterruptedException {
|
public void successWithLibrary() throws IOException, InterruptedException {
|
||||||
HttpRequest[] requests = new HttpRequest[] {
|
AbstractBuild build = mockBuildWithLibrary(GITLAB_CONNECTION_V4, Result.SUCCESS, "test/project.git");
|
||||||
prepareExistsCommitWithSuccessResponse("test/project", SHA1),
|
HttpRequest[] requests = prepareCheckCommitAndUpdateStatusRequests("v4", BuildState.success);
|
||||||
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");
|
|
||||||
|
|
||||||
GitLabCommitStatusPublisher publisher = new GitLabCommitStatusPublisher("jenkins", false);
|
performAndVerify(build, false, requests);
|
||||||
publisher.perform(build, null, listener);
|
|
||||||
|
|
||||||
mockServerClient.verify(requests);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void failed() throws IOException, InterruptedException {
|
public void failed_v3() throws IOException, InterruptedException {
|
||||||
HttpRequest[] requests = new HttpRequest[] {
|
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V3, Result.FAILURE, "test/project.git");
|
||||||
prepareExistsCommitWithSuccessResponse("test/project", SHA1),
|
HttpRequest[] requests = prepareCheckCommitAndUpdateStatusRequests("v3", BuildState.failed);
|
||||||
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");
|
|
||||||
|
|
||||||
GitLabCommitStatusPublisher publisher = new GitLabCommitStatusPublisher("jenkins", false);
|
performAndVerify(build, false, requests);
|
||||||
publisher.perform(build, null, listener);
|
}
|
||||||
|
|
||||||
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
|
@Test
|
||||||
public void failedWithLibrary() throws IOException, InterruptedException {
|
public void failedWithLibrary() throws IOException, InterruptedException {
|
||||||
HttpRequest[] requests = new HttpRequest[] {
|
AbstractBuild build = mockBuildWithLibrary(GITLAB_CONNECTION_V4, Result.FAILURE, "test/project.git");
|
||||||
prepareExistsCommitWithSuccessResponse("test/project", SHA1),
|
HttpRequest[] requests = prepareCheckCommitAndUpdateStatusRequests("v4", BuildState.failed);
|
||||||
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");
|
|
||||||
|
|
||||||
GitLabCommitStatusPublisher publisher = new GitLabCommitStatusPublisher("jenkins", false);
|
performAndVerify(build, false, requests);
|
||||||
publisher.perform(build, null, listener);
|
|
||||||
|
|
||||||
mockServerClient.verify(requests);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void unstable() throws IOException, InterruptedException {
|
public void unstable() throws IOException, InterruptedException {
|
||||||
HttpRequest[] requests = new HttpRequest[] {
|
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V4, Result.UNSTABLE, "test/project.git");
|
||||||
prepareExistsCommitWithSuccessResponse("test/project", SHA1),
|
HttpRequest[] requests = prepareCheckCommitAndUpdateStatusRequests("v4", BuildState.failed);
|
||||||
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");
|
|
||||||
|
|
||||||
GitLabCommitStatusPublisher publisher = new GitLabCommitStatusPublisher("jenkins", false);
|
performAndVerify(build, false, requests);
|
||||||
publisher.perform(build, null, listener);
|
|
||||||
|
|
||||||
mockServerClient.verify(requests);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void unstableWithLibrary() throws IOException, InterruptedException {
|
public void unstableWithLibrary() throws IOException, InterruptedException {
|
||||||
HttpRequest[] requests = new HttpRequest[] {
|
AbstractBuild build = mockBuildWithLibrary(GITLAB_CONNECTION_V4, Result.UNSTABLE, "test/project.git");
|
||||||
prepareExistsCommitWithSuccessResponse("test/project", SHA1),
|
HttpRequest[] requests = prepareCheckCommitAndUpdateStatusRequests("v4", BuildState.failed);
|
||||||
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");
|
|
||||||
|
|
||||||
GitLabCommitStatusPublisher publisher = new GitLabCommitStatusPublisher("jenkins", false);
|
performAndVerify(build, false, requests);
|
||||||
publisher.perform(build, null, listener);
|
|
||||||
|
|
||||||
mockServerClient.verify(requests);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void unstableAsSuccess() throws IOException, InterruptedException {
|
public void unstableAsSuccess() throws IOException, InterruptedException {
|
||||||
HttpRequest[] requests = new HttpRequest[] {
|
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V4, Result.UNSTABLE, "test/project.git");
|
||||||
prepareExistsCommitWithSuccessResponse("test/project", SHA1),
|
HttpRequest[] requests = prepareCheckCommitAndUpdateStatusRequests("v4", BuildState.success);
|
||||||
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");
|
|
||||||
|
|
||||||
GitLabCommitStatusPublisher publisher = new GitLabCommitStatusPublisher("jenkins", true);
|
performAndVerify(build, true, requests);
|
||||||
publisher.perform(build, null, listener);
|
|
||||||
|
|
||||||
mockServerClient.verify(requests);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void running_multipleRepos() throws UnsupportedEncodingException {
|
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[] {
|
HttpRequest[] requests = new HttpRequest[] {
|
||||||
prepareExistsCommitWithSuccessResponse("test/project-1", SHA1),
|
prepareExistsCommitWithSuccessResponse("v4", "test/project-1"),
|
||||||
prepareUpdateCommitStatusWithSuccessResponse("test/project-1", SHA1, jenkins.getInstance().getRootUrl() + "/build/123", BuildState.running),
|
prepareUpdateCommitStatusWithSuccessResponse("v4", "test/project-1", BuildState.running),
|
||||||
prepareExistsCommitWithSuccessResponse("test/project-2", SHA1),
|
prepareExistsCommitWithSuccessResponse("v4", "test/project-2"),
|
||||||
prepareUpdateCommitStatusWithSuccessResponse("test/project-2", SHA1, jenkins.getInstance().getRootUrl() + "/build/123", BuildState.running)
|
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);
|
prebuildAndVerify(build, listener, requests);
|
||||||
publisher.prebuild(build, listener);
|
|
||||||
|
|
||||||
mockServerClient.verify(requests);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void running_commitNotExists() throws UnsupportedEncodingException {
|
public void running_commitNotExists() throws UnsupportedEncodingException {
|
||||||
HttpRequest updateCommitStatus = prepareUpdateCommitStatusWithSuccessResponse("test/project", SHA1, jenkins.getInstance().getRootUrl() + "/build/123", BuildState.running);
|
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V4, null, "test/project.git");
|
||||||
AbstractBuild build = mockBuild(SHA1, "/build/123", GIT_LAB_CONNECTION, null, "test/project.git");
|
HttpRequest updateCommitStatus = prepareUpdateCommitStatusWithSuccessResponse("v4", "test/project", BuildState.running);
|
||||||
|
|
||||||
GitLabCommitStatusPublisher publisher = new GitLabCommitStatusPublisher("jenkins", false);
|
|
||||||
publisher.prebuild(build, listener);
|
|
||||||
|
|
||||||
|
new GitLabCommitStatusPublisher("jenkins", false).prebuild(build, listener);
|
||||||
mockServerClient.verify(updateCommitStatus, VerificationTimes.exactly(0));
|
mockServerClient.verify(updateCommitStatus, VerificationTimes.exactly(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void running_failToUpdate() throws UnsupportedEncodingException {
|
public void running_failToUpdate() throws UnsupportedEncodingException {
|
||||||
prepareExistsCommitWithSuccessResponse("test/project", SHA1);
|
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V4, null, "test/project.git");
|
||||||
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");
|
|
||||||
BuildListener buildListener = mock(BuildListener.class);
|
BuildListener buildListener = mock(BuildListener.class);
|
||||||
|
|
||||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||||
when(buildListener.getLogger()).thenReturn(new PrintStream(outputStream));
|
when(buildListener.getLogger()).thenReturn(new PrintStream(outputStream));
|
||||||
|
|
||||||
GitLabCommitStatusPublisher publisher = new GitLabCommitStatusPublisher("jenkins", false);
|
prepareExistsCommitWithSuccessResponse("v4", "test/project");
|
||||||
publisher.prebuild(build, buildListener);
|
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"));
|
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 {
|
private void performAndVerify(AbstractBuild build, boolean markUnstableAsSuccess, HttpRequest... requests) throws InterruptedException, IOException {
|
||||||
HttpRequest updateCommitStatus = prepareUpdateCommitStatus(projectId, sha, targetUrl, state);
|
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));
|
mockServerClient.when(updateCommitStatus).respond(response().withStatusCode(200));
|
||||||
return updateCommitStatus;
|
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()
|
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")
|
.withMethod("POST")
|
||||||
.withHeader("PRIVATE-TOKEN", "secret")
|
.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 {
|
private HttpRequest prepareExistsCommitWithSuccessResponse(String apiLevel, String projectName) throws UnsupportedEncodingException {
|
||||||
HttpRequest existsCommit = prepareExistsCommit(projectId, sha);
|
HttpRequest existsCommit = prepareExistsCommit(apiLevel, projectName);
|
||||||
mockServerClient.when(existsCommit).respond(response().withStatusCode(200));
|
mockServerClient.when(existsCommit).respond(response().withStatusCode(200));
|
||||||
return existsCommit;
|
return existsCommit;
|
||||||
}
|
}
|
||||||
|
|
||||||
private HttpRequest prepareExistsCommit(String projectId, String sha) throws UnsupportedEncodingException {
|
private HttpRequest prepareExistsCommit(String apiLevel, String projectName) throws UnsupportedEncodingException {
|
||||||
return request()
|
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")
|
.withMethod("GET")
|
||||||
.withHeader("PRIVATE-TOKEN", "secret");
|
.withHeader("PRIVATE-TOKEN", "secret");
|
||||||
}
|
}
|
||||||
|
|
||||||
private HttpRequest prepareGetProjectResponse(String projectName, int projectId) throws IOException {
|
private HttpRequest prepareGetProjectResponse(String projectName) throws IOException {
|
||||||
HttpRequest request= request()
|
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")
|
.withMethod("GET")
|
||||||
. withHeader("PRIVATE-TOKEN", "secret");
|
. 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");
|
response.withHeader("Content-Type", "application/json");
|
||||||
mockServerClient.when(request).respond(response.withStatusCode(200));
|
mockServerClient.when(request).respond(response.withStatusCode(200));
|
||||||
return request;
|
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);
|
AbstractBuild build = mock(AbstractBuild.class);
|
||||||
List<BuildData> buildDatas = new ArrayList<BuildData>();
|
List<BuildData> buildDatas = new ArrayList<>();
|
||||||
BuildData buildData = mock(BuildData.class);
|
BuildData buildData = mock(BuildData.class);
|
||||||
Revision revision = mock(Revision.class);
|
Revision revision = mock(Revision.class);
|
||||||
when(revision.getSha1String()).thenReturn(sha);
|
when(revision.getSha1String()).thenReturn(SHA1);
|
||||||
when(buildData.getLastBuiltRevision()).thenReturn(revision);
|
when(buildData.getLastBuiltRevision()).thenReturn(revision);
|
||||||
when(buildData.getRemoteUrls()).thenReturn(new HashSet<>(Arrays.asList(remoteUrls)));
|
when(buildData.getRemoteUrls()).thenReturn(new HashSet<>(Arrays.asList(remoteUrls)));
|
||||||
Build gitBuild = mock(Build.class);
|
Build gitBuild = mock(Build.class);
|
||||||
|
@ -399,7 +341,7 @@ public class GitLabCommitStatusPublisherTest {
|
||||||
when(build.getActions(BuildData.class)).thenReturn(buildDatas);
|
when(build.getActions(BuildData.class)).thenReturn(buildDatas);
|
||||||
when(build.getAction(BuildData.class)).thenReturn(buildData);
|
when(build.getAction(BuildData.class)).thenReturn(buildData);
|
||||||
when(build.getResult()).thenReturn(result);
|
when(build.getResult()).thenReturn(result);
|
||||||
when(build.getUrl()).thenReturn(buildUrl);
|
when(build.getUrl()).thenReturn(BUILD_URL);
|
||||||
AbstractProject<?, ?> project = mock(AbstractProject.class);
|
AbstractProject<?, ?> project = mock(AbstractProject.class);
|
||||||
when(project.getProperty(GitLabConnectionProperty.class)).thenReturn(new GitLabConnectionProperty(gitLabConnection));
|
when(project.getProperty(GitLabConnectionProperty.class)).thenReturn(new GitLabConnectionProperty(gitLabConnection));
|
||||||
when(build.getProject()).thenReturn(project);
|
when(build.getProject()).thenReturn(project);
|
||||||
|
@ -418,26 +360,26 @@ public class GitLabCommitStatusPublisherTest {
|
||||||
return build;
|
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);
|
AbstractBuild build = mock(AbstractBuild.class);
|
||||||
List<BuildData> buildDatas = new ArrayList<BuildData>();
|
List<BuildData> buildDatas = new ArrayList<>();
|
||||||
BuildData buildData = mock(BuildData.class);
|
BuildData buildData = mock(BuildData.class);
|
||||||
SCMRevisionAction scmRevisionAction = mock(SCMRevisionAction.class);
|
SCMRevisionAction scmRevisionAction = mock(SCMRevisionAction.class);
|
||||||
AbstractGitSCMSource.SCMRevisionImpl revisionImpl = mock(AbstractGitSCMSource.SCMRevisionImpl.class);
|
AbstractGitSCMSource.SCMRevisionImpl revisionImpl = mock(AbstractGitSCMSource.SCMRevisionImpl.class);
|
||||||
|
|
||||||
when(build.getAction(SCMRevisionAction.class)).thenReturn(scmRevisionAction);
|
when(build.getAction(SCMRevisionAction.class)).thenReturn(scmRevisionAction);
|
||||||
when(scmRevisionAction.getRevision()).thenReturn(revisionImpl);
|
when(scmRevisionAction.getRevision()).thenReturn(revisionImpl);
|
||||||
when(revisionImpl.getHash()).thenReturn(sha);
|
when(revisionImpl.getHash()).thenReturn(SHA1);
|
||||||
|
|
||||||
Revision revision = mock(Revision.class);
|
Revision revision = mock(Revision.class);
|
||||||
when(revision.getSha1String()).thenReturn(sha);
|
when(revision.getSha1String()).thenReturn(SHA1);
|
||||||
when(buildData.getLastBuiltRevision()).thenReturn(revision);
|
when(buildData.getLastBuiltRevision()).thenReturn(revision);
|
||||||
when(buildData.getRemoteUrls()).thenReturn(new HashSet<>(Arrays.asList(remoteUrls)));
|
when(buildData.getRemoteUrls()).thenReturn(new HashSet<>(Arrays.asList(remoteUrls)));
|
||||||
|
|
||||||
Build gitBuild = mock(Build.class);
|
Build gitBuild = mock(Build.class);
|
||||||
|
|
||||||
when(gitBuild.getMarked()).thenReturn(revision);
|
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);
|
when(buildData.getLastBuild(any(ObjectId.class))).thenReturn(gitBuild);
|
||||||
Map<String, Build> buildsByBranchName = new HashMap<>();
|
Map<String, Build> buildsByBranchName = new HashMap<>();
|
||||||
buildsByBranchName.put("develop", gitBuild);
|
buildsByBranchName.put("develop", gitBuild);
|
||||||
|
@ -456,7 +398,7 @@ public class GitLabCommitStatusPublisherTest {
|
||||||
|
|
||||||
when(build.getActions(BuildData.class)).thenReturn(buildDatas);
|
when(build.getActions(BuildData.class)).thenReturn(buildDatas);
|
||||||
when(build.getResult()).thenReturn(result);
|
when(build.getResult()).thenReturn(result);
|
||||||
when(build.getUrl()).thenReturn(buildUrl);
|
when(build.getUrl()).thenReturn(BUILD_URL);
|
||||||
|
|
||||||
AbstractProject<?, ?> project = mock(AbstractProject.class);
|
AbstractProject<?, ?> project = mock(AbstractProject.class);
|
||||||
when(project.getProperty(GitLabConnectionProperty.class)).thenReturn(new GitLabConnectionProperty(gitLabConnection));
|
when(project.getProperty(GitLabConnectionProperty.class)).thenReturn(new GitLabConnectionProperty(gitLabConnection));
|
||||||
|
|
|
@ -1,18 +1,8 @@
|
||||||
package com.dabsquared.gitlabjenkins.publisher;
|
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.connection.GitLabConnectionProperty;
|
||||||
import hudson.EnvVars;
|
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.AbstractBuild;
|
||||||
import hudson.model.AbstractProject;
|
import hudson.model.AbstractProject;
|
||||||
import hudson.model.BuildListener;
|
import hudson.model.BuildListener;
|
||||||
|
@ -20,9 +10,6 @@ import hudson.model.Result;
|
||||||
import hudson.model.StreamBuildListener;
|
import hudson.model.StreamBuildListener;
|
||||||
import hudson.model.TaskListener;
|
import hudson.model.TaskListener;
|
||||||
import hudson.plugins.git.util.BuildData;
|
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.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
|
@ -39,17 +26,23 @@ import java.io.IOException;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.text.MessageFormat;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
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.any;
|
||||||
import static org.mockito.Matchers.anyString;
|
import static org.mockito.Matchers.anyString;
|
||||||
import static org.mockito.Mockito.doReturn;
|
import static org.mockito.Mockito.doReturn;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
import static org.mockserver.model.HttpRequest.request;
|
import static org.mockserver.model.HttpRequest.request;
|
||||||
import static org.mockserver.model.HttpResponse.response;
|
import static org.mockserver.model.HttpResponse.response;
|
||||||
|
@ -58,10 +51,6 @@ import static org.mockserver.model.HttpResponse.response;
|
||||||
* @author Nikolay Ustinov
|
* @author Nikolay Ustinov
|
||||||
*/
|
*/
|
||||||
public class GitLabMessagePublisherTest {
|
public class GitLabMessagePublisherTest {
|
||||||
|
|
||||||
private static final String GIT_LAB_CONNECTION = "GitLab";
|
|
||||||
private static final String API_TOKEN = "secret";
|
|
||||||
|
|
||||||
@ClassRule
|
@ClassRule
|
||||||
public static MockServerRule mockServer = new MockServerRule(new Object());
|
public static MockServerRule mockServer = new MockServerRule(new Object());
|
||||||
|
|
||||||
|
@ -72,17 +61,8 @@ public class GitLabMessagePublisherTest {
|
||||||
private BuildListener listener;
|
private BuildListener listener;
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void setupConnection() throws IOException {
|
public static void setupClass() throws IOException {
|
||||||
GitLabConnectionConfig connectionConfig = jenkins.get(GitLabConnectionConfig.class);
|
setupGitLabConnections(jenkins, mockServer);
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
|
@ -97,229 +77,170 @@ public class GitLabMessagePublisherTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void canceled() throws IOException, InterruptedException {
|
public void matrixAggregatable() throws InterruptedException, IOException {
|
||||||
Integer buildNumber = 1;
|
verifyMatrixAggregatable(GitLabMessagePublisher.class, listener);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void matrixAggregatable() throws UnsupportedEncodingException, InterruptedException, IOException {
|
public void canceled_v3() throws IOException, InterruptedException {
|
||||||
AbstractBuild build = mock(AbstractBuild.class);
|
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V3, Result.ABORTED);
|
||||||
AbstractProject project = mock(MatrixConfiguration.class);
|
String defaultNote = formatNote(build, ":point_up: Jenkins Build {0}\n\nResults available at: [Jenkins [{1} #{2}]]({3})");
|
||||||
GitLabCommitStatusPublisher publisher = mock(GitLabCommitStatusPublisher.class);
|
|
||||||
MatrixBuild parentBuild = mock(MatrixBuild.class);
|
|
||||||
|
|
||||||
when(build.getParent()).thenReturn(project);
|
performAndVerify(
|
||||||
when(publisher.createAggregator(any(MatrixBuild.class), any(Launcher.class), any(BuildListener.class))).thenCallRealMethod();
|
build, defaultNote, false, false, false, false, false,
|
||||||
when(publisher.perform(any(AbstractBuild.class), any(Launcher.class), any(BuildListener.class))).thenReturn(true);
|
prepareSendMessageWithSuccessResponse("v3", defaultNote));
|
||||||
|
|
||||||
MatrixAggregator aggregator = publisher.createAggregator(parentBuild, null, listener);
|
|
||||||
aggregator.startBuild();
|
|
||||||
aggregator.endBuild();
|
|
||||||
verify(publisher).perform(parentBuild, null, listener);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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
|
@Test
|
||||||
public void success() throws IOException, InterruptedException {
|
public void success() throws IOException, InterruptedException {
|
||||||
Integer buildNumber = 1;
|
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V4, Result.SUCCESS);
|
||||||
Integer projectId = 3;
|
String defaultNote = formatNote(build, ":white_check_mark: Jenkins Build {0}\n\nResults available at: [Jenkins [{1} #{2}]]({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);
|
|
||||||
|
|
||||||
HttpRequest[] requests = new HttpRequest[] {
|
performAndVerify(
|
||||||
prepareSendMessageWithSuccessResponse(projectId, mergeRequestId, defaultNote)
|
build, defaultNote, false, false, false, false, false,
|
||||||
};
|
prepareSendMessageWithSuccessResponse("v4", 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void success_withOnlyForFailure() throws IOException, InterruptedException {
|
public void success_withOnlyForFailure() throws IOException, InterruptedException {
|
||||||
Integer buildNumber = 1;
|
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V4, Result.SUCCESS);
|
||||||
Integer projectId = 3;
|
|
||||||
Integer mergeRequestId = 1;
|
|
||||||
AbstractBuild build = mockBuild("/build/123", GIT_LAB_CONNECTION, Result.SUCCESS, buildNumber);
|
|
||||||
|
|
||||||
GitLabMessagePublisher publisher = spy(new GitLabMessagePublisher(true, false, false, false, false, null, null, null, null));
|
performAndVerify(build, "test", true, false, false, false, false);
|
||||||
doReturn(projectId).when(publisher).getProjectId(build);
|
|
||||||
doReturn(mergeRequestId).when(publisher).getMergeRequestId(build);
|
|
||||||
publisher.perform(build, null, listener);
|
|
||||||
|
|
||||||
mockServerClient.verifyZeroInteractions();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void failed() throws IOException, InterruptedException {
|
public void failed_v3() throws IOException, InterruptedException {
|
||||||
Integer buildNumber = 1;
|
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V3, Result.FAILURE);
|
||||||
Integer projectId = 3;
|
String defaultNote = formatNote(build, ":negative_squared_cross_mark: Jenkins Build {0}\n\nResults available at: [Jenkins [{1} #{2}]]({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);
|
|
||||||
|
|
||||||
HttpRequest[] requests = new HttpRequest[] {
|
performAndVerify(
|
||||||
prepareSendMessageWithSuccessResponse(projectId, mergeRequestId, defaultNote)
|
build, defaultNote, false, false, false, false, false,
|
||||||
};
|
prepareSendMessageWithSuccessResponse("v3", 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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
|
@Test
|
||||||
public void failed_withOnlyForFailed() throws IOException, InterruptedException {
|
public void failed_withOnlyForFailed() throws IOException, InterruptedException {
|
||||||
Integer buildNumber = 1;
|
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V4, Result.FAILURE);
|
||||||
Integer projectId = 3;
|
String defaultNote = formatNote(build, ":negative_squared_cross_mark: Jenkins Build {0}\n\nResults available at: [Jenkins [{1} #{2}]]({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);
|
|
||||||
|
|
||||||
HttpRequest[] requests = new HttpRequest[] {
|
performAndVerify(
|
||||||
prepareSendMessageWithSuccessResponse(projectId, mergeRequestId, defaultNote)
|
build, defaultNote, true, false, false, false, false,
|
||||||
};
|
prepareSendMessageWithSuccessResponse("v4", 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void canceledWithCustomNote() throws IOException, InterruptedException {
|
public void canceledWithCustomNote() throws IOException, InterruptedException {
|
||||||
Integer buildNumber = 1;
|
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V4, Result.ABORTED);
|
||||||
Integer projectId = 3;
|
|
||||||
Integer mergeRequestId = 1;
|
|
||||||
AbstractBuild build = mockBuild("/build/123", GIT_LAB_CONNECTION, Result.ABORTED, buildNumber);
|
|
||||||
String defaultNote = "abort";
|
String defaultNote = "abort";
|
||||||
|
|
||||||
HttpRequest[] requests = new HttpRequest[] {
|
performAndVerify(
|
||||||
prepareSendMessageWithSuccessResponse(projectId, mergeRequestId, defaultNote)
|
build, defaultNote, false, false, false, true, false,
|
||||||
};
|
prepareSendMessageWithSuccessResponse("v4", 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void successWithCustomNote() throws IOException, InterruptedException {
|
public void successWithCustomNote() throws IOException, InterruptedException {
|
||||||
Integer buildNumber = 1;
|
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V4, Result.SUCCESS);
|
||||||
Integer projectId = 3;
|
|
||||||
Integer mergeRequestId = 1;
|
|
||||||
AbstractBuild build = mockBuild("/build/123", GIT_LAB_CONNECTION, Result.SUCCESS, buildNumber);
|
|
||||||
String defaultNote = "success";
|
String defaultNote = "success";
|
||||||
|
|
||||||
HttpRequest[] requests = new HttpRequest[] {
|
performAndVerify(
|
||||||
prepareSendMessageWithSuccessResponse(projectId, mergeRequestId, defaultNote)
|
build, defaultNote, false, true, false, false, false,
|
||||||
};
|
prepareSendMessageWithSuccessResponse("v4", 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void failedWithCustomNote() throws IOException, InterruptedException {
|
public void failedWithCustomNote() throws IOException, InterruptedException {
|
||||||
Integer buildNumber = 1;
|
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V4, Result.FAILURE);
|
||||||
Integer projectId = 3;
|
|
||||||
Integer mergeRequestId = 1;
|
|
||||||
AbstractBuild build = mockBuild("/build/123", GIT_LAB_CONNECTION, Result.FAILURE, buildNumber);
|
|
||||||
String defaultNote = "failure";
|
String defaultNote = "failure";
|
||||||
|
|
||||||
HttpRequest[] requests = new HttpRequest[] {
|
performAndVerify(
|
||||||
prepareSendMessageWithSuccessResponse(projectId, mergeRequestId, defaultNote)
|
build, defaultNote, false, false, true, false, false,
|
||||||
};
|
prepareSendMessageWithSuccessResponse("v4", 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void unstableWithCustomNote() throws IOException, InterruptedException {
|
public void unstableWithCustomNote() throws IOException, InterruptedException {
|
||||||
Integer buildNumber = 1;
|
AbstractBuild build = mockBuild(GITLAB_CONNECTION_V4, Result.UNSTABLE);
|
||||||
Integer projectId = 3;
|
|
||||||
Integer mergeRequestId = 1;
|
|
||||||
AbstractBuild build = mockBuild("/build/123", GIT_LAB_CONNECTION, Result.UNSTABLE, buildNumber);
|
|
||||||
String defaultNote = "unstable";
|
String defaultNote = "unstable";
|
||||||
|
|
||||||
HttpRequest[] requests = new HttpRequest[] {
|
performAndVerify(
|
||||||
prepareSendMessageWithSuccessResponse(projectId, mergeRequestId, defaultNote)
|
build, defaultNote, false, false, false, false, true,
|
||||||
};
|
prepareSendMessageWithSuccessResponse("v4", 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private HttpRequest prepareSendMessageWithSuccessResponse(Integer projectId, Integer mergeRequestId, String body) throws UnsupportedEncodingException {
|
private void performAndVerify(AbstractBuild build, String note, boolean onlyForFailure, boolean replaceSuccessNote, boolean replaceFailureNote, boolean replaceAbortNote, boolean replaceUnstableNote, HttpRequest... requests) throws InterruptedException, IOException {
|
||||||
HttpRequest updateCommitStatus = prepareSendMessageStatus(projectId, mergeRequestId, body);
|
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));
|
mockServerClient.when(updateCommitStatus).respond(response().withStatusCode(200));
|
||||||
return updateCommitStatus;
|
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()
|
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")
|
.withMethod("POST")
|
||||||
.withHeader("PRIVATE-TOKEN", "secret")
|
.withHeader("PRIVATE-TOKEN", "secret")
|
||||||
.withBody("body=" + URLEncoder.encode(body, "UTF-8"));
|
.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);
|
AbstractBuild build = mock(AbstractBuild.class);
|
||||||
BuildData buildData = mock(BuildData.class);
|
BuildData buildData = mock(BuildData.class);
|
||||||
when(buildData.getRemoteUrls()).thenReturn(new HashSet<>(Arrays.asList(remoteUrls)));
|
when(buildData.getRemoteUrls()).thenReturn(new HashSet<>(Arrays.asList(remoteUrls)));
|
||||||
when(build.getAction(BuildData.class)).thenReturn(buildData);
|
when(build.getAction(BuildData.class)).thenReturn(buildData);
|
||||||
when(build.getResult()).thenReturn(result);
|
when(build.getResult()).thenReturn(result);
|
||||||
when(build.getUrl()).thenReturn(buildUrl);
|
when(build.getUrl()).thenReturn(BUILD_URL);
|
||||||
when(build.getResult()).thenReturn(result);
|
when(build.getResult()).thenReturn(result);
|
||||||
when(build.getUrl()).thenReturn(buildUrl);
|
when(build.getNumber()).thenReturn(BUILD_NUMBER);
|
||||||
when(build.getNumber()).thenReturn(buildNumber);
|
|
||||||
|
|
||||||
AbstractProject<?, ?> project = mock(AbstractProject.class);
|
AbstractProject<?, ?> project = mock(AbstractProject.class);
|
||||||
when(project.getProperty(GitLabConnectionProperty.class)).thenReturn(new GitLabConnectionProperty(gitLabConnection));
|
when(project.getProperty(GitLabConnectionProperty.class)).thenReturn(new GitLabConnectionProperty(gitLabConnection));
|
||||||
|
|
|
@ -1,26 +1,10 @@
|
||||||
package com.dabsquared.gitlabjenkins.publisher;
|
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.AbstractBuild;
|
||||||
import hudson.model.AbstractProject;
|
|
||||||
import hudson.model.BuildListener;
|
import hudson.model.BuildListener;
|
||||||
import hudson.model.Result;
|
import hudson.model.Result;
|
||||||
import hudson.model.StreamBuildListener;
|
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.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
|
@ -35,17 +19,16 @@ import java.io.IOException;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.nio.charset.Charset;
|
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.doReturn;
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.spy;
|
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.HttpRequest.request;
|
||||||
import static org.mockserver.model.HttpResponse.response;
|
import static org.mockserver.model.HttpResponse.response;
|
||||||
|
|
||||||
|
@ -53,10 +36,6 @@ import static org.mockserver.model.HttpResponse.response;
|
||||||
* @author Nikolay Ustinov
|
* @author Nikolay Ustinov
|
||||||
*/
|
*/
|
||||||
public class GitLabVotePublisherTest {
|
public class GitLabVotePublisherTest {
|
||||||
|
|
||||||
private static final String GIT_LAB_CONNECTION = "GitLab";
|
|
||||||
private static final String API_TOKEN = "secret";
|
|
||||||
|
|
||||||
@ClassRule
|
@ClassRule
|
||||||
public static MockServerRule mockServer = new MockServerRule(new Object());
|
public static MockServerRule mockServer = new MockServerRule(new Object());
|
||||||
|
|
||||||
|
@ -67,17 +46,8 @@ public class GitLabVotePublisherTest {
|
||||||
private BuildListener listener;
|
private BuildListener listener;
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void setupConnection() throws IOException {
|
public static void setupClass() throws IOException {
|
||||||
GitLabConnectionConfig connectionConfig = jenkins.get(GitLabConnectionConfig.class);
|
setupGitLabConnections(jenkins, mockServer);
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
|
@ -92,94 +62,51 @@ public class GitLabVotePublisherTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void matrixAggregatable() throws UnsupportedEncodingException, InterruptedException, IOException {
|
public void matrixAggregatable() throws InterruptedException, IOException {
|
||||||
AbstractBuild build = mock(AbstractBuild.class);
|
verifyMatrixAggregatable(GitLabVotePublisher.class, listener);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void success() throws IOException, InterruptedException {
|
public void success_v3() throws IOException, InterruptedException {
|
||||||
Integer buildNumber = 1;
|
performAndVerify(TestUtility.mockSimpleBuild(GITLAB_CONNECTION_V3, Result.SUCCESS), "v3", ":+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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void failed() throws IOException, InterruptedException {
|
public void success_v4() throws IOException, InterruptedException {
|
||||||
Integer buildNumber = 1;
|
performAndVerify(TestUtility.mockSimpleBuild(GITLAB_CONNECTION_V4, Result.SUCCESS), "v4", ":+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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private HttpRequest prepareSendMessageWithSuccessResponse(Integer projectId, Integer mergeRequestId, String body) throws UnsupportedEncodingException {
|
@Test
|
||||||
HttpRequest updateCommitStatus = prepareSendMessageStatus(projectId, mergeRequestId, body);
|
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));
|
mockServerClient.when(updateCommitStatus).respond(response().withStatusCode(200));
|
||||||
return updateCommitStatus;
|
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()
|
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")
|
.withMethod("POST")
|
||||||
.withHeader("PRIVATE-TOKEN", "secret")
|
.withHeader("PRIVATE-TOKEN", "secret")
|
||||||
.withBody("body=" + URLEncoder.encode(body, "UTF-8"));
|
.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;
|
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.gitlab.api.model.Branch;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.runners.MockitoJUnitRunner;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
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 com.dabsquared.gitlabjenkins.gitlab.api.model.builder.generated.BranchBuilder.branch;
|
||||||
import static java.util.Arrays.asList;
|
import static java.util.Arrays.asList;
|
||||||
|
import static junit.framework.TestCase.assertEquals;
|
||||||
import static org.hamcrest.CoreMatchers.is;
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
import static org.junit.Assert.assertThat;
|
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 {
|
public class GitLabProjectBranchesServiceTest {
|
||||||
|
|
||||||
private final static List<String> BRANCH_NAMES_PROJECT_B = asList("master", "B-branch-1", "B-branch-2");
|
private final static List<String> BRANCH_NAMES_PROJECT_B = asList("master", "B-branch-1", "B-branch-2");
|
||||||
|
|
||||||
private GitLabProjectBranchesService branchesService;
|
private GitLabProjectBranchesService branchesService;
|
||||||
|
|
||||||
@Mock
|
private GitLabApiStub apiStub;
|
||||||
private GitLabApi gitlabApi;
|
private GitLabClient gitlabClient;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws IOException {
|
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
|
gitlabClient = new GitLabClient("", apiStub);
|
||||||
when(gitlabApi.getBranches("groupOne/A")).thenReturn(branchNamesProjectA);
|
|
||||||
when(gitlabApi.getBranches("groupOne/B")).thenReturn(convert(BRANCH_NAMES_PROJECT_B));
|
|
||||||
|
|
||||||
// never expire cache for tests
|
// never expire cache for tests
|
||||||
branchesService = new GitLabProjectBranchesService();
|
branchesService = new GitLabProjectBranchesService();
|
||||||
|
@ -45,7 +40,7 @@ public class GitLabProjectBranchesServiceTest {
|
||||||
@Test
|
@Test
|
||||||
public void shouldReturnBranchNamesFromGitlabApi() {
|
public void shouldReturnBranchNamesFromGitlabApi() {
|
||||||
// when
|
// 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
|
// then
|
||||||
assertThat(actualBranchNames, is(BRANCH_NAMES_PROJECT_B));
|
assertThat(actualBranchNames, is(BRANCH_NAMES_PROJECT_B));
|
||||||
|
@ -54,11 +49,11 @@ public class GitLabProjectBranchesServiceTest {
|
||||||
@Test
|
@Test
|
||||||
public void shouldNotMakeUnnecessaryCallsToGitlabApiGetBranches() {
|
public void shouldNotMakeUnnecessaryCallsToGitlabApiGetBranches() {
|
||||||
// when
|
// when
|
||||||
branchesService.getBranches(gitlabApi, "git@git.example.com:groupOne/A.git");
|
branchesService.getBranches(gitlabClient, "git@git.example.com:groupOne/A.git");
|
||||||
|
|
||||||
// then
|
// then
|
||||||
verify(gitlabApi, times(1)).getBranches("groupOne/A");
|
assertEquals(1, apiStub.calls("groupOne/A", Branch.class));
|
||||||
verify(gitlabApi, times(0)).getBranches("groupOne/B");
|
assertEquals(0, apiStub.calls("groupOne/B", Branch.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Branch> convert(List<String> branchNames) {
|
private List<Branch> convert(List<String> branchNames) {
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
package com.dabsquared.gitlabjenkins.service;
|
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.gitlab.api.model.Label;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.runners.MockitoJUnitRunner;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
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 com.dabsquared.gitlabjenkins.gitlab.api.model.builder.generated.LabelBuilder.label;
|
||||||
import static java.util.Arrays.asList;
|
import static java.util.Arrays.asList;
|
||||||
|
import static junit.framework.TestCase.assertEquals;
|
||||||
import static org.hamcrest.CoreMatchers.is;
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
import static org.junit.Assert.assertThat;
|
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 {
|
public class GitLabProjectLabelsServiceTest {
|
||||||
|
|
||||||
private final static List<String> LABELS_PROJECT_B = asList("label1", "label2", "label3");
|
private final static List<String> LABELS_PROJECT_B = asList("label1", "label2", "label3");
|
||||||
|
|
||||||
private GitLabProjectLabelsService labelsService;
|
private GitLabProjectLabelsService labelsService;
|
||||||
|
|
||||||
@Mock
|
private GitLabApiStub apiStub;
|
||||||
private GitLabApi gitlabApi;
|
private GitLabClient gitlabClient;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws IOException {
|
public void setUp() throws IOException {
|
||||||
List<Label> labelsProjectA = convert(asList("label1", "label2"));
|
apiStub = new GitLabApiStub();
|
||||||
|
apiStub.addLabels("groupOne/A", convert(asList("label1", "label2")));
|
||||||
// mock the gitlab factory
|
apiStub.addLabels("groupOne/B", convert(LABELS_PROJECT_B));
|
||||||
when(gitlabApi.getLabels("groupOne/A")).thenReturn(labelsProjectA);
|
|
||||||
when(gitlabApi.getLabels("groupOne/B")).thenReturn(convert(LABELS_PROJECT_B));
|
|
||||||
|
|
||||||
|
gitlabClient = new GitLabClient("", apiStub);
|
||||||
|
|
||||||
// never expire cache for tests
|
// never expire cache for tests
|
||||||
labelsService = new GitLabProjectLabelsService();
|
labelsService = new GitLabProjectLabelsService();
|
||||||
}
|
}
|
||||||
|
@ -45,7 +41,7 @@ public class GitLabProjectLabelsServiceTest {
|
||||||
@Test
|
@Test
|
||||||
public void shouldReturnLabelsFromGitlabApi() {
|
public void shouldReturnLabelsFromGitlabApi() {
|
||||||
// when
|
// 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
|
// then
|
||||||
assertThat(actualLabels, is(LABELS_PROJECT_B));
|
assertThat(actualLabels, is(LABELS_PROJECT_B));
|
||||||
|
@ -54,11 +50,11 @@ public class GitLabProjectLabelsServiceTest {
|
||||||
@Test
|
@Test
|
||||||
public void shouldNotMakeUnnecessaryCallsToGitlabApiGetLabels() {
|
public void shouldNotMakeUnnecessaryCallsToGitlabApiGetLabels() {
|
||||||
// when
|
// when
|
||||||
labelsService.getLabels(gitlabApi, "git@git.example.com:groupOne/A.git");
|
labelsService.getLabels(gitlabClient, "git@git.example.com:groupOne/A.git");
|
||||||
|
|
||||||
// then
|
// then
|
||||||
verify(gitlabApi, times(1)).getLabels("groupOne/A");
|
assertEquals(1, apiStub.calls("groupOne/A", Label.class));
|
||||||
verify(gitlabApi, times(0)).getLabels("groupOne/B");
|
assertEquals(0, apiStub.calls("groupOne/B", Label.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Label> convert(List<String> labels) {
|
private List<Label> convert(List<String> labels) {
|
||||||
|
|
|
@ -1,13 +1,23 @@
|
||||||
package com.dabsquared.gitlabjenkins.testing.gitlab.rule;
|
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.MergeRequest;
|
||||||
|
import com.dabsquared.gitlabjenkins.gitlab.api.model.Pipeline;
|
||||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.Project;
|
import com.dabsquared.gitlabjenkins.gitlab.api.model.Project;
|
||||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.User;
|
import com.dabsquared.gitlabjenkins.gitlab.api.model.User;
|
||||||
import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
|
import hudson.util.Secret;
|
||||||
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
|
import jenkins.model.Jenkins;
|
||||||
import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine;
|
import org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl;
|
||||||
import org.junit.rules.TestRule;
|
import org.junit.rules.TestRule;
|
||||||
import org.junit.runner.Description;
|
import org.junit.runner.Description;
|
||||||
import org.junit.runners.model.Statement;
|
import org.junit.runners.model.Statement;
|
||||||
|
@ -27,21 +37,20 @@ import java.util.UUID;
|
||||||
* @author Robin Müller
|
* @author Robin Müller
|
||||||
*/
|
*/
|
||||||
public class GitLabRule implements TestRule {
|
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 username;
|
||||||
private final String password;
|
private final String password;
|
||||||
|
|
||||||
private List<String> projectIds = new ArrayList<>();
|
private List<String> projectIds = new ArrayList<>();
|
||||||
|
|
||||||
public GitLabRule(String url, int postgresPort) {
|
public GitLabRule(String url, int postgresPort) {
|
||||||
client = new ResteasyClientBuilder()
|
this.url = url;
|
||||||
.httpEngine(new ApacheHttpClient4Engine())
|
this.postgresPort = postgresPort;
|
||||||
.register(new JacksonJsonProvider())
|
client = new V3GitLabClientBuilder().buildClient(url, getApiToken(), false, -1, -1);
|
||||||
.register(new JacksonConfig())
|
|
||||||
.register(new ApiHeaderTokenFilter(getApiToken(postgresPort))).build().target(url)
|
|
||||||
.proxyBuilder(GitLabApi.class)
|
|
||||||
.build();
|
|
||||||
User user = client.getCurrentUser();
|
User user = client.getCurrentUser();
|
||||||
username = user.getUsername();
|
username = user.getUsername();
|
||||||
password = "integration-test";
|
password = "integration-test";
|
||||||
|
@ -57,6 +66,10 @@ public class GitLabRule implements TestRule {
|
||||||
return client.getProject(projectName);
|
return client.getProject(projectName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Pipeline> getPipelines(int projectId) {
|
||||||
|
return client.getPipelines(String.valueOf(projectId));
|
||||||
|
}
|
||||||
|
|
||||||
public List<String> getProjectIds() {
|
public List<String> getProjectIds() {
|
||||||
return projectIds;
|
return projectIds;
|
||||||
}
|
}
|
||||||
|
@ -70,6 +83,22 @@ public class GitLabRule implements TestRule {
|
||||||
return project.getHttpUrlToRepo();
|
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,
|
public MergeRequest createMergeRequest(final Integer projectId,
|
||||||
final String sourceBranch,
|
final String sourceBranch,
|
||||||
final String targetBranch,
|
final String targetBranch,
|
||||||
|
@ -98,7 +127,7 @@ public class GitLabRule implements TestRule {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getApiToken(int postgresPort) {
|
private String getApiToken() {
|
||||||
try {
|
try {
|
||||||
Class.forName("org.postgresql.Driver");
|
Class.forName("org.postgresql.Driver");
|
||||||
try (Connection connection = DriverManager.getConnection("jdbc:postgresql://localhost:" + postgresPort + "/gitlabhq_production", "gitlab", "password")) {
|
try (Connection connection = DriverManager.getConnection("jdbc:postgresql://localhost:" + postgresPort + "/gitlabhq_production", "gitlab", "password")) {
|
||||||
|
|
|
@ -1,23 +1,34 @@
|
||||||
package com.dabsquared.gitlabjenkins.testing.integration;
|
package com.dabsquared.gitlabjenkins.testing.integration;
|
||||||
|
|
||||||
|
|
||||||
import com.dabsquared.gitlabjenkins.GitLabPushTrigger;
|
import com.dabsquared.gitlabjenkins.GitLabPushTrigger;
|
||||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.MergeRequest;
|
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.testing.gitlab.rule.GitLabRule;
|
||||||
import com.dabsquared.gitlabjenkins.trigger.filter.BranchFilterType;
|
import com.dabsquared.gitlabjenkins.trigger.filter.BranchFilterType;
|
||||||
import hudson.Launcher;
|
import hudson.Launcher;
|
||||||
import hudson.model.AbstractBuild;
|
import hudson.model.AbstractBuild;
|
||||||
import hudson.model.BuildListener;
|
import hudson.model.BuildListener;
|
||||||
|
import hudson.model.Descriptor;
|
||||||
import hudson.model.FreeStyleProject;
|
import hudson.model.FreeStyleProject;
|
||||||
|
import hudson.tasks.Publisher;
|
||||||
|
import hudson.util.DescribableList;
|
||||||
import hudson.util.OneShotEvent;
|
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.Git;
|
||||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||||
import org.eclipse.jgit.lib.StoredConfig;
|
import org.eclipse.jgit.lib.StoredConfig;
|
||||||
|
import org.eclipse.jgit.revwalk.RevCommit;
|
||||||
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
|
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.rules.TemporaryFolder;
|
import org.junit.rules.TemporaryFolder;
|
||||||
import org.jvnet.hudson.test.JenkinsRule;
|
import org.jvnet.hudson.test.JenkinsRule;
|
||||||
|
import org.jvnet.hudson.test.SleepBuilder;
|
||||||
import org.jvnet.hudson.test.TestBuilder;
|
import org.jvnet.hudson.test.TestBuilder;
|
||||||
|
import org.jvnet.hudson.test.TestNotifier;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.Inet4Address;
|
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.builder.generated.GitLabPushTriggerBuilder.gitLabPushTrigger;
|
||||||
import static com.dabsquared.gitlabjenkins.testing.gitlab.rule.builder.generated.ProjectRequestBuilder.projectRequest;
|
import static com.dabsquared.gitlabjenkins.testing.gitlab.rule.builder.generated.ProjectRequestBuilder.projectRequest;
|
||||||
import static org.hamcrest.CoreMatchers.is;
|
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.assertSame;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
@ -38,9 +52,10 @@ import static org.junit.Assert.assertTrue;
|
||||||
* @author Robin Müller
|
* @author Robin Müller
|
||||||
*/
|
*/
|
||||||
public class GitLabIT {
|
public class GitLabIT {
|
||||||
|
private static final String GITLAB_URL = "http://localhost:" + System.getProperty("gitlab.http.port", "10080");
|
||||||
|
|
||||||
@Rule
|
@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")));
|
Integer.parseInt(System.getProperty("postgres.port", "5432")));
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
|
@ -51,12 +66,6 @@ public class GitLabIT {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void buildOnPush() throws IOException, InterruptedException, GitAPIException {
|
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();
|
final OneShotEvent buildTriggered = new OneShotEvent();
|
||||||
FreeStyleProject project = jenkins.createFreeStyleProject("test");
|
FreeStyleProject project = jenkins.createFreeStyleProject("test");
|
||||||
GitLabPushTrigger trigger = gitLabPushTrigger().withTriggerOnPush(true).withBranchFilterType(BranchFilterType.All).build();
|
GitLabPushTrigger trigger = gitLabPushTrigger().withTriggerOnPush(true).withBranchFilterType(BranchFilterType.All).build();
|
||||||
|
@ -71,45 +80,15 @@ public class GitLabIT {
|
||||||
});
|
});
|
||||||
project.setQuietPeriod(0);
|
project.setQuietPeriod(0);
|
||||||
|
|
||||||
Git.init().setDirectory(tmp.getRoot()).call();
|
createGitLabProject(false,true, true, false);
|
||||||
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();
|
|
||||||
|
|
||||||
buildTriggered.block(10000);
|
buildTriggered.block(10000);
|
||||||
assertThat(buildTriggered.isSignaled(), is(true));
|
assertThat(buildTriggered.isSignaled(), is(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void buildOnMergeRequest() throws IOException, InterruptedException, GitAPIException {
|
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();
|
final OneShotEvent buildTriggered = new OneShotEvent();
|
||||||
FreeStyleProject project = jenkins.createFreeStyleProject("test");
|
FreeStyleProject project = jenkins.createFreeStyleProject("test");
|
||||||
GitLabPushTrigger trigger = gitLabPushTrigger().withTriggerOnMergeRequest(true).withBranchFilterType(BranchFilterType.All).build();
|
GitLabPushTrigger trigger = gitLabPushTrigger().withTriggerOnMergeRequest(true).withBranchFilterType(BranchFilterType.All).build();
|
||||||
|
@ -124,30 +103,9 @@ public class GitLabIT {
|
||||||
});
|
});
|
||||||
project.setQuietPeriod(0);
|
project.setQuietPeriod(0);
|
||||||
|
|
||||||
// Setup git repository
|
Pair<Integer, String> gitlabData = createGitLabProject(true,false, false, true);
|
||||||
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
|
gitlab.createMergeRequest(gitlabData.getLeft(), "feature", "master", "Merge feature branch to master.");
|
||||||
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.");
|
|
||||||
|
|
||||||
buildTriggered.block(10000);
|
buildTriggered.block(10000);
|
||||||
assertThat(buildTriggered.isSignaled(), is(true));
|
assertThat(buildTriggered.isSignaled(), is(true));
|
||||||
|
@ -155,26 +113,6 @@ public class GitLabIT {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void buildOnNote() throws IOException, InterruptedException, GitAPIException {
|
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();
|
final OneShotEvent buildTriggered = new OneShotEvent();
|
||||||
FreeStyleProject project = jenkins.createFreeStyleProject("test");
|
FreeStyleProject project = jenkins.createFreeStyleProject("test");
|
||||||
GitLabPushTrigger trigger = gitLabPushTrigger()
|
GitLabPushTrigger trigger = gitLabPushTrigger()
|
||||||
|
@ -190,42 +128,134 @@ public class GitLabIT {
|
||||||
});
|
});
|
||||||
project.setQuietPeriod(0);
|
project.setQuietPeriod(0);
|
||||||
|
|
||||||
// Setup git repository
|
Pair<Integer, String> gitlabData = createGitLabProject(true, false, true, false);
|
||||||
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();
|
|
||||||
|
|
||||||
// create merge-request
|
// 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
|
// add trigger after push/merge-request so it may only receive the note-hook
|
||||||
project.addTrigger(trigger);
|
project.addTrigger(trigger);
|
||||||
trigger.start(project, true);
|
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);
|
buildTriggered.block(20000);
|
||||||
assertThat(buildTriggered.isSignaled(), is(true));
|
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() {
|
private String getDocker0Ip() {
|
||||||
try {
|
try {
|
||||||
Enumeration<InetAddress> docker0Addresses = NetworkInterface.getByName("docker0").getInetAddresses();
|
Enumeration<InetAddress> docker0Addresses = NetworkInterface.getByName("docker0").getInetAddresses();
|
||||||
|
|
|
@ -1,17 +1,16 @@
|
||||||
package com.dabsquared.gitlabjenkins.util;
|
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.DataPoints;
|
||||||
import org.junit.experimental.theories.Theories;
|
import org.junit.experimental.theories.Theories;
|
||||||
import org.junit.experimental.theories.Theory;
|
import org.junit.experimental.theories.Theory;
|
||||||
import org.junit.runner.RunWith;
|
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
|
* @author Robin Müller
|
||||||
|
@ -33,8 +32,7 @@ public class ProjectIdUtilTest {
|
||||||
|
|
||||||
@Theory
|
@Theory
|
||||||
public void retrieveProjectId(TestData testData) throws ProjectIdUtil.ProjectIdResolutionException {
|
public void retrieveProjectId(TestData testData) throws ProjectIdUtil.ProjectIdResolutionException {
|
||||||
GitLabApi client = mock(GitLabApi.class);
|
GitLabClient client = new GitLabClient(testData.hostUrl, null);
|
||||||
when(client.getGitLabHostUrl()).thenReturn(testData.baseUrl);
|
|
||||||
|
|
||||||
String projectId = ProjectIdUtil.retrieveProjectId(client, testData.remoteUrl);
|
String projectId = ProjectIdUtil.retrieveProjectId(client, testData.remoteUrl);
|
||||||
|
|
||||||
|
@ -44,12 +42,12 @@ public class ProjectIdUtilTest {
|
||||||
|
|
||||||
static final class TestData {
|
static final class TestData {
|
||||||
|
|
||||||
private final String baseUrl;
|
private final String hostUrl;
|
||||||
private final String remoteUrl;
|
private final String remoteUrl;
|
||||||
private String expectedProjectId;
|
private String expectedProjectId;
|
||||||
|
|
||||||
private TestData(String baseUrl, String remoteUrl) {
|
private TestData(String hostUrl, String remoteUrl) {
|
||||||
this.baseUrl = baseUrl;
|
this.hostUrl = hostUrl;
|
||||||
this.remoteUrl = remoteUrl;
|
this.remoteUrl = remoteUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,7 @@ public abstract class BuildPageRedirectActionTest {
|
||||||
testProject.setScm(new GitSCM(gitRepoUrl));
|
testProject.setScm(new GitSCM(gitRepoUrl));
|
||||||
testProject.setQuietPeriod(0);
|
testProject.setQuietPeriod(0);
|
||||||
QueueTaskFuture<FreeStyleBuild> future = testProject.scheduleBuild2(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);
|
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