Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add artifacts upload library
Browse files Browse the repository at this point in the history
Signed-off-by: Sayali Gaikawad <gaiksaya@amazon.com>
gaiksaya committed Feb 4, 2023
1 parent ad5133e commit c8552da
Showing 5 changed files with 264 additions and 0 deletions.
63 changes: 63 additions & 0 deletions tests/jenkins/TestPublishToArtifactsProdBucket.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package jenkins.tests

import jenkins.tests.BuildPipelineTest
import static com.lesfurets.jenkins.unit.MethodCall.callArgsToString
import static org.hamcrest.CoreMatchers.hasItem
import static org.hamcrest.CoreMatchers.hasItems
import static org.hamcrest.MatcherAssert.assertThat
import org.junit.Before
import org.junit.Test

class TestPublishToArtifactsProdBucket extends BuildPipelineTest {
@Override
@Before
void setUp() {

this.registerLibTester(new PublishToArtifactsProdBucketLibTester('test-role', 'the-windows-msi.msi', 'msi/', 'windows', 'null', true))
this.registerLibTester(new PublishToArtifactsProdBucketLibTester('test-role-2', 'reporting-cli-2.3.0.tg.gz', 'reporting-cli/'))
super.setUp()
}

@Test
public void test() {
super.testPipeline('tests/jenkins/jobs/PublishToArtifactsProdBucket_Jenkinsfile')
}

@Test
void 'verify signing_with_defaults'(){
runScript('tests/jenkins/jobs/PublishToArtifactsProdBucket_Jenkinsfile')
assertThat(getShellCommands('sh', 'sign.sh'), hasItem('\n #!/bin/bash\n set +x\n export ROLE=SIGNER_CLIENT_ROLE\n export EXTERNAL_ID=SIGNER_CLIENT_EXTERNAL_ID\n export UNSIGNED_BUCKET=SIGNER_CLIENT_UNSIGNED_BUCKET\n export SIGNED_BUCKET=SIGNER_CLIENT_SIGNED_BUCKET\n\n /tmp/workspace/sign.sh reporting-cli-2.3.0.tg.gz --platform linux --sigtype .sig\n '
))
}

@Test
void 'verify_signing_with_args'(){
runScript('tests/jenkins/jobs/PublishToArtifactsProdBucket_Jenkinsfile')
assertThat(getShellCommands('sh', 'sign.sh'), hasItem("\n #!/bin/bash\n set +x\n export ROLE=SIGNER_WINDOWS_ROLE\n export EXTERNAL_ID=SIGNER_WINDOWS_EXTERNAL_ID\n export UNSIGNED_BUCKET=SIGNER_WINDOWS_UNSIGNED_BUCKET\n export SIGNED_BUCKET=SIGNER_WINDOWS_SIGNED_BUCKET\n export PROFILE_IDENTIFIER=SIGNER_WINDOWS_PROFILE_IDENTIFIER\n export PLATFORM_IDENTIFIER=SIGNER_WINDOWS_PLATFORM_IDENTIFIER\n\n /tmp/workspace/sign.sh the-windows-msi.msi --platform windows --sigtype null --overwrite \n "))
}

@Test
void 'verifyS3uploads'(){
runScript('tests/jenkins/jobs/PublishToArtifactsProdBucket_Jenkinsfile')
assertThat(getShellCommands('s3Upload', ''), hasItems('{file=the-windows-msi.msi, bucket=ARTIFACT_PRODUCTION_BUCKET_NAME, path=msi/}', '{file=reporting-cli-2.3.0.tg.gz, bucket=ARTIFACT_PRODUCTION_BUCKET_NAME, path=reporting-cli/}'))
}
def getShellCommands(methodName, searchString) {
def shCommands = helper.callStack.findAll { call ->
call.methodName == methodName
}.collect { call ->
callArgsToString(call)
}.findAll { command ->
command.contains(searchString)
}
return shCommands
}
}
34 changes: 34 additions & 0 deletions tests/jenkins/jobs/PublishToArtifactsProdBucket_Jenkinsfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

pipeline {
agent none
stages {
stage('publishToartifactsDotOrg') {
steps {
script {
publishToArtifactsProdBucket(
assumedRoleName: 'test-role',
source: 'the-windows-msi.msi',
destination: 'msi/',
signingPlatform: 'windows',
sigType: 'null',
overwrite: true
)

publishToArtifactsProdBucket(
assumedRoleName: 'test-role-2',
source: 'reporting-cli-2.3.0.tg.gz',
destination: 'reporting-cli/'
)
}
}
}
}
}
67 changes: 67 additions & 0 deletions tests/jenkins/jobs/PublishToArtifactsProdBucket_Jenkinsfile.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
PublishToArtifactsProdBucket_Jenkinsfile.run()
PublishToArtifactsProdBucket_Jenkinsfile.pipeline(groovy.lang.Closure)
PublishToArtifactsProdBucket_Jenkinsfile.echo(Executing on agent [label:none])
PublishToArtifactsProdBucket_Jenkinsfile.stage(publishToartifactsDotOrg, groovy.lang.Closure)
PublishToArtifactsProdBucket_Jenkinsfile.script(groovy.lang.Closure)
PublishToArtifactsProdBucket_Jenkinsfile.publishToArtifactsProdBucket({assumedRoleName=test-role, source=the-windows-msi.msi, destination=msi/, signingPlatform=windows, sigType=null, overwrite=true})
publishToArtifactsProdBucket.legacySCM(groovy.lang.Closure)
publishToArtifactsProdBucket.library({identifier=jenkins@main, retriever=null})
publishToArtifactsProdBucket.signArtifacts({artifactPath=the-windows-msi.msi, platform=windows, sigtype=null, overwrite=true})
signArtifacts.echo(PGP or Windows Signature Signing)
signArtifacts.fileExists(/tmp/workspace/sign.sh)
signArtifacts.git({url=https://github.com/opensearch-project/opensearch-build.git, branch=main})
signArtifacts.sh(curl -sSL https://artifacts.opensearch.org/publickeys/opensearch.pgp | gpg --import -)
signArtifacts.usernamePassword({credentialsId=github_bot_token_name, usernameVariable=GITHUB_USER, passwordVariable=GITHUB_TOKEN})
signArtifacts.string({credentialsId=jenkins-signer-windows-role, variable=SIGNER_WINDOWS_ROLE})
signArtifacts.string({credentialsId=jenkins-signer-windows-external-id, variable=SIGNER_WINDOWS_EXTERNAL_ID})
signArtifacts.string({credentialsId=jenkins-signer-windows-unsigned-bucket, variable=SIGNER_WINDOWS_UNSIGNED_BUCKET})
signArtifacts.string({credentialsId=jenkins-signer-windows-signed-bucket, variable=SIGNER_WINDOWS_SIGNED_BUCKET})
signArtifacts.string({credentialsId=jenkins-signer-windows-profile-identifier, variable=SIGNER_WINDOWS_PROFILE_IDENTIFIER})
signArtifacts.string({credentialsId=jenkins-signer-windows-platform-identifier, variable=SIGNER_WINDOWS_PLATFORM_IDENTIFIER})
signArtifacts.withCredentials([[GITHUB_USER, GITHUB_TOKEN], SIGNER_WINDOWS_ROLE, SIGNER_WINDOWS_EXTERNAL_ID, SIGNER_WINDOWS_UNSIGNED_BUCKET, SIGNER_WINDOWS_SIGNED_BUCKET, SIGNER_WINDOWS_PROFILE_IDENTIFIER, SIGNER_WINDOWS_PLATFORM_IDENTIFIER], groovy.lang.Closure)
signArtifacts.sh(
#!/bin/bash
set +x
export ROLE=SIGNER_WINDOWS_ROLE
export EXTERNAL_ID=SIGNER_WINDOWS_EXTERNAL_ID
export UNSIGNED_BUCKET=SIGNER_WINDOWS_UNSIGNED_BUCKET
export SIGNED_BUCKET=SIGNER_WINDOWS_SIGNED_BUCKET
export PROFILE_IDENTIFIER=SIGNER_WINDOWS_PROFILE_IDENTIFIER
export PLATFORM_IDENTIFIER=SIGNER_WINDOWS_PLATFORM_IDENTIFIER

/tmp/workspace/sign.sh the-windows-msi.msi --platform windows --sigtype null --overwrite
)
publishToArtifactsProdBucket.string({credentialsId=jenkins-aws-production-account, variable=AWS_ACCOUNT_ARTIFACT})
publishToArtifactsProdBucket.string({credentialsId=jenkins-artifact-production-bucket-name, variable=ARTIFACT_PRODUCTION_BUCKET_NAME})
publishToArtifactsProdBucket.withCredentials([AWS_ACCOUNT_ARTIFACT, ARTIFACT_PRODUCTION_BUCKET_NAME], groovy.lang.Closure)
publishToArtifactsProdBucket.withAWS({role=test-role, roleAccount=AWS_ACCOUNT_ARTIFACT, duration=900, roleSessionName=jenkins-session}, groovy.lang.Closure)
publishToArtifactsProdBucket.s3Upload({file=the-windows-msi.msi, bucket=ARTIFACT_PRODUCTION_BUCKET_NAME, path=msi/})
PublishToArtifactsProdBucket_Jenkinsfile.publishToArtifactsProdBucket({assumedRoleName=test-role-2, source=reporting-cli-2.3.0.tg.gz, destination=reporting-cli/})
publishToArtifactsProdBucket.legacySCM(groovy.lang.Closure)
publishToArtifactsProdBucket.library({identifier=jenkins@main, retriever=null})
publishToArtifactsProdBucket.signArtifacts({artifactPath=reporting-cli-2.3.0.tg.gz, platform=linux, sigtype=.sig, overwrite=false})
signArtifacts.echo(PGP or Windows Signature Signing)
signArtifacts.fileExists(/tmp/workspace/sign.sh)
signArtifacts.git({url=https://github.com/opensearch-project/opensearch-build.git, branch=main})
signArtifacts.sh(curl -sSL https://artifacts.opensearch.org/publickeys/opensearch.pgp | gpg --import -)
signArtifacts.usernamePassword({credentialsId=github_bot_token_name, usernameVariable=GITHUB_USER, passwordVariable=GITHUB_TOKEN})
signArtifacts.string({credentialsId=jenkins-signer-client-role, variable=SIGNER_CLIENT_ROLE})
signArtifacts.string({credentialsId=jenkins-signer-client-external-id, variable=SIGNER_CLIENT_EXTERNAL_ID})
signArtifacts.string({credentialsId=jenkins-signer-client-unsigned-bucket, variable=SIGNER_CLIENT_UNSIGNED_BUCKET})
signArtifacts.string({credentialsId=jenkins-signer-client-signed-bucket, variable=SIGNER_CLIENT_SIGNED_BUCKET})
signArtifacts.withCredentials([[GITHUB_USER, GITHUB_TOKEN], SIGNER_CLIENT_ROLE, SIGNER_CLIENT_EXTERNAL_ID, SIGNER_CLIENT_UNSIGNED_BUCKET, SIGNER_CLIENT_SIGNED_BUCKET], groovy.lang.Closure)
signArtifacts.sh(
#!/bin/bash
set +x
export ROLE=SIGNER_CLIENT_ROLE
export EXTERNAL_ID=SIGNER_CLIENT_EXTERNAL_ID
export UNSIGNED_BUCKET=SIGNER_CLIENT_UNSIGNED_BUCKET
export SIGNED_BUCKET=SIGNER_CLIENT_SIGNED_BUCKET

/tmp/workspace/sign.sh reporting-cli-2.3.0.tg.gz --platform linux --sigtype .sig
)
publishToArtifactsProdBucket.string({credentialsId=jenkins-aws-production-account, variable=AWS_ACCOUNT_ARTIFACT})
publishToArtifactsProdBucket.string({credentialsId=jenkins-artifact-production-bucket-name, variable=ARTIFACT_PRODUCTION_BUCKET_NAME})
publishToArtifactsProdBucket.withCredentials([AWS_ACCOUNT_ARTIFACT, ARTIFACT_PRODUCTION_BUCKET_NAME], groovy.lang.Closure)
publishToArtifactsProdBucket.withAWS({role=test-role-2, roleAccount=AWS_ACCOUNT_ARTIFACT, duration=900, roleSessionName=jenkins-session}, groovy.lang.Closure)
publishToArtifactsProdBucket.s3Upload({file=reporting-cli-2.3.0.tg.gz, bucket=ARTIFACT_PRODUCTION_BUCKET_NAME, path=reporting-cli/})
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/
import static org.hamcrest.CoreMatchers.notNullValue
import static org.hamcrest.MatcherAssert.assertThat

class PublishToArtifactsProdBucketLibTester extends LibFunctionTester {

private String assumedRoleName
private String source
private String destination
private String signingPlatform
private String sigtype
private boolean overwrite

public PublishToArtifactsProdBucketLibTester(assumedRoleName, source, destination, signingPlatform, sigtype, overwrite) {
this.assumedRoleName = assumedRoleName
this.source = source
this.destination = destination
this.sigtype = sigtype
this.signingPlatform = signingPlatform
this.overwrite = overwrite
}

public PublishToArtifactsProdBucketLibTester(assumedRoleName, source, destination){
this.assumedRoleName = assumedRoleName
this.source = source
this.destination = destination
}

void configure(helper, binding){
helper.registerAllowedMethod("s3Upload", [Map])
binding.setVariable('GITHUB_BOT_TOKEN_NAME', 'github_bot_token_name')
helper.registerAllowedMethod('git', [Map])
helper.registerAllowedMethod('withCredentials', [Map, Closure], { args, closure ->
closure.delegate = delegate
return helper.callClosure(closure)
})
helper.registerAllowedMethod('withAWS', [Map, Closure], { args, closure ->
closure.delegate = delegate
return helper.callClosure(closure)
})
}

void parameterInvariantsAssertions(call){
assertThat(call.args.assumedRoleName.first(), notNullValue())
assertThat(call.args.source.first(), notNullValue())
assertThat(call.args.destination.first(), notNullValue())
}

boolean expectedParametersMatcher(call) {
return call.args.assumedRoleName.first().toString().equals(this.assumedRoleName)
&& call.args.source.first().toString().equals(this.source)
&& call.args.destination.first().toString().equals(this.destination)
}

String libFunctionName() {
return 'publishToArtifactsProdBucket'
}
}
35 changes: 35 additions & 0 deletions vars/publishToArtifactsProdBucket.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

/**
* Library to sign and upload artifacts to artifacts.opensearch.org
@param Map[assumedRoleName] <required> - IAM role to be assumed for uploading artifacts
@param Map[source] <required> - Path to yml or artifact file.
@param Map[destination] <required> - Artifact type in the manifest, [type] is required for signing yml.
@param Map[signingPlatform] <optional> - The distribution platform for signing. Defaults to linux
@param Map[sigtype] <optional> - signature type. Defaults to '.sig'
@param Map[overwrite]<optional> - Allow output artifacts to overwrite the existing artifacts. Defaults to false
*/
void call(Map args = [:]) {
lib = library(identifier: 'jenkins@main', retriever: legacySCM(scm))
println('Signing the artifacts')
signArtifacts(
artifactPath: args.source,
platform: args.signingPlatform ?: 'linux',
sigtype: args.sigType ?: '.sig',
overwrite: args.overwrite ?: false
)
withCredentials([
string(credentialsId: 'jenkins-aws-production-account', variable: 'AWS_ACCOUNT_ARTIFACT'),
string(credentialsId: 'jenkins-artifact-production-bucket-name', variable: 'ARTIFACT_PRODUCTION_BUCKET_NAME')]) {
withAWS(role: "${args.assumedRoleName}", roleAccount: "${AWS_ACCOUNT_ARTIFACT}", duration: 900, roleSessionName: 'jenkins-session') {
s3Upload(file: "${args.source}", bucket: "${ARTIFACT_PRODUCTION_BUCKET_NAME}", path: "${args.destination}")
}
}
}

0 comments on commit c8552da

Please sign in to comment.