Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow publishing reports on infra.ci #348

Merged
merged 3 commits into from
Apr 27, 2022
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
35 changes: 22 additions & 13 deletions test/groovy/PublishReportsStepTests.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import org.junit.Before
import org.junit.Test
import mock.Infra
import static org.junit.Assert.assertEquals
import static org.junit.Assert.assertFalse
import static org.junit.Assert.assertTrue

class PublishReportsStepTests extends BaseTest {
Expand Down Expand Up @@ -40,39 +41,47 @@ class PublishReportsStepTests extends BaseTest {
// then hardcoded credentials is correct
assertTrue(assertMethodCallContainsPattern('string', 'credentialsId=azure-reports-access-key'))
// No execution
assertTrue(helper.callStack.findAll { call -> call.methodName == 'sh' }.isEmpty())
assertFalse(assertMethodCallContainsPattern('sh','az storage blob'))
assertJobStatusSuccess()
}

@Test
void test_with_trusted_and_html_infra() throws Exception {
def script = loadScript(scriptName)
def file = 'foo.html'
// when running with a html filename
script.call(['foo.html'])
script.call([file])
printCallStack()
// then timeout is default and filename manipulations is in place
assertTrue(assertMethodCallContainsPattern('sh', '--timeout=60 --file=foo.html --name=foo.html --content-type="text/html"'))
assertTrue(assertMethodCallContainsPattern('withEnv', 'TIMEOUT=60'))
assertTrue(assertMethodCallContainsPattern('withEnv', "FILENAME=${file}"))
assertTrue(assertMethodCallContainsPattern('withEnv', 'UPLOADFLAGS=--content-type="text/html"'))
assertTrue(assertMethodCallContainsPattern('sh', 'az storage blob upload --account-name=prodjenkinsreports --container=reports --timeout=${TIMEOUT} --file=${FILENAME} --name=${FILENAME} ${UPLOADFLAGS} --overwrite'))
// another filename manipulations is in place
assertTrue(assertMethodCallContainsPattern('sh', '--source . '))
assertTrue(assertMethodCallContainsPattern('sh', '--destination-path / '))
assertTrue(assertMethodCallContainsPattern('sh', '--pattern foo.html '))
assertTrue(assertMethodCallContainsPattern('sh', '--content-type="text/html"'))
assertTrue(assertMethodCallContainsPattern('withEnv', 'SOURCE_DIRNAME=.'))
assertTrue(assertMethodCallContainsPattern('withEnv', 'DESTINATION_PATH=/'))
assertTrue(assertMethodCallContainsPattern('withEnv', 'PATTERN=foo.html'))
assertTrue(assertMethodCallContainsPattern('sh', 'az storage file upload-batch --account-name prodjenkinsreports --destination reports --source ${SOURCE_DIRNAME} --destination-path ${DESTINATION_PATH} --pattern ${PATTERN} ${UPLOADFLAGS}'))
assertJobStatusSuccess()
}

@Test
void test_with_trusted_and_full_path_css_infra() throws Exception {
def script = loadScript(scriptName)
// when running with a css full path filename
script.call(['/bar/foo.css'])
def file = '/bar/foo.css'
script.call([file])
printCallStack()
// then timeout is default and filename manipulations is in place
assertTrue(assertMethodCallContainsPattern('sh', '--timeout=60 --file=/bar/foo.css --name=/bar/foo.css --content-type="text/css'))
assertTrue(assertMethodCallContainsPattern('withEnv', 'TIMEOUT=60'))
assertTrue(assertMethodCallContainsPattern('withEnv', "FILENAME=${file}"))
assertTrue(assertMethodCallContainsPattern('withEnv', 'UPLOADFLAGS=--content-type="text/css"'))
assertTrue(assertMethodCallContainsPattern('sh', 'az storage blob upload --account-name=prodjenkinsreports --container=reports --timeout=${TIMEOUT} --file=${FILENAME} --name=${FILENAME} ${UPLOADFLAGS} --overwrite'))
// another filename manipulations is in place
assertTrue(assertMethodCallContainsPattern('sh', '--source /bar '))
assertTrue(assertMethodCallContainsPattern('sh', '--destination-path /bar '))
assertTrue(assertMethodCallContainsPattern('sh', '--pattern foo.css '))
assertTrue(assertMethodCallContainsPattern('sh', '--content-type="text/css"'))
assertTrue(assertMethodCallContainsPattern('withEnv', 'SOURCE_DIRNAME=/bar'))
assertTrue(assertMethodCallContainsPattern('withEnv', 'DESTINATION_PATH=/bar'))
assertTrue(assertMethodCallContainsPattern('withEnv', 'PATTERN=foo.css'))
assertTrue(assertMethodCallContainsPattern('sh', 'az storage file upload-batch --account-name prodjenkinsreports --destination reports --source ${SOURCE_DIRNAME} --destination-path ${DESTINATION_PATH} --pattern ${PATTERN} ${UPLOADFLAGS}'))
assertJobStatusSuccess()
}
}
83 changes: 43 additions & 40 deletions vars/publishReports.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -8,52 +8,55 @@
def call(List<String> files, Map params = [:]) {
def timeout = params.get('timeout') ?: '60'

if (!infra.isTrusted()) {
if (!infra.isTrusted() && !infra.isInfra()) {
error 'Can only call publishReports from within the trusted.ci environment'
}

withCredentials([string(credentialsId: 'azure-reports-access-key', variable: 'AZURE_STORAGE_KEY')]) {
docker.image('mcr.microsoft.com/azure-cli:2.0.41').inside {
for (int i = 0; i < files.size(); ++i) {
String filename = files[i]
withEnv(['HOME=/tmp']) {
String uploadFlags = ''
switch (filename) {
case ~/(?i).*\.html/:
uploadFlags = '--content-type="text/html"'
break
case ~/(?i).*\.css/:
uploadFlags = '--content-type="text/css"'
break
case ~/(?i).*\.json/:
uploadFlags = '--content-type="application/json"'
break
case ~/(?i).*\.js/:
uploadFlags = '--content-type="application/javascript"'
break
case ~/(?i).*\.gif/:
uploadFlags = '--content-type="image/gif"'
break
case ~/(?i).*\.png/:
uploadFlags = '--content-type="image/png"'
break
}
// Blob container can be removed once files are uploaded on the azure file storage
sh "az storage blob upload --account-name=prodjenkinsreports --container=reports --timeout=${timeout} --file=${filename} --name=${filename} ${uploadFlags}"
withCredentials([string(credentialsId: 'azure-reports-access-key', variable: 'AZURE_STORAGE_KEY'),]) {
// Sanity Check to check that `az` is installed, in the PATH, and in a decent version
sh 'az version'

// `az storage file upload` doesn't support file uploaded in a remote directory that doesn't exist but upload-batch yes. Unfortunatly the cli syntax is a bit different and require filename and directory name to be set differently.
for(int i = 0; i < files.size(); ++i) {
String filename = files[i]
withEnv(['HOME=/tmp']) {
String uploadFlags = ''
switch (filename) {
case ~/(?i).*\.html/:
uploadFlags = '--content-type="text/html"'
break
case ~/(?i).*\.css/:
uploadFlags = '--content-type="text/css"'
break
case ~/(?i).*\.json/:
uploadFlags = '--content-type="application/json"'
break
case ~/(?i).*\.js/:
uploadFlags = '--content-type="application/javascript"'
break
case ~/(?i).*\.gif/:
uploadFlags = '--content-type="image/gif"'
break
case ~/(?i).*\.png/:
uploadFlags = '--content-type="image/png"'
break
}
def directory = filename.split("/")
def basename = directory[directory.size() - 1]
def dirname = Arrays.copyOfRange(directory, 0, directory.size()-1 ).join("/")

def directory = filename.split("/")
def basename = directory[directory.size() - 1]
def dirname = Arrays.copyOfRange(directory, 0, directory.size() - 1).join("/")
withEnv([
"TIMEOUT=${timeout}",
"FILENAME=${filename}",
"UPLOADFLAGS=${uploadFlags}",
"SOURCE_DIRNAME=${dirname ?: '.'}",
"DESTINATION_PATH=${dirname ?: '/'}",
"PATTERN=${ basename ?: '*' }",
]) {
// Blob container can be removed once files are uploaded on the azure file storage
sh 'az storage blob upload --account-name=prodjenkinsreports --container=reports --timeout=${TIMEOUT} --file=${FILENAME} --name=${FILENAME} ${UPLOADFLAGS} --overwrite'

sh "az storage file upload-batch \
--account-name prodjenkinsreports \
--destination reports \
--source ${dirname ?: '.'} \
--destination-path ${dirname ?: '/'} \
--pattern ${ basename ?: '*' } \
${uploadFlags}"
// `az storage file upload` doesn't support file uploaded in a remote directory that doesn't exist but upload-batch yes. Unfortunately the cli syntax is a bit different and requires filename and directory name to be set differently.
sh 'az storage file upload-batch --account-name prodjenkinsreports --destination reports --source ${SOURCE_DIRNAME} --destination-path ${DESTINATION_PATH} --pattern ${PATTERN} ${UPLOADFLAGS}'
}
}
}
Expand Down