Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,14 @@ data class Pipeline(
} else if (useMultibranchWorkspace) {
writer.writeln("// Calculate custom workspace for multibranch pipelines")
writer.writeln("// This prevents workspace path truncation and branch conflicts")
writer.writeln("// by using a relative path that includes the sanitized branch name")
writer.writeln("// by using a relative path that includes the sanitized job name")
writer.writeln("def customWorkspacePath = null")
writer.writeln("if (env.BRANCH_NAME) {")
val innerWriter = writer.inner()
innerWriter.writeln("// Replace slashes and other special characters with underscores for safe filesystem paths")
innerWriter.writeln("def safeBranch = env.BRANCH_NAME.replaceAll('/', '_').replaceAll(/[^A-Za-z0-9._-]/, '_')")
innerWriter.writeln("customWorkspacePath = \"./workspace//\${safeBranch}\"")
innerWriter.writeln("// Decode URL-encoded characters (e.g., %2F -> /) from job name and sanitize for safe filesystem paths")
innerWriter.writeln("def decodedJobName = java.net.URLDecoder.decode(env.JOB_NAME, 'UTF-8')")
innerWriter.writeln("def safeJobName = decodedJobName.replaceAll(/[^A-Za-z0-9._-]/, '_')")
innerWriter.writeln("customWorkspacePath = \"./workspace//\${safeJobName}\"")
writer.writeln("}")
writer.writeln("")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,11 @@ class PipelineWorkspaceTest {
println(result)

// Verify it contains the runtime check
assertTrue(result.contains("if (env.BRANCH_NAME)"), "Should check for BRANCH_NAME")
assertTrue(result.contains("def rootDir = new File(env.WORKSPACE).parentFile.parent"))
assertTrue(result.contains("def safeBranch = (env.BRANCH_NAME ?: 'unknown').replaceAll(/[^A-Za-z0-9._-]/, '_')"))
assertTrue(result.contains("def customPath"))
assertTrue(result.contains("ws(customPath)"))
assertTrue(result.contains("checkout scm"))
assertTrue(result.contains("else {"), "Should have else block for non-multibranch")
assertTrue(result.contains("if (env.BRANCH_NAME)"), "Should check for BRANCH_NAME to detect multibranch")
assertTrue(result.contains("def decodedJobName = java.net.URLDecoder.decode(env.JOB_NAME, 'UTF-8')"), "Should decode URL-encoded job name")
assertTrue(result.contains("def safeJobName = decodedJobName.replaceAll(/[^A-Za-z0-9._-]/, '_')"), "Should sanitize job name")
assertTrue(result.contains("customWorkspacePath"), "Should define customWorkspacePath")
assertTrue(result.contains("customWorkspace customWorkspacePath"), "Should use customWorkspacePath in agent")
}

@Test
Expand All @@ -61,9 +59,8 @@ class PipelineWorkspaceTest {
println(result)

// Verify it uses custom workspace directly
assertTrue(result.contains("def customPath = \"/my/custom/workspace\""))
assertTrue(result.contains("ws(customPath)"))
assertTrue(result.contains("checkout scm"))
assertTrue(result.contains("def customWorkspacePath = \"/my/custom/workspace\""), "Should define customWorkspacePath with custom value")
assertTrue(result.contains("customWorkspace customWorkspacePath"), "Should use customWorkspacePath in agent")
assertTrue(!result.contains("if (env.BRANCH_NAME)"), "Should NOT check for BRANCH_NAME when custom workspace is set")
}

Expand All @@ -87,10 +84,9 @@ class PipelineWorkspaceTest {
println("\n=== Generated Jenkinsfile with useMultibranchWorkspace=false ===")
println(result)

// Verify it doesn't use any workspace wrapping
assertTrue(!result.contains("ws("), "Should NOT use ws() wrapper")
assertTrue(!result.contains("customPath"), "Should NOT have customPath")
assertTrue(!result.contains("checkout scm"), "Should NOT have checkout scm")
// Verify it doesn't use any custom workspace logic
assertTrue(!result.contains("customWorkspacePath"), "Should NOT have customWorkspacePath")
assertTrue(!result.contains("if (env.BRANCH_NAME)"), "Should NOT check for BRANCH_NAME")
assertTrue(result.contains("stages {"), "Should have stages block directly")
}
}
2 changes: 1 addition & 1 deletion version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.21.13
0.21.14
Loading