mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-10 23:45:44 +01:00
merge
This commit is contained in:
3
.dockerignore
Normal file
3
.dockerignore
Normal file
@@ -0,0 +1,3 @@
|
||||
# ignore everything except scm-server.tar.gz
|
||||
**
|
||||
!scm-server/target/*.tar.gz
|
||||
20
Dockerfile
Normal file
20
Dockerfile
Normal file
@@ -0,0 +1,20 @@
|
||||
FROM openjdk:8u171-alpine3.8
|
||||
|
||||
ENV SCM_HOME=/var/lib/scm
|
||||
|
||||
RUN set -x \
|
||||
&& apk add --no-cache mercurial bash \
|
||||
&& addgroup -S -g 1000 scm \
|
||||
&& adduser -S -s /bin/false -G scm -h /opt/scm-server -D -H -u 1000 scm \
|
||||
&& mkdir ${SCM_HOME} \
|
||||
&& chown scm:scm ${SCM_HOME}
|
||||
|
||||
ADD scm-server/target/scm-server-app.tar.gz /opt
|
||||
RUN chown -R scm:scm /opt/scm-server
|
||||
|
||||
WORKDIR /opt/scm-server
|
||||
VOLUME [ "${SCM_HOME}", "/opt/scm-server/var/log" ]
|
||||
EXPOSE 8080
|
||||
USER scm
|
||||
|
||||
ENTRYPOINT [ "/opt/scm-server/bin/scm-server" ]
|
||||
37
Jenkinsfile
vendored
37
Jenkinsfile
vendored
@@ -4,14 +4,15 @@
|
||||
@Library('github.com/cloudogu/ces-build-lib@59d3e94')
|
||||
import com.cloudogu.ces.cesbuildlib.*
|
||||
|
||||
node() { // No specific label
|
||||
node('docker') {
|
||||
|
||||
// Change this as when we go back to default - necessary for proper SonarQube analysis
|
||||
mainBranch = "2.0.0-m3"
|
||||
|
||||
properties([
|
||||
// Keep only the last 10 build to preserve space
|
||||
buildDiscarder(logRotator(numToKeepStr: '10'))
|
||||
buildDiscarder(logRotator(numToKeepStr: '10')),
|
||||
disableConcurrentBuilds()
|
||||
])
|
||||
|
||||
timeout(activity: true, time: 20, unit: 'MINUTES') {
|
||||
@@ -44,6 +45,26 @@ node() { // No specific label
|
||||
currentBuild.result = 'UNSTABLE'
|
||||
}
|
||||
}
|
||||
|
||||
def commitHash = getCommitHash()
|
||||
def dockerImageTag = "2.0.0-dev-${commitHash.substring(0,7)}-${BUILD_NUMBER}"
|
||||
|
||||
if (isMainBranch()) {
|
||||
stage('Docker') {
|
||||
def image = docker.build('cloudogu/scm-manager')
|
||||
docker.withRegistry('', 'hub.docker.com-cesmarvin') {
|
||||
image.push(dockerImageTag)
|
||||
image.push('latest')
|
||||
}
|
||||
}
|
||||
|
||||
stage('Deployment') {
|
||||
build job: 'scm-manager/next-scm.cloudogu.com', propagate: false, wait: false, parameters: [
|
||||
string(name: 'changeset', value: commitHash),
|
||||
string(name: 'imageTag', value: dockerImageTag)
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Archive Unit and integration test results, if any
|
||||
@@ -62,7 +83,7 @@ Maven setupMavenBuild() {
|
||||
// Keep this version number in sync with .mvn/maven-wrapper.properties
|
||||
Maven mvn = new MavenInDocker(this, "3.5.2-jdk-8")
|
||||
|
||||
if (mainBranch.equals(env.BRANCH_NAME)) {
|
||||
if (isMainBranch()) {
|
||||
// Release starts javadoc, which takes very long, so do only for certain branches
|
||||
mvn.additionalArgs += ' -DperformRelease'
|
||||
// JDK8 is more strict, we should fix this before the next release. Right now, this is just not the focus, yet.
|
||||
@@ -89,7 +110,7 @@ void analyzeWith(Maven mvn) {
|
||||
"-Dsonar.pullrequest.bitbucketcloud.repository=scm-manager "
|
||||
} else {
|
||||
mvnArgs += " -Dsonar.branch.name=${env.BRANCH_NAME} "
|
||||
if (!mainBranch.equals(env.BRANCH_NAME)) {
|
||||
if (!isMainBranch()) {
|
||||
// Avoid exception "The main branch must not have a target" on main branch
|
||||
mvnArgs += " -Dsonar.branch.target=${mainBranch} "
|
||||
}
|
||||
@@ -98,6 +119,10 @@ void analyzeWith(Maven mvn) {
|
||||
}
|
||||
}
|
||||
|
||||
boolean isMainBranch() {
|
||||
return mainBranch.equals(env.BRANCH_NAME)
|
||||
}
|
||||
|
||||
boolean waitForQualityGateWebhookToBeCalled() {
|
||||
boolean isQualityGateSucceeded = true
|
||||
timeout(time: 2, unit: 'MINUTES') { // Needed when there is no webhook for example
|
||||
@@ -114,6 +139,10 @@ String getCommitAuthorComplete() {
|
||||
new Sh(this).returnStdOut 'hg log --branch . --limit 1 --template "{author}"'
|
||||
}
|
||||
|
||||
String getCommitHash() {
|
||||
new Sh(this).returnStdOut 'hg log --branch . --limit 1 --template "{node}"'
|
||||
}
|
||||
|
||||
String getCommitAuthorEmail() {
|
||||
def matcher = getCommitAuthorComplete() =~ "<(.*?)>"
|
||||
matcher ? matcher[0][1] : ""
|
||||
|
||||
21
deployments/helm/.helmignore
Normal file
21
deployments/helm/.helmignore
Normal file
@@ -0,0 +1,21 @@
|
||||
# Patterns to ignore when building packages.
|
||||
# This supports shell glob matching, relative path matching, and
|
||||
# negation (prefixed with !). Only one pattern per line.
|
||||
.DS_Store
|
||||
# Common VCS dirs
|
||||
.git/
|
||||
.gitignore
|
||||
.bzr/
|
||||
.bzrignore
|
||||
.hg/
|
||||
.hgignore
|
||||
.svn/
|
||||
# Common backup files
|
||||
*.swp
|
||||
*.bak
|
||||
*.tmp
|
||||
*~
|
||||
# Various IDEs
|
||||
.project
|
||||
.idea/
|
||||
*.tmproj
|
||||
5
deployments/helm/Chart.yaml
Normal file
5
deployments/helm/Chart.yaml
Normal file
@@ -0,0 +1,5 @@
|
||||
apiVersion: v1
|
||||
appVersion: "1.0"
|
||||
description: A Helm chart for SCM-Manager
|
||||
name: scm-manager
|
||||
version: 0.1.0
|
||||
19
deployments/helm/templates/NOTES.txt
Normal file
19
deployments/helm/templates/NOTES.txt
Normal file
@@ -0,0 +1,19 @@
|
||||
1. Get the application URL by running these commands:
|
||||
{{- if .Values.ingress.enabled }}
|
||||
{{- range .Values.ingress.hosts }}
|
||||
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ . }}{{ $.Values.ingress.path }}
|
||||
{{- end }}
|
||||
{{- else if contains "NodePort" .Values.service.type }}
|
||||
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "scm-manager.fullname" . }})
|
||||
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
|
||||
echo http://$NODE_IP:$NODE_PORT
|
||||
{{- else if contains "LoadBalancer" .Values.service.type }}
|
||||
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
|
||||
You can watch the status of by running 'kubectl get svc -w {{ include "scm-manager.fullname" . }}'
|
||||
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "scm-manager.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
|
||||
echo http://$SERVICE_IP:{{ .Values.service.port }}
|
||||
{{- else if contains "ClusterIP" .Values.service.type }}
|
||||
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ include "scm-manager.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
|
||||
echo "Visit http://127.0.0.1:8080 to use your application"
|
||||
kubectl port-forward $POD_NAME 8080:80
|
||||
{{- end }}
|
||||
32
deployments/helm/templates/_helpers.tpl
Normal file
32
deployments/helm/templates/_helpers.tpl
Normal file
@@ -0,0 +1,32 @@
|
||||
{{/* vim: set filetype=mustache: */}}
|
||||
{{/*
|
||||
Expand the name of the chart.
|
||||
*/}}
|
||||
{{- define "scm-manager.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Create a default fully qualified app name.
|
||||
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
|
||||
If release name contains chart name it will be used as a full name.
|
||||
*/}}
|
||||
{{- define "scm-manager.fullname" -}}
|
||||
{{- if .Values.fullnameOverride -}}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
|
||||
{{- else -}}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride -}}
|
||||
{{- if contains $name .Release.Name -}}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
|
||||
{{- else -}}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Create chart name and version as used by the chart label.
|
||||
*/}}
|
||||
{{- define "scm-manager.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
160
deployments/helm/templates/configmap.yaml
Normal file
160
deployments/helm/templates/configmap.yaml
Normal file
@@ -0,0 +1,160 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ include "scm-manager.fullname" . }}
|
||||
labels:
|
||||
app: {{ include "scm-manager.name" . }}
|
||||
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
|
||||
release: "{{ .Release.Name }}"
|
||||
heritage: "{{ .Release.Service }}"
|
||||
data:
|
||||
server-config.xml: |
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
|
||||
<Configure id="ScmServer" class="org.eclipse.jetty.server.Server">
|
||||
|
||||
<New id="httpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
|
||||
<!-- increase header size for mercurial -->
|
||||
<Set name="requestHeaderSize">16384</Set>
|
||||
<Set name="responseHeaderSize">16384</Set>
|
||||
|
||||
{{- if .Values.ingress.enabled -}}
|
||||
<!--
|
||||
We have to enable ForwardedRequestCustomizer in order to understand X-Forwarded-xxx headers.
|
||||
Without the ForwardedRequestCustomizer, scm will possibly generate wrong links
|
||||
-->
|
||||
<Call name="addCustomizer">
|
||||
<Arg><New class="org.eclipse.jetty.server.ForwardedRequestCustomizer"/></Arg>
|
||||
</Call>
|
||||
{{- end }}
|
||||
</New>
|
||||
|
||||
<!--
|
||||
Connectors
|
||||
-->
|
||||
<Call name="addConnector">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.server.ServerConnector">
|
||||
<Arg name="server">
|
||||
<Ref refid="ScmServer" />
|
||||
</Arg>
|
||||
<Arg name="factories">
|
||||
<Array type="org.eclipse.jetty.server.ConnectionFactory">
|
||||
<Item>
|
||||
<New class="org.eclipse.jetty.server.HttpConnectionFactory">
|
||||
<Arg name="config">
|
||||
<Ref refid="httpConfig" />
|
||||
</Arg>
|
||||
</New>
|
||||
</Item>
|
||||
</Array>
|
||||
</Arg>
|
||||
<Set name="port">
|
||||
<SystemProperty name="jetty.port" default="8080" />
|
||||
</Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
|
||||
<New id="scm-webapp" class="org.eclipse.jetty.webapp.WebAppContext">
|
||||
<Set name="contextPath">/scm</Set>
|
||||
<Set name="war">
|
||||
<SystemProperty name="basedir" default="."/>/var/webapp/scm-webapp.war</Set>
|
||||
<!-- disable directory listings -->
|
||||
<Call name="setInitParameter">
|
||||
<Arg>org.eclipse.jetty.servlet.Default.dirAllowed</Arg>
|
||||
<Arg>false</Arg>
|
||||
</Call>
|
||||
<Set name="tempDirectory">
|
||||
<SystemProperty name="basedir" default="."/>/work/scm
|
||||
</Set>
|
||||
</New>
|
||||
|
||||
<New id="docroot" class="org.eclipse.jetty.webapp.WebAppContext">
|
||||
<Set name="contextPath">/</Set>
|
||||
<Set name="baseResource">
|
||||
<New class="org.eclipse.jetty.util.resource.ResourceCollection">
|
||||
<Arg>
|
||||
<Array type="java.lang.String">
|
||||
<Item>
|
||||
<SystemProperty name="basedir" default="."/>/var/webapp/docroot</Item>
|
||||
</Array>
|
||||
</Arg>
|
||||
</New>
|
||||
</Set>
|
||||
<Set name="tempDirectory">
|
||||
<SystemProperty name="basedir" default="."/>/work/docroot
|
||||
</Set>
|
||||
</New>
|
||||
|
||||
<Set name="handler">
|
||||
<New class="org.eclipse.jetty.server.handler.HandlerCollection">
|
||||
<Set name="handlers">
|
||||
<Array type="org.eclipse.jetty.server.Handler">
|
||||
<Item>
|
||||
<Ref id="scm-webapp" />
|
||||
</Item>
|
||||
<Item>
|
||||
<Ref id="docroot" />
|
||||
</Item>
|
||||
</Array>
|
||||
</Set>
|
||||
</New>
|
||||
</Set>
|
||||
|
||||
</Configure>
|
||||
|
||||
logging.xml: |
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
|
||||
<--
|
||||
in a container environment we only need stdout
|
||||
-->
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
|
||||
<encoder>
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
|
||||
</encoder>
|
||||
|
||||
</appender>
|
||||
|
||||
<logger name="sonia.scm" level="INFO" />
|
||||
|
||||
<!-- suppress massive gzip logging -->
|
||||
<logger name="sonia.scm.filter.GZipFilter" level="WARN" />
|
||||
<logger name="sonia.scm.filter.GZipResponseStream" level="WARN" />
|
||||
|
||||
<logger name="sonia.scm.util.ServiceUtil" level="WARN" />
|
||||
|
||||
<!-- event bus -->
|
||||
<logger name="sonia.scm.event.LegmanScmEventBus" level="INFO" />
|
||||
|
||||
<!-- shiro -->
|
||||
<!--
|
||||
<logger name="org.apache.shiro" level="INFO" />
|
||||
<logger name="org.apache.shiro.authc.pam.ModularRealmAuthenticator" level="DEBUG" />
|
||||
-->
|
||||
|
||||
<!-- svnkit -->
|
||||
<!--
|
||||
<logger name="svnkit" level="WARN" />
|
||||
<logger name="svnkit.network" level="DEBUG" />
|
||||
<logger name="svnkit.fsfs" level="WARN" />
|
||||
-->
|
||||
|
||||
<!-- javahg -->
|
||||
<!--
|
||||
<logger name="com.aragost.javahg" level="DEBUG" />
|
||||
-->
|
||||
|
||||
<!-- ehcache -->
|
||||
<!--
|
||||
<logger name="net.sf.ehcache" level="DEBUG" />
|
||||
-->
|
||||
|
||||
<root level="WARN">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
|
||||
</configuration>
|
||||
77
deployments/helm/templates/deployment.yaml
Normal file
77
deployments/helm/templates/deployment.yaml
Normal file
@@ -0,0 +1,77 @@
|
||||
apiVersion: apps/v1beta2
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "scm-manager.fullname" . }}
|
||||
labels:
|
||||
app: {{ include "scm-manager.name" . }}
|
||||
chart: {{ include "scm-manager.chart" . }}
|
||||
release: {{ .Release.Name }}
|
||||
heritage: {{ .Release.Service }}
|
||||
spec:
|
||||
replicas: 1 # could not be scaled
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
app: {{ include "scm-manager.name" . }}
|
||||
release: {{ .Release.Name }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: {{ include "scm-manager.name" . }}
|
||||
release: {{ .Release.Name }}
|
||||
spec:
|
||||
initContainers:
|
||||
- name: volume-permissions
|
||||
image: alpine:3.8
|
||||
imagePullPolicy: IfNotPresent
|
||||
command: ['sh', '-c', 'chown 1000:1000 /data']
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /data
|
||||
containers:
|
||||
- name: {{ .Chart.Name }}
|
||||
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8080
|
||||
protocol: TCP
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /scm
|
||||
port: http
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /scm
|
||||
port: http
|
||||
resources:
|
||||
{{ toYaml .Values.resources | indent 12 }}
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /var/lib/scm
|
||||
- name: config
|
||||
mountPath: /opt/scm-server/conf
|
||||
volumes:
|
||||
- name: data
|
||||
{{- if .Values.persistence.enabled }}
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ include "scm-manager.fullname" . }}
|
||||
{{- else }}
|
||||
emptyDir: {}
|
||||
{{- end }}
|
||||
- name: config
|
||||
configMap:
|
||||
name: {{ include "scm-manager.fullname" . }}
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{ toYaml . | indent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.affinity }}
|
||||
affinity:
|
||||
{{ toYaml . | indent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.tolerations }}
|
||||
tolerations:
|
||||
{{ toYaml . | indent 8 }}
|
||||
{{- end }}
|
||||
38
deployments/helm/templates/ingress.yaml
Normal file
38
deployments/helm/templates/ingress.yaml
Normal file
@@ -0,0 +1,38 @@
|
||||
{{- if .Values.ingress.enabled -}}
|
||||
{{- $fullName := include "scm-manager.fullname" . -}}
|
||||
{{- $ingressPath := .Values.ingress.path -}}
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ $fullName }}
|
||||
labels:
|
||||
app: {{ include "scm-manager.name" . }}
|
||||
chart: {{ include "scm-manager.chart" . }}
|
||||
release: {{ .Release.Name }}
|
||||
heritage: {{ .Release.Service }}
|
||||
{{- with .Values.ingress.annotations }}
|
||||
annotations:
|
||||
{{ toYaml . | indent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if .Values.ingress.tls }}
|
||||
tls:
|
||||
{{- range .Values.ingress.tls }}
|
||||
- hosts:
|
||||
{{- range .hosts }}
|
||||
- {{ . | quote }}
|
||||
{{- end }}
|
||||
secretName: {{ .secretName }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
rules:
|
||||
{{- range .Values.ingress.hosts }}
|
||||
- host: {{ . | quote }}
|
||||
http:
|
||||
paths:
|
||||
- path: {{ $ingressPath }}
|
||||
backend:
|
||||
serviceName: {{ $fullName }}
|
||||
servicePort: http
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
24
deployments/helm/templates/pvc.yaml
Normal file
24
deployments/helm/templates/pvc.yaml
Normal file
@@ -0,0 +1,24 @@
|
||||
{{- if .Values.persistence.enabled -}}
|
||||
kind: PersistentVolumeClaim
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: {{ include "scm-manager.fullname" . }}
|
||||
labels:
|
||||
app: {{ include "scm-manager.name" . }}
|
||||
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
|
||||
release: "{{ .Release.Name }}"
|
||||
heritage: "{{ .Release.Service }}"
|
||||
spec:
|
||||
accessModes:
|
||||
- {{ .Values.persistence.accessMode | quote }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.persistence.size | quote }}
|
||||
{{- if .Values.persistence.storageClass }}
|
||||
{{- if (eq "-" .Values.persistence.storageClass) }}
|
||||
storageClassName: ""
|
||||
{{- else }}
|
||||
storageClassName: "{{ .Values.persistence.storageClass }}"
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
19
deployments/helm/templates/service.yaml
Normal file
19
deployments/helm/templates/service.yaml
Normal file
@@ -0,0 +1,19 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "scm-manager.fullname" . }}
|
||||
labels:
|
||||
app: {{ include "scm-manager.name" . }}
|
||||
chart: {{ include "scm-manager.chart" . }}
|
||||
release: {{ .Release.Name }}
|
||||
heritage: {{ .Release.Service }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
ports:
|
||||
- port: {{ .Values.service.port }}
|
||||
targetPort: 8080
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
app: {{ include "scm-manager.name" . }}
|
||||
release: {{ .Release.Name }}
|
||||
65
deployments/helm/values.yaml
Normal file
65
deployments/helm/values.yaml
Normal file
@@ -0,0 +1,65 @@
|
||||
# Default values for scm-manager.
|
||||
# This is a YAML-formatted file.
|
||||
# Declare variables to be passed into your templates.
|
||||
|
||||
# replicaCount: 1
|
||||
|
||||
image:
|
||||
repository: cloudogu/scm-manager
|
||||
# TODO change after release, to something more stable
|
||||
tag: latest
|
||||
pullPolicy: Always
|
||||
|
||||
nameOverride: ""
|
||||
fullnameOverride: ""
|
||||
|
||||
service:
|
||||
type: LoadBalancer
|
||||
port: 80
|
||||
|
||||
ingress:
|
||||
enabled: false
|
||||
annotations: {}
|
||||
# kubernetes.io/ingress.class: nginx
|
||||
# kubernetes.io/tls-acme: "true"
|
||||
path: /
|
||||
hosts:
|
||||
- scm-manager.local
|
||||
tls: []
|
||||
# - secretName: scm-manager-tls
|
||||
# hosts:
|
||||
# - scm-manager.local
|
||||
|
||||
## Enable persistence using Persistent Volume Claims
|
||||
## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/
|
||||
##
|
||||
persistence:
|
||||
enabled: true
|
||||
## ghost data Persistent Volume Storage Class
|
||||
## If defined, storageClassName: <storageClass>
|
||||
## If set to "-", storageClassName: "", which disables dynamic provisioning
|
||||
## If undefined (the default) or set to null, no storageClassName spec is
|
||||
## set, choosing the default provisioner. (gp2 on AWS, standard on
|
||||
## GKE, AWS & OpenStack)
|
||||
##
|
||||
# storageClass: "-"
|
||||
accessMode: ReadWriteOnce
|
||||
size: 12Gi
|
||||
|
||||
resources:
|
||||
# We usually recommend not to specify default resources and to leave this as a conscious
|
||||
# choice for the user. This also increases chances charts run on environments with little
|
||||
# resources, such as Minikube. If you do want to specify resources, uncomment the following
|
||||
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
|
||||
limits:
|
||||
cpu: 2000m
|
||||
memory: 2048Mi
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 256Mi
|
||||
|
||||
nodeSelector: {}
|
||||
|
||||
tolerations: []
|
||||
|
||||
affinity: {}
|
||||
@@ -7,9 +7,4 @@ public class NotFoundException extends Exception {
|
||||
|
||||
public NotFoundException() {
|
||||
}
|
||||
|
||||
|
||||
public NotFoundException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,7 +172,7 @@ public class RepositoryAccessITCase {
|
||||
.isNotNull()
|
||||
.contains(String.format("%s/sources/%s", repositoryUrl, changeset.getId()));
|
||||
|
||||
assertThat(response.body().jsonPath().getString("_embedded.tags.find{it.name=='" + tagName + "'}._links.changesets.href"))
|
||||
assertThat(response.body().jsonPath().getString("_embedded.tags.find{it.name=='" + tagName + "'}._links.changeset.href"))
|
||||
.as("assert single tag changesets link")
|
||||
.isNotNull()
|
||||
.contains(String.format("%s/changesets/%s", repositoryUrl, changeset.getId()));
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
//@flow
|
||||
import React from "react";
|
||||
import { repositories } from "@scm-manager/ui-components";
|
||||
import type { Repository } from "@scm-manager/ui-types";
|
||||
|
||||
type Props = {
|
||||
@@ -10,14 +11,16 @@ class ProtocolInformation extends React.Component<Props> {
|
||||
|
||||
render() {
|
||||
const { repository } = this.props;
|
||||
if (!repository._links.httpProtocol) {
|
||||
const href = repositories.getProtocolLinkByType(repository, "http");
|
||||
if (!href) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h4>Clone the repository</h4>
|
||||
<pre>
|
||||
<code>git clone {repository._links.httpProtocol.href}</code>
|
||||
<code>git clone {href}</code>
|
||||
</pre>
|
||||
<h4>Create a new repository</h4>
|
||||
<pre>
|
||||
@@ -30,7 +33,7 @@ class ProtocolInformation extends React.Component<Props> {
|
||||
<br />
|
||||
git commit -m "added readme"
|
||||
<br />
|
||||
git remote add origin {repository._links.httpProtocol.href}
|
||||
git remote add origin {href}
|
||||
<br />
|
||||
git push -u origin master
|
||||
<br />
|
||||
@@ -39,7 +42,7 @@ class ProtocolInformation extends React.Component<Props> {
|
||||
<h4>Push an existing repository</h4>
|
||||
<pre>
|
||||
<code>
|
||||
git remote add origin {repository._links.httpProtocol.href}
|
||||
git remote add origin {href}
|
||||
<br />
|
||||
git push -u origin master
|
||||
<br />
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
//@flow
|
||||
import React from "react";
|
||||
import { repositories } from "@scm-manager/ui-components";
|
||||
import type { Repository } from "@scm-manager/ui-types";
|
||||
|
||||
type Props = {
|
||||
@@ -10,14 +11,15 @@ class ProtocolInformation extends React.Component<Props> {
|
||||
|
||||
render() {
|
||||
const { repository } = this.props;
|
||||
if (!repository._links.httpProtocol) {
|
||||
const href = repositories.getProtocolLinkByType(repository, "http");
|
||||
if (!href) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<h4>Clone the repository</h4>
|
||||
<pre>
|
||||
<code>hg clone {repository._links.httpProtocol.href}</code>
|
||||
<code>hg clone {href}</code>
|
||||
</pre>
|
||||
<h4>Create a new repository</h4>
|
||||
<pre>
|
||||
@@ -26,7 +28,7 @@ class ProtocolInformation extends React.Component<Props> {
|
||||
<br />
|
||||
echo "[paths]" > .hg/hgrc
|
||||
<br />
|
||||
echo "default = {repository._links.httpProtocol.href}" > .hg/hgrc
|
||||
echo "default = {href}" > .hg/hgrc
|
||||
<br />
|
||||
echo "# {repository.name}" > README.md
|
||||
<br />
|
||||
@@ -44,7 +46,7 @@ class ProtocolInformation extends React.Component<Props> {
|
||||
<code>
|
||||
# add the repository url as default to your .hg/hgrc e.g:
|
||||
<br />
|
||||
default = {repository._links.httpProtocol.href}
|
||||
default = {href}
|
||||
<br />
|
||||
# push to remote repository
|
||||
<br />
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
//@flow
|
||||
import React from "react";
|
||||
import { repositories } from "@scm-manager/ui-components";
|
||||
import type { Repository } from "@scm-manager/ui-types";
|
||||
|
||||
type Props = {
|
||||
@@ -10,14 +11,15 @@ class ProtocolInformation extends React.Component<Props> {
|
||||
|
||||
render() {
|
||||
const { repository } = this.props;
|
||||
if (!repository._links.httpProtocol) {
|
||||
const href = repositories.getProtocolLinkByType(repository, "http");
|
||||
if (!href) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<h4>Checkout the repository</h4>
|
||||
<pre>
|
||||
<code>svn checkout {repository._links.httpProtocol.href}</code>
|
||||
<code>svn checkout {href}</code>
|
||||
</pre>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
import * as validation from "./validation.js";
|
||||
import * as urls from "./urls";
|
||||
import * as repositories from "./repositories.js";
|
||||
|
||||
export { validation, urls };
|
||||
export { validation, urls, repositories };
|
||||
|
||||
export { default as DateFromNow } from "./DateFromNow.js";
|
||||
export { default as ErrorNotification } from "./ErrorNotification.js";
|
||||
@@ -18,6 +19,8 @@ export { default as ProtectedRoute } from "./ProtectedRoute.js";
|
||||
|
||||
export { apiClient, NOT_FOUND_ERROR, UNAUTHORIZED_ERROR } from "./apiclient.js";
|
||||
|
||||
|
||||
|
||||
export * from "./buttons";
|
||||
export * from "./forms";
|
||||
export * from "./layout";
|
||||
|
||||
19
scm-ui-components/packages/ui-components/src/repositories.js
Normal file
19
scm-ui-components/packages/ui-components/src/repositories.js
Normal file
@@ -0,0 +1,19 @@
|
||||
// @flow
|
||||
import type { Repository } from "@scm-manager/ui-types";
|
||||
|
||||
// util methods for repositories
|
||||
|
||||
export function getProtocolLinkByType(repository: Repository, type: string) {
|
||||
let protocols = repository._links.protocol;
|
||||
if (protocols) {
|
||||
if (!Array.isArray(protocols)) {
|
||||
protocols = [protocols];
|
||||
}
|
||||
for (let proto of protocols) {
|
||||
if (proto.name === type) {
|
||||
return proto.href;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
// @flow
|
||||
|
||||
import type { Repository } from "@scm-manager/ui-types";
|
||||
import { getProtocolLinkByType, getTypePredicate } from "./repositories";
|
||||
|
||||
describe("getProtocolLinkByType tests", () => {
|
||||
|
||||
it("should return the http protocol link", () => {
|
||||
|
||||
const repository: Repository = {
|
||||
namespace: "scm",
|
||||
name: "core",
|
||||
type: "git",
|
||||
_links: {
|
||||
protocol: [{
|
||||
name: "http",
|
||||
href: "http://scm.scm-manager.org/repo/scm/core"
|
||||
}]
|
||||
}
|
||||
};
|
||||
|
||||
const link = getProtocolLinkByType(repository, "http");
|
||||
expect(link).toBe("http://scm.scm-manager.org/repo/scm/core");
|
||||
});
|
||||
|
||||
it("should return the http protocol link from multiple protocols", () => {
|
||||
|
||||
const repository: Repository = {
|
||||
namespace: "scm",
|
||||
name: "core",
|
||||
type: "git",
|
||||
_links: {
|
||||
protocol: [{
|
||||
name: "http",
|
||||
href: "http://scm.scm-manager.org/repo/scm/core"
|
||||
},{
|
||||
name: "ssh",
|
||||
href: "git@scm.scm-manager.org:scm/core"
|
||||
}]
|
||||
}
|
||||
};
|
||||
|
||||
const link = getProtocolLinkByType(repository, "http");
|
||||
expect(link).toBe("http://scm.scm-manager.org/repo/scm/core");
|
||||
});
|
||||
|
||||
it("should return the http protocol, even if the protocol is a single link", () => {
|
||||
|
||||
const repository: Repository = {
|
||||
namespace: "scm",
|
||||
name: "core",
|
||||
type: "git",
|
||||
_links: {
|
||||
protocol: {
|
||||
name: "http",
|
||||
href: "http://scm.scm-manager.org/repo/scm/core"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const link = getProtocolLinkByType(repository, "http");
|
||||
expect(link).toBe("http://scm.scm-manager.org/repo/scm/core");
|
||||
});
|
||||
|
||||
it("should return null, if such a protocol does not exists", () => {
|
||||
|
||||
const repository: Repository = {
|
||||
namespace: "scm",
|
||||
name: "core",
|
||||
type: "git",
|
||||
_links: {
|
||||
protocol: [{
|
||||
name: "http",
|
||||
href: "http://scm.scm-manager.org/repo/scm/core"
|
||||
},{
|
||||
name: "ssh",
|
||||
href: "git@scm.scm-manager.org:scm/core"
|
||||
}]
|
||||
}
|
||||
};
|
||||
|
||||
const link = getProtocolLinkByType(repository, "awesome");
|
||||
expect(link).toBeNull();
|
||||
});
|
||||
|
||||
it("should return null, if no protocols are available", () => {
|
||||
|
||||
const repository: Repository = {
|
||||
namespace: "scm",
|
||||
name: "core",
|
||||
type: "git",
|
||||
_links: {}
|
||||
};
|
||||
|
||||
const link = getProtocolLinkByType(repository, "http");
|
||||
expect(link).toBeNull();
|
||||
});
|
||||
|
||||
});
|
||||
@@ -1,9 +1,10 @@
|
||||
// @flow
|
||||
export type Link = {
|
||||
href: string
|
||||
href: string,
|
||||
name?: string
|
||||
};
|
||||
|
||||
export type Links = { [string]: Link };
|
||||
export type Links = { [string]: Link | Link[] };
|
||||
|
||||
export type Collection = {
|
||||
_embedded: Object,
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package sonia.scm.api.v2.resources;
|
||||
|
||||
import sonia.scm.PageResult;
|
||||
import sonia.scm.repository.Changeset;
|
||||
import sonia.scm.repository.Repository;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class BranchChangesetCollectionToDtoMapper extends ChangesetCollectionToDtoMapperBase {
|
||||
|
||||
private final ResourceLinks resourceLinks;
|
||||
|
||||
@Inject
|
||||
public BranchChangesetCollectionToDtoMapper(ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper, ResourceLinks resourceLinks) {
|
||||
super(changesetToChangesetDtoMapper);
|
||||
this.resourceLinks = resourceLinks;
|
||||
}
|
||||
|
||||
public CollectionDto map(int pageNumber, int pageSize, PageResult<Changeset> pageResult, Repository repository, String branch) {
|
||||
return this.map(pageNumber, pageSize, pageResult, repository, () -> createSelfLink(repository, branch));
|
||||
}
|
||||
|
||||
private String createSelfLink(Repository repository, String branch) {
|
||||
return resourceLinks.branch().history(repository.getNamespaceAndName(), branch);
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package sonia.scm.api.v2.resources;
|
||||
import com.webcohesion.enunciate.metadata.rs.ResponseCode;
|
||||
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
|
||||
import com.webcohesion.enunciate.metadata.rs.TypeHint;
|
||||
import sonia.scm.NotFoundException;
|
||||
import sonia.scm.PageResult;
|
||||
import sonia.scm.repository.Branches;
|
||||
import sonia.scm.repository.Changeset;
|
||||
@@ -32,14 +33,14 @@ public class BranchRootResource {
|
||||
private final BranchToBranchDtoMapper branchToDtoMapper;
|
||||
private final BranchCollectionToDtoMapper branchCollectionToDtoMapper;
|
||||
|
||||
private final ChangesetCollectionToDtoMapper changesetCollectionToDtoMapper;
|
||||
private final BranchChangesetCollectionToDtoMapper branchChangesetCollectionToDtoMapper;
|
||||
|
||||
@Inject
|
||||
public BranchRootResource(RepositoryServiceFactory serviceFactory, BranchToBranchDtoMapper branchToDtoMapper, BranchCollectionToDtoMapper branchCollectionToDtoMapper, ChangesetCollectionToDtoMapper changesetCollectionToDtoMapper) {
|
||||
public BranchRootResource(RepositoryServiceFactory serviceFactory, BranchToBranchDtoMapper branchToDtoMapper, BranchCollectionToDtoMapper branchCollectionToDtoMapper, BranchChangesetCollectionToDtoMapper changesetCollectionToDtoMapper) {
|
||||
this.serviceFactory = serviceFactory;
|
||||
this.branchToDtoMapper = branchToDtoMapper;
|
||||
this.branchCollectionToDtoMapper = branchCollectionToDtoMapper;
|
||||
this.changesetCollectionToDtoMapper = changesetCollectionToDtoMapper;
|
||||
this.branchChangesetCollectionToDtoMapper = changesetCollectionToDtoMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -98,6 +99,14 @@ public class BranchRootResource {
|
||||
@DefaultValue("0") @QueryParam("page") int page,
|
||||
@DefaultValue("10") @QueryParam("pageSize") int pageSize) throws Exception {
|
||||
try (RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name))) {
|
||||
boolean branchExists = repositoryService.getBranchesCommand()
|
||||
.getBranches()
|
||||
.getBranches()
|
||||
.stream()
|
||||
.anyMatch(branch -> branchName.equals(branch.getName()));
|
||||
if (!branchExists){
|
||||
throw new NotFoundException("branch", branchName);
|
||||
}
|
||||
Repository repository = repositoryService.getRepository();
|
||||
RepositoryPermissions.read(repository).check();
|
||||
ChangesetPagingResult changesets = repositoryService.getLogCommand()
|
||||
@@ -107,7 +116,7 @@ public class BranchRootResource {
|
||||
.getChangesets();
|
||||
if (changesets != null && changesets.getChangesets() != null) {
|
||||
PageResult<Changeset> pageResult = new PageResult<>(changesets.getChangesets(), changesets.getTotal());
|
||||
return Response.ok(changesetCollectionToDtoMapper.map(page, pageSize, pageResult, repository)).build();
|
||||
return Response.ok(branchChangesetCollectionToDtoMapper.map(page, pageSize, pageResult, repository, branchName)).build();
|
||||
} else {
|
||||
return Response.ok().build();
|
||||
}
|
||||
|
||||
@@ -5,31 +5,22 @@ import sonia.scm.repository.Changeset;
|
||||
import sonia.scm.repository.Repository;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ChangesetCollectionToDtoMapper extends PagedCollectionToDtoMapper<Changeset, ChangesetDto> {
|
||||
public class ChangesetCollectionToDtoMapper extends ChangesetCollectionToDtoMapperBase {
|
||||
|
||||
private final ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper;
|
||||
protected final ResourceLinks resourceLinks;
|
||||
private final ResourceLinks resourceLinks;
|
||||
|
||||
@Inject
|
||||
public ChangesetCollectionToDtoMapper(ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper, ResourceLinks resourceLinks) {
|
||||
super("changesets");
|
||||
this.changesetToChangesetDtoMapper = changesetToChangesetDtoMapper;
|
||||
super(changesetToChangesetDtoMapper);
|
||||
this.resourceLinks = resourceLinks;
|
||||
}
|
||||
|
||||
public CollectionDto map(int pageNumber, int pageSize, PageResult<Changeset> pageResult, Repository repository) {
|
||||
return this.map(pageNumber, pageSize, pageResult, repository, () -> createSelfLink(repository));
|
||||
return super.map(pageNumber, pageSize, pageResult, repository, () -> createSelfLink(repository));
|
||||
}
|
||||
|
||||
public CollectionDto map(int pageNumber, int pageSize, PageResult<Changeset> pageResult, Repository repository, Supplier<String> selfLinkSupplier) {
|
||||
return super.map(pageNumber, pageSize, pageResult, selfLinkSupplier.get(), Optional.empty(), changeset -> changesetToChangesetDtoMapper.map(changeset, repository));
|
||||
}
|
||||
|
||||
protected String createSelfLink(Repository repository) {
|
||||
private String createSelfLink(Repository repository) {
|
||||
return resourceLinks.changeset().all(repository.getNamespace(), repository.getName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package sonia.scm.api.v2.resources;
|
||||
|
||||
import sonia.scm.PageResult;
|
||||
import sonia.scm.repository.Changeset;
|
||||
import sonia.scm.repository.Repository;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
class ChangesetCollectionToDtoMapperBase extends PagedCollectionToDtoMapper<Changeset, ChangesetDto> {
|
||||
|
||||
private final ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper;
|
||||
|
||||
ChangesetCollectionToDtoMapperBase(ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper) {
|
||||
super("changesets");
|
||||
this.changesetToChangesetDtoMapper = changesetToChangesetDtoMapper;
|
||||
}
|
||||
|
||||
CollectionDto map(int pageNumber, int pageSize, PageResult<Changeset> pageResult, Repository repository, Supplier<String> selfLinkSupplier) {
|
||||
return super.map(pageNumber, pageSize, pageResult, selfLinkSupplier.get(), Optional.empty(), changeset -> changesetToChangesetDtoMapper.map(changeset, repository));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,19 +6,22 @@ import sonia.scm.repository.Repository;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class FileHistoryCollectionToDtoMapper extends ChangesetCollectionToDtoMapper {
|
||||
public class FileHistoryCollectionToDtoMapper extends ChangesetCollectionToDtoMapperBase {
|
||||
|
||||
|
||||
private final ResourceLinks resourceLinks;
|
||||
|
||||
@Inject
|
||||
public FileHistoryCollectionToDtoMapper(ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper, ResourceLinks resourceLinks) {
|
||||
super(changesetToChangesetDtoMapper, resourceLinks);
|
||||
super(changesetToChangesetDtoMapper);
|
||||
this.resourceLinks = resourceLinks;
|
||||
}
|
||||
|
||||
public CollectionDto map(int pageNumber, int pageSize, PageResult<Changeset> pageResult, Repository repository, String revision, String path) {
|
||||
return super.map(pageNumber, pageSize, pageResult, repository, () -> createSelfLink(repository, revision, path));
|
||||
}
|
||||
|
||||
protected String createSelfLink(Repository repository, String revision, String path) {
|
||||
return super.resourceLinks.fileHistory().self(repository.getNamespace(), repository.getName(), revision, path);
|
||||
private String createSelfLink(Repository repository, String revision, String path) {
|
||||
return resourceLinks.fileHistory().self(repository.getNamespace(), repository.getName(), revision, path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,7 +162,7 @@ public class PermissionRootResource {
|
||||
RepositoryPermissions.permissionWrite(repository).check();
|
||||
String extractedPermissionName = getPermissionName(permissionName);
|
||||
if (!isPermissionExist(new PermissionDto(extractedPermissionName, isGroupPermission(permissionName)), repository)) {
|
||||
throw new NotFoundException("the permission " + extractedPermissionName + " does not exist");
|
||||
throw new NotFoundException("permission", extractedPermissionName);
|
||||
}
|
||||
permission.setGroupPermission(isGroupPermission(permissionName));
|
||||
if (!extractedPermissionName.equals(permission.getName())) {
|
||||
|
||||
@@ -28,7 +28,7 @@ public abstract class TagToTagDtoMapper {
|
||||
Links.Builder linksBuilder = linkingTo()
|
||||
.self(resourceLinks.tag().self(namespaceAndName.getNamespace(), namespaceAndName.getName(), target.getName()))
|
||||
.single(link("sources", resourceLinks.source().self(namespaceAndName.getNamespace(), namespaceAndName.getName(), target.getRevision())))
|
||||
.single(link("changesets", resourceLinks.changeset().self(namespaceAndName.getNamespace(), namespaceAndName.getName(), target.getRevision())));
|
||||
.single(link("changeset", resourceLinks.changeset().self(namespaceAndName.getNamespace(), namespaceAndName.getName(), target.getRevision())));
|
||||
target.add(linksBuilder.build());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ public class BranchRootResourceTest extends RepositoryTestBase {
|
||||
@InjectMocks
|
||||
private BranchToBranchDtoMapperImpl branchToDtoMapper;
|
||||
|
||||
private ChangesetCollectionToDtoMapper changesetCollectionToDtoMapper;
|
||||
private BranchChangesetCollectionToDtoMapper changesetCollectionToDtoMapper;
|
||||
|
||||
private BranchRootResource branchRootResource;
|
||||
|
||||
@@ -90,7 +90,7 @@ public class BranchRootResourceTest extends RepositoryTestBase {
|
||||
|
||||
@Before
|
||||
public void prepareEnvironment() throws Exception {
|
||||
changesetCollectionToDtoMapper = new ChangesetCollectionToDtoMapper(changesetToChangesetDtoMapper, resourceLinks);
|
||||
changesetCollectionToDtoMapper = new BranchChangesetCollectionToDtoMapper(changesetToChangesetDtoMapper, resourceLinks);
|
||||
BranchCollectionToDtoMapper branchCollectionToDtoMapper = new BranchCollectionToDtoMapper(branchToDtoMapper, resourceLinks);
|
||||
branchRootResource = new BranchRootResource(serviceFactory, branchToDtoMapper, branchCollectionToDtoMapper, changesetCollectionToDtoMapper);
|
||||
super.branchRootResource = Providers.of(branchRootResource);
|
||||
@@ -152,6 +152,10 @@ public class BranchRootResourceTest extends RepositoryTestBase {
|
||||
when(logCommandBuilder.setPagingLimit(anyInt())).thenReturn(logCommandBuilder);
|
||||
when(logCommandBuilder.setBranch(anyString())).thenReturn(logCommandBuilder);
|
||||
when(logCommandBuilder.getChangesets()).thenReturn(changesetPagingResult);
|
||||
Branches branches = mock(Branches.class);
|
||||
List<Branch> branchList = Lists.newArrayList(new Branch("master",id));
|
||||
when(branches.getBranches()).thenReturn(branchList);
|
||||
when(branchesCommandBuilder.getBranches()).thenReturn(branches);
|
||||
MockHttpRequest request = MockHttpRequest.get(BRANCH_URL + "/changesets/");
|
||||
MockHttpResponse response = new MockHttpResponse();
|
||||
dispatcher.invoke(request, response);
|
||||
@@ -161,6 +165,5 @@ public class BranchRootResourceTest extends RepositoryTestBase {
|
||||
assertTrue(response.getContentAsString().contains(String.format("\"name\":\"%s\"", authorName)));
|
||||
assertTrue(response.getContentAsString().contains(String.format("\"mail\":\"%s\"", authorEmail)));
|
||||
assertTrue(response.getContentAsString().contains(String.format("\"description\":\"%s\"", commit)));
|
||||
assertTrue(response.getContentAsString().contains(String.format("\"description\":\"%s\"", commit)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ import com.github.sdorra.shiro.SubjectAware;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Sets;
|
||||
import org.apache.shiro.authz.UnauthorizedException;
|
||||
import org.apache.shiro.util.ThreadContext;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
@@ -94,6 +95,10 @@ import static org.mockito.Mockito.when;
|
||||
)
|
||||
public class DefaultRepositoryManagerTest extends ManagerTestBase<Repository> {
|
||||
|
||||
{
|
||||
ThreadContext.unbindSubject();
|
||||
}
|
||||
|
||||
@Rule
|
||||
public ShiroRule shiro = new ShiroRule();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user