Skip to content

Commit

Permalink
Cherry-pick elastic#22076 to 7.x: Cherry-pick to 7.10: packaging back…
Browse files Browse the repository at this point in the history
…ports (elastic#23142)

Backports the following commits to 7.x:
* feat: add a new step to run the e2e tests for certain parts of Beats (elastic#21100)
* [E2E Tests] fix: set versions ony for PRs (elastic#21608)
* [CI: Packaging] fix: push ubi8 images too (elastic#21621)
* fix: remove extra curly brace in script (elastic#21692)
* fix: update fleet test suite name (elastic#21738)
* chore: create CI artifacts for DEV usage (elastic#21645)
* chore: simplify triggering the E2E tests for Beats (elastic#21790)
* chore: delegate variant pushes to the right method (elastic#21861)
* feat: package aliases for snapshots (elastic#21960)
* fix: use proper param name for e2e tests (elastic#22836)

Co-authored-by: Victor Martinez <victormartinezrubio@gmail.com>
Co-authored-by: Manuel de la Peña <mdelapenya@gmail.com>
(cherry picked from commit 1006bd9)
  • Loading branch information
jsoriano committed Jan 7, 2021
1 parent 1aeedfb commit 000785f
Showing 1 changed file with 144 additions and 35 deletions.
179 changes: 144 additions & 35 deletions .ci/packaging.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,24 @@

@Library('apm@current') _

import groovy.transform.Field

/**
This is required to store the test suites we will use to trigger the E2E tests.
*/
@Field def e2eTestSuites = []

pipeline {
agent none
environment {
BASE_DIR = 'src/github.com/elastic/beats'
REPO = 'beats'
BASE_DIR = "src/github.com/elastic/${env.REPO}"
JOB_GCS_BUCKET = 'beats-ci-artifacts'
JOB_GCS_BUCKET_STASH = 'beats-ci-temp'
JOB_GCS_CREDENTIALS = 'beats-ci-gcs-plugin'
DOCKERELASTIC_SECRET = 'secret/observability-team/ci/docker-registry/prod'
DOCKER_REGISTRY = 'docker.elastic.co'
GITHUB_CHECK_E2E_TESTS_NAME = 'E2E Tests'
SNAPSHOT = "true"
PIPELINE_LOG_LEVEL = "INFO"
}
Expand All @@ -34,7 +43,7 @@ pipeline {
}
stages {
stage('Filter build') {
agent { label 'ubuntu && immutable' }
agent { label 'ubuntu-18 && immutable' }
when {
beforeAgent true
anyOf {
Expand Down Expand Up @@ -103,14 +112,14 @@ pipeline {
'x-pack/heartbeat',
// 'x-pack/journalbeat',
'x-pack/metricbeat',
'x-pack/packetbeat',
// 'x-pack/packetbeat',
'x-pack/winlogbeat'
)
}
}
stages {
stage('Package Linux'){
agent { label 'ubuntu && immutable' }
agent { label 'ubuntu-18 && immutable' }
options { skipDefaultCheckout() }
when {
beforeAgent true
Expand Down Expand Up @@ -142,6 +151,7 @@ pipeline {
release()
pushCIDockerImages()
}
prepareE2ETestForPackage("${BEATS_FOLDER}")
}
}
stage('Package Mac OS'){
Expand Down Expand Up @@ -172,6 +182,13 @@ pipeline {
}
}
}
stage('Run E2E Tests for Packages'){
agent { label 'ubuntu-18 && immutable' }
options { skipDefaultCheckout() }
steps {
runE2ETests()
}
}
}
post {
success {
Expand All @@ -190,68 +207,160 @@ pipeline {

def pushCIDockerImages(){
catchError(buildResult: 'UNSTABLE', message: 'Unable to push Docker images', stageResult: 'FAILURE') {
if ("${env.BEATS_FOLDER}" == "auditbeat"){
tagAndPush('auditbeat-oss')
} else if ("${env.BEATS_FOLDER}" == "filebeat") {
tagAndPush('filebeat-oss')
} else if ("${env.BEATS_FOLDER}" == "heartbeat"){
tagAndPush('heartbeat-oss')
if (env?.BEATS_FOLDER?.endsWith('auditbeat')) {
tagAndPush('auditbeat')
} else if (env?.BEATS_FOLDER?.endsWith('filebeat')) {
tagAndPush('filebeat')
} else if (env?.BEATS_FOLDER?.endsWith('heartbeat')) {
tagAndPush('heartbeat')
} else if ("${env.BEATS_FOLDER}" == "journalbeat"){
tagAndPush('journalbeat')
tagAndPush('journalbeat-oss')
} else if ("${env.BEATS_FOLDER}" == "metricbeat"){
tagAndPush('metricbeat-oss')
} else if (env?.BEATS_FOLDER?.endsWith('metricbeat')) {
tagAndPush('metricbeat')
} else if ("${env.BEATS_FOLDER}" == "packetbeat"){
tagAndPush('packetbeat')
tagAndPush('packetbeat-oss')
} else if ("${env.BEATS_FOLDER}" == "x-pack/auditbeat"){
tagAndPush('auditbeat')
} else if ("${env.BEATS_FOLDER}" == "x-pack/elastic-agent") {
tagAndPush('elastic-agent')
} else if ("${env.BEATS_FOLDER}" == "x-pack/filebeat"){
tagAndPush('filebeat')
} else if ("${env.BEATS_FOLDER}" == "x-pack/heartbeat"){
tagAndPush('heartbeat')
} else if ("${env.BEATS_FOLDER}" == "x-pack/metricbeat"){
tagAndPush('metricbeat')
}
}
}

def tagAndPush(name){
def tagAndPush(beatName){
def libbetaVer = env.BEAT_VERSION
def aliasVersion = ""
if("${env.SNAPSHOT}" == "true"){
aliasVersion = libbetaVer.substring(0, libbetaVer.lastIndexOf(".")) // remove third number in version

libbetaVer += "-SNAPSHOT"
aliasVersion += "-SNAPSHOT"
}

def tagName = "${libbetaVer}"
if (isPR()) {
tagName = "pr-${env.CHANGE_ID}"
}

def oldName = "${DOCKER_REGISTRY}/beats/${name}:${libbetaVer}"
def newName = "${DOCKER_REGISTRY}/observability-ci/${name}:${tagName}"
def commitName = "${DOCKER_REGISTRY}/observability-ci/${name}:${env.GIT_BASE_COMMIT}"
dockerLogin(secret: "${DOCKERELASTIC_SECRET}", registry: "${DOCKER_REGISTRY}")
retry(3){
sh(label:'Change tag and push', script: """
docker tag ${oldName} ${newName}
docker push ${newName}
docker tag ${oldName} ${commitName}
docker push ${commitName}
""")

// supported image flavours
def variants = ["", "-oss", "-ubi8"]
variants.each { variant ->
doTagAndPush(beatName, variant, libbetaVer, tagName)
doTagAndPush(beatName, variant, libbetaVer, "${env.GIT_BASE_COMMIT}")

if (!isPR() && aliasVersion != "") {
doTagAndPush(beatName, variant, libbetaVer, aliasVersion)
}
}
}

/**
* @param beatName name of the Beat
* @param variant name of the variant used to build the docker image name
* @param sourceTag tag to be used as source for the docker tag command, usually under the 'beats' namespace
* @param targetTag tag to be used as target for the docker tag command, usually under the 'observability-ci' namespace
*/
def doTagAndPush(beatName, variant, sourceTag, targetTag) {
def sourceName = "${DOCKER_REGISTRY}/beats/${beatName}${variant}:${sourceTag}"
def targetName = "${DOCKER_REGISTRY}/observability-ci/${beatName}${variant}:${targetTag}"

def iterations = 0
retryWithSleep(retries: 3, seconds: 5, backoff: true) {
iterations++
def status = sh(label: "Change tag and push ${targetName}", script: """
docker tag ${sourceName} ${targetName}
docker push ${targetName}
""", returnStatus: true)

if ( status > 0 && iterations < 3) {
error("tag and push failed for ${beatName}, retry")
} else if ( status > 0 ) {
log(level: 'WARN', text: "${beatName} doesn't have ${variant} docker images. See https://github.com/elastic/beats/pull/21621")
}
}
}

def prepareE2ETestForPackage(String beat){
if ("${beat}" == "filebeat" || "${beat}" == "x-pack/filebeat") {
e2eTestSuites.push('fleet')
e2eTestSuites.push('helm')
} else if ("${beat}" == "metricbeat" || "${beat}" == "x-pack/metricbeat") {
e2eTestSuites.push('ALL')
echo("${beat} adds all test suites to the E2E tests job.")
} else if ("${beat}" == "x-pack/elastic-agent") {
e2eTestSuites.push('fleet')
} else {
echo("${beat} does not add any test suite to the E2E tests job.")
return
}
}

def release(){
withBeatsEnv(){
dir("${env.BEATS_FOLDER}") {
sh(label: "Release ${env.BEATS_FOLDER} ${env.PLATFORMS}", script: 'mage package')
withEnv([
"DEV=true"
]) {
dir("${env.BEATS_FOLDER}") {
sh(label: "Release ${env.BEATS_FOLDER} ${env.PLATFORMS}", script: 'mage package')
}
}
publishPackages("${env.BEATS_FOLDER}")
}
}

def runE2ETests(){
if (e2eTestSuites.size() == 0) {
echo("Not triggering E2E tests for PR-${env.CHANGE_ID} because the changes does not affect the E2E.")
return
}

def suites = '' // empty value represents all suites in the E2E tests

catchError(buildResult: 'UNSTABLE', message: 'Unable to run e2e tests', stageResult: 'FAILURE') {
def suitesSet = e2eTestSuites.toSet()

if (!suitesSet.contains('ALL')) {
suitesSet.each { suite ->
suites += "${suite},"
};
}

triggerE2ETests(suites)
}
}

def triggerE2ETests(String suite) {
echo("Triggering E2E tests for PR-${env.CHANGE_ID}. Test suites: ${suite}.")

def branchName = isPR() ? "${env.CHANGE_TARGET}" : "${env.JOB_BASE_NAME}.x"
def e2eTestsPipeline = "e2e-tests/e2e-testing-mbp/${branchName}"

def parameters = [
booleanParam(name: 'forceSkipGitChecks', value: true),
booleanParam(name: 'forceSkipPresubmit', value: true),
booleanParam(name: 'notifyOnGreenBuilds', value: !isPR()),
string(name: 'runTestsSuites', value: suite),
string(name: 'GITHUB_CHECK_NAME', value: env.GITHUB_CHECK_E2E_TESTS_NAME),
string(name: 'GITHUB_CHECK_REPO', value: env.REPO),
string(name: 'GITHUB_CHECK_SHA1', value: env.GIT_BASE_COMMIT),
]
if (isPR()) {
def version = "pr-${env.CHANGE_ID}"
parameters.push(booleanParam(name: 'ELASTIC_AGENT_USE_CI_SNAPSHOTS', value: true))
parameters.push(string(name: 'ELASTIC_AGENT_VERSION', value: "${version}"))
parameters.push(string(name: 'METRICBEAT_VERSION', value: "${version}"))
}

build(job: "${e2eTestsPipeline}",
parameters: parameters,
propagate: false,
wait: false
)

def notifyContext = "${env.GITHUB_CHECK_E2E_TESTS_NAME}"
githubNotify(context: "${notifyContext}", description: "${notifyContext} ...", status: 'PENDING', targetUrl: "${env.JENKINS_URL}search/?q=${e2eTestsPipeline.replaceAll('/','+')}")
}

def withMacOSEnv(Closure body){
withEnvMask( vars: [
[var: "KEYCHAIN_PASS", password: getVaultSecret(secret: "secret/jenkins-ci/macos-codesign-keychain").data.password],
Expand Down

0 comments on commit 000785f

Please sign in to comment.