Skip to content

Commit fe8f853

Browse files
committed
Merge branch 'develop' of ssh://github.com/NginxProxyManager/nginx-proxy-manager into develop
# Conflicts: # backend/schema/endpoints/proxy-hosts.json # backend/templates/_listen.conf
2 parents 1eb6a57 + 5e66d67 commit fe8f853

File tree

309 files changed

+13765
-19216
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

309 files changed

+13765
-19216
lines changed

.github/workflows/stale.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: 'Close stale issues and PRs'
2+
on:
3+
schedule:
4+
- cron: '30 1 * * *'
5+
workflow_dispatch:
6+
7+
jobs:
8+
stale:
9+
runs-on: ubuntu-latest
10+
steps:
11+
- uses: actions/stale@v9
12+
with:
13+
stale-issue-label: 'stale'
14+
stale-pr-label: 'stale'
15+
stale-issue-message: 'Issue is now considered stale. If you want to keep it open, please comment :+1:'
16+
stale-pr-message: 'PR is now considered stale. If you want to keep it open, please comment :+1:'
17+
close-issue-message: 'Issue was closed due to inactivity.'
18+
close-pr-message: 'PR was closed due to inactivity.'
19+
days-before-stale: 182
20+
days-before-close: 365
21+
operations-per-run: 50

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,7 @@
33
._*
44
.vscode
55
certbot-help.txt
6+
test/node_modules
7+
*/node_modules
8+
docker/dev/dnsrouter-config.json.tmp
9+
docker/dev/resolv.conf

.version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.10.4
1+
2.12.3

Jenkinsfile

Lines changed: 152 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,9 @@ pipeline {
1717
IMAGE = 'nginx-proxy-manager'
1818
BUILD_VERSION = getVersion()
1919
MAJOR_VERSION = '2'
20-
BRANCH_LOWER = "${BRANCH_NAME.toLowerCase().replaceAll('/', '-')}"
21-
COMPOSE_PROJECT_NAME = "npm_${BRANCH_LOWER}_${BUILD_NUMBER}"
22-
COMPOSE_FILE = 'docker/docker-compose.ci.yml'
20+
BRANCH_LOWER = "${BRANCH_NAME.toLowerCase().replaceAll('\\\\', '-').replaceAll('/', '-').replaceAll('\\.', '-')}"
21+
BUILDX_NAME = "npm_${BRANCH_LOWER}_${BUILD_NUMBER}"
2322
COMPOSE_INTERACTIVE_NO_CLI = 1
24-
BUILDX_NAME = "${COMPOSE_PROJECT_NAME}"
25-
DOCS_BUCKET = 'jc21-npm-site'
26-
DOCS_CDN = 'EN1G6DEWZUTDT'
2723
}
2824
stages {
2925
stage('Environment') {
@@ -47,7 +43,7 @@ pipeline {
4743
steps {
4844
script {
4945
// Defaults to the Branch name, which is applies to all branches AND pr's
50-
buildxPushTags = "-t docker.io/jc21/${IMAGE}:github-${BRANCH_LOWER}"
46+
buildxPushTags = "-t docker.io/nginxproxymanager/${IMAGE}-dev:${BRANCH_LOWER}"
5147
}
5248
}
5349
}
@@ -60,105 +56,153 @@ pipeline {
6056
sh 'sed -i -E "s/(version-)[0-9]+\\.[0-9]+\\.[0-9]+(-green)/\\1${BUILD_VERSION}\\2/" README.md'
6157
}
6258
}
63-
}
64-
}
65-
stage('Build and Test') {
66-
steps {
67-
script {
68-
// Frontend and Backend
69-
def shStatusCode = sh(label: 'Checking and Building', returnStatus: true, script: '''
70-
set -e
71-
./scripts/ci/frontend-build > ${WORKSPACE}/tmp-sh-build 2>&1
72-
./scripts/ci/test-and-build > ${WORKSPACE}/tmp-sh-build 2>&1
73-
''')
74-
shOutput = readFile "${env.WORKSPACE}/tmp-sh-build"
75-
if (shStatusCode != 0) {
76-
error "${shOutput}"
59+
stage('Docker Login') {
60+
steps {
61+
withCredentials([usernamePassword(credentialsId: 'jc21-dockerhub', passwordVariable: 'dpass', usernameVariable: 'duser')]) {
62+
sh 'docker login -u "${duser}" -p "${dpass}"'
63+
}
7764
}
7865
}
7966
}
80-
post {
81-
always {
82-
sh 'rm -f ${WORKSPACE}/tmp-sh-build'
67+
}
68+
stage('Builds') {
69+
parallel {
70+
stage('Project') {
71+
steps {
72+
script {
73+
// Frontend and Backend
74+
def shStatusCode = sh(label: 'Checking and Building', returnStatus: true, script: '''
75+
set -e
76+
./scripts/ci/frontend-build > ${WORKSPACE}/tmp-sh-build 2>&1
77+
./scripts/ci/test-and-build > ${WORKSPACE}/tmp-sh-build 2>&1
78+
''')
79+
shOutput = readFile "${env.WORKSPACE}/tmp-sh-build"
80+
if (shStatusCode != 0) {
81+
error "${shOutput}"
82+
}
83+
}
84+
}
85+
post {
86+
always {
87+
sh 'rm -f ${WORKSPACE}/tmp-sh-build'
88+
}
89+
failure {
90+
npmGithubPrComment("CI Error:\n\n```\n${shOutput}\n```", true)
91+
}
92+
}
8393
}
84-
failure {
85-
npmGithubPrComment("CI Error:\n\n```\n${shOutput}\n```", true)
94+
stage('Docs') {
95+
steps {
96+
dir(path: 'docs') {
97+
sh 'yarn install'
98+
sh 'yarn build'
99+
}
100+
}
86101
}
87102
}
88103
}
89-
stage('Integration Tests Sqlite') {
104+
stage('Test Sqlite') {
105+
environment {
106+
COMPOSE_PROJECT_NAME = "npm_${BRANCH_LOWER}_${BUILD_NUMBER}_sqlite"
107+
COMPOSE_FILE = 'docker/docker-compose.ci.yml:docker/docker-compose.ci.sqlite.yml'
108+
}
109+
when {
110+
not {
111+
equals expected: 'UNSTABLE', actual: currentBuild.result
112+
}
113+
}
90114
steps {
91-
// Bring up a stack
92-
sh 'docker-compose up -d fullstack-sqlite'
93-
sh './scripts/wait-healthy $(docker-compose ps --all -q fullstack-sqlite) 120'
94-
// Stop and Start it, as this will test it's ability to restart with existing data
95-
sh 'docker-compose stop fullstack-sqlite'
96-
sh 'docker-compose start fullstack-sqlite'
97-
sh './scripts/wait-healthy $(docker-compose ps --all -q fullstack-sqlite) 120'
98-
99-
// Run tests
100-
sh 'rm -rf test/results'
101-
sh 'docker-compose up cypress-sqlite'
102-
// Get results
103-
sh 'docker cp -L "$(docker-compose ps --all -q cypress-sqlite):/test/results" test/'
115+
sh 'rm -rf ./test/results/junit/*'
116+
sh './scripts/ci/fulltest-cypress'
104117
}
105118
post {
106119
always {
107120
// Dumps to analyze later
108-
sh 'mkdir -p debug'
109-
sh 'docker-compose logs fullstack-sqlite > debug/docker_fullstack_sqlite.log'
110-
sh 'docker-compose logs db > debug/docker_db.log'
111-
// Cypress videos and screenshot artifacts
121+
sh 'mkdir -p debug/sqlite'
122+
sh 'docker logs $(docker-compose ps --all -q fullstack) > debug/sqlite/docker_fullstack.log 2>&1'
123+
sh 'docker logs $(docker-compose ps --all -q stepca) > debug/sqlite/docker_stepca.log 2>&1'
124+
sh 'docker logs $(docker-compose ps --all -q pdns) > debug/sqlite/docker_pdns.log 2>&1'
125+
sh 'docker logs $(docker-compose ps --all -q pdns-db) > debug/sqlite/docker_pdns-db.log 2>&1'
126+
sh 'docker logs $(docker-compose ps --all -q dnsrouter) > debug/sqlite/docker_dnsrouter.log 2>&1'
127+
junit 'test/results/junit/*'
128+
sh 'docker-compose down --remove-orphans --volumes -t 30 || true'
129+
}
130+
unstable {
112131
dir(path: 'test/results') {
113-
archiveArtifacts allowEmptyArchive: true, artifacts: '**/*', excludes: '**/*.xml'
132+
archiveArtifacts(allowEmptyArchive: true, artifacts: '**/*', excludes: '**/*.xml')
114133
}
115-
junit 'test/results/junit/*'
116134
}
117135
}
118136
}
119-
stage('Integration Tests Mysql') {
137+
stage('Test Mysql') {
138+
environment {
139+
COMPOSE_PROJECT_NAME = "npm_${BRANCH_LOWER}_${BUILD_NUMBER}_mysql"
140+
COMPOSE_FILE = 'docker/docker-compose.ci.yml:docker/docker-compose.ci.mysql.yml'
141+
}
142+
when {
143+
not {
144+
equals expected: 'UNSTABLE', actual: currentBuild.result
145+
}
146+
}
120147
steps {
121-
// Bring up a stack
122-
sh 'docker-compose up -d fullstack-mysql'
123-
sh './scripts/wait-healthy $(docker-compose ps --all -q fullstack-mysql) 120'
124-
125-
// Run tests
126-
sh 'rm -rf test/results'
127-
sh 'docker-compose up cypress-mysql'
128-
// Get results
129-
sh 'docker cp -L "$(docker-compose ps --all -q cypress-mysql):/test/results" test/'
148+
sh 'rm -rf ./test/results/junit/*'
149+
sh './scripts/ci/fulltest-cypress'
130150
}
131151
post {
132152
always {
133153
// Dumps to analyze later
134-
sh 'mkdir -p debug'
135-
sh 'docker-compose logs fullstack-mysql > debug/docker_fullstack_mysql.log'
136-
sh 'docker-compose logs db > debug/docker_db.log'
137-
// Cypress videos and screenshot artifacts
154+
sh 'mkdir -p debug/mysql'
155+
sh 'docker logs $(docker-compose ps --all -q fullstack) > debug/mysql/docker_fullstack.log 2>&1'
156+
sh 'docker logs $(docker-compose ps --all -q stepca) > debug/mysql/docker_stepca.log 2>&1'
157+
sh 'docker logs $(docker-compose ps --all -q pdns) > debug/mysql/docker_pdns.log 2>&1'
158+
sh 'docker logs $(docker-compose ps --all -q pdns-db) > debug/mysql/docker_pdns-db.log 2>&1'
159+
sh 'docker logs $(docker-compose ps --all -q dnsrouter) > debug/mysql/docker_dnsrouter.log 2>&1'
160+
junit 'test/results/junit/*'
161+
sh 'docker-compose down --remove-orphans --volumes -t 30 || true'
162+
}
163+
unstable {
138164
dir(path: 'test/results') {
139-
archiveArtifacts allowEmptyArchive: true, artifacts: '**/*', excludes: '**/*.xml'
165+
archiveArtifacts(allowEmptyArchive: true, artifacts: '**/*', excludes: '**/*.xml')
140166
}
141-
junit 'test/results/junit/*'
142167
}
143168
}
144169
}
145-
stage('Docs') {
170+
stage('Test Postgres') {
171+
environment {
172+
COMPOSE_PROJECT_NAME = "npm_${BRANCH_LOWER}_${BUILD_NUMBER}_postgres"
173+
COMPOSE_FILE = 'docker/docker-compose.ci.yml:docker/docker-compose.ci.postgres.yml'
174+
}
146175
when {
147176
not {
148177
equals expected: 'UNSTABLE', actual: currentBuild.result
149178
}
150179
}
151180
steps {
152-
dir(path: 'docs') {
153-
sh 'yarn install'
154-
sh 'yarn build'
155-
}
181+
sh 'rm -rf ./test/results/junit/*'
182+
sh './scripts/ci/fulltest-cypress'
183+
}
184+
post {
185+
always {
186+
// Dumps to analyze later
187+
sh 'mkdir -p debug/postgres'
188+
sh 'docker logs $(docker-compose ps --all -q fullstack) > debug/postgres/docker_fullstack.log 2>&1'
189+
sh 'docker logs $(docker-compose ps --all -q stepca) > debug/postgres/docker_stepca.log 2>&1'
190+
sh 'docker logs $(docker-compose ps --all -q pdns) > debug/postgres/docker_pdns.log 2>&1'
191+
sh 'docker logs $(docker-compose ps --all -q pdns-db) > debug/postgres/docker_pdns-db.log 2>&1'
192+
sh 'docker logs $(docker-compose ps --all -q dnsrouter) > debug/postgres/docker_dnsrouter.log 2>&1'
193+
sh 'docker logs $(docker-compose ps --all -q db-postgres) > debug/postgres/docker_db-postgres.log 2>&1'
194+
sh 'docker logs $(docker-compose ps --all -q authentik) > debug/postgres/docker_authentik.log 2>&1'
195+
sh 'docker logs $(docker-compose ps --all -q authentik-redis) > debug/postgres/docker_authentik-redis.log 2>&1'
196+
sh 'docker logs $(docker-compose ps --all -q authentik-ldap) > debug/postgres/docker_authentik-ldap.log 2>&1'
156197

157-
dir(path: 'docs/.vuepress/dist') {
158-
sh 'tar -czf ../../docs.tgz *'
198+
junit 'test/results/junit/*'
199+
sh 'docker-compose down --remove-orphans --volumes -t 30 || true'
200+
}
201+
unstable {
202+
dir(path: 'test/results') {
203+
archiveArtifacts(allowEmptyArchive: true, artifacts: '**/*', excludes: '**/*.xml')
204+
}
159205
}
160-
161-
archiveArtifacts(artifacts: 'docs/docs.tgz', allowEmptyArchive: false)
162206
}
163207
}
164208
stage('MultiArch Build') {
@@ -168,60 +212,59 @@ pipeline {
168212
}
169213
}
170214
steps {
171-
withCredentials([usernamePassword(credentialsId: 'jc21-dockerhub', passwordVariable: 'dpass', usernameVariable: 'duser')]) {
172-
sh 'docker login -u "${duser}" -p "${dpass}"'
173-
sh "./scripts/buildx --push ${buildxPushTags}"
174-
}
215+
sh "./scripts/buildx --push ${buildxPushTags}"
175216
}
176217
}
177-
stage('Docs Deploy') {
178-
when {
179-
allOf {
180-
branch 'master'
181-
not {
182-
equals expected: 'UNSTABLE', actual: currentBuild.result
218+
stage('Docs / Comment') {
219+
parallel {
220+
stage('Docs Job') {
221+
when {
222+
allOf {
223+
branch pattern: "^(develop|master)\$", comparator: "REGEXP"
224+
not {
225+
equals expected: 'UNSTABLE', actual: currentBuild.result
226+
}
227+
}
183228
}
184-
}
185-
}
186-
steps {
187-
npmDocsRelease("$DOCS_BUCKET", "$DOCS_CDN")
188-
}
189-
}
190-
stage('PR Comment') {
191-
when {
192-
allOf {
193-
changeRequest()
194-
not {
195-
equals expected: 'UNSTABLE', actual: currentBuild.result
229+
steps {
230+
build wait: false, job: 'nginx-proxy-manager-docs', parameters: [string(name: 'docs_branch', value: "$BRANCH_NAME")]
196231
}
197232
}
198-
}
199-
steps {
200-
script {
201-
npmGithubPrComment("Docker Image for build ${BUILD_NUMBER} is available on [DockerHub](https://cloud.docker.com/repository/docker/jc21/${IMAGE}) as `jc21/${IMAGE}:github-${BRANCH_LOWER}`\n\n**Note:** ensure you backup your NPM instance before testing this PR image! Especially if this PR contains database changes.", true)
233+
stage('PR Comment') {
234+
when {
235+
allOf {
236+
changeRequest()
237+
not {
238+
equals expected: 'UNSTABLE', actual: currentBuild.result
239+
}
240+
}
241+
}
242+
steps {
243+
script {
244+
npmGithubPrComment("""Docker Image for build ${BUILD_NUMBER} is available on
245+
[DockerHub](https://cloud.docker.com/repository/docker/nginxproxymanager/${IMAGE}-dev)
246+
as `nginxproxymanager/${IMAGE}-dev:${BRANCH_LOWER}`
247+
248+
**Note:** ensure you backup your NPM instance before testing this image! Especially if there are database changes
249+
**Note:** this is a different docker image namespace than the official image
250+
""", true)
251+
}
252+
}
202253
}
203254
}
204255
}
205256
}
206257
post {
207258
always {
208-
sh 'docker-compose down --remove-orphans --volumes -t 30'
209259
sh 'echo Reverting ownership'
210-
sh 'docker run --rm -v $(pwd):/data jc21/ci-tools chown -R $(id -u):$(id -g) /data'
211-
}
212-
success {
213-
juxtapose event: 'success'
214-
sh 'figlet "SUCCESS"'
260+
sh 'docker run --rm -v "$(pwd):/data" jc21/ci-tools chown -R "$(id -u):$(id -g)" /data'
261+
printResult(true)
215262
}
216263
failure {
217-
archiveArtifacts(artifacts: 'debug/**.*', allowEmptyArchive: true)
218-
juxtapose event: 'failure'
219-
sh 'figlet "FAILURE"'
264+
archiveArtifacts(artifacts: 'debug/**/*.*', allowEmptyArchive: true)
220265
}
221266
unstable {
222-
archiveArtifacts(artifacts: 'debug/**.*', allowEmptyArchive: true)
223-
juxtapose event: 'unstable'
224-
sh 'figlet "UNSTABLE"'
267+
archiveArtifacts(artifacts: 'debug/**/*.*', allowEmptyArchive: true)
225268
}
226269
}
227270
}

0 commit comments

Comments
 (0)