Skip to content

Commit 7fcd76a

Browse files
committed
fixup
Signed-off-by: jayfranco999 <[email protected]>
1 parent 3cf5919 commit 7fcd76a

File tree

2 files changed

+58
-35
lines changed

2 files changed

+58
-35
lines changed

test/groovy/PublishBuildStatusReportStepTests.groovy

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import org.junit.Before
22
import org.junit.Test
33
import java.util.Date
44
import java.util.TimeZone
5-
65
import static org.junit.Assert.assertFalse
76
import static org.junit.Assert.assertTrue
87

@@ -13,8 +12,7 @@ class PublishBuildStatusReportStepTests extends BaseTest {
1312
@Before
1413
void setUp() throws Exception {
1514
super.setUp()
16-
helper.registerAllowedMethod('publishReports', [List.class], { _ -> })
17-
// Mock the .format() extension method on the Date class
15+
// Mock the .format() extension method on the Date class for predictable timestamps in logs
1816
Date.metaClass.format = { String format, TimeZone tz -> '2025-06-17T15:10:00Z' }
1917
}
2018

@@ -26,6 +24,7 @@ class PublishBuildStatusReportStepTests extends BaseTest {
2624
void it_succeeds_on_principal_branch() throws Exception {
2725
def script = loadScript(scriptName)
2826
mockPrincipalBranch()
27+
addEnvVar('WORKSPACE', '/home/jenkins/workspace/test-job')
2928
addEnvVar('JENKINS_URL', 'https://ci.jenkins.io/')
3029
addEnvVar('JOB_NAME', 'my-folder/my-job')
3130
addEnvVar('BUILD_NUMBER', '123')
@@ -43,14 +42,24 @@ class PublishBuildStatusReportStepTests extends BaseTest {
4342
assertTrue(assertMethodCallContainsPattern('withEnv', 'ENV_BUILD_NUMBER=123'))
4443
assertTrue(assertMethodCallContainsPattern('withEnv', 'ENV_BUILD_STATUS=SUCCESS'))
4544
assertTrue(assertMethodCallContainsPattern('sh', '.jenkins-scripts/exec_generate_report_'))
46-
assertTrue(assertMethodCallContainsPattern('publishReports', 'build_status_reports/ci.jenkins.io/my-folder/my-job/status.json'))
45+
46+
assertFalse("publishReports should NOT have been called", assertMethodCall('publishReports'))
47+
48+
String expectedLocalPath = '/home/jenkins/workspace/test-job/build_status_reports/ci.jenkins.io/my-folder/my-job/status.json'
49+
String expectedRemoteUrl = 'https://buildsreportsjenkinsio.file.core.windows.net/builds-reports-jenkins-io/build_status_reports/ci.jenkins.io/my-folder/my-job/status.json'
50+
51+
assertTrue(assertMethodCallContainsPattern('withEnv', "AZCOPY_LOCAL_PATH=${expectedLocalPath}"))
52+
assertTrue(assertMethodCallContainsPattern('withEnv', "AZCOPY_DESTINATION_URL=${expectedRemoteUrl}"))
53+
assertTrue(assertMethodCallContainsPattern('sh', 'azcopy logout'))
54+
assertTrue(assertMethodCallContainsPattern('sh', 'azcopy login --identity'))
55+
assertTrue(assertMethodCallContainsPattern('sh', 'azcopy copy'))
4756
}
4857

4958
@Test
5059
void it_uses_fallback_values_when_env_vars_missing() throws Exception {
5160
def script = loadScript(scriptName)
5261
mockPrincipalBranch()
53-
// No env vars set
62+
addEnvVar('WORKSPACE', '/home/jenkins/workspace/fallback-job')
5463

5564
script.call()
5665
printCallStack()
@@ -60,12 +69,16 @@ class PublishBuildStatusReportStepTests extends BaseTest {
6069
assertMethodCallContainsPattern('withEnv', 'ENV_JOB_NAME=unknown_job')
6170
assertMethodCallContainsPattern('withEnv', 'ENV_BUILD_NUMBER=unknown_build')
6271
assertMethodCallContainsPattern('withEnv', 'ENV_BUILD_STATUS=UNKNOWN')
72+
73+
String expectedLocalPath = '/home/jenkins/workspace/fallback-job/build_status_reports/unknown_controller/unknown_job/status.json'
74+
assertTrue(assertMethodCallContainsPattern('withEnv', "AZCOPY_LOCAL_PATH=${expectedLocalPath}"))
75+
assertTrue(assertMethodCallContainsPattern('sh', 'azcopy copy'))
6376
}
6477

6578
@Test
6679
void it_does_nothing_on_non_principal_branch() throws Exception {
6780
def script = loadScript(scriptName)
68-
// No mockPrincipalBranch() call
81+
// No env vars set
6982

7083
script.call()
7184
printCallStack()
@@ -74,6 +87,7 @@ class PublishBuildStatusReportStepTests extends BaseTest {
7487
assertMethodCallContainsPattern('echo', 'Not on a principal branch')
7588
assertFalse(assertMethodCall('libraryResource'))
7689
assertFalse(assertMethodCall('writeFile'))
90+
assertFalse(assertMethodCallContainsPattern('sh', 'azcopy'))
7791
assertFalse(assertMethodCall('publishReports'))
7892
}
7993
}

vars/publishBuildStatusReport.groovy

Lines changed: 38 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -88,64 +88,73 @@ def call(Map config = [:]) {
8888
echo "publishBuildStatusReport - Data for shell script: Controller='${controllerHostname}', Job='${jobName}', Build='${buildNumber}', Status='${buildStatus}'"
8989

9090
// --- Step 2: Define the final path for the JSON report on the agent ---
91-
// This path is constructed in Groovy as it uses Jenkins context (WORKSPACE, controllerHostname, jobName).
92-
// The shell script will be responsible for creating this path and writing the file.
93-
String finalReportDirOnAgent = "${env.WORKSPACE}/build_status_reports/${controllerHostname}/${jobName}"
91+
String finalReportDirRelative = "build_status_reports/${controllerHostname}/${jobName}"
9492
String finalReportFileName = "status.json"
95-
String finalReportPathOnAgent = "${finalReportDirOnAgent}/${finalReportFileName}"
96-
echo "publishBuildStatusReport - Shell script will be instructed to write final report to: ${finalReportPathOnAgent}"
93+
String finalReportPathRelative = "${finalReportDirRelative}/${finalReportFileName}"
94+
String finalReportPathAbsolute = "${env.WORKSPACE}/${finalReportPathRelative}" // Absolute path for shell script
95+
echo "publishBuildStatusReport - Shell script will be instructed to write final report to: ${finalReportPathAbsolute}"
9796

9897
// --- Step 3: Prepare and deploy the utility shell script to the agent ---
99-
final String shellScriptResourcePath = 'io/jenkins/infra/pipeline/generateAndWriteBuildStatusReport.sh' // Assuming this is the agreed name and path
98+
final String shellScriptResourcePath = 'io/jenkins/infra/pipeline/generateAndWriteBuildStatusReport.sh'
10099
String shellScriptContent = libraryResource shellScriptResourcePath
101100

102-
String tempScriptDir = "${env.WORKSPACE}/.jenkins-scripts"
101+
String tempScriptDir = ".jenkins-scripts"
103102
String tempScriptName = "exec_generate_report_${env.BUILD_ID ?: System.currentTimeMillis()}.sh"
104103
String tempScriptPathOnAgent = "${tempScriptDir}/${tempScriptName}"
105104

106-
// Ensure the temporary script directory exists
107-
sh "mkdir -p '${tempScriptDir}'" // Single quotes for safety if tempScriptDir could have spaces (unlikely for .jenkins-scripts)
105+
sh "mkdir -p '${tempScriptDir}'"
108106

109107
writeFile file: tempScriptPathOnAgent, text: shellScriptContent
110108
sh "chmod +x '${tempScriptPathOnAgent}'"
111109
echo "publishBuildStatusReport - Utility shell script deployed to agent at: ${tempScriptPathOnAgent}"
112110

113111
// --- Step 4: Execute the utility shell script ---
114-
// Escape Groovy variables for safe inclusion as environment variable *values*.
115112
String escController = controllerHostname.replaceAll("'", "'\\\\''")
116-
String escJobName = jobName.replaceAll("'", "'\\\\''") // jobName can have '/' - this escaping handles single quotes within.
113+
String escJobName = jobName.replaceAll("'", "'\\\\''")
117114
String escBuildNumber = buildNumber.replaceAll("'", "'\\\\''")
118115
String escBuildStatus = buildStatus.replaceAll("'", "'\\\\''")
119-
// finalReportPathOnAgent is constructed from WORKSPACE and sanitized names, less likely to need escaping for this purpose,
120-
// but for consistency, we can escape it too.
121-
String escFinalReportPathOnAgent = finalReportPathOnAgent.replaceAll("'", "'\\\\''")
116+
String escFinalReportPathOnAgent = finalReportPathAbsolute.replaceAll("'", "'\\\\''")
122117

123118
withEnv([
124119
"ENV_CONTROLLER_HOSTNAME=${escController}",
125120
"ENV_JOB_NAME=${escJobName}",
126121
"ENV_BUILD_NUMBER=${escBuildNumber}",
127122
"ENV_BUILD_STATUS=${escBuildStatus}",
128-
"ENV_TARGET_JSON_FILE_PATH=${escFinalReportPathOnAgent}" // Pass the target path
123+
"ENV_TARGET_JSON_FILE_PATH=${escFinalReportPathOnAgent}"
129124
]) {
130125
echo "publishBuildStatusReport - Executing utility shell script: '${tempScriptPathOnAgent}'"
131-
// Execute the script. It will handle its own file I/O. No stdout capture.
132126
sh "'${tempScriptPathOnAgent}'"
133127
}
134128
echo "publishBuildStatusReport - Utility shell script execution completed."
135129

136-
// --- Step 5: Display generated status.json from workspace (FOR DEBUGGING/VERIFICATION) ---
137-
echo "publishBuildStatusReport - Displaying content of generated report file: ${finalReportPathOnAgent}"
138-
sh "cat '${finalReportPathOnAgent}'"
139-
140-
// --- Step 5: Publish the report (which was created by the shell script) ---
141-
// No Groovy-side validation of file content here, as per "no unnecessary validations".
142-
// We trust the shell script did its job if the 'sh' call above didn't fail (due to set -e in shell script).
143-
// A fileExists check could be added here if deemed essential minimal validation.
144-
echo "publishBuildStatusReport - Publishing report from: ${finalReportPathOnAgent}"
145-
publishReports([finalReportPathOnAgent])
146-
147-
// Cleanup of the temporary utility shell script is omitted as per last discussion.
148-
// Jenkins workspace cleanup will eventually remove it.
130+
// --- Step 5: Publish the generated report using azcopy ---
131+
final String azureBaseUrl = "https://buildsreportsjenkinsio.file.core.windows.net/builds-reports-jenkins-io"
132+
final String remotePath = finalReportPathRelative
133+
final String fullDestinationUrl = "${azureBaseUrl}/${remotePath}"
134+
135+
echo "publishBuildStatusReport - Publishing local file '${finalReportPathAbsolute}' to remote destination '${fullDestinationUrl}'"
136+
137+
// Escape variables for safe use inside the sh command string.
138+
String escLocalPath = finalReportPathAbsolute.replaceAll("'", "'\\\\''")
139+
String escDestinationUrl = fullDestinationUrl.replaceAll("'", "'\\\\''")
140+
141+
withEnv(["AZCOPY_LOCAL_PATH=${escLocalPath}", "AZCOPY_DESTINATION_URL=${escDestinationUrl}"]) {
142+
sh'''
143+
set -ex
144+
echo "Attempting to publish report with azcopy..."
145+
146+
# Ensure any previous azcopy login is cleared to avoid conflicts.
147+
azcopy logout 2>/dev/null || true
148+
149+
# Login using the agent's Managed Identity (credential-less).
150+
azcopy login --identity
151+
152+
# Copy the local file to the remote destination.
153+
azcopy copy "\$AZCOPY_LOCAL_PATH" "\$AZCOPY_DESTINATION_URL" --recursive
154+
155+
echo "azcopy copy command completed."
156+
'''
157+
}
149158

150159
echo "publishBuildStatusReport - Process completed for ${jobName}#${buildNumber}."
151160
}

0 commit comments

Comments
 (0)